1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #include <sal/config.h>
21
22 #include <string_view>
23
24 #include <localizationmgr.hxx>
25
26 #include <basidesh.hxx>
27 #include <baside3.hxx>
28 #include <basobj.hxx>
29 #include <iderdll.hxx>
30 #include <dlged.hxx>
31 #include <managelang.hxx>
32
33 #include <com/sun/star/frame/XLayoutManager.hpp>
34 #include <com/sun/star/resource/MissingResourceException.hpp>
35 #include <com/sun/star/resource/XStringResourceSupplier.hpp>
36 #include <sfx2/bindings.hxx>
37 #include <sfx2/sfxsids.hrc>
38 #include <sfx2/viewfrm.hxx>
39 #include <tools/debug.hxx>
40 #include <osl/diagnose.h>
41
42 namespace basctl
43 {
44
45 using namespace ::com::sun::star;
46 using namespace ::com::sun::star::uno;
47 using namespace ::com::sun::star::lang;
48 using namespace ::com::sun::star::beans;
49 using namespace ::com::sun::star::resource;
50
51 namespace
52 {
53
54 constexpr OUStringLiteral aDot(u".");
55 constexpr OUStringLiteral aEsc(u"&");
56 constexpr OUStringLiteral aSemi(u";");
57
58 } // namespace
59
LocalizationMgr(Shell * pShell,ScriptDocument const & rDocument,OUString const & aLibName,Reference<XStringResourceManager> const & xStringResourceManager)60 LocalizationMgr::LocalizationMgr(
61 Shell* pShell,
62 ScriptDocument const& rDocument,
63 OUString const& aLibName,
64 Reference<XStringResourceManager> const& xStringResourceManager
65 ) :
66 m_xStringResourceManager(xStringResourceManager),
67 m_pShell(pShell),
68 m_aDocument(rDocument),
69 m_aLibName(aLibName)
70 { }
71
isLibraryLocalized()72 bool LocalizationMgr::isLibraryLocalized ()
73 {
74 if (m_xStringResourceManager.is())
75 return m_xStringResourceManager->getLocales().hasElements();
76 return false;
77 }
78
handleTranslationbar()79 void LocalizationMgr::handleTranslationbar ()
80 {
81 static constexpr OUStringLiteral aToolBarResName = u"private:resource/toolbar/translationbar";
82
83 Reference< beans::XPropertySet > xFrameProps
84 ( m_pShell->GetViewFrame()->GetFrame().GetFrameInterface(), uno::UNO_QUERY );
85 if ( !xFrameProps.is() )
86 return;
87
88 Reference< css::frame::XLayoutManager > xLayoutManager;
89 uno::Any a = xFrameProps->getPropertyValue( "LayoutManager" );
90 a >>= xLayoutManager;
91 if ( xLayoutManager.is() )
92 {
93 if ( !isLibraryLocalized() )
94 {
95 xLayoutManager->destroyElement( aToolBarResName );
96 }
97 else
98 {
99 xLayoutManager->createElement( aToolBarResName );
100 xLayoutManager->requestElement( aToolBarResName );
101 }
102 }
103 }
104
105
106 // TODO: -> export from toolkit
107
108
isLanguageDependentProperty(const OUString & aName)109 static bool isLanguageDependentProperty( const OUString& aName )
110 {
111 static struct Prop
112 {
113 const char* sName;
114 sal_Int32 nNameLength;
115 }
116 const vProp[] =
117 {
118 { "Text", 4 },
119 { "Label", 5 },
120 { "Title", 5 },
121 { "HelpText", 8 },
122 { "CurrencySymbol", 14 },
123 { "StringItemList", 14 },
124 { nullptr, 0 }
125 };
126
127 for (Prop const* pProp = vProp; pProp->sName; ++pProp)
128 if (aName.equalsAsciiL(pProp->sName, pProp->nNameLength))
129 return true;
130 return false;
131 }
132
133
implEnableDisableResourceForAllLibraryDialogs(HandleResourceMode eMode)134 void LocalizationMgr::implEnableDisableResourceForAllLibraryDialogs( HandleResourceMode eMode )
135 {
136 Sequence< OUString > aDlgNames = m_aDocument.getObjectNames( E_DIALOGS, m_aLibName );
137 sal_Int32 nDlgCount = aDlgNames.getLength();
138 const OUString* pDlgNames = aDlgNames.getConstArray();
139
140 Reference< XStringResourceResolver > xDummyStringResolver;
141 for( sal_Int32 i = 0 ; i < nDlgCount ; i++ )
142 {
143 OUString aDlgName = pDlgNames[ i ];
144 if (VclPtr<DialogWindow> pWin = m_pShell->FindDlgWin(m_aDocument, m_aLibName, aDlgName))
145 {
146 Reference< container::XNameContainer > xDialog = pWin->GetDialog();
147 if( xDialog.is() )
148 {
149 // Handle dialog itself as control
150 Any aDialogCtrl;
151 aDialogCtrl <<= xDialog;
152 implHandleControlResourceProperties( aDialogCtrl, aDlgName,
153 std::u16string_view(), m_xStringResourceManager, xDummyStringResolver, eMode );
154
155 // Handle all controls
156 Sequence< OUString > aNames = xDialog->getElementNames();
157 const OUString* pNames = aNames.getConstArray();
158 sal_Int32 nCtrls = aNames.getLength();
159 for( sal_Int32 j = 0 ; j < nCtrls ; ++j )
160 {
161 OUString aCtrlName( pNames[j] );
162 Any aCtrl = xDialog->getByName( aCtrlName );
163 implHandleControlResourceProperties( aCtrl, aDlgName,
164 aCtrlName, m_xStringResourceManager, xDummyStringResolver, eMode );
165 }
166 }
167 }
168 }
169 }
170
171
implCreatePureResourceId(std::u16string_view aDialogName,std::u16string_view aCtrlName,std::u16string_view aPropName,const Reference<XStringResourceManager> & xStringResourceManager)172 static OUString implCreatePureResourceId
173 ( std::u16string_view aDialogName, std::u16string_view aCtrlName,
174 std::u16string_view aPropName,
175 const Reference< XStringResourceManager >& xStringResourceManager )
176 {
177 sal_Int32 nUniqueId = xStringResourceManager->getUniqueNumericId();
178 OUString aPureIdStr = OUString::number( nUniqueId )
179 + aDot
180 + aDialogName
181 + aDot;
182 if( !aCtrlName.empty() )
183 {
184 aPureIdStr += aCtrlName + aDot;
185 }
186 aPureIdStr += aPropName;
187 return aPureIdStr;
188 }
189
190 // Works on xStringResourceManager's current language for SET_IDS/RESET_IDS,
191 // anyway only one language should exist when calling this method then,
192 // either the first one for mode SET_IDS or the last one for mode RESET_IDS
implHandleControlResourceProperties(const Any & rControlAny,std::u16string_view aDialogName,std::u16string_view aCtrlName,const Reference<XStringResourceManager> & xStringResourceManager,const Reference<XStringResourceResolver> & xSourceStringResolver,HandleResourceMode eMode)193 sal_Int32 LocalizationMgr::implHandleControlResourceProperties
194 (const Any& rControlAny, std::u16string_view aDialogName, std::u16string_view aCtrlName,
195 const Reference< XStringResourceManager >& xStringResourceManager,
196 const Reference< XStringResourceResolver >& xSourceStringResolver, HandleResourceMode eMode )
197 {
198 sal_Int32 nChangedCount = 0;
199
200 Reference< XPropertySet > xPropertySet;
201 rControlAny >>= xPropertySet;
202 if( xPropertySet.is() && xStringResourceManager.is())
203 {
204 Sequence< Locale > aLocaleSeq = xStringResourceManager->getLocales();
205 sal_Int32 nLocaleCount = aLocaleSeq.getLength();
206 if( nLocaleCount == 0 )
207 return 0;
208
209 Reference< XPropertySetInfo > xPropertySetInfo = xPropertySet->getPropertySetInfo();
210 if( xPropertySetInfo.is() )
211 {
212 // get sequence of control properties
213 Sequence< Property > aPropSeq = xPropertySetInfo->getProperties();
214 const Property* pProps = aPropSeq.getConstArray();
215 sal_Int32 nCtrlProps = aPropSeq.getLength();
216
217 // create a map of tab indices and control names, sorted by tab index
218 for( sal_Int32 j = 0 ; j < nCtrlProps ; ++j )
219 {
220 const Property& rProp = pProps[j];
221 OUString aPropName = rProp.Name;
222 TypeClass eType = rProp.Type.getTypeClass();
223 bool bLanguageDependentProperty =
224 (eType == TypeClass_STRING || eType == TypeClass_SEQUENCE)
225 && isLanguageDependentProperty( aPropName );
226 if( !bLanguageDependentProperty )
227 continue;
228
229 if( eType == TypeClass_STRING )
230 {
231 Any aPropAny = xPropertySet->getPropertyValue( aPropName );
232 OUString aPropStr;
233 aPropAny >>= aPropStr;
234
235 // Replace string by id, add id+string to StringResource
236 if( eMode == SET_IDS )
237 {
238 bool bEscAlreadyExisting = aPropStr.startsWith("&");
239 if( bEscAlreadyExisting )
240 continue;
241
242 OUString aPureIdStr = implCreatePureResourceId
243 ( aDialogName, aCtrlName, aPropName, xStringResourceManager );
244
245 // Set Id for all locales
246 const Locale* pLocales = aLocaleSeq.getConstArray();
247 for( sal_Int32 i = 0 ; i < nLocaleCount ; i++ )
248 {
249 const Locale& rLocale = pLocales[ i ];
250 xStringResourceManager->setStringForLocale( aPureIdStr, aPropStr, rLocale );
251 }
252
253 OUString aPropIdStr = aEsc + aPureIdStr;
254 // TODO?: Change here and in toolkit
255 (void)aSemi;
256 xPropertySet->setPropertyValue( aPropName, Any(aPropIdStr) );
257 }
258 // Replace id by string from StringResource
259 else if( eMode == RESET_IDS )
260 {
261 if( aPropStr.getLength() > 1 )
262 {
263 OUString aPureIdStr = aPropStr.copy( 1 );
264 OUString aNewPropStr = aPropStr;
265 try
266 {
267 aNewPropStr = xStringResourceManager->resolveString( aPureIdStr );
268 }
269 catch(const MissingResourceException&)
270 {
271 }
272 xPropertySet->setPropertyValue( aPropName, Any(aNewPropStr) );
273 }
274 }
275 // Remove Id for all locales
276 else if( eMode == REMOVE_IDS_FROM_RESOURCE )
277 {
278 if( aPropStr.getLength() > 1 )
279 {
280 OUString aPureIdStr = aPropStr.copy( 1 );
281
282 const Locale* pLocales = aLocaleSeq.getConstArray();
283 for( sal_Int32 i = 0 ; i < nLocaleCount ; i++ )
284 {
285 const Locale& rLocale = pLocales[ i ];
286 try
287 {
288 xStringResourceManager->removeIdForLocale( aPureIdStr, rLocale );
289 }
290 catch(const MissingResourceException&)
291 {
292 }
293 }
294 }
295 }
296 // Rename resource id
297 else if( eMode == RENAME_DIALOG_IDS || eMode == RENAME_CONTROL_IDS )
298 {
299 OUString aPureSourceIdStr = aPropStr.copy( 1 );
300
301 OUString aPureIdStr = implCreatePureResourceId
302 ( aDialogName, aCtrlName, aPropName, xStringResourceManager );
303
304 // Set new Id and remove old one for all locales
305 const Locale* pLocales = aLocaleSeq.getConstArray();
306 for( sal_Int32 i = 0 ; i < nLocaleCount ; i++ )
307 {
308 const Locale& rLocale = pLocales[ i ];
309 try
310 {
311 OUString aResStr = xStringResourceManager->resolveStringForLocale
312 ( aPureSourceIdStr, rLocale );
313 xStringResourceManager->removeIdForLocale( aPureSourceIdStr, rLocale );
314 xStringResourceManager->setStringForLocale( aPureIdStr, aResStr, rLocale );
315 }
316 catch(const MissingResourceException&)
317 {}
318 }
319
320 OUString aPropIdStr = aEsc + aPureIdStr;
321 // TODO?: Change here and in toolkit
322 (void)aSemi;
323 xPropertySet->setPropertyValue( aPropName, Any(aPropIdStr) );
324 }
325 // Replace string by string from source StringResourceResolver
326 else if( eMode == MOVE_RESOURCES && xSourceStringResolver.is() )
327 {
328 OUString aPureSourceIdStr = aPropStr.copy( 1 );
329
330 OUString aPureIdStr = implCreatePureResourceId
331 ( aDialogName, aCtrlName, aPropName, xStringResourceManager );
332
333 const Locale& rDefaultLocale = xSourceStringResolver->getDefaultLocale();
334
335 // Set Id for all locales
336 const Locale* pLocales = aLocaleSeq.getConstArray();
337 for( sal_Int32 i = 0 ; i < nLocaleCount ; i++ )
338 {
339 const Locale& rLocale = pLocales[ i ];
340 OUString aResStr;
341 try
342 {
343 aResStr = xSourceStringResolver->resolveStringForLocale
344 ( aPureSourceIdStr, rLocale );
345 }
346 catch(const MissingResourceException&)
347 {
348 aResStr = xSourceStringResolver->resolveStringForLocale
349 ( aPureSourceIdStr, rDefaultLocale );
350 }
351 xStringResourceManager->setStringForLocale( aPureIdStr, aResStr, rLocale );
352 }
353
354 OUString aPropIdStr = aEsc + aPureIdStr;
355 // TODO?: Change here and in toolkit
356 (void)aSemi;
357 xPropertySet->setPropertyValue( aPropName, Any(aPropIdStr) );
358 }
359 // Copy string from source to target resource
360 else if( eMode == COPY_RESOURCES && xSourceStringResolver.is() )
361 {
362 OUString aPureSourceIdStr = aPropStr.copy( 1 );
363
364 const Locale& rDefaultLocale = xSourceStringResolver->getDefaultLocale();
365
366 // Copy Id for all locales
367 const Locale* pLocales = aLocaleSeq.getConstArray();
368 for( sal_Int32 i = 0 ; i < nLocaleCount ; i++ )
369 {
370 const Locale& rLocale = pLocales[ i ];
371 OUString aResStr;
372 try
373 {
374 aResStr = xSourceStringResolver->resolveStringForLocale
375 ( aPureSourceIdStr, rLocale );
376 }
377 catch(const MissingResourceException&)
378 {
379 aResStr = xSourceStringResolver->resolveStringForLocale
380 ( aPureSourceIdStr, rDefaultLocale );
381 }
382 xStringResourceManager->setStringForLocale( aPureSourceIdStr, aResStr, rLocale );
383 }
384 }
385 nChangedCount++;
386 }
387
388 // Listbox / Combobox
389 else if( eType == TypeClass_SEQUENCE )
390 {
391 Any aPropAny = xPropertySet->getPropertyValue( aPropName );
392 Sequence< OUString > aPropStrings;
393 aPropAny >>= aPropStrings;
394
395 const OUString* pPropStrings = aPropStrings.getConstArray();
396 sal_Int32 nPropStringCount = aPropStrings.getLength();
397 if( nPropStringCount == 0 )
398 continue;
399
400 // Replace string by id, add id+string to StringResource
401 if( eMode == SET_IDS )
402 {
403 Sequence< OUString > aIdStrings;
404 aIdStrings.realloc( nPropStringCount );
405 OUString* pIdStrings = aIdStrings.getArray();
406
407 OUString aIdStrBase = aDot
408 + aCtrlName
409 + aDot
410 + aPropName;
411
412 const Locale* pLocales = aLocaleSeq.getConstArray();
413 sal_Int32 i;
414 for ( i = 0; i < nPropStringCount; ++i )
415 {
416 OUString aPropStr = pPropStrings[i];
417 bool bEscAlreadyExisting = aPropStr.startsWith("&");
418 if( bEscAlreadyExisting )
419 {
420 pIdStrings[i] = aPropStr;
421 continue;
422 }
423
424 sal_Int32 nUniqueId = xStringResourceManager->getUniqueNumericId();
425 OUString aPureIdStr = OUString::number( nUniqueId )
426 + aIdStrBase;
427
428 // Set Id for all locales
429 for( sal_Int32 iLocale = 0 ; iLocale < nLocaleCount ; iLocale++ )
430 {
431 const Locale& rLocale = pLocales[ iLocale ];
432 xStringResourceManager->setStringForLocale( aPureIdStr, aPropStr, rLocale );
433 }
434
435 OUString aPropIdStr = aEsc + aPureIdStr;
436 pIdStrings[i] = aPropIdStr;
437 }
438 xPropertySet->setPropertyValue( aPropName, Any(aIdStrings) );
439 }
440 // Replace id by string from StringResource
441 else if( eMode == RESET_IDS )
442 {
443 Sequence< OUString > aNewPropStrings;
444 aNewPropStrings.realloc( nPropStringCount );
445 OUString* pNewPropStrings = aNewPropStrings.getArray();
446
447 sal_Int32 i;
448 for ( i = 0; i < nPropStringCount; ++i )
449 {
450 OUString aIdStr = pPropStrings[i];
451 OUString aNewPropStr = aIdStr;
452 if( aIdStr.getLength() > 1 )
453 {
454 OUString aPureIdStr = aIdStr.copy( 1 );
455 try
456 {
457 aNewPropStr = xStringResourceManager->resolveString( aPureIdStr );
458 }
459 catch(const MissingResourceException&)
460 {
461 }
462 }
463 pNewPropStrings[i] = aNewPropStr;
464 }
465 xPropertySet->setPropertyValue( aPropName, Any(aNewPropStrings) );
466 }
467 // Remove Id for all locales
468 else if( eMode == REMOVE_IDS_FROM_RESOURCE )
469 {
470 const Locale* pLocales = aLocaleSeq.getConstArray();
471 sal_Int32 i;
472 for ( i = 0; i < nPropStringCount; ++i )
473 {
474 OUString aIdStr = pPropStrings[i];
475 if( aIdStr.getLength() > 1 )
476 {
477 OUString aPureIdStr = aIdStr.copy( 1 );
478
479 for( sal_Int32 iLocale = 0 ; iLocale < nLocaleCount ; iLocale++ )
480 {
481 const Locale& rLocale = pLocales[iLocale];
482 try
483 {
484 xStringResourceManager->removeIdForLocale( aPureIdStr, rLocale );
485 }
486 catch(const MissingResourceException&)
487 {
488 }
489 }
490 }
491 }
492 }
493 // Rename resource id
494 else if( eMode == RENAME_CONTROL_IDS )
495 {
496 Sequence< OUString > aIdStrings;
497 aIdStrings.realloc( nPropStringCount );
498 OUString* pIdStrings = aIdStrings.getArray();
499
500 OUString aIdStrBase = aDot
501 + aCtrlName
502 + aDot
503 + aPropName;
504
505 const Locale* pLocales = aLocaleSeq.getConstArray();
506 sal_Int32 i;
507 for ( i = 0; i < nPropStringCount; ++i )
508 {
509 OUString aSourceIdStr = pPropStrings[i];
510 OUString aPureSourceIdStr = aSourceIdStr.copy( 1 );
511
512 sal_Int32 nUniqueId = xStringResourceManager->getUniqueNumericId();
513 OUString aPureIdStr = OUString::number( nUniqueId )
514 + aIdStrBase;
515
516 // Set Id for all locales
517 for( sal_Int32 iLocale = 0 ; iLocale < nLocaleCount ; iLocale++ )
518 {
519 const Locale& rLocale = pLocales[ iLocale ];
520
521 try
522 {
523 OUString aResStr = xStringResourceManager->resolveStringForLocale
524 ( aPureSourceIdStr, rLocale );
525 xStringResourceManager->removeIdForLocale( aPureSourceIdStr, rLocale );
526 xStringResourceManager->setStringForLocale( aPureIdStr, aResStr, rLocale );
527 }
528 catch(const MissingResourceException&)
529 {}
530 }
531
532 OUString aPropIdStr = aEsc + aPureIdStr;
533 pIdStrings[i] = aPropIdStr;
534 }
535 xPropertySet->setPropertyValue( aPropName, Any(aIdStrings) );
536 }
537 // Replace string by string from source StringResourceResolver
538 else if( eMode == MOVE_RESOURCES && xSourceStringResolver.is() )
539 {
540 Sequence< OUString > aIdStrings;
541 aIdStrings.realloc( nPropStringCount );
542 OUString* pIdStrings = aIdStrings.getArray();
543
544 OUString aIdStrBase = aDot
545 + aCtrlName
546 + aDot
547 + aPropName;
548
549 const Locale& rDefaultLocale = xSourceStringResolver->getDefaultLocale();
550
551 const Locale* pLocales = aLocaleSeq.getConstArray();
552 sal_Int32 i;
553 for ( i = 0; i < nPropStringCount; ++i )
554 {
555 OUString aSourceIdStr = pPropStrings[i];
556 OUString aPureSourceIdStr = aSourceIdStr.copy( 1 );
557
558 sal_Int32 nUniqueId = xStringResourceManager->getUniqueNumericId();
559 OUString aPureIdStr = OUString::number( nUniqueId )
560 + aIdStrBase;
561
562 // Set Id for all locales
563 for( sal_Int32 iLocale = 0 ; iLocale < nLocaleCount ; iLocale++ )
564 {
565 const Locale& rLocale = pLocales[ iLocale ];
566
567 OUString aResStr;
568 try
569 {
570 aResStr = xSourceStringResolver->resolveStringForLocale
571 ( aPureSourceIdStr, rLocale );
572 }
573 catch(const MissingResourceException&)
574 {
575 aResStr = xSourceStringResolver->resolveStringForLocale
576 ( aPureSourceIdStr, rDefaultLocale );
577 }
578 xStringResourceManager->setStringForLocale( aPureIdStr, aResStr, rLocale );
579 }
580
581 OUString aPropIdStr = aEsc + aPureIdStr;
582 pIdStrings[i] = aPropIdStr;
583 }
584 xPropertySet->setPropertyValue( aPropName, Any(aIdStrings) );
585 }
586 // Copy string from source to target resource
587 else if( eMode == COPY_RESOURCES && xSourceStringResolver.is() )
588 {
589 const Locale& rDefaultLocale = xSourceStringResolver->getDefaultLocale();
590
591 const Locale* pLocales = aLocaleSeq.getConstArray();
592 sal_Int32 i;
593 for ( i = 0; i < nPropStringCount; ++i )
594 {
595 OUString aSourceIdStr = pPropStrings[i];
596 OUString aPureSourceIdStr = aSourceIdStr.copy( 1 );
597
598 // Set Id for all locales
599 for( sal_Int32 iLocale = 0 ; iLocale < nLocaleCount ; iLocale++ )
600 {
601 const Locale& rLocale = pLocales[ iLocale ];
602
603 OUString aResStr;
604 try
605 {
606 aResStr = xSourceStringResolver->resolveStringForLocale
607 ( aPureSourceIdStr, rLocale );
608 }
609 catch(const MissingResourceException&)
610 {
611 aResStr = xSourceStringResolver->resolveStringForLocale
612 ( aPureSourceIdStr, rDefaultLocale );
613 }
614 xStringResourceManager->setStringForLocale( aPureSourceIdStr, aResStr, rLocale );
615 }
616 }
617 }
618 nChangedCount++;
619 }
620 }
621 }
622 }
623 return nChangedCount;
624 }
625
626
handleAddLocales(const Sequence<Locale> & aLocaleSeq)627 void LocalizationMgr::handleAddLocales( const Sequence< Locale >& aLocaleSeq )
628 {
629 const Locale* pLocales = aLocaleSeq.getConstArray();
630 sal_Int32 nLocaleCount = aLocaleSeq.getLength();
631
632 if( isLibraryLocalized() )
633 {
634 for( sal_Int32 i = 0 ; i < nLocaleCount ; i++ )
635 {
636 const Locale& rLocale = pLocales[ i ];
637 m_xStringResourceManager->newLocale( rLocale );
638 }
639 }
640 else
641 {
642 DBG_ASSERT( nLocaleCount==1, "LocalizationMgr::handleAddLocales(): Only one first locale allowed" );
643
644 const Locale& rLocale = pLocales[ 0 ];
645 m_xStringResourceManager->newLocale( rLocale );
646 enableResourceForAllLibraryDialogs();
647 }
648
649 MarkDocumentModified( m_aDocument );
650
651 // update locale toolbar
652 if (SfxBindings* pBindings = GetBindingsPtr())
653 pBindings->Invalidate( SID_BASICIDE_CURRENT_LANG );
654
655 handleTranslationbar();
656 }
657
658
handleRemoveLocales(const Sequence<Locale> & aLocaleSeq)659 void LocalizationMgr::handleRemoveLocales( const Sequence< Locale >& aLocaleSeq )
660 {
661 const Locale* pLocales = aLocaleSeq.getConstArray();
662 sal_Int32 nLocaleCount = aLocaleSeq.getLength();
663 bool bConsistent = true;
664 bool bModified = false;
665
666 for( sal_Int32 i = 0 ; i < nLocaleCount ; i++ )
667 {
668 const Locale& rLocale = pLocales[ i ];
669 bool bRemove = true;
670
671 // Check if last locale
672 Sequence< Locale > aResLocaleSeq = m_xStringResourceManager->getLocales();
673 if( aResLocaleSeq.getLength() == 1 )
674 {
675 const Locale& rLastResLocale = aResLocaleSeq.getConstArray()[ 0 ];
676 if( localesAreEqual( rLocale, rLastResLocale ) )
677 {
678 disableResourceForAllLibraryDialogs();
679 }
680 else
681 {
682 // Inconsistency, keep last locale
683 bConsistent = false;
684 bRemove = false;
685 }
686 }
687
688 if( bRemove )
689 {
690 try
691 {
692 m_xStringResourceManager->removeLocale( rLocale );
693 bModified = true;
694 }
695 catch(const IllegalArgumentException&)
696 {
697 bConsistent = false;
698 }
699 }
700 }
701 if( bModified )
702 {
703 MarkDocumentModified( m_aDocument );
704
705 // update slots
706 if (SfxBindings* pBindings = GetBindingsPtr())
707 {
708 pBindings->Invalidate( SID_BASICIDE_CURRENT_LANG );
709 pBindings->Invalidate( SID_BASICIDE_MANAGE_LANG );
710 }
711
712 handleTranslationbar();
713 }
714
715 DBG_ASSERT( bConsistent,
716 "LocalizationMgr::handleRemoveLocales(): sequence contains unsupported locales" );
717 }
718
handleSetDefaultLocale(const Locale & rLocale)719 void LocalizationMgr::handleSetDefaultLocale(const Locale& rLocale)
720 {
721 if( !m_xStringResourceManager.is() )
722 return;
723
724 try
725 {
726 m_xStringResourceManager->setDefaultLocale(rLocale);
727 }
728 catch(const IllegalArgumentException&)
729 {
730 OSL_FAIL( "LocalizationMgr::handleSetDefaultLocale: Invalid locale" );
731 }
732
733 // update locale toolbar
734 if (SfxBindings* pBindings = GetBindingsPtr())
735 pBindings->Invalidate( SID_BASICIDE_CURRENT_LANG );
736 }
737
handleSetCurrentLocale(const css::lang::Locale & rLocale)738 void LocalizationMgr::handleSetCurrentLocale(const css::lang::Locale& rLocale)
739 {
740 if( !m_xStringResourceManager.is() )
741 return;
742
743 try
744 {
745 m_xStringResourceManager->setCurrentLocale(rLocale, false);
746 }
747 catch(const IllegalArgumentException&)
748 {
749 OSL_FAIL( "LocalizationMgr::handleSetCurrentLocale: Invalid locale" );
750 }
751
752 // update locale toolbar
753 if (SfxBindings* pBindings = GetBindingsPtr())
754 pBindings->Invalidate( SID_BASICIDE_CURRENT_LANG );
755
756 if (DialogWindow* pDlgWin = dynamic_cast<DialogWindow*>(m_pShell->GetCurWindow()))
757 if (!pDlgWin->IsSuspended())
758 pDlgWin->GetEditor().UpdatePropertyBrowserDelayed();
759 }
760
handleBasicStarted()761 void LocalizationMgr::handleBasicStarted()
762 {
763 if( m_xStringResourceManager.is() )
764 m_aLocaleBeforeBasicStart = m_xStringResourceManager->getCurrentLocale();
765 }
766
handleBasicStopped()767 void LocalizationMgr::handleBasicStopped()
768 {
769 try
770 {
771 if( m_xStringResourceManager.is() )
772 m_xStringResourceManager->setCurrentLocale( m_aLocaleBeforeBasicStart, true );
773 }
774 catch(const IllegalArgumentException&)
775 {
776 }
777 }
778
779
FindDialogWindowForEditor(DlgEditor const * pEditor)780 static DialogWindow* FindDialogWindowForEditor( DlgEditor const * pEditor )
781 {
782 Shell::WindowTable const& aWindowTable = GetShell()->GetWindowTable();
783 for (auto const& window : aWindowTable)
784 {
785 BaseWindow* pWin = window.second;
786 if (!pWin->IsSuspended())
787 if (DialogWindow* pDlgWin = dynamic_cast<DialogWindow*>(pWin))
788 {
789 if (&pDlgWin->GetEditor() == pEditor)
790 return pDlgWin;
791 }
792 }
793 return nullptr;
794 }
795
796
setControlResourceIDsForNewEditorObject(DlgEditor const * pEditor,const Any & rControlAny,std::u16string_view aCtrlName)797 void LocalizationMgr::setControlResourceIDsForNewEditorObject( DlgEditor const * pEditor,
798 const Any& rControlAny, std::u16string_view aCtrlName )
799 {
800 // Get library for DlgEditor
801 DialogWindow* pDlgWin = FindDialogWindowForEditor( pEditor );
802 if( !pDlgWin )
803 return;
804 ScriptDocument aDocument( pDlgWin->GetDocument() );
805 DBG_ASSERT( aDocument.isValid(), "LocalizationMgr::setControlResourceIDsForNewEditorObject: invalid document!" );
806 if ( !aDocument.isValid() )
807 return;
808 const OUString& rLibName = pDlgWin->GetLibName();
809 Reference< container::XNameContainer > xDialogLib( aDocument.getLibrary( E_DIALOGS, rLibName, true ) );
810 Reference< XStringResourceManager > xStringResourceManager =
811 LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );
812
813 // Set resource property
814 if( !xStringResourceManager.is() || !xStringResourceManager->getLocales().hasElements() )
815 return;
816
817 OUString aDialogName = pDlgWin->GetName();
818 Reference< XStringResourceResolver > xDummyStringResolver;
819 sal_Int32 nChangedCount = implHandleControlResourceProperties
820 ( rControlAny, aDialogName, aCtrlName, xStringResourceManager,
821 xDummyStringResolver, SET_IDS );
822
823 if( nChangedCount )
824 MarkDocumentModified( aDocument );
825 }
826
renameControlResourceIDsForEditorObject(DlgEditor const * pEditor,const css::uno::Any & rControlAny,std::u16string_view aNewCtrlName)827 void LocalizationMgr::renameControlResourceIDsForEditorObject( DlgEditor const * pEditor,
828 const css::uno::Any& rControlAny, std::u16string_view aNewCtrlName )
829 {
830 // Get library for DlgEditor
831 DialogWindow* pDlgWin = FindDialogWindowForEditor( pEditor );
832 if( !pDlgWin )
833 return;
834 ScriptDocument aDocument( pDlgWin->GetDocument() );
835 DBG_ASSERT( aDocument.isValid(), "LocalizationMgr::renameControlResourceIDsForEditorObject: invalid document!" );
836 if ( !aDocument.isValid() )
837 return;
838 const OUString& rLibName = pDlgWin->GetLibName();
839 Reference< container::XNameContainer > xDialogLib( aDocument.getLibrary( E_DIALOGS, rLibName, true ) );
840 Reference< XStringResourceManager > xStringResourceManager =
841 LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );
842
843 // Set resource property
844 if( !xStringResourceManager.is() || !xStringResourceManager->getLocales().hasElements() )
845 return;
846
847 OUString aDialogName = pDlgWin->GetName();
848 Reference< XStringResourceResolver > xDummyStringResolver;
849 implHandleControlResourceProperties
850 ( rControlAny, aDialogName, aNewCtrlName, xStringResourceManager,
851 xDummyStringResolver, RENAME_CONTROL_IDS );
852 }
853
854
deleteControlResourceIDsForDeletedEditorObject(DlgEditor const * pEditor,const Any & rControlAny,std::u16string_view aCtrlName)855 void LocalizationMgr::deleteControlResourceIDsForDeletedEditorObject( DlgEditor const * pEditor,
856 const Any& rControlAny, std::u16string_view aCtrlName )
857 {
858 // Get library for DlgEditor
859 DialogWindow* pDlgWin = FindDialogWindowForEditor( pEditor );
860 if( !pDlgWin )
861 return;
862 ScriptDocument aDocument( pDlgWin->GetDocument() );
863 DBG_ASSERT( aDocument.isValid(), "LocalizationMgr::deleteControlResourceIDsForDeletedEditorObject: invalid document!" );
864 if ( !aDocument.isValid() )
865 return;
866 const OUString& rLibName = pDlgWin->GetLibName();
867 Reference< container::XNameContainer > xDialogLib( aDocument.getLibrary( E_DIALOGS, rLibName, true ) );
868 Reference< XStringResourceManager > xStringResourceManager =
869 LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );
870
871 OUString aDialogName = pDlgWin->GetName();
872 Reference< XStringResourceResolver > xDummyStringResolver;
873 sal_Int32 nChangedCount = implHandleControlResourceProperties
874 ( rControlAny, aDialogName, aCtrlName, xStringResourceManager,
875 xDummyStringResolver, REMOVE_IDS_FROM_RESOURCE );
876
877 if( nChangedCount )
878 MarkDocumentModified( aDocument );
879 }
880
setStringResourceAtDialog(const ScriptDocument & rDocument,const OUString & aLibName,std::u16string_view aDlgName,const Reference<container::XNameContainer> & xDialogModel)881 void LocalizationMgr::setStringResourceAtDialog( const ScriptDocument& rDocument, const OUString& aLibName,
882 std::u16string_view aDlgName, const Reference< container::XNameContainer >& xDialogModel )
883 {
884 // Get library
885 Reference< container::XNameContainer > xDialogLib( rDocument.getLibrary( E_DIALOGS, aLibName, true ) );
886 Reference< XStringResourceManager > xStringResourceManager =
887 LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );
888
889 // Set resource property
890 if( !xStringResourceManager.is() )
891 return;
892
893 // Not very elegant as dialog may or may not be localized yet
894 // TODO: Find better place, where dialog is created
895 if( xStringResourceManager->getLocales().hasElements() )
896 {
897 Any aDialogCtrl;
898 aDialogCtrl <<= xDialogModel;
899 Reference< XStringResourceResolver > xDummyStringResolver;
900 implHandleControlResourceProperties( aDialogCtrl, aDlgName,
901 std::u16string_view(), xStringResourceManager,
902 xDummyStringResolver, SET_IDS );
903 }
904
905 Reference< beans::XPropertySet > xDlgPSet( xDialogModel, UNO_QUERY );
906 xDlgPSet->setPropertyValue( "ResourceResolver", Any(xStringResourceManager) );
907 }
908
renameStringResourceIDs(const ScriptDocument & rDocument,const OUString & aLibName,std::u16string_view aDlgName,const Reference<container::XNameContainer> & xDialogModel)909 void LocalizationMgr::renameStringResourceIDs( const ScriptDocument& rDocument, const OUString& aLibName,
910 std::u16string_view aDlgName, const Reference< container::XNameContainer >& xDialogModel )
911 {
912 // Get library
913 Reference< container::XNameContainer > xDialogLib( rDocument.getLibrary( E_DIALOGS, aLibName, true ) );
914 Reference< XStringResourceManager > xStringResourceManager =
915 LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );
916 if( !xStringResourceManager.is() )
917 return;
918
919 Any aDialogCtrl;
920 aDialogCtrl <<= xDialogModel;
921 Reference< XStringResourceResolver > xDummyStringResolver;
922 implHandleControlResourceProperties( aDialogCtrl, aDlgName,
923 std::u16string_view(), xStringResourceManager,
924 xDummyStringResolver, RENAME_DIALOG_IDS );
925
926 // Handle all controls
927 Sequence< OUString > aNames = xDialogModel->getElementNames();
928 const OUString* pNames = aNames.getConstArray();
929 sal_Int32 nCtrls = aNames.getLength();
930 for( sal_Int32 i = 0 ; i < nCtrls ; ++i )
931 {
932 OUString aCtrlName( pNames[i] );
933 Any aCtrl = xDialogModel->getByName( aCtrlName );
934 implHandleControlResourceProperties( aCtrl, aDlgName,
935 aCtrlName, xStringResourceManager,
936 xDummyStringResolver, RENAME_DIALOG_IDS );
937 }
938 }
939
removeResourceForDialog(const ScriptDocument & rDocument,const OUString & aLibName,std::u16string_view aDlgName,const Reference<container::XNameContainer> & xDialogModel)940 void LocalizationMgr::removeResourceForDialog( const ScriptDocument& rDocument, const OUString& aLibName,
941 std::u16string_view aDlgName, const Reference< container::XNameContainer >& xDialogModel )
942 {
943 // Get library
944 Reference< container::XNameContainer > xDialogLib( rDocument.getLibrary( E_DIALOGS, aLibName, true ) );
945 Reference< XStringResourceManager > xStringResourceManager =
946 LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );
947 if( !xStringResourceManager.is() )
948 return;
949
950 Any aDialogCtrl;
951 aDialogCtrl <<= xDialogModel;
952 Reference< XStringResourceResolver > xDummyStringResolver;
953 implHandleControlResourceProperties( aDialogCtrl, aDlgName,
954 std::u16string_view(), xStringResourceManager,
955 xDummyStringResolver, REMOVE_IDS_FROM_RESOURCE );
956
957 // Handle all controls
958 Sequence< OUString > aNames = xDialogModel->getElementNames();
959 const OUString* pNames = aNames.getConstArray();
960 sal_Int32 nCtrls = aNames.getLength();
961 for( sal_Int32 i = 0 ; i < nCtrls ; ++i )
962 {
963 OUString aCtrlName( pNames[i] );
964 Any aCtrl = xDialogModel->getByName( aCtrlName );
965 implHandleControlResourceProperties( aCtrl, aDlgName,
966 aCtrlName, xStringResourceManager,
967 xDummyStringResolver, REMOVE_IDS_FROM_RESOURCE );
968 }
969 }
970
resetResourceForDialog(const Reference<container::XNameContainer> & xDialogModel,const Reference<XStringResourceManager> & xStringResourceManager)971 void LocalizationMgr::resetResourceForDialog( const Reference< container::XNameContainer >& xDialogModel,
972 const Reference< XStringResourceManager >& xStringResourceManager )
973 {
974 if( !xStringResourceManager.is() )
975 return;
976
977 // Dialog as control
978 OUString aDummyName;
979 Any aDialogCtrl;
980 aDialogCtrl <<= xDialogModel;
981 Reference< XStringResourceResolver > xDummyStringResolver;
982 implHandleControlResourceProperties( aDialogCtrl, aDummyName,
983 aDummyName, xStringResourceManager, xDummyStringResolver, RESET_IDS );
984
985 // Handle all controls
986 Sequence< OUString > aNames = xDialogModel->getElementNames();
987 const OUString* pNames = aNames.getConstArray();
988 sal_Int32 nCtrls = aNames.getLength();
989 for( sal_Int32 i = 0 ; i < nCtrls ; ++i )
990 {
991 OUString aCtrlName( pNames[i] );
992 Any aCtrl = xDialogModel->getByName( aCtrlName );
993 implHandleControlResourceProperties( aCtrl, aDummyName,
994 aCtrlName, xStringResourceManager, xDummyStringResolver, RESET_IDS );
995 }
996 }
997
setResourceIDsForDialog(const Reference<container::XNameContainer> & xDialogModel,const Reference<XStringResourceManager> & xStringResourceManager)998 void LocalizationMgr::setResourceIDsForDialog( const Reference< container::XNameContainer >& xDialogModel,
999 const Reference< XStringResourceManager >& xStringResourceManager )
1000 {
1001 if( !xStringResourceManager.is() )
1002 return;
1003
1004 // Dialog as control
1005 OUString aDummyName;
1006 Any aDialogCtrl;
1007 aDialogCtrl <<= xDialogModel;
1008 Reference< XStringResourceResolver > xDummyStringResolver;
1009 implHandleControlResourceProperties( aDialogCtrl, aDummyName,
1010 aDummyName, xStringResourceManager, xDummyStringResolver, SET_IDS );
1011
1012 // Handle all controls
1013 Sequence< OUString > aNames = xDialogModel->getElementNames();
1014 const OUString* pNames = aNames.getConstArray();
1015 sal_Int32 nCtrls = aNames.getLength();
1016 for( sal_Int32 i = 0 ; i < nCtrls ; ++i )
1017 {
1018 OUString aCtrlName( pNames[i] );
1019 Any aCtrl = xDialogModel->getByName( aCtrlName );
1020 implHandleControlResourceProperties( aCtrl, aDummyName,
1021 aCtrlName, xStringResourceManager, xDummyStringResolver, SET_IDS );
1022 }
1023 }
1024
copyResourcesForPastedEditorObject(DlgEditor const * pEditor,const Any & rControlAny,std::u16string_view aCtrlName,const Reference<XStringResourceResolver> & xSourceStringResolver)1025 void LocalizationMgr::copyResourcesForPastedEditorObject( DlgEditor const * pEditor,
1026 const Any& rControlAny, std::u16string_view aCtrlName,
1027 const Reference< XStringResourceResolver >& xSourceStringResolver )
1028 {
1029 // Get library for DlgEditor
1030 DialogWindow* pDlgWin = FindDialogWindowForEditor( pEditor );
1031 if( !pDlgWin )
1032 return;
1033 ScriptDocument aDocument( pDlgWin->GetDocument() );
1034 DBG_ASSERT( aDocument.isValid(), "LocalizationMgr::copyResourcesForPastedEditorObject: invalid document!" );
1035 if ( !aDocument.isValid() )
1036 return;
1037 const OUString& rLibName = pDlgWin->GetLibName();
1038 Reference< container::XNameContainer > xDialogLib( aDocument.getLibrary( E_DIALOGS, rLibName, true ) );
1039 Reference< XStringResourceManager > xStringResourceManager =
1040 LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );
1041
1042 // Set resource property
1043 if( !xStringResourceManager.is() || !xStringResourceManager->getLocales().hasElements() )
1044 return;
1045
1046 OUString aDialogName = pDlgWin->GetName();
1047 implHandleControlResourceProperties
1048 ( rControlAny, aDialogName, aCtrlName, xStringResourceManager,
1049 xSourceStringResolver, MOVE_RESOURCES );
1050 }
1051
copyResourceForDroppedDialog(const Reference<container::XNameContainer> & xDialogModel,std::u16string_view aDialogName,const Reference<XStringResourceManager> & xStringResourceManager,const Reference<XStringResourceResolver> & xSourceStringResolver)1052 void LocalizationMgr::copyResourceForDroppedDialog( const Reference< container::XNameContainer >& xDialogModel,
1053 std::u16string_view aDialogName,
1054 const Reference< XStringResourceManager >& xStringResourceManager,
1055 const Reference< XStringResourceResolver >& xSourceStringResolver )
1056 {
1057 if( !xStringResourceManager.is() )
1058 return;
1059
1060 // Dialog as control
1061 Any aDialogCtrl;
1062 aDialogCtrl <<= xDialogModel;
1063 implHandleControlResourceProperties( aDialogCtrl, aDialogName,
1064 std::u16string_view(), xStringResourceManager, xSourceStringResolver, MOVE_RESOURCES );
1065
1066 // Handle all controls
1067 Sequence< OUString > aNames = xDialogModel->getElementNames();
1068 const OUString* pNames = aNames.getConstArray();
1069 sal_Int32 nCtrls = aNames.getLength();
1070 for( sal_Int32 i = 0 ; i < nCtrls ; ++i )
1071 {
1072 OUString aCtrlName( pNames[i] );
1073 Any aCtrl = xDialogModel->getByName( aCtrlName );
1074 implHandleControlResourceProperties( aCtrl, aDialogName,
1075 aCtrlName, xStringResourceManager, xSourceStringResolver, MOVE_RESOURCES );
1076 }
1077 }
1078
copyResourceForDialog(const Reference<container::XNameContainer> & xDialogModel,const Reference<XStringResourceResolver> & xSourceStringResolver,const Reference<XStringResourceManager> & xTargetStringResourceManager)1079 void LocalizationMgr::copyResourceForDialog(
1080 const Reference< container::XNameContainer >& xDialogModel,
1081 const Reference< XStringResourceResolver >& xSourceStringResolver,
1082 const Reference< XStringResourceManager >& xTargetStringResourceManager )
1083 {
1084 if( !xDialogModel.is() || !xSourceStringResolver.is() || !xTargetStringResourceManager.is() )
1085 return;
1086
1087 OUString aDummyName;
1088 Any aDialogCtrl;
1089 aDialogCtrl <<= xDialogModel;
1090 implHandleControlResourceProperties
1091 ( aDialogCtrl, aDummyName, aDummyName, xTargetStringResourceManager,
1092 xSourceStringResolver, COPY_RESOURCES );
1093
1094 // Handle all controls
1095 Sequence< OUString > aNames = xDialogModel->getElementNames();
1096 const OUString* pNames = aNames.getConstArray();
1097 sal_Int32 nCtrls = aNames.getLength();
1098 for( sal_Int32 i = 0 ; i < nCtrls ; ++i )
1099 {
1100 OUString aCtrlName( pNames[i] );
1101 Any aCtrl = xDialogModel->getByName( aCtrlName );
1102 implHandleControlResourceProperties( aCtrl, aDummyName, aDummyName,
1103 xTargetStringResourceManager, xSourceStringResolver, COPY_RESOURCES );
1104 }
1105 }
1106
getStringResourceFromDialogLibrary(const Reference<container::XNameContainer> & xDialogLib)1107 Reference< XStringResourceManager > LocalizationMgr::getStringResourceFromDialogLibrary
1108 ( const Reference< container::XNameContainer >& xDialogLib )
1109 {
1110 Reference< XStringResourceManager > xStringResourceManager;
1111 if( xDialogLib.is() )
1112 {
1113 Reference< resource::XStringResourceSupplier > xStringResourceSupplier( xDialogLib, UNO_QUERY );
1114 if( xStringResourceSupplier.is() )
1115 {
1116 Reference< resource::XStringResourceResolver >
1117 xStringResourceResolver = xStringResourceSupplier->getStringResource();
1118
1119 xStringResourceManager =
1120 Reference< resource::XStringResourceManager >( xStringResourceResolver, UNO_QUERY );
1121 }
1122 }
1123 return xStringResourceManager;
1124 }
1125
1126 } // namespace basctl
1127
1128 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1129