diff options
Diffstat (limited to 'sw/source/uibase/ribbar')
-rw-r--r-- | sw/source/uibase/ribbar/conarc.cxx | 100 | ||||
-rw-r--r-- | sw/source/uibase/ribbar/concustomshape.cxx | 186 | ||||
-rw-r--r-- | sw/source/uibase/ribbar/conform.cxx | 108 | ||||
-rw-r--r-- | sw/source/uibase/ribbar/conpoly.cxx | 103 | ||||
-rw-r--r-- | sw/source/uibase/ribbar/conrect.cxx | 214 | ||||
-rw-r--r-- | sw/source/uibase/ribbar/drawbase.cxx | 550 | ||||
-rw-r--r-- | sw/source/uibase/ribbar/dselect.cxx | 44 | ||||
-rw-r--r-- | sw/source/uibase/ribbar/inputwin.cxx | 602 | ||||
-rw-r--r-- | sw/source/uibase/ribbar/workctrl.cxx | 1063 |
9 files changed, 2970 insertions, 0 deletions
diff --git a/sw/source/uibase/ribbar/conarc.cxx b/sw/source/uibase/ribbar/conarc.cxx new file mode 100644 index 000000000..16625a4df --- /dev/null +++ b/sw/source/uibase/ribbar/conarc.cxx @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <svx/svdobj.hxx> +#include <svx/svxids.hrc> +#include <vcl/event.hxx> + +#include <view.hxx> +#include <edtwin.hxx> +#include <wrtsh.hxx> +#include <drawbase.hxx> +#include <conarc.hxx> + +ConstArc::ConstArc(SwWrtShell* pWrtShell, SwEditWin* pEditWin, SwView* pSwView) + : SwDrawBase(pWrtShell, pEditWin, pSwView), m_nButtonUpCount(0) +{ +} + +bool ConstArc::MouseButtonDown( const MouseEvent& rMEvt ) +{ + bool bReturn = SwDrawBase::MouseButtonDown(rMEvt); + if (bReturn && !m_nButtonUpCount) + m_aStartPoint = m_pWin->PixelToLogic(rMEvt.GetPosPixel()); + return bReturn; +} + +bool ConstArc::MouseButtonUp( const MouseEvent& rMEvt ) +{ + bool bReturn = false; + + if ((m_pSh->IsDrawCreate() || m_pWin->IsDrawAction()) && rMEvt.IsLeft()) + { + Point aPnt(m_pWin->PixelToLogic(rMEvt.GetPosPixel())); + if (!m_nButtonUpCount && aPnt == m_aStartPoint) + { + SwDrawBase::MouseButtonUp(rMEvt); + bReturn = true; + } + else + { m_nButtonUpCount++; + + if (m_nButtonUpCount == 3) // Generating of circular arc finished + { + SwDrawBase::MouseButtonUp(rMEvt); + m_nButtonUpCount = 0; + bReturn = true; + } + else + m_pSh->EndCreate(SdrCreateCmd::NextPoint); + } + } + + return bReturn; +} + +void ConstArc::Activate(const sal_uInt16 nSlotId) +{ + switch (nSlotId) + { + case SID_DRAW_ARC: + m_pWin->SetSdrDrawMode(OBJ_CARC); + break; + case SID_DRAW_PIE: + m_pWin->SetSdrDrawMode(OBJ_SECT); + break; + case SID_DRAW_CIRCLECUT: + m_pWin->SetSdrDrawMode(OBJ_CCUT); + break; + default: + m_pWin->SetSdrDrawMode(OBJ_NONE); + break; + } + + SwDrawBase::Activate(nSlotId); +} + +void ConstArc::Deactivate() +{ + m_nButtonUpCount = 0; + + SwDrawBase::Deactivate(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/ribbar/concustomshape.cxx b/sw/source/uibase/ribbar/concustomshape.cxx new file mode 100644 index 000000000..a90652f1b --- /dev/null +++ b/sw/source/uibase/ribbar/concustomshape.cxx @@ -0,0 +1,186 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <svx/svdobj.hxx> +#include <svx/sdtagitm.hxx> +#include <svx/svdview.hxx> +#include <editeng/eeitem.hxx> +#include <view.hxx> +#include <edtwin.hxx> +#include <wrtsh.hxx> +#include <drawbase.hxx> +#include <concustomshape.hxx> +#include <svx/gallery.hxx> +#include <sfx2/request.hxx> +#include <svx/fmmodel.hxx> +#include <svl/itempool.hxx> +#include <svl/stritem.hxx> +#include <svx/svdpage.hxx> +#include <svx/svdoashp.hxx> +#include <svx/xfillit0.hxx> +#include <editeng/adjustitem.hxx> + +#include <math.h> + +using namespace com::sun::star; + +ConstCustomShape::ConstCustomShape( SwWrtShell* pWrtShell, SwEditWin* pEditWin, SwView* pSwView, SfxRequest const & rReq ) + : SwDrawBase( pWrtShell, pEditWin, pSwView ) +{ + aCustomShape = ConstCustomShape::GetShapeTypeFromRequest( rReq ); +} + +const OUString& ConstCustomShape::GetShapeType() const +{ + return aCustomShape; +} + +OUString ConstCustomShape::GetShapeTypeFromRequest( SfxRequest const & rReq ) +{ + OUString aRet; + const SfxItemSet* pArgs = rReq.GetArgs(); + if ( pArgs ) + { + const SfxStringItem& rItm = static_cast<const SfxStringItem&>(pArgs->Get( rReq.GetSlot() )); + aRet = rItm.GetValue(); + } + return aRet; +} + +bool ConstCustomShape::MouseButtonDown(const MouseEvent& rMEvt) +{ + bool bReturn = SwDrawBase::MouseButtonDown(rMEvt); + if ( bReturn ) + { + SdrView *pSdrView = m_pSh->GetDrawView(); + if ( pSdrView ) + { + SdrObject* pObj = pSdrView->GetCreateObj(); + if ( pObj ) + { + SetAttributes( pObj ); + bool bForceNoFillStyle = false; + if ( static_cast<SdrObjCustomShape*>(pObj)->UseNoFillStyle() ) + bForceNoFillStyle = true; + + SfxItemSet aAttr( m_pView->GetPool() ); + if ( bForceNoFillStyle ) + aAttr.Put( XFillStyleItem( drawing::FillStyle_NONE ) ); + pObj->SetMergedItemSet(aAttr); + } + } + } + return bReturn; +} + +void ConstCustomShape::Activate(const sal_uInt16 nSlotId) +{ + m_pWin->SetSdrDrawMode( OBJ_CUSTOMSHAPE ); + + SwDrawBase::Activate(nSlotId); +} + +// applying attributes + +void ConstCustomShape::SetAttributes( SdrObject* pObj ) +{ + bool bAttributesAppliedFromGallery = false; + + if ( GalleryExplorer::GetSdrObjCount( GALLERY_THEME_POWERPOINT ) ) + { + std::vector< OUString > aObjList; + if ( GalleryExplorer::FillObjListTitle( GALLERY_THEME_POWERPOINT, aObjList ) ) + { + for ( std::vector<OUString>::size_type i = 0; i < aObjList.size(); i++ ) + { + if ( aObjList[ i ].equalsIgnoreAsciiCase( aCustomShape ) ) + { + FmFormModel aFormModel; + SfxItemPool& rPool(aFormModel.GetItemPool()); + rPool.FreezeIdRanges(); + + if ( GalleryExplorer::GetSdrObj( GALLERY_THEME_POWERPOINT, i, &aFormModel ) ) + { + const SdrObject* pSourceObj = aFormModel.GetPage( 0 )->GetObj( 0 ); + if( pSourceObj ) + { + const SfxItemSet& rSource = pSourceObj->GetMergedItemSet(); + SfxItemSet aDest( + pObj->getSdrModelFromSdrObject().GetItemPool(), + svl::Items< + // Ranges from SdrAttrObj: + SDRATTR_START, SDRATTR_SHADOW_LAST, + SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, + SDRATTR_TEXTDIRECTION, + SDRATTR_TEXTDIRECTION, + // Graphic attributes, 3D properties, + // CustomShape properties: + SDRATTR_GRAF_FIRST, + SDRATTR_CUSTOMSHAPE_LAST, + // Range from SdrTextObj: + EE_ITEMS_START, EE_ITEMS_END>{}); + aDest.Set( rSource ); + pObj->SetMergedItemSet( aDest ); + sal_Int32 nAngle = pSourceObj->GetRotateAngle(); + if ( nAngle ) + { + double a = nAngle * F_PI18000; + pObj->NbcRotate( pObj->GetSnapRect().Center(), nAngle, sin( a ), cos( a ) ); + } + bAttributesAppliedFromGallery = true; + } + } + break; + } + } + } + } + if ( !bAttributesAppliedFromGallery ) + { + pObj->SetMergedItem( SvxAdjustItem( SvxAdjust::Center, RES_PARATR_ADJUST ) ); + pObj->SetMergedItem( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_CENTER ) ); + pObj->SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_BLOCK ) ); + pObj->SetMergedItem( makeSdrTextAutoGrowHeightItem( false ) ); + static_cast<SdrObjCustomShape*>(pObj)->MergeDefaultAttributes( &aCustomShape ); + } +} + +void ConstCustomShape::CreateDefaultObject() +{ + SwDrawBase::CreateDefaultObject(); + SdrView *pSdrView = m_pSh->GetDrawView(); + if ( pSdrView ) + { + const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); + if ( rMarkList.GetMarkCount() == 1 ) + { + SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); + if ( dynamic_cast< const SdrObjCustomShape *>( pObj ) ) + SetAttributes( pObj ); + } + } +} + +// #i33136# +bool ConstCustomShape::doConstructOrthogonal() const +{ + return SdrObjCustomShape::doConstructOrthogonal(aCustomShape); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/ribbar/conform.cxx b/sw/source/uibase/ribbar/conform.cxx new file mode 100644 index 000000000..a61a0d725 --- /dev/null +++ b/sw/source/uibase/ribbar/conform.cxx @@ -0,0 +1,108 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <svx/svdview.hxx> +#include <vcl/ptrstyle.hxx> + +#include <swmodule.hxx> +#include <view.hxx> +#include <edtwin.hxx> +#include <wrtsh.hxx> +#include <drawbase.hxx> +#include <conform.hxx> + +ConstFormControl::ConstFormControl(SwWrtShell* pWrtShell, SwEditWin* pEditWin, SwView* pSwView) : + SwDrawBase(pWrtShell, pEditWin, pSwView) +{ + m_bInsForm = true; +} + +bool ConstFormControl::MouseButtonDown(const MouseEvent& rMEvt) +{ + bool bReturn = false; + + SdrView *pSdrView = m_pSh->GetDrawView(); + + pSdrView->SetOrtho(rMEvt.IsShift()); + pSdrView->SetAngleSnapEnabled(rMEvt.IsShift()); + + if (rMEvt.IsMod2()) + { + pSdrView->SetCreate1stPointAsCenter(true); + pSdrView->SetResizeAtCenter(true); + } + else + { + pSdrView->SetCreate1stPointAsCenter(false); + pSdrView->SetResizeAtCenter(false); + } + + SdrViewEvent aVEvt; + SdrHitKind eHit = pSdrView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt); + + // Only new object; if not in base mode (or pure selection mode) + if (rMEvt.IsLeft() && !m_pWin->IsDrawAction() && + (eHit == SdrHitKind::UnmarkedObject || eHit == SdrHitKind::NONE || m_pSh->IsDrawCreate())) + { + g_bNoInterrupt = true; + m_pWin->CaptureMouse(); + + m_pWin->SetPointer(PointerStyle::DrawRect); + + m_aStartPos = m_pWin->PixelToLogic(rMEvt.GetPosPixel()); + bReturn = m_pSh->BeginCreate( static_cast< sal_uInt16 >(m_pWin->GetSdrDrawMode()), SdrInventor::FmForm, m_aStartPos); + + if (bReturn) + m_pWin->SetDrawAction(true); + } + else + bReturn = SwDrawBase::MouseButtonDown(rMEvt); + + return bReturn; +} + +void ConstFormControl::Activate(const sal_uInt16 nSlotId) +{ + m_pWin->SetSdrDrawMode( static_cast<SdrObjKind>(nSlotId) ); + SwDrawBase::Activate(nSlotId); + m_pSh->GetDrawView()->SetCurrentObj(nSlotId); + + m_pWin->SetPointer(PointerStyle::DrawRect); +} + +void ConstFormControl::CreateDefaultObject() +{ + Point aStartPos(GetDefaultCenterPos()); + Point aEndPos(aStartPos); + aStartPos.AdjustX( -(2 * MM50) ); + aStartPos.AdjustY( -(MM50) ); + aEndPos.AdjustX(2 * MM50 ); + aEndPos.AdjustY(MM50 ); + + if(!m_pSh->HasDrawView()) + m_pSh->MakeDrawView(); + + SdrView *pSdrView = m_pSh->GetDrawView(); + pSdrView->SetDesignMode(); + m_pSh->BeginCreate( static_cast< sal_uInt16 >(m_pWin->GetSdrDrawMode()), SdrInventor::FmForm, aStartPos); + m_pSh->MoveCreate(aEndPos); + m_pSh->EndCreate(SdrCreateCmd::ForceEnd); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/ribbar/conpoly.cxx b/sw/source/uibase/ribbar/conpoly.cxx new file mode 100644 index 000000000..481722734 --- /dev/null +++ b/sw/source/uibase/ribbar/conpoly.cxx @@ -0,0 +1,103 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <svx/svxids.hrc> +#include <vcl/event.hxx> + +#include <view.hxx> +#include <edtwin.hxx> +#include <wrtsh.hxx> +#include <drawbase.hxx> +#include <conpoly.hxx> + +ConstPolygon::ConstPolygon(SwWrtShell* pWrtShell, SwEditWin* pEditWin, SwView* pSwView) : + SwDrawBase(pWrtShell, pEditWin, pSwView) +{ +} + +bool ConstPolygon::MouseButtonUp(const MouseEvent& rMEvt) +{ + bool bReturn = false; + + if (m_pSh->IsDrawCreate()) + { + if (rMEvt.IsLeft() && rMEvt.GetClicks() == 1 && + m_pWin->GetSdrDrawMode() != OBJ_FREELINE && + m_pWin->GetSdrDrawMode() != OBJ_FREEFILL) + { + if (!m_pSh->EndCreate(SdrCreateCmd::NextPoint)) + { + m_pSh->BreakCreate(); + EnterSelectMode(rMEvt); + return true; + } + } + else + { + bReturn = SwDrawBase::MouseButtonUp(rMEvt); + + // #i85045# removed double mechanism to check for AutoClose polygon + // after construction; the method here did not check for already closed and + // also worked only for a single polygon. Removing. + } + } + else + bReturn = SwDrawBase::MouseButtonUp(rMEvt); + + return bReturn; +} + +void ConstPolygon::Activate(const sal_uInt16 nSlotId) +{ + switch (nSlotId) + { + case SID_DRAW_POLYGON_NOFILL: + case SID_DRAW_XPOLYGON_NOFILL: + m_pWin->SetSdrDrawMode(OBJ_PLIN); + break; + + case SID_DRAW_POLYGON: + case SID_DRAW_XPOLYGON: + m_pWin->SetSdrDrawMode(OBJ_POLY); + break; + + case SID_DRAW_BEZIER_NOFILL: + m_pWin->SetSdrDrawMode(OBJ_PATHLINE); + break; + + case SID_DRAW_BEZIER_FILL: + m_pWin->SetSdrDrawMode(OBJ_PATHFILL); + break; + + case SID_DRAW_FREELINE_NOFILL: + m_pWin->SetSdrDrawMode(OBJ_FREELINE); + break; + + case SID_DRAW_FREELINE: + m_pWin->SetSdrDrawMode(OBJ_FREEFILL); + break; + + default: + break; + } + + SwDrawBase::Activate(nSlotId); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/ribbar/conrect.cxx b/sw/source/uibase/ribbar/conrect.cxx new file mode 100644 index 000000000..3484c4a55 --- /dev/null +++ b/sw/source/uibase/ribbar/conrect.cxx @@ -0,0 +1,214 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sfx2/bindings.hxx> +#include <sfx2/viewfrm.hxx> +#include <svx/sdtacitm.hxx> +#include <svx/svdobj.hxx> +#include <svx/sdtagitm.hxx> +#include <svx/sdtakitm.hxx> +#include <svx/sdtaditm.hxx> +#include <svx/sdtaaitm.hxx> +#include <svx/svdview.hxx> +#include <svx/svdocapt.hxx> +#include <editeng/outlobj.hxx> +#include <cmdid.h> +#include <view.hxx> +#include <edtwin.hxx> +#include <wrtsh.hxx> +#include <drawbase.hxx> +#include <conrect.hxx> + +ConstRectangle::ConstRectangle( SwWrtShell* pWrtShell, SwEditWin* pEditWin, + SwView* pSwView ) + : SwDrawBase( pWrtShell, pEditWin, pSwView ) + , bMarquee(false) + , bCapVertical(false) + , mbVertical(false) +{ +} + +bool ConstRectangle::MouseButtonDown(const MouseEvent& rMEvt) +{ + bool bReturn = SwDrawBase::MouseButtonDown(rMEvt); + + if (bReturn) + { + if (m_pWin->GetSdrDrawMode() == OBJ_CAPTION) + { + m_pView->NoRotate(); + if (m_pView->IsDrawSelMode()) + { + m_pView->FlipDrawSelMode(); + m_pSh->GetDrawView()->SetFrameDragSingles(m_pView->IsDrawSelMode()); + } + } + else + { + SdrObject* pObj = m_pView->GetDrawView()->GetCreateObj(); + if (pObj) + { + SfxItemSet aAttr(pObj->getSdrModelFromSdrObject().GetItemPool()); + SwFEShell::SetLineEnds(aAttr, *pObj, m_nSlotId); + pObj->SetMergedItemSet(aAttr); + } + } + } + + return bReturn; +} + +bool ConstRectangle::MouseButtonUp(const MouseEvent& rMEvt) +{ + bool bRet = SwDrawBase::MouseButtonUp(rMEvt); + if( bRet ) + { + SdrView *pSdrView = m_pSh->GetDrawView(); + const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); + SdrObject* pObj = rMarkList.GetMark(0) ? rMarkList.GetMark(0)->GetMarkedSdrObj() + : nullptr; + switch( m_pWin->GetSdrDrawMode() ) + { + case OBJ_TEXT: + if( bMarquee ) + { + m_pSh->ChgAnchor(RndStdIds::FLY_AS_CHAR); + + if( pObj ) + { + // Set the attributes needed for scrolling + SfxItemSet aItemSet( pSdrView->GetModel()->GetItemPool(), + svl::Items<SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST>{}); + + aItemSet.Put( makeSdrTextAutoGrowWidthItem( false ) ); + aItemSet.Put( makeSdrTextAutoGrowHeightItem( false ) ); + aItemSet.Put( SdrTextAniKindItem( SdrTextAniKind::Scroll ) ); + aItemSet.Put( SdrTextAniDirectionItem( SdrTextAniDirection::Left ) ); + aItemSet.Put( SdrTextAniCountItem( 0 ) ); + aItemSet.Put( SdrTextAniAmountItem( + static_cast<sal_Int16>(m_pWin->PixelToLogic(Size(2,1)).Width())) ); + + pObj->SetMergedItemSetAndBroadcast(aItemSet); + } + } + else if(mbVertical) + { + if (SdrTextObj* pText = dynamic_cast<SdrTextObj*>(pObj)) + { + SfxItemSet aSet(pSdrView->GetModel()->GetItemPool()); + + pText->SetVerticalWriting(true); + + aSet.Put(makeSdrTextAutoGrowWidthItem(true)); + aSet.Put(makeSdrTextAutoGrowHeightItem(false)); + aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP)); + aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT)); + + pText->SetMergedItemSet(aSet); + } + } + + if( pObj ) + { + SdrPageView* pPV = pSdrView->GetSdrPageView(); + m_pView->BeginTextEdit( pObj, pPV, m_pWin, true ); + } + m_pView->LeaveDrawCreate(); // Switch to selection mode + m_pSh->GetView().GetViewFrame()->GetBindings().Invalidate(SID_INSERT_DRAW); + break; + + case OBJ_CAPTION: + { + SdrCaptionObj* pCaptObj = dynamic_cast<SdrCaptionObj*>(pObj); + if( bCapVertical && pCaptObj ) + { + pCaptObj->ForceOutlinerParaObject(); + OutlinerParaObject* pOPO = pCaptObj->GetOutlinerParaObject(); + if( pOPO && !pOPO->IsVertical() ) + pOPO->SetVertical( true ); + } + } + break; + default:; //prevent warning + } + } + return bRet; +} + +void ConstRectangle::Activate(const sal_uInt16 nSlotId) +{ + bMarquee = bCapVertical = false; + mbVertical = false; + + switch (nSlotId) + { + case SID_LINE_ARROW_END: + case SID_LINE_ARROW_CIRCLE: + case SID_LINE_ARROW_SQUARE: + case SID_LINE_ARROW_START: + case SID_LINE_CIRCLE_ARROW: + case SID_LINE_SQUARE_ARROW: + case SID_LINE_ARROWS: + case SID_DRAW_LINE: + case SID_DRAW_XLINE: + m_pWin->SetSdrDrawMode(OBJ_LINE); + break; + + case SID_DRAW_MEASURELINE: + m_pWin->SetSdrDrawMode(OBJ_MEASURE); + break; + + case SID_DRAW_RECT: + m_pWin->SetSdrDrawMode(OBJ_RECT); + break; + + case SID_DRAW_ELLIPSE: + m_pWin->SetSdrDrawMode(OBJ_CIRC); + break; + + case SID_DRAW_TEXT_MARQUEE: + bMarquee = true; + m_pWin->SetSdrDrawMode(OBJ_TEXT); + break; + + case SID_DRAW_TEXT_VERTICAL: + mbVertical = true; + m_pWin->SetSdrDrawMode(OBJ_TEXT); + break; + + case SID_DRAW_TEXT: + m_pWin->SetSdrDrawMode(OBJ_TEXT); + break; + + case SID_DRAW_CAPTION_VERTICAL: + bCapVertical = true; + [[fallthrough]]; + case SID_DRAW_CAPTION: + m_pWin->SetSdrDrawMode(OBJ_CAPTION); + break; + + default: + m_pWin->SetSdrDrawMode(OBJ_NONE); + break; + } + + SwDrawBase::Activate(nSlotId); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/ribbar/drawbase.cxx b/sw/source/uibase/ribbar/drawbase.cxx new file mode 100644 index 000000000..f2b13d8d1 --- /dev/null +++ b/sw/source/uibase/ribbar/drawbase.cxx @@ -0,0 +1,550 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <hintids.hxx> +#include <comphelper/lok.hxx> +#include <svx/svdview.hxx> +#include <svx/svdobj.hxx> +#include <svl/ptitem.hxx> +#include <editeng/sizeitem.hxx> +#include <sfx2/request.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/viewfrm.hxx> +#include <fmtclds.hxx> +#include <frmfmt.hxx> +#include <cmdid.h> +#include <view.hxx> +#include <wrtsh.hxx> +#include <drawbase.hxx> +#include <edtwin.hxx> +#include <swmodule.hxx> +#include <swundo.hxx> +#include <SwCapObjType.hxx> +#include <SwRewriter.hxx> +#include <strings.hrc> + +using namespace ::com::sun::star; + +SwDrawBase::SwDrawBase(SwWrtShell* pSwWrtShell, SwEditWin* pWindow, SwView* pSwView) : + m_pView(pSwView), + m_pSh(pSwWrtShell), + m_pWin(pWindow), + m_nSlotId(USHRT_MAX), + m_bCreateObj(true), + m_bInsForm(false) +{ + if ( !m_pSh->HasDrawView() ) + m_pSh->MakeDrawView(); +} + +SwDrawBase::~SwDrawBase() +{ + if (m_pView->GetWrtShellPtr()) // In the view-dtor could the wrtsh already been deleted... + m_pSh->GetDrawView()->SetEditMode(); +} + +bool SwDrawBase::MouseButtonDown(const MouseEvent& rMEvt) +{ + bool bReturn = false; + + SdrView *pSdrView = m_pSh->GetDrawView(); + + // #i33136# + pSdrView->SetOrtho(doConstructOrthogonal() ? !rMEvt.IsShift() : rMEvt.IsShift()); + pSdrView->SetAngleSnapEnabled(rMEvt.IsShift()); + + if (rMEvt.IsMod2()) + { + pSdrView->SetCreate1stPointAsCenter(true); + pSdrView->SetResizeAtCenter(true); + } + else + { + pSdrView->SetCreate1stPointAsCenter(false); + pSdrView->SetResizeAtCenter(false); + } + + SdrViewEvent aVEvt; + SdrHitKind eHit = pSdrView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt); + + // Only new object, if not in the basic mode (or pure selection mode). + if (rMEvt.IsLeft() && !m_pWin->IsDrawAction()) + { + if (IsCreateObj() && (eHit == SdrHitKind::UnmarkedObject || eHit == SdrHitKind::NONE || m_pSh->IsDrawCreate())) + { + g_bNoInterrupt = true; + m_pWin->CaptureMouse(); + + m_aStartPos = m_pWin->PixelToLogic(rMEvt.GetPosPixel()); + + bReturn = m_pSh->BeginCreate( static_cast< sal_uInt16 >(m_pWin->GetSdrDrawMode()), m_aStartPos); + + SetDrawPointer(); + + if ( bReturn ) + m_pWin->SetDrawAction(true); + } + else if (!pSdrView->IsAction()) + { + // BEZIER-EDITOR + m_pWin->CaptureMouse(); + m_aStartPos = m_pWin->PixelToLogic(rMEvt.GetPosPixel()); + sal_uInt16 nEditMode = m_pWin->GetBezierMode(); + + if (eHit == SdrHitKind::Handle && aVEvt.pHdl->GetKind() == SdrHdlKind::BezierWeight) + { + // Drag handle + g_bNoInterrupt = true; + bReturn = pSdrView->BegDragObj(m_aStartPos, nullptr, aVEvt.pHdl); + m_pWin->SetDrawAction(true); + } + else if (eHit == SdrHitKind::MarkedObject && nEditMode == SID_BEZIER_INSERT) + { + // Insert gluepoint + g_bNoInterrupt = true; + bReturn = pSdrView->BegInsObjPoint(m_aStartPos, rMEvt.IsMod1()); + m_pWin->SetDrawAction(true); + } + else if (eHit == SdrHitKind::MarkedObject && rMEvt.IsMod1()) + { + // Select gluepoint + if (!rMEvt.IsShift()) + pSdrView->UnmarkAllPoints(); + + bReturn = pSdrView->BegMarkPoints(m_aStartPos); + m_pWin->SetDrawAction(true); + } + else if (eHit == SdrHitKind::MarkedObject && !rMEvt.IsShift() && !rMEvt.IsMod2()) + { + // Move object + return false; + } + else if (eHit == SdrHitKind::Handle) + { + // Select gluepoint + if (pSdrView->HasMarkablePoints() && (!pSdrView->IsPointMarked(*aVEvt.pHdl) || rMEvt.IsShift())) + { + SdrHdl* pHdl = nullptr; + + if (!rMEvt.IsShift()) + { + pSdrView->UnmarkAllPoints(); + pHdl = pSdrView->PickHandle(m_aStartPos); + } + else + { + if (pSdrView->IsPointMarked(*aVEvt.pHdl)) + { + bReturn = pSdrView->UnmarkPoint(*aVEvt.pHdl); + pHdl = nullptr; + } + else + { + pHdl = pSdrView->PickHandle(m_aStartPos); + } + } + + if (pHdl) + { + g_bNoInterrupt = true; + pSdrView->MarkPoint(*pHdl); + } + } + } + else + { + // Select or drag object + if (m_pSh->IsObjSelectable(m_aStartPos) && eHit == SdrHitKind::UnmarkedObject) + { + if (pSdrView->HasMarkablePoints()) + pSdrView->UnmarkAllPoints(); + + g_bNoInterrupt = false; + // Use drag in edtwin + return false; + } + + g_bNoInterrupt = true; + + if (m_pSh->IsObjSelected()) + { + if (!rMEvt.IsShift()) + { + if (!pSdrView->HasMarkablePoints()) + { + bool bUnlockView = !m_pSh->IsViewLocked(); + m_pSh->LockView( true ); //lock visible section + m_pSh->SelectObj(Point(LONG_MAX, LONG_MAX)); // deselect all + if( bUnlockView ) + m_pSh->LockView( false ); + } + else + pSdrView->UnmarkAllPoints(); + } + } + if (!m_pSh->IsSelFrameMode()) + m_pSh->EnterSelFrameMode(); + + bReturn = m_pSh->BeginMark(m_aStartPos); + if( bReturn ) + m_pWin->SetDrawAction(true); + + SetDrawPointer(); + } + } + } + return bReturn; +} + +bool SwDrawBase::MouseMove(const MouseEvent& rMEvt) +{ + SdrView *pSdrView = m_pSh->GetDrawView(); + Point aPnt(m_pWin->PixelToLogic(rMEvt.GetPosPixel())); + bool bRet = false; + + if (IsCreateObj() && !m_pWin->IsDrawSelMode() && pSdrView->IsCreateObj()) + { + // #i33136# + pSdrView->SetOrtho(doConstructOrthogonal() ? !rMEvt.IsShift() : rMEvt.IsShift()); + pSdrView->SetAngleSnapEnabled(rMEvt.IsShift()); + + m_pSh->MoveCreate(aPnt); + bRet = true; + } + else if (pSdrView->IsAction() || pSdrView->IsInsObjPoint() || pSdrView->IsMarkPoints()) + { + m_pSh->MoveMark(aPnt); + bRet = true; + } + + return bRet; +} + +bool SwDrawBase::MouseButtonUp(const MouseEvent& rMEvt) +{ + bool bReturn = false; + bool bCheckShell = false; + bool bAutoCap = false; + + Point aPnt(m_pWin->PixelToLogic(rMEvt.GetPosPixel())); + + if (IsCreateObj() && m_pSh->IsDrawCreate() && !m_pWin->IsDrawSelMode()) + { + const SdrObjKind nDrawMode = m_pWin->GetSdrDrawMode(); + //objects with multiple point may end at the start position + bool bMultiPoint = OBJ_PLIN == nDrawMode || + OBJ_POLY == nDrawMode || + OBJ_PATHLINE == nDrawMode || + OBJ_PATHFILL == nDrawMode || + OBJ_FREELINE == nDrawMode || + OBJ_FREEFILL == nDrawMode; + if(rMEvt.IsRight() || (aPnt == m_aStartPos && !bMultiPoint)) + { + m_pSh->BreakCreate(); + m_pView->LeaveDrawCreate(); + } + else + { + if (OBJ_NONE == nDrawMode) + { + SwRewriter aRewriter; + + aRewriter.AddRule(UndoArg1, SwResId(STR_FRAME)); + m_pSh->StartUndo(SwUndoId::INSERT, &aRewriter); + } + + m_pSh->EndCreate(SdrCreateCmd::ForceEnd); + if (OBJ_NONE == nDrawMode) // Text border inserted + { + uno::Reference< frame::XDispatchRecorder > xRecorder = + m_pSh->GetView().GetViewFrame()->GetBindings().GetRecorder(); + if ( xRecorder.is() ) + { + SfxRequest aReq(m_pSh->GetView().GetViewFrame(),FN_INSERT_FRAME); + aReq .AppendItem(SfxUInt16Item( FN_INSERT_FRAME, + static_cast<sal_uInt16>(RndStdIds::FLY_AT_PARA) )); + aReq.AppendItem(SfxPointItem( FN_PARAM_1, m_pSh->GetAnchorObjDiff())); + aReq.AppendItem(SvxSizeItem( FN_PARAM_2, m_pSh->GetObjSize())); + aReq.Done(); + } + bAutoCap = true; + if(m_pWin->GetFrameColCount() > 1) + { + SfxItemSet aSet(m_pView->GetPool(),svl::Items<RES_COL,RES_COL>{}); + SwFormatCol aCol(aSet.Get(RES_COL)); + aCol.Init(m_pWin->GetFrameColCount(), aCol.GetGutterWidth(), aCol.GetWishWidth()); + aSet.Put(aCol); + // Template AutoUpdate + SwFrameFormat* pFormat = m_pSh->GetSelectedFrameFormat(); + if(pFormat && pFormat->IsAutoUpdateFormat()) + m_pSh->AutoUpdateFrame(pFormat, aSet); + else + m_pSh->SetFlyFrameAttr( aSet ); + } + } + if (m_pWin->GetSdrDrawMode() == OBJ_NONE) + { + m_pSh->EndUndo(); + } + } + + bReturn = true; + + EnterSelectMode(rMEvt); + } + else + { + SdrView *pSdrView = m_pSh->GetDrawView(); + + if (!pSdrView->HasMarkablePoints()) + { + // NO BEZIER_EDITOR + if ((m_pSh->GetDrawView()->IsMarkObj() || m_pSh->GetDrawView()->IsMarkPoints()) + && rMEvt.IsLeft()) + { + bReturn = m_pSh->EndMark(); + + m_pWin->SetDrawAction(false); + + if (aPnt == m_aStartPos && m_pSh->IsObjSelectable(aPnt)) + { + m_pSh->SelectObj(aPnt, ( rMEvt.IsShift() && + m_pSh->IsSelFrameMode()) ? SW_ADD_SELECT : 0); + + if (!m_pSh->IsObjSelected()) + { + m_pView->LeaveDrawCreate(); // Switch to selection mode + + m_pSh->GetView().GetViewFrame()->GetBindings().Invalidate(SID_INSERT_DRAW); + + if (m_pSh->IsSelFrameMode()) + m_pSh->LeaveSelFrameMode(); + } + m_pView->NoRotate(); + + bCheckShell = true; // if necessary turn on BezierShell + } + else if (!m_pSh->IsObjSelected() && !m_pWin->IsDrawAction()) + { + if (m_pSh->IsObjSelectable(aPnt)) + m_pSh->SelectObj(aPnt, ( rMEvt.IsShift() && + m_pSh->IsSelFrameMode() ) ? SW_ADD_SELECT : 0 ); + else + { + m_pView->LeaveDrawCreate(); + if (m_pSh->IsSelFrameMode()) + m_pSh->LeaveSelFrameMode(); + } + m_pView->NoRotate(); + + bReturn = true; + } + } + } + else + { + // BEZIER_EDITOR + if ( pSdrView->IsAction() ) + { + if ( pSdrView->IsInsObjPoint() ) + bReturn = pSdrView->EndInsObjPoint(SdrCreateCmd::ForceEnd); + else if (pSdrView->IsMarkPoints() ) + bReturn = pSdrView->EndMarkPoints(); + else + { + pSdrView->EndAction(); + bReturn = true; + } + m_pWin->SetDrawAction(false); + + if (aPnt == m_aStartPos) + { + if (!m_pSh->IsObjSelectable(aPnt)) + m_pSh->SelectObj(Point(LONG_MAX, LONG_MAX)); + else if (!bReturn) + { + if (!rMEvt.IsShift()) + pSdrView->UnmarkAllPoints(); + m_pSh->SelectObj(aPnt, (rMEvt.IsShift() && + m_pSh->IsSelFrameMode()) ? SW_ADD_SELECT :0); + } + + if (!m_pSh->IsObjSelected()) + { + m_pView->LeaveDrawCreate(); // Switch to selection mode + + m_pSh->GetView().GetViewFrame()->GetBindings().Invalidate(SID_INSERT_DRAW); + + if (m_pSh->IsSelFrameMode()) + m_pSh->LeaveSelFrameMode(); + } + m_pView->NoRotate(); + + bCheckShell = true; // if necessary turn on BezierShell + } + } + + SetDrawPointer(); + + if (!m_pSh->IsObjSelected() && !m_pWin->IsDrawAction()) + { + m_pView->LeaveDrawCreate(); + if (m_pSh->IsSelFrameMode()) + m_pSh->LeaveSelFrameMode(); + + m_pView->NoRotate(); + bReturn = true; + } + } + } + + if (bCheckShell) + m_pView->AttrChangedNotify(nullptr); // if necessary turn on BezierShell + + //!!!!!!!!!! Attention suicide !!!!!!!!!!! Everything should be renewed once + if ( bAutoCap ) + m_pView->AutoCaption(FRAME_CAP); //Can currently only be FRAME, otherwise convert + // to enums + return bReturn; +} + +void SwDrawBase::Activate(const sal_uInt16 nSlot) +{ + SetSlotId(nSlot); + SdrView *pSdrView = m_pSh->GetDrawView(); + + pSdrView->SetCurrentObj( static_cast< sal_uInt16 >(m_pWin->GetSdrDrawMode()) ); + pSdrView->SetEditMode(false); + + SetDrawPointer(); + m_pSh->NoEdit(); +} + +void SwDrawBase::Deactivate() +{ + SdrView *pSdrView = m_pSh->GetDrawView(); + pSdrView->SetOrtho(false); + pSdrView->SetAngleSnapEnabled(false); + + if (m_pWin->IsDrawAction() && m_pSh->IsDrawCreate()) + m_pSh->BreakCreate(); + + m_pWin->SetDrawAction(false); + + if (m_pWin->IsMouseCaptured()) + m_pWin->ReleaseMouse(); + g_bNoInterrupt = false; + + if (m_pWin->GetApplyTemplate()) + m_pWin->SetApplyTemplate(SwApplyTemplate()); + m_pSh->GetView().GetViewFrame()->GetBindings().Invalidate(SID_INSERT_DRAW); +} + +// Process keyboard events + +// If a KeyEvent is processed then the return value is true, otherwise +// false. + +void SwDrawBase::BreakCreate() +{ + m_pSh->BreakCreate(); + m_pWin->SetDrawAction(false); + m_pWin->ReleaseMouse(); + + Deactivate(); +} + +void SwDrawBase::SetDrawPointer() +{ + SdrView *pSdrView = m_pSh->GetDrawView(); + Point aPnt(m_pWin->OutputToScreenPixel(m_pWin->GetPointerPosPixel())); + aPnt = m_pWin->PixelToLogic(m_pWin->ScreenToOutputPixel(aPnt)); + PointerStyle aPointTyp = pSdrView->GetPreferredPointer(aPnt, m_pSh->GetOut()); + m_pWin->SetPointer(aPointTyp); +} + +// If necessary switch into selection mode + +void SwDrawBase::EnterSelectMode(const MouseEvent& rMEvt) +{ + m_pWin->SetDrawAction(false); + + if (!m_pSh->IsObjSelected() && !m_pWin->IsDrawAction()) + { + Point aPnt(m_pWin->PixelToLogic(rMEvt.GetPosPixel())); + + if (m_pSh->IsObjSelectable(aPnt)) + { + m_pSh->SelectObj(aPnt); + if (rMEvt.GetModifier() == KEY_SHIFT || !m_pSh->IsObjSelected()) + { + m_pView->LeaveDrawCreate(); // Switch to selection mode + + m_pSh->GetView().GetViewFrame()->GetBindings().Invalidate(SID_INSERT_DRAW); + } + } + else + { + m_pView->LeaveDrawCreate(); + if (m_pSh->IsSelFrameMode()) + m_pSh->LeaveSelFrameMode(); + } + m_pView->NoRotate(); + } +} + +void SwDrawBase::CreateDefaultObject() +{ + Point aStartPos = GetDefaultCenterPos(); + Point aEndPos(aStartPos); + aStartPos.AdjustX( -(6 * MM50) ); + aStartPos.AdjustY( -(6 * MM50) ); + aEndPos.AdjustX(6 * MM50 ); + aEndPos.AdjustY(6 * MM50 ); + tools::Rectangle aRect(aStartPos, aEndPos); + m_pSh->CreateDefaultShape( static_cast< sal_uInt16 >(m_pWin->GetSdrDrawMode()), aRect, m_nSlotId); +} + +Point SwDrawBase::GetDefaultCenterPos() const +{ + Size aDocSz(m_pSh->GetDocSize()); + + SwRect aVisArea(m_pSh->VisArea()); + if (comphelper::LibreOfficeKit::isActive()) + { + aVisArea = m_pSh->getLOKVisibleArea(); + aVisArea.Intersection(SwRect(Point(), aDocSz)); + } + + Point aCenter = aVisArea.Center(); + if (aVisArea.Width() > aDocSz.Width()) + aCenter.setX(aDocSz.Width() / 2 + aVisArea.Left()); + if (aVisArea.Height() > aDocSz.Height()) + aCenter.setY(aDocSz.Height() / 2 + aVisArea.Top()); + + return aCenter; +} + +// #i33136# +bool SwDrawBase::doConstructOrthogonal() const +{ + return ( m_nSlotId == SID_DRAW_XPOLYGON || m_nSlotId == SID_DRAW_XPOLYGON_NOFILL || m_nSlotId == SID_DRAW_XLINE ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/ribbar/dselect.cxx b/sw/source/uibase/ribbar/dselect.cxx new file mode 100644 index 000000000..a70583fda --- /dev/null +++ b/sw/source/uibase/ribbar/dselect.cxx @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sfx2/bindings.hxx> +#include <sfx2/viewfrm.hxx> +#include <view.hxx> +#include <edtwin.hxx> +#include <wrtsh.hxx> +#include <cmdid.h> +#include <drawbase.hxx> +#include <dselect.hxx> + +DrawSelection::DrawSelection(SwWrtShell* pWrtShell, SwEditWin* pEditWin, SwView* pSwView) : + SwDrawBase(pWrtShell, pEditWin, pSwView) +{ + m_bCreateObj = false; +} + +void DrawSelection::Activate(const sal_uInt16 nSlotId) +{ + m_pWin->SetSdrDrawMode(OBJ_NONE); + m_pWin->SetObjectSelect( true ); + SwDrawBase::Activate(nSlotId); + + m_pSh->GetView().GetViewFrame()->GetBindings().Invalidate(SID_INSERT_DRAW); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/ribbar/inputwin.cxx b/sw/source/uibase/ribbar/inputwin.cxx new file mode 100644 index 000000000..841dc4a82 --- /dev/null +++ b/sw/source/uibase/ribbar/inputwin.cxx @@ -0,0 +1,602 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> +#include <sal/log.hxx> + +#include <comphelper/string.hxx> +#include <o3tl/safeint.hxx> +#include <officecfg/Office/Common.hxx> +#include <tools/gen.hxx> +#include <sfx2/objface.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/dispatch.hxx> +#include <svx/ruler.hxx> +#include <svl/stritem.hxx> +#include <vcl/event.hxx> + +#include <swtypes.hxx> +#include <cmdid.h> +#include <swmodule.hxx> +#include <wrtsh.hxx> +#include <view.hxx> +#include <inputwin.hxx> +#include <fldbas.hxx> +#include <fldmgr.hxx> +#include <frmfmt.hxx> +#include <cellatr.hxx> +#include <edtwin.hxx> +#include <helpids.h> +#include <strings.hrc> +#include <bitmaps.hlst> + +// Only for the UpdateRange: Delete the box in which the stacked cursor is positioned. +#include <pam.hxx> + +#include <swundo.hxx> + +#include <IDocumentContentOperations.hxx> + +#define ED_POS 2 +#define ED_FORMULA 3 + +SFX_IMPL_POS_CHILDWINDOW_WITHID( SwInputChild, FN_EDIT_FORMULA, SFX_OBJECTBAR_OBJECT ) + +IMPL_LINK(PosEdit, KeyInputHdl, const KeyEvent&, rKEvt, bool) +{ + return ChildKeyInput(rKEvt); +} + +SwInputWindow::SwInputWindow(vcl::Window* pParent, SfxDispatcher const * pDispatcher) + : ToolBox(pParent, WB_3DLOOK|WB_BORDER) + , mxPos(VclPtr<PosEdit>::Create(this)) + , mxEdit(VclPtr<InputEdit>::Create(this)) + , pWrtShell(nullptr) + , pView(nullptr) + , m_bDoesUndo(true) + , m_bResetUndo(false) + , m_bCallUndo(false) +{ + bFirst = true; + bIsTable = bDelSel = false; + + InsertItem(FN_FORMULA_CALC, Image(StockImage::Yes, RID_BMP_FORMULA_CALC), + SwResId(STR_FORMULA_CALC)); + InsertItem(FN_FORMULA_CANCEL, Image(StockImage::Yes, RID_BMP_FORMULA_CANCEL), + SwResId(STR_FORMULA_CANCEL)); + InsertItem(FN_FORMULA_APPLY, Image(StockImage::Yes, RID_BMP_FORMULA_APPLY), + SwResId(STR_FORMULA_APPLY)); + + SetHelpId(FN_FORMULA_CALC, HID_TBX_FORMULA_CALC); + SetHelpId(FN_FORMULA_CANCEL, HID_TBX_FORMULA_CANCEL); + SetHelpId(FN_FORMULA_APPLY, HID_TBX_FORMULA_APPLY); + + SwView *pDispatcherView = dynamic_cast<SwView*>(pDispatcher ? pDispatcher->GetFrame()->GetViewShell() : nullptr); + SwView* pActiveView = ::GetActiveView(); + if (pDispatcherView == pActiveView) + pView = pActiveView; + pWrtShell = pView ? pView->GetWrtShellPtr() : nullptr; + + InsertWindow(ED_POS, mxPos.get(), ToolBoxItemBits::NONE, 0); + SetItemText(ED_POS, SwResId(STR_ACCESS_FORMULA_TYPE)); + mxPos->set_accessible_name(SwResId(STR_ACCESS_FORMULA_TYPE)); + SetAccessibleName(SwResId(STR_ACCESS_FORMULA_TOOLBAR)); + InsertSeparator ( 1 ); + InsertSeparator (); + InsertWindow(ED_FORMULA, mxEdit.get()); + SetItemText(ED_FORMULA, SwResId(STR_ACCESS_FORMULA_TEXT)); + mxEdit->set_accessible_name(SwResId(STR_ACCESS_FORMULA_TEXT)); + SetHelpId(ED_FORMULA, HID_EDIT_FORMULA); + + SetItemBits( FN_FORMULA_CALC, GetItemBits( FN_FORMULA_CALC ) | ToolBoxItemBits::DROPDOWNONLY ); + SetDropdownClickHdl( LINK( this, SwInputWindow, DropdownClickHdl )); + + Size aSizeTbx = CalcWindowSizePixel(); + Size aEditSize = mxEdit->GetSizePixel(); + tools::Rectangle aItemRect( GetItemRect(FN_FORMULA_CALC) ); + long nMaxHeight = std::max(aEditSize.Height(), aItemRect.GetHeight()); + if( nMaxHeight+2 > aSizeTbx.Height() ) + aSizeTbx.setHeight( nMaxHeight+2 ); + Size aSize = GetSizePixel(); + aSize.setHeight( aSizeTbx.Height() ); + SetSizePixel( aSize ); + + // align edit and item vcentered + Size aPosSize = mxPos->GetSizePixel(); + aPosSize.setHeight( nMaxHeight ); + aEditSize.setHeight( nMaxHeight ); + Point aPosPos = mxPos->GetPosPixel(); + Point aEditPos = mxEdit->GetPosPixel(); + aPosPos.setY( (aSize.Height() - nMaxHeight)/2 + 1 ); + aEditPos.setY( (aSize.Height() - nMaxHeight)/2 + 1 ); + mxPos->SetPosSizePixel( aPosPos, aPosSize ); + mxEdit->SetPosSizePixel( aEditPos, aEditSize ); +} + +SwInputWindow::~SwInputWindow() +{ + disposeOnce(); +} + +void SwInputWindow::dispose() +{ + // wake rulers + if(pView) + { + pView->GetHRuler().SetActive(); + pView->GetVRuler().SetActive(); + } + pMgr.reset(); + if(pWrtShell) + pWrtShell->EndSelTableCells(); + + CleanupUglyHackWithUndo(); + + mxPos.disposeAndClear(); + mxEdit.disposeAndClear(); + ToolBox::dispose(); +} + +void SwInputWindow::CleanupUglyHackWithUndo() +{ + if (m_bResetUndo) + { + if (pWrtShell) + { + DelBoxContent(); + pWrtShell->DoUndo(m_bDoesUndo); + if (m_bCallUndo) + { + pWrtShell->Undo(); + } + } + m_bResetUndo = false; // #i117122# once is enough :) + } +} + +void SwInputWindow::Resize() +{ + ToolBox::Resize(); + + long nWidth = GetSizePixel().Width(); + long nLeft = mxEdit->GetPosPixel().X(); + Size aEditSize = mxEdit->GetSizePixel(); + + aEditSize.setWidth( std::max( static_cast<long>(nWidth - nLeft - 5), long(0) ) ); + mxEdit->SetSizePixel( aEditSize ); +} + +void SwInputWindow::ShowWin() +{ + bIsTable = false; + // stop rulers + if (pView) + { + pView->GetHRuler().SetActive( false ); + pView->GetVRuler().SetActive( false ); + + OSL_ENSURE(pWrtShell, "no WrtShell!"); + // Cursor in table + bIsTable = pWrtShell->IsCursorInTable(); + + if( bFirst ) + pWrtShell->SelTableCells( LINK( this, SwInputWindow, + SelTableCellsNotify) ); + if( bIsTable ) + { + const OUString& rPos = pWrtShell->GetBoxNms(); + sal_Int32 nPos = 0; + short nSrch = -1; + while( (nPos = rPos.indexOf( ':',nPos + 1 ) ) != -1 ) + nSrch = static_cast<short>(nPos); + mxPos->set_text( rPos.copy( ++nSrch ) ); + aCurrentTableName = pWrtShell->GetTableFormat()->GetName(); + } + else + mxPos->set_text(SwResId(STR_TBL_FORMULA)); + + // Edit current field + OSL_ENSURE(pMgr == nullptr, "FieldManager not deleted"); + pMgr.reset(new SwFieldMgr); + + // Form should always begin with "=" , so set here + OUString sEdit('='); + if( pMgr->GetCurField() && SwFieldTypesEnum::Formel == pMgr->GetCurTypeId() ) + { + sEdit += pMgr->GetCurFieldPar2(); + } + else if( bFirst && bIsTable ) + { + m_bResetUndo = true; + SAL_WARN_IF( + officecfg::Office::Common::Undo::Steps::get() <= 0, + "sw", "/org.openoffice.Office.Common/Undo/Steps <= 0"); + + m_bDoesUndo = pWrtShell->DoesUndo(); + if( !m_bDoesUndo ) + { + pWrtShell->DoUndo(); + } + + if( !pWrtShell->SwCursorShell::HasSelection() ) + { + pWrtShell->MoveSection( GoCurrSection, fnSectionStart ); + pWrtShell->SetMark(); + pWrtShell->MoveSection( GoCurrSection, fnSectionEnd ); + } + if( pWrtShell->SwCursorShell::HasSelection() ) + { + pWrtShell->StartUndo( SwUndoId::DELETE ); + pWrtShell->Delete(); + if( SwUndoId::EMPTY != pWrtShell->EndUndo( SwUndoId::DELETE )) + { + m_bCallUndo = true; + } + } + pWrtShell->DoUndo(false); + + SfxItemSet aSet( pWrtShell->GetAttrPool(), svl::Items<RES_BOXATR_FORMULA, RES_BOXATR_FORMULA>{} ); + if( pWrtShell->GetTableBoxFormulaAttrs( aSet )) + sEdit += aSet.Get( RES_BOXATR_FORMULA ).GetFormula(); + } + + if( bFirst ) + { + // Set WrtShell flags correctly + pWrtShell->SttSelect(); + pWrtShell->EndSelect(); + } + + bFirst = false; + + mxEdit->connect_changed( LINK( this, SwInputWindow, ModifyHdl )); + + mxEdit->set_text( sEdit ); + sOldFormula = sEdit; + + // For input cut the UserInterface + + pView->GetEditWin().LockKeyInput(true); + pView->GetViewFrame()->GetDispatcher()->Lock(true); + pWrtShell->Push(); + } + + ToolBox::Show(); + + // grab focus after ToolBox is shown so focus isn't potentially lost elsewhere + if (pView) + { + int nPos = mxEdit->get_text().getLength(); + mxEdit->select_region(nPos, nPos); + mxEdit->GrabFocus(); + } +} + +IMPL_LINK( SwInputWindow, MenuHdl, Menu *, pMenu, bool ) +{ + OString aCommand = pMenu->GetCurItemIdent(); + if (!aCommand.isEmpty()) + { + aCommand += " "; + mxEdit->replace_selection(OStringToOUString(aCommand, RTL_TEXTENCODING_ASCII_US)); + } + return false; +} + +IMPL_LINK_NOARG(SwInputWindow, DropdownClickHdl, ToolBox *, void) +{ + sal_uInt16 nCurID = GetCurItemId(); + EndSelection(); // reset back CurItemId ! + if (nCurID == FN_FORMULA_CALC) + { + VclBuilder aBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "modules/swriter/ui/inputwinmenu.ui", ""); + VclPtr<PopupMenu> aPopMenu(aBuilder.get_menu("menu")); + aPopMenu->SetSelectHdl(LINK(this, SwInputWindow, MenuHdl)); + aPopMenu->Execute(this, GetItemRect(FN_FORMULA_CALC), PopupMenuFlags::NoMouseUpClose); + } +} + +void SwInputWindow::Click( ) +{ + sal_uInt16 nCurID = GetCurItemId(); + EndSelection(); // reset back CurItemId ! + switch ( nCurID ) + { + case FN_FORMULA_CANCEL: + { + CancelFormula(); + } + break; + case FN_FORMULA_APPLY: + { + ApplyFormula(); + } + break; + } +} + +void SwInputWindow::ApplyFormula() +{ + pView->GetViewFrame()->GetDispatcher()->Lock(false); + pView->GetEditWin().LockKeyInput(false); + CleanupUglyHackWithUndo(); + pWrtShell->Pop(SwCursorShell::PopMode::DeleteCurrent); + + // Form should always begin with "=", so remove it here again + OUString sEdit(comphelper::string::strip(mxEdit->get_text(), ' ')); + if( !sEdit.isEmpty() && '=' == sEdit[0] ) + sEdit = sEdit.copy( 1 ); + SfxStringItem aParam(FN_EDIT_FORMULA, sEdit); + + pWrtShell->EndSelTableCells(); + pView->GetEditWin().GrabFocus(); + const SfxPoolItem* aArgs[2]; + aArgs[0] = &aParam; + aArgs[1] = nullptr; + pView->GetViewFrame()->GetBindings().Execute( FN_EDIT_FORMULA, aArgs, SfxCallMode::ASYNCHRON ); +} + +void SwInputWindow::CancelFormula() +{ + if(pView) + { + pView->GetViewFrame()->GetDispatcher()->Lock( false ); + pView->GetEditWin().LockKeyInput(false); + CleanupUglyHackWithUndo(); + pWrtShell->Pop(SwCursorShell::PopMode::DeleteCurrent); + + if( bDelSel ) + pWrtShell->EnterStdMode(); + + pWrtShell->EndSelTableCells(); + + pView->GetEditWin().GrabFocus(); + + pView->GetViewFrame()->GetDispatcher()->Execute( FN_EDIT_FORMULA, SfxCallMode::ASYNCHRON); + } +} + +const sal_Unicode CH_LRE = 0x202a; +const sal_Unicode CH_PDF = 0x202c; + +IMPL_LINK( SwInputWindow, SelTableCellsNotify, SwWrtShell&, rCaller, void ) +{ + if(bIsTable) + { + SwFrameFormat* pTableFormat = rCaller.GetTableFormat(); + OUString sBoxNms( rCaller.GetBoxNms() ); + OUString sTableNm; + if( pTableFormat && aCurrentTableName != pTableFormat->GetName() ) + sTableNm = pTableFormat->GetName(); + + mxEdit->UpdateRange( sBoxNms, sTableNm ); + + OUString sNew = OUStringChar(CH_LRE) + mxEdit->get_text() + + OUStringChar(CH_PDF); + + if( sNew != sOldFormula ) + { + // The WrtShell is in the table selection, + // then cancel the table selection otherwise, the cursor is + // positioned "in the forest" and the live update does not work! + pWrtShell->StartAllAction(); + + SwPaM aPam( *pWrtShell->GetStackCursor()->GetPoint() ); + aPam.Move( fnMoveBackward, GoInSection ); + aPam.SetMark(); + aPam.Move( fnMoveForward, GoInSection ); + + IDocumentContentOperations& rIDCO = pWrtShell->getIDocumentContentOperations(); + rIDCO.DeleteRange( aPam ); + rIDCO.InsertString( aPam, sNew ); + pWrtShell->EndAllAction(); + sOldFormula = sNew; + } + } + else + mxEdit->GrabFocus(); +} + +void SwInputWindow::SetFormula( const OUString& rFormula ) +{ + OUString sEdit('='); + if( !rFormula.isEmpty() ) + { + if( '=' == rFormula[0] ) + sEdit = rFormula; + else + sEdit += rFormula; + } + mxEdit->set_text( sEdit ); + mxEdit->select_region(sEdit.getLength(), sEdit.getLength()); + bDelSel = true; +} + +IMPL_LINK_NOARG(SwInputWindow, ModifyHdl, weld::Entry&, void) +{ + if (bIsTable && m_bResetUndo) + { + pWrtShell->StartAllAction(); + DelBoxContent(); + OUString sNew = OUStringChar(CH_LRE) + mxEdit->get_text() + + OUStringChar(CH_PDF); + pWrtShell->SwEditShell::Insert2( sNew ); + pWrtShell->EndAllAction(); + sOldFormula = sNew; + } +} + +void SwInputWindow::DelBoxContent() +{ + if( bIsTable ) + { + pWrtShell->StartAllAction(); + pWrtShell->ClearMark(); + pWrtShell->Pop(SwCursorShell::PopMode::DeleteCurrent); + pWrtShell->Push(); + pWrtShell->MoveSection( GoCurrSection, fnSectionStart ); + pWrtShell->SetMark(); + pWrtShell->MoveSection( GoCurrSection, fnSectionEnd ); + pWrtShell->SwEditShell::Delete(); + pWrtShell->EndAllAction(); + } +} + +IMPL_LINK(InputEdit, KeyInputHdl, const KeyEvent&, rEvent, bool) +{ + bool bHandled = false; + const vcl::KeyCode aCode = rEvent.GetKeyCode(); + if (aCode == KEY_RETURN || aCode == KEY_F2) + { + bHandled = ActivateHdl(*m_xWidget); + } + else if(aCode == KEY_ESCAPE ) + { + static_cast<SwInputWindow*>(GetParent())->CancelFormula(); + bHandled = true; + } + return bHandled || ChildKeyInput(rEvent); +} + +IMPL_LINK_NOARG(InputEdit, ActivateHdl, weld::Entry&, bool) +{ + static_cast<SwInputWindow*>(GetParent())->ApplyFormula(); + return true; +} + +void InputEdit::UpdateRange(const OUString& rBoxes, + const OUString& rName ) +{ + if( rBoxes.isEmpty() ) + { + GrabFocus(); + return; + } + const sal_Unicode cOpen = '<', cClose = '>', + cOpenBracket = '('; + OUString aPrefix = rName; + if(!rName.isEmpty()) + aPrefix += "."; + OUString aBoxes = aPrefix + rBoxes; + + int nSelStartPos, nSelEndPos; + m_xWidget->get_selection_bounds(nSelStartPos, nSelEndPos); + + Selection aSelection(nSelStartPos, nSelEndPos); + sal_uInt16 nSel = static_cast<sal_uInt16>(aSelection.Len()); + // OS: The following expression ensures that in the overwrite mode, + // the selected closing parenthesis will be not deleted. + if( nSel && ( nSel > 1 || + m_xWidget->get_text()[ static_cast<sal_uInt16>(aSelection.Min()) ] != cClose )) + m_xWidget->cut_clipboard(); + else + aSelection.Max() = aSelection.Min(); + OUString aActText(m_xWidget->get_text()); + const sal_uInt16 nLen = aActText.getLength(); + if( !nLen ) + { + OUString aStr = OUStringChar(cOpen) + aBoxes + OUStringChar(cClose); + m_xWidget->set_text(aStr); + sal_Int32 nPos = aStr.indexOf( cClose ); + OSL_ENSURE(nPos != -1, "delimiter not found"); + ++nPos; + m_xWidget->select_region(nPos, nPos); + } + else + { + bool bFound = false; + sal_Unicode cCh; + sal_uInt16 nPos, nEndPos = 0, nStartPos = static_cast<sal_uInt16>(aSelection.Min()); + if( nStartPos-- ) + { + do { + if( cOpen == (cCh = aActText[ nStartPos ] ) || + cOpenBracket == cCh ) + { + bFound = cCh == cOpen; + break; + } + } while( nStartPos-- > 0 ); + } + if( bFound ) + { + bFound = false; + nEndPos = nStartPos; + while( nEndPos < nLen ) + { + if( cClose == aActText[ nEndPos ] ) + { + bFound = true; + break; + } + ++nEndPos; + } + // Only if the current position lies in the range or right behind. + if( bFound && !( nStartPos < o3tl::make_unsigned(aSelection.Max()) && + static_cast<sal_uInt16>(aSelection.Max()) <= nEndPos + 1 )) + bFound = false; + } + if( bFound ) + { + nPos = ++nStartPos + 1; // We want behind + aActText = aActText.replaceAt( nStartPos, nEndPos - nStartPos, aBoxes ); + nPos = nPos + aBoxes.getLength(); + } + else + { + OUString aTmp = OUStringChar(cOpen) + aBoxes + OUStringChar(cClose); + nPos = static_cast<sal_uInt16>(aSelection.Min()); + aActText = aActText.replaceAt( nPos, 0, aTmp ); + nPos = nPos + aTmp.getLength(); + } + if( m_xWidget->get_text() != aActText ) + { + m_xWidget->set_text(aActText); + m_xWidget->select_region(nPos, nPos); + } + } + GrabFocus(); + +} + +SwInputChild::SwInputChild(vcl::Window* _pParent, + sal_uInt16 nId, + SfxBindings const * pBindings, + SfxChildWinInfo* ) : + SfxChildWindow( _pParent, nId ) +{ + pDispatch = pBindings->GetDispatcher(); + SetWindow(VclPtr<SwInputWindow>::Create(_pParent, pDispatch)); + static_cast<SwInputWindow*>(GetWindow())->ShowWin(); + SetAlignment(SfxChildAlignment::LOWESTTOP); +} + +SwInputChild::~SwInputChild() +{ + if(pDispatch) + pDispatch->Lock(false); +} + +SfxChildWinInfo SwInputChild::GetInfo() const +{ + SfxChildWinInfo aInfo = SfxChildWindow::GetInfo(); + return aInfo; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/ribbar/workctrl.cxx b/sw/source/uibase/ribbar/workctrl.cxx new file mode 100644 index 000000000..3e93d5320 --- /dev/null +++ b/sw/source/uibase/ribbar/workctrl.cxx @@ -0,0 +1,1063 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <i18nutil/unicode.hxx> +#include <vcl/InterimItemWindow.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/viewfrm.hxx> +#include <swmodule.hxx> +#include <view.hxx> +#include <initui.hxx> +#include <docsh.hxx> +#include <gloshdl.hxx> +#include <gloslst.hxx> +#include <workctrl.hxx> +#include <strings.hrc> +#include <cmdid.h> +#include <helpids.h> +#include <wrtsh.hxx> +#include <cppuhelper/queryinterface.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <vcl/event.hxx> +#include <vcl/settings.hxx> +#include <rtl/ustring.hxx> +#include <swabstdlg.hxx> +#include <sfx2/zoomitem.hxx> +#include <vcl/svapp.hxx> +#include <vcl/weldutils.hxx> +#include <svx/dialmgr.hxx> +#include <svx/strings.hrc> +#include <bitmaps.hlst> +#include <toolkit/helper/vclunohelper.hxx> +#include <svx/srchdlg.hxx> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/util/XURLTransformer.hpp> + +// Size check +#define NAVI_ENTRIES 18 + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::frame; + +SFX_IMPL_TOOLBOX_CONTROL( SwTbxAutoTextCtrl, SfxVoidItem ); + +SwTbxAutoTextCtrl::SwTbxAutoTextCtrl( + sal_uInt16 nSlotId, + sal_uInt16 nId, + ToolBox& rTbx ) : + SfxToolBoxControl( nSlotId, nId, rTbx ) +{ + rTbx.SetItemBits( nId, ToolBoxItemBits::DROPDOWN | rTbx.GetItemBits( nId ) ); +} + +SwTbxAutoTextCtrl::~SwTbxAutoTextCtrl() +{ +} + +void SwTbxAutoTextCtrl::CreatePopupWindow() +{ + SwView* pView = ::GetActiveView(); + if(pView && !pView->GetDocShell()->IsReadOnly() && + !pView->GetWrtShell().HasReadonlySel() ) + { + Link<Menu*,bool> aLnk = LINK(this, SwTbxAutoTextCtrl, PopupHdl); + + ScopedVclPtrInstance<PopupMenu> pPopup; + SwGlossaryList* pGlossaryList = ::GetGlossaryList(); + const size_t nGroupCount = pGlossaryList->GetGroupCount(); + for(size_t i = 1; i <= nGroupCount; ++i) + { + OUString sTitle = pGlossaryList->GetGroupTitle(i - 1); + const sal_uInt16 nBlockCount = pGlossaryList->GetBlockCount(i -1); + if(nBlockCount) + { + sal_uInt16 nIndex = static_cast<sal_uInt16>(100*i); + // but insert without extension + pPopup->InsertItem( i, sTitle); + VclPtrInstance<PopupMenu> pSub; + pSub->SetSelectHdl(aLnk); + pPopup->SetPopupMenu(i, pSub); + for(sal_uInt16 j = 0; j < nBlockCount; j++) + { + OUString sLongName(pGlossaryList->GetBlockLongName(i - 1, j)); + OUString sShortName(pGlossaryList->GetBlockShortName(i - 1, j)); + + OUString sEntry = sShortName + " - " + sLongName; + pSub->InsertItem(++nIndex, sEntry); + } + } + } + + ToolBox* pToolBox = &GetToolBox(); + sal_uInt16 nId = GetId(); + pToolBox->SetItemDown( nId, true ); + + pPopup->Execute( pToolBox, pToolBox->GetItemRect( nId ), + (pToolBox->GetAlign() == WindowAlign::Top || pToolBox->GetAlign() == WindowAlign::Bottom) ? + PopupMenuFlags::ExecuteDown : PopupMenuFlags::ExecuteRight ); + + pToolBox->SetItemDown( nId, false ); + } + GetToolBox().EndSelection(); +} + +void SwTbxAutoTextCtrl::StateChanged( sal_uInt16, + SfxItemState, + const SfxPoolItem* pState ) +{ + GetToolBox().EnableItem( GetId(), (GetItemState(pState) != SfxItemState::DISABLED) ); +} + +IMPL_STATIC_LINK(SwTbxAutoTextCtrl, PopupHdl, Menu*, pMenu, bool) +{ + sal_uInt16 nId = pMenu->GetCurItemId(); + + sal_uInt16 nBlock = nId / 100; + + SwGlossaryList* pGlossaryList = ::GetGlossaryList(); + OUString sGroup = pGlossaryList->GetGroupName(nBlock - 1); + OUString sShortName = + pGlossaryList->GetBlockShortName(nBlock - 1, nId - (100 * nBlock) - 1); + + SwGlossaryHdl* pGlosHdl = ::GetActiveView()->GetGlosHdl(); + SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); + ::GlossarySetActGroup fnSetActGroup = pFact->SetGlossaryActGroupFunc(); + if ( fnSetActGroup ) + (*fnSetActGroup)( sGroup ); + pGlosHdl->SetCurGroup(sGroup, true); + pGlosHdl->InsertGlossary(sShortName); + + return false; +} + +// Navigation-Popup +// determine the order of the toolbox items +static sal_uInt16 aNavigationInsertIds[ NAVI_ENTRIES ] = +{ + NID_TBL, + NID_FRM, + NID_GRF, + NID_OLE, + NID_PGE, + NID_OUTL, + NID_MARK, + NID_DRW, + NID_CTRL, + NID_REG, + NID_BKM, + NID_SEL, + NID_FTN, + NID_POSTIT, + NID_SRCH_REP, + NID_INDEX_ENTRY, + NID_TABLE_FORMULA, + NID_TABLE_FORMULA_ERROR +}; + +static OUStringLiteral const aNavigationImgIds[ NAVI_ENTRIES ] = +{ + RID_BMP_RIBBAR_TBL, + RID_BMP_RIBBAR_FRM, + RID_BMP_RIBBAR_GRF, + RID_BMP_RIBBAR_OLE, + RID_BMP_RIBBAR_PGE, + RID_BMP_RIBBAR_OUTL, + RID_BMP_RIBBAR_MARK, + RID_BMP_RIBBAR_DRW, + RID_BMP_RIBBAR_CTRL, + RID_BMP_RIBBAR_REG, + RID_BMP_RIBBAR_BKM, + RID_BMP_RIBBAR_SEL, + RID_BMP_RIBBAR_FTN, + RID_BMP_RIBBAR_POSTIT, + RID_BMP_RIBBAR_REP, + RID_BMP_RIBBAR_ENTRY, + RID_BMP_RIBBAR_FORMULA, + RID_BMP_RIBBAR_ERROR +}; + +static const char* aNavigationStrIds[ NAVI_ENTRIES ] = +{ + ST_TBL, + ST_FRM, + ST_GRF, + ST_OLE, + ST_PGE, + ST_OUTL, + ST_MARK, + ST_DRW, + ST_CTRL, + ST_REG, + ST_BKM, + ST_SEL, + ST_FTN, + ST_POSTIT, + ST_SRCH_REP, + ST_INDEX_ENTRY, + ST_TABLE_FORMULA, + ST_TABLE_FORMULA_ERROR +}; + +// these are global strings +static const char* STR_IMGBTN_ARY[] = +{ + STR_IMGBTN_TBL_DOWN, + STR_IMGBTN_FRM_DOWN, + STR_IMGBTN_PGE_DOWN, + STR_IMGBTN_DRW_DOWN, + STR_IMGBTN_CTRL_DOWN, + STR_IMGBTN_REG_DOWN, + STR_IMGBTN_BKM_DOWN, + STR_IMGBTN_GRF_DOWN, + STR_IMGBTN_OLE_DOWN, + STR_IMGBTN_OUTL_DOWN, + STR_IMGBTN_SEL_DOWN, + STR_IMGBTN_FTN_DOWN, + STR_IMGBTN_MARK_DOWN, + STR_IMGBTN_POSTIT_DOWN, + STR_IMGBTN_SRCH_REP_DOWN, + STR_IMGBTN_INDEX_ENTRY_DOWN, + STR_IMGBTN_TBLFML_DOWN, + STR_IMGBTN_TBLFML_ERR_DOWN, + STR_IMGBTN_TBL_UP, + STR_IMGBTN_FRM_UP, + STR_IMGBTN_PGE_UP, + STR_IMGBTN_DRW_UP, + STR_IMGBTN_CTRL_UP, + STR_IMGBTN_REG_UP, + STR_IMGBTN_BKM_UP, + STR_IMGBTN_GRF_UP, + STR_IMGBTN_OLE_UP, + STR_IMGBTN_OUTL_UP, + STR_IMGBTN_SEL_UP, + STR_IMGBTN_FTN_UP, + STR_IMGBTN_MARK_UP, + STR_IMGBTN_POSTIT_UP, + STR_IMGBTN_SRCH_REP_UP, + STR_IMGBTN_INDEX_ENTRY_UP, + STR_IMGBTN_TBLFML_UP, + STR_IMGBTN_TBLFML_ERR_UP +}; + +static OUString lcl_GetScrollToolTip(bool bNext) +{ + sal_uInt16 nResId = SwView::GetMoveType(); + if (!bNext) + nResId += NID_COUNT; + const char* id = STR_IMGBTN_ARY[nResId - NID_START]; + return id ? SwResId(id): OUString(); +} + +namespace { + +class SwZoomBox_Impl final : public InterimItemWindow +{ + std::unique_ptr<weld::ComboBox> m_xWidget; + sal_uInt16 nSlotId; + bool bRelease; + + DECL_LINK(SelectHdl, weld::ComboBox&, void); + DECL_LINK(KeyInputHdl, const KeyEvent&, bool); + DECL_LINK(ActivateHdl, weld::ComboBox&, bool); + DECL_LINK(FocusOutHdl, weld::Widget&, void); + + void Select(); + + void ReleaseFocus(); + +public: + SwZoomBox_Impl(vcl::Window* pParent, sal_uInt16 nSlot); + + virtual void dispose() override + { + m_xWidget.reset(); + InterimItemWindow::dispose(); + } + + virtual void GetFocus() override + { + if (m_xWidget) + m_xWidget->grab_focus(); + InterimItemWindow::GetFocus(); + } + + void save_value() + { + m_xWidget->save_value(); + } + + void set_entry_text(const OUString& rText) + { + m_xWidget->set_entry_text(rText); + } + + virtual ~SwZoomBox_Impl() override + { + disposeOnce(); + } +}; + +} + +SwZoomBox_Impl::SwZoomBox_Impl(vcl::Window* pParent, sal_uInt16 nSlot) + : InterimItemWindow(pParent, "modules/swriter/ui/zoombox.ui", "ZoomBox") + , m_xWidget(m_xBuilder->weld_combo_box("zoom")) + , nSlotId(nSlot) + , bRelease(true) +{ + m_xWidget->set_help_id(HID_PVIEW_ZOOM_LB); + m_xWidget->set_entry_completion(false); + m_xWidget->connect_changed(LINK(this, SwZoomBox_Impl, SelectHdl)); + m_xWidget->connect_key_press(LINK(this, SwZoomBox_Impl, KeyInputHdl)); + m_xWidget->connect_entry_activate(LINK(this, SwZoomBox_Impl, ActivateHdl)); + m_xWidget->connect_focus_out(LINK(this, SwZoomBox_Impl, FocusOutHdl)); + + const char* const aZoomValues[] = + { RID_SVXSTR_ZOOM_25 , RID_SVXSTR_ZOOM_50 , + RID_SVXSTR_ZOOM_75 , RID_SVXSTR_ZOOM_100 , + RID_SVXSTR_ZOOM_150 , RID_SVXSTR_ZOOM_200 , + RID_SVXSTR_ZOOM_WHOLE_PAGE, RID_SVXSTR_ZOOM_PAGE_WIDTH , + RID_SVXSTR_ZOOM_OPTIMAL_VIEW }; + for(const char* pZoomValue : aZoomValues) + { + OUString sEntry = SvxResId(pZoomValue); + m_xWidget->append_text(sEntry); + } + + int nWidth = m_xWidget->get_pixel_size(SvxResId(RID_SVXSTR_ZOOM_200)).Width(); + m_xWidget->set_entry_width_chars(std::ceil(nWidth / m_xWidget->get_approximate_digit_width())); + + SetSizePixel(m_xWidget->get_preferred_size()); +} + +IMPL_LINK(SwZoomBox_Impl, SelectHdl, weld::ComboBox&, rComboBox, void) +{ + if (rComboBox.changed_by_direct_pick()) // only when picked from the list + Select(); +} + +IMPL_LINK_NOARG(SwZoomBox_Impl, ActivateHdl, weld::ComboBox&, bool) +{ + Select(); + return true; +} + +void SwZoomBox_Impl::Select() +{ + if( FN_PREVIEW_ZOOM == nSlotId ) + { + bool bNonNumeric = true; + + OUString sEntry = m_xWidget->get_active_text().replaceAll("%", ""); + SvxZoomItem aZoom(SvxZoomType::PERCENT,100); + if(sEntry == SvxResId( RID_SVXSTR_ZOOM_PAGE_WIDTH ) ) + aZoom.SetType(SvxZoomType::PAGEWIDTH); + else if(sEntry == SvxResId( RID_SVXSTR_ZOOM_OPTIMAL_VIEW ) ) + aZoom.SetType(SvxZoomType::OPTIMAL); + else if(sEntry == SvxResId( RID_SVXSTR_ZOOM_WHOLE_PAGE) ) + aZoom.SetType(SvxZoomType::WHOLEPAGE); + else + { + bNonNumeric = false; + + sal_uInt16 nZoom = static_cast<sal_uInt16>(sEntry.toInt32()); + if(nZoom < MINZOOM) + nZoom = MINZOOM; + if(nZoom > MAXZOOM) + nZoom = MAXZOOM; + aZoom.SetValue(nZoom); + } + + if (bNonNumeric) + { + // put old value back, in case its effectively the same + // as the picked option and no update to number comes + // back from writer + m_xWidget->set_entry_text(m_xWidget->get_saved_value()); + } + + SfxObjectShell* pCurrentShell = SfxObjectShell::Current(); + + pCurrentShell->GetDispatcher()->ExecuteList(SID_ATTR_ZOOM, + SfxCallMode::ASYNCHRON, { &aZoom }); + } + ReleaseFocus(); +} + +IMPL_LINK(SwZoomBox_Impl, KeyInputHdl, const KeyEvent&, rKEvt, bool) +{ + bool bHandled = false; + + sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode(); + + switch (nCode) + { + case KEY_TAB: + bRelease = false; + Select(); + break; + + case KEY_ESCAPE: + m_xWidget->set_entry_text(m_xWidget->get_saved_value()); + ReleaseFocus(); + bHandled = true; + break; + } + + return bHandled || ChildKeyInput(rKEvt); +} + +IMPL_LINK_NOARG(SwZoomBox_Impl, FocusOutHdl, weld::Widget&, void) +{ + if (!m_xWidget->has_focus()) // a combobox can be comprised of different subwidget so double-check if none of those has focus + m_xWidget->set_entry_text(m_xWidget->get_saved_value()); +} + +void SwZoomBox_Impl::ReleaseFocus() +{ + if ( !bRelease ) + { + bRelease = true; + return; + } + SfxViewShell* pCurSh = SfxViewShell::Current(); + + if ( pCurSh ) + { + vcl::Window* pShellWnd = pCurSh->GetWindow(); + + if ( pShellWnd ) + pShellWnd->GrabFocus(); + } +} + +SFX_IMPL_TOOLBOX_CONTROL( SwPreviewZoomControl, SfxUInt16Item); + +SwPreviewZoomControl::SwPreviewZoomControl( + sal_uInt16 nSlotId, + sal_uInt16 nId, + ToolBox& rTbx) : + SfxToolBoxControl( nSlotId, nId, rTbx ) +{ +} + +SwPreviewZoomControl::~SwPreviewZoomControl() +{ +} + +void SwPreviewZoomControl::StateChanged( sal_uInt16 /*nSID*/, + SfxItemState eState, + const SfxPoolItem* pState ) +{ + sal_uInt16 nId = GetId(); + GetToolBox().EnableItem( nId, (GetItemState(pState) != SfxItemState::DISABLED) ); + SwZoomBox_Impl* pBox = static_cast<SwZoomBox_Impl*>(GetToolBox().GetItemWindow( GetId() )); + if(SfxItemState::DEFAULT <= eState) + { + OUString sZoom(unicode::formatPercent(static_cast<const SfxUInt16Item*>(pState)->GetValue(), + Application::GetSettings().GetUILanguageTag())); + pBox->set_entry_text(sZoom); + pBox->save_value(); + } +} + +VclPtr<InterimItemWindow> SwPreviewZoomControl::CreateItemWindow( vcl::Window *pParent ) +{ + VclPtrInstance<SwZoomBox_Impl> pRet( pParent, GetSlotId() ); + return pRet.get(); +} + +namespace { + +class SwJumpToSpecificBox_Impl final : public InterimItemWindow +{ + std::unique_ptr<weld::Entry> m_xWidget; + + sal_uInt16 nSlotId; + + DECL_LINK(KeyInputHdl, const KeyEvent&, bool); + DECL_LINK(SelectHdl, weld::Entry&, bool); +public: + SwJumpToSpecificBox_Impl(vcl::Window* pParent, sal_uInt16 nSlot); + virtual void dispose() override + { + m_xWidget.reset(); + InterimItemWindow::dispose(); + } + virtual void GetFocus() override + { + if (m_xWidget) + m_xWidget->grab_focus(); + InterimItemWindow::GetFocus(); + } + virtual ~SwJumpToSpecificBox_Impl() override + { + disposeOnce(); + } +}; + +} + +IMPL_LINK(SwJumpToSpecificBox_Impl, KeyInputHdl, const KeyEvent&, rKEvt, bool) +{ + return ChildKeyInput(rKEvt); +} + +SwJumpToSpecificBox_Impl::SwJumpToSpecificBox_Impl(vcl::Window* pParent, sal_uInt16 nSlot) + : InterimItemWindow(pParent, "modules/swriter/ui/jumpposbox.ui", "JumpPosBox") + , m_xWidget(m_xBuilder->weld_entry("jumppos")) + , nSlotId(nSlot) +{ + m_xWidget->connect_key_press(LINK(this, SwJumpToSpecificBox_Impl, KeyInputHdl)); + m_xWidget->connect_activate(LINK(this, SwJumpToSpecificBox_Impl, SelectHdl)); + + SetSizePixel(m_xWidget->get_preferred_size()); +} + +IMPL_LINK_NOARG(SwJumpToSpecificBox_Impl, SelectHdl, weld::Entry&, bool) +{ + OUString sEntry(m_xWidget->get_text()); + SfxUInt16Item aPageNum(nSlotId); + aPageNum.SetValue(static_cast<sal_uInt16>(sEntry.toInt32())); + SfxObjectShell* pCurrentShell = SfxObjectShell::Current(); + pCurrentShell->GetDispatcher()->ExecuteList(nSlotId, SfxCallMode::ASYNCHRON, + { &aPageNum }); + return true; +} + +SFX_IMPL_TOOLBOX_CONTROL( SwJumpToSpecificPageControl, SfxUInt16Item); + +SwJumpToSpecificPageControl::SwJumpToSpecificPageControl( + sal_uInt16 nSlotId, + sal_uInt16 nId, + ToolBox& rTbx) : + SfxToolBoxControl( nSlotId, nId, rTbx ) +{} + +SwJumpToSpecificPageControl::~SwJumpToSpecificPageControl() +{} + +VclPtr<InterimItemWindow> SwJumpToSpecificPageControl::CreateItemWindow( vcl::Window *pParent ) +{ + VclPtrInstance<SwJumpToSpecificBox_Impl> pRet( pParent, GetSlotId() ); + return pRet.get(); +} + +namespace { + +class NavElementBox_Base; +class NavElementBox_Impl; + +class NavElementToolBoxControl : public svt::ToolboxController, + public lang::XServiceInfo +{ + public: + explicit NavElementToolBoxControl( + const css::uno::Reference< css::uno::XComponentContext >& rServiceManager ); + + // XInterface + virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) override; + virtual void SAL_CALL acquire() throw () override; + virtual void SAL_CALL release() throw () override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XComponent + virtual void SAL_CALL dispose() override; + + // XStatusListener + virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& Event ) override; + + // XToolbarController + virtual void SAL_CALL execute( sal_Int16 KeyModifier ) override; + virtual void SAL_CALL click() override; + virtual void SAL_CALL doubleClick() override; + virtual css::uno::Reference< css::awt::XWindow > SAL_CALL createPopupWindow() override; + virtual css::uno::Reference< css::awt::XWindow > SAL_CALL createItemWindow( const css::uno::Reference< css::awt::XWindow >& Parent ) override; + + void dispatchCommand( const css::uno::Sequence< css::beans::PropertyValue >& rArgs ); + using svt::ToolboxController::dispatchCommand; + + private: + VclPtr<NavElementBox_Impl> m_xVclBox; + std::unique_ptr<NavElementBox_Base> m_xWeldBox; + NavElementBox_Base* m_pBox; +}; + +class NavElementBox_Base +{ +public: + NavElementBox_Base(std::unique_ptr<weld::ComboBox> xWidget, + const uno::Reference<frame::XFrame>& _xFrame, + NavElementToolBoxControl& rCtrl); + + virtual ~NavElementBox_Base() + { + } + + void set_sensitive(bool bSensitive) + { + m_xWidget->set_sensitive(bSensitive); + } + + void UpdateBox(); + +protected: + std::unique_ptr<weld::ComboBox> m_xWidget; + NavElementToolBoxControl* m_pCtrl; + bool m_bRelease; + uno::Reference< frame::XFrame > m_xFrame; + + virtual bool DoKeyInput(const KeyEvent& rKEvt); + + DECL_LINK(SelectHdl, weld::ComboBox&, void); + DECL_LINK(KeyInputHdl, const KeyEvent&, bool); + + void ReleaseFocus_Impl(); +}; + + +class NavElementBox_Impl final : public InterimItemWindow + , public NavElementBox_Base +{ +public: + NavElementBox_Impl(vcl::Window* pParent, + const uno::Reference<frame::XFrame>& _xFrame, + NavElementToolBoxControl& rCtrl); + + virtual void dispose() override + { + m_xWidget.reset(); + InterimItemWindow::dispose(); + } + + virtual void GetFocus() override + { + if (m_xWidget) + m_xWidget->grab_focus(); + InterimItemWindow::GetFocus(); + } + + virtual bool DoKeyInput(const KeyEvent& rKEvt) override; + + virtual ~NavElementBox_Impl() override + { + disposeOnce(); + } +}; + +} + +NavElementBox_Base::NavElementBox_Base( + std::unique_ptr<weld::ComboBox> xWidget, + const uno::Reference< frame::XFrame >& _xFrame, + NavElementToolBoxControl& _rCtrl ) + : m_xWidget(std::move(xWidget)) + , m_pCtrl(&_rCtrl) + , m_bRelease(true) + , m_xFrame(_xFrame) +{ + m_xWidget->set_size_request(150, -1); + + m_xWidget->make_sorted(); + m_xWidget->freeze(); + for (sal_uInt16 i = 0; i < NID_COUNT; i++) + m_xWidget->append(OUString::number(aNavigationInsertIds[i]), SwResId(aNavigationStrIds[i]), aNavigationImgIds[i]); + m_xWidget->thaw(); + + m_xWidget->connect_changed(LINK(this, NavElementBox_Base, SelectHdl)); + m_xWidget->connect_key_press(LINK(this, NavElementBox_Base, KeyInputHdl)); +} + +NavElementBox_Impl::NavElementBox_Impl( + vcl::Window* _pParent, + const uno::Reference< frame::XFrame >& _xFrame, + NavElementToolBoxControl& _rCtrl ) + : InterimItemWindow(_pParent, "modules/swriter/ui/combobox.ui", "ComboBox") + , NavElementBox_Base(m_xBuilder->weld_combo_box("combobox"), _xFrame, _rCtrl) +{ + SetSizePixel(m_xContainer->get_preferred_size()); +} + +void NavElementBox_Base::ReleaseFocus_Impl() +{ + if ( !m_bRelease ) + { + m_bRelease = true; + return; + } + + if ( m_xFrame.is() && m_xFrame->getContainerWindow().is() ) + m_xFrame->getContainerWindow()->setFocus(); +} + +IMPL_LINK(NavElementBox_Base, SelectHdl, weld::ComboBox&, rComboBox, void) +{ + if (rComboBox.changed_by_direct_pick()) // only when picked from the list + { + SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty ); + + sal_uInt16 nMoveType = rComboBox.get_active_id().toUInt32(); + SwView::SetMoveType( nMoveType ); + + css::uno::Sequence< css::beans::PropertyValue > aArgs; + + /* #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call. + This instance may be deleted in the meantime (i.e. when a dialog is opened + while in Dispatch()), accessing members will crash in this case. */ + ReleaseFocus_Impl(); + + m_pCtrl->dispatchCommand( aArgs ); + } +} + +void NavElementBox_Base::UpdateBox() +{ + sal_uInt16 nMoveType = SwView::GetMoveType(); + for ( size_t i = 0; i < SAL_N_ELEMENTS( aNavigationInsertIds ); ++i ) + { + if ( nMoveType == aNavigationInsertIds[i] ) + { + const char* id = aNavigationStrIds[i]; + OUString sText = SwResId( id ); + m_xWidget->set_active_text(sText); + break; + } + } +} + +IMPL_LINK(NavElementBox_Base, KeyInputHdl, const KeyEvent&, rKEvt, bool) +{ + return DoKeyInput(rKEvt); +} + +bool NavElementBox_Base::DoKeyInput(const KeyEvent& rKEvt) +{ + bool bHandled = false; + + vcl::KeyCode aKeyCode = rKEvt.GetKeyCode(); + sal_uInt16 nCode = aKeyCode.GetCode(); + + switch ( nCode ) + { + case KEY_TAB: + { + m_bRelease = false; + SelectHdl(*m_xWidget); + break; + } + case KEY_RETURN: + { + bHandled = true; + SelectHdl(*m_xWidget); + break; + } + case KEY_ESCAPE: + ReleaseFocus_Impl(); + bHandled = true; + break; + } + + return bHandled; +} + +bool NavElementBox_Impl::DoKeyInput(const KeyEvent& rKEvt) +{ + return NavElementBox_Base::DoKeyInput(rKEvt) || ChildKeyInput(rKEvt); +} + + +NavElementToolBoxControl::NavElementToolBoxControl( const uno::Reference< uno::XComponentContext >& rxContext ) + : svt::ToolboxController( rxContext, + uno::Reference< frame::XFrame >(), + ".uno:NavElement" ), + m_pBox( nullptr ) +{ +} + +// XInterface +css::uno::Any SAL_CALL NavElementToolBoxControl::queryInterface( const css::uno::Type& aType ) +{ + uno::Any a = ToolboxController::queryInterface( aType ); + if ( a.hasValue() ) + return a; + + return ::cppu::queryInterface( aType, static_cast< lang::XServiceInfo* >( this ) ); +} + +void SAL_CALL NavElementToolBoxControl::acquire() throw () +{ + ToolboxController::acquire(); +} + +void SAL_CALL NavElementToolBoxControl::release() throw () +{ + ToolboxController::release(); +} + +// XServiceInfo +sal_Bool SAL_CALL NavElementToolBoxControl::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService( this, ServiceName ); +} + +OUString SAL_CALL NavElementToolBoxControl::getImplementationName() +{ + return "lo.writer.NavElementToolBoxController"; +} + +uno::Sequence< OUString > SAL_CALL NavElementToolBoxControl::getSupportedServiceNames() +{ + return { "com.sun.star.frame.ToolbarController" }; +} + +// XComponent +void SAL_CALL NavElementToolBoxControl::dispose() +{ + svt::ToolboxController::dispose(); + + SolarMutexGuard aSolarMutexGuard; + m_xVclBox.disposeAndClear(); + m_xWeldBox.reset(); + m_pBox = nullptr; +} + +// XStatusListener +void SAL_CALL NavElementToolBoxControl::statusChanged( const frame::FeatureStateEvent& rEvent ) +{ + if (m_pBox) + { + SolarMutexGuard aSolarMutexGuard; + if ( rEvent.FeatureURL.Path == "NavElement" ) + { + if ( rEvent.IsEnabled ) + { + m_pBox->set_sensitive(true); + m_pBox->UpdateBox(); + } + else + m_pBox->set_sensitive(true); + } + } +} + +// XToolbarController +void SAL_CALL NavElementToolBoxControl::execute( sal_Int16 /*KeyModifier*/ ) +{ +} + +void SAL_CALL NavElementToolBoxControl::click() +{ +} + +void SAL_CALL NavElementToolBoxControl::doubleClick() +{ +} + +uno::Reference< awt::XWindow > SAL_CALL NavElementToolBoxControl::createPopupWindow() +{ + return uno::Reference< awt::XWindow >(); +} + +uno::Reference< awt::XWindow > SAL_CALL NavElementToolBoxControl::createItemWindow( + const uno::Reference< awt::XWindow >& xParent ) +{ + uno::Reference< awt::XWindow > xItemWindow; + + if (m_pBuilder) + { + SolarMutexGuard aSolarMutexGuard; + + std::unique_ptr<weld::ComboBox> xWidget(m_pBuilder->weld_combo_box("NavElementWidget")); + + xItemWindow = css::uno::Reference<css::awt::XWindow>(new weld::TransportAsXWindow(xWidget.get())); + + m_xWeldBox.reset(new NavElementBox_Base(std::move(xWidget), m_xFrame, *this)); + m_pBox = m_xWeldBox.get(); + } + else + { + VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow( xParent ); + if ( pParent ) + { + SolarMutexGuard aSolarMutexGuard; + m_xVclBox = VclPtr<NavElementBox_Impl>::Create( pParent, m_xFrame, *this ); + m_pBox = m_xVclBox.get(); + xItemWindow = VCLUnoHelper::GetInterface(m_xVclBox); + } + } + + return xItemWindow; +} + +void NavElementToolBoxControl::dispatchCommand( + const uno::Sequence< beans::PropertyValue >& rArgs ) +{ + uno::Reference< frame::XDispatchProvider > xDispatchProvider( m_xFrame, uno::UNO_QUERY ); + if ( xDispatchProvider.is() ) + { + util::URL aURL; + uno::Reference< frame::XDispatch > xDispatch; + uno::Reference< util::XURLTransformer > xURLTransformer = getURLTransformer(); + + aURL.Complete = ".uno:NavElement"; + xURLTransformer->parseStrict( aURL ); + xDispatch = xDispatchProvider->queryDispatch( aURL, OUString(), 0 ); + if ( xDispatch.is() ) + xDispatch->dispatch( aURL, rArgs ); + } +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +lo_writer_NavElementToolBoxController_get_implementation( + css::uno::XComponentContext *rxContext, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire( new NavElementToolBoxControl( rxContext ) ); +} + +namespace { + +class PrevNextScrollToolboxController : public svt::ToolboxController, + public css::lang::XServiceInfo +{ +public: + enum Type { PREVIOUS, NEXT }; + + PrevNextScrollToolboxController( const css::uno::Reference< css::uno::XComponentContext >& rxContext, Type eType ); + + // XInterface + virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) override; + virtual void SAL_CALL acquire() throw () override; + virtual void SAL_CALL release() throw () override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XComponent + virtual void SAL_CALL dispose() override; + + // XStatusListener + virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override; + +private: + Type meType; +}; + +} + +PrevNextScrollToolboxController::PrevNextScrollToolboxController( const css::uno::Reference< css::uno::XComponentContext > & rxContext, Type eType ) + : svt::ToolboxController( rxContext, + css::uno::Reference< css::frame::XFrame >(), + (eType == PREVIOUS) ? OUString( ".uno:ScrollToPrevious" ): OUString( ".uno:ScrollToNext" ) ), + meType( eType ) +{ + addStatusListener(".uno:NavElement"); +} + +// XInterface +css::uno::Any SAL_CALL PrevNextScrollToolboxController::queryInterface( const css::uno::Type& aType ) +{ + css::uno::Any a = ToolboxController::queryInterface( aType ); + if ( a.hasValue() ) + return a; + + return ::cppu::queryInterface( aType, static_cast< css::lang::XServiceInfo* >( this ) ); +} + +void SAL_CALL PrevNextScrollToolboxController::acquire() throw () +{ + ToolboxController::acquire(); +} + +void SAL_CALL PrevNextScrollToolboxController::release() throw () +{ + ToolboxController::release(); +} + +// XServiceInfo +OUString SAL_CALL PrevNextScrollToolboxController::getImplementationName() +{ + return meType == PrevNextScrollToolboxController::PREVIOUS? + OUString( "lo.writer.PreviousScrollToolboxController" ) : + OUString( "lo.writer.NextScrollToolboxController" ); +} + +sal_Bool SAL_CALL PrevNextScrollToolboxController::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService(this, ServiceName); +} + +css::uno::Sequence< OUString > SAL_CALL PrevNextScrollToolboxController::getSupportedServiceNames() +{ + return { "com.sun.star.frame.ToolbarController" }; +} + +// XComponent +void SAL_CALL PrevNextScrollToolboxController::dispose() +{ + SolarMutexGuard aSolarMutexGuard; + + svt::ToolboxController::dispose(); +} + +// XStatusListener +void SAL_CALL PrevNextScrollToolboxController::statusChanged( const css::frame::FeatureStateEvent& rEvent ) +{ + if (rEvent.FeatureURL.Path == "NavElement") + { + if (m_pToolbar) + m_pToolbar->set_item_tooltip_text(m_aCommandURL.toUtf8(), lcl_GetScrollToolTip(meType != PrevNextScrollToolboxController::PREVIOUS)); + else + { + ToolBox* pToolBox = nullptr; + sal_uInt16 nId = 0; + if (getToolboxId(nId, &pToolBox)) + pToolBox->SetQuickHelpText(nId, lcl_GetScrollToolTip(meType != PrevNextScrollToolboxController::PREVIOUS)); + } + } +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +lo_writer_PreviousScrollToolboxController_get_implementation( + css::uno::XComponentContext *context, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire( new PrevNextScrollToolboxController( context, PrevNextScrollToolboxController::PREVIOUS ) ); +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +lo_writer_NextScrollToolboxController_get_implementation( + css::uno::XComponentContext *context, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire( new PrevNextScrollToolboxController( context, PrevNextScrollToolboxController::NEXT ) ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |