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
