1 /****************************************************************************
2 **
3 ** This file is part of the LibreCAD project, a 2D CAD program
4 **
5 ** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
6 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
7 **
8 **
9 ** This file may be distributed and/or modified under the terms of the
10 ** GNU General Public License version 2 as published by the Free Software
11 ** Foundation and appearing in the file gpl-2.0.txt included in the
12 ** packaging of this file.
13 **
14 ** This program is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ** GNU General Public License for more details.
18 **
19 ** You should have received a copy of the GNU General Public License
20 ** along with this program; if not, write to the Free Software
21 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 **
23 ** This copyright notice MUST APPEAR in all copies of the script!
24 **
25 **********************************************************************/
26 #include<cmath>
27 #include "rs_actionprintpreview.h"
28 
29 #include <QAction>
30 #include <QMouseEvent>
31 #include "rs_dialogfactory.h"
32 #include "rs_graphicview.h"
33 #include "rs_graphic.h"
34 #include "rs_commandevent.h"
35 #include "rs_coordinateevent.h"
36 #include "rs_math.h"
37 #include "rs_preview.h"
38 #include "rs_settings.h"
39 
40 struct RS_ActionPrintPreview::Points {
41 	RS_Vector v1;
42 	RS_Vector v2;
43 };
44 
45 /**
46  * Constructor.
47  */
RS_ActionPrintPreview(RS_EntityContainer & container,RS_GraphicView & graphicView)48 RS_ActionPrintPreview::RS_ActionPrintPreview(RS_EntityContainer& container,
49                                              RS_GraphicView& graphicView)
50     :RS_ActionInterface("Print Preview",
51 						container, graphicView)
52 	, hasOptions(false)
53 	, m_bPaperOffset(false)
54 	, pPoints(new Points{})
55 {
56     actionType=RS2::ActionFilePrintPreview;
57     RS_SETTINGS->beginGroup("/PrintPreview");
58     bool fixed = (RS_SETTINGS->readNumEntry("/PrintScaleFixed", 0) != 0);
59     RS_SETTINGS->endGroup();
60     setPaperScaleFixed(fixed);
61     showOptions();
62 }
63 
64 RS_ActionPrintPreview::~RS_ActionPrintPreview()=default;
65 
init(int status)66 void RS_ActionPrintPreview::init(int status) {
67     RS_ActionInterface::init(status);
68     showOptions();
69 }
70 
mouseMoveEvent(QMouseEvent * e)71 void RS_ActionPrintPreview::mouseMoveEvent(QMouseEvent* e) {
72     switch (getStatus()) {
73     case Moving:
74 		pPoints->v2 = graphicView->toGraph(e->x(), e->y());
75 		// if Shift is pressed the paper moves only horizontally
76 		if (e->modifiers() & Qt::ShiftModifier)
77 			pPoints->v2.y = pPoints->v1.y;
78 		// if Ctrl is pressed the paper moves only vertically
79 		if (e->modifiers() & Qt::ControlModifier)
80 			pPoints->v2.x = pPoints->v1.x;
81         if (graphic) {
82             RS_Vector pinsbase = graphic->getPaperInsertionBase();
83 
84             double scale = graphic->getPaperScale();
85 
86 			graphic->setPaperInsertionBase(pinsbase-pPoints->v2*scale+pPoints->v1*scale);
87         }
88 		pPoints->v1 = pPoints->v2;
89         graphicView->redraw(RS2::RedrawGrid); // DRAW Grid also draws paper, background items
90         break;
91 
92     default:
93         break;
94     }
95 }
96 
97 
98 
mousePressEvent(QMouseEvent * e)99 void RS_ActionPrintPreview::mousePressEvent(QMouseEvent* e) {
100     if (e->button()==Qt::LeftButton) {
101         switch (getStatus()) {
102         case Neutral:
103 			pPoints->v1 = graphicView->toGraph(e->x(), e->y());
104             setStatus(Moving);
105             break;
106 
107         default:
108             break;
109         }
110     }
111 }
112 
113 
mouseReleaseEvent(QMouseEvent * e)114 void RS_ActionPrintPreview::mouseReleaseEvent(QMouseEvent* e) {
115     switch (getStatus()) {
116     case Moving:
117         setStatus(Neutral);
118         break;
119 
120     default:
121         e->accept();
122         break;
123     }
124 }
125 
126 
127 
coordinateEvent(RS_CoordinateEvent * e)128 void RS_ActionPrintPreview::coordinateEvent(RS_CoordinateEvent* e) {
129     RS_Vector pinsbase = graphic->getPaperInsertionBase();
130     RS_Vector mouse = e->getCoordinate();
131 //    qDebug()<<"coordinateEvent= ("<<mouse.x<<", "<<mouse.y<<")";
132 
133     if(m_bPaperOffset) {
134         RS_DIALOGFACTORY->commandMessage(tr("Printout offset in paper coordinates by (%1, %2)").arg(mouse.x).arg(mouse.y));
135         mouse *= graphic->getPaperScale();
136     }else
137         RS_DIALOGFACTORY->commandMessage(tr("Printout offset in graph coordinates by (%1, %2)").arg(mouse.x).arg(mouse.y));
138 
139 //    RS_DIALOGFACTORY->commandMessage(tr("old insertion base (%1, %2)").arg(pinsbase.x).arg(pinsbase.y));
140 //    RS_DIALOGFACTORY->commandMessage(tr("new insertion base (%1, %2)").arg((pinsbase-mouse).x).arg((pinsbase-mouse).y));
141 
142     graphic->setPaperInsertionBase(pinsbase-mouse);
143     graphicView->redraw(RS2::RedrawGrid); // DRAW Grid also draws paper, background items
144 
145 }
146 
147 
148 
commandEvent(RS_CommandEvent * e)149 void RS_ActionPrintPreview::commandEvent(RS_CommandEvent*  e) {
150     QString c = e->getCommand().trimmed().toLower();
151 //    qDebug()<<"cmd="<<c;
152 	if (checkCommand("blackwhite", c)) {
153 		setBlackWhite(true);
154 		RS_DIALOGFACTORY->commandMessage(tr("Printout in Black/White"));
155 		e->accept();
156 		return;
157 	} else if (checkCommand("color", c)) {
158 		setBlackWhite(false);
159 		RS_DIALOGFACTORY->commandMessage(tr("Printout in color"));
160 		e->accept();
161 		return;
162 	} else if (checkCommand("graphoffset", c)) {
163         m_bPaperOffset=false;
164         RS_DIALOGFACTORY->commandMessage(tr("Printout offset in graph coordinates"));
165         e->accept();
166         return;
167     } else if (checkCommand("paperoffset", c)) {
168         m_bPaperOffset=true;
169         RS_DIALOGFACTORY->commandMessage(tr("Printout offset in paper coordinates"));
170         e->accept();
171         return;
172     }else if (checkCommand("help", c)) {
173         RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
174                                          + getAvailableCommands().join(", ")+tr(": select printout offset coordinates")+
175                                          "\n"+tr("type in offset from command line to offset printout")
176                                          );
177         e->accept();
178         return;
179     }
180     //coordinate event
181     if (c.contains(',')){
182         if(c.startsWith('@')) {
183             RS_DIALOGFACTORY->commandMessage(tr("Printout offset ignores relative zero. Ignoring '@'"));
184             c.remove(0, 1);
185         }
186 //        qDebug()<<"offset by absolute coordinate: ";
187 
188         const int commaPos = c.indexOf(',');
189         bool ok1, ok2;
190         double x = RS_Math::eval(c.left(commaPos), &ok1);
191         double y = RS_Math::eval(c.mid(commaPos+1), &ok2);
192         if (ok1 && ok2) {
193             RS_CoordinateEvent ce(RS_Vector(x,y));
194             this->coordinateEvent(&ce);
195             e->accept();
196         }
197     }
198 }
199 
200 
201 
getAvailableCommands()202 QStringList RS_ActionPrintPreview::getAvailableCommands() {
203     QStringList cmd;
204 	cmd +=command("blackwhite");
205 	cmd +=command("color");
206 	cmd +=command("graphoffset");
207     cmd +=command("paperoffset");
208     cmd +=command("help");
209     return cmd;
210 }
211 
resume()212 void RS_ActionPrintPreview::resume() {
213     RS_ActionInterface::resume();
214 }
215 
216 //printout warning in command widget
printWarning(const QString & s)217 void RS_ActionPrintPreview::printWarning(const QString& s) {
218 	RS_DIALOGFACTORY->commandMessage(s);
219 }
220 
showOptions()221 void RS_ActionPrintPreview::showOptions() {
222     RS_ActionInterface::showOptions();
223 	if (!isFinished()) {
224         RS_DIALOGFACTORY->requestOptions(this, true,hasOptions);
225         hasOptions=true;
226     }
227 }
228 
229 
230 
hideOptions()231 void RS_ActionPrintPreview::hideOptions() {
232     RS_ActionInterface::hideOptions();
233 
234     RS_DIALOGFACTORY->requestOptions(this, false);
235 }
236 
updateMouseCursor()237 void RS_ActionPrintPreview::updateMouseCursor() {
238     switch (getStatus()){
239     case Moving:
240         graphicView->setMouseCursor(RS2::ClosedHandCursor);
241         break;
242     default:
243         graphicView->setMouseCursor(RS2::OpenHandCursor);
244     }
245 }
246 
center()247 void RS_ActionPrintPreview::center() {
248     if (graphic) {
249         graphic->centerToPage();
250         graphicView->zoomPage();
251         graphicView->redraw();
252     }
253 }
254 
255 
fit()256 void RS_ActionPrintPreview::fit() {
257     if (graphic) {
258         RS_Vector&& paperSize=RS_Units::convert(graphic->getPaperSize(),
259                                                 RS2::Millimeter, getUnit());
260 
261         if(fabs(paperSize.x)<10.|| fabs(paperSize.y)<10.)
262             printWarning("Warning:: Paper size less than 10mm."
263                          " Paper is too small for fitting to page\n"
264                          "Please set paper size by Menu: Edit->Current Drawing Preferences->Paper");
265         //        double f0=graphic->getPaperScale();
266 		if ( graphic->fitToPage()==false) {
267             RS_DIALOGFACTORY->commandMessage(
268                         tr("RS_ActionPrintPreview::fit(): Invalid paper size")
269                         );
270         }
271         //        if(fabs(f0-graphic->getPaperScale())>RS_TOLERANCE){
272         //only zoomPage when scale changed
273         //        }
274         graphic->centerToPage();
275         graphicView->zoomPage();
276         graphicView->redraw();
277     }
278 }
279 
setScale(double f,bool autoZoom)280 bool RS_ActionPrintPreview::setScale(double f, bool autoZoom) {
281     if (graphic) {
282         if( fabs(f - graphic->getPaperScale()) < RS_TOLERANCE ) return false;
283         graphic->setPaperScale(f);
284 //        graphic->centerToPage();
285         if(autoZoom) graphicView->zoomPage();
286         graphicView->redraw();
287         return true;
288     }
289     return false;
290 }
291 
292 
293 
getScale() const294 double RS_ActionPrintPreview::getScale() const{
295     double ret = 1.0;
296     if (graphic) {
297         ret = graphic->getPaperScale();
298     }
299     return ret;
300 }
301 
302 
setLineWidthScaling(bool state)303 void RS_ActionPrintPreview::setLineWidthScaling(bool state) {
304     graphicView->setLineWidthScaling(state);
305     graphicView->redraw();
306 }
307 
308 
setBlackWhite(bool bw)309 void RS_ActionPrintPreview::setBlackWhite(bool bw) {
310     if (bw) {
311         graphicView->setDrawingMode(RS2::ModeBW);
312     }
313     else {
314         graphicView->setDrawingMode(RS2::ModeFull);
315     }
316     graphicView->redraw();
317 }
318 
319 
getUnit()320 RS2::Unit RS_ActionPrintPreview::getUnit() {
321     if (graphic) {
322         return graphic->getUnit();
323     }
324     else {
325         return RS2::None;
326     }
327 }
328 
329 /** set paperscale fixed */
setPaperScaleFixed(bool fixed)330 void RS_ActionPrintPreview::setPaperScaleFixed(bool fixed)
331 {
332     graphic->setPaperScaleFixed(fixed);
333 }
334 
335 
336 /** get paperscale fixed */
getPaperScaleFixed()337 bool RS_ActionPrintPreview::getPaperScaleFixed()
338 {
339     return graphic->getPaperScaleFixed();
340 }
341 
342 /** calculate number of pages needed to contain a drawing */
calcPagesNum()343 void RS_ActionPrintPreview::calcPagesNum() {
344     if (graphic) {
345         RS_Vector printArea = graphic->getPrintAreaSize(false);
346         RS_Vector graphicSize = graphic->getSize() * graphic->getPaperScale();
347         int pX = ceil(graphicSize.x / printArea.x);
348         int pY = ceil(graphicSize.y / printArea.y);
349 
350         if ( pX > 99 || pY > 99) {
351             RS_DIALOGFACTORY->commandMessage(tr("RS_ActionPrintPreview::calcPagesNum(): "
352                                                 "Limit of pages has been exceeded."));
353             return;
354         }
355 
356         graphic->setPagesNum(pX, pY);
357         graphic->centerToPage();
358         graphicView->zoomPage();
359         graphicView->redraw();
360     }
361 }
362 
363 // EOF
364