00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "marginpreview.h"
00021
00022 #include <klocale.h>
00023 #include <kdebug.h>
00024 #include <qpainter.h>
00025 #include <kcursor.h>
00026
00027 #define A4_WIDTH 595
00028 #define A4_HEIGHT 842
00029 #define A4_TOP 36
00030 #define A4_BOTTOM 806
00031 #define A4_LEFT 18
00032 #define A4_RIGHT 577
00033
00034 #define SCALE(d,z) ((int)(float(d)*z+0.5))
00035 #define UNSCALE(d,z) ((int)(float(d)/z+0.5))
00036
00037 static void draw3DPage(QPainter *p, QRect r)
00038 {
00039
00040 p->fillRect(r,Qt::white);
00041
00042 p->setPen(Qt::black);
00043 p->moveTo(r.left(),r.bottom());
00044 p->lineTo(r.right(),r.bottom());
00045 p->lineTo(r.right(),r.top());
00046 p->setPen(Qt::darkGray);
00047 p->lineTo(r.left(),r.top());
00048 p->lineTo(r.left(),r.bottom());
00049 p->setPen(Qt::gray);
00050 p->moveTo(r.left()+1,r.bottom()-1);
00051 p->lineTo(r.right()-1,r.bottom()-1);
00052 p->lineTo(r.right()-1,r.top()+1);
00053 }
00054
00055 MarginPreview::MarginPreview(QWidget *parent, const char *name)
00056 : QWidget(parent,name)
00057 {
00058 width_ = A4_WIDTH;
00059 height_ = A4_HEIGHT;
00060 top_ = A4_TOP;
00061 bottom_ = A4_BOTTOM;
00062 left_ = A4_LEFT;
00063 right_ = A4_RIGHT;
00064 nopreview_ = false;
00065
00066 box_ = rect();
00067 zoom_ = 1.0;
00068 state_ = Fixed;
00069 oldpos_ = -1;
00070 symetric_ = false;
00071
00072 setMouseTracking(true);
00073 }
00074
00075 MarginPreview::~MarginPreview()
00076 {
00077 }
00078
00079 void MarginPreview::setPageSize(float w, float h)
00080 {
00081 setNoPreview(w <= 0 && h <= 0);
00082
00083 float old_b(height_-bottom_), old_r(width_-right_);
00084 width_ = w;
00085 height_ = h;
00086 resizeEvent(NULL);
00087 setMargins(top_,old_b,left_,old_r);
00088 update();
00089 }
00090
00091 void MarginPreview::setMargins(float t, float b, float l, float r)
00092 {
00093 top_ = t;
00094 left_ = l;
00095 bottom_ = height_-b;
00096 right_ = width_-r;
00097 update();
00098 }
00099
00100 void MarginPreview::setSymetric(bool on)
00101 {
00102 symetric_ = on;
00103 }
00104
00105 void MarginPreview::resizeEvent(QResizeEvent *)
00106 {
00107 if (width_/height_ > float(width())/height())
00108 {
00109 zoom_ = float(width()-3)/width_;
00110 box_.setLeft(1);
00111 box_.setRight(width()-3);
00112 int m = (height()-3-SCALE(height_,zoom_))/2;
00113 box_.setTop(m+1);
00114 box_.setBottom(height()-m-3);
00115 }
00116 else
00117 {
00118 zoom_ = float(height()-3)/height_;
00119 box_.setTop(1);
00120 box_.setBottom(height()-3);
00121 int m = (width()-3-SCALE(width_,zoom_))/2;
00122 box_.setLeft(m+1);
00123 box_.setRight(width()-m-3);
00124 }
00125 }
00126
00127 void MarginPreview::paintEvent(QPaintEvent *)
00128 {
00129 QPainter p(this);
00130
00131 QRect pagebox(QPoint(box_.left()-1,box_.top()-1),QPoint(box_.right()+2,box_.bottom()+2));
00132
00133 if (nopreview_)
00134 {
00135 p.drawText(pagebox,AlignCenter,i18n("No preview available"));
00136 }
00137 else
00138 {
00139 draw3DPage(&p,pagebox);
00140
00141
00142 p.setPen(DotLine);
00143 int m = box_.left()+SCALE(left_,zoom_);
00144 margbox_.setLeft(m+1);
00145 p.drawLine(m,box_.top(),m,box_.bottom());
00146 m = box_.left()+SCALE(right_,zoom_);
00147 margbox_.setRight(m-1);
00148 p.drawLine(m,box_.top(),m,box_.bottom());
00149 m = box_.top()+SCALE(top_,zoom_);
00150 margbox_.setTop(m+1);
00151 p.drawLine(box_.left(),m,box_.right(),m);
00152 m = box_.top()+SCALE(bottom_,zoom_);
00153 margbox_.setBottom(m-1);
00154 p.drawLine(box_.left(),m,box_.right(),m);
00155
00156
00157 p.fillRect(margbox_,QColor(220,220,220));
00158 }
00159 }
00160
00161 void MarginPreview::setNoPreview(bool on)
00162 {
00163 nopreview_ = on;
00164 update();
00165 }
00166
00167
00168
00169
00170
00171
00172 int MarginPreview::locateMouse(const QPoint& p)
00173 {
00174 int tol = 2;
00175 if (p.x() <= margbox_.left()+tol && p.x() >= margbox_.left()-tol)
00176 return LMoving;
00177 else if (p.x() <= margbox_.right()+tol && p.x() >= margbox_.right()-tol)
00178 return RMoving;
00179 else if (p.y() <= margbox_.top()+tol && p.y() >= margbox_.top()-tol)
00180 return TMoving;
00181 else if (p.y() <= margbox_.bottom()+tol && p.y() >= margbox_.bottom()-tol)
00182 return BMoving;
00183 else
00184 return 0;
00185 }
00186
00187 void MarginPreview::mouseMoveEvent(QMouseEvent *e)
00188 {
00189 if (nopreview_ || state_ == Fixed)
00190 return;
00191 int pos = locateMouse(e->pos());
00192 if (state_ == None && e->button() == Qt::NoButton)
00193 {
00194 switch (pos)
00195 {
00196 case 1:
00197 case 2:
00198 setCursor(KCursor::sizeVerCursor());
00199 break;
00200 case 3:
00201 case 4:
00202 setCursor(KCursor::sizeHorCursor());
00203 break;
00204 default:
00205 setCursor(KCursor::arrowCursor());
00206 break;
00207 }
00208 }
00209 else if (state_ > None)
00210 {
00211 int newpos = -1;
00212 switch (state_)
00213 {
00214 case TMoving:
00215 newpos = QMIN(QMAX(e->pos().y(), box_.top()), (symetric_ ? (box_.top()+box_.bottom())/2 : margbox_.bottom()+1));
00216 break;
00217 case BMoving:
00218 newpos = QMIN(QMAX(e->pos().y(), (symetric_? (box_.top()+box_.bottom()+1)/2 : margbox_.top()-1)), box_.bottom());
00219 break;
00220 case LMoving:
00221 newpos = QMIN(QMAX(e->pos().x(), box_.left()), (symetric_ ? (box_.left()+box_.right())/2 : margbox_.right()+1));
00222 break;
00223 case RMoving:
00224 newpos = QMIN(QMAX(e->pos().x(), (symetric_ ? (box_.left()+box_.right()+1)/2 : margbox_.left()-1)), box_.right());
00225 break;
00226 }
00227 if (newpos != oldpos_)
00228 {
00229 QPainter p(this);
00230 p.setRasterOp(Qt::XorROP);
00231 p.setPen(gray);
00232 for (int i=0; i<2; i++, oldpos_ = newpos)
00233 {
00234 if (oldpos_ >= 0)
00235 drawTempLine(&p);
00236 }
00237 }
00238 }
00239 }
00240
00241 void MarginPreview::drawTempLine(QPainter *p)
00242 {
00243 if (state_ >= LMoving)
00244 {
00245 p->drawLine(oldpos_, box_.top(), oldpos_, box_.bottom());
00246 if (symetric_)
00247 {
00248 int mirror = box_.left()+box_.right()-oldpos_;
00249 p->drawLine(mirror, box_.top(), mirror, box_.bottom());
00250 }
00251 }
00252 else
00253 {
00254 p->drawLine(box_.left(), oldpos_, box_.right(), oldpos_);
00255 if (symetric_)
00256 {
00257 int mirror = box_.top()+box_.bottom()-oldpos_;
00258 p->drawLine(box_.left(), mirror, box_.right(), mirror);
00259 }
00260 }
00261 }
00262
00263 void MarginPreview::mousePressEvent(QMouseEvent *e)
00264 {
00265 if (e->button() != Qt::LeftButton || state_ != None)
00266 return;
00267 int mpos = locateMouse(e->pos());
00268 if (mpos)
00269 {
00270 state_ = mpos;
00271 }
00272 }
00273
00274 void MarginPreview::mouseReleaseEvent(QMouseEvent *e)
00275 {
00276 if (state_ > None)
00277 {
00278 QPainter p(this);
00279 p.setRasterOp(Qt::XorROP);
00280 p.setPen(gray);
00281 if (oldpos_ >= 0)
00282 {
00283 drawTempLine(&p);
00284 if (e)
00285 {
00286 float val = 0;
00287 int st(state_);
00288 if (symetric_ && (st == BMoving || st == RMoving))
00289 st--;
00290 switch (st)
00291 {
00292 case TMoving:
00293 val = top_ = UNSCALE(oldpos_-box_.top(), zoom_);
00294 if (symetric_)
00295 bottom_ = height_-top_;
00296 break;
00297 case BMoving:
00298 bottom_ = UNSCALE(oldpos_-box_.top(), zoom_);
00299 val = UNSCALE(box_.bottom()-oldpos_, zoom_);
00300 break;
00301 case LMoving:
00302 val = left_ = UNSCALE(oldpos_-box_.left(), zoom_);
00303 if (symetric_)
00304 right_ = width_-left_;
00305 break;
00306 case RMoving:
00307 right_ = UNSCALE(oldpos_-box_.left(), zoom_);
00308 val = UNSCALE(box_.right()-oldpos_, zoom_);
00309 break;
00310 }
00311 update();
00312 emit marginChanged(st, val);
00313 }
00314 }
00315 state_ = 0;
00316 oldpos_ = -1;
00317 }
00318 }
00319
00320 void MarginPreview::enableRubberBand(bool on)
00321 {
00322 if (on && state_ == Fixed)
00323 state_ = None;
00324 else if (!on && state_ > Fixed)
00325 {
00326 mouseReleaseEvent(NULL);
00327 state_ = Fixed;
00328 }
00329 }
00330
00331 #include "marginpreview.moc"