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