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