// Add a box for the individual to the specified group. private static CMiniTreeIndividual AddToGroup(CIndividualRecord ir, CMiniTreeGroup mtg, bool bSpouse) { CMiniTreeIndividual mti = null; if (Exists(ir)) { CBoxText boxtext = new CBoxText(ir); mti = mtg.AddIndividual(ir, boxtext.m_sFirstName, boxtext.m_sSurname, boxtext.m_sDate, true, false, false, boxtext.m_bConcealed, bSpouse); } else { mti = mtg.AddIndividual(null, "", MainForm.s_config.m_sUnknownName, " ", false, false, false, false, bSpouse); } return mti; }
// Calculate size required for tree by iterating through individuals and building a data structure. protected CMiniTreeGroup CreateDataStructure( CIndividualRecord irSubject ) { // Add subject's frParents CFamilyRecord frParents = m_gedcom.GetFamilyByChild(irSubject, 0); CMiniTreeGroup mtgParents = new CMiniTreeGroup(); CMiniTreeIndividual mtiFather = null; if( frParents != null ) { mtiFather = AddToGroup(frParents.m_xrefHusband, mtgParents, false); } // Create a group for the subejct and their siblings. CMiniTreeGroup mtgSiblings = new CMiniTreeGroup(); // Keeps count of subject's siblings (including subject) int nSiblings = 0; // Keeps track of last added sibling, to hook up to next added sibling. CMiniTreeIndividual mtiRightmostSibling = null; // Keeps track of last added child, to hook up to next added child. CMiniTreeIndividual mtiRightmostChild = null; // For each sibling (including the subject) for(;;) { CIndividualRecord irSibling = GetChild(frParents, nSiblings, irSubject); if (null == irSibling) { break; } if (irSibling == irSubject) { // Add spouses and children of subject, (and subject too, if we need to put wife after them.) CMiniTreeGroup mtgOffspring = null; bool bAddedSubject = false; int nSpouses = 0; CMiniTreeGroup.ECrossbar ecbCrossbar = CMiniTreeGroup.ECrossbar.eCB_Solid; ArrayList alFamily = m_gedcom.GetFamilyArray(irSubject); foreach( CFamilyRecord fr in alFamily ) { CIndividualRecord irSpouse = fr.GetSpouse(irSubject); if (!fr.IsHusband(irSubject)) { mtiRightmostSibling = AddToGroup(irSpouse, mtgSiblings, true); // Subject is female so all but last husband have dotted bars ecbCrossbar = CMiniTreeGroup.ECrossbar.eCB_DottedLeft; } else if (Exists(irSubject) && !bAddedSubject) { // Subject is male, so need to put them in now, before their children. // (Otherwise they get added as a regular sibling later) CBoxText boxtext = new CBoxText(irSubject); mtiRightmostSibling = mtgSiblings.AddIndividual(irSubject, boxtext.m_sFirstName, boxtext.m_sSurname, boxtext.m_sDate, false, frParents != null, true, boxtext.m_bConcealed, false); // To stop subject being added as regular sibling. bAddedSubject = true; } int nGrandchildren = 0; CIndividualRecord irGrandchild = null; // If we have already added an offspring box (from previous marriage) need connect this box to it as its right box. if (mtgOffspring != null) { mtgOffspring.RightBox = mtiRightmostSibling; } // Create a box for the offspring of this marriage mtgOffspring = new CMiniTreeGroup(); // Set crossbar that joins subject to spouse according to whether this is subject's first spouse. mtgOffspring.m_ecCrossbar = ecbCrossbar; // Add children by this spouse CMiniTreeIndividual mtiChild = null; while(true) { // The ordering of children in the tree can be selected to be the same as it is in the GEDCOM file. This // is because the file should be ordered as the user chose to order the fr when entering the data in // their fr history app, regardless of actual birth dates. if (MainForm.s_config.m_bKeepSiblingOrder) { irGrandchild = fr.GetChildByPositionInFile(nGrandchildren); } else { irGrandchild = fr.GetChild(nGrandchildren); } if (irGrandchild == null) { break; } if( Exists(irGrandchild) ) { CBoxText boxtext = new CBoxText(irGrandchild); mtiChild = mtgOffspring.AddIndividual(irGrandchild, boxtext.m_sFirstName, boxtext.m_sSurname, boxtext.m_sDate, true, true, false, boxtext.m_bConcealed, false); // Hook this up to any children by previous spouses. if( nGrandchildren==0 && mtiRightmostChild != null ) { mtiRightmostChild.RightObjectAlien = mtiChild; mtiChild.LeftObjectAlien = mtiRightmostChild; } } nGrandchildren++; } // If we added anything, record it as the right-most child ready to hook to children by next spouse. if( mtiChild != null ) { mtiRightmostChild = mtiChild; } // Add the subjects children to the siblings group mtgSiblings.AddGroup( mtgOffspring ); // Hook the offspring group to the previous sibling if( mtgOffspring != null ) { mtgOffspring.LeftBox = mtiRightmostSibling; } // If subject is husband then we need to add their wife now. if (fr.IsWife(irSpouse)) { ecbCrossbar = CMiniTreeGroup.ECrossbar.eCB_DottedRight; // Hook up to previous rightmost sibling and set this as new rightmost sibling. mtiRightmostSibling = AddToGroup(irSpouse, mtgSiblings, true); // Hook the wife up as box on right of offspring box. if( mtgOffspring != null ) { mtgOffspring.RightBox = mtiRightmostSibling; } } nSpouses++; } if (!bAddedSubject) { CBoxText boxtext = new CBoxText(irSubject); CMiniTreeIndividual mtiWife = mtgSiblings.AddIndividual(irSubject, boxtext.m_sFirstName, boxtext.m_sSurname, boxtext.m_sDate, false, frParents != null, true, boxtext.m_bConcealed, false); if (mtgOffspring != null) { mtgOffspring.m_ecCrossbar = CMiniTreeGroup.ECrossbar.eCB_Solid; mtgOffspring.RightBox = mtiWife; } } } else if( Exists(irSibling) ) { // A sibling (not the subject). CBoxText boxtext = new CBoxText(irSibling); mtgSiblings.AddIndividual(irSibling, boxtext.m_sFirstName, boxtext.m_sSurname, boxtext.m_sDate, true, frParents != null, false, boxtext.m_bConcealed, false); } nSiblings++; } // End: for each child in frParents. // Add siblings group after subject's father mtgParents.AddGroup( mtgSiblings ); // Hook up to subject's father mtgSiblings.LeftBox = mtiFather; // Add subject's mother if( frParents != null ) { CMiniTreeIndividual mtiMother = AddToGroup(frParents.m_xrefWife, mtgParents, false); mtgSiblings.RightBox = mtiMother; } // Return the parents group (which contains the other family groups). return mtgParents; }