# A.8. kscribbleview.cpp

       1 /***************************************************************************
       2                           kscribbleview.cpp  -  description
       3                              -------------------
       4     begin                : Mon Jan 31 11:05:05 CET 2000
       5     copyright            : (C) 2000 by Ralf Nolden
       6     email                : Ralf.Nolden@post.rwth-aachen.de
       7  ***************************************************************************/
       8
       9 /***************************************************************************
      10  *                                                                         *
      11  *   This program is free software; you can redistribute it and/or modify  *
      12  *   it under the terms of the GNU General Public License as published by  *
      13  *   the Free Software Foundation; either version 2 of the License, or     *
      14  *   (at your option) any later version.                                   *
      15  *                                                                         *
      16  ***************************************************************************/
      17 #include <iostream.h>
      18
      19 // include files for Qt
      20 #include <qprinter.h>
      21 #include <qpainter.h>
      22 #include <qdir.h>
      23 #include <qsize.h>
      24 #include <qclipboard.h>
      25 #include <qimage.h>
      26 #include <qdragobject.h>
      27
      28 // include files for KDE
      29 #include <kiconloader.h>
      30
      31 // application specific includes
      32 #include "kscribbleview.h"
      33 #include "kscribbledoc.h"
      34 #include "kscribble.h"
      35
      36
      37 KScribbleView::KScribbleView(KScribbleDoc* pDoc, QWidget *parent, const char* name, int wflags)
      38  : QScrollView(parent, name, wflags | WPaintClever | WNorthWestGravity | WRepaintNoErase)
      39 {
      40   cb = QApplication::clipboard();
      41   viewport()->setAcceptDrops(true);
      42   setDragAutoScroll(true);
      43   doc=pDoc;
      44   action=IDLE;
      45   viewport()->setCursor( Qt::crossCursor );
      46   QSize size=doc->docSize();
      47   resizeContents(size.width(), size.height());
      48   resize(size);
      49 }
      50
      51 KScribbleView::~KScribbleView()
      52 {
      53 }
      54
      55 KScribbleDoc *KScribbleView::getDocument() const
      56 {
      57   return doc;
      58 }
      59
      60 void KScribbleView::update(KScribbleView* pSender){
      61   if(pSender != this)
      62     viewport()->repaint(0,0,visibleWidth(), visibleHeight(), false);
      63 }
      64
      65 void KScribbleView::print(QPrinter *pPrinter)
      66 {
      67   if (pPrinter->setup(this))
      68   {
      69     QPainter p;
      70     p.begin(pPrinter);
      71
      72     ///////////////////////////////
      73     // TODO: add your printing code here
      74     p.drawPixmap(0,0,doc->buffer);
      75     ///////////////////////////////
      76     p.end();
      77   }
      78 }
      79
      80 /** cuts out a selection */
      81 void KScribbleView::cutSelection(){
      82   select=select.normalize();
      83   QPixmap cb_pix;
      84   cb_pix.resize(select.size());
      85   // copy selection to cb_pix and copy to clipboard
      86   bitBlt(&&;cb_pix, 0, 0,
      87          &&;doc->buffer, select.x()+contentsX(),  select.y()+contentsY(), cb_pix.width(), cb_pix.height());
      88   cb->setPixmap(cb_pix);
      89   // fill cb_pix with white and copy to selection area
      90   cb_pix.fill(Qt::white);
      91   bitBlt(&&;doc->buffer, select.x()+contentsX(), select.y()+contentsY(),
      92          &&;cb_pix, 0, 0, cb_pix.width(), cb_pix.height());
      93   action = IDLE;
      94   doc->setModified();
      95   doc->updateAllViews(this);
      96   viewport()->repaint(0,0,visibleWidth(), visibleHeight(), false);
      97 }
      98 /** copies a selection to the clipboard */
      99 void KScribbleView::copySelection(){
     100   select=select.normalize();
     101   QPixmap cb_pix;
     102   cb_pix.resize(select.size());
     103   // copy selection to cb_pix and copy to clipboard
     104   bitBlt(&&;cb_pix, 0, 0,
     105          &&;doc->buffer, select.x()+contentsX(),  select.y()+contentsY(),cb_pix.width(), cb_pix.height());
     106   cb->setPixmap(cb_pix);
     107   action = IDLE;
     108   viewport()->repaint(0,0,visibleWidth(), visibleHeight(), false);
     109 }
     110 /** pastes the clipboard contents to a selection that can be inserted into the picture */
     111 void KScribbleView::pasteSelection(){
     112   select=cb->pixmap().rect();
     113   action = PASTE;
     114   viewport()->setCursor( Qt::sizeAllCursor );
     115 }
     116
     117 void KScribbleView::closeEvent(QCloseEvent* e){
     118
     119 // DO NOT CALL QWidget::closeEvent(e) here !!
     120 // This will accept the closing by QCloseEvent::accept() by default.
     121 // The installed eventFilter() in KScribbleApp takes care for closing the widget
     122 // or ignoring the close event
     123
     124 }
     125
     126 void KScribbleView::keyPressEvent( QKeyEvent *e )
     127 {
     128   switch (e->key())
     129   {
     130     case Key_Right:
     131       scrollBy( 10, 0 );
     132       break;
     133     case Key_Left:
     134       scrollBy( -10,0);
     135       break;
     136     case Key_Up:
     137       scrollBy( 0, -10 );
     138       break;
     139     case Key_Down:
     140       scrollBy( 0, 10 );
     141       break;
     142     case Key_Home:
     143       setContentsPos(0,0);
     144       break;
     145     case Key_End:
     146       setContentsPos(0,viewport()->height()-viewport()->height());
     147       break;
     148     case Key_PageUp:
     149       scrollBy( 0, -viewport()->height() );
     150       break;
     151     case Key_PageDown:
     152       scrollBy( 0, viewport()->height() );
     153       break;
     154   }
     155
     156 }
     157
     158 void KScribbleView::viewportMousePressEvent( QMouseEvent *e )
     159 {
     160   if ( e->button() == LeftButton &&;&&; action == IDLE)
     161   {
     162     action=DRAW;
     163     doc->polyline[2] = doc->polyline[1] = doc->polyline[0] = viewportToContents(e->pos());
     164     doc->updateAllViews(this);
     165   }
     166   else if ( e->button() == RightButton &&;&&; action == IDLE)
     167   {
     168     action = SELECT;
     169     QPoint pt=e->pos();
     170     int x = pt.x() > contentsWidth() ? contentsWidth() : pt.x();
     171     int y = pt.y() > contentsHeight() ? contentsHeight() : pt.y();
     172     select.setLeft(x-1);
     173     select.setTop(y-1);
     174     select.setRight(x-1);
     175     select.setBottom(y-1);
     176   }
     177   else if( action == SELECT )
     178   {
     179     action = IDLE;
     180     select=select.normalize();
     181     // drag
     182     if(select.contains(e->pos(), true)) // point inside the selection
     183     {
     184       tmp.resize(select.size());
     185       bitBlt(&&;tmp, 0, 0,
     186              &&;doc->buffer, select.x()+contentsX(),  select.y()+contentsY(), tmp.width(), tmp.height());
     187       QImage img =tmp.convertToImage();
     188       QDragObject *d = new QImageDrag( img, viewport() );
     189       d->setPixmap(BarIcon("filenew"));
     190       d->drag();
     191     }
     192     // remove selection
     193     else
     194       viewport()->repaint(0,0,visibleWidth(), visibleHeight(), false);
     195   }
     196   else if( action == PASTE )
     197   {
     198     if ( e->button() == RightButton )
     199     {
     200       action = IDLE;
     201       viewport()->setCursor( Qt::crossCursor );
     202     }
     203     QPoint mv_pt (viewport()->height(), viewport()->width());
     204     if(QRect(0,0,mv_pt.x(),mv_pt.y()).contains(e->pos()))
     205       select.moveCenter(e->pos());
     206     else
     207     {
     208       select.moveBottomRight(mv_pt);
     209     }
     210     viewport()->repaint(0,0,visibleWidth(), visibleHeight(), false);
     211   }
     212 }
     213
     214 void KScribbleView::viewportMouseReleaseEvent( QMouseEvent *e )
     215 {
     216   if ( action == DRAW )
     217   {
     218     action = IDLE;
     219     doc->updateAllViews(this);
     220   }
     221   if ( action == SELECT)
     222   {
     223     QPoint pt=e->pos();
     224     int x = pt.x() > 0 ? pt.x() : 0;
     225     int y = pt.y() > 0 ? pt.y() : 0;
     226     select.setRight(x);
     227     select.setBottom(y);
     228     QSize size=doc->docSize();
     229     select = select.intersect(QRect(0,0,size.width(), size.height()));
     230   }
     231 }
     232
     233 /** On paste actions inserts the pasted clipboard contents
     234  */
     235 void KScribbleView::viewportMouseDoubleClickEvent(QMouseEvent* e)
     236 {
     237   if( action == PASTE )
     238   {
     239     action = IDLE;
     240     select.moveCenter(e->pos());
     241     viewport()->setCursor( Qt::crossCursor );
     242     QPixmap cb_pix;
     243     cb_pix.resize(cb->pixmap().size());
     244     cb_pix=cb->pixmap();
     245     bitBlt( &&;doc->buffer, contentsX()+select.x(), contentsY()+select.y(),
     246             &&;cb_pix, 0,0 , select.width(),select.height() );
     247     viewport()->repaint(0,0,visibleWidth(), visibleHeight(), false);
     248     doc->setModified();
     249     doc->updateAllViews(this);
     250   }
     251
     252 }
     253
     254 void KScribbleView::viewportMouseMoveEvent( QMouseEvent *e )
     255 {
     256   if ( action == DRAW )
     257   {
     258     QPainter painter;
     259     painter.begin( &&;doc->buffer );
     260     painter.setPen( doc->currentPen() );
     261     doc->polyline[2] = doc->polyline[1];
     262     doc->polyline[1] = doc->polyline[0];
     263     doc->polyline[0] = viewportToContents(e->pos());
     264     painter.drawPolyline( doc->polyline );
     265     painter.end();
     266
     267     QRect r = doc->polyline.boundingRect();
     268     r = r.normalize();
     269     r.setLeft( r.left() - doc->penWidth() );
     270     r.setTop( r.top() - doc->penWidth() );
     271     r.setRight( r.right() + doc->penWidth() );
     272     r.setBottom( r.bottom() + doc->penWidth() );
     273
     274     bitBlt(viewport(), r.x()-contentsX(), r.y()-contentsY() ,
     275            &&;doc->buffer, r.x(), r.y(), r.width(), r.height() );
     276     doc->setModified();
     277     doc->updateAllViews(this);
     278   }
     279   if ( action == SELECT )
     280   {
     281     QPoint pt=e->pos();
     282     select.setWidth(select.x()+pt.x());
     283     select.setHeight(select.y()+pt.y());
     284     select.setRight(pt.x());
     285     select.setBottom(pt.y());
     286     QSize size=doc->docSize();
     287     select = select.intersect(QRect(0,0,size.width(), size.height()));
     288     viewport()->repaint(0,0,visibleWidth(), visibleHeight(), false);
     289   }
     290   if( action == PASTE )
     291   {
     292     QPoint mv_pt (viewport()->height(), viewport()->width());
     293     if(QRect(0,0,mv_pt.x(),mv_pt.y()).contains(e->pos()))
     294       select.moveCenter(e->pos());
     295     else
     296     {
     297       select.moveBottomRight(mv_pt);
     298     }
     299     QRect pm_rect=cb->pixmap().rect();
     300     select.setWidth(pm_rect.width());
     301     select.setHeight(pm_rect.height());
     302     QSize size=doc->docSize();
     303     select = select.intersect(QRect(0,0,size.width(), size.height()));
     304     viewport()->repaint(0,0,visibleWidth(), visibleHeight(), false);
     305     doc->setModified();
     306     doc->updateAllViews(this);
     307   }
     308 }
     309
     310 //void KScribbleView::viewportResizeEvent( QResizeEvent *e )
     311 //{
     312 //}
     313
     314 void KScribbleView::viewportPaintEvent( QPaintEvent *e )
     315 {
     316   bitBlt( viewport(),0,0, &&;doc->buffer,contentsX() ,contentsY() );
     317
     318   if( action == PASTE )
     319   {
     320     tmp.resize(cb->pixmap().size());
     321     tmp=cb->pixmap();
     322   }
     323   if( action == PASTE || action == DRAG )
     324   {
     325     QSize size=doc->docSize();
     326     select = select.intersect(QRect(0,0,size.width(), size.height()));
     327     if(select.intersects(e->rect()))
     328       bitBlt(viewport(), select.x(), select.y(), &&;tmp, 0, 0, select.width(), select.height());
     329   }
     330   if( action == PASTE || action == DRAG || action == SELECT )
     331   {
     332 //    if(select.intersects(e->rect()))
     333 //    {
     334       QPainter paint_area;
     335       paint_area.begin(viewport());
     336       paint_area.setPen(QPen(Qt::black, 0, DashLine));
     337       paint_area.drawRect( select );
     338       paint_area.end();
     339 //    }
     340   }
     341   QScrollView::viewportPaintEvent(e);
     342 }
     343
     344 void  KScribbleView::viewportDragEnterEvent ( QDragEnterEvent * e)
     345 {
     346   e->accept(QImageDrag::canDecode(e));
     347   action = DRAG;
     348 }
     349
     350 void  KScribbleView::viewportDragMoveEvent ( QDragMoveEvent * e)
     351 {
     352   QImage img;
     353   if ( QImageDrag::decode(e, img) ){
     354     tmp.resize(img.size());
     355     tmp.convertFromImage(img);
     356     select.setWidth(tmp.width());
     357     select.setHeight(tmp.height());
     358     select.moveCenter(e->pos());
     359     viewport()->repaint(0,0,visibleWidth(), visibleHeight(), false);
     360   }
     361 }
     362
     363 void  KScribbleView::viewportDragLeaveEvent ( QDragLeaveEvent * )
     364 {
     365   action = IDLE;
     366   viewport()->repaint(0,0,visibleWidth(), visibleHeight(), false);
     367 }
     368
     369 void  KScribbleView::viewportDropEvent ( QDropEvent * e)
     370 {
     371   QImage img;
     372   if ( QImageDrag::decode(e, img) )
     373   {
     374     tmp.resize(img.size());
     375     tmp.convertFromImage(img);
     376     select.setWidth(tmp.width());
     377     select.setHeight(tmp.height());
     378     select.moveCenter(e->pos());
     379     bitBlt(&&;doc->buffer, select.x()+contentsX(), select.y()+contentsY(),
     380            &&;tmp, 0, 0, tmp.width(), tmp.height());
     381     doc->setModified();
     382     doc->updateAllViews(this);
     383   }
     384   action = IDLE;
     385     viewport()->repaint(0,0,visibleWidth(), visibleHeight(), false);
     386 }