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                 eContext = EnumContext::Context_DrawText;
128             }
129             else
130             {
131                 const sal_uInt32 nInv = pObj->GetObjInventor();
132                 sal_uInt16 nObjId = pObj->GetObjIdentifier();
133                 if (nInv == SdrInventor)
134                 {
135                     if (nObjId == OBJ_GRUP)
136                     {
137                         nObjId = GetObjectTypeFromGroup(pObj);
138                         if (nObjId == 0)
139                             nObjId = OBJ_GRUP;
140                     }
141                     eContext = GetContextForObjectId_SD(nObjId, bIsHandoutPage, bIsNotesPage);
142                 }
143                 else if (nInv == E3dInventor)
144                 {
145                     eContext = EnumContext::Context_3DObject;
146                 }
147                 else if (nInv == FmFormInventor)
148                 {
149                     eContext = EnumContext::Context_Form;
150                 }
151             }
152             break;
153         }
154 
155         default:
156         {
157             switch (GetInventorTypeFromMark(rMarkList))
158             {
159                 case SdrInventor:
160                 {
161                     const sal_uInt16 nObjId = GetObjectTypeFromMark(rMarkList);
162                     if (nObjId == 0)
163                         eContext = EnumContext::Context_MultiObject;
164                     else
165                         eContext = GetContextForObjectId_SD(nObjId, bIsHandoutPage, bIsNotesPage);
166                     break;
167                 }
168 
169                 case E3dInventor:
170                     eContext = EnumContext::Context_3DObject;
171                     break;
172 
173                 case FmFormInventor:
174                     eContext = EnumContext::Context_Form;
175                     break;
176 
177                 case 0:
178                     eContext = EnumContext::Context_MultiObject;
179                     break;
180             }
181             break;
182         }
183     }
184 
185 	return eContext;
186 }
187 
188 
189 
190 
191 EnumContext::Context SelectionAnalyzer::GetContextForObjectId_SC (const sal_uInt16 nObjectId)
192 {
193     switch (nObjectId)
194     {
195         case OBJ_CAPTION:
196         case OBJ_TITLETEXT:
197         case OBJ_OUTLINETEXT:
198         case OBJ_TEXT:
199         case OBJ_TEXTEXT:
200         case OBJ_PATHLINE:
201         case OBJ_PLIN:
202         case OBJ_FREELINE:
203         case OBJ_EDGE:
204         case OBJ_LINE:
205         case OBJ_MEASURE:
206         case OBJ_RECT:
207         case OBJ_CIRC:
208         case OBJ_FREEFILL:
209         case OBJ_PATHFILL:
210         case OBJ_POLY:
211         case OBJ_SECT:
212         case OBJ_CARC:
213         case OBJ_CCUT:
214         case OBJ_CUSTOMSHAPE:
215         case OBJ_GRUP:
216             return EnumContext::Context_Draw;
217 
218         case OBJ_GRAF:
219             return EnumContext::Context_Graphic;
220 
221         case OBJ_OLE2:
222             return EnumContext::Context_OLE;
223 
224         case OBJ_MEDIA:
225             return EnumContext::Context_Media;
226             break;
227 
228         default:
229             return EnumContext::Context_Unknown;
230     }
231 }
232 
233 
234 
235 
236 EnumContext::Context SelectionAnalyzer::GetContextForObjectId_SD (
237     const sal_uInt16 nObjectId,
238     const bool bIsHandoutPage,
239     const bool bIsNotesPage)
240 {
241 	switch (nObjectId)
242 	{
243 		case OBJ_CAPTION:
244 		case OBJ_PATHLINE:
245 		case OBJ_PLIN:
246 		case OBJ_FREELINE:
247 		case OBJ_EDGE:
248 		case OBJ_LINE:
249 		case OBJ_MEASURE:
250 		case OBJ_RECT:
251 		case OBJ_CIRC:
252 		case OBJ_FREEFILL:
253 		case OBJ_PATHFILL:
254 		case OBJ_POLY:
255 		case OBJ_SECT:
256 		case OBJ_CARC:
257 		case OBJ_CCUT:
258 		case OBJ_CUSTOMSHAPE:
259 		case OBJ_GRUP:
260 			return EnumContext::Context_Draw;
261 
262 		case OBJ_TITLETEXT:
263 		case OBJ_OUTLINETEXT:
264 		case OBJ_TEXT:
265 		case OBJ_TEXTEXT:
266 			return EnumContext::Context_TextObject;
267 
268 		case OBJ_GRAF:
269 			return EnumContext::Context_Graphic;
270 
271 		case OBJ_OLE2:
272 			return EnumContext::Context_OLE;
273 
274 		case OBJ_MEDIA:
275 			return EnumContext::Context_Media;
276 
277 		case OBJ_TABLE:
278 			return EnumContext::Context_Table;
279 
280 		case OBJ_PAGE:
281             if (bIsHandoutPage)
282 				return EnumContext::Context_HandoutPage;
283             else if (bIsNotesPage)
284 				return EnumContext::Context_NotesPage;
285 			else
286                 return EnumContext::Context_Unknown;
287 
288         default:
289             return EnumContext::Context_Unknown;
290 	}
291 }
292 
293 
294 
295 
296 sal_uInt32 SelectionAnalyzer::GetInventorTypeFromMark (const SdrMarkList& rMarkList)
297 {
298     const sal_uLong nMarkCount (rMarkList.GetMarkCount());
299 
300     if (nMarkCount < 1)
301         return 0;
302 
303     SdrMark* pMark = rMarkList.GetMark(0);
304     SdrObject* pObj = pMark->GetMarkedSdrObj();
305     const sal_uInt32 nFirstInv = pObj->GetObjInventor();
306 
307     for (sal_uLong nIndex=1; nIndex<nMarkCount; ++nIndex)
308     {
309         pMark = rMarkList.GetMark(nIndex);
310         pObj = pMark->GetMarkedSdrObj();
311         const sal_uInt32 nInv (pObj->GetObjInventor());
312 
313         if (nInv != nFirstInv)
314             return 0;
315     }
316 
317     return nFirstInv;
318 }
319 
320 
321 
322 
323 sal_uInt16 SelectionAnalyzer::GetObjectTypeFromGroup (const SdrObject* pObj)
324 {
325     SdrObjList* pObjList = pObj->GetSubList();
326     if (pObjList)
327     {
328         const sal_uLong nSubObjCount (pObjList->GetObjCount());
329 
330         if (nSubObjCount>0)
331         {
332             SdrObject* pObj = pObjList->GetObj(0);
333             sal_uInt16 nResultType = pObj->GetObjIdentifier();
334 
335             if (nResultType == OBJ_GRUP)
336                 nResultType = GetObjectTypeFromGroup(pObj);
337 
338             if (IsShapeType(nResultType))
339                 nResultType = OBJ_CUSTOMSHAPE;
340 
341             if (IsTextObjType(nResultType))
342                 nResultType = OBJ_TEXT;
343 
344             for (sal_uInt16 nIndex=1; nIndex<nSubObjCount; ++nIndex)
345             {
346                 pObj = pObjList->GetObj(nIndex);
347                 sal_uInt16 nType (pObj->GetObjIdentifier());
348 
349                 if(nType == OBJ_GRUP)
350                     nType = GetObjectTypeFromGroup(pObj);
351 
352                 if (IsShapeType(nType))
353                     nType = OBJ_CUSTOMSHAPE;
354 
355                 if ((nType == OBJ_CUSTOMSHAPE) && (nResultType == OBJ_TEXT))
356                     nType = OBJ_TEXT;
357 
358                 if (IsTextObjType(nType))
359                     nType = OBJ_TEXT;
360 
361                 if ((nType == OBJ_TEXT) && (nResultType == OBJ_CUSTOMSHAPE))
362                     nResultType = OBJ_TEXT;
363 
364                 if (nType != nResultType)
365                     return 0;
366             }
367 
368             return nResultType;
369         }
370     }
371 
372     return 0;
373 }
374 
375 
376 
377 
378 sal_uInt16  SelectionAnalyzer::GetObjectTypeFromMark (const SdrMarkList& rMarkList)
379 {
380     const sal_uLong nMarkCount (rMarkList.GetMarkCount());
381 
382     if (nMarkCount < 1)
383         return 0;
384 
385     SdrMark* pMark = rMarkList.GetMark(0);
386     SdrObject* pObj = pMark->GetMarkedSdrObj();
387     sal_uInt16 nResultType = pObj->GetObjIdentifier();
388 
389     if(nResultType == OBJ_GRUP)
390         nResultType = GetObjectTypeFromGroup(pObj);
391 
392     if (IsShapeType(nResultType))
393         nResultType = OBJ_CUSTOMSHAPE;
394 
395     if (IsTextObjType(nResultType))
396         nResultType = OBJ_TEXT;
397 
398     for (sal_uLong nIndex=1; nIndex<nMarkCount; ++nIndex)
399     {
400         pMark = rMarkList.GetMark(nIndex);
401         pObj = pMark->GetMarkedSdrObj();
402         sal_uInt16 nType = pObj->GetObjIdentifier();
403 
404         if(nType == OBJ_GRUP)
405             nType = GetObjectTypeFromGroup(pObj);
406 
407         if (IsShapeType(nType))
408             nType = OBJ_CUSTOMSHAPE;
409 
410         if ((nType == OBJ_CUSTOMSHAPE) && (nResultType == OBJ_TEXT))
411             nType = OBJ_TEXT;
412 
413         if (IsTextObjType(nType))
414             nType = OBJ_TEXT;
415 
416         if ((nType == OBJ_TEXT) && (nResultType == OBJ_CUSTOMSHAPE))
417             nResultType = OBJ_TEXT;
418 
419         if (nType != nResultType)
420             return 0;
421     }
422 
423     return nResultType;
424 }
425 
426 
427 
428 
429 bool SelectionAnalyzer::IsShapeType (const sal_uInt16 nType)
430 {
431 	switch (nType)
432     {
433 		case OBJ_LINE:
434 		case OBJ_CARC:
435 		case OBJ_PLIN:
436 		case OBJ_PATHLINE:
437 		case OBJ_RECT:
438 		case OBJ_CIRC:
439 		case OBJ_SECT:
440 		case OBJ_CCUT:
441 		case OBJ_PATHFILL:
442 		case OBJ_CUSTOMSHAPE:
443 		case OBJ_CAPTION:
444 		case OBJ_MEASURE:
445 		case OBJ_EDGE:
446 		case OBJ_POLY:
447 		case OBJ_FREELINE:
448 		case OBJ_FREEFILL:
449 			return true;
450 
451 		default:
452             return false;
453 	}
454 }
455 
456 
457 
458 
459 bool SelectionAnalyzer::IsTextObjType (const sal_uInt16 nType)
460 {
461 	switch(nType)
462     {
463 		case OBJ_TEXT:
464 		case OBJ_TEXTEXT:
465 		case OBJ_TITLETEXT:
466 		case OBJ_OUTLINETEXT:
467 			return true;
468 
469 		default:
470             return false;
471 	}
472 }
473 
474 
475 
476 } } // end of namespace ::svx::sidebar
477