diff --git a/help.h b/help.h index 29e9cf7..5a8135c 100644 --- a/help.h +++ b/help.h @@ -2,8 +2,6 @@ #include "common/basicTypes.h" -enum Relation : U8; - unsigned strLen(const char* str); void strCopy(char *to, const char* from); bool strComp(const char* firts, const char* second); //0 - diffrent 1 - same diff --git a/main.cpp b/main.cpp index 8033110..7703968 100644 --- a/main.cpp +++ b/main.cpp @@ -15,33 +15,42 @@ int main() cbreak(); /* get input instantly */ wnoutrefresh(stdscr); /* if not present the first real refresh is missed */ - /*Tree test1("Dechkovi"); //addTree Dechkovi addTree Karamanovi load 0 load 1 (to work with these example trees) + Tree test1("Dechkovi"); //addTree Dechkovi addTree Karamanovi load 0 load 1 (to work with these example trees) Tree test2("Karamanovi"); - test1.addPerson("Rumen", 1968, 8, 9, 0); - test1.addPerson("Nadejda", 1972, 12, 15, 1); - test1.addRelation(0, Husband, 1); - test1.addPerson("Venelin", 1998, 6, 9, 0, 0, 1); - test1.addPerson("Vasil", 2001, 1, 16, 0, 0, 1); - test1.addRelation(2, Brother, 3); - test1.addPerson("Maria-Veronika", 2009, 9, 3, 1, 0, 1); - test1.addRelation(2, Brother, 4); - test1.addRelation(3, Brother, 4); + test1.addPerson("Rumen", true, Nobody, Nobody, {1968, 8, 9}); + test1.addPerson("Nadejda", false, Nobody, Nobody, {1972, 12, 15}); + /* test1.addRelation(0, Husband, 1); */ + test1.addPerson("Venelin", true, 0, 1, {1998, 6, 9}); + test1.addPerson("Vasil", true, 0, 1, {2001, 1, 16}); + /* test1.addRelation(2, Brother, 3); */ + /* test1.addPerson("Maria-Veronika", 2009, 9, 3, 1, 0, 1); */ + /* test1.addRelation(2, Brother, 4); */ + /* test1.addRelation(3, Brother, 4); */ - test2.addPerson("Vasil Dimitrov", 1941, 5, 18, 0); - test2.addPerson("Maria", 0, 0, 0, 1); - test2.addRelation(0, Husband, 1); - test2.addPerson("Dimitar", 0, 0, 0, 0, 0, 1); - test2.addPerson("Nadejda", 1972, 12, 15, 1, 0, 1); - test2.addRelation(2, Brother, 3); - test2.addPerson("Branimira", 0, 0, 0, 1); - test2.addRelation(2, Husband, 4); - test2.addPerson("Ioan", 0, 0, 0, 0, 2, 4); - test2.addPerson("Rumiana", 0, 0, 0, 1, 2, 4); - test2.addRelation(5, Brother, 6); + test2.addPerson("Vasil Dimitrov", true, Nobody, Nobody, {1941, 5, 18}); + test2.addPerson("Maria", false); + /* test2.addRelation(0, Husband, 1); */ + test2.addPerson("Dimitar", true, 0, 1); + test2.addPerson("Nadejda", false, 0, 1, {1972, 12, 15}); + /* test2.addRelation(2, Brother, 3); */ + test2.addPerson("Branimira", false); + /* test2.addRelation(2, Husband, 4); */ + test2.addPerson("Ioan", true, 2, 4); + test2.addPerson("Rumiana", false, 2, 4); + /* test2.addRelation(5, Brother, 6); */ - test1.saveTree(); - test2.saveTree();*/ + test1.draw(); + test2.draw(); + + /* (test1 + test2).draw(4); */ + test1 += test2; + test1.draw(4); + test1.draw(); + + + /* test1.saveTree(); */ + /* test2.saveTree(); */ Tree firstTree("firstTree"); @@ -68,7 +77,7 @@ int main() /* firstTree.print(); */ firstTree.draw(); - firstTree.saveTree(); + /* firstTree.saveTree(); */ /* firstTree.printRel(3); */ firstTree.printOldestAncestors(3); diff --git a/person.cpp b/person.cpp index db80652..aa65a6a 100644 --- a/person.cpp +++ b/person.cpp @@ -161,7 +161,7 @@ void Person::print()const U16 Person::boxWidth() const { - return name_.size() + 4 - 1; /* TODO: get actual lenght */ + return name_.size() + 4; /* TODO: get actual lenght */ } @@ -181,7 +181,8 @@ void Person::draw(I16 drawY, I16 drawX) const U16 width = boxWidth(); WINDOW* pad = newpad(BOX_HEIGHT, width); - box(pad, BOX_HEIGHT, width); + wborder(pad, ACS_VLINE, ACS_VLINE, ACS_HLINE, ACS_HLINE, ACS_LTEE, ACS_URCORNER, ACS_LTEE, ACS_LRCORNER ); + /* box(pad, BOX_HEIGHT, width); */ mvwaddstr(pad, 2, 2, name_.data()); pnoutrefresh(pad, 0, 0, diff --git a/person.h b/person.h index d014beb..7c21bb4 100644 --- a/person.h +++ b/person.h @@ -20,7 +20,10 @@ struct EventTime I8 minute; //0-59 }; -enum { BOX_HEIGHT = 5 }; +enum { + BOX_HEIGHT = 5, + LINK_HEIGHT = 3 +}; class Person { diff --git a/tree.cpp b/tree.cpp index 2cb0477..be808ea 100644 --- a/tree.cpp +++ b/tree.cpp @@ -38,33 +38,28 @@ Tree Tree::operator+ (const Tree& other)// result.people.push(other.people[i]); } - result.relatives.resize(result.numPeople); result.relations.resize(result.numPeople); - result.relatives = relatives; result.relations = relations; for (unsigned i=0; i < other.numPeople; ++i) //Adds the relatives from the II tree { if (newId[i] >= numPeople) //If the member is found in the II tree but not in the I { - result.relatives.push(other.relatives[i]); result.relations.push(other.relations[i]); } else //If he's found in both { for (unsigned j = 0; j < other.people[i].numRel_; ++j) //Adds the number of relatives from the II to the number in the I { - if(newId[other.relatives[i][j]] > numPeople) + if(newId[other.relations[i][j].id] > numPeople) ++result.people[newId[i]].numRel_; } - result.relatives[newId[i]].resize(result.people[newId[i]].numRel_); result.relations[newId[i]].resize(result.people[newId[i]].numRel_); - result.relatives[newId[i]] = relatives[newId[i]]; result.relations[newId[i]] = relations[newId[i]]; - result.relatives[newId[i]] += other.relatives[i]; //The relatives from the II tree - result.relations[newId[i]] += other.relations[i]; + + result.relations[newId[i]] += other.relations[i]; //The relatives from the II tree } } @@ -98,30 +93,28 @@ Tree& Tree::operator+=(const Tree& other) people.push(other.people[i]); } - relatives.resize(idCounter); relations.resize(idCounter); for (unsigned i = 0; i < other.numPeople; ++i) //Merges the relative data { if (newId[i] >= numPeople) { - relatives.push(other.relatives[i]); - for (unsigned j = 0; j < other.people[i].numRel_; ++j) - relatives[newId[i]][j] = newId[ relatives[newId[i]][j] ]; relations.push(other.relations[i]); + for (unsigned j = 0; j < other.people[i].numRel_; ++j) + relations[newId[i]][j].id = newId[ relations[newId[i]][j].id ]; } else //If the member is present in both trees { for (unsigned j = 0; j < other.people[i].numRel_; ++j) //Adds the number of relatives from the II to the number in the I { - if (newId[other.relatives[i][j]] >= numPeople) + if (newId[other.relations[i][j].id] >= numPeople) ++people[newId[i]].numRel_; } - relatives[newId[i]].resize(people[newId[i]].numRel_); + relations[newId[i]].resize(people[newId[i]].numRel_); for (unsigned j = 0; j < other.people[i].numRel_; ++j) { - relatives[newId[i]][j + people[newId[i]].numRel_ - other.people[i].numRel_] = newId[other.relatives[i][j]]; - relations[newId[i]][j + people[newId[i]].numRel_ - other.people[i].numRel_] = other.relations[i][j]; + relations[newId[i]][j + people[newId[i]].numRel_ - other.people[i].numRel_].id = newId[other.relations[i][j].id]; + relations[newId[i]][j + people[newId[i]].numRel_ - other.people[i].numRel_].type = other.relations[i][j].type; } } } @@ -167,12 +160,12 @@ unsigned Tree::findId(const char* name, const short year, const unsigned char mo return Nobody; } -unsigned Tree::findOldestAncestor(const unsigned &id, const bool &isMale)const +unsigned Tree::findOldestAncestor(unsigned id, bool isMale)const { for (unsigned i = 0; i < people[id].numRel_; ++i) { - if (relations[id][i] == Child && people[ relatives[id][i] ].isMale_ == isMale) - return findOldestAncestor(relatives[id][i], isMale); + if (relations[id][i].type == Child && people[ relations[id][i].id ].isMale_ == isMale) + return findOldestAncestor(relations[id][i].id, isMale); } return id; } @@ -207,22 +200,14 @@ void Tree::saveTree() const people[i].save(peopleFile); peopleFile.close(); - std::ofstream relativeFile(treeName + ".relatives", std::ios::binary); std::ofstream relationFile(treeName + ".relations", std::ios::binary); - /*relativeFile.write((char*)&numPeople, sizeof(numPeople)); - relationFile.write((char*)&numPeople, sizeof(numPeople));*/ for (unsigned i = 0; i < numPeople; ++i) { - //relativeFile.write((char*)&people[i].numRel_, sizeof(people[i].numRel_)); - for (unsigned j = 0; j < people[i].numRel_; ++j) - relativeFile.write(reinterpret_cast(&relatives[i][j]), sizeof(relatives[i][j])); - //relationFile.write((char*)&people[i].numRel_, sizeof(people[i].numRel_)); for (unsigned j = 0; j < people[i].numRel_; ++j) relationFile.write(reinterpret_cast(&relations[i][j]), sizeof(relations[i][j])); } - relativeFile.close(); relationFile.close(); } @@ -242,26 +227,17 @@ bool Tree::loadTree() people.sNum(numPeople); peopleFile.close(); - std::ifstream relativeFile(treeName + ".relatives", std::ios::binary); - std::ifstream relationFile(treeName + ".relations", std::ios::binary); - relatives.resize(numPeople); + std::ifstream relationFile(treeName + ".relations", std::ios::binary); relations.resize(numPeople); for (unsigned i = 0; i < numPeople; ++i) { - relatives[i].resize(people[i].numRel_); - for (unsigned j = 0; j < people[i].numRel_; ++j) - relativeFile.read(reinterpret_cast(&relatives[i][j]), sizeof(relatives[i][j])); - relatives[i].sNum(people[i].numRel_); - relations[i].resize(people[i].numRel_); for (unsigned j = 0; j < people[i].numRel_; ++j) relationFile.read(reinterpret_cast(&relations[i][j]), sizeof(relations[i][j])); relations[i].sNum(people[i].numRel_); } - relatives.sNum(numPeople); relations.sNum(numPeople); - relativeFile.close(); relationFile.close(); return 1; } @@ -270,22 +246,22 @@ void Tree::addPerson(const char* name, bool isMale, unsigned father, unsigned mo { Person newPerson(name, birth, isMale, death); people.push(newPerson); - Array newRelative; - relatives.push(newRelative); - Array newRelation; - relations.push(newRelation); + + Array newRels; + relations.push(newRels); ++numPeople; + addRelation(father, Parent, numPeople - 1); addRelation(mother, Parent, numPeople - 1); } -bool Tree::addRelation(const char* firstName, const Relation type, const char* secondName) +bool Tree::addRelation(const char* firstName, const RelType type, const char* secondName) { return addRelation(findId(firstName), type, findId(secondName)); } -bool Tree::addRelation(const unsigned firstId, const Relation type, const unsigned secondId, bool opposite)// +bool Tree::addRelation(const unsigned firstId, const RelType type, const unsigned secondId, bool opposite)// { if (firstId == Nobody || firstId >= numPeople || secondId == Nobody || secondId >= numPeople || type == Invalid) return 0; @@ -293,16 +269,15 @@ bool Tree::addRelation(const unsigned firstId, const Relation type, const unsign unsigned i = 0; for (; i < people[firstId].numRel_; ++i) //If they are already relatives { - if (relatives[firstId][i] == secondId) + if (relations[firstId][i].id == secondId) { - relations[firstId][i] = type; + relations[firstId][i].type = type; break; } } if (i >= people[firstId].numRel_) { - relatives[firstId].push(secondId); - relations[firstId].push(type); + relations[firstId].push({secondId, type}); ++people[firstId].numRel_; } @@ -337,12 +312,11 @@ void Tree::removePerson(const unsigned id) unsigned relId; //Íoìåð íà òåêóùèÿ ðîäíèíàòà for (unsigned i = 0; i < people[id].numRel_; ++i) //Ïðåìàõâàò ñå âðúçêèòå íà ÷ëåíà çà ïðåìàõâàíå { - relId = relatives[id][i]; + relId = relations[id][i].id; for (unsigned j = 0; j < people[relId].numRel_; ++j) { - if (relatives[relId][j] == id) + if (relations[relId][j].id == id) { - relatives[relId].remove(j); relations[relId].remove(j); break; } @@ -351,17 +325,16 @@ void Tree::removePerson(const unsigned id) } for (unsigned i = 0; i < people[numPeople - 2].numRel_; ++i) //Ïîñëåäíèÿò ÷ëåí âçåìà íîìåðà íà ïðåìàõíàòèÿ { - relId = relatives[numPeople - 1][i]; + relId = relations[numPeople - 1][i].id; for (unsigned j = 0; j < people[relId].numRel_; ++j) { - if (relatives[relId][j] == numPeople - 1) + if (relations[relId][j].id == numPeople - 1) { - relatives[relId][j] = id; + relations[relId][j].id = id; break; } } } - relatives.remove(id); relations.remove(id); people.remove(id); --numPeople; @@ -376,9 +349,8 @@ void Tree::removeRelation(const unsigned firstId, const unsigned secondId) { for (unsigned i = 0; i < people[firstId].numRel_; ++i) { - if (relatives[firstId][i] == secondId) + if (relations[firstId][i].id == secondId) { - relatives[firstId].remove(i); relations[firstId].remove(i); --people[firstId].numRel_; break; @@ -386,9 +358,8 @@ void Tree::removeRelation(const unsigned firstId, const unsigned secondId) } for (unsigned i = 0; i < people[secondId].numRel_; ++i) { - if (relatives[secondId][i] == firstId) + if (relations[secondId][i].id == firstId) { - relatives[secondId].remove(i); relations[secondId].remove(i); --people[secondId].numRel_; break; @@ -396,8 +367,10 @@ void Tree::removeRelation(const unsigned firstId, const unsigned secondId) } } -void Tree::draw() const +void Tree::draw(person_id focused) const { + erase(); //Clear the screen + wnoutrefresh(stdscr); /* WINDOW* father = people[0].createPad(); */ /* WINDOW* mother = people[1].createPad(); */ @@ -411,16 +384,16 @@ void Tree::draw() const /* 1, drawX, */ /* 1 +fh-1, drawX + fw-1); */ - const U32 numPpl = people.gNum(); - std::vector drawn(numPpl, false); + /* const U32 numPpl = people.gNum(); */ + /* std::vector drawn(numPpl, false); */ U16 drawY = 0/* (LINES) / 2 */; U16 drawX = 0/* (COLS) / 2 */; - drawLineRec(0, drawY, drawX); + drawLine(focused, drawY, drawX); /* people[0].draw(drawY, drawY); */ /* for(U32 i=0; i &visited)const +void Tree::commonAncestorRec(person_id id, const Array &visited)const { for (unsigned i = 0; i < people[id].numRel_; ++i) { - if (relations[id][i] == Child) + if (relations[id][i].type == Child) { - ++visited[relatives[id][i]]; - commonAncestorRec(relatives[id][i], visited); + ++visited[relations[id][i].id]; + commonAncestorRec(relations[id][i].id, visited); } } } -static void linkToFirstBorn(I16 startY, I16 startX) +static U8 linkToFirstBorn(I16 startY, I16 startX) { if(startY >= -2 && startX >= 0) { @@ -529,9 +502,10 @@ static void linkToFirstBorn(I16 startY, I16 startX) wnoutrefresh(win); delwin(win); } + return 3; } -static void linkToChild(I16 startY, I16 startX, I16 endX) +static U8 linkToChild(I16 startY, I16 startX, I16 endX) { assert(endX >= startX); @@ -550,34 +524,75 @@ static void linkToChild(I16 startY, I16 startX, I16 endX) wnoutrefresh(win); delwin(win); } + return 3; } -I16 Tree::drawLineRec(person_id id, I16 drawY, I16 drawX) const + +I16 Tree::drawLine(person_id id, I16 drawY, I16 drawX) const { people[id].draw(drawY, drawX); - std::vector sons; + + std::vector children; for(U32 i=0; i children; */ + /* for(U32 i=0; i + Tree(Str&& Name) : treeName(std::forward(Name)) {} + /*Tree(const Tree&); + Tree& operator= (const Tree& other);*/ + + Tree operator+ (const Tree& other);//doesnt work + Tree operator- (const Tree& other); + Tree& operator+= (const Tree& other); + Tree& operator-= (const Tree& other); + + void rename(const char* newName); + + person_id findId(const char*, short year=0, const unsigned char month=0, const unsigned char day=0)const; + person_id findOldestAncestor(person_id id, bool sex = 0)const;// + person_id findCommonAncestor(person_id firstId, person_id secondId)const; //oldest common ancestor ID + + void saveTree()const;// + bool loadTree(); + + void addPerson(const char* name, bool isMale, person_id father=Nobody, person_id mother=Nobody, EventTime birth={}, EventTime death={}); + bool addRelation(const char* firstName, RelType, const char* secondName); //Adds a new relation or edits an old one. 0 - failure 1 - success + bool addRelation(person_id firstId, RelType, person_id secondId, bool opposite=0); //0 - failure 1 - success + + void removePerson(person_id id); //Removes a member and the last one takes his ID + void removePerson(const char*, short year = 0, const unsigned char month = 0, const unsigned char day = 0); + void removeRelation(person_id firstId, person_id secondId); + void removeRelation(const char* firstName, const char* secondName); + + void draw(person_id focused=0) const; + + void print()const; + void printRel(person_id id)const; //Prints out close relatives + void printMember(person_id id)const; + void printOldestAncestors(person_id id)const;// + +private: + void commonAncestorRec(person_id id, const Array &visited)const; + /* draw a line of people starting from person with id + return the farthest X that will be drawn */ + I16 drawLine(person_id id, I16 drawY, I16 drawX) const; + I16 drawLineWithWives(person_id id, I16 drawY, I16 drawX) const; + + std::string treeName = "Unnamed"; + unsigned numPeople = 0; + Array people; //The data for each member + Array> relations; //The relatives of each member + + U16 offset = 0; + U8 dist_between = 1; + //Search, ect. +}; + +enum RelType : U8 { Invalid = 0, Parent, @@ -14,63 +81,3 @@ enum Relation : U8 Spouse, ExSpouse }; - -const U32 Nobody = UINT_MAX; //Òîçè íîìåð ùå áúäå çàïàçeí çà ëèïñà íà âðúçêà/÷îâåê - -class Tree -{ -public: - using person_id = U32; - - Tree() = default; - template - Tree(Str&& Name) : treeName(std::forward(Name)) {} - /*Tree(const Tree&); - Tree& operator= (const Tree& other);*/ - - Tree operator+ (const Tree& other); - Tree operator- (const Tree& other); - Tree& operator+= (const Tree& other); - Tree& operator-= (const Tree& other); - - void rename(const char* newName); - - unsigned findId(const char*, const short year=0, const unsigned char month=0, const unsigned char day=0)const; - unsigned findOldestAncestor(const unsigned &id, const bool &sex = 0)const;// - unsigned findCommonAncestor(const unsigned firstId, const unsigned secondId)const; //oldest common ancestor ID - - void saveTree()const;// - bool loadTree(); - - void addPerson(const char* name, bool isMale, unsigned father=Nobody, unsigned mother=Nobody, EventTime birth={}, EventTime death={}); - bool addRelation(const char* firstName, const Relation, const char* secondName); //Adds a new relation or edits an old one. 0 - failure 1 - success - bool addRelation(const unsigned firstId, const Relation, const unsigned secondId, bool opposite=0); //0 - failure 1 - success - - void removePerson(const unsigned id); //Removes a member and the last one takes his ID - void removePerson(const char*, const short year = 0, const unsigned char month = 0, const unsigned char day = 0); - void removeRelation(const unsigned firstId, const unsigned secondId); - void removeRelation(const char* firstName, const char* secondName); - - void draw() const; - - void print()const; - void printRel(const unsigned id)const; //Prints out close relatives - void printMember(const unsigned id)const; - void printOldestAncestors(const unsigned id)const;// - -private: - void commonAncestorRec(const unsigned &id, const Array &visited)const; - /* draw a line of people starting from person with id - return the farthest X that will be drawn */ - I16 drawLineRec(person_id id, I16 drawY, I16 drawX) const; - - std::string treeName = "Unnamed"; - unsigned numPeople = 0; - Array people; //The data for each member - Array> relatives; //The relatives of each member - Array> relations; //The type of relation each member has with his relatives - - U16 offset = 0; - - //Search, ect. -};