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 <fubullet.hxx> 21 22 #include <sfx2/bindings.hxx> 23 #include <sfx2/viewfrm.hxx> 24 #include <editeng/eeitem.hxx> 25 #include <svl/poolitem.hxx> 26 #include <editeng/fontitem.hxx> 27 #include <OutlineView.hxx> 28 #include <OutlineViewShell.hxx> 29 #include <DrawViewShell.hxx> 30 #include <ViewShellBase.hxx> 31 #include <Window.hxx> 32 #include <drawdoc.hxx> 33 #include <strings.hrc> 34 #include <sdresid.hxx> 35 #include <svx/svdoutl.hxx> 36 #include <sfx2/request.hxx> 37 #include <svl/ctloptions.hxx> 38 #include <svl/itempool.hxx> 39 #include <svl/stritem.hxx> 40 #include <tools/debug.hxx> 41 42 #include <svx/svxdlg.hxx> 43 #include <svx/svxids.hrc> 44 45 namespace sd { 46 47 const sal_Unicode CHAR_HARDBLANK = u'\x00A0'; 48 const sal_Unicode CHAR_HARDHYPHEN = u'\x2011'; 49 const sal_Unicode CHAR_SOFTHYPHEN = u'\x00AD'; 50 const sal_Unicode CHAR_RLM = u'\x200F'; 51 const sal_Unicode CHAR_LRM = u'\x200E'; 52 const sal_Unicode CHAR_ZWSP = u'\x200B'; 53 const sal_Unicode CHAR_ZWNBSP = u'\x2060'; 54 const sal_Unicode CHAR_NNBSP = u'\x202F'; //NARROW NO-BREAK SPACE 55 56 57 FuBullet::FuBullet ( 58 ViewShell* pViewSh, 59 ::sd::Window* pWin, 60 ::sd::View* _pView, 61 SdDrawDocument* pDoc, 62 SfxRequest& rReq) 63 : FuPoor(pViewSh, pWin, _pView, pDoc, rReq) 64 { 65 } 66 67 rtl::Reference<FuPoor> FuBullet::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq ) 68 { 69 rtl::Reference<FuPoor> xFunc( new FuBullet( pViewSh, pWin, pView, pDoc, rReq ) ); 70 xFunc->DoExecute(rReq); 71 return xFunc; 72 } 73 74 void FuBullet::DoExecute( SfxRequest& rReq ) 75 { 76 if( rReq.GetSlot() == SID_CHARMAP ) 77 InsertSpecialCharacter(rReq); 78 else 79 { 80 sal_Unicode cMark = 0; 81 switch( rReq.GetSlot() ) 82 { 83 case FN_INSERT_SOFT_HYPHEN: cMark = CHAR_SOFTHYPHEN ; break; 84 case FN_INSERT_HARDHYPHEN: cMark = CHAR_HARDHYPHEN ; break; 85 case FN_INSERT_HARD_SPACE: cMark = CHAR_HARDBLANK ; break; 86 case FN_INSERT_NNBSP: cMark = CHAR_NNBSP ; break; 87 case SID_INSERT_RLM : cMark = CHAR_RLM ; break; 88 case SID_INSERT_LRM : cMark = CHAR_LRM ; break; 89 case SID_INSERT_ZWSP : cMark = CHAR_ZWSP ; break; 90 case SID_INSERT_ZWNBSP: cMark = CHAR_ZWNBSP; break; 91 } 92 93 DBG_ASSERT( cMark != 0, "FuBullet::FuBullet(), illegal slot used!" ); 94 95 if( cMark ) 96 InsertFormattingMark( cMark ); 97 } 98 99 } 100 101 void FuBullet::InsertFormattingMark( sal_Unicode cMark ) 102 { 103 OutlinerView* pOV = nullptr; 104 ::Outliner* pOL = nullptr; 105 106 // depending on ViewShell set Outliner and OutlinerView 107 if( dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr) 108 { 109 pOV = mpView->GetTextEditOutlinerView(); 110 if (pOV) 111 pOL = mpView->GetTextEditOutliner(); 112 } 113 else if( dynamic_cast< const OutlineViewShell *>( mpViewShell ) != nullptr) 114 { 115 pOL = &static_cast<OutlineView*>(mpView)->GetOutliner(); 116 pOV = static_cast<OutlineView*>(mpView)->GetViewByWindow( 117 mpViewShell->GetActiveWindow()); 118 } 119 120 // insert string 121 if(!(pOV && pOL)) 122 return; 123 124 // prevent flickering 125 pOV->HideCursor(); 126 pOL->SetUpdateMode(false); 127 128 // remove old selected text 129 pOV->InsertText( "" ); 130 131 // prepare undo 132 SfxUndoManager& rUndoMgr = pOL->GetUndoManager(); 133 rUndoMgr.EnterListAction(SdResId(STR_UNDO_INSERT_SPECCHAR), 134 "", 0, mpViewShell->GetViewShellBase().GetViewShellId() ); 135 136 // insert given text 137 OUString aStr( cMark ); 138 pOV->InsertText( aStr, true); 139 140 ESelection aSel = pOV->GetSelection(); 141 aSel.nStartPara = aSel.nEndPara; 142 aSel.nStartPos = aSel.nEndPos; 143 pOV->SetSelection(aSel); 144 145 rUndoMgr.LeaveListAction(); 146 147 // restart repainting 148 pOL->SetUpdateMode(true); 149 pOV->ShowCursor(); 150 } 151 152 void FuBullet::InsertSpecialCharacter( SfxRequest const & rReq ) 153 { 154 const SfxItemSet *pArgs = rReq.GetArgs(); 155 const SfxPoolItem* pItem = nullptr; 156 if( pArgs ) 157 pArgs->GetItemState(mpDoc->GetPool().GetWhich(SID_CHARMAP), false, &pItem); 158 159 OUString aChars; 160 vcl::Font aFont; 161 if ( pItem ) 162 { 163 aChars = static_cast<const SfxStringItem*>(pItem)->GetValue(); 164 const SfxPoolItem* pFtItem = nullptr; 165 pArgs->GetItemState( mpDoc->GetPool().GetWhich(SID_ATTR_SPECIALCHAR), false, &pFtItem); 166 const SfxStringItem* pFontItem = dynamic_cast<const SfxStringItem*>( pFtItem ); 167 if ( pFontItem ) 168 { 169 const OUString& aFontName = pFontItem->GetValue(); 170 aFont = vcl::Font( aFontName, Size(1,1) ); 171 } 172 else 173 { 174 SfxItemSet aFontAttr( mpDoc->GetPool() ); 175 mpView->GetAttributes( aFontAttr ); 176 const SvxFontItem* pFItem = static_cast<const SvxFontItem*>(aFontAttr.GetItem( SID_ATTR_CHAR_FONT )); 177 if( pFItem ) 178 aFont = vcl::Font( pFItem->GetFamilyName(), pFItem->GetStyleName(), Size( 1, 1 ) ); 179 } 180 } 181 182 if (aChars.isEmpty()) 183 { 184 SfxAllItemSet aSet( mpDoc->GetPool() ); 185 aSet.Put( SfxBoolItem( FN_PARAM_1, false ) ); 186 187 SfxItemSet aFontAttr( mpDoc->GetPool() ); 188 mpView->GetAttributes( aFontAttr ); 189 const SvxFontItem* pFontItem = static_cast<const SvxFontItem*>(aFontAttr.GetItem( SID_ATTR_CHAR_FONT )); 190 if( pFontItem ) 191 aSet.Put( *pFontItem ); 192 193 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); 194 auto xFrame = mpViewShell ? mpViewShell->GetFrame()->GetFrame().GetFrameInterface() : nullptr; 195 ScopedVclPtr<SfxAbstractDialog> pDlg( pFact->CreateCharMapDialog(mpView->GetViewShell()->GetFrameWeld(), aSet, 196 xFrame) ); 197 198 // If a character is selected, it can be shown 199 // pDLg->SetFont( ); 200 // pDlg->SetChar( ); 201 pDlg->Execute(); 202 return; 203 } 204 205 if (aChars.isEmpty()) 206 return; 207 208 OutlinerView* pOV = nullptr; 209 ::Outliner* pOL = nullptr; 210 211 // determine depending on ViewShell Outliner and OutlinerView 212 if(dynamic_cast< const DrawViewShell *>( mpViewShell )) 213 { 214 pOV = mpView->GetTextEditOutlinerView(); 215 if (pOV) 216 { 217 pOL = mpView->GetTextEditOutliner(); 218 } 219 } 220 else if(dynamic_cast< const OutlineViewShell *>( mpViewShell )) 221 { 222 pOL = &static_cast<OutlineView*>(mpView)->GetOutliner(); 223 pOV = static_cast<OutlineView*>(mpView)->GetViewByWindow( 224 mpViewShell->GetActiveWindow()); 225 } 226 227 // insert special character 228 if (!pOV) 229 return; 230 231 // prevent flicker 232 pOV->HideCursor(); 233 pOL->SetUpdateMode(false); 234 235 /* remember old attributes: 236 To do that, remove selected area before (it has to go anyway). 237 With that, we get unique attributes (and since there is no 238 DeleteSelected() in OutlinerView, it is deleted by inserting an 239 empty string). */ 240 pOV->InsertText( "" ); 241 242 SfxItemSet aOldSet( mpDoc->GetPool(), svl::Items<EE_CHAR_FONTINFO, EE_CHAR_FONTINFO>{} ); 243 aOldSet.Put( pOV->GetAttribs() ); 244 245 SfxUndoManager& rUndoMgr = pOL->GetUndoManager(); 246 ViewShellId nViewShellId = mpViewShell ? mpViewShell->GetViewShellBase().GetViewShellId() : ViewShellId(-1); 247 rUndoMgr.EnterListAction(SdResId(STR_UNDO_INSERT_SPECCHAR), 248 "", 0, nViewShellId ); 249 pOV->InsertText(aChars, true); 250 251 // set attributes (set font) 252 SfxItemSet aSet(pOL->GetEmptyItemSet()); 253 SvxFontItem aFontItem (aFont.GetFamilyType(), aFont.GetFamilyName(), 254 aFont.GetStyleName(), aFont.GetPitch(), 255 aFont.GetCharSet(), 256 EE_CHAR_FONTINFO); 257 aSet.Put(aFontItem); 258 aFontItem.SetWhich(EE_CHAR_FONTINFO_CJK); 259 aSet.Put(aFontItem); 260 aFontItem.SetWhich(EE_CHAR_FONTINFO_CTL); 261 aSet.Put(aFontItem); 262 pOV->SetAttribs(aSet); 263 264 ESelection aSel = pOV->GetSelection(); 265 aSel.nStartPara = aSel.nEndPara; 266 aSel.nStartPos = aSel.nEndPos; 267 pOV->SetSelection(aSel); 268 269 // do not go ahead with setting attributes of special characters 270 pOV->GetOutliner()->QuickSetAttribs(aOldSet, aSel); 271 272 rUndoMgr.LeaveListAction(); 273 274 // show it again 275 pOL->SetUpdateMode(true); 276 pOV->ShowCursor(); 277 } 278 279 void FuBullet::GetSlotState( SfxItemSet& rSet, ViewShell const * pViewShell, SfxViewFrame* pViewFrame ) 280 { 281 if( !(SfxItemState::DEFAULT == rSet.GetItemState( SID_CHARMAP ) || 282 SfxItemState::DEFAULT == rSet.GetItemState( SID_CHARMAP_CONTROL ) || 283 SfxItemState::DEFAULT == rSet.GetItemState( FN_INSERT_SOFT_HYPHEN ) || 284 SfxItemState::DEFAULT == rSet.GetItemState( FN_INSERT_HARDHYPHEN ) || 285 SfxItemState::DEFAULT == rSet.GetItemState( FN_INSERT_HARD_SPACE ) || 286 SfxItemState::DEFAULT == rSet.GetItemState( FN_INSERT_NNBSP ) || 287 SfxItemState::DEFAULT == rSet.GetItemState( SID_INSERT_RLM ) || 288 SfxItemState::DEFAULT == rSet.GetItemState( SID_INSERT_LRM ) || 289 SfxItemState::DEFAULT == rSet.GetItemState( SID_INSERT_ZWNBSP ) || 290 SfxItemState::DEFAULT == rSet.GetItemState( SID_INSERT_ZWSP ))) 291 return; 292 293 ::sd::View* pView = pViewShell ? pViewShell->GetView() : nullptr; 294 OutlinerView* pOLV = pView ? pView->GetTextEditOutlinerView() : nullptr; 295 296 const bool bTextEdit = pOLV; 297 298 SvtCTLOptions aCTLOptions; 299 const bool bCtlEnabled = aCTLOptions.IsCTLFontEnabled(); 300 301 if(!bTextEdit ) 302 { 303 rSet.DisableItem(FN_INSERT_SOFT_HYPHEN); 304 rSet.DisableItem(FN_INSERT_HARDHYPHEN); 305 rSet.DisableItem(FN_INSERT_HARD_SPACE); 306 rSet.DisableItem(FN_INSERT_NNBSP); 307 rSet.DisableItem(SID_INSERT_ZWNBSP); 308 rSet.DisableItem(SID_INSERT_ZWSP); 309 } 310 311 if( !bTextEdit && (dynamic_cast<OutlineViewShell const *>( pViewShell ) == nullptr) ) 312 { 313 rSet.DisableItem(SID_CHARMAP); 314 rSet.DisableItem(SID_CHARMAP_CONTROL); 315 } 316 317 if(!bTextEdit || !bCtlEnabled ) 318 { 319 rSet.DisableItem(SID_INSERT_RLM); 320 rSet.DisableItem(SID_INSERT_LRM); 321 } 322 323 if( pViewFrame ) 324 { 325 SfxBindings& rBindings = pViewFrame->GetBindings(); 326 327 rBindings.SetVisibleState( SID_INSERT_RLM, bCtlEnabled ); 328 rBindings.SetVisibleState( SID_INSERT_LRM, bCtlEnabled ); 329 } 330 } 331 } // end of namespace sd 332 333 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 334
