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