xref: /core/sw/source/uibase/shells/listsh.cxx (revision c456f839)
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 <cmdid.h>
21 #include <sfx2/request.hxx>
22 #include <sfx2/objface.hxx>
23 #include <sfx2/bindings.hxx>
24 #include <sfx2/viewfrm.hxx>
25 #include <svl/eitem.hxx>
26 #include <svl/whiter.hxx>
27 
28 #include <numrule.hxx>
29 #include <wrtsh.hxx>
30 #include <listsh.hxx>
31 #include <view.hxx>
32 
33 #define ShellClass_SwListShell
34 #include <sfx2/msg.hxx>
35 #include <swslots.hxx>
36 
37 #include <IDocumentOutlineNodes.hxx>
38 
39 SFX_IMPL_INTERFACE(SwListShell, SwBaseShell)
40 
41 void SwListShell::InitInterface_Impl()
42 {
43     GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Num_Toolbox);
44 }
45 
46 
47 // #i35572# Functionality of Numbering/Bullet toolbar
48 // for outline numbered paragraphs should match the functions for outlines
49 // available in the navigator. Therefore the code in the following
50 // function is quite similar the code in SwContentTree::ExecCommand.
51 static void lcl_OutlineUpDownWithSubPoints( SwWrtShell& rSh, bool bMove, bool bUp )
52 {
53     const SwOutlineNodes::size_type nActPos = rSh.GetOutlinePos();
54     if ( !(nActPos < SwOutlineNodes::npos && rSh.IsOutlineMovable( nActPos )) )
55         return;
56 
57     rSh.Push();
58     rSh.MakeOutlineSel( nActPos, nActPos, true );
59 
60     if ( bMove )
61     {
62         const IDocumentOutlineNodes* pIDoc( rSh.getIDocumentOutlineNodesAccess() );
63         const int nActLevel = pIDoc->getOutlineLevel( nActPos );
64         SwOutlineNodes::difference_type nDir = 0;
65 
66         if ( !bUp )
67         {
68             // Move down with subpoints:
69             SwOutlineNodes::size_type nActEndPos = nActPos + 1;
70             while ( nActEndPos < pIDoc->getOutlineNodesCount() &&
71                    (!pIDoc->isOutlineInLayout(nActEndPos, *rSh.GetLayout())
72                     || nActLevel < pIDoc->getOutlineLevel(nActEndPos)))
73             {
74                 ++nActEndPos;
75             }
76 
77             if ( nActEndPos < pIDoc->getOutlineNodesCount() )
78             {
79                 // The current subpoint which should be moved
80                 // starts at nActPos and ends at nActEndPos - 1
81                 --nActEndPos;
82                 SwOutlineNodes::size_type nDest = nActEndPos + 2;
83                 while ( nDest < pIDoc->getOutlineNodesCount() &&
84                        (!pIDoc->isOutlineInLayout(nDest, *rSh.GetLayout())
85                         || nActLevel < pIDoc->getOutlineLevel(nDest)))
86                 {
87                     ++nDest;
88                 }
89 
90                 nDir = nDest - 1 - nActEndPos;
91             }
92         }
93         else
94         {
95             // Move up with subpoints:
96             if ( nActPos > 0 )
97             {
98                 SwOutlineNodes::size_type nDest = nActPos - 1;
99                 while (nDest > 0 &&
100                        (!pIDoc->isOutlineInLayout(nDest, *rSh.GetLayout())
101                         || nActLevel < pIDoc->getOutlineLevel(nDest)))
102                 {
103                     --nDest;
104                 }
105 
106                 nDir = nDest - nActPos;
107             }
108         }
109 
110         if ( nDir )
111         {
112             rSh.MoveOutlinePara( nDir );
113             rSh.GotoOutline( nActPos + nDir );
114         }
115     }
116     else
117     {
118         // Up/down with subpoints:
119         rSh.OutlineUpDown( bUp ? -1 : 1 );
120     }
121 
122     rSh.ClearMark();
123     rSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
124 }
125 
126 void SwListShell::Execute(SfxRequest &rReq)
127 {
128     const SfxItemSet* pArgs = rReq.GetArgs();
129     const sal_uInt16 nSlot = rReq.GetSlot();
130     SwWrtShell& rSh = GetShell();
131 
132     // #i35572#
133     const SwNumRule* pCurRule = rSh.GetNumRuleAtCurrCursorPos();
134     OSL_ENSURE( pCurRule, "SwListShell::Execute without NumRule" );
135     bool bOutline = pCurRule && pCurRule->IsOutlineRule();
136 
137     switch (nSlot)
138     {
139         case FN_NUM_BULLET_DOWN:
140         case FN_NUM_BULLET_UP:
141             {
142                 SfxViewFrame * pFrame = GetView().GetViewFrame();
143 
144                 rReq.Done();
145                 rSh.NumUpDown( nSlot == FN_NUM_BULLET_DOWN );
146                 pFrame->GetBindings().Invalidate( SID_TABLE_CELL ); // Update status line!
147             }
148             break;
149 
150         case FN_NUM_BULLET_NEXT:
151             rSh.GotoNextNum();
152             rReq.Done();
153             break;
154 
155         case FN_NUM_BULLET_NONUM:
156             rSh.NoNum();
157             rReq.Done();
158             break;
159 
160         case FN_NUM_BULLET_OUTLINE_DOWN:
161             if ( bOutline )
162                 lcl_OutlineUpDownWithSubPoints( rSh, false, false );
163             else
164                 rSh.MoveNumParas(false, false);
165             rReq.Done();
166             break;
167 
168         case FN_NUM_BULLET_OUTLINE_MOVEDOWN:
169             if ( bOutline )
170                 lcl_OutlineUpDownWithSubPoints( rSh, true, false );
171             else
172                 rSh.MoveNumParas(true, false);
173             rReq.Done();
174             break;
175 
176         case FN_NUM_BULLET_OUTLINE_MOVEUP:
177             if ( bOutline )
178                 lcl_OutlineUpDownWithSubPoints( rSh, true, true );
179             else
180                 rSh.MoveNumParas(true, true);
181             rReq.Done();
182             break;
183 
184         case FN_NUM_BULLET_OUTLINE_UP:
185             if ( bOutline )
186                 lcl_OutlineUpDownWithSubPoints( rSh, false, true );
187             else
188                 rSh.MoveNumParas(false, true);
189             rReq.Done();
190             break;
191 
192         case FN_NUM_BULLET_PREV:
193             rSh.GotoPrevNum();
194             rReq.Done();
195             break;
196 
197         case FN_NUM_OR_NONUM:
198         {
199             bool bApi = rReq.IsAPI();
200             bool bDelete = !rSh.IsNoNum(!bApi);
201             if(pArgs )
202                 bDelete = static_cast<const SfxBoolItem &>(pArgs->Get(rReq.GetSlot())).GetValue();
203             rSh.NumOrNoNum( bDelete, !bApi );
204             rReq.AppendItem( SfxBoolItem( nSlot, bDelete ) );
205             rReq.Done();
206         }
207         break;
208         default:
209             OSL_ENSURE(false, "wrong dispatcher");
210             return;
211     }
212 }
213 
214 void SwListShell::GetState(SfxItemSet &rSet)
215 {
216     SfxWhichIter aIter( rSet );
217     sal_uInt16 nWhich = aIter.FirstWhich();
218     SwWrtShell& rSh = GetShell();
219     sal_uInt8 nCurrentNumLevel = rSh.GetNumLevel();
220     while ( nWhich )
221     {
222         switch( nWhich )
223         {
224             case FN_NUM_OR_NONUM:
225                 rSet.Put(SfxBoolItem(nWhich, GetShell().IsNoNum(false)));
226             break;
227             case FN_NUM_BULLET_OUTLINE_UP:
228             case FN_NUM_BULLET_UP:
229                 if(!nCurrentNumLevel)
230                     rSet.DisableItem(nWhich);
231             break;
232             case FN_NUM_BULLET_OUTLINE_DOWN :
233             {
234                 sal_uInt8 nUpper = 0;
235                 sal_uInt8 nLower = 0;
236                 rSh.GetCurrentOutlineLevels( nUpper, nLower );
237                 if(nLower == (MAXLEVEL - 1))
238                     rSet.DisableItem(nWhich);
239             }
240             break;
241             case FN_NUM_BULLET_DOWN:
242                 if(nCurrentNumLevel == (MAXLEVEL - 1))
243                     rSet.DisableItem(nWhich);
244             break;
245 
246             case FN_NUM_BULLET_NONUM:
247                 if ( rSh.CursorInsideInputField() )
248                 {
249                     rSet.DisableItem(nWhich);
250                 }
251                 break;
252         }
253         nWhich = aIter.NextWhich();
254     }
255 }
256 
257 SwListShell::SwListShell(SwView &_rView) :
258     SwBaseShell(_rView)
259 {
260     SetName("List");
261 }
262 
263 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
264