99581bc990
- Updated header inclusions from QtGui to QtWidgets for consistency and compatibility with Qt 5 and later. - Replaced deprecated QApplication::desktop() with QApplication::primaryScreen() for obtaining screen DPI. - Modified MyOutputHandler to use QMessageLogContext and QString for improved logging. - Changed QMatrix to QTransform for image rotation in ImageCutout class. - Updated various debug statements to use toLocal8Bit() instead of toAscii() for better string handling. - Refactored several classes to use QElapsedTimer instead of QTime for performance measurement. - Ensured all operator overloads in Section and Tag classes are marked as const for better const-correctness.
543 lines
14 KiB
C++
543 lines
14 KiB
C++
/************************************************************************
|
|
* $Id: imagecutout.cpp 661 2011-04-05 13:16:53Z elzubeir $
|
|
*
|
|
* ------------
|
|
* Description:
|
|
* ------------
|
|
*
|
|
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
|
|
*
|
|
* -----------------
|
|
* Revision Details: (Updated by Revision Control System)
|
|
* -----------------
|
|
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
|
|
* $Author: elzubeir $
|
|
* $Revision: 661 $
|
|
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/imagecutout.cpp $
|
|
*
|
|
************************************************************************/
|
|
|
|
#include "imagecutout.h"
|
|
|
|
#include <QPen>
|
|
#include <QCursor>
|
|
#include <QGraphicsSceneMouseEvent>
|
|
#include <QApplication>
|
|
#include <QDrag>
|
|
#include <QMimeData>
|
|
#include <QPainter>
|
|
#include <QBitmap>
|
|
#include <QtDebug>
|
|
#include <QByteArray>
|
|
#include <QBuffer>
|
|
|
|
#include "fullpagescene.h"
|
|
|
|
int ImageCutout::totalCount = 0;
|
|
|
|
ImageCutout::ImageCutout(int id, const QPolygonF & selectionRect, qreal rotationAngle, QString pagename, SELECTION_AREA_TYPE selectionType, SELECTION_MODE mode, QGraphicsItem * parent) :
|
|
QGraphicsPolygonItem(parent),
|
|
m_id(id),
|
|
m_rotationAngle(rotationAngle),
|
|
m_pageName(pagename),
|
|
m_selectionType(selectionType),
|
|
m_mode(mode)
|
|
{
|
|
//image is color coded red //tim_tle is color coded bule //body is color coded green
|
|
QColor color = Qt::red;
|
|
if(m_selectionType == BODY)
|
|
color = Qt::green;
|
|
else if(m_selectionType == TITLE)
|
|
color = Qt::blue;
|
|
|
|
// color & styles
|
|
QPen pen(Qt::DashDotLine);
|
|
pen.setColor(color);
|
|
pen.setWidth(2);
|
|
setPen(pen);
|
|
|
|
QBrush m_brush;
|
|
m_brush.setStyle(Qt::Dense7Pattern);
|
|
m_brush.setColor(color);
|
|
setBrush(m_brush);
|
|
// size
|
|
m_rectangle = selectionRect.boundingRect().toRect();
|
|
setPolygon(selectionRect);
|
|
// zorder on top
|
|
setZValue(1.0);
|
|
|
|
setFlag(QGraphicsItem::ItemIsSelectable, true);
|
|
setFlag(QGraphicsItem::ItemIsFocusable,true);
|
|
|
|
m_isScreenshot = false;
|
|
m_tweaking = false;
|
|
m_tweakingpart = "";
|
|
|
|
m_orderTextItem = 0;
|
|
m_order = 0;
|
|
|
|
m_orderTextItem = new QGraphicsSimpleTextItem("", this);
|
|
|
|
QFont serifFont("Times", 60);
|
|
m_orderTextItem->setFont(serifFont);
|
|
m_orderTextItem->setPen( QPen( Qt::darkBlue, 3) );
|
|
m_orderTextItem->setBrush( Qt::darkBlue);
|
|
m_orderTextItem->setPos( m_rectangle.topLeft());
|
|
m_orderTextItem->setVisible(false);
|
|
}
|
|
|
|
ImageCutout::~ImageCutout()
|
|
{
|
|
if(m_orderTextItem)
|
|
delete m_orderTextItem;
|
|
m_orderTextItem = 0;
|
|
}
|
|
|
|
void ImageCutout::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|
{
|
|
if (m_mode != SELECT)
|
|
return;
|
|
|
|
if (event->button() != Qt::LeftButton)
|
|
{
|
|
event->ignore();
|
|
return;
|
|
}
|
|
|
|
checkBoundary(event->pos().toPoint(), true);
|
|
if(m_tweakingpart != "")
|
|
m_tweaking = true;
|
|
}
|
|
|
|
void ImageCutout::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|
{
|
|
if (m_mode != SELECT)
|
|
{
|
|
if(m_mode == ORDER)
|
|
setCursor( QCursor(Qt::PointingHandCursor) );
|
|
else
|
|
setCursor( QCursor(Qt::ArrowCursor) );
|
|
|
|
return;
|
|
}
|
|
|
|
if(m_orderTextItem)
|
|
m_orderTextItem->setVisible(false);
|
|
|
|
if(m_tweaking)
|
|
{
|
|
QPoint pt = event->pos().toPoint();
|
|
m_rectangle = this->boundingRect().toRect();
|
|
|
|
if ( m_tweakingpart == "topLeft" ) m_rectangle . setTopLeft ( pt ) ;
|
|
else if ( m_tweakingpart == "topRight" ) m_rectangle . setTopRight ( pt ) ;
|
|
else if ( m_tweakingpart == "bottomLeft" ) m_rectangle . setBottomLeft ( pt ) ;
|
|
else if ( m_tweakingpart == "bottomRight" ) m_rectangle . setBottomRight ( pt ) ;
|
|
else if ( m_tweakingpart == "top" ) m_rectangle . setTop ( pt . y () ) ;
|
|
else if ( m_tweakingpart == "bottom" ) m_rectangle . setBottom ( pt . y () ) ;
|
|
else if ( m_tweakingpart == "left" ) m_rectangle . setLeft ( pt . x () ) ;
|
|
else if ( m_tweakingpart == "right" ) m_rectangle . setRight ( pt . x () ) ;
|
|
|
|
update(m_rectangle);
|
|
}
|
|
else
|
|
{
|
|
QImage cutout = createCutout();
|
|
if (cutout.isNull())
|
|
return;
|
|
|
|
//qDebug() << "create image ...";
|
|
|
|
QDrag *drag = new QDrag(event->widget());
|
|
QMimeData *mime = new QMimeData;
|
|
|
|
QByteArray output;
|
|
QBuffer outputBuffer(&output);
|
|
outputBuffer.open(QIODevice::WriteOnly);
|
|
cutout.save(&outputBuffer, "jpg", 100);
|
|
mime->setData("image/jpg", output); //save a copy
|
|
|
|
drag->setMimeData(mime);
|
|
|
|
mime->setImageData(cutout);
|
|
|
|
qreal scale = (static_cast<FullPageScene*>(scene()) )->A4PageScale();
|
|
|
|
drag->setPixmap(QPixmap::fromImage(cutout).scaledToWidth( cutout.width()*scale) );
|
|
//drag->setPixmap(selectedImage);
|
|
drag->setHotSpot(QPoint(0,0));
|
|
|
|
drag->exec();
|
|
}
|
|
}
|
|
|
|
void ImageCutout::mouseReleaseEvent(QGraphicsSceneMouseEvent *)
|
|
{
|
|
if(m_mode == VIEW)
|
|
return;
|
|
|
|
if(m_mode == ORDER)
|
|
{
|
|
orderItems();
|
|
return;
|
|
}
|
|
|
|
m_tweaking = false ;
|
|
m_tweakingpart = "" ;
|
|
//this -> unsetCursor () ;
|
|
setCursor(QCursor(Qt::OpenHandCursor));
|
|
|
|
m_rectangle = m_rectangle.normalized();
|
|
|
|
update(this->boundingRect().toRect());
|
|
|
|
if(m_orderTextItem)
|
|
m_orderTextItem->setPos( m_orderTextItem->mapToParent(0, 0) );
|
|
}
|
|
|
|
QImage ImageCutout::createCutout() const
|
|
{
|
|
if(m_mode != SELECT)
|
|
return QImage();
|
|
|
|
// get selection rect in scene coordinates.
|
|
QRectF sceneRect = mapRectToScene(boundingRect());
|
|
// convert the scene coordinates to item coordinates.
|
|
QPointF topLeftCorner = static_cast<FullPageScene*>(scene())->mapToImageItem(QPointF(sceneRect.left(), sceneRect.top()));
|
|
QPointF bottomRightCorner = static_cast<FullPageScene*>(scene())->mapToImageItem(QPointF(sceneRect.right(), sceneRect.bottom()));
|
|
// exm_tract the selection fragment from the pixmap.
|
|
QPixmap px = static_cast<FullPageScene*>(scene())->getImageCutoutPixmap(QRectF(topLeftCorner, bottomRightCorner));
|
|
if (!px.isNull())
|
|
{
|
|
// after calculating the pixmap, we rotate it if needed
|
|
QImage image = px.toImage();
|
|
QTransform mx;
|
|
mx = mx.rotate(m_rotationAngle);
|
|
// mx = mx.scale(.5, .5); //dont do this
|
|
image = image.transformed(mx);
|
|
return image;
|
|
}
|
|
return QImage();
|
|
}
|
|
|
|
void ImageCutout::keyPressEvent(QKeyEvent *key)
|
|
{
|
|
if(m_mode != SELECT)
|
|
return;
|
|
|
|
if(key->key() == Qt::Key_I)
|
|
m_selectionType = IMAGE;
|
|
else if(key->key() == Qt::Key_T)
|
|
m_selectionType = TITLE;
|
|
else if(key->key() == Qt::Key_B)
|
|
m_selectionType = BODY;
|
|
else if(key->key() == Qt::Key_Delete)
|
|
{
|
|
decreaseOrderByOne(m_order);
|
|
//staticCount--;
|
|
static_cast<FullPageScene*>(scene())->removeImageCutout(this);
|
|
//scene()->removeItem(this);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
QGraphicsPolygonItem::keyPressEvent(key);
|
|
return;
|
|
}
|
|
|
|
scene()->update(sceneBoundingRect());
|
|
//update();
|
|
}
|
|
|
|
bool ImageCutout::operator == (const ImageCutout & cutout)
|
|
{
|
|
return this->boundingRect() == cutout.boundingRect();
|
|
}
|
|
|
|
void ImageCutout::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget */*widget*/)
|
|
{
|
|
painter->setClipRect(option->exposedRect);
|
|
|
|
QColor color = Qt::yellow;
|
|
if(m_selectionType == IMAGE)
|
|
color = Qt::red;
|
|
if(m_selectionType == BODY)
|
|
color = Qt::green;
|
|
else if(m_selectionType == TITLE)
|
|
color = Qt::blue;
|
|
|
|
QPen pen(Qt::NoPen);
|
|
|
|
if(m_mode == VIEW)
|
|
pen.setStyle(Qt::SolidLine);
|
|
|
|
pen.setColor(color);
|
|
pen.setWidth(2);
|
|
|
|
painter->setPen(pen);
|
|
|
|
QBrush m_brush;
|
|
if (m_mode == VIEW)
|
|
{
|
|
m_brush.setStyle(Qt::NoBrush);
|
|
this->setSelected(false);
|
|
}
|
|
else
|
|
{
|
|
m_brush.setStyle(Qt::SolidPattern);
|
|
if(m_isScreenshot)
|
|
{
|
|
this->setOpacity(.7);
|
|
this->setSelected(false);
|
|
}
|
|
else
|
|
this->setOpacity(.2);
|
|
}
|
|
|
|
if(m_orderTextItem)
|
|
{
|
|
if(m_mode == ORDER)
|
|
{
|
|
QString text = QString("%1").arg(m_order);
|
|
m_orderTextItem->setText(text);
|
|
m_orderTextItem->setPos( boundingRect().topLeft() );
|
|
m_orderTextItem->setVisible(true);
|
|
}
|
|
else
|
|
m_orderTextItem->setVisible(false);
|
|
}
|
|
|
|
m_brush.setColor(color);
|
|
painter->setBrush(m_brush);
|
|
|
|
QPolygon ply(m_rectangle, true);
|
|
setPolygon(ply);
|
|
|
|
painter->drawPolygon(polygon(), fillRule());
|
|
scene()->update(sceneBoundingRect());
|
|
}
|
|
|
|
int ImageCutout::id()
|
|
{
|
|
return m_id;
|
|
}
|
|
|
|
QString ImageCutout::pageName()
|
|
{
|
|
return m_pageName;
|
|
}
|
|
|
|
int ImageCutout::pageNumber()
|
|
{
|
|
QString page = m_pageName;
|
|
int index = page.lastIndexOf("/");
|
|
int pagenumber = page.right(page.length()-index-1).replace(".jpg", "").toInt();
|
|
return pagenumber;
|
|
}
|
|
|
|
int ImageCutout::sectionNumber()
|
|
{
|
|
QString page = m_pageName;
|
|
int index = page.lastIndexOf("/");
|
|
int index2 = page.lastIndexOf("/", index-1);
|
|
int id_section = page.mid(index2+1, abs(index2-index)-1).toInt();
|
|
return id_section;
|
|
}
|
|
|
|
int ImageCutout::areaType()
|
|
{
|
|
return static_cast<int> (m_selectionType);
|
|
}
|
|
|
|
void ImageCutout::setScreenshot(bool screenshot)
|
|
{
|
|
m_isScreenshot = screenshot;
|
|
update(this->boundingRect().toRect());
|
|
}
|
|
|
|
void ImageCutout::checkBoundary(QPoint pt, bool t)
|
|
{
|
|
if(m_mode == VIEW)
|
|
return;
|
|
|
|
m_rectangle = this->boundingRect().toRect();
|
|
|
|
if ( m_rectangle.isValid() )
|
|
{
|
|
QPoint m_tl = m_rectangle.topLeft();
|
|
QPoint m_tr = m_rectangle.topRight();
|
|
QPoint m_bl = m_rectangle.bottomLeft();
|
|
QPoint m_br = m_rectangle.bottomRight();
|
|
|
|
const QPoint off(20, 20), offx(20, -20), offy(-20, 20);
|
|
|
|
if ( QRect(m_tl-off,m_tl+off).contains(pt) )
|
|
{
|
|
if (t)
|
|
m_tweakingpart = "topLeft";
|
|
this->setCursor( Qt::SizeFDiagCursor ) ;
|
|
}
|
|
else if( QRect(m_tr-off, m_tr+off).contains(pt) )
|
|
{
|
|
if (t)
|
|
m_tweakingpart = "topRight";
|
|
this->setCursor( Qt::SizeBDiagCursor ) ;
|
|
}
|
|
else if( QRect( m_bl-off, m_bl+off ).contains(pt) )
|
|
{
|
|
if (t)
|
|
m_tweakingpart = "bottomLeft";
|
|
this->setCursor( Qt::SizeBDiagCursor) ;
|
|
}
|
|
else if( QRect( m_br-off, m_br+off).contains(pt) )
|
|
{
|
|
if (t)
|
|
m_tweakingpart = "bottomRight" ;
|
|
this->setCursor( Qt::SizeFDiagCursor );
|
|
}
|
|
else if( QRect( m_tl+offx, m_tr-offx ).contains(pt) )
|
|
{
|
|
if (t)
|
|
m_tweakingpart = "top";
|
|
this->setCursor( Qt::SizeVerCursor ) ;
|
|
}
|
|
else if( QRect( m_bl+offx, m_br-offx ).contains(pt) )
|
|
{
|
|
if (t)
|
|
m_tweakingpart = "bottom";
|
|
this->setCursor( Qt::SizeVerCursor ) ;
|
|
}
|
|
else if( QRect( m_tl+offy, m_bl-offy ).contains(pt) )
|
|
{
|
|
if (t)
|
|
m_tweakingpart = "left";
|
|
this->setCursor( Qt::SizeHorCursor ) ;
|
|
}
|
|
else if( QRect( m_tr+offy, m_br-offy ).contains(pt) )
|
|
{
|
|
if (t)
|
|
m_tweakingpart = "right";
|
|
this->setCursor( Qt::SizeHorCursor );
|
|
}
|
|
else
|
|
this->setCursor( Qt::OpenHandCursor );
|
|
}
|
|
}
|
|
|
|
QRectF ImageCutout::boundingRect() const
|
|
{
|
|
return QRectF(m_rectangle);
|
|
}
|
|
|
|
QString ImageCutout::pages(QList<ImageCutout*> &list)
|
|
{
|
|
if (list.count() <= 0 )
|
|
return "";
|
|
|
|
QStringList names;
|
|
QStringList fullnamesList;
|
|
|
|
for(int i=0; i< list.count() ; i++)
|
|
{
|
|
QString page = list[i]->pageName();
|
|
if ( !fullnamesList.contains(page) )
|
|
{
|
|
fullnamesList.append(page);
|
|
int index = page.lastIndexOf("/");
|
|
QString name = page.right(page.length()-index-1).replace(".jpg", "");
|
|
int number = name.toInt();
|
|
name = QString("%1").arg(number);
|
|
names.append(name);
|
|
}
|
|
}
|
|
|
|
return names.join(",");
|
|
}
|
|
|
|
QStringList ImageCutout::fullPages(QList<ImageCutout*> &list)
|
|
{
|
|
QStringList fullnamesList;
|
|
if (list.count() <= 0 )
|
|
return fullnamesList;
|
|
|
|
for(int i=0; i< list.count() ; i++)
|
|
{
|
|
QString page = list[i]->pageName();
|
|
if ( !fullnamesList.contains(page) )
|
|
fullnamesList.append(page);
|
|
}
|
|
return fullnamesList;
|
|
}
|
|
|
|
void ImageCutout::decreaseOrderByOne(int greaterThanOrder)
|
|
{
|
|
QList<ImageCutout*> list = static_cast<FullPageScene*> (scene() )->imageCutoutsList();
|
|
foreach (ImageCutout *cutout, list)
|
|
{
|
|
if(cutout->order() >= greaterThanOrder)
|
|
cutout->setOrder(cutout->order()-1);
|
|
}
|
|
}
|
|
|
|
void ImageCutout::orderItems()
|
|
{
|
|
FullPageScene *fullpageScene = static_cast<FullPageScene*> (scene() );
|
|
QList<ImageCutout*> list = fullpageScene->imageCutoutsList();
|
|
ImageCutout * firstItem = 0;
|
|
foreach (ImageCutout *cutout, list)
|
|
{
|
|
if(cutout->order() == fullpageScene->currentOrder() )
|
|
{
|
|
fullpageScene->increaseCurrentOrder();
|
|
firstItem = cutout;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//swap between the 2 m_orderTextItems
|
|
int firstOrder = firstItem->order();
|
|
int secondOrder= this->order();
|
|
|
|
this->setOrder(firstOrder);
|
|
firstItem->setOrder(secondOrder);
|
|
|
|
this->update(this->boundingRect());
|
|
firstItem->update(firstItem->boundingRect());
|
|
}
|
|
|
|
void ImageCutout::setMode(SELECTION_MODE mode)
|
|
{
|
|
m_mode = mode;
|
|
update(this->boundingRect().toRect());
|
|
}
|
|
|
|
void ImageCutout::setOrder(int order)
|
|
{
|
|
m_order = order;
|
|
}
|
|
|
|
int ImageCutout::order()
|
|
{
|
|
return m_order;
|
|
}
|
|
|
|
int ImageCutout::getTotalCount()
|
|
{
|
|
return totalCount;
|
|
}
|
|
|
|
void ImageCutout::setTotalCount(int count)
|
|
{
|
|
totalCount = count;
|
|
}
|
|
|
|
void ImageCutout::incrementTotalCount()
|
|
{
|
|
totalCount++;
|
|
}
|
|
|
|
void ImageCutout::decrementTotalCount()
|
|
{
|
|
totalCount--;
|
|
}
|