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 * @file
58 * For LWP filter architecture prototype
59 ************************************************************************/
60
61 #include <memory>
62 #include <lwpfrib.hxx>
63 #include "lwpcharsetmgr.hxx"
64 #include "lwpsection.hxx"
65 #include "lwphyperlinkmgr.hxx"
66 #include <xfilter/xfhyperlink.hxx>
67 #include <xfilter/xfstylemanager.hxx>
68 #include <xfilter/xfsection.hxx>
69 #include <xfilter/xfsectionstyle.hxx>
70 #include <xfilter/xftextspan.hxx>
71 #include <xfilter/xftextcontent.hxx>
72 #include "lwpfribheader.hxx"
73 #include "lwpfribtext.hxx"
74 #include "lwpfribtable.hxx"
75 #include "lwpfribbreaks.hxx"
76 #include "lwpfribframe.hxx"
77 #include "lwpfribsection.hxx"
78 #include "lwpcharacterstyle.hxx"
79 #include "lwpfootnote.hxx"
80 #include "lwpnotes.hxx"
81 #include "lwpfribmark.hxx"
82 #include <lwpchangemgr.hxx>
83 #include <lwpdocdata.hxx>
84 #include <lwpglobalmgr.hxx>
85
86 #include <osl/diagnose.h>
87
88
LwpFrib(LwpPara * pPara)89 LwpFrib::LwpFrib(LwpPara* pPara)
90 : m_pFribMap(nullptr)
91 , m_pPara(pPara)
92 , m_pNext(nullptr)
93 , m_nFribType(0)
94 , m_ModFlag(false)
95 , m_nRevisionType(0)
96 , m_bRevisionFlag(false)
97 , m_nEditor(0)
98 {
99 }
100
~LwpFrib()101 LwpFrib::~LwpFrib()
102 {
103 Deregister();
104 }
105
CreateFrib(LwpPara * pPara,LwpObjectStream * pObjStrm,sal_uInt8 fribtag,sal_uInt8 editID)106 LwpFrib* LwpFrib::CreateFrib(LwpPara* pPara, LwpObjectStream* pObjStrm, sal_uInt8 fribtag,sal_uInt8 editID)
107 {
108 //Read Modifier
109 std::unique_ptr<ModifierInfo> xModInfo;
110 if(fribtag & FRIB_TAG_MODIFIER)
111 {
112 xModInfo.reset(new ModifierInfo);
113 xModInfo->CodePage = 0;
114 xModInfo->FontID = 0;
115 xModInfo->RevisionType = 0;
116 xModInfo->RevisionFlag = false;
117 xModInfo->HasCharStyle = false;
118 xModInfo->HasLangOverride = false;
119 xModInfo->HasHighlight = false;
120 ReadModifiers(pObjStrm, xModInfo.get());
121 }
122
123 //Read frib data
124 std::unique_ptr<LwpFrib> newFrib;
125 sal_uInt16 friblen = pObjStrm->QuickReaduInt16();
126 sal_uInt8 fribtype = fribtag&~FRIB_TAG_TYPEMASK;
127 switch(fribtype)
128 {
129 case FRIB_TAG_INVALID: //fall through
130 case FRIB_TAG_EOP: //fall through
131 default:
132 newFrib.reset(new LwpFrib(pPara));
133 break;
134 case FRIB_TAG_TEXT:
135 {
136 newFrib.reset(new LwpFribText(pPara, (fribtag & FRIB_TAG_NOUNICODE) != 0));
137 break;
138 }
139 case FRIB_TAG_TABLE:
140 newFrib.reset(new LwpFribTable(pPara));
141 break;
142 case FRIB_TAG_TAB:
143 newFrib.reset(new LwpFribTab(pPara));
144 break;
145 case FRIB_TAG_PAGEBREAK:
146 newFrib.reset(new LwpFribPageBreak(pPara));
147 break;
148 case FRIB_TAG_FRAME:
149 newFrib.reset(new LwpFribFrame(pPara));
150 break;
151 case FRIB_TAG_FOOTNOTE:
152 newFrib.reset(new LwpFribFootnote(pPara));
153 break;
154 case FRIB_TAG_COLBREAK:
155 newFrib.reset(new LwpFribColumnBreak(pPara));
156 break;
157 case FRIB_TAG_LINEBREAK:
158 newFrib.reset(new LwpFribLineBreak(pPara));
159 break;
160 case FRIB_TAG_HARDSPACE:
161 newFrib.reset(new LwpFribHardSpace(pPara));
162 break;
163 case FRIB_TAG_SOFTHYPHEN:
164 newFrib.reset(new LwpFribSoftHyphen(pPara));
165 break;
166 case FRIB_TAG_PARANUMBER:
167 newFrib.reset(new LwpFribParaNumber(pPara));
168 break;
169 case FRIB_TAG_UNICODE: //fall through
170 case FRIB_TAG_UNICODE2: //fall through
171 case FRIB_TAG_UNICODE3: //fall through
172 newFrib.reset(new LwpFribUnicode(pPara));
173 break;
174 case FRIB_TAG_NOTE:
175 newFrib.reset(new LwpFribNote(pPara));
176 break;
177 case FRIB_TAG_SECTION:
178 newFrib.reset(new LwpFribSection(pPara));
179 break;
180 case FRIB_TAG_PAGENUMBER:
181 newFrib.reset(new LwpFribPageNumber(pPara));
182 break;
183 case FRIB_TAG_DOCVAR:
184 newFrib.reset(new LwpFribDocVar(pPara));
185 break;
186 case FRIB_TAG_BOOKMARK:
187 newFrib.reset(new LwpFribBookMark(pPara));
188 break;
189 case FRIB_TAG_FIELD:
190 newFrib.reset(new LwpFribField(pPara));
191 break;
192 case FRIB_TAG_CHBLOCK:
193 newFrib.reset(new LwpFribCHBlock(pPara));
194 break;
195 case FRIB_TAG_RUBYMARKER:
196 newFrib.reset(new LwpFribRubyMarker(pPara));
197 break;
198 case FRIB_TAG_RUBYFRAME:
199 newFrib.reset(new LwpFribRubyFrame(pPara));
200 break;
201 }
202
203 //Do not know why the fribTag judgement is necessary, to be checked with
204 if (fribtag & FRIB_TAG_MODIFIER)
205 {
206 newFrib->SetModifiers(xModInfo.release());
207 }
208
209 newFrib->m_nFribType = fribtype;
210 newFrib->m_nEditor = editID;
211 newFrib->Read(pObjStrm, friblen);
212 return newFrib.release();
213 }
214
Read(LwpObjectStream * pObjStrm,sal_uInt16 len)215 void LwpFrib::Read(LwpObjectStream* pObjStrm, sal_uInt16 len)
216 {
217 pObjStrm->SeekRel(len);
218 }
219
SetModifiers(ModifierInfo * pModifiers)220 void LwpFrib::SetModifiers(ModifierInfo* pModifiers)
221 {
222 if (pModifiers)
223 {
224 m_pModifiers.reset( pModifiers );
225 m_ModFlag = true;
226 if (pModifiers->RevisionFlag)
227 {
228 m_bRevisionFlag = true;
229 m_nRevisionType = pModifiers->RevisionType;
230 }
231 }
232 }
233
RegisterStyle(LwpFoundry * pFoundry)234 void LwpFrib::RegisterStyle(LwpFoundry* pFoundry)
235 {
236 if (!m_pModifiers)
237 return;
238 if (!m_pModifiers->FontID && !m_pModifiers->HasCharStyle && !m_pModifiers->HasHighlight)
239 {
240 m_ModFlag = false;
241 return;
242 }
243 //we only read four modifiers, in these modifiers,CodePage and LangOverride are not styles,
244 //so we can only handle fontid and charstyle, if others, we should not reg style
245 //note by ,1-27
246 rtl::Reference<XFFont> pFont;
247 XFTextStyle* pStyle = nullptr;
248 m_StyleName.clear();
249 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
250 XFTextStyle* pNamedStyle = nullptr;
251 if (m_pModifiers->HasCharStyle && pFoundry)
252 {
253 pNamedStyle = dynamic_cast<XFTextStyle*>
254 (pFoundry->GetStyleManager()->GetStyle(m_pModifiers->CharStyleID));
255 }
256 if (pNamedStyle)
257 {
258 LwpCharacterStyle* pCharStyle = nullptr;
259 if (m_pModifiers->FontID && pFoundry)
260 pCharStyle = dynamic_cast<LwpCharacterStyle*>(m_pModifiers->CharStyleID.obj().get());
261 if (pCharStyle)
262 {
263 std::unique_ptr<XFTextStyle> pNewStyle(new XFTextStyle());
264 *pNewStyle = *pNamedStyle;
265
266 pNewStyle->SetStyleName("");
267 pFont = pFoundry->GetFontManger().CreateOverrideFont(pCharStyle->GetFinalFontID(),m_pModifiers->FontID);
268 pNewStyle->SetFont(pFont);
269 IXFStyleRet aNewStyle = pXFStyleManager->AddStyle(std::move(pNewStyle));
270 m_StyleName = aNewStyle.m_pStyle->GetStyleName();
271 pStyle = dynamic_cast<XFTextStyle*>(aNewStyle.m_pStyle);
272 if (aNewStyle.m_bOrigDeleted)
273 pStyle = nullptr;
274 }
275 else
276 m_StyleName = pNamedStyle->GetStyleName();
277 }
278 else
279 {
280 if (m_pModifiers->FontID && pFoundry)
281 {
282 std::unique_ptr<XFTextStyle> pNewStyle(new XFTextStyle());
283 pFont = pFoundry->GetFontManger().CreateFont(m_pModifiers->FontID);
284 pNewStyle->SetFont(pFont);
285 IXFStyleRet aNewStyle = pXFStyleManager->AddStyle(std::move(pNewStyle));
286 m_StyleName = aNewStyle.m_pStyle->GetStyleName();
287 pStyle = dynamic_cast<XFTextStyle*>(aNewStyle.m_pStyle);
288 if (aNewStyle.m_bOrigDeleted)
289 pStyle = nullptr;
290 }
291 }
292
293 if (m_pModifiers->HasHighlight)
294 {
295 XFColor aColor = GetHighlightColor();//right yellow
296 if (pStyle)//change the style directly
297 pStyle->GetFont()->SetBackColor(aColor);
298 else //register a new style
299 {
300 std::unique_ptr<XFTextStyle> pNewStyle(new XFTextStyle());
301
302 if (!m_StyleName.isEmpty())
303 {
304 XFTextStyle* pOldStyle = pXFStyleManager->FindTextStyle(m_StyleName);
305 *pNewStyle = *pOldStyle;
306 pNewStyle->GetFont()->SetBackColor(aColor);
307 }
308 else
309 {
310 pFont = new XFFont;
311 pFont->SetBackColor(aColor);
312 pNewStyle->SetFont(pFont);
313 }
314 m_StyleName = pXFStyleManager->AddStyle(std::move(pNewStyle)).m_pStyle->GetStyleName();
315 }
316 }
317 }
318
ReadModifiers(LwpObjectStream * pObjStrm,ModifierInfo * pModInfo)319 void LwpFrib::ReadModifiers(LwpObjectStream* pObjStrm,ModifierInfo* pModInfo)
320 {
321 for(;;)
322 {
323 bool bFailure;
324
325 // Get the modifier type
326 sal_uInt8 Modifier = pObjStrm->QuickReaduInt8(&bFailure);
327 if (bFailure)
328 break;
329
330 // Stop when we hit the last modifier
331 if (Modifier == FRIB_MTAG_NONE)
332 break;
333
334 // Get the modifier length
335 sal_uInt8 len = pObjStrm->QuickReaduInt8(&bFailure);
336 if (bFailure)
337 break;
338
339 switch (Modifier)
340 {
341 case FRIB_MTAG_FONT:
342 if (len != sizeof(pModInfo->FontID))
343 {
344 OSL_FAIL("FRIB_MTAG_FONT entry wrong size");
345 pObjStrm->SeekRel(len);
346 }
347 else
348 pModInfo->FontID = pObjStrm->QuickReaduInt32();
349 break;
350 case FRIB_MTAG_CHARSTYLE:
351 pModInfo->HasCharStyle = true;
352 pModInfo->CharStyleID.ReadIndexed(pObjStrm);
353 break;
354 case FRIB_MTAG_LANGUAGE:
355 pModInfo->HasLangOverride = true;
356 pModInfo->Language.Read(pObjStrm);
357 break;
358 case FRIB_MTAG_CODEPAGE:
359 if (len != sizeof(pModInfo->CodePage))
360 {
361 OSL_FAIL("FRIB_MTAG_CODEPAGE entry wrong size");
362 pObjStrm->SeekRel(len);
363 }
364 else
365 pModInfo->CodePage = pObjStrm->QuickReaduInt16();
366 break;
367 case FRIB_MTAG_ATTRIBUTE:
368 pModInfo->aTxtAttrOverride.Read(pObjStrm);
369 if (pModInfo->aTxtAttrOverride.IsHighlight())
370 pModInfo->HasHighlight = true;
371 break;
372 case FRIB_MTAG_REVISION:
373 pModInfo->RevisionType = pObjStrm->QuickReaduInt8();
374 pModInfo->RevisionFlag = true;
375 break;
376 default:
377 pObjStrm->SeekRel(len);
378 break;
379 }
380 // TODO: read the modifier data
381 }
382 }
383
384 /**
385 * @descr: Whether there are other fribs following current frib.
386 * @return: True if having following fribs, or false.
387 */
HasNextFrib()388 bool LwpFrib::HasNextFrib()
389 {
390 return GetNext() && GetNext()->GetType() != FRIB_TAG_EOP;
391 }
392
ConvertChars(XFContentContainer * pXFPara,const OUString & text)393 void LwpFrib::ConvertChars(XFContentContainer* pXFPara,const OUString& text)
394 {
395 if (m_ModFlag)
396 {
397 OUString strStyleName = GetStyleName();
398 XFTextSpan *pSpan = new XFTextSpan(text,strStyleName);
399 pXFPara->Add(pSpan);
400 }
401 else
402 {
403 XFTextContent *pSpan = new XFTextContent();
404 pSpan->SetText(text);
405 pXFPara->Add(pSpan);
406 }
407 }
408
ConvertHyperLink(XFContentContainer * pXFPara,const LwpHyperlinkMgr * pHyperlink,const OUString & text)409 void LwpFrib::ConvertHyperLink(XFContentContainer* pXFPara, const LwpHyperlinkMgr* pHyperlink,const OUString& text)
410 {
411 XFHyperlink* pHyper = new XFHyperlink;
412 pHyper->SetHRef(pHyperlink->GetHyperlink());
413 pHyper->SetText(text);
414 pHyper->SetStyleName(GetStyleName());
415 pXFPara->Add(pHyper);
416 }
417
418 /**
419 * @descr: Get the current frib font style
420 * @return: XFFont pointer
421 */
GetFont()422 rtl::Reference<XFFont> LwpFrib::GetFont()
423 {
424 rtl::Reference<XFFont> pFont;
425 if(m_pModifiers&&m_pModifiers->FontID)
426 {
427 LwpFoundry* pFoundry = m_pPara->GetFoundry();
428 if (pFoundry)
429 pFont = pFoundry->GetFontManger().CreateFont(m_pModifiers->FontID);
430 }
431 else
432 {
433 XFParaStyle* pXFParaStyle = m_pPara->GetXFParaStyle();
434 pFont = pXFParaStyle->GetFont();
435 }
436 return pFont;
437 }
438
GetEditor()439 OUString LwpFrib::GetEditor()
440 {
441 LwpGlobalMgr* pGlobal = LwpGlobalMgr::GetInstance();
442 return pGlobal->GetEditorName(m_nEditor);
443 }
444
GetHighlightColor()445 XFColor LwpFrib::GetHighlightColor()
446 {
447 LwpGlobalMgr* pGlobal = LwpGlobalMgr::GetInstance();
448 return pGlobal->GetHighlightColor(m_nEditor);
449 }
450
Register(std::map<LwpFrib *,OUString> * pFribMap)451 void LwpFrib::Register(std::map<LwpFrib*,OUString>* pFribMap)
452 {
453 if (m_pFribMap)
454 throw std::runtime_error("registered already");
455 m_pFribMap = pFribMap;
456 }
457
Deregister()458 void LwpFrib::Deregister()
459 {
460 if (m_pFribMap)
461 {
462 m_pFribMap->erase(this);
463 m_pFribMap = nullptr;
464 }
465 }
466
467 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
468