Merge lp:~marcelstimberg/ubuntu/precise/scribus/merge-1.4-from-debian into lp:ubuntu/precise/scribus

Proposed by Marcel Stimberg
Status: Merged
Merged at revision: 30
Proposed branch: lp:~marcelstimberg/ubuntu/precise/scribus/merge-1.4-from-debian
Merge into: lp:ubuntu/precise/scribus
Diff against target: 525900 lines
To merge this branch: bzr merge lp:~marcelstimberg/ubuntu/precise/scribus/merge-1.4-from-debian
Reviewer Review Type Date Requested Status
Felix Geyer (community) Disapprove
Ubuntu branches Pending
Review via email: mp+92623@code.launchpad.net

Description of the change

This merges the updated debian version that now ships the final 1.4 release instead of the release candidate.

To post a comment you must log in.
Revision history for this message
Felix Geyer (debfx) wrote :

1.4.0.dfsg+r17300-1 has been merged already.

review: Disapprove

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== removed directory '.pc/0001-qreal-double-fixes.patch'
=== removed directory '.pc/0001-qreal-double-fixes.patch/scribus'
=== removed directory '.pc/0001-qreal-double-fixes.patch/scribus/fonts'
=== removed file '.pc/0001-qreal-double-fixes.patch/scribus/fonts/scfontmetrics.cpp'
--- .pc/0001-qreal-double-fixes.patch/scribus/fonts/scfontmetrics.cpp 2011-09-11 22:10:03 +0000
+++ .pc/0001-qreal-double-fixes.patch/scribus/fonts/scfontmetrics.cpp 1970-01-01 00:00:00 +0000
@@ -1,623 +0,0 @@
1/*
2For general Scribus (>=1.3.2) copyright and licensing information please refer
3to the COPYING file provided with the program. Following this notice may exist
4a copyright and/or license notice that predates the release of Scribus 1.3.2
5for which a new license (GPL+exception) is in place.
6*/
7#include <QColor>
8#include <QDebug>
9#include <QMap>
10#include <QMatrix>
11#include <QPainter>
12#include <QPixmap>
13#include <QRegExp>
14#include <QStringList>
15
16#include "fpoint.h"
17#include "fpointarray.h"
18#include "page.h"
19#include "scfontmetrics.h"
20#include "scfonts.h"
21#include "scpainter.h"
22#include "scribusdoc.h"
23#include "style.h"
24#include "util_math.h"
25
26
27// this code contains a set of font related functions
28// that don't really fit within ScFonts.
29
30static FPoint firstP;
31static bool FirstM;
32static QMap<FT_ULong, QString> adobeGlyphNames;
33static const char* table[] = {
34//#include "glyphnames.txt.q"
35 NULL};
36
37// private functions
38static void readAdobeGlyphNames();
39static QString adobeGlyphName(FT_ULong charcode);
40static int traceMoveto( FT_Vector *to, FPointArray *composite );
41static int traceLineto( FT_Vector *to, FPointArray *composite );
42static int traceQuadraticBezier( FT_Vector *control, FT_Vector *to, FPointArray *composite );
43static int traceCubicBezier( FT_Vector *p, FT_Vector *q, FT_Vector *to, FPointArray *composite );
44
45FT_Outline_Funcs OutlineMethods =
46 {
47 (FT_Outline_MoveTo_Func) traceMoveto,
48 (FT_Outline_LineTo_Func) traceLineto,
49 (FT_Outline_ConicTo_Func) traceQuadraticBezier,
50 (FT_Outline_CubicTo_Func) traceCubicBezier,
51 0,
52 0
53 };
54
55
56const qreal FTSCALE = 64.0;
57
58
59int setBestEncoding(FT_Face face)
60{
61 FT_ULong charcode;
62 FT_UInt gindex;
63 bool foundEncoding = false;
64 int countUniCode = 0;
65 int chmapUniCode = -1;
66 int chmapCustom = -1;
67 int retVal = 0;
68 //FT_CharMap defaultEncoding = face->charmap;
69// int defaultchmap=face->charmap ? FT_Get_Charmap_Index(face->charmap) : 0;
70// Since the above function is only available in FreeType 2.1.10 its replaced by
71// the following line, assuming that the default charmap has the index 0
72 int defaultchmap = 0;
73 for(int u = 0; u < face->num_charmaps; u++)
74 {
75 if (face->charmaps[u]->encoding == FT_ENCODING_UNICODE )
76 {
77 FT_Set_Charmap(face, face->charmaps[u]);
78 chmapUniCode = u;
79 gindex = 0;
80 charcode = FT_Get_First_Char( face, &gindex );
81 while ( gindex != 0 )
82 {
83 countUniCode++;
84 charcode = FT_Get_Next_Char( face, charcode, &gindex );
85 }
86// qDebug() << "found Unicode enc for" << face->family_name << face->style_name << "as map" << chmapUniCode << "with" << countUniCode << "glyphs";
87
88 }
89 if (face->charmaps[u]->encoding == FT_ENCODING_ADOBE_CUSTOM)
90 {
91 chmapCustom = u;
92 foundEncoding = true;
93 retVal = 1;
94// qDebug() << "found Custom enc for" << face->family_name << face->style_name;
95 break;
96 }
97 else if (face->charmaps[u]->encoding == FT_ENCODING_MS_SYMBOL)
98 {
99// qDebug() << "found Symbol enc for" << face->family_name << face->style_name;
100
101 chmapCustom = u;
102 foundEncoding = true;
103 retVal = 2;
104 break;
105 }
106 }
107 int mapToSet=defaultchmap;
108 if (chmapUniCode >= 0 && countUniCode >= face->num_glyphs-1)
109 {
110// qDebug() << "using Unicode enc for" << face->family_name << face->style_name;
111
112 mapToSet=chmapUniCode;
113 //FT_Set_Charmap(face, face->charmaps[chmapUniCode]);
114 retVal = 0;
115 }
116 else
117 if (foundEncoding)
118 {
119// qDebug() << "using special enc for" << face->family_name << face->style_name;
120 mapToSet=chmapCustom;
121 //FT_Set_Charmap(face, face->charmaps[chmapCustom]);
122 }
123 else
124 {
125// qDebug() << "using default enc for" << face->family_name << face->style_name;
126 mapToSet=defaultchmap;
127 //FT_Set_Charmap(face, defaultEncoding);
128 retVal = 0;
129 }
130
131 //Fixes #2199, missing glyphs from 1.2.1->1.2.2
132 //If the currently wanted character map is not already Unicode...
133 //if (FT_Get_Charmap_Index(face->charmap)!=chmapUniCode)
134 if (mapToSet!=chmapUniCode)
135 {
136 //Change map so we can count the chars in it
137 FT_Set_Charmap(face, face->charmaps[mapToSet]);
138 //Count the characters in the current map
139 gindex = 0;
140 int countCurrMap=0;
141 charcode = FT_Get_First_Char( face, &gindex );
142 while ( gindex != 0 )
143 {
144 countCurrMap++;
145 charcode = FT_Get_Next_Char( face, charcode, &gindex );
146 }
147 //If the last Unicode map we found before has more characters,
148 //then set it to be the current map.
149
150 if (countUniCode>countCurrMap)
151 {
152// qDebug() << "override with Unicode enc for" << face->family_name << face->style_name << "map" << mapToSet << "has only" << countCurrMap << "glyphs";
153 mapToSet=chmapUniCode;
154 //FT_Set_Charmap(face, face->charmaps[chmapUniCode]);
155 retVal = 0;
156 }
157 }
158// if (face->charmap == NULL || mapToSet!=FT_Get_Charmap_Index(face->charmap))
159 FT_Set_Charmap(face, face->charmaps[mapToSet]);
160// qDebug() << "set map" << mapToSet << "for" << face->family_name << face->style_name;
161// qDebug() << "glyphsForNumbers 0-9:" << FT_Get_Char_Index(face, QChar('0').unicode())
162// << FT_Get_Char_Index(face, QChar('1').unicode()) << FT_Get_Char_Index(face, QChar('2').unicode()) << FT_Get_Char_Index(face, QChar('3').unicode())
163// << FT_Get_Char_Index(face, QChar('4').unicode()) << FT_Get_Char_Index(face, QChar('5').unicode()) << FT_Get_Char_Index(face, QChar('6').unicode())
164// << FT_Get_Char_Index(face, QChar('7').unicode()) << FT_Get_Char_Index(face, QChar('8').unicode()) << FT_Get_Char_Index(face, QChar('9').unicode());
165 return retVal;
166}
167
168FPointArray traceGlyph(FT_Face face, FT_UInt glyphIndex, int chs, qreal *x, qreal *y, bool *err)
169{
170 bool error = false;
171 //AV: not threadsave, but tracechar is only used in ReadMetrics() and fontSample()
172 static FPointArray pts;
173 FPointArray pts2;
174 pts.resize(0);
175 pts2.resize(0);
176 firstP = FPoint(0,0);
177 FirstM = true;
178 error = FT_Set_Char_Size( face, 0, chs*6400, 72, 72 );
179 if (error)
180 {
181 *err = error;
182 return pts2;
183 }
184 if (glyphIndex == 0)
185 {
186 *err = true;
187 return pts2;
188 }
189 error = FT_Load_Glyph( face, glyphIndex, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP );
190 if (error)
191 {
192 *err = error;
193 return pts2;
194 }
195 error = FT_Outline_Decompose(&face->glyph->outline, &OutlineMethods, reinterpret_cast<void*>(&pts));
196 if (error)
197 {
198 *err = error;
199 return pts2;
200 }
201 *x = face->glyph->metrics.horiBearingX / 6400.0;
202 *y = face->glyph->metrics.horiBearingY / 6400.0;
203 QMatrix ma;
204 ma.scale(0.01, -0.01);
205 pts.map(ma);
206 pts.translate(0, chs);
207 pts2.putPoints(0, pts.size()-2, pts, 0);
208
209 return pts2;
210}
211
212
213FPointArray traceChar(FT_Face face, uint chr, int chs, qreal *x, qreal *y, bool *err)
214{
215 bool error = false;
216 FT_UInt glyphIndex;
217 error = FT_Set_Char_Size( face, 0, chs*64, 72, 72 );
218 if (error)
219 {
220 *err = error;
221 return FPointArray();
222 }
223 glyphIndex = FT_Get_Char_Index(face, chr);
224 return traceGlyph(face, glyphIndex, chs, x, y, err);
225}
226
227
228QPixmap FontSample(const ScFace& fnt, int s, QString ts, QColor back, bool force)
229{
230 FT_Face face;
231 FT_Library library;
232 qreal x, y, ymax;
233 bool error;
234 int pen_x;
235 FPoint gp;
236 error = FT_Init_FreeType( &library );
237 error = FT_New_Face( library, QFile::encodeName(fnt.fontFilePath()), fnt.faceIndex(), &face );
238 int encode = setBestEncoding(face);
239 qreal uniEM = static_cast<qreal>(face->units_per_EM);
240
241 qreal m_descent = face->descender / uniEM;
242 qreal m_height = face->height / uniEM;
243 if (m_height == 0)
244 m_height = (face->bbox.yMax - face->bbox.yMin) / uniEM;
245
246 int h = qRound(m_height * s) + 1;
247 qreal a = m_descent * s + 1;
248 int w = qRound((face->bbox.xMax - face->bbox.xMin) / uniEM) * s * (ts.length()+1);
249 if (w < 1)
250 w = s * (ts.length()+1);
251 if (h < 1)
252 h = s;
253 QImage pm(w, h, QImage::Format_ARGB32);
254 pen_x = 0;
255 ymax = 0.0;
256 ScPainter *p = new ScPainter(&pm, pm.width(), pm.height());
257 p->clear(back);
258 p->setFillMode(1);
259 p->setLineWidth(0.0);
260// p->setBrush(back);
261// p->drawRect(0.0, 0.0, static_cast<qreal>(w), static_cast<qreal>(h));
262 p->setBrush(Qt::black);
263 FPointArray gly;
264 uint dv;
265 dv = ts[0].unicode();
266 error = false;
267 gly = traceChar(face, dv, s, &x, &y, &error);
268 if (((encode != 0) || (error)) && (!force))
269 {
270 error = false;
271 FT_ULong charcode;
272 FT_UInt gindex;
273 gindex = 0;
274 charcode = FT_Get_First_Char(face, &gindex );
275 for (int n = 0; n < ts.length(); ++n)
276 {
277 gly = traceChar(face, charcode, s, &x, &y, &error);
278 if (error)
279 break;
280 if (gly.size() > 3)
281 {
282 gly.translate(static_cast<qreal>(pen_x) / 6400.0, a);
283 gp = getMaxClipF(&gly);
284 ymax = qMax(ymax, gp.y());
285 p->setupPolygon(&gly);
286 p->fillPath();
287 }
288 pen_x += face->glyph->advance.x;
289 charcode = FT_Get_Next_Char(face, charcode, &gindex );
290 if (gindex == 0)
291 break;
292 }
293 }
294 else
295 {
296 for (int n = 0; n < ts.length(); ++n)
297 {
298 dv = ts[n].unicode();
299 error = false;
300 gly = traceChar(face, dv, s, &x, &y, &error);
301 if (gly.size() > 3)
302 {
303 gly.translate(static_cast<qreal>(pen_x) / 6400.0, a);
304 gp = getMaxClipF(&gly);
305 ymax = qMax(ymax, gp.y());
306 p->setupPolygon(&gly);
307 p->fillPath();
308 }
309 pen_x += face->glyph->advance.x;
310 }
311 }
312 p->end();
313 QPixmap pmr;
314 pmr=QPixmap::fromImage(pm.copy(0, 0, qMin(qRound(gp.x()), w), qMin(qRound(ymax), h)));
315// this one below gives some funny results
316// pmr.convertFromImage(pm.scaled(qMin(qRound(gp.x()), w), qMin(qRound(ymax), h), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
317// pmr.resize(qMin(qRound(gp.x()), w), qMin(qRound(ymax), h));
318 delete p;
319 FT_Done_FreeType( library );
320 return pmr;
321}
322
323/** Same as FontSample() with \n strings support added.
32409/26/2004 petr vanek
325
326QPixmap fontSamples(ScFace * fnt, int s, QString ts, QColor back)
327{
328 QStringList lines = QStringList::split("\n", ts);
329 QPixmap ret(640, 480);
330 QPixmap sample;
331 QPainter *painter = new QPainter(&ret);
332 int y = 0;
333 int x = 0;
334 ret.fill(back);
335 for ( QStringList::Iterator it = lines.begin(); it != lines.end(); ++it )
336 {
337 sample = FontSample(fnt, s, *it, back);
338 if (!sample.isNull())
339 painter->drawPixmap(0, y, sample, 0, 0);
340 y = y + sample.height();
341 if (x < sample.width())
342 x = sample.width();
343 } // for
344 delete(painter);
345 QPixmap final(x, y);
346 if ((x != 0) && (y != 0))
347 {
348 QPainter *fpainter = new QPainter(&final);
349 fpainter->drawPixmap(0, 0, ret, 0, 0, x, y);
350 delete(fpainter);
351 }
352 return final;
353}
354*/
355
356bool GlyNames(FT_Face face, QMap<uint, std::pair<QChar, QString> >& GList)
357{
358 char buf[50];
359 FT_ULong charcode;
360 FT_UInt gindex;
361 setBestEncoding(face);
362 gindex = 0;
363 charcode = FT_Get_First_Char(face, &gindex );
364 const bool hasPSNames = FT_HAS_GLYPH_NAMES(face);
365 if (adobeGlyphNames.empty())
366 readAdobeGlyphNames();
367// qDebug() << "reading metrics for" << face->family_name << face->style_name;
368 while (gindex != 0)
369 {
370 bool notfound = true;
371 if (hasPSNames)
372 notfound = FT_Get_Glyph_Name(face, gindex, &buf, 50);
373
374 // just in case FT gives empty string or ".notdef"
375 // no valid glyphname except ".notdef" starts with '.'
376// qDebug() << "\t" << gindex << " '" << charcode << "' --> '" << (notfound? "notfound" : buf) << "'";
377 if (notfound || buf[0] == '\0' || buf[0] == '.')
378 GList.insert(gindex, std::make_pair(QChar(static_cast<uint>(charcode)),adobeGlyphName(charcode)));
379 else
380 GList.insert(gindex, std::make_pair(QChar(static_cast<uint>(charcode)),QString(reinterpret_cast<char*>(buf))));
381
382 charcode = FT_Get_Next_Char(face, charcode, &gindex );
383 }
384 // Let's see if we can find some more...
385 int maxSlot1 = face->num_glyphs;
386 if (hasPSNames)
387 for (int gindex = 1; gindex < maxSlot1; ++gindex)
388 {
389 if (!GList.contains(gindex))
390 {
391 bool found = ! FT_Get_Glyph_Name(face, gindex, &buf, 50);
392 if (found)
393 {
394 QString glyphname(reinterpret_cast<char*>(buf));
395 charcode = 0;
396 QMap<uint,std::pair<QChar,QString> >::Iterator gli;
397 for (gli = GList.begin(); gli != GList.end(); ++gli)
398 {
399 if (glyphname == gli.value().second)
400 {
401 charcode = gli.value().first.unicode();
402 break;
403 }
404 }
405// qDebug() << "\tmore: " << gindex << " '" << charcode << "' --> '" << buf << "'";
406 GList.insert(gindex, std::make_pair(QChar(static_cast<uint>(charcode)), glyphname));
407 }
408 }
409 }
410
411 return true;
412}
413
414
415static int traceMoveto( FT_Vector *to, FPointArray *composite )
416{
417 qreal tox = ( to->x / FTSCALE );
418 qreal toy = ( to->y / FTSCALE );
419 if (!FirstM)
420 {
421 composite->addPoint(firstP);
422 composite->addPoint(firstP);
423 composite->setMarker();
424 }
425 else
426 FirstM = false;
427 composite->addPoint(tox, toy);
428 composite->addPoint(tox, toy);
429 firstP.setXY(tox, toy);
430 return 0;
431}
432
433static int traceLineto( FT_Vector *to, FPointArray *composite )
434{
435 qreal tox = ( to->x / FTSCALE );
436 qreal toy = ( to->y / FTSCALE );
437 if ( !composite->hasLastQuadPoint(tox, toy, tox, toy, tox, toy, tox, toy))
438 composite->addQuadPoint(tox, toy, tox, toy, tox, toy, tox, toy);
439 return 0;
440}
441
442static int traceQuadraticBezier( FT_Vector *control, FT_Vector *to, FPointArray *composite )
443{
444 qreal x1 = ( control->x / FTSCALE );
445 qreal y1 = ( control->y / FTSCALE );
446 qreal x2 = ( to->x / FTSCALE );
447 qreal y2 = ( to->y / FTSCALE );
448 if ( !composite->hasLastQuadPoint(x2, y2, x1, y1, x2, y2, x2, y2))
449 composite->addQuadPoint(x2, y2, x1, y1, x2, y2, x2, y2);
450 return 0;
451}
452
453static int traceCubicBezier( FT_Vector *p, FT_Vector *q, FT_Vector *to, FPointArray *composite )
454{
455 qreal x1 = ( p->x / FTSCALE );
456 qreal y1 = ( p->y / FTSCALE );
457 qreal x2 = ( q->x / FTSCALE );
458 qreal y2 = ( q->y / FTSCALE );
459 qreal x3 = ( to->x / FTSCALE );
460 qreal y3 = ( to->y / FTSCALE );
461 if ( !composite->hasLastQuadPoint(x3, y3, x2, y2, x3, y3, x3, y3) )
462 {
463 composite->setPoint(composite->size()-1, FPoint(x1, y1));
464 composite->addQuadPoint(x3, y3, x2, y2, x3, y3, x3, y3);
465 }
466 return 0;
467}
468
469/// init the Adobe Glyph List
470void readAdobeGlyphNames()
471{
472 adobeGlyphNames.clear();
473 QRegExp pattern("(\\w*);([0-9A-Fa-f]{4})");
474 for (uint i=0; table[i]; ++i) {
475 if (pattern.indexIn(table[i]) >= 0) {
476 FT_ULong unicode = pattern.cap(2).toULong(0, 16);
477 qDebug() << QString("reading glyph name %1 for unicode %2(%3)").arg(pattern.cap(1)).arg(unicode).arg(pattern.cap(2));
478 adobeGlyphNames.insert(unicode, pattern.cap(1));
479 }
480 }
481}
482
483
484/// if in AGL, use that name, else use "uni1234" or "u12345"
485QString adobeGlyphName(FT_ULong charcode)
486{
487 static const char HEX[] = "0123456789ABCDEF";
488 QString result;
489 if (adobeGlyphNames.contains(charcode))
490 return adobeGlyphNames[charcode];
491 else if (charcode < 0x10000) {
492 result = QString("uni") + HEX[charcode>>12 & 0xF]
493 + HEX[charcode>> 8 & 0xF]
494 + HEX[charcode>> 4 & 0xF]
495 + HEX[charcode & 0xF];
496 }
497 else {
498 result = QString("u");
499 for (int i= 28; i >= 0; i-=4) {
500 if (charcode & (0xF << i))
501 result += HEX[charcode >> i & 0xF];
502 }
503 }
504 return result;
505}
506
507/*
508qreal Cwidth(ScribusDoc *, ScFace* scFace, QString ch, int Size, QString ch2)
509{
510 qreal width;
511 FT_Vector delta;
512 FT_Face face;
513 uint c1 = ch.at(0).unicode();
514 uint c2 = ch2.at(0).unicode();
515 qreal size10=Size/10.0;
516 if (scFace->canRender(ch[0]))
517 {
518 width = scFace->charWidth(ch[0])*size10;
519 face = scFace->ftFace();
520 /\****
521 Ok, this looks like a regression between Freetype 2.1.9 -> 2.1.10.
522 Ignoring the value of FT_HAS_KERNING for now -- AV
523 ****\/
524 if (true || FT_HAS_KERNING(face) )
525 {
526 uint cl = FT_Get_Char_Index(face, c1);
527 uint cr = FT_Get_Char_Index(face, c2);
528 FT_Error error = FT_Get_Kerning(face, cl, cr, FT_KERNING_UNSCALED, &delta);
529 if (error) {
530 qDebug() << QString("Error %2 when accessing kerning pair for font %1").arg(scFace->scName()).arg(error);
531 }
532 else {
533 qreal uniEM = static_cast<qreal>(face->units_per_EM);
534 width += delta.x / uniEM * size10;
535 }
536 }
537 else {
538 qDebug() << QString("Font %1 has no kerning pairs (according to Freetype)").arg(scFace->scName());
539 }
540 return width;
541 }
542 else
543 return size10;
544}
545
546qreal RealCWidth(ScribusDoc *, ScFace* scFace, QString ch, int Size)
547{
548 qreal w, ww;
549 uint c1 = ch.at(0).unicode();
550 FT_Face face;
551 if (scFace->canRender(ch.at(0)))
552 {
553 face = scFace->ftFace();
554 uint cl = FT_Get_Char_Index(face, c1);
555 int error = FT_Load_Glyph(face, cl, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP );
556 if (!error) {
557 qreal uniEM = static_cast<qreal>(face->units_per_EM);
558 w = (face->glyph->metrics.width + fabs((qreal)face->glyph->metrics.horiBearingX)) / uniEM * (Size / 10.0);
559 ww = face->glyph->metrics.horiAdvance / uniEM * (Size / 10.0);
560 return qMax(ww, w);
561 }
562 else
563 sDebug(QString("internal error: missing glyph: %1 (char %2) error=%3").arg(c1).arg(ch).arg(error));
564
565 }
566 return static_cast<qreal>(Size / 10.0);
567}
568
569qreal RealCHeight(ScribusDoc *, ScFace* scFace, QString ch, int Size)
570{
571 qreal w;
572 uint c1 = ch.at(0).unicode();
573 FT_Face face;
574 if (scFace->canRender(ch.at(0)))
575 {
576 face = scFace->ftFace();
577 uint cl = FT_Get_Char_Index(face, c1);
578 int error = FT_Load_Glyph(face, cl, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP );
579 if (!error) {
580 qreal uniEM = static_cast<qreal>(face->units_per_EM);
581 w = face->glyph->metrics.height / uniEM * (Size / 10.0);
582 }
583 else {
584 sDebug(QString("internal error: missing glyph: %1 (char %2) error=%3").arg(c1).arg(ch).arg(error));
585 w = Size / 10.0;
586 }
587 return w;
588 }
589 else
590 return static_cast<qreal>(Size / 10.0);
591}
592
593qreal RealCAscent(ScribusDoc *, ScFace* scFace, QString ch, int Size)
594{
595 qreal w;
596 uint c1 = ch.at(0).unicode();
597 FT_Face face;
598 if (scFace->canRender(ch.at(0)))
599 {
600 face = scFace->ftFace();
601 uint cl = FT_Get_Char_Index(face, c1);
602 int error = FT_Load_Glyph(face, cl, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP );
603 if (! error) {
604 qreal uniEM = static_cast<qreal>(face->units_per_EM);
605 w = face->glyph->metrics.horiBearingY / uniEM * (Size / 10.0);
606 }
607 else {
608 sDebug(QString("internal error: missing glyph: %1 (char %2) error=%3").arg(c1).arg(ch).arg(error));
609 w = Size / 10.0;
610 }
611 return w;
612 }
613 else
614 return static_cast<qreal>(Size / 10.0);
615}
616
617qreal RealFHeight(ScribusDoc *, ScFace* scFace, int Size)
618{
619 FT_Face face = scFace->ftFace();
620 qreal uniEM = static_cast<qreal>(face->units_per_EM);
621 return face->height / uniEM * (Size / 10.0);
622}
623*/
6240
=== removed file '.pc/0001-qreal-double-fixes.patch/scribus/pageitem.cpp'
--- .pc/0001-qreal-double-fixes.patch/scribus/pageitem.cpp 2011-09-11 22:10:03 +0000
+++ .pc/0001-qreal-double-fixes.patch/scribus/pageitem.cpp 1970-01-01 00:00:00 +0000
@@ -1,5999 +0,0 @@
1/*
2For general Scribus (>=1.3.2) copyright and licensing information please refer
3to the COPYING file provided with the program. Following this notice may exist
4a copyright and/or license notice that predates the release of Scribus 1.3.2
5for which a new license (GPL+exception) is in place.
6*/
7/***************************************************************************
8 pageitem.cpp - description
9 -------------------
10 begin : Sat Apr 7 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 "pageitem.h"
25#include <QPainter>
26#include <QPen>
27#include <QFont>
28#include <QRegion>
29#include <QPoint>
30#include <QFileInfo>
31#include <qdrawutil.h>
32#include <QRegExp>
33#include <QMessageBox>
34#include <QPolygon>
35#include <cassert>
36#include <QDebug>
37#include <iostream>
38#include <sstream>
39#include <string>
40
41#include "canvas.h"
42#include "cmsettings.h"
43#include "colorblind.h"
44#include "commonstrings.h"
45#include "cpalette.h"
46#include "guidemanager.h"
47#include "page.h"
48#include "pageitem_latexframe.h"
49#include "pageitem_textframe.h"
50#include "prefsmanager.h"
51#include "propertiespalette.h"
52#include "resourcecollection.h"
53#include "scclocale.h"
54#include "sccolorengine.h"
55#include "scconfig.h"
56#include "scpainter.h"
57#include "scpaths.h"
58#include "scpattern.h"
59#include "scribus.h"
60#include "scribusapp.h"
61#include "scribuscore.h"
62#include "scribusdoc.h"
63#include "scribusstructs.h"
64#include "scribuswin.h"
65#include "sctextstream.h"
66#include "serializer.h"
67#include "selection.h"
68#include "sclimits.h"
69#include "text/nlsconfig.h"
70#include "desaxe/saxXML.h"
71#include "undomanager.h"
72#include "undostate.h"
73#include "util.h"
74#include "util_formats.h"
75#include "util_math.h"
76#include "util_text.h"
77#include "util_file.h"
78#ifdef HAVE_CAIRO
79 #include <cairo.h>
80#endif
81
82using namespace std;
83
84PageItem::PageItem(const PageItem & other)
85 : QObject(other.parent()),
86 UndoObject(other), SingleObservable<PageItem>(other.m_Doc->itemsChanged()),
87
88// 200 attributes! That is madness, or to quote some famous people from Kriquet:
89// "THAT ALL HAS TO GO!"
90 gXpos(other.gXpos),
91 gYpos(other.gYpos),
92 gWidth(other.gWidth),
93 gHeight(other.gHeight),
94 GrType(other.GrType),
95 GrStartX(other.GrStartX),
96 GrStartY(other.GrStartY),
97 GrEndX(other.GrEndX),
98 GrEndY(other.GrEndY),
99 Cols(other.Cols),
100 ColGap(other.ColGap),
101 PLineArt(other.PLineArt),
102 PLineEnd(other.PLineEnd),
103 PLineJoin(other.PLineJoin),
104 NamedLStyle(other.NamedLStyle),
105 Clip(other.Clip),
106 PoLine(other.PoLine),
107 ContourLine(other.ContourLine),
108 imageClip(other.imageClip),
109 Segments(other.Segments),
110 effectsInUse(other.effectsInUse),
111 PoShow(other.PoShow),
112 BaseOffs(other.BaseOffs),
113 textPathType(other.textPathType),
114 textPathFlipped(other.textPathFlipped),
115 ClipEdited(other.ClipEdited),
116 FrameType(other.FrameType),
117 ItemNr(other.ItemNr),
118 Frame(other.Frame),
119 OwnPage(other.OwnPage),
120 oldOwnPage(other.oldOwnPage),
121 pixm(other.pixm),
122 Pfile(other.Pfile),
123 Pfile2(other.Pfile2),
124 Pfile3(other.Pfile3),
125 IProfile(other.IProfile),
126 UseEmbedded(other.UseEmbedded),
127 EmProfile(other.EmProfile),
128 IRender(other.IRender),
129
130 PictureIsAvailable(other.PictureIsAvailable),
131 OrigW(other.OrigW),
132 OrigH(other.OrigH),
133 BBoxX(other.BBoxX),
134 BBoxH(other.BBoxH),
135 CurX(other.CurX),
136 CurY(other.CurY),
137 CPos(other.CPos),
138 itemText(other.itemText),
139 isBookmark(other.isBookmark),
140 HasSel(other.HasSel),
141// Tinput(other.Tinput),
142 isAutoText(other.isAutoText),
143 BackBox(NULL), // otherwise other.BackBox->NextBox would be inconsistent
144 NextBox(NULL), // otherwise other.NextBox->BackBox would be inconsistent
145 firstChar(0), // since this box is unlinked now
146 MaxChars(0), // since the layout is invalid now
147 inPdfArticle(other.inPdfArticle),
148 isRaster(other.isRaster),
149 OldB(other.OldB),
150 OldH(other.OldH),
151 OldB2(other.OldB2),
152 OldH2(other.OldH2),
153 Sizing(other.Sizing),
154 toPixmap(other.toPixmap),
155 LayerNr(other.LayerNr),
156 ScaleType(other.ScaleType),
157 AspectRatio(other.AspectRatio),
158 Groups(other.Groups),
159 DashValues(other.DashValues),
160 DashOffset(other.DashOffset),
161 fill_gradient(other.fill_gradient),
162 fillRule(other.fillRule),
163 doOverprint(other.doOverprint),
164 LeftLink(other.LeftLink),
165 RightLink(other.RightLink),
166 TopLink(other.TopLink),
167 BottomLink(other.BottomLink),
168 LeftLinkID(other.LeftLinkID),
169 RightLinkID(other.RightLinkID),
170 TopLinkID(other.TopLinkID),
171 BottomLinkID(other.BottomLinkID),
172 LeftLine(other.LeftLine),
173 RightLine(other.RightLine),
174 TopLine(other.TopLine),
175 BottomLine(other.BottomLine),
176 isTableItem(other.isTableItem),
177 isSingleSel(other.isSingleSel),
178 isGroupControl(other.isGroupControl),
179 groupsLastItem(other.groupsLastItem),
180 BoundingX(other.BoundingX),
181 BoundingY(other.BoundingY),
182 BoundingW(other.BoundingW),
183 BoundingH(other.BoundingH),
184 ChangedMasterItem(other.ChangedMasterItem),
185 OnMasterPage(other.OnMasterPage),
186 isEmbedded(other.isEmbedded),
187
188 // protected
189 undoManager(other.undoManager),
190 m_ItemType(other.m_ItemType),
191 AnName(other.AnName),
192 patternVal(other.patternVal),
193 patternScaleX(other.patternScaleX),
194 patternScaleY(other.patternScaleY),
195 patternOffsetX(other.patternOffsetX),
196 patternOffsetY(other.patternOffsetY),
197 patternRotation(other.patternRotation),
198 fillColorVal(other.fillColorVal),
199 lineColorVal(other.lineColorVal),
200 lineShadeVal(other.lineShadeVal),
201 fillShadeVal(other.fillShadeVal),
202 fillTransparencyVal(other.fillTransparencyVal),
203 lineTransparencyVal(other.lineTransparencyVal),
204 fillBlendmodeVal(other.fillBlendmodeVal),
205 lineBlendmodeVal(other.lineBlendmodeVal),
206 m_ImageIsFlippedH(other.m_ImageIsFlippedH),
207 m_ImageIsFlippedV(other.m_ImageIsFlippedV),
208 m_Locked(other.m_Locked),
209 m_SizeLocked(other.m_SizeLocked),
210 textFlowModeVal(other.textFlowModeVal),
211 pageItemAttributes(other.pageItemAttributes),
212 m_PrintEnabled(other.m_PrintEnabled),
213 tagged(other.tagged),
214 fillQColor(other.fillQColor),
215 strokeQColor(other.strokeQColor),
216 Xpos(other.Xpos),
217 Ypos(other.Ypos),
218 Width(other.Width),
219 Height(other.Height),
220 Rot(other.Rot),
221 Select(other.Select),
222 LocalScX(other.LocalScX),
223 LocalScY(other.LocalScY),
224 LocalX(other.LocalX),
225 LocalY(other.LocalY),
226 Reverse(other.Reverse),
227 m_startArrowIndex(other.m_startArrowIndex),
228 m_endArrowIndex(other.m_endArrowIndex),
229 Extra(other.Extra),
230 TExtra(other.TExtra),
231 BExtra(other.BExtra),
232 RExtra(other.RExtra),
233 firstLineOffsetP(other.firstLineOffsetP),
234 RadRect(other.RadRect),
235 oldXpos(other.oldXpos),
236 oldYpos(other.oldYpos),
237 oldWidth(other.oldWidth),
238 oldHeight(other.oldHeight),
239 oldRot(other.oldRot),
240 oldLocalScX(other.oldLocalScX),
241 oldLocalScY(other.oldLocalScY),
242 oldLocalX(other.oldLocalX),
243 oldLocalY(other.oldLocalY),
244 m_Doc(other.m_Doc),
245 m_isAnnotation(other.m_isAnnotation),
246 m_annotation(other.m_annotation),
247 PicArt(other.PicArt),
248 m_lineWidth(other.m_lineWidth),
249 Oldm_lineWidth(other.Oldm_lineWidth)
250{
251 QString tmp;
252 m_Doc->TotalItems++;
253 AnName += tmp.setNum(m_Doc->TotalItems);
254 uniqueNr = m_Doc->TotalItems;
255 invalid = true;
256 if (other.isInlineImage)
257 {
258 QFileInfo inlFi(Pfile);
259 QString ext = inlFi.suffix();
260 tempImageFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_XXXXXX." + ext);
261 tempImageFile->open();
262 QString fileName = getLongPathName(tempImageFile->fileName());
263 tempImageFile->close();
264 copyFile(Pfile, fileName);
265 Pfile = fileName;
266 isInlineImage = true;
267 }
268 else
269 {
270 tempImageFile = NULL;
271 isInlineImage = false;
272 }
273}
274
275
276PageItem::PageItem(ScribusDoc *pa, ItemType newType, double x, double y, double w, double h, double w2, QString fill, QString outline)
277 // Initialize superclass(es)
278 : QObject(pa), SingleObservable<PageItem>(pa->itemsChanged()),
279 // Initialize member variables
280 itemText(pa),
281 undoManager(UndoManager::instance()),
282 lineShadeVal(100),
283 fillShadeVal(100),
284 fillTransparencyVal(0.0),
285 lineTransparencyVal(0.0),
286 fillBlendmodeVal(0),
287 lineBlendmodeVal(0),
288 m_ImageIsFlippedH(0),
289 m_ImageIsFlippedV(0),
290 m_Locked(false),
291 m_SizeLocked(false),
292 textFlowModeVal(TextFlowDisabled)
293{
294 m_Doc = pa;
295 QString tmp;
296 BackBox = 0;
297 NextBox = 0;
298 oldXpos = Xpos = x;
299 oldYpos = Ypos = y;
300 //CB Surely we can remove some of these?
301 OldB2 = OldB = oldWidth = Width = w;
302 OldH2 = OldH = oldHeight = Height = h;
303 BoundingX = x;
304 BoundingY = y;
305 BoundingW = w;
306 BoundingH = h;
307 m_ItemType = newType;
308 oldRot = Rot = 0;
309 fillColorVal = fill;
310 lineColorVal = m_ItemType == PageItem::TextFrame ? fill : outline;
311 gXpos = gYpos = 0;
312 gWidth = gHeight = 0;
313 GrType = 0;
314 GrStartX = 0;
315 GrStartY = 0;
316 GrEndX = w;
317 GrEndY = 0;
318 patternVal = "";
319 patternScaleX = 100;
320 patternScaleY = 100;
321 patternOffsetX = 0;
322 patternOffsetY = 0;
323 patternRotation = 0;
324 m_lineWidth = w2;
325 Oldm_lineWidth = w2;
326 PLineArt = Qt::PenStyle(m_Doc->toolSettings.dLineArt);
327 PLineEnd = Qt::FlatCap;
328 PLineJoin = Qt::MiterJoin;
329 Select = false;
330 ClipEdited = false;
331 FrameType = 0;
332 CurX = 0;
333 CurY = 0;
334 CPos = 0;
335 oldCPos = 0;
336 Extra = 0;
337 TExtra = 0;
338 BExtra = 0;
339 RExtra = 0;
340 firstChar = 0;
341 MaxChars = 0;
342 Pfile = "";
343 pixm = ScImage();
344 pixm.imgInfo.lowResType = m_Doc->toolSettings.lowResType;
345 Pfile2 = "";
346 Pfile3 = "";
347 oldLocalScX = LocalScX = 1;
348 oldLocalScY = LocalScY = 1;
349 OrigW = 0;
350 OrigH = 0;
351 oldLocalX = LocalX = 0;
352 oldLocalY = LocalY = 0;
353 BBoxX = 0;
354 BBoxH = 0;
355 RadRect = 0;
356 if ((m_ItemType == TextFrame) || (m_ItemType == ImageFrame) || (m_ItemType == PathText))
357 // TODO: Frame should become a read-only calculated property
358 Frame = true;
359 else
360 Frame = false;
361 switch (m_ItemType)
362 {
363 case Polygon:
364 Clip.setPoints(4, static_cast<int>(w/2), 0, static_cast<int>(w), static_cast<int>(h/2),
365 static_cast<int>(w/2), static_cast<int>(h), 0,static_cast<int>(h/2));
366 break;
367 default:
368 Clip.setPoints(4, 0,0, static_cast<int>(w),0, static_cast<int>(w), static_cast<int>(h), 0,static_cast<int>(h));
369 break;
370 }
371 PoLine.resize(0);
372 ContourLine.resize(0);
373 imageClip.resize(0);
374 Segments.clear();
375 PoShow = false;
376 BaseOffs = 0;
377 textPathType = 0;
378 textPathFlipped = false;
379 OwnPage = m_Doc->currentPage()->pageNr();
380 oldOwnPage = OwnPage;
381 savedOwnPage = OwnPage;
382 PicArt = true;
383 PictureIsAvailable = false;
384 m_PrintEnabled = true;
385 isBookmark = false;
386 m_isAnnotation = false;
387
388 switch (m_ItemType)
389 {
390 case ImageFrame:
391 case LatexFrame:
392 //We can't determine if this is a latex frame here
393 // because c++'s typeinfos are still saying it's
394 // a plain pageitem
395 // This is fixed in the PageItem_LatexFrame constructor
396 AnName = tr("Image");
397 setUPixmap(Um::IImageFrame);
398 break;
399 case TextFrame:
400 AnName = tr("Text");
401 setUPixmap(Um::ITextFrame);
402 break;
403 case Line:
404 AnName = tr("Line");
405 setUPixmap(Um::ILine);
406 break;
407 case Polygon:
408 AnName = tr("Polygon");
409 setUPixmap(Um::IPolygon);
410 break;
411 case PolyLine:
412 AnName = tr("Polyline");
413 setUPixmap(Um::IPolyline);
414 break;
415 case PathText:
416 AnName = tr("PathText");
417 setUPixmap(Um::IPathText);
418 break;
419 default:
420 AnName = "Item";
421 break;
422 }
423 m_Doc->TotalItems++;
424 AnName += tmp.setNum(m_Doc->TotalItems); // +" "+QDateTime::currentDateTime().toString();
425 uniqueNr = m_Doc->TotalItems;
426 AutoName = true;
427 setUName(AnName);
428 m_annotation.setBorderColor(outline);
429 HasSel = false;
430// Tinput = false;
431 isAutoText = false;
432 inPdfArticle = false;
433 isRaster = false;
434 Sizing = false;
435 toPixmap = false;
436 UseEmbedded = true;
437 IRender = Intent_Relative_Colorimetric;
438 EmProfile = "";
439 Groups.clear();
440 LayerNr = m_Doc->activeLayer();
441 ScaleType = true;
442 AspectRatio = true;
443 Reverse = false;
444 NamedLStyle = "";
445 DashValues.clear();
446 DashOffset = 0;
447 fillRule = true;
448 doOverprint = false;
449 fill_gradient = VGradient(VGradient::linear);
450 fill_gradient.clearStops();
451 if (fillColorVal != CommonStrings::None)
452 {
453 const ScColor& col = m_Doc->PageColors[fillColorVal];
454 QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
455 fill_gradient.addStop(qcol, 0.0, 0.5, 1.0, fillColorVal, 100);
456 fill_gradient.addStop(qcol, 1.0, 0.5, 1.0, fillColorVal, 100);
457 }
458 else
459 {
460 if (m_Doc->toolSettings.dBrush != CommonStrings::None)
461 {
462 const ScColor& col = m_Doc->PageColors[m_Doc->toolSettings.dBrush];
463 QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
464 fill_gradient.addStop(qcol, 0.0, 0.5, 1.0, m_Doc->toolSettings.dBrush, 100);
465 fill_gradient.addStop(qcol, 1.0, 0.5, 1.0, m_Doc->toolSettings.dBrush, 100);
466 }
467 else
468 {
469 if (lineColorVal != CommonStrings::None)
470 {
471 const ScColor& col = m_Doc->PageColors[lineColorVal];
472 QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
473 fill_gradient.addStop(qcol, 0.0, 0.5, 1.0, lineColorVal, 100);
474 fill_gradient.addStop(qcol, 1.0, 0.5, 1.0, lineColorVal, 100);
475 }
476 else
477 {
478 if (m_Doc->toolSettings.dPen != CommonStrings::None)
479 {
480 const ScColor& col = m_Doc->PageColors[m_Doc->toolSettings.dPen];
481 QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
482 fill_gradient.addStop(qcol, 0.0, 0.5, 1.0, m_Doc->toolSettings.dPen, 100);
483 fill_gradient.addStop(qcol, 1.0, 0.5, 1.0, m_Doc->toolSettings.dPen, 100);
484 }
485 else if (m_Doc->PageColors.contains("Black"))
486 {
487 const ScColor& col = m_Doc->PageColors["Black"];
488 QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
489 fill_gradient.addStop(qcol, 0.0, 0.5, 1.0, "Black", 100);
490 fill_gradient.addStop(qcol, 1.0, 0.5, 1.0, "Black", 100);
491 }
492 }
493 }
494 }
495 firstLineOffsetP = FLOPRealGlyphHeight;
496 Cols = m_Doc->toolSettings.dCols;
497 ColGap = m_Doc->toolSettings.dGap;
498 LeftLink = 0;
499 RightLink = 0;
500 TopLink = 0;
501 BottomLink = 0;
502 LeftLinkID = 0;
503 RightLinkID = 0;
504 TopLinkID = 0;
505 BottomLinkID = 0;
506 LeftLine = 0;
507 RightLine = false;
508 TopLine = false;
509 BottomLine = false;
510 isTableItem = false;
511 isSingleSel = false;
512 Dirty = false;
513 invalid = true;
514 isGroupControl = false;
515 groupsLastItem = 0;
516 ChangedMasterItem = false;
517 isEmbedded = false;
518 OnMasterPage = m_Doc->currentPage()->pageName();
519 m_startArrowIndex = m_Doc->toolSettings.dStartArrow;
520 m_endArrowIndex = m_Doc->toolSettings.dEndArrow;
521 effectsInUse.clear();
522 //Page Item Attributes
523 pageItemAttributes.clear();
524 for(ObjAttrVector::Iterator objAttrIt = m_Doc->docItemAttributes.begin() ; objAttrIt != m_Doc->docItemAttributes.end(); ++objAttrIt )
525 {
526 if (((*objAttrIt).autoaddto=="textframes" && m_ItemType==TextFrame) ||
527 ((*objAttrIt).autoaddto=="imageframes" && m_ItemType==ImageFrame)
528 )
529 pageItemAttributes.append(*objAttrIt);
530 }
531 tempImageFile = NULL;
532 isInlineImage = false;
533}
534
535void PageItem::setXPos(const double newXPos, bool drawingOnly)
536{
537 Xpos = newXPos;
538 if (drawingOnly || m_Doc->isLoading())
539 return;
540 checkChanges();
541 emit position(Xpos, Ypos);
542}
543
544void PageItem::setYPos(const double newYPos, bool drawingOnly)
545{
546 Ypos = newYPos;
547 if (drawingOnly || m_Doc->isLoading())
548 return;
549 checkChanges();
550 emit position(Xpos, Ypos);
551}
552
553void PageItem::setXYPos(const double newXPos, const double newYPos, bool drawingOnly)
554{
555 Xpos = newXPos;
556 Ypos = newYPos;
557 if (drawingOnly || m_Doc->isLoading())
558 return;
559 checkChanges();
560 emit position(Xpos, Ypos);
561}
562
563void PageItem::moveBy(const double dX, const double dY, bool drawingOnly)
564{
565 if (dX==0.0 && dY==0.0)
566 return;
567 invalid = true;
568 if (dX!=0.0)
569 Xpos+=dX;
570 if (dY!=0.0)
571 Ypos+=dY;
572 if (drawingOnly || m_Doc->isLoading())
573 return;
574 checkChanges();
575 emit position(Xpos, Ypos);
576}
577
578void PageItem::setWidth(const double newWidth)
579{
580 Width = newWidth;
581 updateConstants();
582 checkChanges();
583 emit widthAndHeight(Width, Height);
584}
585
586void PageItem::setHeight(const double newHeight)
587{
588 Height = newHeight;
589 updateConstants();
590 checkChanges();
591 emit widthAndHeight(Width, Height);
592}
593
594void PageItem::setWidthHeight(const double newWidth, const double newHeight, bool drawingOnly)
595{
596 Width = newWidth;
597 Height = newHeight;
598 updateConstants();
599 if (drawingOnly)
600 return;
601 checkChanges();
602 emit widthAndHeight(Width, Height);
603}
604
605void PageItem::setWidthHeight(const double newWidth, const double newHeight)
606{
607 Width = newWidth;
608 Height = newHeight;
609 updateConstants();
610 checkChanges();
611 emit widthAndHeight(Width, Height);
612}
613
614void PageItem::resizeBy(const double dH, const double dW)
615{
616 if (dH==0.0 && dW==0.0)
617 return;
618 if (dH!=0.0)
619 Width+=dH;
620 if (dW!=0.0)
621 Height+=dW;
622 updateConstants();
623 checkChanges();
624 emit widthAndHeight(Width, Height);
625}
626
627void PageItem::setRotation(const double newRotation, bool drawingOnly)
628{
629 Rot=newRotation;
630 checkChanges();
631 if (drawingOnly || m_Doc->isLoading())
632 return;
633 emit rotation(Rot);
634}
635
636void PageItem::rotateBy(const double dR)
637{
638 if (dR==0.0)
639 return;
640 Rot+=dR;
641 checkChanges();
642 emit rotation(Rot);
643}
644
645void PageItem::setSelected(const bool toSelect)
646{
647 Select=toSelect;
648}
649
650void PageItem::setImageXScale(const double newImageXScale)
651{
652 LocalScX=newImageXScale;
653 checkChanges();
654 emit imageOffsetScale(LocalScX, LocalScY, LocalX, LocalY);
655}
656
657void PageItem::setImageYScale(const double newImageYScale)
658{
659 LocalScY=newImageYScale;
660 checkChanges();
661 emit imageOffsetScale(LocalScX, LocalScY, LocalX, LocalY);
662}
663
664void PageItem::setImageXYScale(const double newImageXScale, const double newImageYScale)
665{
666 LocalScX=newImageXScale;
667 LocalScY=newImageYScale;
668 checkChanges();
669 emit imageOffsetScale(LocalScX, LocalScY, LocalX, LocalY);
670}
671
672void PageItem::setImageXOffset(const double newImageXOffset)
673{
674 LocalX=newImageXOffset;
675 checkChanges();
676 emit imageOffsetScale(LocalScX, LocalScY, LocalX, LocalY);
677}
678
679void PageItem::setImageYOffset(const double newImageYOffset)
680{
681 LocalY=newImageYOffset;
682 checkChanges();
683 emit imageOffsetScale(LocalScX, LocalScY, LocalX, LocalY);
684}
685
686void PageItem::setImageXYOffset(const double newImageXOffset, const double newImageYOffset)
687{
688 LocalX=newImageXOffset;
689 LocalY=newImageYOffset;
690 checkChanges();
691 emit imageOffsetScale(LocalScX, LocalScY, LocalX, LocalY);
692}
693
694void PageItem::moveImageXYOffsetBy(const double dX, const double dY)
695{
696 if (dX==0.0 && dY==0.0)
697 return;
698 if (dX!=0.0)
699 LocalX+=dX;
700 if (dY!=0.0)
701 LocalY+=dY;
702 checkChanges();
703 emit imageOffsetScale(LocalScX, LocalScY, LocalX, LocalY);
704}
705
706void PageItem::setReversed(bool newReversed)
707{
708 Reverse=newReversed;
709}
710
711
712/// returns true if text overflows
713bool PageItem::frameOverflows() const
714{
715#ifndef NLS_PROTO
716 // Fix #6991 : "Text overflow" warning when there is a text underflow in fact
717 /*return NextBox == NULL && itemText.length() > static_cast<int>(MaxChars);*/
718 return ( NextBox == NULL )
719 && ( static_cast<int> ( firstChar ) < itemText.length() )
720 // Fix #7766 : scribus.textOverflows() returns 0 if there is no place for the overflow mark
721 /*&& ( firstChar < MaxChars )*/
722 && ( firstChar <= MaxChars )
723 && ( itemText.length() > static_cast<int> ( MaxChars ) );
724#else
725 return false; // FIXME:NLS
726#endif
727}
728
729int PageItem::firstInFrame() const
730{
731 return firstChar;
732}
733int PageItem::lastInFrame() const
734{
735#ifndef NLS_PROTO
736 return qMin(signed(MaxChars), itemText.length()) - 1;
737#else
738 return itemText.length() - 1;
739#endif
740}
741
742
743void PageItem::link(PageItem* nxt)
744{
745 assert( !nextInChain() );
746 assert( !nxt->prevInChain() );
747 for (PageItem* ff=nxt; ff; ff=ff->nextInChain())
748 {
749 assert (ff != this);
750 }
751 // Append only if necessary to avoid the
752 // charstyle: access at end of text warning
753 if (nxt->itemText.length() > 0)
754 itemText.append(nxt->itemText);
755 NextBox = nxt;
756 nxt->BackBox = this;
757 // update AutoText
758 if (isAutoText)
759 {
760 PageItem* after = nxt;
761 while (after)
762 {
763 after->isAutoText = true;
764 m_Doc->LastAuto = after;
765 after = after->NextBox;
766 }
767 }
768 else if (nxt->isAutoText)
769 {
770 PageItem* before = this;
771 while (before)
772 {
773 before->isAutoText = true;
774 m_Doc->FirstAuto = before;
775 before = before->BackBox;
776 }
777 }
778 invalid = true;
779 while (nxt)
780 {
781 nxt->itemText = itemText;
782 nxt->invalid = true;
783 nxt->firstChar = 0;
784 nxt = nxt->NextBox;
785 }
786 if (UndoManager::undoEnabled())
787 {
788 ItemState<std::pair<PageItem*, PageItem*> > *is = new ItemState<std::pair<PageItem*, PageItem*> >(UndoManager::LinkTextFrame);
789 is->set("LINK_TEXT_FRAME", "linkTextFrame");
790 is->setItem(std::pair<PageItem*, PageItem*>(this, NextBox));
791 undoManager->action(this, is);
792 }
793}
794
795void PageItem::unlink()
796{
797 if( NextBox )
798 {
799 PageItem *undoNextBox=NextBox;
800 // make sure lastInFrame is valid
801 layout();
802 /*
803 //<< CB #6332: Stop the StoryText cut and break and act like other publishing apps
804 // move following text to new StoryText
805 itemText.select(lastInFrame()+1, itemText.length()-lastInFrame()-1);
806 */
807 StoryText follow(m_Doc);
808 /*
809 follow.setDefaultStyle(itemText.defaultStyle());
810 follow.insert(0, itemText, true);
811 // remove following text from this chain
812 itemText.removeSelection();
813 //>>
814 */
815 // update auto pointers
816 if (isAutoText)
817 {
818 PageItem* before = this;
819 while (before)
820 {
821 before->isAutoText = false;
822 before = before->BackBox;
823 }
824 m_Doc->FirstAuto = NextBox;
825 }
826 // link following frames to new text
827 NextBox->firstChar = 0;
828 NextBox->BackBox = NULL;
829 while (NextBox) {
830 NextBox->itemText = follow;
831 NextBox->invalid = true;
832 NextBox->firstChar = 0;
833 NextBox = NextBox->NextBox;
834 }
835 // NextBox == NULL now
836 NextBox = NULL;
837 if (UndoManager::undoEnabled())
838 {
839 ItemState<std::pair<PageItem*, PageItem*> > *is = new ItemState<std::pair<PageItem*, PageItem*> >(UndoManager::UnlinkTextFrame);
840 is->set("UNLINK_TEXT_FRAME", "unlinkTextFrame");
841 is->setItem(std::pair<PageItem*, PageItem*>(this, undoNextBox));
842 undoManager->action(this, is);
843 }
844 }
845}
846
847
848void PageItem::dropLinks()
849{
850 // update auto pointers
851 if (isAutoText && NextBox == 0)
852 {
853 m_Doc->LastAuto = BackBox;
854 }
855 if (isAutoText && BackBox == 0)
856 {
857 m_Doc->FirstAuto = NextBox;
858 }
859 isAutoText = false;
860
861 // leave text in remaining chain
862 PageItem* before = BackBox;
863 PageItem* after = NextBox;
864 if (after != 0 || before != 0)
865 {
866 itemText = StoryText(m_Doc);
867 if (before)
868 before->NextBox = after;
869 if (after)
870 {
871 after->BackBox = before;
872 while (after)
873 {
874 after->invalid = true;
875 after->firstChar = 0;
876 after = after->NextBox;
877 }
878 }
879 // JG we should set BackBox and NextBox to NULL at a point
880 BackBox = NextBox = NULL;
881 }
882}
883
884/// tests if a character is displayed by this frame
885bool PageItem::frameDisplays(int textpos) const
886{
887#ifndef NLS_PROTO
888 return 0 <= textpos && textpos < signed(MaxChars) && textpos < itemText.length();
889#else
890 return true; // FIXME:NLS
891#endif
892}
893
894
895/// returns the style at the current charpos
896const ParagraphStyle& PageItem::currentStyle() const
897{
898 if (frameDisplays(CPos))
899 return itemText.paragraphStyle(CPos);
900 else
901 return itemText.defaultStyle();
902}
903
904/// returns the style at the current charpos for changing
905ParagraphStyle& PageItem::changeCurrentStyle()
906{
907 if (frameDisplays(CPos))
908 return const_cast<ParagraphStyle&>(itemText.paragraphStyle(CPos));
909 else
910 return const_cast<ParagraphStyle&>(itemText.defaultStyle());
911}
912
913/// returns the style at the current charpos
914const CharStyle& PageItem::currentCharStyle() const
915{
916 if (frameDisplays(CPos))
917 return itemText.charStyle(CPos);
918 else
919 return itemText.defaultStyle().charStyle();
920}
921
922void PageItem::setTextToFrameDistLeft(double newLeft)
923{
924 Extra=newLeft;
925 emit textToFrameDistances(Extra, TExtra, BExtra, RExtra);
926}
927
928void PageItem::setTextToFrameDistRight(double newRight)
929{
930 RExtra=newRight;
931 emit textToFrameDistances(Extra, TExtra, BExtra, RExtra);
932}
933
934void PageItem::setTextToFrameDistTop(double newTop)
935{
936 TExtra=newTop;
937 emit textToFrameDistances(Extra, TExtra, BExtra, RExtra);
938}
939
940void PageItem::setTextToFrameDistBottom(double newBottom)
941{
942 BExtra=newBottom;
943 emit textToFrameDistances(Extra, TExtra, BExtra, RExtra);
944}
945
946void PageItem::setTextToFrameDist(double newLeft, double newRight, double newTop, double newBottom)
947{
948 Extra=newLeft;
949 RExtra=newRight;
950 TExtra=newTop;
951 BExtra=newBottom;
952 emit textToFrameDistances(Extra, TExtra, BExtra, RExtra);
953}
954
955double PageItem::gridOffset() const { return m_Doc->typographicSettings.offsetBaseGrid; }
956double PageItem::gridDistance() const { return m_Doc->typographicSettings.valueBaseGrid; }
957
958void PageItem::setGridOffset(double) { } // FIXME
959void PageItem::setGridDistance(double) { } // FIXME
960void PageItem::setColumns(int n)
961{
962 Cols = qMax(1, n); //FIXME: undo
963}
964void PageItem::setColumnGap(double gap)
965{
966 ColGap = gap; //FIXME: undo
967}
968
969void PageItem::setCornerRadius(double newRadius)
970{
971 RadRect=newRadius;
972 emit cornerRadius(RadRect);
973}
974
975
976
977
978
979
980
981
982
983/** Paints the item.
984 CHANGE: cullingArea is in doc coordinates!
985 */
986void PageItem::DrawObj(ScPainter *p, QRectF cullingArea)
987{
988// qDebug << "PageItem::DrawObj";
989 double sc;
990 if (!m_Doc->DoDrawing)
991 {
992// Tinput = false;
993 return;
994 }
995 if (cullingArea.isNull())
996 {
997 cullingArea = QRectF(QPointF(m_Doc->minCanvasCoordinate.x(), m_Doc->minCanvasCoordinate.y()),
998 QPointF(m_Doc->maxCanvasCoordinate.x(), m_Doc->maxCanvasCoordinate.y())).toAlignedRect();
999 }
1000
1001 DrawObj_Pre(p, sc);
1002 if (m_Doc->layerOutline(LayerNr))
1003 {
1004 if ((itemType()==TextFrame || itemType()==ImageFrame || itemType()==PathText || itemType()==Line || itemType()==PolyLine) && (!isGroupControl))
1005 DrawObj_Item(p, cullingArea, sc);
1006 }
1007 else
1008 {
1009 if (!isGroupControl)
1010 DrawObj_Item(p, cullingArea, sc);
1011 }
1012 DrawObj_Post(p);
1013}
1014
1015void PageItem::DrawObj_Pre(ScPainter *p, double &sc)
1016{
1017 ScribusView* view = m_Doc->view();
1018 sc = view->scale();
1019 p->save();
1020 if (!isEmbedded)
1021 p->translate(Xpos, Ypos);
1022 p->rotate(Rot);
1023 if (m_Doc->layerOutline(LayerNr))
1024 {
1025 p->setPen(m_Doc->layerMarker(LayerNr), 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
1026 p->setFillMode(ScPainter::None);
1027 p->setBrushOpacity(1.0);
1028 p->setPenOpacity(1.0);
1029 }
1030 else
1031 {
1032 if (!isGroupControl)
1033 {
1034 if (fillBlendmode() != 0)
1035 p->beginLayer(1.0 - fillTransparency(), fillBlendmode());
1036
1037 p->setLineWidth(m_lineWidth);
1038 if (GrType != 0)
1039 {
1040 if (GrType == 8)
1041 {
1042 if ((patternVal.isEmpty()) || (!m_Doc->docPatterns.contains(patternVal)))
1043 {
1044 p->fill_gradient = VGradient(VGradient::linear);
1045 if (fillColor() != CommonStrings::None)
1046 {
1047 p->setBrush(fillQColor);
1048 p->setFillMode(ScPainter::Solid);
1049 }
1050 else
1051 p->setFillMode(ScPainter::None);
1052 if ((!patternVal.isEmpty()) && (!m_Doc->docPatterns.contains(patternVal)))
1053 {
1054 GrType = 0;
1055 patternVal = "";
1056 }
1057 }
1058 else
1059 {
1060 p->setPattern(&m_Doc->docPatterns[patternVal], patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation);
1061 p->setFillMode(ScPainter::Pattern);
1062 }
1063 }
1064 else
1065 {
1066 if (fill_gradient.Stops() < 2) // fall back to solid filling if there are not enough colorstops in the gradient.
1067 {
1068 if (fillColor() != CommonStrings::None)
1069 {
1070 p->setBrush(fillQColor);
1071 p->setFillMode(ScPainter::Solid);
1072 }
1073 else
1074 p->setFillMode(ScPainter::None);
1075 }
1076 else
1077 {
1078 p->setFillMode(ScPainter::Gradient);
1079 p->fill_gradient = fill_gradient;
1080 QMatrix grm;
1081 grm.rotate(Rot);
1082 FPointArray gra;
1083 switch (GrType)
1084 {
1085 case 1:
1086 case 2:
1087 case 3:
1088 case 4:
1089 case 6:
1090 p->setGradient(VGradient::linear, FPoint(GrStartX, GrStartY), FPoint(GrEndX, GrEndY));
1091 break;
1092 case 5:
1093 case 7:
1094 gra.setPoints(2, GrStartX, GrStartY, GrEndX, GrEndY);
1095 p->setGradient(VGradient::radial, gra.point(0), gra.point(1), gra.point(0));
1096 break;
1097 }
1098 }
1099 }
1100 }
1101 else
1102 {
1103 p->fill_gradient = VGradient(VGradient::linear);
1104 if (fillColor() != CommonStrings::None)
1105 {
1106 p->setBrush(fillQColor);
1107 p->setFillMode(ScPainter::Solid);
1108 }
1109 else
1110 p->setFillMode(ScPainter::None);
1111 }
1112 if (lineColor() != CommonStrings::None)
1113 {
1114// if ((m_lineWidth == 0) && ! asLine())
1115// p->setLineWidth(0);
1116// else
1117// {
1118 p->setPen(strokeQColor, m_lineWidth, PLineArt, PLineEnd, PLineJoin);
1119 if (DashValues.count() != 0)
1120 p->setDash(DashValues, DashOffset);
1121// }
1122 }
1123 else
1124 p->setLineWidth(0);
1125 if (fillBlendmode() == 0)
1126 p->setBrushOpacity(1.0 - fillTransparency());
1127 if (lineBlendmode() == 0)
1128 p->setPenOpacity(1.0 - lineTransparency());
1129 p->setFillRule(fillRule);
1130 }
1131 }
1132}
1133
1134void PageItem::DrawObj_Post(ScPainter *p)
1135{
1136 bool doStroke=true;
1137 ScribusView* view = m_Doc->view();
1138 if (!isGroupControl)
1139 {
1140 if (m_Doc->layerOutline(LayerNr))
1141 {
1142 if (itemType()!=Line)
1143 {
1144 p->setPen(m_Doc->layerMarker(LayerNr), 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
1145 p->setFillMode(ScPainter::None);
1146 p->setBrushOpacity(1.0);
1147 p->setPenOpacity(1.0);
1148 if (itemType()==PolyLine)
1149 p->setupPolygon(&PoLine, false);
1150 else if (itemType() == PathText)
1151 {
1152 if (PoShow)
1153 p->setupPolygon(&PoLine, false);
1154 else
1155 doStroke = false;
1156 }
1157 else
1158 p->setupPolygon(&PoLine);
1159 if (doStroke)
1160 p->strokePath();
1161 if (itemType()==ImageFrame)
1162 {
1163 if (imageClip.size() != 0)
1164 {
1165 p->setupPolygon(&imageClip);
1166 p->strokePath();
1167 }
1168 }
1169 }
1170 }
1171 else
1172 {
1173 if (fillBlendmode() != 0)
1174 p->endLayer();
1175 if (itemType()==PathText || itemType()==PolyLine || itemType()==Line)
1176 doStroke=false;
1177 if ((doStroke) && (!m_Doc->RePos))
1178 {
1179 if (lineBlendmode() != 0)
1180 p->beginLayer(1.0 - lineTransparency(), lineBlendmode());
1181// if (lineColor() != CommonStrings::None)
1182// {
1183// p->setPen(strokeQColor, m_lineWidth, PLineArt, PLineEnd, PLineJoin);
1184// if (DashValues.count() != 0)
1185// p->setDash(DashValues, DashOffset);
1186// }
1187// else
1188// p->setLineWidth(0);
1189 if (!isTableItem)
1190 {
1191 if ((itemType() == LatexFrame) || (itemType() == ImageFrame))
1192 p->setupPolygon(&PoLine);
1193 if (NamedLStyle.isEmpty())
1194 {
1195 if (lineColor() != CommonStrings::None)
1196 {
1197 p->setPen(strokeQColor, m_lineWidth, PLineArt, PLineEnd, PLineJoin);
1198 if (DashValues.count() != 0)
1199 p->setDash(DashValues, DashOffset);
1200 p->strokePath();
1201 }
1202 }
1203 else
1204 {
1205 multiLine ml = m_Doc->MLineStyles[NamedLStyle];
1206 QColor tmp;
1207 for (int it = ml.size()-1; it > -1; it--)
1208 {
1209 struct SingleLine& sl = ml[it];
1210 // Qt4 if ((!sl.Color != CommonStrings::None) && (sl.Width != 0))
1211 if (sl.Color != CommonStrings::None) // && (sl.Width != 0))
1212 {
1213 SetQColor(&tmp, sl.Color, sl.Shade);
1214 p->setPen(tmp, sl.Width, static_cast<Qt::PenStyle>(sl.Dash), static_cast<Qt::PenCapStyle>(sl.LineEnd), static_cast<Qt::PenJoinStyle>(sl.LineJoin));
1215 p->strokePath();
1216 }
1217 }
1218 }
1219 }
1220 if (lineBlendmode() != 0)
1221 p->endLayer();
1222 }
1223 }
1224 }
1225 if ((!isEmbedded) && (!m_Doc->RePos))
1226 {
1227 double aestheticFactor(5.0);
1228 double scpInv = 1.0 / (qMax(view->scale(), 1.0) * aestheticFactor);
1229 if (!isGroupControl)
1230 {
1231 if ((Frame) && (m_Doc->guidesSettings.framesShown) && ((itemType() == ImageFrame) || (itemType() == LatexFrame) || (itemType() == PathText)))
1232 {
1233 p->setPen(PrefsManager::instance()->appPrefs.DFrameNormColor, scpInv, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
1234 if ((isBookmark) || (m_isAnnotation))
1235 p->setPen(PrefsManager::instance()->appPrefs.DFrameAnnotationColor, scpInv, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
1236 if ((BackBox != 0) || (NextBox != 0))
1237 p->setPen(PrefsManager::instance()->appPrefs.DFrameLinkColor, scpInv, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
1238 if (m_Locked)
1239 p->setPen(PrefsManager::instance()->appPrefs.DFrameLockColor, scpInv, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
1240 p->setFillMode(0);
1241 if (itemType()==PathText)
1242 {
1243 if (Clip.count() != 0)
1244 {
1245 FPointArray tclip;
1246 FPoint np = FPoint(Clip.point(0));
1247 tclip.resize(2);
1248 tclip.setPoint(0, np);
1249 tclip.setPoint(1, np);
1250 for (int a = 1; a < Clip.size(); ++a)
1251 {
1252 np = FPoint(Clip.point(a));
1253 tclip.putPoints(tclip.size(), 4, np.x(), np.y(), np.x(), np.y(), np.x(), np.y(), np.x(), np.y());
1254 }
1255 np = FPoint(Clip.point(0));
1256 tclip.putPoints(tclip.size(), 2, np.x(), np.y(), np.x(), np.y());
1257 p->setupPolygon(&tclip);
1258 }
1259 }
1260 else
1261// Ugly Hack to fix rendering problems with cairo >=1.5.10 && <1.8.0 follows
1262#ifdef HAVE_CAIRO
1263 #if ((CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 5, 10)) && (CAIRO_VERSION < CAIRO_VERSION_ENCODE(1, 8, 0)))
1264 p->setupPolygon(&PoLine, false);
1265 #else
1266 p->setupPolygon(&PoLine);
1267 #endif
1268#else
1269 p->setupPolygon(&PoLine);
1270#endif
1271 p->strokePath();
1272 }
1273 }
1274 if ((m_Doc->guidesSettings.framesShown) && textFlowUsesContourLine() && (ContourLine.size() != 0))
1275 {
1276 p->setPen(Qt::darkGray, 1.0 / qMax(view->scale(), 1.0), Qt::DotLine, Qt::FlatCap, Qt::MiterJoin);
1277// Ugly Hack to fix rendering problems with cairo >=1.5.10 && <1.8.0 follows
1278#ifdef HAVE_CAIRO
1279 #if ((CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 5, 10)) && (CAIRO_VERSION < CAIRO_VERSION_ENCODE(1, 8, 0)))
1280 p->setupPolygon(&ContourLine, false);
1281 #else
1282 p->setupPolygon(&ContourLine);
1283 #endif
1284#else
1285 p->setupPolygon(&ContourLine);
1286#endif
1287 p->strokePath();
1288 }
1289 if ((m_Doc->guidesSettings.layerMarkersShown) && (m_Doc->layerCount() > 1) && (!m_Doc->layerOutline(LayerNr)) && ((isGroupControl) || (Groups.count() == 0)) && (!view->m_canvas->isPreviewMode()))
1290 {
1291 p->setPen(Qt::black, 0.5/ m_Doc->view()->scale(), Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
1292 p->setPenOpacity(1.0);
1293 p->setBrush(m_Doc->layerMarker(LayerNr));
1294 p->setBrushOpacity(1.0);
1295 p->setFillMode(ScPainter::Solid);
1296 double ofwh = 10;
1297 double ofx = Width - ofwh/2;
1298 double ofy = Height - ofwh*3;
1299 p->drawRect(ofx, ofy, ofwh, ofwh);
1300 }
1301 //CB disabled for now
1302 //if (m_Doc->m_Selection->findItem(this)!=-1)
1303 // drawLockedMarker(p);
1304 }
1305// Tinput = false;
1306 FrameOnly = false;
1307 p->restore();
1308}
1309
1310void PageItem::DrawObj_Embedded(ScPainter *p, QRectF cullingArea, const CharStyle& style, PageItem* cembedded)
1311{
1312 if (!cembedded)
1313 return;
1314 if (!m_Doc->DoDrawing)
1315 return;
1316 QList<PageItem*> emG;
1317 QStack<PageItem*> groupStack;
1318 groupStack.clear();
1319 emG.clear();
1320 emG.append(cembedded);
1321 if (cembedded->Groups.count() != 0)
1322 {
1323 for (int ga=0; ga<m_Doc->FrameItems.count(); ++ga)
1324 {
1325 if (m_Doc->FrameItems.at(ga)->Groups.count() != 0)
1326 {
1327 if (m_Doc->FrameItems.at(ga)->Groups.top() == cembedded->Groups.top())
1328 {
1329 if (m_Doc->FrameItems.at(ga)->ItemNr != cembedded->ItemNr)
1330 {
1331 if (!emG.contains(m_Doc->FrameItems.at(ga)))
1332 emG.append(m_Doc->FrameItems.at(ga));
1333 }
1334 }
1335 }
1336 }
1337 }
1338 for (int em = 0; em < emG.count(); ++em)
1339 {
1340 PageItem* embedded = emG.at(em);
1341 if (embedded->isGroupControl)
1342 {
1343 p->save();
1344 FPointArray cl = embedded->PoLine.copy();
1345 QMatrix mm;
1346 mm.translate((embedded->gXpos * (style.scaleH() / 1000.0)), ( - (embedded->gHeight * (style.scaleV() / 1000.0)) + embedded->gYpos * (style.scaleV() / 1000.0)));
1347 if (style.baselineOffset() != 0)
1348 mm.translate(0, -embedded->gHeight * (style.baselineOffset() / 1000.0));
1349 mm.scale(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
1350 mm.rotate(embedded->rotation());
1351 cl.map( mm );
1352 p->beginLayer(1.0 - embedded->fillTransparency(), embedded->fillBlendmode(), &cl);
1353 groupStack.push(embedded->groupsLastItem);
1354 continue;
1355 }
1356 p->save();
1357 double x = embedded->xPos();
1358 double y = embedded->yPos();
1359 embedded->Xpos = embedded->gXpos;
1360 embedded->Ypos = (embedded->gHeight * (style.scaleV() / 1000.0)) + embedded->gYpos;
1361 p->translate((embedded->gXpos * (style.scaleH() / 1000.0)), ( - (embedded->gHeight * (style.scaleV() / 1000.0)) + embedded->gYpos * (style.scaleV() / 1000.0)));
1362 if (style.baselineOffset() != 0)
1363 {
1364 p->translate(0, -embedded->gHeight * (style.baselineOffset() / 1000.0));
1365 embedded->Ypos -= embedded->gHeight * (style.baselineOffset() / 1000.0);
1366 }
1367 p->scale(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
1368 embedded->Dirty = Dirty;
1369 embedded->invalid = true;
1370 double sc;
1371 double pws = embedded->m_lineWidth;
1372 embedded->DrawObj_Pre(p, sc);
1373 switch(embedded->itemType())
1374 {
1375 case ImageFrame:
1376 case TextFrame:
1377 case LatexFrame:
1378 case Polygon:
1379 case PathText:
1380 embedded->DrawObj_Item(p, cullingArea, sc);
1381 break;
1382 case Line:
1383 case PolyLine:
1384 embedded->m_lineWidth = pws * qMin(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
1385 embedded->DrawObj_Item(p, cullingArea, sc);
1386 break;
1387 default:
1388 break;
1389 }
1390 embedded->m_lineWidth = pws * qMin(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
1391 embedded->DrawObj_Post(p);
1392 embedded->Xpos = x;
1393 embedded->Ypos = y;
1394 p->restore();
1395 if (groupStack.count() != 0)
1396 {
1397 while (embedded == groupStack.top())
1398 {
1399 p->endLayer();
1400 p->restore();
1401 groupStack.pop();
1402 if (groupStack.count() == 0)
1403 break;
1404 }
1405 }
1406 embedded->m_lineWidth = pws;
1407 }
1408 for (int em = 0; em < emG.count(); ++em)
1409 {
1410 PageItem* embedded = emG.at(em);
1411 if (!embedded->isTableItem)
1412 continue;
1413 p->save();
1414 double x = embedded->xPos();
1415 double y = embedded->yPos();
1416 embedded->Xpos = embedded->gXpos;
1417 embedded->Ypos = (embedded->gHeight * (style.scaleV() / 1000.0)) + embedded->gYpos;
1418 p->translate((embedded->gXpos * (style.scaleH() / 1000.0)), ( - (embedded->gHeight * (style.scaleV() / 1000.0)) + embedded->gYpos * (style.scaleV() / 1000.0)));
1419 if (style.baselineOffset() != 0)
1420 {
1421 p->translate(0, -embedded->gHeight * (style.baselineOffset() / 1000.0));
1422 embedded->Ypos -= embedded->gHeight * (style.baselineOffset() / 1000.0);
1423 }
1424 p->scale(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
1425 p->rotate(embedded->rotation());
1426 double pws = embedded->m_lineWidth;
1427 embedded->m_lineWidth = pws * qMin(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
1428 if ((embedded->lineColor() != CommonStrings::None) && (embedded->lineWidth() != 0.0))
1429 {
1430 QColor tmp;
1431 embedded->SetQColor(&tmp, embedded->lineColor(), embedded->lineShade());
1432 if ((embedded->TopLine) || (embedded->RightLine) || (embedded->BottomLine) || (embedded->LeftLine))
1433 {
1434 p->setPen(tmp, embedded->lineWidth(), embedded->PLineArt, Qt::SquareCap, embedded->PLineJoin);
1435 if (embedded->TopLine)
1436 p->drawLine(FPoint(0.0, 0.0), FPoint(embedded->width(), 0.0));
1437 if (embedded->RightLine)
1438 p->drawLine(FPoint(embedded->width(), 0.0), FPoint(embedded->width(), embedded->height()));
1439 if (embedded->BottomLine)
1440 p->drawLine(FPoint(embedded->width(), embedded->height()), FPoint(0.0, embedded->height()));
1441 if (embedded->LeftLine)
1442 p->drawLine(FPoint(0.0, embedded->height()), FPoint(0.0, 0.0));
1443 }
1444 }
1445 embedded->m_lineWidth = pws;
1446 embedded->Xpos = x;
1447 embedded->Ypos = y;
1448 p->restore();
1449 }
1450}
1451
1452
1453void PageItem::paintObj(QPainter *p)
1454{
1455 if ((!m_Doc->DoDrawing) || (m_Doc->RePos))
1456 {
1457 FrameOnly = false;
1458 return;
1459 }
1460 double sc = m_Doc->view()->scale();
1461 double handleSize = 6.0 / sc;
1462 double halfSize = 3.0 / sc;
1463 if ((!FrameOnly) && (!m_Doc->RePos))
1464 {
1465 if (!m_Doc->m_Selection->isEmpty())
1466 {
1467// qDebug() << "Item: " << ItemNr << "W: " << Width << "H: " << Height;
1468 if (Groups.count() == 0)
1469 {
1470 //Locked line colour selection
1471 if (m_Locked)
1472 p->setPen(QPen(PrefsManager::instance()->appPrefs.DFrameLockColor, 1.0 / sc, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
1473 else
1474 p->setPen(QPen(PrefsManager::instance()->appPrefs.DFrameColor, 1.0 / sc, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
1475 p->setBrush(Qt::NoBrush);
1476 double lw2 = 1.0 / sc;
1477 double lw = 1.0 / sc;
1478 Qt::PenCapStyle le = Qt::FlatCap;
1479 if (NamedLStyle.isEmpty())
1480 {
1481 lw2 = (m_lineWidth / 2.0) / sc;
1482 lw = qMax(m_lineWidth, 1.0) / sc;
1483 le = PLineEnd;
1484 }
1485 else
1486 {
1487 multiLine ml = m_Doc->MLineStyles[NamedLStyle];
1488 lw2 = (ml[ml.size()-1].Width / 2.0) / sc;
1489 lw = qMax(ml[ml.size()-1].Width, 1.0) / sc;
1490 le = static_cast<Qt::PenCapStyle>(ml[ml.size()-1].LineEnd);
1491 }
1492 //Draw our frame outline
1493 if (asLine())
1494 {
1495 if (le != Qt::FlatCap)
1496 p->drawRect(QRectF(-lw2, -lw2, Width+lw, lw));
1497 else
1498 p->drawRect(QRectF(-1 / sc, -lw2, Width, lw));
1499 }
1500 else
1501 p->drawRect(QRectF(0, 0, Width, Height));
1502// p->setPen(QPen(PrefsManager::instance()->appPrefs.DFrameColor, 1.0 / sc, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
1503 p->setBrush(PrefsManager::instance()->appPrefs.DFrameColor);
1504 p->setPen(Qt::NoPen);
1505 if ((!m_Locked) && (!m_SizeLocked))
1506 {
1507 if (! asLine())
1508 {
1509 p->drawRect(QRectF(0.0, 0.0, handleSize, handleSize));
1510 p->drawRect(QRectF(Width - handleSize, Height - handleSize, handleSize, handleSize));
1511 p->drawRect(QRectF(Width - handleSize, 0.0, handleSize, handleSize));
1512 p->drawRect(QRectF(0.0, Height - handleSize, handleSize, handleSize));
1513 if (Width > 6)
1514 {
1515 p->drawRect(QRectF(Width / 2.0 - halfSize, Height - handleSize, handleSize, handleSize));
1516 p->drawRect(QRectF(Width / 2.0 - halfSize, 0.0, handleSize, handleSize));
1517 }
1518 if (Height > 6)
1519 {
1520 p->drawRect(QRectF(Width - handleSize, Height / 2.0 - halfSize, handleSize, handleSize));
1521 p->drawRect(QRectF(0.0, Height / 2.0 - halfSize, handleSize, handleSize));
1522 }
1523 }
1524 else
1525 {
1526 p->drawRect(QRectF(-halfSize, -halfSize, handleSize, handleSize));
1527 p->drawRect(QRectF(Width + halfSize, -halfSize, -handleSize, handleSize));
1528 }
1529 }
1530 }
1531 else
1532 {
1533 p->setPen(QPen(PrefsManager::instance()->appPrefs.DFrameGroupColor, 1.0 / sc, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
1534 p->setBrush(Qt::NoBrush);
1535 p->drawRect(QRectF(0.0, 0.0, Width, Height));
1536 if (m_Doc->m_Selection->count() == 1)
1537 {
1538 p->setPen(Qt::NoPen);
1539// p->setPen(QPen(PrefsManager::instance()->appPrefs.DFrameGroupColor, 1.0 / sc, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
1540 p->setBrush(PrefsManager::instance()->appPrefs.DFrameGroupColor);
1541 p->drawRect(QRectF(0.0, 0.0, handleSize, handleSize));
1542 p->drawRect(QRectF(Width - handleSize, Height - handleSize, handleSize, handleSize));
1543 p->drawRect(QRectF(Width - handleSize, 0.0, handleSize, handleSize));
1544 p->drawRect(QRectF(0.0, Height - handleSize, handleSize, handleSize));
1545 if (Width > 6)
1546 {
1547 p->drawRect(QRectF(Width / 2.0 - halfSize, Height - handleSize, handleSize, handleSize));
1548 p->drawRect(QRectF(Width / 2.0 - halfSize, 0.0, handleSize, handleSize));
1549 }
1550 if (Height > 6)
1551 {
1552 p->drawRect(QRectF(Width - handleSize, Height / 2.0 - halfSize, handleSize, handleSize));
1553 p->drawRect(QRectF(0.0, Height / 2.0 - halfSize, handleSize, handleSize));
1554 }
1555 }
1556 }
1557 }
1558 }
1559 FrameOnly = false;
1560}
1561
1562QImage PageItem::DrawObj_toImage()
1563{
1564 QList<PageItem*> emG;
1565 emG.clear();
1566 double minx = std::numeric_limits<double>::max();
1567 double miny = std::numeric_limits<double>::max();
1568 double maxx = -std::numeric_limits<double>::max();
1569 double maxy = -std::numeric_limits<double>::max();
1570 if (Groups.count() != 0)
1571 {
1572 for (int ga=0; ga<m_Doc->Items->count(); ++ga)
1573 {
1574 if (m_Doc->Items->at(ga)->Groups.count() != 0)
1575 {
1576 if (m_Doc->Items->at(ga)->Groups.top() == Groups.top())
1577 {
1578 if (!emG.contains(m_Doc->Items->at(ga)))
1579 {
1580 emG.append(m_Doc->Items->at(ga));
1581 PageItem *currItem = m_Doc->Items->at(ga);
1582 double x1, x2, y1, y2;
1583 currItem->getVisualBoundingRect(&x1, &y1, &x2, &y2);
1584 minx = qMin(minx, x1);
1585 miny = qMin(miny, y1);
1586 maxx = qMax(maxx, x2);
1587 maxy = qMax(maxy, y2);
1588 }
1589 }
1590 }
1591 }
1592 for (int em = 0; em < emG.count(); ++em)
1593 {
1594 PageItem* currItem = emG.at(em);
1595 currItem->gXpos = currItem->xPos() - minx;
1596 currItem->gYpos = currItem->yPos() - miny;
1597 currItem->gWidth = maxx - minx;
1598 currItem->gHeight = maxy - miny;
1599 }
1600 }
1601 else
1602 {
1603 double x1, x2, y1, y2;
1604 getVisualBoundingRect(&x1, &y1, &x2, &y2);
1605 minx = qMin(minx, x1);
1606 miny = qMin(miny, y1);
1607 maxx = qMax(maxx, x2);
1608 maxy = qMax(maxy, y2);
1609 gXpos = xPos() - minx;
1610 gYpos = yPos() - miny;
1611 gWidth = maxx - minx;
1612 gHeight = maxy - miny;
1613 emG.append(this);
1614 }
1615 return DrawObj_toImage(emG);
1616}
1617
1618QImage PageItem::DrawObj_toImage(QList<PageItem*> &emG)
1619{
1620 QImage retImg = QImage(qRound(gWidth), qRound(gHeight), QImage::Format_ARGB32);
1621// retImg.fill( qRgba(255, 255, 255, 0) );
1622 retImg.fill( qRgba(0, 0, 0, 0) );
1623 ScPainter *painter = new ScPainter(&retImg, retImg.width(), retImg.height(), 1, 0);
1624// painter->setZoomFactor(1.0);
1625 painter->setZoomFactor(qMax(qRound(gWidth) / gWidth, qRound(gHeight) / gHeight));
1626 QStack<PageItem*> groupStack;
1627 for (int em = 0; em < emG.count(); ++em)
1628 {
1629 PageItem* embedded = emG.at(em);
1630 if (embedded->isGroupControl)
1631 {
1632 painter->save();
1633 FPointArray cl = embedded->PoLine.copy();
1634 QMatrix mm;
1635 mm.translate(embedded->gXpos, embedded->gYpos);
1636 mm.rotate(embedded->rotation());
1637 cl.map( mm );
1638 painter->beginLayer(1.0 - embedded->fillTransparency(), embedded->fillBlendmode(), &cl);
1639 groupStack.push(embedded->groupsLastItem);
1640 continue;
1641 }
1642 painter->save();
1643// qDebug()<<embedded<<embedded->xPos()<<embedded->yPos()<<embedded->gXpos<<embedded->gYpos;
1644// double x = embedded->xPos();
1645// double y = embedded->yPos();
1646// embedded->Xpos = embedded->gXpos;
1647// embedded->Ypos = embedded->gYpos;
1648 // Seems to work without all this coordinates mess. To monitor tho
1649 painter->translate(embedded->gXpos, embedded->gYpos);
1650 embedded->isEmbedded = true;
1651 embedded->invalid = true;
1652 embedded->DrawObj(painter, QRectF());
1653// embedded->Xpos = x;
1654// embedded->Ypos = y;
1655 embedded->isEmbedded = false;
1656 painter->restore();
1657 if (groupStack.count() != 0)
1658 {
1659 while (embedded == groupStack.top())
1660 {
1661 painter->endLayer();
1662 painter->restore();
1663 groupStack.pop();
1664 if (groupStack.count() == 0)
1665 break;
1666 }
1667 }
1668 }
1669 for (int em = 0; em < emG.count(); ++em)
1670 {
1671 PageItem* embedded = emG.at(em);
1672 if (!embedded->isTableItem)
1673 continue;
1674 painter->save();
1675// double x = embedded->xPos();
1676// double y = embedded->yPos();
1677// embedded->Xpos = embedded->gXpos;
1678// embedded->Ypos = embedded->gYpos;
1679 painter->translate(embedded->gXpos, embedded->gYpos);
1680 painter->rotate(embedded->rotation());
1681 embedded->isEmbedded = true;
1682 embedded->invalid = true;
1683 if ((embedded->lineColor() != CommonStrings::None) && (embedded->lineWidth() != 0.0))
1684 {
1685 QColor tmp;
1686 embedded->SetQColor(&tmp, embedded->lineColor(), embedded->lineShade());
1687 if ((embedded->TopLine) || (embedded->RightLine) || (embedded->BottomLine) || (embedded->LeftLine))
1688 {
1689 painter->setPen(tmp, embedded->lineWidth(), embedded->PLineArt, Qt::SquareCap, embedded->PLineJoin);
1690 if (embedded->TopLine)
1691 painter->drawLine(FPoint(0.0, 0.0), FPoint(embedded->width(), 0.0));
1692 if (embedded->RightLine)
1693 painter->drawLine(FPoint(embedded->width(), 0.0), FPoint(embedded->width(), embedded->height()));
1694 if (embedded->BottomLine)
1695 painter->drawLine(FPoint(embedded->width(), embedded->height()), FPoint(0.0, embedded->height()));
1696 if (embedded->LeftLine)
1697 painter->drawLine(FPoint(0.0, embedded->height()), FPoint(0.0, 0.0));
1698 }
1699 }
1700 embedded->isEmbedded = false;
1701// embedded->Xpos = x;
1702// embedded->Ypos = y;
1703 painter->restore();
1704 }
1705 painter->end();
1706 delete painter;
1707 return retImg;
1708}
1709
1710QString PageItem::ExpandToken(uint base)
1711{
1712 uint zae = 0;
1713 QChar ch = itemText.text(base);
1714 QString chstr = ch;
1715 if (ch == SpecialChars::PAGENUMBER)
1716 {
1717 // compatibility mode: ignore subsequent pagenumber chars
1718 if (base > 0 && itemText.text(base-1) == SpecialChars::PAGENUMBER)
1719 return "";
1720 if ((!m_Doc->masterPageMode()) && (OwnPage != -1))
1721 {
1722 QString out("%1");
1723 //CB Section numbering
1724 chstr = out.arg(m_Doc->getSectionPageNumberForPageIndex(OwnPage), -(int)zae);
1725 }
1726 else
1727 return "#";
1728 }
1729 else if (ch == SpecialChars::PAGECOUNT)
1730 {
1731 if (!m_Doc->masterPageMode())
1732 {
1733 QString out("%1");
1734 int key = m_Doc->getSectionKeyForPageIndex(OwnPage);
1735 if (key == -1)
1736 return "%";
1737 chstr = out.arg(getStringFromSequence(m_Doc->sections[key].type, m_Doc->sections[key].toindex - m_Doc->sections[key].fromindex + 1));
1738 }
1739 else
1740 return "%";
1741 }
1742 return chstr;
1743}
1744
1745void PageItem::SetQColor(QColor *tmp, QString farbe, double shad)
1746{
1747 const ScColor& col = m_Doc->PageColors[farbe];
1748 *tmp = ScColorEngine::getShadeColorProof(col, m_Doc, shad);
1749 if ((m_Doc->view()) && (m_Doc->view()->m_canvas->usePreviewVisual()))
1750 {
1751 VisionDefectColor defect;
1752 *tmp = defect.convertDefect(*tmp, m_Doc->view()->m_canvas->previewVisual());
1753 }
1754}
1755
1756/**
1757 layout glyphs translates the chars into a number of glyphs, applying the Charstyle
1758 'style'. The following fields are set in layout: glyph, more, scaleH, scaleV, xoffset, yoffset, xadvance.
1759 If the DropCap-bit in style.effects is set and yadvance is > 0, scaleH/V, x/yoffset and xadvance
1760 are modified to scale the glyphs to this height.
1761 Otherwise yadvance is set to the max ascender of all generated glyphs.
1762 It scales according to smallcaps and
1763 sets xadvance to the advance width without kerning. If more than one glyph
1764 is generated, kerning is included in all but the last xadvance.
1765*/
1766double PageItem::layoutGlyphs(const CharStyle& style, const QString& chars, GlyphLayout& layout)
1767{
1768 double retval = 0.0;
1769 double asce = style.font().ascent(style.fontSize() / 10.0);
1770 int chst = style.effects() & 1919;
1771/* if (chars[0] == SpecialChars::ZWSPACE ||
1772 chars[0] == SpecialChars::ZWNBSPACE ||
1773 chars[0] == SpecialChars::NBSPACE ||
1774 chars[0] == SpecialChars::NBHYPHEN ||
1775 chars[0] == SpecialChars::SHYPHEN ||
1776 chars[0] == SpecialChars::PARSEP ||
1777 chars[0] == SpecialChars::COLBREAK ||
1778 chars[0] == SpecialChars::LINEBREAK ||
1779 chars[0] == SpecialChars::FRAMEBREAK ||
1780 chars[0] == SpecialChars::TAB)
1781 {
1782 layout.glyph = ScFace::CONTROL_GLYPHS + chars[0].unicode();
1783 }
1784 else */
1785 {
1786 layout.glyph = style.font().char2CMap(chars[0].unicode());
1787 }
1788
1789 double tracking = 0.0;
1790 if ( (style.effects() & ScStyle_StartOfLine) == 0)
1791 tracking = style.fontSize() * style.tracking() / 10000.0;
1792
1793 layout.xoffset = tracking;
1794 layout.yoffset = 0;
1795 if (chst != ScStyle_Default)
1796 {
1797 if (chst & ScStyle_Superscript)
1798 {
1799 retval -= asce * m_Doc->typographicSettings.valueSuperScript / 100.0;
1800 layout.yoffset -= asce * m_Doc->typographicSettings.valueSuperScript / 100.0;
1801 layout.scaleV = layout.scaleH = qMax(m_Doc->typographicSettings.scalingSuperScript / 100.0, 10.0 / style.fontSize());
1802 }
1803 else if (chst & ScStyle_Subscript)
1804 {
1805 retval += asce * m_Doc->typographicSettings.valueSubScript / 100.0;
1806 layout.yoffset += asce * m_Doc->typographicSettings.valueSubScript / 100.0;
1807 layout.scaleV = layout.scaleH = qMax(m_Doc->typographicSettings.scalingSubScript / 100.0, 10.0 / style.fontSize());
1808 }
1809 else {
1810 layout.scaleV = layout.scaleH = 1.0;
1811 }
1812 layout.scaleH *= style.scaleH() / 1000.0;
1813 layout.scaleV *= style.scaleV() / 1000.0;
1814 if (chst & ScStyle_AllCaps)
1815 {
1816 layout.glyph = style.font().char2CMap(chars[0].toUpper().unicode());
1817 }
1818 if (chst & ScStyle_SmallCaps)
1819 {
1820 double smallcapsScale = m_Doc->typographicSettings.valueSmallCaps / 100.0;
1821 QChar uc = chars[0].toUpper();
1822 if (uc != chars[0])
1823 {
1824 layout.glyph = style.font().char2CMap(chars[0].toUpper().unicode());
1825 layout.scaleV *= smallcapsScale;
1826 layout.scaleH *= smallcapsScale;
1827 }
1828 }
1829 }
1830 else {
1831 layout.scaleH = style.scaleH() / 1000.0;
1832 layout.scaleV = style.scaleV() / 1000.0;
1833 }
1834
1835/* if (layout.glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBSPACE.unicode())) {
1836 uint replGlyph = style.font().char2CMap(QChar(' '));
1837 layout.xadvance = style.font().glyphWidth(replGlyph, style.fontSize() / 10) * layout.scaleH;
1838 layout.yadvance = style.font().glyphBBox(replGlyph, style.fontSize() / 10).ascent * layout.scaleV;
1839 }
1840 else if (layout.glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBHYPHEN.unicode())) {
1841 uint replGlyph = style.font().char2CMap(QChar('-'));
1842 layout.xadvance = style.font().glyphWidth(replGlyph, style.fontSize() / 10) * layout.scaleH;
1843 layout.yadvance = style.font().glyphBBox(replGlyph, style.fontSize() / 10).ascent * layout.scaleV;
1844 }
1845 else if (layout.glyph >= ScFace::CONTROL_GLYPHS) {
1846 layout.xadvance = 0;
1847 layout.yadvance = 0;
1848 }
1849 else */
1850 {
1851 layout.xadvance = style.font().glyphWidth(layout.glyph, style.fontSize() / 10) * layout.scaleH;
1852 layout.yadvance = style.font().glyphBBox(layout.glyph, style.fontSize() / 10).ascent * layout.scaleV;
1853 }
1854 if (layout.xadvance > 0)
1855 layout.xadvance += tracking;
1856
1857 if (chars.length() > 1) {
1858 layout.grow();
1859 layoutGlyphs(style, chars.mid(1), *layout.more);
1860 layout.xadvance += style.font().glyphKerning(layout.glyph, layout.more->glyph, style.fontSize() / 10) * layout.scaleH;
1861 if (layout.more->yadvance > layout.yadvance)
1862 layout.yadvance = layout.more->yadvance;
1863 }
1864 else {
1865 layout.shrink();
1866 }
1867 return retval;
1868}
1869
1870void PageItem::drawGlyphs(ScPainter *p, const CharStyle& style, GlyphLayout& glyphs)
1871{
1872 uint glyph = glyphs.glyph;
1873 if ((m_Doc->guidesSettings.showControls) &&
1874 (glyph == style.font().char2CMap(QChar(' ')) || glyph >= ScFace::CONTROL_GLYPHS))
1875 {
1876 bool stroke = false;
1877 if (glyph >= ScFace::CONTROL_GLYPHS)
1878 glyph -= ScFace::CONTROL_GLYPHS;
1879 else
1880 glyph = 32;
1881 QMatrix chma, chma4, chma5;
1882 FPointArray points;
1883 if (glyph == SpecialChars::TAB.unicode())
1884 {
1885 points = m_Doc->symTab.copy();
1886 chma4.translate(glyphs.xoffset + glyphs.xadvance - ((style.fontSize() / 10.0) * glyphs.scaleH * 0.7), glyphs.yoffset - ((style.fontSize() / 10.0) * glyphs.scaleV * 0.5));
1887 }
1888 else if (glyph == SpecialChars::COLBREAK.unicode())
1889 {
1890 points = m_Doc->symNewCol.copy();
1891 chma4.translate(glyphs.xoffset, glyphs.yoffset-((style.fontSize() / 10.0) * glyphs.scaleV * 0.6));
1892 }
1893 else if (glyph == SpecialChars::FRAMEBREAK.unicode())
1894 {
1895 points = m_Doc->symNewFrame.copy();
1896 chma4.translate(glyphs.xoffset, glyphs.yoffset-((style.fontSize() / 10.0) * glyphs.scaleV * 0.6));
1897 }
1898 else if (glyph == SpecialChars::PARSEP.unicode())
1899 {
1900 points = m_Doc->symReturn.copy();
1901 chma4.translate(glyphs.xoffset, glyphs.yoffset-((style.fontSize() / 10.0) * glyphs.scaleV * 0.8));
1902 }
1903 else if (glyph == SpecialChars::LINEBREAK.unicode())
1904 {
1905 points = m_Doc->symNewLine.copy();
1906 chma4.translate(glyphs.xoffset, glyphs.yoffset-((style.fontSize() / 10.0) * glyphs.scaleV * 0.4));
1907 }
1908 else if (glyph == SpecialChars::NBSPACE.unicode() ||
1909 glyph == 32)
1910 {
1911 stroke = (glyph == 32);
1912 points = m_Doc->symNonBreak.copy();
1913 chma4.translate(glyphs.xoffset, glyphs.yoffset-((style.fontSize() / 10.0) * glyphs.scaleV * 0.4));
1914 }
1915 else if (glyph == SpecialChars::NBHYPHEN.unicode())
1916 {
1917 points = style.font().glyphOutline(style.font().char2CMap(QChar('-')), style.fontSize() / 100);
1918 chma4.translate(glyphs.xoffset, glyphs.yoffset-((style.fontSize() / 10.0) * glyphs.scaleV));
1919 }
1920 else if (glyph == SpecialChars::SHYPHEN.unicode())
1921 {
1922 points.resize(0);
1923 points.addQuadPoint(0, -10, 0, -10, 0, -6, 0, -6);
1924 stroke = true;
1925 }
1926 else // ???
1927 {
1928 points.resize(0);
1929 points.addQuadPoint(0, -10, 0, -10, 0, -9, 0, -9);
1930 points.addQuadPoint(0, -9, 0, -9, 1, -9, 1, -9);
1931 points.addQuadPoint(1, -9, 1, -9, 1, -10, 1, -10);
1932 points.addQuadPoint(1, -10, 1, -10, 0, -10, 0, -10);
1933 }
1934 chma.scale(glyphs.scaleH * style.fontSize() / 100.0, glyphs.scaleV * style.fontSize() / 100.0);
1935 points.map(chma * chma4);
1936 p->setupPolygon(&points, true);
1937 QColor oldBrush = p->brush();
1938 p->setBrush( (style.effects() & ScStyle_SuppressSpace) ? Qt::green
1939 : PrefsManager::instance()->appPrefs.DControlCharColor);
1940 if (stroke)
1941 {
1942 QColor tmp = p->pen();
1943 p->setPen(p->brush(), 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
1944 p->setLineWidth(style.fontSize() * glyphs.scaleV / 200.0);
1945 p->strokePath();
1946 p->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
1947 }
1948 else
1949 {
1950 p->setFillMode(1);
1951 p->fillPath();
1952 }
1953 p->setBrush(oldBrush);
1954 if (glyphs.more)
1955 {
1956 p->translate(glyphs.xadvance, 0);
1957 drawGlyphs(p, style, *glyphs.more);
1958 }
1959 return;
1960 }
1961 else if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBSPACE.unicode()) ||
1962 glyph == (ScFace::CONTROL_GLYPHS + 32))
1963 glyph = style.font().char2CMap(QChar(' '));
1964 else if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBHYPHEN.unicode()))
1965 glyph = style.font().char2CMap(QChar('-'));
1966
1967 if (glyph >= ScFace::CONTROL_GLYPHS || (style.effects() & ScStyle_SuppressSpace)) {
1968// qDebug("drawGlyphs: skipping %d", glyph);
1969 // all those are empty
1970 if (glyphs.more)
1971 {
1972 p->translate(glyphs.xadvance, 0);
1973 drawGlyphs(p, style, *glyphs.more);
1974 }
1975 return;
1976 }
1977// if (style.font().canRender(QChar(glyph)))
1978 {
1979 FPointArray gly = style.font().glyphOutline(glyph);
1980 // Do underlining first so you can get typographically correct
1981 // underlines when drawing a white outline
1982 if (((style.effects() & ScStyle_Underline) || ((style.effects() & ScStyle_UnderlineWords) && glyph != style.font().char2CMap(QChar(' ')))) && (style.strokeColor() != CommonStrings::None))
1983 {
1984 double st, lw;
1985 if ((style.underlineOffset() != -1) || (style.underlineWidth() != -1))
1986 {
1987 if (style.underlineOffset() != -1)
1988 st = (style.underlineOffset() / 1000.0) * (style.font().descent(style.fontSize() / 10.0));
1989 else
1990 st = style.font().underlinePos(style.fontSize() / 10.0);
1991 if (style.underlineWidth() != -1)
1992 lw = (style.underlineWidth() / 1000.0) * (style.fontSize() / 10.0);
1993 else
1994 lw = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
1995 }
1996 else
1997 {
1998 st = style.font().underlinePos(style.fontSize() / 10.0);
1999 lw = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
2000 }
2001 if (style.baselineOffset() != 0)
2002 st += (style.fontSize() / 10.0) * glyphs.scaleV * (style.baselineOffset() / 1000.0);
2003 QColor tmpC = p->pen();
2004 p->setPen(p->brush());
2005 p->setLineWidth(lw);
2006 if (style.effects() & ScStyle_Subscript)
2007 p->drawLine(FPoint(glyphs.xoffset, glyphs.yoffset - st), FPoint(glyphs.xoffset + glyphs.xadvance, glyphs.yoffset - st));
2008 else
2009 p->drawLine(FPoint(glyphs.xoffset, -st), FPoint(glyphs.xoffset + glyphs.xadvance, -st));
2010 p->setPen(tmpC);
2011 }
2012 if (gly.size() > 3)
2013 {
2014 if (glyph == 0)
2015 {
2016// qDebug() << QString("glyph 0: (%1,%2) * %3 %4 + %5").arg(glyphs.xoffset).arg(glyphs.yoffset).arg(glyphs.scaleH).arg(glyphs.scaleV).arg(glyphs.xadvance));
2017 }
2018 p->save();
2019 p->translate(glyphs.xoffset, glyphs.yoffset - ((style.fontSize() / 10.0) * glyphs.scaleV));
2020 if (Reverse)
2021 {
2022 p->scale(-1, 1);
2023 p->translate(-glyphs.xadvance, 0);
2024 }
2025 if (style.baselineOffset() != 0)
2026 p->translate(0, -(style.fontSize() / 10.0) * (style.baselineOffset() / 1000.0));
2027 double glxSc = glyphs.scaleH * style.fontSize() / 100.00;
2028 double glySc = glyphs.scaleV * style.fontSize() / 100.0;
2029 p->scale(glxSc, glySc);
2030// p->setFillMode(1);
2031 bool fr = p->fillRule();
2032 p->setFillRule(false);
2033// double a = gly.point(0).x();
2034// double b = gly.point(0).y();
2035// double c = gly.point(3).x();
2036// double d = gly.point(3).y();
2037// qDebug() << QString("drawglyphs: %1 (%2,%3) (%4,%5) scaled %6,%7 trans %8,%9")
2038// .arg(gly.size()).arg(a).arg(b).arg(c).arg(d)
2039// .arg(p->worldMatrix().m11()).arg(p->worldMatrix().m22()).arg(p->worldMatrix().dx()).arg(p->worldMatrix().dy());
2040 p->setupPolygon(&gly, true);
2041 if (m_Doc->layerOutline(LayerNr))
2042 {
2043 p->save();
2044 p->setPen(m_Doc->layerMarker(LayerNr), 0.5, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
2045 p->setFillMode(ScPainter::None);
2046 p->setBrushOpacity(1.0);
2047 p->setPenOpacity(1.0);
2048 p->strokePath();
2049 p->restore();
2050 p->setFillRule(fr);
2051 p->restore();
2052 if (glyphs.more)
2053 {
2054 p->translate(glyphs.xadvance, 0);
2055 drawGlyphs(p, style, *glyphs.more);
2056 }
2057 return;
2058 }
2059 if (glyph == 0)
2060 {
2061 p->setPen(PrefsManager::instance()->appPrefs.DControlCharColor, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
2062 p->setLineWidth(style.fontSize() * glyphs.scaleV * style.outlineWidth() * 2 / 10000.0);
2063 p->strokePath();
2064 }
2065 else if ((style.font().isStroked()) && (style.strokeColor() != CommonStrings::None) && ((style.fontSize() * glyphs.scaleV * style.outlineWidth() / 10000.0) != 0))
2066 {
2067 QColor tmp = p->brush();
2068 p->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
2069 p->setLineWidth(style.fontSize() * glyphs.scaleV * style.outlineWidth() / 10000.0);
2070 p->strokePath();
2071 }
2072 else
2073 {
2074 if ((style.effects() & ScStyle_Shadowed) && (style.strokeColor() != CommonStrings::None))
2075 {
2076 p->save();
2077 p->translate((style.fontSize() * glyphs.scaleH * style.shadowXOffset() / 10000.0) / glxSc, -(style.fontSize() * glyphs.scaleV * style.shadowYOffset() / 10000.0) / glySc);
2078 QColor tmp = p->brush();
2079 p->setBrush(p->pen());
2080 p->setupPolygon(&gly, true);
2081 p->fillPath();
2082 p->setBrush(tmp);
2083 p->restore();
2084 p->setupPolygon(&gly, true);
2085 }
2086 if (style.fillColor() != CommonStrings::None)
2087 p->fillPath();
2088 if ((style.effects() & ScStyle_Outline) && (style.strokeColor() != CommonStrings::None) && ((style.fontSize() * glyphs.scaleV * style.outlineWidth() / 10000.0) != 0))
2089 {
2090 p->setLineWidth((style.fontSize() * glyphs.scaleV * style.outlineWidth() / 10000.0) / glySc);
2091 p->strokePath();
2092 }
2093 }
2094 p->setFillRule(fr);
2095 p->restore();
2096 }
2097 else {
2098// qDebug() << "drawGlyphs: empty glyph" << glyph;
2099 }
2100 if ((style.effects() & ScStyle_Strikethrough) && (style.strokeColor() != CommonStrings::None))
2101 {
2102 double st, lw;
2103 if ((style.strikethruOffset() != -1) || (style.strikethruWidth() != -1))
2104 {
2105 if (style.strikethruOffset() != -1)
2106 st = (style.strikethruOffset() / 1000.0) * (style.font().ascent(style.fontSize() / 10.0));
2107 else
2108 st = style.font().strikeoutPos(style.fontSize() / 10.0);
2109 if (style.strikethruWidth() != -1)
2110 lw = (style.strikethruWidth() / 1000.0) * (style.fontSize() / 10.0);
2111 else
2112 lw = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
2113 }
2114 else
2115 {
2116 st = style.font().strikeoutPos(style.fontSize() / 10.0);
2117 lw = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
2118 }
2119 if (style.baselineOffset() != 0)
2120 st += (style.fontSize() / 10.0) * glyphs.scaleV * (style.baselineOffset() / 1000.0);
2121 p->setPen(p->brush());
2122 p->setLineWidth(lw);
2123 p->drawLine(FPoint(glyphs.xoffset, glyphs.yoffset - st), FPoint(glyphs.xoffset + glyphs.xadvance, glyphs.yoffset - st));
2124 }
2125 }
2126/* else
2127 {
2128 p->setLineWidth(1);
2129 p->setPen(red);
2130 p->setBrush(red);
2131 p->setFillMode(1);
2132 p->drawRect(glyphs.xoffset, glyphs.yoffset - (style.fontSize() / 10.0) * glyphs.scaleV , (style.fontSize() / 10.0) * glyphs.scaleH, (style.fontSize() / 10.0) * glyphs.scaleV);
2133 }
2134 */
2135 if (glyphs.more)
2136 {
2137 p->translate(glyphs.xadvance, 0);
2138 drawGlyphs(p, style, *glyphs.more);
2139 }
2140}
2141
2142void PageItem::DrawPolyL(QPainter *p, QPolygon pts)
2143{
2144 if (Segments.count() != 0)
2145 {
2146 QList<uint>::Iterator it2end=Segments.end();
2147 uint FirstVal = 0;
2148 for (QList<uint>::Iterator it2 = Segments.begin(); it2 != it2end; ++it2)
2149 {
2150 p->drawPolygon(pts.constData() + FirstVal, (*it2)-FirstVal);
2151 FirstVal = (*it2);
2152 }
2153 p->drawPolygon(pts.constData() + FirstVal, pts.size() - FirstVal);
2154 }
2155 else
2156 p->drawPolygon(pts);
2157/*
2158 QColor tmp;
2159 if (Segments.count() != 0)
2160 {
2161 QList<uint>::Iterator it2end=Segments.end();
2162 uint FirstVal = 0;
2163 for (QList<uint>::Iterator it2 = Segments.begin(); it2 != it2end; ++it2)
2164 {
2165 if (NamedLStyle.isEmpty())
2166 {
2167 if (lineColor() != CommonStrings::None)
2168 p->setPen(QPen(strokeQColor, m_lineWidth, PLineArt, PLineEnd, PLineJoin));
2169 p->drawPolygon(pts.constData() + FirstVal, (*it2)-FirstVal);
2170 }
2171 else
2172 {
2173 multiLine ml = m_Doc->MLineStyles[NamedLStyle];
2174 for (int it = ml.size()-1; it > -1; it--)
2175 {
2176 SetQColor(&tmp, ml[it].Color, ml[it].Shade);
2177 p->setPen(QPen(tmp,
2178 qMax(static_cast<int>(ml[it].Width), 1),
2179 static_cast<Qt::PenStyle>(ml[it].Dash),
2180 static_cast<Qt::PenCapStyle>(ml[it].LineEnd),
2181 static_cast<Qt::PenJoinStyle>(ml[it].LineJoin)));
2182 p->drawPolygon(pts.constData() + FirstVal, (*it2)-FirstVal);
2183 }
2184 }
2185 FirstVal = (*it2);
2186 }
2187 if (NamedLStyle.isEmpty())
2188 {
2189 if (lineColor() != CommonStrings::None)
2190 p->setPen(QPen(strokeQColor, m_lineWidth, PLineArt, PLineEnd, PLineJoin));
2191 p->drawPolygon(pts.constData() + FirstVal, pts.size() - FirstVal);
2192 }
2193 else
2194 {
2195 multiLine ml = m_Doc->MLineStyles[NamedLStyle];
2196 for (int it = ml.size()-1; it > -1; it--)
2197 {
2198 SetQColor(&tmp, ml[it].Color, ml[it].Shade);
2199 p->setPen(QPen(tmp,
2200 qMax(static_cast<int>(ml[it].Width), 1),
2201 static_cast<Qt::PenStyle>(ml[it].Dash),
2202 static_cast<Qt::PenCapStyle>(ml[it].LineEnd),
2203 static_cast<Qt::PenJoinStyle>(ml[it].LineJoin)));
2204 p->drawPolygon(pts.constData() + FirstVal, pts.size() - FirstVal);
2205 }
2206 }
2207 }
2208 else
2209 {
2210 if (NamedLStyle.isEmpty())
2211 {
2212 if (lineColor() != CommonStrings::None)
2213 p->setPen(QPen(strokeQColor, m_lineWidth, PLineArt, PLineEnd, PLineJoin));
2214 p->drawPolygon(pts);
2215 }
2216 else
2217 {
2218 multiLine ml = m_Doc->MLineStyles[NamedLStyle];
2219 for (int it = ml.size()-1; it > -1; it--)
2220 {
2221 SetQColor(&tmp, ml[it].Color, ml[it].Shade);
2222 p->setPen(QPen(tmp,
2223 qMax(static_cast<int>(ml[it].Width), 1),
2224 static_cast<Qt::PenStyle>(ml[it].Dash),
2225 static_cast<Qt::PenCapStyle>(ml[it].LineEnd),
2226 static_cast<Qt::PenJoinStyle>(ml[it].LineJoin)));
2227 p->drawPolygon(pts);
2228 }
2229 }
2230 } */
2231}
2232
2233void PageItem::setItemName(const QString& newName)
2234{
2235 if (AnName == newName)
2236 return; // nothing to do -> return
2237 if (newName.isEmpty())
2238 return;
2239 QString oldName = AnName;
2240 AnName = generateUniqueCopyName(newName);
2241 AutoName = false;
2242 if (UndoManager::undoEnabled())
2243 {
2244 SimpleState *ss = new SimpleState(Um::Rename, QString(Um::FromTo).arg(AnName).arg(newName));
2245 ss->set("OLD_NAME", oldName);
2246 ss->set("NEW_NAME", newName);
2247 undoManager->action(this, ss);
2248 }
2249 setUName(AnName); // set the name for the UndoObject too
2250}
2251
2252void PageItem::setPattern(const QString &newPattern)
2253{
2254 if (patternVal != newPattern)
2255 patternVal = newPattern;
2256}
2257
2258void PageItem::gradientVector(double& startX, double& startY, double& endX, double& endY) const
2259{
2260 startX = GrStartX;
2261 startY = GrStartY;
2262 endX = GrEndX;
2263 endY = GrEndY;
2264}
2265
2266void PageItem::setGradientVector(double startX, double startY, double endX, double endY)
2267{
2268 GrStartX = startX;
2269 GrStartY = startY;
2270 GrEndX = endX;
2271 GrEndY = endY;
2272}
2273
2274void PageItem::setPatternTransform(double scaleX, double scaleY, double offsetX, double offsetY, double rotation)
2275{
2276 patternScaleX = scaleX;
2277 patternScaleY = scaleY;
2278 patternOffsetX = offsetX;
2279 patternOffsetY = offsetY;
2280 patternRotation = rotation;
2281}
2282
2283void PageItem::patternTransform(double &scaleX, double &scaleY, double &offsetX, double &offsetY, double &rotation) const
2284{
2285 scaleX = patternScaleX;
2286 scaleY = patternScaleY;
2287 offsetX = patternOffsetX;
2288 offsetY = patternOffsetY;
2289 rotation = patternRotation;
2290}
2291
2292void PageItem::setFillColor(const QString &newColor)
2293{
2294 QString tmp = newColor;
2295 if (tmp != CommonStrings::None)
2296 {
2297 if (!m_Doc->PageColors.contains(newColor))
2298 {
2299 switch(itemType())
2300 {
2301 case ImageFrame:
2302 case LatexFrame:
2303 tmp = m_Doc->toolSettings.dBrushPict;
2304 case TextFrame:
2305 case PathText:
2306 tmp = m_Doc->toolSettings.dTextBackGround;
2307 break;
2308 case Line:
2309 case PolyLine:
2310 case Polygon:
2311 tmp = m_Doc->toolSettings.dBrush;
2312 break;
2313 default:
2314 break;
2315 }
2316 }
2317 }
2318 if (fillColorVal == tmp)
2319 {
2320 setFillQColor();
2321 return;
2322 }
2323 if (UndoManager::undoEnabled())
2324 {
2325 SimpleState *ss = new SimpleState(Um::SetFill,
2326 QString(Um::ColorFromTo).arg(fillColorVal).arg(tmp),
2327 Um::IFill);
2328 ss->set("FILL", "fill");
2329 ss->set("OLD_FILL", fillColorVal);
2330 ss->set("NEW_FILL", tmp);
2331 undoManager->action(this, ss);
2332 }
2333 fillColorVal = tmp;
2334 if (GrType == 0)
2335 {
2336 fill_gradient = VGradient(VGradient::linear);
2337 fill_gradient.clearStops();
2338 if (fillColorVal != CommonStrings::None)
2339 {
2340 const ScColor& col = m_Doc->PageColors[fillColorVal];
2341 fill_gradient.addStop(ScColorEngine::getRGBColor(col, m_Doc), 0.0, 0.5, 1.0, fillColorVal, 100);
2342 fill_gradient.addStop(ScColorEngine::getRGBColor(col, m_Doc), 1.0, 0.5, 1.0, fillColorVal, 100);
2343 }
2344 }
2345 setFillQColor();
2346//CB unused in 135 emit colors(lineColorVal, fillColorVal, lineShadeVal, fillShadeVal);
2347}
2348
2349void PageItem::setFillShade(double newShade)
2350{
2351 if (fillShadeVal == newShade)
2352 {
2353 setFillQColor();
2354 return;
2355 }
2356 if (UndoManager::undoEnabled())
2357 {
2358 SimpleState *ss = new SimpleState(Um::SetShade,
2359 QString(Um::FromTo).arg(fillShadeVal).arg(newShade),
2360 Um::IShade);
2361 ss->set("SHADE", "shade");
2362 ss->set("OLD_SHADE", fillShadeVal);
2363 ss->set("NEW_SHADE", newShade);
2364 undoManager->action(this, ss);
2365 }
2366 fillShadeVal = newShade;
2367 setFillQColor();
2368//CB unused in 135 emit colors(lineColorVal, fillColorVal, lineShadeVal, fillShadeVal);
2369}
2370
2371void PageItem::setFillTransparency(double newTransparency)
2372{
2373 if (fillTransparencyVal == newTransparency)
2374 return; // nothing to do -> return
2375 if (UndoManager::undoEnabled())
2376 {
2377 SimpleState *ss = new SimpleState(Um::Transparency,
2378 QString(Um::FromTo).arg(fillTransparencyVal).arg(newTransparency),
2379 Um::ITransparency);
2380 ss->set("TRANSPARENCY", "transparency");
2381 ss->set("OLD_TP", fillTransparencyVal);
2382 ss->set("NEW_TP", newTransparency);
2383 undoManager->action(this, ss);
2384 }
2385 fillTransparencyVal = newTransparency;
2386}
2387
2388void PageItem::setFillBlendmode(int newBlendmode)
2389{
2390 if (fillBlendmodeVal == newBlendmode)
2391 return; // nothing to do -> return
2392 fillBlendmodeVal = newBlendmode;
2393}
2394
2395void PageItem::setLineColor(const QString &newColor)
2396{
2397 QString tmp = newColor;
2398 if (tmp != CommonStrings::None)
2399 {
2400 if (!m_Doc->PageColors.contains(newColor))
2401 {
2402 switch(itemType())
2403 {
2404 case TextFrame:
2405 case PathText:
2406 tmp = m_Doc->toolSettings.dTextLineColor;
2407 break;
2408 case Line:
2409 tmp = m_Doc->toolSettings.dPenLine;
2410 break;
2411 case PolyLine:
2412 case Polygon:
2413 case ImageFrame:
2414 case LatexFrame:
2415 tmp = m_Doc->toolSettings.dPen;
2416 break;
2417 default:
2418 break;
2419 }
2420 }
2421 }
2422 if (lineColorVal == tmp)
2423 {
2424 setLineQColor();
2425 return;
2426 }
2427 if (UndoManager::undoEnabled())
2428 {
2429 SimpleState *ss = new SimpleState(Um::SetLineColor,
2430 QString(Um::ColorFromTo).arg(lineColorVal).arg(tmp),
2431 Um::IFill);
2432 ss->set("LINE_COLOR", "line_color");
2433 ss->set("OLD_COLOR", lineColorVal);
2434 ss->set("NEW_COLOR", tmp);
2435 undoManager->action(this, ss);
2436 }
2437 lineColorVal = tmp;
2438 setLineQColor();
2439//CB unused in 135 emit colors(lineColorVal, fillColorVal, lineShadeVal, fillShadeVal);
2440}
2441
2442void PageItem::setLineShade(double newShade)
2443{
2444 if (lineShadeVal == newShade)
2445 {
2446 setLineQColor();
2447 return;
2448 }
2449 if (UndoManager::undoEnabled())
2450 {
2451 SimpleState *ss = new SimpleState(Um::SetLineShade,
2452 QString(Um::FromTo).arg(lineShadeVal).arg(newShade),
2453 Um::IShade);
2454 ss->set("LINE_SHADE", "line_shade");
2455 ss->set("OLD_SHADE", lineShadeVal);
2456 ss->set("NEW_SHADE", newShade);
2457 undoManager->action(this, ss);
2458 }
2459 lineShadeVal = newShade;
2460 setLineQColor();
2461//CB unused in 135 emit colors(lineColorVal, fillColorVal, lineShadeVal, fillShadeVal);
2462}
2463
2464void PageItem::setLineQColor()
2465{
2466 if (lineColorVal != CommonStrings::None)
2467 {
2468 if (!m_Doc->PageColors.contains(lineColorVal))
2469 {
2470 switch(itemType())
2471 {
2472 case TextFrame:
2473 case PathText:
2474 lineColorVal = m_Doc->toolSettings.dTextLineColor;
2475 break;
2476 case Line:
2477 lineColorVal = m_Doc->toolSettings.dPenLine;
2478 break;
2479 case PolyLine:
2480 case Polygon:
2481 case ImageFrame:
2482 case LatexFrame:
2483 lineColorVal = m_Doc->toolSettings.dPen;
2484 break;
2485 default:
2486 break;
2487 }
2488 }
2489 if (!m_Doc->PageColors.contains(lineColorVal))
2490 lineColorVal = m_Doc->toolSettings.dPen;
2491 const ScColor& col = m_Doc->PageColors[lineColorVal];
2492 strokeQColor = ScColorEngine::getShadeColorProof(col, m_Doc, lineShadeVal);
2493 }
2494 if ((m_Doc->view()) && (m_Doc->view()->m_canvas->usePreviewVisual()))
2495 {
2496 VisionDefectColor defect;
2497 strokeQColor = defect.convertDefect(strokeQColor, m_Doc->view()->m_canvas->previewVisual());
2498 }
2499}
2500
2501void PageItem::setFillQColor()
2502{
2503 if (fillColorVal != CommonStrings::None)
2504 {
2505 if (!m_Doc->PageColors.contains(fillColorVal))
2506 {
2507 switch(itemType())
2508 {
2509 case ImageFrame:
2510 case LatexFrame:
2511 fillColorVal = m_Doc->toolSettings.dBrushPict;
2512 case TextFrame:
2513 case PathText:
2514 fillColorVal = m_Doc->toolSettings.dTextBackGround;
2515 break;
2516 case Line:
2517 case PolyLine:
2518 case Polygon:
2519 fillColorVal = m_Doc->toolSettings.dBrush;
2520 break;
2521 default:
2522 break;
2523 }
2524 }
2525 const ScColor& col = m_Doc->PageColors[fillColorVal];
2526 fillQColor = ScColorEngine::getShadeColorProof(col, m_Doc, fillShadeVal);
2527 }
2528 if ((m_Doc->view()) && (m_Doc->view()->m_canvas->usePreviewVisual()))
2529 {
2530 VisionDefectColor defect;
2531 fillQColor = defect.convertDefect(fillQColor, m_Doc->view()->m_canvas->previewVisual());
2532 }
2533}
2534
2535void PageItem::setLineTransparency(double newTransparency)
2536{
2537 if (lineTransparencyVal == newTransparency)
2538 return; // nothing to do -> return
2539 if (UndoManager::undoEnabled())
2540 {
2541 SimpleState *ss = new SimpleState(Um::LineTransparency,
2542 QString(Um::FromTo).arg(lineTransparencyVal).arg(newTransparency),
2543 Um::ITransparency);
2544 ss->set("LINE_TRANSPARENCY", "transparency");
2545 ss->set("OLD_TP", lineTransparencyVal);
2546 ss->set("NEW_TP", newTransparency);
2547 undoManager->action(this, ss);
2548 }
2549 lineTransparencyVal = newTransparency;
2550}
2551
2552void PageItem::setLineBlendmode(int newBlendmode)
2553{
2554 if (lineBlendmodeVal == newBlendmode)
2555 return; // nothing to do -> return
2556 lineBlendmodeVal = newBlendmode;
2557}
2558
2559void PageItem::setLineStyle(Qt::PenStyle newStyle)
2560{
2561 if (PLineArt == newStyle)
2562 return; // nothing to do -> return
2563 if (UndoManager::undoEnabled())
2564 {
2565 SimpleState *ss = new SimpleState(Um::LineStyle,"",Um::ILineStyle);
2566 ss->set("LINE_STYLE", "line_style");
2567 ss->set("OLD_STYLE", static_cast<int>(PLineArt));
2568 ss->set("NEW_STYLE", static_cast<int>(newStyle));
2569 undoManager->action(this, ss);
2570 }
2571 PLineArt = newStyle;
2572}
2573
2574void PageItem::setLineWidth(double newWidth)
2575{
2576 if (m_lineWidth == newWidth)
2577 return; // nothing to do -> return
2578 if (UndoManager::undoEnabled())
2579 {
2580 SimpleState *ss = new SimpleState(Um::LineWidth,
2581 QString(Um::FromTo).arg(m_lineWidth).arg(newWidth),Um::ILineStyle);
2582 ss->set("LINE_WIDTH", "line_width");
2583 ss->set("OLD_WIDTH", m_lineWidth);
2584 ss->set("NEW_WIDTH", newWidth);
2585 undoManager->action(this, ss);
2586 }
2587 Oldm_lineWidth=m_lineWidth;
2588 m_lineWidth = newWidth;
2589}
2590
2591void PageItem::setLineEnd(Qt::PenCapStyle newStyle)
2592{
2593 if (PLineEnd == newStyle)
2594 return; // nothing to do -> return
2595 if (UndoManager::undoEnabled())
2596 {
2597 SimpleState *ss = new SimpleState(Um::LineEnd,"",Um::ILineStyle);
2598 ss->set("LINE_END", "line_end");
2599 ss->set("OLD_STYLE", static_cast<int>(PLineEnd));
2600 ss->set("NEW_STYLE", static_cast<int>(newStyle));
2601 undoManager->action(this, ss);
2602 }
2603 PLineEnd = newStyle;
2604}
2605
2606void PageItem::setLineJoin(Qt::PenJoinStyle newStyle)
2607{
2608 if (PLineJoin == newStyle)
2609 return; // nothing to do -> return
2610 if (UndoManager::undoEnabled())
2611 {
2612 SimpleState *ss = new SimpleState(Um::LineJoin,"",Um::ILineStyle);
2613 ss->set("LINE_JOIN", "line_join");
2614 ss->set("OLD_STYLE", static_cast<int>(PLineJoin));
2615 ss->set("NEW_STYLE", static_cast<int>(newStyle));
2616 undoManager->action(this, ss);
2617 }
2618 PLineJoin = newStyle;
2619}
2620
2621void PageItem::setCustomLineStyle(const QString& newStyle)
2622{
2623 if (NamedLStyle == newStyle)
2624 return; // nothing to do -> return
2625 if (UndoManager::undoEnabled())
2626 {
2627 QString oldStyle = NamedLStyle.isEmpty() ? Um::NoStyle : NamedLStyle;
2628 QString nStyle = newStyle.isEmpty() ? Um::NoStyle : newStyle;
2629 QString action = newStyle.isEmpty() ? Um::NoLineStyle : Um::CustomLineStyle;
2630 SimpleState *ss = new SimpleState(action,
2631 QString(Um::FromTo).arg(oldStyle).arg(nStyle),Um::ILineStyle);
2632 ss->set("CUSTOM_LINE_STYLE", "customlinestyle");
2633 ss->set("OLD_STYLE", NamedLStyle);
2634 ss->set("NEW_STYLE", newStyle);
2635 undoManager->action(this, ss);
2636 }
2637 NamedLStyle = newStyle;
2638}
2639
2640void PageItem::setStartArrowIndex(int newIndex)
2641{
2642 if (m_startArrowIndex == newIndex)
2643 return; // nothing to do -> return
2644 if (UndoManager::undoEnabled())
2645 {
2646 SimpleState *ss = new SimpleState(Um::StartArrow,"",Um::IArrow);
2647 ss->set("START_ARROW", "startarrow");
2648 ss->set("OLD_INDEX", m_startArrowIndex);
2649 ss->set("NEW_INDEX", newIndex);
2650 undoManager->action(this, ss);
2651 }
2652 m_startArrowIndex = newIndex;
2653}
2654
2655void PageItem::setEndArrowIndex(int newIndex)
2656{
2657 if (m_endArrowIndex == newIndex)
2658 return; // nothing to do -> return
2659 if (UndoManager::undoEnabled())
2660 {
2661 SimpleState *ss = new SimpleState(Um::EndArrow,"",Um::IArrow);
2662 ss->set("END_ARROW", "endarrow");
2663 ss->set("OLD_INDEX", m_endArrowIndex);
2664 ss->set("NEW_INDEX", newIndex);
2665 undoManager->action(this, ss);
2666 }
2667 m_endArrowIndex = newIndex;
2668}
2669
2670void PageItem::setImageFlippedH(bool flipped)
2671{
2672 if (flipped != m_ImageIsFlippedH)
2673 flipImageH();
2674}
2675
2676void PageItem::flipImageH()
2677{
2678 if (UndoManager::undoEnabled())
2679 {
2680 SimpleState *ss = new SimpleState(Um::FlipH, 0, Um::IFlipH);
2681 ss->set("IMAGEFLIPH", "imagefliph");
2682 undoManager->action(this, ss);
2683 }
2684 m_ImageIsFlippedH = !m_ImageIsFlippedH;
2685 emit frameFlippedH(m_ImageIsFlippedH);
2686}
2687
2688void PageItem::setImageFlippedV(bool flipped)
2689{
2690 if (flipped != m_ImageIsFlippedV)
2691 flipImageV();
2692}
2693
2694void PageItem::flipImageV()
2695{
2696 if (UndoManager::undoEnabled())
2697 {
2698 SimpleState *ss = new SimpleState(Um::FlipV, 0, Um::IFlipV);
2699 ss->set("IMAGEFLIPV", "imageflipv");
2700 undoManager->action(this, ss);
2701 }
2702 m_ImageIsFlippedV = !m_ImageIsFlippedV;
2703 emit frameFlippedV(m_ImageIsFlippedV);
2704}
2705
2706void PageItem::setImageScalingMode(bool freeScale, bool keepRatio)
2707{
2708 if (ScaleType == freeScale && AspectRatio == keepRatio)
2709 return;
2710 if (UndoManager::undoEnabled())
2711 {
2712 QString from = ScaleType ? Um::FreeScaling : Um::FrameSize;
2713 from += ", ";
2714 from += AspectRatio ? Um::KeepRatio : Um::BreakRatio;
2715 QString to = freeScale ? Um::FreeScaling : Um::FrameSize;
2716 to += ", ";
2717 to += keepRatio ? Um::KeepRatio : Um::BreakRatio;
2718 SimpleState *ss = new SimpleState(Um::ImageScaling, QString(Um::FromTo).arg(from).arg(to), Um::IImageScaling);
2719 ss->set("SCALE_MODE", "scaling_mode");
2720 if (freeScale != ScaleType)
2721 {
2722 ss->set("SCALE_TYPE", freeScale);
2723 if (!freeScale)
2724 {
2725 //if switching from free scaling to frame size
2726 //in undo must be offset and scale saved
2727 ss->set("OLD_IMAGEXOFFSET", LocalX);
2728 ss->set("OLD_IMAGEYOFFSET", LocalY);
2729 ss->set("OLD_IMAGEXSCALE", LocalScX);
2730 ss->set("OLD_IMAGEYSCALE", LocalScY);
2731 }
2732 }
2733 if (keepRatio != AspectRatio)
2734 ss->set("ASPECT_RATIO", keepRatio);
2735 undoManager->action(this, ss);
2736 }
2737 ScaleType = freeScale;
2738 AspectRatio = keepRatio;
2739 AdjustPictScale();
2740 update();
2741}
2742
2743void PageItem::toggleLock()
2744{
2745 if (UndoManager::undoEnabled())
2746 {
2747 SimpleState *ss;
2748 if (m_Locked)
2749 ss = new SimpleState(Um::UnLock, 0, Um::IUnLock);
2750 else
2751 ss = new SimpleState(Um::Lock, 0, Um::ILock);
2752 ss->set("LOCK", "lock");
2753 undoManager->action(this, ss);
2754 }
2755 m_Locked = !m_Locked;
2756 emit frameLocked(m_Locked);
2757}
2758
2759void PageItem::setLocked(bool isLocked)
2760{
2761 if (isLocked != m_Locked)
2762 toggleLock();
2763}
2764
2765void PageItem::setGroupsLastItem(PageItem* item)
2766{
2767 if (UndoManager::undoEnabled())
2768 {
2769 ItemState<std::pair<PageItem*, PageItem*> > *is = new ItemState<std::pair<PageItem*, PageItem*> >("GroupsLastItem");
2770 is->set("GROUPS_LASTITEM", "groups_lastitem");
2771 is->setItem(std::pair<PageItem*, PageItem*>(this->groupsLastItem, item));
2772 undoManager->action(this, is);
2773 }
2774 groupsLastItem = item;
2775}
2776
2777void PageItem::toggleSizeLock()
2778{
2779 if (UndoManager::undoEnabled())
2780 {
2781 SimpleState *ss;
2782 if (m_SizeLocked)
2783 ss = new SimpleState(Um::SizeUnLock, 0, Um::IUnLock);
2784 else
2785 ss = new SimpleState(Um::SizeLock, 0, Um::ILock);
2786 ss->set("SIZE_LOCK", "size_lock");
2787 undoManager->action(this, ss);
2788 }
2789 m_SizeLocked = !m_SizeLocked;
2790 emit frameSizeLocked(m_SizeLocked);
2791}
2792
2793void PageItem::setSizeLocked(bool isLocked)
2794{
2795 if (isLocked != m_SizeLocked)
2796 toggleSizeLock();
2797}
2798
2799
2800void PageItem::setPrintEnabled(bool toPrint)
2801{
2802 if (toPrint != m_PrintEnabled)
2803 togglePrintEnabled();
2804}
2805
2806void PageItem::togglePrintEnabled()
2807{
2808 if (UndoManager::undoEnabled())
2809 {
2810 SimpleState *ss;
2811 if (m_PrintEnabled)
2812 ss = new SimpleState(Um::DisablePrint, 0, Um::IDisablePrint);
2813 else
2814 ss = new SimpleState(Um::EnablePrint, 0, Um::IEnablePrint);
2815 ss->set("PRINT_ENABLED", "print_enabled");
2816 undoManager->action(this, ss);
2817 }
2818 m_PrintEnabled=!m_PrintEnabled;
2819 emit printEnabled(m_PrintEnabled);
2820}
2821
2822void PageItem::setTextFlowMode(TextFlowMode mode)
2823{
2824 if (textFlowModeVal == mode)
2825 return;
2826 if (UndoManager::undoEnabled())
2827 {
2828 QString stateMessage;
2829 if( mode == TextFlowUsesFrameShape )
2830 stateMessage = Um::ObjectFrame;
2831 else if( mode == TextFlowUsesBoundingBox )
2832 stateMessage = Um::BoundingBox;
2833 else if( mode == TextFlowUsesContourLine )
2834 stateMessage = Um::ContourLine;
2835 else if( mode == TextFlowUsesImageClipping )
2836 stateMessage = Um::ImageClip;
2837 else
2838 stateMessage = Um::NoTextFlow;
2839 SimpleState *ss = new SimpleState(stateMessage, "", Um::IFont);
2840 ss->set("TEXTFLOW_OLDMODE", (int) textFlowModeVal);
2841 ss->set("TEXTFLOW_NEWMODE", (int) mode);
2842 undoManager->action(this, ss);
2843 }
2844 textFlowModeVal = mode;
2845
2846 checkTextFlowInteractions();
2847}
2848
2849void PageItem::checkTextFlowInteractions(bool allItems)
2850{
2851 if(!m_Doc->isLoading())
2852 {
2853 QRectF baseRect(getBoundingRect());
2854 QList<PageItem*>* items = OnMasterPage.isEmpty() ? &m_Doc->DocItems : &m_Doc->MasterItems;
2855 for(int idx = (allItems ? items->count()-1 : ItemNr-1); idx >= 0 ; --idx)
2856 {
2857 if(idx != static_cast<int>(ItemNr)) // avoids itself
2858 {
2859 if(items->at(idx)->asTextFrame()) // do not bother with no text frames
2860 {
2861 QRectF uRect(items->at(idx)->getBoundingRect());
2862 if(baseRect.intersects(uRect))
2863 {
2864 items->at(idx)->update();
2865 }
2866 }
2867 }
2868 }
2869 }
2870}
2871
2872void PageItem::convertTo(ItemType newType)
2873{
2874 if (m_ItemType == newType)
2875 return; // nothing to do -> return
2876 assert(newType != 1); //DEBUG CR 2005-02-06
2877 assert(newType != 3); //DEBUG CR 2005-02-06
2878 QString fromType = "", toType = "";
2879 switch (m_ItemType)
2880 {
2881 case ImageFrame:
2882 if (asLatexFrame()) {
2883 fromType = Um::LatexFrame;
2884 } else {
2885 fromType = Um::ImageFrame;
2886 }
2887 break;
2888 case TextFrame:
2889 fromType = Um::TextFrame;
2890 break;
2891 case Polygon:
2892 fromType = Um::Polygon;
2893 break;
2894 default:
2895 fromType = "";
2896 break;
2897 }
2898 switch (newType)
2899 {
2900 case ImageFrame:
2901 toType = Um::ImageFrame;
2902 setUPixmap(Um::IImageFrame);
2903 break;
2904 case LatexFrame:
2905 toType = Um::LatexFrame;
2906 setUPixmap(Um::ILatexFrame);
2907 break;
2908 case TextFrame:
2909 toType = Um::TextFrame;
2910 setUPixmap(Um::ITextFrame);
2911 break;
2912 case Polygon:
2913 toType = Um::Polygon;
2914 setUPixmap(Um::IPolygon);
2915 break;
2916 case PolyLine:
2917 toType = Um::Polyline;
2918 setUPixmap(Um::IPolyline);
2919 break;
2920 default:
2921 toType = "";
2922 setUPixmap(NULL);
2923 break;
2924 }
2925 /*
2926 if (UndoManager::undoEnabled())
2927 {
2928 SimpleState *ss = new SimpleState(Um::ConvertTo + " " + toType,
2929 QString(Um::FromTo).arg(fromType).arg(toType));
2930 ss->set("CONVERT", "convert");
2931 ss->set("PAGEITEM", reinterpret_cast<int>(this));
2932 ss->set("OLD_TYPE", m_ItemType);
2933 ss->set("NEW_TYPE", newType);
2934 undoManager->action(this, ss);
2935 }
2936 */
2937 m_ItemType = newType;
2938 emit frameType(m_ItemType);
2939}
2940
2941void PageItem::setLayer(int layerId)
2942{
2943 if (LayerNr == layerId)
2944 return;
2945 if (UndoManager::undoEnabled())
2946 {
2947 SimpleState *ss = new SimpleState(Um::SendToLayer,
2948 QString(Um::FromTo).arg(LayerNr).arg(layerId),
2949 Um::ILayerAction);
2950 ss->set("SEND_TO_LAYER", "send_to_layer");
2951 ss->set("OLD_LAYER", LayerNr);
2952 ss->set("NEW_LAYER", layerId);
2953 undoManager->action(this, ss);
2954 }
2955 LayerNr = layerId;
2956}
2957
2958void PageItem::checkChanges(bool force)
2959{
2960 bool spreadChanges(false);
2961 // has the item been resized
2962 if (force || ((oldWidth != Width || oldHeight != Height) && shouldCheck()))
2963 {
2964 resizeUndoAction();
2965 spreadChanges = (textFlowMode() != TextFlowDisabled );
2966 }
2967 // has the item been rotated
2968 if (force || ((oldRot != Rot) && (shouldCheck())))
2969 {
2970 rotateUndoAction();
2971 spreadChanges = (textFlowMode() != TextFlowDisabled );
2972 }
2973 // has the item been moved
2974 if (force || ((oldXpos != Xpos || oldYpos != Ypos) && shouldCheck()))
2975 {
2976 moveUndoAction();
2977 spreadChanges = (textFlowMode() != TextFlowDisabled );
2978 }
2979 // has the item's image been moved
2980 if (force || ((oldLocalX != LocalX || oldLocalY != LocalY) && shouldCheck()))
2981 changeImageOffsetUndoAction();
2982 // has the item's image been scaled
2983 if (force || ((oldLocalScX != LocalScX || oldLocalScY != LocalScY) && shouldCheck()))
2984 changeImageScaleUndoAction();
2985
2986 if(spreadChanges)
2987 {
2988 checkTextFlowInteractions();
2989 }
2990}
2991
2992bool PageItem::shouldCheck()
2993{
2994 return ((!m_Doc->view()->mousePressed()) &&
2995 (!ScCore->primaryMainWindow()->arrowKeyDown()) &&
2996 (!ScCore->primaryMainWindow()->propertiesPalette->userActionOn()));
2997}
2998
2999void PageItem::moveUndoAction()
3000{
3001 if (oldXpos == Xpos && oldYpos == Ypos)
3002 return;
3003 if (UndoManager::undoEnabled())
3004 {
3005 QString oldp;
3006 QString newp;
3007 if (oldOwnPage == -1)
3008 oldp = Um::ScratchSpace;
3009 else
3010 oldp = QString(Um::PageNmbr).arg(m_Doc->FirstPnum + oldOwnPage);
3011 if (OwnPage == -1)
3012 newp = Um::ScratchSpace;
3013 else
3014 newp = QString(Um::PageNmbr).arg(m_Doc->FirstPnum + OwnPage);
3015 SimpleState *ss = new SimpleState(Um::Move,
3016 QString(Um::MoveFromTo).arg(oldXpos).arg(oldYpos).arg(oldp).
3017 arg(Xpos).arg(Ypos).arg(newp), Um::IMove);
3018 ss->set("OLD_XPOS", oldXpos);
3019 ss->set("OLD_YPOS", oldYpos);
3020 ss->set("NEW_XPOS", Xpos);
3021 ss->set("NEW_YPOS", Ypos);
3022 undoManager->action(this, ss);
3023 }
3024 oldXpos = Xpos;
3025 oldYpos = Ypos;
3026 oldOwnPage = OwnPage;
3027}
3028
3029void PageItem::resizeUndoAction()
3030{
3031 if (oldHeight == Height && oldWidth == Width)
3032 return;
3033 if (UndoManager::undoEnabled())
3034 {
3035 SimpleState *ss = new SimpleState(Um::Resize,
3036 QString(Um::ResizeFromTo).arg(oldWidth).arg(oldHeight).arg(Width).arg(Height),
3037 Um::IResize);
3038 ss->set("OLD_WIDTH", oldWidth);
3039 ss->set("OLD_HEIGHT", oldHeight);
3040 ss->set("NEW_WIDTH", Width);
3041 ss->set("NEW_HEIGHT", Height);
3042 ss->set("OLD_RXPOS", oldXpos);
3043 ss->set("OLD_RYPOS", oldYpos);
3044 ss->set("NEW_RXPOS", Xpos);
3045 ss->set("NEW_RYPOS", Ypos);
3046 ss->set("OLD_RROT", oldRot);
3047 ss->set("NEW_RROT", Rot);
3048 undoManager->action(this, ss);
3049 }
3050 oldXpos = Xpos;
3051 oldYpos = Ypos;
3052 oldHeight = Height;
3053 oldWidth = Width;
3054 oldOwnPage = OwnPage;
3055 oldRot = Rot;
3056}
3057
3058void PageItem::rotateUndoAction()
3059{
3060 if (oldRot == Rot)
3061 return;
3062 if (UndoManager::undoEnabled())
3063 {
3064 SimpleState *ss = new SimpleState(Um::Rotate,
3065 QString(Um::FromTo).arg(oldRot).arg(Rot),
3066 Um::IRotate);
3067 ss->set("OLD_ROT", oldRot);
3068 ss->set("NEW_ROT", Rot);
3069 ss->set("OLD_RXPOS", oldXpos);
3070 ss->set("OLD_RYPOS", oldYpos);
3071 ss->set("NEW_RXPOS", Xpos);
3072 ss->set("NEW_RYPOS", Ypos);
3073 ss->set("OLD_RWIDTH", oldWidth);
3074 ss->set("OLD_RHEIGHT", oldHeight);
3075 ss->set("NEW_RWIDTH", Width);
3076 ss->set("NEW_RHEIGHT", Height);
3077 undoManager->action(this, ss);
3078 }
3079 oldRot = Rot;
3080 oldXpos = Xpos;
3081 oldYpos = Ypos;
3082 oldOwnPage = OwnPage;
3083 oldWidth = Width;
3084 oldHeight = Height;
3085}
3086
3087void PageItem::changeImageOffsetUndoAction()
3088{
3089 if (oldLocalX == LocalX && oldLocalY == LocalY)
3090 return;
3091 if (UndoManager::undoEnabled())
3092 {
3093 SimpleState *ss = new SimpleState(Um::ImageOffset,
3094 QString(Um::ImageOffsetFromTo).arg(oldLocalX).arg(oldLocalY).arg(LocalX).arg(LocalY), Um::IMove);
3095 ss->set("IMAGE_OFFSET", "image_offset");
3096 ss->set("OLD_IMAGEXOFFSET", oldLocalX);
3097 ss->set("OLD_IMAGEYOFFSET", oldLocalY);
3098 ss->set("NEW_IMAGEXOFFSET", LocalX);
3099 ss->set("NEW_IMAGEYOFFSET", LocalY);
3100 undoManager->action(this, ss);
3101 }
3102 oldLocalX = LocalX;
3103 oldLocalY = LocalY;
3104}
3105
3106void PageItem::changeImageScaleUndoAction()
3107{
3108 //#9817: Hack for this rounding issue caused by conversion to text values. Undo needs fixing.
3109 if ((ScCLocale::toDoubleC(ScCLocale::toQStringC(oldLocalScX)) ==
3110 ScCLocale::toDoubleC(ScCLocale::toQStringC(LocalScX)))
3111 && (ScCLocale::toDoubleC(ScCLocale::toQStringC(oldLocalScY)) ==
3112 ScCLocale::toDoubleC(ScCLocale::toQStringC(LocalScY))))
3113 return;
3114 if (UndoManager::undoEnabled())
3115 {
3116 SimpleState *ss = new SimpleState(Um::ImageScale,
3117 QString(Um::ImageScaleFromTo).arg(oldLocalScX).arg(oldLocalScY).arg(LocalScX).arg(LocalScY), Um::IMove);
3118 ss->set("IMAGE_SCALE", "image_scale");
3119 ss->set("OLD_IMAGEXSCALE", oldLocalScX);
3120 ss->set("OLD_IMAGEYSCALE", oldLocalScY);
3121 ss->set("NEW_IMAGEXSCALE", LocalScX);
3122 ss->set("NEW_IMAGEYSCALE", LocalScY);
3123 undoManager->action(this, ss);
3124 }
3125 oldLocalScX = LocalScX;
3126 oldLocalScY = LocalScY;
3127}
3128
3129void PageItem::restore(UndoState *state, bool isUndo)
3130{
3131 bool useRasterBackup = m_Doc->useRaster;
3132 bool SnapGuidesBackup = m_Doc->SnapGuides;
3133 m_Doc->useRaster = false;
3134 m_Doc->SnapGuides = false;
3135 SimpleState *ss = dynamic_cast<SimpleState*>(state);
3136 bool oldMPMode=m_Doc->masterPageMode();
3137 m_Doc->setMasterPageMode(!OnMasterPage.isEmpty());
3138 Page *oldCurrentPage = m_Doc->currentPage();
3139 if (!OnMasterPage.isEmpty())
3140 {
3141 oldCurrentPage = m_Doc->currentPage();
3142 m_Doc->setCurrentPage(m_Doc->MasterPages.at(m_Doc->MasterNames[OnMasterPage]));
3143 }
3144 if (ss)
3145 {
3146 if (ss->contains("OLD_XPOS"))
3147 restoreMove(ss, isUndo);
3148 else if (ss->contains("OLD_HEIGHT"))
3149 restoreResize(ss, isUndo);
3150 else if (ss->contains("OLD_ROT"))
3151 restoreRotate(ss, isUndo);
3152 else if (ss->contains("FILL"))
3153 restoreFill(ss, isUndo);
3154 else if (ss->contains("SHADE"))
3155 restoreShade(ss, isUndo);
3156 else if (ss->contains("LINE_COLOR"))
3157 restoreLineColor(ss, isUndo);
3158 else if (ss->contains("LINE_SHADE"))
3159 restoreLineShade(ss, isUndo);
3160 else if (ss->contains("IMAGEFLIPH"))
3161 {
3162 select();
3163 m_Doc->itemSelection_FlipH();
3164 }
3165 else if (ss->contains("IMAGEFLIPV"))
3166 {
3167 select();
3168 m_Doc->itemSelection_FlipV();
3169 }
3170 else if (ss->contains("LOCK"))
3171 {
3172 select();
3173 m_Doc->itemSelection_ToggleLock();
3174 }
3175 else if (ss->contains("SIZE_LOCK"))
3176 {
3177 select();
3178 m_Doc->itemSelection_ToggleSizeLock();
3179 }
3180 else if (ss->contains("PRINT_ENABLED"))
3181 {
3182 select();
3183 m_Doc->itemSelection_TogglePrintEnabled();
3184 }
3185 else if (ss->contains("NEW_NAME"))
3186 restoreName(ss, isUndo);
3187 else if (ss->contains("TRANSPARENCY"))
3188 restoreFillTP(ss, isUndo);
3189 else if (ss->contains("LINE_TRANSPARENCY"))
3190 restoreLineTP(ss, isUndo);
3191 else if (ss->contains("LINE_STYLE"))
3192 restoreLineStyle(ss, isUndo);
3193 else if (ss->contains("LINE_END"))
3194 restoreLineEnd(ss, isUndo);
3195 else if (ss->contains("LINE_JOIN"))
3196 restoreLineJoin(ss, isUndo);
3197 else if (ss->contains("LINE_WIDTH"))
3198 restoreLineWidth(ss, isUndo);
3199 else if (ss->contains("CUSTOM_LINE_STYLE"))
3200 restoreCustomLineStyle(ss, isUndo);
3201 else if (ss->contains("START_ARROW"))
3202 restoreArrow(ss, isUndo, true);
3203 else if (ss->contains("END_ARROW"))
3204 restoreArrow(ss, isUndo, false);
3205 else if (ss->contains("PSTYLE"))
3206 restorePStyle(ss, isUndo);
3207 else if (ss->contains("CONVERT"))
3208 restoreType(ss, isUndo);
3209 else if (ss->contains("TEXTFLOW_OLDMODE"))
3210 restoreTextFlowing(ss, isUndo);
3211 else if (ss->contains("SCALE_MODE"))
3212 restoreImageScaleMode(ss, isUndo);
3213 else if (ss->contains("IMAGE_SCALE"))
3214 restoreImageScaleChange(ss, isUndo);
3215 else if (ss->contains("IMAGE_OFFSET"))
3216 restoreImageOffsetChange(ss, isUndo);
3217 else if (ss->contains("EDIT_CONTOUR"))
3218 restorePoly(ss, isUndo, true);
3219 else if (ss->contains("EDIT_SHAPE"))
3220 restorePoly(ss, isUndo, false);
3221 else if (ss->contains("RESET_CONTOUR"))
3222 restoreContourLine(ss, isUndo);
3223 else if (ss->contains("CHANGE_SHAPE_TYPE"))
3224 restoreShapeType(ss, isUndo);
3225 else if (ss->contains("MIRROR_PATH_H"))
3226 {
3227 bool editContour = m_Doc->nodeEdit.isContourLine;
3228 m_Doc->nodeEdit.isContourLine = ss->getBool("IS_CONTOUR");
3229 select();
3230 m_Doc->MirrorPolyH(m_Doc->m_Selection->itemAt(0));
3231 m_Doc->nodeEdit.isContourLine = editContour;
3232 }
3233 else if (ss->contains("MIRROR_PATH_V"))
3234 {
3235 bool editContour = m_Doc->nodeEdit.isContourLine;
3236 m_Doc->nodeEdit.isContourLine = ss->getBool("IS_CONTOUR");
3237 select();
3238 m_Doc->MirrorPolyV(m_Doc->m_Selection->itemAt(0));
3239 m_Doc->nodeEdit.isContourLine = editContour;
3240 }
3241 else if (ss->contains("SEND_TO_LAYER"))
3242 restoreLayer(ss, isUndo);
3243 else if (ss->contains("GET_IMAGE"))
3244 restoreGetImage(ss, isUndo);
3245 else if (ss->contains("GROUPS_LASTITEM"))
3246 restoreGroupsLastItem(ss, isUndo);
3247 else if (ss->contains("EDIT_SHAPE_OR_CONTOUR"))
3248 restoreShapeContour(ss, isUndo);
3249 else if (ss->contains("APPLY_IMAGE_EFFECTS"))
3250 restoreImageEffects(ss, isUndo);
3251 else if (ss->contains("STEXT"))
3252 restoreEditText(ss, isUndo);
3253 else if (ss->contains("CLEAR_IMAGE"))
3254 restoreClearImage(ss,isUndo);
3255 else if (ss->contains("LINK_TEXT_FRAME"))
3256 restoreLinkTextFrame(ss,isUndo);
3257 else if (ss->contains("UNLINK_TEXT_FRAME"))
3258 restoreUnlinkTextFrame(ss,isUndo);
3259 }
3260 if (!OnMasterPage.isEmpty())
3261 m_Doc->setCurrentPage(oldCurrentPage);
3262 m_Doc->setMasterPageMode(oldMPMode);
3263 m_Doc->useRaster = useRasterBackup;
3264 m_Doc->SnapGuides = SnapGuidesBackup;
3265}
3266
3267void PageItem::restoreMove(SimpleState *state, bool isUndo)
3268{
3269 double ox = state->getDouble("OLD_XPOS");
3270 double oy = state->getDouble("OLD_YPOS");
3271 double x = state->getDouble("NEW_XPOS");
3272 double y = state->getDouble("NEW_YPOS");
3273 double mx = ox - x;
3274 double my = oy - y;
3275 if (!isUndo)
3276 {
3277 mx = -mx;
3278 my = -my;
3279 }
3280 m_Doc->MoveItem(mx, my, this, false);
3281 oldXpos = Xpos;
3282 oldYpos = Ypos;
3283 oldOwnPage = OwnPage;
3284}
3285
3286void PageItem::restoreResize(SimpleState *state, bool isUndo)
3287{
3288 double ow = state->getDouble("OLD_WIDTH");
3289 double oh = state->getDouble("OLD_HEIGHT");
3290 double w = state->getDouble("NEW_WIDTH");
3291 double h = state->getDouble("NEW_HEIGHT");
3292 double ox = state->getDouble("OLD_RXPOS");
3293 double oy = state->getDouble("OLD_RYPOS");
3294 double x = state->getDouble("NEW_RXPOS");
3295 double y = state->getDouble("NEW_RYPOS");
3296 double ort = state->getDouble("OLD_RROT");
3297 double rt = state->getDouble("NEW_RROT");
3298 double mx = ox - x;
3299 double my = oy - y;
3300 int stateCode = state->transactionCode;
3301 bool redraw = ((stateCode != 1) && (stateCode != 3));
3302 if (isUndo)
3303 {
3304 m_Doc->SizeItem(ow, oh, this, false, true, redraw);
3305 m_Doc->MoveItem(mx, my, this, false);
3306 m_Doc->RotateItem(ort, this);
3307 }
3308 else
3309 {
3310 mx = -mx;
3311 my = -my;
3312 m_Doc->SizeItem(w, h, this, false, true, redraw);
3313 m_Doc->MoveItem(mx, my, this, false);
3314 m_Doc->RotateItem(rt, this);
3315 }
3316 oldWidth = Width;
3317 oldHeight = Height;
3318 oldXpos = Xpos;
3319 oldYpos = Ypos;
3320 oldOwnPage = OwnPage;
3321 oldRot = Rot;
3322}
3323
3324void PageItem::restoreRotate(SimpleState *state, bool isUndo)
3325{
3326 double ort = state->getDouble("OLD_ROT");
3327 double rt = state->getDouble("NEW_ROT");
3328 double ox = state->getDouble("OLD_RXPOS");
3329 double oy = state->getDouble("OLD_RYPOS");
3330 double x = state->getDouble("NEW_RXPOS");
3331 double y = state->getDouble("NEW_RYPOS");
3332 double ow = state->getDouble("OLD_RWIDTH");
3333 double oh = state->getDouble("OLD_RHEIGHT");
3334 double w = state->getDouble("NEW_RWIDTH");
3335 double h = state->getDouble("NEW_RHEIGHT");
3336 int stateCode = state->transactionCode;
3337 bool redraw = ((stateCode != 1) && (stateCode != 3));;
3338 //CB Commented out test code
3339 //QRect oldR(getRedrawBounding(view->scale()));
3340 //double mx = ox - x;
3341 //double my = oy - y;
3342 if (isUndo)
3343 {
3344 /*Rot=ort;
3345 Xpos+=mx;
3346 Ypos+=my;
3347 Width=ow;
3348 Height=oh;*/
3349 m_Doc->RotateItem(ort, this);
3350 m_Doc->MoveItem(ox - Xpos, oy - Ypos, this, false);
3351 m_Doc->SizeItem(ow, oh, this, false, true, redraw);
3352 }
3353 else
3354 {
3355 /*mx = -mx;
3356 my = -my;
3357 Rot=rt;
3358 Xpos-=mx;
3359 Ypos-=my;
3360 Width=w;
3361 Height=h;
3362 */
3363 m_Doc->RotateItem(rt, this);
3364 m_Doc->MoveItem(x - Xpos, y - Ypos, this, false);
3365 m_Doc->SizeItem(w, h, this, false, true, redraw);
3366 }
3367 /*
3368 m_Doc->setRedrawBounding(this);
3369 QRect newR(getRedrawBounding(view->scale()));
3370 view->updateContents(newR.unite(oldR));
3371 OwnPage = m_Doc->OnPage(this);
3372 */
3373 oldRot = Rot;
3374 oldXpos = Xpos;
3375 oldYpos = Ypos;
3376 oldOwnPage = OwnPage;
3377 oldWidth = Width;
3378 oldHeight = Height;
3379}
3380
3381void PageItem::restoreFill(SimpleState *state, bool isUndo)
3382{
3383 QString fill = state->get("OLD_FILL");
3384 if (!isUndo)
3385 fill = state->get("NEW_FILL");
3386 select();
3387 m_Doc->itemSelection_SetItemBrush(fill);
3388}
3389
3390void PageItem::restoreShade(SimpleState *state, bool isUndo)
3391{
3392 int shade = state->getInt("OLD_SHADE");
3393 if (!isUndo)
3394 shade = state->getInt("NEW_SHADE");
3395 select();
3396 m_Doc->itemSelection_SetItemBrushShade(shade);
3397}
3398
3399void PageItem::restoreLineColor(SimpleState *state, bool isUndo)
3400{
3401 QString fill = state->get("OLD_COLOR");
3402 if (!isUndo)
3403 fill = state->get("NEW_COLOR");
3404 select();
3405 m_Doc->itemSelection_SetItemPen(fill);
3406}
3407
3408void PageItem::restoreLineShade(SimpleState *state, bool isUndo)
3409{
3410 int shade = state->getInt("OLD_SHADE");
3411 if (!isUndo)
3412 shade = state->getInt("NEW_SHADE");
3413 select();
3414 m_Doc->itemSelection_SetItemPenShade(shade);
3415}
3416
3417void PageItem::restoreFillTP(SimpleState *state, bool isUndo)
3418{
3419 double tp = state->getDouble("OLD_TP");
3420 if (!isUndo)
3421 tp = state->getDouble("NEW_TP");
3422 select();
3423 m_Doc->itemSelection_SetItemFillTransparency(tp);
3424}
3425
3426void PageItem::restoreLineTP(SimpleState *state, bool isUndo)
3427{
3428 double tp = state->getDouble("OLD_TP");
3429 if (!isUndo)
3430 tp = state->getDouble("NEW_TP");
3431 select();
3432 m_Doc->itemSelection_SetItemLineTransparency(tp);
3433}
3434
3435
3436void PageItem::restoreLineStyle(SimpleState *state, bool isUndo)
3437{
3438 Qt::PenStyle ps = static_cast<Qt::PenStyle>(state->getInt("OLD_STYLE"));
3439 if (!isUndo)
3440 ps = static_cast<Qt::PenStyle>(state->getInt("NEW_STYLE"));
3441 select();
3442 m_Doc->itemSelection_SetLineArt(ps);
3443}
3444
3445void PageItem::restoreLineEnd(SimpleState *state, bool isUndo)
3446{
3447 Qt::PenCapStyle pcs = static_cast<Qt::PenCapStyle>(state->getInt("OLD_STYLE"));
3448 if (!isUndo)
3449 pcs = static_cast<Qt::PenCapStyle>(state->getInt("NEW_STYLE"));
3450 select();
3451 m_Doc->itemSelection_SetLineEnd(pcs);
3452}
3453
3454void PageItem::restoreLineJoin(SimpleState *state, bool isUndo)
3455{
3456 Qt::PenJoinStyle pjs = static_cast<Qt::PenJoinStyle>(state->getInt("OLD_STYLE"));
3457 if (!isUndo)
3458 pjs = static_cast<Qt::PenJoinStyle>(state->getInt("NEW_STYLE"));
3459 select();
3460 m_Doc->itemSelection_SetLineJoin(pjs);
3461}
3462
3463void PageItem::restoreLineWidth(SimpleState *state, bool isUndo)
3464{
3465 double w = state->getDouble("OLD_WIDTH");
3466 if (!isUndo)
3467 w = state->getDouble("NEW_WIDTH");
3468 select();
3469 m_Doc->itemSelection_SetLineWidth(w);
3470}
3471
3472void PageItem::restoreCustomLineStyle(SimpleState *state, bool isUndo)
3473{
3474 QString style = state->get("OLD_STYLE");
3475 if (!isUndo)
3476 style = state->get("NEW_STYLE");
3477 setCustomLineStyle(style);
3478}
3479
3480void PageItem::restoreName(SimpleState *state, bool isUndo)
3481{
3482 QString name = state->get("OLD_NAME");
3483 if (!isUndo)
3484 name = state->get("NEW_NAME");
3485 setItemName(name);
3486}
3487
3488void PageItem::restoreArrow(SimpleState *state, bool isUndo, bool isStart)
3489{
3490 int i = state->getInt("OLD_INDEX");
3491 if (!isUndo)
3492 i = state->getInt("NEW_INDEX");
3493 if (isStart)
3494 setStartArrowIndex(i);
3495 else
3496 setEndArrowIndex(i);
3497}
3498
3499
3500void PageItem::restorePStyle(SimpleState *state, bool isUndo)
3501{
3502 int styleid = state->getInt("OLD_STYLE");
3503 if (!isUndo)
3504 styleid = state->getInt("NEW_STYLE");
3505 //will be done later with other text-undo:
3506 // m_Doc->chAbStyle(this, styleid);
3507}
3508
3509
3510// FIXME: This must go into class ScribusDoc!
3511// For now we'll just make it independent of 'this' -- AV
3512void PageItem::restoreType(SimpleState *state, bool isUndo)
3513{
3514 // well, probably not the best way to handle pointers...
3515 PageItem * item = reinterpret_cast<PageItem *>(state->getInt("PAGEITEM"));
3516 int type = state->getInt("OLD_TYPE");
3517 if (!isUndo)
3518 type = state->getInt("NEW_TYPE");
3519 ScribusView* view = m_Doc->view();
3520 view->Deselect(false);
3521 view->SelectItem(item, false);
3522 switch (type) {
3523 case ImageFrame: view->ToPicFrame(); break;
3524 case TextFrame: view->ToTextFrame(); break;
3525 case Polygon: view->ToPolyFrame(); break;
3526 case PolyLine: view->ToBezierFrame(); break;
3527 }
3528 view->requestMode(modeNormal);
3529}
3530
3531void PageItem::restoreTextFlowing(SimpleState *state, bool isUndo)
3532{
3533 TextFlowMode oldMode = (TextFlowMode) state->getInt("TEXTFLOW_OLDMODE");
3534 TextFlowMode newMode = (TextFlowMode) state->getInt("TEXTFLOW_NEWMODE");
3535 if (isUndo)
3536 textFlowModeVal = oldMode;
3537 else
3538 textFlowModeVal = newMode;
3539
3540 QList<PageItem*> pList;
3541 for(int idx = ItemNr-1; idx >= 0 ; --idx)
3542 {
3543 pList << m_Doc->Items->at(idx);
3544 }
3545
3546 QRectF baseRect(getBoundingRect());
3547 for(int idx(0); idx < pList.count(); ++idx)
3548 {
3549 QRectF uRect(pList.at(idx)->getBoundingRect());
3550 if(baseRect.intersects(uRect))
3551 pList.at(idx)->update();
3552 }
3553}
3554
3555void PageItem::restoreImageScaleMode(SimpleState *state, bool isUndo)
3556{
3557 bool type=ScaleType;
3558 if (state->contains("SCALE_TYPE"))
3559 {
3560 if (isUndo)
3561 type = !state->getBool("SCALE_TYPE");
3562 else
3563 type = state->getBool("SCALE_TYPE");
3564 //if restoring free scaling
3565 //old offset and scale ratio must be restored
3566 if (type)
3567 {
3568 double oscx = state->getDouble("OLD_IMAGEXSCALE");
3569 double oscy = state->getDouble("OLD_IMAGEYSCALE");
3570 double ox = state->getDouble("OLD_IMAGEXOFFSET");
3571 double oy = state->getDouble("OLD_IMAGEYOFFSET");
3572 Selection tempSelection(this, false);
3573 tempSelection.addItem(this, true);
3574 m_Doc->itemSelection_SetImageScale(oscx, oscy, &tempSelection);
3575 m_Doc->itemSelection_SetImageOffset(ox, oy, &tempSelection);
3576 }
3577
3578 }
3579
3580 bool ratio=AspectRatio;
3581 if (state->contains("ASPECT_RATIO"))
3582 {
3583 if (isUndo)
3584 ratio = !state->getBool("ASPECT_RATIO");
3585 else
3586 ratio = state->getBool("ASPECT_RATIO");
3587 }
3588
3589 setImageScalingMode(type, ratio);
3590}
3591
3592void PageItem::restoreImageScaleChange(SimpleState *state, bool isUndo)
3593{
3594 double oscx = state->getDouble("OLD_IMAGEXSCALE");
3595 double oscy = state->getDouble("OLD_IMAGEYSCALE");
3596 double scx = state->getDouble("NEW_IMAGEXSCALE");
3597 double scy = state->getDouble("NEW_IMAGEYSCALE");
3598 Selection tempSelection(this, false);
3599 tempSelection.addItem(this, true);
3600 if (!isUndo)
3601 m_Doc->itemSelection_SetImageScale(scx, scy, &tempSelection);
3602 else
3603 m_Doc->itemSelection_SetImageScale(oscx, oscy, &tempSelection);
3604}
3605
3606void PageItem::restoreImageOffsetChange(SimpleState *state, bool isUndo)
3607{
3608 double ox = state->getDouble("OLD_IMAGEXOFFSET");
3609 double oy = state->getDouble("OLD_IMAGEYOFFSET");
3610 double x = state->getDouble("NEW_IMAGEXOFFSET");
3611 double y = state->getDouble("NEW_IMAGEYOFFSET");
3612 Selection tempSelection(this, false);
3613 tempSelection.addItem(this, true);
3614 if (!isUndo)
3615 m_Doc->itemSelection_SetImageOffset(x, y, &tempSelection);
3616 else
3617 m_Doc->itemSelection_SetImageOffset(ox, oy, &tempSelection);
3618}
3619
3620void PageItem::restoreClearImage(UndoState *state, bool isUndo)
3621{
3622 if (!isImageFrame())
3623 return;
3624 if (isUndo)
3625 {
3626 ItemState<ScImageEffectList> *is = dynamic_cast<ItemState<ScImageEffectList>*>(state);
3627 Pfile = is->get("CI_PFILE");
3628 loadImage(Pfile, false);
3629 effectsInUse = is->getItem();
3630 setImageFlippedH(is->getBool("CI_FLIPPH"));
3631 setImageFlippedV(is->getBool("CI_FLIPPV"));
3632 setImageScalingMode(is->getBool("CI_SCALING"),is->getBool("CI_ASPECT"));
3633 setImageXYOffset(is->getDouble("CI_XOFF"), is->getDouble("CI_YOFF"));
3634 setImageXYScale(is->getDouble("CI_XSCALE"), is->getDouble("CI_YSCALE"));
3635 setFillTransparency(is->getDouble("CI_FILLT"));
3636 setLineTransparency(is->getDouble("CI_LINET"));
3637 select();
3638 m_Doc->updatePic();
3639 }
3640 else
3641 asImageFrame()->clearContents();
3642}
3643
3644void PageItem::restoreLinkTextFrame(UndoState *state, bool isUndo)
3645{
3646 if (!isTextFrame())
3647 return;
3648 if (isUndo)
3649 {
3650 unlink();
3651 }
3652 else
3653 {
3654 ItemState<std::pair<PageItem*, PageItem*> > *is = dynamic_cast<ItemState<std::pair<PageItem*, PageItem*> >*>(state);
3655 asTextFrame()->link(is->getItem().second->asTextFrame());
3656 }
3657}
3658
3659void PageItem::restoreUnlinkTextFrame(UndoState *state, bool isUndo)
3660{
3661 if (!isTextFrame())
3662 return;
3663 if (isUndo)
3664 {
3665 ItemState<std::pair<PageItem*, PageItem*> > *is = dynamic_cast<ItemState<std::pair<PageItem*, PageItem*> >*>(state);
3666 asTextFrame()->link(is->getItem().second->asTextFrame());
3667 }
3668 else
3669 {
3670 unlink();
3671 }
3672}
3673
3674
3675void PageItem::restorePoly(SimpleState *state, bool isUndo, bool isContour)
3676{
3677 int mode = state->getInt("MODE");
3678 int rot = state->getInt("ROT");
3679 ScribusView* view = m_Doc->view();
3680 double scaling = state->getDouble("SCALING");
3681 bool editContour = m_Doc->nodeEdit.isContourLine;
3682 m_Doc->nodeEdit.isContourLine = isContour;
3683 select();
3684 if (isUndo)
3685 {
3686 if (mode % 2 != 0 && mode != 0)
3687 --mode;
3688 else
3689 ++mode;
3690 if (mode == 2)
3691 scaling = (1.0 - (100.0 / (100.0 + scaling))) * 100.0;
3692 else if (mode == 3)
3693 scaling = ((100.0 / (100.0 - scaling)) - 1.0) * 100.0;
3694 }
3695 view->TransformPoly(mode, rot, scaling);
3696 m_Doc->nodeEdit.isContourLine = editContour;
3697}
3698
3699void PageItem::restoreContourLine(SimpleState *state, bool isUndo)
3700{
3701 ItemState<FPointArray> *is = dynamic_cast<ItemState<FPointArray>*>(state);
3702 if (is)
3703 {
3704 if (isUndo)
3705 ContourLine = is->getItem();
3706 else
3707 ContourLine = PoLine.copy();
3708 ClipEdited = true;
3709 }
3710}
3711
3712void PageItem::restoreShapeType(SimpleState *state, bool isUndo)
3713{
3714 // Store shape info in this form:
3715 // CHANGE_SHAPE_TYPE - ID of the undo operation
3716 // OLD_FRAME_TYPE - original frame type
3717 // NEW_FRAME_TYPE - change of frame type
3718 // binary QPair<FPointArray, FPointArray> - .first original shape, .second new shape
3719 ItemState<QPair<FPointArray,FPointArray> > *is = dynamic_cast<ItemState<QPair<FPointArray,FPointArray> >*>(state);
3720 if (is)
3721 {
3722 if (isUndo)
3723 {
3724 this->FrameType = is->getInt("OLD_FRAME_TYPE");
3725 this->PoLine = is->getItem().first;
3726 }
3727 else
3728 {
3729 this->FrameType = is->getInt("NEW_FRAME_TYPE");
3730 this->PoLine = is->getItem().second;
3731 }
3732 ClipEdited = true;
3733 }
3734}
3735
3736void PageItem::restoreLayer(SimpleState *state, bool isUndo)
3737{
3738 ScribusView* view = m_Doc->view();
3739 setLayer(isUndo ? state->getInt("OLD_LAYER") : state->getInt("NEW_LAYER"));
3740 view->Deselect(true);
3741 m_Doc->regionsChanged()->update(QRectF());
3742}
3743
3744void PageItem::restoreGetImage(UndoState *state, bool isUndo)
3745{
3746 ItemState<ScImageEffectList> *is = dynamic_cast<ItemState<ScImageEffectList>*>(state);
3747 QString fn = is->get("OLD_IMAGE_PATH");
3748 if (!isUndo)
3749 fn = is->get("NEW_IMAGE_PATH");
3750 if (fn.isEmpty())
3751 {
3752 Selection tempSelection(this, false);
3753 tempSelection.addItem(this, true);
3754 m_Doc->itemSelection_ClearItem(&tempSelection);
3755 }
3756 else
3757 {
3758 loadImage(fn, false);
3759 if (isUndo)
3760 {
3761 //restore old image settings
3762 effectsInUse = is->getItem();
3763 setImageFlippedH(is->getBool("FLIPPH"));
3764 setImageFlippedV(is->getBool("FLIPPV"));
3765 setImageScalingMode(is->getBool("SCALING"), is->getBool("ASPECT"));
3766 setImageXYOffset(is->getDouble("XOFF"), is->getDouble("YOFF"));
3767 setImageXYScale(is->getDouble("XSCALE"), is->getDouble("YSCALE"));
3768 setFillTransparency(is->getDouble("FILLT"));
3769 setLineTransparency(is->getDouble("LINET"));
3770 }
3771 select();
3772 m_Doc->updatePic();
3773 }
3774}
3775
3776void PageItem::restoreGroupsLastItem(SimpleState *state, bool isUndo)
3777{
3778 ItemState<std::pair<PageItem*, PageItem*> > *is = dynamic_cast<ItemState<std::pair<PageItem*, PageItem*> > *>(state);
3779 if (is)
3780 {
3781 if (isUndo)
3782 this->groupsLastItem = is->getItem().first;
3783 else
3784 this->groupsLastItem = is->getItem().second;
3785 }
3786}
3787
3788void PageItem::restoreShapeContour(UndoState *state, bool isUndo)
3789{
3790 ItemState<QPair<FPointArray,FPointArray> > *istate =
3791 dynamic_cast<ItemState<QPair<FPointArray,FPointArray> >*>(state);
3792 if (istate)
3793 {
3794 FPointArray oldClip = istate->getItem().first;
3795 FPointArray newClip = istate->getItem().second;
3796 bool isContour = istate->getBool("IS_CONTOUR");
3797 double oldX = istate->getDouble("OLD_X");
3798 double oldY = istate->getDouble("OLD_Y");
3799 double newX = istate->getDouble("NEW_X");
3800 double newY = istate->getDouble("NEW_Y");
3801 double mx = oldX - newX;
3802 double my = oldY - newY;
3803
3804 if (isUndo)
3805 {
3806 if (isContour)
3807 ContourLine = oldClip;
3808 else
3809 PoLine = oldClip;
3810 }
3811 else
3812 {
3813 mx = -mx;
3814 my = -my;
3815 if (isContour)
3816 ContourLine = newClip;
3817 else
3818 PoLine = newClip;
3819 }
3820 m_Doc->AdjustItemSize(this);
3821 m_Doc->MoveItem(mx, my, this, false);
3822 m_Doc->regionsChanged()->update(QRectF());
3823 }
3824
3825}
3826
3827void PageItem::restoreImageEffects(UndoState *state, bool isUndo)
3828{
3829 ItemState<QPair<ScImageEffectList, ScImageEffectList> > *istate =
3830 dynamic_cast<ItemState<QPair<ScImageEffectList,ScImageEffectList> >*>(state);
3831 if (istate)
3832 {
3833 if (isUndo)
3834 effectsInUse = istate->getItem().first;
3835 else
3836 effectsInUse = istate->getItem().second;
3837
3838 select();
3839 m_Doc->updatePic();
3840 }
3841}
3842
3843void PageItem::restoreEditText(SimpleState *state, bool isUndo)
3844{
3845 if (!isTextFrame())
3846 return;
3847 itemText.deselectAll();
3848 HasSel = false;
3849 EditAct action = (EditAct) state->getInt("STEXT");
3850 if (action == PARAMFULL || action == PARAMSEL)
3851 {
3852 QString buffer;
3853 if (isUndo)
3854 buffer.append(state->get("STEXT_OLD"));
3855 else
3856 buffer.append(state->get("STEXT_NEW"));
3857 if (!buffer.isEmpty())
3858 {
3859 Serializer dig(*m_Doc);
3860 dig.store<ScribusDoc>("<scribusdoc>", m_Doc);
3861 StoryText::desaxeRules("/", dig, "SCRIBUSTEXT");
3862 dig.addRule("/SCRIBUSTEXT", desaxe::Result<StoryText>());
3863 dig.parseMemory(buffer.toStdString().c_str(), buffer.length());
3864 StoryText* story = dig.result<StoryText>();
3865 if (action == PARAMFULL)
3866 {
3867 itemText.selectAll();
3868 itemText.clear();
3869 itemText.append(*story);
3870 }
3871 else if (action == PARAMSEL)
3872 {
3873 itemText.deselectAll();
3874 int SelStart = state->getInt("STEXT_SELSTART");
3875 itemText.select(SelStart,state->getInt("STEXT_SELLEN"));
3876 asTextFrame()->deleteSelectedTextFromFrame();
3877 int ItemLength = itemText.length();
3878 itemText.insert(SelStart, *story);
3879 // If we have inserted at end of text we have to restore trailing style
3880 if (ItemLength == SelStart && story->length() > 0 && story->text(-1) != SpecialChars::PARSEP)
3881 {
3882 itemText.setStyle(-1, story->paragraphStyle(story->length()));
3883 }
3884 itemText.select(SelStart, story->length());
3885 HasSel = true;
3886 }
3887 CPos = itemText.endOfSelection();
3888 delete story;
3889 }
3890 else { qDebug() << "UNDO buffer EMPTY";}
3891 }
3892 else if (action == REPSAX)
3893 {
3894 QString buffout, buffin; //buffout is deleted, buffin is inserted
3895 int pos = state->getInt("STEXT_CPOS");
3896 if (isUndo)
3897 {
3898 buffin.append(state->get("STEXT_OLD"));
3899 buffout.append(state->get("STEXT_NEW"));
3900 }
3901 else
3902 {
3903 buffin.append(state->get("STEXT_NEW"));
3904 buffout.append(state->get("STEXT_OLD"));
3905 }
3906
3907 Serializer dig(*m_Doc);
3908 dig.store<ScribusDoc>("<scribusdoc>", m_Doc);
3909 StoryText::desaxeRules("/", dig, "SCRIBUSTEXT");
3910 dig.addRule("/SCRIBUSTEXT", desaxe::Result<StoryText>());
3911 dig.parseMemory(buffout.toStdString().c_str(), buffout.length());
3912 StoryText* story = dig.result<StoryText>();
3913 itemText.select(pos,story->length());
3914 asTextFrame()->deleteSelectedTextFromFrame();
3915
3916 Serializer dig2(*m_Doc);
3917 dig2.store<ScribusDoc>("<scribusdoc>", m_Doc);
3918 StoryText::desaxeRules("/", dig2, "SCRIBUSTEXT");
3919 dig2.addRule("/SCRIBUSTEXT", desaxe::Result<StoryText>());
3920 dig2.parseMemory(buffin.toStdString().c_str(), buffin.length());
3921 story = dig2.result<StoryText>();
3922 itemText.insert(pos,*story);
3923 itemText.select(pos, story->length());
3924 HasSel = true;
3925 CPos = pos + story->length();
3926 delete story;
3927 }
3928 else if (action == INSSAX || action == DELSAX)
3929 {
3930 QString str = state->get("STEXT_STR");
3931 if (str.isEmpty())
3932 str = itemTextSaxed;
3933 int pos = state->getInt("STEXT_CPOS");
3934 Serializer dig(*m_Doc);
3935 dig.store<ScribusDoc>("<scribusdoc>", m_Doc);
3936 StoryText::desaxeRules("/", dig, "SCRIBUSTEXT");
3937 dig.addRule("/SCRIBUSTEXT", desaxe::Result<StoryText>());
3938 dig.parseMemory(str.toStdString().c_str(), str.length());
3939 StoryText* story = dig.result<StoryText>();
3940 if ((action == INSSAX && isUndo) || (action == DELSAX && !isUndo))
3941 {
3942 //undo for INSSAX, redo for DELSAX
3943 itemText.select(pos, story->length());
3944 asTextFrame()->deleteSelectedTextFromFrame();
3945 }
3946 else
3947 {
3948 //undo for DELSAX, redo for INSSAX
3949 itemText.insert(pos, *story);
3950 CPos = pos + story->length();
3951 }
3952 delete story;
3953 }
3954 else if (action == INS)
3955 {
3956 QString str = state->get("STEXT_STR");
3957 int pos = state->getInt("STEXT_CPOS");
3958 if (isUndo)
3959 {
3960 itemText.select(pos, str.length());
3961 asTextFrame()->deleteSelectedTextFromFrame();
3962 }
3963 else
3964 {
3965 itemText.insertChars(pos, str, true);
3966 CPos = pos + str.length();
3967 }
3968 }
3969 // after Undo or Redo new actions should create new undoStates
3970 asTextFrame()->lastUndoAction = NOACTION;
3971
3972 m_Doc->scMW()->setTBvals(this);
3973 update();
3974}
3975
3976QString PageItem::getItemTextSaxed(EditActPlace undoItem)
3977{
3978 if (!isTextFrame()) return "";
3979 StoryText iT(m_Doc);
3980 iT.setDefaultStyle(itemText.defaultStyle());
3981 if (undoItem == FRAME)
3982 iT.insert(0, itemText);
3983 else
3984 {
3985 int StartOldSel = -1, LenOldSel = -1;
3986 if (undoItem == PARAGRAPH)
3987 {
3988 LenOldSel = 0;
3989 if (HasSel)
3990 {
3991 StartOldSel = itemText.startOfSelection();
3992 LenOldSel = itemText.lengthOfSelection();
3993 }
3994 asTextFrame()->expandParaSelection(true);
3995 }
3996 else if (undoItem == CHAR || (undoItem == SELECTION && !HasSel))
3997 {
3998 LenOldSel = itemText.lengthOfSelection();
3999 if (LenOldSel > 0)
4000 StartOldSel = itemText.startOfSelection();
4001 if (CPos >= itemText.length())
4002 return "";
4003 itemText.select(CPos,1);
4004 HasSel = true;
4005 }
4006 //is SELECTION
4007 iT.insert(0, itemText, HasSel);
4008 if (LenOldSel > 0) //restoring old selection if undoItem was PARAPGRAPH
4009 {
4010 itemText.select(StartOldSel, LenOldSel);
4011 HasSel = true;
4012 }
4013 else if (LenOldSel == 0)
4014 {
4015 itemText.deselectAll();
4016 HasSel = false;
4017 }
4018 }
4019 //saxing text
4020 std::ostringstream xmlString;
4021 SaxXML xmlStream(xmlString);
4022 xmlStream.beginDoc();
4023 iT.saxx(xmlStream, "SCRIBUSTEXT");
4024 xmlStream.endDoc();
4025 std::string xml(xmlString.str());
4026 return QString(xml.c_str());
4027}
4028
4029QString PageItem::getItemTextSaxed(int selStart, int selLength)
4030{
4031 if (selStart < 0 || selLength < 0)
4032 return QString();
4033
4034 StoryText it(m_Doc);
4035 it.setDefaultStyle(itemText.defaultStyle());
4036
4037 int oldSelStart = -1, oldSelLength = -1;
4038 oldSelStart = itemText.startOfSelection();
4039 oldSelLength = itemText.lengthOfSelection();
4040
4041 itemText.select(selStart, selLength);
4042 it.insert(0, itemText, (selLength > 0));
4043
4044 if (oldSelLength > 0) //restoring old selection if undoItem was PARAPGRAPH
4045 {
4046 itemText.select(oldSelStart, oldSelLength);
4047 HasSel = true;
4048 }
4049 else if (oldSelLength == 0)
4050 {
4051 itemText.deselectAll();
4052 HasSel = false;
4053 }
4054
4055 //saxing text
4056 std::ostringstream xmlString;
4057 SaxXML xmlStream(xmlString);
4058 xmlStream.beginDoc();
4059 it.saxx(xmlStream, "SCRIBUSTEXT");
4060 xmlStream.endDoc();
4061 std::string xml(xmlString.str());
4062 return QString(xml.c_str());
4063}
4064
4065QString PageItem::getTextSaxed(QString str)
4066{
4067 StoryText iT(m_Doc);
4068 iT.setDefaultStyle(itemText.defaultStyle());
4069 iT.insertChars(0,str,true);
4070 std::ostringstream xmlString;
4071 SaxXML xmlStream(xmlString);
4072 xmlStream.beginDoc();
4073 iT.saxx(xmlStream, "SCRIBUSTEXT");
4074 xmlStream.endDoc();
4075 std::string xml(xmlString.str());
4076 return QString(xml.c_str());
4077}
4078
4079void PageItem::select()
4080{
4081 if (m_Doc->m_Selection->count() == 1 && m_Doc->m_Selection->itemAt()->isTextFrame())
4082 m_Doc->m_Selection->itemAt()->asTextFrame()->lastUndoAction = PageItem::NOACTION;
4083 m_Doc->view()->Deselect(false);
4084 //CB #2969 add this true parm to addItem so we dont connectToGUI, the rest of view->SelectItem isnt needed anyway
4085 m_Doc->m_Selection->addItem(this, true);
4086}
4087
4088ObjAttrVector* PageItem::getObjectAttributes()
4089{
4090 return &pageItemAttributes;
4091}
4092
4093ObjectAttribute PageItem::getObjectAttribute(QString attributeName) const
4094{
4095 int countFound=0;
4096 ObjAttrVector::const_iterator foundIt = pageItemAttributes.begin();
4097 for(ObjAttrVector::const_iterator objAttrIt = pageItemAttributes.begin() ; objAttrIt != pageItemAttributes.end(); ++objAttrIt )
4098 {
4099 if ((*objAttrIt).name==attributeName)
4100 {
4101 ++countFound;
4102 foundIt=objAttrIt;
4103 }
4104 }
4105 ObjectAttribute returnAttribute;
4106 if(countFound==1)
4107 returnAttribute=(*foundIt);
4108 else
4109 returnAttribute.name=QString::null;
4110 return returnAttribute;
4111}
4112
4113
4114void PageItem::setObjectAttributes(ObjAttrVector* map)
4115{
4116 pageItemAttributes=*map;
4117}
4118
4119QString PageItem::generateUniqueCopyName(const QString originalName) const
4120{
4121 if (!m_Doc->itemNameExists(originalName))
4122 return originalName;
4123
4124 // Start embellishing the name until we get an acceptable unique name
4125 // first we prefix `Copy of' if it's not already there
4126 QString newname(originalName);
4127 if (!originalName.startsWith( tr("Copy of")))
4128 newname.prepend( tr("Copy of")+" ");
4129
4130 // See if the name prefixed by "Copy of " is free
4131 if (m_Doc->itemNameExists(newname))
4132 {
4133 // Search the string for (number) at the end and capture
4134 // both the number and the text leading up to it sans brackets.
4135 // Copy of fred (5)
4136 // ^^^^^^^^^^^^ ^ (where ^ means captured)
4137 static QRegExp rx("^(.*)\\s+\\((\\d+)\\)$");
4138 int numMatches = rx.lastIndexIn(newname);
4139 // Add a (number) suffix to the end of the name. We start at the
4140 // old suffix's value if there was one, or at 2 if there was not.
4141 int suffixnum = 2;
4142 QString prefix(newname);
4143 if (numMatches != -1)
4144 {
4145 // Already had a suffix; use the name w/o suffix for prefix and
4146 // grab the old suffix value as a starting point.
4147 QStringList matches = rx.capturedTexts();
4148 prefix = matches[1];
4149 suffixnum = matches[2].toInt();
4150 }
4151 // Keep on incrementing the suffix 'till we find a free name
4152 do
4153 {
4154 newname = prefix + " (" + QString::number(suffixnum) + ")";
4155 suffixnum ++;
4156 }
4157 while (m_Doc->itemNameExists(newname));
4158 }
4159 // Unnecessary assert, previous code ensure condition is always true - JG
4160 // assert(!m_Doc->itemNameExists(newname));
4161 return newname;
4162}
4163
4164void PageItem::setTagged(bool tag)
4165{
4166 tagged=tag;
4167}
4168
4169void PageItem::replaceNamedResources(ResourceCollection& newNames)
4170{
4171 QMap<QString,QString>::ConstIterator it;
4172
4173 it = newNames.colors().find(fillColor());
4174 if (it != newNames.colors().end())
4175 setFillColor(*it);
4176
4177 it = newNames.colors().find(lineColor());
4178 if (it != newNames.colors().end())
4179 setLineColor(*it);
4180
4181 QList<VColorStop*> cstops = fill_gradient.colorStops();
4182 for (uint cst = 0; cst < fill_gradient.Stops(); ++cst)
4183 {
4184 it = newNames.colors().find(cstops.at(cst)->name);
4185 if (it != newNames.colors().end())
4186 {
4187 if (*it != CommonStrings::None)
4188 cstops.at(cst)->name = *it;
4189 }
4190 }
4191 if (effectsInUse.count() != 0)
4192 {
4193 QString col1 = CommonStrings::None;
4194 QString col2 = CommonStrings::None;
4195 QString col3 = CommonStrings::None;
4196 QString col4 = CommonStrings::None;
4197 for (int a = 0; a < effectsInUse.count(); ++a)
4198 {
4199 QString tmpstr = effectsInUse.at(a).effectParameters;
4200 QString tmpstr2 = "";
4201 ScTextStream fp(&tmpstr, QIODevice::ReadOnly);
4202 switch (effectsInUse.at(a).effectCode)
4203 {
4204 case ScImage::EF_QUADTONE:
4205 col1 = fp.readLine();
4206 col2 = fp.readLine();
4207 col3 = fp.readLine();
4208 col4 = fp.readLine();
4209 it = newNames.colors().find(col1);
4210 if (it != newNames.colors().end())
4211 {
4212 if (*it != CommonStrings::None)
4213 tmpstr2 += *it + "\n";
4214 else
4215 tmpstr2 += col1 + "\n";
4216 }
4217 else
4218 tmpstr2 += col1 + "\n";
4219 it = newNames.colors().find(col2);
4220 if (it != newNames.colors().end())
4221 {
4222 if (*it != CommonStrings::None)
4223 tmpstr2 += *it + "\n";
4224 else
4225 tmpstr2 += col2 + "\n";
4226 }
4227 else
4228 tmpstr2 += col2 + "\n";
4229 it = newNames.colors().find(col3);
4230 if (it != newNames.colors().end())
4231 {
4232 if (*it != CommonStrings::None)
4233 tmpstr2 += *it + "\n";
4234 else
4235 tmpstr2 += col3 + "\n";
4236 }
4237 else
4238 tmpstr2 += col3 + "\n";
4239 it = newNames.colors().find(col4);
4240 if (it != newNames.colors().end())
4241 {
4242 if (*it != CommonStrings::None)
4243 tmpstr2 += *it + "\n";
4244 else
4245 tmpstr2 += col4 + "\n";
4246 }
4247 else
4248 tmpstr2 += col4 + "\n";
4249 tmpstr2 += fp.readAll();
4250 break;
4251 case ScImage::EF_TRITONE:
4252 col1 = fp.readLine();
4253 col2 = fp.readLine();
4254 col3 = fp.readLine();
4255 it = newNames.colors().find(col1);
4256 if (it != newNames.colors().end())
4257 {
4258 if (*it != CommonStrings::None)
4259 tmpstr2 += *it + "\n";
4260 else
4261 tmpstr2 += col1 + "\n";
4262 }
4263 else
4264 tmpstr2 += col1 + "\n";
4265 it = newNames.colors().find(col2);
4266 if (it != newNames.colors().end())
4267 {
4268 if (*it != CommonStrings::None)
4269 tmpstr2 += *it + "\n";
4270 else
4271 tmpstr2 += col2 + "\n";
4272 }
4273 else
4274 tmpstr2 += col2 + "\n";
4275 it = newNames.colors().find(col3);
4276 if (it != newNames.colors().end())
4277 {
4278 if (*it != CommonStrings::None)
4279 tmpstr2 += *it + "\n";
4280 else
4281 tmpstr2 += col3 + "\n";
4282 }
4283 else
4284 tmpstr2 += col3 + "\n";
4285 tmpstr2 += fp.readAll();
4286 break;
4287 case ScImage::EF_DUOTONE:
4288 col1 = fp.readLine();
4289 col2 = fp.readLine();
4290 it = newNames.colors().find(col1);
4291 if (it != newNames.colors().end())
4292 {
4293 if (*it != CommonStrings::None)
4294 tmpstr2 += *it + "\n";
4295 else
4296 tmpstr2 += col1 + "\n";
4297 }
4298 else
4299 tmpstr2 += col1 + "\n";
4300 it = newNames.colors().find(col2);
4301 if (it != newNames.colors().end())
4302 {
4303 if (*it != CommonStrings::None)
4304 tmpstr2 += *it + "\n";
4305 else
4306 tmpstr2 += col2 + "\n";
4307 }
4308 else
4309 tmpstr2 += col2 + "\n";
4310 tmpstr2 += fp.readAll();
4311 break;
4312 case ScImage::EF_COLORIZE:
4313 col1 = fp.readLine();
4314 it = newNames.colors().find(col1);
4315 if (it != newNames.colors().end())
4316 {
4317 if (*it != CommonStrings::None)
4318 tmpstr2 += *it + "\n" + fp.readAll();
4319 else
4320 tmpstr2 += col1 + "\n" + fp.readAll();
4321 }
4322 else
4323 tmpstr2 += col1 + "\n" + fp.readAll();
4324 break;
4325 default:
4326 tmpstr2 = tmpstr;
4327 break;
4328 }
4329 effectsInUse[a].effectParameters = tmpstr2;
4330 }
4331 }
4332
4333 it = newNames.patterns().find(pattern());
4334 if (it != newNames.patterns().end())
4335 setPattern(*it);
4336
4337 it = newNames.lineStyles().find(customLineStyle());
4338 if (it != newNames.lineStyles().end())
4339 setCustomLineStyle(*it);
4340
4341 if (prevInChain() == NULL)
4342 itemText.replaceNamedResources(newNames);
4343}
4344
4345
4346void PageItem::getNamedResources(ResourceCollection& lists) const
4347{
4348 lists.collectColor(lineColor());
4349 if (GrType == 0)
4350 lists.collectColor(fillColor());
4351 else if (GrType < 8)
4352 {
4353 QList<VColorStop*> cstops = fill_gradient.colorStops();
4354 for (uint cst = 0; cst < fill_gradient.Stops(); ++cst)
4355 {
4356 lists.collectColor(cstops.at(cst)->name);
4357 }
4358 }
4359 if (effectsInUse.count() != 0)
4360 {
4361 for (int a = 0; a < effectsInUse.count(); ++a)
4362 {
4363 QString tmpstr = effectsInUse.at(a).effectParameters;
4364 ScTextStream fp(&tmpstr, QIODevice::ReadOnly);
4365 switch (effectsInUse.at(a).effectCode)
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches