summaryrefslogtreecommitdiffstats
path: root/kdeprint/marginpreview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kdeprint/marginpreview.cpp')
-rw-r--r--kdeprint/marginpreview.cpp331
1 files changed, 331 insertions, 0 deletions
diff --git a/kdeprint/marginpreview.cpp b/kdeprint/marginpreview.cpp
new file mode 100644
index 000000000..2190b4958
--- /dev/null
+++ b/kdeprint/marginpreview.cpp
@@ -0,0 +1,331 @@
+/*
+ * 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"