1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <unotools/moduleoptions.hxx>
21 #include <comphelper/sequenceashashmap.hxx>
22 #include <unotools/configitem.hxx>
23 #include <comphelper/processfactory.hxx>
24 #include <comphelper/sequence.hxx>
25 #include <osl/diagnose.h>
26 #include <o3tl/enumarray.hxx>
27 #include <rtl/instance.hxx>
28 #include <com/sun/star/uno/Any.hxx>
29 #include <com/sun/star/uno/Sequence.hxx>
30 #include <com/sun/star/beans/PropertyValue.hpp>
31 #include <com/sun/star/container/XNameAccess.hpp>
32 #include <com/sun/star/frame/XModel.hpp>
33 #include <com/sun/star/lang/XServiceInfo.hpp>
34 #include <com/sun/star/document/XTypeDetection.hpp>
35 #include <com/sun/star/util/PathSubstitution.hpp>
36 #include <com/sun/star/util/XStringSubstitution.hpp>
38 #include "itemholder1.hxx"
40 /*-************************************************************************************************************
41 @descr These values are used to define necessary keys from our configuration management to support
42 all functionality of these implementation.
43 It's a fast way to make changes if some keys change its name or location!
45 Property handle are necessary to specify right position in return list of configuration
46 for asked values. We ask it with a list of properties to get its values. The returned list
47 has the same order like our given name list!
49 NAMELIST[ PROPERTYHANDLE_xxx ] => VALUELIST[ PROPERTYHANDLE_xxx ]
50 *//*-*************************************************************************************************************/
51 #define ROOTNODE_FACTORIES "Setup/Office/Factories"
52 #define PATHSEPARATOR "/"
54 // Attention: The property "ooSetupFactoryEmptyDocumentURL" is read from configuration but not used! There is
55 // special code that uses hard coded strings to return them.
56 #define PROPERTYNAME_SHORTNAME "ooSetupFactoryShortName"
57 #define PROPERTYNAME_TEMPLATEFILE "ooSetupFactoryTemplateFile"
58 #define PROPERTYNAME_WINDOWATTRIBUTES "ooSetupFactoryWindowAttributes"
59 #define PROPERTYNAME_EMPTYDOCUMENTURL "ooSetupFactoryEmptyDocumentURL"
60 #define PROPERTYNAME_DEFAULTFILTER "ooSetupFactoryDefaultFilter"
61 #define PROPERTYNAME_ICON "ooSetupFactoryIcon"
63 #define PROPERTYHANDLE_SHORTNAME 0
64 #define PROPERTYHANDLE_TEMPLATEFILE 1
65 #define PROPERTYHANDLE_WINDOWATTRIBUTES 2
66 #define PROPERTYHANDLE_EMPTYDOCUMENTURL 3
67 #define PROPERTYHANDLE_DEFAULTFILTER 4
68 #define PROPERTYHANDLE_ICON 5
70 #define PROPERTYCOUNT 6
72 #define FACTORYNAME_WRITER "com.sun.star.text.TextDocument"
73 #define FACTORYNAME_WRITERWEB "com.sun.star.text.WebDocument"
74 #define FACTORYNAME_WRITERGLOBAL "com.sun.star.text.GlobalDocument"
75 #define FACTORYNAME_CALC "com.sun.star.sheet.SpreadsheetDocument"
76 #define FACTORYNAME_DRAW "com.sun.star.drawing.DrawingDocument"
77 #define FACTORYNAME_IMPRESS "com.sun.star.presentation.PresentationDocument"
78 #define FACTORYNAME_MATH "com.sun.star.formula.FormulaProperties"
79 #define FACTORYNAME_CHART "com.sun.star.chart2.ChartDocument"
80 #define FACTORYNAME_DATABASE "com.sun.star.sdb.OfficeDatabaseDocument"
81 #define FACTORYNAME_STARTMODULE "com.sun.star.frame.StartModule"
82 #define FACTORYNAME_BASIC "com.sun.star.script.BasicIDE"
84 #define FACTORYCOUNT 11
88 /*-************************************************************************************************************
89 @descr This struct hold information about one factory. We declare a complete array which can hold infos
90 for all well known factories. Values of enum "EFactory" (see header!) are directly used as index!
91 So we can support a fast access on this information.
92 *//*-*************************************************************************************************************/
97 // initialize empty struct
103 // easy way to reset struct member!
108 sTemplateFile
.clear();
109 sDefaultFilter
.clear();
111 bChangedTemplateFile
= false;
112 bChangedDefaultFilter
= false;
113 bDefaultFilterReadonly
= false;
116 // returns list of properties, which has changed only!
117 // We use given value of sNodeBase to build full qualified paths ...
118 // Last sign of it must be "/". because we use it directly, without any additional things!
119 css::uno::Sequence
< css::beans::PropertyValue
> getChangedProperties( const OUString
& sNodeBase
)
121 // a) reserve memory for max. count of changed properties
122 // b) add names and values of changed ones only and count it
123 // c) resize return list by using count
124 css::uno::Sequence
< css::beans::PropertyValue
> lProperties ( 4 );
125 sal_Int8 nRealyChanged
= 0;
127 if( bChangedTemplateFile
)
129 lProperties
[nRealyChanged
].Name
= sNodeBase
+ PROPERTYNAME_TEMPLATEFILE
;
131 if ( !sTemplateFile
.isEmpty() )
133 lProperties
[nRealyChanged
].Value
134 <<= getStringSubstitution()
135 ->reSubstituteVariables( sTemplateFile
);
139 lProperties
[nRealyChanged
].Value
<<= sTemplateFile
;
144 if( bChangedDefaultFilter
)
146 lProperties
[nRealyChanged
].Name
= sNodeBase
+ PROPERTYNAME_DEFAULTFILTER
;
147 lProperties
[nRealyChanged
].Value
<<= sDefaultFilter
;
151 // Don't forget to reset changed flags! Otherwise we save it again and again and ...
152 bChangedTemplateFile
= false;
153 bChangedDefaultFilter
= false;
155 lProperties
.realloc( nRealyChanged
);
159 // We must support setting AND marking of changed values.
160 // That's why we can't make our member public. We must use get/set/init methods
161 // to control access on it!
162 bool getInstalled () const { return bInstalled
; };
163 const OUString
& getFactory () const { return sFactory
; };
164 const OUString
& getTemplateFile () const { return sTemplateFile
; };
165 const OUString
& getDefaultFilter () const { return sDefaultFilter
; };
166 bool isDefaultFilterReadonly() const { return bDefaultFilterReadonly
; }
167 sal_Int32
getIcon () const { return nIcon
; };
169 // If you call set-methods - we check for changes of values and mark it.
170 // But if you wish to set it without that... you must initialize it!
171 void initInstalled () { bInstalled
= true; }
172 void initFactory ( const OUString
& sNewFactory
) { sFactory
= sNewFactory
; }
173 void initDefaultFilter ( const OUString
& sNewDefaultFilter
) { sDefaultFilter
= sNewDefaultFilter
; }
174 void setDefaultFilterReadonly( const bool bVal
){bDefaultFilterReadonly
= bVal
;}
175 void initIcon ( sal_Int32 nNewIcon
) { nIcon
= nNewIcon
; }
177 void initTemplateFile( const OUString
& sNewTemplateFile
)
179 if ( !sNewTemplateFile
.isEmpty() )
181 sTemplateFile
= getStringSubstitution()->substituteVariables( sNewTemplateFile
, false );
185 sTemplateFile
= sNewTemplateFile
;
189 void setTemplateFile( const OUString
& sNewTemplateFile
)
191 if( sTemplateFile
!= sNewTemplateFile
)
193 sTemplateFile
= sNewTemplateFile
;
194 bChangedTemplateFile
= true;
198 void setDefaultFilter( const OUString
& sNewDefaultFilter
)
200 if( sDefaultFilter
!= sNewDefaultFilter
)
202 sDefaultFilter
= sNewDefaultFilter
;
203 bChangedDefaultFilter
= true;
208 css::uno::Reference
< css::util::XStringSubstitution
> const & getStringSubstitution()
210 if ( !xSubstVars
.is() )
212 xSubstVars
.set( css::util::PathSubstitution::create(::comphelper::getProcessComponentContext()) );
219 OUString sTemplateFile
;
220 OUString sDefaultFilter
;
223 bool bChangedTemplateFile
:1;
224 bool bChangedDefaultFilter
:1;
225 bool bDefaultFilterReadonly
:1;
227 css::uno::Reference
< css::util::XStringSubstitution
> xSubstVars
;
232 class SvtModuleOptions_Impl
: public ::utl::ConfigItem
239 // constructor / destructor
241 SvtModuleOptions_Impl();
242 virtual ~SvtModuleOptions_Impl() override
;
244 // override methods of baseclass
246 virtual void Notify( const css::uno::Sequence
< OUString
>& lPropertyNames
) override
;
250 bool IsModuleInstalled ( SvtModuleOptions::EModule eModule
) const;
251 css::uno::Sequence
< OUString
> GetAllServiceNames();
252 OUString
const & GetFactoryName ( SvtModuleOptions::EFactory eFactory
) const;
253 OUString
const & GetFactoryStandardTemplate( SvtModuleOptions::EFactory eFactory
) const;
254 static OUString
GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory eFactory
);
255 OUString
const & GetFactoryDefaultFilter ( SvtModuleOptions::EFactory eFactory
) const;
256 bool IsDefaultFilterReadonly( SvtModuleOptions::EFactory eFactory
) const;
257 sal_Int32
GetFactoryIcon ( SvtModuleOptions::EFactory eFactory
) const;
258 static bool ClassifyFactoryByName ( const OUString
& sName
,
259 SvtModuleOptions::EFactory
& eFactory
);
260 void SetFactoryStandardTemplate( SvtModuleOptions::EFactory eFactory
,
261 const OUString
& sTemplate
);
262 void SetFactoryDefaultFilter ( SvtModuleOptions::EFactory eFactory
,
263 const OUString
& sFilter
);
264 void MakeReadonlyStatesAvailable();
269 static css::uno::Sequence
< OUString
> impl_ExpandSetNames ( const css::uno::Sequence
< OUString
>& lSetNames
);
270 void impl_Read ( const css::uno::Sequence
< OUString
>& lSetNames
);
272 virtual void ImplCommit() override
;
277 o3tl::enumarray
<SvtModuleOptions::EFactory
, FactoryInfo
> m_lFactories
;
278 bool m_bReadOnlyStatesWellKnown
;
281 /*-************************************************************************************************************
283 @descr We open our configuration here and read all necessary values from it.
284 These values are cached till everyone call Commit(). Then we write changed ones back to cfg.
286 @seealso baseclass ConfigItem
287 @seealso method impl_Read()
289 *//*-*************************************************************************************************************/
290 SvtModuleOptions_Impl::SvtModuleOptions_Impl()
291 : ::utl::ConfigItem( ROOTNODE_FACTORIES
)
292 , m_bReadOnlyStatesWellKnown( false )
294 // First initialize list of factory infos! Otherwise we couldn't guarantee right working of these class.
295 for( auto & rFactory
: m_lFactories
)
298 // Get name list of all existing set node names in configuration to read her properties in impl_Read().
299 // These list is a list of long names of our factories.
300 const css::uno::Sequence
< OUString
> lFactories
= GetNodeNames( OUString() );
301 impl_Read( lFactories
);
303 // Enable notification for changes by using configuration directly.
304 // So we can update our internal values immediately.
305 EnableNotification( lFactories
);
308 SvtModuleOptions_Impl::~SvtModuleOptions_Impl()
310 assert(!IsModified()); // should have been committed
313 /*-************************************************************************************************************
314 @short called for notify of configmanager
315 @descr This method is called from the ConfigManager before application ends or from the
316 PropertyChangeListener if the sub tree broadcasts changes. You must update our
319 @attention We are registered for pure set node names only. So we can use our internal method "impl_Read()" to
320 update our info list. Because - this method expand given name list to full qualified property list
321 and use it to read the values. These values are filled into our internal member list m_lFactories
324 @seealso method impl_Read()
326 @param "lNames" is the list of set node entries which should be updated.
328 *//*-*************************************************************************************************************/
329 void SvtModuleOptions_Impl::Notify( const css::uno::Sequence
< OUString
>& )
331 OSL_FAIL( "SvtModuleOptions_Impl::Notify() Not implemented yet!" );
334 /*-****************************************************************************************************
335 @short write changes to configuration
336 @descr This method writes the changed values into the sub tree
337 and should always called in our destructor to guarantee consistency of config data.
339 @attention We clear complete set in configuration first and write it completely new! So we don't must
340 distinguish between existing, added or removed elements. Our internal cached values
341 are the only and right ones.
343 @seealso baseclass ConfigItem
345 *//*-*****************************************************************************************************/
346 void SvtModuleOptions_Impl::ImplCommit()
348 // Reserve memory for ALL possible factory properties!
349 // Step over all factories and get her really changed values only.
350 // Build list of these ones and use it for commit.
351 css::uno::Sequence
< css::beans::PropertyValue
> lCommitProperties( FACTORYCOUNT
*PROPERTYCOUNT
);
352 sal_Int32 nRealCount
= 0;
354 for( FactoryInfo
& rInfo
: m_lFactories
)
356 // These path is used to build full qualified property names...
357 // See pInfo->getChangedProperties() for further information
358 sBasePath
= PATHSEPARATOR
+ rInfo
.getFactory() + PATHSEPARATOR
;
360 const css::uno::Sequence
< css::beans::PropertyValue
> lChangedProperties
= rInfo
.getChangedProperties ( sBasePath
);
361 std::copy(lChangedProperties
.begin(), lChangedProperties
.end(), std::next(lCommitProperties
.begin(), nRealCount
));
362 nRealCount
+= lChangedProperties
.getLength();
364 // Resize commit list to real size.
365 // If nothing to do - suppress calling of configuration...
366 // It could be too expensive :-)
369 lCommitProperties
.realloc( nRealCount
);
370 SetSetProperties( OUString(), lCommitProperties
);
374 /*-****************************************************************************************************
375 @short access method to get internal values
376 @descr These methods implement easy access to our internal values.
377 You give us right enum value to specify which module interest you ... we return right information.
379 @attention Some people use any value as enum ... but we support in header specified values only!
380 We use it directly as index in our internal list. If enum value isn't right - we crash with an
381 "index out of range"!!! Please use me right - otherwise there is no guarantee.
382 @param "eModule" , index in list - specify module
383 @return Queried information.
385 @onerror We return default values. (mostly "not installed"!)
387 *//*-*****************************************************************************************************/
388 bool SvtModuleOptions_Impl::IsModuleInstalled( SvtModuleOptions::EModule eModule
) const
392 case SvtModuleOptions::EModule::WRITER
:
393 return m_lFactories
[SvtModuleOptions::EFactory::WRITER
].getInstalled();
394 case SvtModuleOptions::EModule::WEB
:
395 return m_lFactories
[SvtModuleOptions::EFactory::WRITERWEB
].getInstalled();
396 case SvtModuleOptions::EModule::GLOBAL
:
397 return m_lFactories
[SvtModuleOptions::EFactory::WRITERGLOBAL
].getInstalled();
398 case SvtModuleOptions::EModule::CALC
:
399 return m_lFactories
[SvtModuleOptions::EFactory::CALC
].getInstalled();
400 case SvtModuleOptions::EModule::DRAW
:
401 return m_lFactories
[SvtModuleOptions::EFactory::DRAW
].getInstalled();
402 case SvtModuleOptions::EModule::IMPRESS
:
403 return m_lFactories
[SvtModuleOptions::EFactory::IMPRESS
].getInstalled();
404 case SvtModuleOptions::EModule::MATH
:
405 return m_lFactories
[SvtModuleOptions::EFactory::MATH
].getInstalled();
406 case SvtModuleOptions::EModule::CHART
:
407 return m_lFactories
[SvtModuleOptions::EFactory::CHART
].getInstalled();
408 case SvtModuleOptions::EModule::STARTMODULE
:
409 return m_lFactories
[SvtModuleOptions::EFactory::STARTMODULE
].getInstalled();
410 case SvtModuleOptions::EModule::BASIC
:
411 return true; // Couldn't be deselected by setup yet!
412 case SvtModuleOptions::EModule::DATABASE
:
413 return m_lFactories
[SvtModuleOptions::EFactory::DATABASE
].getInstalled();
419 css::uno::Sequence
< OUString
> SvtModuleOptions_Impl::GetAllServiceNames()
421 std::vector
<OUString
> aVec
;
423 for( const auto & rFactory
: m_lFactories
)
424 if( rFactory
.getInstalled() )
425 aVec
.push_back( rFactory
.getFactory() );
427 return comphelper::containerToSequence(aVec
);
430 OUString
const & SvtModuleOptions_Impl::GetFactoryName( SvtModuleOptions::EFactory eFactory
) const
432 return m_lFactories
[eFactory
].getFactory();
435 OUString
SvtModuleOptions::GetFactoryShortName(SvtModuleOptions::EFactory eFactory
)
437 // Attention: Hard configured yet ... because it's not fine to make changes possible by xml file yet.
438 // But it's good to plan further possibilities!
440 //return m_lFactories[eFactory].sShortName;
445 case SvtModuleOptions::EFactory::WRITER
: sShortName
= "swriter";
447 case SvtModuleOptions::EFactory::WRITERWEB
: sShortName
= "swriter/web";
449 case SvtModuleOptions::EFactory::WRITERGLOBAL
: sShortName
= "swriter/GlobalDocument";
451 case SvtModuleOptions::EFactory::CALC
: sShortName
= "scalc";
453 case SvtModuleOptions::EFactory::DRAW
: sShortName
= "sdraw";
455 case SvtModuleOptions::EFactory::IMPRESS
: sShortName
= "simpress";
457 case SvtModuleOptions::EFactory::MATH
: sShortName
= "smath";
459 case SvtModuleOptions::EFactory::CHART
: sShortName
= "schart";
461 case SvtModuleOptions::EFactory::BASIC
: sShortName
= "sbasic";
463 case SvtModuleOptions::EFactory::DATABASE
: sShortName
= "sdatabase";
466 OSL_FAIL( "unknown factory" );
473 OUString
const & SvtModuleOptions_Impl::GetFactoryStandardTemplate( SvtModuleOptions::EFactory eFactory
) const
475 return m_lFactories
[eFactory
].getTemplateFile();
478 OUString
SvtModuleOptions_Impl::GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory eFactory
)
480 // Attention: Hard configured yet ... because it's not fine to make changes possible by xml file yet.
481 // But it's good to plan further possibilities!
483 //return m_lFactories[eFactory].getEmptyDocumentURL();
488 case SvtModuleOptions::EFactory::WRITER
: sURL
= "private:factory/swriter";
490 case SvtModuleOptions::EFactory::WRITERWEB
: sURL
= "private:factory/swriter/web";
492 case SvtModuleOptions::EFactory::WRITERGLOBAL
: sURL
= "private:factory/swriter/GlobalDocument";
494 case SvtModuleOptions::EFactory::CALC
: sURL
= "private:factory/scalc";
496 case SvtModuleOptions::EFactory::DRAW
: sURL
= "private:factory/sdraw";
498 case SvtModuleOptions::EFactory::IMPRESS
: sURL
= "private:factory/simpress?slot=6686";
500 case SvtModuleOptions::EFactory::MATH
: sURL
= "private:factory/smath";
502 case SvtModuleOptions::EFactory::CHART
: sURL
= "private:factory/schart";
504 case SvtModuleOptions::EFactory::BASIC
: sURL
= "private:factory/sbasic";
506 case SvtModuleOptions::EFactory::DATABASE
: sURL
= "private:factory/sdatabase?Interactive";
509 OSL_FAIL( "unknown factory" );
515 OUString
const & SvtModuleOptions_Impl::GetFactoryDefaultFilter( SvtModuleOptions::EFactory eFactory
) const
517 return m_lFactories
[eFactory
].getDefaultFilter();
520 bool SvtModuleOptions_Impl::IsDefaultFilterReadonly( SvtModuleOptions::EFactory eFactory
) const
522 return m_lFactories
[eFactory
].isDefaultFilterReadonly();
525 sal_Int32
SvtModuleOptions_Impl::GetFactoryIcon( SvtModuleOptions::EFactory eFactory
) const
527 return m_lFactories
[eFactory
].getIcon();
530 void SvtModuleOptions_Impl::SetFactoryStandardTemplate( SvtModuleOptions::EFactory eFactory
,
531 const OUString
& sTemplate
)
533 m_lFactories
[eFactory
].setTemplateFile( sTemplate
);
537 void SvtModuleOptions_Impl::SetFactoryDefaultFilter( SvtModuleOptions::EFactory eFactory
,
538 const OUString
& sFilter
)
540 m_lFactories
[eFactory
].setDefaultFilter( sFilter
);
544 /*-************************************************************************************************************
545 @short return list of key names of our configuration management which represent our module tree
546 @descr You give use a list of current existing set node names .. and we expand it for all
547 well known properties which are necessary for this implementation.
548 These full expanded list should be used to get values of this properties.
551 @return List of all relative addressed properties of given set entry names.
553 @onerror List will be empty.
555 *//*-*************************************************************************************************************/
556 css::uno::Sequence
< OUString
> SvtModuleOptions_Impl::impl_ExpandSetNames( const css::uno::Sequence
< OUString
>& lSetNames
)
558 sal_Int32 nCount
= lSetNames
.getLength();
559 css::uno::Sequence
< OUString
> lPropNames ( nCount
*PROPERTYCOUNT
);
560 OUString
* pPropNames
= lPropNames
.getArray();
561 sal_Int32 nPropStart
= 0;
563 for( const auto& rSetName
: lSetNames
)
565 pPropNames
[nPropStart
+PROPERTYHANDLE_SHORTNAME
] = rSetName
+ PATHSEPARATOR PROPERTYNAME_SHORTNAME
;
566 pPropNames
[nPropStart
+PROPERTYHANDLE_TEMPLATEFILE
] = rSetName
+ PATHSEPARATOR PROPERTYNAME_TEMPLATEFILE
;
567 pPropNames
[nPropStart
+PROPERTYHANDLE_WINDOWATTRIBUTES
] = rSetName
+ PATHSEPARATOR PROPERTYNAME_WINDOWATTRIBUTES
;
568 pPropNames
[nPropStart
+PROPERTYHANDLE_EMPTYDOCUMENTURL
] = rSetName
+ PATHSEPARATOR PROPERTYNAME_EMPTYDOCUMENTURL
;
569 pPropNames
[nPropStart
+PROPERTYHANDLE_DEFAULTFILTER
] = rSetName
+ PATHSEPARATOR PROPERTYNAME_DEFAULTFILTER
;
570 pPropNames
[nPropStart
+PROPERTYHANDLE_ICON
] = rSetName
+ PATHSEPARATOR PROPERTYNAME_ICON
;
571 nPropStart
+= PROPERTYCOUNT
;
577 /*-************************************************************************************************************
578 @short helper to classify given factory by name
579 @descr Every factory has its own long and short name. So we can match right enum value for internal using.
581 @attention We change in/out parameter "eFactory" in every case! But you should use it only, if return value is sal_True!
582 Algorithm: Set out-parameter to probably value ... and check the longname.
583 If it matches with these factory - break operation and return true AND right set parameter.
584 Otherwise try next one and so on. If no factory was found return false. Out parameter eFactory
585 is set to last tried value but shouldn't be used! Because our return value is false!
586 @param "sLongName" , long name of factory, which should be classified
587 @return "eFactory" , right enum value, which match given long name
588 and true for successfully classification, false otherwise
590 @onerror We return false.
592 *//*-*************************************************************************************************************/
593 bool SvtModuleOptions_Impl::ClassifyFactoryByName( const OUString
& sName
, SvtModuleOptions::EFactory
& eFactory
)
597 eFactory
= SvtModuleOptions::EFactory::WRITER
;
598 bState
= ( sName
== FACTORYNAME_WRITER
);
602 eFactory
= SvtModuleOptions::EFactory::WRITERWEB
;
603 bState
= ( sName
== FACTORYNAME_WRITERWEB
);
608 eFactory
= SvtModuleOptions::EFactory::WRITERGLOBAL
;
609 bState
= ( sName
== FACTORYNAME_WRITERGLOBAL
);
614 eFactory
= SvtModuleOptions::EFactory::CALC
;
615 bState
= ( sName
== FACTORYNAME_CALC
);
620 eFactory
= SvtModuleOptions::EFactory::DRAW
;
621 bState
= ( sName
== FACTORYNAME_DRAW
);
626 eFactory
= SvtModuleOptions::EFactory::IMPRESS
;
627 bState
= ( sName
== FACTORYNAME_IMPRESS
);
632 eFactory
= SvtModuleOptions::EFactory::MATH
;
633 bState
= ( sName
== FACTORYNAME_MATH
);
638 eFactory
= SvtModuleOptions::EFactory::CHART
;
639 bState
= ( sName
== FACTORYNAME_CHART
);
644 eFactory
= SvtModuleOptions::EFactory::DATABASE
;
645 bState
= ( sName
== FACTORYNAME_DATABASE
);
650 eFactory
= SvtModuleOptions::EFactory::STARTMODULE
;
651 bState
= ( sName
== FACTORYNAME_STARTMODULE
);
656 eFactory
= SvtModuleOptions::EFactory::BASIC
;
657 bState
= ( sName
== FACTORYNAME_BASIC
);
663 /*-************************************************************************************************************
664 @short read factory configuration
665 @descr Give us a list of pure factory names (long names!) which can be used as
666 direct set node names... and we read her property values and fill internal list.
667 These method can be used by initial reading at ctor and later updating by "Notify()".
670 @seealso method Notify()
672 @param "lFactories" is the list of set node entries which should be read.
673 @onerror We do nothing.
675 *//*-*************************************************************************************************************/
676 void SvtModuleOptions_Impl::impl_Read( const css::uno::Sequence
< OUString
>& lFactories
)
678 // Expand every set node name in lFactories to full qualified paths to its properties
679 // and get right values from configuration.
680 const css::uno::Sequence
< OUString
> lProperties
= impl_ExpandSetNames( lFactories
);
681 const css::uno::Sequence
< css::uno::Any
> lValues
= GetProperties( lProperties
);
683 // Safe impossible cases.
684 // We need values from ALL configuration keys.
685 // Follow assignment use order of values in relation to our list of key names!
686 OSL_ENSURE( !(lProperties
.getLength()!=lValues
.getLength()), "SvtModuleOptions_Impl::impl_Read()\nI miss some values of configuration keys!" );
688 // Algorithm: We step over all given factory names and classify it. These enum value can be used as direct index
689 // in our member list m_lFactories! VAriable nPropertyStart marks start position of every factory
690 // and her properties in expanded property/value list. The defines PROPERTHANDLE_xxx are used as offset values
691 // added to nPropertyStart. So we can address every property relative in these lists.
692 // If we found any valid values ... we reset all existing information for corresponding m_lFactories-entry and
693 // use a pointer to these struct in memory directly to set new values.
694 // But we set it only, if bInstalled is true. Otherwise all other values of a factory can be undeclared .. They
695 // shouldn't be used then.
696 // Attention: If a propertyset of a factory will be ignored we must step to next start position of next factory infos!
697 // see "nPropertyStart += PROPERTYCOUNT" ...
699 sal_Int32 nPropertyStart
= 0;
700 FactoryInfo
* pInfo
= nullptr;
701 SvtModuleOptions::EFactory eFactory
;
703 for( const OUString
& sFactoryName
: lFactories
)
705 if( ClassifyFactoryByName( sFactoryName
, eFactory
) )
710 pInfo
= &(m_lFactories
[eFactory
]);
713 pInfo
->initInstalled();
714 pInfo
->initFactory ( sFactoryName
);
716 if (lValues
[nPropertyStart
+PROPERTYHANDLE_TEMPLATEFILE
] >>= sTemp
)
717 pInfo
->initTemplateFile( sTemp
);
718 if (lValues
[nPropertyStart
+PROPERTYHANDLE_DEFAULTFILTER
] >>= sTemp
)
719 pInfo
->initDefaultFilter( sTemp
);
720 if (lValues
[nPropertyStart
+PROPERTYHANDLE_ICON
] >>= nTemp
)
721 pInfo
->initIcon( nTemp
);
723 nPropertyStart
+= PROPERTYCOUNT
;
727 void SvtModuleOptions_Impl::MakeReadonlyStatesAvailable()
729 if (m_bReadOnlyStatesWellKnown
)
732 css::uno::Sequence
< OUString
> lFactories
= GetNodeNames(OUString());
733 std::transform(lFactories
.begin(), lFactories
.end(), lFactories
.begin(),
734 [](const OUString
& rFactory
) -> OUString
{
735 return rFactory
+ PATHSEPARATOR PROPERTYNAME_DEFAULTFILTER
;
738 css::uno::Sequence
< sal_Bool
> lReadonlyStates
= GetReadOnlyStates(lFactories
);
739 sal_Int32 c
= lFactories
.getLength();
740 for (sal_Int32 i
=0; i
<c
; ++i
)
742 OUString
& rFactoryName
= lFactories
[i
];
743 SvtModuleOptions::EFactory eFactory
;
745 if (!ClassifyFactoryByName(rFactoryName
, eFactory
))
748 FactoryInfo
& rInfo
= m_lFactories
[eFactory
];
749 rInfo
.setDefaultFilterReadonly(lReadonlyStates
[i
]);
752 m_bReadOnlyStatesWellKnown
= true;
757 std::weak_ptr
<SvtModuleOptions_Impl
> g_pModuleOptions
;
760 /*-************************************************************************************************************
761 @short standard constructor and destructor
762 @descr This will initialize an instance with default values. We initialize/deinitialize our static data
763 container and create a static mutex, which is used for threadsafe code in further time of this object.
765 @seealso method impl_GetOwnStaticMutex()
767 *//*-*************************************************************************************************************/
768 SvtModuleOptions::SvtModuleOptions()
770 // Global access, must be guarded (multithreading!)
771 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
773 m_pImpl
= g_pModuleOptions
.lock();
776 m_pImpl
= std::make_shared
<SvtModuleOptions_Impl
>();
777 g_pModuleOptions
= m_pImpl
;
778 ItemHolder1::holdConfigItem(EItem::ModuleOptions
);
782 SvtModuleOptions::~SvtModuleOptions()
784 // Global access, must be guarded (multithreading!)
785 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
790 /*-************************************************************************************************************
791 @short access to configuration data
792 @descr This methods allow read/write access to configuration values.
793 They are threadsafe. All calls are forwarded to impl-data-container. See there for further information!
795 @seealso method impl_GetOwnStaticMutex()
797 *//*-*************************************************************************************************************/
798 bool SvtModuleOptions::IsModuleInstalled( EModule eModule
) const
800 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
801 return m_pImpl
->IsModuleInstalled( eModule
);
804 OUString
SvtModuleOptions::GetFactoryName( EFactory eFactory
) const
806 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
807 return m_pImpl
->GetFactoryName( eFactory
);
810 OUString
SvtModuleOptions::GetFactoryStandardTemplate( EFactory eFactory
) const
812 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
813 return m_pImpl
->GetFactoryStandardTemplate( eFactory
);
816 OUString
SvtModuleOptions::GetFactoryEmptyDocumentURL( EFactory eFactory
) const
818 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
819 return SvtModuleOptions_Impl::GetFactoryEmptyDocumentURL( eFactory
);
822 OUString
SvtModuleOptions::GetFactoryDefaultFilter( EFactory eFactory
) const
824 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
825 return m_pImpl
->GetFactoryDefaultFilter( eFactory
);
828 bool SvtModuleOptions::IsDefaultFilterReadonly( EFactory eFactory
) const
830 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
831 m_pImpl
->MakeReadonlyStatesAvailable();
832 return m_pImpl
->IsDefaultFilterReadonly( eFactory
);
835 sal_Int32
SvtModuleOptions::GetFactoryIcon( EFactory eFactory
) const
837 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
838 return m_pImpl
->GetFactoryIcon( eFactory
);
841 bool SvtModuleOptions::ClassifyFactoryByName( const OUString
& sName
,
844 // We don't need any mutex here ... because we don't use any member here!
845 return SvtModuleOptions_Impl::ClassifyFactoryByName( sName
, eFactory
);
848 void SvtModuleOptions::SetFactoryStandardTemplate( EFactory eFactory
,
849 const OUString
& sTemplate
)
851 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
852 m_pImpl
->SetFactoryStandardTemplate( eFactory
, sTemplate
);
855 void SvtModuleOptions::SetFactoryDefaultFilter( EFactory eFactory
,
856 const OUString
& sFilter
)
858 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
859 m_pImpl
->SetFactoryDefaultFilter( eFactory
, sFilter
);
862 bool SvtModuleOptions::IsMath() const
864 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
865 return m_pImpl
->IsModuleInstalled( EModule::MATH
);
868 bool SvtModuleOptions::IsChart() const
870 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
871 return m_pImpl
->IsModuleInstalled( EModule::CHART
);
874 bool SvtModuleOptions::IsCalc() const
876 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
877 return m_pImpl
->IsModuleInstalled( EModule::CALC
);
880 bool SvtModuleOptions::IsDraw() const
882 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
883 return m_pImpl
->IsModuleInstalled( EModule::DRAW
);
886 bool SvtModuleOptions::IsWriter() const
888 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
889 return m_pImpl
->IsModuleInstalled( EModule::WRITER
);
892 bool SvtModuleOptions::IsImpress() const
894 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
895 return m_pImpl
->IsModuleInstalled( EModule::IMPRESS
);
898 bool SvtModuleOptions::IsDataBase() const
900 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
901 return m_pImpl
->IsModuleInstalled( EModule::DATABASE
);
906 class theModuleOptionsMutex
: public rtl::Static
<osl::Mutex
, theModuleOptionsMutex
> {};
908 /*-****************************************************************************************************
909 @short return a reference to a static mutex
910 @descr These class is threadsafe.
911 We create a static mutex only for one time and use it to protect our refcount and container
913 @return A reference to a static mutex member.
915 *//*-*****************************************************************************************************/
916 ::osl::Mutex
& SvtModuleOptions::impl_GetOwnStaticMutex()
918 return theModuleOptionsMutex::get();
921 OUString
SvtModuleOptions::GetModuleName( EModule eModule
) const
925 case SvtModuleOptions::EModule::WRITER
: { return "Writer"; }
926 case SvtModuleOptions::EModule::WEB
: { return "Web"; }
927 case SvtModuleOptions::EModule::GLOBAL
: { return "Global"; }
928 case SvtModuleOptions::EModule::CALC
: { return "Calc"; }
929 case SvtModuleOptions::EModule::DRAW
: { return "Draw"; }
930 case SvtModuleOptions::EModule::IMPRESS
: { return "Impress"; }
931 case SvtModuleOptions::EModule::MATH
: { return "Math"; }
932 case SvtModuleOptions::EModule::CHART
: { return "Chart"; }
933 case SvtModuleOptions::EModule::BASIC
: { return "Basic"; }
934 case SvtModuleOptions::EModule::DATABASE
: { return "Database"; }
936 OSL_FAIL( "unknown module" );
943 SvtModuleOptions::EFactory
SvtModuleOptions::ClassifyFactoryByShortName(const OUString
& sName
)
945 if ( sName
== "swriter" )
946 return EFactory::WRITER
;
947 if (sName
.equalsIgnoreAsciiCase("swriter/Web")) // sometimes they are registered for swriter/web :-(
948 return EFactory::WRITERWEB
;
949 if (sName
.equalsIgnoreAsciiCase("swriter/GlobalDocument")) // sometimes they are registered for swriter/globaldocument :-(
950 return EFactory::WRITERGLOBAL
;
951 if ( sName
== "scalc" )
952 return EFactory::CALC
;
953 if ( sName
== "sdraw" )
954 return EFactory::DRAW
;
955 if ( sName
== "simpress" )
956 return EFactory::IMPRESS
;
957 if ( sName
== "schart" )
958 return EFactory::CHART
;
959 if ( sName
== "smath" )
960 return EFactory::MATH
;
961 if ( sName
== "sbasic" )
962 return EFactory::BASIC
;
963 if ( sName
== "sdatabase" )
964 return EFactory::DATABASE
;
966 return EFactory::UNKNOWN_FACTORY
;
969 SvtModuleOptions::EFactory
SvtModuleOptions::ClassifyFactoryByServiceName(const OUString
& sName
)
971 if (sName
== FACTORYNAME_WRITERGLOBAL
)
972 return EFactory::WRITERGLOBAL
;
973 if (sName
== FACTORYNAME_WRITERWEB
)
974 return EFactory::WRITERWEB
;
975 if (sName
== FACTORYNAME_WRITER
)
976 return EFactory::WRITER
;
977 if (sName
== FACTORYNAME_CALC
)
978 return EFactory::CALC
;
979 if (sName
== FACTORYNAME_DRAW
)
980 return EFactory::DRAW
;
981 if (sName
== FACTORYNAME_IMPRESS
)
982 return EFactory::IMPRESS
;
983 if (sName
== FACTORYNAME_MATH
)
984 return EFactory::MATH
;
985 if (sName
== FACTORYNAME_CHART
)
986 return EFactory::CHART
;
987 if (sName
== FACTORYNAME_DATABASE
)
988 return EFactory::DATABASE
;
989 if (sName
== FACTORYNAME_STARTMODULE
)
990 return EFactory::STARTMODULE
;
991 if (sName
== FACTORYNAME_BASIC
)
992 return EFactory::BASIC
;
994 return EFactory::UNKNOWN_FACTORY
;
997 SvtModuleOptions::EFactory
SvtModuleOptions::ClassifyFactoryByURL(const OUString
& sURL
,
998 const css::uno::Sequence
< css::beans::PropertyValue
>& lMediaDescriptor
)
1000 css::uno::Reference
< css::uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
1002 css::uno::Reference
< css::container::XNameAccess
> xFilterCfg
;
1003 css::uno::Reference
< css::container::XNameAccess
> xTypeCfg
;
1007 xContext
->getServiceManager()->createInstanceWithContext("com.sun.star.document.FilterFactory", xContext
), css::uno::UNO_QUERY
);
1009 xContext
->getServiceManager()->createInstanceWithContext("com.sun.star.document.TypeDetection", xContext
), css::uno::UNO_QUERY
);
1011 catch(const css::uno::RuntimeException
&)
1013 catch(const css::uno::Exception
&)
1014 { return EFactory::UNKNOWN_FACTORY
; }
1016 ::comphelper::SequenceAsHashMap
stlDesc(lMediaDescriptor
);
1018 // is there already a filter inside the descriptor?
1019 OUString sFilterName
= stlDesc
.getUnpackedValueOrDefault("FilterName", OUString());
1020 if (!sFilterName
.isEmpty())
1024 ::comphelper::SequenceAsHashMap
stlFilterProps (xFilterCfg
->getByName(sFilterName
));
1025 OUString sDocumentService
= stlFilterProps
.getUnpackedValueOrDefault("DocumentService", OUString());
1026 SvtModuleOptions::EFactory eApp
= SvtModuleOptions::ClassifyFactoryByServiceName(sDocumentService
);
1028 if (eApp
!= EFactory::UNKNOWN_FACTORY
)
1031 catch(const css::uno::RuntimeException
&)
1033 catch(const css::uno::Exception
&)
1034 { /* do nothing here ... may the following code can help!*/ }
1037 // is there already a type inside the descriptor?
1038 OUString sTypeName
= stlDesc
.getUnpackedValueOrDefault("TypeName", OUString());
1039 if (sTypeName
.isEmpty())
1042 // start flat detection of URL
1043 css::uno::Reference
< css::document::XTypeDetection
> xDetect(xTypeCfg
, css::uno::UNO_QUERY
);
1044 sTypeName
= xDetect
->queryTypeByURL(sURL
);
1047 if (sTypeName
.isEmpty())
1048 return EFactory::UNKNOWN_FACTORY
;
1050 // yes - there is a type info
1051 // Try to find the preferred filter.
1054 ::comphelper::SequenceAsHashMap
stlTypeProps (xTypeCfg
->getByName(sTypeName
));
1055 OUString sPreferredFilter
= stlTypeProps
.getUnpackedValueOrDefault("PreferredFilter", OUString());
1056 ::comphelper::SequenceAsHashMap
stlFilterProps (xFilterCfg
->getByName(sPreferredFilter
));
1057 OUString sDocumentService
= stlFilterProps
.getUnpackedValueOrDefault("DocumentService", OUString());
1058 SvtModuleOptions::EFactory eApp
= SvtModuleOptions::ClassifyFactoryByServiceName(sDocumentService
);
1060 if (eApp
!= EFactory::UNKNOWN_FACTORY
)
1063 catch(const css::uno::RuntimeException
&)
1065 catch(const css::uno::Exception
&)
1066 { /* do nothing here ... may the following code can help!*/ }
1068 // no filter/no type/no detection result => no fun :-)
1069 return EFactory::UNKNOWN_FACTORY
;
1072 SvtModuleOptions::EFactory
SvtModuleOptions::ClassifyFactoryByModel(const css::uno::Reference
< css::frame::XModel
>& xModel
)
1074 css::uno::Reference
< css::lang::XServiceInfo
> xInfo(xModel
, css::uno::UNO_QUERY
);
1076 return EFactory::UNKNOWN_FACTORY
;
1078 const css::uno::Sequence
< OUString
> lServices
= xInfo
->getSupportedServiceNames();
1080 for (const OUString
& rService
: lServices
)
1082 SvtModuleOptions::EFactory eApp
= SvtModuleOptions::ClassifyFactoryByServiceName(rService
);
1083 if (eApp
!= EFactory::UNKNOWN_FACTORY
)
1087 return EFactory::UNKNOWN_FACTORY
;
1090 css::uno::Sequence
< OUString
> SvtModuleOptions::GetAllServiceNames()
1092 ::osl::MutexGuard
aGuard( impl_GetOwnStaticMutex() );
1093 return m_pImpl
->GetAllServiceNames();
1096 OUString
SvtModuleOptions::GetDefaultModuleName() const
1099 if (m_pImpl
->IsModuleInstalled(SvtModuleOptions::EModule::WRITER
))
1100 aModule
= GetFactoryShortName(SvtModuleOptions::EFactory::WRITER
);
1101 else if (m_pImpl
->IsModuleInstalled(SvtModuleOptions::EModule::CALC
))
1102 aModule
= GetFactoryShortName(SvtModuleOptions::EFactory::CALC
);
1103 else if (m_pImpl
->IsModuleInstalled(SvtModuleOptions::EModule::IMPRESS
))
1104 aModule
= GetFactoryShortName(SvtModuleOptions::EFactory::IMPRESS
);
1105 else if (m_pImpl
->IsModuleInstalled(SvtModuleOptions::EModule::DATABASE
))
1106 aModule
= GetFactoryShortName(SvtModuleOptions::EFactory::DATABASE
);
1107 else if (m_pImpl
->IsModuleInstalled(SvtModuleOptions::EModule::DRAW
))
1108 aModule
= GetFactoryShortName(SvtModuleOptions::EFactory::DRAW
);
1109 else if (m_pImpl
->IsModuleInstalled(SvtModuleOptions::EModule::WEB
))
1110 aModule
= GetFactoryShortName(SvtModuleOptions::EFactory::WRITERWEB
);
1111 else if (m_pImpl
->IsModuleInstalled(SvtModuleOptions::EModule::GLOBAL
))
1112 aModule
= GetFactoryShortName(SvtModuleOptions::EFactory::WRITERGLOBAL
);
1113 else if (m_pImpl
->IsModuleInstalled(SvtModuleOptions::EModule::MATH
))
1114 aModule
= GetFactoryShortName(SvtModuleOptions::EFactory::MATH
);
1118 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */