Avoid potential negative array index access to cached text.
[LibreOffice.git] / framework / source / uielement / statusbarmerger.cxx
blobc8e6633be9f0d242583c6560d78a8bf3dba777ad
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
19 #include <uielement/statusbarmerger.hxx>
20 #include <o3tl/string_view.hxx>
22 using com::sun::star::beans::PropertyValue;
23 using com::sun::star::uno::Sequence;
25 namespace framework
27 namespace {
29 const char16_t MERGECOMMAND_ADDAFTER[] = u"AddAfter";
30 const char16_t MERGECOMMAND_ADDBEFORE[] = u"AddBefore";
31 const char16_t MERGECOMMAND_REPLACE[] = u"Replace";
32 const char16_t MERGECOMMAND_REMOVE[] = u"Remove";
34 void lcl_ConvertSequenceToValues(
35 const Sequence< PropertyValue > &rSequence,
36 AddonStatusbarItem &rItem )
38 OUString sAlignment;
39 bool bAutoSize = false;
40 bool bOwnerDraw = false;
41 bool bMandatory = true;
43 for ( PropertyValue const & aPropVal : rSequence )
45 if ( aPropVal.Name == "URL" )
46 aPropVal.Value >>= rItem.aCommandURL;
47 else if ( aPropVal.Name == "Title" )
48 aPropVal.Value >>= rItem.aLabel;
49 else if ( aPropVal.Name == "Context" )
50 aPropVal.Value >>= rItem.aContext;
51 else if ( aPropVal.Name == "Alignment" )
52 aPropVal.Value >>= sAlignment;
53 else if ( aPropVal.Name == "AutoSize" )
54 aPropVal.Value >>= bAutoSize;
55 else if ( aPropVal.Name == "OwnerDraw" )
56 aPropVal.Value >>= bOwnerDraw;
57 else if ( aPropVal.Name == "Mandatory" )
58 aPropVal.Value >>= bMandatory;
59 else if ( aPropVal.Name == "Width" )
61 sal_Int32 aWidth = 0;
62 aPropVal.Value >>= aWidth;
63 rItem.nWidth = sal_uInt16( aWidth );
67 StatusBarItemBits nItemBits(StatusBarItemBits::NONE);
68 if ( bAutoSize )
69 nItemBits |= StatusBarItemBits::AutoSize;
70 if ( bOwnerDraw )
71 nItemBits |= StatusBarItemBits::UserDraw;
72 if ( bMandatory )
73 nItemBits |= StatusBarItemBits::Mandatory;
74 if ( sAlignment == "center" )
75 nItemBits |= StatusBarItemBits::Center;
76 else if ( sAlignment == "right" )
77 nItemBits |= StatusBarItemBits::Right;
78 else
79 // if unset, defaults to left alignment
80 nItemBits |= StatusBarItemBits::Left;
81 rItem.nItemBits = nItemBits;
84 void lcl_CreateStatusbarItem( StatusBar* pStatusbar,
85 sal_uInt16 nPos,
86 sal_uInt16 nItemId,
87 const AddonStatusbarItem& rAddonItem )
89 pStatusbar->InsertItem( nItemId,
90 rAddonItem.nWidth,
91 rAddonItem.nItemBits,
92 STATUSBAR_OFFSET,
93 nPos );
94 pStatusbar->SetItemCommand( nItemId, rAddonItem.aCommandURL );
95 pStatusbar->SetQuickHelpText( nItemId, rAddonItem.aLabel );
96 pStatusbar->SetAccessibleName( nItemId, rAddonItem.aLabel );
98 // add-on specific data
99 AddonStatusbarItemData *pUserData = new AddonStatusbarItemData;
100 pUserData->aLabel = rAddonItem.aLabel;
101 pStatusbar->SetItemData( nItemId, pUserData );
104 bool lcl_MergeItems( StatusBar* pStatusbar,
105 sal_uInt16 nPos,
106 sal_uInt16 nModIndex,
107 sal_uInt16& rItemId,
108 const AddonStatusbarItemContainer& rAddonItems )
110 const sal_uInt16 nSize( rAddonItems.size() );
111 for ( sal_Int32 i = 0; i < nSize; i++ )
113 const AddonStatusbarItem& rItem = rAddonItems[i];
114 if ( !StatusbarMerger::IsCorrectContext( rItem.aContext ) )
115 continue;
117 sal_uInt16 nInsPos = nPos + nModIndex + i;
118 if ( nInsPos > pStatusbar->GetItemCount() )
119 nInsPos = STATUSBAR_APPEND;
121 lcl_CreateStatusbarItem( pStatusbar, nInsPos, rItemId, rItem );
122 ++rItemId;
125 return true;
128 bool lcl_ReplaceItem( StatusBar* pStatusbar,
129 sal_uInt16 nPos,
130 sal_uInt16& rItemId,
131 const AddonStatusbarItemContainer& rAddonToolbarItems )
133 pStatusbar->RemoveItem( pStatusbar->GetItemId( nPos ) );
134 return lcl_MergeItems( pStatusbar, nPos, 0, rItemId, rAddonToolbarItems );
137 bool lcl_RemoveItems( StatusBar* pStatusbar,
138 sal_uInt16 nPos,
139 std::u16string_view rMergeCommandParameter )
141 sal_Int32 nCount = o3tl::toInt32(rMergeCommandParameter);
142 if ( nCount > 0 )
144 for ( sal_Int32 i = 0; i < nCount; i++ )
146 if ( nPos < pStatusbar->GetItemCount() )
147 pStatusbar->RemoveItem( nPos );
150 return true;
155 bool StatusbarMerger::IsCorrectContext(
156 std::u16string_view rContext )
158 return rContext.empty();
161 bool StatusbarMerger::ConvertSeqSeqToVector(
162 const Sequence< Sequence< PropertyValue > > &rSequence,
163 AddonStatusbarItemContainer& rContainer )
165 for ( auto const & i : rSequence )
167 AddonStatusbarItem aStatusBarItem;
168 lcl_ConvertSequenceToValues( i, aStatusBarItem );
169 rContainer.push_back( aStatusBarItem );
172 return true;
175 sal_uInt16 StatusbarMerger::FindReferencePos(
176 StatusBar* pStatusbar,
177 std::u16string_view rReferencePoint )
179 for ( sal_uInt16 nPos = 0; nPos < pStatusbar->GetItemCount(); nPos++ )
181 const OUString rCmd = pStatusbar->GetItemCommand( pStatusbar->GetItemId( nPos ) );
182 if ( rReferencePoint == rCmd )
183 return nPos;
186 return STATUSBAR_ITEM_NOTFOUND;
189 bool StatusbarMerger::ProcessMergeOperation(
190 StatusBar* pStatusbar,
191 sal_uInt16 nPos,
192 sal_uInt16& rItemId,
193 std::u16string_view rMergeCommand,
194 std::u16string_view rMergeCommandParameter,
195 const AddonStatusbarItemContainer& rItems )
197 if ( rMergeCommand == MERGECOMMAND_ADDAFTER )
198 return lcl_MergeItems( pStatusbar, nPos, 1, rItemId, rItems );
199 else if ( rMergeCommand == MERGECOMMAND_ADDBEFORE )
200 return lcl_MergeItems( pStatusbar, nPos, 0, rItemId, rItems );
201 else if ( rMergeCommand == MERGECOMMAND_REPLACE )
202 return lcl_ReplaceItem( pStatusbar, nPos, rItemId, rItems );
203 else if ( rMergeCommand == MERGECOMMAND_REMOVE )
204 return lcl_RemoveItems( pStatusbar, nPos, rMergeCommandParameter );
206 return false;
209 bool StatusbarMerger::ProcessMergeFallback(
210 StatusBar* pStatusbar,
211 sal_uInt16& rItemId,
212 std::u16string_view rMergeCommand,
213 std::u16string_view rMergeFallback,
214 const AddonStatusbarItemContainer& rItems )
216 // fallback IGNORE or REPLACE/REMOVE item not found
217 if (( rMergeFallback == u"Ignore" ) ||
218 ( rMergeCommand == MERGECOMMAND_REPLACE ) ||
219 ( rMergeCommand == MERGECOMMAND_REMOVE ) )
221 return true;
223 else if (( rMergeCommand == MERGECOMMAND_ADDBEFORE ) ||
224 ( rMergeCommand == MERGECOMMAND_ADDAFTER ) )
226 if ( rMergeFallback == u"AddFirst" )
227 return lcl_MergeItems( pStatusbar, 0, 0, rItemId, rItems );
228 else if ( rMergeFallback == u"AddLast" )
229 return lcl_MergeItems( pStatusbar, STATUSBAR_APPEND, 0, rItemId, rItems );
232 return false;
237 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */