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 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 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 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 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 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 static ::cppu::OWeakObject* CreateController( 181 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xSMGR, 182 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame, 183 StatusBar* pStatusbar, 184 const ::rtl::OUString& rCommandURL, 185 sal_uInt16 nId, 186 sal_uInt16 nWidth, 187 const ::rtl::OUString& rControlType ); 188 189 */ 190 } 191 192 bool StatusbarMerger::IsCorrectContext( 193 const OUString& rContext, 194 const OUString& rModuleIdentifier ) 195 { 196 return (( rContext.getLength() == 0 ) || ( rContext.indexOf( rModuleIdentifier ) >= 0 )); 197 } 198 199 bool StatusbarMerger::ConvertSeqSeqToVector( 200 const Sequence< Sequence< PropertyValue > > &rSequence, 201 AddonStatusbarItemContainer& rContainer ) 202 { 203 for ( sal_Int32 i = 0; i < rSequence.getLength(); i++ ) 204 { 205 AddonStatusbarItem aStatusBarItem; 206 lcl_ConvertSequenceToValues( rSequence[i], aStatusBarItem ); 207 rContainer.push_back( aStatusBarItem ); 208 } 209 210 return true; 211 } 212 213 sal_uInt16 StatusbarMerger::FindReferencePos( 214 StatusBar* pStatusbar, 215 const OUString& rReferencePoint ) 216 { 217 for ( sal_uInt16 nPos = 0; nPos < pStatusbar->GetItemCount(); nPos++ ) 218 { 219 const ::rtl::OUString rCmd = pStatusbar->GetItemCommand( pStatusbar->GetItemId( nPos ) ); 220 if ( rReferencePoint == rCmd ) 221 return nPos; 222 } 223 224 return STATUSBAR_ITEM_NOTFOUND; 225 } 226 227 bool StatusbarMerger::ProcessMergeOperation( 228 StatusBar* pStatusbar, 229 sal_uInt16 nPos, 230 sal_uInt16& rItemId, 231 const ::rtl::OUString& rModuleIdentifier, 232 const ::rtl::OUString& rMergeCommand, 233 const ::rtl::OUString& rMergeCommandParameter, 234 const AddonStatusbarItemContainer& rItems ) 235 { 236 if ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_ADDAFTER ) ) ) 237 return lcl_MergeItems( pStatusbar, nPos, 1, rItemId, rModuleIdentifier, rItems ); 238 else if ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_ADDBEFORE ) ) ) 239 return lcl_MergeItems( pStatusbar, nPos, 0, rItemId, rModuleIdentifier, rItems ); 240 else if ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_REPLACE ) ) ) 241 return lcl_ReplaceItem( pStatusbar, nPos, rItemId, rModuleIdentifier, rItems ); 242 else if ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_REMOVE ) ) ) 243 return lcl_RemoveItems( pStatusbar, nPos, rMergeCommandParameter ); 244 245 return false; 246 } 247 248 bool StatusbarMerger::ProcessMergeFallback( 249 StatusBar* pStatusbar, 250 sal_uInt16 /*nPos*/, 251 sal_uInt16& rItemId, 252 const ::rtl::OUString& rModuleIdentifier, 253 const ::rtl::OUString& rMergeCommand, 254 const ::rtl::OUString& rMergeFallback, 255 const AddonStatusbarItemContainer& rItems ) 256 { 257 // fallback IGNORE or REPLACE/REMOVE item not found 258 if (( rMergeFallback.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGEFALLBACK_IGNORE ))) || 259 ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_REPLACE ))) || 260 ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_REMOVE ))) ) 261 { 262 return true; 263 } 264 else if (( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_ADDBEFORE ))) || 265 ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_ADDAFTER ))) ) 266 { 267 if ( rMergeFallback.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGEFALLBACK_ADDFIRST ))) 268 return lcl_MergeItems( pStatusbar, 0, 0, rItemId, rModuleIdentifier, rItems ); 269 else if ( rMergeFallback.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGEFALLBACK_ADDLAST ))) 270 return lcl_MergeItems( pStatusbar, STATUSBAR_APPEND, 0, rItemId, rModuleIdentifier, rItems ); 271 } 272 273 return false; 274 } 275 276 277 } 278