1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7 /***************************************************************************
8                           scribusview.cpp  -  description
9                              -------------------
10     begin                : Fre Apr  6 21:47:55 CEST 2001
11     copyright            : (C) 2001 by Franz Schmid
12     email                : Franz.Schmid@altmuehlnet.de
13  ***************************************************************************/
14 
15 /***************************************************************************
16  *                                                                         *
17  *   This program is free software; you can redistribute it and/or modify  *
18  *   it under the terms of the GNU General Public License as published by  *
19  *   the Free Software Foundation; either version 2 of the License, or     *
20  *   (at your option) any later version.                                   *
21  *                                                                         *
22  ***************************************************************************/
23 
24 #include "scribusview.h"
25 
26 #include "scconfig.h"
27 #include "sclimits.h"
28 
29 #include <QColor>
30 #include <QCursor>
31 #include <QDebug>
32 #include <QDrag>
33 #include <QEvent>
34 #include <QFile>
35 #include <QFileInfo>
36 #include <QFont>
37 #include <QFontMetrics>
38 #include <QImage>
39 #include <QImageReader>
40 #include <QList>
41 #include <QMenu>
42 #include <QMessageBox>
43 #include <QMimeData>
44 #include <QPixmap>
45 #include <QPolygon>
46 #include <QStack>
47 #include <QStringList>
48 #include <QStyleOptionRubberBand>
49 #include <QWidgetAction>
50 
51 #include <cstdio>
52 #include <cstdlib>
53 
54 #ifdef HAVE_UNISTD_H
55 #include <unistd.h>
56 #endif
57 
58 #include <QUrl>
59 #include <QDir>
60 #include <QSizeGrip>
61 
62 #include "actionmanager.h"
63 #include "appmodehelper.h"
64 #include "appmodes.h"
65 #include "canvas.h"
66 #include "canvasgesture.h"
67 #include "canvasmode.h"
68 #include "canvasmode_imageimport.h"
69 #include "canvasmode_objimport.h"
70 #include "commonstrings.h"
71 #include "fileloader.h"
72 #include "filewatcher.h"
73 #include "hyphenator.h"
74 #include "iconmanager.h"
75 #include "loadsaveplugin.h"
76 #include "text/textlayoutpainter.h"
77 #include "pageitem.h"
78 #include "pageitem_group.h"
79 #include "pageitem_imageframe.h"
80 #include "pageitem_latexframe.h"
81 #include "pageitem_line.h"
82 #include "pageitem_pathtext.h"
83 #include "pageitem_polygon.h"
84 #include "pageitem_polyline.h"
85 #include "pageitem_table.h"
86 #include "pageitem_textframe.h"
87 #include "plugins/formatidlist.h"
88 #include "prefscontext.h"
89 #include "prefsfile.h"
90 #include "prefsmanager.h"
91 #include "scclocale.h"
92 #include "scmimedata.h"
93 #include "scpage.h"
94 #include "scpainter.h"
95 #include "scpaths.h"
96 #include "scribusapp.h"
97 #include "scribuscore.h"
98 #include "scribuswin.h"
99 #include "scribusXml.h"
100 #include "selection.h"
101 #include "selectionrubberband.h"
102 #include "serializer.h"
103 #include "ui/extimageprops.h"
104 #include "ui/guidemanager.h"
105 #include "ui/hruler.h"
106 #include "ui/insertTable.h"
107 #include "ui/pageitemattributes.h"
108 #include "ui/pageselector.h"
109 #include "ui/propertiespalette.h"
110 #include "ui/propertiespalette_line.h"
111 #include "ui/rulermover.h"
112 #include "ui/scrapbookpalette.h"
113 #include "ui/storyeditor.h"
114 #include "ui/symbolpalette.h"
115 #include "ui/viewtoolbar.h"
116 #include "ui/vruler.h"
117 #include "undomanager.h"
118 #include "units.h"
119 #include "util.h"
120 #include "util_color.h"
121 #include "util_formats.h"
122 #include "util_math.h"
123 
124 using namespace std;
125 
ScribusView(QWidget * win,ScribusMainWindow * mw,ScribusDoc * doc)126 ScribusView::ScribusView(QWidget* win, ScribusMainWindow* mw, ScribusDoc *doc) :
127 	QScrollArea(win),
128 	m_doc(doc),
129 	m_canvas(new Canvas(doc, this)),
130 	Prefs(&(PrefsManager::instance().appPrefs)),
131 	undoManager(UndoManager::instance()),
132 	m_ScMW(mw),
133 	RCenter(-1,-1),
134 	m_vhRulerHW(17)
135 {
136 	setObjectName("s");
137 	QPalette p=palette();
138 	p.setBrush(QPalette::Window, PrefsManager::instance().appPrefs.displayPrefs.scratchColor);
139 	setPalette(p);
140 	setAttribute(Qt::WA_StaticContents);
141 	setAttribute(Qt::WA_InputMethodEnabled, true);
142 	setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
143 	setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
144 	setViewportMargins(m_vhRulerHW, m_vhRulerHW, 0, 0);
145 	setWidgetResizable(false);
146 	m_canvasMode = CanvasMode::createForAppMode(this, m_doc->appMode);
147 	setWidget(m_canvas);
148 	//already done by QScrollArea: widget()->installEventFilter(this);
149 	installEventFilter(this); // FIXME:av
150 	//	viewport()->setBackgroundMode(Qt::PaletteBackground);
151 	setFocusPolicy(Qt::ClickFocus);
152 	QFont fo = QFont(font());
153 	// #8058: Better not use too small font size on Windows
154 	// in case ClearType is not enabled
155 	int posi = fo.pointSize() - (ScCore->isWinGUI() ? 1 : 2);
156 	fo.setPointSize(posi);
157 
158 	horizRuler = new Hruler(this, m_doc);
159 	vertRuler = new Vruler(this, m_doc);
160 	horizRuler->installEventFilter(this);
161 	vertRuler->installEventFilter(this);
162 
163 	rulerMover = new RulerMover(this);
164 	rulerMover->setFocusPolicy(Qt::NoFocus);
165 	horizRuler->setGeometry(m_vhRulerHW, 1, width()-m_vhRulerHW-1, m_vhRulerHW);
166 	vertRuler->setGeometry(1, m_vhRulerHW, m_vhRulerHW, height()-m_vhRulerHW-1);
167 	rulerMover->setGeometry(1, 1, m_vhRulerHW, m_vhRulerHW);
168 
169 	m_ready = true;
170 	m_canvas->setMouseTracking(true);
171 	setAcceptDrops(true);
172 	m_canvas->setAcceptDrops(true);
173 	// FIXME setDragAutoScroll(false);
174 	m_doc->DragP = false;
175 	m_doc->leaveDrag = false;
176 	m_doc->SubMode = -1;
177 	storedFramesShown = m_doc->guidesPrefs().framesShown;
178 	storedShowControls = m_doc->guidesPrefs().showControls;
179 	setRulersShown(m_doc->guidesPrefs().rulersShown);
180 
181 	m_canvas->m_viewMode.viewAsPreview = false;
182 	m_canvas->setPreviewVisual(-1);
183 	m_previousMode = -1;
184 
185 	redrawMarker = new SelectionRubberBand(QRubberBand::Rectangle, this);
186 	redrawMarker->hide();
187 
188 	m_canvas->newRedrawPolygon();
189 	m_canvas->resetRenderMode();
190 	//  #13101 : "viewPreviewMode" is checked if necessary in ScribusMainWindow::newActWin()
191 	//  At this point the view and parent window may not be able to perform all what is necessary to
192 	//  enable preview mode anyway, especially when loading an existing doc.
193 	//	m_ScMW->scrActions["viewPreviewMode"]->setChecked(m_canvas->m_viewMode.viewAsPreview);
194 	m_mousePointDoc = FPoint(0,0);
195 	m_doc->regionsChanged()->connectObserver(this);
196 	connect(this, SIGNAL(HaveSel()), m_doc, SLOT(selectionChanged()));
197 	// Commented out to fix bug #7865
198 	//	m_dragTimer = new QTimer(this);
199 	//	connect(m_dragTimer, SIGNAL(timeout()), this, SLOT(dragTimerTimeOut()));
200 	//	m_dragTimer->stop();
201 	m_dragTimerFired = false;
202 
203 	clockLabel = new ClockWidget(this, m_doc);
204 	clockLabel->setGeometry(m_vhRulerHW + 1, height() - m_vhRulerHW - 61, 60, 60);
205 	clockLabel->setVisible(false);
206 
207 	endEditButton = new QPushButton(IconManager::instance().loadIcon("22/exit.png"), tr("End Edit"), this);
208 	endEditButton->setGeometry(m_vhRulerHW + 1, height() - m_vhRulerHW - endEditButton->minimumSizeHint().height() - 1, endEditButton->minimumSizeHint().width(), endEditButton->minimumSizeHint().height());
209 	endEditButton->setVisible(false);
210 
211 	languageChange();
212 
213 	connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
214 	connect(endEditButton, SIGNAL(clicked()), m_ScMW, SLOT(slotEndSpecialEdit()));
215 }
216 
~ScribusView()217 ScribusView::~ScribusView()
218 {
219 	while (m_canvasMode)
220 	{
221 		m_canvasMode->deactivate(false);
222 		m_canvasMode = m_canvasMode->delegate();
223 	}
224 }
225 
changeEvent(QEvent * e)226 void ScribusView::changeEvent(QEvent *e)
227 {
228 	if (e->type() == QEvent::LanguageChange)
229 	{
230 		languageChange();
231 	}
232 	else
233 		QFrame::changeEvent(e);
234 }
235 
nativeGestureEvent(QNativeGestureEvent * e)236 void ScribusView::nativeGestureEvent(QNativeGestureEvent *e)
237 {
238 	if (e->gestureType() == Qt::ZoomNativeGesture)
239 	{
240 		double delta = 1 + e->value();
241 		FPoint mp = m_canvas->globalToCanvas(e->globalPos());
242 		zoom(mp.x(), mp.y(), m_canvas->scale() * delta, true);
243 	}
244 	if (e->gestureType() == Qt::SmartZoomNativeGesture)
245 	{
246 		static bool zoomTo100 = false;
247 		FPoint mp = m_canvas->globalToCanvas(e->globalPos());
248 		if (zoomTo100)
249 		{
250 			zoom(mp.x(), mp.y(), Prefs->displayPrefs.displayScale, true);
251 		}
252 		else
253 		{
254 			zoom(mp.x(), mp.y(), Prefs->displayPrefs.displayScale*0.75, true);
255 		}
256 		zoomTo100 = !zoomTo100;
257 	}
258 	e->accept();
259 }
260 
iconSetChange()261 void ScribusView::iconSetChange()
262 {
263 	IconManager& iconManager = IconManager::instance();
264 	endEditButton->setIcon(iconManager.loadIcon("22/exit.png"));
265 }
266 
languageChange()267 void ScribusView::languageChange()
268 {
269 	endEditButton->setToolTip( tr("Click here to leave this special edit mode"));
270 }
271 
toggleCMS(bool cmsOn)272 void ScribusView::toggleCMS(bool cmsOn)
273 {
274 	m_doc->enableCMS(cmsOn);
275 	m_ScMW->requestUpdate(reqCmsOptionsUpdate);
276 	DrawNew();
277 }
278 
279 
switchPreviewVisual(int vis)280 void ScribusView::switchPreviewVisual(int vis)
281 {
282 	m_canvas->setPreviewVisual(vis);
283 	m_doc->viewAsPreview = m_canvas->usePreviewVisual();
284 	m_doc->previewVisual = m_canvas->previewVisual();
285 	m_doc->recalculateColors();
286 	m_doc->recalcPicturesRes();
287 	DrawNew();
288 }
289 
togglePreviewEdit(bool edit)290 void ScribusView::togglePreviewEdit(bool edit)
291 {
292 	m_doc->editOnPreview = edit;
293 	m_ScMW->setPreviewToolbar();
294 	m_EditModeWasOn = true;
295 	DrawNew();
296 }
297 
togglePreview(bool inPreview)298 void ScribusView::togglePreview(bool inPreview)
299 {
300 	this->requestMode(modeNormal);
301 	deselectItems(true);
302 	undoManager->setUndoEnabled(false);
303 	m_canvas->m_viewMode.viewAsPreview = inPreview;
304 	m_doc->drawAsPreview = inPreview;
305 	bool recalc = false;
306 	m_doc->editOnPreview = false;
307 	m_ScMW->scrActions["viewEditInPreview"]->setChecked(false);
308 	m_AnnotChanged = false;
309 	m_EditModeWasOn = false;
310 	m_ChangedState = m_doc->isModified();
311 
312 	if (inPreview)
313 	{
314 		m_ScMW->scrActions["viewEditInPreview"]->setEnabled(true);
315 		storedFramesShown = m_doc->guidesPrefs().framesShown;
316 		m_doc->guidesPrefs().framesShown = false;
317 		storedShowControls = m_doc->guidesPrefs().showControls;
318 		m_doc->guidesPrefs().showControls = false;
319 		m_canvas->m_viewMode.previewVisual = 0;
320 		m_doc->previewVisual = 0;
321 		// warning popping up in case colour management and out-of-gamut-display are active
322 		// as from #4346: Add a preview for daltonian - PV
323 		if (m_doc->HasCMS && m_doc->Gamut)
324 		{
325 			ScMessageBox::information(m_ScMW, tr("Preview Mode"),
326 									  "<qt>" + tr("Out of gamut colors display is active. Therefore the color display may not match the perception by visually impaired") + "</qt>");
327 		}
328 	}
329 	else
330 	{
331 		if (m_AnnotChanged)
332 			m_doc->ResetFormFields();
333 		m_ScMW->scrActions["viewEditInPreview"]->setEnabled(false);
334 		m_doc->guidesPrefs().framesShown = storedFramesShown;
335 		m_doc->guidesPrefs().showControls = storedShowControls;
336 		m_canvas->m_viewMode.previewVisual = 0;
337 		m_doc->previewVisual = 0;
338 		if (m_ScMW->viewToolBar->visualMenu->currentIndex() != m_doc->previewVisual)
339 			recalc = true;
340 		m_ScMW->viewToolBar->setDoc(m_doc);
341 	}
342 	m_ScMW->appModeHelper->setPreviewMode(inPreview);
343 	m_ScMW->setPreviewToolbar();
344 	m_ScMW->viewToolBar->setViewPreviewMode(inPreview);
345 	ScGuardedPtr<ScribusDoc> docPtr = m_doc->guardedPtr();
346 	if (recalc)
347 	{
348 		m_doc->recalculateColors();
349 		m_doc->recalcPicturesRes();
350 	}
351 	if (docPtr) // document may have been destroyed in-between
352 	{
353 		DrawNew();
354 		if ((!m_EditModeWasOn) && (!m_AnnotChanged))
355 			m_doc->setModified(m_ChangedState);
356 	}
357 	undoManager->setUndoEnabled(true);
358 }
359 
changed(QRectF re,bool)360 void ScribusView::changed(QRectF re, bool)
361 {
362 	double scale = m_canvas->scale();
363 	int newCanvasWidth  = qRound((m_doc->maxCanvasCoordinate.x() - m_doc->minCanvasCoordinate.x()) * scale);
364 	int newCanvasHeight = qRound((m_doc->maxCanvasCoordinate.y() - m_doc->minCanvasCoordinate.y()) * scale);
365 	QSize newCanvasSize(newCanvasWidth, newCanvasHeight);
366 	if (!re.isValid() && /* don't check this all the time */
367 			(m_oldCanvasSize != newCanvasSize))
368 	{
369 		QSize maxViewport = maximumViewportSize();
370 		horizontalScrollBar()->setRange(0, newCanvasWidth - maxViewport.width());
371 		verticalScrollBar()->setRange(0, newCanvasHeight - maxViewport.height());
372 		/*	qDebug() << "adjustCanvas [" << m_oldCanvasSize.width() << m_oldCanvasSize.height() << " ] -> [" << newCanvasWidth << newCanvasHeight
373 				<< "] (" << Doc->minCanvasCoordinate.x() << Doc->minCanvasCoordinate.y() << ") - ("
374 				<< Doc->maxCanvasCoordinate.x() << Doc->maxCanvasCoordinate.y() << ") @" << scale << maxViewport;
375 		*/
376 		widget()->resize(newCanvasWidth, newCanvasHeight);
377 		m_oldCanvasSize = newCanvasSize;
378 	}
379 	if (!m_doc->isLoading() && !m_ScMW->scriptIsRunning())
380 	{
381 // 		qDebug() << "ScribusView-changed(): changed region:" << re;
382 		m_canvas->setForcedRedraw(true);
383 		updateCanvas(re);
384 	}
385 }
386 
handleObjectImport(QMimeData * mimeData,TransactionSettings * trSettings)387 bool ScribusView::handleObjectImport(QMimeData* mimeData, TransactionSettings* trSettings)
388 {
389 	requestMode(modeImportObject);
390 	CanvasMode_ObjImport* objImport = qobject_cast<CanvasMode_ObjImport*>(m_canvasMode);
391 	if (objImport)
392 	{
393 		objImport->setMimeData(mimeData);
394 		objImport->setTransactionSettings(trSettings);
395 		return true;
396 	}
397 	delete trSettings;
398 	delete mimeData;
399 	return false;
400 }
401 
startGesture(CanvasGesture * gesture)402 void ScribusView::startGesture(CanvasGesture* gesture)
403 {
404 	//qDebug() << "start gesture" << typeid(*m_canvasMode).name()
405 	//		<< "---->"
406 	//		<< typeid(*gesture).name();
407 	if (m_canvasMode != gesture)
408 	{
409 		m_canvasMode->deactivate(true);
410 		gesture->setDelegate(m_canvasMode);
411 		m_canvasMode = gesture;
412 		m_canvasMode->activate(false);
413 		if (m_doc->appMode != modeEditClip)
414 			m_canvas->repaint();
415 	}
416 }
417 
stopGesture()418 void ScribusView::stopGesture()
419 {
420 	//qDebug() << "stop gesture" << typeid(*m_canvasMode).name() << (m_canvasMode->delegate() != 0);
421 	if (m_canvasMode->delegate())
422 	{
423 		m_canvasMode->deactivate(false);
424 		m_canvasMode = m_canvasMode->delegate();
425 		m_canvasMode->activate(true);
426 		if (PrefsManager::instance().appPrefs.uiPrefs.stickyTools)
427 		{
428 			m_canvas->setForcedRedraw(true);
429 			//			Doc->m_Selection->clear();
430 			//			emit HaveSel();
431 			m_canvas->resetRenderMode();
432 			updateContents();
433 		}
434 		else
435 			m_canvas->repaint();
436 	}
437 }
438 
439 /**
440 switches between appmodes:
441  - for submodes, activate the appropriate dialog or palette
442  - set a new CanvasMode if necessary
443  - call ScribusMainWindow::setAppMode(), which de/activates actions
444  */
requestMode(int appMode)445 void ScribusView::requestMode(int appMode)
446 {
447 	bool updateNecessary = false;
448 	//	qDebug() << "request mode:" << appMode;
449 	switch (appMode) // filter submodes
450 	{
451 		case submodePaintingDone:   // return to normal mode
452 			appMode = modeNormal;
453 			m_previousMode = -1;
454 			updateNecessary = true;
455 			break;
456 		case submodeEndNodeEdit:     // return from node/shape editing
457 			appMode = modeNormal;
458 			m_previousMode = -1;
459 			updateNecessary = true;
460 			break;
461 		case submodeLoadPic:         // open GetImage dialog
462 			m_ScMW->slotGetContent();
463 			appMode = m_doc->appMode;
464 			m_previousMode = appMode;
465 			break;
466 		case submodeStatusPic:       // open ManageImages dialog
467 			appMode = m_doc->appMode;
468 			m_previousMode = appMode;
469 			m_ScMW->StatusPic();
470 			break;
471 		case submodeEditExternal:    // open external image editor
472 			appMode = m_doc->appMode;
473 			m_previousMode = appMode;
474 			m_ScMW->callImageEditor();
475 			break;
476 		case submodeAnnotProps:
477 			appMode = m_doc->appMode;
478 			m_previousMode = appMode;
479 			m_ScMW->ModifyAnnot();
480 			break;
481 		case submodeEditSymbol:
482 			appMode = m_doc->appMode;
483 			m_previousMode = appMode;
484 			m_ScMW->editSelectedSymbolStart();
485 			break;
486 		default:
487 			if (appMode < 0 || appMode > submodeFirstSubmode)
488 				appMode = modeNormal;
489 			m_previousMode = appMode;
490 			break;
491 	}
492 
493 	if (m_doc->appMode != appMode)
494 	{
495 		m_ScMW->appModeHelper->setApplicationMode(m_ScMW, m_doc, appMode);
496 		CanvasMode* newCanvasMode = modeInstances.value(appMode);
497 		if (!newCanvasMode)
498 		{
499 			newCanvasMode = CanvasMode::createForAppMode(this, appMode);
500 			modeInstances[appMode] = newCanvasMode;
501 		}
502 		if (newCanvasMode)
503 		{
504 			m_canvasMode->deactivate(false);
505 			m_canvasMode = newCanvasMode;
506 			m_canvasMode->activate(false);
507 		}
508 		updateNecessary = true;
509 	}
510 	else
511 	{
512 		m_ScMW->appModeHelper->setApplicationMode(m_ScMW, m_doc, appMode);
513 	}
514 	if (updateNecessary)
515 		updateCanvas();
516 	//setCursorBasedOnAppMode(appMode);
517 }
518 
519 /*
520 void ScribusView::setCursorBasedOnAppMode(int appMode)
521 {
522 	IconManager* im=IconManager::instance();
523 	int docSelectionCount = Doc->m_Selection->count();
524 	switch (appMode)
525 	{
526 		case modeDrawShapes:
527 		case modeDrawArc:
528 		case modeDrawSpiral:
529 			if (docSelectionCount!=0)
530 				Deselect(true);
531 			setCursor(im->loadCursor("drawframe.png"));
532 			break;
533 		case modeDrawImage:
534 			if (docSelectionCount!=0)
535 				Deselect(true);
536 			setCursor(im->loadCursor("drawimageframe.png"));
537 			break;
538 		case modeDrawLatex:
539 			if (docSelectionCount!=0)
540 				Deselect(true);
541 			setCursor(im->loadCursor("drawlatexframe.png"));
542 			break;
543 		case modeDrawText:
544 			if (docSelectionCount!=0)
545 				Deselect(true);
546 			setCursor(im->loadCursor("drawtextframe.png"));
547 			break;
548 		case modeDrawTable2:
549 			if (docSelectionCount!=0)
550 				Deselect(true);
551 			setCursor(im->loadCursor("drawtable.png"));
552 			break;
553 		case modeDrawRegularPolygon:
554 			if (docSelectionCount!=0)
555 				Deselect(true);
556 			setCursor(im->loadCursor("drawpolyline.png"));
557 			break;
558 		case modeMagnifier:
559 			if (docSelectionCount!=0)
560 				Deselect(true);
561 			Magnify = true;
562 			setCursor(im->loadCursor("lupez.png"));
563 			break;
564 		case modePanning:
565 			setCursor(im->loadCursor("handc.png"));
566 			break;
567 		case modeDrawLine:
568 		case modeDrawBezierLine:
569 			setCursor(QCursor(Qt::CrossCursor));
570 			break;
571 		case modeDrawCalligraphicLine:
572 		case modeDrawFreehandLine:
573 			setCursor(im->loadCursor("DrawFreeLine.png", 0, 32));
574 			break;
575 		case modeEyeDropper:
576 			setCursor(im->loadCursor("colorpickercursor.png", 0, 32));
577 			break;
578 		case modeInsertPDFButton:
579 		case modeInsertPDFRadioButton:
580 		case modeInsertPDFTextfield:
581 		case modeInsertPDFCheckbox:
582 		case modeInsertPDFCombobox:
583 		case modeInsertPDFListbox:
584 		case modeInsertPDFTextAnnotation:
585 		case modeInsertPDFLinkAnnotation:
586 		case modeInsertPDF3DAnnotation:
587 			if (docSelectionCount!=0)
588 				Deselect(true);
589 			setCursor(QCursor(Qt::CrossCursor));
590 			break;
591 		case modeLinkFrames:
592 			setCursor(im->loadCursor("LinkTextFrame.png", 0, 31));
593 			break;
594 		case modeMeasurementTool:
595 		case modeEditGradientVectors:
596 		case modeEditMeshGradient:
597 		case modeEditArc:
598 		case modeEditPolygon:
599 		case modeEditSpiral:
600 			setCursor(QCursor(Qt::CrossCursor));
601 			break;
602 		default:
603 			setCursor(QCursor(Qt::ArrowCursor));
604 		break;
605 	}
606 }
607 */
608 
609 
610 /*
611 void ScribusView::paintEvent ( QPaintEvent * p )
612 {
613 	#ifndef _WIN32
614 	if (p->spontaneous())
615 		evSpon = true;
616 	#endif
617 	QScrollArea::paintEvent(p);
618 //	QPainter qp(viewport());
619 //	drawContents(&qp, p->rect().x(), p->rect().y(), p->rect().width(), p->rect().height());
620 }
621 */
622 
enterEvent(QEvent * e)623 void ScribusView::enterEvent(QEvent * e)
624 {
625 	m_canvasMode->enterEvent(e);
626 }
627 
leaveEvent(QEvent * e)628 void ScribusView::leaveEvent(QEvent *e)
629 {
630 	m_canvasMode->leaveEvent(e);
631 }
632 
contentsDragEnterEvent(QDragEnterEvent * e)633 void ScribusView::contentsDragEnterEvent(QDragEnterEvent *e)
634 {
635 	QString text;
636 	bool /* dataFound = false, */ fromFile = false;
637 	const ScElemMimeData* elemData = qobject_cast<const ScElemMimeData*>(e->mimeData());
638 	if (elemData)
639 		text = elemData->scribusElem();
640 	else if (e->mimeData()->hasUrls())
641 	{
642 		QList<QUrl> urls = e->mimeData()->urls();
643 		if (!urls.isEmpty())
644 		{
645 			QUrl url = urls[0];
646 			QFileInfo fi(url.toLocalFile());
647 			if (fi.exists())
648 			{
649 				fromFile = true;
650 				text = url.toLocalFile();
651 			}
652 		}
653 	}
654 
655 	bool hasSupportedFormat = !text.isEmpty();
656 	hasSupportedFormat |= e->mimeData()->hasFormat("text/inline");
657 	hasSupportedFormat |= e->mimeData()->hasFormat("text/symbol");
658 	hasSupportedFormat |= e->mimeData()->hasUrls();
659 	if (!hasSupportedFormat)
660 	{
661 		e->ignore();
662 		return;
663 	}
664 
665 	e->accept();
666 	e->acceptProposedAction();
667 
668 	if (text.isEmpty())
669 		return;
670 
671 	double gx, gy, gw, gh;
672 	ScriXmlDoc ss;
673 	if (ss.readElemHeader(text, fromFile, &gx, &gy, &gw, &gh))
674 	{
675 		FPoint dragPosDoc = m_canvas->globalToCanvas(widget()->mapToGlobal(e->pos()));
676 		dragX = dragPosDoc.x(); //e->pos().x() / m_canvas->scale();
677 		dragY = dragPosDoc.y(); //e->pos().y() / m_canvas->scale();
678 		dragW = gw;
679 		dragH = gh;
680 		DraggedGroup = true;
681 		getDragRectScreen(&gx, &gy, &gw, &gh);
682 		//		QPoint evP = viewport()->mapToGlobal(e->pos());
683 		//		evP -= QPoint(contentsX(), contentsY());
684 		//		redrawMarker->setGeometry(QRect(evP.x() + 1, evP.y() + 1, qRound(gw), qRound(gh)).normalized());
685 		//		if (!redrawMarker->isVisible())
686 		//			redrawMarker->show();
687 		emit ItemGeom();
688 	}
689 }
690 
contentsDragMoveEvent(QDragMoveEvent * e)691 void ScribusView::contentsDragMoveEvent(QDragMoveEvent *e)
692 {
693 	QString text;
694 	e->accept();
695 	if (e->mimeData()->hasText())
696 	{
697 		e->acceptProposedAction();
698 		text = e->mimeData()->text();
699 		if (DraggedGroup)
700 		{
701 			//			double gx, gy, gw, gh;
702 			FPoint dragPosDoc = m_canvas->globalToCanvas(widget()->mapToGlobal(e->pos()));
703 			dragX = dragPosDoc.x(); //e->pos().x() / m_canvas->scale();
704 			dragY = dragPosDoc.y(); //e->pos().y() / m_canvas->scale();
705 			//			getDragRectScreen(&gx, &gy, &gw, &gh);
706 			//			QPoint evP = viewport()->mapToGlobal(e->pos());
707 			//			evP -= QPoint(contentsX(), contentsY());
708 			//			redrawMarker->setGeometry(QRect(evP.x() + 2, evP.y() + 2, qRound(gw - 2), qRound(gh - 2)).normalized());
709 			//			if (!redrawMarker->isVisible())
710 			//				redrawMarker->show();
711 			emit MousePos(dragX, dragY); //+Doc->minCanvasCoordinate.x(), dragY+Doc->minCanvasCoordinate.y());
712 			QPoint pos = m_canvas->canvasToLocal(dragPosDoc);
713 			horizRuler->draw(pos.x());
714 			vertRuler->draw(pos.y());
715 			//			return;
716 		}
717 		/*		QUrl ur(text);
718 		QFileInfo fi = QFileInfo(ur.toLocalFile());
719 		QString ext = fi.extension(false).toUpper();
720 		QStrList imfo = QImageIO::inputFormats();
721 		if (ext == "JPG")
722 			ext = "JPEG";
723 		img = ((imfo.contains(ext))||(ext=="PS")||(ext=="EPS")||(ext=="TIF"));
724 		if (!SeleItemPos(e->pos()))
725 		{
726 			if (SelItem.count() != 0)
727 				Deselect(true);
728 		}
729 		else
730 		{
731 			item = SelItem.at(0);
732 			if (img)
733 			{
734 				if (item->PType != 2)
735 					Deselect(true);
736 			}
737 			else
738 			{
739 				if (item->PType != 4)
740 					Deselect(true);
741 			}
742 		} */
743 	}
744 }
745 
contentsDragLeaveEvent(QDragLeaveEvent *)746 void ScribusView::contentsDragLeaveEvent(QDragLeaveEvent *)
747 {
748 	if (DraggedGroup)
749 	{
750 		DraggedGroup = false;
751 		m_canvas->resetRenderMode();
752 		//		redrawMarker->hide();
753 		updateContents();
754 	}
755 }
756 
contentsDropEvent(QDropEvent * e)757 void ScribusView::contentsDropEvent(QDropEvent *e)
758 {
759 	QString text;
760 	QUrl url;
761 	PageItem *currItem;
762 	UndoTransaction activeTransaction;
763 	bool img = false;
764 	bool selectedItemByDrag = false;
765 	int re = 0;
766 
767 	m_canvas->resetRenderMode();
768 	e->accept();
769 
770 	FPoint dropPosDoc = m_canvas->globalToCanvas(widget()->mapToGlobal(e->pos()));
771 	QPointF dropPosDocQ(dropPosDoc.x(), dropPosDoc.y());
772 
773 	//Loop through all items and see which one(s) were under the drop point on the current layer
774 	//Should make a nice function for this.
775 	//#9051: loop in reverse order so that items in front of others are prioritized
776 	m_doc->m_Selection->delaySignalsOn();
777 	for (int i = m_doc->Items->count() - 1; i >= 0 ; --i)
778 	{
779 		PageItem* item = m_doc->Items->at(i);
780 		if (item->m_layerID != m_doc->activeLayer())
781 			continue;
782 		if ((m_doc->masterPageMode())  && (!((item->OwnPage == -1) || (item->OwnPage == m_doc->currentPage()->pageNr()))))
783 			continue;
784 		if (m_canvas->frameHitTest(dropPosDocQ, item) >= Canvas::INSIDE)
785 		{
786 			deselectItems(false);
787 			m_doc->m_Selection->addItem(item);
788 			selectedItemByDrag = true;
789 			break;
790 		}
791 	}
792 	m_doc->m_Selection->delaySignalsOff();
793 
794 	QStringList imfo;
795 	QList<QByteArray> imgs = QImageReader::supportedImageFormats();
796 	for (int i = 0; i < imgs.count(); ++i )
797 	{
798 		imfo.append(QString(imgs.at(i)).toUpper());
799 	}
800 	QString formatD(FormatsManager::instance()->extensionListForFormat(FormatsManager::IMAGESIMGFRAME, 1).toUpper());
801 	imfo += formatD.split("|");
802 
803 	if (e->mimeData()->hasUrls())
804 	{
805 		if ((e->mimeData()->urls().count() == 1) || selectedItemByDrag)
806 		{
807 			url = e->mimeData()->urls().at(0);
808 			text.clear();
809 		}
810 		else
811 		{
812 			int dropOffsetX = 0;
813 			int dropOffsetY = 0;
814 			QList<QUrl> fileUrls = e->mimeData()->urls();
815 			for (int a = 0; a < fileUrls.count(); a++)
816 			{
817 				url = fileUrls[a];
818 				QFileInfo fi(url.toLocalFile());
819 				QString ext = fi.suffix().toUpper();
820 				if (ext == "JPG")
821 					ext = "JPEG";
822 				if (!imfo.contains(ext) || !fi.exists() || selectedItemByDrag)
823 					continue;
824 				int z = m_doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, dropPosDoc.x() + dropOffsetX, dropPosDoc.y() + dropOffsetY, 1, 1, m_doc->itemToolPrefs().shapeLineWidth, m_doc->itemToolPrefs().imageFillColor, m_doc->itemToolPrefs().imageStrokeColor);
825 				PageItem *item = m_doc->Items->at(z);
826 				item->m_layerID = m_doc->activeLayer();
827 				m_doc->loadPict(url.toLocalFile(), item);
828 				double iw = static_cast<double>(item->OrigW * 72.0 / item->pixm.imgInfo.xres);
829 				double ih = static_cast<double>(item->OrigH * 72.0 / item->pixm.imgInfo.yres);
830 				if (iw > ih)
831 				{
832 					double pw = m_doc->currentPage()->width();
833 					if (iw > pw)
834 					{
835 						ih = pw * (ih / iw);
836 						iw = pw;
837 					}
838 				}
839 				else
840 				{
841 					double ph = m_doc->currentPage()->height();
842 					if (ih > ph)
843 					{
844 						iw = ph * (iw / ih);
845 						ih = ph;
846 					}
847 				}
848 				item->setWidth(iw);
849 				item->setHeight(ih);
850 				item->OldB2 = item->width();
851 				item->OldH2 = item->height();
852 				item->updateClip();
853 				item->adjustPictScale();
854 				item->update();
855 				dropOffsetX += m_doc->opToolPrefs().dispX;
856 				dropOffsetY += m_doc->opToolPrefs().dispY;
857 			}
858 			emit DocChanged();
859 			update();
860 			return;
861 		}
862 	}
863 	else if (e->mimeData()->hasFormat("application/x-scribus-elem"))
864 	{
865 		const ScElemMimeData* scMimeData = qobject_cast<const ScElemMimeData*>(e->mimeData());
866 		if (scMimeData)
867 			text = scMimeData->scribusElem();
868 	}
869 	else if (e->mimeData()->hasFormat("text/symbol"))
870 	{
871 		e->acceptProposedAction();
872 		activateWindow();
873 		if (!m_ScMW->scriptIsRunning())
874 			raise();
875 		m_ScMW->newActWin((dynamic_cast<ScribusWin*>(m_doc->WinHan))->getSubWin());
876 		updateContents();
877 		QString patternVal = e->mimeData()->data("text/symbol");
878 		m_doc->m_Selection->delaySignalsOn();
879 		for (int i = m_doc->Items->count() - 1; i >= 0 ; --i)
880 		{
881 			PageItem* item = m_doc->Items->at(i);
882 			if (item->m_layerID != m_doc->activeLayer())
883 				continue;
884 			if ((m_doc->masterPageMode())  && (!((item->OwnPage == -1) || (item->OwnPage == m_doc->currentPage()->pageNr()))))
885 				continue;
886 			if ((m_canvas->frameHitTest(dropPosDocQ, item) >= Canvas::INSIDE) && (item->itemType() == PageItem::Symbol))
887 			{
888 				deselectItems(false);
889 				m_doc->m_Selection->addItem(item);
890 				item->setPattern(patternVal);
891 				selectedItemByDrag = true;
892 				break;
893 			}
894 		}
895 		m_doc->m_Selection->delaySignalsOff();
896 		if (!selectedItemByDrag)
897 		{
898 			int z = m_doc->itemAdd(PageItem::Symbol, PageItem::Unspecified, dropPosDoc.x(), dropPosDoc.y(), 1, 1, 0, CommonStrings::None, CommonStrings::None);
899 			PageItem *item = m_doc->Items->at(z);
900 			item->m_layerID = m_doc->activeLayer();
901 			ScPattern pat = m_doc->docPatterns[patternVal];
902 			item->setWidth(pat.width);
903 			item->setHeight(pat.height);
904 			item->OldB2 = item->width();
905 			item->OldH2 = item->height();
906 			item->setPattern(patternVal);
907 			item->updateClip();
908 			deselectItems(false);
909 			m_doc->m_Selection->addItem(item);
910 		}
911 		emit DocChanged();
912 		update();
913 		return;
914 	}
915 	else if (e->mimeData()->hasFormat("text/inline"))
916 	{
917 		if (((m_doc->appMode == modeEditTable) || (m_doc->appMode == modeEdit)) && (!m_doc->m_Selection->isEmpty()))
918 		{
919 			PageItem *item = m_doc->m_Selection->itemAt(0);
920 			if (item->isTextFrame() || item->isTable())
921 			{
922 				e->acceptProposedAction();
923 				activateWindow();
924 				if (!m_ScMW->scriptIsRunning())
925 					raise();
926 				m_ScMW->newActWin((dynamic_cast<ScribusWin*>(m_doc->WinHan))->getSubWin());
927 				updateContents();
928 				QString patternVal = e->mimeData()->data("text/inline");
929 				int id = patternVal.toInt();
930 				PageItem_TextFrame *cItem;
931 				if (m_doc->appMode == modeEditTable)
932 					cItem = item->asTable()->activeCell().textFrame();
933 				else
934 					cItem = item->asTextFrame();
935 				if (cItem->HasSel)
936 					cItem->deleteSelectedTextFromFrame();
937 				cItem->invalidateLayout(false);
938 				cItem->itemText.insertObject(id);
939 				if (item->isTable())
940 					item->asTable()->update();
941 				else
942 					item->update();
943 				emit DocChanged();
944 				update();
945 				return;
946 			}
947 		}
948 	}
949 
950 	//	qDebug() << "ScribusView::contentsDropEvent" << e->mimeData()->formats() << url;
951 	if (url.isEmpty() && text.isEmpty())
952 	{
953 		e->ignore();
954 		return;
955 	}
956 
957 	e->acceptProposedAction();
958 	//<<#3524
959 	activateWindow();
960 	if (!m_ScMW->scriptIsRunning())
961 		raise();
962 
963 	ScribusWin* sw = dynamic_cast<ScribusWin*>(m_doc->WinHan);
964 	if (!sw)
965 		qFatal("ScribusView::contentsDropEvent !sw");
966 	m_ScMW->newActWin(sw->getSubWin());
967 	updateContents();
968 	//>>
969 	QFileInfo fi;
970 	QString ext;
971 	if (!e->mimeData()->hasFormat("application/x-scribus-elem"))
972 	{
973 		fi.setFile(url.toLocalFile());
974 		ext = fi.suffix().toUpper();
975 	}
976 	if (ext == "JPG")
977 		ext = "JPEG";
978 	img = imfo.contains(ext);
979 	bool vectorFile = false;
980 	if (fi.exists())
981 	{
982 		if (fi.suffix().toLower() == "sce")
983 			vectorFile = true;
984 		else
985 		{
986 			FileLoader *fileLoader = new FileLoader(url.toLocalFile());
987 			int testResult = fileLoader->testFile();
988 			delete fileLoader;
989 			if ((testResult != -1) && (testResult >= FORMATID_FIRSTUSER))
990 				vectorFile = true;
991 		}
992 	}
993 	else
994 	{
995 		if ((text.startsWith("<SCRIBUSELEM")) || (text.startsWith("SCRIBUSFRAGMENT")))
996 			vectorFile = true;
997 	}
998 	//		qDebug() << "drop - img:" << img << "file:" << fi.exists() << "suffix:" << fi.suffix() << "select by drag:" << selectedItemByDrag;
999 	//CB When we drag an image to a page from outside
1000 	//SeleItemPos is from 1.2.x. Needs reenabling for dragging *TO* a frame
1001 	if ((fi.exists()) && (img) && !selectedItemByDrag && !vectorFile)// && (!SeleItemPos(e->pos())))
1002 	{
1003 		int z = m_doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, dropPosDoc.x(), dropPosDoc.y(), 1, 1, m_doc->itemToolPrefs().shapeLineWidth, m_doc->itemToolPrefs().imageFillColor, m_doc->itemToolPrefs().imageStrokeColor);
1004 		PageItem *item = m_doc->Items->at(z);
1005 		item->m_layerID = m_doc->activeLayer();
1006 		m_doc->loadPict(url.toLocalFile(), item);
1007 
1008 		double iw = static_cast<double>(item->OrigW * 72.0 / item->pixm.imgInfo.xres);
1009 		double ih = static_cast<double>(item->OrigH * 72.0 / item->pixm.imgInfo.yres);
1010 		if (iw > ih)
1011 		{
1012 			double pw = m_doc->currentPage()->width();
1013 			if (iw > pw)
1014 			{
1015 				ih = pw * (ih / iw);
1016 				iw = pw;
1017 			}
1018 		}
1019 		else
1020 		{
1021 			double ph = m_doc->currentPage()->height();
1022 			if (ih > ph)
1023 			{
1024 				iw = ph * (iw / ih);
1025 				ih = ph;
1026 			}
1027 		}
1028 
1029 		item->setWidth(iw);
1030 		item->setHeight(ih);
1031 		item->OldB2 = item->width();
1032 		item->OldH2 = item->height();
1033 		item->updateClip();
1034 		item->adjustPictScale();
1035 		item->update();
1036 		emit DocChanged();
1037 		update();
1038 		return;
1039 	}
1040 	if (selectedItemByDrag && (m_canvas->frameHitTest(dropPosDocQ, m_doc->m_Selection->itemAt(0)) >= Canvas::INSIDE) && ((!vectorFile) || (img)))
1041 	{
1042 		PageItem *item = m_doc->m_Selection->itemAt(0);
1043 		if (item->itemType() == PageItem::ImageFrame)
1044 		{
1045 			if ((fi.exists()) && (img))
1046 				m_doc->loadPict(url.toLocalFile(), item);
1047 		}
1048 		else if (item->itemType() == PageItem::TextFrame)
1049 		{
1050 			if ((fi.exists()) && (!img))
1051 			{
1052 				gtGetText* gt = new gtGetText(m_doc);
1053 				QStringList exts = gt->getSupportedTypes();
1054 				if (exts.contains(fi.suffix().toLower()))
1055 				{
1056 					ImportSetup impsetup;
1057 					impsetup.runDialog = true;
1058 					impsetup.encoding = "";
1059 					impsetup.prefixNames = true;
1060 					impsetup.textOnly = false;
1061 					impsetup.importer = -1;
1062 					impsetup.filename = url.toLocalFile();
1063 					if (item->itemText.length() != 0)
1064 					{
1065 						int t = ScMessageBox::warning(this, CommonStrings::trWarning, tr("Do you really want to clear all your text?"),
1066 														QMessageBox::Yes | QMessageBox::No,
1067 														QMessageBox::No,	// GUI default
1068 														QMessageBox::Yes);	// batch default
1069 						if (t == QMessageBox::No)
1070 						{
1071 							delete gt;
1072 							return;
1073 						}
1074 					}
1075 					gt->launchImporter(impsetup.importer, impsetup.filename, impsetup.textOnly, impsetup.encoding, false, impsetup.prefixNames, item);
1076 					m_ScMW->updateFromDrop();
1077 				}
1078 				else
1079 				{
1080 					QByteArray file;
1081 					QTextCodec *codec = QTextCodec::codecForLocale();
1082 					// TODO create a Dialog for selecting the codec
1083 					if (loadRawText(url.toLocalFile(), file))
1084 					{
1085 						QString txt = codec->toUnicode( file.data() );
1086 						txt.replace(QRegExp("\r"), QChar(13));
1087 						txt.replace(QRegExp("\n"), QChar(13));
1088 						txt.replace(QRegExp("\t"), QChar(9));
1089 						item->itemText.insertChars(txt, true);
1090 					}
1091 				}
1092 				if (m_doc->docHyphenator->AutoCheck)
1093 					m_doc->docHyphenator->slotHyphenate(item);
1094 				item->invalidateLayout();
1095 				item->update();
1096 				delete gt;
1097 			}
1098 		}
1099 		emit DocChanged();
1100 		update();
1101 	}
1102 	else
1103 	{
1104 		deselectItems(true);
1105 		int oldDocItemCount = m_doc->Items->count();
1106 		if ((!img || vectorFile) && (m_doc->DraggedElem == nullptr))
1107 		{
1108 			activeTransaction = undoManager->beginTransaction(Um::SelectionGroup, Um::IGroup, Um::Create, "", Um::ICreate);
1109 			bool fromScrapbook = false;
1110 			if (fi.exists())
1111 			{
1112 				if (fi.suffix().toLower() == "sce")
1113 				{
1114 					fromScrapbook = true;
1115 					emit LoadElem(url.toLocalFile(), dropPosDoc.x(), dropPosDoc.y(), true, false, m_doc, this);
1116 				}
1117 				else
1118 				{
1119 					FileLoader *fileLoader = new FileLoader(url.toLocalFile());
1120 					int testResult = fileLoader->testFile();
1121 					delete fileLoader;
1122 					if ((testResult != -1) && (testResult >= FORMATID_FIRSTUSER))
1123 					{
1124 						const FileFormat * fmt = LoadSavePlugin::getFormatById(testResult);
1125 						if (fmt)
1126 						{
1127 							// We disable undo here as we are only interested by the item creation undo actions
1128 							// We create them manually after import
1129 							undoManager->setUndoEnabled(false);
1130 							m_doc->dontResize = true;
1131 							fmt->loadFile(url.toLocalFile(), LoadSavePlugin::lfUseCurrentPage|LoadSavePlugin::lfInteractive|LoadSavePlugin::lfScripted);
1132 							undoManager->setUndoEnabled(true);
1133 							if (m_doc->m_Selection->count() > 0)
1134 							{
1135 								if (UndoManager::undoEnabled())
1136 								{
1137 									// Create undo actions for created items
1138 									for (int i = 0; i < m_doc->m_Selection->count(); ++i)
1139 									{
1140 										PageItem* newItem = m_doc->m_Selection->itemAt(i);
1141 										ScItemState<PageItem*> *is = new ScItemState<PageItem*>("Create PageItem");
1142 										is->set("CREATE_ITEM");
1143 										is->setItem(newItem);
1144 										//Undo target rests with the Page for object specific undo
1145 										int pindex = (newItem->OwnPage > -1) ? newItem->OwnPage : 0;
1146 										UndoObject *target = m_doc->Pages->at(pindex);
1147 										undoManager->action(target, is);
1148 									}
1149 								}
1150 								double x2, y2, w, h;
1151 								// We disable undo temporarily as move actions are not necessary
1152 								// to perform undo correctly here
1153 								undoManager->setUndoEnabled(false);
1154 								m_doc->m_Selection->getGroupRect(&x2, &y2, &w, &h);
1155 								m_doc->moveGroup(dropPosDoc.x() - x2, dropPosDoc.y() - y2);
1156 								m_ScMW->requestUpdate(reqColorsUpdate | reqSymbolsUpdate | reqTextStylesUpdate | reqLineStylesUpdate);
1157 								undoManager->setUndoEnabled(true);
1158 							}
1159 							m_doc->dontResize = false;
1160 						}
1161 					}
1162 				}
1163 			}
1164 			else
1165 			{
1166 				emit LoadElem(QString(text), dropPosDoc.x(), dropPosDoc.y(), false, false, m_doc, this);
1167 			}
1168 			Selection tmpSelection(this, false);
1169 			tmpSelection.copy(*m_doc->m_Selection, true);
1170 			for (int i = oldDocItemCount; i < m_doc->Items->count(); ++i)
1171 			{
1172 				currItem = m_doc->Items->at(i);
1173 				m_doc->setRedrawBounding(currItem);
1174 				tmpSelection.addItem(currItem, true);
1175 				if (currItem->isBookmark)
1176 					emit AddBM(currItem);
1177 			}
1178 			m_doc->m_Selection->copy(tmpSelection, false);
1179 			if (!fromScrapbook && m_doc->m_Selection->count() == 1)
1180 			{
1181 				PageItem *newItem = m_doc->m_Selection->itemAt(0);
1182 				if ((newItem->width() > m_doc->currentPage()->width()) || (newItem->height() > m_doc->currentPage()->height()))
1183 				{
1184 					m_doc->rescaleGroup(newItem, qMin(qMin(m_doc->currentPage()->width() / newItem->width(), m_doc->currentPage()->height() / newItem->height()), 1.0));
1185 					newItem->update();
1186 				}
1187 			}
1188 			activeTransaction.commit();
1189 			activeTransaction.reset();
1190 		}
1191 		else
1192 		{
1193 			if (m_doc->DraggedElem != nullptr)
1194 			{
1195 				if (!m_doc->leaveDrag)
1196 				{
1197 					QMenu *pmen = new QMenu();
1198 					pmen->addAction( tr("Copy Here"));
1199 					QAction* mov = pmen->addAction( tr("Move Here"));
1200 					pmen->addAction( tr("Cancel"));
1201 					for (int i=0; i<m_doc->DragElements.count(); ++i)
1202 					{
1203 						if (m_doc->DragElements[i]->locked())
1204 						{
1205 							mov->setEnabled(false);
1206 							break;
1207 						}
1208 					}
1209 					re = pmen->actions().indexOf(pmen->exec(QCursor::pos()));
1210 					delete pmen;
1211 					pmen = nullptr;
1212 				}
1213 				else
1214 					re = 1;
1215 				if ((re == 2) || (re == -1))
1216 				{
1217 					updateContents();
1218 					return;
1219 				}
1220 				if ((re == 1) || (m_doc->leaveDrag))
1221 				{
1222 					QList<PageItem*> pasted;
1223 					emit LoadElem(QString(text), dropPosDoc.x(), dropPosDoc.y(), false, false, m_doc, this);
1224 					for (int i = oldDocItemCount; i < m_doc->Items->count(); ++i)
1225 					{
1226 						pasted.append(m_doc->Items->at(i));
1227 					}
1228 					Selection tmpSelection(this, false);
1229 					tmpSelection.copy(*m_doc->m_Selection, true);
1230 					for (int i = 0; i < m_doc->DragElements.count(); ++i)
1231 					{
1232 						tmpSelection.addItem(m_doc->DragElements[i], true);
1233 					}
1234 					m_doc->m_Selection->copy(tmpSelection, false);
1235 					PageItem* bb;
1236 					int fin;
1237 					for (int i = 0; i < m_doc->DragElements.count(); ++i)
1238 					{
1239 						bb = pasted.at(i);
1240 						currItem = m_doc->m_Selection->itemAt(i);
1241 						if ((currItem->isTextFrame()) && ((currItem->nextInChain() != nullptr) || (currItem->prevInChain() != nullptr)))
1242 						{
1243 							PageItem* before = currItem->prevInChain();
1244 							PageItem* after = currItem->nextInChain();
1245 							currItem->unlink();
1246 							if (before != nullptr)
1247 							{
1248 								fin = m_doc->m_Selection->findItem(before);
1249 								if (fin != -1)
1250 									before = pasted.at(fin);
1251 								before->unlink();
1252 								before->link(bb);
1253 							}
1254 							if (after != nullptr)
1255 							{
1256 								fin = m_doc->m_Selection->findItem(after);
1257 								if (fin != -1)
1258 									after = pasted.at(fin);
1259 								bb->link(after);
1260 							}
1261 						}
1262 					}
1263 					pasted.clear();
1264 					m_doc->itemSelection_DeleteItem();
1265 				}
1266 			}
1267 			if (!img && (re == 0))
1268 				emit LoadElem(QString(text), dropPosDoc.x(), dropPosDoc.y(), false, false, m_doc, this);
1269 			m_doc->DraggedElem = nullptr;
1270 			m_doc->DragElements.clear();
1271 			Selection tmpSelection(this, false);
1272 			tmpSelection.copy(*m_doc->m_Selection, true);
1273 			for (int i = oldDocItemCount; i < m_doc->Items->count(); ++i)
1274 			{
1275 				currItem = m_doc->Items->at(i);
1276 				m_doc->setRedrawBounding(currItem);
1277 				tmpSelection.addItem(currItem, true);
1278 				if (currItem->isBookmark)
1279 					emit AddBM(currItem);
1280 			}
1281 			m_doc->m_Selection->copy(tmpSelection, false);
1282 		}
1283 		if (m_doc->m_Selection->count() > 1)
1284 		{
1285 			m_doc->m_Selection->connectItemToGUI();
1286 			double gx, gy, gh, gw;
1287 			m_doc->m_Selection->getGroupRect(&gx, &gy, &gw, &gh);
1288 			double nx = gx;
1289 			double ny = gy;
1290 			if (!m_doc->ApplyGuides(&nx, &ny) && !m_doc->ApplyGuides(&nx, &ny,true))
1291 			{
1292 				FPoint npx;
1293 				npx = m_doc->ApplyGridF(FPoint(nx, ny));
1294 				nx = npx.x();
1295 				ny = npx.y();
1296 			}
1297 			activeTransaction = undoManager->beginTransaction(Um::SelectionGroup, Um::IGroup, Um::Move, "", Um::IMove);
1298 			m_doc->moveGroup(nx - gx, ny - gy);
1299 			m_doc->m_Selection->getGroupRect(&gx, &gy, &gw, &gh);
1300 			nx = gx + gw;
1301 			ny = gy + gh;
1302 			m_doc->ApplyGuides(&nx, &ny);
1303 			m_doc->ApplyGuides(&nx, &ny,true);
1304 			m_doc->moveGroup(nx - (gx + gw), ny - (gy + gh));
1305 			m_doc->m_Selection->getGroupRect(&gx, &gy, &gw, &gh);
1306 			for (int i = 0; i < m_doc->m_Selection->count(); ++i)
1307 			{
1308 				PageItem *currItem = m_doc->m_Selection->itemAt(i);
1309 				currItem->m_layerID = m_doc->activeLayer();
1310 				currItem->gXpos = currItem->xPos() - gx;
1311 				currItem->gYpos = currItem->yPos() - gy;
1312 				currItem->gWidth = gw;
1313 				currItem->gHeight = gh;
1314 			}
1315 			activeTransaction.commit();
1316 			activeTransaction.reset();
1317 			emit ItemGeom();
1318 		}
1319 		else if (m_doc->m_Selection->count() == 1)
1320 		{
1321 			m_doc->m_Selection->connectItemToGUI();
1322 			currItem = m_doc->m_Selection->itemAt(0);
1323 			currItem->m_layerID = m_doc->activeLayer();
1324 			if (m_doc->SnapGrid)
1325 			{
1326 				double nx = currItem->xPos();
1327 				double ny = currItem->yPos();
1328 				if (!m_doc->ApplyGuides(&nx, &ny) && !m_doc->ApplyGuides(&nx, &ny,true))
1329 				{
1330 					FPoint npx;
1331 					npx = m_doc->ApplyGridF(FPoint(nx, ny));
1332 					nx = npx.x();
1333 					ny = npx.y();
1334 				}
1335 				m_doc->moveItem(nx - currItem->xPos(), ny - currItem->yPos(), currItem);
1336 			}
1337 		}
1338 		if ((m_doc->m_Selection->count() > 0) && (m_doc->appMode != modeNormal))
1339 			this->requestMode(modeNormal);
1340 		updateContents();
1341 	}
1342 	if (!m_doc->masterPageMode())
1343 	{
1344 		int docPagesCount = m_doc->Pages->count();
1345 		int docCurrPageNo = m_doc->currentPageNumber();
1346 		for (int i = 0; i < docPagesCount; ++i)
1347 		{
1348 			double x = m_doc->Pages->at(i)->xOffset();
1349 			double y = m_doc->Pages->at(i)->yOffset();
1350 			double w = m_doc->Pages->at(i)->width();
1351 			double h = m_doc->Pages->at(i)->height();
1352 			if (QRectF(x, y, w, h).contains(dropPosDocQ))
1353 			{
1354 				if (docCurrPageNo != i)
1355 				{
1356 					m_doc->setCurrentPage(m_doc->Pages->at(i));
1357 					m_ScMW->slotSetCurrentPage(i);
1358 					DrawNew();
1359 				}
1360 				break;
1361 			}
1362 		}
1363 		setRulerPos(contentsX(), contentsY());
1364 	}
1365 }
1366 
getDragRectScreen(double * x,double * y,double * w,double * h)1367 void ScribusView::getDragRectScreen(double *x, double *y, double *w, double *h)
1368 {
1369 	QPoint in(qRound(dragX * m_canvas->scale()), qRound(dragY * m_canvas->scale()));
1370 	//	in -= QPoint(qRound(Doc->minCanvasCoordinate.x() * m_canvas->scale()), qRound(Doc->minCanvasCoordinate.y() * m_canvas->scale()));
1371 	QPoint out = contentsToViewport(in);
1372 	*x = static_cast<double>(out.x());
1373 	*y = static_cast<double>(out.y());
1374 	*w = dragW * m_canvas->scale();
1375 	*h = dragH * m_canvas->scale();
1376 }
1377 
getGroupRectScreen(double * x,double * y,double * w,double * h)1378 void ScribusView::getGroupRectScreen(double *x, double *y, double *w, double *h)
1379 {
1380 	double gx, gy, gh, gw;
1381 	m_doc->m_Selection->getGroupRect(&gx, &gy, &gw, &gh);
1382 	QPoint in(qRound(gx * m_canvas->scale()), qRound(gy * m_canvas->scale()));
1383 	//	in -= QPoint(qRound(Doc->minCanvasCoordinate.x() * m_canvas->scale()), qRound(Doc->minCanvasCoordinate.y() * m_canvas->scale()));
1384 	QPoint out = contentsToViewport(in);
1385 	*x = static_cast<double>(out.x());
1386 	*y = static_cast<double>(out.y());
1387 	*w = gw * m_canvas->scale();
1388 	*h = gh * m_canvas->scale();
1389 }
1390 
1391 
1392 
RefreshGradient(PageItem * currItem,double dx,double dy)1393 void ScribusView::RefreshGradient(PageItem *currItem, double dx, double dy)
1394 {
1395 	QTransform matrix;
1396 	QRect rect = currItem->getRedrawBounding(m_canvas->scale());
1397 	m_canvas->Transform(currItem, matrix);
1398 	FPointArray fpNew;
1399 	if (editStrokeGradient)
1400 		fpNew.setPoints(2, currItem->GrStrokeStartX, currItem->GrStrokeStartY, currItem->GrStrokeEndX, currItem->GrStrokeEndY);
1401 	else
1402 		fpNew.setPoints(2, currItem->GrStartX, currItem->GrStartY, currItem->GrEndX, currItem->GrEndY);
1403 	fpNew.map(matrix);
1404 	if (dx < 8.0) dx = 8.0;
1405 	if (dy < 8.0) dy = 8.0;
1406 	int grl = (int) floor( qMin(fpNew.point(0).x(), fpNew.point(1).x()) - dx );
1407 	int grr = (int) ceil ( qMax(fpNew.point(0).x(), fpNew.point(1).x()) + dx );
1408 	int grb = (int) ceil ( qMax(fpNew.point(0).y(), fpNew.point(1).y()) + dy );
1409 	int grt = (int) floor( qMin(fpNew.point(0).y(), fpNew.point(1).y()) - dy );
1410 	rect |= QRect(grl, grt, grr-grl, grb-grt);
1411 	updateContents(rect);
1412 }
1413 
1414 
1415 //CB-->elsewhere, util, however, only used in the view for now
PointOnLine(QPoint Start,QPoint End,QRect MArea)1416 bool ScribusView::PointOnLine(QPoint Start, QPoint End, QRect MArea)
1417 {
1418 	QPoint an, en;
1419 	if (Start.x() == End.x())
1420 	{
1421 		an = Start.y() > End.y() ? End : Start;
1422 		en = an == End ? Start : End;
1423 		for (int i = an.y(); i < en.y(); ++i)
1424 		{
1425 			if (MArea.contains(an.x(), i))
1426 				return true;
1427 		}
1428 	}
1429 	if (Start.y() == End.y())
1430 	{
1431 		an = Start.x() > End.x() ? End : Start;
1432 		en = an == End ? Start : End;
1433 		for (int i = an.x(); i < en.x(); ++i)
1434 		{
1435 			if (MArea.contains(i, an.y()))
1436 				return true;
1437 		}
1438 	}
1439 	if (abs(Start.x() - End.x()) > abs(Start.y() - End.y()))
1440 	{
1441 		an = Start.x() > End.x() ? End : Start;
1442 		en = an == End ? Start : End;
1443 		double stg = (en.y() - an.y()) / static_cast<double>((en.x() - an.x()));
1444 		for (int i = an.x(); i < en.x(); ++i)
1445 		{
1446 			if (MArea.contains(i, an.y() + qRound((i - an.x()) * stg)))
1447 				return true;
1448 		}
1449 	}
1450 	else
1451 	{
1452 		an = Start.y() > End.y() ? End : Start;
1453 		en = an == End ? Start : End;
1454 		double stg = (en.x() - an.x()) / static_cast<double>((en.y() - an.y()));
1455 		for (int i = an.y(); i < en.y(); ++i)
1456 		{
1457 			if (MArea.contains(an.x() + qRound((i - an.y()) * stg), i))
1458 				return true;
1459 		}
1460 	}
1461 	return false;
1462 }
1463 
1464 //CB-->Doc??
TransformPoly(int mode,int rot,double scaling)1465 void ScribusView::TransformPoly(int mode, int rot, double scaling)
1466 {
1467 	PageItem *currItem = m_doc->m_Selection->itemAt(0);
1468 	currItem->ClipEdited = true;
1469 	QTransform ma;
1470 	undoManager->setUndoEnabled(false);
1471 	if (m_doc->nodeEdit.isContourLine())
1472 	{
1473 		FPoint tp2(getMinClipF(&currItem->ContourLine));
1474 		FPoint tp(getMaxClipF(&currItem->ContourLine));
1475 		FPoint tpS = currItem->ContourLine.widthHeight();
1476 		currItem->ContourLine.translate(-qRound((tp.x() + tp2.x()) / 2.0), -qRound((tp.y() + tp2.y()) / 2.0));
1477 		switch (mode)
1478 		{
1479 			case 0:
1480 				ma.rotate(-rot);
1481 				break;
1482 			case 1:
1483 				ma.rotate(rot);
1484 				break;
1485 			case 2:
1486 				ma.scale(1.0 - (scaling / 100.0), 1.0 - (scaling / 100.0));
1487 				break;
1488 			case 3:
1489 				ma.scale(1.0 + (scaling / 100.0), 1.0 + (scaling / 100.0));
1490 				break;
1491 			case 4:
1492 				ma.shear(0.017455, 0);
1493 				break;
1494 			case 5:
1495 				ma.shear(-0.017455, 0);
1496 				break;
1497 			case 6:
1498 				ma.shear(0, -0.017455);
1499 				break;
1500 			case 7:
1501 				ma.shear(0, 0.017455);
1502 				break;
1503 			case 8:
1504 				ma.scale(1.0 - (scaling / tpS.x()), 1.0 - (scaling / tpS.y()));
1505 				break;
1506 			case 9:
1507 				ma.scale(1.0 + (scaling / tpS.x()), 1.0 + (scaling / tpS.y()));
1508 				break;
1509 				//10-13 are for scaling the contour line in shape edit mode
1510 			case 10:
1511 				{
1512 					double s = 1.0 - (scaling / (tp2.x() - tp.x()));
1513 					ma.scale(s, 1);
1514 					ma.translate(-scaling / s / 2, 0);
1515 				}
1516 				break;
1517 			case 11:
1518 				{
1519 					double s = 1.0 - (scaling / (tp2.x() - tp.x()));
1520 					ma.scale(s, 1);
1521 					ma.translate(scaling / s / 2, 0);
1522 				}
1523 				break;
1524 			case 12:
1525 				{
1526 					double s = 1.0 - (scaling / (tp2.y() - tp.y()));
1527 					ma.scale(1, s);
1528 					ma.translate(0, -scaling / s / 2);
1529 				}
1530 				break;
1531 			case 13:
1532 				{
1533 					double s = 1.0 - (scaling/(tp2.y() - tp.y()));
1534 					ma.scale(1, s);
1535 					ma.translate(0, scaling / s / 2);
1536 				}
1537 				break;
1538 		}
1539 		currItem->ContourLine.map(ma);
1540 		currItem->ContourLine.translate(qRound((tp.x() + tp2.x()) / 2.0), qRound((tp.y() + tp2.y()) / 2.0));
1541 		updateContents();
1542 		currItem->FrameOnly = true;
1543 		m_doc->regionsChanged()->update(QRect());
1544 		undoManager->setUndoEnabled(true);
1545 		if (UndoManager::undoEnabled())
1546 		{
1547 			undoManager->setUndoEnabled(false);
1548 			currItem->checkChanges(true);
1549 			undoManager->setUndoEnabled(true);
1550 			SimpleState *ss = new SimpleState(Um::EditContourLine, "", Um::IBorder);
1551 			ss->set("EDIT_CONTOUR");
1552 			ss->set("MODE", mode);
1553 			ss->set("ROT", rot);
1554 			ss->set("SCALING", scaling);
1555 			undoManager->action(currItem, ss);
1556 		}
1557 		emit DocChanged();
1558 		return;
1559 	}
1560 	FPoint oldPos(currItem->xyPos());
1561 	double offsX = currItem->width() / 2.0;
1562 	double offsY = currItem->height() / 2.0;
1563 	double oldWidth = currItem->width();
1564 	double oldHeight = currItem->height();
1565 	ma.translate(-offsX, -offsY);
1566 	switch (mode)
1567 	{
1568 		case 0:
1569 			ma.rotate(-rot);
1570 			break;
1571 		case 1:
1572 			ma.rotate(rot);
1573 			break;
1574 		case 2:
1575 			ma.scale(1.0 - (scaling / 100.0), 1.0 - (scaling / 100.0));
1576 			break;
1577 		case 3:
1578 			ma.scale(1.0 + (scaling / 100.0), 1.0 + (scaling / 100.0));
1579 			break;
1580 		case 4:
1581 			ma.shear(0.017455, 0);
1582 			break;
1583 		case 5:
1584 			ma.shear(-0.017455, 0);
1585 			break;
1586 		case 6:
1587 			ma.shear(0, -0.017455);
1588 			break;
1589 		case 7:
1590 			ma.shear(0, 0.017455);
1591 			break;
1592 		case 8:
1593 			ma.scale(1.0 - (scaling / oldWidth), 1.0 - (scaling / oldHeight));
1594 			break;
1595 		case 9:
1596 			ma.scale(1.0 + (scaling / oldWidth), 1.0 + (scaling / oldHeight));
1597 			break;
1598 	}
1599 	currItem->PoLine.map(ma);
1600 	currItem->PoLine.translate(offsX, offsY);
1601 	m_doc->adjustItemSize(currItem);
1602 	QTransform ma2;
1603 	ma2.translate(oldPos.x(), oldPos.y());
1604 	ma2.scale(1, 1);
1605 	ma2.translate(offsX, offsY);
1606 	FPoint n(-offsX, -offsY);
1607 	switch (mode)
1608 	{
1609 		case 0:
1610 			ma2.rotate(-rot);
1611 			break;
1612 		case 1:
1613 			ma2.rotate(rot);
1614 			break;
1615 		case 2:
1616 			ma2.scale(1.0 - (scaling / 100.0), 1.0 - (scaling / 100.0));
1617 			break;
1618 		case 3:
1619 			ma2.scale(1.0 + (scaling / 100.0), 1.0 + (scaling / 100.0));
1620 			break;
1621 		case 4:
1622 			ma2.shear(0.017455, 0);
1623 			break;
1624 		case 5:
1625 			ma2.shear(-0.017455, 0);
1626 			break;
1627 		case 6:
1628 			ma2.shear(0, -0.017455);
1629 			break;
1630 		case 7:
1631 			ma2.shear(0, 0.017455);
1632 			break;
1633 		case 8:
1634 			ma2.scale(1.0 - (scaling / oldWidth), 1.0 - (scaling / oldHeight));
1635 			break;
1636 		case 9:
1637 			ma2.scale(1.0 + (scaling / oldWidth), 1.0 + (scaling / oldHeight));
1638 			break;
1639 	}
1640 	double x = ma2.m11() * n.x() + ma2.m21() * n.y() + ma2.dx();
1641 	double y = ma2.m22() * n.y() + ma2.m12() * n.x() + ma2.dy();
1642 	m_doc->moveItem(x-oldPos.x(), y-oldPos.y(), currItem);
1643 	if (currItem->isPathText())
1644 		currItem->updatePolyClip();
1645 	m_doc->setRedrawBounding(currItem);
1646 	m_doc->regionsChanged()->update(QRect());
1647 	currItem->update();
1648 	currItem->FrameType = 3;
1649 	undoManager->setUndoEnabled(true);
1650 	if (UndoManager::undoEnabled())
1651 	{
1652 		undoManager->setUndoEnabled(false);
1653 		currItem->checkChanges(true);
1654 		undoManager->setUndoEnabled(true);
1655 		SimpleState *ss = new SimpleState(Um::EditShape, "", Um::IBorder);
1656 		ss->set("EDIT_SHAPE");
1657 		ss->set("MODE", mode);
1658 		ss->set("ROT", rot);
1659 		ss->set("SCALING", scaling);
1660 		undoManager->action(currItem, ss);
1661 	}
1662 	emit DocChanged();
1663 }
1664 
slotSetCurs(int x,int y)1665 bool ScribusView::slotSetCurs(int x, int y)
1666 {
1667 	PageItem *item;
1668 	if (!m_doc->getItem(&item))
1669 		return false;
1670 
1671 	PageItem_TextFrame *textFrame;
1672 	QPointF canvasPoint;
1673 	QTransform mm = item->getTransform();
1674 	QPointF textFramePoint = mm.map(QPointF(0, 0));
1675 	if (item->isTextFrame())
1676 	{
1677 		textFrame = item->asTextFrame();
1678 		canvasPoint = m_canvas->globalToCanvas(QPoint(x,y)).toQPointF();
1679 	}
1680 	else if (item->isTable())
1681 	{
1682 		// Move to cell under cursor and position the text cursor.
1683 		PageItem_Table *table = item->asTable();
1684 		QPointF tablePoint = m_canvas->globalToCanvas(QPoint(x, y)).toQPointF();
1685 		table->moveTo(table->cellAt(tablePoint));
1686 		textFrame = table->activeCell().textFrame();
1687 		mm = textFrame->getTransform();
1688 		canvasPoint = table->getTransform().inverted().map(tablePoint) - table->gridOffset();
1689 	}
1690 	else if (item->isImageFrame())
1691 		return true;
1692 	else
1693 		return false;
1694 
1695 	if (m_canvas->frameHitTest(canvasPoint, textFrame) == Canvas::INSIDE)
1696 	{
1697 		// #9592 : layout must be valid here, or screenToPosition() may crash
1698 		if (textFrame->invalid)
1699 			textFrame->layout();
1700 
1701 		double px = canvasPoint.x() - textFramePoint.x();
1702 		double py = canvasPoint.y() - textFramePoint.y();
1703 		FPoint point(px, py);
1704 		if (mm.isInvertible() && textFrame->itemText.length() > 0)
1705 		{
1706 			qreal tx = 0, ty = 0;
1707 			mm.inverted().map(canvasPoint.x(), canvasPoint.y(), &tx, &ty);
1708 			point.setXY(tx, ty);
1709 		}
1710 		if (textFrame->imageFlippedH())
1711 			point.setX(textFrame->width() - point.x());
1712 		if (textFrame->imageFlippedV())
1713 			point.setY(textFrame->height() - point.y());
1714 		if (textFrame->itemText.length() == 0)
1715 			textFrame->itemText.setCursorPosition(0);
1716 		else
1717 		{
1718 			int result = textFrame->textLayout.pointToPosition(point.toQPointF());
1719 			if (result >= 0)
1720 				textFrame->itemText.setCursorPosition(result);
1721 		}
1722 
1723 		if (textFrame->itemText.length() > 0)
1724 		{
1725 			int pos = qMax(0, qMin(textFrame->itemText.cursorPosition(), textFrame->itemText.length()));
1726 			if (textFrame->itemText.hasSelection())
1727 			{
1728 				int firstSelected = textFrame->itemText.startOfSelection();
1729 				int lastSelected  = qMax(textFrame->itemText.endOfSelection() - 1, 0);
1730 				pos = qMax(firstSelected, qMin(pos, lastSelected));
1731 			}
1732 			m_doc->currentStyle.charStyle() = textFrame->currentCharStyle();
1733 			emit ItemCharStyle(m_doc->currentStyle.charStyle());
1734 			emit ItemTextEffects(m_doc->currentStyle.charStyle().effects());
1735 			emit ItemTextAlign(textFrame->itemText.paragraphStyle(pos).alignment());
1736 			return true;
1737 		}
1738 		m_doc->currentStyle.charStyle() = textFrame->itemText.defaultStyle().charStyle();
1739 		emit ItemCharStyle(textFrame->itemText.defaultStyle().charStyle());
1740 		emit ItemTextEffects(textFrame->itemText.defaultStyle().charStyle().effects());
1741 		emit ItemTextAlign(0);
1742 		return true;
1743 	}
1744 	return false;
1745 }
1746 
1747 
dragTimerTimeOut()1748 void ScribusView::dragTimerTimeOut()
1749 {
1750 	m_dragTimerFired = true;
1751 	// #0007865
1752 	// 	qApp->changeOverrideCursor(QCursor(loadIcon("dragpix.png")));
1753 }
1754 
getResizeCursor(PageItem * currItem,QRect mpo,Qt::CursorShape cursorShape)1755 Qt::CursorShape ScribusView::getResizeCursor(PageItem *currItem, QRect mpo, Qt::CursorShape cursorShape)
1756 {
1757 	QTransform ma;
1758 	m_canvas->Transform(currItem, ma);
1759 	QPoint tx = ma.map(QPoint(static_cast<int>(currItem->width()), 0));
1760 	QPoint tx2 = ma.map(QPoint(0, static_cast<int>(currItem->height())));
1761 	if (mpo.contains(tx) || mpo.contains(tx2))
1762 	{
1763 		double rr = fabs(currItem->rotation());
1764 		if (((rr >= 0.0) && (rr < 45.0)) || ((rr >= 135.0) && (rr < 225.0)) || ((rr >=315.0) && (rr <= 360.0)))
1765 			cursorShape = Qt::SizeBDiagCursor;
1766 		if (((rr >= 45.0) && (rr < 135.0)) || ((rr >= 225.0) && (rr < 315.0)))
1767 			cursorShape = Qt::SizeFDiagCursor;
1768 	}
1769 	tx = ma.map(QPoint(static_cast<int>(currItem->width()), static_cast<int>(currItem->height())/2));
1770 	tx2 = ma.map(QPoint(0, static_cast<int>(currItem->height())/2));
1771 	if (mpo.contains(tx) || mpo.contains(tx2))
1772 	{
1773 		double rr = fabs(currItem->rotation());
1774 		if (((rr >= 0.0) && (rr < 45.0)) || ((rr >= 135.0) && (rr < 225.0)) || ((rr >= 315.0) && (rr <= 360.0)))
1775 			cursorShape = Qt::SizeHorCursor;
1776 		if (((rr >= 45.0) && (rr < 135.0)) || ((rr >= 225.0) && (rr < 315.0)))
1777 			cursorShape = Qt::SizeVerCursor;
1778 	}
1779 	tx = ma.map(QPoint(static_cast<int>(currItem->width())/2, 0));
1780 	tx2 = ma.map(QPoint(static_cast<int>(currItem->width())/2, static_cast<int>(currItem->height())));
1781 	if (mpo.contains(tx) || mpo.contains(tx2))
1782 	{
1783 		double rr = fabs(currItem->rotation());
1784 		if (((rr >= 0.0) && (rr < 45.0)) || ((rr >= 135.0) && (rr < 225.0)) || ((rr >= 315.0) && (rr <= 360.0)))
1785 			cursorShape = Qt::SizeVerCursor;
1786 		if (((rr >= 45.0) && (rr < 135.0)) || ((rr >= 225.0) && (rr < 315.0)))
1787 			cursorShape = Qt::SizeHorCursor;
1788 	}
1789 	tx = ma.map(QPoint(static_cast<int>(currItem->width()), static_cast<int>(currItem->height())));
1790 	tx2 = ma.map(QPoint(0, 0));
1791 	if (mpo.contains(tx) || mpo.contains(tx2))
1792 	{
1793 		if (!currItem->sizeHLocked() && ! currItem->sizeVLocked())
1794 		{
1795 			double rr = fabs(currItem->rotation());
1796 			if (((rr >= 0.0) && (rr < 45.0)) || ((rr >= 135.0) && (rr < 225.0)) ||
1797 					((rr >= 315.0) && (rr <= 360.0)))
1798 				cursorShape = Qt::SizeFDiagCursor;
1799 			if (((rr >= 45.0) && (rr < 135.0)) || ((rr >= 225.0) && (rr < 315.0)))
1800 				cursorShape = Qt::SizeBDiagCursor;
1801 		}
1802 	}
1803 	return cursorShape;
1804 }
1805 
selectItemByNumber(int nr,bool draw,bool single)1806 void ScribusView::selectItemByNumber(int nr, bool draw, bool single)
1807 {
1808 	if (nr < m_doc->Items->count())
1809 		selectItem(m_doc->Items->at(nr), draw, single);
1810 }
1811 
1812 //CB-->Doc/Fix
selectItem(PageItem * currItem,bool draw,bool single)1813 void ScribusView::selectItem(PageItem *currItem, bool draw, bool single)
1814 {
1815 	if (!currItem->isSelected())
1816 	{
1817 		if (single)
1818 		{
1819 			m_doc->m_Selection->addItem(currItem);
1820 			currItem->isSingleSel = true;
1821 			updateContents();
1822 		}
1823 		else
1824 		{
1825 			m_doc->m_Selection->addItem(currItem);
1826 			if (draw)
1827 				updateContents(currItem->getRedrawBounding(m_canvas->scale()));
1828 		}
1829 	}
1830 	if (draw && !m_doc->m_Selection->isEmpty())
1831 	{
1832 		double x, y, w, h;
1833 		m_doc->m_Selection->getGroupRect(&x, &y, &w, &h);
1834 		getGroupRectScreen(&x, &y, &w, &h);
1835 		updateContents();
1836 		emit ItemGeom();
1837 		emit HaveSel();
1838 	}
1839 }
1840 
1841 //CB Remove bookmark interaction here, item/doc should do it
deselectItems(bool)1842 void ScribusView::deselectItems(bool /*prop*/)
1843 {
1844 	if (m_doc->m_Selection->isEmpty())
1845 		return;
1846 
1847 	const double scale = m_canvas->scale();
1848 	PageItem* currItem = nullptr;
1849 	for (int i = 0; i < m_doc->m_Selection->count(); ++i)
1850 	{
1851 		currItem = m_doc->m_Selection->itemAt(i);
1852 		if ((currItem->isTextFrame()) && (currItem->isBookmark))
1853 			emit ChBMText(currItem);
1854 	}
1855 	if (!m_doc->m_Selection->isMultipleSelection())
1856 	{
1857 		currItem = m_doc->m_Selection->itemAt(0);
1858 		if (currItem != nullptr)
1859 		{
1860 			currItem->itemText.deselectAll();
1861 			currItem->HasSel = false;
1862 		}
1863 	}
1864 	double x, y, w, h;
1865 	m_doc->m_Selection->getVisualGroupRect(&x, &y, &w, &h);
1866 	m_doc->m_Selection->clear();
1867 	updateCanvas(x - 5 / scale, y - 5 / scale, w + 10 / scale, h + 10 / scale);
1868 }
1869 
1870 // FIXME:av -> CanvasMode_legacy / Doc
1871 //CB Remove emit/start pasting objects
PasteToPage()1872 void ScribusView::PasteToPage()
1873 {
1874 	UndoTransaction activeTransaction;
1875 	int ac = m_doc->Items->count();
1876 	if (UndoManager::undoEnabled())
1877 		activeTransaction = undoManager->beginTransaction(m_doc->currentPage()->getUName(), nullptr, Um::Paste, "", Um::IPaste);
1878 
1879 	QString buffer = ScMimeData::clipboardScribusElem();
1880 	emit LoadElem(buffer, dragX, dragY, false, false, m_doc, this);
1881 
1882 	m_doc->DraggedElem = nullptr;
1883 	m_doc->DragElements.clear();
1884 	updateContents();
1885 	Selection newObjects(this, false);
1886 	for (int as = ac; as < m_doc->Items->count(); ++as)
1887 	{
1888 		PageItem* currItem = m_doc->Items->at(as);
1889 		if (currItem->isBookmark)
1890 			emit AddBM(currItem);
1891 		newObjects.addItem(currItem);
1892 		currItem->m_layerID = m_doc->activeLayer();
1893 	}
1894 	if (newObjects.count() > 1)
1895 	{
1896 		double gx, gy, gh, gw;
1897 		newObjects.getGroupRect(&gx, &gy, &gw, &gh);
1898 		m_doc->moveGroup(dragX - gx, dragY - gy, &newObjects);
1899 		newObjects.getGroupRect(&gx, &gy, &gw, &gh);
1900 		double nx = gx;
1901 		double ny = gy;
1902 		if (!m_doc->ApplyGuides(&nx, &ny) && !m_doc->ApplyGuides(&nx, &ny,true))
1903 		{
1904 			FPoint npx;
1905 			npx = m_doc->ApplyGridF(FPoint(nx, ny));
1906 			nx = npx.x();
1907 			ny = npx.y();
1908 		}
1909 		m_doc->moveGroup(nx - gx, ny - gy, &newObjects);
1910 		newObjects.getGroupRect(&gx, &gy, &gw, &gh);
1911 		nx = gx + gw;
1912 		ny = gy + gh;
1913 		m_doc->ApplyGuides(&nx, &ny);
1914 		m_doc->ApplyGuides(&nx, &ny,true);
1915 		m_doc->moveGroup(nx - (gx + gw), ny - (gy + gh), &newObjects);
1916 		newObjects.getGroupRect(&gx, &gy, &gw, &gh);
1917 		emit ItemGeom();
1918 		emit HaveSel();
1919 	}
1920 	else if (newObjects.count() == 1)
1921 	{
1922 		PageItem *currItem = newObjects.itemAt(0);
1923 		if (m_doc->SnapGrid)
1924 		{
1925 			double nx = currItem->xPos();
1926 			double ny = currItem->yPos();
1927 			if (!m_doc->ApplyGuides(&nx, &ny) && !m_doc->ApplyGuides(&nx, &ny,true))
1928 			{
1929 				FPoint npx;
1930 				npx = m_doc->ApplyGridF(FPoint(nx, ny));
1931 				nx = npx.x();
1932 				ny = npx.y();
1933 			}
1934 			m_doc->moveItem(nx - currItem->xPos(), ny - currItem->yPos(), currItem);
1935 		}
1936 		currItem->emitAllToGUI();
1937 	}
1938 	else // newObjects.count() == 0
1939 	{
1940 		if (activeTransaction)
1941 		{
1942 			activeTransaction.cancel();
1943 			activeTransaction.reset();
1944 		}
1945 		return;
1946 	}
1947 	newObjects.clear();
1948 	if (activeTransaction)
1949 	{
1950 		activeTransaction.commit();
1951 		activeTransaction.reset();
1952 	}
1953 	emit DocChanged();
1954 }
1955 
resizeEvent(QResizeEvent * event)1956 void ScribusView::resizeEvent ( QResizeEvent * event )
1957 {
1958 	// 	qDebug() << "ScribusView::resizeEvent";
1959 	QScrollArea::resizeEvent(event);
1960 	horizRuler->setGeometry(m_vhRulerHW, 1, width()-m_vhRulerHW-1, m_vhRulerHW);
1961 	vertRuler->setGeometry(1, m_vhRulerHW, m_vhRulerHW, height()-m_vhRulerHW-1);
1962 	rulerMover->setGeometry(1, 1, m_vhRulerHW, m_vhRulerHW);
1963 	if (clockLabel->isExpanded())
1964 	{
1965 		clockLabel->setGeometry(m_vhRulerHW + 1, height() - m_vhRulerHW - 61, 60, 60);
1966 		clockLabel->setFixedSize(60, 60);
1967 	}
1968 	else
1969 	{
1970 		clockLabel->setGeometry(m_vhRulerHW + 1, height() - m_vhRulerHW - 16, 15, 15);
1971 		clockLabel->setFixedSize(15, 15);
1972 	}
1973 	endEditButton->setGeometry(m_vhRulerHW + 1, height() - m_vhRulerHW - endEditButton->minimumSizeHint().height() - 1, endEditButton->minimumSizeHint().width(), endEditButton->minimumSizeHint().height());
1974 	m_canvas->setForcedRedraw(true);
1975 	m_canvas->resetRenderMode();
1976 	// Per Qt doc, not painting should be done in a resizeEvent,
1977 	// a paint event will be emitted right afterwards
1978 	// m_canvas->update();
1979 }
1980 
setHBarGeometry(QScrollBar & bar,int x,int y,int w,int h)1981 void ScribusView::setHBarGeometry(QScrollBar &bar, int x, int y, int w, int h)
1982 {
1983 	bar.setGeometry(x, y, w, h);
1984 	if (m_ready)
1985 		horizRuler->setGeometry(m_vhRulerHW, 1, w-m_vhRulerHW-1, m_vhRulerHW);
1986 }
1987 
setVBarGeometry(QScrollBar & bar,int x,int y,int w,int h)1988 void ScribusView::setVBarGeometry(QScrollBar &bar, int x, int y, int w, int h)
1989 {
1990 	bar.setGeometry(x, y, w, h);
1991 	if (m_ready)
1992 	{
1993 		vertRuler->setGeometry(1, m_vhRulerHW, m_vhRulerHW, h-m_vhRulerHW-1);
1994 		rulerMover->setGeometry(1, 1, m_vhRulerHW, m_vhRulerHW);
1995 	}
1996 }
1997 
mousePressed()1998 bool ScribusView::mousePressed()
1999 {
2000 	return m_canvas->m_viewMode.m_MouseButtonPressed;
2001 }
2002 
resetMousePressed()2003 void ScribusView::resetMousePressed()
2004 {
2005 	m_canvas->m_viewMode.m_MouseButtonPressed = false;
2006 }
2007 
2008 
startGroupTransaction(const QString & action,const QString & description,QPixmap * actionIcon,Selection * customSelection)2009 void ScribusView::startGroupTransaction(const QString& action, const QString& description, QPixmap* actionIcon, Selection* customSelection)
2010 {
2011 	Selection* itemSelection = (customSelection!=nullptr) ? customSelection : m_doc->m_Selection;
2012 	assert(itemSelection!=nullptr);
2013 	int selectedItemCount=itemSelection->count();
2014 	Q_ASSERT(selectedItemCount > 0);
2015 	if (!m_groupTransaction)
2016 	{
2017 		QString tooltip = description;
2018 		QString target = Um::SelectionGroup;
2019 		QPixmap* targetIcon = Um::IGroup;
2020 		if (tooltip.isEmpty() && selectedItemCount > 1)
2021 		{
2022 			if (selectedItemCount <= Um::ItemsInvolvedLimit)
2023 			{
2024 				tooltip = Um::ItemsInvolved + "\n";
2025 				for (int i = 0; i < selectedItemCount; ++i)
2026 					tooltip += "\t" + itemSelection->itemAt(i)->getUName() + "\n";
2027 			}
2028 			else
2029 			{
2030 				tooltip = Um::ItemsInvolved2 + "\n";
2031 			}
2032 		}
2033 		if (selectedItemCount == 1)
2034 		{
2035 			target = itemSelection->itemAt(0)->getUName();
2036 			targetIcon = itemSelection->itemAt(0)->getUPixmap();
2037 		}
2038 		m_groupTransaction = undoManager->beginTransaction(target, targetIcon,
2039 														   action, tooltip, actionIcon);
2040 	}
2041 	++m_groupTransactions;
2042 }
2043 
2044 
2045 /**
2046 
2047 */
endGroupTransaction()2048 void ScribusView::endGroupTransaction()
2049 {
2050 	if (m_groupTransactions > 0)
2051 	{
2052 		--m_groupTransactions;
2053 	}
2054 	if (m_groupTransaction && m_groupTransactions == 0)
2055 	{
2056 		m_groupTransaction.commit();
2057 		m_groupTransaction.reset();
2058 	}
2059 }
2060 
2061 /**
2062    Always cancels the toplevel transaction and all enclosed ones
2063  */
cancelGroupTransaction()2064 void ScribusView::cancelGroupTransaction()
2065 {
2066 	if (m_groupTransaction && m_groupTransactions == 1)
2067 	{
2068 		m_groupTransaction.cancel();
2069 		m_groupTransaction.reset();
2070 	}
2071 	else if (m_groupTransaction)
2072 	{
2073 		m_groupTransaction.markFailed();
2074 	}
2075 	if (m_groupTransactions > 0)
2076 		--m_groupTransactions;
2077 }
2078 
2079 
2080 // jjsa 27-03-2004 add for better setting while zooming
2081 //CB find a new name
rememberOldZoomLocation(int mx,int my)2082 void ScribusView::rememberOldZoomLocation(int mx, int my)
2083 {
2084 	m_oldZoomX = mx;
2085 	m_oldZoomY = my;
2086 }
2087 
setRulerPos(int x,int y)2088 void ScribusView::setRulerPos(int x, int y)
2089 {
2090 	if (m_ScMW->scriptIsRunning())
2091 		return;
2092 	if (m_doc->guidesPrefs().rulerMode)
2093 	{
2094 		horizRuler->shift(x / m_canvas->scale() - m_doc->currentPage()->xOffset());
2095 		vertRuler->shift(y / m_canvas->scale() - m_doc->currentPage()->yOffset());
2096 	}
2097 	else
2098 	{
2099 		horizRuler->shift(x / m_canvas->scale());
2100 		vertRuler->shift(y / m_canvas->scale());
2101 	}
2102 	//	horizRuler->offs += qRound(Doc->minCanvasCoordinate.x() - 1 - Doc->rulerXoffset);
2103 	//	vertRuler->offs += qRound(Doc->minCanvasCoordinate.y() - 1 - Doc->rulerYoffset);
2104 	horizRuler->shiftRel(0*m_doc->minCanvasCoordinate.x() - m_doc->rulerXoffset);
2105 	vertRuler->shiftRel(0*m_doc->minCanvasCoordinate.y() - m_doc->rulerYoffset);
2106 	horizRuler->update();
2107 	vertRuler->update();
2108 	//	evSpon = true;
2109 	QString newStatusBarText(" ");
2110 	if ((verticalScrollBar()->isSliderDown()) || (horizontalScrollBar()->isSliderDown()))
2111 	{
2112 		QList<int> pag;
2113 		pag.clear();
2114 		int docPageCount=m_doc->Pages->count();
2115 		for (int i = 0; i < docPageCount; ++i)
2116 		{
2117 			int xs = static_cast<int>(m_doc->Pages->at(i)->xOffset() * m_canvas->scale());
2118 			int ys = static_cast<int>(m_doc->Pages->at(i)->yOffset() * m_canvas->scale());
2119 			int ws = static_cast<int>(m_doc->Pages->at(i)->width() * m_canvas->scale());
2120 			int hs = static_cast<int>(m_doc->Pages->at(i)->height() * m_canvas->scale());
2121 			QRect drawRect = QRect(x, y, visibleWidth(), visibleHeight());
2122 			//			drawRect.moveBy(qRound(-Doc->minCanvasCoordinate.x() * m_canvas->scale()), qRound(-Doc->minCanvasCoordinate.y() * m_canvas->scale()));
2123 			if (drawRect.intersects(QRect(xs, ys, ws, hs)))
2124 				pag.append(i+1);
2125 		}
2126 		if (!pag.isEmpty())
2127 			newStatusBarText=( tr("Page %1 to %2").arg(pag.first()).arg(pag.last()));
2128 	}
2129 	m_ScMW->setStatusBarInfoText(newStatusBarText);
2130 }
2131 
2132 
2133 //CB This MUST now be called AFTER a call to doc->addPage or doc->addMasterPage as it
2134 //does NOT create a page anymore.
addPage(int nr,bool mov)2135 ScPage* ScribusView::addPage(int nr, bool mov)
2136 {
2137 	ScPage* fe=m_doc->Pages->at(nr);
2138 	Q_ASSERT(fe!=nullptr);
2139 	if (fe==nullptr)
2140 		return nullptr;
2141 	//Note this picks up the new page or master page depending on the mode.
2142 	//	reformPages(mov);
2143 	m_doc->reformPages(mov);
2144 	m_ScMW->slotSetCurrentPage(nr);
2145 	m_canvas->m_viewMode.m_MouseButtonPressed = false;
2146 	m_doc->DragP = false;
2147 	m_doc->leaveDrag = false;
2148 	m_canvas->m_viewMode.operItemMoving = false;
2149 	MidButt = false;
2150 	HaveSelRect = false;
2151 	Magnify = false;
2152 	m_doc->nodeEdit.setEdPoints(true);
2153 	DraggedGroup = false;
2154 	//FIXME:av	MoveGY = false;
2155 	//FIXME:av	MoveGX = false;
2156 	m_doc->nodeEdit.setIsContourLine(false);
2157 	return fe;
2158 }
2159 
reformPages(bool moveObjects)2160 void ScribusView::reformPages(bool moveObjects)
2161 {
2162 	m_doc->reformPages(moveObjects);
2163 	reformPagesView();
2164 }
2165 
reformPagesView()2166 void ScribusView::reformPagesView()
2167 {
2168 	if (!m_ScMW->scriptIsRunning())
2169 		setContentsPos(qRound((m_doc->currentPage()->xOffset() - 10 - 0 * m_doc->minCanvasCoordinate.x()) * m_canvas->scale()), qRound((m_doc->currentPage()->yOffset() - 10 - 0 * m_doc->minCanvasCoordinate.y()) * m_canvas->scale()));
2170 	if (!m_doc->isLoading())
2171 	{
2172 		setRulerPos(contentsX(), contentsY());
2173 		m_ScMW->slotSetCurrentPage(m_doc->currentPage()->pageNr());
2174 	}
2175 }
2176 
updatesOn(bool on)2177 void ScribusView::updatesOn(bool on)
2178 {
2179 	updateOn = on;
2180 	setUpdatesEnabled(on);
2181 	viewport()->setUpdatesEnabled(on);
2182 }
2183 
2184 
2185 /*!
2186   paints the canvas inside the box given in canvas coordinates
2187  */
updateCanvas(QRectF box)2188 void ScribusView::updateCanvas(QRectF box)
2189 {
2190 	if (box.isValid())
2191 	{
2192 		QPoint upperLeft = m_canvas->canvasToLocal(box.topLeft());
2193 		QPoint lowerRight = m_canvas->canvasToLocal(box.bottomRight());
2194 		upperLeft.setX(qMax(0, upperLeft.x() - 10));
2195 		upperLeft.setY(qMax(0, upperLeft.y() - 10));
2196 		lowerRight.setX(qMax(0, lowerRight.x() + 10));
2197 		lowerRight.setY(qMax(0, lowerRight.y() + 10));
2198 		//		qDebug() << "updateCanvas:" << upperLeft << lowerRight;
2199 		m_canvas->update(upperLeft.x(), upperLeft.y(), lowerRight.x() - upperLeft.x(), lowerRight.y() - upperLeft.y());
2200 	}
2201 	else
2202 	{
2203 		m_canvas->update(horizontalScrollBar()->value(), verticalScrollBar()->value(), viewport()->width(), viewport()->height());
2204 	}
2205 }
2206 
2207 
2208 /*!
2209   Scrolls the canvas so (x,y) becomes the origin
2210  */
setCanvasOrigin(double x,double y)2211 void ScribusView::setCanvasOrigin(double x, double y)
2212 {
2213 	double scale = m_canvas->scale();
2214 	horizontalScrollBar()->setValue(qRound(x * scale));
2215 	verticalScrollBar()->setValue(qRound(y * scale));
2216 	// fix ranges
2217 	QSize maxViewport = maximumViewportSize();
2218 	int newCanvasWidth  = qRound((m_doc->maxCanvasCoordinate.x() - m_doc->minCanvasCoordinate.x()) * scale);
2219 	int newCanvasHeight = qRound((m_doc->maxCanvasCoordinate.y() - m_doc->minCanvasCoordinate.y()) * scale);
2220 	horizontalScrollBar()->setRange(0, newCanvasWidth - maxViewport.width());
2221 	verticalScrollBar()->setRange(0, newCanvasHeight - maxViewport.height());
2222 }
2223 
2224 
2225 /*!
2226   Scrolls the canvas so (x,y) is in the center of the viewport
2227  */
setCanvasCenter(double x,double y)2228 void ScribusView::setCanvasCenter(double x, double y)
2229 {
2230 	double scale = m_canvas->scale();
2231 	setCanvasOrigin(x - viewport()->width() / scale,
2232 					y - viewport()->height() / scale);
2233 }
2234 
2235 /*!
2236   Scrolls canvas relatively
2237  */
scrollCanvasBy(double deltaX,double deltaY)2238 void ScribusView::scrollCanvasBy(double deltaX, double deltaY)
2239 {
2240 	double scale = m_canvas->scale();
2241 	horizontalScrollBar()->setValue(qRound(horizontalScrollBar()->value() + deltaX * scale));
2242 	verticalScrollBar()->setValue(qRound(verticalScrollBar()->value() + deltaX * scale));
2243 }
2244 
2245 
2246 /*!
2247   returns the canvas's origin in canvas coordinates.
2248   Doc->minCanvasCoordinate <= result <= Doc->maxCanvasCoordinate
2249  */
canvasOrigin() const2250 FPoint ScribusView::canvasOrigin() const
2251 {
2252 	double scale = m_canvas->scale();
2253 	return FPoint(horizontalScrollBar()->value() / scale, verticalScrollBar()->value() / scale);
2254 }
2255 
2256 
2257 /*!
2258   returns the visible part of the canvas in canvas coordinates
2259  */
visibleCanvasRect() const2260 QRectF ScribusView::visibleCanvasRect() const
2261 {
2262 	double scale = m_canvas->scale();
2263 	return QRectF(horizontalScrollBar()->value() / scale + m_doc->minCanvasCoordinate.x(),
2264 				  verticalScrollBar()->value() / scale + m_doc->minCanvasCoordinate.y(),
2265 				  viewport()->width() / scale,
2266 				  viewport()->height() / scale);
2267 }
2268 
setZoom()2269 void ScribusView::setZoom()
2270 {
2271 	double x = qMax(contentsX() / m_canvas->scale(), m_doc->minCanvasCoordinate.x());
2272 	double y = qMax(contentsY() / m_canvas->scale(), m_doc->minCanvasCoordinate.y());
2273 	double w = qMin(visibleWidth() / m_canvas->scale(), m_doc->maxCanvasCoordinate.x() - m_doc->minCanvasCoordinate.x());
2274 	double h = qMin(visibleHeight() / m_canvas->scale(), m_doc->maxCanvasCoordinate.y() - m_doc->minCanvasCoordinate.y());
2275 
2276 	int zoomX = qRound(x + w / 2);
2277 	int zoomY = qRound(y + h / 2);
2278 	rememberOldZoomLocation(zoomX, zoomY);
2279 
2280 	zoom(m_oldZoomX, m_oldZoomY, m_ScMW->zoomSpinBox->value() / 100.0 * Prefs->displayPrefs.displayScale, false);
2281 	setFocus();
2282 }
2283 
slotZoom100()2284 void ScribusView::slotZoom100()
2285 {
2286 	double x = qMax(contentsX() / m_canvas->scale(), m_doc->minCanvasCoordinate.x());
2287 	double y = qMax(contentsY() / m_canvas->scale(), m_doc->minCanvasCoordinate.y());
2288 	double w = qMin(visibleWidth() / m_canvas->scale(), m_doc->maxCanvasCoordinate.x() - m_doc->minCanvasCoordinate.x());
2289 	double h = qMin(visibleHeight() / m_canvas->scale(), m_doc->maxCanvasCoordinate.y() - m_doc->minCanvasCoordinate.y());
2290 
2291 	int zoomX = qRound(x + w / 2);
2292 	int zoomY = qRound(y + h / 2);
2293 	rememberOldZoomLocation(zoomX, zoomY);
2294 
2295 	int zoomPointX(m_oldZoomX), zoomPointY(m_oldZoomY);
2296 	if (m_doc->m_Selection->count() != 0)
2297 	{
2298 		QRectF selRect = m_doc->m_Selection->getVisualGroupRect();
2299 		zoomPointX = qRound(selRect.x() + selRect.width() / 2.0);
2300 		zoomPointY = qRound(selRect.y() + selRect.height() / 2.0);
2301 	}
2302 	else if (m_doc->currentPage() != nullptr)
2303 	{
2304 		ScPage* currentPage = m_doc->currentPage();
2305 		zoomPointX = qRound(currentPage->xOffset() + currentPage->width() / 2.0);
2306 		zoomPointY = qRound(currentPage->yOffset() + currentPage->height() / 2.0);
2307 	}
2308 	zoom(zoomPointX, zoomPointY, Prefs->displayPrefs.displayScale, false);
2309 }
2310 
slotZoomIn(int mx,int my,bool preservePoint)2311 void ScribusView::slotZoomIn(int mx, int my, bool preservePoint)
2312 {
2313 	// FIXME : mx and my should really be ScribusView local coordinates or global coordinates
2314 	int oldZoomX(mx), oldZoomY(my);
2315 	if ((mx == 0) && (my == 0))
2316 	{
2317 		double x = qMax(contentsX() / m_canvas->scale(), m_doc->minCanvasCoordinate.x());
2318 		double y = qMax(contentsY() / m_canvas->scale(), m_doc->minCanvasCoordinate.y());
2319 		double w = qMin(visibleWidth() / m_canvas->scale(), m_doc->maxCanvasCoordinate.x() - m_doc->minCanvasCoordinate.x());
2320 		double h = qMin(visibleHeight() / m_canvas->scale(), m_doc->maxCanvasCoordinate.y() - m_doc->minCanvasCoordinate.y());
2321 		oldZoomX = qRound(w / 2.0 + x);
2322 		oldZoomY = qRound(h / 2.0 + y);
2323 	}
2324 	rememberOldZoomLocation(oldZoomX, oldZoomY);
2325 
2326 	double newScale = m_canvas->scale() * (1 + static_cast<double>(m_doc->opToolPrefs().magStep) / 100.0);
2327 	if (static_cast<int>(newScale * 100.0) > static_cast<int>(100.0 * static_cast<double>(m_doc->opToolPrefs().magStep) * Prefs->displayPrefs.displayScale / 100.0))
2328 		newScale = m_canvas->scale() + static_cast<double>(m_doc->opToolPrefs().magStep) * Prefs->displayPrefs.displayScale / 100.0;
2329 
2330 	int zoomPointX(m_oldZoomX), zoomPointY(m_oldZoomY);
2331 	if (!preservePoint)
2332 	{
2333 		if (m_doc->m_Selection->count() != 0)
2334 		{
2335 			QRectF selRect = m_doc->m_Selection->getVisualGroupRect();
2336 			zoomPointX = qRound(selRect.x() + selRect.width() / 2.0);
2337 			zoomPointY = qRound(selRect.y() + selRect.height() / 2.0);
2338 		}
2339 	}
2340 	zoom(zoomPointX, zoomPointY, newScale, preservePoint);
2341 }
2342 
2343 /** Verkleinert die Ansicht */
slotZoomOut(int mx,int my,bool preservePoint)2344 void ScribusView::slotZoomOut(int mx, int my, bool preservePoint)
2345 {
2346 	// FIXME : mx and my should really be ScribusView local coordinates or global coordinates
2347 	int oldZoomX(mx), oldZoomY(my);
2348 	if ((mx == 0) && (my == 0))
2349 	{
2350 		double x = qMax(contentsX() / m_canvas->scale(), m_doc->minCanvasCoordinate.x());
2351 		double y = qMax(contentsY() / m_canvas->scale(), m_doc->minCanvasCoordinate.y());
2352 		double w = qMin(visibleWidth() / m_canvas->scale(), m_doc->maxCanvasCoordinate.x() - m_doc->minCanvasCoordinate.x());
2353 		double h = qMin(visibleHeight() / m_canvas->scale(), m_doc->maxCanvasCoordinate.y() - m_doc->minCanvasCoordinate.y());
2354 		oldZoomX = qRound(w / 2.0 + x);
2355 		oldZoomY = qRound(h / 2.0 + y);
2356 	}
2357 	rememberOldZoomLocation(oldZoomX, oldZoomY);
2358 
2359 	double newScale = m_canvas->scale() - static_cast<double>(m_doc->opToolPrefs().magStep) * Prefs->displayPrefs.displayScale / 100.0;
2360 	if (newScale <= Prefs->displayPrefs.displayScale / 100.0)
2361 		newScale = m_canvas->scale() / (1 + static_cast<double>(m_doc->opToolPrefs().magStep) / 100.0);
2362 	if (newScale <= Prefs->displayPrefs.displayScale / 100.0)
2363 		newScale = m_canvas->scale();
2364 
2365 	int zoomPointX(m_oldZoomX), zoomPointY(m_oldZoomY);
2366 	if (!preservePoint)
2367 	{
2368 		if (m_doc->m_Selection->count() != 0)
2369 		{
2370 			QRectF selRect = m_doc->m_Selection->getVisualGroupRect();
2371 			zoomPointX = qRound(selRect.x() + selRect.width() / 2.0);
2372 			zoomPointY = qRound(selRect.y() + selRect.height() / 2.0);
2373 		}
2374 	}
2375 	zoom(zoomPointX, zoomPointY, newScale, preservePoint);
2376 }
2377 
DrawNew()2378 void ScribusView::DrawNew()
2379 {
2380 	// 	qDebug("ScribusView::DrawNew");
2381 	// 	printBacktrace(24);
2382 	if (m_ScMW->scriptIsRunning())
2383 		return;
2384 	m_canvas->setForcedRedraw(true);
2385 	m_canvas->resetRenderMode();
2386 	updateContents();
2387 	setRulerPos(contentsX(), contentsY());
2388 	m_ScMW->slotSetCurrentPage(m_doc->currentPage()->pageNr());
2389 	//	disconnect(m_ScMW->zoomSpinBox, SIGNAL(valueChanged(double)), this, SLOT(setZoom()));
2390 	//	m_ScMW->zoomSpinBox->setValue(m_canvas->scale()/Prefs->displayPrefs.displayScale*100);
2391 	//	connect(m_ScMW->zoomSpinBox, SIGNAL(valueChanged(double)), this, SLOT(setZoom()));
2392 }
2393 
setCanvasCenterPos(double x,double y)2394 void ScribusView::setCanvasCenterPos(double x, double y)
2395 {
2396 	if (m_ScMW->scriptIsRunning())
2397 		return;
2398 	QPoint nx = m_canvas->canvasToLocal(FPoint(x, y));
2399 	QSize viewsize = viewport()->size();
2400 	//	qDebug() << "setCCPo" << nx << viewsize;
2401 	setContentsPos(nx.x() - viewsize.width() / 2, nx.y() - viewsize.height() / 2);
2402 }
2403 
setCanvasPos(double x,double y)2404 void ScribusView::setCanvasPos(double x, double y)
2405 {
2406 	if (m_ScMW->scriptIsRunning())
2407 		return;
2408 	QPoint nx = m_canvas->canvasToLocal(FPoint(x, y));
2409 	setContentsPos(nx.x(), nx.y());
2410 }
2411 
GotoLayer(int l)2412 void ScribusView::GotoLayer(int l)
2413 {
2414 	int level = m_doc->layerCount()-l-1;
2415 	int layerID = m_doc->layerIDFromLevel(level);
2416 	if (layerID == -1)
2417 		return;
2418 	m_doc->setActiveLayer(layerID);
2419 	//CB TODO fix this to use view calls after 1.3.2 release
2420 	m_ScMW->changeLayer(m_doc->activeLayer());
2421 	emit layerChanged(layerID);
2422 }
2423 
ChgUnit(int unitIndex)2424 void ScribusView::ChgUnit(int unitIndex)
2425 {
2426 	emit unitChanged(unitIndex);
2427 	unitChange();
2428 	vertRuler->update();
2429 	horizRuler->update();
2430 }
2431 
2432 
GotoPa(int pageNumber)2433 void ScribusView::GotoPa(int pageNumber)
2434 {
2435 	deselectItems();
2436 	GotoPage(pageNumber - 1);
2437 	setFocus();
2438 }
2439 
GotoPage(int pageIndex)2440 void ScribusView::GotoPage(int pageIndex)
2441 {
2442 	QRectF newTrimRect = m_doc->Pages->at(pageIndex)->trimRect();
2443 	QRectF oldTrimRect = m_doc->currentPage() ? m_doc->currentPage()->trimRect() : newTrimRect;
2444 	m_doc->setCurrentPage(m_doc->Pages->at(pageIndex));
2445 	if (m_ScMW->scriptIsRunning())
2446 		return;
2447 	QRect updateRect = m_canvas->canvasToLocal(oldTrimRect.united(newTrimRect));
2448 	m_ScMW->slotSetCurrentPage(pageIndex);
2449 	m_canvas->setForcedRedraw(true);
2450 	m_canvas->resetRenderMode();
2451 	setCanvasPos(m_doc->currentPage()->xOffset() - 10, m_doc->currentPage()->yOffset() - 10);
2452 	updateContents(updateRect.adjusted(-5, -5, 10, 10));
2453 	m_ScMW->HaveNewSel();
2454 }
2455 
showMasterPage(int nr)2456 void ScribusView::showMasterPage(int nr)
2457 {
2458 	// #9684 : we need Deselect() to emit HaveSel() when switching masterpage
2459 	deselectItems(true);
2460 	OldScale = m_canvas->scale();
2461 	if (!m_doc->masterPageMode())
2462 		this->requestMode(modeNormal);
2463 	m_doc->setMasterPageMode(true);
2464 	m_doc->setCurrentPage(m_doc->Pages->at(nr));
2465 	m_ScMW->pageSelector->setEnabled(false);
2466 	updateOn = false;
2467 	setZoom();
2468 	m_oldZoomX = qRound(m_doc->currentPage()->xOffset()- 10);
2469 	m_oldZoomY = qRound(m_doc->currentPage()->yOffset()- 10);
2470 	setCanvasPos(m_doc->currentPage()->xOffset() - 10, m_doc->currentPage()->yOffset() - 10);
2471 	updateOn = true;
2472 	endEditButton->setVisible(true);
2473 	DrawNew();
2474 }
2475 
hideMasterPage()2476 void ScribusView::hideMasterPage()
2477 {
2478 	deselectItems(true);
2479 	if (m_doc->masterPageMode())
2480 		this->requestMode(modeNormal);
2481 	m_doc->setMasterPageMode(false);
2482 	m_ScMW->pageSelector->setEnabled(true);
2483 	endEditButton->setVisible(false);
2484 	resizeContents(qRound((m_doc->maxCanvasCoordinate.x() - m_doc->minCanvasCoordinate.x()) * m_canvas->scale()), qRound((m_doc->maxCanvasCoordinate.y() - m_doc->minCanvasCoordinate.y()) * m_canvas->scale()));
2485 }
2486 
showSymbolPage(const QString & symbolName)2487 void ScribusView::showSymbolPage(const QString& symbolName)
2488 {
2489 	deselectItems(false);
2490 	OldScale = m_canvas->scale();
2491 	if (!m_doc->symbolEditMode())
2492 		this->requestMode(modeNormal);
2493 	m_doc->setSymbolEditMode(true, symbolName);
2494 	m_doc->setCurrentPage(m_doc->Pages->at(0));
2495 	m_ScMW->pageSelector->setEnabled(false);
2496 	m_ScMW->layerMenu->setEnabled(false);
2497 	updateOn = false;
2498 	setZoom();
2499 	m_oldZoomX = qRound(m_doc->currentPage()->xOffset()- 10);
2500 	m_oldZoomY = qRound(m_doc->currentPage()->yOffset()- 10);
2501 	setCanvasPos(m_doc->currentPage()->xOffset() - 10, m_doc->currentPage()->yOffset() - 10);
2502 	updateOn = true;
2503 	endEditButton->setVisible(true);
2504 	DrawNew();
2505 }
2506 
hideSymbolPage()2507 void ScribusView::hideSymbolPage()
2508 {
2509 	updatesOn(false);
2510 	deselectItems(true);
2511 	if (m_doc->symbolEditMode())
2512 		this->requestMode(modeNormal);
2513 	m_doc->setSymbolEditMode(false);
2514 	updatesOn(true);
2515 	endEditButton->setVisible(false);
2516 	m_doc->setCurrentPage(m_doc->Pages->at(0));
2517 	m_ScMW->pageSelector->setEnabled(true);
2518 	m_ScMW->layerMenu->setEnabled(true);
2519 	resizeContents(qRound((m_doc->maxCanvasCoordinate.x() - m_doc->minCanvasCoordinate.x()) * m_canvas->scale()), qRound((m_doc->maxCanvasCoordinate.y() - m_doc->minCanvasCoordinate.y()) * m_canvas->scale()));
2520 }
2521 
showInlinePage(int id)2522 void ScribusView::showInlinePage(int id)
2523 {
2524 	deselectItems(false);
2525 	OldScale = m_canvas->scale();
2526 	if (!m_doc->inlineEditMode())
2527 		this->requestMode(modeNormal);
2528 	m_doc->setInlineEditMode(true, id);
2529 	m_doc->setCurrentPage(m_doc->Pages->at(0));
2530 	m_ScMW->pageSelector->setEnabled(false);
2531 	m_ScMW->layerMenu->setEnabled(false);
2532 	updateOn = false;
2533 	setZoom();
2534 	m_oldZoomX = qRound(m_doc->currentPage()->xOffset() - 10);
2535 	m_oldZoomY = qRound(m_doc->currentPage()->yOffset() - 10);
2536 	setCanvasPos(m_doc->currentPage()->xOffset() - 10, m_doc->currentPage()->yOffset() - 10);
2537 	updateOn = true;
2538 	endEditButton->setVisible(true);
2539 	DrawNew();
2540 }
2541 
hideInlinePage()2542 void ScribusView::hideInlinePage()
2543 {
2544 	updatesOn(false);
2545 	deselectItems(true);
2546 	if (m_doc->inlineEditMode())
2547 		this->requestMode(modeNormal);
2548 	m_doc->setInlineEditMode(false);
2549 	updatesOn(true);
2550 	endEditButton->setVisible(false);
2551 	m_doc->setCurrentPage(m_doc->Pages->at(0));
2552 	m_ScMW->pageSelector->setEnabled(true);
2553 	m_ScMW->layerMenu->setEnabled(true);
2554 	resizeContents(qRound((m_doc->maxCanvasCoordinate.x() - m_doc->minCanvasCoordinate.x()) * m_canvas->scale()), qRound((m_doc->maxCanvasCoordinate.y() - m_doc->minCanvasCoordinate.y()) * m_canvas->scale()));
2555 }
2556 
MPageToPixmap(const QString & name,int maxGr,bool drawFrame)2557 QImage ScribusView::MPageToPixmap(const QString& name, int maxGr, bool drawFrame)
2558 {
2559 	ScLayer layer;
2560 	layer.isViewable = false;
2561 	int Nr = m_doc->MasterNames[name];
2562 	int clipx = static_cast<int>(m_doc->scratch()->left());
2563 	int clipy = static_cast<int>(m_doc->scratch()->top());
2564 	int clipw = qRound(m_doc->MasterPages.at(Nr)->width());
2565 	int cliph = qRound(m_doc->MasterPages.at(Nr)->height());
2566 	if (clipw <= 0 || cliph <= 0)
2567 		return QImage();
2568 
2569 	double sca = m_canvas->scale();
2570 	bool   frs = m_doc->guidesPrefs().framesShown;
2571 	double cx = m_doc->minCanvasCoordinate.x();
2572 	double cy = m_doc->minCanvasCoordinate.y();
2573 
2574 	m_doc->minCanvasCoordinate = FPoint(0, 0);
2575 	ScPage* act = m_doc->currentPage();
2576 	bool mMode = m_doc->masterPageMode();
2577 	m_doc->setMasterPageMode(true);
2578 	m_doc->setCurrentPage(m_doc->MasterPages.at(Nr));
2579 	bool ctrls = m_doc->guidesPrefs().showControls;
2580 	m_doc->guidesPrefs().showControls = false;
2581 	m_doc->guidesPrefs().framesShown = false;
2582 	setScale(1.0);
2583 	m_canvas->setPreviewMode(true);
2584 	m_canvas->setForcedRedraw(true);
2585 	QImage pm = QImage(clipw, cliph, QImage::Format_ARGB32_Premultiplied);
2586 	ScPainter *painter = new ScPainter(&pm, pm.width(), pm.height(), 1.0, 0);
2587 	painter->clear(m_doc->paperColor());
2588 	painter->translate(-clipx, -clipy);
2589 	painter->setLineWidth(1);
2590 	if (drawFrame)
2591 	{
2592 		painter->setPen(Qt::black, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
2593 		painter->setBrush(m_doc->paperColor());
2594 		painter->drawRect(clipx, clipy, clipw, cliph);
2595 	}
2596 	painter->beginLayer(1.0, 0);
2597 	int layerCount = m_doc->layerCount();
2598 	for (int layerLevel = 0; layerLevel < layerCount; ++layerLevel)
2599 	{
2600 		m_doc->Layers.levelToLayer(layer, layerLevel);
2601 		m_canvas->DrawPageItems(painter, layer, QRect(clipx, clipy, clipw, cliph), false);
2602 		m_canvas->DrawPageItems(painter, layer, QRect(clipx, clipy, clipw, cliph), true);
2603 	}
2604 	painter->endLayer();
2605 	painter->end();
2606 	double sx = pm.width() / static_cast<double>(maxGr);
2607 	double sy = pm.height() / static_cast<double>(maxGr);
2608 	QImage im;
2609 	if (sy < sx)
2610 		im = pm.scaled(static_cast<int>(pm.width() / sx), static_cast<int>(pm.height() / sx), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
2611 	else
2612 		im = pm.scaled(static_cast<int>(pm.width() / sy), static_cast<int>(pm.height() / sy), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
2613 	delete painter;
2614 	painter=nullptr;
2615 	m_canvas->setPreviewMode(false);
2616 	m_canvas->setForcedRedraw(false);
2617 	m_doc->guidesPrefs().framesShown = frs;
2618 	m_doc->guidesPrefs().showControls = ctrls;
2619 	setScale(sca);
2620 	m_doc->setMasterPageMode(mMode);
2621 	m_doc->setCurrentPage(act);
2622 	m_doc->minCanvasCoordinate = FPoint(cx, cy);
2623 
2624 	return im;
2625 }
2626 
PageToPixmap(int Nr,int maxGr,PageToPixmapFlags flags)2627 QImage ScribusView::PageToPixmap(int Nr, int maxGr, PageToPixmapFlags flags)
2628 {
2629 	QImage im;
2630 	double sx = maxGr / m_doc->DocPages.at(Nr)->width();
2631 	double sy = maxGr / m_doc->DocPages.at(Nr)->height();
2632 	double sc = qMin(sx, sy);
2633 	int clipx = static_cast<int>(m_doc->DocPages.at(Nr)->xOffset() * sc);
2634 	int clipy = static_cast<int>(m_doc->DocPages.at(Nr)->yOffset() * sc);
2635 	int clipw = qRound(m_doc->DocPages.at(Nr)->width() * sc);
2636 	int cliph = qRound(m_doc->DocPages.at(Nr)->height() * sc);
2637 	if ((clipw <=0) || (cliph <= 0))
2638 		return im;
2639 	im = QImage(clipw, cliph, QImage::Format_ARGB32_Premultiplied);
2640 	if (im.isNull())
2641 		return im;
2642 	im.fill( qRgba(0, 0, 0, 0) );
2643 	int oldAppMode = m_doc->appMode;
2644 	requestMode(modeNormal);
2645 	double oldScale = m_canvas->scale();
2646 	double cx = m_doc->minCanvasCoordinate.x();
2647 	double cy = m_doc->minCanvasCoordinate.y();
2648 	m_doc->minCanvasCoordinate = FPoint(0, 0);
2649 	bool oldFramesShown  = m_doc->guidesPrefs().framesShown;
2650 	bool oldShowControls = m_doc->guidesPrefs().showControls;
2651 	bool oldDrawAsPreview = m_doc->drawAsPreview;
2652 	m_doc->guidesPrefs().framesShown = false;
2653 	m_doc->guidesPrefs().showControls = false;
2654 	bool cmsCorr = false;
2655 	if ((m_doc->cmsSettings().CMSinUse) && (m_doc->cmsSettings().GamutCheck))
2656 	{
2657 		cmsCorr = true;
2658 		m_doc->cmsSettings().GamutCheck = false;
2659 		m_doc->enableCMS(true);
2660 	}
2661 	m_doc->drawAsPreview = true;
2662 	m_canvas->setScale(sc);
2663 	m_canvas->setPreviewMode(true);
2664 	m_canvas->setForcedRedraw(true);
2665 	ScPage* act = m_doc->currentPage();
2666 	bool mMode = m_doc->masterPageMode();
2667 	m_doc->setMasterPageMode(false);
2668 	m_doc->setLoading(true);
2669 	m_doc->setCurrentPage(m_doc->DocPages.at(Nr));
2670 	ScPainter *painter = new ScPainter(&im, im.width(), im.height(), 1.0, 0);
2671 	if (flags & Pixmap_DrawBackground)
2672 		painter->clear(m_doc->paperColor());
2673 	else if (flags & Pixmap_DrawWhiteBackground)
2674 		painter->clear(QColor(255, 255, 255));
2675 	painter->translate(-clipx, -clipy);
2676 	painter->setFillMode(ScPainter::Solid);
2677 	if (flags & Pixmap_DrawFrame)
2678 	{
2679 		painter->setPen(Qt::black, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
2680 		painter->setBrush(m_doc->paperColor());
2681 		painter->drawRect(clipx, clipy, clipw, cliph);
2682 	}
2683 	painter->beginLayer(1.0, 0);
2684 	painter->setZoomFactor(m_canvas->scale());
2685 
2686 	QList<QPair<PageItem*, int> > changedList;
2687 	ScPage* page = m_doc->DocPages.at(Nr);
2688 	PageItem* currItem;
2689 	if ((page->FromMaster.count() != 0) && !flags.testFlag(Pixmap_DontReloadImages))
2690 	{
2691 		QList<PageItem*> itemList = page->FromMaster;
2692 		while (itemList.count() > 0)
2693 		{
2694 			currItem = itemList.takeFirst();
2695 			if (currItem->isGroup())
2696 			{
2697 				itemList = currItem->getChildren() + itemList;
2698 				continue;
2699 			}
2700 			if (!currItem->isImageFrame() || !currItem->imageIsAvailable)
2701 				continue;
2702 			if (currItem->pixm.imgInfo.lowResType == 0)
2703 				continue;
2704 			changedList.append(qMakePair(currItem, currItem->pixm.imgInfo.lowResType));
2705 			currItem->pixm.imgInfo.lowResType = 0;
2706 			int fho = currItem->imageFlippedH();
2707 			int fvo = currItem->imageFlippedV();
2708 			double imgX = currItem->imageXOffset();
2709 			double imgY = currItem->imageYOffset();
2710 			m_doc->loadPict(currItem->Pfile, currItem, true);
2711 			currItem->setImageFlippedH(fho);
2712 			currItem->setImageFlippedV(fvo);
2713 			currItem->setImageXOffset(imgX);
2714 			currItem->setImageYOffset(imgY);
2715 		}
2716 	}
2717 	if ((m_doc->Items->count() != 0) && !flags.testFlag(Pixmap_DontReloadImages))
2718 	{
2719 		FPoint orig = m_canvas->localToCanvas(QPoint(clipx, clipy));
2720 		QRectF cullingArea = QRectF(orig.x(), orig.y(), qRound(clipw / sc + 0.5), qRound(cliph / sc + 0.5));
2721 		QList<PageItem*> itemList = *(m_doc->Items);
2722 		while (itemList.count() > 0)
2723 		{
2724 			currItem = itemList.takeFirst();
2725 			if (currItem->isGroup())
2726 			{
2727 				itemList = currItem->getChildren() + itemList;
2728 				continue;
2729 			}
2730 			double w = currItem->visualWidth();
2731 			double h = currItem->visualHeight();
2732 			double x = -currItem->visualLineWidth() / 2.0;
2733 			double y = -currItem->visualLineWidth() / 2.0;
2734 			QRectF boundingRect = currItem->getTransform().mapRect(QRectF(x, y, w, h));
2735 			if (!cullingArea.intersects(boundingRect.adjusted(0.0, 0.0, 1.0, 1.0)))
2736 				continue;
2737 			if (!currItem->isImageFrame() || !currItem->imageIsAvailable)
2738 				continue;
2739 			if (currItem->pixm.imgInfo.lowResType == 0)
2740 				continue;
2741 			changedList.append(qMakePair(currItem, currItem->pixm.imgInfo.lowResType));
2742 			currItem->pixm.imgInfo.lowResType = 0;
2743 			int fho = currItem->imageFlippedH();
2744 			int fvo = currItem->imageFlippedV();
2745 			double imgX = currItem->imageXOffset();
2746 			double imgY = currItem->imageYOffset();
2747 			m_doc->loadPict(currItem->Pfile, currItem, true);
2748 			currItem->setImageFlippedH(fho);
2749 			currItem->setImageFlippedV(fvo);
2750 			currItem->setImageXOffset(imgX);
2751 			currItem->setImageYOffset(imgY);
2752 		}
2753 	}
2754 
2755 	ScLayer layer;
2756 	layer.isViewable = false;
2757 	int layerCount = m_doc->layerCount();
2758 	for (int layerLevel = 0; layerLevel < layerCount; ++layerLevel)
2759 	{
2760 		m_doc->Layers.levelToLayer(layer, layerLevel);
2761 		m_canvas->DrawMasterItems(painter, m_doc->DocPages.at(Nr), layer, QRect(clipx, clipy, clipw, cliph));
2762 		m_canvas->DrawPageItems(painter, layer, QRect(clipx, clipy, clipw, cliph), false);
2763 		m_canvas->DrawPageItems(painter, layer, QRect(clipx, clipy, clipw, cliph), true);
2764 	}
2765 	painter->endLayer();
2766 	painter->end();
2767 	delete painter;
2768 	painter=nullptr;
2769 
2770 	if (changedList.count() != 0)
2771 	{
2772 		QPair<PageItem*, int> itemPair;
2773 		for (int it = 0; it < changedList.count(); it++)
2774 		{
2775 			itemPair = changedList.at(it);
2776 			currItem = itemPair.first;
2777 			currItem->pixm.imgInfo.lowResType = itemPair.second;
2778 			int fho = currItem->imageFlippedH();
2779 			int fvo = currItem->imageFlippedV();
2780 			double imgX = currItem->imageXOffset();
2781 			double imgY = currItem->imageYOffset();
2782 			m_doc->loadPict(currItem->Pfile, currItem, true);
2783 			currItem->setImageFlippedH(fho);
2784 			currItem->setImageFlippedV(fvo);
2785 			currItem->setImageXOffset(imgX);
2786 			currItem->setImageYOffset(imgY);
2787 		}
2788 	}
2789 	if (cmsCorr)
2790 	{
2791 		m_doc->cmsSettings().GamutCheck = true;
2792 		m_doc->enableCMS(true);
2793 	}
2794 	m_doc->drawAsPreview = oldDrawAsPreview;
2795 	m_doc->guidesPrefs().framesShown  = oldFramesShown;
2796 	m_doc->guidesPrefs().showControls = oldShowControls;
2797 	m_canvas->setScale(oldScale);
2798 	m_doc->setMasterPageMode(mMode);
2799 	m_doc->setCurrentPage(act);
2800 	m_doc->setLoading(false);
2801 	m_canvas->setPreviewMode(m_doc->drawAsPreview);
2802 	m_canvas->setForcedRedraw(false);
2803 	m_doc->minCanvasCoordinate = FPoint(cx, cy);
2804 	requestMode(oldAppMode);
2805 	return im;
2806 }
2807 
setNewRulerOrigin(QMouseEvent * m)2808 void ScribusView::setNewRulerOrigin(QMouseEvent *m)
2809 {
2810 	QPoint py = viewport()->mapFromGlobal(m->globalPos());
2811 	m_doc->rulerXoffset = (py.x() + contentsX()) / m_canvas->scale() + 0*m_doc->minCanvasCoordinate.x();
2812 	m_doc->rulerYoffset = (py.y() + contentsY()) / m_canvas->scale() + 0*m_doc->minCanvasCoordinate.y();
2813 	if (m_doc->guidesPrefs().rulerMode)
2814 	{
2815 		m_doc->rulerXoffset -= m_doc->currentPage()->xOffset();
2816 		m_doc->rulerYoffset -= m_doc->currentPage()->yOffset();
2817 	}
2818 	setRulerPos(contentsX(), contentsY());
2819 	m_canvas->newRedrawPolygon();
2820 	int docSelectionCount=m_doc->m_Selection->count();
2821 	if (docSelectionCount != 0)
2822 	{
2823 		if (docSelectionCount > 1)
2824 		{
2825 			double x, y, w, h;
2826 			m_doc->m_Selection->getGroupRect(&x, &y, &w, &h);
2827 			emit ItemGeom();
2828 		}
2829 		else
2830 			m_doc->m_Selection->itemAt(0)->emitAllToGUI();
2831 	}
2832 }
2833 
editExtendedImageProperties()2834 void ScribusView::editExtendedImageProperties()
2835 {
2836 	if (m_doc->m_Selection->isEmpty())
2837 		return;
2838 	PageItem *currItem = m_doc->m_Selection->itemAt(0);
2839 	if (!currItem->pixm.imgInfo.valid)
2840 		return;
2841 	QScopedPointer<ExtImageProps> dia(new ExtImageProps(this, &currItem->pixm.imgInfo, currItem, this));
2842 	static_cast<void>(dia->exec());
2843 	m_ScMW->propertiesPalette->setTextFlowMode(currItem->textFlowMode());
2844 }
2845 
ToPicFrame()2846 void ScribusView::ToPicFrame()
2847 {
2848 	Selection tempSelection(*m_doc->m_Selection);
2849 	m_doc->m_Selection->delaySignalsOn();
2850 	updatesOn(false);
2851 	deselectItems(true);
2852 	Selection restoreSelection(this);
2853 	m_doc->itemSelection_convertItemsTo(PageItem::ImageFrame, &restoreSelection, &tempSelection);
2854 	m_doc->m_Selection->copy(restoreSelection, true);
2855 	updatesOn(true);
2856 	m_doc->m_Selection->delaySignalsOff();
2857 }
2858 
ToPolyFrame()2859 void ScribusView::ToPolyFrame()
2860 {
2861 	Selection tempSelection(*m_doc->m_Selection);
2862 	m_doc->m_Selection->delaySignalsOn();
2863 	updatesOn(false);
2864 	deselectItems(true);
2865 	Selection restoreSelection(this);
2866 	m_doc->itemSelection_convertItemsTo(PageItem::Polygon, &restoreSelection, &tempSelection);
2867 	m_doc->m_Selection->copy(restoreSelection, true);
2868 	updatesOn(true);
2869 	m_doc->m_Selection->delaySignalsOff();
2870 }
2871 
ToTextFrame()2872 void ScribusView::ToTextFrame()
2873 {
2874 	Selection tempSelection(*m_doc->m_Selection);
2875 	m_doc->m_Selection->delaySignalsOn();
2876 	updatesOn(false);
2877 	deselectItems(true);
2878 	Selection restoreSelection(this);
2879 	m_doc->itemSelection_convertItemsTo(PageItem::TextFrame, &restoreSelection, &tempSelection);
2880 	m_doc->m_Selection->copy(restoreSelection, true);
2881 	updatesOn(true);
2882 	m_doc->m_Selection->delaySignalsOff();
2883 }
2884 
ToBezierFrame()2885 void ScribusView::ToBezierFrame()
2886 {
2887 	Selection tempSelection(*m_doc->m_Selection);
2888 	m_doc->m_Selection->delaySignalsOn();
2889 	updatesOn(false);
2890 	deselectItems(true);
2891 	Selection restoreSelection(this);
2892 	m_doc->itemSelection_convertItemsTo(PageItem::PolyLine, &restoreSelection, &tempSelection);
2893 	m_doc->m_Selection->copy(restoreSelection, true);
2894 	updatesOn(true);
2895 	m_doc->m_Selection->delaySignalsOff();
2896 }
2897 
Bezier2Poly()2898 void ScribusView::Bezier2Poly()
2899 {
2900 	Selection tempSelection(*m_doc->m_Selection);
2901 	m_doc->m_Selection->delaySignalsOn();
2902 	updatesOn(false);
2903 	deselectItems(true);
2904 	Selection restoreSelection(this);
2905 	m_doc->itemSelection_convertItemsTo(PageItem::Polygon, &restoreSelection, &tempSelection);
2906 	m_doc->m_Selection->copy(restoreSelection, true);
2907 	updatesOn(true);
2908 	m_doc->m_Selection->delaySignalsOff();
2909 }
2910 
ToPathText()2911 void ScribusView::ToPathText()
2912 {
2913 	if (m_doc->m_Selection->count() <= 1)
2914 		return;
2915 
2916 	PageItem* currItem = m_doc->m_Selection->itemAt(0);
2917 	PageItem *polyLineItem;
2918 	if (currItem->isTextFrame())
2919 		polyLineItem = m_doc->m_Selection->itemAt(1);
2920 	else
2921 	{
2922 		polyLineItem = m_doc->m_Selection->itemAt(0);
2923 		currItem = m_doc->m_Selection->itemAt(1);
2924 	}
2925 	ParagraphStyle dstyle(currItem->itemText.defaultStyle());
2926 	if (polyLineItem->asPolyLine() || polyLineItem->asPolygon() || polyLineItem->asSpiral() || polyLineItem->asArc() || polyLineItem->asRegularPolygon())
2927 	{
2928 		deselectItems(true);
2929 		PageItem* newItem = m_doc->convertItemTo(currItem, PageItem::PathText, polyLineItem);
2930 		newItem->itemText.setDefaultStyle(dstyle);
2931 		newItem->itemText.applyCharStyle(0, newItem->itemText.length(), dstyle.charStyle());
2932 		newItem->invalid = true;
2933 		newItem->update();
2934 		selectItem(newItem);
2935 		emit DocChanged();
2936 	}
2937 }
2938 
FromPathText()2939 void ScribusView::FromPathText()
2940 {
2941 	PageItem *currItem;
2942 	if (!m_doc->getItem(&currItem))
2943 		return;
2944 
2945 	deselectItems(true);
2946 	PageItem* newItem = m_doc->convertItemTo(currItem, PageItem::TextFrame);
2947 	selectItem(newItem);
2948 	m_doc->bringItemSelectionToFront();
2949 	update();
2950 }
2951 
2952 // FIXME: the following code is untested, but it should give an idea for
2953 // anyone who wants to fix and knows how to test it.
2954 class TextToPathPainter: public TextLayoutPainter
2955 {
2956 		ScribusView* m_view;
2957 		PageItem* m_item;
2958 		QList<PageItem*> &m_group;
2959 		int m_counter;
2960 
2961 	public:
TextToPathPainter(ScribusView * view,PageItem * item,QList<PageItem * > & group)2962 		TextToPathPainter(ScribusView* view, PageItem* item, QList<PageItem*> &group)
2963 			: m_view(view)
2964 			, m_item(item)
2965 			, m_group(group)
2966 			, m_counter(0)
2967 		{}
2968 
drawGlyph(const GlyphCluster & gc)2969 		void drawGlyph(const GlyphCluster& gc) override
2970 		{
2971 			double current_x = 0.0;
2972 			for (const GlyphLayout& gl : gc.glyphs())
2973 			{
2974 				if (gl.glyph >= ScFace::CONTROL_GLYPHS)
2975 				{
2976 					current_x += gl.xadvance * gl.scaleH;
2977 					continue;
2978 				}
2979 
2980 				FPointArray outline = font().glyphOutline(gl.glyph);
2981 				if (outline.size() < 4)
2982 					return;
2983 				QTransform transform;
2984 				if (m_item->isPathText())
2985 					transform = matrix();
2986 				if (m_item->imageFlippedH())
2987 				{
2988 					transform.translate(m_item->width(), 0);
2989 					transform.scale(-1, 1);
2990 				}
2991 				if (m_item->imageFlippedV())
2992 				{
2993 					transform.translate(0, m_item->height());
2994 					transform.scale(1, -1);
2995 				}
2996 				transform.translate(x() + gl.xoffset + current_x , y() + gl.yoffset);
2997 				transform.translate(0, -(fontSize() * gl.scaleV));
2998 				transform.scale(gl.scaleH * fontSize() / 10.0, gl.scaleV * fontSize() / 10.0);
2999 				outline.map(transform);
3000 				int z = m_view->m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, m_item->xPos(), m_item->yPos(), m_item->width(), m_item->height(), 0, fillColor().color, CommonStrings::None);
3001 				PageItem* item = m_view->m_doc->Items->at(z);
3002 				m_view->undoManager->setUndoEnabled(false);
3003 				item->setTextFlowMode(m_item->textFlowMode());
3004 				item->setSizeLocked(m_item->sizeLocked());
3005 				item->setLocked(m_item->locked());
3006 				item->NamedLStyle = m_item->NamedLStyle;
3007 				item->setItemName(m_item->itemName() + "+U" + QString::number(m_counter++));
3008 				item->PoLine = outline.copy();
3009 				if (!m_item->asPathText())
3010 					item->setRotation(m_item->rotation());
3011 				item->setFillColor(fillColor().color);
3012 				item->setFillShade(fillColor().shade);
3013 				m_view->m_doc->adjustItemSize(item);
3014 				item->ContourLine = item->PoLine.copy();
3015 				item->ClipEdited = true;
3016 				item->FrameType = 3;
3017 				item->OldB2 = item->width();
3018 				item->OldH2 = item->height();
3019 				m_view->m_doc->setRedrawBounding(item);
3020 				m_view->undoManager->setUndoEnabled(true);
3021 				m_group.append(m_view->m_doc->Items->takeAt(z));
3022 
3023 				current_x += gl.xadvance * gl.scaleH;
3024 			}
3025 		}
3026 
drawGlyphOutline(const GlyphCluster & gc,bool fill)3027 		void drawGlyphOutline(const GlyphCluster& gc, bool fill) override
3028 		{
3029 			double current_x = 0.0;
3030 			for (const GlyphLayout& gl : gc.glyphs())
3031 			{
3032 				if (gl.glyph >= ScFace::CONTROL_GLYPHS)
3033 				{
3034 					current_x += gl.xadvance * gl.scaleH;
3035 					continue;
3036 				}
3037 
3038 				FPointArray outline = font().glyphOutline(gl.glyph);
3039 				if (outline.size() < 4)
3040 					return;
3041 				QTransform transform;
3042 				if (m_item->isPathText())
3043 					transform = matrix();
3044 				if (m_item->imageFlippedH())
3045 				{
3046 					transform.translate(m_item->width(), 0);
3047 					transform.scale(-1, 1);
3048 				}
3049 				if (m_item->imageFlippedV())
3050 				{
3051 					transform.translate(0, m_item->height());
3052 					transform.scale(1, -1);
3053 				}
3054 				transform.translate(x() + gl.xoffset + current_x , y() + gl.yoffset);
3055 				transform.translate(0, -(fontSize() * gl.scaleV));
3056 				transform.scale(gl.scaleH * fontSize() / 10.0, gl.scaleV * fontSize() / 10.0);
3057 				outline.map(transform);
3058 				int z = m_view->m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, m_item->xPos(), m_item->yPos(), m_item->width(), m_item->height(), strokeWidth(), fillColor().color, strokeColor().color);
3059 				PageItem* item = m_view->m_doc->Items->at(z);
3060 				m_view->undoManager->setUndoEnabled(false);
3061 				item->setTextFlowMode(m_item->textFlowMode());
3062 				item->setSizeLocked(m_item->sizeLocked());
3063 				item->setLocked(m_item->locked());
3064 				item->NamedLStyle = m_item->NamedLStyle;
3065 				item->setItemName(m_item->itemName() + "+U" + QString::number(m_counter++));
3066 				item->PoLine = outline.copy();
3067 				if (!m_item->asPathText())
3068 					item->setRotation(m_item->rotation());
3069 				item->setFillColor(fillColor().color);
3070 				item->setFillShade(fillColor().shade);
3071 				item->setLineColor(strokeColor().color);
3072 				item->setLineShade(strokeColor().shade);
3073 				item->setLineWidth(strokeWidth());
3074 				m_view->m_doc->adjustItemSize(item);
3075 				item->ContourLine = item->PoLine.copy();
3076 				item->ClipEdited = true;
3077 				item->FrameType = 3;
3078 				item->OldB2 = item->width();
3079 				item->OldH2 = item->height();
3080 				m_view->m_doc->setRedrawBounding(item);
3081 				m_view->undoManager->setUndoEnabled(true);
3082 				m_group.append(m_view->m_doc->Items->takeAt(z));
3083 
3084 				current_x += gl.xadvance * gl.scaleH;
3085 			}
3086 		}
3087 
drawLine(QPointF start,QPointF end)3088 		void drawLine(QPointF start, QPointF end) override
3089 		{
3090 			QTransform transform = matrix();
3091 			transform.translate(x(), y());
3092 			int z = m_view->m_doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, m_item->xPos(), m_item->yPos(), m_item->width(), m_item->height(), m_item->lineWidth(), m_item->lineColor(), m_item->fillColor());
3093 			PageItem* item = m_view->m_doc->Items->at(z);
3094 			m_view->undoManager->setUndoEnabled(false);
3095 			item->setTextFlowMode(m_item->textFlowMode());
3096 			item->setSizeLocked(m_item->sizeLocked());
3097 			item->setLocked(m_item->locked());
3098 			item->NamedLStyle = m_item->NamedLStyle;
3099 			item->setItemName(m_item->itemName() + "+U" + QString::number(m_counter++));
3100 			item->PoLine.resize(0);
3101 			item->PoLine.addQuadPoint(FPoint(start), FPoint(start), FPoint(end), FPoint(end));
3102 			item->PoLine.map(transform);
3103 			item->setLineColor(fillColor().color);
3104 			item->setLineShade(fillColor().shade);
3105 			item->setLineWidth(strokeWidth());
3106 			m_view->m_doc->adjustItemSize(item);
3107 			item->ContourLine = item->PoLine.copy();
3108 			item->ClipEdited = true;
3109 			item->FrameType = 3;
3110 			item->OldB2 = item->width();
3111 			item->OldH2 = item->height();
3112 			m_view->m_doc->setRedrawBounding(item);
3113 			m_view->undoManager->setUndoEnabled(true);
3114 			m_group.append(m_view->m_doc->Items->takeAt(z));
3115 		}
3116 
drawRect(QRectF rect)3117 		void drawRect(QRectF rect) override {}
drawObject(PageItem * item)3118 		void drawObject(PageItem* item) override {}
3119 };
3120 
TextToPath()3121 void ScribusView::TextToPath()
3122 {
3123 	if (m_doc->appMode == modeEditClip)
3124 		requestMode(submodeEndNodeEdit);
3125 	Selection tmpSelection(this, false);
3126 	tmpSelection.copy(*m_doc->m_Selection, false);
3127 	PageItem *currItem = tmpSelection.itemAt(0);
3128 	if ((currItem->prevInChain() != nullptr) || (currItem->nextInChain() != nullptr))
3129 	{
3130 		// select whole chain
3131 		PageItem *backItem = currItem;
3132 		while (backItem->prevInChain() != nullptr)
3133 			backItem = backItem->prevInChain();
3134 		currItem = backItem;
3135 		deselectItems(true);
3136 		tmpSelection.addItem(currItem);
3137 		backItem = currItem->nextInChain();
3138 		while (backItem != nullptr)
3139 		{
3140 			tmpSelection.addItem(backItem);
3141 			if (backItem->nextInChain() != nullptr)
3142 				backItem = backItem->nextInChain();
3143 			else
3144 				break;
3145 		}
3146 	}
3147 
3148 	QList<PageItem*> delItems, newGroupedItems;
3149 	int selectedItemCount = tmpSelection.count();
3150 	if (selectedItemCount <= 0)
3151 		return;
3152 
3153 	UndoTransaction trans(undoManager->beginTransaction(currItem->getUName(), currItem->getUPixmap(), Um::ToOutlines, "", nullptr));
3154 	int offset = 0;
3155 
3156 	int oldRotMode = m_doc->rotationMode();
3157 	m_doc->setRotationMode(0);
3158 
3159 	for (int i = 0; i < selectedItemCount; ++i)
3160 	{
3161 		PageItem *currItem = tmpSelection.itemAt(offset);
3162 		bool cont = false;
3163 		if ((!((currItem->isTextFrame()) || (currItem->isPathText()))) || (currItem->locked()) || currItem->itemText.length() == 0)
3164 			cont = true;
3165 		if (currItem == m_ScMW->storyEditor->currentItem() && m_doc == m_ScMW->storyEditor->currentDocument())
3166 		{
3167 			ScMessageBox::information(m_ScMW, tr("Cannot Convert In-Use Item"), "<qt>" + tr("The item %1 is currently being edited by Story Editor. The convert to outlines operation for this item will be skipped").arg(currItem->itemName()) + "</qt>");
3168 			cont = true;
3169 		}
3170 		//Deselect();
3171 		if (cont)
3172 		{
3173 			++offset;
3174 			continue;
3175 		}
3176 
3177 		// We usually don't need any of the undo actions created by TextToPathPainter. If we did take them into account,
3178 		// the created items woud reappear when redoing an undone TextToPath action
3179 		int textLen = currItem->itemText.length();
3180 		if (textLen > 1)
3181 			undoManager->setUndoEnabled(false);
3182 		TextToPathPainter p(this, currItem, newGroupedItems);
3183 		currItem->textLayout.render(&p);
3184 		if (textLen > 1)
3185 			undoManager->setUndoEnabled(true);
3186 
3187 		if ((currItem->isPathText()) && (currItem->PoShow))
3188 		{
3189 			int z = m_doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, currItem->xPos(), currItem->yPos(), currItem->width(), currItem->height(), currItem->lineWidth(), CommonStrings::None, currItem->lineColor());
3190 			PageItem *bb = m_doc->Items->at(z);
3191 			undoManager->setUndoEnabled(false);
3192 			bb->PoLine = currItem->PoLine.copy();
3193 			bb->ClipEdited = true;
3194 			bb->FrameType = 3;
3195 			bb->OldB2 = bb->width();
3196 			bb->OldH2 = bb->height();
3197 			bb->setRotation(currItem->rotation());
3198 			m_doc->adjustItemSize(bb);
3199 			undoManager->setUndoEnabled(true);
3200 			newGroupedItems.append(m_doc->Items->takeAt(z));
3201 		}
3202 		if (currItem->isTextFrame())
3203 		{
3204 			if ((!currItem->NamedLStyle.isEmpty()) || (currItem->lineColor() != CommonStrings::None) || (!currItem->strokePattern().isEmpty()) || (!currItem->strokeGradient().isEmpty()))
3205 			{
3206 				PageItem* newItem = new PageItem_Polygon(*currItem);
3207 				newItem->convertTo(PageItem::Polygon);
3208 				newItem->ClipEdited = true;
3209 				newItem->FrameType = 3;
3210 				newItem->OldB2 = newItem->width();
3211 				newItem->OldH2 = newItem->height();
3212 				newItem->Clip = flattenPath(newItem->PoLine, newItem->Segments);
3213 				newItem->ContourLine = newItem->PoLine.copy();
3214 				newGroupedItems.prepend(newItem);
3215 			}
3216 		}
3217 		delItems.append(tmpSelection.takeItem(offset));
3218 	}
3219 
3220 	tmpSelection.clear();
3221 	int ind = -1;
3222 	if (currItem->isGroupChild())
3223 		ind = currItem->parentGroup()->groupItemList.indexOf(currItem);
3224 	else
3225 		ind = m_doc->Items->indexOf(currItem);
3226 	if (newGroupedItems.count() > 1)
3227 	{
3228 		double minx =  std::numeric_limits<double>::max();
3229 		double miny =  std::numeric_limits<double>::max();
3230 		double maxx = -std::numeric_limits<double>::max();
3231 		double maxy = -std::numeric_limits<double>::max();
3232 		for (int ep = 0; ep < newGroupedItems.count(); ++ep)
3233 		{
3234 			double x1, x2, y1, y2;
3235 			newGroupedItems.at(ep)->getVisualBoundingRect(&x1, &y1, &x2, &y2);
3236 			minx = qMin(minx, x1);
3237 			miny = qMin(miny, y1);
3238 			maxx = qMax(maxx, x2);
3239 			maxy = qMax(maxy, y2);
3240 		}
3241 		double gx = minx;
3242 		double gy = miny;
3243 		double gw = maxx - minx;
3244 		double gh = maxy - miny;
3245 		int z = m_doc->itemAdd(PageItem::Group, PageItem::Rectangle, gx, gy, gw, gh, 0, CommonStrings::None, CommonStrings::None);
3246 		PageItem *gItem = m_doc->Items->takeAt(z);
3247 		m_doc->groupObjectsToItem(gItem, newGroupedItems);
3248 		gItem->Parent = currItem->Parent;
3249 		gItem->gXpos = currItem->gXpos;
3250 		gItem->gYpos = currItem->gYpos;
3251 		if (currItem->isGroupChild())
3252 			currItem->parentGroup()->groupItemList.insert(ind+1, gItem);
3253 		else
3254 			m_doc->Items->insert(ind+1, gItem);
3255 	}
3256 	else if (newGroupedItems.count() > 0)
3257 	{
3258 		newGroupedItems.at(0)->Parent = currItem->Parent;
3259 		if (currItem->isGroupChild())
3260 			currItem->parentGroup()->groupItemList.insert(ind+1, newGroupedItems.at(0));
3261 		else
3262 			m_doc->Items->insert(ind+1, newGroupedItems.at(0));
3263 	}
3264 
3265 	int toDeleteItemCount = delItems.count();
3266 	if (toDeleteItemCount != 0)
3267 	{
3268 		tmpSelection.clear();
3269 		for (int i = 0; i < toDeleteItemCount; ++i)
3270 			tmpSelection.addItem(delItems.takeAt(0)); //yes, 0, remove the first
3271 		m_doc->itemSelection_DeleteItem(&tmpSelection);
3272 	}
3273 
3274 	m_doc->setRotationMode(oldRotMode);
3275 	m_ScMW->HaveNewSel();
3276 	deselectItems(true);
3277 	trans.commit();
3278 }
3279 
keyPressEvent(QKeyEvent * k)3280 void ScribusView::keyPressEvent(QKeyEvent *k)
3281 {
3282 	if (m_canvasMode)
3283 		m_canvasMode->keyPressEvent(k);
3284 }
3285 
keyReleaseEvent(QKeyEvent * k)3286 void ScribusView::keyReleaseEvent(QKeyEvent *k)
3287 {
3288 	if (m_canvasMode)
3289 		m_canvasMode->keyReleaseEvent(k);
3290 }
3291 
inputMethodEvent(QInputMethodEvent * event)3292 void ScribusView::inputMethodEvent(QInputMethodEvent * event)
3293 {
3294 	//qDebug() << "IME" << event->commitString() << event->preeditString() << "attributes:" << event->attributes().count();
3295 	// #9682 : Avoid parameter type ambiguity in QKeyEvent constructor with Qt3Support enabled Qt builds
3296 	Qt::KeyboardModifiers modifiers = Qt::NoModifier;
3297 
3298 	const QString& commitString = event->commitString();
3299 	for (int i = 0; i < commitString.length(); ++i)
3300 	{
3301 		QKeyEvent ev(QEvent::KeyPress, 0, modifiers, commitString.mid(i, 1));
3302 		keyPressEvent(&ev);
3303 	}
3304 }
3305 
inputMethodQuery(Qt::InputMethodQuery query) const3306 QVariant ScribusView::inputMethodQuery(Qt::InputMethodQuery query) const
3307 {
3308 	//	qDebug() << "IMQ" << query;
3309 	return QVariant();
3310 }
3311 
wheelEvent(QWheelEvent * w)3312 void ScribusView::wheelEvent(QWheelEvent *w)
3313 {
3314 	if (w->modifiers() == Qt::ControlModifier)
3315 	{
3316 		FPoint mp = m_canvas->globalToCanvas(w->globalPos());
3317 		w->delta() > 0 ? slotZoomIn(mp.x(), mp.y() , true) : slotZoomOut(mp.x(), mp.y(), true);
3318 	}
3319 	else
3320 	{
3321 		int dX = 0, dY = 0;
3322 		int moveBy = (w->delta() < 0) ? Prefs->uiPrefs.wheelJump : -Prefs->uiPrefs.wheelJump;
3323 		if ((w->orientation() != Qt::Vertical) || ( w->modifiers() == Qt::ShiftModifier ))
3324 			dX = moveBy;
3325 		else
3326 			dY = moveBy;
3327 		scrollBy(dX, dY);
3328 	}
3329 	w->accept();
3330 }
3331 
setObjectUndoMode()3332 void ScribusView::setObjectUndoMode()
3333 {
3334 	_isGlobalMode = undoManager->isGlobalMode();
3335 	if (!m_ScMW->HaveDoc)
3336 		return;
3337 
3338 	//qDebug(QString("%1 %2").arg((int)m_ScMW).arg(m_ScMW->scrActions.contains("editActionMode")));
3339 	m_ScMW->scrActions["editActionMode"]->setChecked(true);
3340 	int docSelectionCount=m_doc->m_Selection->count();
3341 	if (docSelectionCount == 1)
3342 		undoManager->showObject(m_doc->m_Selection->itemAt(0)->getUId());
3343 	else if (docSelectionCount > 1)
3344 		undoManager->showObject(Um::NO_UNDO_STACK);
3345 	else if (docSelectionCount == 0)
3346 		undoManager->showObject(m_doc->currentPage()->getUId());
3347 }
3348 
setGlobalUndoMode()3349 void ScribusView::setGlobalUndoMode()
3350 {
3351 	if (!m_ScMW->HaveDoc)
3352 		return;
3353 
3354 	m_ScMW->scrActions["editActionMode"]->setChecked(!_isGlobalMode);
3355 	if (_isGlobalMode)
3356 		undoManager->showObject(Um::GLOBAL_UNDO_MODE);
3357 	else
3358 	{
3359 		int docSelectionCount=m_doc->m_Selection->count();
3360 		if (docSelectionCount == 1)
3361 			undoManager->showObject(m_doc->m_Selection->itemAt(0)->getUId());
3362 		else if (docSelectionCount > 1)
3363 			undoManager->showObject(Um::NO_UNDO_STACK);
3364 		else if (docSelectionCount == 0)
3365 			undoManager->showObject(m_doc->currentPage()->getUId());
3366 	}
3367 }
3368 
unitChange()3369 void ScribusView::unitChange()
3370 {
3371 	vertRuler->unitChange();
3372 	horizRuler->unitChange();
3373 }
3374 
setRulersShown(bool isShown)3375 void ScribusView::setRulersShown(bool isShown)
3376 {
3377 	vertRuler->setVisible(isShown);
3378 	horizRuler->setVisible(isShown);
3379 	rulerMover->setVisible(isShown);
3380 	int newTopLeftMargin = isShown ? m_vhRulerHW : 0;
3381 	setViewportMargins(newTopLeftMargin, newTopLeftMargin, 0, 0);
3382 }
3383 
setScale(const double newScale)3384 void ScribusView::setScale(const double newScale)
3385 {
3386 	double Scale=newScale;
3387 	double v=m_doc->opToolPrefs().magMin*Prefs->displayPrefs.displayScale/100.0;
3388 	if (Scale < v)
3389 		Scale=v;
3390 	double v2=m_doc->opToolPrefs().magMax*Prefs->displayPrefs.displayScale/100.0;
3391 	if (Scale > v2)
3392 		Scale=v2;
3393 	double v3=320*Prefs->displayPrefs.displayScale;
3394 	if (Scale > v3)
3395 		Scale=v3;
3396 
3397 	m_canvas->setScale(Scale);
3398 
3399 	m_ScMW->zoomSpinBox->blockSignals(true);
3400 	m_ScMW->zoomSpinBox->setValue(m_canvas->scale()/Prefs->displayPrefs.displayScale*100);
3401 	m_ScMW->zoomSpinBox->blockSignals(false);
3402 
3403 	unitChange();
3404 }
3405 
3406 
3407 
scale() const3408 double ScribusView::scale() const
3409 {
3410 	return m_canvas->scale();
3411 }
3412 
eventFilter(QObject * obj,QEvent * event)3413 bool ScribusView::eventFilter(QObject *obj, QEvent *event)
3414 {
3415 	//	if (obj == horizRuler || obj == vertRuler || obj == rulerMover)
3416 	//		return true; // FIXME:av
3417 
3418 	if (obj == widget() && event->type() == QEvent::MouseMove)
3419 	{
3420 		auto* m = dynamic_cast<QMouseEvent*> (event);
3421 		m_mousePointDoc=m_canvas->globalToCanvas(m->globalPos());
3422 		FPoint p = m_canvas->localToCanvas(QPoint(m->x(),m->y()));
3423 		emit MousePos(p.x(),p.y());
3424 		horizRuler->draw(m->x() + qRound(m_doc->minCanvasCoordinate.x() * m_canvas->scale())); //  - 2 * contentsX());
3425 		vertRuler->draw(m->y() + qRound(m_doc->minCanvasCoordinate.y() * m_canvas->scale()));
3426 		m_canvasMode->mouseMoveEvent(m);
3427 		return true;
3428 	}
3429 	if (obj == widget() && event->type() == QEvent::MouseButtonRelease)
3430 	{
3431 		auto* m = dynamic_cast<QMouseEvent*> (event);
3432 		m_canvasMode->mouseReleaseEvent(m);
3433 		m_canvas->m_viewMode.m_MouseButtonPressed = false;
3434 		if (linkAfterDraw)
3435 		{
3436 			//user creates new frame using linking tool
3437 			PageItem * secondFrame = m_doc->m_Selection->itemAt(0);
3438 			if (secondFrame && firstFrame)
3439 			{
3440 				firstFrame->link(secondFrame);
3441 				firstFrame = nullptr;
3442 				secondFrame->emitAllToGUI();
3443 			}
3444 			linkAfterDraw = false;
3445 		}
3446 		if (ImageAfterDraw)
3447 		{
3448 			//user creates new frame using linking tool
3449 			PageItem * frame = m_doc->m_Selection->itemAt(0);
3450 			requestMode(modeImportImage);
3451 			if (frame)
3452 			{
3453 				auto* cm = qobject_cast<CanvasMode_ImageImport*>(canvasMode());
3454 				if (!cm)
3455 					qFatal("ScribusView::eventFilter cm nullptr");
3456 				cm->setImage(frame);
3457 				cm->updateList();
3458 			}
3459 			ImageAfterDraw = false;
3460 		}
3461 		return true;
3462 	}
3463 	if (obj == widget() && event->type() == QEvent::MouseButtonPress)
3464 	{
3465 		auto* m = dynamic_cast<QMouseEvent*> (event);
3466 		bool linkmode = (m_doc->appMode == modeLinkFrames);
3467 		firstFrame = m_doc->m_Selection->itemAt(0);
3468 		m_canvasMode->mousePressEvent(m);
3469 		//if user don't click any frame he want to draw new frame and link it
3470 		bool requestDrawMode = (m_doc->ElemToLink == nullptr);
3471 		requestDrawMode &= (firstFrame && !firstFrame->nextInChain());
3472 		if (linkmode && requestDrawMode)
3473 		{
3474 			//switch to drawing new text frame
3475 			linkAfterDraw = true;
3476 			requestMode(modeDrawText);
3477 			m_canvasMode->mousePressEvent(m);
3478 		}
3479 		else
3480 			firstFrame = nullptr;
3481 		if(m_doc->appMode == modeImportImage && ImageAfterDraw)
3482 		{
3483 			//switch to drawing new text frame
3484 			requestMode(modeDrawImage);
3485 			m_canvasMode->mousePressEvent(m);
3486 		}
3487 		m_canvas->m_viewMode.m_MouseButtonPressed = true;
3488 		return true;
3489 	}
3490 	if (obj == widget() && event->type() == QEvent::MouseButtonDblClick)
3491 	{
3492 		auto* m = dynamic_cast<QMouseEvent*> (event);
3493 		m_canvasMode->mouseDoubleClickEvent(m);
3494 		return true;
3495 	}
3496 	if (event->type() == QEvent::KeyPress)
3497 	{
3498 		auto* k = dynamic_cast<QKeyEvent*> (event);
3499 		m_canvasMode->keyPressEvent(k);
3500 		return true;
3501 	}
3502 	if (event->type() == QEvent::KeyRelease)
3503 	{
3504 		auto* m = dynamic_cast<QKeyEvent*> (event);
3505 		m_canvasMode->keyReleaseEvent(m);
3506 		return true;
3507 	}
3508 	if (obj == widget() && event->type() == QEvent::DragEnter)
3509 	{
3510 		auto* d = dynamic_cast<QDragEnterEvent*> (event);
3511 		contentsDragEnterEvent(d);
3512 		return true;
3513 	}
3514 	if (obj == widget() && event->type() == QEvent::DragLeave)
3515 	{
3516 		auto* d = dynamic_cast<QDragLeaveEvent*> (event);
3517 		contentsDragLeaveEvent(d);
3518 		return true;
3519 	}
3520 	if (obj == widget() && event->type() == QEvent::DragMove)
3521 	{
3522 		auto* d = dynamic_cast<QDragMoveEvent*> (event);
3523 		contentsDragMoveEvent(d);
3524 		return true;
3525 	}
3526 	if (obj == widget() && event->type() == QEvent::Drop)
3527 	{
3528 		auto* d = dynamic_cast<QDropEvent*> (event);
3529 		contentsDropEvent(d);
3530 		return true;
3531 	}
3532 	if (event->type() == QEvent::NativeGesture)
3533 	{
3534 		auto *ng = static_cast<QNativeGestureEvent*>(event);
3535 		nativeGestureEvent(ng);
3536 		return true;
3537 	}
3538 
3539 	// rulermover events
3540 	// hruler events
3541 	// vruler events
3542 
3543 	return QScrollArea::eventFilter(obj, event);
3544 }
3545 
3546 //Legacy
3547 
updateContents(QRect box)3548 void ScribusView::updateContents(QRect box)
3549 {
3550 	if (box.isValid())
3551 		m_canvas->update(box);
3552 	else
3553 		m_canvas->update();
3554 }
3555 
updateContents(int x,int y,int w,int h)3556 void ScribusView::updateContents(int x, int y, int w, int h)
3557 {
3558 	updateContents(QRect(x, y, w, h));
3559 }
3560 
repaintContents(QRect box)3561 void ScribusView::repaintContents(QRect box)
3562 {
3563 	if (box.isValid())
3564 		m_canvas->repaint(box);
3565 	else
3566 		m_canvas->repaint();
3567 }
3568 
resizeContents(int w,int h)3569 void ScribusView::resizeContents(int w, int h)  // deprecated
3570 {
3571 	//	qDebug() << "ScribusView::resizeContents(" << w << "," << h << ")";
3572 	int originX = qRound(m_doc->minCanvasCoordinate.x() * scale());
3573 	int originY = qRound(m_doc->minCanvasCoordinate.y() * scale());
3574 	widget()->resize(w - 0*originX, h - 0*originY);
3575 }
3576 
contentsToViewport(QPoint p)3577 QPoint ScribusView::contentsToViewport(QPoint p) // deprecated
3578 {
3579 	return p + viewport()->pos();
3580 }
3581 
viewportToContents(QPoint p)3582 QPoint ScribusView::viewportToContents(QPoint p) // deprecated
3583 {
3584 	return p - viewport()->pos();
3585 }
3586 
contentsX()3587 int ScribusView::contentsX() // deprecated
3588 {
3589 	int originX = qRound(m_doc->minCanvasCoordinate.x() * scale());
3590 	return horizontalScrollBar()->value() + originX;
3591 }
3592 
contentsY()3593 int ScribusView::contentsY() // deprecated
3594 {
3595 	int originY = qRound(m_doc->minCanvasCoordinate.y() * scale());
3596 	return verticalScrollBar()->value() + originY;
3597 }
3598 
contentsWidth()3599 int ScribusView::contentsWidth()
3600 {
3601 	return horizontalScrollBar()->maximum() - horizontalScrollBar()->minimum();
3602 }
3603 
contentsHeight()3604 int ScribusView::contentsHeight()
3605 {
3606 	return verticalScrollBar()->maximum() - verticalScrollBar()->minimum();
3607 }
3608 
setContentsPos(int x,int y)3609 void ScribusView::setContentsPos(int x, int y)
3610 {
3611 	horizontalScrollBar()->setValue(x);
3612 	verticalScrollBar()->setValue(y);
3613 	setRulerPos(contentsX(), contentsY());
3614 }
3615 
3616 
scrollContentsBy(int dx,int dy)3617 void ScribusView::scrollContentsBy(int dx, int dy)
3618 {
3619 	QScrollArea::scrollContentsBy (dx, dy);
3620 	setRulerPos(contentsX(), contentsY());
3621 }
3622 
scrollBy(int x,int y)3623 void ScribusView::scrollBy(int x, int y) // deprecated
3624 {
3625 	setContentsPos(horizontalScrollBar()->value() + x, verticalScrollBar()->value() + y);
3626 }
3627 
zoom(double scale)3628 void ScribusView::zoom(double scale)
3629 {
3630 	double zPointX = m_oldZoomX;
3631 	double zPointY = m_oldZoomY;
3632 	if (scale <= 0.0)
3633 		scale = m_canvas->scale();
3634 	if (!m_doc->m_Selection->isEmpty())
3635 	{
3636 		PageItem *currItem = m_doc->m_Selection->itemAt(0);
3637 		zPointX = currItem->xPos() + currItem->width() / 2.0;
3638 		zPointY = currItem->yPos() + currItem->height() / 2.0;
3639 	}
3640 	zoom( qRound(zPointX), qRound(zPointY), scale, false);
3641 }
3642 
zoom(int canvasX,int canvasY,double scale,bool preservePoint)3643 void ScribusView::zoom(int canvasX, int canvasY, double scale, bool preservePoint)
3644 {
3645 	QPoint globalPoint = m_canvas->canvasToGlobal(QPointF(canvasX, canvasY));
3646 	double oldScale = m_canvas->scale();
3647 	double newScale = (scale > (Prefs->opToolPrefs.magMax / 100) * Prefs->displayPrefs.displayScale) ? ((Prefs->opToolPrefs.magMax / 100) * Prefs->displayPrefs.displayScale) : scale;
3648 	undoManager->setUndoEnabled(false);
3649 	updatesOn(false);
3650 	setScale(newScale);
3651 
3652 	FPoint minPos = m_doc->minCanvasCoordinate;
3653 	FPoint maxPos = m_doc->maxCanvasCoordinate;
3654 	if (newScale > oldScale)
3655 	{
3656 		// Try to set scrollBars values in a reasonable way after important zoom out
3657 		QRectF optimalRect = m_doc->canvasOptimalRect();
3658 		double minX = qMax(minPos.x(), optimalRect.left());
3659 		double minY = qMax(minPos.y(), optimalRect.top());
3660 		double maxX = qMin(maxPos.x(), optimalRect.right());
3661 		double maxY = qMin(maxPos.y(), optimalRect.bottom());
3662 		minPos.setXY(minX, minY);
3663 		maxPos.setXY(maxX, maxY);
3664 	}
3665 
3666 	// FIXME : find a way to avoid adjustCanvas/resizeContents, cause unnecessary paintEvents despite updates disabled
3667 	if (minPos != m_doc->minCanvasCoordinate || maxPos != m_doc->maxCanvasCoordinate)
3668 		m_doc->adjustCanvas(minPos, maxPos, true);
3669 	else
3670 	{
3671 		int nw = qMax(qRound((m_doc->maxCanvasCoordinate.x() - m_doc->minCanvasCoordinate.x()) * m_canvas->scale()), visibleWidth());
3672 		int nh = qMax(qRound((m_doc->maxCanvasCoordinate.y() - m_doc->minCanvasCoordinate.y()) * m_canvas->scale()), visibleHeight());
3673 		resizeContents(nw, nh);
3674 	}
3675 
3676 	QPoint localPoint = m_canvas->canvasToLocal( QPointF(canvasX, canvasY) );
3677 
3678 	QPoint canvasPoint;
3679 	if (preservePoint)
3680 		canvasPoint = viewport()->mapFromGlobal(globalPoint);
3681 	else
3682 		canvasPoint = QPoint(viewport()->width() / 2, viewport()->height() / 2);
3683 
3684 	int contentPosX = localPoint.x() - canvasPoint.x();
3685 	int contentPosY = localPoint.y() - canvasPoint.y();
3686 
3687 	QSize maxViewport = maximumViewportSize();
3688 	minPos = m_canvas->localToCanvas(QPoint(horizontalScrollBar()->minimum(), verticalScrollBar()->minimum()));
3689 	maxPos = m_canvas->localToCanvas(QPoint(horizontalScrollBar()->maximum() + maxViewport.width(), verticalScrollBar()->maximum() + maxViewport.height()));
3690 
3691 	int hMin = qMin(contentPosX, horizontalScrollBar()->minimum());
3692 	int hMax = qMax(contentPosX, horizontalScrollBar()->maximum());
3693 	int vMin = qMin(contentPosY, verticalScrollBar()->minimum());
3694 	int vMax = qMax(contentPosY, verticalScrollBar()->maximum());
3695 	if ((hMin < horizontalScrollBar()->minimum()) || (hMax > horizontalScrollBar()->maximum()) ||
3696 		(vMin < verticalScrollBar()->minimum())   || (vMax > verticalScrollBar()->maximum()))
3697 	{
3698 		QSize maxViewport = maximumViewportSize();
3699 		minPos = m_canvas->localToCanvas(QPoint(hMin, vMin));
3700 		maxPos = m_canvas->localToCanvas(QPoint(hMax + maxViewport.width(), vMax + maxViewport.height()));
3701 	}
3702 
3703 	m_doc->adjustCanvas(minPos, maxPos);
3704 	localPoint = m_canvas->canvasToLocal(QPointF(canvasX, canvasY));
3705 	if (preservePoint)
3706 		canvasPoint = viewport()->mapFromGlobal(globalPoint);
3707 	else
3708 		canvasPoint = QPoint(viewport()->width() / 2, viewport()->height() / 2);
3709 	contentPosX = localPoint.x() - canvasPoint.x();
3710 	contentPosY = localPoint.y() - canvasPoint.y();
3711 	setContentsPos(contentPosX, contentPosY);
3712 
3713 	updatesOn(true);
3714 	undoManager->setUndoEnabled(true);
3715 }
3716 
saveViewState()3717 void ScribusView::saveViewState()
3718 {
3719 	ViewState viewState;
3720 	viewState.currentPage = m_doc->currentPageNumber();
3721 	viewState.contentX = horizontalScrollBar()->value();
3722 	viewState.contentY = verticalScrollBar()->value();
3723 	viewState.canvasScale = m_canvas->scale();
3724 	viewState.minCanvasCoordinate = m_doc->minCanvasCoordinate;
3725 	viewState.maxCanvasCoordinate = m_doc->maxCanvasCoordinate;
3726 	m_viewStates.push(viewState);
3727 }
3728 
restoreViewState()3729 void ScribusView::restoreViewState()
3730 {
3731 	if (m_viewStates.isEmpty())
3732 		return;
3733 
3734 	ViewState viewState = m_viewStates.pop();
3735 	m_doc->minCanvasCoordinate = viewState.minCanvasCoordinate;
3736 	m_doc->maxCanvasCoordinate = viewState.maxCanvasCoordinate;
3737 	setScale(viewState.canvasScale);
3738 
3739 	// #12857 : the number of pages may change when undoing/redoing
3740 	// page addition/deletion while in edit mode, so take some extra
3741 	// care so that storedPageNum is in appropriate range
3742 	int currentPage = qMin(viewState.currentPage, m_doc->DocPages.count() - 1);
3743 	m_doc->setCurrentPage(m_doc->DocPages.at(currentPage));
3744 	setContentsPos(viewState.contentX, viewState.contentY);
3745 }
3746 
stopAllDrags()3747 void ScribusView::stopAllDrags() // deprecated
3748 {
3749 	m_canvas->m_viewMode.m_MouseButtonPressed = false;
3750 	m_canvas->m_viewMode.operItemMoving = false;
3751 	m_canvas->m_viewMode.operItemResizing = false;
3752 	MidButt = false;
3753 }
3754 
setRedrawMarkerShown(bool shown)3755 void ScribusView::setRedrawMarkerShown(bool shown)
3756 {
3757 	if (shown != redrawMarker->isVisible())
3758 		redrawMarker->setVisible(shown);
3759 }
3760