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 #include "infopopup.h"
00054
00055
00056 using namespace std;
00057
00058
00059
00060
00061 class ReadDrag : public QStoredDrag
00062 {
00063 public:
00064 ReadDrag( QPixmap & pixmap, QPoint & hotspot, QWidget * w ) : QStoredDrag("min_mime_type", w) {
00065 setPixmap( pixmap, hotspot );
00066
00067 }
00068 ReadDrag( QWidget* w ) : QStoredDrag("min_mime_type", w) { }
00069 ~ReadDrag(){}
00070
00071 };
00072
00073 TrapperView::TrapperView(TrapperDoc* pDoc, QWidget *parent, const char* name, QString _viewMode )
00074 : QScrollView(parent, name, WResizeNoErase|WStaticContents|WDestructiveClose), doc( pDoc )
00075 {
00076
00077
00078 viewport()->setAcceptDrops( true );
00079 setDragAutoScroll( true );
00080 allow_dragging = true;
00081 dragging = false;
00082 moving = false;
00083 rubber_band = 0;
00084 last_click_selected_read = false;
00085 last_click_changed_selection = false;
00086 time_course = false;
00087 tc_normalize = false;
00088
00089 setFocusPolicy(StrongFocus);
00090
00091 if ( _viewMode.isNull() )
00092 {
00093 _viewMode = "closeup";
00094 }
00095
00096 viewModes = new ViewModes( _viewMode, doc );
00097
00098
00099 list<string> type_list = GeneralMaker::listRegistered();
00100 for( list<string>::iterator it = type_list.begin(); it != type_list.end(); ++it ) {
00101 zoom_cutoff[ *it ] = 0;
00102 }
00103 zoom_cutoff["DnaStrData"] = 4;
00104 zoom_cutoff["QualityData"] = 4;
00105 zoom_cutoff["ChromatData"] = 8;
00106 zoom_cutoff["DnpData"] = 1;
00107
00108 min_cutoff = 0.0009765625;
00109
00110
00111
00112
00113 globalRows = 50;
00114 globalBases = 2000;
00115
00116
00117 rowheight = 5;
00118 basewidth = 1;
00119 magnifyX = 8;
00120 magnifyY = 4;
00121 zoomfactor = 2;
00122 spaceBetweenRows = 0;
00123 center_point = 0;
00124
00125 read_cluster_min_num = 10;
00126 read_cluster_window = 100;
00127
00128
00129 fitContentsizeToData();
00130
00131
00132 viewport()->setPaletteBackgroundColor(white);
00133 viewport()->setBackgroundMode( Qt::FixedColor );
00134 setCaption( "yes" );
00135 viewport()->setMouseTracking(TRUE);
00136 }
00137
00138
00139 TrapperView::~TrapperView()
00140 {
00141
00142 if ( viewModes ) {
00143 delete viewModes;
00144 viewModes = NULL;
00145 }
00146 }
00147
00148 void TrapperView::fitContentsizeToData()
00149 {
00150 Database::SecondaryIterator<ReadData>* end_it = new Database::SecondaryIterator<ReadData>( "end", doc, "ReadData" );
00151 int ret_end = end_it->last();
00152 Database::SecondaryIterator<ReadData>* row_it = new Database::SecondaryIterator<ReadData>( "pos", doc, "ReadData" );
00153 int ret_row = row_it->last();
00154 ReadData* r_end = (ret_end != DB_NOTFOUND) ? end_it->answer() : 0;
00155 ReadData* r_row = (ret_row != DB_NOTFOUND) ? row_it->answer() : 0;
00156 if ( r_end ) {
00157
00158 globalBases = r_end->endPos() + 50;
00159 }
00160 if ( r_row ) {
00161
00162 globalRows = r_row->row() + 500;
00163 }
00164
00165 delete end_it;
00166 delete row_it;
00167
00168 resizeContents(static_cast<int>(globalBases * magnifyX * basewidth), globalRows * rowheight * magnifyY);
00169
00170 }
00171
00172 QString TrapperView::mode()
00173 {
00174 return viewModes->currentViewMode()->name();
00175 }
00176
00177 TrapperDoc *TrapperView::getDocument() const
00178 {
00179 return doc;
00180 }
00181
00182 void TrapperView::update(TrapperView* pSender)
00183 {
00184 if(pSender != this)
00185 repaint();
00186 }
00187
00188 void TrapperView::print(QPrinter *pPrinter)
00189 {
00190 if (pPrinter->setup(this))
00191 {
00192 QPainter p;
00193 p.begin(pPrinter);
00194
00195
00196
00197
00198
00199 p.end();
00200 }
00201 }
00202
00203 void TrapperView::closeEvent(QCloseEvent*)
00204 {
00205
00206
00207 }
00208
00209 void TrapperView::convertToDnaCoordinates( TR_DNA & x_dna, TR_DNA & y_dna, const TR_PIX cx, const TR_PIX cy )
00210 {
00211 x_dna = pixelCoordToDna_X(cx);
00212 y_dna = pixelCoordToDna_Y(cy);
00213 return;
00214 }
00215
00216 TR_DNA TrapperView::pixelCoordToDna_X( TR_PIX cx )
00217 {
00218
00219
00220
00221
00222
00223
00224 return static_cast<TR_DNA>(cx / ( basewidth * magnifyX ));
00225 }
00226
00227 TR_DNA TrapperView::pixelCoordToDna_Y( TR_PIX cy )
00228 {
00229 return cy / ( rowheight * magnifyY );
00230 }
00231
00232 void TrapperView::convertToPixelCoordinates( TR_PIX & x_pix, TR_PIX & y_pix, TR_DNA x_dna, TR_DNA y_dna )
00233 {
00234 x_pix = dnaCoordToPixel_X(x_dna);
00235 y_pix = dnaCoordToPixel_Y(y_dna);
00236 return;
00237 }
00238
00239 TR_PIX TrapperView::dnaCoordToPixel_X( TR_DNA x_dna )
00240 {
00241
00242
00243
00244
00245
00246
00247
00248 return static_cast<TR_PIX>(x_dna * basewidth * magnifyX);
00249 }
00250
00251 TR_PIX TrapperView::dnaCoordToPixel_Y( TR_DNA y_dna )
00252 {
00253 return y_dna * rowheight * magnifyY;
00254 }
00255
00256 void TrapperView::paintFeatures( QPainter* p, QPainter * bitmapPainter, db_recno_t readRecno,
00257 TR_PIX x_pix, TR_PIX y_pix,
00258 TR_DNA x_dna_relative, TR_DNA dna_len ,
00259 double width, TR_PIX height, bool selected, int center_relative,
00260 bool overlap, TR_DNA bg, TR_DNA eg )
00261 {
00262
00263 int pix_len = static_cast<int>(dna_len*width);
00264 if ( pix_len < 1 ) {
00265 pix_len = 1;
00266 }
00267
00268
00269 Layer * layer;
00270
00271 p->setPen( Qt::black );
00272
00273
00274 QBrush brush;
00275 brush.setStyle( Qt::SolidPattern );
00276 brush.setColor( Qt::white );
00277 p->fillRect( x_pix , y_pix , pix_len , height ,brush) ;
00278
00279 brush.setColor( Qt::color1 );
00280
00281 if ( bitmapPainter && selected )
00282 bitmapPainter->fillRect( x_pix , y_pix , pix_len , height ,brush) ;
00283
00284
00285
00286
00287
00288
00289
00290
00291 y_pix += 1;
00292 height -= 2;
00293
00294
00295
00296
00297
00298 if ( !time_course ) {
00299
00300 TR_PIX heightLayerSum = 0;
00301
00302
00303 for (layer = viewModes->currentViewMode()->layerList.first(); layer; layer = viewModes->currentViewMode()->layerList.next() ) {
00304 TR_PIX heightLayer = layer->heightInPix( height );
00305 Database::SecondaryIterator<SpatialFeatureData> * it;
00306 for (it = layer->featureList.first(); it; it = layer->featureList.next() ) {
00307
00308 if ( magnifyX < min_cutoff || magnifyY < min_cutoff ) continue;
00309 int cutoff = zoom_cutoff[ it->name() ];
00310 if ( magnifyX < cutoff || magnifyY < cutoff ) continue;
00311
00312 it->key()->setReadRecno( readRecno );
00313 if ( it->set() == 0 ) {
00314 int ret;
00315 do {
00316
00317
00318 it->answer()->gui()->paint( p, x_pix, y_pix + heightLayerSum , x_dna_relative, x_dna_relative + dna_len -1 , width, heightLayer, center_relative );
00319
00320 } while ( (ret = it->nextdup()) == 0);
00321
00322
00323 }
00324 it->closeCursor();
00325 }
00326 heightLayerSum += heightLayer;
00327 }
00328 }
00329 else {
00330
00331
00332 Database::SecondaryIterator<ReadMetaData> read_meta_it( "readRecno", doc, "ReadMetaData" );
00333
00334 read_meta_it.key()->setReadRecno( readRecno );
00335 assert(read_meta_it.set() == 0 );
00336 if ( read_meta_it.answer()->tc_vec.stlVector().size() != 0 ) {
00337
00338
00339 Database::PrimaryIterator<ReadData> read_it( doc, "ReadData" );
00340 assert( read_it.setFromRecno(readRecno) == 0 );
00341
00342
00343 int tc_len = dnaCoordToPixel_X( read_it.answer()->endPos() - read_it.answer()->startPos() + 1 );
00344 int start_tc_pix = dnaCoordToPixel_X( read_it.answer()->startPos() ) + 1;
00345 int stop_tc_pix = start_tc_pix + tc_len;
00346
00347
00348
00349
00350 int numpoints = read_meta_it.answer()->tc_vec.stlVector().size();
00351 if ( numpoints > 0 ) {
00352
00353
00354 int pix_per_point = tc_len/numpoints;
00355
00356
00357
00358 int start_paint_index = 0;
00359 int stop_paint_index = numpoints;
00360
00361
00362
00363
00364 double max_tc(0.000001);
00365 if ( tc_normalize ) {
00366 bool foundmax(false);
00367 for( size_t i = 0; i < read_meta_it.answer()->tc_vec.stlVector().size(); i++ ) {
00368 if ( read_meta_it.answer()->tc_vec.stlVector()[i] > max_tc ) {
00369 max_tc = read_meta_it.answer()->tc_vec.stlVector()[i];
00370 foundmax = true;
00371 }
00372 }
00373 if ( !foundmax ) {
00374 max_tc = 1;
00375 }
00376 }
00377
00378 QBrush brush;
00379 for( int i = start_paint_index; i < stop_paint_index && i < numpoints; i++ ) {
00380 brush.setStyle( Qt::SolidPattern );
00381 QColor tc_color;
00382 double tc_val = read_meta_it.answer()->tc_vec.stlVector()[i];
00383 if ( ( tc_normalize && tc_val/max_tc < 0.125 ) || ( !tc_normalize && tc_val < 1) ) {
00384 tc_color.setNamedColor("#0000FF");
00385 }
00386 else if ( ( tc_normalize && tc_val/max_tc < 0.250 ) || ( !tc_normalize && tc_val < 2 ) ) {
00387 tc_color.setNamedColor("#00BFFF");
00388 }
00389 else if ( ( tc_normalize && tc_val/max_tc < 0.375 ) || ( !tc_normalize && tc_val < 5 ) ) {
00390 tc_color.setNamedColor("#20B2AA");
00391 }
00392 else if ( ( tc_normalize && tc_val/max_tc < 0.500 ) || ( !tc_normalize && tc_val < 10 ) ) {
00393 tc_color.setNamedColor("#32CD32");
00394 }
00395 else if ( ( tc_normalize && tc_val/max_tc < 0.625 ) || ( !tc_normalize && tc_val < 100 ) ) {
00396 tc_color.setNamedColor("#FFD700");
00397 }
00398 else if ( ( tc_normalize && tc_val/max_tc < 0.750 ) || ( !tc_normalize && tc_val < 500 ) ) {
00399 tc_color.setNamedColor("#FFA500");
00400 }
00401 else if ( ( tc_normalize && tc_val/max_tc < 0.875 ) || ( !tc_normalize && tc_val < 1000 ) ) {
00402 tc_color.setNamedColor("#FF4500");
00403 }
00404 else {
00405 tc_color.setNamedColor("#FF0000");
00406 }
00407
00408 brush.setColor( tc_color );
00409 p->fillRect( start_tc_pix + i* pix_per_point, read_it.answer()->row()*rowheight*magnifyY + 2, pix_per_point, rowheight*magnifyY - spaceBetweenRows - 2,brush) ;
00410
00411 }
00412
00413 }
00414 }
00415
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 QPen oldpen( p->pen() ), newpen( p->pen() );
00436
00437 if ( selected ) {
00438 newpen.setColor( Qt::red );
00439 if ( moving )
00440 newpen.setStyle( Qt::DashLine);
00441 }
00442 if ( overlap ) {
00443 newpen.setColor(Qt::green);
00444 }
00445 p->setPen(newpen);
00446
00447
00448 p->drawRect( x_pix , y_pix, pix_len, height ) ;
00449
00450
00451 brush.setStyle( Qt::Dense4Pattern );
00452 brush.setColor( Qt::white );
00453 if ( x_dna_relative < bg ) {
00454 p->fillRect( x_pix , y_pix, static_cast<int>((bg - x_dna_relative)*width), height, brush ) ;
00455 }
00456 if ( x_dna_relative + dna_len > eg ) {
00457 int goodlen = eg - x_dna_relative + 1;
00458 if ( goodlen < 0 ) goodlen = 0;
00459 p->fillRect( static_cast<int>(x_pix + goodlen*width), y_pix, static_cast<int>((dna_len - goodlen )*width), height, brush ) ;
00460 }
00461
00462 p->setPen( oldpen );
00463
00464
00465
00466
00467 }
00468
00469
00470 void TrapperView::drawContents(QPainter* p, TR_PIX cx, TR_PIX cy, TR_PIX cw, TR_PIX ch)
00471 {
00472
00473
00474
00475
00476 drawContents_helper(p, NULL, cx, cy, cw, ch, 0, 0);
00477 paintGrid( p, cx, cy, cw, ch);
00478 }
00479
00480 void TrapperView::drawContents_helper(QPainter* p,QPainter* bitmapPainter, int cx, int cy, int cw, int ch, int dx, int dy)
00481 {
00482
00483
00484
00485
00486
00487
00488 if ( moving ) {
00489 assert( bitmapPainter == 0 );
00490
00491
00492 p->setRasterOp(NotXorROP);
00493
00494 if ( moveOn ) {
00495 p->drawPixmap(oldMovePoint, dragPixmap);
00496 }
00497 else {
00498 oldMovePoint = contentsToViewport(mousePressedPoint - dragWindowPoint);
00499 p->setRasterOp(NotXorROP);
00500 p->drawPixmap(oldMovePoint, dragPixmap);
00501
00502 }
00503
00504
00505 oldMovePoint = contentsToViewport(mousePressedPoint - dragWindowPoint + QPoint(0, dnaCoordToPixel_Y(pixelCoordToDna_Y(y_delta)) ));
00506
00507
00508 p->drawPixmap(oldMovePoint, dragPixmap);
00509
00510 moveOn = true;
00511 return;
00512
00513 }
00514
00515
00516 TR_DNA x_dna, y_dna;
00517 TR_DNA x2_dna, y2_dna;
00518 TR_DNA h_dna, w_dna;
00519
00520 convertToDnaCoordinates( x_dna, y_dna, cx, cy );
00521 convertToDnaCoordinates( x2_dna, y2_dna, cx + cw - 1, cy + ch - 1 );
00522
00523
00524
00525
00526 x_dna -= 10;
00527 x2_dna += 10;
00528
00529 w_dna = x2_dna - x_dna + 1;
00530 h_dna = y2_dna - y_dna + 1;
00531
00532
00533
00534 TR_PIX x_pix, y_pix;
00535 convertToPixelCoordinates( x_pix, y_pix, x_dna, y_dna );
00536
00537 TR_PIX cx_paint = x_pix + dx;
00538 TR_PIX cy_paint = y_pix + dy;
00539
00540
00541
00542
00543 readsInRect = new ReadsInRect( doc );
00544
00545
00546 readsInRect->setWindowCoord( x_dna, y_dna, w_dna,h_dna );
00547
00548 int previous_row(-1), previous_end(-1);
00549 for ( ReadData * r = readsInRect->first(); r; r = readsInRect->next() ) {
00550
00551
00552 bool overlap(false);
00553 if ( r->row() == previous_row && (r->startPos() <= previous_end ) ) {
00554 overlap = true;
00555 }
00556 previous_row = r->row();
00557 previous_end = r->endPos();
00558
00559 bool selected = isSelected( r->getRecno() );
00560
00561
00562
00563
00564
00565 TR_DNA x1_dna_paint = max( r->startPos(), x_dna ) ;
00566 TR_DNA x2_dna_paint = min( r->endPos(), x_dna + w_dna - 1 ) ;
00567
00568 TR_PIX x_pix_adjust, y_pix_adjust;
00569 convertToPixelCoordinates( x_pix_adjust, y_pix_adjust, x1_dna_paint - x_dna, r->row() - y_dna );
00570
00571
00572
00573
00574 TR_DNA len = x2_dna_paint - x1_dna_paint +1 ;
00575
00576 paintFeatures( p, bitmapPainter, r->getRecno(),
00577 x_pix_adjust + cx_paint, y_pix_adjust + cy_paint,
00578 x1_dna_paint - r->startPos(), len,
00579 basewidth*magnifyX, rowheight*magnifyY - spaceBetweenRows , selected, center_point - r->startPos(),
00580 overlap, 0, r->endPos() - r->startPos() );
00581
00582
00583 }
00584
00585
00586 delete readsInRect;
00587
00588
00589
00590
00591 if ( rubber_band ) {
00592 QPen oldpen( p->pen() );
00593 QPen newpen( Qt::black, 0, Qt::DotLine );
00594
00595 p->setPen( newpen );
00596 p->drawRect( *rubber_band );
00597 p->setPen( oldpen );
00598
00599 }
00600
00601 return;
00602
00603
00604 }
00605
00606 void TrapperView::paintGrid(QPainter* p, TR_PIX cx, TR_PIX cy, TR_PIX cw, TR_PIX ch)
00607 {
00608 p->setPen( Qt::black );
00609
00610 int local_rowheight = 100;
00611 int toprow=cy/local_rowheight;
00612 int bottomrow=(cy+ch+local_rowheight-1)/local_rowheight;
00613 int colwidth=100;
00614 int leftcol=cx/colwidth;
00615 int rightcol=(cx+cw+colwidth-1)/colwidth;
00616
00617
00618 QFont f;
00619 f.setPointSize(10);
00620 p->setFont(f);
00621 int viewport_toprow=contentsY()/local_rowheight - 2;
00622 if (viewport_toprow <0 ) viewport_toprow = 0;
00623
00624 int viewport_bottomrow=(cy+ch+local_rowheight-1)/local_rowheight + 1;
00625 for( int i = leftcol; i <= rightcol; i++ ) {
00626 p->drawText( i*colwidth + dnaCoordToPixel_X(1)/2, 10, QString().setNum(pixelCoordToDna_X( i*colwidth )) );
00627 }
00628 for( int i = viewport_toprow; i < viewport_bottomrow; i++ ) {
00629 p->drawText( 0, i*local_rowheight, QString().setNum(pixelCoordToDna_Y( i*local_rowheight )) );
00630 }
00631
00632 return;
00633
00634
00635
00636 for (int r=toprow; r<=bottomrow; r++) {
00637 int py=r*local_rowheight - dnaCoordToPixel_Y(1)/2;
00638 for (int c=leftcol; c<=rightcol; c++) {
00639 int px=c*colwidth + dnaCoordToPixel_X(1)/2;
00640 p->drawLine(px, py, px+2, py);
00641
00642 }
00643 }
00644
00645
00646
00647 bottomrow=(cy+ch+rowheight-1)/rowheight;
00648 int center_x = dnaCoordToPixel_X(center_point) + dnaCoordToPixel_X(1)/2;
00649 p->drawLine(center_x, 0, center_x, bottomrow*rowheight );
00650
00651 }
00652
00653 void TrapperView::moveData(TR_PIX dx, TR_PIX dy)
00654 {
00655
00656 TR_DNA col_delta, row_delta;
00657 row_delta = pixelCoordToDna_Y( dy );
00658 col_delta = pixelCoordToDna_X( dx);
00659
00660 AlgoMoveParam param( col_delta, row_delta );
00661
00662 runAlgo( "Move Reads", getSelectedReads(), ¶m );
00663
00664 last_move_x = param.get_x_delta();
00665 last_move_y = param.get_y_delta();
00666
00667
00668 }
00669
00670 void TrapperView::clearLastMove()
00671 {
00672 last_move_x = last_move_y = 0;
00673 }
00674
00675
00676 void TrapperView::contentsMousePressEvent(QMouseEvent* e)
00677 {
00678 setFocus();
00679
00680 QString msg = "Row: " + QString().setNum(pixelCoordToDna_Y(e->y())) + ", col: " + QString().setNum(pixelCoordToDna_X(e->x()));
00681 sendMsg( msg );
00682
00683 y_delta = 0;
00684 y_delta_previous = 0;
00685
00686 bool ctrlclick = Qt::ControlButton & e->state();
00687 bool leftbutton = Qt::LeftButton & e->stateAfter();
00688
00689 if ( ctrlclick ) {
00690 ctrl = true;
00691 }
00692 else {
00693 ctrl = false;
00694 }
00695
00696
00697
00698
00699
00700 mousePressedPoint.setX( e->x() );
00701 mousePressedPoint.setY( e->y() );
00702
00703
00704
00705 RubberStart=contentsToViewport(e->pos());
00706 RubberEnd = RubberStart;
00707 RubberOn=FALSE;
00708
00709
00710
00711 moveOn = false;
00712
00713
00714 TR_DNA x_dna, y_dna;
00715 convertToDnaCoordinates( x_dna, y_dna, e->x(), e->y() );
00716
00717 readsInRect = new ReadsInRect( doc );
00718
00719 readsInRect->setWindowCoord( x_dna, y_dna, 3, 3 );
00720 ReadData * r = readsInRect->first();
00721 if ( r ) {
00722 if ( ctrlclick ) {
00723 if ( isSelected( r->getRecno() ) ) {
00724 select( r->getRecno(), false );
00725 last_click_selected_read = false;
00726 last_click_changed_selection = true;
00727 }
00728 else {
00729 select( r->getRecno(), true);
00730 last_click_selected_read = true;
00731 last_selected_recno = r->getRecno();
00732 last_click_changed_selection = true;
00733 }
00734 }
00735 else {
00736 if ( isSelected( r->getRecno() ) ) {
00737 last_click_selected_read = true;
00738 last_selected_recno = r->getRecno();
00739 last_click_changed_selection = false;
00740 }
00741 else {
00742 clearSelected();
00743 select( r->getRecno(), true);
00744 last_click_selected_read = true;
00745 last_selected_recno = r->getRecno();
00746 last_click_changed_selection = true;
00747 }
00748
00749 }
00750 if ( last_click_selected_read )
00751 dragging = TRUE;
00752 }
00753 else {
00754
00755
00756
00757
00758 if ( ctrlclick ) {
00759 last_click_selected_read = false;
00760 last_click_changed_selection = false;
00761 }
00762 else {
00763 last_click_selected_read = false;
00764 if ( selectedReads.size() > 0 )
00765 last_click_changed_selection = true;
00766
00767 clearSelected();
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777 }
00778 if ( rubber_band != 0 ) {
00779 delete rubber_band;
00780 }
00781 if (leftbutton && !last_click_selected_read) {
00782 moving = false;
00783 rubber_band = new QRect( mousePressedPoint, mousePressedPoint );
00784 }
00785
00786 }
00787
00788
00789 delete readsInRect;
00790
00791
00792 if ( last_click_selected_read )
00793 {
00794 cerr<<"filling pixmap..."<<endl;
00795 dragWindowPoint.setX( size().width() );
00796 dragWindowPoint.setY( size().height() );
00797 QRect re( mousePressedPoint - dragWindowPoint, mousePressedPoint + dragWindowPoint );
00798
00799
00800 dragPixmap.resize( re.size() );
00801 QPainter p2;
00802 p2.begin(&dragPixmap, this);
00803 dragBitmap.resize( re.size() );
00804 p3.begin(&dragBitmap, this);
00805 QBrush brush;
00806 brush.setStyle( Qt::SolidPattern );
00807 brush.setColor( Qt::white );
00808 p2.fillRect( 0 , 0 , re.width() , re.height() ,brush) ;
00809 brush.setColor( Qt::color0 );
00810
00811 p3.fillRect( 0 , 0 , re.width() , re.height() ,brush) ;
00812
00813 QPoint tl = re.topLeft() ;
00814 QPoint br = re.bottomRight() ;
00815
00816 drawContents_helper(&p2, &p3, tl.x(), tl.y(), br.x() - tl.x() + 1, br.y() - tl.y() + 1,
00817 - ( mousePressedPoint.x() - dragWindowPoint.x() ), - ( mousePressedPoint.y() - dragWindowPoint.y() ));
00818
00819 dragPixmap.setMask(dragBitmap);
00820
00821 p2.end();
00822 p3.end();
00823 }
00824 }
00825
00826
00827 void TrapperView::contentsMouseMoveEvent(QMouseEvent* e)
00828 {
00829 QString msg = "Row: " + QString().setNum(pixelCoordToDna_Y(e->y())) + ", col: " + QString().setNum(pixelCoordToDna_X(e->x()));
00830 sendMsg( msg );
00831
00832 bool nobutton = Qt::NoButton & e->state();
00833
00834 if ( nobutton ) {
00835 moving = false;
00836 return;
00837 }
00838
00839
00840
00841 if ( allow_dragging && dragging ) {
00842
00843
00844
00845
00846 ReadDrag *d = new ReadDrag( dragPixmap, dragWindowPoint, this );
00847
00848 QByteArray ar;
00849 QDataStream data_stream(ar, IO_WriteOnly);
00850 writeSelected(data_stream);
00851
00852 d->setEncodedData(ar);
00853 d->dragCopy();
00854 dragging = FALSE;
00855 moving = false;
00856 last_click_selected_read = false;
00857
00858 }
00859 else if ( last_click_selected_read ) {
00860
00861
00862 moving = true;
00863
00864 curr_mouse_pos = e->pos();
00865
00866 y_delta = (curr_mouse_pos - mousePressedPoint).y();
00867
00868 if ( pixelCoordToDna_Y( y_delta) == pixelCoordToDna_Y( y_delta_previous ) ) {
00869
00870 return;
00871 }
00872
00873 y_delta_previous = y_delta;
00874
00875
00876
00877 QPainter p(viewport());
00878 drawContents_helper(&p, 0,0,0,0,0,0,0);
00879 return;
00880
00881
00882 updateContents();
00883 }
00884 else if ( rubber_band != 0 ) {
00885
00886
00887 QPainter p(viewport());
00888 p.setPen(QColor(255,255,255));
00889 p.setRasterOp(NotROP);
00890 if(RubberOn) drawRubber(&p);
00891 RubberEnd= contentsToViewport(e->pos());
00892 drawRubber(&p);
00893 RubberOn=TRUE;
00894 return;
00895
00896
00897 curr_mouse_pos = e->pos();
00898
00899 QRect oldband = rubber_band->normalize();
00900
00901 rubber_band->setSize( QSize( curr_mouse_pos.x() - mousePressedPoint.x(),
00902 curr_mouse_pos.y() - mousePressedPoint.y() ) );
00903
00904
00905 QPoint margin( 1, 1 );
00906 QRect norm = rubber_band->normalize();
00907
00908 updateContents( QRect( norm.topLeft() - margin, norm.bottomRight() + margin ).unite( QRect(oldband.topLeft() - margin, oldband.bottomRight() + margin ) ) );
00909 }
00910
00911 }
00912
00913 void TrapperView::contentsMouseReleaseEvent(QMouseEvent* e)
00914 {
00915 dragging = false;
00916
00917
00918 if ( moving ) {
00919
00920 moveData(0, y_delta);
00921
00922
00923
00924
00925 if(moveOn)
00926 {
00927 updateContents();
00928 moveOn=FALSE;
00929 }
00930
00931
00932 moving = false;
00933 }
00934 else {
00935
00936 bool ctrlclick = Qt::ControlButton & e->state();
00937
00938 if ( !ctrlclick && last_click_selected_read ) {
00939 clearSelected();
00940 select( last_selected_recno, true );
00941 last_click_changed_selection = true;
00942
00943 }
00944
00945
00946
00947
00948
00949 if ( rubber_band != 0 ) {
00950
00951 readsInRect = new ReadsInRect( doc );
00952
00953 TR_DNA x_dna, y_dna, w_dna, h_dna, x2_dna, y2_dna;
00954 TR_PIX x_pix, y_pix, w_pix, h_pix;
00955
00956 QRect norm = rubber_band->normalize();
00957
00958 RubberStart = viewportToContents( RubberStart );
00959 RubberEnd = viewportToContents( RubberEnd );
00960
00961 norm = QRect(
00962 RubberStart.x(),
00963 RubberStart.y(),
00964 RubberEnd.x()-RubberStart.x(),
00965 RubberEnd.y()-RubberStart.y()
00966 ).normalize();
00967
00968
00969 rubber_band->setTopLeft( norm.topLeft() );
00970 rubber_band->setBottomRight( norm.bottomRight() );
00971
00972 rubber_band->rect( &x_pix, &y_pix, &w_pix, &h_pix);
00973 convertToDnaCoordinates( x_dna, y_dna, x_pix, y_pix );
00974 convertToDnaCoordinates( x2_dna, y2_dna, x_pix + w_pix, y_pix + h_pix);
00975
00976 w_dna = x2_dna - x_dna;
00977 h_dna = y2_dna - y_dna;
00978
00979
00980 readsInRect->setWindowCoord( x_dna, y_dna, w_dna,h_dna );
00981 if ( !ctrlclick)
00982 clearSelected();
00983
00984 for ( ReadData * r = readsInRect->first(); r; r = readsInRect->next() ) {
00985 last_click_changed_selection = true;
00986 select( r->getRecno(), true);
00987 }
00988
00989 QPainter p(viewport());
00990 p.setPen(QColor(255,255,255));
00991 p.setRasterOp(NotROP);
00992 if(RubberOn)
00993 {
00994 drawRubber(&p);
00995 RubberOn=FALSE;
00996 }
00997 else
00998 {
00999 RubberEnd=RubberStart;
01000 }
01001
01002
01003 delete rubber_band;
01004 rubber_band = 0;
01005 delete readsInRect;
01006
01007 }
01008
01009 }
01010 if ( last_click_changed_selection ) {
01011 updateContents();
01012 }
01013
01014 moving = false;
01015 dragging = false;
01016 last_click_changed_selection = false;
01017 last_click_selected_read = false;
01018
01019 }
01020
01021 void TrapperView::contentsContextMenuEvent( QContextMenuEvent * e )
01022 {
01023 if ( last_click_changed_selection ) {
01024 updateContents();
01025 }
01026 moving = false;
01027 dragging = false;
01028 last_click_selected_read = false;
01029 last_click_changed_selection = false;
01030
01031 QPopupMenu* contextMenu = new QPopupMenu( this );
01032 Q_CHECK_PTR( contextMenu );
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042 algoMenu = new QPopupMenu( this );
01043 Q_CHECK_PTR( algoMenu );
01044 list<string> algos = AlgoMaker::algosRegistered();
01045 list<string>::iterator stIt;
01046
01047 for (stIt = algos.begin() ; stIt != algos.end(); ++stIt )
01048 {
01049 algoMenu->insertItem ( stIt->c_str() );
01050 }
01051 connect( algoMenu, SIGNAL( activated( int ) ),
01052 this, SLOT( slotStartAlgo( int ) ) );
01053 contextMenu->insertItem( "&Operations", algoMenu );
01054
01055
01056
01057
01058 infoMenu = new QPopupMenu(this);
01059
01060 vector<list<string> > infos = getInfo( e->pos() );
01061 QPtrList<QPopupMenu> infolist;
01062 infolist.setAutoDelete( true );
01063
01064 for( size_t i = 0; i < infos.size(); i++ ) {
01065 stIt = infos[i].begin();
01066 if ( stIt == infos[i].end() ) continue;
01067 infolist.append(new InfoPopup(this));
01068 ++stIt;
01069
01070 for ( ; stIt != infos[i].end(); ++stIt ) {
01071
01072
01073 infolist.last()->insertItem ( stIt->c_str() );
01074 }
01075
01076
01077 infoMenu->insertItem(infos[i].begin()->c_str(), infolist.last());
01078 }
01079
01080
01081
01082 contextMenu->insertItem( "&Info", infoMenu );
01083
01084
01085
01086 switchViewMenu = new QPopupMenu( this );
01087 Q_CHECK_PTR( switchViewMenu );
01088 TrapperConf * conf = TrapperConf::instance();
01089 QStringList names = conf->viewModeNames();
01090
01091 QStringList::Iterator it = names.begin();
01092 for ( ; it != names.end(); ++it )
01093 {
01094 switchViewMenu->insertItem ( *it );
01095 }
01096 connect( switchViewMenu, SIGNAL( activated( int ) ),
01097 this, SLOT( slotSwitchToMode( int ) ) );
01098 contextMenu->insertItem( "&Switch to viewmode", switchViewMenu );
01099
01100
01101 contextMenu->insertSeparator();
01102 contextSelectMenu = new QPopupMenu( this );
01103 Q_CHECK_PTR( contextSelectMenu );
01104
01105 contextSelectMenu->insertItem("above");
01106 contextSelectMenu->insertItem("below");
01107 contextSelectMenu->insertItem("left");
01108 contextSelectMenu->insertItem("right");
01109 connect( contextSelectMenu, SIGNAL( activated( int ) ),
01110 this, SLOT( slotContextSelect( int ) ) );
01111 contextMenu->insertItem( "&Select all", contextSelectMenu );
01112
01113
01114
01115
01116
01117
01118 contextMenu->insertSeparator();
01119 contextMenu->insertItem("Scroll Here", this, SLOT(slotScrollToMouse()) );
01120 contextMenu->insertItem("Scroll to pos", this, SLOT(slotScrollToPos()) );
01121
01122 contextMenu->exec( QCursor::pos() );
01123 delete contextMenu;
01124 delete switchViewMenu;
01125 delete algoMenu;
01126 delete infoMenu;
01127 delete contextSelectMenu;
01128 }
01129
01130 void TrapperView::slotSwitchToMode( int i )
01131 {
01132 QString viewMode = switchViewMenu->text(i);
01133 viewModes->setMode( viewMode );
01134 doc->changedViewList();
01135 updateContents();
01136 }
01137
01138 void TrapperView::slotStartAlgo( int i )
01139 {
01140 QString algoStr = algoMenu->text(i);
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158 ViewParam param(this);
01159
01160 updateContents();
01161 runAlgo( algoStr.ascii(), getSelectedReads(), ¶m );
01162
01163 clearLastMove();
01164 }
01165
01166
01167 void TrapperView::slotScrollToMouse()
01168 {
01169 scrollTo(mousePressedPoint.x(), mousePressedPoint.y());
01170
01171 }
01172
01173 void TrapperView::slotScrollToPos()
01174 {
01175 bool ok;
01176 int res = QInputDialog::getInteger(
01177 "Scroll to position", "Enter row:", 0, 0, numeric_limits<int>::max(), 1,
01178 &ok, 0 );
01179
01180 if ( ok ) {
01181
01182 } else {
01183
01184 return;
01185 }
01186 TR_PIX y = dnaCoordToPixel_Y(res);
01187
01188 res = QInputDialog::getInteger(
01189 "Scroll to position", "Enter column:", 0, 0, numeric_limits<int>::max(), 1,
01190 &ok, 0 );
01191
01192 if ( ok ) {
01193
01194 } else {
01195
01196 return;
01197 }
01198
01199 TR_PIX x = dnaCoordToPixel_X(res);
01200
01201 scrollTo(x, y);
01202
01203 }
01204
01205 void TrapperView::slotSetCenter()
01206 {
01207 center_point = mousePressedCol();
01208
01209 updateContents();
01210 }
01211
01212 void TrapperView::slotClearCenter()
01213 {
01214 center_point = 0;
01215 updateContents();
01216 }
01217
01218 void TrapperView::slotContextSelect(int i)
01219 {
01220 QString direction = contextSelectMenu->text(i);
01221 int start, stop;
01222
01223 if ( direction == "above" || direction == "below") {
01224 if ( direction == "above" ){
01225 start = 0;
01226 stop = mousePressedRow();
01227 }
01228 else {
01229 start = mousePressedRow();
01230 stop = globalRows;
01231 }
01232 selectRows(start, stop);
01233 }
01234 else {
01235 assert(direction == "left" || direction == "right");
01236 if ( direction == "left" ){
01237 start = 0;
01238 stop = mousePressedCol();
01239 }
01240 else {
01241 start = mousePressedCol();
01242 stop = globalBases;
01243 }
01244 selectCols(start, stop);
01245 }
01246
01247
01248 }
01249
01250 void TrapperView::findRead()
01251 {
01252 bool ok;
01253 QString res = QInputDialog::getText ( "Find read", "Enter read name:", QLineEdit::Normal, QString::null, &ok );
01254
01255
01256 if ( ok ) {
01257
01258 } else {
01259
01260 return;
01261 }
01262
01263 Database::SecondaryIterator<ReadMetaData> name_it( "name", doc, "ReadMetaData" );
01264 name_it.key()->setName( res );
01265 if ( name_it.setRange() != 0 ) {
01266 cerr<<"Error, couldn't find "<<res<<" in db"<<endl;
01267 return;
01268 }
01269 clearSelected();
01270
01271 do {
01272 select(name_it.answer()->readRecno(), true);
01273 } while ( name_it.next() == 0 && name_it.answer()->name().find(res.ascii()) < name_it.answer()->name().size() );
01274
01275
01276 updateContents();
01277
01278
01279
01280
01281
01282
01283 }
01284
01285 void TrapperView::findTag()
01286 {
01287 bool ok;
01288 QString res = QInputDialog::getText ( "Find tag", "Enter tag name:", QLineEdit::Normal, QString::null, &ok );
01289
01290
01291 if ( ok ) {
01292
01293 } else {
01294
01295 return;
01296 }
01297
01298 Database::SecondaryIterator<TagData> info_it( "info", doc, "TagData" );
01299 info_it.key()->setInfo( res );
01300 if ( info_it.setRange() != 0 ) {
01301 cerr<<"Error, couldn't find "<<res<<" in db"<<endl;
01302 return;
01303 }
01304 clearSelected();
01305
01306 do {
01307 select(info_it.answer()->readRecno(), true);
01308 } while ( info_it.next() == 0 && info_it.answer()->getInfo().find(res.ascii()) < info_it.answer()->getInfo().size() );
01309
01310
01311 updateContents();
01312
01313
01314
01315
01316
01317
01318 }
01319
01320
01321 std::set<db_recno_t>& TrapperView::getSelectedReads()
01322 {
01323 return selectedReads;
01324 }
01325
01326 void TrapperView::select( db_recno_t recno, bool status )
01327 {
01328 RecnoMap::iterator pos;
01329 if ( status == true && !isSelected(recno) ) {
01330 selectedReads.insert( recno );
01331 clearLastMove();
01332 }
01333 else if ( ( pos = selectedReads.find( recno )) != selectedReads.end() ) {
01334 selectedReads.erase( pos );
01335 clearLastMove();
01336 }
01337
01338 }
01339
01340 bool TrapperView::isSelected( db_recno_t recno )
01341 {
01342 return selectedReads.find( recno ) != selectedReads.end();
01343 }
01344
01345 void TrapperView::clearSelected()
01346 {
01347 selectedReads.clear();
01348 clearLastMove();
01349 }
01350
01351 std::vector<std::list<std::string > > TrapperView::getInfo( const QPoint& pos )
01352 {
01353 vector<list<string> > result;
01354 list<string> readResult;
01355 list<string> featResult;
01356 list<string> generalResult;
01357
01358
01359 TR_DNA row = pixelCoordToDna_Y( pos.y() );
01360 TR_DNA col = pixelCoordToDna_X( pos.x() );
01361
01362 readsInRect = new ReadsInRect( doc );
01363 readsInRect->setWindowCoord( col, row, 1, 1 );
01364
01365 ReadData * r = readsInRect->first();
01366
01367 ostringstream os;
01368 if ( r ) {
01369 Database::SecondaryIterator<ReadMetaData> read_m_it( "readRecno", doc, "ReadMetaData" );
01370
01371 read_m_it.key()->setReadRecno( r->getRecno() );
01372
01373 assert(read_m_it.set() == 0);
01374
01375
01376 list<string> types = GeneralMaker::listRegistered();
01377 readResult.push_back( "Read info" );
01378 readResult.push_back( read_m_it.answer()->name() );
01379
01380 os<<"TC:";
01381 for( size_t i = 0; i < read_m_it.answer()->tc_vec.stlVector().size(); i++ ) {
01382 os<<' '<<read_m_it.answer()->tc_vec.stlVector()[i];
01383 }
01384 readResult.push_back( os.str() );
01385
01386 os.str("");
01387 os<<"Strand: "<<read_m_it.answer()->strand();
01388 readResult.push_back( os.str() );
01389 os.str("");
01390 os<<"Mate: "<<read_m_it.answer()->mate() << ' ' << read_m_it.answer()->mateLength();
01391 readResult.push_back( os.str() );
01392 os.str("");
01393 os<<"Begin good: "<<read_m_it.answer()->beginGood();
01394 readResult.push_back( os.str() );
01395 os.str("");
01396 os<<"End good: "<<read_m_it.answer()->endGood();
01397 readResult.push_back( os.str() );
01398 os.str("");
01399 os<<"Read index: "<<col - r->startPos();
01400 readResult.push_back( os.str() );
01401
01402
01403 featResult.push_back( "Feature info" );
01404
01405
01406 for( list<string>::iterator it = types.begin(); it != types.end(); ++it ) {
01407 GeneralData * data = GeneralMaker::newData( *it );
01408 SpatialFeatureData * fdata = dynamic_cast<SpatialFeatureData *>( data );
01409
01410
01411 if ( fdata ) {
01412 Database::SecondaryIterator<SpatialFeatureData> featIt( "readRecno", doc, it->c_str() );
01413
01414 featIt.key()->setReadRecno( r->getRecno() );
01415
01416 string featInfo;
01417
01418 if ( featIt.set() == 0 ) {
01419
01420 int ret;
01421 do {
01422
01423 featInfo = featIt.answer()->info()->getPosInfo( col - r->startPos() );
01424 if ( !featInfo.empty() ) {
01425 featResult.push_back( featInfo );
01426 }
01427 featInfo = featIt.answer()->info()->getRangeInfo( 0, r->endPos() - r->startPos() );
01428 if ( !featInfo.empty() ) {
01429 readResult.push_back( featInfo );
01430 }
01431
01432
01433 } while ( (ret = featIt.nextdup()) == 0);
01434 }
01435 }
01436
01437 delete data;
01438
01439 }
01440
01441
01442
01443 }
01444 generalResult.push_back("General info");
01445 os.str("");
01446 os<<"Row: "<<row<<", Col: "<<col;
01447 generalResult.push_back( os.str() );
01448
01449 result.push_back(readResult);
01450 result.push_back(featResult);
01451 result.push_back(generalResult);
01452
01453 delete readsInRect;
01454 return result;
01455 }
01456
01457 void TrapperView::runAlgo( const std::string& AlgoType, std::set< db_recno_t >& recnoList, AlgoParam* param )
01458 {
01459
01460 if (selectedReads.size() > 0 ) {
01461
01462 Algo * algo = AlgoMaker::newAlgo( AlgoType, doc , recnoList, param );
01463 doc->addAlgorithm( algo );
01464 algo->start();
01465 doc->removeAlgorithm( algo );
01466 delete algo;
01467
01468 updateContents();
01469 fitContentsizeToData();
01470 }
01471
01472 }
01473
01474 void TrapperView::zoomIn()
01475 {
01476 zoomInX();
01477 zoomInY();
01478 }
01479
01480 void TrapperView::zoomInX()
01481 {
01482 if ( magnifyX >= 128 ) {
01483 return;
01484 }
01485
01486
01487 magnifyX *= zoomfactor;
01488 if ( static_cast<int>(globalBases * magnifyX * basewidth) < 0 ) {
01489 magnifyX /= zoomfactor;
01490 return;
01491 }
01492
01493
01494
01495
01496 QPoint p = viewportToContents(viewport()->rect().topLeft()) + QPoint(visibleWidth()/2, 0);
01497
01498 resizeContents(static_cast<int>(globalBases * magnifyX * basewidth), globalRows * rowheight * magnifyY);
01499
01500 setContentsPos(p.x()*zoomfactor - visibleWidth()/2, p.y());
01501
01502
01503
01504 }
01505
01506 void TrapperView::zoomInY()
01507 {
01508 if ( magnifyY >= 8 )
01509 return;
01510 magnifyY *= zoomfactor;
01511
01512
01513 QPoint p = viewportToContents(viewport()->rect().topLeft());
01514
01515 resizeContents(static_cast<int>(globalBases * magnifyX * basewidth), globalRows * rowheight * magnifyY);
01516 setContentsPos(p.x(), p.y()*zoomfactor);
01517
01518 updateContents();
01519 }
01520
01521 void TrapperView::zoomOut()
01522 {
01523 zoomOutX();
01524 zoomOutY();
01525 }
01526
01527 void TrapperView::zoomOutX()
01528 {
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539 if ( magnifyX <= 7.62939453125e-06 ) {
01540 return;
01541 }
01542 magnifyX /= zoomfactor;
01543
01544
01545 QPoint p = viewportToContents(viewport()->rect().topLeft()) + QPoint(visibleWidth()/2, 0);
01546
01547
01548
01549
01550
01551 resizeContents(static_cast<int>(globalBases * magnifyX * basewidth), globalRows * rowheight * magnifyY);
01552 setContentsPos(p.x()/zoomfactor - visibleWidth()/2, p.y());
01553
01554 updateContents();
01555 }
01556
01557 void TrapperView::zoomOutY()
01558 {
01559 if ( magnifyY <= 1 )
01560 {
01561 return;
01562 }
01563 magnifyY /= zoomfactor;
01564
01565
01566 QPoint p = viewportToContents(viewport()->rect().topLeft());
01567 resizeContents(static_cast<int>(globalBases * magnifyX * basewidth), globalRows * rowheight * magnifyY);
01568 setContentsPos(p.x(), p.y()/zoomfactor);
01569
01570 updateContents();
01571 }
01572
01573 void TrapperView::doZoom()
01574 {
01575
01576
01577
01578
01579
01580
01581 resizeContents(static_cast<int>(globalBases * magnifyX * basewidth), globalRows * rowheight * magnifyY);
01582
01583
01584
01585
01586 updateContents();
01587
01588 }
01589
01590 void TrapperView::scrollTo(TR_PIX x, TR_PIX y)
01591 {
01592 setContentsPos( x, y );
01593
01594
01595 }
01596
01597
01598 void TrapperView::enlarge()
01599 {
01600 globalRows *= 2;
01601 globalBases = static_cast<int32_t>(globalBases * 1.25);
01602 resizeContents(static_cast<int>(globalBases * magnifyX * basewidth), globalRows * rowheight * magnifyY);
01603 updateContents();
01604 }
01605
01606 void TrapperView::shrink()
01607 {
01608 globalRows = static_cast<int32_t>(globalRows * 0.5);
01609 globalBases = static_cast<int32_t>(globalBases * 0.8);
01610 resizeContents(static_cast<int>(globalBases * magnifyX * basewidth), globalRows * rowheight * magnifyY);
01611 updateContents();
01612 }
01613
01614
01615 void TrapperView::selectAll()
01616 {
01617 clearSelected();
01618 Database::PrimaryIterator<ReadData> iter( doc, "ReadData" );
01619
01620 if ( iter.first() == 0 ) {
01621
01622 do {
01623 select( iter.answer()->getRecno(), true );
01624
01625 } while ( iter.next() == 0 );
01626
01627 }
01628 updateContents();
01629
01630 }
01631
01632 void TrapperView::selectBetween()
01633 {
01634 bool ok;
01635 TR_DNA start, stop;
01636 int res = QInputDialog::getInteger("Select between rows", "Enter start row for selected reads:", 0, 1, numeric_limits<int>::max(), 1,
01637 &ok, 0 );
01638 if ( ok ) {
01639 start = res;
01640 }
01641 else {
01642 return;
01643 }
01644
01645 res = QInputDialog::getInteger("Select between rows",
01646 "Enter stop row for selected reads:",
01647 0, 1, numeric_limits<int>::max(), 1,
01648 &ok, 0 );
01649 if ( ok ) {
01650 stop = res;
01651 if ( start > stop ) {
01652 TR_DNA tmp = start;
01653 start = stop;
01654 stop = tmp;
01655 }
01656 }
01657 else {
01658 return;
01659 }
01660 selectRows(start, stop);
01661
01662 }
01663
01664 void TrapperView::selectRows(int start, int stop)
01665 {
01666 if ( !ctrl )
01667 clearSelected();
01668
01669 Database::SecondaryIterator<ReadData> row_it( "pos", doc, "ReadData" );
01670 row_it.key()->setRow(start);
01671 row_it.key()->setStartPos(0);
01672
01673 if ( row_it.setRange() != 0 ) {
01674
01675 return;
01676 }
01677
01678 do {
01679 select( row_it.answer()->getRecno(), true );
01680 }while( row_it.next() == 0 && row_it.answer()->row() <= stop );
01681
01682 updateContents();
01683
01684 }
01685
01686
01687 void TrapperView::selectBetweenCols()
01688 {
01689 bool ok;
01690 TR_DNA start, stop;
01691 int res = QInputDialog::getInteger("Select between cols", "Enter start col for selected reads:", 0, 1, numeric_limits<int>::max(), 1,
01692 &ok, 0 );
01693 if ( ok ) {
01694 start = res;
01695 }
01696 else {
01697 return;
01698 }
01699
01700 res = QInputDialog::getInteger("Select between cols",
01701 "Enter stop col for selected reads:",
01702 0, 1, numeric_limits<int>::max(), 1,
01703 &ok, 0 );
01704 if ( ok ) {
01705 stop = res;
01706 if ( start > stop ) {
01707 TR_DNA tmp = start;
01708 start = stop;
01709 stop = tmp;
01710 }
01711 }
01712 else {
01713 return;
01714 }
01715
01716 selectCols(start, stop);
01717 }
01718
01719 void TrapperView::selectCols(int start, int stop)
01720 {
01721 if ( !ctrl )
01722 clearSelected();
01723
01724 Database::SecondaryIterator<ReadData> row_it( "end", doc, "ReadData" );
01725 row_it.key()->setRow(0);
01726 row_it.key()->setEndPos(start);
01727
01728 if ( row_it.setRange() != 0 ) {
01729
01730 return;
01731 }
01732
01733 do {
01734 if ( row_it.answer()->startPos() >= start ) {
01735 select( row_it.answer()->getRecno(), true );
01736 }
01737 }while( row_it.next() == 0 && row_it.answer()->endPos() <= stop );
01738
01739 updateContents();
01740
01741 }
01742
01743
01744 void TrapperView::contentsDragEnterEvent(QDragEnterEvent* event)
01745 {
01746 event->accept( TRUE );
01747 }
01748
01749 void TrapperView::contentsDragMoveEvent ( QDragMoveEvent* e )
01750 {
01751
01752
01753
01754
01755
01756
01757
01758 }
01759
01760 void TrapperView::contentsDropEvent(QDropEvent* event)
01761 {
01762
01763
01764 QPoint deltaMovement = event->pos() - mousePressedPoint;
01765 TR_DNA x_dna_movDelta;
01766 TR_DNA y_dna_movDelta;
01767
01768 convertToDnaCoordinates( x_dna_movDelta, y_dna_movDelta, deltaMovement.x(), deltaMovement.y() );
01769
01770
01771 TrapperView* w = dynamic_cast<TrapperView*>( event->source() );
01772
01773 if ( !w) {
01774
01775 return;
01776 }
01777
01778
01779 assert(w);
01780
01781 if ( w->getDocument() == this->getDocument() ) {
01782
01783 moveData( deltaMovement.x(), deltaMovement.y() );
01784 }
01785 else {
01786 QByteArray ar( event->encodedData("min_mime_type") );
01787 QDataStream data_stream(ar, IO_ReadOnly);
01788
01789 readSelected(data_stream);
01790 updateContents();
01791 }
01792
01793
01794 }
01795
01796 void TrapperView::writeSelected(QDataStream& data_stream)
01797 {
01798
01799
01800
01801
01802
01803 list<string> type_list = GeneralMaker::listRegistered();
01804
01805
01806
01807 for( set<db_recno_t>::iterator recno_it = selectedReads.begin(); recno_it != selectedReads.end(); ++recno_it ) {
01808
01809 db_recno_t recno(*recno_it);
01810
01811
01812 Database::PrimaryIterator<ReadData>* read_it = new Database::PrimaryIterator<ReadData>(doc, "ReadData");
01813
01814
01815 read_it->setFromRecno(recno);
01816
01817
01818 data_stream<<"ReadData";
01819
01820
01821 read_it->answer()->writeStream(data_stream);
01822
01823
01824 delete read_it;
01825
01826
01827 for( list<string>::iterator type_it = type_list.begin(); type_it != type_list.end(); ++type_it ) {
01828
01829 GeneralData * data = GeneralMaker::newData( *type_it );
01830 FeatureData * fdata = dynamic_cast<FeatureData *>( data );
01831
01832
01833 if ( fdata ) {
01834
01835 Database::SecondaryIterator<FeatureData> featIt( "readRecno", doc, type_it->c_str() );
01836
01837
01838 featIt.key()->setReadRecno( recno );
01839
01840 if ( featIt.set() == 0 ) {
01841 int ret;
01842 do {
01843
01844
01845 data_stream<<type_it->c_str();
01846
01847
01848 featIt.answer()->writeStream(data_stream);
01849
01850 } while ((ret = featIt.nextdup())== 0);
01851
01852 }
01853
01854 }
01855
01856 delete data;
01857
01858 }
01859
01860 }
01861
01862 }
01863
01864 void TrapperView::readSelected(QDataStream& data_stream)
01865 {
01866
01867 clearSelected();
01868
01869 db_recno_t recno(0);
01870
01871
01872
01873 TR_DNA rowmin(numeric_limits<TR_DNA>::max());
01874 TR_DNA colmin(numeric_limits<TR_DNA>::max());
01875
01876 while ( !data_stream.atEnd() ) {
01877
01878
01879 char* data_type;
01880
01881 data_stream>>data_type;
01882
01883 string type(data_type);
01884
01885
01886 Database::Creator<GeneralData> a_creator(doc, type);
01887
01888
01889 a_creator.data()->readStream(data_stream);
01890
01891 if ( ReadData* data = dynamic_cast<ReadData*>(a_creator.data())) {
01892
01893
01894 recno = a_creator.create(false);
01895 select(recno, true);
01896 if ( data->row() < rowmin ) {
01897 rowmin = data->row();
01898 }
01899 if ( data->startPos() < colmin ) {
01900 colmin = data->startPos();
01901 }
01902
01903 }
01904 else {
01905
01906 FeatureData* data = dynamic_cast<FeatureData*>(a_creator.data());
01907 assert( data );
01908 assert( recno != 0 );
01909
01910
01911 data->setReadRecno(recno);
01912
01913
01914 a_creator.create(false);
01915 }
01916
01917 delete data_type;
01918 }
01919 fitContentsizeToData();
01920 moveData( -dnaCoordToPixel_X(colmin - 1), -dnaCoordToPixel_Y(rowmin - 1) );
01921 clearLastMove();
01922 }
01923
01924 void TrapperView::setDragMode(bool status)
01925 {
01926 allow_dragging = status;
01927 }
01928
01929 void TrapperView::copy()
01930 {
01931 QByteArray ar;
01932 QDataStream str(ar, IO_WriteOnly);
01933
01934 writeSelected(str);
01935 QClipboard* cb = QApplication::clipboard();
01936 ReadDrag* r = new ReadDrag(this);
01937 r->setEncodedData(ar);
01938 cb->setData(r, QClipboard::Clipboard);
01939
01940 }
01941
01942 void TrapperView::paste()
01943 {
01944
01945 QClipboard* cb = QApplication::clipboard();
01946 QMimeSource* r = cb->data(QClipboard::Clipboard);
01947
01948 QByteArray ar(r->encodedData("min_mime_type"));
01949 QDataStream str(ar, IO_ReadOnly);
01950
01951 readSelected(str);
01952 updateContents();
01953 }
01954
01955 void TrapperView::cut()
01956 {
01957 copy();
01958 Destroyer d(doc);
01959 for( set<db_recno_t>::iterator it = selectedReads.begin(); it != selectedReads.end(); ++it ) {
01960 d.destroy(*it);
01961 }
01962 clearSelected();
01963 updateContents();
01964
01965 }
01966
01967 void TrapperView::undo()
01968 {
01969 moveData( -dnaCoordToPixel_X(last_move_x), -dnaCoordToPixel_Y(last_move_y) );
01970 }
01971
01972 TR_DNA TrapperView::mousePressedRow()
01973 {
01974 return pixelCoordToDna_Y( mousePressedPoint.y() );
01975
01976
01977 }
01978
01979 TR_DNA TrapperView::mousePressedCol()
01980 {
01981 return pixelCoordToDna_X( mousePressedPoint.x() );
01982
01983 }
01984
01985 void TrapperView::sendMsg( const QString& msg)
01986 {
01987 emit message(msg);
01988 }
01989
01990 void TrapperView::setViewTimeCourse(bool toggle)
01991 {
01992 if ( time_course != toggle) {
01993 updateContents();
01994 }
01995 time_course = toggle;
01996 }
01997
01998 void TrapperView::setNormalizeTimeCourse(bool toggle)
01999 {
02000 if ( tc_normalize != toggle) {
02001 updateContents();
02002 }
02003 tc_normalize = toggle;
02004 }
02005
02006 void TrapperView::scrollToNextCluster(bool forward)
02007 {
02008
02009
02010 Database::SecondaryIterator<ReadData> start_it( "start", doc, "ReadData" );
02011
02012 TR_DNA start;
02013 if ( forward ) {
02014 start = pixelCoordToDna_X( contentsX() + visibleWidth()*3/5 ) + 1;
02015 }
02016 else {
02017 start = pixelCoordToDna_X( contentsX() + visibleWidth()*2/5 );
02018 }
02019
02020 while( true ) {
02021
02022 start_it.key()->setStartPos( start );
02023
02024
02025 if ( forward ) {
02026 if ( start_it.setRange() != 0 ){
02027
02028 return;
02029 }
02030
02031 }
02032 else {
02033 if (start_it.setRange() == 0) {
02034 if ( start_it.prev() != 0 ) {
02035 return;
02036 }
02037 }
02038 else {
02039 if (start_it.last() != 0){
02040
02041 }
02042 }
02043 }
02044
02045
02046 start = start_it.answer()->startPos();
02047 TR_DNA stop;
02048 if ( forward ) {
02049 stop = start + read_cluster_window;
02050 }
02051 else {
02052 stop = start - read_cluster_window;
02053 }
02054
02055
02056 size_t num_in_win(0);
02057
02058 do {
02059 num_in_win++;
02060
02061 }while( ( (forward && start_it.next() == 0) || (!forward && start_it.prev() == 0) ) &&
02062 ( (forward && start_it.answer()->startPos() < stop) || (!forward && start_it.answer()->startPos() > stop) ) &&
02063 num_in_win < read_cluster_min_num );
02064
02065 if ( num_in_win == read_cluster_min_num ) {
02066
02067 scrollTo( dnaCoordToPixel_X(start) - visibleWidth()/2, contentsY() );
02068
02069 return;
02070 }
02071 else if ( forward && start_it.answer()->startPos() >= stop ) {
02072 start++;
02073 }
02074 else if ( !forward && start_it.answer()->startPos() <= stop ) {
02075 start--;
02076 }
02077 else {
02078 return;
02079 }
02080
02081
02082 }
02083
02084
02085
02086 }
02087
02088 void TrapperView::setClusterWindow(int window_size)
02089 {
02090 read_cluster_window = window_size;
02091 }
02092
02093
02094 void TrapperView::setClusterMinNum(int num)
02095 {
02096 read_cluster_min_num = num;
02097 }