1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
3  *
4  *  The Contents of this file are made available subject to the terms of
5  *  either of the following licenses
6  *
7  *         - GNU Lesser General Public License Version 2.1
8  *         - Sun Industry Standards Source License Version 1.1
9  *
10  *  Sun Microsystems Inc., October, 2000
11  *
12  *  GNU Lesser General Public License Version 2.1
13  *  =============================================
14  *  Copyright 2000 by Sun Microsystems, Inc.
15  *  901 San Antonio Road, Palo Alto, CA 94303, USA
16  *
17  *  This library is free software; you can redistribute it and/or
18  *  modify it under the terms of the GNU Lesser General Public
19  *  License version 2.1, as published by the Free Software Foundation.
20  *
21  *  This library is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  *  Lesser General Public License for more details.
25  *
26  *  You should have received a copy of the GNU Lesser General Public
27  *  License along with this library; if not, write to the Free Software
28  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29  *  MA  02111-1307  USA
30  *
31  *
32  *  Sun Industry Standards Source License Version 1.1
33  *  =================================================
34  *  The contents of this file are subject to the Sun Industry Standards
35  *  Source License Version 1.1 (the "License"); You may not use this file
36  *  except in compliance with the License. You may obtain a copy of the
37  *  License at http://www.openoffice.org/license.html.
38  *
39  *  Software provided under this License is provided on an "AS IS" basis,
40  *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
41  *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
42  *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
43  *  See the License for the specific provisions governing your rights and
44  *  obligations concerning the Software.
45  *
46  *  The Initial Developer of the Original Code is: IBM Corporation
47  *
48  *  Copyright: 2008 by IBM Corporation
49  *
50  *  All Rights Reserved.
51  *
52  *  Contributor(s): _______________________________________
53  *
54  *
55  ************************************************************************/
56 
57 #include <memory>
58 #include "lwpfootnote.hxx"
59 #include <xfilter/xffootnote.hxx>
60 #include <xfilter/xfendnote.hxx>
61 #include <xfilter/xffootnoteconfig.hxx>
62 #include <xfilter/xfendnoteconfig.hxx>
63 #include <xfilter/xfstylemanager.hxx>
64 #include <xfilter/xftextspan.hxx>
65 #include "lwppara.hxx"
66 #include "lwpdoc.hxx"
67 #include "lwpfnlayout.hxx"
68 #include <lwpglobalmgr.hxx>
69 
LwpFribFootnote(LwpPara * pPara)70 LwpFribFootnote::LwpFribFootnote(LwpPara* pPara)
71     : LwpFrib(pPara)
72 {
73 }
74 
75 /**
76  * @descr  read footnote frib information
77  */
Read(LwpObjectStream * pObjStrm,sal_uInt16)78 void LwpFribFootnote::Read(LwpObjectStream* pObjStrm, sal_uInt16 /*len*/)
79 {
80     m_Footnote.ReadIndexed(pObjStrm);
81 }
82 
83 /**
84  * @descr  Register footnote style by calling LwpFootnote::RegisterStyle()
85  */
RegisterNewStyle()86 void LwpFribFootnote::RegisterNewStyle()
87 {
88     LwpFootnote* pFootnote = GetFootnote();
89     if (pFootnote)
90     {
91         //register footnote number font style
92         LwpFrib::RegisterStyle(m_pPara->GetFoundry());
93         //register footnote content style
94         pFootnote->SetFoundry(m_pPara->GetFoundry());
95         pFootnote->RegisterStyle();
96     }
97 }
98 
99 /**
100  * @descr  Parse footnote  by calling LwpFootnote::XFConvert()
101  */
XFConvert(XFContentContainer * pCont)102 void LwpFribFootnote::XFConvert(XFContentContainer* pCont)
103 {
104     LwpFootnote* pFootnote = GetFootnote();
105     if (!pFootnote)
106         return;
107 
108     rtl::Reference<XFContentContainer> xContent;
109     if (pFootnote->GetType() == FN_FOOTNOTE)
110     {
111         xContent.set(new XFFootNote);
112     }
113     else
114     {
115         xContent.set(new XFEndNote);
116     }
117     pFootnote->XFConvert(xContent.get());
118     if (m_ModFlag)
119     {
120         //set footnote number font style
121         rtl::Reference<XFTextSpan> xSpan(new XFTextSpan);
122         xSpan->SetStyleName(GetStyleName());
123         //add the xffootnote into the content container
124         xSpan->Add(xContent.get());
125         pCont->Add(xSpan.get());
126     }
127     else
128     {
129         pCont->Add(xContent.get());
130     }
131 }
132 
133 /**
134  * @descr  Get foonote object
135  */
GetFootnote()136 LwpFootnote* LwpFribFootnote::GetFootnote()
137 {
138     return dynamic_cast<LwpFootnote*>(m_Footnote.obj().get());
139 }
140 
LwpFootnote(LwpObjectHeader const & objHdr,LwpSvStream * pStrm)141 LwpFootnote::LwpFootnote(LwpObjectHeader const& objHdr, LwpSvStream* pStrm)
142     : LwpOrderedObject(objHdr, pStrm)
143     , m_nType(0)
144     , m_nRow(0)
145 {
146 }
147 
~LwpFootnote()148 LwpFootnote::~LwpFootnote() {}
149 
150 /**
151  * @descr  Read foonote object
152  */
Read()153 void LwpFootnote::Read()
154 {
155     LwpOrderedObject::Read();
156     m_nType = m_pObjStrm->QuickReaduInt16();
157     m_nRow = m_pObjStrm->QuickReaduInt16();
158     m_Content.ReadIndexed(m_pObjStrm.get());
159     m_pObjStrm->SkipExtra();
160 }
161 
162 /**
163  * @descr  Register footnote style
164  */
RegisterStyle()165 void LwpFootnote::RegisterStyle()
166 {
167     //Only register footnote contents style,
168     //Endnote contents style registers in LwpEnSuperTableLayout::RegisterStyle
169     if (m_nType == FN_FOOTNOTE)
170     {
171         LwpContent* pContent = FindFootnoteContent();
172         if (pContent)
173         {
174             pContent->SetFoundry(m_pFoundry);
175             pContent->DoRegisterStyle();
176         }
177     }
178 }
179 
180 /**
181  * @descr  Parse footnote
182  */
XFConvert(XFContentContainer * pCont)183 void LwpFootnote::XFConvert(XFContentContainer* pCont)
184 {
185     LwpContent* pContent = FindFootnoteContent();
186     if (pContent)
187     {
188         pContent->DoXFConvert(pCont);
189     }
190 }
191 
192 /**
193  * @descr  Get endnote cell layout which contains current endnote content
194  */
GetCellLayout()195 LwpCellLayout* LwpFootnote::GetCellLayout()
196 {
197     LwpEnSuperTableLayout* pEnSuperLayout = FindFootnoteTableLayout();
198     if (pEnSuperLayout)
199     {
200         LwpTableLayout* pTableLayout
201             = dynamic_cast<LwpTableLayout*>(pEnSuperLayout->GetMainTableLayout());
202         if (pTableLayout)
203         {
204             LwpRowLayout* pRowLayout = pTableLayout->GetRowLayout(m_nRow);
205             if (pRowLayout)
206             {
207                 return dynamic_cast<LwpCellLayout*>(pRowLayout->GetChildHead().obj().get());
208             }
209         }
210     }
211     return nullptr;
212 }
213 
214 /**
215  * @descr  Get division which footnote table contains current footnote content, copy from lwp source code
216  */
GetFootnoteTableDivision()217 LwpDocument* LwpFootnote::GetFootnoteTableDivision()
218 {
219     if (!m_pFoundry)
220         return nullptr;
221 
222     LwpDocument* pPrev = nullptr;
223     LwpDocument* pDivision = nullptr;
224     LwpDocument* pFootnoteDivision = nullptr;
225 
226     // Make sure the footnote does belong to some division
227     // The division might not have a DivisionInfo if it's being Destruct()ed
228     pPrev = m_pFoundry->GetDocument();
229     pFootnoteDivision = pPrev;
230     if (!pPrev || pPrev->GetDivInfoID().IsNull())
231         return nullptr;
232 
233     switch (m_nType)
234     {
235         case FN_FOOTNOTE:
236         {
237             // Footnotes always use the source division
238             return pFootnoteDivision;
239         }
240         case FN_DIVISION:
241         {
242             // Start with the footnote's division
243             pDivision = pPrev;
244             break;
245         }
246         case FN_DIVISION_SEPARATE:
247         {
248             // It had better be the next division
249             pDivision = pPrev->GetNextDivision();
250             break;
251         }
252         case FN_DIVISIONGROUP:
253         case FN_DIVISIONGROUP_SEPARATE:
254         {
255             pDivision = pPrev->GetLastInGroupWithContents();
256             break;
257         }
258         case FN_DOCUMENT:
259         case FN_DOCUMENT_SEPARATE:
260         {
261             pDivision = pFootnoteDivision->GetRootDocument();
262             if (pDivision)
263                 pDivision = pDivision->GetLastDivisionWithContents();
264             break;
265         }
266     }
267 
268     // Make sure we're using the proper endnote division, if it's separate
269     if (m_nType & FN_MASK_SEPARATE)
270         pDivision = GetEndnoteDivision(pDivision);
271     // Don't use a division that's specifically for endnotes
272     else
273     {
274         while (pDivision)
275         {
276             if (pDivision->GetEndnoteType() == FN_DONTCARE)
277                 break;
278             if (m_nType == FN_DIVISIONGROUP)
279                 pDivision = pDivision->GetPreviousInGroup();
280             else
281                 pDivision = pDivision->GetPreviousDivisionWithContents();
282         }
283     }
284     if (pDivision)
285         return pDivision;
286     return nullptr;
287 }
288 
289 /**
290  * @descr  Get division which endnote table contains current endnote content, copy from lwp source code
291  */
GetEndnoteDivision(LwpDocument * pPossible)292 LwpDocument* LwpFootnote::GetEndnoteDivision(LwpDocument* pPossible)
293 {
294     LwpDocument* pDivision = pPossible;
295     sal_uInt16 nDivType;
296 
297     // In case we have multiple endnote divisions, walk backwards until
298     // we find one.
299     while (pDivision)
300     {
301         // Do we already have the right division?
302         nDivType = pDivision->GetEndnoteType();
303         if (nDivType == m_nType)
304             return pDivision;
305         // When we hit the first non-endnote division, stop looking.
306         // -- SDC 10/8/96
307         if (nDivType == FN_DONTCARE)
308             break;
309         pDivision = pDivision->GetPreviousDivision();
310     }
311     return nullptr;
312 }
313 
314 /**
315  * @descr  Get footnote table class name
316  */
GetTableClass() const317 OUString LwpFootnote::GetTableClass() const
318 {
319     OUString strClassName;
320     switch (GetType() & FN_MASK_BASE)
321     {
322         case FN_BASE_FOOTNOTE:
323         {
324             strClassName = STR_DivisionFootnote;
325             break;
326         }
327         case FN_BASE_DOCUMENT:
328         {
329             strClassName = STR_DocumentEndnote;
330             break;
331         }
332         case FN_BASE_DIVISION:
333         {
334             strClassName = STR_DivisionEndnote;
335             break;
336         }
337         case FN_BASE_DIVISIONGROUP:
338         {
339             strClassName = STR_DivisionGroupEndnote;
340             break;
341         }
342     }
343     return strClassName;
344 }
345 
346 /**
347  * @descr  Find footnote tablelayout, copy from lwp source code
348  */
FindFootnoteTableLayout()349 LwpEnSuperTableLayout* LwpFootnote::FindFootnoteTableLayout()
350 {
351     LwpDocument* pDivision = GetFootnoteTableDivision();
352     if (!pDivision)
353         return nullptr;
354 
355     LwpFoundry* pFoundry = pDivision->GetFoundry();
356     OUString strClassName = GetTableClass();
357     if (strClassName.isEmpty())
358         return nullptr;
359 
360     LwpContent* pContent = nullptr;
361 
362     while ((pContent = pFoundry->EnumContents(pContent)) != nullptr)
363         if (pContent->IsTable() && (strClassName == pContent->GetClassName())
364             && pContent->IsActive() && pContent->GetLayout(nullptr).is())
365         {
366             // Found it!
367             return static_cast<LwpEnSuperTableLayout*>(
368                 static_cast<LwpTable*>(pContent)->GetSuperTableLayout());
369         }
370 
371     return nullptr;
372 }
373 
374 /**
375  * @descr  Find footnote contents
376  */
FindFootnoteContent()377 LwpContent* LwpFootnote::FindFootnoteContent()
378 {
379     LwpContent* pContent = dynamic_cast<LwpContent*>(m_Content.obj().get());
380     //if the content has layout, the content has footnote contents;
381     //or looking for the celllayout and return the footnote contents.
382     if (pContent && pContent->GetLayout(nullptr).is())
383         return pContent;
384 
385     LwpCellLayout* pCellLayout = GetCellLayout();
386     if (pCellLayout)
387     {
388         pContent = dynamic_cast<LwpContent*>(pCellLayout->GetContent().obj().get());
389     }
390 
391     return pContent;
392 }
393 
LwpFootnoteTable(LwpObjectHeader const & objHdr,LwpSvStream * pStrm)394 LwpFootnoteTable::LwpFootnoteTable(LwpObjectHeader const& objHdr, LwpSvStream* pStrm)
395     : LwpTable(objHdr, pStrm)
396 {
397 }
398 
Read()399 void LwpFootnoteTable::Read()
400 {
401     LwpTable::Read();
402     m_pObjStrm->SkipExtra();
403 }
404 
405 /**
406  * @descr  Read footnote number options information
407  */
Read(LwpObjectStream * pObjStrm)408 void LwpFootnoteNumberOptions::Read(LwpObjectStream* pObjStrm)
409 {
410     m_nFlag = pObjStrm->QuickReaduInt16();
411     m_nStartingNumber = pObjStrm->QuickReaduInt16();
412     m_LeadingText.Read(pObjStrm);
413     m_TrailingText.Read(pObjStrm);
414     pObjStrm->SkipExtra();
415 }
416 
417 /**
418  * @descr  Read footnote separator options information
419  */
Read(LwpObjectStream * pObjStrm)420 void LwpFootnoteSeparatorOptions::Read(LwpObjectStream* pObjStrm)
421 {
422     m_nFlag = pObjStrm->QuickReaduInt16();
423     m_nLength = pObjStrm->QuickReaduInt32();
424     m_nIndent = pObjStrm->QuickReaduInt32();
425     m_nAbove = pObjStrm->QuickReaduInt32();
426     m_nBelow = pObjStrm->QuickReaduInt32();
427     m_BorderStuff.Read(pObjStrm);
428     pObjStrm->SkipExtra();
429 }
430 
LwpFootnoteOptions(LwpObjectHeader const & objHdr,LwpSvStream * pStrm)431 LwpFootnoteOptions::LwpFootnoteOptions(LwpObjectHeader const& objHdr, LwpSvStream* pStrm)
432     : LwpObject(objHdr, pStrm)
433     , m_nFlag(0)
434 {
435 }
436 
~LwpFootnoteOptions()437 LwpFootnoteOptions::~LwpFootnoteOptions() {}
438 
439 /**
440  * @descr  Register footnote options object
441  */
Read()442 void LwpFootnoteOptions::Read()
443 {
444     m_nFlag = m_pObjStrm->QuickReaduInt16();
445     m_FootnoteNumbering.Read(m_pObjStrm.get());
446     m_EndnoteDivisionNumbering.Read(m_pObjStrm.get());
447     m_EndnoteDivisionGroupNumbering.Read(m_pObjStrm.get());
448     m_EndnoteDocNumbering.Read(m_pObjStrm.get());
449     m_FootnoteSeparator.Read(m_pObjStrm.get());
450     m_FootnoteContinuedSeparator.Read(m_pObjStrm.get());
451     m_ContinuedOnMessage.Read(m_pObjStrm.get());
452     m_ContinuedFromMessage.Read(m_pObjStrm.get());
453     m_pObjStrm->SkipExtra();
454 }
455 
456 /**
457  * @descr  Register footnote options style
458  */
RegisterStyle()459 void LwpFootnoteOptions::RegisterStyle()
460 {
461     RegisterFootnoteStyle();
462     RegisterEndnoteStyle();
463 }
464 
465 /**
466  * @descr  Register footnote configuration information
467  */
RegisterFootnoteStyle()468 void LwpFootnoteOptions::RegisterFootnoteStyle()
469 {
470     std::unique_ptr<XFFootnoteConfig> xFootnoteConfig(new XFFootnoteConfig);
471     xFootnoteConfig->SetStartValue(m_FootnoteNumbering.GetStartingNumber() - 1);
472     xFootnoteConfig->SetNumPrefix(m_FootnoteNumbering.GetLeadingText());
473     xFootnoteConfig->SetNumSuffix(m_FootnoteNumbering.GetTrailingText());
474     if (m_FootnoteNumbering.GetReset() == LwpFootnoteNumberOptions::RESET_PAGE)
475     {
476         xFootnoteConfig->SetRestartOnPage();
477     }
478     if (GetContinuedFrom())
479     {
480         xFootnoteConfig->SetMessageFrom(GetContinuedFromMessage());
481     }
482     if (GetContinuedOn())
483     {
484         xFootnoteConfig->SetMessageOn(GetContinuedOnMessage());
485     }
486 
487     xFootnoteConfig->SetMasterPage(m_strMasterPage);
488     XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
489     pXFStyleManager->SetFootnoteConfig(xFootnoteConfig.release());
490 }
491 
492 /**
493  * @descr  Register endnote configuration information
494  */
RegisterEndnoteStyle()495 void LwpFootnoteOptions::RegisterEndnoteStyle()
496 {
497     std::unique_ptr<XFEndnoteConfig> xEndnoteConfig(new XFEndnoteConfig);
498     xEndnoteConfig->SetStartValue(m_EndnoteDocNumbering.GetStartingNumber() - 1);
499     OUString message = m_EndnoteDocNumbering.GetLeadingText();
500     if (message.isEmpty())
501     {
502         message = "["; //default prefix
503     }
504     xEndnoteConfig->SetNumPrefix(message);
505     message = m_EndnoteDocNumbering.GetTrailingText();
506     if (message.isEmpty())
507     {
508         message = "]"; //default suffix
509     }
510     xEndnoteConfig->SetNumSuffix(message);
511     if (m_EndnoteDocNumbering.GetReset() == LwpFootnoteNumberOptions::RESET_PAGE)
512     {
513         xEndnoteConfig->SetRestartOnPage();
514     }
515 
516     xEndnoteConfig->SetMasterPage(m_strMasterPage);
517 
518     XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
519     pXFStyleManager->SetEndnoteConfig(xEndnoteConfig.release());
520 }
521 
522 /**
523  * @descr  Get continue on message
524  */
GetContinuedOnMessage() const525 OUString LwpFootnoteOptions::GetContinuedOnMessage() const
526 {
527     if (m_ContinuedOnMessage.HasValue())
528     {
529         return m_ContinuedOnMessage.str();
530     }
531     // else return default message
532     return STRID_FOOTCONTINUEDON;
533 }
534 
535 /**
536  * @descr  Get continue from message
537  */
GetContinuedFromMessage() const538 OUString LwpFootnoteOptions::GetContinuedFromMessage() const
539 {
540     if (m_ContinuedFromMessage.HasValue())
541     {
542         return m_ContinuedFromMessage.str();
543     }
544     // else return default message
545     return STRID_FOOTCONTINUEDFROM;
546 }
547 
548 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
549