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_create.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 <QWidgetAction>
30
31 #include "appmodes.h"
32 #include "canvas.h"
33 #include "fpoint.h"
34 #include "fpointarray.h"
35 #include "hyphenator.h"
36 #include "pageitem_table.h"
37 #include "pageitem_textframe.h"
38 #include "prefscontext.h"
39 #include "prefsfile.h"
40 #include "prefsmanager.h"
41 #include "scraction.h"
42 #include "scribus.h"
43 #include "scribusXml.h"
44 #include "scribusdoc.h"
45 #include "scribusview.h"
46 #include "selection.h"
47 #include "text/frect.h"
48 #include "ui/basepointwidget.h"
49 #include "ui/hruler.h"
50 #include "ui/insertTable.h"
51 #include "ui/pageselector.h"
52 #include "ui/propertiespalette.h"
53 #include "ui/scrapbookpalette.h"
54 #include "ui/vruler.h"
55 #include "undomanager.h"
56 #include "units.h"
57 #include "util.h"
58 #include "util_math.h"
59
CreateMode(ScribusView * view)60 CreateMode::CreateMode(ScribusView* view) : CanvasMode(view)
61 {
62 canvasPressCoord.setXY(-1.0, -1.0);
63 mouseGlobalCoord.setXY(-1.0, -1.0);
64 }
65
drawControls(QPainter * p)66 void CreateMode::drawControls(QPainter* p)
67 {
68 if (!inItemCreation) return;
69
70 QPointF topLeft(createObjectPos.x(), createObjectPos.y());
71 QPointF btRight(canvasCurrCoord.x(), canvasCurrCoord.y());
72 QColor drawColor = qApp->palette().color(QPalette::Active, QPalette::Highlight);
73
74 if (createObjectMode != modeDrawLine)
75 {
76 QRectF bounds = QRectF(topLeft, btRight).normalized();
77 //Lock Height to Width for Control Modifier for region drawing
78 if (modifiers==Qt::ControlModifier)
79 {
80 bounds.setHeight(bounds.width());
81 if (btRight.y()<topLeft.y())
82 bounds.moveBottom(topLeft.y());
83 if (btRight.x()<topLeft.x() && btRight.y()>topLeft.y())
84 bounds.moveTop(topLeft.y());
85 }
86 QRect localRect = m_canvas->canvasToLocal(bounds);
87 if (localRect.width() <= 0 || localRect.height() <= 0)
88 return;
89 p->setRenderHint(QPainter::Antialiasing);
90
91 p->save();
92 p->setPen(QPen(drawColor, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
93 drawColor.setAlpha(64);
94 p->setBrush(drawColor);
95 p->drawRect(localRect);
96
97 drawColor.setAlpha(255);
98 p->setBrush(Qt::NoBrush);
99 p->setPen(QPen(drawColor, 1, Qt::DashLine, Qt::FlatCap, Qt::MiterJoin));
100
101 int frameType = 0, itemType = 0;
102 getFrameItemTypes(itemType, frameType);
103 if (frameType == PageItem::Ellipse)
104 {
105 p->drawEllipse(localRect);
106 }
107 else if (createObjectMode == modeDrawArc)
108 {
109 QPainterPath path;
110 path.moveTo(localRect.width() / 2.0, localRect.height() / 2.0);
111 path.arcTo(0.0, 0.0, localRect.width(), localRect.height(), m_doc->itemToolPrefs().arcStartAngle, m_doc->itemToolPrefs().arcSweepAngle);
112 path.closeSubpath();
113 p->translate(localRect.left(), localRect.top());
114 p->drawPath(path);
115 }
116 else if (createObjectMode == modeDrawRegularPolygon)
117 {
118 QPainterPath path = regularPolygonPath(localRect.width(), localRect.height(), m_doc->itemToolPrefs().polyCorners, m_doc->itemToolPrefs().polyUseFactor, m_doc->itemToolPrefs().polyFactor, m_doc->itemToolPrefs().polyRotation, m_doc->itemToolPrefs().polyCurvature, m_doc->itemToolPrefs().polyInnerRot, m_doc->itemToolPrefs().polyOuterCurvature);
119 p->translate(localRect.left(), localRect.top());
120 p->drawPath(path);
121 }
122 else if (createObjectMode == modeDrawSpiral)
123 {
124 QPainterPath path = spiralPath(localRect.width(), localRect.height(), m_doc->itemToolPrefs().spiralStartAngle, m_doc->itemToolPrefs().spiralEndAngle, m_doc->itemToolPrefs().spiralFactor);
125 p->translate(localRect.left(), localRect.top());
126 p->drawPath(path);
127 }
128 else if ((createObjectMode == modeDrawShapes) && (createObjectSubMode > 1))
129 {
130 FPointArray poly;
131 int valCount = m_doc->ValCount;
132 double *vals = m_doc->ShapeValues;
133 for (int a = 0; a < valCount-3; a += 4)
134 {
135 if (vals[a] < 0)
136 {
137 poly.setMarker();
138 continue;
139 }
140 double x1 = localRect.width() * vals[a] / 100.0;
141 double y1 = localRect.height() * vals[a+1] / 100.0;
142 double x2 = localRect.width() * vals[a+2] / 100.0;
143 double y2 = localRect.height() * vals[a+3] / 100.0;
144 poly.addPoint(x1, y1);
145 poly.addPoint(x2, y2);
146 }
147 QPainterPath path = poly.toQPainterPath(false);
148 p->translate(localRect.left(), localRect.top());
149 p->drawPath(path);
150 }
151 p->restore();
152 }
153 else
154 {
155 QPoint p1 = m_canvas->canvasToLocal(topLeft);
156 QPoint p2 = m_canvas->canvasToLocal(btRight);
157
158 p->save();
159 p->setPen(QPen(drawColor, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
160 p->setBrush(drawColor);
161 p->drawLine(p1, p2);
162 p->restore();
163 }
164 }
165
GetItem(PageItem ** pi)166 inline bool CreateMode::GetItem(PageItem** pi)
167 {
168 *pi = m_doc->m_Selection->itemAt(0);
169 return (*pi) != nullptr;
170 }
171
172 // the following code was moved from scribusview.cpp:
173
174
enterEvent(QEvent * e)175 void CreateMode::enterEvent(QEvent *e)
176 {
177 if (!m_MouseButtonPressed)
178 {
179 setModeCursor();
180 }
181 }
182
183
leaveEvent(QEvent * e)184 void CreateMode::leaveEvent(QEvent *e)
185 {
186 }
187
188
activate(bool fromGesture)189 void CreateMode::activate(bool fromGesture)
190 {
191 // qDebug() << "CreateMode::activate" << fromGesture;
192 CanvasMode::activate(fromGesture);
193
194 PageItem* currItem;
195 if (!fromGesture || !GetItem(&currItem) || !m_createTransaction)
196 {
197 if (m_createTransaction)
198 {
199 // qDebug() << "canceling left over create Transaction";
200 m_createTransaction.cancel();
201 m_createTransaction.reset();
202 }
203 canvasPressCoord.setXY(-1.0, -1.0);
204 mouseGlobalCoord.setXY(-1.0, -1.0);
205 inItemCreation = false;
206 }
207 setModeCursor();
208 }
209
deactivate(bool forGesture)210 void CreateMode::deactivate(bool forGesture)
211 {
212 // qDebug() << "CreateMode::deactivate" << forGesture;
213 if (!forGesture)
214 {
215 if (m_createTransaction)
216 {
217 // qDebug() << "CreateMode::deactivate: canceling left over create Transaction";
218 m_createTransaction.cancel();
219 m_createTransaction.reset();
220 }
221 }
222
223 CanvasMode::deactivate(forGesture);
224 }
225
keyPressEvent(QKeyEvent * e)226 void CreateMode::keyPressEvent(QKeyEvent *e)
227 {
228 commonkeyPressEvent_Default(e);
229 }
230
keyReleaseEvent(QKeyEvent * e)231 void CreateMode::keyReleaseEvent(QKeyEvent *e)
232 {
233 commonkeyReleaseEvent(e);
234 }
235
mouseDoubleClickEvent(QMouseEvent * m)236 void CreateMode::mouseDoubleClickEvent(QMouseEvent *m)
237 {
238 m->accept();
239 m_MouseButtonPressed = false;
240 m_canvas->resetRenderMode();
241 }
242
mouseMoveEvent(QMouseEvent * m)243 void CreateMode::mouseMoveEvent(QMouseEvent *m)
244 {
245 const FPoint mousePointDoc = m_canvas->globalToCanvas(m->globalPos());
246 modifiers = m->modifiers();
247
248 double newX, newY;
249 PageItem *currItem;
250 QPainter p;
251 // QRect tx;
252 m->accept();
253 // qDebug() << "legacy mode move:" << m->x() << m->y() << m_canvas->globalToCanvas(m->globalPos()).x() << m_canvas->globalToCanvas(m->globalPos()).y();
254 // emit MousePos(m->x()/m_canvas->scale(),// + m_doc->minCanvasCoordinate.x(),
255 // m->y()/m_canvas->scale()); // + m_doc->minCanvasCoordinate.y());
256
257 if (commonMouseMove(m))
258 return;
259 if (GetItem(&currItem))
260 {
261 // newX = mousePointDoc.x(); //m_view->translateToDoc(m->x(), m->y()).x());
262 // newY = mousePointDoc.y(); //m_view->translateToDoc(m->x(), m->y()).y());
263 return;
264 }
265 if ((!m_MouseButtonPressed) || !(m->buttons() & Qt::LeftButton))
266 {
267 m_canvas->displayCorrectedXYHUD(m->globalPos(), mousePointDoc.x(), mousePointDoc.y());
268 return;
269 }
270
271 newX = mousePointDoc.x();
272 newY = mousePointDoc.y();
273 if (createObjectMode == modeDrawLine)
274 {
275 if (m_doc->SnapGrid)
276 {
277 newX = qRound(newX / m_doc->guidesPrefs().minorGridSpacing) * m_doc->guidesPrefs().minorGridSpacing;
278 newY = qRound(newY / m_doc->guidesPrefs().minorGridSpacing) * m_doc->guidesPrefs().minorGridSpacing;
279 }
280 if (m->modifiers() & Qt::ControlModifier)
281 {
282 QRectF bounds(QPointF(createObjectPos.x(), createObjectPos.y()), QPointF(newX, newY));
283 double newRot = xy2Deg(bounds.width(), bounds.height());
284 if (newRot < 0.0)
285 newRot += 360;
286 newRot = constrainAngle(newRot, m_doc->opToolPrefs().constrain);
287 double len = qMax(0.01, distance(bounds.width(), bounds.height()));
288 bounds.setSize(len * QSizeF(cosd(newRot), sind(newRot)));
289 newX = bounds.right();
290 newY = bounds.bottom();
291 }
292 }
293 //CB: #8099: Readd snapping for drag creation of lines by commenting this else..
294 //else
295 //{
296 FPoint np2 = m_doc->ApplyGridF(FPoint(newX, newY));
297 double nx = np2.x();
298 double ny = np2.y();
299 m_doc->ApplyGuides(&nx, &ny);
300 m_doc->ApplyGuides(&nx, &ny,true);
301 if (nx != np2.x())
302 xSnap = nx;
303 if (ny != np2.y())
304 ySnap = ny;
305 // #8959 : suppress qRound here as this prevent drawing line with angle constrain
306 // precisely and does not allow to stick precisely to grid or guides
307 newX = /*qRound(*/nx/*)*/;
308 newY = /*qRound(*/ny/*)*/;
309 //}
310
311 canvasCurrCoord.setXY(newX, newY);
312 m_view->HaveSelRect = true;
313
314 double wSize = canvasCurrCoord.x() - createObjectPos.x();
315 double hSize = canvasCurrCoord.y() - createObjectPos.y();
316 QRectF createObjectRect(createObjectPos.x(), createObjectPos.y(), wSize, hSize);
317 createObjectRect = createObjectRect.normalized();
318 if (createObjectMode != modeDrawLine)
319 {
320 if (modifiers == Qt::ControlModifier)
321 hSize = wSize;
322 m_canvas->displaySizeHUD(m->globalPos(), wSize, hSize, false);
323 }
324 else
325 {
326 double angle = -xy2Deg(wSize, hSize);
327 if (angle < 0.0)
328 angle = angle + 360;
329 double trueLength = sqrt(pow(createObjectRect.width(), 2) + pow(createObjectRect.height(), 2));
330 m_canvas->displaySizeHUD(m->globalPos(), trueLength, angle, true);
331 }
332
333 // Necessary for drawControls to be called
334 m_canvas->repaint();
335 }
336
mousePressEvent(QMouseEvent * m)337 void CreateMode::mousePressEvent(QMouseEvent *m)
338 {
339 const FPoint mousePointDoc = m_canvas->globalToCanvas(m->globalPos());
340 modifiers = m->modifiers();
341
342 double Rxp = 0, Ryp = 0;
343 m_MouseButtonPressed = true;
344 m_view->HaveSelRect = false;
345 m_doc->DragP = false;
346 m_doc->leaveDrag = false;
347 inItemCreation = false;
348 // oldClip = 0;
349 m->accept();
350 m_view->registerMousePress(m->globalPos());
351 // QRect mpo(m->x()-m_doc->guidesPrefs().grabRadius, m->y()-m_doc->guidesPrefs().grabRadius, m_doc->guidesPrefs().grabRadius*2, m_doc->guidesPrefs().grabRadius*2);
352 // mpo.moveBy(qRound(m_doc->minCanvasCoordinate.x() * m_canvas->scale()), qRound(m_doc->minCanvasCoordinate.y() * m_canvas->scale()));
353 canvasPressCoord = mousePointDoc;
354 createObjectMode = m_doc->appMode;
355 createObjectSubMode = m_doc->SubMode;
356 createObjectPos = m_doc->ApplyGridF(canvasPressCoord);
357
358 Rxp = m_doc->ApplyGridF(canvasPressCoord).x();
359 canvasPressCoord.setX(qRound(Rxp));
360 Ryp = m_doc->ApplyGridF(canvasPressCoord).y();
361 canvasPressCoord.setXY(qRound(Rxp), qRound(Ryp));
362
363 canvasCurrCoord = canvasPressCoord;
364 m_doc->ApplyGuides(&Rxp, &Ryp);
365 m_doc->ApplyGuides(&Rxp, &Ryp,true);
366 createObjectPos.setXY(Rxp, Ryp);
367
368 if (m->button() == Qt::MidButton)
369 {
370 m_view->MidButt = true;
371 if (m->modifiers() & Qt::ControlModifier)
372 m_view->DrawNew();
373 return;
374 }
375
376 if (m->button() == Qt::RightButton)
377 {
378 m_view->requestMode(modeNormal);
379 return;
380 }
381 if (m->button() != Qt::LeftButton)
382 return;
383 selectPage(m);
384
385 switch (m_doc->appMode)
386 {
387 case modeDrawTable2:
388 m_view->deselectItems(false);
389 break;
390 }
391
392 inItemCreation = true;
393 }
394
mouseReleaseEvent(QMouseEvent * m)395 void CreateMode::mouseReleaseEvent(QMouseEvent *m)
396 {
397 modifiers = m->modifiers();
398
399 PageItem *currItem;
400 m_MouseButtonPressed = false;
401 m_canvas->resetRenderMode();
402 m->accept();
403 // m_view->stopDragTimer();
404
405 m_createTransaction = Um::instance()->beginTransaction("creating");
406 currItem = doCreateNewObject();
407 if (m_createTransaction && currItem)
408 {
409 m_view->resetMousePressed();
410 currItem->checkChanges(true);
411 QString targetName = Um::ScratchSpace;
412 if (currItem->OwnPage > -1)
413 targetName = m_doc->Pages->at(currItem->OwnPage)->getUName();
414 m_createTransaction.commit(targetName, currItem->getUPixmap(),
415 Um::Create + " " + currItem->getUName(), "", Um::ICreate);
416 m_createTransaction.reset();
417 m_doc->changed();
418 /*currItem->update();
419 currItem->emitAllToGUI();*/
420 }
421 else if (m_createTransaction)
422 {
423 m_createTransaction.cancel();
424 m_createTransaction.reset();
425 }
426 if (!PrefsManager::instance().appPrefs.uiPrefs.stickyTools)
427 {
428 m_view->requestMode(modeNormal);
429 }
430 else
431 {
432 m_view->updateCanvas();
433 int appMode = m_doc->appMode;
434 m_view->requestMode(appMode);
435 }
436 inItemCreation = false;
437 }
438
selectPage(QMouseEvent * m)439 void CreateMode::selectPage(QMouseEvent *m)
440 {
441 m_MouseButtonPressed = true;
442 FPoint mousePointDoc = m_canvas->globalToCanvas(m->globalPos());
443 canvasPressCoord = mousePointDoc;
444 // QRect mpo(m->x()-m_doc->guidesPrefs().grabRadius, m->y()-m_doc->guidesPrefs().grabRadius, m_doc->guidesPrefs().grabRadius*2, m_doc->guidesPrefs().grabRadius*2);
445 // mpo.moveBy(qRound(Doc->minCanvasCoordinate.x() * m_canvas->scale()), qRound(m_doc->minCanvasCoordinate.y() * m_canvas->scale()));
446 m_doc->nodeEdit.deselect();
447 m_view->deselectItems(false);
448 if (!m_doc->masterPageMode())
449 {
450 int i = m_doc->OnPage(canvasPressCoord.x(), canvasPressCoord.y());
451 if (i!=-1)
452 {
453 uint docCurrPageNo=m_doc->currentPageNumber();
454 uint j=static_cast<uint>(i);
455 if (docCurrPageNo != j)
456 {
457 m_doc->setCurrentPage(m_doc->Pages->at(j));
458 m_view->m_ScMW->slotSetCurrentPage(j);
459 m_view->DrawNew();
460 }
461 }
462 /* uint docPagesCount=m_doc->Pages->count();
463 uint docCurrPageNo=m_doc->currentPageNumber();
464 for (uint i = 0; i < docPagesCount; ++i)
465 {
466 int x = static_cast<int>(m_doc->Pages->at(i)->xOffset() * m_canvas->scale());
467 int y = static_cast<int>(m_doc->Pages->at(i)->yOffset() * m_canvas->scale());
468 int w = static_cast<int>(m_doc->Pages->at(i)->width() * m_canvas->scale());
469 int h = static_cast<int>(m_doc->Pages->at(i)->height() * m_canvas->scale());
470 if (QRect(x, y, w, h).intersects(mpo))
471 {
472 if (docCurrPageNo != i)
473 {
474 m_doc->setCurrentPage(m_doc->Pages->at(i));
475 setMenTxt(i);
476 DrawNew();
477 }
478 break;
479 }
480 } */
481
482 //FIXME m_view->setRulerPos(m_view->contentsX(), m_view->contentsY());
483 }
484 }
485
SetupDrawNoResize(int nr)486 void CreateMode::SetupDrawNoResize(int nr)
487 {
488 PageItem* currItem = m_doc->Items->at(nr);
489 // currItem->setFont(Doc->toolSettings.textFont);
490 // currItem->setFontSize(Doc->toolSettings.textSize);
491 m_doc->m_Selection->delaySignalsOn();
492 m_doc->m_Selection->clear();
493 m_doc->m_Selection->addItem(currItem);
494 m_doc->m_Selection->delaySignalsOff();
495 // emit DocChanged();
496 currItem->Sizing = false /*currItem->asLine() ? false : true*/;
497 //#6456 m_view->resetMoveTimer();
498 }
499
getFrameItemTypes(int & itemType,int & frameType)500 void CreateMode::getFrameItemTypes(int& itemType, int& frameType)
501 {
502 itemType = (int) PageItem::Polygon;
503 frameType = (int) PageItem::Rectangle;
504 switch (createObjectMode)
505 {
506 case modeDrawShapes:
507 switch (createObjectSubMode)
508 {
509 case 0:
510 itemType = (int) PageItem::Polygon;
511 frameType = (int) PageItem::Rectangle;
512 break;
513 case 1:
514 itemType = (int) PageItem::Polygon;
515 frameType = (int) PageItem::Ellipse;
516 break;
517 default:
518 itemType = (int) PageItem::Polygon;
519 frameType = (int) PageItem::Unspecified;
520 break;
521 }
522 break;
523 case modeDrawLine:
524 itemType = (int) PageItem::Line;
525 frameType = (int) PageItem::Unspecified;
526 break;
527 case modeDrawLatex:
528 itemType = (int) PageItem::LatexFrame;
529 frameType = (int) PageItem::Unspecified;
530 break;
531 case modeDrawImage:
532 itemType = (int) PageItem::ImageFrame;
533 frameType = (int) PageItem::Unspecified;
534 break;
535 case modeDrawText:
536 itemType = (int) PageItem::TextFrame;
537 frameType = (int) PageItem::Unspecified;
538 break;
539 case modeDrawRegularPolygon:
540 itemType = (int) PageItem::RegularPolygon;
541 frameType = (int) PageItem::Unspecified;
542 break;
543 case modeDrawArc:
544 itemType = (int) PageItem::Arc;
545 frameType = (int) PageItem::Unspecified;
546 break;
547 case modeDrawSpiral:
548 itemType = (int) PageItem::Spiral;
549 frameType = (int) PageItem::Unspecified;
550 break;
551 case modeInsertPDFButton:
552 case modeInsertPDFRadioButton:
553 case modeInsertPDFTextfield:
554 case modeInsertPDFCheckbox:
555 case modeInsertPDFCombobox:
556 case modeInsertPDFListbox:
557 case modeInsertPDFTextAnnotation:
558 case modeInsertPDFLinkAnnotation:
559 itemType = (int) PageItem::TextFrame;
560 frameType = (int) PageItem::Unspecified;
561 break;
562 case modeDrawTable2:
563 itemType = (int) PageItem::Table;
564 frameType = (int) PageItem::Unspecified;
565 break;
566 case modeInsertPDF3DAnnotation:
567 itemType = (int) PageItem::OSGFrame;
568 frameType = (int) PageItem::Unspecified;
569 break;
570 }
571 }
572
doCreateNewObject()573 PageItem* CreateMode::doCreateNewObject()
574 {
575 int z = -1;
576 double rot, len;
577
578 double wSize = canvasCurrCoord.x() - createObjectPos.x();
579 double hSize = canvasCurrCoord.y() - createObjectPos.y();
580 bool skipOneClick = (modifiers == Qt::ShiftModifier);
581 if ((createObjectMode == modeDrawLine) || (createObjectMode == modeDrawTable2) ||
582 (createObjectMode == modeInsertPDFButton) || (createObjectMode == modeInsertPDFTextfield) ||
583 (createObjectMode == modeInsertPDFTextfield) || (createObjectMode == modeInsertPDFCheckbox) ||
584 (createObjectMode == modeInsertPDFCombobox) || (createObjectMode == modeInsertPDFListbox) ||
585 (createObjectMode == modeInsertPDFTextAnnotation) || (createObjectMode == modeInsertPDFLinkAnnotation) ||
586 (createObjectMode == modeInsertPDF3DAnnotation) || (createObjectMode == modeInsertPDFRadioButton))
587 {
588 skipOneClick = false;
589 }
590 if (!skipOneClick)
591 {
592 if ((!m_view->moveTimerElapsed()) || ((fabs(wSize) < 2.0) && (fabs(hSize) < 2.0)))
593 {
594 if (!doOneClick(createObjectPos, canvasCurrCoord))
595 {
596 return nullptr;
597 }
598 }
599 }
600
601 wSize = canvasCurrCoord.x() - createObjectPos.x();
602 hSize = canvasCurrCoord.y() - createObjectPos.y();
603 //Lock Height to Width for Control Modifier for final item creation
604 if (createObjectMode != modeDrawLine)
605 {
606 if (modifiers == Qt::ControlModifier)
607 hSize = wSize;
608 }
609
610 PageItem *newObject = nullptr, *currItem = nullptr;
611 // FIXME for modeDrawLine
612 QRectF createObjectRect(createObjectPos.x(), createObjectPos.y(), wSize, hSize);
613 if (createObjectMode != modeDrawLine)
614 {
615 createObjectRect = createObjectRect.normalized();
616 if (modifiers==Qt::ControlModifier)
617 {
618 //bottom right and upper left are ok
619 //upper right
620 if (canvasCurrCoord.y() < createObjectPos.y() && createObjectPos.x()<canvasCurrCoord.x())
621 createObjectRect.translate(0.0, -createObjectRect.height());
622 //bottom left
623 if (canvasCurrCoord.x()<createObjectPos.x() && canvasCurrCoord.y()>createObjectPos.y())
624 createObjectRect.translate(0.0, createObjectRect.height());
625 }
626 }
627 double Rxp = createObjectRect.x();
628 double Ryp = createObjectRect.y();
629 double Rxpd = createObjectRect.width();
630 double Rypd = createObjectRect.height();
631
632 switch (createObjectMode)
633 {
634 case modeDrawShapes:
635 switch (createObjectSubMode)
636 {
637 case 0:
638 if (modifiers == Qt::ShiftModifier)
639 z = m_doc->itemAddArea(PageItem::Polygon, PageItem::Rectangle, Rxp, Ryp, m_doc->itemToolPrefs().shapeLineWidth, m_doc->itemToolPrefs().shapeFillColor, m_doc->itemToolPrefs().shapeLineColor);
640 else
641 z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, Rxp, Ryp, Rxpd, Rypd, m_doc->itemToolPrefs().shapeLineWidth, m_doc->itemToolPrefs().shapeFillColor, m_doc->itemToolPrefs().shapeLineColor);
642 m_doc->Items->at(z)->FrameType = 0;
643 break;
644 case 1:
645 if (modifiers == Qt::ShiftModifier)
646 z = m_doc->itemAddArea(PageItem::Polygon, PageItem::Ellipse, Rxp, Ryp, m_doc->itemToolPrefs().shapeLineWidth, m_doc->itemToolPrefs().shapeFillColor, m_doc->itemToolPrefs().shapeLineColor);
647 else
648 z = m_doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, Rxp, Ryp, Rxpd, Rypd, m_doc->itemToolPrefs().shapeLineWidth, m_doc->itemToolPrefs().shapeFillColor, m_doc->itemToolPrefs().shapeLineColor);
649 m_doc->Items->at(z)->FrameType = 1;
650 break;
651 default:
652 if (modifiers == Qt::ShiftModifier)
653 z = m_doc->itemAddArea(PageItem::Polygon, PageItem::Unspecified, Rxp, Ryp, m_doc->itemToolPrefs().shapeLineWidth, m_doc->itemToolPrefs().shapeFillColor, m_doc->itemToolPrefs().shapeLineColor);
654 else
655 z = m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, Rxp, Ryp, Rxpd, Rypd, m_doc->itemToolPrefs().shapeLineWidth, m_doc->itemToolPrefs().shapeFillColor, m_doc->itemToolPrefs().shapeLineColor);
656 m_doc->Items->at(z)->SetFrameShape(m_doc->ValCount, m_doc->ShapeValues);
657 m_doc->adjustItemSize(m_doc->Items->at(z));
658 m_doc->setRedrawBounding(m_doc->Items->at(z));
659 m_doc->Items->at(z)->FrameType = createObjectSubMode + 2;
660 break;
661 }
662 break;
663 case modeDrawLine:
664 Rxp = createObjectPos.x();
665 Ryp = createObjectPos.y();
666 m_doc->ApplyGuides(&Rxp, &Ryp);
667 m_doc->ApplyGuides(&Rxp, &Ryp,true);
668 rot = xy2Deg(Rxpd, Rypd);
669 if (rot < 0.0)
670 rot += 360;
671 len = qMax(0.01, distance(Rxpd, Rypd));
672 z = m_doc->itemAdd(PageItem::Line, PageItem::Unspecified, Rxp, Ryp, len, 1, m_doc->itemToolPrefs().lineWidth, CommonStrings::None, m_doc->itemToolPrefs().lineColor);
673 m_doc->Items->at(z)->setRotation(rot);
674 m_doc->Items->at(z)->setRedrawBounding();
675 break;
676 case modeDrawLatex:
677 if (modifiers == Qt::ShiftModifier)
678 z = m_doc->itemAddArea(PageItem::LatexFrame, PageItem::Unspecified, Rxp, Ryp, 1, m_doc->itemToolPrefs().imageFillColor, m_doc->itemToolPrefs().imageStrokeColor);
679 else
680 z = m_doc->itemAdd(PageItem::LatexFrame, PageItem::Unspecified, Rxp, Ryp, Rxpd, Rypd, m_doc->itemToolPrefs().shapeLineWidth, m_doc->itemToolPrefs().imageFillColor, m_doc->itemToolPrefs().imageStrokeColor);
681 break;
682 case modeDrawImage:
683 if (modifiers == Qt::ShiftModifier)
684 z = m_doc->itemAddArea(PageItem::ImageFrame, PageItem::Unspecified, Rxp, Ryp, 1, m_doc->itemToolPrefs().imageFillColor, m_doc->itemToolPrefs().imageStrokeColor);
685 else
686 z = m_doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, Rxp, Ryp, Rxpd, Rypd, m_doc->itemToolPrefs().shapeLineWidth, m_doc->itemToolPrefs().imageFillColor, m_doc->itemToolPrefs().imageStrokeColor);
687 break;
688 case modeDrawText:
689 if (modifiers == Qt::ShiftModifier)
690 z = m_doc->itemAddArea(PageItem::TextFrame, PageItem::Unspecified, Rxp, Ryp, m_doc->itemToolPrefs().shapeLineWidth, CommonStrings::None, m_doc->itemToolPrefs().textFont);
691 else
692 z = m_doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, Rxp, Ryp, Rxpd, Rypd, m_doc->itemToolPrefs().shapeLineWidth, CommonStrings::None, m_doc->itemToolPrefs().textFont);
693 break;
694 case modeDrawRegularPolygon:
695 if (modifiers == Qt::ShiftModifier)
696 z = m_doc->itemAddArea(PageItem::RegularPolygon, PageItem::Unspecified, Rxp, Ryp, m_doc->itemToolPrefs().shapeLineWidth, m_doc->itemToolPrefs().shapeFillColor, m_doc->itemToolPrefs().lineColor);
697 else
698 z = m_doc->itemAdd(PageItem::RegularPolygon, PageItem::Unspecified, Rxp, Ryp, Rxpd, Rypd, m_doc->itemToolPrefs().shapeLineWidth, m_doc->itemToolPrefs().shapeFillColor, m_doc->itemToolPrefs().lineColor);
699 break;
700 case modeDrawArc:
701 if (modifiers == Qt::ShiftModifier)
702 z = m_doc->itemAddArea(PageItem::Arc, PageItem::Unspecified, Rxp, Ryp, m_doc->itemToolPrefs().shapeLineWidth, m_doc->itemToolPrefs().shapeFillColor, m_doc->itemToolPrefs().lineColor);
703 else
704 z = m_doc->itemAdd(PageItem::Arc, PageItem::Unspecified, Rxp, Ryp, Rxpd, Rypd, m_doc->itemToolPrefs().shapeLineWidth, m_doc->itemToolPrefs().shapeFillColor, m_doc->itemToolPrefs().lineColor);
705 m_doc->setRedrawBounding(m_doc->Items->at(z));
706 break;
707 case modeDrawSpiral:
708 if (modifiers == Qt::ShiftModifier)
709 z = m_doc->itemAddArea(PageItem::Spiral, PageItem::Unspecified, Rxp, Ryp, m_doc->itemToolPrefs().shapeLineWidth, CommonStrings::None, m_doc->itemToolPrefs().lineColor);
710 else
711 z = m_doc->itemAdd(PageItem::Spiral, PageItem::Unspecified, Rxp, Ryp, Rxpd, Rypd, m_doc->itemToolPrefs().shapeLineWidth, CommonStrings::None, m_doc->itemToolPrefs().lineColor);
712 m_doc->adjustItemSize(m_doc->Items->at(z));
713 m_doc->setRedrawBounding(m_doc->Items->at(z));
714 break;
715 case modeInsertPDFButton:
716 case modeInsertPDFRadioButton:
717 case modeInsertPDFTextfield:
718 case modeInsertPDFCheckbox:
719 case modeInsertPDFCombobox:
720 case modeInsertPDFListbox:
721 case modeInsertPDFTextAnnotation:
722 case modeInsertPDFLinkAnnotation:
723 z = m_doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, Rxp, Ryp, Rxpd, Rypd, m_doc->itemToolPrefs().shapeLineWidth, CommonStrings::None, m_doc->itemToolPrefs().textColor);
724 currItem = m_doc->Items->at(z);
725 currItem->setIsAnnotation(true);
726 currItem->AutoName = false;
727 switch (m_doc->appMode)
728 {
729 case modeInsertPDFButton:
730 currItem->annotation().setType(Annotation::Button);
731 currItem->annotation().setFlag(Annotation::Flag_PushButton);
732 currItem->setItemName( CommonStrings::itemName_PushButton + QString("%1").arg(m_doc->TotalItems));
733 break;
734 case modeInsertPDFRadioButton:
735 currItem->annotation().setType(Annotation::RadioButton);
736 currItem->annotation().setFlag(Annotation::Flag_Radio | Annotation::Flag_NoToggleToOff);
737 currItem->setItemName( CommonStrings::itemName_RadioButton + QString("%1").arg(m_doc->TotalItems));
738 break;
739 case modeInsertPDFTextfield:
740 currItem->annotation().setType(Annotation::Textfield);
741 currItem->setItemName( CommonStrings::itemName_TextField + QString("%1").arg(m_doc->TotalItems));
742 break;
743 case modeInsertPDFCheckbox:
744 currItem->annotation().setType(Annotation::Checkbox);
745 currItem->setItemName( CommonStrings::itemName_CheckBox + QString("%1").arg(m_doc->TotalItems));
746 break;
747 case modeInsertPDFCombobox:
748 currItem->annotation().setType(Annotation::Combobox);
749 currItem->annotation().setFlag(Annotation::Flag_Combo);
750 currItem->setItemName( CommonStrings::itemName_ComboBox + QString("%1").arg(m_doc->TotalItems));
751 break;
752 case modeInsertPDFListbox:
753 currItem->annotation().setType(Annotation::Listbox);
754 currItem->setItemName( CommonStrings::itemName_ListBox + QString("%1").arg(m_doc->TotalItems));
755 break;
756 case modeInsertPDFTextAnnotation:
757 currItem->annotation().setType(Annotation::Text);
758 currItem->setItemName( CommonStrings::itemName_TextAnnotation + QString("%1").arg(m_doc->TotalItems));
759 break;
760 case modeInsertPDFLinkAnnotation:
761 currItem->annotation().setType(Annotation::Link);
762 currItem->annotation().setZiel(m_doc->currentPage()->pageNr());
763 currItem->annotation().setAction("0 0");
764 currItem->setItemName( CommonStrings::itemName_LinkAnnotation + QString("%1").arg(m_doc->TotalItems));
765 currItem->setTextFlowMode(PageItem::TextFlowDisabled);
766 break;
767 }
768 break;
769 case modeDrawTable2:
770 // TODO: Figure out what these conditions actually do.
771 if ((m_doc->m_Selection->isEmpty()) && (m_view->HaveSelRect) && (!m_view->MidButt))
772 {
773 m_view->HaveSelRect = false;
774 // Calculate table rectangle.
775 FRect tableRect = adjustedRect(canvasPressCoord, canvasCurrCoord);
776 if (tableRect.width() < 6 || tableRect.height() < 6)
777 {
778 // Ignore tiny tables.
779 m_view->requestMode(submodePaintingDone);
780 break;
781 }
782 // Show table insert dialog.
783 // qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
784 InsertTable *dia = new InsertTable(m_view, static_cast<int>(tableRect.height()/6), static_cast<int>(tableRect.width()/6));
785 if (!dia->exec())
786 {
787 m_view->requestMode(submodePaintingDone);
788 delete dia;
789 dia = nullptr;
790 break;
791 }
792 int numRows = dia->Rows->value();
793 int numColumns = dia->Cols->value();
794 delete dia;
795 dia = nullptr;
796 // Add the table item.
797 // TODO: This should be done in an undo transaction.
798 m_doc->dontResize = true;
799 z = m_doc->itemAdd(PageItem::Table, PageItem::Unspecified,
800 tableRect.x(),
801 tableRect.y(),
802 tableRect.width(),
803 tableRect.height(),
804 0, // Unused.
805 CommonStrings::None, // Unused.
806 CommonStrings::None); // Unused.
807 PageItem_Table *table = m_doc->Items->at(z)->asTable();
808 table->insertRows(0, numRows - 1);
809 table->insertColumns(0, numColumns - 1);
810 table->adjustTableToFrame();
811 table->adjustFrameToTable();
812 m_doc->dontResize = false;
813 m_doc->setRedrawBounding(table);
814 }
815 break;
816 case modeInsertPDF3DAnnotation:
817 if (modifiers == Qt::ShiftModifier)
818 {
819 z = m_doc->itemAddArea(PageItem::OSGFrame, PageItem::Unspecified, Rxp, Ryp, 1, m_doc->itemToolPrefs().imageFillColor, m_doc->itemToolPrefs().imageStrokeColor);
820 }
821 else
822 {
823 z = m_doc->itemAdd(PageItem::OSGFrame, PageItem::Unspecified, Rxp, Ryp, Rxpd, Rypd, m_doc->itemToolPrefs().shapeLineWidth, m_doc->itemToolPrefs().imageFillColor, m_doc->itemToolPrefs().imageStrokeColor);
824 }
825 currItem = m_doc->Items->at(z);
826 currItem->setIsAnnotation(true);
827 currItem->AutoName = false;
828 currItem->annotation().setType(Annotation::Annot3D);
829 currItem->setItemName( tr("3DAnnot") + QString("%1").arg(m_doc->TotalItems));
830 break;
831 }
832 if (z >= 0)
833 {
834 SetupDrawNoResize(z);
835 newObject = m_doc->Items->at(z);
836 newObject->ContourLine = newObject->PoLine.copy();
837 m_doc->setRedrawBounding(newObject);
838 }
839 return newObject;
840 }
841
doOneClick(FPoint & startPoint,FPoint & endPoint)842 bool CreateMode::doOneClick(FPoint& startPoint, FPoint& endPoint)
843 {
844 bool doCreate = false;
845 double xSize, ySize;
846 int originPoint = 0;
847
848 if (QApplication::keyboardModifiers() & Qt::ControlModifier)
849 return true;
850
851 PrefsContext* sizes = PrefsManager::instance().prefsFile->getContext("ObjectSize");
852 bool doRemember = sizes->getBool("Remember", true);
853
854 int lmode = (createObjectMode == modeDrawLine) ? 1 : 0;
855 if (lmode == 0)
856 {
857 xSize = sizes->getDouble("defWidth", 100.0);
858 ySize = sizes->getDouble("defHeight", 100.0);
859 originPoint = sizes->getInt("Origin", 0);
860 }
861 else
862 {
863 xSize = sizes->getDouble("defLength", 100.0);
864 ySize = sizes->getDouble("defAngle", 0.0);
865 originPoint = sizes->getInt("OriginL", 0);
866 }
867
868 if (lmode == 0)
869 {
870 if (doRemember)
871 {
872 sizes->set("defWidth", xSize);
873 sizes->set("defHeight", ySize);
874 sizes->set("Origin", originPoint);
875 }
876 endPoint.setXY(startPoint.x() + xSize, startPoint.y() + ySize);
877 switch (originPoint)
878 {
879 case 0:
880 break;
881 case 1:
882 startPoint.setX(startPoint.x() - xSize);
883 endPoint.setX(endPoint.x() - xSize);
884 break;
885 case 2:
886 startPoint.setXY(startPoint.x() - xSize / 2.0, startPoint.y() - ySize / 2.0);
887 endPoint.setXY(endPoint.x() - xSize / 2.0, endPoint.y() - ySize / 2.0);
888 break;
889 case 3:
890 startPoint.setY(startPoint.y() - ySize);
891 endPoint.setY(endPoint.y() - ySize);
892 break;
893 case 4:
894 startPoint.setXY(startPoint.x() - xSize, startPoint.y() - ySize);
895 endPoint.setXY(endPoint.x() - xSize, endPoint.y() - ySize);
896 break;
897 }
898 }
899 else
900 {
901 FPoint oldStart = startPoint;
902 if (doRemember)
903 {
904 sizes->set("defLength", xSize);
905 sizes->set("defAngle", ySize);
906 sizes->set("OriginL", originPoint);
907 }
908 double angle = -ySize * M_PI / 180.0;
909 switch (originPoint)
910 {
911 case 0:
912 endPoint = FPoint(startPoint.x() + xSize * cos(angle), startPoint.y() + xSize * sin(angle));
913 break;
914 case 1:
915 startPoint = FPoint(oldStart.x() - xSize * cos(angle), oldStart.y() - xSize * sin(angle));
916 endPoint = oldStart;
917 break;
918 case 2:
919 startPoint = FPoint(oldStart.x() - xSize / 2.0 * cos(angle), oldStart.y() - xSize / 2.0 * sin(angle));
920 endPoint = FPoint(oldStart.x() + xSize / 2.0 * cos(angle), oldStart.y() + xSize / 2.0 * sin(angle));
921 break;
922 }
923 }
924 sizes->set("Remember", doRemember);
925 doCreate = true;
926
927 //delete dia;
928 return doCreate;
929 }
930
adjustedRect(FPoint & firstPoint,FPoint & secondPoint)931 FRect CreateMode::adjustedRect(FPoint &firstPoint, FPoint &secondPoint)
932 {
933 // Lock to grid.
934 FPoint first = m_doc->ApplyGridF(firstPoint);
935 FPoint second = m_doc->ApplyGridF(secondPoint);
936
937 // Lock to guides and items.
938 double firstX = first.x();
939 double firstY = first.y();
940 m_doc->ApplyGuides(&firstX, &firstY);
941 m_doc->ApplyGuides(&firstX, &firstY,true);
942
943 double secondX = second.x();
944 double secondY = second.y();
945 m_doc->ApplyGuides(&secondX, &secondY);
946 m_doc->ApplyGuides(&secondX, &secondY,true);
947
948 // Return normalized rectangle.
949 FRect rect(firstX, firstY, secondX - firstX, secondY - firstY);
950
951 return rect.normalize();
952 }
953
954 // void CreateMode::setResizeCursor(int how)
955 // {
956 // switch (how)
957 // {
958 // case 1:
959 // case 2:
960 // qApp->changeOverrideCursor(QCursor(Qt::SizeFDiagCursor));
961 // break;
962 // case 3:
963 // case 4:
964 // qApp->changeOverrideCursor(QCursor(Qt::SizeBDiagCursor));
965 // break;
966 // case 5:
967 // case 8:
968 // qApp->changeOverrideCursor(QCursor(Qt::SizeVerCursor));
969 // break;
970 // case 6:
971 // case 7:
972 // qApp->changeOverrideCursor(QCursor(Qt::SizeHorCursor));
973 // break;
974 // default:
975 // qApp->changeOverrideCursor(QCursor(Qt::SizeAllCursor));
976 // break;
977 // }
978 // }
979
980