Subversion Repositories Scribus

Rev

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

Rev Author Line No. Line
17827 craig 1
#include <QMessageBox>
2
#include "pageitem_noteframe.h"
3
#include "pageitem_textframe.h"
4
#include "pageitem.h"
5
#include "scribus.h"
6
#include "scribusdoc.h"
7
#include "undomanager.h"
8
#include "util_text.h"
9
 
10
#include <cmath>
11
 
12
PageItem_NoteFrame::PageItem_NoteFrame(NotesStyle *nStyle, ScribusDoc *doc, double x, double y, double w, double h, double w2, QString fill, QString outline)
13
    : PageItem_TextFrame(doc, x, y, w, h, w2, fill, outline)
14
{
15
        m_nstyle = nStyle;
16
        m_masterFrame = NULL;
17
        itemText.clear();
18
 
19
        AnName = generateUniqueCopyName(nStyle->isEndNotes() ? tr("Endnote frame ") + m_nstyle->name() : tr("Footnote frame ") + m_nstyle->name(), false);
20
        AutoName = false; //endnotes frame will saved with name
21
        setUName(AnName);
22
 
23
        //set default style for note frame
24
        ParagraphStyle newStyle;
25
        if (nStyle->notesParStyle().isEmpty() || (nStyle->notesParStyle() == tr("No Style")))
26
        {
27
                if (nStyle->isEndNotes())
28
                        //set default doc style
29
                        newStyle.setParent(m_Doc->paragraphStyles()[0].name());
30
                else
31
                {
32
                        newStyle.setParent(m_masterFrame->itemText.defaultStyle().parent());
33
                        newStyle.applyStyle(m_masterFrame->currentStyle());
34
                }
35
        }
36
        else
37
                newStyle.setParent(nStyle->notesParStyle());
38
        itemText.blockSignals(true);
39
        itemText.setDefaultStyle(newStyle);
40
        itemText.blockSignals(false);
41
 
42
        textFlowModeVal = TextFlowUsesFrameShape;
43
        setColumns(1);
44
 
45
        if (m_nstyle->isAutoNotesHeight())
46
                m_SizeVLocked = true;
47
        else
48
                m_SizeVLocked = false;
49
        if (m_nstyle->isAutoNotesWidth())
50
                m_SizeHLocked = true;
51
        else
52
                m_SizeHLocked = false;
53
        if (m_nstyle->isAutoNotesHeight() && m_nstyle->isAutoNotesWidth())
54
                m_SizeLocked = true;
55
        else
56
                m_SizeLocked = false;
57
        deleteIt = false;
58
        l_notes.empty();
59
}
60
 
61
PageItem_NoteFrame::PageItem_NoteFrame(ScribusDoc *doc, double x, double y, double w, double h, double w2, QString fill, QString outline)
62
    : PageItem_TextFrame(doc, x, y, w, h, w2, fill, outline)
63
{
64
        m_nstyle = NULL;
65
        m_masterFrame = NULL;
66
        textFlowModeVal = TextFlowUsesFrameShape;
67
        deleteIt = false;
68
        l_notes.empty();
69
}
70
 
71
PageItem_NoteFrame::PageItem_NoteFrame(PageItem_TextFrame* inFrame, NotesStyle *nStyle) : PageItem_TextFrame(inFrame->doc(),inFrame->xPos(), inFrame->yPos(),inFrame->width(), inFrame->height(),inFrame->lineWidth(), inFrame->fillColor(), inFrame->lineColor())
72
{
73
        m_nstyle = nStyle;
74
        m_masterFrame = inFrame;
75
 
76
        AnName = generateUniqueCopyName(nStyle->isEndNotes() ? tr("Endnote frame ") + m_nstyle->name() : tr("Footnote frame ") + m_nstyle->name(), false);
77
        AutoName = false;
78
        setUName(AnName);
79
 
80
        //set default style for note frame
81
        ParagraphStyle newStyle;
82
        if (nStyle->notesParStyle().isEmpty() || (nStyle->notesParStyle() == tr("No Style")))
83
        {
84
                if (nStyle->isEndNotes())
85
                        //set default doc style
86
                        newStyle.setParent(m_Doc->paragraphStyles()[0].name());
87
                else
88
                {
89
                        newStyle.setParent(m_masterFrame->itemText.defaultStyle().parent());
90
                        newStyle.applyStyle(m_masterFrame->currentStyle());
91
                }
92
        }
93
        else
94
                newStyle.setParent(nStyle->notesParStyle());
95
        itemText.blockSignals(true);
96
        itemText.setDefaultStyle(newStyle);
97
        itemText.blockSignals(false);
98
 
99
        double frameHeight = calculateLineSpacing(newStyle, this);
100
        if (frameHeight == 0.0 && !m_nstyle->isAutoNotesHeight())
101
                frameHeight = newStyle.charStyle().fontSize()/10;
18095 craig 102
        m_height = oldHeight = frameHeight;
103
        oldWidth = m_width;
18022 craig 104
        oldRot = m_rotation;
18032 craig 105
        oldXpos = m_xPos;
106
        m_yPos = oldYpos =m_masterFrame->yPos() + m_masterFrame->height();
17827 craig 107
 
108
        textFlowModeVal = TextFlowUsesFrameShape;
109
        setColumns(1);
110
 
111
        if (m_nstyle->isAutoWeldNotesFrames() && (m_masterFrame != NULL))
112
        {
113
                addWelded(m_masterFrame);
114
                m_masterFrame->addWelded(this);
115
                m_masterFrame->setWeldPoint(0, m_masterFrame->height(), this);
116
                setWeldPoint(0,0, m_masterFrame);
117
        }
118
        if (m_nstyle->isAutoNotesHeight())
119
                m_SizeVLocked = true;
120
        else
121
                m_SizeVLocked = false;
122
        if (m_nstyle->isAutoNotesWidth())
123
                m_SizeHLocked = true;
124
        else
125
                m_SizeHLocked = false;
126
        if (m_nstyle->isAutoNotesHeight() && m_nstyle->isAutoNotesWidth())
127
                m_SizeLocked = true;
128
        else
129
                m_SizeLocked = false;
130
        deleteIt = false;
131
        l_notes.empty();
132
}
133
 
134
void PageItem_NoteFrame::setNS(NotesStyle *nStyle, PageItem_TextFrame* master)
135
{
136
        m_nstyle = nStyle;
137
        if (master != NULL)
138
                m_masterFrame = master;
139
        itemText.clear();
140
 
141
        AnName = generateUniqueCopyName(m_nstyle->isEndNotes() ? "Endnote frame " + m_nstyle->name() : "Footnote frame " + m_nstyle->name(), false);
142
        setUName(AnName);
143
 
144
        //set default style for note frame
145
        ParagraphStyle newStyle;
146
        if (nStyle->notesParStyle().isEmpty() || (nStyle->notesParStyle() == tr("No Style")))
147
        {
148
                if (nStyle->isEndNotes() || (m_masterFrame == NULL))
149
                {
150
                        //set default doc style
151
                        newStyle.setParent(m_Doc->paragraphStyles()[0].name());
152
                }
153
                else if (master != NULL)
154
                {
155
                        newStyle.setParent(m_masterFrame->itemText.defaultStyle().parent());
156
                        newStyle.applyStyle(m_masterFrame->currentStyle());
157
                }
158
        }
159
        else
160
                newStyle.setParent(nStyle->notesParStyle());
161
        itemText.blockSignals(true);
162
        itemText.setDefaultStyle(newStyle);
163
        itemText.blockSignals(false);
164
 
165
        if (m_nstyle->isAutoNotesHeight())
166
                m_SizeVLocked = true;
167
        else
168
                m_SizeVLocked = false;
169
        if (m_nstyle->isAutoNotesWidth())
170
                m_SizeHLocked = true;
171
        else
172
                m_SizeHLocked = false;
173
        if (m_nstyle->isAutoNotesHeight() && m_nstyle->isAutoNotesWidth())
174
                m_SizeLocked = true;
175
        else
176
                m_SizeLocked = false;
177
}
178
 
179
void PageItem_NoteFrame::layout()
180
{
181
        if (!invalid || l_notes.isEmpty())
182
                return;
183
        if (!m_Doc->flag_layoutNotesFrames)
184
                return;
185
        if (itemText.length() == 0)
186
                return;
187
        if ((masterFrame() != NULL) && masterFrame()->invalid)
188
                return;
189
 
190
        //while layouting notes frames undo should be disabled
191
        UndoManager::instance()->setUndoEnabled(false);
192
 
18095 craig 193
        if (m_nstyle->isAutoNotesWidth() && (m_width != m_masterFrame->width()))
17827 craig 194
        {
18095 craig 195
                oldWidth = m_width = m_masterFrame->width();
17827 craig 196
                updateClip();
197
        }
198
 
199
        if ((m_Doc->appMode == modeEdit) && isSelected())
200
                updateNotesText();
201
 
202
        PageItem_TextFrame::layout();
18095 craig 203
        int oldH = m_height;
17827 craig 204
        if (notesStyle()->isAutoNotesHeight())
205
        {
206
                if (frameOverflows())
207
                {
208
                        //increase height while text don`t fit in frame
18032 craig 209
                        double maxH = m_Doc->currentPage()->height() - m_xPos;
17827 craig 210
                        while (frameOverflows())
211
                        {
18095 craig 212
                                oldHeight = m_height += 8;
17827 craig 213
                                updateClip(false);
214
                                invalid = true;
215
                                PageItem_TextFrame::layout();
18095 craig 216
                                if (m_height >= maxH)
17827 craig 217
                                        break;
218
                        }
219
                }
220
                double hackValue = 0.5;
18095 craig 221
                oldHeight = m_height = ceil(maxY) + m_textDistanceMargins.Bottom + hackValue;
17827 craig 222
                updateConstants();
223
                updateClip();
224
                invalid = true;
225
                PageItem_TextFrame::layout();
226
        }
227
        if (oldH != height())
228
        {
229
                if (masterFrame() != NULL)
230
                {
231
                        foreach(PageItem_NoteFrame* nF, masterFrame()->notesFramesList())
232
                                nF->invalid = true;
233
                }
234
        }
235
        invalid = false;
236
        m_Doc->regionsChanged()->update(getBoundingRect());
237
        UndoManager::instance()->setUndoEnabled(true);
238
}
239
 
240
void PageItem_NoteFrame::insertNote(TextNote *note)
241
{
242
        Mark* mrk = note->noteMark();
243
        if (mrk == NULL)
244
        {
245
                mrk = m_Doc->newMark();
246
                mrk->setType(MARKNoteFrameType);
247
                QString label = "NoteFrameMark_" + notesStyle()->name();
248
                if (notesStyle()->range() == NSRsection)
249
                        label += " in section " + m_Doc->getSectionNameForPageIndex(note->masterMark()->OwnPage) + " page " + QString::number(note->masterMark()->OwnPage +1);
250
                else if (notesStyle()->range() == NSRpage)
251
                        label += " on page " + QString::number(note->masterMark()->OwnPage +1);
252
                else if (notesStyle()->range() == NSRstory)
253
                        label += " in " + note->masterMark()->getItemPtr()->firstInChain()->itemName();
254
                else if (notesStyle()->range() == NSRframe)
255
                        label += " in frame " + note->masterMark()->getItemName();
256
                mrk->label = label + "_" + note->numString();
257
                mrk->setNotePtr(note);
258
                getUniqueName(mrk->label, m_Doc->marksLabelsList(MARKNoteFrameType), "_");
259
                note->setNoteMark(mrk);
260
        }
261
        mrk->setItemPtr(this);
262
        mrk->setString(notesStyle()->prefix() + note->numString() + note->notesStyle()->suffix());
263
 
264
        StoryText story;
265
        if (!note->saxedText().isEmpty())
266
                story = desaxeString(m_Doc, note->saxedText());
267
        story.insertMark(mrk, 0);
268
        story.setDefaultStyle(itemText.defaultStyle());
269
//      story.applyCharStyle(0, story.length(), itemText.charStyle());
270
        if (itemText.length() > 0)
271
                itemText.insertChars(itemText.length(), SpecialChars::PARSEP);
272
        itemText.insert(itemText.length(), story);
273
}
274
 
275
void PageItem_NoteFrame::updateNotes(QList<TextNote*> nList, bool clear)
276
{
277
        if (nList == l_notes && !clear)
278
                return;
279
        UndoManager::instance()->setUndoEnabled(false);
280
        m_Doc->setNotesChanged(true);
281
        //itemText.blockSignals(true);
282
 
283
        if (clear)
284
        {
285
                itemText.selectAll();
286
                deleteSelectedTextFromFrame();
287
                l_notes = nList;
288
                for (int a=0; a < l_notes.count(); ++a)
289
                        insertNote(l_notes.at(a));
290
        }
291
        else
292
        {
293
                //just insert new notes into frame notes list
294
                int count = nList.count();
295
                if (count > 0)
296
                {
297
                        for (int i=0; i< count; ++i)
298
                        {
299
                                TextNote* note = nList.at(i);
300
                                if (!l_notes.contains(note))
301
                                {
302
                                        l_notes.append(note);
303
                                        insertNote(note);
304
                                }
305
                        }
306
                }
307
        }
308
        UndoManager::instance()->setUndoEnabled(true);
309
        //itemText.blockSignals(false);
310
        invalid = true;
311
}
312
 
313
void PageItem_NoteFrame::updateNotesText()
314
{
315
        //read texts from notes frame and copy it to note`s data
316
        if (l_notes.isEmpty() || (itemText.length() == 0))
317
                return;
318
 
319
        int oldSelStart = itemText.startOfSelection();
320
        int oldSelLen = itemText.lengthOfSelection();
321
        int pos = 0;
322
        int startPos = 0;
323
        TextNote *note = NULL;
324
        Mark* prevMrk = NULL;
325
        while (pos < itemText.length())
326
        {
18524 avox 327
        if (itemText.hasMark(pos))
17827 craig 328
                {
18524 avox 329
            Mark* mark = itemText.mark(pos);
330
            if  (mark->isType(MARKNoteFrameType))
331
            {
332
                if (prevMrk != NULL)
333
                {
334
                    note = prevMrk->getNotePtr();
335
                    if (note != NULL)
336
                    {
337
                        int offset = 0;
338
                        if (itemText.text(pos-1) == SpecialChars::PARSEP)
339
                            ++offset;
340
                        int len = pos - startPos -offset;
341
                        if (len <= 0)
342
                            note->setSaxedText("");
343
                        else
344
                            note->setSaxedText(getItemTextSaxed(startPos, len));
345
                        note->textLen = len;
346
                        itemText.deselectAll();
347
                    }
348
                }
349
                prevMrk = mark;
350
                startPos = pos +1;
351
            }
17827 craig 352
                }
353
                ++pos;
354
        }
355
        if (prevMrk != NULL)
356
        {
357
                note = prevMrk->getNotePtr();
358
                Q_ASSERT(note != NULL);
359
                if (startPos != pos)
360
                {
361
                        note->setSaxedText(getItemTextSaxed(startPos, pos - startPos));
362
                        note->textLen = pos - startPos;
363
                }
364
                else //empty note text (only note marker)
365
                {
366
                        note->setSaxedText("");
367
                        note->textLen = 0;
368
                }
369
        }
370
        if (oldSelLen > 0)
371
                itemText.select(oldSelStart, oldSelLen);
372
}
373
 
374
void PageItem_NoteFrame::restoreDeleteNoteText(SimpleState *state, bool isUndo)
375
{
376
        PageItem::restoreDeleteFrameText(state, isUndo);
377
        updateNotesText();
378
}
379
 
380
void PageItem_NoteFrame::restoreInsertNoteText(SimpleState *state, bool isUndo)
381
{
382
        PageItem::restoreInsertFrameText(state, isUndo);
383
        updateNotesText();
384
}
385
 
386
void PageItem_NoteFrame::unWeld(bool doUndo)
387
{
388
        if (doUndo)
389
                PageItem::unWeld();
390
        else
391
        {
392
                for (int a = 0 ; a < weldList.count(); a++)
393
                {
394
                        weldingInfo wInf = weldList.at(a);
395
                        PageItem *pIt = wInf.weldItem;
396
                        for (int b = 0 ; b < pIt->weldList.count(); b++)
397
                        {
398
                                weldingInfo wInf2 = pIt->weldList.at(b);
399
                                PageItem *pIt2 = wInf2.weldItem;
400
                                if (pIt2 == this)
401
                                {
402
                                        pIt->weldList.removeAt(b);
403
                                        break;
404
                                }
405
                        }
406
                }
407
                weldList.clear();
408
        }
409
}
410
 
411
int PageItem_NoteFrame::findNoteCpos(TextNote* note)
412
{
413
        //find position of note in note`s frame
414
        if (itemText.length() == 0)
415
                return -1;
416
        for (int pos=0; pos < itemText.length(); ++pos)
417
        {
18524 avox 418
        Mark* mark = itemText.mark(pos);
419
        if (itemText.hasMark(pos) && mark->isType(MARKNoteFrameType))
17827 craig 420
                {
18524 avox 421
            if (mark->getNotePtr() == note)
17827 craig 422
                                return (pos);
423
                }
424
        }
425
        return -1;
426
}