16#include <com/sun/star/configuration/theDefaultProvider.hpp>
17#include <com/sun/star/lang/XMultiServiceFactory.hpp>
18#include <com/sun/star/beans/NamedValue.hpp>
19#include <com/sun/star/beans/PropertyAttribute.hpp>
20#include <com/sun/star/beans/UnknownPropertyException.hpp>
21#include <com/sun/star/beans/XPropertySetInfo.hpp>
22#include <com/sun/star/configuration/ReadWriteAccess.hpp>
23#include <com/sun/star/container/XNameAccess.hpp>
24#include <com/sun/star/container/XNameReplace.hpp>
25#include <com/sun/star/container/XHierarchicalName.hpp>
26#include <com/sun/star/uno/Reference.hxx>
27#include <com/sun/star/uno/Type.hxx>
28#include <com/sun/star/uno/TypeClass.hpp>
29#include <com/sun/star/util/XChangesBatch.hpp>
30#include <com/sun/star/util/SearchFlags.hpp>
31#include <com/sun/star/util/SearchAlgorithms2.hpp>
33#include <rtl/ustrbuf.hxx>
51#define SHORT_LEN_LIMIT 7
52#define LONG_LEN_LIMIT 11
53#define HYPER_LEN_LIMIT 20
61 Prop_Impl( OUString sName, OUString sProperty, Any aValue )
72 OUString sPropertyPath;
76 explicit UserData( OUString aPropertyPath,
bool isReadOnly )
77 : bIsPropertyPath( true )
78 , bIsReadOnly( isReadOnly )
79 , sPropertyPath(
std::move(aPropertyPath))
84 : bIsPropertyPath( false )
85 , bIsReadOnly( false )
87 , aXNameAccess( rXNameAccess )
94 bool bNonSpace = rKeyEvent.GetKeyCode().GetCode() !=
KEY_SPACE;
95 if (m_bNumericOnly && bNonSpace )
98 sal_uInt16 nGroup = rKeyCode.
GetGroup();
99 sal_uInt16 nKey = rKeyCode.
GetCode();
138 if ( !bValid && ( rKeyCode.
IsMod1() && (
150 : GenericDialogController(pParent,
"cui/ui/aboutconfigdialog.ui",
"AboutConfig")
151 , m_xResetBtn(m_xBuilder->weld_button(
"reset"))
152 , m_xEditBtn(m_xBuilder->weld_button(
"edit"))
153 , m_xSearchBtn(m_xBuilder->weld_button(
"searchButton"))
154 , m_xSearchEdit(m_xBuilder->weld_entry(
"searchEntry"))
155 , m_xPrefBox(m_xBuilder->weld_tree_view(
"preferences"))
156 , m_xScratchIter(m_xPrefBox->make_iterator())
172 util::SearchFlags::REG_NOT_ENDOFLINE);
174 float fWidth =
m_xPrefBox->get_approximate_digit_width();
175 std::vector<int> aWidths
177 o3tl::narrowing<int>(fWidth * 65),
178 o3tl::narrowing<int>(fWidth * 20),
179 o3tl::narrowing<int>(fWidth * 8)
188 UserData *pUserData = weld::fromId<UserData*>(m_xPrefBox->get_id(rIter));
189 if (pUserData && pUserData->bIsReadOnly)
191 return CuiResId(RID_CUISTR_OPT_READONLY);
201 m_xPrefBox->make_sorted();
205 bool bSortAtoZ = m_xPrefBox->get_sort_order();
208 if (nColumn == m_xPrefBox->get_sort_column())
210 bSortAtoZ = !bSortAtoZ;
211 m_xPrefBox->set_sort_order(bSortAtoZ);
215 int nOldSortColumn = m_xPrefBox->get_sort_column();
216 if (nOldSortColumn != -1)
218 m_xPrefBox->set_sort_column(nColumn);
233 const OUString& rType,
const OUString& rValue,
const weld::TreeIter* pParentEntry,
234 bool bInsertToPrefBox,
bool bIsReadOnly)
236 m_vectorUserData.push_back(std::make_unique<UserData>(rPropertyPath, bIsReadOnly));
237 if (bInsertToPrefBox)
270 FillItems( xConfigAccess,
nullptr, 0,
true );
278 std::vector< std::shared_ptr< Prop_Impl > >::iterator pIter;
284 xNameReplace->replaceByName( (*pIter)->Property, (*pIter)->Value );
287 xChangesBatch->commitChanges();
292 int lineage,
bool bLoadAll)
295 xNameAccess, uno::UNO_QUERY_THROW )->getHierarchicalName();
297 for(
const OUString& item : seqItems )
299 Any aNode = xNameAccess->getByName( item );
301 bool bNotLeaf =
false;
306 xNextNameAccess.set(aNode, uno::UNO_QUERY);
307 bNotLeaf = xNextNameAccess.is();
317 FillItems(xNextNameAccess,
nullptr, lineage + 1,
true);
321 m_vectorUserData.push_back(std::make_unique<UserData>(xNextNameAccess, lineage + 1));
335 OUString sPropertyName = item;
337 [&sPath, &sPropertyName](
const prefBoxEntry& rEntry) ->
bool
339 return rEntry.pUserData->sPropertyPath == sPath
340 && rEntry.sStatus == sPropertyName;
344 css::uno::Reference<css::configuration::XReadWriteAccess> m_xReadWriteAccess;
345 m_xReadWriteAccess = css::configuration::ReadWriteAccess::create(
346 ::comphelper::getProcessComponentContext(),
"*");
347 beans::Property aProperty;
351 aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName(sPath +
"/"
353 bReadOnly = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
355 catch (css::beans::UnknownPropertyException)
357 SAL_WARN(
"cui.options",
"unknown property: " << sPath +
"/" + sPropertyName);
360 OUString
sType = aNode.getValueTypeName();
361 OUStringBuffer sValue;
367 switch( aNode.getValueType().getTypeClass() )
369 case css::uno::TypeClass_VOID:
372 case css::uno::TypeClass_BOOLEAN:
373 sValue = OUString::boolean( aNode.get<
bool>() );
376 case css::uno::TypeClass_SHORT:
377 case css::uno::TypeClass_LONG:
378 case css::uno::TypeClass_HYPER:
379 sValue = OUString::number( aNode.get<sal_Int64>() );
382 case css::uno::TypeClass_DOUBLE:
383 sValue = OUString::number( aNode.get<
double>() );
386 case css::uno::TypeClass_STRING:
387 sValue = aNode.get<OUString>();
390 case css::uno::TypeClass_SEQUENCE:
391 if(
sType ==
"[]boolean" )
394 for( sal_Int32 j = 0; j != seq.getLength(); ++j )
400 sValue.append(OUString::boolean( seq[j] ));
403 else if(
sType ==
"[]byte" )
408 OUString s = OUString::number(
410 if( s.getLength() == 1 )
414 sValue.append(s.toAsciiUpperCase());
417 else if(
sType ==
"[][]byte" )
420 for( sal_Int32 j = 0; j != seq.getLength(); ++j )
428 OUString s = OUString::number(
430 if( s.getLength() == 1 )
434 sValue.append(s.toAsciiUpperCase());
438 else if(
sType ==
"[]short" )
441 for( sal_Int32 j = 0; j != seq.getLength(); ++j )
447 sValue.append(
static_cast<sal_Int32
>(seq[j]) );
450 else if(
sType ==
"[]long" )
453 for( sal_Int32 j = 0; j != seq.getLength(); ++j )
459 sValue.append( seq[j] );
462 else if(
sType ==
"[]hyper" )
465 for( sal_Int32 j = 0; j != seq.getLength(); ++j )
471 sValue.append( seq[j] );
474 else if(
sType ==
"[]double" )
477 for( sal_Int32 j = 0; j != seq.getLength(); ++j )
483 sValue.append( seq[j] );
486 else if(
sType ==
"[]string" )
489 for( sal_Int32 j = 0; j != seq.getLength(); ++j )
495 sValue.append(seq[j]);
502 "path \"" << sPath <<
"\" member " << item
503 <<
" of unsupported type " <<
sType);
510 "path \"" << sPath <<
"\" member " << item
511 <<
" of unsupported type " <<
sType);
518 for(
int j = 1; j < lineage; ++j)
532 css::configuration::theDefaultProvider::get( xContext ) );
534 beans::NamedValue aProperty;
535 aProperty.Name =
"nodepath";
536 aProperty.Value <<= sNodePath;
540 OUString sAccessString;
543 sAccessString =
"com.sun.star.configuration.ConfigurationUpdateAccess";
545 sAccessString =
"com.sun.star.configuration.ConfigurationAccess";
548 xConfigProvider->createInstanceWithArguments(
549 sAccessString, aArgumentList ),
550 uno::UNO_QUERY_THROW );
557 bool isModifiedBefore =
false;
561 if( rProp->Name == nInd->Name && rProp->Property == nInd->Property )
566 isModifiedBefore =
true;
571 if( !isModifiedBefore )
578 std::vector<OUString> tempVector;
586 tempVector.push_back(word);
587 }
while(
index >= 0 );
592 const OUString& rValue,
594 : GenericDialogController(pWindow,
"cui/ui/aboutconfigvaluedialog.ui",
"AboutConfigValueDialog")
595 , m_bNumericOnly(limit != 0)
596 , m_xEDValue(m_xBuilder->weld_entry(
"valuebox"))
615 StandardHdl_Impl(*m_xEditBtn);
621 if (!m_xPrefBox->get_selected(m_xScratchIter.get()))
624 UserData *pUserData = weld::fromId<UserData*>(m_xPrefBox->get_id(*m_xScratchIter));
625 if (!pUserData || !pUserData->bIsPropertyPath || pUserData->bIsReadOnly)
629 OUString sPropertyName = m_xPrefBox->get_text(*m_xScratchIter, 1);
630 OUString sPropertyType = m_xPrefBox->get_text(*m_xScratchIter, 2);
631 OUString sPropertyValue = m_xPrefBox->get_text(*m_xScratchIter, 3);
634 if (sPropertyType ==
"void")
636 css::uno::Reference<css::beans::XPropertySetInfo> info(
638 css::uno::UNO_QUERY_THROW);
641 t = info->getPropertyByName(sPropertyName).Type;
642 }
catch (css::beans::UnknownPropertyException &) {
649 sPropertyType =
t.getTypeName();
650 switch (
t.getTypeClass()) {
651 case css::uno::TypeClass_BOOLEAN:
652 sPropertyValue =
"false";
654 case css::uno::TypeClass_SHORT:
655 case css::uno::TypeClass_LONG:
656 case css::uno::TypeClass_HYPER:
657 case css::uno::TypeClass_DOUBLE:
658 sPropertyValue =
"0";
666 auto pProperty = std::make_shared<Prop_Impl>( pUserData->sPropertyPath, sPropertyName,
Any( sPropertyValue ) );
667 bool bSaveChanges =
false;
669 bool bOpenDialog =
true;
670 OUString sDialogValue;
672 if( sPropertyType ==
"boolean" )
675 if( sPropertyValue ==
"true" )
677 sDialogValue =
"false";
682 sDialogValue =
"true";
686 pProperty->Value <<= bValue;
690 else if ( sPropertyType ==
"void" )
696 sDialogValue = sPropertyValue;
706 if( sPropertyType ==
"short" )
708 else if( sPropertyType ==
"long" )
710 else if( sPropertyType ==
"hyper" )
717 OUString sNewValue = aValueDialog.
getValue();
719 if ( sPropertyType ==
"short")
722 sal_Int32 nNumb = sNewValue.toInt32();
726 throw uno::Exception(
"out of range short",
nullptr);
727 nShort =
static_cast<sal_Int16
>(nNumb);
728 pProperty->Value <<= nShort;
730 else if( sPropertyType ==
"long" )
732 sal_Int32 nLong = sNewValue.toInt32();
733 if( nLong==0 && sNewValue.getLength()!=1)
734 throw uno::Exception(
"out of range long",
nullptr);
735 pProperty->Value <<= nLong;
737 else if( sPropertyType ==
"hyper")
739 sal_Int64 nHyper = sNewValue.toInt64();
740 if( nHyper==0 && sNewValue.getLength()!=1)
741 throw uno::Exception(
"out of range hyper",
nullptr);
742 pProperty->Value <<= nHyper;
744 else if( sPropertyType ==
"double")
746 double nDoub = sNewValue.toDouble();
747 if( nDoub ==0 && sNewValue.getLength()!=1)
748 throw uno::Exception(
"out of range double",
nullptr);
749 pProperty->Value <<= nDoub;
751 else if( sPropertyType ==
"float")
753 float nFloat = sNewValue.toFloat();
754 if( nFloat ==0 && sNewValue.getLength()!=1)
755 throw uno::Exception(
"out of range float",
nullptr);
756 pProperty->Value <<= nFloat;
758 else if( sPropertyType ==
"string" )
760 pProperty->Value <<= sNewValue;
762 else if( sPropertyType ==
"[]short" )
766 std::vector< OUString > seqStr = commaStringToSequence( sNewValue );
771 std::transform(seqStr.begin(), seqStr.end(), seqShort.getArray(),
773 { return static_cast<sal_Int16>(str.toInt32()); });
774 pProperty->Value <<= seqShort;
776 else if( sPropertyType ==
"[]long" )
778 std::vector< OUString > seqStrLong = commaStringToSequence( sNewValue );
781 std::transform(seqStrLong.begin(), seqStrLong.end(), seqLong.getArray(),
782 [](
const auto& str) { return str.toInt32(); });
783 pProperty->Value <<= seqLong;
785 else if( sPropertyType ==
"[]hyper" )
787 std::vector< OUString > seqStrHyper = commaStringToSequence( sNewValue );
789 std::transform(seqStrHyper.begin(), seqStrHyper.end(), seqHyper.getArray(),
790 [](
const auto& str) { return str.toInt64(); });
791 pProperty->Value <<= seqHyper;
793 else if( sPropertyType ==
"[]double" )
795 std::vector< OUString > seqStrDoub = commaStringToSequence( sNewValue );
797 std::transform(seqStrDoub.begin(), seqStrDoub.end(), seqDoub.getArray(),
798 [](
const auto& str) { return str.toDouble(); });
799 pProperty->Value <<= seqDoub;
801 else if( sPropertyType ==
"[]float" )
803 std::vector< OUString > seqStrFloat = commaStringToSequence( sNewValue );
805 std::transform(seqStrFloat.begin(), seqStrFloat.end(), seqFloat.getArray(),
806 [](
const auto& str) { return str.toFloat(); });
807 pProperty->Value <<= seqFloat;
809 else if( sPropertyType ==
"[]string" )
814 throw uno::Exception(
"unknown property type " + sPropertyType,
nullptr);
816 sDialogValue = sNewValue;
822 AddToModifiedVector( pProperty );
825 m_xPrefBox->set_text(*m_xScratchIter, sPropertyType, 2);
826 m_xPrefBox->set_text(*m_xScratchIter, sDialogValue, 3);
828 auto it = std::find_if(m_prefBoxEntries.begin(), m_prefBoxEntries.end(),
829 [&pUserData, &sPropertyName](
const prefBoxEntry& rEntry) ->
bool
831 return rEntry.pUserData->sPropertyPath == pUserData->sPropertyPath
832 && rEntry.sStatus == sPropertyName;
835 if (it != m_prefBoxEntries.end())
837 it->sValue = sDialogValue;
839 auto modifiedIt = std::find_if(
840 m_modifiedPrefBoxEntries.begin(), m_modifiedPrefBoxEntries.end(),
841 [&pUserData, &sPropertyName](
const prefBoxEntry& rEntry) ->
bool
843 return rEntry.pUserData->sPropertyPath == pUserData->sPropertyPath
844 && rEntry.sStatus == sPropertyName;
848 if (modifiedIt != m_modifiedPrefBoxEntries.end())
850 modifiedIt->sValue = sDialogValue;
854 m_modifiedPrefBoxEntries.push_back(*it);
859 catch( uno::Exception& )
870 m_xPrefBox->freeze();
873 m_xPrefBox->make_unsorted();
875 if (m_xSearchEdit->get_text().isEmpty())
879 FillItems( xConfigAccess );
883 m_options.searchString = m_xSearchEdit->get_text();
885 for (
auto const& it : m_prefBoxEntries)
887 sal_Int32 endPos, startPos = 0;
889 for(
size_t i = 0;
i < 5; ++
i)
894 scrTxt = it.pUserData->sPropertyPath;
904 endPos = scrTxt.getLength();
916 m_xPrefBox->make_sorted();
919 m_xPrefBox->expand_row(rEntry);
927 OUString sPathWithProperty = rEntry.
pUserData->sPropertyPath;
928 sal_Int32
index = sPathWithProperty.lastIndexOf(rEntry.
sProp);
929 OUString sPath = sPathWithProperty.copy(0,
index);
931 std::unique_ptr<weld::TreeIter> xParentEntry(
m_xPrefBox->make_iterator());
932 std::unique_ptr<weld::TreeIter> xGrandParentEntry;
936 int prevIndex =
index;
949 OUString sParentName = sPath.copy(prevIndex+1,
index - prevIndex - 1);
951 bool hasEntry =
false;
954 if (!xGrandParentEntry)
955 bStartOk =
m_xPrefBox->get_iter_first(*xParentEntry);
958 m_xPrefBox->copy_iterator(*xGrandParentEntry, *xParentEntry);
959 bStartOk =
m_xPrefBox->iter_children(*xParentEntry);
966 if (
m_xPrefBox->get_text(*xParentEntry, 0) == sParentName)
971 }
while (
m_xPrefBox->iter_next_sibling(*xParentEntry));
976 m_xPrefBox->insert(xGrandParentEntry.get(), -1, &sParentName,
nullptr,
nullptr,
nullptr,
false, xParentEntry.get());
981 m_xPrefBox->set_sensitive(*xParentEntry,
true);
984 xGrandParentEntry =
m_xPrefBox->make_iterator(xParentEntry.get());
985 }
while(
index < sPath.getLength() - 1);
997 if (m_xPrefBox->iter_has_child(rEntry))
999 UserData *pUserData = weld::fromId<UserData*>(m_xPrefBox->get_id(rEntry));
1000 if (pUserData && !pUserData->bIsPropertyPath)
1002 assert(pUserData->aXNameAccess.is());
1003 FillItems(pUserData->aXNameAccess, &rEntry, pUserData->aLineage);
Reference< XExecutableDialog > m_xDialog
std::vector< prefBoxEntry > m_modifiedPrefBoxEntries
std::vector< std::unique_ptr< UserData > > m_vectorUserData
void FillItems(const css::uno::Reference< css::container::XNameAccess > &xNameAccess, const weld::TreeIter *pParentEntry=nullptr, int lineage=0, bool bLoadAll=false)
CuiAboutConfigTabPage(weld::Window *pParent)
void InsertEntry(const prefBoxEntry &rEntry)
std::vector< prefBoxEntry > m_prefBoxEntries
void AddToModifiedVector(const std::shared_ptr< Prop_Impl > &rProp)
std::vector< std::shared_ptr< Prop_Impl > > m_vectorOfModified
std::unique_ptr< weld::TreeView > m_xPrefBox
virtual ~CuiAboutConfigTabPage() override
static std::vector< OUString > commaStringToSequence(std::u16string_view rCommaSepString)
static css::uno::Reference< css::container::XNameAccess > getConfigAccess(const OUString &sNodePath, bool bUpdate)
std::unique_ptr< weld::Button > m_xSearchBtn
i18nutil::SearchOptions2 m_options
std::unique_ptr< weld::Button > m_xEditBtn
std::unique_ptr< weld::Button > m_xResetBtn
std::unique_ptr< weld::TreeIter > m_xScratchIter
virtual ~CuiAboutConfigValueDialog() override
std::unique_ptr< weld::Entry > m_xEDValue
CuiAboutConfigValueDialog(weld::Window *pWindow, const OUString &rValue, int limit)
OUString getValue() const
bool SearchForward(const OUString &rStr, sal_Int32 *pStart, sal_Int32 *pEnd, css::util::SearchResult *pRes=nullptr)
sal_uInt16 GetGroup() const
sal_uInt16 GetCode() const
std::shared_ptr< weld::Dialog > m_xDialog
OUString CuiResId(TranslateId aKey)
#define TOOLS_WARN_EXCEPTION(area, stream)
constexpr sal_uInt16 KEY_X
constexpr sal_uInt16 KEY_V
constexpr sal_uInt16 KEY_EQUAL
constexpr sal_uInt16 KEY_COMMA
constexpr sal_uInt16 KEY_POINT
constexpr sal_uInt16 KEYGROUP_MISC
constexpr sal_uInt16 KEY_Z
constexpr sal_uInt16 KEY_A
constexpr sal_uInt16 KEY_SPACE
constexpr sal_uInt16 KEYGROUP_NUM
constexpr sal_uInt16 KEY_C
constexpr sal_uInt16 KEY_SUBTRACT
constexpr sal_uInt16 KEYGROUP_CURSOR
#define LINK(Instance, Class, Member)
#define SAL_WARN(area, stream)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
OUString toId(const void *pValue)
IMPL_LINK(CuiAboutConfigValueDialog, KeyInputHdl, const KeyEvent &, rKeyEvent, bool)
IMPL_LINK_NOARG(CuiAboutConfigTabPage, ResetBtnHdl_Impl, weld::Button &, void)
Prop_Impl(OUString sName, OUString sProperty, Any aValue)
TransliterationFlags transliterateFlags