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 #include <uielement/statusbarmerger.hxx> 23 24 using rtl::OUString; 25 using com::sun::star::frame::XFrame; 26 using com::sun::star::uno::Reference; 27 using com::sun::star::beans::PropertyValue; 28 using com::sun::star::uno::Sequence; 29 30 namespace framework 31 { 32 namespace { 33 34 static const char MERGE_STATUSBAR_URL[] = "URL"; 35 static const char MERGE_STATUSBAR_TITLE[] = "Title"; 36 static const char MERGE_STATUSBAR_CONTEXT[] = "Context"; 37 static const char MERGE_STATUSBAR_ALIGN[] = "Alignment"; 38 static const char MERGE_STATUSBAR_AUTOSIZE[] = "AutoSize"; 39 static const char MERGE_STATUSBAR_OWNERDRAW[] = "OwnerDraw"; 40 static const char MERGE_STATUSBAR_WIDTH[] = "Width"; 41 42 static const char STATUSBAR_ALIGN_LEFT[] = "left"; 43 static const char STATUSBAR_ALIGN_CENTER[] = "center"; 44 static const char STATUSBAR_ALIGN_RIGHT[] = "right"; 45 46 static const char MERGECOMMAND_ADDAFTER[] = "AddAfter"; 47 static const char MERGECOMMAND_ADDBEFORE[] = "AddBefore"; 48 static const char MERGECOMMAND_REPLACE[] = "Replace"; 49 static const char MERGECOMMAND_REMOVE[] = "Remove"; 50 51 static const char MERGEFALLBACK_ADDLAST[] = "AddLast"; 52 static const char MERGEFALLBACK_ADDFIRST[] = "AddFirst"; 53 static const char MERGEFALLBACK_IGNORE[] = "Ignore"; 54 55 56 static void lcl_ConvertSequenceToValues( 57 const Sequence< PropertyValue > &rSequence, 58 AddonStatusbarItem &rItem ) 59 { 60 OUString sAlignment; 61 sal_Bool bAutoSize = sal_False; 62 sal_Bool bOwnerDraw = sal_False; 63 64 PropertyValue aPropVal; 65 for ( sal_Int32 i = 0; i < rSequence.getLength(); i++ ) 66 { 67 aPropVal = rSequence[i]; 68 if ( aPropVal.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGE_STATUSBAR_URL ) ) ) 69 aPropVal.Value >>= rItem.aCommandURL; 70 else if ( aPropVal.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGE_STATUSBAR_TITLE ) ) ) 71 aPropVal.Value >>= rItem.aLabel; 72 else if ( aPropVal.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGE_STATUSBAR_CONTEXT ) ) ) 73 aPropVal.Value >>= rItem.aContext; 74 else if ( aPropVal.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGE_STATUSBAR_ALIGN ) ) ) 75 aPropVal.Value >>= sAlignment; 76 else if ( aPropVal.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGE_STATUSBAR_AUTOSIZE ) ) ) 77 aPropVal.Value >>= bAutoSize; 78 else if ( aPropVal.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGE_STATUSBAR_OWNERDRAW ) ) ) 79 aPropVal.Value >>= bOwnerDraw; 80 else if ( aPropVal.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGE_STATUSBAR_WIDTH ) ) ) 81 { 82 sal_Int32 aWidth = 0; 83 aPropVal.Value >>= aWidth; 84 rItem.nWidth = sal_uInt16( aWidth ); 85 } 86 } 87 88 sal_uInt16 nItemBits(0); 89 if ( bAutoSize ) 90 nItemBits |= SIB_AUTOSIZE; 91 if ( bOwnerDraw ) 92 nItemBits |= SIB_USERDRAW; 93 if ( sAlignment.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( STATUSBAR_ALIGN_CENTER ))) 94 nItemBits |= SIB_CENTER; 95 else if ( sAlignment.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( STATUSBAR_ALIGN_RIGHT ))) 96 nItemBits |= SIB_RIGHT; 97 else 98 // if unset, defaults to left alignment 99 nItemBits |= SIB_LEFT; 100 rItem.nItemBits = nItemBits; 101 } 102 103 static void lcl_CreateStatusbarItem( StatusBar* pStatusbar, 104 sal_uInt16 nPos, 105 sal_uInt16 nItemId, 106 const AddonStatusbarItem& rAddonItem ) 107 { 108 pStatusbar->InsertItem( nItemId, 109 rAddonItem.nWidth, 110 rAddonItem.nItemBits, 111 STATUSBAR_OFFSET, 112 nPos ); 113 pStatusbar->SetItemCommand( nItemId, rAddonItem.aCommandURL ); 114 pStatusbar->SetQuickHelpText( nItemId, rAddonItem.aLabel ); 115 pStatusbar->SetAccessibleName( nItemId, rAddonItem.aLabel ); 116 117 // add-on specific data 118 AddonStatusbarItemData *pUserData = new AddonStatusbarItemData; 119 pUserData->aLabel = rAddonItem.aLabel; 120 pUserData->nItemBits = rAddonItem.nItemBits; 121 pStatusbar->SetItemData( nItemId, pUserData ); 122 } 123 124 static bool lcl_MergeItems( StatusBar* pStatusbar, 125 sal_uInt16 nPos, 126 sal_uInt16 nModIndex, 127 sal_uInt16& rItemId, 128 const ::rtl::OUString& rModuleIdentifier, 129 const AddonStatusbarItemContainer& rAddonItems ) 130 { 131 const sal_uInt16 nSize( rAddonItems.size() ); 132 for ( sal_Int32 i = 0; i < nSize; i++ ) 133 { 134 const AddonStatusbarItem& rItem = rAddonItems[i]; 135 if ( !StatusbarMerger::IsCorrectContext( rItem.aContext, rModuleIdentifier ) ) 136 continue; 137 138 sal_uInt16 nInsPos = nPos + nModIndex + i; 139 if ( nInsPos > pStatusbar->GetItemCount() ) 140 nInsPos = STATUSBAR_APPEND; 141 142 lcl_CreateStatusbarItem( pStatusbar, nInsPos, rItemId, rItem ); 143 ++rItemId; 144 } 145 146 return true; 147 } 148 149 static bool lcl_ReplaceItem( StatusBar* pStatusbar, 150 sal_uInt16 nPos, 151 sal_uInt16& rItemId, 152 const ::rtl::OUString& rModuleIdentifier, 153 const AddonStatusbarItemContainer& rAddonToolbarItems ) 154 { 155 pStatusbar->RemoveItem( pStatusbar->GetItemId( nPos ) ); 156 return lcl_MergeItems( pStatusbar, nPos, 0, rItemId, rModuleIdentifier, rAddonToolbarItems ); 157 } 158 159 static bool lcl_RemoveItems( StatusBar* pStatusbar, 160 sal_uInt16 nPos, 161 const ::rtl::OUString& rMergeCommandParameter ) 162 { 163 sal_Int32 nCount = rMergeCommandParameter.toInt32(); 164 if ( nCount > 0 ) 165 { 166 for ( sal_Int32 i = 0; i < nCount; i++ ) 167 { 168 if ( nPos < pStatusbar->GetItemCount() ) 169 pStatusbar->RemoveItem( nPos ); 170 } 171 } 172 return true; 173 } 174 175 /* 176 static ::cppu::OWeakObject* CreateController( 177 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xSMGR, 178 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame, 179 StatusBar* pStatusbar, 180 const ::rtl::OUString& rCommandURL, 181 sal_uInt16 nId, 182 sal_uInt16 nWidth, 183 const ::rtl::OUString& rControlType ); 184 185 */ 186 } 187 188 bool StatusbarMerger::IsCorrectContext( 189 const OUString& rContext, 190 const OUString& rModuleIdentifier ) 191 { 192 return (( rContext.getLength() == 0 ) || ( rContext.indexOf( rModuleIdentifier ) >= 0 )); 193 } 194 195 bool StatusbarMerger::ConvertSeqSeqToVector( 196 const Sequence< Sequence< PropertyValue > > &rSequence, 197 AddonStatusbarItemContainer& rContainer ) 198 { 199 for ( sal_Int32 i = 0; i < rSequence.getLength(); i++ ) 200 { 201 AddonStatusbarItem aStatusBarItem; 202 lcl_ConvertSequenceToValues( rSequence[i], aStatusBarItem ); 203 rContainer.push_back( aStatusBarItem ); 204 } 205 206 return true; 207 } 208 209 sal_uInt16 StatusbarMerger::FindReferencePos( 210 StatusBar* pStatusbar, 211 const OUString& rReferencePoint ) 212 { 213 for ( sal_uInt16 nPos = 0; nPos < pStatusbar->GetItemCount(); nPos++ ) 214 { 215 const ::rtl::OUString rCmd = pStatusbar->GetItemCommand( pStatusbar->GetItemId( nPos ) ); 216 if ( rReferencePoint == rCmd ) 217 return nPos; 218 } 219 220 return STATUSBAR_ITEM_NOTFOUND; 221 } 222 223 bool StatusbarMerger::ProcessMergeOperation( 224 StatusBar* pStatusbar, 225 sal_uInt16 nPos, 226 sal_uInt16& rItemId, 227 const ::rtl::OUString& rModuleIdentifier, 228 const ::rtl::OUString& rMergeCommand, 229 const ::rtl::OUString& rMergeCommandParameter, 230 const AddonStatusbarItemContainer& rItems ) 231 { 232 if ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_ADDAFTER ) ) ) 233 return lcl_MergeItems( pStatusbar, nPos, 1, rItemId, rModuleIdentifier, rItems ); 234 else if ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_ADDBEFORE ) ) ) 235 return lcl_MergeItems( pStatusbar, nPos, 0, rItemId, rModuleIdentifier, rItems ); 236 else if ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_REPLACE ) ) ) 237 return lcl_ReplaceItem( pStatusbar, nPos, rItemId, rModuleIdentifier, rItems ); 238 else if ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_REMOVE ) ) ) 239 return lcl_RemoveItems( pStatusbar, nPos, rMergeCommandParameter ); 240 241 return false; 242 } 243 244 bool StatusbarMerger::ProcessMergeFallback( 245 StatusBar* pStatusbar, 246 sal_uInt16 /*nPos*/, 247 sal_uInt16& rItemId, 248 const ::rtl::OUString& rModuleIdentifier, 249 const ::rtl::OUString& rMergeCommand, 250 const ::rtl::OUString& rMergeFallback, 251 const AddonStatusbarItemContainer& rItems ) 252 { 253 // fallback IGNORE or REPLACE/REMOVE item not found 254 if (( rMergeFallback.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGEFALLBACK_IGNORE ))) || 255 ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_REPLACE ))) || 256 ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_REMOVE ))) ) 257 { 258 return true; 259 } 260 else if (( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_ADDBEFORE ))) || 261 ( rMergeCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGECOMMAND_ADDAFTER ))) ) 262 { 263 if ( rMergeFallback.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGEFALLBACK_ADDFIRST ))) 264 return lcl_MergeItems( pStatusbar, 0, 0, rItemId, rModuleIdentifier, rItems ); 265 else if ( rMergeFallback.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MERGEFALLBACK_ADDLAST ))) 266 return lcl_MergeItems( pStatusbar, STATUSBAR_APPEND, 0, rItemId, rModuleIdentifier, rItems ); 267 } 268 269 return false; 270 } 271 272 273 } 274