ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/gclib/gfview/mdichild.cpp
Revision: 45
Committed: Tue Sep 6 18:19:20 2011 UTC (12 years, 10 months ago) by gpertea
File size: 24028 byte(s)
Log Message:
added gfview files

Line File contents
1 /********************************************************************************
2 * *
3 * *
4 *********************************************************************************/
5
6 #include <stdio.h>
7 #include "mdichild.h"
8 #include "clv_icons.h"
9
10 /*******************************************************************************/
11
12
13 // ========= static members initialization: ================
14 short MDIChild::numInst=0; //number of instances
15 FXFont* MDIChild::ifont=NULL;
16 FXIcon* MDIChild::icnDefCS=NULL;
17 FXIcon* MDIChild::icnBaseCS=NULL;
18 FXIcon* MDIChild::icnDensCS=NULL;
19 //============================================================
20
21 // Map
22 FXDEFMAP(MDIChild) MDIChildMap[]={
23 //________Message_Type____________________ID___________________Message_Handler________
24 FXMAPFUNCS(SEL_CHANGED, MDIChild::ID_CLXZOOM,
25 MDIChild::ID_CLYZOOM, MDIChild::onCmdClZoom),
26 FXMAPFUNC(SEL_COMMAND, MDIChild::ID_CLNOZOOM, MDIChild::onNoZoom),
27 FXMAPFUNC(SEL_COMMAND, MDIChild::ID_CLGRPS, MDIChild::onCmdGrps),
28 FXMAPFUNC(SEL_COMMAND, MDIChild::ID_CL1PXZOOM, MDIChild::onMaxZoom),
29 FXMAPFUNC(SEL_CLICKED, MDIChild::ID_CLVIEW, MDIChild::onSeqSelect),
30 FXMAPFUNC(SEL_RIGHTBUTTONPRESS, MDIChild::ID_CLVIEW, MDIChild::onRMouseDown),
31 FXMAPFUNC(SEL_RIGHTBUTTONRELEASE, MDIChild::ID_CLVIEW, MDIChild::onRMouseUp),
32 FXMAPFUNC(SEL_MIDDLEBUTTONPRESS, MDIChild::ID_CLVIEW, MDIChild::onMMouseDown),
33 FXMAPFUNC(SEL_MIDDLEBUTTONRELEASE, MDIChild::ID_CLVIEW, MDIChild::onMMouseUp),
34 FXMAPFUNC(SEL_MOTION, MDIChild::ID_CLVIEW, MDIChild::onMouseMove),
35 FXMAPFUNCS(SEL_COMMAND, MDIChild::ID_CSTYLE1,
36 MDIChild::ID_CSTYLE3, MDIChild::onColorOption),
37 FXMAPFUNC(SEL_COMMAND, MDIChild::ID_CONTIG, MDIChild::onSelContig),
38 FXMAPFUNC(SEL_COMMAND, MDIChild::ID_HIDEGAPS, MDIChild::onHideGaps),
39 FXMAPFUNC(SEL_COMMAND, MDIChild::ID_SELSEQ, MDIChild::onSelSeq),
40 FXMAPFUNC(SEL_CONFIGURE, 0, MDIChild::onMaxRestore),
41 };
42
43
44 // Object implementation
45 FXIMPLEMENT(MDIChild,FXMDIChild,MDIChildMap,ARRAYNUMBER(MDIChildMap))
46
47
48 /*******************************************************************************/
49 // Make some windows
50 MDIChild::MDIChild(FXMDIClient* p,const FXString& name,FXIcon* ic,
51 FXMenuPane* mn,FXuint opts,FXint x,FXint y,FXint w,FXint h)
52 :FXMDIChild(p,name, ic, mn, opts, x, y, w, h) {
53 FXString s;
54 // Tooltip
55 wasMaximized=false;
56 new FXToolTip(getApp());
57 layoutparser=NULL;
58 groupHolder=NULL;
59 zooming=false;
60 panning=false;
61 prevColumn=-1;
62 contents=new FXVerticalFrame(this,FRAME_NONE|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0);
63
64 vframe=new FXVerticalFrame(contents,FRAME_NONE|LAYOUT_FILL_Y|LAYOUT_FILL_X,
65 0,0,0,0,0,0,0,0);
66 FXHorizontalFrame* hf=new FXHorizontalFrame(vframe,FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP);
67 //contig and option buttons:
68 new FXLabel(hf, "Cluster:", NULL, LAYOUT_CENTER_Y);
69
70 selcontig=new FXComboBox(hf,32,this,ID_CONTIG,
71 COMBOBOX_NORMAL|FRAME_SUNKEN|FRAME_THICK|LAYOUT_CENTER_Y);
72 selcontig->setNumVisible(10);
73 selcontig->setEditable(FALSE);
74 pop=new FXPopup(this);
75 if (numInst<=0) {
76 icnDefCS=new FXXPMIcon(getApp(), cs_default, FXRGB(192,192,192),IMAGE_ALPHACOLOR);
77 icnBaseCS=new FXXPMIcon(getApp(), cs_base, FXRGB(192,192,192),IMAGE_ALPHACOLOR);
78 icnDensCS=new FXXPMIcon(getApp(), cs_density, FXRGB(192,192,192),IMAGE_ALPHACOLOR);
79 ifont=new FXFont(getApp(),"helvetica", 10, FXFont::Bold); //info font
80 }
81 numInst++;
82
83 clropt1=new FXOption(pop,"\t\tCoverage/quality color style",
84 icnDensCS,
85 this,ID_CSTYLE2,JUSTIFY_HZ_APART);
86 clropt2=new FXOption(pop,"\t\tSimple/Group color style", icnDefCS,
87 this, ID_CSTYLE1,JUSTIFY_HZ_APART);
88 clropt3=new FXOption(pop,"\t\tNucleotide color style",
89 icnBaseCS,
90 this,ID_CSTYLE3,JUSTIFY_HZ_APART);
91 new FXOptionMenu(hf, pop,
92 LAYOUT_TOP|FRAME_RAISED|FRAME_THICK|JUSTIFY_HZ_APART);
93 new FXButton(hf, "G\tLoad groups\tShow groups loaded from another layout file",
94 NULL,this, ID_CLGRPS,
95 LAYOUT_TOP|FRAME_RAISED|FRAME_THICK|JUSTIFY_HZ_APART);
96 cbgaps=new FXCheckButton(hf,"hide contig gaps",this, MDIChild::ID_HIDEGAPS);
97 hframe=new FXHorizontalFrame(vframe,FRAME_NONE|LAYOUT_FILL_X|LAYOUT_FILL_Y|ICON_BEFORE_TEXT,
98 0,0,0,0,0,0,0,0);
99 vframe= new FXVerticalFrame(hframe,FRAME_NONE|LAYOUT_FILL_Y|LAYOUT_FILL_X,
100 0,0,0,0,0,0,0,0);
101 clframe=new FXHorizontalFrame(vframe,FRAME_SUNKEN|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_BOTTOM,
102 0,0,0,0,0,0,0,0);
103 alignview=new FXGView(clframe, this,MDIChild::ID_CLVIEW, LAYOUT_FILL_X|LAYOUT_FILL_Y);
104
105 hf = new FXHorizontalFrame(vframe,FRAME_SUNKEN|LAYOUT_FILL_X,
106 0,0,0,0,0,0,0,0);
107 //=== seq_info box:
108 FXVerticalFrame* vf = new FXVerticalFrame(hf, FRAME_NONE|LAYOUT_CENTER_Y|LAYOUT_FILL_X);
109 FXHorizontalFrame* hhf=new FXHorizontalFrame(vf,
110 FRAME_NONE|LAYOUT_CENTER_Y|LAYOUT_FILL_X, 0,0,0,0,0,0,0,0);
111 selseq=new FXComboBox(hhf,28,this,ID_SELSEQ,
112 COMBOBOX_NORMAL|FRAME_SUNKEN|FRAME_THICK|LAYOUT_CENTER_Y);
113 selseq->setNumVisible(12);
114 selseq->setEditable(FALSE);
115 seqData = new FXLabel(hhf, " ", NULL,
116 FRAME_SUNKEN|JUSTIFY_LEFT|LAYOUT_FILL_X);
117 //seqComment=new FXTextField(vf,120,NULL,0,JUSTIFY_LEFT|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X);
118 seqData->setFont(ifont);
119 seqAsmInfo=new FXLabel(vf, " ", NULL,
120 FRAME_SUNKEN|JUSTIFY_LEFT|LAYOUT_FILL_X);
121 seqAsmInfo->setFont(ifont);
122 //===slider box:
123 vf = new FXVerticalFrame(hf, FRAME_RAISED);
124 sliderZX=new FXSlider(vf,this,MDIChild::ID_CLXZOOM,
125 LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|FRAME_RAISED,
126 0,0,160,22,0,0,0,0);
127
128 hf=new FXHorizontalFrame(vf,FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,0,0,0,0);
129 nozoomBtn=new FXButton(hf, "&1x1",NULL, this, MDIChild::ID_CLNOZOOM,
130 FRAME_RAISED|FRAME_THICK|LAYOUT_CENTER_Y);
131 new FXButton(hf, "1p&x",NULL, this, MDIChild::ID_CL1PXZOOM,
132 FRAME_RAISED|FRAME_THICK|LAYOUT_CENTER_X|LAYOUT_CENTER_Y);
133 zxLabel=new FXLabel(hf, "1.000", NULL,
134 FRAME_SUNKEN|JUSTIFY_RIGHT|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_RIGHT|LAYOUT_CENTER_Y,
135 0,0,6*6,14);
136
137 s.format("%02.3f",alignview->getZoomX());
138 zxLabel->setText(s);
139 columnInfo=new FXLabel(vframe, " ",
140 NULL, JUSTIFY_LEFT|FRAME_SUNKEN|LAYOUT_FILL_X);
141 //=== vframe filled ===
142
143 toolframe=new FXVerticalFrame(hframe,FRAME_RAISED|LAYOUT_FILL_Y);
144 //new FXLabel(toolframe, "Y Scale:", NULL, LAYOUT_CENTER_X);
145 sliderZY=new FXSlider(toolframe,this,MDIChild::ID_CLYZOOM,
146 SLIDER_VERTICAL|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_CENTER_X|FRAME_RAISED,
147 0,0,22,140,0,0,0,0);
148
149 sliderZY->setRange(10,100); //
150 sliderZY->setValue((FXint)(alignview->getZoomY()*100));
151
152 sliderZX->setRange(10,1000);//
153 sliderZX->setValue((FXint)(alignview->getZoomX()*1000));
154 s.format("%02.2f",alignview->getZoomY());
155 zyLabel=new FXLabel(toolframe, s, NULL,
156 FRAME_SUNKEN|LAYOUT_CENTER_X|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT,
157 0,0,6*6,14);
158
159 alignview->setFocus();
160 }
161
162 void MDIChild::showSeqInfo(ClSeq* seq) {
163 FXString s;
164
165 if (seq!=NULL && seq==alignview->selSeq) { //selection
166 s.format("%s (%d nt)", seq->name.text(), seq->len);
167 selseq->setText(s);
168 if (seq->ins>0 || seq->dels>0)
169 s.format(" %s range: %d to %d | clipL:%d clipR:%d | gaps: %d dels: %d",
170 seq->reversed?"-":"+",
171 seq->clipL+1, seq->len-seq->clipR,
172 seq->clipL, seq->clipR,
173 seq->ins, seq->dels);
174
175 else
176 s.format(" %s range: %d to %d | clipL:%d clipR:%d ",
177 seq->reversed?"-":"+",
178 seq->clipL+1, seq->len-seq->clipR,
179 seq->clipL, seq->clipR);
180 seqData->setText(s);
181 //seqComment->setText(seq->comment);
182 if (seq->group>=0)
183 s.format("Layout location: %d to %d [group %d]",
184 seq->cl_xpos+seq->clipL, seq->cl_xpos+seq->len-seq->clipR-1, seq->group);
185 else
186 s.format("Layout location: %d to %d",
187 seq->cl_xpos+seq->clipL, seq->cl_xpos+seq->len-seq->clipR-1);
188 seqAsmInfo->setText(s);
189 }
190 else { //deselect
191 selseq->setText(" ");
192 seqData->setText(" ");
193 seqAsmInfo->setText(" ");
194 }
195 int cidx=alignview->getSelCol();
196 if (prevColumn==cidx) return;
197 prevColumn=cidx;
198 FXString cinfo;
199 if (cidx>=0) {
200 ColumnData* c=alignview->getColumnData(cidx);
201 if (c->letter!=0) {
202 cinfo.format("Column %d ['%c']: %d layers, %d mismatches ",
203 cidx+alignview->getXLeft(), c->letter, c->thickness, c->mismatches);
204 if (c->mismatches>1 && c->thickness>3) {
205 cinfo+=" [ ";
206 for (int i=0;i<3;i++) {
207 if (c->ntdata[i].count>0) {
208 s.format(" %d%c ", c->ntdata[i].count, c->ntdata[i].letter);
209 cinfo+=s;
210 }
211 }
212 cinfo+=" ] ";
213 }
214 }
215 else
216 cinfo.format("Column %d (%d layers)", cidx+alignview->getXLeft(), c->thickness);
217 columnInfo->setText(cinfo);
218 }
219 else {
220 columnInfo->setText(" ");
221 }
222 }
223
224 long MDIChild::onSeqSelect(FXObject*,FXSelector sel,void* ptr){
225 showSeqInfo((ClSeq*)ptr);
226 return 1;
227 }
228
229 long MDIChild::onCmdClZoom(FXObject*,FXSelector sel,void*){
230 FXuint sid=FXSELID(sel);
231 FXString s;
232 switch(sid) {
233 case ID_CLXZOOM:
234 alignview->ZoomX(((double)sliderZX->getValue())/1000);
235 s.format("%2.3f",alignview->getZoomX());
236 zxLabel->setText(s);
237 break;
238 case ID_CLYZOOM:
239 alignview->ZoomY(((double)sliderZY->getValue())/100);
240 s.format("%2.2f",alignview->getZoomY());
241 zyLabel->setText(s);
242 break;
243 }
244 return 1;
245 }
246
247 long MDIChild::onColorOption(FXObject*,FXSelector sel,void*){
248 FXuint sid=FXSELID(sel);
249 switch(sid) {
250 case ID_CSTYLE1:
251 alignview->setColorStyle(FXGView::csDefault);
252 break;
253 case ID_CSTYLE2:
254 alignview->setColorStyle(FXGView::csDensity);
255 break;
256 case ID_CSTYLE3:
257 alignview->setColorStyle(FXGView::csBaseColor);
258 break;
259 }
260 this->ungrab(); //? bug?
261 return 1;
262 }
263
264 // Show up
265 void MDIChild::create(){
266 FXMDIChild::create();
267 show();
268 }
269
270
271 long MDIChild::onRMouseDown(FXObject*,FXSelector,void* ptr) {
272 FXEvent *ev = (FXEvent*)ptr;
273 //prevCursor=getApp();
274 alignview->setDragCursor(getApp()->getDefaultCursor(DEF_MOVE_CURSOR));
275 alignview->grab();
276 // While the right-button mouse is down, do zooming
277 zooming=true;
278 startZX=alignview->getZoomX();
279 startZY=alignview->getZoomY();
280 zoomPt.x=ev->win_x;
281 zoomPt.y=ev->win_y;
282 return 1;
283 }
284
285 long MDIChild::onMMouseDown(FXObject*,FXSelector,void* ptr) {
286 //FXEvent *ev = (FXEvent*)ptr;
287 //prevCursor=getApp();
288 alignview->setDragCursor(getApp()->getDefaultCursor(DEF_MOVE_CURSOR));
289 alignview->grab();
290 // While the right-button mouse is down, do zooming
291 panning=true;
292 //startZX=alignview->getZoomX();
293 //startZY=alignview->getZoomY();
294 //zoomPt.x=ev->win_x;
295 //zoomPt.y=ev->win_y;
296 return 1;
297 }
298
299 long MDIChild::onMouseMove(FXObject*, FXSelector, void* ptr){
300 FXEvent *ev=(FXEvent*)ptr;
301 if (zooming) {
302 //compute distance:
303 //int dx=(ev->win_x-zoomPt.x)*2;
304 //int dy=(zoomPt.y-ev->win_y)/3;
305 double newzx = startZX+((double)(ev->win_x-zoomPt.x)*2)/1000;
306 double newzy = startZY+(((double)(zoomPt.y-ev->win_y))/3)/100;
307 int minzx, maxzx;
308 int minzy, maxzy;
309 sliderZX->getRange(minzx, maxzx);
310 sliderZY->getRange(minzy, maxzy);
311 if (newzx*1000<minzx) newzx=(double)minzx/1000;
312 else
313 if (newzx*1000>maxzx) newzx=(double)maxzx/1000;
314 if (newzy*100<minzy) newzy=(double)minzy/100;
315 else
316 if (newzy*100>maxzy) newzy=(double)maxzy/100;
317 if (newzx!=alignview->getZoomX() ||
318 newzy!=alignview->getZoomY()) {
319 alignview->Zoom(newzx,newzy,
320 zoomPt.x, zoomPt.y);
321 FXString s;
322 sliderZX->setValue((FXint)(newzx*1000));
323 sliderZX->forceRefresh();
324 s.format("%2.3f",alignview->getZoomX());
325 zxLabel->setText(s);
326 sliderZY->setValue((FXint)(newzy*100));
327 sliderZY->forceRefresh();
328 s.format("%2.2f",alignview->getZoomY());
329 zyLabel->setText(s);
330 }
331 }
332 if (panning) {
333 alignview->scrollBy((ev->win_x-ev->last_x)*2, (ev->win_y-ev->last_y)*2);
334 }
335 return 1;
336 }
337
338
339 long MDIChild::onNoZoom(FXObject*,FXSelector sel,void*) {
340 sliderZX->setValue(1000);
341 zxLabel->setText("1.000");
342 sliderZY->setValue(100);
343 zyLabel->setText("1.00");
344 alignview->Zoom(1,1);
345 return 1;
346 }
347
348 long MDIChild::onMaxZoom(FXObject*,FXSelector sel,void*) {
349 FXString s;
350 double newzx, newzy;
351 alignview->set1pxZoom();
352 newzx=alignview->getZoomX();
353 newzy=alignview->getZoomY();
354 sliderZX->setValue((FXint)(newzx*1000));
355 sliderZX->forceRefresh();
356 s.format("%2.3f",newzx);
357 zxLabel->setText(s);
358 sliderZY->setValue((FXint)(newzy*100));
359 sliderZY->forceRefresh();
360 s.format("%2.2f",newzy);
361 zyLabel->setText(s);
362 return 1;
363 }
364
365 long MDIChild::onCmdGrps(FXObject*,FXSelector sel,void*) {
366 FXString ofile=FXFileDialog::getOpenFilename(this,"Open file", //NULL,
367 "Contig files (*.ace,*.lyt)\nAny file (*)");
368 if (!ofile.empty()) loadGroups(ofile);
369 return 1;
370 }
371
372
373
374 long MDIChild::onRMouseUp(FXObject*,FXSelector,void* ptr){
375 //FXEvent *ev=(FXEvent*) ptr;
376 alignview->ungrab();
377 zooming=false;
378 if (!panning)
379 alignview->setDragCursor(getApp()->getDefaultCursor(DEF_ARROW_CURSOR));
380 return 1;
381 }
382
383 long MDIChild::onMMouseUp(FXObject*,FXSelector,void* ptr){
384 alignview->ungrab();
385 panning=false;
386 if (!zooming)
387 alignview->setDragCursor(getApp()->getDefaultCursor(DEF_ARROW_CURSOR));
388 return 1;
389 }
390
391
392 bool MDIChild::openFile(const char* filename) {
393 //try to recognize the file type and call the appropriate loader
394 FILE* f;
395 if ((f=fopen(filename, "r"))==NULL) {
396 FXMessageBox::error(this,MBOX_OK,"File error",
397 "Cannot open file '%s'", filename);
398 }
399 fclose(f);
400 FXString fname(filename);
401 AceParser ap(fname.text());
402 if (ap.open()) {
403 delete layoutparser;
404 layoutparser=NULL;
405 layoutparser=new AceParser(fname.text());
406 return loadLayoutFile(fname);
407 }
408 else { //assumes it's our layout format file
409 delete layoutparser;
410 layoutparser=NULL;
411 layoutparser=new LayoutParser(fname.text());
412 }
413 return loadLayoutFile(fname);
414 }
415
416
417 bool MDIChild::loadLayoutFile(FXString& lytfile) {
418 if (!layoutparser->open()) {
419 FXMessageBox::error(this,MBOX_OK,"File error",
420 "Cannot open file '%s'. Not a valid file?", lytfile.text());
421 delete layoutparser;
422 layoutparser=NULL;
423 return false;
424 }
425 alignview->filetype=layoutparser->getFileType();
426 isAce=(alignview->filetype=='A');
427 if (!layoutparser->parseContigs() || layoutparser->getNumContigs()==0) {
428 //if (!layoutparser->parse() || layoutparser->getNumContigs()==0) {
429 FXMessageBox::error(this,MBOX_OK,"File error",
430 "Error encountered parsing file '%s'. Not a valid file?", lytfile.text());
431 delete layoutparser;
432 layoutparser=NULL;
433 return false;
434 }
435 file=lytfile;
436 //file validated. Load align data:
437 //show all contig labels:
438 layoutparser->contigsByNumSeqs();
439 FXString name;
440 for (int i=0; i<layoutparser->getNumContigs(); i++) {
441 LytCtgData* ctg=layoutparser->getContig(i);
442 name.format("%s (%d seqs, %d nts)", ctg->name, ctg->numseqs,
443 ctg->len);
444 selcontig->appendItem(name);
445 }
446 //show first contig:
447 selcontig->setCurrentItem(0);
448 selContig(0, cbgaps->getCheck());
449 if (alignview->HasSeqs()) {
450 clropt3->enable();
451 cbgaps->show();
452 }
453 else {
454 clropt3->disable();
455 cbgaps->hide();
456 }
457 alignview->setColorStyle(FXGView::csDensity);
458 return true;
459 }
460
461 void MDIChild::loadGroups(FXString& lytfile) {
462 //assumes sequences already loaded here
463 if (alignview->seqlist->Count()==0) {
464 FXMessageBox::error(this,MBOX_OK,"Action error",
465 "You need a valid layout file loaded before setting groups.");
466 return;
467 }
468 LayoutParser* lp = new AceParser(lytfile.text());
469 if (!lp->open()) { //try ACE first
470 delete lp;
471 lp=new LayoutParser(lytfile.text());
472 }
473 else lp->close();
474 if (!lp->open() ||
475 !lp->parse()) {
476 FXMessageBox::error(this,MBOX_OK,"File error",
477 "Error encountered opening/parsing layout file '%s'. Not a layout file?", lytfile.text());
478 delete lp;
479 return;
480 }
481 delete groupHolder;
482 //groupHolder=NULL;
483 groupHolder=lp;
484 assignGroups();
485 }
486
487 void MDIChild::assignGroups() {
488 if (groupHolder==NULL) return;
489 int numGroups=0;
490 //we must count only contigs having at least one
491 //sequence in common with the currently displayed layout
492 //for each contig, test all component sequences
493 //groupHolder->parseContigs();
494 int nc=groupHolder->getNumContigs();
495 for (int i=0; i<nc; i++) {
496 LytCtgData* ctg=groupHolder->getContig(i);
497 bool assigned=false;
498 //for each sequence, see if it's in the viewer's current layout
499 for (int j=0;j<ctg->numseqs;j++) {
500 FXString s(ctg->seqs[j]->name);
501 if (alignview->setSeqGrp(s, numGroups)) assigned=true;
502 }
503 if (assigned) numGroups++; //advance to next group
504 }
505 if (numGroups>0) {
506 //alignview->initGrpColors(numGroups);
507 alignview->update();
508 }
509 else
510 FXMessageBox::information(this,MBOX_OK,"Information",
511 "No groups were found for sequences in the selected contig");
512 }
513
514 void MDIChild::selContig(int ctgno, bool hideGaps) {
515 if (ctgno<0 || ctgno>=layoutparser->getNumContigs()) return;
516 alignview->Clear();
517 FXApp* fapp=getApp();
518 fapp->beginWaitCursor();
519 fapp->forceRefresh();
520
521 layoutparser->loadContig(ctgno);
522 LytCtgData* ctg=layoutparser->getContig(ctgno);
523 char *ctgseq=layoutparser->getContigSeq(ctg);
524 //now ctgseq contains '*'
525 //for each position, record how many '*' chars we have on the left
526 int* ctgrm=NULL;
527 bool removeGaps=hideGaps;
528 int ctglen=ctg->len;
529 if (removeGaps && ctgseq!=NULL) {
530 int len=strlen(ctgseq);
531 GMALLOC(ctgrm, (len+1)*sizeof(int));
532 int numstars=0;
533 ctgrm[0]=0;
534 for (int i=1;i<len;i++) {
535 numstars += (ctgseq[i-1]=='*');
536 ctgrm[i]=numstars;
537 }
538 ctgrm[len]=ctgrm[len-1];
539 //now remove all the stars from the contig sequence
540 if (numstars>0) {
541 char* cleanseq=NULL;
542 GMALLOC(cleanseq, len-numstars+1);
543 ctglen-=numstars;
544 int j=0;
545 for (int i=0;i<=len;i++)
546 if (ctgseq[i]!='*') {
547 cleanseq[j] = ctgseq[i];
548 j++;
549 }
550 GFREE(ctgseq);
551 ctgseq=cleanseq;
552 removeGaps=true;
553 }
554 else removeGaps=false;
555 }
556 alignview->addContig(ctg->name, ctglen, ctgseq, ctg->offs);
557 GFREE(ctgseq);
558 int numseqs=ctg->numseqs;
559 for (int i=0;i<numseqs;i++) { //reload each read sequence
560 LytSeqInfo* seq=ctg->seqs[i];
561
562 char* s=layoutparser->getSeq(seq);
563 // GMessage("seq %d : %s \n", i, seq->name);
564
565 int slen=0;
566 if (isAceFile() && (s==NULL || (slen=strlen(s))!=(unsigned int)seq->seglen())) {
567 FXMessageBox::error(this,MBOX_OK,"File error",
568 "Error reading sequence '%s' (declared %d, loaded %d). Invalid ACE file?",
569 seq->name, seq->length(), slen);
570 delete layoutparser;
571 layoutparser=NULL;
572 GFREE(s);
573 return;
574 }
575 if (removeGaps && s!=NULL) {
576 //shift all coordinates and lengths accordingly, remove gaps
577 int clpL=seq->left-1;
578 int clpR=seq->length()-seq->right;
579 int old_start=seq->offs+clpL;
580 int old_end=seq->offs+seq->length()-clpR-1;
581 int new_start=old_start-ctgrm[old_start-1];
582 int new_end=old_end-ctgrm[old_end-1];
583 //fix interseg coordinates too, when introns are given
584 // otherwise the "remove gaps" is going to mess up the MSA !!
585
586 for (int g = 0; g < seq->numisegs; g++) {
587 int prevcoord=seq->intersegs[g].segEnd;
588 seq->intersegs[g].segEnd-=ctgrm[prevcoord-1];
589 prevcoord=seq->intersegs[g].nextStart;
590 seq->intersegs[g].nextStart-=ctgrm[prevcoord-1];
591 }
592 //now create the cleaned copy of the sequence
593 char* clnseq=NULL;
594 int newlen=new_end-new_start+1+clpL+clpR;
595 GMALLOC(clnseq, sizeof(char)*(newlen+1));
596 clnseq[newlen]='\0';
597 if (clpL>0) strncpy(clnseq, s, clpL);
598 int j=clpL;
599 int numdels=0;
600 int numins=0;
601 for (int b=clpL; b<seq->length()-clpR; b++) {
602 int ctgpos=seq->offs+b;
603 //delete only if there was also a '*' in the initial contig seq
604 if (ctgrm[ctgpos]-ctgrm[ctgpos-1]==0) {
605 clnseq[j] = s[b];
606 if (s[b]=='*' || s[b]=='-') {
607 clnseq[j]='-';
608 numins++;
609 }
610 j++;
611 }
612 else {
613 if (s[b]!='*' && s[b]!='-')
614 numdels++;
615 }
616 }
617 clnseq[j]='\0';
618 if (clpR>0) strncat(clnseq, s+(seq->length()-clpR), clpR);
619 GFREE(s);
620 s=clnseq;
621 alignview->addSeq(seq->name, newlen, new_start-clpL, seq->reversed,
622 clpL,clpR,s, numins, numdels);
623 //alignview->addSeq(seq,s);
624 } //gaps removal
625 else { // raw sequence display (with all gaps in place)
626 /*alignview->addSeq(seq->name, seq->length(), seq->offs, seq->reversed,
627 seq->left-1,seq->length()-seq->right,s);*/
628 alignview->addSeq(seq,s);
629 }
630 GFREE(s);
631 }
632 alignview->buildLayout();
633 assignGroups();
634 selseq->clearItems();
635 showSeqInfo(NULL);
636 for (int i=0;i<alignview->seqlist->Count();i++) {
637 ClSeq* seq=alignview->seqlist->Get(i);
638 if (seq==alignview->contig) continue;
639 FXString name;
640 name.format ("%s (%d nt)", seq->name.text(), seq->len);
641 selseq->appendItem(name);
642 }
643 fapp->endWaitCursor();
644 if (alignview->HasSeqs()) {
645 clropt3->enable();
646 cbgaps->show();
647 }
648 else {
649 clropt3->disable();
650 cbgaps->hide();
651 }
652 }
653
654 long MDIChild::onSelContig(FXObject*,FXSelector,void* ptr) {
655 selContig(selcontig->getCurrentItem(), cbgaps->getCheck());
656 return 1;
657 }
658
659 long MDIChild::onHideGaps(FXObject*,FXSelector,void* ptr) {
660 selContig(selcontig->getCurrentItem(), cbgaps->getCheck());
661 return 1;
662 }
663
664
665 long MDIChild::onSelSeq(FXObject*,FXSelector,void* ptr) {
666 int seqidx=selseq->getCurrentItem();
667 if (seqidx<0) return 1;
668 ClSeq* seq=alignview->seqlist->Get(seqidx);
669 alignview->selectSeq(seq, true);
670 showSeqInfo(seq);
671 return 1;
672 }
673
674 long MDIChild::onMaxRestore(FXObject* sender,FXSelector sel,void* ptr) {
675 FXbool maximized=isMaximized();
676 if (wasMaximized!=maximized) {
677 FXWindow* mainwin=getShell();
678 mainwin->handle(mainwin, FXSEL(SEL_COMMAND, ID_MAXRESTORE),ptr);
679 wasMaximized=maximized;
680 }
681 return FXMDIChild::handle(sender,sel,ptr);
682 }
683
684 MDIChild::~MDIChild() {
685 delete pop;
686 delete layoutparser;
687 delete groupHolder;
688 //== static members:
689 numInst--;
690 if (numInst==0) {
691 delete ifont;
692 delete icnDefCS;
693 delete icnBaseCS;
694 delete icnDensCS;
695 }
696 }