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 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16
17 #include "canvasmode_normal.h"
18
19 #include <QApplication>
20 #include <QButtonGroup>
21 #include <QCheckBox>
22 #include <QCursor>
23 #include <QEvent>
24 #include <QMessageBox>
25 #include <QMouseEvent>
26 #include <QPainterPath>
27 #include <QPoint>
28 #include <QRect>
29 #include <QTimer>
30 #include <QToolTip>
31 #include <QWidgetAction>
32 #include <QDrag>
33 #include <QDebug>
34
35 #include "appmodes.h"
36 #include "canvas.h"
37 #include "canvasgesture_linemove.h"
38 #include "canvasgesture_resize.h"
39 #include "canvasgesture_rulermove.h"
40 #include "fileloader.h"
41 #include "fpoint.h"
42 #include "fpointarray.h"
43 #include "hyphenator.h"
44 #include "iconmanager.h"
45 #include "loadsaveplugin.h"
46 #include "pageitem_arc.h"
47 #include "pageitem_line.h"
48 #include "pageitem_regularpolygon.h"
49 #include "plugins/formatidlist.h"
50 #include "prefscontext.h"
51 #include "prefsfile.h"
52 #include "prefsmanager.h"
53 #include "scmimedata.h"
54 #include "scraction.h"
55 #include "scribus.h"
56 #include "scribusXml.h"
57 #include "scribusdoc.h"
58 #include "scribusview.h"
59 #include "selection.h"
60 #include "ui/aligndistribute.h"
61 #include "ui/contextmenu.h"
62 #include "ui/customfdialog.h"
63 #include "ui/insertTable.h"
64 #include "ui/pageselector.h"
65 #include "ui/polyprops.h"
66 #include "ui/propertiespalette.h"
67 #include "ui/propertiespalette_line.h"
68 #include "ui/propertiespalette_text.h"
69 #include "ui/propertiespalette_xyz.h"
70 #include "undomanager.h"
71 #include "util.h"
72 #include "util_math.h"
73
CanvasMode_Normal(ScribusView * view)74 CanvasMode_Normal::CanvasMode_Normal(ScribusView* view) : CanvasMode(view), m_ScMW(view->m_ScMW)
75 {
76 }
77
GetItem(PageItem ** pi)78 inline bool CanvasMode_Normal::GetItem(PageItem** pi)
79 {
80 *pi = m_doc->m_Selection->itemAt(0);
81 return (*pi) != nullptr;
82 }
83
drawControls(QPainter * p)84 void CanvasMode_Normal::drawControls(QPainter* p)
85 {
86 // qDebug() << "CanvasMode_Normal::drawControls";
87 if (m_canvas->m_viewMode.operItemMoving)
88 drawOutline(p, m_objectDeltaPos.x(), m_objectDeltaPos.y());
89 else
90 drawSelection(p, !m_doc->drawAsPreview);
91 }
92
enterEvent(QEvent * e)93 void CanvasMode_Normal::enterEvent(QEvent *e)
94 {
95 if (!m_canvas->m_viewMode.m_MouseButtonPressed)
96 {
97 setModeCursor();
98 }
99 }
100
leaveEvent(QEvent * e)101 void CanvasMode_Normal::leaveEvent(QEvent *e)
102 {
103 }
104
105
activate(bool fromGesture)106 void CanvasMode_Normal::activate(bool fromGesture)
107 {
108 // qDebug() << "CanvasMode_Normal::activate" << fromGesture;
109 CanvasMode::activate(fromGesture);
110
111 m_canvas->m_viewMode.m_MouseButtonPressed = false;
112 m_canvas->resetRenderMode();
113 m_doc->DragP = false;
114 m_doc->leaveDrag = false;
115 m_canvas->m_viewMode.operItemMoving = false;
116 m_canvas->m_viewMode.operItemResizing = false;
117 m_view->MidButt = false;
118 m_mousePressPoint.setXY(0, 0);
119 m_mouseCurrentPoint.setXY(0, 0);
120 m_mouseSavedPoint.setXY(0, 0);
121 m_objectDeltaPos.setXY(0,0 );
122 m_frameResizeHandle = -1;
123 m_shiftSelItems = false;
124 m_hoveredItem = nullptr;
125 setModeCursor();
126 if (fromGesture)
127 {
128 m_view->update();
129 }
130 }
131
deactivate(bool forGesture)132 void CanvasMode_Normal::deactivate(bool forGesture)
133 {
134 // qDebug() << "CanvasMode_Normal::deactivate" << forGesture;
135 m_view->setRedrawMarkerShown(false);
136 CanvasMode::deactivate(forGesture);
137 }
138
mouseDoubleClickEvent(QMouseEvent * m)139 void CanvasMode_Normal::mouseDoubleClickEvent(QMouseEvent *m)
140 {
141 PageItem *currItem = nullptr;
142 m->accept();
143 m_canvas->m_viewMode.m_MouseButtonPressed = false;
144 if (m_doc->drawAsPreview)
145 {
146 if (GetItem(&currItem))
147 {
148 if (currItem->isAnnotation())
149 {
150 if (currItem->annotation().Type() == Annotation::Text)
151 {
152 currItem->annotation().setOpen(!currItem->annotation().IsOpen());
153 currItem->asTextFrame()->setTextAnnotationOpen(currItem->annotation().IsOpen());
154 currItem->update();
155 m_view->updateContents();
156 }
157 }
158 }
159 return;
160 }
161 m_canvas->resetRenderMode();
162 // m_view->stopDragTimer();
163 if (m_doc->m_Selection->isMultipleSelection())
164 {
165 if (GetItem(&currItem))
166 {
167 /* CB: old code, removing this as shift-alt select on an unselected table selects a cell now.
168 //#6789 is closed by sorting this.
169 if (currItem->isTableItem)
170 {
171 m_view->Deselect(false);
172 m_doc->m_Selection->addItem(currItem);
173 currItem->isSingleSel = true;
174 //CB FIXME don't call this if the added item is item 0
175 if (!m_doc->m_Selection->primarySelectionIs(currItem))
176 currItem->emitAllToGUI();
177 m_view->updateContents(currItem->getRedrawBounding(m_canvas->scale()));
178 }*/
179 }
180 return;
181 }
182 if (GetItem(&currItem))
183 {
184 if (currItem->isLatexFrame())
185 {
186 if (currItem->locked()) // || (!currItem->ScaleType))
187 {
188 return;
189 }
190 if (currItem->imageVisible())
191 m_view->requestMode(modeEdit);
192 }
193 else if (currItem->isOSGFrame())
194 {
195 m_view->requestMode(submodeEditExternal);
196 }
197 else if ((currItem->itemType() == PageItem::Polygon) || (currItem->itemType() == PageItem::PolyLine) || (currItem->itemType() == PageItem::Group) || (currItem->itemType() == PageItem::ImageFrame) || (currItem->itemType() == PageItem::PathText))
198 {
199 if (currItem->locked()) //|| (!currItem->ScaleType))
200 {
201 //mousePressEvent(m);
202 return;
203 }
204 //If we double click on an image frame and theres no image assigned, open the
205 //load picture dialog, else put it into edit mode if the frame is set to show the image
206 if (currItem->itemType() == PageItem::ImageFrame)
207 {
208 if (currItem->Pfile.isEmpty())
209 m_view->requestMode(submodeLoadPic);
210 else if (!currItem->imageIsAvailable)
211 m_view->requestMode(submodeStatusPic);
212 else if (currItem->imageVisible())
213 m_view->requestMode(modeEdit);
214 }
215 else if (currItem->itemType() == PageItem::TextFrame)
216 {
217 m_view->requestMode(modeEdit);
218 }
219 else
220 {
221 m_view->requestMode(modeEditClip);
222 m_ScMW->scrActions["itemUngroup"]->setEnabled(false);
223 }
224 }
225 else if (currItem->itemType() == PageItem::TextFrame)
226 {
227 // See if double click was on a frame handle
228 FPoint p = m_canvas->globalToCanvas(m->globalPos());
229 Canvas::FrameHandle fh = m_canvas->frameHitTest(QPointF(p.x(),p.y()), currItem);
230 //CB if annotation, open the annotation dialog
231 if (currItem->isAnnotation())
232 {
233 m_view->requestMode(submodeAnnotProps);
234 //mousePressEvent(m);
235 }
236 else if (fh == Canvas::SOUTH)
237 currItem->asTextFrame()->setTextFrameHeight();
238 //else if not in mode edit, set mode edit
239 else if (m_doc->appMode != modeEdit)
240 {
241 m_view->requestMode(modeEdit);
242 m_view->slotSetCurs(m->globalPos().x(), m->globalPos().y());
243 //used for updating Notes Styles Editor and menu actions for marks
244 //if cursor is in mark`s place
245 m_ScMW->setTBvals(currItem);
246 //CB ignore the double click and go with a single one
247 //if we werent in mode edit before.
248 //unsure if this is correct, but its ok given we had no
249 //double click select until now.
250 // mousePressEvent(m);
251 }
252 }
253 else if (currItem->isSymbol())
254 {
255 if (!m_doc->symbolEditMode())
256 m_view->requestMode(submodeEditSymbol);
257 }
258 else if (currItem->isArc())
259 {
260 m_view->requestMode(modeEditArc);
261 }
262 else if (currItem->isRegularPolygon())
263 {
264 m_view->requestMode(modeEditPolygon);
265 }
266 else if (currItem->isSpiral())
267 {
268 m_view->requestMode(modeEditSpiral);
269 }
270 else if (currItem->isTable())
271 {
272 m_view->requestMode(modeEditTable);
273 m_view->slotSetCurs(m->globalPos().x(), m->globalPos().y());
274 m_ScMW->setTBvals(currItem);
275 }
276 }
277 }
278
279
mouseMoveEvent(QMouseEvent * m)280 void CanvasMode_Normal::mouseMoveEvent(QMouseEvent *m)
281 {
282 // qDebug()<<"CanvasMode_Normal::mouseMoveEvent";
283 // const double mouseX = m->globalX();
284 // const double mouseY = m->globalY();
285 const FPoint mousePointDoc = m_canvas->globalToCanvas(m->globalPos());
286
287 bool wasLastPostOverGuide = m_lastPosWasOverGuide;
288 m_lastPosWasOverGuide = false;
289 PageItem *currItem=nullptr;
290 bool erf = false;
291 m->accept();
292 // qDebug() << "legacy mode move:" << m->x() << m->y() << m_canvas->globalToCanvas(m->globalPos()).x() << m_canvas->globalToCanvas(m->globalPos()).y();
293 // emit MousePos(m->x()/m_canvas->scale(),// + m_doc->minCanvasCoordinate.x(),
294 // m->y()/m_canvas->scale()); // + m_doc->minCanvasCoordinate.y());
295
296 if (commonMouseMove(m))
297 return;
298 // m_mouseCurrentPoint = mousePointDoc;
299 bool movingOrResizing = (m_canvas->m_viewMode.operItemMoving || m_canvas->m_viewMode.operItemResizing);
300 bool mouseIsOnPage = (m_doc->OnPage(mousePointDoc.x(), mousePointDoc.y()) != -1);
301 if ((m_doc->guidesPrefs().guidesShown) && (!m_doc->GuideLock) && (!movingOrResizing) && (mouseIsOnPage))
302 {
303 // #9002: Resize points undraggable when object is aligned to a guide
304 // Allow item resize when guides are aligned to item while preserving
305 // ability to drag guide when guis is in foreground and inside selection
306 bool enableGuideGesture(false);
307 Canvas::FrameHandle frameResizeHandle(Canvas::OUTSIDE);
308 if (m_doc->m_Selection->count() > 0)
309 {
310 double gx = 0.0;
311 double gy = 0.0;
312 double gw = 0.0;
313 double gh = 0.0;
314 m_doc->m_Selection->getVisualGroupRect(&gx, &gy, &gw, &gh);
315 frameResizeHandle = m_canvas->frameHitTest(QPointF(mousePointDoc.x(), mousePointDoc.y()), QRectF(gx, gy, gw, gh));
316 }
317 else
318 {
319 PageItem* hoveredItem = m_canvas->itemUnderCursor(m->globalPos(), nullptr, m->modifiers());
320 if (hoveredItem)
321 frameResizeHandle = m_canvas->frameHitTest(QPointF(mousePointDoc.x(), mousePointDoc.y()), hoveredItem);
322 }
323 enableGuideGesture |= (frameResizeHandle == Canvas::OUTSIDE);
324 enableGuideGesture |= ((m_doc->guidesPrefs().renderStackOrder.indexOf(3) > m_doc->guidesPrefs().renderStackOrder.indexOf(4)) && ((frameResizeHandle == Canvas::INSIDE) && (m->modifiers() != SELECT_BENEATH)));
325 enableGuideGesture |= ((m_doc->guidesPrefs().renderStackOrder.indexOf(3) < m_doc->guidesPrefs().renderStackOrder.indexOf(4)) && ((frameResizeHandle == Canvas::INSIDE) && (m->modifiers() == SELECT_BENEATH)));
326 if (enableGuideGesture)
327 {
328 if (!m_guideMoveGesture)
329 {
330 m_guideMoveGesture = new RulerGesture(m_view, RulerGesture::HORIZONTAL);
331 connect(m_guideMoveGesture, SIGNAL(guideInfo(int,qreal)), m_ScMW->alignDistributePalette, SLOT(setGuide(int,qreal)));
332 }
333 if (m_guideMoveGesture->mouseHitsGuide(mousePointDoc))
334 {
335 m_lastPosWasOverGuide = true;
336 switch (m_guideMoveGesture->getMode())
337 {
338 case RulerGesture::HORIZONTAL:
339 m_view->setCursor(QCursor(Qt::SplitVCursor));
340 break;
341 case RulerGesture::VERTICAL:
342 m_view->setCursor(QCursor(Qt::SplitHCursor));
343 break;
344 default:
345 m_view->setCursor(QCursor(Qt::ArrowCursor));
346 }
347 return;
348 }
349 m_view->setCursor(QCursor(Qt::ArrowCursor));
350 }
351 if (wasLastPostOverGuide)
352 {
353 Qt::CursorShape cursorShape = m_view->cursor().shape();
354 if ((cursorShape == Qt::SplitHCursor) || (cursorShape == Qt::SplitVCursor))
355 m_view->setCursor(QCursor(Qt::ArrowCursor));
356 }
357 }
358 else if (!mouseIsOnPage)
359 {
360 Qt::CursorShape cursorShape = m_view->cursor().shape();
361 if ((cursorShape == Qt::SplitHCursor) || (cursorShape == Qt::SplitVCursor))
362 m_view->setCursor(QCursor(Qt::ArrowCursor));
363 }
364
365 //<<#10116 Show overflow counter HUD
366 if (!movingOrResizing && mouseIsOnPage)
367 {
368 PageItem* hoveredItem = nullptr;
369 hoveredItem = m_canvas->itemUnderCursor(m->globalPos(), hoveredItem, m->modifiers());
370 if (hoveredItem)
371 {
372 if (m_doc->drawAsPreview)
373 {
374 if (hoveredItem->isAnnotation())
375 {
376 QString toolT = "";
377 if (!hoveredItem->annotation().ToolTip().isEmpty())
378 toolT = hoveredItem->annotation().ToolTip();
379 if (hoveredItem->annotation().Type() == Annotation::Button)
380 {
381 if (!hoveredItem->annotation().RollOver().isEmpty())
382 toolT = hoveredItem->annotation().RollOver();
383 else if (!hoveredItem->annotation().Down().isEmpty())
384 toolT = hoveredItem->annotation().Down();
385 }
386 else if (hoveredItem->annotation().Type() == Annotation::Link)
387 {
388 if (hoveredItem->annotation().ActionType() == Annotation::Action_GoTo)
389 toolT = QString( tr("Go to Page %1").arg(hoveredItem->annotation().Ziel() + 1));
390 else if (hoveredItem->annotation().ActionType() == Annotation::Action_URI)
391 toolT = QString( tr("Go to URL %1").arg(hoveredItem->annotation().Extern()));
392 else if ((hoveredItem->annotation().ActionType() == Annotation::Action_GoToR_FileAbs) || (hoveredItem->annotation().ActionType() == Annotation::Action_GoToR_FileRel))
393 toolT = QString( tr("Go to Page %1 in File %2").arg(hoveredItem->annotation().Ziel() + 1).arg(hoveredItem->annotation().Extern()));
394 m_view->setCursor(QCursor(Qt::PointingHandCursor));
395 }
396 if (toolT.isEmpty())
397 toolT = hoveredItem->itemText.plainText();
398 if (!toolT.isEmpty())
399 QToolTip::showText(m->globalPos() + QPoint(5, 5), toolT, m_canvas);
400 if (hoveredItem != m_hoveredItem)
401 {
402 if (m_hoveredItem)
403 handleMouseLeave(m_hoveredItem);
404 handleMouseEnter(hoveredItem);
405 }
406 m_hoveredItem = hoveredItem;
407 if ((hoveredItem->annotation().Type() == Annotation::Text) && (hoveredItem->annotation().IsOpen()))
408 {
409 if (m_view->moveTimerElapsed() && m_canvas->m_viewMode.m_MouseButtonPressed && (m->buttons() & Qt::LeftButton) && (!hoveredItem->locked()))
410 {
411 double dx = mousePointDoc.x() - m_mouseCurrentPoint.x();
412 double dy = mousePointDoc.y() - m_mouseCurrentPoint.y();
413 hoveredItem->setXYPos(hoveredItem->xPos() + dx, hoveredItem->yPos() + dy, true);
414 m_mouseCurrentPoint = mousePointDoc;
415 m_canvas->resetRenderMode();
416 m_canvas->setRenderModeUseBuffer(false);
417 m_canvas->repaint();
418 }
419 }
420 }
421 else
422 {
423 if (QToolTip::isVisible())
424 QToolTip::hideText();
425 m_hoveredItem = nullptr;
426 }
427 }
428 else
429 {
430 if (hoveredItem->isTextFrame() && hoveredItem->frameOverflows())
431 {
432 if (m_canvas->cursorOverTextFrameControl(m->globalPos(), hoveredItem))
433 {
434 QToolTip::showText(m->globalPos() + QPoint(5, 5), tr("Overflow Characters: %1 (%2 White Spaces)\nClick to link to existing text frame or auto-create new linked text frame").arg(hoveredItem->frameOverflowCount()).arg(hoveredItem->frameOverflowBlankCount()), m_canvas);
435 }
436 }
437 else
438 if (QToolTip::isVisible())
439 QToolTip::hideText();
440 }
441 }
442 else
443 {
444 if (QToolTip::isVisible())
445 QToolTip::hideText();
446 if (m_doc->drawAsPreview)
447 {
448 if (m_hoveredItem)
449 handleMouseLeave(m_hoveredItem);
450 m_hoveredItem = nullptr;
451 }
452 }
453 }
454
455 //>>#10116
456 if (m_doc->drawAsPreview)
457 return;
458 m_mouseCurrentPoint = mousePointDoc;
459 if ((GetItem(&currItem)) && (!m_shiftSelItems))
460 {
461 double newX = qRound(mousePointDoc.x()); //m_view->translateToDoc(m->x(), m->y()).x());
462 double newY = qRound(mousePointDoc.y()); //m_view->translateToDoc(m->x(), m->y()).y());
463 // #0007865
464 if (/*(((m_view->dragTimerElapsed()) && (m->buttons() & Qt::LeftButton)) ||*/
465 (m_view->moveTimerElapsed())
466 && (m->buttons() & Qt::RightButton)
467 && (m_canvas->m_viewMode.m_MouseButtonPressed)
468 && (!m_doc->DragP)
469 && (!(currItem->isSingleSel)))
470 {
471 // start drag
472 // m_view->stopDragTimer();
473 if ((fabs(m_mousePressPoint.x() - newX) > 10) || (fabs(m_mousePressPoint.y() - newY) > 10))
474 {
475 m_canvas->setRenderMode(Canvas::RENDER_NORMAL);
476 // m_view->resetDragTimer();
477 m_doc->DragP = true;
478 m_doc->leaveDrag = false;
479 m_doc->DraggedElem = currItem;
480 m_doc->DragElements.clear();
481 for (int dre=0; dre<m_doc->m_Selection->count(); ++dre)
482 m_doc->DragElements.append(m_doc->m_Selection->itemAt(dre));
483 ScElemMimeData* md = ScriXmlDoc::writeToMimeData(m_doc, m_doc->m_Selection);
484 QDrag* dr = new QDrag(m_view);
485 dr->setMimeData(md);
486 const QPixmap& pm = IconManager::instance().loadPixmap("dragpix.png");
487 dr->setPixmap(pm);
488 // dr->setDragCursor(pm, Qt::CopyAction);
489 // dr->setDragCursor(pm, Qt::MoveAction);
490 // dr->setDragCursor(pm, Qt::LinkAction);
491 dr->exec();
492 m_doc->DragP = false;
493 m_doc->leaveDrag = false;
494 m_canvas->m_viewMode.m_MouseButtonPressed = false;
495 m_doc->DraggedElem = nullptr;
496 m_doc->DragElements.clear();
497 m_view->setCursor(QCursor(Qt::ArrowCursor));
498 m_view->updateContents();
499 }
500 return;
501 }
502 if (m_doc->DragP)
503 return;
504
505 //Operations run here:
506 //Item resize, esp after creating a new one
507 if (m_view->moveTimerElapsed() && m_canvas->m_viewMode.m_MouseButtonPressed && (m->buttons() & Qt::LeftButton) &&
508 ((m_doc->appMode == modeNormal)) && (!currItem->locked()))
509 {
510 // m_view->stopDragTimer();
511 if (!m_canvas->m_viewMode.operItemResizing)
512 {
513 //Dragging an item (plus more?)
514 newX = mousePointDoc.x(); //static_cast<int>(m->x()/sc);
515 newY = mousePointDoc.y(); //static_cast<int>(m->y()/sc);
516 m_canvas->m_viewMode.operItemMoving = true;
517 if (!(m_doc->drawAsPreview && !m_doc->editOnPreview))
518 m_view->setCursor(Qt::ClosedHandCursor);
519 else
520 m_view->setCursor(QCursor(Qt::ArrowCursor));
521 erf = false;
522 int dX = qRound(newX - m_mousePressPoint.x()), dY = qRound(newY - m_mousePressPoint.y());
523 if (!m_doc->m_Selection->isMultipleSelection())
524 {
525 erf = true;
526 currItem = m_doc->m_Selection->itemAt(0);
527 //Control Alt drag image in frame without being in edit mode
528 if ((currItem->isImageFrame()) && (m->modifiers() & Qt::ControlModifier) && (m->modifiers() & Qt::AltModifier))
529 {
530 QTransform mm1 = currItem->getTransform();
531 QTransform mm2 = mm1.inverted();
532 QPointF rota = mm2.map(QPointF(newX, newY)) - mm2.map(QPointF(m_mouseSavedPoint.x(), m_mouseSavedPoint.y()));
533 currItem->moveImageInFrame(rota.x() / currItem->imageXScale(), rota.y() / currItem->imageYScale());
534 currItem->update();
535 m_mouseSavedPoint.setXY(newX, newY);
536 }
537 else
538 {
539 //Dragging orthogonally - Ctrl Drag
540 if ((m->modifiers() & Qt::ControlModifier) && !(m->modifiers() & Qt::ShiftModifier) && !(m->modifiers() & Qt::AltModifier))
541 {
542 if (abs(dX) > abs(dY))
543 dY = 0;
544 else if (abs(dY) > abs(dX))
545 dX = 0;
546 erf = false;
547 dX += qRound(m_dragConstrainInitPtX - currItem->xPos());
548 dY += qRound(m_dragConstrainInitPtY - currItem->yPos());
549 }
550 double gx, gy, gh, gw;
551 m_objectDeltaPos.setXY(dX, dY);
552 // m_doc->m_Selection->getGroupRect(&gx, &gy, &gw, &gh);
553 m_doc->m_Selection->getVisualGroupRect(&gx, &gy, &gw, &gh);
554 // #10677 : temporary hack : we need to introduce the
555 // concept of item snapping points to handle better
556 // the various types of items
557 if (currItem->isLine())
558 {
559 QPointF startPoint = currItem->asLine()->startPoint();
560 QPointF endPoint = currItem->asLine()->endPoint();
561 gx = qMin(startPoint.x(), endPoint.x());
562 gy = qMin(startPoint.y(), endPoint.y());
563 gw = fabs(startPoint.x() - endPoint.x());
564 gh = fabs(startPoint.y() - endPoint.y());
565 }
566 if (m_doc->SnapGuides)
567 {
568 double nx = gx + m_objectDeltaPos.x();
569 double ny = gy + m_objectDeltaPos.y();
570 double nxo = nx, nyo = ny;
571 m_doc->ApplyGuides(&nx, &ny);
572 m_objectDeltaPos += FPoint(nx - nxo, ny - nyo);
573 nx = nxo = gx + gw + m_objectDeltaPos.x();
574 ny = nyo = gy + gh + m_objectDeltaPos.y();
575 m_doc->ApplyGuides(&nx, &ny);
576 m_objectDeltaPos += FPoint(nx - nxo, ny - nyo);
577 if (false)
578 {
579 nx = nxo = gx + gw / 2 + m_objectDeltaPos.x();
580 ny = nyo = gy + gh / 2 + m_objectDeltaPos.y();
581 m_doc->ApplyGuides(&nx, &ny);
582 m_objectDeltaPos += FPoint(nx - nxo, ny - nyo);
583 }
584 }
585 if (m_doc->SnapElement)
586 {
587 xSnap = 0;
588 ySnap = 0;
589 double snapWidth[] = { 0, gw, gw / 2 };
590 double snapHeight[] = { 0, gh, gh / 2 };
591 if (m_objectDeltaPos.x() < 0)
592 std::swap(snapWidth[0], snapWidth[2]);
593 if (m_objectDeltaPos.y() < 0)
594 std::swap(snapHeight[0], snapHeight[2]);
595 double nx,ny,nyo,nxo;
596 for (int i = 0; i < 3; i++)
597 {
598 nx = gx + snapWidth[i] + m_objectDeltaPos.x();
599 ny = gy + snapHeight[i] + m_objectDeltaPos.y();
600 nxo = nx, nyo = ny;
601 m_doc->ApplyGuides(&nx, &ny,true);
602 m_objectDeltaPos += FPoint(nx - nxo, ny - nyo);
603 if (ny != nyo)
604 ySnap = ny;
605 if (nx != nxo)
606 xSnap = nx;
607 }
608 }
609 if (m_doc->SnapGrid)
610 {
611 double gx, gy, gh, gw, gxo, gyo;
612 m_doc->m_Selection->getVisualGroupRect(&gx, &gy, &gw, &gh);
613 gx += m_objectDeltaPos.x();
614 gy += m_objectDeltaPos.y();
615 gxo = gx;
616 gyo = gy;
617 QRectF nr = m_doc->ApplyGridF(QRectF(gx, gy, gw, gh));
618 gx = nr.x();
619 gy = nr.y();
620 if ((fabs(gx - gxo) < (m_doc->guidesPrefs().guideRad) / m_canvas->scale()) && (fabs(gy - gyo) < (m_doc->guidesPrefs().guideRad) / m_canvas->scale()))
621 m_objectDeltaPos += FPoint(gx - gxo, gy - gyo);
622 }
623 }
624 }
625 else
626 {
627 double gx, gy, gh, gw;
628 m_doc->m_Selection->getVisualGroupRect(&gx, &gy, &gw, &gh);
629 int dX = qRound(newX - m_mousePressPoint.x()), dY = qRound(newY - m_mousePressPoint.y());
630 erf = true;
631 if (m->modifiers() & Qt::ControlModifier)
632 {
633 if (abs(dX) > abs(dY))
634 dY = 0;
635 else if (abs(dY) > abs(dX))
636 dX = 0;
637 erf = false;
638 dX += m_dragConstrainInitPtX-qRound(gx);
639 dY += m_dragConstrainInitPtY-qRound(gy);
640 }
641 m_objectDeltaPos.setXY(dX, dY);
642 if (m_doc->SnapGuides)
643 {
644 double nx = gx + m_objectDeltaPos.x();
645 double ny = gy + m_objectDeltaPos.y();
646 double nxo = nx, nyo = ny;
647 m_doc->ApplyGuides(&nx, &ny);
648 m_objectDeltaPos += FPoint(nx - nxo, ny - nyo);
649 nx = nxo = gx + gw + m_objectDeltaPos.x();
650 ny = nyo = gy + gh + m_objectDeltaPos.y();
651 m_doc->ApplyGuides(&nx, &ny);
652 m_objectDeltaPos += FPoint(nx-nxo, ny-nyo);
653 if (false)
654 {
655 nx = nxo = gx + gw/2 + m_objectDeltaPos.x();
656 ny = nyo = gy + gh/2 + m_objectDeltaPos.y();
657 m_doc->ApplyGuides(&nx, &ny);
658 m_objectDeltaPos += FPoint(nx-nxo, ny-nyo);
659 }
660 }
661 if (m_doc->SnapElement)
662 {
663 xSnap = 0;
664 ySnap = 0;
665 double snapWidth[] = { 0, gw, gw / 2 };
666 double snapHeight[] = { 0, gh, gh / 2 };
667 if (m_objectDeltaPos.x() <0 )
668 std::swap(snapWidth[0], snapWidth[2]);
669 if (m_objectDeltaPos.y() < 0)
670 std::swap(snapHeight[0], snapHeight[2]);
671 double nx,ny,nyo,nxo;
672 for (int i = 0; i < 3; i++)
673 {
674 nx = gx + snapWidth[i] + m_objectDeltaPos.x();
675 ny = gy + snapHeight[i] + m_objectDeltaPos.y();
676 nxo = nx, nyo = ny;
677 m_doc->ApplyGuides(&nx, &ny,true);
678 m_objectDeltaPos += FPoint(nx - nxo, ny - nyo);
679 if (ny != nyo)
680 ySnap = ny;
681 if (nx != nxo)
682 xSnap = nx;
683 }
684 }
685 if (m_doc->SnapGrid)
686 {
687 double gx, gy, gh, gw, gxo, gyo;
688 m_doc->m_Selection->getVisualGroupRect(&gx, &gy, &gw, &gh);
689 gx += m_objectDeltaPos.x();
690 gy += m_objectDeltaPos.y();
691 gxo = gx;
692 gyo = gy;
693 QRectF nr = m_doc->ApplyGridF(QRectF(gx, gy, gw, gh));
694 gx = nr.x();
695 gy = nr.y();
696 if ((fabs(gx - gxo) < (m_doc->guidesPrefs().guideRad) / m_canvas->scale()) && (fabs(gy - gyo) < (m_doc->guidesPrefs().guideRad) / m_canvas->scale()))
697 m_objectDeltaPos += FPoint(gx - gxo, gy - gyo);
698 }
699 }
700 if (erf)
701 {
702 m_mouseCurrentPoint.setXY(newX, newY);
703 }
704
705 {
706 double gx, gy, gh, gw;
707 m_doc->m_Selection->getVisualGroupRect(&gx, &gy, &gw, &gh);
708 m_doc->adjustCanvas(FPoint(gx,gy), FPoint(gx + gw, gy + gh));
709 QPoint selectionCenter = m_canvas->canvasToLocal(QPointF(gx + gw / 2, gy + gh / 2));
710 QPoint localMousePos = m_canvas->canvasToLocal(mousePointDoc);
711 int localwidth = static_cast<int>(gw * m_canvas->scale());
712 int localheight = static_cast<int>(gh * m_canvas->scale());
713 if (localwidth > 200)
714 {
715 localwidth = 0;
716 selectionCenter.setX(localMousePos.x());
717 }
718 if (localheight > 200)
719 {
720 localheight = 0;
721 selectionCenter.setY(localMousePos.y());
722 }
723 m_view->ensureVisible(selectionCenter.x(), selectionCenter.y(), localwidth / 2 + 20, localheight / 2 + 20);
724 m_canvas->repaint();
725 m_doc->m_Selection->getGroupRect(&gx, &gy, &gw, &gh);
726 m_canvas->displayCorrectedXYHUD(m->globalPos(), gx + m_objectDeltaPos.x(), gy + m_objectDeltaPos.y());
727 }
728 }
729 }
730
731 // move page item
732 if ((!m_canvas->m_viewMode.m_MouseButtonPressed) && (m_doc->appMode != modeDrawBezierLine))
733 {
734 if (m_doc->m_Selection->isMultipleSelection())
735 {
736 double gx, gy, gh, gw;
737 m_doc->m_Selection->getVisualGroupRect(&gx, &gy, &gw, &gh);
738 int how = m_canvas->frameHitTest(QPointF(mousePointDoc.x(),mousePointDoc.y()), QRectF(gx, gy, gw, gh));
739 if (how >= 0)
740 {
741 if (how > 0)
742 setResizeCursor(how);
743 else
744 m_view->setCursor(QCursor(Qt::OpenHandCursor));
745 }
746 else
747 {
748 setModeCursor();
749 }
750 return;
751 }
752 for (int a = 0; a < m_doc->m_Selection->count(); ++a)
753 {
754 currItem = m_doc->m_Selection->itemAt(a);
755 if (currItem->locked())
756 break;
757 QTransform p;
758 m_canvas->Transform(currItem, p);
759 QRect mpo = QRect(m->x() - m_doc->guidesPrefs().grabRadius, m->y() - m_doc->guidesPrefs().grabRadius, m_doc->guidesPrefs().grabRadius * 2, m_doc->guidesPrefs().grabRadius * 2);
760 if ((QRegion(p.map(QPolygon(QRect(-3, -3, static_cast<int>(currItem->width() + 6), static_cast<int>(currItem->height() + 6))))).contains(mpo)))
761 {
762 QRect tx = p.mapRect(QRect(0, 0, static_cast<int>(currItem->width()), static_cast<int>(currItem->height())));
763 if ((tx.intersects(mpo)) && (!currItem->locked()))
764 {
765 Qt::CursorShape cursorShape = Qt::OpenHandCursor;
766 if (!currItem->sizeLocked())
767 cursorShape = m_view->getResizeCursor(currItem, mpo, cursorShape);
768 m_view->setCursor(QCursor(cursorShape));
769 }
770 }
771 }
772 if (GetItem(&currItem) && (m_doc->appMode == modeNormal))
773 {
774 int how = m_canvas->frameHitTest(QPointF(mousePointDoc.x(),mousePointDoc.y()), currItem);
775 if (how > 0)
776 {
777 if (currItem->isLine())
778 m_view->setCursor(QCursor(Qt::SizeAllCursor));
779 else if (!currItem->locked() && !currItem->sizeLocked())
780 {
781 if ((!currItem->sizeHLocked() && !currItem->sizeVLocked()) || (currItem->sizeHLocked() && (how == Canvas::SOUTH || how == Canvas::NORTH))
782 || (currItem->sizeVLocked() && (how == Canvas::EAST || how == Canvas::WEST)))
783 setResizeCursor(how, currItem->rotation());
784 }
785 }
786 else if (how == 0)
787 {
788 if (!(m_doc->drawAsPreview && !m_doc->editOnPreview))
789 m_view->setCursor(QCursor(Qt::OpenHandCursor));
790 else
791 m_view->setCursor(QCursor(Qt::ArrowCursor));
792 }
793 else
794 {
795 m_view->setCursor(QCursor(Qt::ArrowCursor));
796 }
797 }
798 }
799 }
800 else
801 {
802 if ((m_canvas->m_viewMode.m_MouseButtonPressed) && (m->buttons() & Qt::LeftButton))
803 {
804 double newX = qRound(mousePointDoc.x());
805 double newY = qRound(mousePointDoc.y());
806 m_mouseSavedPoint.setXY(newX, newY);
807 QPoint startP = m_canvas->canvasToGlobal(m_mousePressPoint);
808 m_view->redrawMarker->setGeometry(QRect(m_view->mapFromGlobal(startP), m_view->mapFromGlobal(m->globalPos())).normalized());
809 m_view->setRedrawMarkerShown(true);
810 m_view->HaveSelRect = true;
811 return;
812 }
813 }
814 }
815
mousePressEvent(QMouseEvent * m)816 void CanvasMode_Normal::mousePressEvent(QMouseEvent *m)
817 {
818 // qDebug("CanvasMode_Normal::mousePressEvent");
819 const FPoint mousePointDoc = m_canvas->globalToCanvas(m->globalPos());
820 PageItem *currItem;
821
822 m_objectDeltaPos = FPoint(0, 0);
823 m_mousePressPoint = m_mouseCurrentPoint = mousePointDoc;
824 m_mouseSavedPoint = mousePointDoc;
825 m_canvas->m_viewMode.m_MouseButtonPressed = true;
826 m_canvas->m_viewMode.operItemMoving = false;
827 m_view->HaveSelRect = false;
828 m_doc->DragP = false;
829 m_doc->leaveDrag = false;
830 m->accept();
831 m_view->registerMousePress(m->globalPos());
832
833 if (m->button() == Qt::MidButton)
834 {
835 m_view->MidButt = true;
836 if (m->modifiers() & Qt::ControlModifier)
837 m_view->DrawNew();
838 return;
839 }
840
841 if ((GetItem(&currItem)) && (!m_lastPosWasOverGuide))
842 {
843 if ((currItem->isLine()) && (!m_doc->m_Selection->isMultipleSelection()) && (!m_doc->drawAsPreview))
844 {
845 if (!m_lineMoveGesture)
846 m_lineMoveGesture = new LineMove(this);
847
848 m_lineMoveGesture->mousePressEvent(m);
849 if (m_lineMoveGesture->haveLineItem())
850 {
851 m_view->startGesture(m_lineMoveGesture);
852 return;
853 }
854 }
855 else
856 {
857 bool isMS=m_doc->m_Selection->isMultipleSelection();
858 if ((isMS || (!isMS && (!currItem->locked() && !currItem->sizeLocked()))) && (!m_doc->drawAsPreview))
859 {
860 if (!m_resizeGesture)
861 m_resizeGesture = new ResizeGesture(this);
862
863 m_resizeGesture->mousePressEvent(m);
864 if (m_resizeGesture->frameHandle() > 0)
865 {
866 m_view->startGesture(m_resizeGesture);
867 return;
868 }
869 }
870 //#7928 else
871 //#7928 return;
872 }
873 if (!(m_doc->drawAsPreview && !m_doc->editOnPreview))
874 m_view->setCursor(Qt::ClosedHandCursor);
875 else
876 m_view->setCursor(QCursor(Qt::ArrowCursor));
877 #if 1
878 // normal edit mode
879 m_canvas->PaintSizeRect(QRect());
880 double gx, gy, gh, gw;
881 bool shiftSel = true;
882 m_doc->m_Selection->getVisualGroupRect(&gx, &gy, &gw, &gh);
883 m_dragConstrainInitPtX = qRound(gx);
884 m_dragConstrainInitPtY = qRound(gy);
885 m_frameResizeHandle = m_canvas->frameHitTest(QPointF(mousePointDoc.x(),mousePointDoc.y()), QRectF(gx, gy, gw, gh));
886 if (m_frameResizeHandle == Canvas::OUTSIDE ||
887 (m_frameResizeHandle == Canvas::INSIDE && m->modifiers() != Qt::NoModifier))
888 {
889 m_frameResizeHandle = 0;
890 m_doc->m_Selection->delaySignalsOn();
891 m_view->updatesOn(false);
892 shiftSel = SeleItem(m);
893 m_view->updatesOn(true);
894 m_doc->m_Selection->delaySignalsOff();
895 }
896 if (((m_doc->m_Selection->isEmpty()) || (!shiftSel)) && (m->modifiers() == Qt::ShiftModifier))
897 {
898 m_shiftSelItems = true;
899 m_mouseCurrentPoint = m_mousePressPoint = m_mouseSavedPoint = mousePointDoc;
900 }
901 else
902 m_shiftSelItems = false;
903 m_canvas->setRenderModeFillBuffer();
904 #endif
905 }
906 else // !GetItem()
907 {
908 SeleItem(m);
909 if (m_doc->m_Selection->isEmpty())
910 {
911 m_mouseCurrentPoint = m_mousePressPoint = m_mouseSavedPoint = mousePointDoc;
912 m_view->redrawMarker->setGeometry(m->globalPos().x(), m->globalPos().y(), 1, 1);
913 m_view->setRedrawMarkerShown(true);
914 }
915 else
916 {
917 if (!(m_doc->drawAsPreview && !m_doc->editOnPreview))
918 m_canvas->setRenderModeFillBuffer();
919 }
920 }
921 /* if (m->button() == MidButton)
922 {
923 MidButt = true;
924 if (m_doc->m_Selection->count() != 0)
925 m_view->Deselect(true);
926 DrawNew();
927 } */
928 if ((m_doc->m_Selection->count() != 0) && (m->button() == Qt::RightButton))
929 {
930 m_canvas->m_viewMode.m_MouseButtonPressed = true;
931 m_mousePressPoint = m_mouseCurrentPoint;
932 }
933 if (m_doc->drawAsPreview && !m_doc->editOnPreview)
934 {
935 m_canvas->setRenderModeUseBuffer(false);
936 if (m_doc->m_Selection->count() == 1)
937 {
938 currItem = m_doc->m_Selection->itemAt(0);
939 if (currItem->isAnnotation())
940 {
941 if (currItem->annotation().Type() == Annotation::Checkbox)
942 handleCheckBoxPress(currItem);
943 else if (currItem->annotation().Type() == Annotation::RadioButton)
944 handleRadioButtonPress(currItem);
945 else if (currItem->annotation().Type() == Annotation::Button)
946 handlePushButtonPress(currItem);
947 }
948 }
949 }
950 // Commented out to fix bug #7865
951 // if ((m_doc->m_Selection->count() != 0) && (m->button() == Qt::LeftButton) && (frameResizeHandle == 0))
952 // {
953 // m_view->startDragTimer();
954 // }
955 m_canvas->PaintSizeRect(QRect());
956 }
957
958
mouseReleaseEvent(QMouseEvent * m)959 void CanvasMode_Normal::mouseReleaseEvent(QMouseEvent *m)
960 {
961 // qDebug("CanvasMode_Normal::mouseReleaseEvent");
962 #ifdef GESTURE_FRAME_PREVIEW
963 clearPixmapCache();
964 #endif // GESTURE_FRAME_PREVIEW
965 const FPoint mousePointDoc = m_canvas->globalToCanvas(m->globalPos());
966 PageItem *currItem;
967 m_canvas->m_viewMode.m_MouseButtonPressed = false;
968 m_canvas->resetRenderMode();
969 m->accept();
970 m_view->setRedrawMarkerShown(false);
971 // m_view->stopDragTimer();
972 //m_canvas->update(); //ugly in a mouseReleaseEvent!!!!!!!
973
974 // right click
975 // opens context menu
976 if (m->button() == Qt::RightButton && (!m_doc->DragP) )
977 {
978 if ((!GetItem(&currItem)) && (!m_doc->drawAsPreview))
979 {
980 createContextMenu(nullptr, mousePointDoc.x(), mousePointDoc.y());
981 return;
982 }
983 if ((GetItem(&currItem)) && (!(m_doc->drawAsPreview && !m_doc->editOnPreview)))
984 {
985 createContextMenu(currItem, mousePointDoc.x(), mousePointDoc.y());
986 return;
987 }
988 }
989
990 // link text frames
991 //<<#10116: Click on overflow icon to get into link frame mode
992 PageItem* clickedItem = nullptr;
993 clickedItem = m_canvas->itemUnderCursor(m->globalPos(), clickedItem, m->modifiers());
994 if (clickedItem && clickedItem->isTextFrame() && (!clickedItem->isAnnotation()) && (!m_doc->drawAsPreview))
995 {
996 if (clickedItem->frameOverflows())
997 {
998 if (m_canvas->cursorOverTextFrameControl(m->globalPos(), clickedItem))
999 {
1000 m_view->requestMode(modeLinkFrames);
1001 return;
1002 }
1003 }
1004 }
1005
1006 // drag move?
1007 //>>#10116
1008 if (m_view->moveTimerElapsed() && (GetItem(&currItem)))
1009 {
1010 // m_view->stopDragTimer();
1011 m_canvas->setRenderModeUseBuffer(false);
1012 if (!m_doc->m_Selection->isMultipleSelection())
1013 {
1014 m_doc->setRedrawBounding(currItem);
1015 currItem->OwnPage = m_doc->OnPage(currItem);
1016 m_canvas->m_viewMode.operItemResizing = false;
1017 if (currItem->isLine())
1018 m_view->updateContents();
1019 }
1020 if (m_canvas->m_viewMode.operItemMoving)
1021 {
1022 // we want to invalidate all frames under the moved frame
1023 // hm, I will try to be more explicit :) - pm
1024 int itemIndex = m_doc->Items->count();
1025 PageItem* underItem( m_canvas->itemUnderItem(currItem, itemIndex) );
1026 while (underItem)
1027 {
1028 if (underItem->isTextFrame())
1029 underItem->asTextFrame()->invalidateLayout(false);
1030 else
1031 underItem->invalidateLayout();
1032
1033 underItem = m_canvas->itemUnderItem(currItem, itemIndex);
1034 }
1035
1036 m_view->updatesOn(false);
1037 if (!m_view->groupTransactionStarted())
1038 {
1039 m_view->startGroupTransaction(Um::Move, "", Um::IMove);
1040 }
1041 if (m_doc->m_Selection->isMultipleSelection())
1042 {
1043 m_doc->moveGroup(m_objectDeltaPos.x(), m_objectDeltaPos.y());
1044 double gx, gy, gh, gw;
1045 m_doc->m_Selection->getVisualGroupRect(&gx, &gy, &gw, &gh);
1046 double nx = gx;
1047 double ny = gy;
1048 if (!m_doc->ApplyGuides(&nx, &ny) && !m_doc->ApplyGuides(&nx, &ny,true))
1049 {
1050 QRectF nr = m_doc->ApplyGridF(QRectF(gx, gy, gw, gh));
1051 nx = nr.x();
1052 ny = nr.y();
1053 }
1054 m_doc->moveGroup(nx - gx, ny - gy);
1055 m_doc->m_Selection->getVisualGroupRect(&gx, &gy, &gw, &gh);
1056 nx = gx + gw;
1057 ny = gy + gh;
1058 if (m_doc->ApplyGuides(&nx, &ny) && !m_doc->ApplyGuides(&nx, &ny,true))
1059 m_doc->moveGroup(nx - (gx + gw), ny - (gy + gh));
1060 m_doc->m_Selection->setGroupRect();
1061 }
1062 else
1063 {
1064 currItem = m_doc->m_Selection->itemAt(0);
1065 m_doc->moveItem(m_objectDeltaPos.x(), m_objectDeltaPos.y(), currItem);
1066 if (m_doc->SnapGrid)
1067 {
1068 double nx = currItem->xPos();
1069 double ny = currItem->yPos();
1070 if (!m_doc->ApplyGuides(&nx, &ny) && !m_doc->ApplyGuides(&nx, &ny,true))
1071 {
1072 double gx, gy, gh, gw, gxo, gyo;
1073 m_doc->m_Selection->getVisualGroupRect(&gx, &gy, &gw, &gh);
1074 gxo = gx;
1075 gyo = gy;
1076 QRectF nr = m_doc->ApplyGridF(QRectF(gx, gy, gw, gh));
1077 gx = nr.x();
1078 gy = nr.y();
1079 if ((fabs(gx - gxo) < (m_doc->guidesPrefs().guideRad) / m_canvas->scale()) && (fabs(gy - gyo) < (m_doc->guidesPrefs().guideRad) / m_canvas->scale()))
1080 {
1081 nx += (gx - gxo);
1082 ny += (gy - gyo);
1083 }
1084 }
1085 m_doc->moveItem(nx-currItem->xPos(), ny-currItem->yPos(), currItem);
1086 }
1087 }
1088 m_canvas->m_viewMode.operItemMoving = false;
1089 if (m_doc->m_Selection->isMultipleSelection())
1090 {
1091 double gx, gy, gh, gw;
1092 m_doc->m_Selection->getGroupRect(&gx, &gy, &gw, &gh);
1093 FPoint maxSize(gx + gw + m_doc->scratch()->right(), gy + gh + m_doc->scratch()->bottom());
1094 FPoint minSize(gx - m_doc->scratch()->left(), gy - m_doc->scratch()->top());
1095 m_doc->adjustCanvas(minSize, maxSize);
1096 }
1097 m_doc->setRedrawBounding(currItem);
1098 currItem->OwnPage = m_doc->OnPage(currItem);
1099 if (currItem->OwnPage != -1)
1100 {
1101 m_doc->setCurrentPage(m_doc->Pages->at(currItem->OwnPage));
1102 m_view->m_ScMW->slotSetCurrentPage(currItem->OwnPage);
1103 }
1104 //CB done with emitAllToGUI
1105 //emit HaveSel();
1106 //EmitValues(currItem);
1107 //CB need this for? a moved item will send its new data with the new xpos/ypos emits
1108 //CB TODO And what if we have dragged to a new page. Items X&Y are not updated anyway now
1109 //currItem->emitAllToGUI();
1110 m_view->updatesOn(true);
1111 m_view->updateContents();
1112 m_doc->changed();
1113 }
1114 }
1115
1116
1117 //CB Drag selection performed here
1118 if (((m_doc->m_Selection->isEmpty()) && (m_view->HaveSelRect) && (!m_view->MidButt)) || ((m_shiftSelItems) && (m_view->HaveSelRect) && (!m_view->MidButt)))
1119 {
1120 // get newly selection rectangle
1121 double dx = m_mouseSavedPoint.x() - m_mousePressPoint.x();
1122 double dy = m_mouseSavedPoint.y() - m_mousePressPoint.y();
1123 QRectF canvasSele = QRectF(m_mousePressPoint.x(), m_mousePressPoint.y(), dx, dy).normalized();
1124 QRectF localSele = m_canvas->canvasToLocalF(canvasSele).normalized();
1125 if (!m_doc->masterPageMode())
1126 {
1127 uint docPagesCount = m_doc->Pages->count();
1128 uint docCurrPageNo = m_doc->currentPageNumber();
1129 for (uint i = 0; i < docPagesCount; ++i)
1130 {
1131 ScPage* page = m_doc->Pages->at(i);
1132 QRectF pageRect(page->xOffset(), page->yOffset(), page->width(), page->height());
1133 if (pageRect.intersects(canvasSele))
1134 {
1135 if (docCurrPageNo != i)
1136 {
1137 m_doc->setCurrentPage(m_doc->Pages->at(i));
1138 m_view->m_ScMW->slotSetCurrentPage(i);
1139 }
1140 break;
1141 }
1142 }
1143 m_view->setRulerPos(m_view->contentsX(), m_view->contentsY());
1144 }
1145 int docItemCount = m_doc->Items->count();
1146 if (docItemCount != 0)
1147 {
1148 m_doc->m_Selection->delaySignalsOn();
1149
1150 // modifier keys
1151 bool altPressed = m->modifiers() & Qt::AltModifier;
1152 bool shiftPressed = m->modifiers() & Qt::ShiftModifier;
1153
1154 for (int a = 0; a < docItemCount; ++a)
1155 {
1156 PageItem* docItem = m_doc->Items->at(a);
1157 if ((m_doc->masterPageMode()) && (docItem->OnMasterPage != m_doc->currentPage()->pageName()))
1158 continue;
1159 if (m_doc->canSelectItemOnLayer(docItem->m_layerID))
1160 {
1161 // get current item rect/bounding box
1162 QRectF apr2 = m_canvas->canvasToLocalF( docItem->getCurrentBoundingRect(docItem->lineWidth()) );
1163
1164 bool is_selected = docItem->isSelected();
1165
1166 // alt selection
1167 bool select = altPressed ? localSele.intersects(apr2) :
1168 localSele.contains(apr2);
1169
1170 // make selection
1171 if (!is_selected && select)
1172 m_doc->m_Selection->addItem(docItem);
1173 else if (is_selected && shiftPressed && select) // shift selection - invert selection
1174 m_doc->m_Selection->removeItem(docItem);
1175 }
1176 }
1177 m_doc->m_Selection->delaySignalsOff();
1178 if (m_doc->m_Selection->count() > 1)
1179 {
1180 double x, y, w, h;
1181 m_doc->m_Selection->getGroupRect(&x, &y, &w, &h);
1182 m_view->getGroupRectScreen(&x, &y, &w, &h);
1183 }
1184 }
1185 m_view->HaveSelRect = false;
1186 m_shiftSelItems = false;
1187 // m_view->redrawMarker->hide();
1188 m_view->updateContents();
1189 }
1190 if (m_doc->appMode != modeEdit)
1191 {
1192 if (!PrefsManager::instance().appPrefs.uiPrefs.stickyTools)
1193 m_view->requestMode(modeNormal);
1194 else
1195 {
1196 int appMode = m_doc->appMode;
1197 m_view->requestMode(appMode);
1198 }
1199 }
1200 if (GetItem(&currItem))
1201 {
1202 if (m_doc->m_Selection->count() > 1)
1203 {
1204 double x, y, w, h;
1205 m_doc->m_Selection->getGroupRect(&x, &y, &w, &h);
1206 m_canvas->m_viewMode.operItemMoving = false;
1207 m_canvas->m_viewMode.operItemResizing = false;
1208 m_view->updateContents(QRect(static_cast<int>(x - 5), static_cast<int>(y - 5), static_cast<int>(w + 10), static_cast<int>(h + 10)));
1209 }
1210 /*else
1211 currItem->emitAllToGUI();*/
1212 }
1213 else
1214 m_view->deselectItems(true);
1215
1216 xSnap = ySnap = 0;
1217 m_canvas->setRenderModeUseBuffer(false);
1218 m_doc->DragP = false;
1219 m_doc->leaveDrag = false;
1220 m_canvas->m_viewMode.operItemMoving = false;
1221 m_canvas->m_viewMode.operItemResizing = false;
1222 m_view->MidButt = false;
1223 m_shiftSelItems = false;
1224 if (m_view->groupTransactionStarted())
1225 {
1226 for (int i = 0; i < m_doc->m_Selection->count(); ++i)
1227 m_doc->m_Selection->itemAt(i)->checkChanges(true);
1228 m_view->endGroupTransaction();
1229 }
1230 for (int i = 0; i < m_doc->m_Selection->count(); ++i)
1231 m_doc->m_Selection->itemAt(i)->checkChanges(true);
1232
1233 //Commit drag created items to undo manager.
1234 if (m_doc->m_Selection->count() > 0)
1235 {
1236 if (m_doc->m_Selection->itemAt(0)!=nullptr)
1237 {
1238 m_doc->itemAddCommit(m_doc->m_Selection->itemAt(0));
1239 }
1240 }
1241
1242 //Make sure the Zoom spinbox and page selector don't have focus if we click on the canvas
1243 m_view->m_ScMW->zoomSpinBox->clearFocus();
1244 m_view->m_ScMW->pageSelector->clearFocus();
1245 if (m_doc->m_Selection->count() > 0)
1246 {
1247 if (m_doc->m_Selection->itemAt(0) != nullptr) // is there the old clip stored for the undo action
1248 {
1249 currItem = m_doc->m_Selection->itemAt(0);
1250 m_doc->nodeEdit.finishTransaction(currItem);
1251 }
1252 }
1253 if (m_doc->drawAsPreview && !m_doc->editOnPreview)
1254 {
1255 if (m_doc->m_Selection->count() == 1)
1256 {
1257 currItem = m_doc->m_Selection->itemAt(0);
1258 if (currItem->isAnnotation())
1259 {
1260 if (currItem->annotation().Type() == Annotation::Text)
1261 {
1262 if (currItem->annotation().IsOpen())
1263 {
1264 if (m_canvas->cursorOverFrameControl(m->globalPos(), QRectF(245, 20, 11, 11), currItem))
1265 {
1266 currItem->annotation().setOpen(false);
1267 currItem->asTextFrame()->setTextAnnotationOpen(false);
1268 currItem->update();
1269 m_view->updateContents();
1270 }
1271 }
1272 }
1273 if (currItem->annotation().Type() == Annotation::Link)
1274 handleLinkAnnotation(currItem);
1275 else if (currItem->annotation().Type() == Annotation::Checkbox)
1276 handleCheckBoxRelease(currItem);
1277 else if (currItem->annotation().Type() == Annotation::RadioButton)
1278 handleRadioButtonRelease(currItem);
1279 else if (currItem->annotation().Type() == Annotation::Button)
1280 handlePushButtonRelease(currItem);
1281 }
1282 }
1283 }
1284 }
1285
handleCheckBoxPress(PageItem * currItem)1286 void CanvasMode_Normal::handleCheckBoxPress(PageItem* currItem)
1287 {
1288 m_view->m_AnnotChanged = true;
1289 currItem->annotation().setOnState(true);
1290 currItem->update();
1291 if (currItem->annotation().ActionType() == Annotation::Action_JavaScript)
1292 handleJavaAction(currItem, Annotation::Java_PressButton);
1293 m_doc->regionsChanged()->update(currItem->getVisualBoundingRect());
1294 }
1295
handlePushButtonPress(PageItem * currItem)1296 void CanvasMode_Normal::handlePushButtonPress(PageItem* currItem)
1297 {
1298 currItem->annotation().setOnState(true);
1299 currItem->update();
1300 if (currItem->annotation().ActionType() == Annotation::Action_JavaScript)
1301 handleJavaAction(currItem, Annotation::Java_PressButton);
1302 m_doc->regionsChanged()->update(currItem->getVisualBoundingRect());
1303 }
1304
handleRadioButtonPress(PageItem * currItem)1305 void CanvasMode_Normal::handleRadioButtonPress(PageItem* currItem)
1306 {
1307 m_view->m_AnnotChanged = true;
1308 if (currItem->isGroupChild())
1309 {
1310 PageItem *group = currItem->Parent->asGroupFrame();
1311 for (int a = 0; a < group->groupItemList.count(); a++)
1312 {
1313 PageItem *gItem = group->groupItemList[a];
1314 if ((gItem->isAnnotation()) && (gItem->annotation().Type() == Annotation::RadioButton))
1315 {
1316 gItem->update();
1317 }
1318 }
1319 }
1320 else
1321 {
1322 int op = currItem->OwnPage;
1323 uint docItemCount = m_doc->Items->count();
1324 for (uint i = 0; i < docItemCount; ++i)
1325 {
1326 PageItem *gItem = m_doc->Items->at(i);
1327 if ((gItem->isAnnotation()) && (gItem->annotation().Type() == Annotation::RadioButton) && (gItem->OwnPage == op))
1328 {
1329 gItem->update();
1330 }
1331 }
1332 }
1333 currItem->annotation().setOnState(true);
1334 currItem->update();
1335 if (currItem->annotation().ActionType() == Annotation::Action_JavaScript)
1336 handleJavaAction(currItem, Annotation::Java_PressButton);
1337 m_view->updateContents();
1338 }
1339
handleCheckBoxRelease(PageItem * currItem)1340 void CanvasMode_Normal::handleCheckBoxRelease(PageItem* currItem)
1341 {
1342 m_view->m_AnnotChanged = true;
1343 currItem->annotation().setOnState(false);
1344 currItem->annotation().setCheckState(!currItem->annotation().IsChecked());
1345 if (currItem->annotation().ActionType() == Annotation::Action_JavaScript)
1346 handleJavaAction(currItem, Annotation::Java_ReleaseButton);
1347 currItem->update();
1348 m_doc->regionsChanged()->update(currItem->getVisualBoundingRect());
1349 }
1350
handlePushButtonRelease(PageItem * currItem)1351 void CanvasMode_Normal::handlePushButtonRelease(PageItem* currItem)
1352 {
1353 m_view->m_AnnotChanged = true;
1354 currItem->annotation().setOnState(false);
1355 currItem->update();
1356 switch (currItem->annotation().ActionType())
1357 {
1358 case Annotation::Action_JavaScript:
1359 handleJavaAction(currItem, Annotation::Java_ReleaseButton);
1360 break;
1361 case Annotation::Action_GoTo:
1362 case Annotation::Action_URI:
1363 case Annotation::Action_GoToR_FileAbs:
1364 case Annotation::Action_GoToR_FileRel:
1365 handleLinkAnnotation(currItem);
1366 break;
1367 case Annotation::Action_ResetForm:
1368 m_doc->ResetFormFields();
1369 break;
1370 case Annotation::Action_ImportData:
1371 m_doc->ImportData();
1372 break;
1373 case Annotation::Action_SubmitForm:
1374 m_doc->SubmitForm();
1375 break;
1376 case Annotation::Action_Named:
1377 handleNamedAction(currItem);
1378 default:
1379 break;
1380 }
1381 }
1382
handleRadioButtonRelease(PageItem * currItem)1383 void CanvasMode_Normal::handleRadioButtonRelease(PageItem* currItem)
1384 {
1385 m_view->m_AnnotChanged = true;
1386 if (currItem->isGroupChild())
1387 {
1388 PageItem *group = currItem->Parent->asGroupFrame();
1389 for (int a = 0; a < group->groupItemList.count(); a++)
1390 {
1391 PageItem *gItem = group->groupItemList[a];
1392 if ((gItem->isAnnotation()) && (gItem->annotation().Type() == Annotation::RadioButton))
1393 {
1394 gItem->annotation().setCheckState(false);
1395 gItem->update();
1396 }
1397 }
1398 }
1399 else
1400 {
1401 int op = currItem->OwnPage;
1402 uint docItemCount = m_doc->Items->count();
1403 for (uint i = 0; i < docItemCount; ++i)
1404 {
1405 PageItem *gItem = m_doc->Items->at(i);
1406 if ((gItem->isAnnotation()) && (gItem->annotation().Type() == Annotation::RadioButton) && (gItem->OwnPage == op))
1407 {
1408 gItem->annotation().setCheckState(false);
1409 gItem->update();
1410 }
1411 }
1412 }
1413 currItem->annotation().setCheckState(true);
1414 currItem->annotation().setOnState(false);
1415 if (currItem->annotation().ActionType() == Annotation::Action_JavaScript)
1416 handleJavaAction(currItem, Annotation::Java_ReleaseButton);
1417 currItem->update();
1418 m_view->updateContents();
1419 }
1420
handleJavaAction(PageItem * currItem,int event)1421 void CanvasMode_Normal::handleJavaAction(PageItem* currItem, int event)
1422 {
1423 QString scriptCode = "";
1424 switch (event)
1425 {
1426 case Annotation::Java_PressButton:
1427 scriptCode = currItem->annotation().D_act();
1428 break;
1429 case Annotation::Java_ReleaseButton:
1430 scriptCode = currItem->annotation().Action();
1431 break;
1432 case Annotation::Java_EnterWidget:
1433 scriptCode = currItem->annotation().E_act();
1434 break;
1435 case Annotation::Java_LeaveWidget:
1436 scriptCode = currItem->annotation().X_act();
1437 break;
1438 case Annotation::Java_FocusIn:
1439 scriptCode = currItem->annotation().Fo_act();
1440 break;
1441 case Annotation::Java_FocusOut:
1442 scriptCode = currItem->annotation().Bl_act();
1443 break;
1444 case Annotation::Java_SelectionChg:
1445 scriptCode = currItem->annotation().K_act();
1446 break;
1447 case Annotation::Java_FieldFormat:
1448 scriptCode = currItem->annotation().F_act();
1449 break;
1450 case Annotation::Java_FieldValidate:
1451 scriptCode = currItem->annotation().V_act();
1452 break;
1453 case Annotation::Java_FieldCalculate:
1454 scriptCode = currItem->annotation().C_act();
1455 break;
1456 default:
1457 break;
1458 }
1459 if (!scriptCode.isEmpty())
1460 {
1461 // Execute the JavasScript Code
1462 // qDebug() << "JavaScript:" << scriptCode;
1463 }
1464 }
1465
handleNamedAction(PageItem * currItem)1466 void CanvasMode_Normal::handleNamedAction(PageItem* currItem)
1467 {
1468 m_view->deselectItems(true);
1469 QString name = currItem->annotation().Action();
1470 if (name == "FirstPage")
1471 m_view->GotoPage(0);
1472 else if (name == "PrevPage")
1473 m_view->GotoPage(qMax(0, m_doc->currentPageNumber()-1));
1474 else if (name == "NextPage")
1475 m_view->GotoPage(qMin(m_doc->currentPageNumber()+1, m_doc->Pages->count()-1));
1476 else if (name == "LastPage")
1477 m_view->GotoPage(m_doc->Pages->count()-1);
1478 else if (name == "Print")
1479 m_ScMW->slotFilePrint();
1480 else if (name == "Close")
1481 m_ScMW->slotFileClose();
1482 else if (name == "Quit")
1483 m_ScMW->slotFileQuit();
1484 else if (name == "FitHeight")
1485 m_ScMW->slotZoom(-100);
1486 else if (name == "FitWidth")
1487 m_ScMW->slotZoom(-200);
1488 }
1489
handleLinkAnnotation(PageItem * currItem)1490 void CanvasMode_Normal::handleLinkAnnotation(PageItem* currItem)
1491 {
1492 if (currItem->annotation().ActionType() == Annotation::Action_GoTo)
1493 {
1494 m_view->deselectItems(true);
1495 if (currItem->annotation().Ziel() < m_doc->Pages->count())
1496 m_view->GotoPage(currItem->annotation().Ziel());
1497 else
1498 {
1499 QString message = tr("Page %1 does not exist!").arg(currItem->annotation().Ziel() + 1);
1500 ScMessageBox::warning(m_view, CommonStrings::trWarning, message);
1501 }
1502 }
1503 else if (currItem->annotation().ActionType() == Annotation::Action_URI)
1504 {
1505 QString message = tr("Link Target is Web URL.\nURL: %1").arg(currItem->annotation().Extern());
1506 ScMessageBox::information(m_view, tr("Information"), message);
1507 }
1508 else if ((currItem->annotation().ActionType() == Annotation::Action_GoToR_FileAbs) || (currItem->annotation().ActionType() == Annotation::Action_GoToR_FileRel))
1509 {
1510 QString message = tr("Link Target is external File.\nFile: %1\nPage: %2").arg(currItem->annotation().Extern()).arg(currItem->annotation().Ziel() + 1);
1511 ScMessageBox::information(m_view, tr("Information"), message);
1512 }
1513 }
1514
handleFocusOut(PageItem * currItem)1515 void CanvasMode_Normal::handleFocusOut(PageItem* currItem)
1516 {
1517 if (currItem->annotation().ActionType() == Annotation::Action_JavaScript)
1518 handleJavaAction(currItem, Annotation::Java_FocusOut);
1519 }
1520
handleFocusIn(PageItem * currItem)1521 void CanvasMode_Normal::handleFocusIn(PageItem* currItem)
1522 {
1523 if (currItem->annotation().ActionType() == Annotation::Action_JavaScript)
1524 handleJavaAction(currItem, Annotation::Java_FocusIn);
1525 }
1526
handleMouseLeave(PageItem * currItem)1527 void CanvasMode_Normal::handleMouseLeave(PageItem* currItem)
1528 {
1529 if (currItem->annotation().ActionType() == Annotation::Action_JavaScript)
1530 handleJavaAction(currItem, Annotation::Java_LeaveWidget);
1531 }
1532
handleMouseEnter(PageItem * currItem)1533 void CanvasMode_Normal::handleMouseEnter(PageItem* currItem)
1534 {
1535 if (currItem->annotation().ActionType() == Annotation::Action_JavaScript)
1536 handleJavaAction(currItem, Annotation::Java_EnterWidget);
1537 }
1538
keyPressEvent(QKeyEvent * e)1539 void CanvasMode_Normal::keyPressEvent(QKeyEvent *e)
1540 {
1541 commonkeyPressEvent_NormalNodeEdit(e);
1542 }
1543
keyReleaseEvent(QKeyEvent * e)1544 void CanvasMode_Normal::keyReleaseEvent(QKeyEvent *e)
1545 {
1546 commonkeyReleaseEvent(e);
1547 }
1548
1549 //CB-->Doc/Fix
SeleItem(QMouseEvent * m)1550 bool CanvasMode_Normal::SeleItem(QMouseEvent *m)
1551 {
1552 PageItem *previousSelectedItem = nullptr;
1553 if (m_doc->m_Selection->count() != 0)
1554 previousSelectedItem = m_doc->m_Selection->itemAt(0);
1555 m_canvas->m_viewMode.operItemSelecting = true;
1556
1557 QTransform p;
1558 PageItem *currItem;
1559 m_canvas->m_viewMode.m_MouseButtonPressed = true;
1560 FPoint mousePointDoc = m_canvas->globalToCanvas(m->globalPos());
1561 m_mouseCurrentPoint = mousePointDoc;
1562 // double grabRadius = m_doc->guidesPrefs().grabRadius / m_canvas->scale();
1563 int MxpS = static_cast<int>(mousePointDoc.x()); //m->x()/m_canvas->scale() + 0*m_doc->minCanvasCoordinate.x());
1564 int MypS = static_cast<int>(mousePointDoc.y()); //m->y()/m_canvas->scale() + 0*m_doc->minCanvasCoordinate.y());
1565 // QRectF mpo(m_mouseCurrentPoint.x()-grabRadius, m_mouseCurrentPoint.y()-grabRadius, grabRadius*2, grabRadius*2);
1566 m_doc->nodeEdit.deselect();
1567
1568 // Guides are on foreground and want to be processed first
1569 if ((m_doc->guidesPrefs().guidesShown) && (m_doc->OnPage(MxpS, MypS) != -1))
1570 {
1571 // #9002: Resize points undraggable when object is aligned to a guide
1572 // Allow item resize when guides are aligned to item while preserving
1573 // ability to drag guide when guis is in foreground and inside selection
1574 bool enableGuideGesture(false);
1575 Canvas::FrameHandle frameResizeHandle(Canvas::OUTSIDE);
1576 if (m_doc->m_Selection->count() > 0)
1577 {
1578 double gx(0.0), gy(0.0), gw(0.0), gh(0.0);
1579 m_doc->m_Selection->getVisualGroupRect(&gx, &gy, &gw, &gh);
1580 frameResizeHandle = m_canvas->frameHitTest(QPointF(mousePointDoc.x(), mousePointDoc.y()), QRectF(gx, gy, gw, gh));
1581 }
1582 else
1583 {
1584 PageItem* hoveredItem = m_canvas->itemUnderCursor(m->globalPos(), nullptr, m->modifiers());
1585 if (hoveredItem)
1586 frameResizeHandle = m_canvas->frameHitTest(QPointF(mousePointDoc.x(), mousePointDoc.y()), hoveredItem);
1587 }
1588 enableGuideGesture |= (frameResizeHandle == Canvas::OUTSIDE);
1589 enableGuideGesture |= ((m_doc->guidesPrefs().renderStackOrder.indexOf(3) > m_doc->guidesPrefs().renderStackOrder.indexOf(4)) && ((frameResizeHandle == Canvas::INSIDE) && (m->modifiers() != SELECT_BENEATH)));
1590 enableGuideGesture |= ((m_doc->guidesPrefs().renderStackOrder.indexOf(3) < m_doc->guidesPrefs().renderStackOrder.indexOf(4)) && ((frameResizeHandle == Canvas::INSIDE) && (m->modifiers() == SELECT_BENEATH)));
1591 if (enableGuideGesture)
1592 {
1593 if (!m_guideMoveGesture)
1594 {
1595 m_guideMoveGesture = new RulerGesture(m_view, RulerGesture::HORIZONTAL);
1596 connect(m_guideMoveGesture, SIGNAL(guideInfo(int,qreal)), m_ScMW->alignDistributePalette,SLOT(setGuide(int,qreal)));
1597 }
1598 if ((!m_doc->GuideLock) && m_guideMoveGesture->mouseHitsGuide(mousePointDoc))
1599 {
1600 m_view->startGesture(m_guideMoveGesture);
1601 m_guideMoveGesture->mouseMoveEvent(m);
1602 m_doc->m_Selection->connectItemToGUI();
1603 // qDebug()<<"Out Of SeleItem"<<__LINE__;
1604 return true;
1605 }
1606 // If we call startGesture now, a new guide is created each time.
1607 // ### could be a weakness to avoid calling it tho.
1608 // m_view->startGesture(guideMoveGesture);
1609 m_guideMoveGesture->mouseSelectGuide(m);
1610 }
1611 }
1612
1613 bool pageChanged(false);
1614 if (!m_doc->masterPageMode())
1615 {
1616 int pgNum = -1;
1617 int docPageCount = m_doc->Pages->count() - 1;
1618 MarginStruct pageBleeds;
1619 bool drawBleed = false;
1620 if (!m_doc->bleeds()->isNull() && m_doc->guidesPrefs().showBleed)
1621 drawBleed = true;
1622 for (int i = docPageCount; i > -1; i--)
1623 {
1624 if (drawBleed)
1625 m_doc->getBleeds(i, pageBleeds);
1626 int x = static_cast<int>(m_doc->Pages->at(i)->xOffset() - pageBleeds.left());
1627 int y = static_cast<int>(m_doc->Pages->at(i)->yOffset() - pageBleeds.top());
1628 int w = static_cast<int>(m_doc->Pages->at(i)->width() + pageBleeds.left() + pageBleeds.right());
1629 int h = static_cast<int>(m_doc->Pages->at(i)->height() + pageBleeds.bottom() + pageBleeds.top());
1630 if (QRect(x, y, w, h).contains(MxpS, MypS))
1631 {
1632 pgNum = i;
1633 if (drawBleed) // check again if its really on the correct page
1634 {
1635 for (int j = docPageCount; j > -1; j--)
1636 {
1637 int xn = static_cast<int>(m_doc->Pages->at(j)->xOffset());
1638 int yn = static_cast<int>(m_doc->Pages->at(j)->yOffset());
1639 int wn = static_cast<int>(m_doc->Pages->at(j)->width());
1640 int hn = static_cast<int>(m_doc->Pages->at(j)->height());
1641 if (QRect(xn, yn, wn, hn).contains(MxpS, MypS))
1642 {
1643 pgNum = j;
1644 break;
1645 }
1646 }
1647 }
1648 break;
1649 }
1650 }
1651 if (pgNum >= 0)
1652 {
1653 if (m_doc->currentPageNumber() != pgNum)
1654 {
1655 m_doc->setCurrentPage(m_doc->Pages->at(pgNum));
1656 m_view->m_ScMW->slotSetCurrentPage(pgNum);
1657 pageChanged = true;
1658 }
1659 }
1660 m_view->setRulerPos(m_view->contentsX(), m_view->contentsY());
1661 }
1662
1663 currItem = nullptr;
1664 if ((m->modifiers() & SELECT_BENEATH) != 0)
1665 {
1666 for (int i = 0; i < m_doc->m_Selection->count(); ++i)
1667 {
1668 if (m_canvas->frameHitTest(QPointF(mousePointDoc.x(), mousePointDoc.y()), m_doc->m_Selection->itemAt(i)) >= 0)
1669 {
1670 currItem = m_doc->m_Selection->itemAt(i);
1671 m_doc->m_Selection->removeItem(currItem);
1672 break;
1673 }
1674 }
1675 }
1676 else if ( (m->modifiers() & SELECT_MULTIPLE) == Qt::NoModifier)
1677 {
1678 m_view->deselectItems(false);
1679 }
1680
1681 currItem = m_canvas->itemUnderCursor(m->globalPos(), currItem, ((m->modifiers() & SELECT_IN_GROUP) || (m_doc->drawAsPreview && !m_doc->editOnPreview)));
1682 if (currItem)
1683 {
1684 m_doc->m_Selection->delaySignalsOn();
1685 if (m_doc->m_Selection->containsItem(currItem))
1686 {
1687 m_doc->m_Selection->removeItem(currItem);
1688 }
1689 else
1690 {
1691 //CB: If we have a selection but the user clicks with control on another item that is not below the current
1692 //then clear and select the new item
1693 if ((m->modifiers() == SELECT_BENEATH) && m_canvas->frameHitTest(QPointF(mousePointDoc.x(), mousePointDoc.y()), currItem) >= 0)
1694 m_doc->m_Selection->clear();
1695 //CB: #7186: This was prependItem, does not seem to need to be anymore with current select code
1696 if (m_doc->drawAsPreview && !m_doc->editOnPreview)
1697 m_doc->m_Selection->clear();
1698 m_doc->m_Selection->addItem(currItem);
1699 if (((m->modifiers() & SELECT_IN_GROUP) || (m_doc->drawAsPreview && !m_doc->editOnPreview)) && (!currItem->isGroup()))
1700 {
1701 currItem->isSingleSel = true;
1702 }
1703 }
1704 if (pageChanged)
1705 {
1706 m_canvas->setForcedRedraw(true);
1707 m_canvas->update();
1708 }
1709 else
1710 m_canvas->update();
1711
1712 m_doc->m_Selection->delaySignalsOff();
1713 if (m_doc->m_Selection->count() > 1)
1714 {
1715 m_doc->beginUpdate();
1716 for (int aa = 0; aa < m_doc->m_Selection->count(); ++aa)
1717 {
1718 PageItem *bb = m_doc->m_Selection->itemAt(aa);
1719 bb->update();
1720 }
1721 m_doc->endUpdate();
1722 double x, y, w, h;
1723 m_doc->m_Selection->getGroupRect(&x, &y, &w, &h);
1724 m_view->getGroupRectScreen(&x, &y, &w, &h);
1725 }
1726 if (previousSelectedItem != nullptr)
1727 {
1728 if (currItem != previousSelectedItem)
1729 {
1730 handleFocusOut(previousSelectedItem);
1731 handleFocusIn(currItem);
1732 }
1733 }
1734 else
1735 handleFocusIn(currItem);
1736 return true;
1737 }
1738
1739 // Guide selection for case where items are in front of guide
1740 // Code below looks unnecessary after fixing #15989
1741 /*if ((m_doc->guidesPrefs().guidesShown) && (m_doc->OnPage(MxpS, MypS) != -1))
1742 {
1743 bool enableGuideGesture(false);
1744 Canvas::FrameHandle frameResizeHandle(Canvas::OUTSIDE);
1745 if (m_doc->m_Selection->count() > 0)
1746 {
1747 double gx(0.0), gy(0.0), gw(0.0), gh(0.0);
1748 m_doc->m_Selection->getVisualGroupRect(&gx, &gy, &gw, &gh);
1749 frameResizeHandle = m_canvas->frameHitTest(QPointF(mousePointDoc.x(), mousePointDoc.y()), QRectF(gx, gy, gw, gh));
1750 }
1751 else
1752 {
1753 PageItem* hoveredItem = m_canvas->itemUnderCursor(m->globalPos(), nullptr, m->modifiers());
1754 if (hoveredItem)
1755 frameResizeHandle = m_canvas->frameHitTest(QPointF(mousePointDoc.x(), mousePointDoc.y()), hoveredItem);
1756 }
1757 enableGuideGesture |= (frameResizeHandle == Canvas::OUTSIDE);
1758 enableGuideGesture |= ((frameResizeHandle == Canvas::INSIDE) && (m->modifiers() == SELECT_BENEATH));
1759 if (enableGuideGesture)
1760 {
1761 if (!m_guideMoveGesture)
1762 {
1763 m_guideMoveGesture = new RulerGesture(m_view, RulerGesture::HORIZONTAL);
1764 connect(m_guideMoveGesture, SIGNAL(guideInfo(int,qreal)), m_ScMW->alignDistributePalette, SLOT(setGuide(int,qreal)));
1765 }
1766 if ( (!m_doc->GuideLock) && (m_guideMoveGesture->mouseHitsGuide(mousePointDoc)) )
1767 {
1768 m_view->startGesture(m_guideMoveGesture);
1769 m_guideMoveGesture->mouseMoveEvent(m);
1770 m_doc->m_Selection->connectItemToGUI();
1771 return true;
1772 }
1773 // If we call startGesture now, a new guide is created each time.
1774 // ### could be a weakness to avoid calling it tho.
1775 // m_view->startGesture(guideMoveGesture);
1776 m_guideMoveGesture->mouseSelectGuide(m);
1777 }
1778 }*/
1779
1780 m_doc->m_Selection->connectItemToGUI();
1781 if ( !(m->modifiers() & SELECT_MULTIPLE))
1782 {
1783 if (m_doc->m_Selection->isEmpty())
1784 {
1785 m_canvas->setForcedRedraw(true);
1786 m_canvas->update();
1787 }
1788 else
1789 m_view->deselectItems(true);
1790 }
1791 if (previousSelectedItem != nullptr)
1792 handleFocusOut(previousSelectedItem);
1793 return false;
1794 }
1795
importToPage()1796 void CanvasMode_Normal::importToPage()
1797 {
1798 QString fileName;
1799 QString allFormats = tr("All Supported Formats")+" (";
1800 QStringList formats;
1801 int fmtCode = FORMATID_FIRSTUSER;
1802 const FileFormat *fmt = LoadSavePlugin::getFormatById(fmtCode);
1803 while (fmt != nullptr)
1804 {
1805 if (fmt->load)
1806 {
1807 formats.append(fmt->filter);
1808 int an = fmt->filter.indexOf("(");
1809 int en = fmt->filter.indexOf(")");
1810 while (an != -1)
1811 {
1812 allFormats += fmt->filter.mid(an+1, en-an-1)+" ";
1813 an = fmt->filter.indexOf("(", en);
1814 en = fmt->filter.indexOf(")", an);
1815 }
1816 }
1817 fmtCode++;
1818 fmt = LoadSavePlugin::getFormatById(fmtCode);
1819 }
1820 allFormats += "*.sce *.SCE);;";
1821 formats.append("Scribus Objects (*.sce *.SCE)");
1822 formats.sort();
1823 allFormats += formats.join(";;");
1824 PrefsContext* dirs = PrefsManager::instance().prefsFile->getContext("dirs");
1825 QString wdir = dirs->get("pastefile", ".");
1826 FPoint pastePoint = m_mouseCurrentPoint;
1827 CustomFDialog dia(m_view, wdir, tr("Open"), allFormats, fdExistingFiles | fdShowImportOptions | fdDisableOk);
1828 if (dia.exec() == QDialog::Accepted)
1829 fileName = dia.selectedFile();
1830 else
1831 return;
1832 if (!fileName.isEmpty())
1833 {
1834 PrefsManager::instance().prefsFile->getContext("dirs")->set("pastefile", fileName.left(fileName.lastIndexOf("/")));
1835 m_doc->setLoading(true);
1836 QFileInfo fi(fileName);
1837 bool savedAlignGrid = m_doc->SnapGrid;
1838 bool savedAlignGuides = m_doc->SnapGuides;
1839 bool savedAlignElement = m_doc->SnapElement;
1840 m_doc->SnapElement = false;
1841 m_doc->SnapGrid = false;
1842 m_doc->SnapGuides = false;
1843 if (fi.suffix().toLower() == "sce")
1844 m_ScMW->slotElemRead(fileName, pastePoint.x(), pastePoint.y(), true, false, m_doc, m_doc->view());
1845 else
1846 {
1847 m_doc->dontResize = true;
1848 FileLoader *fileLoader = new FileLoader(fileName);
1849 int testResult = fileLoader->testFile();
1850 delete fileLoader;
1851 if ((testResult != -1) && (testResult >= FORMATID_FIRSTUSER))
1852 {
1853 const FileFormat * fmt = LoadSavePlugin::getFormatById(testResult);
1854 if (fmt)
1855 {
1856 fmt->loadFile(fileName, LoadSavePlugin::lfUseCurrentPage|LoadSavePlugin::lfInteractive|LoadSavePlugin::lfScripted);
1857 }
1858 }
1859 m_doc->dontResize = false;
1860 }
1861 for (int a = 0; a < m_doc->m_Selection->count(); ++a)
1862 {
1863 PageItem *currItem = m_doc->m_Selection->itemAt(a);
1864 currItem->m_layerID = m_doc->activeLayer();
1865 }
1866 if (m_doc->m_Selection->count() > 0)
1867 {
1868 PageItem *newItem = m_doc->m_Selection->itemAt(0);
1869 if (dia.currentOptionIndex() == 1)
1870 {
1871 if ((newItem->width() > m_doc->currentPage()->width()) || (newItem->height() > m_doc->currentPage()->height()))
1872 m_doc->rescaleGroup(newItem, qMin(qMin(m_doc->currentPage()->width() / newItem->width(), m_doc->currentPage()->height() / newItem->height()), 1.0));
1873 }
1874 else if (dia.currentOptionIndex() == 2)
1875 {
1876 m_doc->rescaleGroup(newItem, qMax(qMin(m_doc->currentPage()->width() / newItem->width(), m_doc->currentPage()->height() / newItem->height()), 1.0));
1877 }
1878 double x2, y2, w, h;
1879 m_doc->m_Selection->getGroupRect(&x2, &y2, &w, &h);
1880 m_doc->moveGroup(pastePoint.x() - x2, pastePoint.y() - y2);
1881 m_ScMW->requestUpdate(reqColorsUpdate | reqSymbolsUpdate | reqLineStylesUpdate | reqTextStylesUpdate);
1882 }
1883 m_doc->SnapGrid = savedAlignGrid;
1884 m_doc->SnapGuides = savedAlignGuides;
1885 m_doc->SnapElement = savedAlignElement;
1886 m_doc->setLoading(false);
1887 m_doc->view()->DrawNew();
1888 if (m_doc->m_Selection->count() > 0)
1889 {
1890 m_doc->m_Selection->connectItemToGUI();
1891 m_ScMW->HaveNewSel();
1892 }
1893 }
1894 }
1895
createContextMenu(PageItem * currItem,double mx,double my)1896 void CanvasMode_Normal::createContextMenu(PageItem* currItem, double mx, double my)
1897 {
1898 ContextMenu* cmen=nullptr;
1899 // qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
1900 m_view->setObjectUndoMode();
1901 m_mouseCurrentPoint.setXY(mx, my);
1902 if (currItem!=nullptr)
1903 cmen = new ContextMenu(*(m_doc->m_Selection), m_ScMW, m_doc);
1904 else
1905 cmen = new ContextMenu(m_ScMW, m_doc, mx, my);
1906 if (cmen)
1907 cmen->exec(QCursor::pos());
1908 m_view->setGlobalUndoMode();
1909 delete cmen;
1910 }
1911