/src/libreoffice/sw/source/uibase/shells/drwbassh.cxx
Line | Count | Source |
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 <hintids.hxx> |
21 | | #include <swtypes.hxx> |
22 | | #include <sfx2/objface.hxx> |
23 | | #include <sfx2/request.hxx> |
24 | | #include <sfx2/bindings.hxx> |
25 | | #include <sfx2/viewfrm.hxx> |
26 | | #include <svx/svdview.hxx> |
27 | | #include <svl/whiter.hxx> |
28 | | #include <svx/swframevalidation.hxx> |
29 | | #include <svx/anchorid.hxx> |
30 | | #include <svx/hlnkitem.hxx> |
31 | | #include <osl/diagnose.h> |
32 | | #include <drawdoc.hxx> |
33 | | #include <uitool.hxx> |
34 | | #include <fmtornt.hxx> |
35 | | #include <cmdid.h> |
36 | | #include <swmodule.hxx> |
37 | | #include <wrtsh.hxx> |
38 | | #include <wview.hxx> |
39 | | #include <edtwin.hxx> |
40 | | #include <viewopt.hxx> |
41 | | #include <dcontact.hxx> |
42 | | #include <frmfmt.hxx> |
43 | | #include <drawbase.hxx> |
44 | | #include <drwbassh.hxx> |
45 | | #include <swdtflvr.hxx> |
46 | | #include <svx/svditer.hxx> |
47 | | #define ShellClass_SwDrawBaseShell |
48 | | #include <sfx2/msg.hxx> |
49 | | #include <swslots.hxx> |
50 | | #include <svx/svxdlg.hxx> |
51 | | #include <svx/svdogrp.hxx> |
52 | | #include <vcl/unohelp2.hxx> |
53 | | #include <swabstdlg.hxx> |
54 | | #include <swundo.hxx> |
55 | | #include <com/sun/star/text/HoriOrientation.hpp> |
56 | | #include <com/sun/star/text/VertOrientation.hpp> |
57 | | #include <com/sun/star/text/RelOrientation.hpp> |
58 | | #include <com/sun/star/uno/Reference.hxx> |
59 | | #include <IDocumentDrawModelAccess.hxx> |
60 | | #include <fmtfollowtextflow.hxx> |
61 | | #include <textboxhelper.hxx> |
62 | | #include <svx/diagram/DiagramHelper_svx.hxx> |
63 | | #include <svl/grabbagitem.hxx> |
64 | | #include <IDocumentSettingAccess.hxx> |
65 | | |
66 | | using namespace ::com::sun::star; |
67 | | using namespace css::beans; |
68 | | using namespace css::uno; |
69 | | |
70 | | SFX_IMPL_SUPERCLASS_INTERFACE(SwDrawBaseShell, SwBaseShell) |
71 | | |
72 | | void SwDrawBaseShell::InitInterface_Impl() |
73 | 9 | { |
74 | 9 | } |
75 | | |
76 | | |
77 | | SwDrawBaseShell::SwDrawBaseShell(SwView &_rView) |
78 | 0 | : SwBaseShell(_rView) |
79 | 0 | { |
80 | 0 | GetShell().NoEdit(); |
81 | |
|
82 | 0 | SwEditWin& rWin = GetView().GetEditWin(); |
83 | |
|
84 | 0 | rWin.SetBezierMode(SID_BEZIER_MOVE); |
85 | |
|
86 | 0 | if ( !_rView.GetDrawFuncPtr() ) |
87 | 0 | _rView.GetEditWin().StdDrawMode( SdrObjKind::NONE, true ); |
88 | |
|
89 | 0 | SwTransferable::CreateSelection( GetShell() ); |
90 | 0 | } |
91 | | |
92 | | SwDrawBaseShell::~SwDrawBaseShell() |
93 | 0 | { |
94 | 0 | GetView().ExitDraw(); |
95 | 0 | GetShell().Edit(); |
96 | 0 | SwTransferable::ClearSelection( GetShell() ); |
97 | 0 | } |
98 | | |
99 | | void SwDrawBaseShell::Execute(SfxRequest& rReq) |
100 | 0 | { |
101 | 0 | SwWrtShell *pSh = &GetShell(); |
102 | 0 | SdrView* pSdrView = pSh->GetDrawView(); |
103 | 0 | const SfxItemSet *pArgs = rReq.GetArgs(); |
104 | 0 | sal_uInt16 nSlotId = rReq.GetSlot(); |
105 | 0 | bool bChanged = pSdrView->GetModel().IsChanged(); |
106 | 0 | pSdrView->GetModel().SetChanged(false); |
107 | 0 | const SfxPoolItem* pItem = nullptr; |
108 | 0 | if(pArgs) |
109 | 0 | pArgs->GetItemState(nSlotId, false, &pItem); |
110 | |
|
111 | 0 | bool bAlignPossible = pSh->IsAlignPossible(); |
112 | |
|
113 | 0 | bool bTopParam = true, bBottomParam = true; |
114 | 0 | bool bDone = false; |
115 | 0 | SfxBindings& rBind = GetView().GetViewFrame().GetBindings(); |
116 | |
|
117 | 0 | switch (nSlotId) |
118 | 0 | { |
119 | 0 | case FN_DRAW_WRAP_DLG: |
120 | 0 | { |
121 | 0 | if(pSdrView->GetMarkedObjectList().GetMarkCount() != 0) |
122 | 0 | { |
123 | 0 | if(!pArgs) |
124 | 0 | { |
125 | 0 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); |
126 | 0 | if( rMarkList.GetMark(0) != nullptr ) |
127 | 0 | { |
128 | 0 | SfxItemSet aSet(SfxItemSet::makeFixedSfxItemSet< |
129 | 0 | RES_LR_SPACE, RES_UL_SPACE, |
130 | 0 | RES_SURROUND, RES_SURROUND, |
131 | 0 | RES_ANCHOR, RES_ANCHOR, |
132 | 0 | RES_WRAP_INFLUENCE_ON_OBJPOS, RES_WRAP_INFLUENCE_ON_OBJPOS, |
133 | 0 | SID_HTML_MODE, SID_HTML_MODE, |
134 | 0 | FN_DRAW_WRAP_DLG, FN_DRAW_WRAP_DLG>( GetPool() )); |
135 | |
|
136 | 0 | aSet.Put(SfxBoolItem(SID_HTML_MODE, |
137 | 0 | 0 != ::GetHtmlMode(pSh->GetView().GetDocShell()))); |
138 | |
|
139 | 0 | aSet.Put(SfxInt16Item(FN_DRAW_WRAP_DLG, pSh->GetLayerId().get())); |
140 | |
|
141 | 0 | pSh->GetObjAttr(aSet); |
142 | |
|
143 | 0 | auto xRequest = std::make_shared<SfxRequest>(rReq); |
144 | 0 | rReq.Ignore(); // the 'old' request is not relevant any more |
145 | 0 | SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); |
146 | 0 | VclPtr<SfxAbstractDialog> pDlg(pFact->CreateSwWrapDlg(GetView().GetFrameWeld(), aSet, pSh)); |
147 | 0 | pDlg->StartExecuteAsync( |
148 | 0 | [pDlg, pSh, xRequest=std::move(xRequest)] (sal_Int32 nResult)->void |
149 | 0 | { |
150 | 0 | if (nResult == RET_OK) |
151 | 0 | { |
152 | 0 | const SfxItemSet* pOutSet = pDlg->GetOutputItemSet(); |
153 | 0 | if(const SfxInt16Item* pWrapItem = pOutSet->GetItemIfSet(FN_DRAW_WRAP_DLG, false)) |
154 | 0 | { |
155 | 0 | short nLayer = pWrapItem->GetValue(); |
156 | 0 | if (nLayer == 1) |
157 | 0 | pSh->SelectionToHeaven(); |
158 | 0 | else |
159 | 0 | pSh->SelectionToHell(); |
160 | 0 | } |
161 | |
|
162 | 0 | pSh->SetObjAttr(*pOutSet); |
163 | 0 | } |
164 | 0 | pDlg->disposeOnce(); |
165 | 0 | xRequest->Done(); |
166 | 0 | } |
167 | 0 | ); |
168 | 0 | } |
169 | 0 | } |
170 | 0 | } |
171 | 0 | } |
172 | 0 | break; |
173 | | |
174 | 0 | case SID_ATTR_TRANSFORM: |
175 | 0 | { |
176 | 0 | if(pSdrView->GetMarkedObjectList().GetMarkCount() != 0) |
177 | 0 | { |
178 | 0 | if(!pArgs) |
179 | 0 | { |
180 | 0 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); |
181 | 0 | if( rMarkList.GetMark(0) != nullptr ) |
182 | 0 | { |
183 | 0 | SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); |
184 | 0 | VclPtr<SfxAbstractTabDialog> pDlg; |
185 | 0 | bool bCaption = false; |
186 | | |
187 | | // Allowed anchorages: |
188 | 0 | RndStdIds nAnchor = pSh->GetAnchorId(); |
189 | 0 | SvxAnchorIds nAllowedAnchors = SvxAnchorIds::Paragraph | SvxAnchorIds::Character | SvxAnchorIds::Page; |
190 | 0 | sal_uInt16 nHtmlMode = ::GetHtmlMode(pSh->GetView().GetDocShell()); |
191 | |
|
192 | 0 | if ( pSh->IsFlyInFly() ) |
193 | 0 | nAllowedAnchors |= SvxAnchorIds::Fly; |
194 | |
|
195 | 0 | if (pObj->GetObjIdentifier() == SdrObjKind::Caption ) |
196 | 0 | bCaption = true; |
197 | |
|
198 | 0 | if (bCaption) |
199 | 0 | { |
200 | 0 | SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); |
201 | 0 | VclPtr<AbstractSvxCaptionDialog> pCaptionDlg = |
202 | 0 | pFact->CreateCaptionDialog( rReq.GetFrameWeld(), pSdrView, nAllowedAnchors ); |
203 | 0 | pDlg.reset(pCaptionDlg); |
204 | 0 | pCaptionDlg->SetValidateFramePosLink( LINK(this, SwDrawBaseShell, ValidatePosition) ); |
205 | 0 | } |
206 | 0 | else |
207 | 0 | { |
208 | 0 | SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); |
209 | 0 | VclPtr<AbstractSvxTransformTabDialog> pTransform = |
210 | 0 | pFact->CreateSvxTransformTabDialog(rReq.GetFrameWeld(), nullptr, pSdrView, nAllowedAnchors); |
211 | 0 | pDlg.reset(pTransform); |
212 | 0 | pTransform->SetValidateFramePosLink( LINK(this, SwDrawBaseShell, ValidatePosition) ); |
213 | 0 | } |
214 | 0 | SfxItemSet aNewAttr(pSdrView->GetGeoAttrFromMarked()); |
215 | |
|
216 | 0 | SfxItemSet aSet(*aNewAttr.GetPool(), pDlg->GetInputRanges(*aNewAttr.GetPool())); |
217 | 0 | FieldUnit eMetric = ::GetDfltMetric( dynamic_cast<SwWebView*>(&GetView()) != nullptr ); |
218 | 0 | SwModule::get()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)) ); |
219 | |
|
220 | 0 | aSet.Put( aNewAttr, false ); |
221 | |
|
222 | 0 | if (bCaption) |
223 | 0 | pSdrView->GetAttributes( aSet ); |
224 | |
|
225 | 0 | aSet.Put(SfxInt16Item(SID_ATTR_TRANSFORM_ANCHOR, static_cast<sal_Int16>(nAnchor))); |
226 | 0 | bool bRTL; |
227 | 0 | bool bVertL2R; |
228 | 0 | aSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_IN_VERTICAL_TEXT, pSh->IsFrameVertical(true, bRTL, bVertL2R))); |
229 | 0 | aSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_IN_RTL_TEXT, bRTL)); |
230 | |
|
231 | 0 | SwFrameFormat* pFrameFormat = FindFrameFormat( pObj ); |
232 | |
|
233 | 0 | aSet.Put( pFrameFormat->GetFormatAttr(RES_FOLLOW_TEXT_FLOW) ); |
234 | |
|
235 | 0 | SwFormatVertOrient aVOrient(pFrameFormat->GetFormatAttr(RES_VERT_ORIENT)); |
236 | 0 | aSet.Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_ORIENT, aVOrient.GetVertOrient())); |
237 | 0 | aSet.Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_RELATION, aVOrient.GetRelationOrient() )); |
238 | 0 | aSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_VERT_POSITION, aVOrient.GetPos())); |
239 | |
|
240 | 0 | SwFormatHoriOrient aHOrient(pFrameFormat->GetFormatAttr(RES_HORI_ORIENT)); |
241 | 0 | aSet.Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_ORIENT, aHOrient.GetHoriOrient())); |
242 | 0 | aSet.Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_RELATION, aHOrient.GetRelationOrient() )); |
243 | 0 | aSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_HORI_MIRROR, aHOrient.IsPosToggle())); |
244 | 0 | aSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_HORI_POSITION, aHOrient.GetPos())); |
245 | |
|
246 | 0 | const IDocumentSettingAccess& rIDSA = pFrameFormat->getIDocumentSettingAccess(); |
247 | 0 | if (rIDSA.get(DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS)) |
248 | 0 | { |
249 | 0 | SfxGrabBagItem aItem(RES_CHRATR_GRABBAG, |
250 | 0 | std::map<OUString, css::uno::Any>{ |
251 | 0 | { u"DoNotMirrorRtlDrawObjs"_ustr, uno::Any(true) } } ); |
252 | 0 | aSet.Put(aItem); |
253 | 0 | } |
254 | |
|
255 | 0 | aSet.Put(SfxUInt16Item(SID_HTML_MODE, nHtmlMode)); |
256 | |
|
257 | 0 | pDlg->SetInputSet( &aSet ); |
258 | |
|
259 | 0 | pDlg->StartExecuteAsync([bCaption, bChanged, pDlg, pFrameFormat, pSdrView, |
260 | 0 | pSh, &rMarkList, this]( |
261 | 0 | sal_Int32 nResult){ |
262 | 0 | pSdrView->GetModel().SetChanged(false); |
263 | |
|
264 | 0 | if (nResult == RET_OK) |
265 | 0 | { |
266 | 0 | SwFormatVertOrient aVOrientFinal(pFrameFormat->GetFormatAttr(RES_VERT_ORIENT)); |
267 | 0 | SwFormatHoriOrient aHOrientFinal(pFrameFormat->GetFormatAttr(RES_HORI_ORIENT)); |
268 | |
|
269 | 0 | const SfxItemSet* pOutSet = pDlg->GetOutputItemSet(); |
270 | 0 | pSh->StartAllAction(); |
271 | | |
272 | | // #i30451# |
273 | 0 | pSh->StartUndo(SwUndoId::INSFMTATTR); |
274 | |
|
275 | 0 | pSdrView->SetGeoAttrToMarked(*pOutSet); |
276 | |
|
277 | 0 | if (bCaption) |
278 | 0 | pSdrView->SetAttributes(*pOutSet); |
279 | |
|
280 | 0 | bool bPosCorr = |
281 | 0 | SfxItemState::SET != pOutSet->GetItemState( |
282 | 0 | SID_ATTR_TRANSFORM_POS_X, false ) && |
283 | 0 | SfxItemState::SET != pOutSet->GetItemState( |
284 | 0 | SID_ATTR_TRANSFORM_POS_Y, false ); |
285 | |
|
286 | 0 | SfxItemSet aFrameAttrSet(SfxItemSet::makeFixedSfxItemSet<RES_FRMATR_BEGIN, RES_FRMATR_END - 1>(GetPool())); |
287 | |
|
288 | 0 | bool bSingleSelection = rMarkList.GetMarkCount() == 1; |
289 | |
|
290 | 0 | if(const SfxInt16Item* pAnchorItem = pOutSet->GetItemIfSet( |
291 | 0 | SID_ATTR_TRANSFORM_ANCHOR, false)) |
292 | 0 | { |
293 | 0 | if(!bSingleSelection) |
294 | 0 | pSh->ChgAnchor(static_cast<RndStdIds>(pAnchorItem |
295 | 0 | ->GetValue()), false, bPosCorr ); |
296 | 0 | else |
297 | 0 | { |
298 | 0 | SwFormatAnchor aAnchor(pFrameFormat->GetAnchor()); |
299 | 0 | aAnchor.SetType(static_cast<RndStdIds>(pAnchorItem->GetValue())); |
300 | 0 | aFrameAttrSet.Put( aAnchor ); |
301 | 0 | } |
302 | 0 | } |
303 | 0 | const SfxInt16Item* pHoriOrient = |
304 | 0 | pOutSet->GetItemIfSet(SID_ATTR_TRANSFORM_HORI_ORIENT, false); |
305 | 0 | const SfxInt16Item* pHoriRelation = |
306 | 0 | pOutSet->GetItemIfSet(SID_ATTR_TRANSFORM_HORI_RELATION, false); |
307 | 0 | const SfxInt32Item* pHoriPosition = |
308 | 0 | pOutSet->GetItemIfSet(SID_ATTR_TRANSFORM_HORI_POSITION, false); |
309 | 0 | const SfxBoolItem* pHoriMirror = |
310 | 0 | pOutSet->GetItemIfSet(SID_ATTR_TRANSFORM_HORI_MIRROR, false); |
311 | 0 | if(pHoriOrient || pHoriRelation || pHoriPosition || pHoriMirror) |
312 | 0 | { |
313 | 0 | if(pHoriOrient) |
314 | 0 | aHOrientFinal.SetHoriOrient(pHoriOrient->GetValue()); |
315 | 0 | if(pHoriRelation) |
316 | 0 | aHOrientFinal.SetRelationOrient(pHoriRelation->GetValue()); |
317 | 0 | if(pHoriPosition) |
318 | 0 | aHOrientFinal.SetPos( pHoriPosition->GetValue()); |
319 | 0 | if(pHoriMirror) |
320 | 0 | aHOrientFinal.SetPosToggle( pHoriMirror->GetValue()); |
321 | 0 | aFrameAttrSet.Put(aHOrientFinal); |
322 | 0 | } |
323 | |
|
324 | 0 | const SfxInt16Item* pVertOrient = |
325 | 0 | pOutSet->GetItemIfSet(SID_ATTR_TRANSFORM_VERT_ORIENT, false); |
326 | 0 | const SfxInt16Item* pVertRelation = |
327 | 0 | pOutSet->GetItemIfSet(SID_ATTR_TRANSFORM_VERT_RELATION, false); |
328 | 0 | const SfxInt32Item* pVertPosition = |
329 | 0 | pOutSet->GetItemIfSet(SID_ATTR_TRANSFORM_VERT_POSITION, false); |
330 | 0 | if(pVertOrient || pVertRelation || pVertPosition ) |
331 | 0 | { |
332 | 0 | if(pVertOrient) |
333 | 0 | aVOrientFinal.SetVertOrient(pVertOrient->GetValue()); |
334 | 0 | if(pVertRelation) |
335 | 0 | aVOrientFinal.SetRelationOrient(pVertRelation->GetValue()); |
336 | 0 | if(pVertPosition) |
337 | 0 | aVOrientFinal.SetPos( pVertPosition->GetValue()); |
338 | 0 | aFrameAttrSet.Put( aVOrientFinal ); |
339 | 0 | } |
340 | 0 | const SwFormatFollowTextFlow* pFollowItem = |
341 | 0 | pOutSet->GetItemIfSet(RES_FOLLOW_TEXT_FLOW, false); |
342 | 0 | if(pFollowItem) |
343 | 0 | aFrameAttrSet.Put(*pFollowItem); |
344 | |
|
345 | 0 | if(aFrameAttrSet.Count()) |
346 | 0 | pSh->SetDrawingAttr(aFrameAttrSet); |
347 | |
|
348 | 0 | GetView().GetViewFrame().GetBindings().InvalidateAll(false); |
349 | | |
350 | | // #i30451# |
351 | 0 | pSh->EndUndo( SwUndoId::INSFMTATTR ); |
352 | |
|
353 | 0 | pSh->EndAllAction(); |
354 | 0 | } |
355 | |
|
356 | 0 | if (pSdrView->GetModel().IsChanged()) |
357 | 0 | pSh->SetModified(); |
358 | 0 | else if (bChanged) |
359 | 0 | pSdrView->GetModel().SetChanged(); |
360 | |
|
361 | 0 | pDlg->disposeOnce(); |
362 | 0 | }); |
363 | 0 | } |
364 | 0 | } |
365 | 0 | else |
366 | 0 | { |
367 | 0 | pSh->StartAllAction(); |
368 | 0 | pSdrView->SetGeoAttrToMarked( *pArgs ); |
369 | 0 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); |
370 | 0 | SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); |
371 | 0 | if (pObj) |
372 | 0 | { |
373 | 0 | SwFrameFormat* pFrameFormat = FindFrameFormat(pObj); |
374 | 0 | if (pFrameFormat) |
375 | 0 | { |
376 | 0 | const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor(); |
377 | | // Don't change shape position / size, just update the anchor doc model |
378 | | // position. |
379 | 0 | pSh->ChgAnchor(rAnchor.GetAnchorId(), /*bSameOnly=*/true); |
380 | 0 | } |
381 | 0 | } |
382 | 0 | pSh->EndAllAction(); |
383 | 0 | } |
384 | 0 | } |
385 | 0 | } |
386 | 0 | break; |
387 | | |
388 | 0 | case SID_DELETE: |
389 | 0 | case FN_BACKSPACE: |
390 | 0 | if (pSh->GetSelectedObjCount() && !pSdrView->IsTextEdit()) |
391 | 0 | { |
392 | 0 | bDone = true; |
393 | |
|
394 | 0 | const Point aPt = pSh->GetObjRect().TopLeft(); // tdf#150589 |
395 | |
|
396 | 0 | if( GetView().IsDrawRotate() ) |
397 | 0 | { |
398 | 0 | pSh->SetDragMode( SdrDragMode::Move ); |
399 | 0 | GetView().FlipDrawRotate(); |
400 | 0 | } |
401 | |
|
402 | 0 | pSh->SetModified(); |
403 | 0 | pSh->DelSelectedObj(); |
404 | |
|
405 | 0 | if (rReq.IsAPI() || |
406 | 0 | GetView().GetEditWin().IsObjectSelect() ) |
407 | 0 | { |
408 | | // If basic call, then back to the text shell, because the |
409 | | // Basic otherwise has no possibility to return. |
410 | 0 | if (GetView().GetDrawFuncPtr()) |
411 | 0 | { |
412 | 0 | GetView().GetDrawFuncPtr()->Deactivate(); |
413 | 0 | GetView().SetDrawFuncPtr(nullptr); |
414 | 0 | } |
415 | 0 | GetView().LeaveDrawCreate(); // Switch to selection mode |
416 | 0 | } |
417 | |
|
418 | 0 | if (pSh->IsSelFrameMode()) |
419 | 0 | { |
420 | 0 | pSh->LeaveSelFrameMode(); |
421 | | // #105852# FME <- perhaps fixed by tdf#150589 |
422 | 0 | static_cast<SwEditShell*>(pSh)->SetCursor(aPt); |
423 | 0 | } |
424 | |
|
425 | 0 | } |
426 | 0 | break; |
427 | | |
428 | 0 | case SID_GROUP: |
429 | 0 | if (pSh->GetSelectedObjCount() > 1 && pSh->IsGroupAllowed()) |
430 | 0 | { |
431 | 0 | pSh->GroupSelection(); |
432 | 0 | rBind.Invalidate(SID_UNGROUP); |
433 | 0 | } |
434 | 0 | break; |
435 | | |
436 | 0 | case SID_UNGROUP: |
437 | 0 | if (pSh->IsGroupSelected(true) && pSh->IsUnGroupAllowed()) |
438 | 0 | { |
439 | 0 | pSh->UnGroupSelection(); |
440 | 0 | rBind.Invalidate(SID_GROUP); |
441 | 0 | } |
442 | 0 | break; |
443 | | |
444 | 0 | case SID_ENTER_GROUP: |
445 | 0 | if (pSh->IsGroupSelected(false)) |
446 | 0 | { |
447 | 0 | pSdrView->EnterMarkedGroup(); |
448 | 0 | rBind.InvalidateAll(false); |
449 | 0 | } |
450 | 0 | break; |
451 | | |
452 | 0 | case SID_LEAVE_GROUP: |
453 | 0 | if (pSdrView->IsGroupEntered()) |
454 | 0 | { |
455 | 0 | pSdrView->LeaveOneGroup(); |
456 | 0 | rBind.Invalidate(SID_ENTER_GROUP); |
457 | 0 | rBind.Invalidate(SID_UNGROUP); |
458 | 0 | } |
459 | 0 | break; |
460 | | |
461 | 0 | case SID_REGENERATE_DIAGRAM: |
462 | 0 | case SID_DIAGRAM_TO_GROUP: |
463 | 0 | case SID_EDIT_DIAGRAM: |
464 | 0 | { |
465 | 0 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); |
466 | |
|
467 | 0 | if (1 == rMarkList.GetMarkCount()) |
468 | 0 | { |
469 | 0 | SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); |
470 | | |
471 | | // Support advanced DiagramHelper |
472 | 0 | if(nullptr != pObj && pObj->isDiagram()) |
473 | 0 | { |
474 | 0 | if (SID_REGENERATE_DIAGRAM == nSlotId) |
475 | 0 | { |
476 | 0 | pSdrView->UnmarkAll(); |
477 | 0 | pObj->getDiagramHelper()->reLayout(); |
478 | 0 | pSdrView->MarkObj(pObj, pSdrView->GetSdrPageView()); |
479 | 0 | } |
480 | 0 | else if(SID_EDIT_DIAGRAM == nSlotId) |
481 | 0 | { |
482 | 0 | VclAbstractDialogFactory* pFact = VclAbstractDialogFactory::Create(); |
483 | 0 | VclPtr<VclAbstractDialog> pDlg = pFact->CreateDiagramDialog( |
484 | 0 | GetView().GetFrameWeld(), |
485 | 0 | *static_cast<SdrObjGroup*>(pObj)); |
486 | 0 | pDlg->StartExecuteAsync( |
487 | 0 | [pDlg] (sal_Int32 /*nResult*/)->void |
488 | 0 | { |
489 | 0 | pDlg->disposeOnce(); |
490 | 0 | } |
491 | 0 | ); |
492 | 0 | } |
493 | 0 | else // SID_DIAGRAM_TO_GROUP |
494 | 0 | { |
495 | 0 | pSdrView->UnmarkAll(); |
496 | 0 | pObj->getDiagramHelper()->disconnectFromSdrObjGroup(true); |
497 | 0 | pSdrView->MarkObj(pObj, pSdrView->GetSdrPageView()); |
498 | 0 | } |
499 | 0 | } |
500 | 0 | } |
501 | 0 | } |
502 | 0 | break; |
503 | | |
504 | 0 | case SID_OBJECT_ALIGN_LEFT: |
505 | 0 | case SID_OBJECT_ALIGN_CENTER: |
506 | 0 | case SID_OBJECT_ALIGN_RIGHT: |
507 | 0 | case SID_OBJECT_ALIGN_UP: |
508 | 0 | case SID_OBJECT_ALIGN_MIDDLE: |
509 | 0 | case SID_OBJECT_ALIGN_DOWN: |
510 | 0 | { |
511 | 0 | if ( bAlignPossible ) |
512 | 0 | { |
513 | 0 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); |
514 | 0 | if (rMarkList.GetMarkCount() == 1 |
515 | 0 | && !SwTextBoxHelper::hasTextFrame(rMarkList.GetMark(0)->GetMarkedSdrObj())) |
516 | 0 | { |
517 | 0 | sal_Int16 nHorizOrient = -1, nVertOrient = -1; |
518 | |
|
519 | 0 | switch (nSlotId) |
520 | 0 | { |
521 | 0 | case SID_OBJECT_ALIGN_LEFT: |
522 | 0 | nHorizOrient = text::HoriOrientation::LEFT; |
523 | 0 | break; |
524 | 0 | case SID_OBJECT_ALIGN_CENTER: |
525 | 0 | nHorizOrient = text::HoriOrientation::CENTER; |
526 | 0 | break; |
527 | 0 | case SID_OBJECT_ALIGN_RIGHT: |
528 | 0 | nHorizOrient = text::HoriOrientation::RIGHT; |
529 | 0 | break; |
530 | 0 | case SID_OBJECT_ALIGN_UP: |
531 | 0 | nVertOrient = text::VertOrientation::TOP; |
532 | 0 | break; |
533 | 0 | case SID_OBJECT_ALIGN_MIDDLE: |
534 | 0 | nVertOrient = text::VertOrientation::CENTER; |
535 | 0 | break; |
536 | 0 | case SID_OBJECT_ALIGN_DOWN: |
537 | 0 | nVertOrient = text::VertOrientation::BOTTOM; |
538 | 0 | break; |
539 | 0 | default: |
540 | 0 | break; |
541 | 0 | } |
542 | | |
543 | 0 | if (nHorizOrient != -1) |
544 | 0 | { |
545 | 0 | pSh->StartAction(); |
546 | 0 | SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); |
547 | 0 | SwFrameFormat* pFrameFormat = FindFrameFormat( pObj ); |
548 | 0 | SwFormatHoriOrient aHOrient(pFrameFormat->GetFormatAttr(RES_HORI_ORIENT)); |
549 | 0 | aHOrient.SetHoriOrient( nHorizOrient ); |
550 | 0 | pFrameFormat->SetFormatAttr(aHOrient); |
551 | 0 | pSh->EndAction(); |
552 | 0 | } |
553 | |
|
554 | 0 | if (nVertOrient != -1) |
555 | 0 | { |
556 | 0 | pSh->StartAction(); |
557 | 0 | SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); |
558 | 0 | SwFrameFormat* pFrameFormat = FindFrameFormat( pObj ); |
559 | 0 | SwFormatVertOrient aVOrient(pFrameFormat->GetFormatAttr(RES_VERT_ORIENT)); |
560 | 0 | aVOrient.SetVertOrient( nVertOrient ); |
561 | 0 | pFrameFormat->SetFormatAttr(aVOrient); |
562 | 0 | pSh->EndAction(); |
563 | 0 | } |
564 | |
|
565 | 0 | break; |
566 | 0 | } |
567 | | |
568 | 0 | pSh->StartAction(); |
569 | 0 | switch (nSlotId) |
570 | 0 | { |
571 | 0 | case SID_OBJECT_ALIGN_LEFT: |
572 | 0 | pSdrView->AlignMarkedObjects(SdrHorAlign::Left, SdrVertAlign::NONE); |
573 | 0 | break; |
574 | 0 | case SID_OBJECT_ALIGN_CENTER: |
575 | 0 | pSdrView->AlignMarkedObjects(SdrHorAlign::Center, SdrVertAlign::NONE); |
576 | 0 | break; |
577 | 0 | case SID_OBJECT_ALIGN_RIGHT: |
578 | 0 | pSdrView->AlignMarkedObjects(SdrHorAlign::Right, SdrVertAlign::NONE); |
579 | 0 | break; |
580 | 0 | case SID_OBJECT_ALIGN_UP: |
581 | 0 | pSdrView->AlignMarkedObjects(SdrHorAlign::NONE, SdrVertAlign::Top); |
582 | 0 | break; |
583 | 0 | case SID_OBJECT_ALIGN_MIDDLE: |
584 | 0 | pSdrView->AlignMarkedObjects(SdrHorAlign::NONE, SdrVertAlign::Center); |
585 | 0 | break; |
586 | 0 | case SID_OBJECT_ALIGN_DOWN: |
587 | 0 | pSdrView->AlignMarkedObjects(SdrHorAlign::NONE, SdrVertAlign::Bottom); |
588 | 0 | break; |
589 | 0 | } |
590 | 0 | pSh->EndAction(); |
591 | 0 | } |
592 | 0 | } |
593 | 0 | break; |
594 | | |
595 | 0 | case FN_FRAME_UP: |
596 | 0 | bTopParam = false; |
597 | 0 | [[fallthrough]]; |
598 | 0 | case SID_FRAME_TO_TOP: |
599 | 0 | pSh->SelectionToTop( bTopParam ); |
600 | 0 | break; |
601 | | |
602 | 0 | case FN_FRAME_DOWN: |
603 | 0 | bBottomParam = false; |
604 | 0 | [[fallthrough]]; |
605 | 0 | case SID_FRAME_TO_BOTTOM: |
606 | 0 | pSh->SelectionToBottom( bBottomParam ); |
607 | 0 | break; |
608 | | |
609 | 0 | case FN_NAME_SHAPE: |
610 | 0 | { |
611 | 0 | bDone = true; |
612 | |
|
613 | 0 | if(1 == pSdrView->GetMarkedObjectList().GetMarkCount()) |
614 | 0 | { |
615 | | // #i68101# |
616 | 0 | rtl::Reference<SdrObject> pSelected = pSdrView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(); |
617 | 0 | assert(pSelected && "DrawViewShell::FuTemp03: nMarkCount, but no object (!)"); |
618 | 0 | OUString aOrigName(pSelected->GetName()); |
619 | |
|
620 | 0 | SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); |
621 | 0 | VclPtr<AbstractSvxObjectNameDialog> pDlg(pFact->CreateSvxObjectNameDialog(GetView().GetFrameWeld(), aOrigName)); |
622 | |
|
623 | 0 | pDlg->SetCheckNameHdl(LINK(this, SwDrawBaseShell, CheckGroupShapeNameHdl)); |
624 | |
|
625 | 0 | pDlg->StartExecuteAsync( |
626 | 0 | [pDlg, pSelected, pSh, aOrigName] (sal_Int32 nResult)->void |
627 | 0 | { |
628 | 0 | if (nResult == RET_OK) |
629 | 0 | { |
630 | 0 | OUString aNewName = pDlg->GetName(); |
631 | 0 | pSelected->SetName(aNewName); |
632 | 0 | pSh->SetModified(); |
633 | | |
634 | | // update accessibility sidebar object name if we modify the object name on the navigator bar |
635 | 0 | if (!aNewName.isEmpty() && aOrigName != aNewName) |
636 | 0 | { |
637 | 0 | auto pFrameFormat = FindFrameFormat(pSelected.get()); |
638 | 0 | if (pFrameFormat) |
639 | 0 | { |
640 | 0 | if (SwNode* pSwNode = pFrameFormat->GetAnchor().GetAnchorNode()) |
641 | 0 | pSwNode->resetAndQueueAccessibilityCheck(true); |
642 | 0 | } |
643 | 0 | } |
644 | 0 | } |
645 | 0 | pDlg->disposeOnce(); |
646 | 0 | } |
647 | 0 | ); |
648 | 0 | } |
649 | |
|
650 | 0 | break; |
651 | 0 | } |
652 | | |
653 | | // #i68101# |
654 | 0 | case FN_TITLE_DESCRIPTION_SHAPE: |
655 | 0 | { |
656 | 0 | bDone = true; |
657 | |
|
658 | 0 | if(1 == pSdrView->GetMarkedObjectList().GetMarkCount()) |
659 | 0 | { |
660 | 0 | rtl::Reference<SdrObject> pSelected = pSdrView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(); |
661 | 0 | assert(pSelected && "DrawViewShell::FuTemp03: nMarkCount, but no object (!)"); |
662 | 0 | OUString aTitle(pSelected->GetTitle()); |
663 | 0 | OUString aDescription(pSelected->GetDescription()); |
664 | 0 | bool isDecorative(pSelected->IsDecorative()); |
665 | |
|
666 | 0 | SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); |
667 | 0 | VclPtr<AbstractSvxObjectTitleDescDialog> pDlg(pFact->CreateSvxObjectTitleDescDialog(GetView().GetFrameWeld(), |
668 | 0 | aTitle, aDescription, isDecorative)); |
669 | |
|
670 | 0 | pDlg->StartExecuteAsync( |
671 | 0 | [pDlg, pSelected, pSh] (sal_Int32 nResult)->void |
672 | 0 | { |
673 | 0 | if (nResult == RET_OK) |
674 | 0 | { |
675 | 0 | pSelected->SetTitle(pDlg->GetTitle()); |
676 | 0 | pSelected->SetDescription(pDlg->GetDescription()); |
677 | 0 | pSelected->SetDecorative(pDlg->IsDecorative()); |
678 | |
|
679 | 0 | pSh->SetModified(); |
680 | 0 | } |
681 | 0 | pDlg->disposeOnce(); |
682 | 0 | } |
683 | 0 | ); |
684 | 0 | } |
685 | |
|
686 | 0 | break; |
687 | 0 | } |
688 | | |
689 | 0 | case SID_OPEN_HYPERLINK: |
690 | 0 | { |
691 | 0 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); |
692 | 0 | SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); |
693 | 0 | LoadURL(GetShell(), pObj->getHyperlink(), LoadUrlFlags::NewView, |
694 | 0 | /*rTargetFrameName=*/OUString()); |
695 | 0 | break; |
696 | 0 | } |
697 | | |
698 | 0 | case SID_EDIT_HYPERLINK: |
699 | 0 | case SID_INSERT_HYPERLINK: |
700 | 0 | case SID_HYPERLINK_DIALOG: |
701 | 0 | { |
702 | 0 | GetView().GetViewFrame().SetChildWindow(SID_HYPERLINK_DIALOG, true); |
703 | 0 | break; |
704 | 0 | } |
705 | | |
706 | 0 | case SID_HYPERLINK_SETLINK: |
707 | 0 | { |
708 | 0 | if(pItem) |
709 | 0 | { |
710 | 0 | const SvxHyperlinkItem& rHLinkItem = *static_cast<const SvxHyperlinkItem *>(pItem); |
711 | 0 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); |
712 | 0 | SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); |
713 | 0 | pObj->setHyperlink(rHLinkItem.GetURL()); |
714 | 0 | } |
715 | 0 | break; |
716 | 0 | } |
717 | | |
718 | 0 | case SID_REMOVE_HYPERLINK: |
719 | 0 | { |
720 | 0 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); |
721 | 0 | SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); |
722 | 0 | pObj->setHyperlink(OUString()); |
723 | 0 | break; |
724 | 0 | } |
725 | | |
726 | 0 | case SID_COPY_HYPERLINK_LOCATION: |
727 | 0 | { |
728 | 0 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); |
729 | 0 | SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); |
730 | 0 | uno::Reference<datatransfer::clipboard::XClipboard> xClipboard |
731 | 0 | = GetView().GetEditWin().GetClipboard(); |
732 | 0 | vcl::unohelper::TextDataObject::CopyStringTo(pObj->getHyperlink(), xClipboard); |
733 | 0 | break; |
734 | 0 | } |
735 | | |
736 | 0 | default: |
737 | 0 | OSL_ENSURE(false, "wrong Dispatcher"); |
738 | 0 | return; |
739 | 0 | } |
740 | 0 | if(!bDone) |
741 | 0 | { |
742 | 0 | if(nSlotId >= SID_OBJECT_ALIGN_LEFT && nSlotId <= SID_OBJECT_ALIGN_DOWN) |
743 | 0 | rBind.Invalidate(SID_ATTR_LONG_LRSPACE); |
744 | 0 | if (pSdrView->GetModel().IsChanged()) |
745 | 0 | pSh->SetModified(); |
746 | 0 | else if (bChanged) |
747 | 0 | pSdrView->GetModel().SetChanged(); |
748 | 0 | } |
749 | 0 | } |
750 | | |
751 | | // Checks whether a given name is allowed for a group shape |
752 | | |
753 | | IMPL_LINK( SwDrawBaseShell, CheckGroupShapeNameHdl, AbstractSvxObjectNameDialog&, rNameDialog, bool ) |
754 | 0 | { |
755 | 0 | SwWrtShell &rSh = GetShell(); |
756 | 0 | SdrView *pSdrView = rSh.GetDrawView(); |
757 | 0 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); |
758 | 0 | OSL_ENSURE(rMarkList.GetMarkCount() == 1, "wrong draw selection"); |
759 | 0 | SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); |
760 | 0 | const OUString sCurrentName = pObj->GetName(); |
761 | 0 | OUString sNewName = rNameDialog.GetName(); |
762 | 0 | bool bRet = false; |
763 | 0 | if (sNewName.isEmpty() || sCurrentName == sNewName) |
764 | 0 | bRet = true; |
765 | 0 | else |
766 | 0 | { |
767 | 0 | bRet = true; |
768 | 0 | SwDrawModel* pModel = rSh.getIDocumentDrawModelAccess().GetDrawModel(); |
769 | 0 | SdrObjListIter aIter( pModel->GetPage(0), SdrIterMode::DeepWithGroups ); |
770 | 0 | while( aIter.IsMore() ) |
771 | 0 | { |
772 | 0 | SdrObject* pTempObj = aIter.Next(); |
773 | 0 | if ( pObj != pTempObj && pTempObj->GetName() == sNewName ) |
774 | 0 | { |
775 | 0 | bRet = false; |
776 | 0 | break; |
777 | 0 | } |
778 | 0 | } |
779 | 0 | } |
780 | 0 | return bRet; |
781 | 0 | } |
782 | | |
783 | | void SwDrawBaseShell::GetState(SfxItemSet& rSet) |
784 | 0 | { |
785 | 0 | SwWrtShell &rSh = GetShell(); |
786 | 0 | SdrView* pSdrView = rSh.GetDrawViewWithValidMarkList(); |
787 | 0 | SfxWhichIter aIter( rSet ); |
788 | 0 | sal_uInt16 nWhich = aIter.FirstWhich(); |
789 | 0 | bool bProtected = rSh.IsSelObjProtected(FlyProtectFlags::Content) != FlyProtectFlags::NONE; |
790 | |
|
791 | 0 | if (!bProtected) // Look in the parent |
792 | 0 | bProtected |= rSh.IsSelObjProtected( FlyProtectFlags::Content|FlyProtectFlags::Parent ) != FlyProtectFlags::NONE; |
793 | |
|
794 | 0 | while( nWhich ) |
795 | 0 | { |
796 | 0 | switch( nWhich ) |
797 | 0 | { |
798 | 0 | case FN_DRAW_WRAP_DLG: |
799 | 0 | case SID_ATTR_TRANSFORM: |
800 | 0 | case SID_FRAME_TO_TOP: |
801 | 0 | case SID_FRAME_TO_BOTTOM: |
802 | 0 | case FN_FRAME_UP: |
803 | 0 | case FN_FRAME_DOWN: |
804 | 0 | case SID_DELETE: |
805 | 0 | case FN_BACKSPACE: |
806 | 0 | if( bProtected || !rSh.GetSelectedObjCount() ) |
807 | 0 | rSet.DisableItem( nWhich ); |
808 | 0 | break; |
809 | 0 | case SID_GROUP: |
810 | 0 | if ( rSh.GetSelectedObjCount() < 2 || bProtected || !rSh.IsGroupAllowed() ) |
811 | 0 | rSet.DisableItem( nWhich ); |
812 | 0 | break; |
813 | 0 | case SID_UNGROUP: |
814 | 0 | if ( !rSh.IsGroupSelected(true) || bProtected || !rSh.IsUnGroupAllowed() ) |
815 | 0 | rSet.DisableItem( nWhich ); |
816 | 0 | break; |
817 | 0 | case SID_ENTER_GROUP: |
818 | 0 | if ( !rSh.IsGroupSelected(false) ) |
819 | 0 | rSet.DisableItem( nWhich ); |
820 | 0 | break; |
821 | 0 | case SID_LEAVE_GROUP: |
822 | 0 | if ( !pSdrView->IsGroupEntered() ) |
823 | 0 | rSet.DisableItem( nWhich ); |
824 | 0 | break; |
825 | 0 | case SID_OBJECT_ALIGN_LEFT: |
826 | 0 | case SID_OBJECT_ALIGN_CENTER: |
827 | 0 | case SID_OBJECT_ALIGN_RIGHT: |
828 | 0 | case SID_OBJECT_ALIGN_UP: |
829 | 0 | case SID_OBJECT_ALIGN_MIDDLE: |
830 | 0 | case SID_OBJECT_ALIGN_DOWN: |
831 | 0 | case SID_OBJECT_ALIGN: |
832 | 0 | { |
833 | 0 | bool bDisableThis = false; |
834 | 0 | bool bDisableHoriz = false; |
835 | 0 | bool bHoriz = (nWhich == SID_OBJECT_ALIGN_LEFT || nWhich == SID_OBJECT_ALIGN_CENTER || |
836 | 0 | nWhich == SID_OBJECT_ALIGN_RIGHT); |
837 | 0 | bool bVert = (nWhich == SID_OBJECT_ALIGN_UP || nWhich == SID_OBJECT_ALIGN_MIDDLE || |
838 | 0 | nWhich == SID_OBJECT_ALIGN_DOWN); |
839 | 0 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); |
840 | 0 | if ( !rSh.IsAlignPossible() || bProtected ) |
841 | 0 | { |
842 | 0 | bDisableThis = true; |
843 | 0 | rSet.DisableItem( nWhich ); |
844 | 0 | } |
845 | 0 | else if ( rSh.GetAnchorId() == RndStdIds::FLY_AS_CHAR ) |
846 | 0 | { |
847 | | //if only one object is selected it can only be vertically |
848 | | // aligned because it is character bound |
849 | 0 | if( rMarkList.GetMarkCount() == 1 ) |
850 | 0 | { |
851 | 0 | bDisableHoriz = true; |
852 | 0 | rSet.DisableItem(SID_OBJECT_ALIGN_LEFT); |
853 | 0 | rSet.DisableItem(SID_OBJECT_ALIGN_CENTER); |
854 | 0 | rSet.DisableItem(SID_OBJECT_ALIGN_RIGHT); |
855 | 0 | } |
856 | 0 | } |
857 | |
|
858 | 0 | if (bHoriz && !bDisableThis && !bDisableHoriz && |
859 | 0 | rMarkList.GetMarkCount() == 1) |
860 | 0 | { |
861 | 0 | sal_Int16 nHoriOrient = -1; |
862 | 0 | switch(nWhich) |
863 | 0 | { |
864 | 0 | case SID_OBJECT_ALIGN_LEFT: |
865 | 0 | nHoriOrient = text::HoriOrientation::LEFT; |
866 | 0 | break; |
867 | 0 | case SID_OBJECT_ALIGN_CENTER: |
868 | 0 | nHoriOrient = text::HoriOrientation::CENTER; |
869 | 0 | break; |
870 | 0 | case SID_OBJECT_ALIGN_RIGHT: |
871 | 0 | nHoriOrient = text::HoriOrientation::RIGHT; |
872 | 0 | break; |
873 | 0 | default: |
874 | 0 | break; |
875 | 0 | } |
876 | | |
877 | 0 | SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); |
878 | 0 | SwFrameFormat* pFrameFormat = FindFrameFormat(pObj); |
879 | 0 | if (pFrameFormat) |
880 | 0 | { |
881 | 0 | SwFormatHoriOrient aHOrient( |
882 | 0 | pFrameFormat->GetFormatAttr(RES_HORI_ORIENT)); |
883 | 0 | rSet.Put(SfxBoolItem(nWhich, aHOrient.GetHoriOrient() == nHoriOrient)); |
884 | 0 | } |
885 | 0 | } |
886 | | |
887 | 0 | if (bVert && !bDisableThis && rMarkList.GetMarkCount() == 1) |
888 | 0 | { |
889 | 0 | sal_Int16 nVertOrient = -1; |
890 | 0 | switch(nWhich) |
891 | 0 | { |
892 | 0 | case SID_OBJECT_ALIGN_UP: |
893 | 0 | nVertOrient = text::VertOrientation::TOP; |
894 | 0 | break; |
895 | 0 | case SID_OBJECT_ALIGN_MIDDLE: |
896 | 0 | nVertOrient = text::VertOrientation::CENTER; |
897 | 0 | break; |
898 | 0 | case SID_OBJECT_ALIGN_DOWN: |
899 | 0 | nVertOrient = text::VertOrientation::BOTTOM; |
900 | 0 | break; |
901 | 0 | default: |
902 | 0 | break; |
903 | 0 | } |
904 | | |
905 | 0 | SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); |
906 | 0 | SwFrameFormat* pFrameFormat = FindFrameFormat(pObj); |
907 | 0 | if (pFrameFormat) |
908 | 0 | { |
909 | 0 | SwFormatVertOrient aVOrient( |
910 | 0 | pFrameFormat->GetFormatAttr(RES_VERT_ORIENT)); |
911 | 0 | rSet.Put(SfxBoolItem(nWhich, aVOrient.GetVertOrient() == nVertOrient)); |
912 | 0 | } |
913 | 0 | } |
914 | 0 | } |
915 | 0 | break; |
916 | | |
917 | 0 | case FN_NAME_SHAPE : |
918 | 0 | { |
919 | 0 | if(1 != pSdrView->GetMarkedObjectList().GetMarkCount()) |
920 | 0 | { |
921 | 0 | rSet.DisableItem( nWhich ); |
922 | 0 | } |
923 | 0 | } |
924 | 0 | break; |
925 | | |
926 | | // #i68101# |
927 | 0 | case FN_TITLE_DESCRIPTION_SHAPE: |
928 | 0 | { |
929 | 0 | const bool bIsWebView(nullptr != dynamic_cast<SwWebView*>(&GetView())); |
930 | |
|
931 | 0 | if(!bIsWebView && 1 != pSdrView->GetMarkedObjectList().GetMarkCount()) |
932 | 0 | { |
933 | 0 | rSet.DisableItem( nWhich ); |
934 | 0 | } |
935 | 0 | } |
936 | 0 | break; |
937 | | |
938 | 0 | case SID_OPEN_HYPERLINK: |
939 | 0 | case SID_INSERT_HYPERLINK: |
940 | 0 | case SID_EDIT_HYPERLINK: |
941 | 0 | case SID_HYPERLINK_DIALOG: |
942 | 0 | case SID_REMOVE_HYPERLINK: |
943 | 0 | case SID_COPY_HYPERLINK_LOCATION: |
944 | 0 | { |
945 | 0 | if (pSdrView->GetMarkedObjectList().GetMarkCount() != 1) |
946 | 0 | { |
947 | 0 | rSet.DisableItem(nWhich); |
948 | 0 | break; |
949 | 0 | } |
950 | | |
951 | 0 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); |
952 | 0 | SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); |
953 | 0 | SdrObjKind nObjType = pObj->GetObjIdentifier(); |
954 | | |
955 | | // Only enable hyperlink for the following types |
956 | 0 | switch (nObjType) |
957 | 0 | { |
958 | 0 | case SdrObjKind::PathFill: |
959 | 0 | case SdrObjKind::CircleSection: |
960 | 0 | case SdrObjKind::Line: |
961 | 0 | case SdrObjKind::CustomShape: |
962 | 0 | case SdrObjKind::Text: |
963 | 0 | case SdrObjKind::Rectangle: |
964 | 0 | case SdrObjKind::Caption: |
965 | 0 | case SdrObjKind::Polygon: |
966 | 0 | case SdrObjKind::PolyLine: |
967 | 0 | case SdrObjKind::E3D_Scene: |
968 | 0 | case SdrObjKind::Measure: |
969 | 0 | case SdrObjKind::Edge: |
970 | 0 | break; |
971 | 0 | default: |
972 | 0 | rSet.DisableItem(nWhich); |
973 | 0 | break; |
974 | 0 | } |
975 | | |
976 | 0 | if (nWhich == SID_OPEN_HYPERLINK || nWhich == SID_REMOVE_HYPERLINK |
977 | 0 | || nWhich == SID_EDIT_HYPERLINK || nWhich == SID_COPY_HYPERLINK_LOCATION) |
978 | 0 | { |
979 | 0 | if (pObj->getHyperlink().isEmpty()) |
980 | 0 | rSet.DisableItem(nWhich); |
981 | 0 | } |
982 | 0 | if (nWhich == SID_INSERT_HYPERLINK && !pObj->getHyperlink().isEmpty()) |
983 | 0 | { |
984 | 0 | rSet.DisableItem(nWhich); |
985 | 0 | } |
986 | 0 | } |
987 | 0 | break; |
988 | | |
989 | 0 | case SID_HYPERLINK_GETLINK: |
990 | 0 | { |
991 | 0 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); |
992 | 0 | if (rMarkList.GetMark(0) != nullptr) |
993 | 0 | { |
994 | 0 | SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); |
995 | 0 | OUString sHyperLink = pObj->getHyperlink(); |
996 | 0 | SvxHyperlinkItem aHLinkItem; |
997 | 0 | aHLinkItem.SetShowName(false); |
998 | 0 | aHLinkItem.SetShowText(false); |
999 | 0 | aHLinkItem.SetURL(sHyperLink); |
1000 | 0 | rSet.Put(aHLinkItem); |
1001 | 0 | } |
1002 | 0 | } |
1003 | 0 | break; |
1004 | | |
1005 | 0 | case SID_REGENERATE_DIAGRAM: |
1006 | 0 | case SID_EDIT_DIAGRAM: |
1007 | 0 | { |
1008 | 0 | bool bDisable(true); |
1009 | 0 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); |
1010 | 0 | if (nullptr != rMarkList.GetMark(0)) |
1011 | 0 | { |
1012 | 0 | SdrObject* pObj(rMarkList.GetMark(0)->GetMarkedSdrObj()); |
1013 | |
|
1014 | 0 | if(nullptr != pObj && pObj->isDiagram()) |
1015 | 0 | { |
1016 | 0 | bDisable = false; |
1017 | 0 | } |
1018 | 0 | } |
1019 | |
|
1020 | 0 | if(bDisable) |
1021 | 0 | { |
1022 | 0 | rSet.DisableItem(nWhich); |
1023 | 0 | } |
1024 | 0 | } |
1025 | 0 | break; |
1026 | 0 | } |
1027 | 0 | nWhich = aIter.NextWhich(); |
1028 | 0 | } |
1029 | 0 | } |
1030 | | |
1031 | | void SwDrawBaseShell::GetDrawAttrStateForIFBX( SfxItemSet& rSet ) |
1032 | 0 | { |
1033 | 0 | SwWrtShell *pSh = &GetShell(); |
1034 | 0 | SdrView* pSdrView = pSh->GetDrawView(); |
1035 | 0 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); |
1036 | 0 | if( rMarkList.GetMark(0) != nullptr ) |
1037 | 0 | { |
1038 | 0 | SfxItemSet aNewAttr(pSdrView->GetGeoAttrFromMarked()); |
1039 | 0 | rSet.Put(aNewAttr,false); |
1040 | 0 | } |
1041 | 0 | } |
1042 | | |
1043 | | bool SwDrawBaseShell::Disable(SfxItemSet& rSet, sal_uInt16 nWhich) |
1044 | 0 | { |
1045 | 0 | bool bDisable = GetShell().IsSelObjProtected(FlyProtectFlags::Content) != FlyProtectFlags::NONE; |
1046 | |
|
1047 | 0 | if (bDisable) |
1048 | 0 | { |
1049 | 0 | if (nWhich) |
1050 | 0 | rSet.DisableItem( nWhich ); |
1051 | 0 | else |
1052 | 0 | { |
1053 | 0 | SfxWhichIter aIter( rSet ); |
1054 | 0 | nWhich = aIter.FirstWhich(); |
1055 | 0 | while (nWhich) |
1056 | 0 | { |
1057 | 0 | rSet.DisableItem( nWhich ); |
1058 | 0 | nWhich = aIter.NextWhich(); |
1059 | 0 | } |
1060 | 0 | } |
1061 | 0 | } |
1062 | |
|
1063 | 0 | return bDisable; |
1064 | 0 | } |
1065 | | |
1066 | | void SwDrawBaseShell::DisableState( SfxItemSet& rSet ) |
1067 | 0 | { |
1068 | 0 | SwWrtShell *pSh = &GetShell(); |
1069 | 0 | SdrView* pSdrView = pSh->GetDrawView(); |
1070 | 0 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); |
1071 | 0 | const size_t nMarkCount = rMarkList.GetMarkCount(); |
1072 | 0 | bool bShowArea = true, bShowMeasure = true, bShowConnector = true; |
1073 | |
|
1074 | 0 | for (size_t i = 0; i < nMarkCount && i < 50; ++i) |
1075 | 0 | { |
1076 | 0 | SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj(); |
1077 | 0 | SdrObjKind nObjType = pObj->GetObjIdentifier(); |
1078 | |
|
1079 | 0 | if ( nObjType != SdrObjKind::Measure ) |
1080 | 0 | bShowMeasure = false; |
1081 | |
|
1082 | 0 | if ( nObjType != SdrObjKind::Edge ) |
1083 | 0 | bShowConnector = false; |
1084 | | |
1085 | | // If marked object is 2D, disable format area command. |
1086 | 0 | if ( nObjType == SdrObjKind::PolyLine || |
1087 | 0 | nObjType == SdrObjKind::Line || |
1088 | 0 | nObjType == SdrObjKind::PathLine || |
1089 | 0 | nObjType == SdrObjKind::FreehandLine || |
1090 | 0 | nObjType == SdrObjKind::Edge || |
1091 | 0 | nObjType == SdrObjKind::CircleArc || |
1092 | 0 | bShowMeasure ) |
1093 | 0 | bShowArea = false; |
1094 | |
|
1095 | 0 | if (!bShowArea && !bShowMeasure) |
1096 | 0 | break; |
1097 | 0 | } |
1098 | |
|
1099 | 0 | if (!bShowArea) |
1100 | 0 | rSet.DisableItem(SID_ATTRIBUTES_AREA); |
1101 | |
|
1102 | 0 | if (!bShowMeasure) |
1103 | 0 | rSet.DisableItem(SID_MEASURE_DLG); |
1104 | |
|
1105 | 0 | if (!bShowConnector) |
1106 | 0 | rSet.DisableItem(SID_CONNECTION_DLG); |
1107 | |
|
1108 | 0 | Disable(rSet); |
1109 | |
|
1110 | 0 | } |
1111 | | |
1112 | | // Validate of drawing positions |
1113 | | |
1114 | | IMPL_LINK(SwDrawBaseShell, ValidatePosition, SvxSwFrameValidation&, rValidation, void ) |
1115 | 0 | { |
1116 | 0 | SwWrtShell *pSh = &GetShell(); |
1117 | 0 | rValidation.nMinHeight = MINFLY; |
1118 | 0 | rValidation.nMinWidth = MINFLY; |
1119 | |
|
1120 | 0 | SwRect aBoundRect; |
1121 | | |
1122 | | // OD 18.09.2003 #i18732# - adjustment for allowing vertical position |
1123 | | // aligned to page for fly frame anchored to paragraph or to character. |
1124 | 0 | const RndStdIds eAnchorType = rValidation.nAnchorType; |
1125 | 0 | const SwFormatAnchor* pAnchor = nullptr; |
1126 | 0 | SdrView* pSdrView = pSh->GetDrawView(); |
1127 | 0 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); |
1128 | 0 | if( rMarkList.GetMarkCount() == 1 ) |
1129 | 0 | { |
1130 | 0 | SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); |
1131 | 0 | SwFrameFormat* pFrameFormat = FindFrameFormat( pObj ); |
1132 | 0 | pAnchor = &pFrameFormat->GetAnchor(); |
1133 | 0 | } |
1134 | |
|
1135 | 0 | pSh->CalcBoundRect( aBoundRect, eAnchorType, |
1136 | 0 | rValidation.nHRelOrient, |
1137 | 0 | rValidation.nVRelOrient, |
1138 | 0 | pAnchor, |
1139 | 0 | rValidation.bFollowTextFlow, |
1140 | 0 | rValidation.bMirror, nullptr, &rValidation.aPercentSize); |
1141 | |
|
1142 | 0 | bool bIsInVertical( false ); |
1143 | 0 | { |
1144 | 0 | bool bRTL; |
1145 | 0 | bool bVertL2R; |
1146 | 0 | bIsInVertical = pSh->IsFrameVertical(true, bRTL, bVertL2R); |
1147 | 0 | } |
1148 | 0 | if(bIsInVertical) |
1149 | 0 | { |
1150 | 0 | Point aPos(aBoundRect.Pos()); |
1151 | 0 | tools::Long nTmp = aPos.X(); |
1152 | 0 | aPos.setX( aPos.Y() ); |
1153 | 0 | aPos.setY( nTmp ); |
1154 | 0 | Size aSize(aBoundRect.SSize()); |
1155 | 0 | nTmp = aSize.Width(); |
1156 | 0 | aSize.setWidth( aSize.Height() ); |
1157 | 0 | aSize.setHeight( nTmp ); |
1158 | 0 | aBoundRect.Chg( aPos, aSize ); |
1159 | | //exchange width/height to enable correct values |
1160 | 0 | nTmp = rValidation.nWidth; |
1161 | 0 | rValidation.nWidth = rValidation.nHeight; |
1162 | 0 | rValidation.nHeight = nTmp; |
1163 | 0 | } |
1164 | 0 | if ((eAnchorType == RndStdIds::FLY_AT_PAGE) || (eAnchorType == RndStdIds::FLY_AT_FLY)) |
1165 | 0 | { |
1166 | | // MinimalPosition |
1167 | 0 | rValidation.nMinHPos = aBoundRect.Left(); |
1168 | 0 | rValidation.nMinVPos = aBoundRect.Top(); |
1169 | 0 | SwTwips nH = rValidation.nHPos; |
1170 | 0 | SwTwips nV = rValidation.nVPos; |
1171 | |
|
1172 | 0 | if (rValidation.nHPos + rValidation.nWidth > aBoundRect.Right()) |
1173 | 0 | { |
1174 | 0 | if (rValidation.nHoriOrient == text::HoriOrientation::NONE) |
1175 | 0 | { |
1176 | 0 | rValidation.nHPos -= ((rValidation.nHPos + rValidation.nWidth) - aBoundRect.Right()); |
1177 | 0 | nH = rValidation.nHPos; |
1178 | 0 | } |
1179 | 0 | else |
1180 | 0 | rValidation.nWidth = aBoundRect.Right() - rValidation.nHPos; |
1181 | 0 | } |
1182 | |
|
1183 | 0 | if (rValidation.nHPos + rValidation.nWidth > aBoundRect.Right()) |
1184 | 0 | rValidation.nWidth = aBoundRect.Right() - rValidation.nHPos; |
1185 | |
|
1186 | 0 | if (rValidation.nVPos + rValidation.nHeight > aBoundRect.Bottom()) |
1187 | 0 | { |
1188 | 0 | if (rValidation.nVertOrient == text::VertOrientation::NONE) |
1189 | 0 | { |
1190 | 0 | rValidation.nVPos -= ((rValidation.nVPos + rValidation.nHeight) - aBoundRect.Bottom()); |
1191 | 0 | nV = rValidation.nVPos; |
1192 | 0 | } |
1193 | 0 | else |
1194 | 0 | rValidation.nHeight = aBoundRect.Bottom() - rValidation.nVPos; |
1195 | 0 | } |
1196 | |
|
1197 | 0 | if (rValidation.nVPos + rValidation.nHeight > aBoundRect.Bottom()) |
1198 | 0 | rValidation.nHeight = aBoundRect.Bottom() - rValidation.nVPos; |
1199 | |
|
1200 | 0 | if ( rValidation.nVertOrient != text::VertOrientation::NONE ) |
1201 | 0 | nV = aBoundRect.Top(); |
1202 | |
|
1203 | 0 | if ( rValidation.nHoriOrient != text::HoriOrientation::NONE ) |
1204 | 0 | nH = aBoundRect.Left(); |
1205 | |
|
1206 | 0 | rValidation.nMaxHPos = aBoundRect.Right() - rValidation.nWidth; |
1207 | 0 | rValidation.nMaxHeight = aBoundRect.Bottom() - nV; |
1208 | |
|
1209 | 0 | rValidation.nMaxVPos = aBoundRect.Bottom() - rValidation.nHeight; |
1210 | 0 | rValidation.nMaxWidth = aBoundRect.Right() - nH; |
1211 | 0 | } |
1212 | 0 | else if ((eAnchorType == RndStdIds::FLY_AT_PARA) || (eAnchorType == RndStdIds::FLY_AT_CHAR)) |
1213 | 0 | { |
1214 | 0 | if (rValidation.nHPos + rValidation.nWidth > aBoundRect.Right()) |
1215 | 0 | { |
1216 | 0 | if (rValidation.nHoriOrient == text::HoriOrientation::NONE) |
1217 | 0 | { |
1218 | 0 | rValidation.nHPos -= ((rValidation.nHPos + rValidation.nWidth) - aBoundRect.Right()); |
1219 | 0 | } |
1220 | 0 | else |
1221 | 0 | rValidation.nWidth = aBoundRect.Right() - rValidation.nHPos; |
1222 | 0 | } |
1223 | | |
1224 | | // OD 29.09.2003 #i17567#, #i18732# - consider following the text flow |
1225 | | // and alignment at page areas. |
1226 | 0 | const bool bMaxVPosAtBottom = !rValidation.bFollowTextFlow || |
1227 | 0 | rValidation.nVRelOrient == text::RelOrientation::PAGE_FRAME || |
1228 | 0 | rValidation.nVRelOrient == text::RelOrientation::PAGE_PRINT_AREA || |
1229 | 0 | rValidation.nVRelOrient == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM; |
1230 | 0 | { |
1231 | 0 | SwTwips nTmpMaxVPos = ( bMaxVPosAtBottom |
1232 | 0 | ? aBoundRect.Bottom() |
1233 | 0 | : aBoundRect.Height() ) - |
1234 | 0 | rValidation.nHeight; |
1235 | 0 | if ( rValidation.nVPos > nTmpMaxVPos ) |
1236 | 0 | { |
1237 | 0 | if (rValidation.nVertOrient == text::VertOrientation::NONE) |
1238 | 0 | { |
1239 | 0 | rValidation.nVPos = nTmpMaxVPos; |
1240 | 0 | } |
1241 | 0 | else |
1242 | 0 | { |
1243 | 0 | rValidation.nHeight = ( bMaxVPosAtBottom |
1244 | 0 | ? aBoundRect.Bottom() |
1245 | 0 | : aBoundRect.Height() ) - rValidation.nVPos; |
1246 | 0 | } |
1247 | 0 | } |
1248 | 0 | } |
1249 | |
|
1250 | 0 | rValidation.nMinHPos = aBoundRect.Left(); |
1251 | 0 | rValidation.nMaxHPos = aBoundRect.Right() - rValidation.nWidth; |
1252 | |
|
1253 | 0 | rValidation.nMinVPos = aBoundRect.Top(); |
1254 | | // OD 26.09.2003 #i17567#, #i18732# - determine maximum vertical position |
1255 | 0 | if ( bMaxVPosAtBottom ) |
1256 | 0 | { |
1257 | 0 | rValidation.nMaxVPos = aBoundRect.Bottom() - rValidation.nHeight; |
1258 | 0 | } |
1259 | 0 | else |
1260 | 0 | { |
1261 | 0 | rValidation.nMaxVPos = aBoundRect.Height() - rValidation.nHeight; |
1262 | 0 | } |
1263 | | |
1264 | | // Maximum width height |
1265 | 0 | const SwTwips nH = ( rValidation.nHoriOrient != text::HoriOrientation::NONE ) |
1266 | 0 | ? aBoundRect.Left() |
1267 | 0 | : rValidation.nHPos; |
1268 | 0 | const SwTwips nV = ( rValidation.nVertOrient != text::VertOrientation::NONE ) |
1269 | 0 | ? aBoundRect.Top() |
1270 | 0 | : rValidation.nVPos; |
1271 | 0 | rValidation.nMaxHeight = rValidation.nMaxVPos + rValidation.nHeight - nV; |
1272 | 0 | rValidation.nMaxWidth = rValidation.nMaxHPos + rValidation.nWidth - nH; |
1273 | 0 | } |
1274 | 0 | else if (eAnchorType == RndStdIds::FLY_AS_CHAR) |
1275 | 0 | { |
1276 | 0 | rValidation.nMinHPos = 0; |
1277 | 0 | rValidation.nMaxHPos = 0; |
1278 | |
|
1279 | 0 | rValidation.nMaxHeight = aBoundRect.Height(); |
1280 | 0 | rValidation.nMaxWidth = aBoundRect.Width(); |
1281 | |
|
1282 | 0 | rValidation.nMaxVPos = aBoundRect.Height(); |
1283 | 0 | rValidation.nMinVPos = -aBoundRect.Height() + rValidation.nHeight; |
1284 | 0 | if (rValidation.nMaxVPos < rValidation.nMinVPos) |
1285 | 0 | { |
1286 | 0 | rValidation.nMinVPos = rValidation.nMaxVPos; |
1287 | 0 | rValidation.nMaxVPos = -aBoundRect.Height(); |
1288 | 0 | } |
1289 | 0 | } |
1290 | 0 | if(bIsInVertical) |
1291 | 0 | { |
1292 | | //restore width/height exchange |
1293 | 0 | tools::Long nTmp = rValidation.nWidth; |
1294 | 0 | rValidation.nWidth = rValidation.nHeight; |
1295 | 0 | rValidation.nHeight = nTmp; |
1296 | 0 | } |
1297 | |
|
1298 | 0 | if (rValidation.nMaxWidth < rValidation.nWidth) |
1299 | 0 | rValidation.nWidth = rValidation.nMaxWidth; |
1300 | 0 | if (rValidation.nMaxHeight < rValidation.nHeight) |
1301 | 0 | rValidation.nHeight = rValidation.nMaxHeight; |
1302 | 0 | } |
1303 | | |
1304 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |