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