You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
332 lines
7.4 KiB
332 lines
7.4 KiB
15 years ago
|
/*
|
||
|
* This file is part of the KDE libraries
|
||
|
* Copyright (c) 2001 Michael Goffioul <kdeprint@swing.be>
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU Library General Public
|
||
|
* License version 2 as published by the Free Software Foundation.
|
||
|
*
|
||
|
* This library 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
|
||
|
* Library General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU Library General Public License
|
||
|
* along with this library; see the file COPYING.LIB. If not, write to
|
||
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
* Boston, MA 02110-1301, USA.
|
||
|
**/
|
||
|
|
||
|
#include "marginpreview.h"
|
||
|
|
||
|
#include <klocale.h>
|
||
|
#include <kdebug.h>
|
||
|
#include <qpainter.h>
|
||
|
#include <kcursor.h>
|
||
|
|
||
|
#define A4_WIDTH 595
|
||
|
#define A4_HEIGHT 842
|
||
|
#define A4_TOP 36
|
||
|
#define A4_BOTTOM 806
|
||
|
#define A4_LEFT 18
|
||
|
#define A4_RIGHT 577
|
||
|
|
||
|
#define SCALE(d,z) ((int)(float(d)*z+0.5))
|
||
|
#define UNSCALE(d,z) ((int)(float(d)/z+0.5))
|
||
|
|
||
|
static void draw3DPage(QPainter *p, QRect r)
|
||
|
{
|
||
|
// draw white page
|
||
|
p->fillRect(r,Qt::white);
|
||
|
// draw 3D border
|
||
|
p->setPen(Qt::black);
|
||
|
p->moveTo(r.left(),r.bottom());
|
||
|
p->lineTo(r.right(),r.bottom());
|
||
|
p->lineTo(r.right(),r.top());
|
||
|
p->setPen(Qt::darkGray);
|
||
|
p->lineTo(r.left(),r.top());
|
||
|
p->lineTo(r.left(),r.bottom());
|
||
|
p->setPen(Qt::gray);
|
||
|
p->moveTo(r.left()+1,r.bottom()-1);
|
||
|
p->lineTo(r.right()-1,r.bottom()-1);
|
||
|
p->lineTo(r.right()-1,r.top()+1);
|
||
|
}
|
||
|
|
||
|
MarginPreview::MarginPreview(QWidget *parent, const char *name)
|
||
|
: QWidget(parent,name)
|
||
|
{
|
||
|
width_ = A4_WIDTH;
|
||
|
height_ = A4_HEIGHT;
|
||
|
top_ = A4_TOP;
|
||
|
bottom_ = A4_BOTTOM;
|
||
|
left_ = A4_LEFT;
|
||
|
right_ = A4_RIGHT;
|
||
|
nopreview_ = false;
|
||
|
|
||
|
box_ = rect();
|
||
|
zoom_ = 1.0;
|
||
|
state_ = Fixed;
|
||
|
oldpos_ = -1;
|
||
|
symetric_ = false;
|
||
|
|
||
|
setMouseTracking(true);
|
||
|
}
|
||
|
|
||
|
MarginPreview::~MarginPreview()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void MarginPreview::setPageSize(float w, float h)
|
||
|
{
|
||
|
setNoPreview(w <= 0 && h <= 0);
|
||
|
// do not change relative margins when changing page size !!
|
||
|
float old_b(height_-bottom_), old_r(width_-right_);
|
||
|
width_ = w;
|
||
|
height_ = h;
|
||
|
resizeEvent(NULL);
|
||
|
setMargins(top_,old_b,left_,old_r);
|
||
|
update();
|
||
|
}
|
||
|
|
||
|
void MarginPreview::setMargins(float t, float b, float l, float r)
|
||
|
{
|
||
|
top_ = t;
|
||
|
left_ = l;
|
||
|
bottom_ = height_-b;
|
||
|
right_ = width_-r;
|
||
|
update();
|
||
|
}
|
||
|
|
||
|
void MarginPreview::setSymetric(bool on)
|
||
|
{
|
||
|
symetric_ = on;
|
||
|
}
|
||
|
|
||
|
void MarginPreview::resizeEvent(QResizeEvent *)
|
||
|
{
|
||
|
if (width_/height_ > float(width())/height())
|
||
|
{
|
||
|
zoom_ = float(width()-3)/width_;
|
||
|
box_.setLeft(1);
|
||
|
box_.setRight(width()-3);
|
||
|
int m = (height()-3-SCALE(height_,zoom_))/2;
|
||
|
box_.setTop(m+1);
|
||
|
box_.setBottom(height()-m-3);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
zoom_ = float(height()-3)/height_;
|
||
|
box_.setTop(1);
|
||
|
box_.setBottom(height()-3);
|
||
|
int m = (width()-3-SCALE(width_,zoom_))/2;
|
||
|
box_.setLeft(m+1);
|
||
|
box_.setRight(width()-m-3);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void MarginPreview::paintEvent(QPaintEvent *)
|
||
|
{
|
||
|
QPainter p(this);
|
||
|
|
||
|
QRect pagebox(QPoint(box_.left()-1,box_.top()-1),QPoint(box_.right()+2,box_.bottom()+2));
|
||
|
|
||
|
if (nopreview_)
|
||
|
{
|
||
|
p.drawText(pagebox,AlignCenter,i18n("No preview available"));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
draw3DPage(&p,pagebox);
|
||
|
|
||
|
// draw margins
|
||
|
p.setPen(DotLine);
|
||
|
int m = box_.left()+SCALE(left_,zoom_);
|
||
|
margbox_.setLeft(m+1);
|
||
|
p.drawLine(m,box_.top(),m,box_.bottom());
|
||
|
m = box_.left()+SCALE(right_,zoom_);
|
||
|
margbox_.setRight(m-1);
|
||
|
p.drawLine(m,box_.top(),m,box_.bottom());
|
||
|
m = box_.top()+SCALE(top_,zoom_);
|
||
|
margbox_.setTop(m+1);
|
||
|
p.drawLine(box_.left(),m,box_.right(),m);
|
||
|
m = box_.top()+SCALE(bottom_,zoom_);
|
||
|
margbox_.setBottom(m-1);
|
||
|
p.drawLine(box_.left(),m,box_.right(),m);
|
||
|
|
||
|
// fill useful area
|
||
|
p.fillRect(margbox_,QColor(220,220,220));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void MarginPreview::setNoPreview(bool on)
|
||
|
{
|
||
|
nopreview_ = on;
|
||
|
update();
|
||
|
}
|
||
|
|
||
|
// 0: nothing
|
||
|
// 1: top
|
||
|
// 2: bottom
|
||
|
// 3: left
|
||
|
// 4: right
|
||
|
int MarginPreview::locateMouse(const QPoint& p)
|
||
|
{
|
||
|
int tol = 2;
|
||
|
if (p.x() <= margbox_.left()+tol && p.x() >= margbox_.left()-tol)
|
||
|
return LMoving;
|
||
|
else if (p.x() <= margbox_.right()+tol && p.x() >= margbox_.right()-tol)
|
||
|
return RMoving;
|
||
|
else if (p.y() <= margbox_.top()+tol && p.y() >= margbox_.top()-tol)
|
||
|
return TMoving;
|
||
|
else if (p.y() <= margbox_.bottom()+tol && p.y() >= margbox_.bottom()-tol)
|
||
|
return BMoving;
|
||
|
else
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void MarginPreview::mouseMoveEvent(QMouseEvent *e)
|
||
|
{
|
||
|
if (nopreview_ || state_ == Fixed)
|
||
|
return;
|
||
|
int pos = locateMouse(e->pos());
|
||
|
if (state_ == None && e->button() == Qt::NoButton)
|
||
|
{
|
||
|
switch (pos)
|
||
|
{
|
||
|
case 1:
|
||
|
case 2:
|
||
|
setCursor(KCursor::sizeVerCursor());
|
||
|
break;
|
||
|
case 3:
|
||
|
case 4:
|
||
|
setCursor(KCursor::sizeHorCursor());
|
||
|
break;
|
||
|
default:
|
||
|
setCursor(KCursor::arrowCursor());
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else if (state_ > None)
|
||
|
{
|
||
|
int newpos = -1;
|
||
|
switch (state_)
|
||
|
{
|
||
|
case TMoving:
|
||
|
newpos = QMIN(QMAX(e->pos().y(), box_.top()), (symetric_ ? (box_.top()+box_.bottom())/2 : margbox_.bottom()+1));
|
||
|
break;
|
||
|
case BMoving:
|
||
|
newpos = QMIN(QMAX(e->pos().y(), (symetric_? (box_.top()+box_.bottom()+1)/2 : margbox_.top()-1)), box_.bottom());
|
||
|
break;
|
||
|
case LMoving:
|
||
|
newpos = QMIN(QMAX(e->pos().x(), box_.left()), (symetric_ ? (box_.left()+box_.right())/2 : margbox_.right()+1));
|
||
|
break;
|
||
|
case RMoving:
|
||
|
newpos = QMIN(QMAX(e->pos().x(), (symetric_ ? (box_.left()+box_.right()+1)/2 : margbox_.left()-1)), box_.right());
|
||
|
break;
|
||
|
}
|
||
|
if (newpos != oldpos_)
|
||
|
{
|
||
|
QPainter p(this);
|
||
|
p.setRasterOp(Qt::XorROP);
|
||
|
p.setPen(gray);
|
||
|
for (int i=0; i<2; i++, oldpos_ = newpos)
|
||
|
{
|
||
|
if (oldpos_ >= 0)
|
||
|
drawTempLine(&p);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void MarginPreview::drawTempLine(QPainter *p)
|
||
|
{
|
||
|
if (state_ >= LMoving)
|
||
|
{
|
||
|
p->drawLine(oldpos_, box_.top(), oldpos_, box_.bottom());
|
||
|
if (symetric_)
|
||
|
{
|
||
|
int mirror = box_.left()+box_.right()-oldpos_;
|
||
|
p->drawLine(mirror, box_.top(), mirror, box_.bottom());
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
p->drawLine(box_.left(), oldpos_, box_.right(), oldpos_);
|
||
|
if (symetric_)
|
||
|
{
|
||
|
int mirror = box_.top()+box_.bottom()-oldpos_;
|
||
|
p->drawLine(box_.left(), mirror, box_.right(), mirror);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void MarginPreview::mousePressEvent(QMouseEvent *e)
|
||
|
{
|
||
|
if (e->button() != Qt::LeftButton || state_ != None)
|
||
|
return;
|
||
|
int mpos = locateMouse(e->pos());
|
||
|
if (mpos)
|
||
|
{
|
||
|
state_ = mpos;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void MarginPreview::mouseReleaseEvent(QMouseEvent *e)
|
||
|
{
|
||
|
if (state_ > None)
|
||
|
{
|
||
|
QPainter p(this);
|
||
|
p.setRasterOp(Qt::XorROP);
|
||
|
p.setPen(gray);
|
||
|
if (oldpos_ >= 0)
|
||
|
{
|
||
|
drawTempLine(&p);
|
||
|
if (e)
|
||
|
{
|
||
|
float val = 0;
|
||
|
int st(state_);
|
||
|
if (symetric_ && (st == BMoving || st == RMoving))
|
||
|
st--;
|
||
|
switch (st)
|
||
|
{
|
||
|
case TMoving:
|
||
|
val = top_ = UNSCALE(oldpos_-box_.top(), zoom_);
|
||
|
if (symetric_)
|
||
|
bottom_ = height_-top_;
|
||
|
break;
|
||
|
case BMoving:
|
||
|
bottom_ = UNSCALE(oldpos_-box_.top(), zoom_);
|
||
|
val = UNSCALE(box_.bottom()-oldpos_, zoom_);
|
||
|
break;
|
||
|
case LMoving:
|
||
|
val = left_ = UNSCALE(oldpos_-box_.left(), zoom_);
|
||
|
if (symetric_)
|
||
|
right_ = width_-left_;
|
||
|
break;
|
||
|
case RMoving:
|
||
|
right_ = UNSCALE(oldpos_-box_.left(), zoom_);
|
||
|
val = UNSCALE(box_.right()-oldpos_, zoom_);
|
||
|
break;
|
||
|
}
|
||
|
update();
|
||
|
emit marginChanged(st, val);
|
||
|
}
|
||
|
}
|
||
|
state_ = 0;
|
||
|
oldpos_ = -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void MarginPreview::enableRubberBand(bool on)
|
||
|
{
|
||
|
if (on && state_ == Fixed)
|
||
|
state_ = None;
|
||
|
else if (!on && state_ > Fixed)
|
||
|
{
|
||
|
mouseReleaseEvent(NULL);
|
||
|
state_ = Fixed;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#include "marginpreview.moc"
|