1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <tools/debug.hxx>
21 #include <i18nlangtag/languagetag.hxx>
23 #include <com/sun/star/linguistic2/ConversionDictionaryType.hpp>
24 #include <com/sun/star/linguistic2/ConversionPropertyType.hpp>
25 #include <com/sun/star/lang/Locale.hpp>
26 #include <com/sun/star/uno/Reference.h>
27 #include <com/sun/star/document/XFilter.hpp>
28 #include <com/sun/star/beans/PropertyValue.hpp>
29 #include <xmloff/namespacemap.hxx>
30 #include <xmloff/xmlnamespace.hxx>
31 #include <unotools/streamwrap.hxx>
33 #include "convdic.hxx"
34 #include "convdicxml.hxx"
35 #include <linguistic/misc.hxx>
39 using namespace com::sun::star
;
40 using namespace com::sun::star::lang
;
41 using namespace com::sun::star::uno
;
42 using namespace com::sun::star::linguistic2
;
43 using namespace linguistic
;
46 #define XML_NAMESPACE_TCD_STRING "http://openoffice.org/2003/text-conversion-dictionary"
47 #define CONV_TYPE_HANGUL_HANJA u"Hangul / Hanja"
48 #define CONV_TYPE_SCHINESE_TCHINESE u"Chinese simplified / Chinese traditional"
51 static OUString
ConversionTypeToText( sal_Int16 nConversionType
)
54 if (nConversionType
== ConversionDictionaryType::HANGUL_HANJA
)
55 aRes
= CONV_TYPE_HANGUL_HANJA
;
56 else if (nConversionType
== ConversionDictionaryType::SCHINESE_TCHINESE
)
57 aRes
= CONV_TYPE_SCHINESE_TCHINESE
;
61 static sal_Int16
GetConversionTypeFromText( std::u16string_view rText
)
64 if (rText
== CONV_TYPE_HANGUL_HANJA
)
65 nRes
= ConversionDictionaryType::HANGUL_HANJA
;
66 else if (rText
== CONV_TYPE_SCHINESE_TCHINESE
)
67 nRes
= ConversionDictionaryType::SCHINESE_TCHINESE
;
73 class ConvDicXMLImportContext
:
74 public SvXMLImportContext
77 ConvDicXMLImportContext( ConvDicXMLImport
&rImport
) :
78 SvXMLImportContext( rImport
)
82 ConvDicXMLImport
& GetConvDicImport()
84 return static_cast<ConvDicXMLImport
&>(GetImport());
88 virtual css::uno::Reference
<XFastContextHandler
> SAL_CALL
createFastChildContext(
89 sal_Int32 Element
, const css::uno::Reference
< css::xml::sax::XFastAttributeList
> & xAttrList
) override
;
93 class ConvDicXMLDictionaryContext_Impl
:
94 public ConvDicXMLImportContext
96 LanguageType nLanguage
;
97 sal_Int16 nConversionType
;
100 ConvDicXMLDictionaryContext_Impl( ConvDicXMLImport
&rImport
) :
101 ConvDicXMLImportContext( rImport
),
102 nLanguage(LANGUAGE_NONE
), nConversionType(-1)
106 // SvXMLImportContext
107 virtual void SAL_CALL
startFastElement( sal_Int32 nElement
, const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& Attribs
) override
;
108 virtual css::uno::Reference
<XFastContextHandler
> SAL_CALL
createFastChildContext(
109 sal_Int32 Element
, const css::uno::Reference
< css::xml::sax::XFastAttributeList
> & xAttrList
) override
;
113 class ConvDicXMLEntryTextContext_Impl
:
114 public ConvDicXMLImportContext
119 ConvDicXMLEntryTextContext_Impl( ConvDicXMLImport
&rImport
) :
120 ConvDicXMLImportContext( rImport
)
124 // SvXMLImportContext
125 virtual void SAL_CALL
startFastElement( sal_Int32 nElement
, const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& Attribs
) override
;
126 virtual css::uno::Reference
<XFastContextHandler
> SAL_CALL
createFastChildContext(
127 sal_Int32 Element
, const css::uno::Reference
< css::xml::sax::XFastAttributeList
> & xAttrList
) override
;
129 const OUString
& GetLeftText() const { return aLeftText
; }
133 class ConvDicXMLRightTextContext_Impl
:
134 public ConvDicXMLImportContext
137 ConvDicXMLEntryTextContext_Impl
&rEntryContext
;
140 ConvDicXMLRightTextContext_Impl(
141 ConvDicXMLImport
&rImport
,
142 ConvDicXMLEntryTextContext_Impl
&rParentContext
) :
143 ConvDicXMLImportContext( rImport
),
144 rEntryContext( rParentContext
)
148 // SvXMLImportContext
149 virtual void SAL_CALL
endFastElement( sal_Int32 nElement
) override
;
150 virtual void SAL_CALL
characters( const OUString
&rChars
) override
;
155 //void ConvDicXMLImportContext::characters(const OUString & /*rChars*/)
158 Whitespace occurring within the content of token elements is "trimmed"
159 from the ends (i.e. all whitespace at the beginning and end of the
160 content is removed), and "collapsed" internally (i.e. each sequence of
161 1 or more whitespace characters is replaced with one blank character).
163 //collapsing not done yet!
167 css::uno::Reference
<XFastContextHandler
> ConvDicXMLImportContext::createFastChildContext(
169 const css::uno::Reference
< css::xml::sax::XFastAttributeList
> & /*xAttrList*/ )
171 if ( Element
== ConvDicXMLToken::TEXT_CONVERSION_DICTIONARY
)
172 return new ConvDicXMLDictionaryContext_Impl( GetConvDicImport() );
177 void ConvDicXMLDictionaryContext_Impl::startFastElement( sal_Int32
/*nElement*/,
178 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& rxAttrList
)
180 for (auto &aIter
: sax_fastparser::castToFastAttributeList( rxAttrList
))
182 switch (aIter
.getToken())
184 case XML_NAMESPACE_TCD
| XML_LANG
:
185 nLanguage
= LanguageTag::convertToLanguageType( aIter
.toString() );
187 case XML_NAMESPACE_TCD
| XML_CONVERSION_TYPE
:
188 nConversionType
= GetConversionTypeFromText( aIter
.toString() );
194 GetConvDicImport().SetLanguage( nLanguage
);
195 GetConvDicImport().SetConversionType( nConversionType
);
199 css::uno::Reference
<XFastContextHandler
> ConvDicXMLDictionaryContext_Impl::createFastChildContext(
201 const css::uno::Reference
< css::xml::sax::XFastAttributeList
> & /*xAttrList*/ )
203 if ( Element
== ConvDicXMLToken::ENTRY
)
204 return new ConvDicXMLEntryTextContext_Impl( GetConvDicImport() );
208 css::uno::Reference
<XFastContextHandler
> ConvDicXMLEntryTextContext_Impl::createFastChildContext(
210 const css::uno::Reference
< css::xml::sax::XFastAttributeList
> & /*xAttrList*/ )
212 if ( Element
== ConvDicXMLToken::RIGHT_TEXT
)
213 return new ConvDicXMLRightTextContext_Impl( GetConvDicImport(), *this );
217 void ConvDicXMLEntryTextContext_Impl::startFastElement(
218 sal_Int32
/*Element*/,
219 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& rxAttrList
)
221 for (auto &aIter
: sax_fastparser::castToFastAttributeList( rxAttrList
))
223 switch (aIter
.getToken())
225 case XML_NAMESPACE_TCD
| XML_LEFT_TEXT
:
226 aLeftText
= aIter
.toString();
235 void ConvDicXMLRightTextContext_Impl::characters( const OUString
&rChars
)
237 aRightText
+= rChars
;
240 void ConvDicXMLRightTextContext_Impl::endFastElement( sal_Int32
/*nElement*/ )
242 ConvDic
*pDic
= GetConvDicImport().GetDic();
244 pDic
->AddEntry( rEntryContext
.GetLeftText(), aRightText
);
248 bool ConvDicXMLExport::Export()
250 uno::Reference
< document::XExporter
> xExporter( this );
251 uno::Reference
< document::XFilter
> xFilter( xExporter
, UNO_QUERY
);
252 uno::Sequence
< beans::PropertyValue
> aProps(0);
253 xFilter
->filter( aProps
); // calls exportDoc implicitly
259 ErrCode
ConvDicXMLExport::exportDoc( enum ::xmloff::token::XMLTokenEnum
/*eClass*/ )
261 GetNamespaceMap_().Add( "tcd",
262 XML_NAMESPACE_TCD_STRING
, XML_NAMESPACE_TCD
);
264 GetDocHandler()->startDocument();
266 // Add xmlns line and some other arguments
267 AddAttribute( GetNamespaceMap_().GetAttrNameByKey( XML_NAMESPACE_TCD
),
268 GetNamespaceMap_().GetNameByKey( XML_NAMESPACE_TCD
) );
269 AddAttributeASCII( XML_NAMESPACE_TCD
, "package", "org.openoffice.Office" );
271 OUString
aIsoLang( LanguageTag::convertToBcp47( rDic
.nLanguage
) );
272 AddAttribute( XML_NAMESPACE_TCD
, "lang", aIsoLang
);
273 OUString
aConvType( ConversionTypeToText( rDic
.nConversionType
) );
274 AddAttribute( XML_NAMESPACE_TCD
, "conversion-type", aConvType
);
276 //!! block necessary in order to have SvXMLElementExport d-tor called
277 //!! before the call to endDocument
279 SvXMLElementExport
aRoot( *this, XML_NAMESPACE_TCD
, "text-conversion-dictionary", true, true );
283 GetDocHandler()->endDocument();
290 void ConvDicXMLExport::ExportContent_()
292 // acquire sorted list of all keys
293 std::set
<OUString
> aKeySet
;
294 for (auto const& elem
: rDic
.aFromLeft
)
295 aKeySet
.insert( elem
.first
);
297 for (const OUString
& aLeftText
: aKeySet
)
299 AddAttribute( XML_NAMESPACE_TCD
, "left-text", aLeftText
);
300 if (rDic
.pConvPropType
) // property-type list available?
302 sal_Int16 nPropertyType
= -1;
303 PropTypeMap::iterator aIt2
= rDic
.pConvPropType
->find( aLeftText
);
304 if (aIt2
!= rDic
.pConvPropType
->end())
305 nPropertyType
= (*aIt2
).second
;
306 DBG_ASSERT( nPropertyType
, "property-type not found" );
307 if (nPropertyType
== -1)
308 nPropertyType
= ConversionPropertyType::NOT_DEFINED
;
309 AddAttribute( XML_NAMESPACE_TCD
, "property-type", OUString::number( nPropertyType
) );
311 SvXMLElementExport
aEntryMain( *this, XML_NAMESPACE_TCD
,
312 "entry" , true, true );
314 pair
< ConvMap::iterator
, ConvMap::iterator
> aRange
=
315 rDic
.aFromLeft
.equal_range(aLeftText
);
316 for (auto aIt
= aRange
.first
; aIt
!= aRange
.second
; ++aIt
)
318 DBG_ASSERT( aLeftText
== (*aIt
).first
, "key <-> entry mismatch" );
319 OUString
aRightText( (*aIt
).second
);
320 SvXMLElementExport
aEntryRightText( *this, XML_NAMESPACE_TCD
,
321 "right-text" , true, false );
322 Characters( aRightText
);
327 //!! see comment for pDic member
328 ConvDicXMLImport::ConvDicXMLImport( ConvDic
*pConvDic
) :
329 SvXMLImport ( comphelper::getProcessComponentContext(), "com.sun.star.lingu2.ConvDicXMLImport", SvXMLImportFlags::ALL
),
330 pDic ( pConvDic
), nLanguage(LANGUAGE_NONE
), nConversionType(-1)
332 GetNamespaceMap().Add( GetXMLToken(XML_NP_TCD
), GetXMLToken(XML_N_TCD
), XML_NAMESPACE_TCD
);
335 SvXMLImportContext
* ConvDicXMLImport::CreateFastContext(
337 const css::uno::Reference
< css::xml::sax::XFastAttributeList
> & /*xAttrList*/ )
339 if( Element
== ConvDicXMLToken::TEXT_CONVERSION_DICTIONARY
)
340 return new ConvDicXMLDictionaryContext_Impl( *this );
344 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */