Subversion Repositories Scribus

Rev

Rev 18524 | Rev 19310 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
17560 jainbasil 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.'
6
*/
7
#include "api_textitem.h"
8
#include "units.h"
9
#include "scribusdoc.h"
10
#include "selection.h"
11
#include "utils.h"
12
#include "hyphenator.h"
13
#include "scripterimpl.h"
14
 
18524 avox 15
template<typename T>
16
class ApplyCharstyleHelper {
17
        PageItem* item;
18
        T value;
19
public:
20
        ApplyCharstyleHelper(PageItem* i, T v) : item(i), value(v) {}
21
 
22
        void apply(void (CharStyle::*f)(T), int p, int len)
23
        {
24
                CharStyle cs;
25
                (cs.*f)(value);
26
                if (item->HasSel)
27
                {
28
                        int max = qMax(p+len, item->itemText.length());
29
                        for (int b = p; b < max; b++)
30
                        {
31
                                if (item->itemText.selected(b))
32
                                        item->itemText.applyCharStyle(b, 1, cs);
33
                        }
34
                }
35
                else
36
                {
37
                        item->itemText.applyCharStyle(p, len, cs);
38
                }
39
        }
40
 
41
};
42
 
17638 jainbasil 43
TextAPI::TextAPI(PageItem_TextFrame* inner) : ItemAPI(inner)
17560 jainbasil 44
{
45
        qDebug() << "TextItemWrapper loaded";
46
        setObjectName("textItem");
47
        item = inner;
48
}
49
 
17638 jainbasil 50
QString TextAPI::font()
17560 jainbasil 51
{
52
        if (item->HasSel)
53
        {
54
                for (int b = 0; b < item->itemText.length(); b++)
55
                        if (item->itemText.selected(b))
56
                                return item->itemText.charStyle(b).font().scName();
57
                return NULL;
58
        }
59
        else
60
                return item->currentCharStyle().font().scName();
61
}
62
 
17638 jainbasil 63
void TextAPI::setFont(QString name)
17560 jainbasil 64
{
65
        if (PrefsManager::instance()->appPrefs.fontPrefs.AvailFonts.contains(name))
66
        {
67
                int Apm = ScCore->primaryMainWindow()->doc->appMode;
68
                ScCore->primaryMainWindow()->doc->m_Selection->clear();
69
                ScCore->primaryMainWindow()->doc->m_Selection->addItem(item);
70
                if (item->HasSel)
71
                        ScCore->primaryMainWindow()->doc->appMode = modeEdit;
72
                ScCore->primaryMainWindow()->SetNewFont(name);
73
                ScCore->primaryMainWindow()->doc->appMode = Apm;
74
                ScCore->primaryMainWindow()->view->Deselect();
75
        }
76
        else
77
        {
78
                RAISE("Font not found");
79
        }
80
 
81
}
82
 
17638 jainbasil 83
double TextAPI::fontSize()
17560 jainbasil 84
{
85
        if (item->HasSel)
86
        {
87
                for (int b = 0; b < item->itemText.length(); b++)
88
                        if (item->itemText.selected(b))
89
                                return item->itemText.charStyle(b).fontSize() / 10.0;
90
                return NULL;
91
        }
92
        else
93
        {
94
                return item->currentCharStyle().fontSize() / 10.0;
95
        }
96
}
97
 
17638 jainbasil 98
void TextAPI::setFontSize(double size)
17560 jainbasil 99
{
100
        int Apm = ScCore->primaryMainWindow()->doc->appMode;
101
        ScCore->primaryMainWindow()->doc->m_Selection->clear();
102
        ScCore->primaryMainWindow()->doc->m_Selection->addItem(item);
103
        if (item->HasSel)
104
                ScCore->primaryMainWindow()->doc->appMode = modeEdit;
105
        ScCore->primaryMainWindow()->doc->itemSelection_SetFontSize(qRound(size * 10.0));
106
        ScCore->primaryMainWindow()->doc->appMode = Apm;
107
        ScCore->primaryMainWindow()->view->Deselect();
108
}
109
 
17638 jainbasil 110
void TextAPI::setText(QString text)
17560 jainbasil 111
{
112
        text.replace("\r\n", SpecialChars::PARSEP);
113
        text.replace(QChar('\n') , SpecialChars::PARSEP);
114
        item->itemText.clear();
115
//      for (int a = 0; a < ScCore->primaryMainWindow()->doc->FrameItems.count(); ++a)
116
//      {
117
//              ScCore->primaryMainWindow()->doc->FrameItems[a]->ItemNr = a;
118
//      } TODO fix this :FrameItems has been changed to QHash from QList
119
        qDebug()<<"text : "<<text;
120
        item->itemText.insertChars(0, text);
121
        item->invalidateLayout();
122
        item->Dirty = false;
123
        ScCore->primaryMainWindow()->view->DrawNew();
124
}
125
 
17638 jainbasil 126
QString TextAPI::text()
17560 jainbasil 127
{
128
        QString text = "";
129
        for (int a = 0; a < item->itemText.length(); a++)
130
        {
131
                if (item->HasSel)
132
                {
133
                        if (item->itemText.selected(a))
134
                                text += item->itemText.text(a);
135
                }
136
                else
137
                {
138
                        text += item->itemText.text(a);
139
                }
140
        } // for
141
        return text;
142
}
143
 
17638 jainbasil 144
int TextAPI::textLines()
17560 jainbasil 145
{
18999 avox 146
        return item->textLayout.lines();
17560 jainbasil 147
}
148
 
17638 jainbasil 149
int TextAPI::textLength()
17560 jainbasil 150
{
151
        return item->itemText.length();
152
}
153
 
17638 jainbasil 154
double TextAPI::lineSpacing()
17560 jainbasil 155
{
156
        return item->currentStyle().lineSpacing();
157
}
158
 
17638 jainbasil 159
void TextAPI::setLineSpacing(double value)
17560 jainbasil 160
{
161
        int Apm = ScCore->primaryMainWindow()->doc->appMode;
162
        ScCore->primaryMainWindow()->doc->m_Selection->clear();
163
        ScCore->primaryMainWindow()->doc->m_Selection->addItem(item);
164
        if (item->HasSel)
165
                ScCore->primaryMainWindow()->doc->appMode = modeEdit;
166
        ScCore->primaryMainWindow()->doc->itemSelection_SetLineSpacing(value);
167
        ScCore->primaryMainWindow()->doc->appMode = Apm;
168
        ScCore->primaryMainWindow()->view->Deselect();
169
}
170
 
17638 jainbasil 171
QList<QVariant> TextAPI::distances()
17560 jainbasil 172
{
173
        QList<QVariant> l;
174
        l.append(pts2value(item->textToFrameDistLeft(), ScCore->primaryMainWindow()->doc->unitIndex()));
175
        l.append(pts2value(item->textToFrameDistRight(), ScCore->primaryMainWindow()->doc->unitIndex()));
176
        l.append(pts2value(item->textToFrameDistTop(), ScCore->primaryMainWindow()->doc->unitIndex()));
177
        l.append(pts2value(item->textToFrameDistBottom(), ScCore->primaryMainWindow()->doc->unitIndex()));
178
        return l;
179
}
180
 
17638 jainbasil 181
void TextAPI::insertText(QString text, int position)
17560 jainbasil 182
{
183
        text.replace("\r\n", SpecialChars::PARSEP);
184
        text.replace(QChar('\n') , SpecialChars::PARSEP);
185
        if ((position < -1) || (position > static_cast<int>(item->itemText.length())))
186
        {
187
                RAISE("Value of position out of bound.");
188
                return;
189
        }
190
        if (position == -1)
191
                position = item->itemText.length();
192
        item->itemText.insertChars(position, text);
193
        item->Dirty = true;
194
        if (ScCore->primaryMainWindow()->doc->DoDrawing)
195
        {
196
                // FIXME adapt to Qt-4 painting style
197
                item->Dirty = false;
198
        }
199
        ScCore->primaryMainWindow()->view->DrawNew();
200
}
201
 
17638 jainbasil 202
void TextAPI::setLineSpacingMode(int mode)
17560 jainbasil 203
{
204
        if (!checkHaveDocument())
205
                RAISE("No document open");
206
        if (mode < 0 || mode > 3) // Use constants?
207
        {
208
                RAISE("Line space mode invalid, must be 0, 1 or 2");
209
        }
210
 
211
        int Apm = ScCore->primaryMainWindow()->doc->appMode;
212
        ScCore->primaryMainWindow()->doc->m_Selection->clear();
213
        ScCore->primaryMainWindow()->doc->m_Selection->addItem(item);
214
        if (item->HasSel)
215
                ScCore->primaryMainWindow()->doc->appMode = modeEdit;
216
        ScCore->primaryMainWindow()->doc->itemSelection_SetLineSpacingMode(mode);
217
        ScCore->primaryMainWindow()->doc->appMode = Apm;
218
        ScCore->primaryMainWindow()->view->Deselect();
219
}
220
 
17638 jainbasil 221
void TextAPI::setDistances(double left, double right, double top, double bottom)
17560 jainbasil 222
{
223
        if (!checkHaveDocument())
224
                RAISE("No document open");
225
        if (left < 0.0 || right < 0.0 || top < 0.0 || bottom < 0.0)
226
        {
227
                RAISE("Text distances out of bounds, must be positive.");
228
        }
229
 
230
        item->setTextToFrameDist(ValueToPoint(left), ValueToPoint(right), ValueToPoint(top), ValueToPoint(bottom));
231
}
232
 
17638 jainbasil 233
void TextAPI::setTextAlignment(int alignment)
17560 jainbasil 234
{
235
        if (!checkHaveDocument())
236
                RAISE("No document open");
237
        if ((alignment > 4) || (alignment < 0))
238
        {
239
                RAISE("Alignment out of range. Should be between 0 and 4");
240
        }
241
        int Apm = ScCore->primaryMainWindow()->doc->appMode;
242
        ScCore->primaryMainWindow()->doc->m_Selection->clear();
243
        ScCore->primaryMainWindow()->doc->m_Selection->addItem(item);
244
        if (item->HasSel)
245
                ScCore->primaryMainWindow()->doc->appMode = modeEdit;
246
        ScCore->primaryMainWindow()->setNewAlignment(alignment);
247
        ScCore->primaryMainWindow()->doc->appMode = Apm;
248
        ScCore->primaryMainWindow()->view->Deselect();
249
}
250
 
17638 jainbasil 251
void TextAPI::setTextColor(QString color)
17560 jainbasil 252
{
253
        if (!checkHaveDocument())
254
                RAISE("No document open");
18524 avox 255
 
256
        ApplyCharstyleHelper<QString>(item, color).apply(&CharStyle::setFillColor, 0, item->itemText.length());
257
 
258
//      for (int b = 0; b < item->itemText.length(); b++)
259
//      {
260
//              //FIXME: doc method
261
//              if (item->HasSel)
262
//              {
263
//                      if (item->itemText.selected(b))
264
//                              item->itemText.item(b)->setFillColor(color);
265
//              }
266
//              else
267
//                      item->itemText.item(b)->setFillColor(color);
268
//      }
17560 jainbasil 269
}
270
 
17638 jainbasil 271
void TextAPI::setTextStroke(QString color)
17560 jainbasil 272
{
273
        if (!checkHaveDocument())
274
                RAISE("No document open");
18524 avox 275
 
276
        ApplyCharstyleHelper<QString>(item, color).apply(&CharStyle::setStrokeColor, 0, item->itemText.length());
277
 
278
//      for (int b = 0; b < item->itemText.length(); b++)
279
//      {
280
//              //FIXME:NLS use document method for item
281
//              if (item->HasSel)
282
//              {
283
//                      if (item->itemText.selected(b))
284
//                              item->itemText.item(b)->setStrokeColor(color);
285
//              }
286
//              else
287
//                      item->itemText.item(b)->setStrokeColor(color);
288
//      }
17560 jainbasil 289
}
290
 
17638 jainbasil 291
void TextAPI::setTextScalingV(double value)
17560 jainbasil 292
{
293
        if (!checkHaveDocument())
294
                RAISE("No document open");
295
        if (value < 10)
296
        {
297
                RAISE("Character scaling out of bounds, must be >= 10");
298
        }
299
 
300
        int Apm = ScCore->primaryMainWindow()->doc->appMode;
301
        ScCore->primaryMainWindow()->doc->m_Selection->clear();
302
        ScCore->primaryMainWindow()->doc->m_Selection->addItem(item);
303
        if (item->HasSel)
304
                ScCore->primaryMainWindow()->doc->appMode = modeEdit;
305
        ScCore->primaryMainWindow()->doc->itemSelection_SetScaleV(qRound(value * 10));
306
        ScCore->primaryMainWindow()->doc->appMode = Apm;
307
        ScCore->primaryMainWindow()->view->Deselect();
308
 
309
}
310
 
17638 jainbasil 311
void TextAPI::setTextScalingH(double value)
17560 jainbasil 312
{
313
        if (!checkHaveDocument())
314
                RAISE("No document open");
315
        if (value < 10)
316
        {
317
                RAISE("Character scaling out of bounds, must be >= 10");
318
        }
319
 
320
        int Apm = ScCore->primaryMainWindow()->doc->appMode;
321
        ScCore->primaryMainWindow()->doc->m_Selection->clear();
322
        ScCore->primaryMainWindow()->doc->m_Selection->addItem(item);
323
        if (item->HasSel)
324
                ScCore->primaryMainWindow()->doc->appMode = modeEdit;
325
        ScCore->primaryMainWindow()->doc->itemSelection_SetScaleH(qRound(value * 10));
326
        ScCore->primaryMainWindow()->doc->appMode = Apm;
327
        ScCore->primaryMainWindow()->view->Deselect();
328
 
329
}
330
 
17638 jainbasil 331
void TextAPI::setTextShade(int w)
17560 jainbasil 332
{
333
        if (!checkHaveDocument())
334
                RAISE("No document open");
335
        if ((w < 0) || (w > 100))
336
        {
337
                RAISE("value out of bound. Should be between 0 and 100");
338
        }
339
        //FIXME:NLS use document method for that
18524 avox 340
 
341
        ApplyCharstyleHelper<double>(item, w).apply(&CharStyle::setFillShade, 0, item->itemText.length());
342
 
343
//      for (int b = 0; b < item->itemText.length(); ++b)
344
//      {
345
//              if (item->HasSel)
346
//              {
347
//                      if (item->itemText.selected(b))
348
//                              item->itemText.item(b)->setFillShade(w);
349
//              }
350
//              else
351
//                      item->itemText.item(b)->setFillShade(w);
352
//      }
17560 jainbasil 353
}
354
 
17638 jainbasil 355
void TextAPI::selectText(int start, int selcount)
17560 jainbasil 356
{
357
        if (!checkHaveDocument())
358
                RAISE("No document open");
359
 
360
        if (selcount == -1)
361
        {
362
                // user wants to select all after the start point
363
                selcount = item->itemText.length() - start;
364
                if (selcount < 0)
365
                        // user passed start that's > text in the frame
366
                        selcount = 0;
367
        }
368
        if ((start < 0) || ((start + selcount) > static_cast<int>(item->itemText.length())))
369
        {
370
                RAISE("Selection index out of bounds");
371
        }
372
 
373
        item->itemText.deselectAll();
374
        if (selcount == 0)
375
        {
376
                item->HasSel = false;
377
                return;
378
        }
379
        item->itemText.select(start, selcount, true);
380
        item->HasSel = true;
381
}
382
 
17638 jainbasil 383
void TextAPI::linkToTextFrame(QString name2)
17560 jainbasil 384
{
385
        if(name2.isEmpty())
386
        {
387
                RAISE("Destination text frame name is empty.");
388
        }
389
        if (!checkHaveDocument())
390
                RAISE("No document open");
391
 
392
        PageItem *toitem = GetUniqueItem(name2);
393
        if (toitem == NULL)
394
                return;
395
        if (!(toitem->asTextFrame()))
396
        {
397
                RAISE("Can only link text frames.");
398
        }
399
        if (toitem->itemText.length() > 0)
400
        {
401
                RAISE("Target frame must be empty.");
402
        }
403
 
404
        if (toitem->nextInChain() != 0)
405
        {
406
                RAISE("Target frame links to another frame.");
407
        }
408
        if (toitem->prevInChain() != 0)
409
        {
410
                RAISE("Target frame is linked to by another frame.");
411
        }
412
        if (toitem->itemName() == item->itemName())
413
        {
414
                RAISE("Source and target are the same object.");
415
        }
416
        // references to the others boxes
417
        item->link(toitem);
418
        ScCore->primaryMainWindow()->view->DrawNew();
419
        ScCore->primaryMainWindow()->slotDocCh();
420
}
421
 
17638 jainbasil 422
void TextAPI::unLinkTextFrames()
17560 jainbasil 423
{
424
        if (!checkHaveDocument())
425
                RAISE("No document open");
426
        // only linked
427
        if (item->prevInChain() == 0)
428
        {
429
                RAISE("Object is not a linked text frame, can't unlink.");
430
        }
431
        item->prevInChain()->unlink();
432
        // enable 'save icon' stuff
433
        ScCore->primaryMainWindow()->slotDocCh();
434
        ScCore->primaryMainWindow()->view->DrawNew();
435
}
436
 
17638 jainbasil 437
bool TextAPI::deleteText()
17560 jainbasil 438
{
439
        if (!checkHaveDocument())
440
                RAISE("No document open");
441
        if (item->HasSel){}
442
//              item->deleteSelectedTextFromFrame();
443
        else
444
        {
445
                item->itemText.clear();
446
                //for (int a = 0; a < ScCore->primaryMainWindow()->doc->FrameItems.count(); ++a)
447
                //{
448
                //      ScCore->primaryMainWindow()->doc->FrameItems.at(a)->ItemNr = a;
449
                //}TODO fix this,
450
        }
451
}
452
 
17638 jainbasil 453
bool TextAPI::traceText()
17560 jainbasil 454
{
455
        if (!checkHaveDocument())
456
                RAISE("No document open");
457
        if (item->invalid)
458
                item->layout();
459
        ScCore->primaryMainWindow()->view->Deselect(true);
460
        ScCore->primaryMainWindow()->view->SelectItem(item);
461
        ScCore->primaryMainWindow()->view->TextToPath();
17638 jainbasil 462
    return true;
17560 jainbasil 463
}
464
 
17638 jainbasil 465
int TextAPI::textOverFlows(bool checkLinks)
17560 jainbasil 466
{
467
        if (!checkHaveDocument())
468
                RAISE("No document open");
469
        /* original solution
470
        if (item->itemText.count() > item->MaxChars)
471
        return PyBool_FromLong(static_cast<long>(true));
472
        return PyBool_FromLong(static_cast<long>(false)); */
473
        /*
474
         uint firstFrame = 0;
475
        if (nolinks)
476
                firstFrame = item->itemText.count();
477
        uint chars = item->itemText.count();
478
        uint maxchars = item->MaxChars;
479
        while (item->NextBox != 0) {
480
                item = item->NextBox;
481
                chars += item->itemText.count();
482
                maxchars += item->MaxChars;
483
        }
484
        // no overrun
485
        if (nolinks)
486
                return PyInt_FromLong(maxchars - firstFrame);
487
 
488
        if (maxchars > chars)
489
                return PyInt_FromLong(0);
490
        // number of overrunning letters
491
        return PyInt_FromLong(static_cast<long>(chars - maxchars));
492
         */
493
        // refresh overflow information
494
        item->invalidateLayout();
495
        item->layout();
496
        return item->frameOverflows();
497
}
498
 
17638 jainbasil 499
bool TextAPI::hyphenate()
17560 jainbasil 500
{
501
        if (!checkHaveDocument())
502
                RAISE("No document open");
503
        ScCore->primaryMainWindow()->doc->docHyphenator->slotHyphenate(item);
504
        return true;
505
}
506
 
17638 jainbasil 507
bool TextAPI::dehyphenate()
17560 jainbasil 508
{
509
        if (!checkHaveDocument())
510
                RAISE("No document open");
511
        ScCore->primaryMainWindow()->doc->docHyphenator->slotDeHyphenate(item);
512
        return false;
513
}
514
 
17638 jainbasil 515
bool TextAPI::PDFBookMark()
17560 jainbasil 516
{
517
        if (!checkHaveDocument())
518
                RAISE("No document open");
519
        if (item->isBookmark)
520
                return true;
521
        return false;
522
}
523
 
17638 jainbasil 524
void TextAPI::setPDFBookMark(bool toggle)
17560 jainbasil 525
{
526
        if (!checkHaveDocument())
527
                RAISE("No document open");
528
        if (item->isBookmark == toggle)
529
        {
530
                return;
531
        }
532
        if (toggle)
533
        {
534
                item->setIsAnnotation(false);
535
                ScCore->primaryMainWindow()->AddBookMark(item);
536
        }
537
        else
538
                ScCore->primaryMainWindow()->DelBookMark(item);
539
        item->isBookmark = toggle;
540
}
541
 
17638 jainbasil 542
TextAPI::~TextAPI()
17560 jainbasil 543
{
544
        qDebug() << "TextItemWrapper deleted";
545
}
546
 
547