/* * This file is part of the KDE libraries * Copyright (c) 2001 Michael Goffioul * * 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 #include #include #include #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(TQPainter *p, TQRect 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(TQWidget *parent, const char *name) : TQWidget(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(TQResizeEvent *) { 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(TQPaintEvent *) { TQPainter p(this); TQRect pagebox(TQPoint(box_.left()-1,box_.top()-1),TQPoint(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_,TQColor(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 TQPoint& 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(TQMouseEvent *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 = TQMIN(TQMAX(e->pos().y(), box_.top()), (symetric_ ? (box_.top()+box_.bottom())/2 : margbox_.bottom()+1)); break; case BMoving: newpos = TQMIN(TQMAX(e->pos().y(), (symetric_? (box_.top()+box_.bottom()+1)/2 : margbox_.top()-1)), box_.bottom()); break; case LMoving: newpos = TQMIN(TQMAX(e->pos().x(), box_.left()), (symetric_ ? (box_.left()+box_.right())/2 : margbox_.right()+1)); break; case RMoving: newpos = TQMIN(TQMAX(e->pos().x(), (symetric_ ? (box_.left()+box_.right()+1)/2 : margbox_.left()-1)), box_.right()); break; } if (newpos != oldpos_) { TQPainter p(this); p.setRasterOp(TQt::XorROP); p.setPen(gray); for (int i=0; i<2; i++, oldpos_ = newpos) { if (oldpos_ >= 0) drawTempLine(&p); } } } } void MarginPreview::drawTempLine(TQPainter *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(TQMouseEvent *e) { if (e->button() != Qt::LeftButton || state_ != None) return; int mpos = locateMouse(e->pos()); if (mpos) { state_ = mpos; } } void MarginPreview::mouseReleaseEvent(TQMouseEvent *e) { if (state_ > None) { TQPainter p(this); p.setRasterOp(TQt::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"