00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <qprinter.h>
00017 #include <qinputdialog.h>
00018 #include <qlineedit.h>
00019 #include <qstring.h>
00020 #include <qcstring.h>
00021 #include <qvaluelist.h>
00022 #include <qwidget.h>
00023 #include <qdragobject.h>
00024 #include <qclipboard.h>
00025 #include <qapplication.h>
00026
00027 #include <qpopupmenu.h>
00028 #include <qlabel.h>
00029 #include "trapperconf.h"
00030 #include <qcursor.h>
00031
00032 #include "trapperview.h"
00033 #include "trapperdoc.h"
00034
00035 #include "generalmaker.h"
00036
00037 #include "featuregui.h"
00038 #include "readdata.h"
00039
00040 #include "viewmode.h"
00041 #include <string>
00042 #include <iostream>
00043
00044 #include "algomaker.h"
00045 #include "algo.h"
00046
00047 #include <algorithm>
00048 #include <cstdlib>
00049 #include <vector>
00050 #include "readsinrect.h"
00051 #include <sstream>
00052 #include "destroyer.h"
00053
00054 using namespace std;
00055
00056
00057
00058
00059 class ReadDrag : public QStoredDrag
00060 {
00061 public:
00062 ReadDrag( QPixmap & pixmap, QPoint & hotspot, QWidget * w ) : QStoredDrag("min_mime_type", w) {
00063 setPixmap( pixmap, hotspot );
00064
00065 }
00066 ReadDrag( QWidget* w ) : QStoredDrag("min_mime_type", w) { }
00067 ~ReadDrag(){}
00068
00069 };
00070
00071 TrapperView::TrapperView(TrapperDoc* pDoc, QWidget *parent, const char* name, QString _viewMode )
00072 : QScrollView(parent, name, WResizeNoErase|WStaticContents|WDestructiveClose), doc( pDoc )
00073 {
00074
00075
00076 viewport()->setAcceptDrops( true );
00077 setDragAutoScroll( true );
00078 allow_dragging = true;
00079 dragging = false;
00080 moving = false;
00081 rubber_band = 0;
00082 last_click_selected_read = false;
00083 last_click_changed_selection = false;
00084
00085
00086 if ( _viewMode.isNull() )
00087 {
00088 _viewMode = "closeup";
00089 }
00090
00091 viewModes = new ViewModes( _viewMode, doc );
00092
00093
00094 list<string> type_list = GeneralMaker::listRegistered();
00095 for( list<string>::iterator it = type_list.begin(); it != type_list.end(); ++it ) {
00096 zoom_cutoff[ *it ] = 0;
00097 }
00098 zoom_cutoff["DnaStrData"] = 4;
00099 zoom_cutoff["QualityData"] = 4;
00100 zoom_cutoff["ChromatData"] = 8;
00101
00102
00103
00104
00105 globalRows = 50;
00106 globalBases = 2000;
00107
00108
00109 rowheight = 5;
00110 basewidth = 1;
00111 magnifyX = magnifyY = 1;
00112 zoomfactor = 2;
00113 spaceBetweenRows = 0;
00114 center_point = 0;
00115
00116 fitContentsizeToData();
00117
00118
00119 viewport()->setPaletteBackgroundColor(white);
00120 viewport()->setBackgroundMode( Qt::FixedColor );
00121 setCaption( "yes" );
00122 viewport()->setMouseTracking(TRUE);
00123 }
00124
00125
00126 TrapperView::~TrapperView()
00127 {
00128
00129 if ( viewModes ) {
00130 delete viewModes;
00131 viewModes = NULL;
00132 }
00133 }
00134
00135 void TrapperView::fitContentsizeToData()
00136 {
00137 Database::SecondaryIterator<ReadData>* end_it = new Database::SecondaryIterator<ReadData>( "end", doc, "ReadData" );
00138 int ret_end = end_it->last();
00139 Database::SecondaryIterator<ReadData>* row_it = new Database::SecondaryIterator<ReadData>( "pos", doc, "ReadData" );
00140 int ret_row = row_it->last();
00141 ReadData* r_end = (ret_end != DB_NOTFOUND) ? end_it->answer() : 0;
00142 ReadData* r_row = (ret_row != DB_NOTFOUND) ? row_it->answer() : 0;
00143 if ( r_end ) {
00144
00145 globalBases = r_end->endPos() + 50;
00146 }
00147 if ( r_row ) {
00148
00149 globalRows = r_row->row() + 500;
00150 }
00151
00152 delete end_it;
00153 delete row_it;
00154
00155 resizeContents(globalBases * magnifyX * basewidth , globalRows * rowheight * magnifyY);
00156
00157 }
00158
00159 QString TrapperView::mode()
00160 {
00161 return viewModes->currentViewMode()->name();
00162 }
00163
00164 TrapperDoc *TrapperView::getDocument() const
00165 {
00166 return doc;
00167 }
00168
00169 void TrapperView::update(TrapperView* pSender)
00170 {
00171 if(pSender != this)
00172 repaint();
00173 }
00174
00175 void TrapperView::print(QPrinter *pPrinter)
00176 {
00177 if (pPrinter->setup(this))
00178 {
00179 QPainter p;
00180 p.begin(pPrinter);
00181
00182
00183
00184
00185
00186 p.end();
00187 }
00188 }
00189
00190 void TrapperView::closeEvent(QCloseEvent*)
00191 {
00192
00193
00194 }
00195
00196 void TrapperView::convertToDnaCoordinates( TR_DNA & x_dna, TR_DNA & y_dna, const TR_PIX cx, const TR_PIX cy )
00197 {
00198 x_dna = pixelCoordToDna_X(cx);
00199 y_dna = pixelCoordToDna_Y(cy);
00200 return;
00201 }
00202
00203 TR_DNA TrapperView::pixelCoordToDna_X( TR_PIX cx )
00204 {
00205
00206
00207
00208
00209
00210
00211 return cx / ( basewidth * magnifyX );
00212 }
00213
00214 TR_DNA TrapperView::pixelCoordToDna_Y( TR_PIX cy )
00215 {
00216 return cy / ( rowheight * magnifyY );
00217 }
00218
00219 void TrapperView::convertToPixelCoordinates( TR_PIX & x_pix, TR_PIX & y_pix, TR_DNA x_dna, TR_DNA y_dna )
00220 {
00221 x_pix = dnaCoordToPixel_X(x_dna);
00222 y_pix = dnaCoordToPixel_Y(y_dna);
00223 return;
00224 }
00225
00226 TR_PIX TrapperView::dnaCoordToPixel_X( TR_DNA x_dna )
00227 {
00228
00229
00230
00231
00232
00233
00234
00235 return x_dna * basewidth * magnifyX;
00236 }
00237
00238 TR_PIX TrapperView::dnaCoordToPixel_Y( TR_DNA y_dna )
00239 {
00240 return y_dna * rowheight * magnifyY;
00241 }
00242
00243 void TrapperView::paintFeatures( QPainter* p, QPainter * bitmapPainter, db_recno_t readRecno,
00244 TR_PIX x_pix, TR_PIX y_pix,
00245 TR_DNA x_dna_relative, TR_DNA dna_len ,
00246 double width, TR_PIX height, bool selected, int center_relative,
00247 bool overlap, TR_DNA bg, TR_DNA eg )
00248 {
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 Layer * layer;
00261
00262 p->setPen( Qt::black );
00263
00264
00265 QBrush brush;
00266 brush.setStyle( Qt::SolidPattern );
00267 brush.setColor( Qt::white );
00268 p->fillRect( x_pix , y_pix , dna_len*width , height ,brush) ;
00269
00270 brush.setColor( Qt::color1 );
00271
00272 if ( bitmapPainter && selected )
00273 bitmapPainter->fillRect( x_pix , y_pix , dna_len*width , height ,brush) ;
00274
00275
00276
00277
00278
00279
00280
00281
00282 y_pix += 1;
00283 height -= 2;
00284
00285
00286
00287
00288
00289
00290 TR_PIX heightLayerSum = 0;
00291
00292
00293 for (layer = viewModes->currentViewMode()->layerList.first(); layer; layer = viewModes->currentViewMode()->layerList.next() )
00294 {
00295 TR_PIX heightLayer = layer->heightInPix( height );
00296 Database::SecondaryIterator<FeatureData> * it;
00297 for (it = layer->featureList.first(); it; it = layer->featureList.next() )
00298 {
00299 int cutoff = zoom_cutoff[ it->name() ];
00300 if ( magnifyX < cutoff || magnifyY < cutoff ) continue;
00301
00302 it->key()->setReadRecno( readRecno );
00303 if ( it->set() == 0 ) {
00304 int ret;
00305 do {
00306
00307
00308
00309
00310
00311 it->answer()->gui()->paint( p, x_pix, y_pix + heightLayerSum , x_dna_relative, x_dna_relative + dna_len -1 , width, heightLayer, center_relative );
00312
00313 } while ( (ret = it->nextdup()) == 0);
00314
00315
00316 }
00317 it->closeCursor();
00318 }
00319 heightLayerSum += heightLayer;
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 QPen oldpen( p->pen() ), newpen( p->pen() );
00331
00332 if ( selected ) {
00333 newpen.setColor( Qt::red );
00334 if ( moving )
00335 newpen.setStyle( Qt::DashLine);
00336 }
00337 if ( overlap ) {
00338 newpen.setColor(Qt::green);
00339 }
00340 p->setPen(newpen);
00341
00342 if ( magnifyX < 1.0 ) {
00343
00344
00345
00346
00347
00348
00349 }
00350
00351 p->drawRect( x_pix , y_pix, dna_len*width , height ) ;
00352
00353
00354 brush.setStyle( Qt::Dense4Pattern );
00355 brush.setColor( Qt::white );
00356 if ( x_dna_relative < bg ) {
00357 p->fillRect( x_pix , y_pix, (bg - x_dna_relative)*width , height, brush ) ;
00358 }
00359 if ( x_dna_relative + dna_len > eg ) {
00360 int goodlen = eg - x_dna_relative + 1;
00361 if ( goodlen < 0 ) goodlen = 0;
00362 p->fillRect( x_pix + goodlen*width , y_pix, (dna_len - goodlen )*width, height, brush ) ;
00363 }
00364
00365
00366
00367 p->setPen( oldpen );
00368
00369
00370 }
00371
00372
00373 void TrapperView::drawContents(QPainter* p, TR_PIX cx, TR_PIX cy, TR_PIX cw, TR_PIX ch)
00374 {
00375
00376
00377
00378
00379 drawContents_helper(p, NULL, cx, cy, cw, ch, 0, 0);
00380 paintGrid( p, cx, cy, cw, ch);
00381 }
00382
00383 void TrapperView::drawContents_helper(QPainter* p,QPainter* bitmapPainter, int cx, int cy, int cw, int ch, int dx, int dy)
00384 {
00385
00386
00387
00388
00389
00390 if ( moving ) {
00391 assert( bitmapPainter == 0 );
00392
00393
00394 p->setRasterOp(NotXorROP);
00395
00396 if ( moveOn ) {
00397 p->drawPixmap(oldMovePoint, dragPixmap);
00398 }
00399 else {
00400 oldMovePoint = contentsToViewport(mousePressedPoint - dragWindowPoint);
00401 p->setRasterOp(NotXorROP);
00402 p->drawPixmap(oldMovePoint, dragPixmap);
00403
00404 }
00405
00406
00407 oldMovePoint = contentsToViewport(mousePressedPoint - dragWindowPoint + QPoint(0, dnaCoordToPixel_Y(pixelCoordToDna_Y(y_delta)) ));
00408
00409
00410 p->drawPixmap(oldMovePoint, dragPixmap);
00411
00412 moveOn = true;
00413 return;
00414
00415 }
00416
00417
00418 TR_DNA x_dna, y_dna;
00419 TR_DNA x2_dna, y2_dna;
00420 TR_DNA h_dna, w_dna;
00421
00422 convertToDnaCoordinates( x_dna, y_dna, cx, cy );
00423 convertToDnaCoordinates( x2_dna, y2_dna, cx + cw - 1, cy + ch - 1 );
00424
00425
00426
00427
00428 x_dna -= 10;
00429 x2_dna += 10;
00430
00431 w_dna = x2_dna - x_dna + 1;
00432 h_dna = y2_dna - y_dna + 1;
00433
00434
00435
00436
00437 TR_PIX x_pix, y_pix;
00438 convertToPixelCoordinates( x_pix, y_pix, x_dna, y_dna );
00439
00440 TR_PIX cx_paint = x_pix + dx;
00441 TR_PIX cy_paint = y_pix + dy;
00442
00443
00444
00445 readsInRect = new ReadsInRect( doc );
00446
00447
00448 readsInRect->setWindowCoord( x_dna, y_dna, w_dna,h_dna );
00449
00450 int previous_row(-1), previous_end(-1);
00451 for ( ReadData * r = readsInRect->first(); r; r = readsInRect->next() )
00452 {
00453
00454
00455 bool overlap(false);
00456 if ( r->row() == previous_row && (r->startPos() <= previous_end ) ) {
00457 overlap = true;
00458 }
00459 previous_row = r->row();
00460 previous_end = r->endPos();
00461
00462 bool selected = isSelected( r->getRecno() );
00463
00464
00465
00466
00467
00468 TR_DNA x1_dna_paint = max( r->startPos(), x_dna ) ;
00469 TR_DNA x2_dna_paint = min( r->endPos(), x_dna + w_dna - 1 ) ;
00470
00471 TR_PIX x_pix_adjust, y_pix_adjust;
00472 convertToPixelCoordinates( x_pix_adjust, y_pix_adjust, x1_dna_paint - x_dna, r->row() - y_dna );
00473
00474
00475
00476
00477 TR_DNA len = x2_dna_paint - x1_dna_paint +1 ;
00478
00479 paintFeatures( p, bitmapPainter, r->getRecno(),
00480 x_pix_adjust + cx_paint , y_pix_adjust + cy_paint,
00481 x1_dna_paint - r->startPos(), len,
00482 basewidth*magnifyX, rowheight*magnifyY - spaceBetweenRows , selected, center_point - r->startPos(),
00483 overlap, r->beginGood(), r->endGood() );
00484
00485 }
00486
00487
00488 delete readsInRect;
00489
00490
00491
00492
00493 if ( rubber_band ) {
00494 QPen oldpen( p->pen() );
00495 QPen newpen( Qt::black, 0, Qt::DotLine );
00496
00497 p->setPen( newpen );
00498 p->drawRect( *rubber_band );
00499 p->setPen( oldpen );
00500
00501 }
00502
00503 }
00504
00505 void TrapperView::paintGrid(QPainter* p, TR_PIX cx, TR_PIX cy, TR_PIX cw, TR_PIX ch)
00506 {
00507 p->setPen( Qt::black );
00508
00509
00510
00511 int local_rowheight = 100;
00512 int toprow=cy/local_rowheight;
00513 int bottomrow=(cy+ch+local_rowheight-1)/local_rowheight;
00514 int colwidth=100;
00515 int leftcol=cx/colwidth;
00516 int rightcol=(cx+cw+colwidth-1)/colwidth;
00517 for (int r=toprow; r<=bottomrow; r++) {
00518
00519 int py=r*local_rowheight - dnaCoordToPixel_Y(1)/2;
00520 for (int c=leftcol; c<=rightcol; c++) {
00521 int px=c*colwidth + dnaCoordToPixel_X(1)/2;
00522 p->drawLine(px, py, px+2, py);
00523
00524 }
00525 }
00526 QFont f;
00527 f.setPointSize(10);
00528 p->setFont(f);
00529 int viewport_toprow=contentsY()/local_rowheight - 2;
00530 if (viewport_toprow <0 ) viewport_toprow = 0;
00531
00532 int viewport_bottomrow=(cy+ch+local_rowheight-1)/local_rowheight + 1;
00533 int viewport_leftcol=contentsX()/colwidth;
00534 int viewport_rightcol=(contentsX() + contentsWidth() +colwidth-1)/colwidth;
00535
00536
00537 for( int i = viewport_leftcol; i < viewport_rightcol; i++ ) {
00538 p->drawText( i*colwidth + dnaCoordToPixel_X(1)/2, 10, QString().setNum(pixelCoordToDna_X( i*colwidth )) );
00539 }
00540 for( int i = viewport_toprow; i < viewport_bottomrow; i++ ) {
00541 p->drawText( 0, i*local_rowheight, QString().setNum(pixelCoordToDna_Y( i*local_rowheight )) );
00542 }
00543
00544 bottomrow=(cy+ch+rowheight-1)/rowheight;
00545 int center_x = dnaCoordToPixel_X(center_point) + dnaCoordToPixel_X(1)/2;
00546 p->drawLine(center_x, 0, center_x, bottomrow*rowheight );
00547 }
00548
00549 void TrapperView::moveData(TR_PIX dx, TR_PIX dy)
00550 {
00551
00552 TR_DNA col_delta, row_delta;
00553 row_delta = pixelCoordToDna_Y( dy );
00554 col_delta = pixelCoordToDna_X( dx);
00555
00556 AlgoMoveParam param( col_delta, row_delta );
00557
00558 runAlgo( "Move Reads", getSelectedReads(), ¶m );
00559
00560 last_move_x = param.get_x_delta();
00561 last_move_y = param.get_y_delta();
00562
00563
00564 }
00565
00566 void TrapperView::clearLastMove()
00567 {
00568 last_move_x = last_move_y = 0;
00569 }
00570
00571
00572 void TrapperView::contentsMousePressEvent(QMouseEvent* e)
00573 {
00574 QString msg = "Row: " + QString().setNum(pixelCoordToDna_Y(e->y())) + ", col: " + QString().setNum(pixelCoordToDna_X(e->x()));
00575 sendMsg( msg );
00576
00577 y_delta = 0;
00578 y_delta_previous = 0;
00579
00580 bool ctrlclick = Qt::ControlButton & e->state();
00581 bool leftbutton = Qt::LeftButton & e->stateAfter();
00582
00583
00584
00585
00586
00587 mousePressedPoint.setX( e->x() );
00588 mousePressedPoint.setY( e->y() );
00589
00590
00591
00592 RubberStart=contentsToViewport(e->pos());
00593 RubberEnd = RubberStart;
00594 RubberOn=FALSE;
00595
00596
00597
00598 moveOn = false;
00599
00600
00601 TR_DNA x_dna, y_dna;
00602 convertToDnaCoordinates( x_dna, y_dna, e->x(), e->y() );
00603
00604 readsInRect = new ReadsInRect( doc );
00605
00606 readsInRect->setWindowCoord( x_dna, y_dna, 3, 3 );
00607 ReadData * r = readsInRect->first();
00608 if ( r ) {
00609 if ( ctrlclick ) {
00610 if ( isSelected( r->getRecno() ) ) {
00611 select( r->getRecno(), false );
00612 last_click_selected_read = false;
00613 last_click_changed_selection = true;
00614 }
00615 else {
00616 select( r->getRecno(), true);
00617 last_click_selected_read = true;
00618 last_selected_recno = r->getRecno();
00619 last_click_changed_selection = true;
00620 }
00621 }
00622 else {
00623 if ( isSelected( r->getRecno() ) ) {
00624 last_click_selected_read = true;
00625 last_selected_recno = r->getRecno();
00626 last_click_changed_selection = false;
00627 }
00628 else {
00629 clearSelected();
00630 select( r->getRecno(), true);
00631 last_click_selected_read = true;
00632 last_selected_recno = r->getRecno();
00633 last_click_changed_selection = true;
00634 }
00635
00636 }
00637 if ( last_click_selected_read )
00638 dragging = TRUE;
00639 }
00640 else {
00641
00642
00643
00644
00645 if ( ctrlclick ) {
00646 last_click_selected_read = false;
00647 last_click_changed_selection = false;
00648 }
00649 else {
00650 last_click_selected_read = false;
00651 if ( selectedReads.size() > 0 )
00652 last_click_changed_selection = true;
00653
00654 clearSelected();
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664 }
00665 if ( rubber_band != 0 ) {
00666 delete rubber_band;
00667 }
00668 if (leftbutton && !last_click_selected_read) {
00669 moving = false;
00670 rubber_band = new QRect( mousePressedPoint, mousePressedPoint );
00671 }
00672
00673 }
00674
00675
00676 delete readsInRect;
00677
00678
00679 {
00680 dragWindowPoint.setX( size().width() );
00681 dragWindowPoint.setY( size().height() );
00682 QRect re( mousePressedPoint - dragWindowPoint, mousePressedPoint + dragWindowPoint );
00683
00684
00685 dragPixmap.resize( re.size() );
00686 QPainter p2;
00687 p2.begin(&dragPixmap, this);
00688 dragBitmap.resize( re.size() );
00689 p3.begin(&dragBitmap, this);
00690 QBrush brush;
00691 brush.setStyle( Qt::SolidPattern );
00692 brush.setColor( Qt::white );
00693 p2.fillRect( 0 , 0 , re.width() , re.height() ,brush) ;
00694 brush.setColor( Qt::color0 );
00695
00696 p3.fillRect( 0 , 0 , re.width() , re.height() ,brush) ;
00697
00698 QPoint tl = re.topLeft() ;
00699 QPoint br = re.bottomRight() ;
00700
00701 drawContents_helper(&p2, &p3, tl.x(), tl.y(), br.x() - tl.x() + 1, br.y() - tl.y() + 1,
00702 - ( mousePressedPoint.x() - dragWindowPoint.x() ), - ( mousePressedPoint.y() - dragWindowPoint.y() ));
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712 dragPixmap.setMask(dragBitmap);
00713
00714 p2.end();
00715 p3.end();
00716 }
00717 }
00718
00719
00720 void TrapperView::contentsMouseMoveEvent(QMouseEvent* e)
00721 {
00722 QString msg = "Row: " + QString().setNum(pixelCoordToDna_Y(e->y())) + ", col: " + QString().setNum(pixelCoordToDna_X(e->x()));
00723 sendMsg( msg );
00724
00725 bool nobutton = Qt::NoButton & e->state();
00726
00727 if ( nobutton ) {
00728 moving = false;
00729 return;
00730 }
00731
00732
00733 if ( allow_dragging && dragging ) {
00734
00735
00736
00737 ReadDrag *d = new ReadDrag( dragPixmap, dragWindowPoint, this );
00738
00739 QByteArray ar;
00740 QDataStream data_stream(ar, IO_WriteOnly);
00741 writeSelected(data_stream);
00742
00743 d->setEncodedData(ar);
00744 d->dragCopy();
00745 dragging = FALSE;
00746 moving = false;
00747 last_click_selected_read = false;
00748
00749 }
00750 else if ( last_click_selected_read ) {
00751
00752
00753 moving = true;
00754
00755 curr_mouse_pos = e->pos();
00756
00757 y_delta = (curr_mouse_pos - mousePressedPoint).y();
00758
00759 if ( pixelCoordToDna_Y( y_delta) == pixelCoordToDna_Y( y_delta_previous ) ) {
00760
00761 return;
00762 }
00763
00764 y_delta_previous = y_delta;
00765
00766
00767
00768 QPainter p(viewport());
00769 drawContents_helper(&p, 0,0,0,0,0,0,0);
00770 return;
00771
00772
00773 updateContents();
00774 }
00775 else if ( rubber_band != 0 ) {
00776
00777
00778 QPainter p(viewport());
00779 p.setPen(QColor(255,255,255));
00780 p.setRasterOp(NotROP);
00781 if(RubberOn) drawRubber(&p);
00782 RubberEnd= contentsToViewport(e->pos());
00783 drawRubber(&p);
00784 RubberOn=TRUE;
00785 return;
00786
00787
00788 curr_mouse_pos = e->pos();
00789
00790 QRect oldband = rubber_band->normalize();
00791
00792 rubber_band->setSize( QSize( curr_mouse_pos.x() - mousePressedPoint.x(),
00793 curr_mouse_pos.y() - mousePressedPoint.y() ) );
00794
00795
00796 QPoint margin( 1, 1 );
00797 QRect norm = rubber_band->normalize();
00798
00799 updateContents( QRect( norm.topLeft() - margin, norm.bottomRight() + margin ).unite( QRect(oldband.topLeft() - margin, oldband.bottomRight() + margin ) ) );
00800 }
00801
00802 }
00803
00804 void TrapperView::contentsMouseReleaseEvent(QMouseEvent* e)
00805 {
00806 dragging = false;
00807
00808
00809 if ( moving ) {
00810
00811 moveData(0, y_delta);
00812
00813
00814
00815
00816 if(moveOn)
00817 {
00818 updateContents();
00819 moveOn=FALSE;
00820 }
00821
00822
00823 moving = false;
00824 }
00825 else {
00826
00827 bool ctrlclick = Qt::ControlButton & e->state();
00828
00829 if ( !ctrlclick && last_click_selected_read ) {
00830 clearSelected();
00831 select( last_selected_recno, true );
00832 last_click_changed_selection = true;
00833
00834 }
00835 if ( last_click_changed_selection ) {
00836 updateContents();
00837 }
00838
00839
00840 if ( rubber_band != 0 ) {
00841
00842 readsInRect = new ReadsInRect( doc );
00843
00844 TR_DNA x_dna, y_dna, w_dna, h_dna, x2_dna, y2_dna;
00845 TR_PIX x_pix, y_pix, w_pix, h_pix;
00846
00847 QRect norm = rubber_band->normalize();
00848
00849 RubberStart = viewportToContents( RubberStart );
00850 RubberEnd = viewportToContents( RubberEnd );
00851
00852 norm = QRect(
00853 RubberStart.x(),
00854 RubberStart.y(),
00855 RubberEnd.x()-RubberStart.x(),
00856 RubberEnd.y()-RubberStart.y()
00857 ).normalize();
00858
00859
00860 rubber_band->setTopLeft( norm.topLeft() );
00861 rubber_band->setBottomRight( norm.bottomRight() );
00862
00863 rubber_band->rect( &x_pix, &y_pix, &w_pix, &h_pix);
00864 convertToDnaCoordinates( x_dna, y_dna, x_pix, y_pix );
00865 convertToDnaCoordinates( x2_dna, y2_dna, x_pix + w_pix, y_pix + h_pix);
00866
00867 w_dna = x2_dna - x_dna;
00868 h_dna = y2_dna - y_dna;
00869
00870
00871 readsInRect->setWindowCoord( x_dna, y_dna, w_dna,h_dna );
00872 if ( !ctrlclick)
00873 clearSelected();
00874
00875 for ( ReadData * r = readsInRect->first(); r; r = readsInRect->next() ) {
00876 select( r->getRecno(), true);
00877 }
00878
00879 QPainter p(viewport());
00880 p.setPen(QColor(255,255,255));
00881 p.setRasterOp(NotROP);
00882 if(RubberOn)
00883 {
00884 drawRubber(&p);
00885 RubberOn=FALSE;
00886 }
00887 else
00888 {
00889 RubberEnd=RubberStart;
00890 }
00891
00892
00893 delete rubber_band;
00894 rubber_band = 0;
00895 delete readsInRect;
00896 updateContents();
00897 }
00898
00899 }
00900 moving = false;
00901 dragging = false;
00902 last_click_changed_selection = false;
00903 last_click_selected_read = false;
00904
00905 }
00906
00907 void TrapperView::contentsContextMenuEvent( QContextMenuEvent * e )
00908 {
00909 if ( last_click_changed_selection ) {
00910 updateContents();
00911 }
00912 moving = false;
00913 last_click_selected_read = false;
00914 last_click_changed_selection = false;
00915
00916 QPopupMenu* contextMenu = new QPopupMenu( this );
00917 Q_CHECK_PTR( contextMenu );
00918 QLabel *caption = new QLabel( "<font color=darkblue><u><b>"
00919 "Context Menu</b></u></font>", this );
00920 caption->setAlignment( Qt::AlignCenter );
00921 contextMenu->insertItem( caption );
00922
00923
00924
00925
00926
00927 algoMenu = new QPopupMenu( this );
00928 Q_CHECK_PTR( algoMenu );
00929 list<string> algos = AlgoMaker::algosRegistered();
00930 list<string>::iterator stIt;
00931
00932 for (stIt = algos.begin() ; stIt != algos.end(); ++stIt )
00933 {
00934 algoMenu->insertItem ( stIt->c_str() );
00935 }
00936 connect( algoMenu, SIGNAL( activated( int ) ),
00937 this, SLOT( slotStartAlgo( int ) ) );
00938 contextMenu->insertItem( "&Operations", algoMenu );
00939
00940
00941
00942
00943 infoMenu = new QPopupMenu(this);
00944
00945 vector<list<string> > infos = getInfo( e->pos() );
00946 QPtrList<QPopupMenu> infolist;
00947 infolist.setAutoDelete( true );
00948
00949 for( size_t i = 0; i < infos.size(); i++ ) {
00950 stIt = infos[i].begin();
00951 if ( stIt == infos[i].end() ) continue;
00952 infolist.append(new QPopupMenu(this));
00953 ++stIt;
00954
00955 for ( ; stIt != infos[i].end(); ++stIt ) {
00956
00957
00958 infolist.last()->insertItem ( stIt->c_str() );
00959 }
00960
00961
00962 infoMenu->insertItem(infos[i].begin()->c_str(), infolist.last());
00963 }
00964
00965
00966 contextMenu->insertItem( "&Info", infoMenu );
00967
00968
00969
00970 switchViewMenu = new QPopupMenu( this );
00971 Q_CHECK_PTR( switchViewMenu );
00972 TrapperConf * conf = TrapperConf::instance();
00973 QStringList names = conf->viewModeNames();
00974
00975 QStringList::Iterator it = names.begin();
00976 for ( ; it != names.end(); ++it )
00977 {
00978 switchViewMenu->insertItem ( *it );
00979 }
00980 connect( switchViewMenu, SIGNAL( activated( int ) ),
00981 this, SLOT( slotSwitchToMode( int ) ) );
00982 contextMenu->insertItem( "&Switch to viewmode", switchViewMenu );
00983
00984
00985 contextMenu->insertSeparator();
00986 contextMenu->insertItem("Set chromat center", this, SLOT(slotSetCenter()));
00987 contextMenu->insertItem("Clear chromat center", this, SLOT(slotClearCenter()));
00988
00989 contextMenu->insertSeparator();
00990 contextMenu->insertItem("Scroll Here", this, SLOT(slotScrollToMouse()) );
00991 contextMenu->insertItem("Scroll to pos", this, SLOT(slotScrollToPos()) );
00992
00993 contextMenu->exec( QCursor::pos() );
00994 delete contextMenu;
00995 delete switchViewMenu;
00996 delete algoMenu;
00997 delete infoMenu;
00998 }
00999
01000 void TrapperView::slotSwitchToMode( int i )
01001 {
01002 QString viewMode = switchViewMenu->text(i);
01003 viewModes->setMode( viewMode );
01004 doc->changedViewList();
01005 updateContents();
01006 }
01007
01008 void TrapperView::slotStartAlgo( int i )
01009 {
01010 QString algoStr = algoMenu->text(i);
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028 ViewParam param(this);
01029
01030 updateContents();
01031 runAlgo( algoStr.ascii(), getSelectedReads(), ¶m );
01032
01033 clearLastMove();
01034 }
01035
01036 void TrapperView::slotScrollToMouse()
01037 {
01038 scrollTo(mousePressedPoint.x(), mousePressedPoint.y());
01039
01040 }
01041
01042 void TrapperView::slotScrollToPos()
01043 {
01044 bool ok;
01045 int res = QInputDialog::getInteger(
01046 "Scroll to position", "Enter row:", 0, 0, numeric_limits<int>::max(), 1,
01047 &ok, 0 );
01048
01049 if ( ok ) {
01050
01051 } else {
01052
01053 return;
01054 }
01055 TR_PIX y = dnaCoordToPixel_Y(res);
01056
01057 res = QInputDialog::getInteger(
01058 "Scroll to position", "Enter column:", 0, 0, numeric_limits<int>::max(), 1,
01059 &ok, 0 );
01060
01061 if ( ok ) {
01062
01063 } else {
01064
01065 return;
01066 }
01067
01068 TR_PIX x = dnaCoordToPixel_X(res);
01069
01070 scrollTo(x, y);
01071
01072 }
01073
01074 void TrapperView::slotSetCenter()
01075 {
01076 center_point = mousePressedCol();
01077
01078 updateContents();
01079 }
01080
01081 void TrapperView::slotClearCenter()
01082 {
01083 center_point = 0;
01084 updateContents();
01085 }
01086
01087 void TrapperView::findRead()
01088 {
01089 bool ok;
01090 QString res = QInputDialog::getText ( "Find read", "Enter read name:", QLineEdit::Normal, QString::null, &ok );
01091
01092
01093 if ( ok ) {
01094
01095 } else {
01096
01097 return;
01098 }
01099
01100 Database::SecondaryIterator<ReadData> name_it( "name", doc, "ReadData" );
01101 name_it.key()->setName( res );
01102 if ( name_it.set() != 0 ) {
01103 cerr<<"Error, couldn't find "<<res<<" in db"<<endl;
01104 return;
01105 }
01106 clearSelected();
01107 select(name_it.answer()->getRecno(), true);
01108 TR_PIX y = dnaCoordToPixel_Y(name_it.answer()->row());
01109 TR_PIX x = dnaCoordToPixel_X(name_it.answer()->startPos());
01110 scrollTo(x, y);
01111
01112 }
01113
01114
01115 std::set<db_recno_t>& TrapperView::getSelectedReads()
01116 {
01117 return selectedReads;
01118 }
01119
01120 void TrapperView::select( db_recno_t recno, bool status )
01121 {
01122 RecnoMap::iterator pos;
01123 if ( status == true && !isSelected(recno) ) {
01124 selectedReads.insert( recno );
01125 clearLastMove();
01126 }
01127 else if ( ( pos = selectedReads.find( recno )) != selectedReads.end() ) {
01128 selectedReads.erase( pos );
01129 clearLastMove();
01130 }
01131
01132 }
01133
01134 bool TrapperView::isSelected( db_recno_t recno )
01135 {
01136 return selectedReads.find( recno ) != selectedReads.end();
01137 }
01138
01139 void TrapperView::clearSelected()
01140 {
01141 selectedReads.clear();
01142 clearLastMove();
01143 }
01144
01145 std::vector<std::list<std::string > > TrapperView::getInfo( const QPoint& pos )
01146 {
01147 vector<list<string> > result;
01148 list<string> readResult;
01149 list<string> featResult;
01150 list<string> generalResult;
01151
01152
01153 TR_DNA row = pixelCoordToDna_Y( pos.y() );
01154 TR_DNA col = pixelCoordToDna_X( pos.x() );
01155
01156 readsInRect = new ReadsInRect( doc );
01157 readsInRect->setWindowCoord( col, row, 1, 1 );
01158
01159 ReadData * r = readsInRect->first();
01160
01161 ostringstream os;
01162 if ( r ) {
01163 list<string> types = GeneralMaker::listRegistered();
01164 readResult.push_back( "Read info" );
01165 readResult.push_back( r->name() );
01166
01167 os<<"Strand: "<<r->strand();
01168 readResult.push_back( r->strand() );
01169 os.str("");
01170 os<<"Mate: "<<r->mate() << ' ' << r->mateLength();
01171 readResult.push_back( os.str() );
01172 os.str("");
01173 os<<"Begin good: "<<r->beginGood();
01174 readResult.push_back( os.str() );
01175 os.str("");
01176 os<<"End good: "<<r->endGood();
01177 readResult.push_back( os.str() );
01178 os.str("");
01179 os<<"Read index: "<<col - r->startPos();
01180 readResult.push_back( os.str() );
01181
01182
01183 featResult.push_back( "Feature info" );
01184
01185
01186 for( list<string>::iterator it = types.begin(); it != types.end(); ++it ) {
01187 GeneralData * data = GeneralMaker::newData( *it );
01188 FeatureData * fdata = dynamic_cast<FeatureData *>( data );
01189
01190
01191 if ( fdata ) {
01192 Database::SecondaryIterator<FeatureData> featIt( "readRecno", doc, it->c_str() );
01193
01194 featIt.key()->setReadRecno( r->getRecno() );
01195
01196 string featInfo;
01197
01198 if ( featIt.set() == 0 ) {
01199
01200 int ret;
01201 do {
01202
01203 featInfo = featIt.answer()->info()->getPosInfo( col - r->startPos() );
01204 if ( !featInfo.empty() ) {
01205 featResult.push_back( featInfo );
01206 }
01207 featInfo = featIt.answer()->info()->getRangeInfo( 0, r->endPos() - r->startPos() );
01208 if ( !featInfo.empty() ) {
01209 readResult.push_back( featInfo );
01210 }
01211
01212
01213 } while ( (ret = featIt.nextdup()) == 0);
01214 }
01215 }
01216
01217 delete data;
01218
01219 }
01220
01221
01222 }
01223 generalResult.push_back("General info");
01224 os.str("");
01225 os<<"Row: "<<row<<", Col: "<<col;
01226 generalResult.push_back( os.str() );
01227
01228 result.push_back(readResult);
01229 result.push_back(featResult);
01230 result.push_back(generalResult);
01231
01232 delete readsInRect;
01233 return result;
01234 }
01235
01236 void TrapperView::runAlgo( const std::string& AlgoType, std::set< db_recno_t >& recnoList, AlgoParam* param )
01237 {
01238
01239 if (selectedReads.size() > 0 ) {
01240
01241 Algo * algo = AlgoMaker::newAlgo( AlgoType, doc , recnoList, param );
01242 doc->addAlgorithm( algo );
01243 algo->start();
01244 doc->removeAlgorithm( algo );
01245 delete algo;
01246
01247 updateContents();
01248 fitContentsizeToData();
01249 }
01250
01251 }
01252
01253 void TrapperView::zoomIn()
01254 {
01255 zoomInX();
01256 zoomInY();
01257 }
01258
01259 void TrapperView::zoomInX()
01260 {
01261 if ( magnifyX >= 128 )
01262 return;
01263
01264 magnifyX *= zoomfactor;
01265
01266
01267 QPoint p = viewportToContents(viewport()->rect().topLeft());
01268
01269
01270
01271
01272
01273 resizeContents(globalBases * magnifyX * basewidth , globalRows * rowheight * magnifyY);
01274 setContentsPos(p.x()*zoomfactor, p.y());
01275
01276 updateContents();
01277
01278 }
01279
01280 void TrapperView::zoomInY()
01281 {
01282 if ( magnifyY >= 128 )
01283 return;
01284 magnifyY *= zoomfactor;
01285
01286
01287 QPoint p = viewportToContents(viewport()->rect().topLeft());
01288
01289 resizeContents(globalBases * magnifyX * basewidth , globalRows * rowheight * magnifyY);
01290 setContentsPos(p.x(), p.y()*zoomfactor);
01291
01292 updateContents();
01293 }
01294
01295 void TrapperView::zoomOut()
01296 {
01297 zoomOutX();
01298 zoomOutY();
01299 }
01300
01301 void TrapperView::zoomOutX()
01302 {
01303
01304 if ( magnifyX <= 0.25 )
01305 {
01306 return;
01307 }
01308 magnifyX /= zoomfactor;
01309
01310
01311 QPoint p = viewportToContents(viewport()->rect().topLeft());
01312
01313
01314
01315
01316
01317 resizeContents(globalBases * magnifyX * basewidth , globalRows * rowheight * magnifyY);
01318 setContentsPos(p.x()/zoomfactor, p.y());
01319
01320 updateContents();
01321 }
01322
01323 void TrapperView::zoomOutY()
01324 {
01325 if ( magnifyY <= 1 )
01326 {
01327 return;
01328 }
01329 magnifyY /= zoomfactor;
01330
01331
01332 QPoint p = viewportToContents(viewport()->rect().topLeft());
01333 resizeContents(globalBases * magnifyX * basewidth , globalRows * rowheight * magnifyY);
01334 setContentsPos(p.x(), p.y()/zoomfactor);
01335
01336 updateContents();
01337 }
01338
01339 void TrapperView::doZoom()
01340 {
01341
01342
01343
01344
01345
01346
01347 resizeContents(globalBases * magnifyX * basewidth , globalRows * rowheight * magnifyY);
01348
01349
01350
01351
01352 updateContents();
01353
01354 }
01355
01356 void TrapperView::scrollTo(TR_PIX x, TR_PIX y)
01357 {
01358 setContentsPos( x, y );
01359 updateContents();
01360
01361 }
01362
01363
01364 void TrapperView::enlarge()
01365 {
01366 globalRows *= 2;
01367 globalBases *= 1.25;
01368 resizeContents(globalBases * magnifyX * basewidth , globalRows * rowheight * magnifyY);
01369 updateContents();
01370 }
01371
01372 void TrapperView::shrink()
01373 {
01374 globalRows *= 0.5;
01375 globalBases *= 0.8;
01376 resizeContents(globalBases * magnifyX * basewidth , globalRows * rowheight * magnifyY);
01377 updateContents();
01378 }
01379
01380
01381 void TrapperView::selectAll()
01382 {
01383 clearSelected();
01384 Database::PrimaryIterator<ReadData> iter( doc, "ReadData" );
01385
01386 if ( iter.first() == 0 ) {
01387
01388 do {
01389 select( iter.answer()->getRecno(), true );
01390
01391 } while ( iter.next() == 0 );
01392
01393 }
01394 updateContents();
01395
01396 }
01397
01398 void TrapperView::selectBetween()
01399 {
01400 clearSelected();
01401 bool ok;
01402 TR_DNA start, stop;
01403 int res = QInputDialog::getInteger("Select between rows", "Enter start row for selected reads:", 0, 1, numeric_limits<int>::max(), 1,
01404 &ok, 0 );
01405 if ( ok ) {
01406 start = res;
01407 }
01408 else {
01409 return;
01410 }
01411
01412 res = QInputDialog::getInteger("Select between rows",
01413 "Enter stop row for selected reads:",
01414 0, 1, numeric_limits<int>::max(), 1,
01415 &ok, 0 );
01416 if ( ok ) {
01417 stop = res;
01418 if ( start > stop ) {
01419 TR_DNA tmp = start;
01420 start = stop;
01421 stop = tmp;
01422 }
01423 }
01424 else {
01425 return;
01426 }
01427
01428 Database::SecondaryIterator<ReadData> row_it( "pos", doc, "ReadData" );
01429 row_it.key()->setRow(start);
01430 row_it.key()->setStartPos(0);
01431
01432 if ( row_it.setRange() != 0 ) {
01433
01434 return;
01435 }
01436
01437 do {
01438 select( row_it.answer()->getRecno(), true );
01439 }while( row_it.next() == 0 && row_it.answer()->row() <= stop );
01440
01441 updateContents();
01442
01443 }
01444
01445
01446
01447
01448 void TrapperView::contentsDragEnterEvent(QDragEnterEvent* event)
01449 {
01450
01451 event->accept(
01452 TRUE
01453 );
01454 }
01455
01456 void TrapperView::contentsDragMoveEvent ( QDragMoveEvent* e )
01457 {
01458
01459
01460
01461
01462
01463
01464
01465 }
01466
01467 void TrapperView::contentsDropEvent(QDropEvent* event)
01468 {
01469
01470
01471 QPoint deltaMovement = event->pos() - mousePressedPoint;
01472 TR_DNA x_dna_movDelta;
01473 TR_DNA y_dna_movDelta;
01474
01475 convertToDnaCoordinates( x_dna_movDelta, y_dna_movDelta, deltaMovement.x(), deltaMovement.y() );
01476
01477
01478 TrapperView* w = dynamic_cast<TrapperView*>( event->source() );
01479
01480 if ( !w) {
01481
01482 return;
01483 }
01484
01485
01486 assert(w);
01487
01488 if ( w->getDocument() == this->getDocument() ) {
01489
01490 moveData( deltaMovement.x(), deltaMovement.y() );
01491 }
01492 else {
01493 QByteArray ar( event->encodedData("min_mime_type") );
01494 QDataStream data_stream(ar, IO_ReadOnly);
01495
01496 readSelected(data_stream);
01497 updateContents();
01498 }
01499
01500
01501 }
01502
01503 void TrapperView::writeSelected(QDataStream& data_stream)
01504 {
01505
01506
01507
01508
01509
01510 list<string> type_list = GeneralMaker::listRegistered();
01511
01512
01513
01514 for( set<db_recno_t>::iterator recno_it = selectedReads.begin(); recno_it != selectedReads.end(); ++recno_it ) {
01515
01516 db_recno_t recno(*recno_it);
01517
01518
01519 Database::PrimaryIterator<ReadData>* read_it = new Database::PrimaryIterator<ReadData>(doc, "ReadData");
01520
01521
01522 read_it->setFromRecno(recno);
01523
01524
01525 data_stream<<"ReadData";
01526
01527
01528 read_it->answer()->writeStream(data_stream);
01529
01530
01531 delete read_it;
01532
01533
01534 for( list<string>::iterator type_it = type_list.begin(); type_it != type_list.end(); ++type_it ) {
01535
01536 GeneralData * data = GeneralMaker::newData( *type_it );
01537 FeatureData * fdata = dynamic_cast<FeatureData *>( data );
01538
01539
01540 if ( fdata ) {
01541
01542 Database::SecondaryIterator<FeatureData> featIt( "readRecno", doc, type_it->c_str() );
01543
01544
01545 featIt.key()->setReadRecno( recno );
01546
01547 if ( featIt.set() == 0 ) {
01548 int ret;
01549 do {
01550
01551
01552 data_stream<<type_it->c_str();
01553
01554
01555 featIt.answer()->writeStream(data_stream);
01556
01557 } while ((ret = featIt.nextdup())== 0);
01558
01559 }
01560
01561 }
01562
01563 delete data;
01564
01565 }
01566
01567 }
01568
01569 }
01570
01571 void TrapperView::readSelected(QDataStream& data_stream)
01572 {
01573
01574 clearSelected();
01575
01576 db_recno_t recno(0);
01577
01578
01579
01580 TR_DNA rowmin(numeric_limits<TR_DNA>::max());
01581 TR_DNA colmin(numeric_limits<TR_DNA>::max());
01582
01583 while ( !data_stream.atEnd() ) {
01584
01585
01586 char* data_type;
01587
01588 data_stream>>data_type;
01589
01590 string type(data_type);
01591
01592
01593 Database::Creator<GeneralData> a_creator(doc, type);
01594
01595
01596 a_creator.data()->readStream(data_stream);
01597
01598 if ( ReadData* data = dynamic_cast<ReadData*>(a_creator.data())) {
01599
01600
01601 recno = a_creator.create(false);
01602 select(recno, true);
01603 if ( data->row() < rowmin ) {
01604 rowmin = data->row();
01605 }
01606 if ( data->startPos() < colmin ) {
01607 colmin = data->startPos();
01608 }
01609
01610 }
01611 else {
01612
01613 FeatureData* data = dynamic_cast<FeatureData*>(a_creator.data());
01614 assert( data );
01615 assert( recno != 0 );
01616
01617
01618 data->setReadRecno(recno);
01619
01620
01621 a_creator.create(false);
01622 }
01623
01624 delete data_type;
01625 }
01626 fitContentsizeToData();
01627 moveData( -dnaCoordToPixel_X(colmin - 1), -dnaCoordToPixel_Y(rowmin - 1) );
01628 clearLastMove();
01629 }
01630
01631 void TrapperView::setDragMode(bool status)
01632 {
01633 allow_dragging = status;
01634 }
01635
01636 void TrapperView::copy()
01637 {
01638 QByteArray ar;
01639 QDataStream str(ar, IO_WriteOnly);
01640
01641 writeSelected(str);
01642 QClipboard* cb = QApplication::clipboard();
01643 ReadDrag* r = new ReadDrag(this);
01644 r->setEncodedData(ar);
01645 cb->setData(r, QClipboard::Clipboard);
01646
01647 }
01648
01649 void TrapperView::paste()
01650 {
01651
01652 QClipboard* cb = QApplication::clipboard();
01653 QMimeSource* r = cb->data(QClipboard::Clipboard);
01654
01655 QByteArray ar(r->encodedData("min_mime_type"));
01656 QDataStream str(ar, IO_ReadOnly);
01657
01658 readSelected(str);
01659 updateContents();
01660 }
01661
01662 void TrapperView::cut()
01663 {
01664 copy();
01665 Destroyer d(doc);
01666 for( set<db_recno_t>::iterator it = selectedReads.begin(); it != selectedReads.end(); ++it ) {
01667 d.destroy(*it);
01668 }
01669 clearSelected();
01670 updateContents();
01671
01672 }
01673
01674 void TrapperView::undo()
01675 {
01676 moveData( -dnaCoordToPixel_X(last_move_x), -dnaCoordToPixel_Y(last_move_y) );
01677 }
01678
01679 TR_DNA TrapperView::mousePressedRow()
01680 {
01681 return pixelCoordToDna_Y( mousePressedPoint.y() );
01682
01683
01684 }
01685
01686 TR_DNA TrapperView::mousePressedCol()
01687 {
01688 return pixelCoordToDna_X( mousePressedPoint.x() );
01689
01690 }
01691
01692 void TrapperView::sendMsg( const QString& msg)
01693 {
01694 emit message(msg);
01695 }
01696