xref: /core/basctl/source/basicide/localizationmgr.cxx (revision 330959905ae935eca431cc35f8132cf7094324d3)
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