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 						  hruler.cpp  -  description
9 							 -------------------
10 	begin                : Tue Apr 10 2001
11 	copyright            : (C) 2001 by Franz Schmid
12 	email                : Franz.Schmid@altmuehlnet.de
13  ***************************************************************************/
14 
15 /***************************************************************************
16  *                                                                         *
17  *   This program is free software; you can redistribute it and/or modify  *
18  *   it under the terms of the GNU General Public License as published by  *
19  *   the Free Software Foundation; either version 2 of the License, or     *
20  *   (at your option) any later version.                                   *
21  *                                                                         *
22  ***************************************************************************/
23 
24 #include <cmath>
25 
26 #include <QCursor>
27 #include <QMouseEvent>
28 // #include <QDebug>
29 #include <QPaintEvent>
30 #include <QPainter>
31 #include <QPixmap>
32 #include <QPixmap>
33 #include <QPolygon>
34 #include <QRect>
35 
36 #include "canvasgesture_rulermove.h"
37 #include "hruler.h"
38 #include "scpage.h"
39 
40 #include "scribusdoc.h"
41 #include "scribusview.h"
42 #include "selection.h"
43 #include "units.h"
44 
45 #include "iconmanager.h"
46 
47 #ifdef Q_OS_MAC
48 #define topline 1
49 #else
50 #define topline 3
51 #endif
52 #define bottomline 15
53 #define rulerheight (bottomline - topline)
54 #define midline (topline + rulerheight/2)
55 #define tabline 7
56 
Hruler(ScribusView * pa,ScribusDoc * doc)57 Hruler::Hruler(ScribusView *pa, ScribusDoc *doc) : QWidget(pa),
58 	m_doc(doc),
59 	m_view(pa)
60 {
61 	setBackgroundRole(QPalette::Window);
62 	//setAutoFillBackground(true);
63 	setMouseTracking(true);
64 	rulerGesture = new RulerGesture(m_view, RulerGesture::HORIZONTAL);
65 	unitChange();
66 }
67 
textBase() const68 double Hruler::textBase() const
69 {
70 	return m_itemPos + m_lineCorr + m_distLeft;
71 }
72 
textWidth() const73 double Hruler::textWidth() const
74 {
75 	return m_itemEndPos - m_itemPos - 2 * m_lineCorr - m_distLeft - m_distRight;
76 }
77 
78 
textPosToCanvas(double x) const79 double Hruler::textPosToCanvas(double x) const
80 {
81 	return x + textBase();
82 }
83 
textPosToLocal(double x) const84 int Hruler::textPosToLocal(double x) const
85 {
86 	return qRound(textPosToCanvas(x) * m_scaling)- m_view->contentsX();
87 }
88 
localToTextPos(int x) const89 double Hruler::localToTextPos(int x) const
90 {
91 	return ((x + m_view->contentsX()) / m_scaling - textBase());
92 }
93 
shift(double pos)94 void Hruler::shift(double pos)
95 {
96 	m_offset = pos;
97 }
98 
shiftRel(double dist)99 void Hruler::shiftRel(double dist)
100 {
101 	m_offset += dist;
102 }
103 
104 
findRulerHandle(QPoint mp,double grabRadius)105 int Hruler::findRulerHandle(QPoint mp, double grabRadius)
106 {
107 	int mx = mp.x();
108 	QRect fpo;
109 
110 	int result = rc_none;
111 
112 	int pos = textPosToLocal(0);
113 	if (pos - 1 < (mx + grabRadius) && pos - 1 > (mx - grabRadius))
114 		result = rc_leftFrameDist;
115 
116 	pos = textPosToLocal(textWidth());
117 	if (pos + 1 < (mx + grabRadius) && pos + 1 > (mx - grabRadius))
118 		result = rc_rightFrameDist;
119 
120 	double colWidth = (textWidth() - m_colGap * (m_cols - 1)) / m_cols;
121 
122 	m_currCol = 0;
123 	for (int currCol = 0; currCol < m_cols; ++currCol)
124 	{
125 		pos = textPosToLocal((colWidth + m_colGap) * currCol);
126 		fpo = QRect(pos, topline, static_cast<int>(colWidth * m_scaling), rulerheight);
127 		if (fpo.contains(mp))
128 		{
129 			m_currCol = currCol + 1;
130 			break;
131 		}
132 	}
133 	if (m_currCol == 0)
134 	{
135 		m_currCol = 1;
136 		return result;
137 	}
138 
139 	pos = textPosToLocal(m_firstIndent + m_leftMargin + (colWidth + m_colGap) * (m_currCol - 1));
140 	fpo = QRect(pos - 1, topline, grabRadius + 1, rulerheight/2);
141 	if (fpo.contains(mp))
142 	{
143 		return rc_indentFirst;
144 	}
145 	pos = textPosToLocal(m_leftMargin + (colWidth + m_colGap) * (m_currCol - 1));
146 	fpo = QRect(pos - 1, midline, grabRadius + 1, rulerheight/2);
147 	if (fpo.contains(mp))
148 	{
149 		return rc_leftMargin;
150 	}
151 	pos = textPosToLocal(m_rightMargin + (colWidth + m_colGap) * (m_currCol- 1));
152 	fpo = QRect(pos - grabRadius, midline, grabRadius, rulerheight / 2);
153 	if (fpo.contains(mp))
154 	{
155 		return rc_rightMargin;
156 	}
157 	if (m_tabValues.count() != 0)
158 	{
159 		for (int yg = 0; yg < m_tabValues.count(); yg++)
160 		{
161 			pos = textPosToLocal(m_tabValues[yg].tabPosition + (colWidth + m_colGap) * (m_currCol - 1));
162 			fpo = QRect(pos - grabRadius, tabline, 2 * grabRadius, rulerheight / 2 + 2);
163 			if (fpo.contains(mp))
164 			{
165 				result = rc_tab;
166 				m_currTab = yg;
167 				break;
168 			}
169 		}
170 	}
171 	return result;
172 }
173 
174 
mousePressEvent(QMouseEvent * m)175 void Hruler::mousePressEvent(QMouseEvent *m)
176 {
177 	if (m_doc->isLoading())
178 		return;
179 	m_mousePressed = true;
180 	m_mouseX = m->x();
181 	if (m_textEditMode)
182 	{
183 		m_rulerCode = findRulerHandle(m->pos(), m_doc->guidesPrefs().grabRadius);
184 
185 		if ((m_rulerCode == rc_none) && (m_currCol != 0) && (m->button() == Qt::LeftButton))
186 		{
187 			ParagraphStyle::TabRecord tb;
188 			tb.tabPosition = localToTextPos(m->x());
189 			tb.tabType = 0;
190 			tb.tabFillChar = m_doc->itemToolPrefs().textTabFillChar[0];
191 			m_tabValues.prepend(tb);
192 			m_currTab = 0;
193 			m_rulerCode = rc_tab;
194 			updateTabList();
195 			qApp->setOverrideCursor(QCursor(Qt::SizeHorCursor));
196 			emit DocChanged(false);
197 		}
198 	}
199 	else
200 	{
201 		if (m_doc->guidesPrefs().guidesShown)
202 		{
203 			qApp->setOverrideCursor(QCursor(Qt::SplitVCursor));
204 			m_view->startGesture(rulerGesture);
205 			m_view->registerMousePress(m->globalPos());
206 		}
207 	}
208 }
209 
mouseReleaseEvent(QMouseEvent * m)210 void Hruler::mouseReleaseEvent(QMouseEvent *m)
211 {
212 	if (m_doc->isLoading())
213 	{
214 		m_mousePressed = false;
215 		return;
216 	}
217 	if (m_textEditMode && m_currItem)
218 	{
219 		if ((m->y() < height()) && (m->y() > 0))
220 		{
221 			bool mustApplyStyle = false;
222 			ParagraphStyle paraStyle;
223 			double colWidth = (textWidth() - m_colGap * (m_cols - 1)) / m_cols;
224 			switch (m_rulerCode)
225 			{
226 				case rc_leftFrameDist:
227 					m_doc->m_Selection->itemAt(0)->setTextToFrameDistLeft(m_distLeft);
228 					emit DocChanged(false);
229 					break;
230 				case rc_rightFrameDist:
231 					m_doc->m_Selection->itemAt(0)->setTextToFrameDistRight(m_distRight);
232 					emit DocChanged(false);
233 					break;
234 				case rc_indentFirst:
235 					paraStyle.setFirstIndent(m_firstIndent);
236 					mustApplyStyle = true;
237 					emit DocChanged(false);
238 					break;
239 				case rc_leftMargin:
240 					paraStyle.setLeftMargin(m_leftMargin);
241 					paraStyle.setFirstIndent(m_firstIndent);
242 					mustApplyStyle = true;
243 					emit DocChanged(false);
244 					break;
245 				case rc_rightMargin:
246 					paraStyle.setRightMargin(colWidth - m_rightMargin);
247 					mustApplyStyle = true;
248 					emit DocChanged(false);
249 					break;
250 				case rc_tab:
251 					if (m->button() == Qt::RightButton)
252 					{
253 						m_tabValues[m_currTab].tabType += 1;
254 						if (m_tabValues[m_currTab].tabType > 4)
255 							m_tabValues[m_currTab].tabType = 0;
256 					}
257 					paraStyle.setTabValues(m_tabValues);
258 					mustApplyStyle = true;
259 					emit DocChanged(false);
260 					break;
261 				default:
262 					break;
263 			}
264 			if (mustApplyStyle)
265 			{
266 				Selection tempSelection(this, false);
267 				tempSelection.addItem(m_currItem);
268 				m_doc->itemSelection_ApplyParagraphStyle(paraStyle, &tempSelection);
269 			}
270 			else
271 			{
272 				m_currItem->update();
273 			}
274 		}
275 		else
276 		{
277 			if (m_rulerCode == rc_tab)
278 			{
279 				m_tabValues.removeAt(m_currTab);
280 				m_currTab = 0;
281 				ParagraphStyle paraStyle;
282 				paraStyle.setTabValues(m_tabValues);
283 				Selection tempSelection(this, false);
284 				tempSelection.addItem(m_currItem);
285 				m_doc->itemSelection_ApplyParagraphStyle(paraStyle, &tempSelection);
286 				emit DocChanged(false);
287 			}
288 		}
289 		m_rulerCode = rc_none;
290 		m_view->DrawNew();
291 		m_doc->m_Selection->itemAt(0)->emitAllToGUI();
292 	}
293 	else if (m_mousePressed && rulerGesture->isActive())
294 		rulerGesture->mouseReleaseEvent(m);
295 	m_mousePressed = false;
296 	qApp->restoreOverrideCursor();
297 }
298 
enterEvent(QEvent * e)299 void Hruler::enterEvent(QEvent *e)
300 {
301 	if (m_textEditMode)
302 		qApp->changeOverrideCursor(IconManager::instance().loadCursor("tab.png", 3));
303 }
304 
leaveEvent(QEvent * m)305 void Hruler::leaveEvent(QEvent *m)
306 {
307 	emit MarkerMoved(0, -1);
308 	qApp->restoreOverrideCursor();
309 	m_view->m_canvasMode->setModeCursor();
310 }
311 
mouseMoveEvent(QMouseEvent * m)312 void Hruler::mouseMoveEvent(QMouseEvent *m)
313 {
314 	if (m_doc->isLoading())
315 		return;
316 	if (m_textEditMode)
317 	{
318 		double colWidth = (textWidth() - m_colGap * (m_cols - 1)) / m_cols;
319 		int ColEnd, ColStart;
320 		double oldInd;
321 		if (m_rulerCode == rc_leftFrameDist || m_rulerCode == rc_rightFrameDist)
322 		{
323 			ColStart = 0; //textPosToLocal(0);
324 			ColEnd   = width(); //textPosToLocal(textWidth());
325 		}
326 		else
327 		{
328 			ColStart = textPosToLocal((colWidth + m_colGap) * (m_currCol- 1));
329 			ColEnd   = textPosToLocal((colWidth + m_colGap) * (m_currCol- 1) + colWidth);
330 		}
331 		if ((m_mousePressed) && (m->y() < height()) && (m->y() > 0) && (m->x() > ColStart - m_doc->guidesPrefs().grabRadius) && (m->x() < ColEnd + m_doc->guidesPrefs().grabRadius))
332 		{
333 			qApp->changeOverrideCursor(QCursor(Qt::SizeHorCursor));
334 			double toplimit = textWidth() + m_distRight - (m_colGap * (m_cols - 1)) - 1;
335 			double toplimit2 = textWidth() + m_distLeft - (m_colGap * (m_cols - 1)) - 1;
336 			switch (m_rulerCode)
337 			{
338 				case rc_leftFrameDist:
339 					m_distLeft -= (m_mouseX - m->x()) / m_scaling;
340 					if (m_distLeft < 0)
341 						m_distLeft = 0;
342 					if (m_distLeft > toplimit2)
343 						m_distLeft = toplimit2;
344 					emit MarkerMoved(m_currItem->xPos(), textBase() - m_currItem->xPos());
345 					repaint();
346 					break;
347 				case rc_rightFrameDist:
348 					m_distRight += (m_mouseX - m->x()) / m_scaling;
349 					if (m_distRight < 0)
350 						m_distRight = 0;
351 					if (m_distRight > toplimit)
352 						m_distRight = toplimit;
353 					emit MarkerMoved(textBase(), toplimit - m_distRight);
354 					repaint();
355 					break;
356 				case rc_indentFirst:
357 					m_firstIndent -= (m_mouseX - m->x()) / m_scaling;
358 					if (m_firstIndent + m_leftMargin < 0)
359 						m_firstIndent = -m_leftMargin;
360 					if (m_firstIndent + m_leftMargin > colWidth)
361 						m_firstIndent  = colWidth - m_leftMargin;
362 					emit MarkerMoved(textBase(), m_firstIndent + m_leftMargin);
363 					repaint();
364 					break;
365 				case rc_leftMargin:
366 					oldInd = m_leftMargin + m_firstIndent;
367 					m_leftMargin -= (m_mouseX - m->x()) / m_scaling;
368 					if (m_leftMargin < 0)
369 						m_leftMargin = 0;
370 					if (m_leftMargin > colWidth - 1)
371 						m_leftMargin  = colWidth - 1;
372 					m_firstIndent = oldInd - m_leftMargin;
373 					emit MarkerMoved(textBase(), m_leftMargin);
374 					repaint();
375 					break;
376 				case rc_rightMargin:
377 					m_rightMargin -= (m_mouseX - m->x()) / m_scaling;
378 					if (m_rightMargin < 0)
379 						m_rightMargin = 0;
380 					if (m_rightMargin > colWidth - 1)
381 						m_rightMargin  = colWidth - 1;
382 					emit MarkerMoved(textBase(), m_rightMargin);
383 					repaint();
384 					break;
385 				case rc_tab:
386 					m_tabValues[m_currTab].tabPosition -= (m_mouseX - m->x()) / m_scaling;
387 					if (m_tabValues[m_currTab].tabPosition < 0)
388 						m_tabValues[m_currTab].tabPosition = 0;
389 					if (m_tabValues[m_currTab].tabPosition > colWidth - 1)
390 						m_tabValues[m_currTab].tabPosition  = colWidth - 1;
391 					emit MarkerMoved(textBase(), m_tabValues[m_currTab].tabPosition);
392 					updateTabList();
393 					repaint();
394 					break;
395 				default:
396 					break;
397 			}
398 			m_mouseX = m->x();
399 			return;
400 		}
401 		if ((!m_mousePressed) && (m->y() < height()) && (m->y() > 0) && (m->x() > ColStart - 2*m_doc->guidesPrefs().grabRadius) && (m->x() < ColEnd + 2*m_doc->guidesPrefs().grabRadius))
402 		{
403 			setCursor(IconManager::instance().loadCursor("tab.png", 3));
404 			switch (findRulerHandle(m->pos(), m_doc->guidesPrefs().grabRadius))
405 			{
406 				case rc_leftFrameDist:
407 					setCursor(QCursor(Qt::SplitHCursor));
408 					break;
409 				case rc_rightFrameDist:
410 					setCursor(QCursor(Qt::SplitHCursor));
411 					break;
412 				case rc_indentFirst:
413 					setCursor(QCursor(Qt::SizeHorCursor));
414 					break;
415 				case rc_leftMargin:
416 					setCursor(QCursor(Qt::SizeHorCursor));
417 					break;
418 				case rc_rightMargin:
419 					setCursor(QCursor(Qt::SizeHorCursor));
420 					break;
421 				case rc_tab:
422 					setCursor(QCursor(Qt::SizeHorCursor));
423 					break;
424 			}
425 			draw(m->x());
426 			double marker = localToTextPos(m->x());
427 			emit MarkerMoved(textBase(), marker);
428 			return;
429 		}
430 		if ((m_mousePressed) && (m_rulerCode == rc_tab) && ((m->y() > height()) || (m->y() < 0)))
431 		{
432 			setCursor(IconManager::instance().loadCursor("DelPoint.png", 1, 1));
433 			return;
434 		}
435 		setCursor(QCursor(Qt::ArrowCursor));
436 	}
437 	else
438 	{
439 		if (m_mousePressed && rulerGesture->isActive())
440 			rulerGesture->mouseMoveEvent(m);
441 		else
442 			setCursor(QCursor(Qt::ArrowCursor));
443 	}
444 }
445 
paintEvent(QPaintEvent * e)446 void Hruler::paintEvent(QPaintEvent *e)
447 {
448 	if (m_doc->isLoading())
449 		return;
450 	double sc = m_view->scale();
451 	m_scaling = sc;
452 	QFont ff = font();
453 	ff.setPointSize(6);
454 	setFont(ff);
455 	QPainter p;
456 	p.begin(this);
457 	p.setClipRect(e->rect());
458 	p.setFont(font());
459 
460 	drawMarks(p);
461 
462 	if (m_textEditMode)
463 	{
464 		int rectX1 = textPosToLocal(m_distLeft);
465 		int rectX2 = textPosToLocal(m_itemEndPos - m_itemPos - m_distRight);
466 		const QPalette& palette = this->palette();
467 		const QColor& textColor = palette.color(QPalette::Text);
468 		p.fillRect(QRect(QPoint(rectX1, 1), QPoint(rectX2, 15)), palette.window());
469 		p.drawLine(rectX1, 16, rectX2, 16);
470 		p.save();
471 		p.setRenderHints(QPainter::Antialiasing, true);
472 		if (m_reverse)
473 		{
474 			p.translate( textPosToLocal(0), 0);
475 			p.scale(-1, 1);
476 			p.translate( textPosToLocal(m_distLeft) - textPosToLocal(m_itemEndPos - m_itemPos - m_distRight), 0);
477 			p.translate(-textPosToLocal(0), 0);
478 		}
479 		for (int currCol = 0; currCol < m_cols; ++currCol)
480 		{
481 			double colWidth = (textWidth() - m_colGap * (m_cols - 1)) / m_cols;
482 			double pos = (colWidth + m_colGap) * currCol;
483 			double endPos = pos + colWidth;
484 			drawTextMarks(pos, endPos, p);
485 
486 			p.setPen(QPen(Qt::blue, 2, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
487 			int xPos = textPosToLocal(pos);
488 			p.drawLine(xPos, topline, xPos, bottomline);
489 			if (currCol == 0)
490 			{
491 				p.drawLine(xPos, 15, (xPos + 4), 15);
492 				p.drawLine(xPos, topline, (xPos + 4), topline);
493 			}
494 
495 			p.setPen(QPen(Qt::blue, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
496 
497 			xPos = textPosToLocal(pos + m_firstIndent + m_leftMargin);
498 			QPolygon cr;
499 			cr.setPoints(3, xPos, midline, xPos + 3, topline, xPos - 3, topline);
500 			p.drawPolygon(cr);
501 
502 			xPos = textPosToLocal(pos + m_leftMargin);
503 			QPolygon cr2;
504 			cr2.setPoints(3, xPos, midline, xPos + 3, bottomline, xPos - 3, bottomline);
505 			p.drawPolygon(cr2);
506 
507 			xPos = textPosToLocal(pos + m_rightMargin);
508 			QPolygon cr3;
509 			cr3.setPoints(3, xPos, topline, xPos, bottomline, xPos - 3, midline);
510 			p.drawPolygon(cr3);
511 
512 			if (m_tabValues.count() != 0)
513 			{
514 				p.setPen(QPen(textColor, 2, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
515 				for (int yg = 0; yg < signed(m_tabValues.count()); yg++)
516 				{
517 					xPos = textPosToLocal(pos + m_tabValues[yg].tabPosition);
518 					if (pos + m_tabValues[yg].tabPosition < endPos)
519 					{
520 						switch (static_cast<int>(m_tabValues[yg].tabType))
521 						{
522 							case 0:
523 								if (m_reverse)
524 								{
525 									p.save();
526 									p.translate(pos + m_tabValues[yg].tabPosition, 0);
527 									p.scale(-1, 1);
528 									p.drawLine(0, tabline, 0, bottomline);
529 									p.drawLine(0, bottomline, 8, bottomline);
530 									p.restore();
531 								}
532 								else
533 								{
534 									p.drawLine(xPos, tabline, xPos, bottomline);
535 									p.drawLine(xPos, bottomline, xPos+8, bottomline);
536 								}
537 								break;
538 							case 1:
539 								if (m_reverse)
540 								{
541 									p.save();
542 									p.translate(pos + m_tabValues[yg].tabPosition, 0);
543 									p.scale(-1, 1);
544 									p.drawLine(0, tabline, 0, bottomline);
545 									p.drawLine(0, bottomline, -8, bottomline);
546 									p.restore();
547 								}
548 								else
549 								{
550 									p.drawLine(xPos, tabline, xPos, bottomline);
551 									p.drawLine(xPos, bottomline, xPos-8, bottomline);
552 								}
553 								break;
554 							case 2:
555 							case 3:
556 								p.drawLine(xPos, tabline, xPos, bottomline);
557 								p.drawLine(xPos - 4, bottomline, xPos + 4, bottomline);
558 								p.drawLine(xPos + 3, bottomline - 3, xPos + 2, bottomline - 3);
559 								break;
560 							case 4:
561 								p.drawLine(xPos, tabline, xPos, bottomline);
562 								p.drawLine(xPos - 4, bottomline, xPos + 4, bottomline);
563 								break;
564 							default:
565 								break;
566 						}
567 					}
568 				}
569 			}
570 
571 			p.setPen(QPen(Qt::blue, 2, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
572 			xPos = textPosToLocal(endPos);
573 			p.drawLine(xPos, topline, xPos, bottomline);
574 			if (currCol == m_cols - 1)
575 			{
576 				p.drawLine(xPos, bottomline, xPos - 4 , bottomline);
577 				p.drawLine(xPos, topline, xPos - 4, topline);
578 			}
579 		}
580 		p.restore();
581 	}
582 	if (m_drawMark && !m_mousePressed)
583 	{
584 		drawMarker(p);
585 	}
586 	p.end();
587 }
588 
589 
drawMarker(QPainter & p)590 void Hruler::drawMarker(QPainter& p)
591 {
592 	// draw slim marker
593 	QPolygon cr;
594 	p.resetTransform();
595 	p.translate(-m_view->contentsX(), 0);
596 	p.setPen(Qt::red);
597 	p.setBrush(Qt::red);
598 	cr.setPoints(5,  m_whereToDraw, 5, m_whereToDraw, 16, m_whereToDraw, 5, m_whereToDraw + 2, 0, m_whereToDraw - 2, 0);
599 	p.drawPolygon(cr);
600 }
601 
602 
drawMarks(QPainter & p)603 void Hruler::drawMarks(QPainter& p)
604 {
605 	const QPalette& palette = this->palette();
606 	const QColor& textColor = palette.color(QPalette::Text);
607 	p.setBrush(textColor);
608 	p.setPen(textColor);
609 
610 	double sc = m_scaling;
611 	double cc = width() / sc;
612 	double firstMark = ceil(m_offset / m_iter) * m_iter - m_offset;
613 	while (firstMark < cc)
614 	{
615 		p.drawLine(qRound(firstMark * sc), 13, qRound(firstMark * sc), 16);
616 		firstMark += m_iter;
617 	}
618 	firstMark = ceil(m_offset / m_iter2) * m_iter2 - m_offset;
619 	int markC = static_cast<int>(ceil(m_offset / m_iter2));
620 
621 	QString tx;
622 	double xl, frac;
623 	while (firstMark < cc)
624 	{
625 		p.drawLine(qRound(firstMark * sc), topline + 5, qRound(firstMark * sc), 16);
626 		switch (m_doc->unitIndex())
627 		{
628 			case SC_MM:
629 				tx = QString::number(markC * m_iter2 / (m_iter2 / 100) / m_cor);
630 				break;
631 			case SC_IN:
632 				xl = (markC * m_iter2 / m_iter2) / m_cor;
633 				tx = QString::number(static_cast<int>(xl));
634 				frac = fabs(xl - static_cast<int>(xl));
635 				if ((static_cast<int>(xl) == 0) && (frac > 0.1))
636 					tx = "";
637 				if ((frac > 0.24) && (frac < 0.26))
638 					tx += QChar(0xBC);
639 				if ((frac > 0.49) && (frac < 0.51))
640 					tx += QChar(0xBD);
641 				if ((frac > 0.74) && (frac < 0.76))
642 					tx += QChar(0xBE);
643 				break;
644 			case SC_P:
645 			case SC_C:
646 				tx = QString::number(markC * m_iter2 / (m_iter2 / 5) / m_cor);
647 				break;
648 			case SC_CM:
649 				tx = QString::number(markC * m_iter2 / m_iter2 / m_cor);
650 				break;
651 			default:
652 				tx = QString::number(markC * m_iter2);
653 				break;
654 		}
655 		drawNumber(tx, qRound(firstMark * sc) + 2, 9, p);
656 		//p.drawText(qRound(firstMark * sc) + 2, 9, tx);
657 		firstMark += m_iter2;
658 		markC++;
659 	}
660 }
661 
drawTextMarks(double pos,double endPos,QPainter & p)662 void Hruler::drawTextMarks(double pos, double endPos, QPainter& p)
663 {
664 	double xl;
665 
666 	p.setPen(QPen(Qt::blue, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
667 	p.setBrush(Qt::blue);
668 	for (xl = pos; xl < endPos; xl += m_iter)
669 	{
670 		int xli = textPosToLocal(xl);
671 		p.drawLine(xli, 10, xli, 16);
672 	}
673 	for (xl = pos; xl < endPos; xl += m_iter2)
674 	{
675 		int xli = textPosToLocal(xl);
676 		p.drawLine(xli, topline, xli, 16);
677 		switch (m_doc->unitIndex())
678 		{
679 			case SC_IN:
680 				{
681 					QString tx = "";
682 					int num1 = static_cast<int>((xl - pos) / m_iter2 / m_cor);
683 					if (num1 != 0)
684 						tx = QString::number(num1);
685 					double frac = (xl / m_iter2 / m_cor) - num1;
686 					if ((frac > 0.24) && (frac < 0.26))
687 						tx += QChar(0xBC);
688 					if ((frac > 0.49) && (frac < 0.51))
689 						tx += QChar(0xBD);
690 					if ((frac > 0.74) && (frac < 0.76))
691 						tx += QChar(0xBE);
692 					if (m_reverse)
693 					{
694 						p.save();
695 						p.translate(xli - 2, 0);
696 						p.scale(-1, 1);
697 						drawNumber(tx, 0, 17, p);
698 						//p.drawText(0, 17, tx);
699 						p.restore();
700 					}
701 					else
702 						drawNumber(tx, xli + 2, 9, p);
703 					//p.drawText(qRound((xl + 2 / sc) * sc), 9, tx);
704 					break;
705 				}
706 			case SC_P:
707 				if (m_reverse)
708 				{
709 					p.save();
710 					p.translate(xli - 2, 0);
711 					p.scale(-1, 1);
712 					drawNumber(QString::number((xl - pos) / m_iter / m_cor), 0, 17, p);
713 					//p.drawText(0, 17, QString::number((xl - pos) / m_iter / m_cor));
714 					p.restore();
715 				}
716 				else
717 					drawNumber(QString::number((xl - pos) / m_iter / m_cor), xli + 2, 9, p);
718 				//p.drawText(qRound((xl + 2 / sc) * sc), 9, QString::number((xl - pos) / m_iter / m_cor));
719 				break;
720 			case SC_CM:
721 				if (m_reverse)
722 				{
723 					p.save();
724 					p.translate(xli - 2, 0);
725 					p.scale(-1, 1);
726 					drawNumber(QString::number((xl - pos) / m_iter / 10 / m_cor), 0, 9, p);
727 					//p.drawText(0, 9, QString::number((xl - pos) / m_iter / 10 / m_cor));
728 					p.restore();
729 				}
730 				else
731 					drawNumber(QString::number((xl - pos) / m_iter / 10 / m_cor), xli + 2, 9, p);
732 				//p.drawText(qRound((xl + 2 / sc) * sc), 9, QString::number((xl - pos) / m_iter / 10 / m_cor));
733 				break;
734 			case SC_C:
735 				if (m_reverse)
736 				{
737 					p.save();
738 					p.translate(xli - 2, 0);
739 					p.scale(-1, 1);
740 					drawNumber(QString::number((xl - pos) / m_iter  / m_cor), 0, 9, p);
741 					//p.drawText(0, 9, QString::number((xl - pos) / m_iter  / m_cor));
742 					p.restore();
743 				}
744 				else
745 					drawNumber(QString::number((xl - pos) / m_iter  / m_cor), xli + 2, 9, p);
746 				//p.drawText(qRound((xl + 2 / sc) * sc), 9, QString::number((xl - pos) / m_iter  / m_cor));
747 				break;
748 			default:
749 				if (m_reverse)
750 				{
751 					p.save();
752 					p.translate(xli - 2, 0);
753 					p.scale(-1, 1);
754 					drawNumber(QString::number((xl - pos) / m_iter * 10 / m_cor), 0, 9, p);
755 					//p.drawText(0, 9, QString::number((xl - pos) / m_iter * 10 / m_cor));
756 					p.restore();
757 				}
758 				else
759 					drawNumber(QString::number((xl - pos) / m_iter * 10 / m_cor), xli + 2, 9, p);
760 				//p.drawText(qRound((xl + 2 / sc) * sc), 9, QString::number((xl - pos) / m_iter * 10 / m_cor));
761 				break;
762 		}
763 	}
764 }
765 
drawNumber(const QString & txt,int x,int y0,QPainter & p)766 void Hruler::drawNumber(const QString& txt, int x, int y0, QPainter & p)
767 {
768 	const int y = y0 - 3 + topline;
769 	p.drawText(x,y,txt);
770 }
771 
ruleSpacing()772 double Hruler::ruleSpacing()
773 {
774 	return m_iter;
775 }
776 
draw(int where)777 void Hruler::draw(int where)
778 {
779 	// erase old marker
780 	int currentCoor = where - m_view->contentsX();
781 	m_whereToDraw = where;
782 	m_drawMark = true;
783 	repaint(m_oldMark - 3, 0, 7, 17);
784 	//	m_drawMark = false;
785 	m_oldMark = currentCoor;
786 }
787 
setItem(PageItem * item)788 void Hruler::setItem(PageItem * item)
789 {
790 	m_currItem = item;
791 	QTransform mm = m_currItem->getTransform();
792 	QPointF itPos = mm.map(QPointF(0, m_currItem->yPos()));
793 	m_itemScale = mm.m11();
794 	m_itemPos = itPos.x();
795 	m_itemEndPos = m_itemPos + item->width() * m_itemScale;
796 	/*if (m_doc->guidesPrefs().rulerMode)
797 	{
798 		m_itemPos -= m_doc->currentPage()->xOffset();
799 		m_itemEndPos -= m_doc->currentPage()->xOffset();
800 	}*/
801 
802 	if ((item->lineColor() != CommonStrings::None) || (!item->strokePattern().isEmpty()))
803 		m_lineCorr = item->lineWidth() / 2.0;
804 	else
805 		m_lineCorr = 0;
806 	m_colGap = item->m_columnGap;
807 	m_cols = item->m_columns;
808 	m_distLeft  = item->textToFrameDistLeft();
809 	m_distRight = item->textToFrameDistRight();
810 
811 	const ParagraphStyle& currentStyle = item->currentStyle();
812 	m_firstIndent = currentStyle.firstIndent();
813 	m_leftMargin = currentStyle.leftMargin();
814 	double columnWidth = (item->width() - (item->columnGap() * (item->columns() - 1))
815 						  - item->textToFrameDistLeft() - item->textToFrameDistLeft()
816 						  - 2*m_lineCorr) / item->columns();
817 	m_rightMargin = columnWidth - currentStyle.rightMargin();
818 	m_reverse = item->imageFlippedH();
819 	m_textEditMode = true;
820 	m_tabValues = currentStyle.tabValues();
821 }
822 
updateTabList()823 void Hruler::updateTabList()
824 {
825 	ParagraphStyle::TabRecord tb;
826 	tb.tabPosition = m_tabValues[m_currTab].tabPosition;
827 	tb.tabType = m_tabValues[m_currTab].tabType;
828 	tb.tabFillChar =  m_tabValues[m_currTab].tabFillChar;
829 	int tab_n = m_tabValues.count();
830 	int tab_i = tab_n;
831 	m_tabValues.removeAt(m_currTab);
832 	for (int i = m_tabValues.count() - 1; i > -1; --i)
833 	{
834 		if (tb.tabPosition < m_tabValues[i].tabPosition)
835 			tab_i = i;
836 	}
837 	m_currTab = tab_i;
838 	if (tab_n == tab_i)
839 	{
840 		m_tabValues.append(tb);
841 		m_currTab = m_tabValues.count() - 1;
842 	}
843 	else
844 	{
845 		m_tabValues.insert(m_currTab, tb);
846 	}
847 }
848 
unitChange()849 void Hruler::unitChange()
850 {
851 	double sc = m_view->scale();
852 	m_cor = 1;
853 	int docUnitIndex=m_doc->unitIndex();
854 	switch (docUnitIndex)
855 	{
856 		case SC_PT:
857 			if (sc > 1 && sc <= 4)
858 				m_cor = 2;
859 			if (sc > 4)
860 				m_cor = 10;
861 			if (sc < 0.3)
862 			{
863 				m_iter = unitRulerGetIter1FromIndex(docUnitIndex) * 3;
864 				m_iter2 = unitRulerGetIter2FromIndex(docUnitIndex) * 3;
865 			}
866 			else if (sc < 0.5)
867 			{
868 				m_iter = unitRulerGetIter1FromIndex(docUnitIndex) * 2;
869 				m_iter2 = unitRulerGetIter2FromIndex(docUnitIndex) * 2;
870 			}
871 			else
872 			{
873 				m_iter = unitRulerGetIter1FromIndex(docUnitIndex) / m_cor;
874 				m_iter2 = unitRulerGetIter2FromIndex(docUnitIndex) / m_cor;
875 			}
876 			break;
877 		case SC_MM:
878 			if (sc > 1)
879 				m_cor = 10;
880 			m_iter = unitRulerGetIter1FromIndex(docUnitIndex) / m_cor;
881 			m_iter2 = unitRulerGetIter2FromIndex(docUnitIndex) / m_cor;
882 			break;
883 		case SC_IN:
884 			m_iter = unitRulerGetIter1FromIndex(docUnitIndex);
885 			m_iter2 = unitRulerGetIter2FromIndex(docUnitIndex);
886 			if (sc > 1 && sc <= 4)
887 			{
888 				m_cor = 2;
889 				m_iter /= m_cor;
890 				m_iter2 /= m_cor;
891 			}
892 			if (sc > 4)
893 			{
894 				m_cor = 4;
895 				m_iter /= m_cor;
896 				m_iter2 /= m_cor;
897 			}
898 			if (sc < 0.25)
899 			{
900 				m_cor = 0.5;
901 				m_iter = 72.0 * 16.0;
902 				m_iter2 = 72.0 * 2.0;
903 			}
904 			break;
905 		case SC_P:
906 			m_iter = unitRulerGetIter1FromIndex(docUnitIndex);
907 			m_iter2 = unitRulerGetIter2FromIndex(docUnitIndex);
908 			if (sc >= 1 && sc <= 4)
909 			{
910 				m_cor = 1;
911 				m_iter = 12.0;
912 				m_iter2 = 60.0;
913 			}
914 			if (sc > 4)
915 			{
916 				m_cor = 2;
917 				m_iter = 6.0;
918 				m_iter2 = 12.0;
919 			}
920 			if (sc < 0.3)
921 			{
922 				m_cor = 0.25;
923 				m_iter = 12.0 * 4;
924 				m_iter2 = 60.0 * 4;
925 			}
926 			else
927 				if (sc < 1)
928 				{
929 					m_cor = 1;
930 					m_iter = 12.0;
931 					m_iter2 = 60.0;
932 				}
933 			break;
934 		case SC_CM:
935 			if (sc > 1 && sc <= 4)
936 				m_cor = 1;
937 			if (sc > 4)
938 				m_cor = 10;
939 			if (sc < 0.6)
940 			{
941 				m_cor=0.1;
942 				m_iter = 720.0 / 25.4;
943 				m_iter2 = 7200.0 / 25.4;
944 			}
945 			else
946 			{
947 				m_iter = unitRulerGetIter1FromIndex(docUnitIndex) / m_cor;
948 				m_iter2 = unitRulerGetIter2FromIndex(docUnitIndex) / m_cor;
949 			}
950 			break;
951 		case SC_C:
952 			m_iter = unitRulerGetIter1FromIndex(docUnitIndex);
953 			m_iter2 = unitRulerGetIter2FromIndex(docUnitIndex);
954 			if (sc >= 1 && sc <= 4)
955 			{
956 				m_cor = 1;
957 				m_iter = 72.0 / 25.4 * 4.512;
958 				m_iter2 = 72.0 / 25.4 * 4.512 * 5.0;
959 			}
960 			if (sc > 4)
961 			{
962 				m_cor = 2;
963 				m_iter = 72.0 / 25.4 * 4.512 / 2.0;
964 				m_iter2 = 72.0 / 25.4 * 4.512;
965 			}
966 			if (sc < 0.3)
967 			{
968 				m_cor = 0.1;
969 				m_iter = 72.0 / 25.4 * 4.512 * 10;
970 				m_iter2 = 72.0 / 25.4 * 4.512 * 5.0 * 10;
971 			}
972 			else
973 				if (sc < 1)
974 				{
975 					m_cor = 1;
976 					m_iter = 72.0 / 25.4 * 4.512;
977 					m_iter2 = 72.0 / 25.4 * 4.512 * 5.0;
978 				}
979 			break;
980 		default:
981 			if (sc > 1 && sc <= 4)
982 				m_cor = 2;
983 			if (sc > 4)
984 				m_cor = 10;
985 			m_iter = unitRulerGetIter1FromIndex(0) / m_cor;
986 			m_iter2 = unitRulerGetIter2FromIndex(0) / m_cor;
987 			break;
988 	}
989 }
990