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