1 |
/* |
2 |
tgf-edit.cc, part of |
3 |
|
4 |
treegraph |
5 |
|
6 |
Tree formatting program |
7 |
|
8 |
Generates vector graphics (SVG,EPS) from .tgf-tree description files. |
9 |
|
10 |
Copyright (c) 2003-04 by Joern Mueller |
11 |
|
12 |
|
13 |
This program is free software; you can redistribute it and/or |
14 |
modify it under the terms of the GNU General Public License |
15 |
as published by the Free Software Foundation; either version 2 |
16 |
of the License, or (at your option) any later version. |
17 |
|
18 |
This program is distributed in the hope that it will be useful, |
19 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
21 |
GNU General Public License for more details. |
22 |
|
23 |
You should have received a copy of the GNU General Public License |
24 |
along with this program (GPL.html); if not, write to the Free Software |
25 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
26 |
(also: http://www.gnu.org) |
27 |
*/ |
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
#include "tgf-tree.h" |
36 |
|
37 |
void tree::edit(void) |
38 |
{ |
39 |
cout << "Type '?' for help.\n"; |
40 |
while(1){ |
41 |
cout << "\n> "; |
42 |
|
43 |
string txt; |
44 |
getline(cin,txt); |
45 |
if(txt[0]=='x') break; |
46 |
else if(txt[0]=='?'){ |
47 |
cout << "Available commands: (<L> is node label; label of whole tree is 'root')\n\n"; |
48 |
cout << "swap <L> swaps sublineages of <L>. Same as perm <L> 2 1\n"; |
49 |
cout << "perm <L> i_1 i_2 .. i_n permutes the n sublineages of <L>\n"; |
50 |
cout << "dump <L> writes subtree (the clade characterized by <L>) to file\n"; |
51 |
cout << "ladder <L> ladderizes right\n"; |
52 |
cout << "dladder <L> ladderizes left\n"; |
53 |
cout << "mladder <L> symmetric ladderization\n"; |
54 |
cout << "coll <L> collapses <L>\n"; |
55 |
cout << "mv <L> <L2> makes <L> a child node of <L2>\n"; |
56 |
cout << "del <L> deletes all sublineages of <L>, leaving <L> as terminal\n"; |
57 |
cout << "root <L> inserts new root between <L> and its ancestral node\n"; |
58 |
cout << "x quits edit mode\n"; |
59 |
cout << endl; |
60 |
continue; |
61 |
} |
62 |
|
63 |
vector<string> arglist; |
64 |
arglist.reserve(5); |
65 |
for(;;) { |
66 |
string::size_type p=txt.find(' '); |
67 |
arglist.push_back(txt.substr(0,p)); |
68 |
if(p!=string::npos) txt=txt.substr(p+1); |
69 |
else break; |
70 |
} |
71 |
|
72 |
//alle Befehle ausser 'x' haben ein Argument |
73 |
string cmd=arglist[0]; |
74 |
if(arglist.size()<2){ |
75 |
cout << "Unknown: '" << cmd << "'\n"; |
76 |
cout << "Type '?' for help.\n"; |
77 |
continue; |
78 |
} |
79 |
const tnode *nd=lb.bfind_label(arglist[1].c_str()); |
80 |
if(nd==0){ |
81 |
cout << "Node with label '" << arglist[1] << "' does not exist.\n"; |
82 |
continue; |
83 |
} |
84 |
if(cmd=="ladder" || cmd=="dladder"){ |
85 |
((tnode*)nd)->ladderize_sichtbare((cmd=="ladder")?1:-1); |
86 |
drty=true; |
87 |
} else if(cmd=="mladder"){ |
88 |
((tnode*)nd)->symladderize(1); |
89 |
drty=true; |
90 |
} else if(cmd=="swap"){ |
91 |
((tnode*)nd)->swap_children(); |
92 |
drty=true; |
93 |
} else if(cmd=="perm"){ |
94 |
list<int> pm; |
95 |
for(int i=2; i<arglist.size(); i++){ |
96 |
int k=atoi(arglist[i].c_str()); |
97 |
pm.push_back(k); |
98 |
} |
99 |
if(((tnode*)nd)->permute(pm)) |
100 |
drty=true; |
101 |
} else if(cmd=="dump"){ |
102 |
if(arglist[1]=="root") nd=0; |
103 |
cout << "Save as: "; |
104 |
string fname; |
105 |
cin >> fname; |
106 |
ofstream ausg(fname.c_str()); |
107 |
cout << "Saving...\n"; |
108 |
write(ausg,nd); |
109 |
cout << "Done.\n"; |
110 |
} else if(cmd=="del"){ |
111 |
remove_subtree((tnode*)nd); |
112 |
drty = true; |
113 |
} else if(cmd=="mv"){ |
114 |
cout << "Move " << arglist[1] << " to " << arglist[2] << endl; |
115 |
const tnode *nd2=lb.bfind_label(arglist[2].c_str()); |
116 |
if(nd2==0){ |
117 |
cout << "Node with label '" << arglist[2] << "' does not exist.\n"; |
118 |
continue; |
119 |
} |
120 |
if(nd->prev==0){ |
121 |
cout << "root can not be moved. Use \"root\" command first.\n"; |
122 |
continue; |
123 |
} |
124 |
if(nd->prev==nd2){ |
125 |
cout << arglist[1] << " is already a child node of " << arglist[2] << endl; |
126 |
continue; |
127 |
} |
128 |
(((tnode*)nd)->prev)->removechild((tnode*)nd); |
129 |
((tnode*)nd2)->insertchild((tnode*)nd); |
130 |
drty=true; |
131 |
} else if(cmd=="coll"){ |
132 |
if(nd->has_label()) |
133 |
lb.kill_label(nd->label()); |
134 |
((tnode*)nd)->collapse(); |
135 |
drty=true; |
136 |
} else if(cmd=="root"){ |
137 |
try { |
138 |
if(reroot((tnode*)nd)){ |
139 |
drty=true; |
140 |
} |
141 |
} |
142 |
catch(fehler){ |
143 |
cout << "Error in reroot\n"; |
144 |
} |
145 |
} else { |
146 |
cout << "Unknown: '" << cmd << "'\n"; |
147 |
cout << "Type '?' for help.\n"; |
148 |
} |
149 |
} |
150 |
|
151 |
if(dirty()){ |
152 |
cout << "Recalculating node positions...\n"; |
153 |
calcpos(); |
154 |
} |
155 |
} |