trapperview.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002  *                                                                             *
00003  *   Copyright (C) 2003  Erik Sjolund,  (<html>Erik Sj&ouml;lund</html>)       *
00004  *                       Center for Genomics and Bioinformatics,               *
00005  *                       Karolinska Institutet,                                *
00006  *                       Stockholm,                                            *
00007  *                       Sweden                                                *
00008  *                                                                             *
00009  *  Author: Erik Sjolund                                                       *
00010  *  Email: erik.sjolund@adivo.se                                               *
00011  *                                                                             *
00012  *******************************************************************************
00013  */
00014 
00015 
00016 #ifndef TRAPPER2VIEW_H
00017 #define TRAPPER2VIEW_H
00018 
00019 // include files for Qt
00020 #include <qpixmap.h>
00021 #include <qpainter.h>
00022 #include <qbitmap.h>
00023 #include <qwidget.h>
00024 #include <qscrollview.h>
00025 #include "trappertypes.h"
00026 #include <list>
00027 #include <db_cxx.h>
00028 #include "readdata.h"
00029 #include "algoparam.h"//NB, should maybe be removed
00030 #include "viewparam.h"//NB, should maybe be removed
00031 #include "readsinrect.h"
00032 #include <set>
00033 #include <map>
00034 #include <vector>
00035 
00036 class QPopupMenu;
00037 class ViewModes;
00038 class TrapperDoc;
00039 class QLabel;
00040 class QString;
00041 #include "generaldata.h"
00042 //class GeneralData::SecondaryIterator;
00043 
00044 #include <iostream>
00045 // using namespace std;
00046 
00047 /** \brief This class gives an iterator interface to the reads that are visible inside a 
00048   * specified window ( a rectangle ) in the dna coordinate system.
00049   * 
00050   * The reads are indexed in a btree where the order of the records is:
00051   *  higher row number is bigger,
00052   *  and if the same row number: higher endPosition of the read is bigger.
00053   *
00054   * Sketch about the interior:
00055   * To find out the visible reads of a window this class starts the search
00056   * in the top left corner of the visible window and search for the next bigger 
00057   * read. If the found read lies outside of the search window we do another search 
00058   * from another row. We make use of the fact that berkeley db has a cursor 
00059   * when we do the searching. So sometimes we just take the next bigger record
00060   * instead of doing a btree search. 
00061   * 
00062   * Important: This indexing and searching relies on the fact that the reads do not overlap. 
00063   * Therefore you must be careful when adding a new read or moving an old read to see
00064   * that the space needed is not used by another read. 
00065   */
00066 
00067 class ReadsInRect;
00068 
00069 
00070 /** @author Source Framework Automatically Generated by KDevelop, (c) The KDevelop Team.
00071   * @version KDevelop version 1.1 code generation
00072   */
00073 
00074 
00075 /** \brief The view to graphically present the reads and their features. 
00076   * The user will mainly interact with this window.
00077   * 
00078   * Functionality given to the user: Scrolling, zooming, drag and drop of the reads to move them around, selecting
00079   * reads and start algorithms.
00080   *
00081   * This software is designed to have totally decoupled view and data classes. The view is stateless
00082   * ( it does not store any data ) and will for every update newly read in all data needed to paint up the view.
00083   *  In other words, the view does not cash anything.
00084   *
00085   * This has some nice implications: 
00086   *  Data algorithm classes will work directly with the data classes and will 
00087   * not be aware of any views. Any number of views can be opened up and they will be independent and will
00088   * not be aware of each other.
00089   *
00090   * For it to be possible to take this design approach the data classes must respond quickly to queries
00091   * because any delay here will make the views appear sluggish. Scrolling will here be the toughest test for
00092   * the speed of the data class queries. Because by scrolling, new data should be painted very fast to
00093   * the view. The user would not like big delays here.
00094   * 
00095   * To make the data class queries very fast, the data is stored in the embedded database Berkeley Db.
00096   * 
00097   * 
00098   * About how the reads and features get shown in TrapperView:
00099   * TrapperView is inherited from QScrollView. QScrollView gives us the scroll bars and also gives convertion methods
00100   * between the coordinate system of the actual window ( the viewport ) and the coordinate system of the
00101   * content window ( the big window the user has to scroll to see all of it ).
00102   * QScrollView gives us the possibility to place out "static" widgets on the content window, and QScrollView would
00103   * then handle the scrolling automatically. But we would like a totally stateless view so we take another approach.
00104   * We reimplement the virtual method drawContents() that is called everytime some part of the window should be painted,
00105   * e.g. when the user has dragged the scrollbars.
00106   * The method drawContents() takes as arguments the "content" pixel coordinates of a rectangle to be painted.
00107   * Some background pixels are painted to enhance the "movement feeling" when scrolling.
00108   * Then drawContents_helper() is called ( which is also is reused when painting reads in a drag & drop ).
00109   * In drawContents_helper() we first convert to DNA coordinates, i.e. the x-axis unit is a nucleotid-base and the y-axis unit
00110   * is a row. We then use the class ReadsInRect that can tell us which reads are visible in our painting rectangle.
00111   * Now paintFeatures() is called for each read. In paintFeatures(), features for the read are painted in different layers inside the
00112   * read rectangle.
00113   */
00114 
00115 class TrapperView : public QScrollView
00116 {
00117     Q_OBJECT
00118 
00119     friend class TrapperDoc;
00120 
00121 public:
00122   /** Constructor for the view
00123    * @param pDoc  your document instance that the view represents. Create a document before calling the constructor
00124    * or connect an already existing document to a new MDI child widget.*/
00125   TrapperView(TrapperDoc* pDoc, QWidget* parent, const char *name, QString _viewMode = QString("everything") );
00126 //   TrapperView(TrapperDoc* pDoc, QWidget* parent, const char *name, QString _viewMode = QString("closeup") );
00127   /** Destructor for the main view */
00128   ~TrapperView();
00129   /** returns a pointer to the document connected to the view*/
00130   TrapperDoc *getDocument() const;
00131   /** gets called to redraw the document contents if it has been modified */
00132   void update(TrapperView* pSender);
00133   /** contains the implementation for printing functionality and gets called by TrapperApp::slotFilePrint() */
00134   void print(QPrinter *pPrinter);
00135   /** the name of the view mode that the TrapperView is using right now */
00136   QString mode();
00137   /** zooms in */
00138   void zoomIn();
00139   /** zooms in X-direction*/
00140   void zoomInX();
00141   /** zooms in Y-direction*/
00142   void zoomInY();
00143   /** zooms out */
00144   void zoomOut();
00145   /** zooms out X-dir*/
00146   void zoomOutX();
00147   /** zooms out Y-dir*/
00148   void zoomOutY();
00149   /** selects all */
00150   void selectAll();
00151   /** selects between rows */
00152   void selectBetween();
00153   /** selects between cols */
00154   void selectBetweenCols();
00155   /** selects between specified rows */
00156   void selectRows(int start, int stop);
00157   /** selects between specified cols */
00158   void selectCols(int start, int stop);
00159   /** finds a read */
00160   void findRead();
00161   /** finds a tag */
00162   void findTag();
00163   /** enlarges view*/
00164   void enlarge();
00165   /** shrinks view*/
00166   void shrink();
00167   /** sets pointer mode*/
00168   void setDragMode(bool status);
00169   /** copies selected data*/
00170   void copy();
00171   /** pastes selected data*/
00172   void paste();
00173   /** cuts selected data*/
00174   void cut();
00175   /** undoes last move*/
00176   void undo();
00177   /** gets row position of last mouse press*/
00178   TR_DNA mousePressedRow();
00179   /** gets col position of last mouse press*/
00180   TR_DNA mousePressedCol();
00181   /** Sends out a message*/
00182   void sendMsg( const QString& msg);
00183   /** sets visualization mode for time course data*/
00184   void setViewTimeCourse(bool toggle);
00185   /** sets normalization mode for time course data*/
00186   void setNormalizeTimeCourse(bool toggle);
00187   /** scrolls to next visible read cluster*/
00188   void scrollToNextCluster(bool forward);
00189   /** sets cluster window size*/
00190   void setClusterWindow(int window_size);
00191   /** sets cluster minimum read num size*/
00192   void setClusterMinNum(int num);
00193 
00194 public slots:
00195   void slotSwitchToMode( int i );
00196   void slotStartAlgo( int i );
00197   void slotScrollToMouse();
00198   void slotScrollToPos();
00199   void slotSetCenter();
00200   void slotClearCenter();
00201   void slotContextSelect(int i);
00202   
00203 protected:
00204   void contentsDragEnterEvent(QDragEnterEvent* event);
00205   void contentsDropEvent(QDropEvent* event);
00206   void contentsMouseMoveEvent(QMouseEvent* e);
00207   void contentsMouseReleaseEvent(QMouseEvent* e);
00208   void contentsContextMenuEvent( QContextMenuEvent * e );
00209   void contentsMousePressEvent(QMouseEvent* e);
00210   void contentsDragMoveEvent ( QDragMoveEvent * );
00211   virtual void closeEvent(QCloseEvent*);
00212   void doZoom();
00213   void scrollTo(TR_PIX x, TR_PIX y);
00214   
00215   void drawContents(QPainter* p, TR_PIX cx, TR_PIX cy, TR_PIX cw, TR_PIX ch);
00216   
00217   /** \brief paint a rectangle of the window
00218    *
00219    * @param p  where to paint to
00220    * @param bmp  where to paint a bitmask, we paint to the bitmask on the same places as we paint to p. 
00221    * @param cx x coordinate of rectangle in "content" coordinate system
00222    * @param cy y coordinate of rectangle in "content" coordinate system
00223    * @param cw width of rectangle in "content" coordinate system
00224    * @param ch height of rectangle in "content" coordinate system
00225    * @param dx displace painting with this
00226    * @param dy displace painting with this
00227    */
00228   
00229   
00230   void drawContents_helper(QPainter* p,QPainter* bitmapPainter, int cx, int cy, int cw, int ch, int dx, int dy);
00231 
00232 
00233     /** \brief paint border line around the read rectangle. Then divide the rectangle into layers
00234      * and paint features of the read into these layers.
00235      *
00236      * @param p where to paint
00237      * @param bmp  where to paint a bitmask, we paint to the bitmask on the same places as we paint to p. 
00238      * @param readRecno the index of the read in the underlying berkeley db. 
00239      * @param x_pix x "content" coordinate of the upperleft corner of the paint area 
00240      * @param y_pix y "content" coordinate of the upperleft corner of the paint area 
00241      * @param x1_dna x dna coordinate of the left most position to paint seen relative the left side of the read 
00242      * @param x2_dna x dna coordinate of the right most position to paint seen relative the left side of the read 
00243      * @param width the pixel width of one x dna coordinate 
00244      * @param height the pixel width of one x dna coordinate 
00245      * @param highlight if true change the read border color 
00246      */
00247 
00248 
00249   void paintFeatures( QPainter* p, QPainter * bitmapPainter, db_recno_t readRecno, 
00250                       TR_PIX x_pix, TR_PIX y_pix, 
00251                       TR_DNA x_dna_relative, TR_DNA dna_len , 
00252                       /*TR_PIX*/double width, TR_PIX height, bool selected, int center_relative, 
00253                       bool overlap, TR_DNA bg, TR_DNA eg );
00254   
00255   /** \brief paint some extra dots in the background of the window. These will move along when the
00256    * user scrolls. Nice to have some visual feedback of movement when there are no reads in the window */
00257   void paintGrid(QPainter* p, TR_PIX cx, TR_PIX cy, TR_PIX cw, TR_PIX ch);
00258   void convertToPixelCoordinates( TR_PIX & x_pix, TR_PIX & y_pix, TR_DNA x_dna, TR_DNA y_dna );
00259   void convertToDnaCoordinates( TR_DNA & x_dna, TR_DNA & y_dna, const TR_PIX cx, const TR_PIX cy );
00260   TR_PIX dnaCoordToPixel_X( TR_DNA cx );
00261   TR_PIX dnaCoordToPixel_Y( TR_DNA cy );
00262   TR_DNA pixelCoordToDna_X( TR_PIX x_dna );
00263   TR_DNA pixelCoordToDna_Y( TR_PIX y_dna );
00264 
00265   std::set< db_recno_t >& getSelectedReads();
00266   void select( db_recno_t recno, bool status );
00267   bool isSelected( db_recno_t recno );
00268   void clearSelected();
00269   std::vector<std::list<std::string> > getInfo( const QPoint& pos );
00270   
00271   void runAlgo( const std::string& AlgoType, std::set< db_recno_t >& recnoList, AlgoParam* param = 0 );
00272   void writeSelected(QDataStream& data_stream);
00273   void readSelected(QDataStream& data_stream);
00274   
00275   void moveData(TR_PIX dx, TR_PIX dy);
00276   
00277   void fitContentsizeToData();
00278 
00279   void clearLastMove();
00280   
00281   TR_PIX basewidth;
00282   TR_PIX spaceBetweenRows;
00283   TR_PIX rowheight;
00284   TR_DNA globalRows, globalBases;
00285   TR_DNA center_point;
00286   
00287   TrapperDoc *doc;
00288   QLabel * lab;
00289 //   u_int16_t magnifyX;
00290   double magnifyX;
00291   u_int16_t magnifyY;
00292   int zoomfactor;
00293   ViewModes * viewModes;
00294   QPopupMenu *switchViewMenu;
00295   QPopupMenu *algoMenu;
00296   QPopupMenu *infoMenu;
00297   QPopupMenu *contextSelectMenu;
00298   
00299   
00300   typedef std::set<db_recno_t> RecnoMap;
00301   /** The index values ( of type db_recno_t ) of all selected reads.
00302    *  
00303    * Just some thoughts about implemantion: 
00304    * Right now they are stored as an STL map but   
00305    * there are other alternatives of how to implement this: Maybe an
00306    * STL bitset or STL vector<bool> or maybe store it in a berkeley db.
00307    * If you want to select all possible reads, 4^32, then you would
00308    * lower your memory consumption if used a bitset. And going with
00309    * a berkeley db you would have even lower memory demands.
00310    *
00311    * 040315: Changed selectedReads into std::set --EA
00312    */
00313   std::set<db_recno_t> selectedReads;
00314   std::map<std::string, int> zoom_cutoff;
00315   int min_cutoff;
00316   
00317   ReadsInRect * readsInRect;
00318   bool dragging;
00319   bool allow_dragging;
00320   bool moving;
00321   bool last_click_selected_read;
00322   bool last_click_changed_selection;
00323   db_recno_t last_selected_recno;
00324   QPoint curr_mouse_pos;
00325   TR_PIX y_delta;
00326   TR_PIX y_delta_previous;
00327   
00328   TR_DNA last_move_x;
00329   TR_DNA last_move_y;
00330 
00331   bool time_course;
00332   bool tc_normalize;
00333 
00334   int read_cluster_min_num;
00335   TR_DNA read_cluster_window;
00336   
00337   
00338 private:
00339   QPixmap dragPixmap;
00340   QBitmap dragBitmap;
00341   QPainter p3;
00342   QPoint mousePressedPoint;
00343   QPoint dragWindowPoint;
00344   QRect* rubber_band;
00345   bool ctrl;
00346 
00347   //RUBBERTEST
00348   QPoint RubberStart,RubberEnd;
00349   bool RubberOn;
00350   QPoint oldMovePoint;
00351   bool moveOn;
00352   
00353 
00354 
00355 
00356   void drawRubber(QPainter *p)
00357   {
00358     QPen ppen = p->pen();
00359     ppen.setStyle(Qt::DotLine);
00360     p->setPen(ppen);
00361     p->drawRect(
00362                 RubberStart.x(),
00363                 RubberStart.y(),
00364                 RubberEnd.x()-RubberStart.x(),
00365                 RubberEnd.y()-RubberStart.y()
00366                 );
00367   }
00368   //END RUBBERTEST
00369 signals:
00370   void createView( QString );
00371   void message( const QString& );
00372 };
00373 
00374 #endif

Generated on Fri Jul 17 20:19:29 2009 for ngsview by  doxygen 1.5.1