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 "precompiled_svx.hxx" 23 24 #include "svx/sidebar/SelectionAnalyzer.hxx" 25 #include "svx/svdmrkv.hxx" 26 #include "svx/svdobj.hxx" 27 #include "svx/svdotext.hxx" 28 #include "svx/svdpage.hxx" 29 #include "svx/fmglob.hxx" 30 #include "svx/globl3d.hxx" 31 32 using sfx2::sidebar::EnumContext; 33 34 35 namespace svx { namespace sidebar { 36 37 EnumContext::Context SelectionAnalyzer::GetContextForSelection_SC (const SdrMarkList& rMarkList) 38 { 39 EnumContext::Context eContext = EnumContext::Context_Unknown; 40 41 switch (rMarkList.GetMarkCount()) 42 { 43 case 0: 44 // Empty selection. Return Context_Unknown to let the caller 45 // substitute it with the default context. 46 break; 47 48 case 1: 49 { 50 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); 51 if ( pObj->ISA(SdrTextObj) && ((SdrTextObj*)pObj)->IsInEditMode() ) 52 { 53 eContext = EnumContext::Context_DrawText; 54 } 55 else 56 { 57 const sal_uInt32 nInv = pObj->GetObjInventor(); 58 const sal_uInt16 nObjId = pObj->GetObjIdentifier(); 59 if (nInv == SdrInventor) 60 eContext = GetContextForObjectId_SC(nObjId); 61 else if (nInv == FmFormInventor) 62 eContext = EnumContext::Context_Form; 63 } 64 break; 65 } 66 67 default: 68 { 69 // Multi selection. 70 switch (GetInventorTypeFromMark(rMarkList)) 71 { 72 case SdrInventor: 73 { 74 const sal_uInt16 nObjId (GetObjectTypeFromMark(rMarkList)); 75 if (nObjId == 0) 76 eContext = EnumContext::Context_MultiObject; 77 else 78 eContext = GetContextForObjectId_SC(nObjId); 79 break; 80 } 81 82 case FmFormInventor: 83 eContext = EnumContext::Context_Form; 84 break; 85 86 case 0: 87 eContext = EnumContext::Context_MultiObject; 88 break; 89 } 90 } 91 } 92 93 return eContext; 94 } 95 96 97 98 99 EnumContext::Context SelectionAnalyzer::GetContextForSelection_SD ( 100 const SdrMarkList& rMarkList, 101 const bool bIsMasterPage, 102 const bool bIsHandoutPage, 103 const bool bIsNotesPage) 104 { 105 EnumContext::Context eContext = EnumContext::Context_Unknown; 106 107 // Note that some cases are handled by the caller. They rely on 108 // sd specific data. 109 switch (rMarkList.GetMarkCount()) 110 { 111 case 0: 112 if (bIsHandoutPage) 113 eContext = EnumContext::Context_HandoutPage; 114 else if (bIsNotesPage) 115 eContext = EnumContext::Context_NotesPage; 116 else if (bIsMasterPage) 117 eContext = EnumContext::Context_MasterPage; 118 else 119 eContext = EnumContext::Context_DrawPage; 120 break; 121 122 case 1: 123 { 124 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); 125 if (pObj->ISA(SdrTextObj) && ((SdrTextObj*)pObj)->IsInEditMode()) 126 { 127 if (pObj->GetObjIdentifier() == OBJ_TABLE) 128 { 129 // Let a table object take precedence over text 130 // edit mode. The panels for text editing are 131 // present for table context as well, anyway. 132 eContext = EnumContext::Context_Table; 133 } 134 else 135 eContext = EnumContext::Context_DrawText; 136 } 137 else 138 { 139 const sal_uInt32 nInv = pObj->GetObjInventor(); 140 sal_uInt16 nObjId = pObj->GetObjIdentifier(); 141 if (nInv == SdrInventor) 142 { 143 if (nObjId == OBJ_GRUP) 144 { 145 nObjId = GetObjectTypeFromGroup(pObj); 146 if (nObjId == 0) 147 nObjId = OBJ_GRUP; 148 } 149 eContext = GetContextForObjectId_SD(nObjId, bIsHandoutPage, bIsNotesPage); 150 } 151 else if (nInv == E3dInventor) 152 { 153 eContext = EnumContext::Context_3DObject; 154 } 155 else if (nInv == FmFormInventor) 156 { 157 eContext = EnumContext::Context_Form; 158 } 159 } 160 break; 161 } 162 163 default: 164 { 165 switch (GetInventorTypeFromMark(rMarkList)) 166 { 167 case SdrInventor: 168 { 169 const sal_uInt16 nObjId = GetObjectTypeFromMark(rMarkList); 170 if (nObjId == 0) 171 eContext = EnumContext::Context_MultiObject; 172 else 173 eContext = GetContextForObjectId_SD(nObjId, bIsHandoutPage, bIsNotesPage); 174 break; 175 } 176 177 case E3dInventor: 178 eContext = EnumContext::Context_3DObject; 179 break; 180 181 case FmFormInventor: 182 eContext = EnumContext::Context_Form; 183 break; 184 185 case 0: 186 eContext = EnumContext::Context_MultiObject; 187 break; 188 } 189 break; 190 } 191 } 192 193 return eContext; 194 } 195 196 197 198 199 EnumContext::Context SelectionAnalyzer::GetContextForObjectId_SC (const sal_uInt16 nObjectId) 200 { 201 switch (nObjectId) 202 { 203 case OBJ_CAPTION: 204 case OBJ_TITLETEXT: 205 case OBJ_OUTLINETEXT: 206 case OBJ_TEXT: 207 case OBJ_TEXTEXT: 208 case OBJ_PATHLINE: 209 case OBJ_PLIN: 210 case OBJ_FREELINE: 211 case OBJ_EDGE: 212 case OBJ_LINE: 213 case OBJ_MEASURE: 214 case OBJ_RECT: 215 case OBJ_CIRC: 216 case OBJ_FREEFILL: 217 case OBJ_PATHFILL: 218 case OBJ_POLY: 219 case OBJ_SECT: 220 case OBJ_CARC: 221 case OBJ_CCUT: 222 case OBJ_CUSTOMSHAPE: 223 case OBJ_GRUP: 224 return EnumContext::Context_Draw; 225 226 case OBJ_GRAF: 227 return EnumContext::Context_Graphic; 228 229 case OBJ_OLE2: 230 return EnumContext::Context_OLE; 231 232 case OBJ_MEDIA: 233 return EnumContext::Context_Media; 234 break; 235 236 default: 237 return EnumContext::Context_Unknown; 238 } 239 } 240 241 242 243 244 EnumContext::Context SelectionAnalyzer::GetContextForObjectId_SD ( 245 const sal_uInt16 nObjectId, 246 const bool bIsHandoutPage, 247 const bool bIsNotesPage) 248 { 249 switch (nObjectId) 250 { 251 case OBJ_CAPTION: 252 case OBJ_PATHLINE: 253 case OBJ_PLIN: 254 case OBJ_FREELINE: 255 case OBJ_EDGE: 256 case OBJ_LINE: 257 case OBJ_MEASURE: 258 case OBJ_RECT: 259 case OBJ_CIRC: 260 case OBJ_FREEFILL: 261 case OBJ_PATHFILL: 262 case OBJ_POLY: 263 case OBJ_SECT: 264 case OBJ_CARC: 265 case OBJ_CCUT: 266 case OBJ_CUSTOMSHAPE: 267 case OBJ_GRUP: 268 return EnumContext::Context_Draw; 269 270 case OBJ_TITLETEXT: 271 case OBJ_OUTLINETEXT: 272 case OBJ_TEXT: 273 case OBJ_TEXTEXT: 274 return EnumContext::Context_TextObject; 275 276 case OBJ_GRAF: 277 return EnumContext::Context_Graphic; 278 279 case OBJ_OLE2: 280 return EnumContext::Context_OLE; 281 282 case OBJ_MEDIA: 283 return EnumContext::Context_Media; 284 285 case OBJ_TABLE: 286 return EnumContext::Context_Table; 287 288 case OBJ_PAGE: 289 if (bIsHandoutPage) 290 return EnumContext::Context_HandoutPage; 291 else if (bIsNotesPage) 292 return EnumContext::Context_NotesPage; 293 else 294 return EnumContext::Context_Unknown; 295 296 default: 297 return EnumContext::Context_Unknown; 298 } 299 } 300 301 302 303 304 sal_uInt32 SelectionAnalyzer::GetInventorTypeFromMark (const SdrMarkList& rMarkList) 305 { 306 const sal_uLong nMarkCount (rMarkList.GetMarkCount()); 307 308 if (nMarkCount < 1) 309 return 0; 310 311 SdrMark* pMark = rMarkList.GetMark(0); 312 SdrObject* pObj = pMark->GetMarkedSdrObj(); 313 const sal_uInt32 nFirstInv = pObj->GetObjInventor(); 314 315 for (sal_uLong nIndex=1; nIndex<nMarkCount; ++nIndex) 316 { 317 pMark = rMarkList.GetMark(nIndex); 318 pObj = pMark->GetMarkedSdrObj(); 319 const sal_uInt32 nInv (pObj->GetObjInventor()); 320 321 if (nInv != nFirstInv) 322 return 0; 323 } 324 325 return nFirstInv; 326 } 327 328 329 330 331 sal_uInt16 SelectionAnalyzer::GetObjectTypeFromGroup (const SdrObject* pObj) 332 { 333 SdrObjList* pObjList = pObj->GetSubList(); 334 if (pObjList) 335 { 336 const sal_uLong nSubObjCount (pObjList->GetObjCount()); 337 338 if (nSubObjCount>0) 339 { 340 SdrObject* pObj = pObjList->GetObj(0); 341 sal_uInt16 nResultType = pObj->GetObjIdentifier(); 342 343 if (nResultType == OBJ_GRUP) 344 nResultType = GetObjectTypeFromGroup(pObj); 345 346 if (IsShapeType(nResultType)) 347 nResultType = OBJ_CUSTOMSHAPE; 348 349 if (IsTextObjType(nResultType)) 350 nResultType = OBJ_TEXT; 351 352 for (sal_uInt16 nIndex=1; nIndex<nSubObjCount; ++nIndex) 353 { 354 pObj = pObjList->GetObj(nIndex); 355 sal_uInt16 nType (pObj->GetObjIdentifier()); 356 357 if(nType == OBJ_GRUP) 358 nType = GetObjectTypeFromGroup(pObj); 359 360 if (IsShapeType(nType)) 361 nType = OBJ_CUSTOMSHAPE; 362 363 if ((nType == OBJ_CUSTOMSHAPE) && (nResultType == OBJ_TEXT)) 364 nType = OBJ_TEXT; 365 366 if (IsTextObjType(nType)) 367 nType = OBJ_TEXT; 368 369 if ((nType == OBJ_TEXT) && (nResultType == OBJ_CUSTOMSHAPE)) 370 nResultType = OBJ_TEXT; 371 372 if (nType != nResultType) 373 return 0; 374 } 375 376 return nResultType; 377 } 378 } 379 380 return 0; 381 } 382 383 384 385 386 sal_uInt16 SelectionAnalyzer::GetObjectTypeFromMark (const SdrMarkList& rMarkList) 387 { 388 const sal_uLong nMarkCount (rMarkList.GetMarkCount()); 389 390 if (nMarkCount < 1) 391 return 0; 392 393 SdrMark* pMark = rMarkList.GetMark(0); 394 SdrObject* pObj = pMark->GetMarkedSdrObj(); 395 sal_uInt16 nResultType = pObj->GetObjIdentifier(); 396 397 if(nResultType == OBJ_GRUP) 398 nResultType = GetObjectTypeFromGroup(pObj); 399 400 if (IsShapeType(nResultType)) 401 nResultType = OBJ_CUSTOMSHAPE; 402 403 if (IsTextObjType(nResultType)) 404 nResultType = OBJ_TEXT; 405 406 for (sal_uLong nIndex=1; nIndex<nMarkCount; ++nIndex) 407 { 408 pMark = rMarkList.GetMark(nIndex); 409 pObj = pMark->GetMarkedSdrObj(); 410 sal_uInt16 nType = pObj->GetObjIdentifier(); 411 412 if(nType == OBJ_GRUP) 413 nType = GetObjectTypeFromGroup(pObj); 414 415 if (IsShapeType(nType)) 416 nType = OBJ_CUSTOMSHAPE; 417 418 if ((nType == OBJ_CUSTOMSHAPE) && (nResultType == OBJ_TEXT)) 419 nType = OBJ_TEXT; 420 421 if (IsTextObjType(nType)) 422 nType = OBJ_TEXT; 423 424 if ((nType == OBJ_TEXT) && (nResultType == OBJ_CUSTOMSHAPE)) 425 nResultType = OBJ_TEXT; 426 427 if (nType != nResultType) 428 return 0; 429 } 430 431 return nResultType; 432 } 433 434 435 436 437 bool SelectionAnalyzer::IsShapeType (const sal_uInt16 nType) 438 { 439 switch (nType) 440 { 441 case OBJ_LINE: 442 case OBJ_CARC: 443 case OBJ_PLIN: 444 case OBJ_PATHLINE: 445 case OBJ_RECT: 446 case OBJ_CIRC: 447 case OBJ_SECT: 448 case OBJ_CCUT: 449 case OBJ_PATHFILL: 450 case OBJ_CUSTOMSHAPE: 451 case OBJ_CAPTION: 452 case OBJ_MEASURE: 453 case OBJ_EDGE: 454 case OBJ_POLY: 455 case OBJ_FREELINE: 456 case OBJ_FREEFILL: 457 458 // #122145# adding OBJ_OLE2 since these also allow line/fill style and may 459 // be multiselected/grouped with normal draw objects, e.g. math OLE objects 460 case OBJ_OLE2: 461 return true; 462 463 default: 464 return false; 465 } 466 } 467 468 469 470 471 bool SelectionAnalyzer::IsTextObjType (const sal_uInt16 nType) 472 { 473 switch(nType) 474 { 475 case OBJ_TEXT: 476 case OBJ_TEXTEXT: 477 case OBJ_TITLETEXT: 478 case OBJ_OUTLINETEXT: 479 return true; 480 481 default: 482 return false; 483 } 484 } 485 486 487 488 } } // end of namespace ::svx::sidebar 489