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 | } |