/* Marcion
Copyright (C) 2009 - 2011 Milan Konvicka
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; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program */
#include "mimage.h"
//
CMImage::CMImage(QWidget * parent)
: QGraphicsView(parent),start(),scene(),current(0),
sel_rect(0),
pixmap(),
popup(),
popupSel(tr("selection")),
selection(),
sel_pen(QColor(0,0,0)),
sel_brush(QColor(0,0,0,127)),
_m_mode(CMImage::Move),
_s_mode(Normal),
_i_mode(Image),
bt_popup(false)
{
viewport()->setCursor(Qt::OpenHandCursor);
setScene(&scene);
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(slot_customContextMenuRequested(QPoint)));
//emit mouseModeChanged(CMImage::Move);
}
CMImage::~CMImage()
{
if(sel_rect)
delete sel_rect;
if(current)
delete current;
}
//
void CMImage::mousePressEvent ( QMouseEvent * e )
{
QPointF pmap(mapToScene(e->pos()));
if(e->button()==Qt::LeftButton)
{
if(current)
{
switch(_m_mode)
{
case CMImage::Move :
start=mapToScene(e->pos()+
QPoint(viewport()->width()/2,viewport()->height()/2));
viewport()->setCursor(Qt::ClosedHandCursor);
break;
case CMImage::Select :
scene.update();
if(_s_mode==Normal)
{
selection.setTopLeft(pmap);
selection.setBottomRight(QPoint(pmap.x()+1,pmap.y()+1));
}
else
{
if(sel_rect)
switch(_s_mode)
{
case Normal :
break;
case LeftTop :
if(pmap.x()<selection.right()&&pmap.y()<selection.bottom())
{
selection.setTopLeft(pmap);
sel_rect->setRect(selection);
}
break;
case RightTop :
if(pmap.x()>selection.left()&&pmap.y()<selection.bottom())
{
selection.setTopRight(pmap);
sel_rect->setRect(selection);
}
break;
case LeftBottom :
if(pmap.x()<selection.right()&&pmap.y()>selection.top())
{
selection.setBottomLeft(pmap);
sel_rect->setRect(selection);
}
break;
case RightBottom :
if(pmap.x()>selection.left()&&pmap.y()>selection.top())
{
selection.setBottomRight(pmap);
sel_rect->setRect(selection);
}
break;
}
}
break;
}
}
}
}
void CMImage::mouseReleaseEvent ( QMouseEvent * e)
{
if(e->button()==Qt::LeftButton)
{
if(current)
{
switch(_m_mode)
{
case CMImage::Move :
viewport()->setCursor(Qt::OpenHandCursor);
start=QPointF();
break;
case CMImage::Select :
//_s_mode=Normal;
break;
}
}
}
}
void CMImage::mouseMoveEvent ( QMouseEvent * e )
{
QPointF pmap(mapToScene(e->pos()));
if(e->buttons()==Qt::LeftButton)
{
if(current)
{
switch(_m_mode)
{
case CMImage::Move :
if(!start.isNull())
{
centerOn(start-e->pos());
}
break;
case CMImage::Select :
if(!selection.isNull())
{
if(_s_mode==Normal)
{
selection.setBottomRight(pmap);
if(sel_rect)
sel_rect->setRect(selection);
else
sel_rect=scene.addRect(selection,sel_pen,sel_brush);
}
else
{
if(sel_rect)
switch(_s_mode)
{
case Normal :
break;
case LeftTop :
if(pmap.x()<selection.right()&&pmap.y()<selection.bottom())
{
selection.setTopLeft(pmap);
sel_rect->setRect(selection);
}
break;
case RightTop :
if(pmap.x()>selection.left()&&pmap.y()<selection.bottom())
{
selection.setTopRight(pmap);
sel_rect->setRect(selection);
}
break;
case LeftBottom :
if(pmap.x()<selection.right()&&pmap.y()>selection.top())
{
selection.setBottomLeft(pmap);
sel_rect->setRect(selection);
}
break;
case RightBottom :
if(pmap.x()>selection.left()&&pmap.y()>selection.top())
{
selection.setBottomRight(pmap);
sel_rect->setRect(selection);
}
break;
}
}
}
break;
}
}
}
emit positionChanged(pmap);
}
void CMImage::clearPixmap()
{
if(sel_rect)
{
scene.removeItem(sel_rect);
delete sel_rect;
sel_rect=0;
}
if(current)
{
delete current;
current=0;
}
scene.clear();
}
void CMImage::setPixmap(QPixmap const & pm)
{
if(sel_rect)
{
scene.removeItem(sel_rect);
delete sel_rect;
sel_rect=0;
}
if(current)
{
delete current;
current=0;
}
pixmap=pm;
current=scene.addPixmap(pm);
}
bool CMImage::loadPage(QString const & filename,qreal stretch)
{
USE_CLEAN_WAIT
m_msg()->MsgMsg(tr("displaying '")+filename+"' ...");
if(sel_rect)
{
scene.removeItem(sel_rect);
delete sel_rect;
sel_rect=0;
}
if(current)
delete current;
current=0;
//QPixmap pixmap(filename);
//try{
if(!pixmap.load(filename))
{
m_msg()->MsgErr("'"+filename+tr("' not loaded"));
return false;
}
/*}
catch(...)
{
messages->MsgErr("'"+filename+tr("exception"));
return false;
}*/
int newwidth;
if(stretch==(qreal)0)
newwidth=viewport()->width()-10;
else
newwidth=pixmap.width()*stretch;
scene.clear();
QPixmap sp=pixmap.scaledToWidth(newwidth);
scene.setSceneRect(sp.rect());
current=scene.addPixmap(sp);
centerOn(1,1);
m_msg()->MsgOk();
return true;
}
/*void CMImage::init(CMessages * const messages)
{
CMessages ** m((CMessages**)&this->messages);
*m=messages;
}*/
void CMImage::scale(qreal zoom)
{
USE_CLEAN_WAIT
scene.clear();
QPixmap sp=pixmap.scaledToWidth(pixmap.width()*zoom);
scene.setSceneRect(sp.rect());
current=scene.addPixmap(sp);
}
void CMImage::slot_customContextMenuRequested(QPoint pos)
{
if(current)
{
a_move->setChecked(_m_mode==CMImage::Move);
a_select->setChecked(_m_mode==CMImage::Select);
popupSel.setEnabled(sel_rect);
a_copy->setEnabled(sel_rect);
if(a_copy_text)
a_copy_text->setEnabled(sel_rect);
a_clr_selection->setEnabled(sel_rect);
a_sel_lt->setChecked(_s_mode==LeftTop);
a_sel_lb->setChecked(_s_mode==LeftBottom);
a_sel_rt->setChecked(_s_mode==RightTop);
a_sel_rb->setChecked(_s_mode==RightBottom);
a_sel_norm->setChecked(_s_mode==Normal);
QAction * a;
if((a=popup.exec(bt_popup?pos:QCursor::pos())))
{
if(a==a_move)
setMouseMode(Move);
else if(a==a_select)
setMouseMode(Select);
else if(a==a_clr_selection)
{
if(sel_rect)
{
scene.removeItem(sel_rect);
delete sel_rect;
sel_rect=0;
}
selection=QRectF();
_s_mode=Normal;
}
else if(a==a_copy)
{
if(sel_rect)
{
QImage cimage(selection.width(),selection.height(),QImage::Format_RGB16);
QPainter p(&cimage);
sel_rect->hide();
scene.render(&p,QRectF(0,0,cimage.width(),cimage.height()),selection);
sel_rect->show();
QApplication::clipboard()->setImage(cimage);
m_msg()->MsgMsg(tr("image was copied into clipboard, pos: ")+QString::number(selection.x())+","+QString::number(selection.y())+tr(" size: ")+QString::number(selection.width())+","+QString::number(selection.height()));
}
}
else if(a==a_copy_text)
{
emit copyTextRequested(selection);
}
else if(a==a_sel_lt)
_s_mode=LeftTop;
else if(a==a_sel_lb)
_s_mode=LeftBottom;
else if(a==a_sel_rt)
_s_mode=RightTop;
else if(a==a_sel_rb)
_s_mode=RightBottom;
else if(a==a_sel_norm)
_s_mode=Normal;
else if(a==a_repaint)
scene.update();
else if(a==a_sett)
emit settingsActivated(a_sett->isChecked());
}
bt_popup=false;
}
}
void CMImage::showPopupOnButton(QPoint pos)
{
bt_popup=true;
slot_customContextMenuRequested(pos);
}
/*void CMImage::enablePdfMenu()
{
a_copy_text->setVisible(true);
}*/
void CMImage::setMouseMode(MouseMode mouse_mode,bool signal)
{
_s_mode=Normal;
switch(mouse_mode)
{
case Move :
_m_mode=CMImage::Move;
/*if(sel_rect)
{
scene.removeItem(sel_rect);
delete sel_rect;
sel_rect=0;
}
selection=QRectF();*/
viewport()->setCursor(Qt::OpenHandCursor);
//m_msg()->MsgMsg("mouse mode: move");
break;
case Select :
_m_mode=CMImage::Select;
viewport()->setCursor(Qt::CrossCursor);
//m_msg()->MsgMsg("mouse mode: select");
break;
}
if(signal)
emit mouseModeChanged(_m_mode);
}
void CMImage::setSettingsState(bool state)
{
a_sett->setChecked(state);
}
void CMImage::setSelectionBorderColor(QColor const & color)
{
sel_pen.setColor(color);
if(sel_rect)
sel_rect->setPen(sel_pen);
}
void CMImage::setSelectionBorderWidth(int width)
{
sel_pen.setWidth(width);
if(sel_rect)
sel_rect->setPen(sel_pen);
}
void CMImage::setSelectionFillColor(QColor const & color)
{
sel_brush.setColor(color);
if(sel_rect)
sel_rect->setBrush(sel_brush);
}
/*void CMImage::setSelectionFillOpacity(int opacity)
{
QColor c(sel_brush.color());
c.setAlpha(opacity);
sel_brush.setColor(c);
if(sel_rect)
sel_rect->setBrush(sel_brush);
}*/
void CMImage::cancelSelection()
{
if(sel_rect)
{
scene.removeItem(sel_rect);
delete sel_rect;
sel_rect=0;
}
}
void CMImage::setImageMode(ImageMode imode)
{
(a_sel_lt=popupSel.addAction(QIcon(":/new/icons/icons/sel_lt.png"),tr("resize left top")))->setCheckable(true);
(a_sel_lb=popupSel.addAction(QIcon(":/new/icons/icons/sel_lb.png"),tr("resize left bottom")))->setCheckable(true);
(a_sel_rt=popupSel.addAction(QIcon(":/new/icons/icons/sel_rt.png"),tr("resize right top")))->setCheckable(true);
(a_sel_rb=popupSel.addAction(QIcon(":/new/icons/icons/sel_rb.png"),tr("resize right bottom")))->setCheckable(true);
(a_sel_norm=popupSel.addAction(QIcon(":/new/icons/icons/sel_new.png"),tr("start new")))->setCheckable(true);
(a_move=popup.addAction(tr("move")))->setCheckable(true);
(a_select=popup.addAction(tr("select")))->setCheckable(true);
popup.addSeparator();
popup.addMenu(&popupSel);
a_copy=popup.addAction(tr("copy image"));
if(imode==Pdf)
a_copy_text=popup.addAction(tr("copy text"));
else
a_copy_text=0;
a_clr_selection=popup.addAction(tr("clear selection"));
popup.addSeparator();
a_repaint=popup.addAction(tr("repaint"));
(a_sett=popup.addAction(QIcon(":/new/icons/icons/settings.png"),tr("settings")))->setCheckable(true);
_i_mode=imode;
}