Logo Search packages:      
Sourcecode: kmess version File versions

inkedit.cpp

/***************************************************************************
                          inkvedit.cpp -  description
                             -------------------
    begin                : Wed May 14 2008
    copyright            : (C) 2008 by Antonio Nastasi
    email                : sifcenter@gmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "inkedit.h"

#include "../kmessdebug.h"

#include <KIcon>
#include <KColorDialog>

#include <QBuffer>
#include <QMouseEvent>
#include <QPainter>
#include <QPen>



// Constructor
InkEdit::InkEdit( QWidget *parent )
: QWidget( parent )
, Ui::InkEdit()
, color_( Qt::black )
, erasingImage_( false )
, image_( 0 )
, isEmpty_( true )
, scribbling_( false )
{
  setupUi( this );
  setAttribute( Qt::WA_StaticContents );

  // Set the buttons
  colorButton_->setIcon( KIcon( "format-stroke-color" ) );
  eraseButton_->setIcon( KIcon( "draw-eraser"         ) );
  clearButton_->setIcon( KIcon( "edit-clear"          ) );

  connect( colorButton_, SIGNAL(     clicked() ),
           this,         SLOT  ( changeColor() ) );
  connect( eraseButton_, SIGNAL(     clicked() ),
           this,         SLOT  (  eraseBrush() ) );
  connect( clearButton_, SIGNAL(     clicked() ),
           this,         SLOT  (  clearImage() ) );
}



// Clear the current image
void InkEdit::clearImage()
{
  if( image_ == 0 )
  {
    kWarning() << "Uninitialized usage of InkEdit!";
    return;
  }

  image_->pixels.fill( qRgb( 255, 255, 255 ) );
  update();
  isEmpty_ = true;

  // Reset the drawn area
  image_->area = QRect();

  emit inkChanged();
}



// Change color for current pen
void InkEdit::changeColor()
{
  QColor color;
  int result = KColorDialog::getColor( color );
  if ( result == KColorDialog::Accepted )
  {
    color_ = color;
  }
}



// Crop the image to send only the drawed area
void InkEdit::cropImage( QPoint position )
{
  if( image_ == 0 )
  {
    kWarning() << "Uninitialized usage of InkEdit!";
    return;
  }

  int sizePen = sizePen_->value();

  // Adjust the initial size and position
  if( image_->area.topLeft().x() == - 1 || image_->area.topLeft().y() == -1 )
  {
    image_->area.setTopLeft( QPoint( position.x(), position.y() ) );
    image_->area.setBottomRight( QPoint( position.x() + sizePen , position.y() + sizePen ) );
    return;
  }

  // Adjust the x position and width
  if( position.x() < image_->area.topLeft().x() )
  {
    image_->area.setTopLeft( QPoint( position.x() - sizePen , image_->area.topLeft().y() ) );
  }
  else if( position.x() > image_->area.bottomRight().x() )
  {
    image_->area.setBottomRight( QPoint( position.x() + sizePen, image_->area.bottomRight().y() ) );
  }

  // Adjust the y position and height
  if( position.y() < image_->area.topLeft().y() )
  {
    image_->area.setTopLeft( QPoint( image_->area.topLeft().x(), position.y( )  - sizePen ) );
  }
  else if( position.y() > image_->area.bottomRight().y() )
  {
    image_->area.setBottomRight( QPoint( image_->area.bottomRight().x() , position.y()+ sizePen ) );
  }
}



// Draw a line from start point to last point
void InkEdit::drawLineTo( const QPoint &endPoint )
{
  if( image_ == 0 )
  {
    kWarning() << "Uninitialized usage of InkEdit!";
    return;
  }

  QPainter painter( &(image_->pixels) );

  QColor color = color_;
  if( erasingImage_ )
  {
    color = QColor( "white" );
  }

  painter.setPen( QPen( color, sizePen_->value(), Qt::SolidLine, Qt::RoundCap,
                  Qt::RoundJoin ) );

  painter.drawLine( lastPoint_, endPoint );

  int rad = (1 / 2) + 2;
  update( QRect( lastPoint_, endPoint ).normalized()
          .adjusted( -rad, -rad, +rad, +rad ) );

  lastPoint_ = endPoint;
}



// Erase brush was selected
void InkEdit::eraseBrush()
{
  erasingImage_ = ! erasingImage_;

  if( erasingImage_ )
  {
    eraseButton_->setIcon( KIcon( "draw-freehand" ) );
  }
  else
  {
    eraseButton_->setIcon( KIcon( "draw-eraser" ) );
  }
}



// Return if the image is empty
bool InkEdit::isEmpty()
{
  return isEmpty_;
}



void InkEdit::mousePressEvent( QMouseEvent *event )
{
  if( image_ == 0 )
  {
    kWarning() << "Uninitialized usage of InkEdit!";
    return;
  }

  if( event->button() == Qt::LeftButton )
  {
    lastPoint_ = event->pos();
    cropImage( lastPoint_ );
    scribbling_ = true;
  }
}



void InkEdit::mouseMoveEvent(QMouseEvent *event)
{
  if( image_ == 0 )
  {
    kWarning() << "Uninitialized usage of InkEdit!";
    return;
  }

  if( ( event->buttons() & Qt::LeftButton ) && scribbling_ )
  {
    QPoint position = event->pos();
    cropImage(  position );
    drawLineTo( position );
  }
}



void InkEdit::mouseReleaseEvent(QMouseEvent *event)
{
  if( image_ == 0 )
  {
    kWarning() << "Uninitialized usage of InkEdit!";
    return;
  }

  if( event->button() == Qt::LeftButton && scribbling_ )
  {
    QPoint position = event->pos();
    cropImage(  position );
    drawLineTo( position );

    isEmpty_ = false;
    scribbling_ = false;
    emit inkChanged();
  }
}



void InkEdit::paintEvent(QPaintEvent */*event*/)
{
  if( image_ == 0 || image_->pixels.isNull() )
  {
    kWarning() << "Uninitialized usage of InkEdit!";
    return;
  }

  QPainter painter( this );
  painter.drawImage( QPoint(0, 0), image_->pixels );
}



void InkEdit::resizeEvent( QResizeEvent *event )
{
  if( image_ == 0 )
  {
    kWarning() << "Uninitialized usage of InkEdit!";
    return;
  }

  if( width() > image_->pixels.width() || height() > image_->pixels.height() )
  {
    int newWidth = qMax( width() + 128, image_->pixels.width() );
    int newHeight = qMax( height() + 128, image_->pixels.height() );
    resizeImage( &(image_->pixels), QSize( newWidth, newHeight ) );
    update();
  }

  QWidget::resizeEvent( event );
}



// Return the image
InkImage *InkEdit::getImage()
{
  return image_;
}



// Return the bytes rapresents the image
const QByteArray& InkEdit::getImageBytes()
{
  if( image_ == 0 )
  {
    kWarning() << "Uninitialized usage of InkEdit!";
    imageBytes_.clear();
    return imageBytes_;
  }

  QBuffer buffer( &imageBytes_ );
  buffer.open( QIODevice::WriteOnly );
  image_->pixels.copy( image_->area ).save( &buffer, "PNG" );
 //image_->pixels.scaled( size(), Qt::KeepAspectRatio, Qt::SmoothTransformation ).save( &buffer, "PNG" );
  return imageBytes_;
}



void InkEdit::resizeImage( QImage *image, const QSize &newSize )
{
  if( image_ == 0 )
  {
    kWarning() << "Uninitialized usage of InkEdit!";
    return;
  }

  if( image->size() == newSize )
  {
    return;
  }

  QImage newImage( newSize, QImage::Format_ARGB32 );
  newImage.fill( qRgb( 255, 255, 255 ) );
  QPainter painter( &newImage );
  if( ! image->isNull() )
  {
    painter.drawImage( QPoint( 0, 0 ), (*image).scaled( newSize, Qt::KeepAspectRatio, Qt::SmoothTransformation ) );
  }
  else
  {
    painter.drawImage( QPoint( 0, 0 ), *image );
  }

  *image = newImage;
}



// Change the image
void InkEdit::setImage( InkImage *newImage )
{
  image_ = newImage;
  update();

  if( image_ )
  {
    // Initialize the image if needed
    if( ! image_->initialized )
    {
      resizeImage( &(image_->pixels), size() );
      clearImage();
      image_->initialized = true;
    }

    isEmpty_ = image_->area.isNull();
  }
  else
  {
    isEmpty_ = true;
  }
}



#include "inkedit.moc"

Generated by  Doxygen 1.6.0   Back to index