1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_framework.hxx"
24
25 #include <uielement/statusbarmerger.hxx>
26
27 using rtl::OUString;
28 using com::sun::star::frame::XFrame;
29 using com::sun::star::uno::Reference;
30 using com::sun::star::beans::PropertyValue;
31 using com::sun::star::uno::Sequence;
32
33 namespace framework
34 {
35 namespace {
36
37 static const char MERGE_STATUSBAR_URL[] = "URL";
38 static const char MERGE_STATUSBAR_TITLE[] = "Title";
39 static const char MERGE_STATUSBAR_CONTEXT[] = "Context";
40 static const char MERGE_STATUSBAR_ALIGN[] = "Alignment";
41 static const char MERGE_STATUSBAR_AUTOSIZE[] = "AutoSize";
42 static const char MERGE_STATUSBAR_OWNERDRAW[] = "OwnerDraw";
43 static const char MERGE_STATUSBAR_WIDTH[] = "Width";
44
45 static const char STATUSBAR_ALIGN_LEFT[] = "left";
46 static const char STATUSBAR_ALIGN_CENTER[] = "center";
47 static const char STATUSBAR_ALIGN_RIGHT[] = "right";
48
49 static const char MERGECOMMAND_ADDAFTER[] = "AddAfter";
50 static const char MERGECOMMAND_ADDBEFORE[] = "AddBefore";
51 static const char MERGECOMMAND_REPLACE[] = "Replace";
52 static const char MERGECOMMAND_REMOVE[] = "Remove";
53
54 static const char MERGEFALLBACK_ADDLAST[] = "AddLast";
55 static const char MERGEFALLBACK_ADDFIRST[] = "AddFirst";
56 static const char MERGEFALLBACK_IGNORE[] = "Ignore";
57
58
lcl_ConvertSequenceToValues(const Sequence<PropertyValue> & rSequence,AddonStatusbarItem & rItem)59 static void lcl_ConvertSequenceToValues(
60 const Sequence< PropertyValue > &rSequence,
61 AddonStatusbarItem &rItem )
62 {
63 OUString sAlignment;
64 sal_Bool bAutoSize = sal_False;
65 sal_Bool bOwnerDraw = sal_False;
66
67 PropertyValue aPropVal;
68 for ( sal_Int32 i = 0; i < rSequence.getLength(); i++ )
69 {
70 aPropVal = rSequence[i];
71 if ( aPropVal.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGE_STATUSBAR_URL ) ) )
72 aPropVal.Value >>= rItem.aCommandURL;
73 else if ( aPropVal.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGE_STATUSBAR_TITLE ) ) )
74 aPropVal.Value >>= rItem.aLabel;
75 else if ( aPropVal.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGE_STATUSBAR_CONTEXT ) ) )
76 aPropVal.Value >>= rItem.aContext;
77 else if ( aPropVal.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGE_STATUSBAR_ALIGN ) ) )
78 aPropVal.Value >>= sAlignment;
79 else if ( aPropVal.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGE_STATUSBAR_AUTOSIZE ) ) )
80 aPropVal.Value >>= bAutoSize;
81 else if ( aPropVal.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGE_STATUSBAR_OWNERDRAW ) ) )
82 aPropVal.Value >>= bOwnerDraw;
83 else if ( aPropVal.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGE_STATUSBAR_WIDTH ) ) )
84 {
85 sal_Int32 aWidth = 0;
86 aPropVal.Value >>= aWidth;
87 rItem.nWidth = sal_uInt16( aWidth );
88 }
89 }
90
91 sal_uInt16 nItemBits(0);
92 if ( bAutoSize )
93 nItemBits |= SIB_AUTOSIZE;
94 if ( bOwnerDraw )
95 nItemBits |= SIB_USERDRAW;
96 if ( sAlignment.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( STATUSBAR_ALIGN_CENTER )))
97 nItemBits |= SIB_CENTER;
98 else if ( sAlignment.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( STATUSBAR_ALIGN_RIGHT )))
99 nItemBits |= SIB_RIGHT;
100 else
101 // if unset, defaults to left alignment
102 nItemBits |= SIB_LEFT;
103 rItem.nItemBits = nItemBits;
104 }
105
lcl_CreateStatusbarItem(StatusBar * pStatusbar,sal_uInt16 nPos,sal_uInt16 nItemId,const AddonStatusbarItem & rAddonItem)106 static void lcl_CreateStatusbarItem( StatusBar* pStatusbar,
107 sal_uInt16 nPos,
108 sal_uInt16 nItemId,
109 const AddonStatusbarItem& rAddonItem )
110 {
111 pStatusbar->InsertItem( nItemId,
112 rAddonItem.nWidth,
113 rAddonItem.nItemBits,
114 STATUSBAR_OFFSET,
115 nPos );
116 pStatusbar->SetItemCommand( nItemId, rAddonItem.aCommandURL );
117 pStatusbar->SetQuickHelpText( nItemId, rAddonItem.aLabel );
118 pStatusbar->SetAccessibleName( nItemId, rAddonItem.aLabel );
119
120 // add-on specific data
121 AddonStatusbarItemData *pUserData = new AddonStatusbarItemData;
122 pUserData->aLabel = rAddonItem.aLabel;
123 pUserData->nItemBits = rAddonItem.nItemBits;
124 pStatusbar->SetItemData( nItemId, pUserData );
125 }
126
lcl_MergeItems(StatusBar * pStatusbar,sal_uInt16 nPos,sal_uInt16 nModIndex,sal_uInt16 & rItemId,const::rtl::OUString & rModuleIdentifier,const AddonStatusbarItemContainer & rAddonItems)127 static bool lcl_MergeItems( StatusBar* pStatusbar,
128 sal_uInt16 nPos,
129 sal_uInt16 nModIndex,
130 sal_uInt16& rItemId,
131 const ::rtl::OUString& rModuleIdentifier,
132 const AddonStatusbarItemContainer& rAddonItems )
133 {
134 OSL_ENSURE(rAddonItems.size() <= 0xffff, "Caution: Not all items get handled (!)");
135 const sal_uInt16 nSize( static_cast< sal_uInt16 >(rAddonItems.size()) );
136 for ( sal_Int32 i = 0; i < nSize; i++ )
137 {
138 const AddonStatusbarItem& rItem = rAddonItems[i];
139 if ( !StatusbarMerger::IsCorrectContext( rItem.aContext, rModuleIdentifier ) )
140 continue;
141
142 sal_uInt16 nInsPos = nPos + nModIndex + i;
143 if ( nInsPos > pStatusbar->GetItemCount() )
144 nInsPos = STATUSBAR_APPEND;
145
146 lcl_CreateStatusbarItem( pStatusbar, nInsPos, rItemId, rItem );
147 ++rItemId;
148 }
149
150 return true;
151 }
152
lcl_ReplaceItem(StatusBar * pStatusbar,sal_uInt16 nPos,sal_uInt16 & rItemId,const::rtl::OUString & rModuleIdentifier,const AddonStatusbarItemContainer & rAddonToolbarItems)153 static bool lcl_ReplaceItem( StatusBar* pStatusbar,
154 sal_uInt16 nPos,
155 sal_uInt16& rItemId,
156 const ::rtl::OUString& rModuleIdentifier,
157 const AddonStatusbarItemContainer& rAddonToolbarItems )
158 {
159 pStatusbar->RemoveItem( pStatusbar->GetItemId( nPos ) );
160 return lcl_MergeItems( pStatusbar, nPos, 0, rItemId, rModuleIdentifier, rAddonToolbarItems );
161 }
162
lcl_RemoveItems(StatusBar * pStatusbar,sal_uInt16 nPos,const::rtl::OUString & rMergeCommandParameter)163 static bool lcl_RemoveItems( StatusBar* pStatusbar,
164 sal_uInt16 nPos,
165 const ::rtl::OUString& rMergeCommandParameter )
166 {
167 sal_Int32 nCount = rMergeCommandParameter.toInt32();
168 if ( nCount > 0 )
169 {
170 for ( sal_Int32 i = 0; i < nCount; i++ )
171 {
172 if ( nPos < pStatusbar->GetItemCount() )
173 pStatusbar->RemoveItem( nPos );
174 }
175 }
176 return true;
177 }
178
179 }
180
IsCorrectContext(const OUString & rContext,const OUString & rModuleIdentifier)181 bool StatusbarMerger::IsCorrectContext(
182 const OUString& rContext,
183 const OUString& rModuleIdentifier )
184 {
185 return (( rContext.getLength() == 0 ) || ( rContext.indexOf( rModuleIdentifier ) >= 0 ));
186 }
187
ConvertSeqSeqToVector(const Sequence<Sequence<PropertyValue>> & rSequence,AddonStatusbarItemContainer & rContainer)188 bool StatusbarMerger::ConvertSeqSeqToVector(
189 const Sequence< Sequence< PropertyValue > > &rSequence,
190 AddonStatusbarItemContainer& rContainer )
191 {
192 for ( sal_Int32 i = 0; i < rSequence.getLength(); i++ )
193 {
194 AddonStatusbarItem aStatusBarItem;
195 lcl_ConvertSequenceToValues( rSequence[i], aStatusBarItem );
196 rContainer.push_back( aStatusBarItem );
197 }
198
199 return true;
200 }
201
FindReferencePos(StatusBar * pStatusbar,const OUString & rReferencePoint)202 sal_uInt16 StatusbarMerger::FindReferencePos(
203 StatusBar* pStatusbar,
204 const OUString& rReferencePoint )
205 {
206 for ( sal_uInt16 nPos = 0; nPos < pStatusbar->GetItemCount(); nPos++ )
207 {
208 const ::rtl::OUString rCmd = pStatusbar->GetItemCommand( pStatusbar->GetItemId( nPos ) );
209 if ( rReferencePoint == rCmd )
210 return nPos;
211 }
212
213 return STATUSBAR_ITEM_NOTFOUND;
214 }
215
ProcessMergeOperation(StatusBar * pStatusbar,sal_uInt16 nPos,sal_uInt16 & rItemId,const::rtl::OUString & rModuleIdentifier,const::rtl::OUString & rMergeCommand,const::rtl::OUString & rMergeCommandParameter,const AddonStatusbarItemContainer & rItems)216 bool StatusbarMerger::ProcessMergeOperation(
217 StatusBar* pStatusbar,
218 sal_uInt16 nPos,
219 sal_uInt16& rItemId,
220 const ::rtl::OUString& rModuleIdentifier,
221 const ::rtl::OUString& rMergeCommand,
222 const ::rtl::OUString& rMergeCommandParameter,
223 const AddonStatusbarItemContainer& rItems )
224 {
225 if ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_ADDAFTER ) ) )
226 return lcl_MergeItems( pStatusbar, nPos, 1, rItemId, rModuleIdentifier, rItems );
227 else if ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_ADDBEFORE ) ) )
228 return lcl_MergeItems( pStatusbar, nPos, 0, rItemId, rModuleIdentifier, rItems );
229 else if ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_REPLACE ) ) )
230 return lcl_ReplaceItem( pStatusbar, nPos, rItemId, rModuleIdentifier, rItems );
231 else if ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_REMOVE ) ) )
232 return lcl_RemoveItems( pStatusbar, nPos, rMergeCommandParameter );
233
234 return false;
235 }
236
ProcessMergeFallback(StatusBar * pStatusbar,sal_uInt16,sal_uInt16 & rItemId,const::rtl::OUString & rModuleIdentifier,const::rtl::OUString & rMergeCommand,const::rtl::OUString & rMergeFallback,const AddonStatusbarItemContainer & rItems)237 bool StatusbarMerger::ProcessMergeFallback(
238 StatusBar* pStatusbar,
239 sal_uInt16 /*nPos*/,
240 sal_uInt16& rItemId,
241 const ::rtl::OUString& rModuleIdentifier,
242 const ::rtl::OUString& rMergeCommand,
243 const ::rtl::OUString& rMergeFallback,
244 const AddonStatusbarItemContainer& rItems )
245 {
246 // fallback IGNORE or REPLACE/REMOVE item not found
247 if (( rMergeFallback.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGEFALLBACK_IGNORE ))) ||
248 ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_REPLACE ))) ||
249 ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_REMOVE ))) )
250 {
251 return true;
252 }
253 else if (( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_ADDBEFORE ))) ||
254 ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_ADDAFTER ))) )
255 {
256 if ( rMergeFallback.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGEFALLBACK_ADDFIRST )))
257 return lcl_MergeItems( pStatusbar, 0, 0, rItemId, rModuleIdentifier, rItems );
258 else if ( rMergeFallback.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGEFALLBACK_ADDLAST )))
259 return lcl_MergeItems( pStatusbar, STATUSBAR_APPEND, 0, rItemId, rModuleIdentifier, rItems );
260 }
261
262 return false;
263 }
264
265
266 }
267