summaryrefslogtreecommitdiff
path: root/sw/source/uibase/wrtsh
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2014-05-26 17:43:14 +0200
committerMichael Stahl <mstahl@redhat.com>2014-05-27 11:13:02 +0200
commit35029b250318b3a4f02cef5194abdd3f68311c43 (patch)
tree5026ab2dab620dcdcae84e574483ce3c325e5a78 /sw/source/uibase/wrtsh
parentf8d26c68e48e52265d4f20a1527bf52828c046ad (diff)
sw: move sw/source/core/uibase to sw/source/uibase
It's too confusing to have UI code inside of core; the important part is that it's separated from the optional UI code in swui library. Change-Id: I640a52723d5802faf08f3b8eaa03cd937fd93449
Diffstat (limited to 'sw/source/uibase/wrtsh')
-rw-r--r--sw/source/uibase/wrtsh/delete.cxx533
-rw-r--r--sw/source/uibase/wrtsh/move.cxx689
-rw-r--r--sw/source/uibase/wrtsh/navmgr.cxx228
-rw-r--r--sw/source/uibase/wrtsh/select.cxx966
-rw-r--r--sw/source/uibase/wrtsh/wrtsh.hrc39
-rw-r--r--sw/source/uibase/wrtsh/wrtsh.src46
-rw-r--r--sw/source/uibase/wrtsh/wrtsh1.cxx1801
-rw-r--r--sw/source/uibase/wrtsh/wrtsh2.cxx542
-rw-r--r--sw/source/uibase/wrtsh/wrtsh3.cxx227
-rw-r--r--sw/source/uibase/wrtsh/wrtsh4.cxx238
-rw-r--r--sw/source/uibase/wrtsh/wrtundo.cxx154
11 files changed, 5463 insertions, 0 deletions
diff --git a/sw/source/uibase/wrtsh/delete.cxx b/sw/source/uibase/wrtsh/delete.cxx
new file mode 100644
index 000000000000..dcb9d4c52d0c
--- /dev/null
+++ b/sw/source/uibase/wrtsh/delete.cxx
@@ -0,0 +1,533 @@
+/* -*- 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 <wrtsh.hxx>
+#include <crsskip.hxx>
+#include <swcrsr.hxx>
+#include <editeng/lrspitem.hxx>
+// #134369#
+#include <view.hxx>
+#include <drawbase.hxx>
+
+inline void SwWrtShell::OpenMark()
+{
+ StartAllAction();
+ ResetCursorStack();
+ KillPams();
+ SetMark();
+}
+
+inline void SwWrtShell::CloseMark( bool bOkFlag )
+{
+ if( bOkFlag )
+ UpdateAttr();
+ else
+ SwapPam();
+
+ ClearMark();
+ EndAllAction();
+}
+
+// #i23725#
+bool SwWrtShell::TryRemoveIndent()
+{
+ bool bResult = false;
+
+ SfxItemSet aAttrSet(GetAttrPool(), RES_LR_SPACE, RES_LR_SPACE);
+ GetCurAttr(aAttrSet);
+
+ SvxLRSpaceItem aItem = (const SvxLRSpaceItem &)aAttrSet.Get(RES_LR_SPACE);
+ short aOldFirstLineOfst = aItem.GetTxtFirstLineOfst();
+
+ if (aOldFirstLineOfst > 0)
+ {
+ aItem.SetTxtFirstLineOfst(0);
+ bResult = true;
+ }
+ else if (aOldFirstLineOfst < 0)
+ {
+ aItem.SetTxtFirstLineOfst(0);
+ aItem.SetLeft(aItem.GetLeft() + aOldFirstLineOfst);
+
+ bResult = true;
+ }
+ else if (aItem.GetLeft() != 0)
+ {
+ aItem.SetLeft(0);
+ bResult = true;
+ }
+
+ if (bResult)
+ {
+ aAttrSet.Put(aItem);
+ SetAttrSet(aAttrSet);
+ }
+
+ return bResult;
+}
+
+/** Description: Erase the line. */
+
+long SwWrtShell::DelLine()
+{
+ SwActContext aActContext(this);
+ ResetCursorStack();
+ // remember the old cursor
+ Push();
+ ClearMark();
+ SwCrsrShell::LeftMargin();
+ SetMark();
+ SwCrsrShell::RightMargin();
+
+ long nRet = Delete();
+ Pop(false);
+ if( nRet )
+ UpdateAttr();
+ return nRet;
+}
+
+long SwWrtShell::DelToStartOfLine()
+{
+ OpenMark();
+ SwCrsrShell::LeftMargin();
+ long nRet = Delete();
+ CloseMark( 0 != nRet );
+ return nRet;
+}
+
+long SwWrtShell::DelToEndOfLine()
+{
+ OpenMark();
+ SwCrsrShell::RightMargin();
+ long nRet = Delete();
+ CloseMark( 0 != nRet );
+ return 1;
+}
+
+long SwWrtShell::DelLeft()
+{
+ // If it's a Fly, throw it away
+ int nSelType = GetSelectionType();
+ const int nCmp = nsSelectionType::SEL_FRM | nsSelectionType::SEL_GRF | nsSelectionType::SEL_OLE | nsSelectionType::SEL_DRW;
+ if( nCmp & nSelType )
+ {
+ // #108205# Remember object's position.
+ Point aTmpPt = GetObjRect().TopLeft();
+
+ DelSelectedObj();
+
+ // #108205# Set cursor to remembered position.
+ SetCrsr(&aTmpPt);
+
+ LeaveSelFrmMode();
+ UnSelectFrm();
+
+ nSelType = GetSelectionType();
+ if ( nCmp & nSelType )
+ {
+ EnterSelFrmMode();
+ GotoNextFly();
+ }
+
+ return 1L;
+ }
+
+ // If a selection exists, erase this
+ if ( IsSelection() )
+ {
+ if( !IsBlockMode() || HasSelection() )
+ {
+ //OS: Once again Basic: SwActContext must be leaved
+ //before EnterStdMode!
+ {
+ SwActContext aActContext(this);
+ ResetCursorStack();
+ Delete();
+ UpdateAttr();
+ }
+ if( IsBlockMode() )
+ {
+ NormalizePam();
+ ClearMark();
+ EnterBlockMode();
+ }
+ else
+ EnterStdMode();
+ return 1L;
+ }
+ else
+ EnterStdMode();
+ }
+
+ // JP 29.06.95: never erase a table standing in front of it.
+ bool bSwap = false;
+ const SwTableNode * pWasInTblNd = SwCrsrShell::IsCrsrInTbl();
+
+ if( SwCrsrShell::IsSttPara())
+ {
+ // #i4032# Don't actually call a 'delete' if we
+ // changed the table cell, compare DelRight().
+ const SwStartNode * pSNdOld = pWasInTblNd ?
+ GetSwCrsr()->GetNode()->FindTableBoxStartNode() :
+ 0;
+
+ // If the cursor is at the beginning of a paragraph, try to step
+ // backwards. On failure we are done.
+ if( !SwCrsrShell::Left(1,CRSR_SKIP_CHARS) )
+ return 0;
+
+ // If the cursor entered or left a table (or both) we are done. No step
+ // back.
+ const SwTableNode* pIsInTblNd = SwCrsrShell::IsCrsrInTbl();
+ if( pIsInTblNd != pWasInTblNd )
+ return 0;
+
+ const SwStartNode* pSNdNew = pIsInTblNd ?
+ GetSwCrsr()->GetNode()->FindTableBoxStartNode() :
+ 0;
+
+ // #i4032# Don't actually call a 'delete' if we
+ // changed the table cell, compare DelRight().
+ if ( pSNdOld != pSNdNew )
+ return 0;
+
+ OpenMark();
+ SwCrsrShell::Right(1,CRSR_SKIP_CHARS);
+ SwCrsrShell::SwapPam();
+ bSwap = true;
+ }
+ else
+ {
+ OpenMark();
+ SwCrsrShell::Left(1,CRSR_SKIP_CHARS);
+ }
+ long nRet = Delete();
+ if( !nRet && bSwap )
+ SwCrsrShell::SwapPam();
+ CloseMark( 0 != nRet );
+ return nRet;
+}
+
+long SwWrtShell::DelRight()
+{
+ // Will be or'ed, if a tableselection exists;
+ // will here be implemented on nsSelectionType::SEL_TBL
+ long nRet = 0;
+ int nSelection = GetSelectionType();
+ if(nSelection & nsSelectionType::SEL_TBL_CELLS)
+ nSelection = nsSelectionType::SEL_TBL;
+ if(nSelection & nsSelectionType::SEL_TXT)
+ nSelection = nsSelectionType::SEL_TXT;
+
+ const SwTableNode * pWasInTblNd = NULL;
+
+ switch( nSelection & ~(nsSelectionType::SEL_BEZ) )
+ {
+ case nsSelectionType::SEL_POSTIT:
+ case nsSelectionType::SEL_TXT:
+ case nsSelectionType::SEL_TBL:
+ case nsSelectionType::SEL_NUM:
+ // If a selection exists, erase it.
+ if( IsSelection() )
+ {
+ if( !IsBlockMode() || HasSelection() )
+ {
+ //OS: And once again Basic: SwActContext must be
+ //leaved before EnterStdMode !
+ {
+ SwActContext aActContext(this);
+ ResetCursorStack();
+ Delete();
+ UpdateAttr();
+ }
+ if( IsBlockMode() )
+ {
+ NormalizePam();
+ ClearMark();
+ EnterBlockMode();
+ }
+ else
+ EnterStdMode();
+ nRet = 1L;
+ break;
+ }
+ else
+ EnterStdMode();
+ }
+
+ pWasInTblNd = IsCrsrInTbl();
+
+ if( nsSelectionType::SEL_TXT & nSelection && SwCrsrShell::IsSttPara() &&
+ SwCrsrShell::IsEndPara() )
+ {
+ // save cursor
+ SwCrsrShell::Push();
+
+ bool bDelFull = false;
+ if ( SwCrsrShell::Right(1,CRSR_SKIP_CHARS) )
+ {
+ const SwTableNode * pCurrTblNd = IsCrsrInTbl();
+ bDelFull = pCurrTblNd && pCurrTblNd != pWasInTblNd;
+ }
+
+ // restore cursor
+ SwCrsrShell::Pop( false );
+
+ if( bDelFull )
+ {
+ DelFullPara();
+ UpdateAttr();
+ break;
+ }
+ }
+
+ {
+ // #108049# Save the startnode of the current cell
+ const SwStartNode * pSNdOld;
+ pSNdOld = GetSwCrsr()->GetNode()->
+ FindTableBoxStartNode();
+
+ if ( SwCrsrShell::IsEndPara() )
+ {
+ // #i41424# Introduced a couple of
+ // Push()-Pop() pairs here. The reason for this is that a
+ // Right()-Left() combination does not make sure, that
+ // the cursor will be in its initial state, because there
+ // may be a numbering in front of the next paragraph.
+ SwCrsrShell::Push();
+
+ if ( SwCrsrShell::Right(1, CRSR_SKIP_CHARS) )
+ {
+ if (IsCrsrInTbl() || (pWasInTblNd != IsCrsrInTbl()))
+ {
+ /** #108049# Save the startnode of the current
+ cell. May be different to pSNdOld as we have
+ moved. */
+ const SwStartNode * pSNdNew = GetSwCrsr()
+ ->GetNode()->FindTableBoxStartNode();
+
+ /** #108049# Only move instead of deleting if we
+ have moved to a different cell */
+ if (pSNdOld != pSNdNew)
+ {
+ SwCrsrShell::Pop( true );
+ break;
+ }
+ }
+ }
+
+ // restore cursor
+ SwCrsrShell::Pop( false );
+ }
+ }
+
+ OpenMark();
+ SwCrsrShell::Right(1,CRSR_SKIP_CELLS);
+ nRet = Delete();
+ CloseMark( 0 != nRet );
+ break;
+
+ case nsSelectionType::SEL_FRM:
+ case nsSelectionType::SEL_GRF:
+ case nsSelectionType::SEL_OLE:
+ case nsSelectionType::SEL_DRW:
+ case nsSelectionType::SEL_DRW_TXT:
+ case nsSelectionType::SEL_DRW_FORM:
+ {
+ // #108205# Remember object's position.
+ Point aTmpPt = GetObjRect().TopLeft();
+
+ DelSelectedObj();
+
+ // #108205# Set cursor to remembered position.
+ SetCrsr(&aTmpPt);
+
+ LeaveSelFrmMode();
+ UnSelectFrm();
+ // #134369#
+ OSL_ENSURE( !IsFrmSelected(),
+ "<SwWrtShell::DelRight(..)> - <SwWrtShell::UnSelectFrm()> should unmark all objects" );
+ // #134369#
+ // leave draw mode, if necessary.
+ {
+ if (GetView().GetDrawFuncPtr())
+ {
+ GetView().GetDrawFuncPtr()->Deactivate();
+ GetView().SetDrawFuncPtr(NULL);
+ }
+ if ( GetView().IsDrawMode() )
+ {
+ GetView().LeaveDrawCreate();
+ }
+ }
+ }
+
+ // #134369#
+ // <IsFrmSelected()> can't be true - see above.
+ {
+ nSelection = GetSelectionType();
+ if ( nsSelectionType::SEL_FRM & nSelection ||
+ nsSelectionType::SEL_GRF & nSelection ||
+ nsSelectionType::SEL_OLE & nSelection ||
+ nsSelectionType::SEL_DRW & nSelection )
+ {
+ EnterSelFrmMode();
+ GotoNextFly();
+ }
+ }
+ nRet = 1;
+ break;
+ }
+ return nRet;
+}
+
+long SwWrtShell::DelToEndOfPara()
+{
+ SwActContext aActContext(this);
+ ResetCursorStack();
+ Push();
+ SetMark();
+ if( !MovePara(fnParaCurr,fnParaEnd))
+ {
+ Pop(false);
+ return 0;
+ }
+ long nRet = Delete();
+ Pop(false);
+ if( nRet )
+ UpdateAttr();
+ return nRet;
+}
+
+long SwWrtShell::DelToStartOfPara()
+{
+ SwActContext aActContext(this);
+ ResetCursorStack();
+ Push();
+ SetMark();
+ if( !MovePara(fnParaCurr,fnParaStart))
+ {
+ Pop(false);
+ return 0;
+ }
+ long nRet = Delete();
+ Pop(false);
+ if( nRet )
+ UpdateAttr();
+ return nRet;
+}
+
+// All erase operations should work with Find instead with
+// Nxt-/PrvDelim, because the latter works with Wrap Around
+// -- that's probably not wished.
+
+long SwWrtShell::DelToStartOfSentence()
+{
+ if(IsStartOfDoc())
+ return 0;
+ OpenMark();
+ long nRet = _BwdSentence() ? Delete() : 0;
+ CloseMark( 0 != nRet );
+ return nRet;
+}
+
+long SwWrtShell::DelToEndOfSentence()
+{
+ if(IsEndOfDoc())
+ return 0;
+ OpenMark();
+ long nRet(0);
+ // fdo#60967: special case that is documented in help: delete
+ // paragraph following table if cursor is at end of last cell in table
+ if (IsEndOfTable())
+ {
+ Push();
+ ClearMark();
+ if (SwCrsrShell::Right(1,CRSR_SKIP_CHARS))
+ {
+ SetMark();
+ if (!IsEndPara()) // can only be at the end if it's empty
+ { // for an empty paragraph this would actually select the _next_
+ SwCrsrShell::MovePara(fnParaCurr, fnParaEnd);
+ }
+ if (!IsEndOfDoc()) // do not delete last paragraph in body text
+ {
+ nRet = DelFullPara() ? 1 : 0;
+ }
+ }
+ Pop(false);
+ }
+ else
+ {
+ nRet = _FwdSentence() ? Delete() : 0;
+ }
+ CloseMark( 0 != nRet );
+ return nRet;
+}
+
+long SwWrtShell::DelNxtWord()
+{
+ if(IsEndOfDoc())
+ return 0;
+ SwActContext aActContext(this);
+ ResetCursorStack();
+ EnterStdMode();
+ SetMark();
+ if(IsEndWrd() && !IsSttWrd())
+ _NxtWrdForDelete(); // #i92468#
+ if(IsSttWrd() || IsEndPara())
+ _NxtWrdForDelete(); // #i92468#
+ else
+ _EndWrd();
+
+ long nRet = Delete();
+ if( nRet )
+ UpdateAttr();
+ else
+ SwapPam();
+ ClearMark();
+ return nRet;
+}
+
+long SwWrtShell::DelPrvWord()
+{
+ if(IsStartOfDoc())
+ return 0;
+ SwActContext aActContext(this);
+ ResetCursorStack();
+ EnterStdMode();
+ SetMark();
+ if ( !IsSttWrd() ||
+ !_PrvWrdForDelete() ) // #i92468#
+ {
+ if (IsEndWrd() || IsSttPara())
+ _PrvWrdForDelete(); // #i92468#
+ else
+ _SttWrd();
+ }
+ long nRet = Delete();
+ if( nRet )
+ UpdateAttr();
+ else
+ SwapPam();
+ ClearMark();
+ return nRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/wrtsh/move.cxx b/sw/source/uibase/wrtsh/move.cxx
new file mode 100644
index 000000000000..64a390e056a5
--- /dev/null
+++ b/sw/source/uibase/wrtsh/move.cxx
@@ -0,0 +1,689 @@
+/* -*- 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 <wrtsh.hxx>
+#include <view.hxx>
+#include <viewopt.hxx>
+#include <crsskip.hxx>
+
+/**
+ Always:
+ - Reset of the cursor stack
+ - retrigger timer
+ - if applicable: GCAttr
+
+ on selection
+ - SttSelect()
+
+ else
+ - EndSelect()
+ */
+
+const long nReadOnlyScrollOfst = 10;
+
+class ShellMoveCrsr
+{
+ SwWrtShell* pSh;
+ bool bAct;
+public:
+ inline ShellMoveCrsr( SwWrtShell* pWrtSh, bool bSel )
+ {
+ bAct = !pWrtSh->ActionPend() && (pWrtSh->GetFrmType(0,false) & FRMTYPE_FLY_ANY);
+ ( pSh = pWrtSh )->MoveCrsr( bSel );
+ pWrtSh->GetView().GetViewFrame()->GetBindings().Invalidate(SID_HYPERLINK_GETLINK);
+ }
+ inline ~ShellMoveCrsr()
+ {
+ if( bAct )
+ {
+ // The action is used for scrolling in "single paragraph"
+ // frames with fixed height.
+ pSh->StartAllAction();
+ pSh->EndAllAction();
+ }
+ }
+};
+
+void SwWrtShell::MoveCrsr( bool bWithSelect )
+{
+ ResetCursorStack();
+ if ( IsGCAttr() )
+ {
+ GCAttr();
+ ClearGCAttr();
+ }
+ if ( bWithSelect )
+ SttSelect();
+ else
+ {
+ EndSelect();
+ (this->*fnKillSel)( 0, false );
+ }
+}
+
+bool SwWrtShell::SimpleMove( FNSimpleMove FnSimpleMove, bool bSelect )
+{
+ bool nRet;
+ if( bSelect )
+ {
+ SttCrsrMove();
+ MoveCrsr( true );
+ nRet = (this->*FnSimpleMove)();
+ EndCrsrMove();
+ }
+ else if( ( nRet = (this->*FnSimpleMove)() ) )
+ MoveCrsr( false );
+ return nRet;
+}
+
+bool SwWrtShell::Left( sal_uInt16 nMode, bool bSelect,
+ sal_uInt16 nCount, bool bBasicCall, bool bVisual )
+{
+ if ( !bSelect && !bBasicCall && IsCrsrReadonly() && !GetViewOptions()->IsSelectionInReadonly())
+ {
+ Point aTmp( VisArea().Pos() );
+ aTmp.X() -= VisArea().Width() * nReadOnlyScrollOfst / 100;
+ rView.SetVisArea( aTmp );
+ return true;
+ }
+ else
+ {
+ ShellMoveCrsr aTmp( this, bSelect );
+ return SwCrsrShell::Left( nCount, nMode, bVisual );
+ }
+}
+
+bool SwWrtShell::Right( sal_uInt16 nMode, bool bSelect,
+ sal_uInt16 nCount, bool bBasicCall, bool bVisual )
+{
+ if ( !bSelect && !bBasicCall && IsCrsrReadonly() && !GetViewOptions()->IsSelectionInReadonly() )
+ {
+ Point aTmp( VisArea().Pos() );
+ aTmp.X() += VisArea().Width() * nReadOnlyScrollOfst / 100;
+ aTmp.X() = rView.SetHScrollMax( aTmp.X() );
+ rView.SetVisArea( aTmp );
+ return true;
+ }
+ else
+ {
+ ShellMoveCrsr aTmp( this, bSelect );
+ return SwCrsrShell::Right( nCount, nMode, bVisual );
+ }
+}
+
+bool SwWrtShell::Up( bool bSelect, sal_uInt16 nCount, bool bBasicCall )
+{
+ if ( !bSelect && !bBasicCall && IsCrsrReadonly() && !GetViewOptions()->IsSelectionInReadonly())
+ {
+ Point aTmp( VisArea().Pos() );
+ aTmp.Y() -= VisArea().Height() * nReadOnlyScrollOfst / 100;
+ rView.SetVisArea( aTmp );
+ return true;
+ }
+
+ ShellMoveCrsr aTmp( this, bSelect );
+ return SwCrsrShell::Up( nCount );
+}
+
+bool SwWrtShell::Down( bool bSelect, sal_uInt16 nCount, bool bBasicCall )
+{
+ if ( !bSelect && !bBasicCall && IsCrsrReadonly() && !GetViewOptions()->IsSelectionInReadonly())
+ {
+ Point aTmp( VisArea().Pos() );
+ aTmp.Y() += VisArea().Height() * nReadOnlyScrollOfst / 100;
+ aTmp.Y() = rView.SetVScrollMax( aTmp.Y() );
+ rView.SetVisArea( aTmp );
+ return true;
+ }
+
+ ShellMoveCrsr aTmp( this, bSelect );
+ return SwCrsrShell::Down( nCount );
+}
+
+bool SwWrtShell::LeftMargin( bool bSelect, bool bBasicCall )
+{
+ if ( !bSelect && !bBasicCall && IsCrsrReadonly() )
+ {
+ Point aTmp( VisArea().Pos() );
+ aTmp.X() = DOCUMENTBORDER;
+ rView.SetVisArea( aTmp );
+ return true;
+ }
+ else
+ {
+ ShellMoveCrsr aTmp( this, bSelect );
+ return SwCrsrShell::LeftMargin();
+ }
+}
+
+bool SwWrtShell::RightMargin( bool bSelect, bool bBasicCall )
+{
+ if ( !bSelect && !bBasicCall && IsCrsrReadonly() )
+ {
+ Point aTmp( VisArea().Pos() );
+ aTmp.X() = GetDocSize().Width() - VisArea().Width() + DOCUMENTBORDER;
+ if( DOCUMENTBORDER > aTmp.X() )
+ aTmp.X() = DOCUMENTBORDER;
+ rView.SetVisArea( aTmp );
+ return true;
+ }
+ else
+ {
+ ShellMoveCrsr aTmp( this, bSelect );
+ return SwCrsrShell::RightMargin(bBasicCall);
+ }
+}
+
+bool SwWrtShell::GoStart( bool bKeepArea, bool *pMoveTable,
+ bool bSelect, bool bDontMoveRegion )
+{
+ if ( IsCrsrInTbl() )
+ {
+ const bool bBoxSelection = HasBoxSelection();
+ if( !bBlockMode )
+ {
+ if ( !bSelect )
+ EnterStdMode();
+ else
+ SttSelect();
+ }
+ // Table cell ?
+ if ( !bBoxSelection && (MoveSection( fnSectionCurr, fnSectionStart)
+ || bDontMoveRegion))
+ {
+ if ( pMoveTable )
+ *pMoveTable = false;
+ return true;
+ }
+ if( MoveTable( fnTableCurr, fnTableStart ) || bDontMoveRegion )
+ {
+ if ( pMoveTable )
+ *pMoveTable = true;
+ return true;
+ }
+ else if( bBoxSelection && pMoveTable )
+ {
+ // JP 09.01.96: We have a box selection (or a empty cell)
+ // and we want select (pMoveTable will be
+ // set in SelAll). Then the table must not
+ // be left, otherwise there is no selection
+ // of the entire table possible!
+ *pMoveTable = true;
+ return true;
+ }
+ }
+
+ if( !bBlockMode )
+ {
+ if ( !bSelect )
+ EnterStdMode();
+ else
+ SttSelect();
+ }
+ const sal_uInt16 nFrmType = GetFrmType(0,false);
+ if ( FRMTYPE_FLY_ANY & nFrmType )
+ {
+ if( MoveSection( fnSectionCurr, fnSectionStart ) )
+ return true;
+ else if ( FRMTYPE_FLY_FREE & nFrmType || bDontMoveRegion )
+ return false;
+ }
+ if(( FRMTYPE_HEADER | FRMTYPE_FOOTER | FRMTYPE_FOOTNOTE ) & nFrmType )
+ {
+ if ( MoveSection( fnSectionCurr, fnSectionStart ) )
+ return true;
+ else if ( bKeepArea )
+ return true;
+ }
+ // Regions ???
+ return SwCrsrShell::MoveRegion( fnRegionCurrAndSkip, fnRegionStart ) ||
+ SwCrsrShell::SttEndDoc(true);
+}
+
+bool SwWrtShell::GoEnd(bool bKeepArea, bool *pMoveTable)
+{
+ if ( pMoveTable && *pMoveTable )
+ return MoveTable( fnTableCurr, fnTableEnd );
+
+ if ( IsCrsrInTbl() )
+ {
+ if ( MoveSection( fnSectionCurr, fnSectionEnd ) ||
+ MoveTable( fnTableCurr, fnTableEnd ) )
+ return true;
+ }
+ else
+ {
+ const sal_uInt16 nFrmType = GetFrmType(0,false);
+ if ( FRMTYPE_FLY_ANY & nFrmType )
+ {
+ if ( MoveSection( fnSectionCurr, fnSectionEnd ) )
+ return true;
+ else if ( FRMTYPE_FLY_FREE & nFrmType )
+ return false;
+ }
+ if(( FRMTYPE_HEADER | FRMTYPE_FOOTER | FRMTYPE_FOOTNOTE ) & nFrmType )
+ {
+ if ( MoveSection( fnSectionCurr, fnSectionEnd) )
+ return true;
+ else if ( bKeepArea )
+ return true;
+ }
+ }
+ // Regions ???
+ return SwCrsrShell::MoveRegion( fnRegionCurrAndSkip, fnRegionEnd ) ||
+ SwCrsrShell::SttEndDoc(false);
+}
+
+bool SwWrtShell::SttDoc( bool bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return GoStart(false, 0, bSelect );
+}
+
+bool SwWrtShell::EndDoc( bool bSelect)
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return GoEnd();
+}
+
+bool SwWrtShell::SttNxtPg( bool bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return MovePage( fnPageNext, fnPageStart );
+}
+
+bool SwWrtShell::SttPrvPg( bool bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return MovePage( fnPagePrev, fnPageStart );
+}
+
+bool SwWrtShell::EndNxtPg( bool bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return MovePage( fnPageNext, fnPageEnd );
+}
+
+bool SwWrtShell::EndPrvPg( bool bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return MovePage( fnPagePrev, fnPageEnd );
+}
+
+bool SwWrtShell::SttPg( bool bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return MovePage( fnPageCurr, fnPageStart );
+}
+
+bool SwWrtShell::EndPg( bool bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return MovePage( fnPageCurr, fnPageEnd );
+}
+
+bool SwWrtShell::SttPara( bool bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return MovePara( fnParaCurr, fnParaStart );
+}
+
+bool SwWrtShell::EndPara( bool bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ return MovePara(fnParaCurr,fnParaEnd);
+}
+
+// Column-by-jumping.
+// SSelection with or without
+// returns success or failure
+
+bool SwWrtShell::StartOfColumn( bool bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect);
+ return MoveColumn(fnColumnCurr, fnColumnStart);
+}
+
+bool SwWrtShell::EndOfColumn( bool bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect);
+ return MoveColumn(fnColumnCurr, fnColumnEnd);
+}
+
+bool SwWrtShell::StartOfNextColumn( bool bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect);
+ return MoveColumn( fnColumnNext, fnColumnStart);
+}
+
+bool SwWrtShell::EndOfNextColumn( bool bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect);
+ return MoveColumn(fnColumnNext, fnColumnEnd);
+}
+
+bool SwWrtShell::StartOfPrevColumn( bool bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect);
+ return MoveColumn(fnColumnPrev, fnColumnStart);
+}
+
+bool SwWrtShell::EndOfPrevColumn( bool bSelect )
+{
+ ShellMoveCrsr aTmp( this, bSelect);
+ return MoveColumn(fnColumnPrev, fnColumnEnd);
+}
+
+bool SwWrtShell::PushCrsr(SwTwips lOffset, bool bSelect)
+{
+ bool bDiff = false;
+ SwRect aOldRect( GetCharRect() ), aTmpArea( VisArea() );
+
+ // bDestOnStack indicates if I could not set the coursor at the current
+ // position, because in this region is no content.
+ if( !bDestOnStack )
+ {
+ Point aPt( aOldRect.Center() );
+
+ if( !IsCrsrVisible() )
+ // set CrsrPos to top-/bottom left pos. So the pagescroll is not
+ // be dependent on the current cursor, but on the visarea.
+ aPt.Y() = aTmpArea.Top() + aTmpArea.Height() / 2;
+
+ aPt.Y() += lOffset;
+ aDest = GetCntntPos(aPt,lOffset > 0);
+ aDest.X() = aPt.X();
+ bDestOnStack = true;
+ }
+
+ // If we had a frame selection, it must be removed after the fnSetCrsr
+ // and we have to remember the position on the stack to return to it later.
+ bool bIsFrmSel = false;
+
+ //Target position is now within the viewable region -->
+ //Place the cursor at the target position; remember that no target
+ //position is longer on the stack.
+ //The new visible region is to be determined beforehand.
+ aTmpArea.Pos().Y() += lOffset;
+ if( aTmpArea.IsInside(aDest) )
+ {
+ if( bSelect )
+ SttSelect();
+ else
+ EndSelect();
+
+ bIsFrmSel = IsFrmSelected();
+ bool bIsObjSel = 0 != IsObjSelected();
+
+ // unselect frame
+ if( bIsFrmSel || bIsObjSel )
+ {
+ UnSelectFrm();
+ LeaveSelFrmMode();
+ if ( bIsObjSel )
+ {
+ GetView().SetDrawFuncPtr( NULL );
+ GetView().LeaveDrawCreate();
+ }
+
+ CallChgLnk();
+ }
+
+ (this->*fnSetCrsr)( &aDest, true );
+
+ bDiff = aOldRect != GetCharRect();
+
+ if( bIsFrmSel )
+ {
+ // In frames take only the upper corner
+ // so that it can be re-selected.
+ aOldRect.SSize( 5, 5 );
+ }
+
+ // reset Dest. SPoint Flags
+ bDestOnStack = false;
+ }
+
+ // Position into the stack; bDiff indicates if there is a
+ // difference between the old and the new cursor position.
+ pCrsrStack = new CrsrStack( bDiff, bIsFrmSel, aOldRect.Center(),
+ lOffset, pCrsrStack );
+ return !bDestOnStack && bDiff;
+}
+
+bool SwWrtShell::PopCrsr(bool bUpdate, bool bSelect)
+{
+ if( 0 == pCrsrStack)
+ return false;
+
+ const bool bValidPos = pCrsrStack->bValidCurPos;
+ if( bUpdate && bValidPos )
+ {
+ // If a predecessor is on the stack,
+ // use the flag for a valid position.
+ SwRect aTmpArea(VisArea());
+ aTmpArea.Pos().Y() -= pCrsrStack->lOffset;
+ if( aTmpArea.IsInside( pCrsrStack->aDocPos ) )
+ {
+ if( bSelect )
+ SttSelect();
+ else
+ EndSelect();
+
+ (this->*fnSetCrsr)(&pCrsrStack->aDocPos, !pCrsrStack->bIsFrmSel);
+ if( pCrsrStack->bIsFrmSel && IsObjSelectable(pCrsrStack->aDocPos))
+ {
+ HideCrsr();
+ SelectObj( pCrsrStack->aDocPos );
+ EnterSelFrmMode( &pCrsrStack->aDocPos );
+ }
+ }
+ // If a discrepancy between the visible range and the
+ // remembered cursor position occurs, all of the remembered
+ // positions are thrown away.
+ else
+ {
+ _ResetCursorStack();
+ return false;
+ }
+ }
+ CrsrStack *pTmp = pCrsrStack;
+ pCrsrStack = pCrsrStack->pNext;
+ delete pTmp;
+ if( 0 == pCrsrStack )
+ {
+ ePageMove = MV_NO;
+ bDestOnStack = false;
+ }
+ return bValidPos;
+}
+
+// Reset of all pushed cursor positions; these will
+// not be displayed ( --> No Start-/EndAction!!)
+
+void SwWrtShell::_ResetCursorStack()
+{
+ CrsrStack *pTmp = pCrsrStack;
+ while(pCrsrStack)
+ {
+ pTmp = pCrsrStack->pNext;
+ delete pCrsrStack;
+ pCrsrStack = pTmp;
+ }
+ ePageMove = MV_NO;
+ bDestOnStack = false;
+}
+/**
+ if no stack exists --> cancel selection
+ if stack && change of direction
+ --> pop cursor and return
+ else
+ --> push cursor
+ transpose cursor
+*/
+
+bool SwWrtShell::PageCrsr(SwTwips lOffset, bool bSelect)
+{
+ // Do nothing if an offset of 0 was indicated
+ if(!lOffset) return false;
+ // Was once used to force a reformat of the layout.
+ // This has not work that way, because the cursor was not set
+ // because this does not happen within a
+ // Start-/EndActionParentheses.
+ // Because only SwViewShell::EndAction() is called at the end,
+ // no updating of the display of the cursor position takes place.
+ // The CrsrShell-Actionparentheses cannot be used, because it
+ // always leads to displaying the cursor, thus also,
+ // if after the scroll scrolled in a region without a valid postition.
+ // SwViewShell::StartAction();
+ PageMove eDir = lOffset > 0? MV_PAGE_DOWN: MV_PAGE_UP;
+ // Change of direction and stack present
+ if( eDir != ePageMove && ePageMove != MV_NO && PopCrsr( true, bSelect ))
+ return true;
+
+ const bool bRet = PushCrsr(lOffset, bSelect);
+ ePageMove = eDir;
+ return bRet;
+}
+
+bool SwWrtShell::GotoPage(sal_uInt16 nPage, bool bRecord)
+{
+ ShellMoveCrsr aTmp( this, false);
+ if( SwCrsrShell::GotoPage(nPage) && bRecord)
+ {
+ if(IsSelFrmMode())
+ {
+ UnSelectFrm();
+ LeaveSelFrmMode();
+ }
+ return true;
+ }
+ return false;
+}
+
+bool SwWrtShell::GotoMark( const ::sw::mark::IMark* const pMark, bool bSelect, bool bStart )
+{
+ ShellMoveCrsr aTmp( this, bSelect );
+ SwPosition aPos = *GetCrsr()->GetPoint();
+ bool bRet = SwCrsrShell::GotoMark( pMark, bStart );
+ if (bRet)
+ aNavigationMgr.addEntry(aPos);
+ return bRet;
+}
+
+bool SwWrtShell::GotoFly( const OUString& rName, FlyCntType eType, bool bSelFrame )
+{
+ SwPosition aPos = *GetCrsr()->GetPoint();
+ bool bRet = SwFEShell::GotoFly(rName, eType, bSelFrame);
+ if (bRet)
+ aNavigationMgr.addEntry(aPos);
+ return bRet;
+}
+
+bool SwWrtShell::GotoINetAttr( const SwTxtINetFmt& rAttr )
+{
+ SwPosition aPos = *GetCrsr()->GetPoint();
+ bool bRet = SwCrsrShell::GotoINetAttr(rAttr);
+ if (bRet)
+ aNavigationMgr.addEntry(aPos);
+ return bRet;
+}
+
+void SwWrtShell::GotoOutline( sal_uInt16 nIdx )
+{
+ addCurrentPosition();
+ SwCrsrShell::GotoOutline (nIdx);
+}
+
+bool SwWrtShell::GotoOutline( const OUString& rName )
+{
+ SwPosition aPos = *GetCrsr()->GetPoint();
+ bool bRet = SwCrsrShell::GotoOutline (rName);
+ if (bRet)
+ aNavigationMgr.addEntry(aPos);
+ return bRet;
+}
+
+bool SwWrtShell::GotoRegion( const OUString& rName )
+{
+ SwPosition aPos = *GetCrsr()->GetPoint();
+ bool bRet = SwCrsrShell::GotoRegion (rName);
+ if (bRet)
+ aNavigationMgr.addEntry(aPos);
+ return bRet;
+ }
+
+bool SwWrtShell::GotoRefMark( const OUString& rRefMark, sal_uInt16 nSubType,
+ sal_uInt16 nSeqNo )
+{
+ SwPosition aPos = *GetCrsr()->GetPoint();
+ bool bRet = SwCrsrShell::GotoRefMark(rRefMark, nSubType, nSeqNo);
+ if (bRet)
+ aNavigationMgr.addEntry(aPos);
+ return bRet;
+}
+
+bool SwWrtShell::GotoNextTOXBase( const OUString* pName )
+{
+ SwPosition aPos = *GetCrsr()->GetPoint();
+ bool bRet = SwCrsrShell::GotoNextTOXBase(pName);
+ if (bRet)
+ aNavigationMgr.addEntry(aPos);
+ return bRet;
+}
+
+bool SwWrtShell::GotoTable( const OUString& rName )
+{
+ SwPosition aPos = *GetCrsr()->GetPoint();
+ bool bRet = SwCrsrShell::GotoTable(rName);
+ if (bRet)
+ aNavigationMgr.addEntry(aPos);
+ return bRet;
+}
+
+bool SwWrtShell::GotoFld( const SwFmtFld& rFld ) {
+ SwPosition aPos = *GetCrsr()->GetPoint();
+ bool bRet = SwCrsrShell::GotoFld(rFld);
+ if (bRet)
+ aNavigationMgr.addEntry(aPos);
+ return bRet;
+}
+
+const SwRangeRedline* SwWrtShell::GotoRedline( sal_uInt16 nArrPos, bool bSelect ) {
+ SwPosition aPos = *GetCrsr()->GetPoint();
+ const SwRangeRedline *pRedline = SwCrsrShell::GotoRedline(nArrPos, bSelect);
+ if (pRedline)
+ aNavigationMgr.addEntry(aPos);
+ return pRedline;
+}
+
+bool SwWrtShell::SelectTxtAttr( sal_uInt16 nWhich, const SwTxtAttr* pAttr )
+{
+ bool bRet;
+ {
+ SwMvContext aMvContext(this);
+ SttSelect();
+ bRet = SwCrsrShell::SelectTxtAttr( nWhich, false, pAttr );
+ }
+ EndSelect();
+ return bRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/wrtsh/navmgr.cxx b/sw/source/uibase/wrtsh/navmgr.cxx
new file mode 100644
index 000000000000..cb4fc1b6cd07
--- /dev/null
+++ b/sw/source/uibase/wrtsh/navmgr.cxx
@@ -0,0 +1,228 @@
+/* -*- 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/.
+ */
+
+#include "navmgr.hxx"
+#include "wrtsh.hxx"
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <cmdid.h>
+#include <view.hxx>
+#include <doc.hxx>
+#include <unocrsr.hxx>
+
+#include <com/sun/star/frame/XLayoutManager.hpp>
+
+/**
+ * If SMART is defined, the navigation history has recency with temporal ordering enhancement,
+ * as described on http://zing.ncsl.nist.gov/hfweb/proceedings/greenberg/
+ */
+
+#define SMART 1
+
+// This method positions the cursor to the position rPos.
+
+void SwNavigationMgr::GotoSwPosition(const SwPosition &rPos) {
+ // EnterStdMode() prevents the cursor to 'block' the current
+ // shell when it should move from the image back to the normal shell
+ m_rMyShell.EnterStdMode();
+ m_rMyShell.StartAllAction();
+ // cursor consists of two SwPositions: Point and Mark.
+ // Such a pair is called a PaM. SwPaM is derived from SwRing.
+ // The Ring contains the single regions of a multi-selection.
+ SwPaM* pPaM = m_rMyShell.GetCrsr();
+
+ if(pPaM->HasMark())
+ pPaM->DeleteMark(); // If there was a selection, get rid of it
+ *pPaM->GetPoint() = rPos; // Position Cursor
+
+ m_rMyShell.EndAllAction();
+}
+
+// Ctor for the SwNavigationMgr class
+// Sets the shell to the current shell
+// and the index of the current position to 0
+
+SwNavigationMgr::SwNavigationMgr(SwWrtShell & rShell)
+ : m_nCurrent(0), m_rMyShell(rShell)
+{
+}
+
+// This method is used by the navigation shell - defined in sw/source/ui/inc/navsh.hxx
+// and implemented in sw/source/ui/shells/navsh.cxx
+// It is called when we want to check if the back button should be enabled or not.
+// The back button should be enabled only if there are some entries in the navigation history
+
+bool SwNavigationMgr::backEnabled() {
+ return (m_nCurrent > 0);
+}
+
+// Similar to backEnabled() method.
+// The forward button should be enabled if we ever clicked back
+// Due to the implementation of the navigation class, this is when the
+// current position within the navigation history entries in not the last one
+// i.e. when the m_nCurrent index is not at the end of the m_entries vector
+
+bool SwNavigationMgr::forwardEnabled() {
+ return m_nCurrent+1 < m_entries.size();
+}
+
+// The goBack() method positions the cursor to the previous entry in the navigation history
+// If there was no history to go forward to, it adds the current position of the cursor
+// to the history so we could go forward to where we came from
+
+void SwNavigationMgr::goBack() {
+
+ // Although the button should be disabled whenever the backEnabled() returns false,
+ // the UI is sometimes not as responsive as we would like it to be :)
+ // this check prevents segmentation faults and in this way the class is not relying on the UI
+
+ if (backEnabled()) {
+ /* Trying to get the current cursor */
+ SwPaM* pPaM = m_rMyShell.GetCrsr();
+ if (!pPaM) {
+ return;
+ }
+ // This flag will be used to manually refresh the buttons
+
+ bool bForwardWasDisabled = !forwardEnabled();
+
+ // If we're going backwards in our history, but the current location is not
+ // in the history then we need to add *here* to it so that we can "go
+ // forward" to here again.
+
+ if (bForwardWasDisabled) {
+
+ // the cursor consists of two SwPositions: Point and Mark.
+ // We are adding the current Point to the navigation history
+ // so we could later navigate forward to it
+
+ // The addEntry() method returns true iff we should decrement
+ // the index before navigating back
+
+ if (addEntry(*pPaM->GetPoint()) ) {
+ m_nCurrent--;
+ }
+ }
+ m_nCurrent--;
+ // Position cursor to appropriate navigation history entry
+ GotoSwPosition(*m_entries[m_nCurrent]->GetPoint());
+ // Refresh the buttons
+ if (bForwardWasDisabled)
+ m_rMyShell.GetView().GetViewFrame()->GetBindings().Invalidate(FN_NAVIGATION_FORWARD);
+ if (!backEnabled())
+ m_rMyShell.GetView().GetViewFrame()->GetBindings().Invalidate(FN_NAVIGATION_BACK);
+ }
+}
+
+// The goForward() method positions the cursor to the next entry in the navigation history
+
+void SwNavigationMgr::goForward() {
+
+ // Although the button should be disabled whenever the backForward() returns false,
+ // the UI is sometimes not as responsive as we would like it to be :)
+ // this check prevents segmentation faults and in this way the class is not relying on the UI
+
+ if (forwardEnabled()) {
+ // This flag will be used to manually refresh the buttons
+ bool bBackWasDisabled = !backEnabled();
+ // The current index is positioned at the current entry in the navigation history
+ // We have to increment it to go to the next entry
+ m_nCurrent++;
+ GotoSwPosition(*m_entries[m_nCurrent]->GetPoint());
+ // Refresh the buttons
+ if (bBackWasDisabled)
+ m_rMyShell.GetView().GetViewFrame()->GetBindings().Invalidate(FN_NAVIGATION_BACK);
+ if (!forwardEnabled())
+ m_rMyShell.GetView().GetViewFrame()->GetBindings().Invalidate(FN_NAVIGATION_FORWARD);
+ }
+}
+
+// This method adds the SwPosition rPos to the navigation history
+// rPos is usually the current position of the cursor in the document
+
+bool SwNavigationMgr::addEntry(const SwPosition& rPos) {
+ // Flags that will be used for refreshing the buttons
+ bool bBackWasDisabled = !backEnabled();
+ bool bForwardWasEnabled = forwardEnabled();
+
+ bool bRet = false; // return value of the function.
+ // Indicates whether the index should be decremented before
+ // jumping back or not
+#if SMART
+ // If any forward history exists, twist the tail of the
+ // list from the current position to the end
+ if (bForwardWasEnabled) {
+
+ size_t number_ofm_entries = m_entries.size(); // To avoid calling m_entries.size() multiple times
+ int curr = m_nCurrent; // Index from which we'll twist the tail.
+ int n = (number_ofm_entries - curr) / 2; // Number of entries that will swap places
+ for (int i = 0; i < n; i++) {
+ ::std::swap(m_entries[curr + i], m_entries[number_ofm_entries -1 - i]);
+ }
+
+ if (*m_entries.back()->GetPoint() != rPos)
+ {
+ SwUnoCrsr *const pCursor = m_rMyShell.GetDoc()->CreateUnoCrsr(rPos);
+ m_entries.push_back(::boost::shared_ptr<SwUnoCrsr>(pCursor));
+ }
+ bRet = true;
+ }
+ else {
+ if ( (!m_entries.empty() && *m_entries.back()->GetPoint() != rPos) || m_entries.empty() ) {
+ SwUnoCrsr *const pCursor = m_rMyShell.GetDoc()->CreateUnoCrsr(rPos);
+ m_entries.push_back(::boost::shared_ptr<SwUnoCrsr>(pCursor));
+ bRet = true;
+ }
+ if (m_entries.size() > 1 && *m_entries.back()->GetPoint() == rPos)
+ bRet = true;
+ if (m_entries.size() == 1 && *m_entries.back()->GetPoint() == rPos)
+ bRet = false;
+ }
+#else
+ m_entries.erase(m_entries.begin() + m_nCurrent, m_entries.end());
+ SwUnoCrsr *const pCursor = m_rMyShell.GetDoc()->CreateUnoCrsr(rPos);
+ m_entries.push_back(::boost::shared_ptr<SwUnoCrsr>(pCursor));
+ bRet = true;
+#endif
+ m_nCurrent = m_entries.size();
+
+ // Refresh buttons
+ if (bBackWasDisabled)
+ m_rMyShell.GetView().GetViewFrame()->GetBindings().Invalidate(FN_NAVIGATION_BACK);
+ if (bForwardWasEnabled)
+ m_rMyShell.GetView().GetViewFrame()->GetBindings().Invalidate(FN_NAVIGATION_FORWARD);
+
+ // show the Navigation toolbar
+ css::uno::Reference< css::frame::XFrame > xFrame =
+ m_rMyShell.GetView().GetViewFrame()->GetFrame().GetFrameInterface();
+ if (xFrame.is())
+ {
+ css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
+ if (xPropSet.is())
+ {
+ css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
+ css::uno::Any aValue = xPropSet->getPropertyValue("LayoutManager");
+
+ aValue >>= xLayoutManager;
+ if (xLayoutManager.is())
+ {
+ const OUString sResourceURL( "private:resource/toolbar/navigationobjectbar" );
+ css::uno::Reference< css::ui::XUIElement > xUIElement = xLayoutManager->getElement(sResourceURL);
+ if (!xUIElement.is())
+ {
+ xLayoutManager->createElement( sResourceURL );
+ xLayoutManager->showElement( sResourceURL );
+ }
+ }
+ }
+ }
+
+ return bRet;
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/wrtsh/select.cxx b/sw/source/uibase/wrtsh/select.cxx
new file mode 100644
index 000000000000..76a4c2eb8d66
--- /dev/null
+++ b/sw/source/uibase/wrtsh/select.cxx
@@ -0,0 +1,966 @@
+/* -*- 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 <limits.h>
+#include <hintids.hxx>
+#include <sfx2/bindings.hxx>
+#include <svl/eitem.hxx>
+#include <svl/macitem.hxx>
+#include <unotools/charclass.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <cmdid.h>
+#include <view.hxx>
+#include <basesh.hxx>
+#include <wrtsh.hxx>
+#include <frmatr.hxx>
+#include <initui.hxx>
+#include <mdiexp.hxx>
+#include <fmtcol.hxx>
+#include <frmfmt.hxx>
+#include <swundo.hxx>
+#include <swevent.hxx>
+#include <swdtflvr.hxx>
+#include <crsskip.hxx>
+#include <doc.hxx>
+#include <wordcountdialog.hxx>
+
+namespace com { namespace sun { namespace star { namespace util {
+ struct SearchOptions;
+} } } }
+
+using namespace ::com::sun::star::util;
+
+static long nStartDragX = 0, nStartDragY = 0;
+static bool bStartDrag = false;
+
+void SwWrtShell::Invalidate()
+{
+ // to avoid making the slot volatile, invalidate it every time if something could have been changed
+ // this is still much cheaper than asking for the state every 200 ms (and avoid background processing)
+ GetView().GetViewFrame()->GetBindings().Invalidate( FN_STAT_SELMODE );
+ SwWordCountWrapper *pWrdCnt = (SwWordCountWrapper*)GetView().GetViewFrame()->GetChildWindow(SwWordCountWrapper::GetChildWindowId());
+ if (pWrdCnt)
+ pWrdCnt->UpdateCounts();
+}
+
+bool SwWrtShell::SelNearestWrd()
+{
+ SwMvContext aMvContext(this);
+ if( !IsInWrd() && !IsEndWrd() && !IsSttWrd() )
+ PrvWrd();
+ if( IsEndWrd() )
+ Left(CRSR_SKIP_CELLS, false, 1, false );
+ return SelWrd();
+}
+
+bool SwWrtShell::SelWrd(const Point *pPt, bool )
+{
+ bool bRet;
+ {
+ SwMvContext aMvContext(this);
+ SttSelect();
+ bRet = SwCrsrShell::SelectWord( pPt );
+ }
+ EndSelect();
+ if( bRet )
+ {
+ bSelWrd = true;
+ if(pPt)
+ aStart = *pPt;
+ }
+ return bRet;
+}
+
+void SwWrtShell::SelSentence(const Point *pPt, bool )
+{
+ {
+ SwMvContext aMvContext(this);
+ ClearMark();
+ SwCrsrShell::GoStartSentence();
+ SttSelect();
+ SwCrsrShell::GoEndSentence();
+ }
+ EndSelect();
+ if(pPt)
+ aStart = *pPt;
+ bSelLn = true;
+ bSelWrd = false; // disable SelWord, otherwise no SelLine goes on
+}
+
+void SwWrtShell::SelPara(const Point *pPt, bool )
+{
+ {
+ SwMvContext aMvContext(this);
+ ClearMark();
+ SwCrsrShell::MovePara( fnParaCurr, fnParaStart );
+ SttSelect();
+ SwCrsrShell::MovePara( fnParaCurr, fnParaEnd );
+ }
+ EndSelect();
+ if(pPt)
+ aStart = *pPt;
+ bSelLn = false;
+ bSelWrd = false; // disable SelWord, otherwise no SelLine goes on
+}
+
+long SwWrtShell::SelAll()
+{
+ const bool bLockedView = IsViewLocked();
+ LockView( true );
+ {
+ if(bBlockMode)
+ LeaveBlockMode();
+ SwMvContext aMvContext(this);
+ bool bMoveTable = false;
+ SwPosition *pStartPos = 0;
+ SwPosition *pEndPos = 0;
+ SwShellCrsr* pTmpCrsr = 0;
+ if( !HasWholeTabSelection() )
+ {
+ if ( IsSelection() && IsCrsrPtAtEnd() )
+ SwapPam();
+ pTmpCrsr = getShellCrsr( false );
+ if( pTmpCrsr )
+ {
+ pStartPos = new SwPosition( *pTmpCrsr->GetPoint() );
+ pEndPos = new SwPosition( *pTmpCrsr->GetMark() );
+ }
+ Push();
+ bool bIsFullSel = !MoveSection( fnSectionCurr, fnSectionStart);
+ SwapPam();
+ bIsFullSel &= !MoveSection( fnSectionCurr, fnSectionEnd);
+ Pop(false);
+ GoStart(true, &bMoveTable, false, !bIsFullSel);
+ }
+ else
+ {
+ EnterStdMode();
+ SttEndDoc(true);
+ }
+ SttSelect();
+ GoEnd(true, &bMoveTable);
+
+ bool bStartsWithTable = StartsWithTable();
+ if (bStartsWithTable)
+ {
+ // Disable table cursor to make sure getShellCrsr() returns m_pCurCrsr, not m_pTblCrsr.
+ if (IsTableMode())
+ TblCrsrToCursor();
+ // Do the extended select all on m_pCurCrsr.
+ ExtendedSelectAll(/*bFootnotes =*/ false);
+ }
+
+ SwDoc *pDoc = GetDoc();
+ if ( pDoc )
+ {
+ pDoc->SetPrepareSelAll();
+ }
+
+ if( pStartPos )
+ {
+ pTmpCrsr = getShellCrsr( false );
+ if( pTmpCrsr )
+ {
+ // Some special handling for sections (e.g. TOC) at the beginning of the document body
+ // to avoid the selection of the first section
+ // if the last selection was behind the first section or
+ // if the last selection was already the first section
+ // In this both cases we select to the end of document
+ if( ( *pTmpCrsr->GetPoint() < *pEndPos ||
+ ( *pStartPos == *pTmpCrsr->GetMark() &&
+ *pEndPos == *pTmpCrsr->GetPoint() ) ) && !bStartsWithTable)
+ SwCrsrShell::SttEndDoc(false);
+ }
+ delete pStartPos;
+ delete pEndPos;
+ }
+ }
+ EndSelect();
+ LockView( bLockedView );
+ return 1;
+}
+
+// Desciption: Text search
+
+sal_uLong SwWrtShell::SearchPattern( const SearchOptions& rSearchOpt, bool bSearchInNotes,
+ SwDocPositions eStt, SwDocPositions eEnd,
+ FindRanges eFlags, bool bReplace )
+{
+ // no enhancement of existing selections
+ if(!(eFlags & FND_IN_SEL))
+ ClearMark();
+ bool bCancel = false;
+ sal_uLong nRet = Find( rSearchOpt, bSearchInNotes, eStt, eEnd, bCancel, eFlags, bReplace );
+ if(bCancel)
+ {
+ Undo(1);
+ nRet = ULONG_MAX;
+ }
+ return nRet;
+}
+
+// Description: search for templates
+
+sal_uLong SwWrtShell::SearchTempl( const OUString &rTempl,
+ SwDocPositions eStt, SwDocPositions eEnd,
+ FindRanges eFlags, const OUString* pReplTempl )
+{
+ // no enhancement of existing selections
+ if(!(eFlags & FND_IN_SEL))
+ ClearMark();
+ SwTxtFmtColl *pColl = GetParaStyle(rTempl, SwWrtShell::GETSTYLE_CREATESOME);
+ SwTxtFmtColl *pReplaceColl = 0;
+ if( pReplTempl )
+ pReplaceColl = GetParaStyle(*pReplTempl, SwWrtShell::GETSTYLE_CREATESOME );
+
+ bool bCancel = false;
+ sal_uLong nRet = Find(pColl? *pColl: GetDfltTxtFmtColl(),
+ eStt,eEnd, bCancel, eFlags, pReplaceColl);
+ if(bCancel)
+ {
+ Undo(1);
+ nRet = ULONG_MAX;
+ }
+ return nRet;
+}
+
+// search for attributes
+
+sal_uLong SwWrtShell::SearchAttr( const SfxItemSet& rFindSet, bool bNoColls,
+ SwDocPositions eStart, SwDocPositions eEnde,
+ FindRanges eFlags, const SearchOptions* pSearchOpt,
+ const SfxItemSet* pReplaceSet )
+{
+ // no enhancement of existing selections
+ if (!(eFlags & FND_IN_SEL))
+ ClearMark();
+
+ // Searching
+ bool bCancel = false;
+ sal_uLong nRet = Find( rFindSet, bNoColls, eStart, eEnde, bCancel, eFlags, pSearchOpt, pReplaceSet);
+
+ if(bCancel)
+ {
+ Undo(1);
+ nRet = ULONG_MAX;
+ }
+ return nRet;
+}
+
+// Selection modes
+
+void SwWrtShell::PushMode()
+{
+ pModeStack = new ModeStack( pModeStack, bIns, bExtMode, bAddMode, bBlockMode );
+}
+
+void SwWrtShell::PopMode()
+{
+ if ( 0 == pModeStack )
+ return;
+
+ if ( bExtMode && !pModeStack->bExt )
+ LeaveExtMode();
+ if ( bAddMode && !pModeStack->bAdd )
+ LeaveAddMode();
+ if ( bBlockMode && !pModeStack->bBlock )
+ LeaveBlockMode();
+ bIns = pModeStack->bIns;
+
+ ModeStack *pTmp = pModeStack->pNext;
+ delete pModeStack;
+ pModeStack = pTmp;
+}
+
+// Two methodes for setting cursors: the first maps at the
+// eponymous methodes in the CursorShell, the second removes
+// all selections at first.
+
+long SwWrtShell::SetCrsr(const Point *pPt, bool bTextOnly)
+{
+ // Remove a possibly present selection at the position
+ // of the mouseclick
+
+ if(!IsInSelect() && ChgCurrPam(*pPt)) {
+ ClearMark();
+ }
+
+ return SwCrsrShell::SetCrsr(*pPt, bTextOnly);
+}
+
+long SwWrtShell::SetCrsrKillSel(const Point *pPt, bool bTextOnly )
+{
+ SwActContext aActContext(this);
+ ResetSelect(pPt,false);
+ return SwCrsrShell::SetCrsr(*pPt, bTextOnly);
+}
+
+void SwWrtShell::UnSelectFrm()
+{
+ // Remove Frame selection with guaranteed invalid position
+ Point aPt(LONG_MIN, LONG_MIN);
+ SelectObj(aPt, 0);
+ SwTransferable::ClearSelection( *this );
+}
+
+// Remove of all selections
+
+long SwWrtShell::ResetSelect(const Point *,bool)
+{
+ if(IsSelFrmMode())
+ {
+ UnSelectFrm();
+ LeaveSelFrmMode();
+ }
+ else
+ {
+ // SwActContext opens an Action -
+ // to avoid problems in the basic process with the
+ // shell switching, GetChgLnk().Call() may be called
+ // after EndAction().
+ {
+ SwActContext aActContext(this);
+ bSelWrd = bSelLn = false;
+ KillPams();
+ ClearMark();
+ fnKillSel = &SwWrtShell::Ignore;
+ fnSetCrsr = &SwWrtShell::SetCrsr;
+ }
+
+ // After canceling of all selections an update of Attr-Controls
+ // could be necessary.
+ GetChgLnk().Call(this);
+ }
+ Invalidate();
+ SwTransferable::ClearSelection( *this );
+ return 1;
+}
+
+// Do nothing
+
+long SwWrtShell::Ignore(const Point *, bool ) {
+ return 1;
+}
+
+// Begin of a selection process.
+
+void SwWrtShell::SttSelect()
+{
+ if(bInSelect)
+ return;
+ if(!HasMark())
+ SetMark();
+ if( bBlockMode )
+ {
+ SwShellCrsr* pTmp = getShellCrsr( true );
+ if( !pTmp->HasMark() )
+ pTmp->SetMark();
+ }
+ fnKillSel = &SwWrtShell::Ignore;
+ fnSetCrsr = &SwWrtShell::SetCrsr;
+ bInSelect = true;
+ Invalidate();
+ SwTransferable::CreateSelection( *this );
+}
+
+// End of a selection process.
+
+void SwWrtShell::EndSelect()
+{
+ if(bInSelect && !bExtMode)
+ {
+ bInSelect = false;
+ if (bAddMode)
+ {
+ AddLeaveSelect(0, false);
+ }
+ else
+ {
+ SttLeaveSelect(0, false);
+ fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
+ fnKillSel = &SwWrtShell::ResetSelect;
+ }
+ }
+ SwWordCountWrapper *pWrdCnt = (SwWordCountWrapper*)GetView().GetViewFrame()->GetChildWindow(SwWordCountWrapper::GetChildWindowId());
+ if (pWrdCnt)
+ pWrdCnt->UpdateCounts();
+}
+
+long SwWrtShell::ExtSelWrd(const Point *pPt, bool )
+{
+ SwMvContext aMvContext(this);
+ if( IsTableMode() )
+ return 1;
+
+ // Bug 66823: actual crsr has in additional mode no selection?
+ // Then destroy the actual an go to prev, this will be expand
+ if( !HasMark() && GoPrevCrsr() )
+ {
+ bool bHasMark = HasMark(); // thats wrong!
+ GoNextCrsr();
+ if( bHasMark )
+ {
+ DestroyCrsr();
+ GoPrevCrsr();
+ }
+ }
+
+ // check the direction of the selection with the new point
+ bool bRet = false, bMoveCrsr = true, bToTop = false;
+ SwCrsrShell::SelectWord( &aStart ); // select the startword
+ SwCrsrShell::Push(); // save the cursor
+ SwCrsrShell::SetCrsr( *pPt ); // and check the direction
+
+ switch( SwCrsrShell::CompareCursor( StackMkCurrPt ))
+ {
+ case -1: bToTop = false; break;
+ case 1: bToTop = true; break;
+ default: bMoveCrsr = false; break;
+ }
+
+ SwCrsrShell::Pop( false ); // retore the saved cursor
+
+ if( bMoveCrsr )
+ {
+ // select to Top but cursor select to Bottom? or
+ // select to Bottom but cursor select to Top? --> swap the cursor
+ if( bToTop )
+ SwapPam();
+
+ SwCrsrShell::Push(); // save cur cursor
+ if( SwCrsrShell::SelectWord( pPt )) // select the current word
+ {
+ if( bToTop )
+ SwapPam();
+ Combine();
+ bRet = true;
+ }
+ else
+ {
+ SwCrsrShell::Pop( false );
+ if( bToTop )
+ SwapPam();
+ }
+ }
+ else
+ bRet = true;
+ return bRet ? 1 : 0;
+}
+
+long SwWrtShell::ExtSelLn(const Point *pPt, bool )
+{
+ SwMvContext aMvContext(this);
+ SwCrsrShell::SetCrsr(*pPt);
+ if( IsTableMode() )
+ return 1;
+
+ // Bug 66823: actual crsr has in additional mode no selection?
+ // Then destroy the actual an go to prev, this will be expand
+ if( !HasMark() && GoPrevCrsr() )
+ {
+ bool bHasMark = HasMark(); // thats wrong!
+ GoNextCrsr();
+ if( bHasMark )
+ {
+ DestroyCrsr();
+ GoPrevCrsr();
+ }
+ }
+
+ // if applicable fit the selection to the "Mark"
+ bool bToTop = !IsCrsrPtAtEnd();
+ SwapPam();
+
+ // The "Mark" has to be at the end or the beginning of the line.
+ if( bToTop ? !IsEndSentence() : !IsStartSentence() )
+ {
+ if( bToTop )
+ {
+ if( !IsEndPara() )
+ SwCrsrShell::Right(1,CRSR_SKIP_CHARS);
+ SwCrsrShell::GoEndSentence();
+ }
+ else
+ SwCrsrShell::GoStartSentence();
+ }
+ SwapPam();
+
+ return (bToTop ? SwCrsrShell::GoStartSentence() : SwCrsrShell::GoEndSentence()) ? 1 : 0;
+}
+
+// Back into the standard mode: no mode, no selections.
+
+void SwWrtShell::EnterStdMode()
+{
+ if(bAddMode)
+ LeaveAddMode();
+ if(bBlockMode)
+ LeaveBlockMode();
+ bBlockMode = false;
+ bExtMode = false;
+ bInSelect = false;
+ if(IsSelFrmMode())
+ {
+ UnSelectFrm();
+ LeaveSelFrmMode();
+ }
+ else
+ {
+ // SwActContext opens and action which has to be
+ // closed prior to the call of
+ // GetChgLnk().Call()
+ {
+ SwActContext aActContext(this);
+ bSelWrd = bSelLn = false;
+ if( !IsRetainSelection() )
+ KillPams();
+ ClearMark();
+ fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
+ fnKillSel = &SwWrtShell::ResetSelect;
+ }
+ }
+ Invalidate();
+ SwTransferable::ClearSelection( *this );
+}
+
+// Extended Mode
+
+void SwWrtShell::EnterExtMode()
+{
+ if(bBlockMode)
+ {
+ LeaveBlockMode();
+ KillPams();
+ ClearMark();
+ }
+ bExtMode = true;
+ bAddMode = false;
+ bBlockMode = false;
+ SttSelect();
+}
+
+void SwWrtShell::LeaveExtMode()
+{
+ bExtMode = false;
+ EndSelect();
+}
+
+// End of a selection; if the selection is empty,
+// ClearMark().
+
+long SwWrtShell::SttLeaveSelect(const Point *, bool )
+{
+ if(SwCrsrShell::HasSelection() && !IsSelTblCells() && bClearMark) {
+ return 0;
+ }
+ ClearMark();
+ return 1;
+}
+
+// Leaving of the selection mode in additional mode
+
+long SwWrtShell::AddLeaveSelect(const Point *, bool )
+{
+ if(IsTableMode()) LeaveAddMode();
+ else if(SwCrsrShell::HasSelection())
+ CreateCrsr();
+ return 1;
+}
+
+// Additional Mode
+
+void SwWrtShell::EnterAddMode()
+{
+ if(IsTableMode()) return;
+ if(bBlockMode)
+ LeaveBlockMode();
+ fnKillSel = &SwWrtShell::Ignore;
+ fnSetCrsr = &SwWrtShell::SetCrsr;
+ bAddMode = true;
+ bBlockMode = false;
+ bExtMode = false;
+ if(SwCrsrShell::HasSelection())
+ CreateCrsr();
+ Invalidate();
+}
+
+void SwWrtShell::LeaveAddMode()
+{
+ fnKillSel = &SwWrtShell::ResetSelect;
+ fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
+ bAddMode = false;
+ Invalidate();
+}
+
+// Block Mode
+
+void SwWrtShell::EnterBlockMode()
+{
+ bBlockMode = false;
+ EnterStdMode();
+ bBlockMode = true;
+ CrsrToBlockCrsr();
+ Invalidate();
+}
+
+void SwWrtShell::LeaveBlockMode()
+{
+ bBlockMode = false;
+ BlockCrsrToCrsr();
+ EndSelect();
+ Invalidate();
+}
+
+// Insert mode
+
+void SwWrtShell::SetInsMode( bool bOn )
+{
+ bIns = bOn;
+ SwCrsrShell::SetOverwriteCrsr( !bIns );
+ const SfxBoolItem aTmp( SID_ATTR_INSERT, bIns );
+ GetView().GetViewFrame()->GetBindings().SetState( aTmp );
+ StartAction();
+ EndAction();
+ Invalidate();
+}
+//Overwrite mode is incompatible with red-lining
+void SwWrtShell::SetRedlineModeAndCheckInsMode( sal_uInt16 eMode )
+{
+ SetRedlineMode( eMode );
+ if (IsRedlineOn())
+ SetInsMode( true );
+}
+
+// Edit frame
+
+long SwWrtShell::BeginFrmDrag(const Point *pPt, bool)
+{
+ fnDrag = &SwFEShell::Drag;
+ if(bStartDrag)
+ {
+ Point aTmp( nStartDragX, nStartDragY );
+ SwFEShell::BeginDrag( &aTmp, false );
+ }
+ else
+ SwFEShell::BeginDrag( pPt, false );
+ return 1;
+}
+
+void SwWrtShell::EnterSelFrmMode(const Point *pPos)
+{
+ if(pPos)
+ {
+ nStartDragX = pPos->X();
+ nStartDragY = pPos->Y();
+ bStartDrag = true;
+ }
+ bLayoutMode = true;
+ HideCrsr();
+
+ // equal call of BeginDrag in the SwFEShell
+ fnDrag = &SwWrtShell::BeginFrmDrag;
+ fnEndDrag = &SwWrtShell::UpdateLayoutFrm;
+ SwBaseShell::SetFrmMode( FLY_DRAG_START, this );
+ Invalidate();
+}
+
+void SwWrtShell::LeaveSelFrmMode()
+{
+ fnDrag = &SwWrtShell::BeginDrag;
+ fnEndDrag = &SwWrtShell::DefaultEndDrag;
+ bLayoutMode = false;
+ bStartDrag = false;
+ Edit();
+ SwBaseShell::SetFrmMode( FLY_DRAG_END, this );
+ Invalidate();
+}
+
+// Description: execute framebound macro
+
+IMPL_LINK( SwWrtShell, ExecFlyMac, void *, pFlyFmt )
+{
+ const SwFrmFmt *pFmt = pFlyFmt ? (SwFrmFmt*)pFlyFmt : GetFlyFrmFmt();
+ OSL_ENSURE(pFmt, "no frame format");
+ const SvxMacroItem &rFmtMac = pFmt->GetMacro();
+
+ if(rFmtMac.HasMacro(SW_EVENT_OBJECT_SELECT))
+ {
+ const SvxMacro &rMac = rFmtMac.GetMacro(SW_EVENT_OBJECT_SELECT);
+ if( IsFrmSelected() )
+ bLayoutMode = true;
+ CallChgLnk();
+ ExecMacro( rMac );
+ }
+ return 0;
+}
+
+long SwWrtShell::UpdateLayoutFrm(const Point *pPt, bool )
+{
+ // still a dummy
+ SwFEShell::EndDrag( pPt, false );
+ fnDrag = &SwWrtShell::BeginFrmDrag;
+ return 1;
+}
+
+// Handler for toggling the modes. Returns back the old mode.
+
+bool SwWrtShell::ToggleAddMode()
+{
+ bAddMode ? LeaveAddMode(): EnterAddMode();
+ Invalidate();
+ return !bAddMode;
+}
+
+bool SwWrtShell::ToggleBlockMode()
+{
+ bBlockMode ? LeaveBlockMode(): EnterBlockMode();
+ Invalidate();
+ return !bBlockMode;
+}
+
+bool SwWrtShell::ToggleExtMode()
+{
+ bExtMode ? LeaveExtMode() : EnterExtMode();
+ Invalidate();
+ return !bExtMode;
+}
+
+// Dragging in standard mode (Selecting of content)
+
+long SwWrtShell::BeginDrag(const Point * /*pPt*/, bool )
+{
+ if(bSelWrd)
+ {
+ bInSelect = true;
+ if( !IsCrsrPtAtEnd() )
+ SwapPam();
+
+ fnDrag = &SwWrtShell::ExtSelWrd;
+ fnSetCrsr = &SwWrtShell::Ignore;
+ }
+ else if(bSelLn)
+ {
+ bInSelect = true;
+ fnDrag = &SwWrtShell::ExtSelLn;
+ fnSetCrsr = &SwWrtShell::Ignore;
+ }
+ else
+ {
+ fnDrag = &SwWrtShell::DefaultDrag;
+ SttSelect();
+ }
+
+ return 1;
+}
+
+long SwWrtShell::DefaultDrag(const Point *, bool )
+{
+ if( IsSelTblCells() )
+ aSelTblLink.Call(this);
+
+ return 1;
+}
+
+long SwWrtShell::DefaultEndDrag(const Point * /*pPt*/, bool )
+{
+ fnDrag = &SwWrtShell::BeginDrag;
+ if( IsExtSel() )
+ LeaveExtSel();
+
+ if( IsSelTblCells() )
+ aSelTblLink.Call(this);
+ EndSelect();
+ return 1;
+}
+
+// #i32329# Enhanced table selection
+bool SwWrtShell::SelectTableRowCol( const Point& rPt, const Point* pEnd, bool bRowDrag )
+{
+ SwMvContext aMvContext(this);
+ SttSelect();
+ if(SelTblRowCol( rPt, pEnd, bRowDrag ))
+ {
+ fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
+ fnKillSel = &SwWrtShell::ResetSelect;
+ return true;
+ }
+ return false;
+}
+
+// Description: Selection of a table line or column
+
+bool SwWrtShell::SelectTableRow()
+{
+ if ( SelTblRow() )
+ {
+ fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
+ fnKillSel = &SwWrtShell::ResetSelect;
+ return true;
+ }
+ return false;
+}
+
+bool SwWrtShell::SelectTableCol()
+{
+ if ( SelTblCol() )
+ {
+ fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
+ fnKillSel = &SwWrtShell::ResetSelect;
+ return true;
+ }
+ return false;
+}
+
+bool SwWrtShell::SelectTableCell()
+{
+ if ( SelTblBox() )
+ {
+ fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
+ fnKillSel = &SwWrtShell::ResetSelect;
+ return true;
+ }
+ return false;
+}
+
+// Description: Check if a word selection is present.
+// According to the rules for intelligent cut / paste
+// surrounding spaces are cut out.
+// Return: Delivers the type of the word selection.
+
+int SwWrtShell::IntelligentCut(int nSelection, bool bCut)
+{
+ // On multiple selection no intelligent drag and drop
+ // there are multiple cursors, since a second was placed
+ // already at the target position.
+ if( IsAddMode() || !(nSelection & nsSelectionType::SEL_TXT) )
+ return sal_False;
+
+ OUString sTxt;
+ CharClass& rCC = GetAppCharClass();
+
+ // If the first character is no word character,
+ // no word selected.
+ sal_Unicode cPrev = GetChar(false);
+ sal_Unicode cNext = GetChar(true, -1);
+ if( !cPrev || !cNext ||
+ !rCC.isLetterNumeric( ( sTxt = OUString(cPrev) ), 0 ) ||
+ !rCC.isLetterNumeric( ( sTxt = OUString(cNext) ), 0 ) )
+ return NO_WORD;
+
+ cPrev = GetChar(false, -1);
+ cNext = GetChar(true);
+
+ int cWord = NO_WORD;
+ // is a word seleced?
+ if(!cWord && cPrev && cNext &&
+ CH_TXTATR_BREAKWORD != cPrev && CH_TXTATR_INWORD != cPrev &&
+ CH_TXTATR_BREAKWORD != cNext && CH_TXTATR_INWORD != cNext &&
+ !rCC.isLetterNumeric( ( sTxt = OUString(cPrev) ), 0 ) &&
+ !rCC.isLetterNumeric( ( sTxt = OUString(cNext) ), 0 ) )
+ cWord = WORD_NO_SPACE;
+
+ if(cWord == WORD_NO_SPACE && ' ' == cPrev )
+ {
+ cWord = WORD_SPACE_BEFORE;
+ // delete the space before
+ if(bCut)
+ {
+ Push();
+ if(IsCrsrPtAtEnd())
+ SwapPam();
+ ClearMark();
+ SetMark();
+ SwCrsrShell::Left(1,CRSR_SKIP_CHARS);
+ SwFEShell::Delete();
+ Pop( false );
+ }
+ }
+ else if(cWord == WORD_NO_SPACE && cNext == ' ')
+ {
+ cWord = WORD_SPACE_AFTER;
+ // delete the space behind
+ if(bCut) {
+ Push();
+ if(!IsCrsrPtAtEnd()) SwapPam();
+ ClearMark();
+ SetMark();
+ SwCrsrShell::Right(1,CRSR_SKIP_CHARS);
+ SwFEShell::Delete();
+ Pop( false );
+ }
+ }
+ return cWord;
+}
+
+ // jump to the next / previous hyperlink - inside text and also
+ // on graphics
+bool SwWrtShell::SelectNextPrevHyperlink( bool bNext )
+{
+ StartAction();
+ bool bRet = SwCrsrShell::SelectNxtPrvHyperlink( bNext );
+ if( !bRet )
+ {
+ // will we have this feature?
+ EnterStdMode();
+ if( bNext )
+ SttEndDoc(true);
+ else
+ SttEndDoc(false);
+ bRet = SwCrsrShell::SelectNxtPrvHyperlink( bNext );
+ }
+ EndAction();
+
+ bool bCreateXSelection = false;
+ const bool bFrmSelected = IsFrmSelected() || IsObjSelected();
+ if( IsSelection() )
+ {
+ if ( bFrmSelected )
+ UnSelectFrm();
+
+ // Set the function pointer for the canceling of the selection
+ // set at cursor
+ fnKillSel = &SwWrtShell::ResetSelect;
+ fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
+ bCreateXSelection = true;
+ }
+ else if( bFrmSelected )
+ {
+ EnterSelFrmMode();
+ bCreateXSelection = true;
+ }
+ else if( (CNT_GRF | CNT_OLE ) & GetCntType() )
+ {
+ SelectObj( GetCharRect().Pos() );
+ EnterSelFrmMode();
+ bCreateXSelection = true;
+ }
+
+ if( bCreateXSelection )
+ SwTransferable::CreateSelection( *this );
+
+ return bRet;
+}
+
+// For the preservation of the selection the cursor will be moved left
+// after SetMark(), so that the cursor is not moved by inserting text.
+// Because a present selection at the CORE page is cleared at the
+// current cursor position, the cursor will be pushed on the stack.
+// After moving, they will again resummarized.
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/wrtsh/wrtsh.hrc b/sw/source/uibase/wrtsh/wrtsh.hrc
new file mode 100644
index 000000000000..824a47f1c053
--- /dev/null
+++ b/sw/source/uibase/wrtsh/wrtsh.hrc
@@ -0,0 +1,39 @@
+/* -*- 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 .
+ */
+#ifndef _WRTSH_HRC
+#define _WRTSH_HRC
+
+#include "rcid.hrc"
+
+#define STR_DDEERROR_APP1 (RC_WRTSH_BEGIN + 2)
+#define STR_DDEERROR_APP2 (RC_WRTSH_BEGIN + 3)
+#define STR_DDEERROR_DATA1 (RC_WRTSH_BEGIN + 4)
+#define STR_DDEERROR_DATA2 (RC_WRTSH_BEGIN + 5)
+#define STR_DDEERROR_LINK1 (RC_WRTSH_BEGIN + 6)
+#define STR_DDEERROR_LINK2 (RC_WRTSH_BEGIN + 7)
+
+#define WRTSH_ACT_END STR_DDEERROR_LINK2
+
+#if WRTSH_ACT_END > RC_WRTSH_END
+#error Resource-Id Ueberlauf
+#endif
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/wrtsh/wrtsh.src b/sw/source/uibase/wrtsh/wrtsh.src
new file mode 100644
index 000000000000..5d6e3bff3f9b
--- /dev/null
+++ b/sw/source/uibase/wrtsh/wrtsh.src
@@ -0,0 +1,46 @@
+/* -*- 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 "wrtsh.hrc"
+
+String STR_DDEERROR_APP1
+{
+ Text[ en-US ] = "Application [" ;
+};
+String STR_DDEERROR_APP2
+{
+ Text[ en-US ] = "] is not responding." ;
+};
+String STR_DDEERROR_DATA1
+{
+ Text[ en-US ] = "Data for [" ;
+};
+String STR_DDEERROR_DATA2
+{
+ Text[ en-US ] = "] cannot be obtained" ;
+};
+String STR_DDEERROR_LINK1
+{
+ Text[ en-US ] = "Link to [" ;
+};
+String STR_DDEERROR_LINK2
+{
+ Text[ en-US ] = "] cannot be established" ;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx b/sw/source/uibase/wrtsh/wrtsh1.cxx
new file mode 100644
index 000000000000..b1893be9f54c
--- /dev/null
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -0,0 +1,1801 @@
+/* -*- 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 <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/embed/XVisualObject.hpp>
+#include <com/sun/star/embed/EmbedMisc.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+
+#include <svx/dialogs.hrc>
+
+#include <math.h>
+#include <hintids.hxx>
+#include <svx/hdft.hxx>
+#include <svx/svdview.hxx>
+#include <sot/factory.hxx>
+#include <svl/itemiter.hxx>
+#include <tools/bigint.hxx>
+#include <sot/storage.hxx>
+#include <svtools/insdlg.hxx>
+#include <sfx2/frmdescr.hxx>
+#include <sfx2/ipclient.hxx>
+#include <svtools/ehdl.hxx>
+#include <svtools/soerr.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/formatbreakitem.hxx>
+#include <editeng/svxacorr.hxx>
+#include <editeng/ulspitem.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/msgbox.hxx>
+#include <sfx2/printer.hxx>
+#include <unotools/charclass.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <svx/svxdlg.hxx>
+#include <svx/extrusionbar.hxx>
+#include <svx/fontworkbar.hxx>
+#include <frmfmt.hxx>
+#include <fmtftn.hxx>
+#include <fmthdft.hxx>
+#include <fmtpdsc.hxx>
+#include <wdocsh.hxx>
+#include <basesh.hxx>
+#include <swmodule.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <uitool.hxx>
+#include <cmdid.h>
+#include <cfgitems.hxx>
+#include <pagedesc.hxx>
+#include <frmmgr.hxx>
+#include <shellio.hxx>
+#include <uinums.hxx>
+#include <swundo.hxx>
+#include <swcli.hxx>
+#include <poolfmt.hxx>
+#include <wview.hxx>
+#include <edtwin.hxx>
+#include <fmtcol.hxx>
+#include <swtable.hxx>
+#include <caption.hxx>
+#include <viscrs.hxx>
+#include <swdtflvr.hxx>
+#include <crsskip.hxx>
+#include <doc.hxx>
+#include <wrtsh.hrc>
+#include <SwStyleNameMapper.hxx>
+#include <sfx2/request.hxx>
+#include <paratr.hxx>
+#include <ndtxt.hxx>
+#include <editeng/acorrcfg.hxx>
+#include <IMark.hxx>
+#include <sfx2/bindings.hxx>
+#include <svx/dialmgr.hxx>
+
+// -> #111827#
+#include <SwRewriter.hxx>
+#include <comcore.hrc>
+// <- #111827#
+
+#include <toolkit/helper/vclunohelper.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include "PostItMgr.hxx"
+#include <sfx2/msgpool.hxx>
+
+using namespace sw::mark;
+using namespace com::sun::star;
+
+#define COMMON_INI_LIST \
+ fnDrag(&SwWrtShell::BeginDrag),\
+ fnSetCrsr(&SwWrtShell::SetCrsr),\
+ fnEndDrag(&SwWrtShell::DefaultEndDrag),\
+ fnKillSel(&SwWrtShell::Ignore),\
+ pModeStack(0), \
+ ePageMove(MV_NO),\
+ pCrsrStack(0), \
+ rView(rShell),\
+ aNavigationMgr(*this), \
+ bDestOnStack(false)
+
+#define BITFLD_INI_LIST \
+ bClearMark = \
+ bIns = true;\
+ bAddMode = \
+ bBlockMode = \
+ bExtMode = \
+ bInSelect = \
+ bCopy = \
+ bLayoutMode = \
+ bSelWrd = \
+ bSelLn = \
+ mbRetainSelection = false; \
+ bIsInClickToEdit = false;
+
+static SvxAutoCorrect* lcl_IsAutoCorr()
+{
+ SvxAutoCorrect* pACorr = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ if( pACorr && !pACorr->IsAutoCorrFlag( CptlSttSntnc | CptlSttWrd |
+ AddNonBrkSpace | ChgOrdinalNumber |
+ ChgToEnEmDash | SetINetAttr | Autocorrect ))
+ pACorr = 0;
+ return pACorr;
+}
+
+void SwWrtShell::NoEdit(bool bHideCrsr)
+{
+ if(bHideCrsr)
+ HideCrsr();
+}
+
+void SwWrtShell::Edit()
+{
+ if (CanInsert())
+ {
+ ShowCrsr();
+ }
+}
+
+bool SwWrtShell::IsEndWrd()
+{
+ SwMvContext aMvContext(this);
+ if(IsEndPara() && !IsSttPara())
+ return true;
+
+ return IsEndWord();
+}
+
+// Insert string
+void SwWrtShell::InsertByWord( const OUString & rStr)
+{
+ if( !rStr.isEmpty() )
+ {
+ bool bDelim = GetAppCharClass().isLetterNumeric( rStr, 0 );
+ sal_Int32 nPos = 0, nStt = 0;
+ for( ; nPos < rStr.getLength(); nPos++ )
+ {
+ bool bTmpDelim = GetAppCharClass().isLetterNumeric( rStr, nPos );
+ if( bTmpDelim != bDelim )
+ {
+ Insert( rStr.copy( nStt, nPos - nStt ));
+ nStt = nPos;
+ }
+ }
+ if( nStt != nPos )
+ Insert( rStr.copy( nStt, nPos - nStt ));
+ }
+}
+
+void SwWrtShell::Insert( const OUString &rStr )
+{
+ ResetCursorStack();
+ if( !CanInsert() )
+ return;
+
+ bool bStarted = false;
+ bool bHasSel = HasSelection(),
+ bCallIns = bIns /*|| bHasSel*/;
+ bool bDeleted = false;
+
+ if( bHasSel || ( !bIns && SelectHiddenRange() ) )
+ {
+ // Only here parenthesizing, because the normal
+ // insert is already in parentheses at Editshell.
+ StartAllAction();
+
+ // #111827#
+ SwRewriter aRewriter;
+
+ aRewriter.AddRule(UndoArg1, GetCrsrDescr());
+ aRewriter.AddRule(UndoArg2, OUString(SW_RES(STR_YIELDS)));
+ {
+ OUString aTmpStr;
+ aTmpStr += SW_RES(STR_START_QUOTE);
+ aTmpStr += rStr;
+ aTmpStr += SW_RES(STR_END_QUOTE);
+
+ aRewriter.AddRule(UndoArg3, rStr);
+ }
+
+ StartUndo(UNDO_REPLACE, &aRewriter);
+ bStarted = true;
+ bDeleted = DelRight() != 0;
+ }
+
+ bCallIns ?
+ SwEditShell::Insert2( rStr, bDeleted ) : SwEditShell::Overwrite( rStr );
+
+ if( bStarted )
+ {
+ EndAllAction();
+ EndUndo();
+ }
+}
+
+// Maximum height limit not possible, because the maximum height
+// of the current frame can not be obtained.
+
+void SwWrtShell::Insert( const OUString &rPath, const OUString &rFilter,
+ const Graphic &rGrf, SwFlyFrmAttrMgr *pFrmMgr,
+ bool bRule )
+{
+ ResetCursorStack();
+ if ( !CanInsert() )
+ return;
+
+ StartAllAction();
+
+ SwRewriter aRewriter;
+ aRewriter.AddRule(UndoArg1, SW_RES(STR_GRAPHIC));
+
+ StartUndo(UNDO_INSERT, &aRewriter);
+
+ if ( HasSelection() )
+ DelRight();
+ // Inserted graphics in its own paragraph,
+ // if at the end of a non-empty paragraph.
+ //For i120928,avoid to split node
+
+ EnterSelFrmMode();
+
+ bool bSetGrfSize = true;
+ bool bOwnMgr = false;
+
+ if ( !pFrmMgr )
+ {
+ bOwnMgr = true;
+ pFrmMgr = new SwFlyFrmAttrMgr( true, this, FRMMGR_TYPE_GRF );
+
+ // CAUTION
+ // GetAttrSet makes an adjustment
+ // While pasting is a SwFrmSize present
+ // because of the DEF-Framesize
+ // These must be removed explicitly for the optimal size.
+ pFrmMgr->DelAttr(RES_FRM_SIZE);
+ }
+ else
+ {
+ Size aSz( pFrmMgr->GetSize() );
+ if ( !aSz.Width() || !aSz.Height() )
+ {
+ aSz.Width() = aSz.Height() = 567;
+ pFrmMgr->SetSize( aSz );
+ }
+ else if ( aSz.Width() != DFLT_WIDTH && aSz.Height() != DFLT_HEIGHT )
+ bSetGrfSize = false;
+
+ pFrmMgr->SetHeightSizeType(ATT_FIX_SIZE);
+ }
+
+ // Insert the graphic
+ SwFEShell::Insert(rPath, rFilter, &rGrf, &pFrmMgr->GetAttrSet());
+ if ( bOwnMgr )
+ pFrmMgr->UpdateAttrMgr();
+
+ if( bSetGrfSize && !bRule )
+ {
+ Size aGrfSize, aBound = GetGraphicDefaultSize();
+ GetGrfSize( aGrfSize );
+
+ // Add the margin attributes to GrfSize,
+ // because these counts at the margin additionally
+ aGrfSize.Width() += pFrmMgr->CalcWidthBorder();
+ aGrfSize.Height()+= pFrmMgr->CalcHeightBorder();
+
+ const BigInt aTempWidth( aGrfSize.Width() );
+ const BigInt aTempHeight( aGrfSize.Height());
+
+ // Fit width if necessary, scale down the height proportional thereafter.
+ if( aGrfSize.Width() > aBound.Width() )
+ {
+ aGrfSize.Width() = aBound.Width();
+ aGrfSize.Height() = ((BigInt)aBound.Width()) * aTempHeight / aTempWidth;
+ }
+ // Fit hight if necessary, scale down the width proportional thereafter.
+ if( aGrfSize.Height() > aBound.Height() )
+ {
+ aGrfSize.Height() = aBound.Height();
+ aGrfSize.Width() = ((BigInt)aBound.Height()) * aTempWidth / aTempHeight;
+ }
+ pFrmMgr->SetSize( aGrfSize );
+ pFrmMgr->UpdateFlyFrm();
+ }
+ if ( bOwnMgr )
+ delete pFrmMgr;
+
+ EndUndo();
+ EndAllAction();
+}
+
+// Insert an OLE-Objekt into the CORE.
+// if no object is transfered, then one will be created.
+
+void SwWrtShell::InsertObject( const svt::EmbeddedObjectRef& xRef, SvGlobalName *pName,
+ bool bActivate, sal_uInt16 nSlotId )
+{
+ ResetCursorStack();
+ if( !CanInsert() )
+ return;
+
+ if( !xRef.is() )
+ {
+ // temporary storage
+ svt::EmbeddedObjectRef xObj;
+ uno::Reference < embed::XStorage > xStor = comphelper::OStorageHelper::GetTemporaryStorage();
+ bool bDoVerb = true;
+ if ( pName )
+ {
+ comphelper::EmbeddedObjectContainer aCnt( xStor );
+ OUString aName;
+ // TODO/LATER: get aspect?
+ xObj.Assign( aCnt.CreateEmbeddedObject( pName->GetByteSequence(), aName ), embed::Aspects::MSOLE_CONTENT );
+ }
+ else
+ {
+ SvObjectServerList aServerList;
+ switch (nSlotId)
+ {
+ case SID_INSERT_OBJECT:
+ {
+ aServerList.FillInsertObjects();
+ aServerList.Remove( SwDocShell::Factory().GetClassId() );
+ // Intentionally no break!
+ }
+
+ // TODO/LATER: recording! Convert properties to items
+ case SID_INSERT_PLUGIN:
+ case SID_INSERT_FLOATINGFRAME:
+ {
+ SfxSlotPool* pSlotPool = SW_MOD()->GetSlotPool();
+ const SfxSlot* pSlot = pSlotPool->GetSlot(nSlotId);
+ OString aCmd(".uno:");
+ aCmd += pSlot->GetUnoName();
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ SfxAbstractInsertObjectDialog* pDlg =
+ pFact->CreateInsertObjectDialog( GetWin(), OStringToOUString( aCmd, RTL_TEXTENCODING_UTF8 ), xStor, &aServerList );
+ if ( pDlg )
+ {
+ pDlg->Execute();
+ bDoVerb = pDlg->IsCreateNew();
+ OUString aIconMediaType;
+ uno::Reference< io::XInputStream > xIconMetaFile = pDlg->GetIconIfIconified( &aIconMediaType );
+ xObj.Assign( pDlg->GetObject(),
+ xIconMetaFile.is() ? embed::Aspects::MSOLE_ICON : embed::Aspects::MSOLE_CONTENT );
+ if ( xIconMetaFile.is() )
+ xObj.SetGraphicStream( xIconMetaFile, aIconMediaType );
+
+ DELETEZ( pDlg );
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ if ( xObj.is() )
+ {
+ if( InsertOleObject( xObj ) && bActivate && bDoVerb )
+ {
+ SfxInPlaceClient* pClient = GetView().FindIPClient( xObj.GetObject(), &GetView().GetEditWin() );
+ if ( !pClient )
+ {
+ pClient = new SwOleClient( &GetView(), &GetView().GetEditWin(), xObj );
+ SetCheckForOLEInCaption( true );
+ }
+
+ if ( xObj.GetViewAspect() == embed::Aspects::MSOLE_ICON )
+ {
+ SwRect aArea = GetAnyCurRect( RECT_FLY_PRT_EMBEDDED, 0, xObj.GetObject() );
+ aArea.Pos() += GetAnyCurRect( RECT_FLY_EMBEDDED, 0, xObj.GetObject() ).Pos();
+ MapMode aMapMode( MAP_TWIP );
+ Size aSize = xObj.GetSize( &aMapMode );
+ aArea.Width( aSize.Width() );
+ aArea.Height( aSize.Height() );
+ RequestObjectResize( aArea, xObj.GetObject() );
+ }
+ else
+ CalcAndSetScale( xObj );
+
+ //#50270# We don't need to handle error, this is handled by the
+ //DoVerb in the SfxViewShell
+ pClient->DoVerb( SVVERB_SHOW );
+
+ // TODO/LATER: set document name - should be done in Client
+ }
+ }
+ }
+ else
+ {
+ if( HasSelection() )
+ DelRight();
+ InsertOleObject( xRef );
+ }
+}
+
+// Insert object into the Core.
+// From ClipBoard or Insert
+
+bool SwWrtShell::InsertOleObject( const svt::EmbeddedObjectRef& xRef, SwFlyFrmFmt **pFlyFrmFmt )
+{
+ ResetCursorStack();
+ StartAllAction();
+
+ StartUndo(UNDO_INSERT);
+
+ //Some differences between StarMath and any other objects:
+ //1. Selections should be deleted. For StarMath the Text should be
+ // passed to the Object
+ //2. If the cursor is at the end of an non empty paragraph a paragraph
+ // break should be insertet. StarMath objects are character bound and
+ // no break should be inserted.
+ //3. If an selection is passed to a StarMath object, this object should
+ // not be activated. sal_False should be returned then.
+ bool bStarMath = true;
+ bool bActivate = true;
+
+ // set parent to get correct VisArea(in case of object needing parent printer)
+ uno::Reference < container::XChild > xChild( xRef.GetObject(), uno::UNO_QUERY );
+ if ( xChild.is() )
+ xChild->setParent( mpDoc->GetDocShell()->GetModel() );
+
+ SvGlobalName aCLSID( xRef->getClassID() );
+ bStarMath = ( SotExchange::IsMath( aCLSID ) != 0 );
+ if( IsSelection() )
+ {
+ if( bStarMath )
+ {
+ OUString aMathData;
+ GetSelectedText( aMathData, GETSELTXT_PARABRK_TO_ONLYCR );
+
+ if( !aMathData.isEmpty() && svt::EmbeddedObjectRef::TryRunningState( xRef.GetObject() ) )
+ {
+ uno::Reference < beans::XPropertySet > xSet( xRef->getComponent(), uno::UNO_QUERY );
+ if ( xSet.is() )
+ {
+ try
+ {
+ xSet->setPropertyValue("Formula", uno::makeAny( OUString( aMathData ) ) );
+ bActivate = false;
+ }
+ catch (const uno::Exception&)
+ {
+ }
+ }
+ }
+ }
+ DelRight();
+ }
+
+ if ( !bStarMath )
+ SwFEShell::SplitNode( false, false );
+
+ EnterSelFrmMode();
+
+ SwFlyFrmAttrMgr aFrmMgr( true, this, FRMMGR_TYPE_OLE );
+ aFrmMgr.SetHeightSizeType(ATT_FIX_SIZE);
+
+ SwRect aBound;
+ CalcBoundRect( aBound, aFrmMgr.GetAnchor() );
+
+ //The Size should be suggested by the OLE server
+ MapMode aMapMode( MAP_TWIP );
+ Size aSz = xRef.GetSize( &aMapMode );
+
+ //Object size can be limited
+ if ( aSz.Width() > aBound.Width() )
+ {
+ //Always limit proportional.
+ aSz.Height() = aSz.Height() * aBound.Width() / aSz.Width();
+ aSz.Width() = aBound.Width();
+ }
+ aFrmMgr.SetSize( aSz );
+ SwFlyFrmFmt *pFmt = SwFEShell::InsertObject( xRef, &aFrmMgr.GetAttrSet() );
+
+ // --> #i972#
+ if ( bStarMath && mpDoc->get( IDocumentSettingAccess::MATH_BASELINE_ALIGNMENT ) )
+ AlignFormulaToBaseline( xRef.GetObject() );
+
+ if (pFlyFrmFmt)
+ *pFlyFrmFmt = pFmt;
+
+ if ( SotExchange::IsChart( aCLSID ) )
+ {
+ uno::Reference< embed::XEmbeddedObject > xEmbeddedObj( xRef.GetObject(), uno::UNO_QUERY );
+ if ( xEmbeddedObj.is() )
+ {
+ bool bDisableDataTableDialog = false;
+ svt::EmbeddedObjectRef::TryRunningState( xEmbeddedObj );
+ uno::Reference< beans::XPropertySet > xProps( xEmbeddedObj->getComponent(), uno::UNO_QUERY );
+ if ( xProps.is() &&
+ ( xProps->getPropertyValue("DisableDataTableDialog") >>= bDisableDataTableDialog ) &&
+ bDisableDataTableDialog )
+ {
+ xProps->setPropertyValue("DisableDataTableDialog",
+ uno::makeAny( sal_False ) );
+ xProps->setPropertyValue("DisableComplexChartTypes",
+ uno::makeAny( sal_False ) );
+ uno::Reference< util::XModifiable > xModifiable( xProps, uno::UNO_QUERY );
+ if ( xModifiable.is() )
+ {
+ xModifiable->setModified( sal_True );
+ }
+ }
+ }
+ }
+
+ EndAllAction();
+ GetView().AutoCaption(OLE_CAP, &aCLSID);
+
+ SwRewriter aRewriter;
+
+ if ( bStarMath )
+ aRewriter.AddRule(UndoArg1, SW_RES(STR_MATH_FORMULA));
+ else if ( SotExchange::IsChart( aCLSID ) )
+ aRewriter.AddRule(UndoArg1, SW_RES(STR_CHART));
+ else
+ aRewriter.AddRule(UndoArg1, SW_RES(STR_OLE));
+
+ EndUndo(UNDO_INSERT, &aRewriter);
+
+ return bActivate;
+}
+
+// The current selected OLE object will be loaded with the
+// verb into the server.
+
+void SwWrtShell::LaunchOLEObj( long nVerb )
+{
+ if ( GetCntType() == CNT_OLE &&
+ !GetView().GetViewFrame()->GetFrame().IsInPlace() )
+ {
+ svt::EmbeddedObjectRef& xRef = GetOLEObject();
+ OSL_ENSURE( xRef.is(), "OLE not found" );
+ SfxInPlaceClient* pCli=0;
+
+ pCli = GetView().FindIPClient( xRef.GetObject(), &GetView().GetEditWin() );
+ if ( !pCli )
+ pCli = new SwOleClient( &GetView(), &GetView().GetEditWin(), xRef );
+
+ ((SwOleClient*)pCli)->SetInDoVerb( true );
+
+ CalcAndSetScale( xRef );
+ pCli->DoVerb( nVerb );
+
+ ((SwOleClient*)pCli)->SetInDoVerb( false );
+ CalcAndSetScale( xRef );
+ }
+}
+
+void SwWrtShell::MoveObjectIfActive( svt::EmbeddedObjectRef& xObj, const Point& rOffset )
+{
+ try
+ {
+ sal_Int32 nState = xObj->getCurrentState();
+ if ( nState == ::com::sun::star::embed::EmbedStates::INPLACE_ACTIVE
+ || nState == ::com::sun::star::embed::EmbedStates::UI_ACTIVE )
+ {
+ SfxInPlaceClient* pCli =
+ GetView().FindIPClient( xObj.GetObject(), &(GetView().GetEditWin()) );
+ if ( pCli )
+ {
+ Rectangle aArea = pCli->GetObjArea();
+ aArea += rOffset;
+ pCli->SetObjArea( aArea );
+ }
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ }
+}
+
+void SwWrtShell::CalcAndSetScale( svt::EmbeddedObjectRef& xObj,
+ const SwRect *pFlyPrtRect,
+ const SwRect *pFlyFrmRect,
+ const bool bNoTxtFrmPrtAreaChanged )
+{
+ // Setting the scale of the client. This arises from the difference
+ // between the VisArea of the object and the ObjArea.
+ OSL_ENSURE( xObj.is(), "ObjectRef not valid" );
+
+ sal_Int64 nAspect = xObj.GetViewAspect();
+ if ( nAspect == embed::Aspects::MSOLE_ICON )
+ return; // the replacement image is completely controlled by container in this case
+
+ sal_Int64 nMisc = 0;
+ bool bLinkingChart = false;
+
+ try
+ {
+ nMisc = xObj->getStatus( nAspect );
+
+ // This can surely only be a non-active object, if desired they
+ // get the new size set as VisArea (StarChart).
+ if( embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE & nMisc )
+ {
+ // TODO/MBA: testing
+ SwRect aRect( pFlyPrtRect ? *pFlyPrtRect
+ : GetAnyCurRect( RECT_FLY_PRT_EMBEDDED, 0, xObj.GetObject() ));
+ if( !aRect.IsEmpty() )
+ {
+ // TODO/LEAN: getMapUnit can switch object to running state
+ // xObj.TryRunningState();
+
+ MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
+
+ // TODO/LATER: needs complete VisArea?!
+ Size aSize( OutputDevice::LogicToLogic( aRect.SVRect(), MAP_TWIP, aUnit ).GetSize() );
+ awt::Size aSz;
+ aSz.Width = aSize.Width();
+ aSz.Height = aSize.Height();
+ xObj->setVisualAreaSize( nAspect, aSz );
+ // #i48419# - action 'UpdateReplacement' doesn't
+ // have to change the modified state of the document.
+ // This is only a workaround for the defect, that this action
+ // modifies a document after load, because unnecessarily the
+ // replacement graphic is updated, in spite of the fact that
+ // nothing has been changed.
+ // If the replacement graphic changes by this action, the document
+ // will be already modified via other mechanisms.
+ {
+ bool bResetEnableSetModified(false);
+ if ( GetDoc()->GetDocShell()->IsEnableSetModified() )
+ {
+ GetDoc()->GetDocShell()->EnableSetModified( false );
+ bResetEnableSetModified = true;
+ }
+
+ //#i79576# don't destroy chart replacement images on load
+ //#i79578# don't request a new replacement image for charts to often
+ //a chart sends a modified call to the framework if it was changed
+ //thus the replacement update is already handled elsewhere
+ if ( !SotExchange::IsChart( xObj->getClassID() ) )
+ xObj.UpdateReplacement();
+
+ if ( bResetEnableSetModified )
+ {
+ GetDoc()->GetDocShell()->EnableSetModified( true );
+ }
+ }
+ }
+
+ // TODO/LATER: this is only a workaround,
+ uno::Reference< chart2::XChartDocument > xChartDocument( xObj->getComponent(), uno::UNO_QUERY );
+ bLinkingChart = ( xChartDocument.is() && !xChartDocument->hasInternalDataProvider() );
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ // TODO/LATER: handle the error
+ return;
+ }
+
+ SfxInPlaceClient* pCli = GetView().FindIPClient( xObj.GetObject(), &GetView().GetEditWin() );
+ if ( !pCli )
+ {
+ if ( (embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY & nMisc)
+ || bLinkingChart
+ // TODO/LATER: ResizeOnPrinterChange
+ //|| SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE & xObj->GetMiscStatus()
+ // --> OD #i117189# - refine condition for non-resizable objects
+ // non-resizable objects need to be set the size back by this method
+ || ( bNoTxtFrmPrtAreaChanged && nMisc & embed::EmbedMisc::EMBED_NEVERRESIZE ) )
+ {
+ pCli = new SwOleClient( &GetView(), &GetView().GetEditWin(), xObj );
+ }
+ else
+ return;
+ }
+
+ // TODO/LEAN: getMapUnit can switch object to running state
+ // xObj.TryRunningState();
+
+ awt::Size aSize;
+ try
+ {
+ aSize = xObj->getVisualAreaSize( nAspect );
+ }
+ catch (const embed::NoVisualAreaSizeException&)
+ {
+ OSL_FAIL("Can't get visual area size!\n" );
+ // the scaling will not be done
+ }
+ catch (const uno::Exception&)
+ {
+ // TODO/LATER: handle the error
+ OSL_FAIL("Can't get visual area size!\n" );
+ return;
+ }
+
+ Size _aVisArea( aSize.Width, aSize.Height );
+
+ Fraction aScaleWidth( 1, 1 );
+ Fraction aScaleHeight( 1, 1 );
+
+ bool bUseObjectSize = false;
+
+ // As long as there comes no reasonable size from the object,
+ // nothing can be scaled.
+ if( _aVisArea.Width() && _aVisArea.Height() )
+ {
+ const MapMode aTmp( MAP_TWIP );
+ MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
+ _aVisArea = OutputDevice::LogicToLogic( _aVisArea, aUnit, aTmp);
+ Size aObjArea;
+ if ( pFlyPrtRect )
+ aObjArea = pFlyPrtRect->SSize();
+ else
+ aObjArea = GetAnyCurRect( RECT_FLY_PRT_EMBEDDED, 0, xObj.GetObject() ).SSize();
+
+ // differ the aObjArea and _aVisArea by 1 Pixel then set new VisArea
+ long nX, nY;
+ SwSelPaintRects::Get1PixelInLogic( *this, &nX, &nY );
+ if( !( _aVisArea.Width() - nX <= aObjArea.Width() &&
+ _aVisArea.Width() + nX >= aObjArea.Width() &&
+ _aVisArea.Height()- nY <= aObjArea.Height()&&
+ _aVisArea.Height()+ nY >= aObjArea.Height() ))
+ {
+ if ( nMisc & embed::EmbedMisc::EMBED_NEVERRESIZE )
+ {
+ // the object must not be scaled,
+ // the size stored in object must be used for restoring
+ bUseObjectSize = true;
+ }
+ else
+ {
+ aScaleWidth = Fraction( aObjArea.Width(), _aVisArea.Width() );
+ aScaleHeight = Fraction( aObjArea.Height(), _aVisArea.Height());
+ }
+ }
+ }
+
+ // Now is the favorable time to set the ObjArea.
+ // The Scaling must be considered.
+ SwRect aArea;
+ if ( pFlyPrtRect )
+ {
+ aArea = *pFlyPrtRect;
+ aArea += pFlyFrmRect->Pos();
+ }
+ else
+ {
+ aArea = GetAnyCurRect( RECT_FLY_PRT_EMBEDDED, 0, xObj.GetObject() );
+ aArea.Pos() += GetAnyCurRect( RECT_FLY_EMBEDDED, 0, xObj.GetObject() ).Pos();
+ }
+
+ if ( bUseObjectSize )
+ {
+ // --> this moves non-resizable object so that when adding borders the baseline remains the same
+ const SwFlyFrmFmt *pFlyFrmFmt = dynamic_cast< const SwFlyFrmFmt * >( GetFlyFrmFmt() );
+ OSL_ENSURE( pFlyFrmFmt, "Could not find fly frame." );
+ if ( pFlyFrmFmt )
+ {
+ const Point &rPoint = pFlyFrmFmt->GetLastFlyFrmPrtRectPos();
+ SwRect aRect( pFlyPrtRect ? *pFlyPrtRect
+ : GetAnyCurRect( RECT_FLY_PRT_EMBEDDED, 0, xObj.GetObject() ));
+ aArea += rPoint - aRect.Pos(); // adjust area by diff of printing area position in order to keep baseline alignment correct.
+ }
+ aArea.Width ( _aVisArea.Width() );
+ aArea.Height( _aVisArea.Height() );
+ RequestObjectResize( aArea, xObj.GetObject() );
+ }
+ else
+ {
+ aArea.Width ( Fraction( aArea.Width() ) / pCli->GetScaleWidth() );
+ aArea.Height( Fraction( aArea.Height() ) / pCli->GetScaleHeight());
+ }
+
+ pCli->SetObjAreaAndScale( aArea.SVRect(), aScaleWidth, aScaleHeight );
+}
+
+void SwWrtShell::ConnectObj( svt::EmbeddedObjectRef& xObj, const SwRect &rPrt,
+ const SwRect &rFrm )
+{
+ SfxInPlaceClient* pCli = GetView().FindIPClient( xObj.GetObject(), &GetView().GetEditWin());
+ if ( !pCli )
+ pCli = new SwOleClient( &GetView(), &GetView().GetEditWin(), xObj );
+ CalcAndSetScale( xObj, &rPrt, &rFrm );
+}
+
+// Insert hard page break;
+// Selections will be overwritten
+
+void SwWrtShell::InsertPageBreak(const OUString *pPageDesc, ::boost::optional<sal_uInt16> oPgNum )
+{
+ ResetCursorStack();
+ if( CanInsert() )
+ {
+ SwActContext aActContext(this);
+ StartUndo(UNDO_UI_INSERT_PAGE_BREAK);
+
+ if ( !IsCrsrInTbl() )
+ {
+ if(HasSelection())
+ DelRight();
+ SwFEShell::SplitNode();
+ // delete the numbered attribute of the last line if the last line is empty
+ GetDoc()->ClearLineNumAttrs( *GetCrsr()->GetPoint() );
+ }
+
+ const SwPageDesc *pDesc = pPageDesc
+ ? FindPageDescByName( *pPageDesc, true ) : 0;
+ if( pDesc )
+ {
+ SwFmtPageDesc aDesc( pDesc );
+ aDesc.SetNumOffset( oPgNum );
+ SetAttrItem( aDesc );
+ }
+ else
+ SetAttrItem( SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE, RES_BREAK) );
+ EndUndo(UNDO_UI_INSERT_PAGE_BREAK);
+ }
+}
+
+// Insert hard page break;
+// Selections will be overwritten
+
+void SwWrtShell::InsertLineBreak()
+{
+ ResetCursorStack();
+ if( CanInsert() )
+ {
+ if(HasSelection())
+ DelRight();
+
+ const sal_Unicode cIns = 0x0A;
+ SvxAutoCorrect* pACorr = lcl_IsAutoCorr();
+ if( pACorr )
+ AutoCorrect( *pACorr, cIns );
+ else
+ SwWrtShell::Insert( OUString( cIns ) );
+ }
+}
+
+// Insert hard column break;
+// Selections will be overwritten
+
+void SwWrtShell::InsertColumnBreak()
+{
+ SwActContext aActContext(this);
+ ResetCursorStack();
+ if( CanInsert() )
+ {
+ StartUndo(UNDO_UI_INSERT_COLUMN_BREAK);
+
+ if ( !IsCrsrInTbl() )
+ {
+ if(HasSelection())
+ DelRight();
+ SwFEShell::SplitNode( false, false );
+ }
+ SetAttrItem(SvxFmtBreakItem(SVX_BREAK_COLUMN_BEFORE, RES_BREAK));
+
+ EndUndo(UNDO_UI_INSERT_COLUMN_BREAK);
+ }
+}
+
+// Insert footnote
+// rStr - optional footnote mark
+
+void SwWrtShell::InsertFootnote(const OUString &rStr, bool bEndNote, bool bEdit )
+{
+ ResetCursorStack();
+ if( CanInsert() )
+ {
+ if(HasSelection())
+ {
+ //collapse cursor to the end
+ if(!IsCrsrPtAtEnd())
+ SwapPam();
+ ClearMark();
+ }
+ SwPosition aPos = *GetCrsr()->GetPoint();
+ SwFmtFtn aFootNote( bEndNote );
+ if(!rStr.isEmpty())
+ aFootNote.SetNumStr( rStr );
+
+ SetAttrItem(aFootNote);
+
+ if( bEdit )
+ {
+ // For editing the footnote text.
+ Left(CRSR_SKIP_CHARS, false, 1, false );
+ GotoFtnTxt();
+ }
+ aNavigationMgr.addEntry(aPos);
+ }
+}
+
+// SplitNode; also, because
+// - of deleting selected content;
+// - of reset of the Cursorstack if necessary.
+
+void SwWrtShell::SplitNode( bool bAutoFmt, bool bCheckTableStart )
+{
+ ResetCursorStack();
+ if( CanInsert() )
+ {
+ SwActContext aActContext(this);
+
+ rView.GetEditWin().FlushInBuffer();
+ bool bHasSel = HasSelection();
+ if( bHasSel )
+ {
+ StartUndo( UNDO_INSERT );
+ DelRight();
+ }
+
+ SwFEShell::SplitNode( bAutoFmt, bCheckTableStart );
+ if( bHasSel )
+ EndUndo( UNDO_INSERT );
+ }
+}
+
+// Turn on numbering
+// Parameter: Optional specification of a name for the named list;
+// this indicates a position if it is possible to convert them
+// into a number and less than nMaxRules.
+
+// To test the CharFormats at the numbering
+// external void SetNumChrFmt( SwWrtShell*, SwNumRules& );
+
+// -> #i40041#
+// Preconditions (as far as OD has figured out):
+// - <SwEditShell::HasNumber()> is sal_False, if <bNum> is sal_True
+// - <SwEditShell::HasBullet()> is sal_False, if <bNum> is sal_False
+// Behavior of method is determined by the current situation at the current
+// cursor position in the document.
+void SwWrtShell::NumOrBulletOn(bool bNum)
+{
+ // determine numbering rule found at current cursor position in the document.
+ const SwNumRule* pCurRule = GetNumRuleAtCurrCrsrPos();
+
+ StartUndo(UNDO_NUMORNONUM);
+
+ const SwNumRule * pNumRule = pCurRule;
+
+ // - activate outline rule respectively turning on outline rule for
+ // current text node. But, only for turning on a numbering (<bNum> == sal_True).
+ // - overwrite found numbering rule at current cursor position, if
+ // no numbering rule can be retrieved from the paragraph style.
+ bool bContinueFoundNumRule( false );
+ bool bActivateOutlineRule( false );
+ int nActivateOutlineLvl( MAXLEVEL ); // only relevant, if <bActivateOutlineRule> == sal_True
+ SwTxtFmtColl * pColl = GetCurTxtFmtColl();
+ if ( pColl )
+ {
+ // retrieve numbering rule at paragraph
+ // style, which is found at current cursor position in the document.
+ SwNumRule* pCollRule = mpDoc->FindNumRulePtr(pColl->GetNumRule().GetValue());
+ // #125993# - The outline numbering rule isn't allowed
+ // to be derived from a parent paragraph style to a derived one.
+ // Thus check, if the found outline numbering rule is directly
+ // set at the paragraph style <pColl>. If not, set <pCollRule> to NULL
+ if ( pCollRule && pCollRule == GetDoc()->GetOutlineNumRule() )
+ {
+ const SwNumRule* pDirectCollRule =
+ mpDoc->FindNumRulePtr(pColl->GetNumRule( false ).GetValue());
+ if ( !pDirectCollRule )
+ {
+ pCollRule = 0;
+ }
+ }
+
+ if ( !pCollRule )
+ {
+ pNumRule = pCollRule;
+ }
+ // no activation or continuation of outline numbering in Writer/Web document
+ else if ( bNum &&
+ !dynamic_cast<SwWebDocShell*>(GetDoc()->GetDocShell()) &&
+ pCollRule == GetDoc()->GetOutlineNumRule() )
+ {
+ if ( pNumRule == pCollRule )
+ {
+ // check, if text node at current cursor positioned is counted.
+ // If not, let it been counted. Then it has to be checked,
+ // of the outline numbering has to be activated or continued.
+ SwTxtNode* pTxtNode =
+ GetCrsr()->GetPoint()->nNode.GetNode().GetTxtNode();
+ if ( pTxtNode && !pTxtNode->IsCountedInList() )
+ {
+ // check, if numbering of the outline level of the paragraph
+ // style is active. If not, activate this outline level.
+ nActivateOutlineLvl = pColl->GetAssignedOutlineStyleLevel();
+ OSL_ENSURE( pColl->IsAssignedToListLevelOfOutlineStyle(),
+ "<SwWrtShell::NumOrBulletOn(..)> - paragraph style with outline rule, but no outline level" );
+ if ( pColl->IsAssignedToListLevelOfOutlineStyle() &&
+ pCollRule->Get( static_cast<sal_uInt16>(nActivateOutlineLvl) ).GetNumberingType()
+ == SVX_NUM_NUMBER_NONE )
+ {
+ // activate outline numbering
+ bActivateOutlineRule = true;
+ }
+ else
+ {
+ // turning on outline numbering at current cursor position
+ bContinueFoundNumRule = true;
+ }
+ }
+ else
+ {
+ // #i101234#
+ // activate outline numbering, because from the precondition
+ // it's known, that <SwEdit::HasNumber()> == sal_False
+ bActivateOutlineRule = true;
+ nActivateOutlineLvl = pColl->GetAssignedOutlineStyleLevel();
+ }
+ }
+ else if ( !pNumRule )
+ {
+ // #i101234#
+ // Check, if corresponding list level of the outline numbering
+ // has already a numbering format set.
+ nActivateOutlineLvl = pColl->GetAssignedOutlineStyleLevel();
+ if ( pCollRule->Get( static_cast<sal_uInt16>(nActivateOutlineLvl) ).GetNumberingType()
+ == SVX_NUM_NUMBER_NONE )
+ {
+ // activate outline numbering, because from the precondition
+ // it's known, that <SwEdit::HasNumber()> == sal_False
+ bActivateOutlineRule = true;
+ }
+ else
+ {
+ // turning on outline numbering at current cursor position
+ bContinueFoundNumRule = true;
+ }
+ }
+ else
+ {
+ // check, if numbering of the outline level of the paragraph
+ // style is active. If not, activate this outline level.
+ nActivateOutlineLvl = pColl->GetAssignedOutlineStyleLevel();
+ OSL_ENSURE( pColl->IsAssignedToListLevelOfOutlineStyle(),
+ "<SwWrtShell::NumOrBulletOn(..)> - paragraph style with outline rule, but no outline level" );
+ if ( pColl->IsAssignedToListLevelOfOutlineStyle() &&
+ pCollRule->Get( static_cast<sal_uInt16>(nActivateOutlineLvl) ).GetNumberingType()
+ == SVX_NUM_NUMBER_NONE )
+ {
+ // activate outline numbering
+ bActivateOutlineRule = true;
+ }
+ else
+ {
+ // turning on outline numbering at current cursor position
+ bContinueFoundNumRule = true;
+ }
+ }
+ pNumRule = pCollRule;
+ }
+ }
+
+ // Only automatic numbering/bullet rules should be changed.
+ // Note: The outline numbering rule is also an automatic one. It's only
+ // changed, if it has to be activated.
+ if ( pNumRule )
+ {
+ if ( !pNumRule->IsAutoRule() )
+ {
+ pNumRule = 0;
+ }
+ else if ( pNumRule == GetDoc()->GetOutlineNumRule() &&
+ !bActivateOutlineRule && !bContinueFoundNumRule )
+ {
+ pNumRule = 0;
+ }
+ }
+
+ // Search for a previous numbering/bullet rule to continue it.
+ OUString sContinuedListId;
+ if ( !pNumRule )
+ {
+ pNumRule = GetDoc()->SearchNumRule( *GetCrsr()->GetPoint(),
+ false, bNum, false, 0,
+ sContinuedListId );
+ bContinueFoundNumRule = pNumRule != 0;
+ }
+
+ if (pNumRule)
+ {
+ SwNumRule aNumRule(*pNumRule);
+
+ // do not change found numbering/bullet rule, if it should only be continued.
+ if ( !bContinueFoundNumRule )
+ {
+ SwTxtNode * pTxtNode = GetCrsr()->GetPoint()->nNode.GetNode().GetTxtNode();
+
+ if (pTxtNode)
+ {
+ // use above retrieve outline level, if outline numbering has to be activated.
+ int nLevel = bActivateOutlineRule
+ ? nActivateOutlineLvl
+ : pTxtNode->GetActualListLevel();
+
+ if (nLevel < 0)
+ nLevel = 0;
+
+ if (nLevel >= MAXLEVEL)
+ nLevel = MAXLEVEL - 1;
+
+ SwNumFmt aFmt(aNumRule.Get(static_cast<sal_uInt16>(nLevel)));
+
+ if (bNum)
+ aFmt.SetNumberingType(SVX_NUM_ARABIC);
+ else
+ {
+ // #i63395# Only apply user defined default bullet font
+ if ( numfunc::IsDefBulletFontUserDefined() )
+ {
+ const Font* pFnt = &numfunc::GetDefBulletFont();
+ aFmt.SetBulletFont( pFnt );
+ }
+ aFmt.SetBulletChar( numfunc::GetBulletChar(static_cast<sal_uInt8>(nLevel)));
+ aFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL);
+ // #i93908# clear suffix for bullet lists
+ aFmt.SetPrefix(OUString());
+ aFmt.SetSuffix(OUString());
+ }
+ aNumRule.Set(static_cast<sal_uInt16>(nLevel), aFmt);
+ }
+ }
+
+ // reset indent attribute on applying list style
+ SetCurNumRule( aNumRule, false, sContinuedListId, true );
+ }
+ else
+ {
+ // #i95907#
+ const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
+ numfunc::GetDefaultPositionAndSpaceMode() );
+ SwNumRule aNumRule( GetUniqueNumRuleName(), ePosAndSpaceMode );
+ // Append the character template at the numbering.
+ SwCharFmt* pChrFmt;
+ SwDocShell* pDocSh = GetView().GetDocShell();
+ // #i63395#
+ // Only apply user defined default bullet font
+ const Font* pFnt = numfunc::IsDefBulletFontUserDefined()
+ ? &numfunc::GetDefBulletFont()
+ : 0;
+
+ if (bNum)
+ {
+ pChrFmt = GetCharFmtFromPool( RES_POOLCHR_NUM_LEVEL );
+ }
+ else
+ {
+ pChrFmt = GetCharFmtFromPool( RES_POOLCHR_BUL_LEVEL );
+ }
+
+ const SwTxtNode* pTxtNode = GetCrsr()->GetPoint()->nNode.GetNode().GetTxtNode();
+ const SwTwips nWidthOfTabs = pTxtNode
+ ? pTxtNode->GetWidthOfLeadingTabs()
+ : 0;
+ GetDoc()->RemoveLeadingWhiteSpace( *GetCrsr()->GetPoint() );
+
+ const bool bHtml = 0 != PTR_CAST(SwWebDocShell, pDocSh);
+ const bool bRightToLeft = IsInRightToLeftText();
+ for( sal_uInt8 nLvl = 0; nLvl < MAXLEVEL; ++nLvl )
+ {
+ SwNumFmt aFmt( aNumRule.Get( nLvl ) );
+ aFmt.SetCharFmt( pChrFmt );
+
+ if (! bNum)
+ {
+ // #i63395#
+ // Only apply user defined default bullet font
+ if ( pFnt )
+ {
+ aFmt.SetBulletFont( pFnt );
+ }
+ aFmt.SetBulletChar( numfunc::GetBulletChar(nLvl) );
+ aFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL);
+ // #i93908# clear suffix for bullet lists
+ aFmt.SetPrefix(OUString());
+ aFmt.SetSuffix(OUString());
+ }
+
+ // #i95907#
+ if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
+ {
+ if(bHtml && nLvl)
+ {
+ // 1/2" for HTML
+ aFmt.SetLSpace(720);
+ aFmt.SetAbsLSpace(nLvl * 720);
+ }
+ else if ( nWidthOfTabs > 0 )
+ {
+ aFmt.SetAbsLSpace(nWidthOfTabs + nLvl * 720);
+ }
+ }
+
+ // #i38904# Default alignment for
+ // numbering/bullet should be rtl in rtl paragraph:
+ if ( bRightToLeft )
+ {
+ aFmt.SetNumAdjust( SVX_ADJUST_RIGHT );
+ }
+
+ aNumRule.Set( nLvl, aFmt );
+ }
+
+ // #i95907#
+ if ( pTxtNode &&
+ ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
+ {
+
+ const SwTwips nTxtNodeIndent = pTxtNode->GetAdditionalIndentForStartingNewList();
+ if ( ( nTxtNodeIndent + nWidthOfTabs ) != 0 )
+ {
+ // #i111172#
+ // If text node is already inside a list, assure that the indents
+ // are the same. Thus, adjust the indent change value by subtracting
+ // indents of to be applied list style.
+ SwTwips nIndentChange = nTxtNodeIndent + nWidthOfTabs;
+ if ( pTxtNode->GetNumRule() )
+ {
+ const SwNumFmt aFmt( aNumRule.Get( 0 ) );
+ if ( aFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
+ {
+ nIndentChange -= aFmt.GetIndentAt() + aFmt.GetFirstLineIndent();
+ }
+ }
+ aNumRule.ChangeIndent( nIndentChange );
+ }
+ }
+ // reset indent attribute on applying list style
+ // start new list
+ SetCurNumRule( aNumRule, true, OUString(), true );
+ }
+
+ EndUndo(UNDO_NUMORNONUM);
+}
+// <- #i40041#
+
+void SwWrtShell::NumOn()
+{
+ NumOrBulletOn(true);
+}
+
+void SwWrtShell::NumOrBulletOff()
+{
+ const SwNumRule * pCurNumRule = GetNumRuleAtCurrCrsrPos();
+
+ if (pCurNumRule)
+ {
+ if (pCurNumRule->IsOutlineRule())
+ {
+ SwNumRule aNumRule(*pCurNumRule);
+
+ SwTxtNode * pTxtNode =
+ GetCrsr()->GetPoint()->nNode.GetNode().GetTxtNode();
+
+ if (pTxtNode)
+ {
+ int nLevel = pTxtNode->GetActualListLevel();
+
+ if (nLevel < 0)
+ nLevel = 0;
+
+ if (nLevel >= MAXLEVEL)
+ nLevel = MAXLEVEL - 1;
+
+ SwNumFmt aFmt(aNumRule.Get(static_cast<sal_uInt16>(nLevel)));
+
+ aFmt.SetNumberingType(SVX_NUM_NUMBER_NONE);
+ aNumRule.Set(nLevel, aFmt);
+
+ // no start or continuation of a list - the outline style is only changed.
+ SetCurNumRule( aNumRule, false );
+ }
+ }
+ else
+ {
+ DelNumRules();
+ }
+
+ // #126346# - Cursor can not be anymore in front of
+ // a label, because numbering/bullet is switched off.
+ SetInFrontOfLabel( false );
+ }
+}
+// <- #i29560#
+
+// Request Default-Bulletlist
+
+void SwWrtShell::BulletOn()
+{
+ NumOrBulletOn(false);
+}
+
+SelectionType SwWrtShell::GetSelectionType() const
+{
+ // ContentType cannot be determined within a
+ // Start-/Endaction parentheses.
+ // Because there is no invalid value TEXT will be returned.
+ // The value does not matter, it may be updated in endaction anyway.
+
+ if ( BasicActionPend() )
+ return IsSelFrmMode() ? nsSelectionType::SEL_FRM : nsSelectionType::SEL_TXT;
+
+ SwView &_rView = ((SwView&)GetView());
+ if (_rView.GetPostItMgr() && _rView.GetPostItMgr()->HasActiveSidebarWin() )
+ return nsSelectionType::SEL_POSTIT;
+
+ // Inserting a frame is not a DrawMode
+ int nCnt;
+ if ( !_rView.GetEditWin().IsFrmAction() &&
+ (IsObjSelected() || (_rView.IsDrawMode() && !IsFrmSelected()) ))
+ {
+ if (GetDrawView()->IsTextEdit())
+ nCnt = nsSelectionType::SEL_DRW_TXT;
+ else
+ {
+ if (GetView().IsFormMode()) // Only Form selected
+ nCnt = nsSelectionType::SEL_DRW_FORM;
+ else
+ nCnt = nsSelectionType::SEL_DRW; // Any draw object
+
+ if (_rView.IsBezierEditMode())
+ nCnt |= nsSelectionType::SEL_BEZ;
+ else if( GetDrawView()->GetContext() == SDRCONTEXT_MEDIA )
+ nCnt |= nsSelectionType::SEL_MEDIA;
+
+ if (svx::checkForSelectedCustomShapes(
+ const_cast<SdrView *>(GetDrawView()),
+ true /* bOnlyExtruded */ ))
+ {
+ nCnt |= nsSelectionType::SEL_EXTRUDED_CUSTOMSHAPE;
+ }
+ sal_uInt32 nCheckStatus = 0;
+ if (svx::checkForSelectedFontWork(
+ const_cast<SdrView *>(GetDrawView()), nCheckStatus ))
+ {
+ nCnt |= nsSelectionType::SEL_FONTWORK;
+ }
+ }
+
+ return nCnt;
+ }
+
+ nCnt = GetCntType();
+
+ if ( IsFrmSelected() )
+ {
+ if (_rView.IsDrawMode())
+ _rView.LeaveDrawCreate(); // clean up (Bug #45639)
+ if ( !(nCnt & (CNT_GRF | CNT_OLE)) )
+ return nsSelectionType::SEL_FRM;
+ }
+
+ if ( IsCrsrInTbl() )
+ nCnt |= nsSelectionType::SEL_TBL;
+
+ if ( IsTableMode() )
+ nCnt |= (nsSelectionType::SEL_TBL | nsSelectionType::SEL_TBL_CELLS);
+
+ // Do not pop up numbering toolbar, if the text node has a numbering of type SVX_NUM_NUMBER_NONE.
+ const SwNumRule* pNumRule = GetNumRuleAtCurrCrsrPos();
+ if ( pNumRule )
+ {
+ const SwTxtNode* pTxtNd =
+ GetCrsr()->GetPoint()->nNode.GetNode().GetTxtNode();
+
+ if ( pTxtNd && pTxtNd->IsInList() )
+ {
+ const SwNumFmt& rFmt = pNumRule->Get(sal::static_int_cast< sal_uInt8, sal_Int32>(pTxtNd->GetActualListLevel()));
+ if ( SVX_NUM_NUMBER_NONE != rFmt.GetNumberingType() )
+ nCnt |= nsSelectionType::SEL_NUM;
+ }
+ }
+
+ return nCnt;
+}
+
+// Find the text collection with the name rCollname
+// Returns: Pointer at the collection or 0, if no
+// text collection with this name exists, or
+// this is a default template.
+
+SwTxtFmtColl *SwWrtShell::GetParaStyle(const OUString &rCollName, GetStyle eCreate )
+{
+ SwTxtFmtColl* pColl = FindTxtFmtCollByName( rCollName );
+ if( !pColl && GETSTYLE_NOCREATE != eCreate )
+ {
+ sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName( rCollName, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL );
+ if( USHRT_MAX != nId || GETSTYLE_CREATEANY == eCreate )
+ pColl = GetTxtCollFromPool( nId );
+ }
+ return pColl;
+}
+
+// Find the text collection with the name rCollname
+// Returns: Pointer at the collection or 0, if no
+// character template with this name exists, or
+// this is a default template or template is automatic.
+
+SwCharFmt *SwWrtShell::GetCharStyle(const OUString &rFmtName, GetStyle eCreate )
+{
+ SwCharFmt* pFmt = FindCharFmtByName( rFmtName );
+ if( !pFmt && GETSTYLE_NOCREATE != eCreate )
+ {
+ sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName( rFmtName, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
+ if( USHRT_MAX != nId || GETSTYLE_CREATEANY == eCreate )
+ pFmt = (SwCharFmt*)GetFmtFromPool( nId );
+ }
+ return pFmt;
+}
+
+// Find the table format with the name rFmtname
+// Returns: Pointer at the collection or 0, if no
+// frame format with this name exists or
+// this is a default format or the format is automatic.
+
+SwFrmFmt *SwWrtShell::GetTblStyle(const OUString &rFmtName)
+{
+ SwFrmFmt *pFmt = 0;
+ for( sal_uInt16 i = GetTblFrmFmtCount(); i; )
+ if( !( pFmt = &GetTblFrmFmt( --i ) )->IsDefault() &&
+ pFmt->GetName() == rFmtName && IsUsed( *pFmt ) )
+ return pFmt;
+ return 0;
+}
+
+SwNavigationMgr& SwWrtShell::GetNavigationMgr() {
+ return aNavigationMgr;
+}
+
+void SwWrtShell::addCurrentPosition() {
+ SwPaM* pPaM = GetCrsr();
+ aNavigationMgr.addEntry(*pPaM->GetPoint());
+}
+
+// Applying templates
+
+void SwWrtShell::SetPageStyle(const OUString &rCollName)
+{
+ if( !SwCrsrShell::HasSelection() && !IsSelFrmMode() && !IsObjSelected() )
+ {
+ SwPageDesc* pDesc = FindPageDescByName( rCollName, true );
+ if( pDesc )
+ ChgCurPageDesc( *pDesc );
+ }
+}
+
+// Access templates
+
+OUString SwWrtShell::GetCurPageStyle( const bool bCalcFrm ) const
+{
+ return GetPageDesc(GetCurPageDesc( bCalcFrm )).GetName();
+}
+
+// Change the current template referring to the existing change.
+
+void SwWrtShell::QuickUpdateStyle()
+{
+ SwTxtFmtColl *pColl = GetCurTxtFmtColl();
+
+ // Default cannot be changed
+ if(pColl && !pColl->IsDefault())
+ {
+ FillByEx(pColl);
+ // Also apply the template to remove hard attribute assignment.
+ SetTxtFmtColl(pColl);
+ }
+}
+
+void SwWrtShell::AutoUpdatePara(SwTxtFmtColl* pColl, const SfxItemSet& rStyleSet, SwPaM* pPaM )
+{
+ SwPaM* pCrsr = pPaM ? pPaM : GetCrsr( );
+ SfxItemSet aCoreSet( GetAttrPool(),
+ RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
+ RES_PARATR_BEGIN, RES_PARATR_END - 1,
+ RES_FRMATR_BEGIN, RES_FRMATR_END - 1,
+ SID_ATTR_TABSTOP_POS, SID_ATTR_TABSTOP_POS,
+ SID_ATTR_TABSTOP_DEFAULTS, SID_ATTR_TABSTOP_DEFAULTS,
+ SID_ATTR_TABSTOP_OFFSET, SID_ATTR_TABSTOP_OFFSET,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
+ SID_ATTR_PARA_MODEL, SID_ATTR_PARA_KEEP,
+ SID_ATTR_PARA_PAGENUM, SID_ATTR_PARA_PAGENUM,
+ 0 );
+ GetPaMAttr( pCrsr, aCoreSet );
+ bool bReset = false;
+ SfxItemIter aParaIter( aCoreSet );
+ const SfxPoolItem* pParaItem = aParaIter.FirstItem();
+ while( pParaItem )
+ {
+ if(!IsInvalidItem(pParaItem))
+ {
+ sal_uInt16 nWhich = pParaItem->Which();
+ if(SFX_ITEM_SET == aCoreSet.GetItemState(nWhich) &&
+ SFX_ITEM_SET == rStyleSet.GetItemState(nWhich))
+ {
+ aCoreSet.ClearItem(nWhich);
+ bReset = true;
+ }
+ }
+ pParaItem = aParaIter.NextItem();
+ }
+ StartAction();
+ if(bReset)
+ {
+ ResetAttr( std::set<sal_uInt16>(), pCrsr );
+ SetAttrSet(aCoreSet, 0, pCrsr);
+ }
+ mpDoc->ChgFmt(*pColl, rStyleSet );
+ EndAction();
+}
+
+void SwWrtShell::AutoUpdateFrame( SwFrmFmt* pFmt, const SfxItemSet& rStyleSet )
+{
+ StartAction();
+
+ ResetFlyFrmAttr( 0, &rStyleSet );
+ pFmt->SetFmtAttr( rStyleSet );
+
+ EndAction();
+}
+
+void SwWrtShell::AutoCorrect( SvxAutoCorrect& rACorr, sal_Unicode cChar )
+{
+ ResetCursorStack();
+ if(CanInsert())
+ {
+ bool bStarted = false;
+ if(HasSelection())
+ {
+ // Only parenthese here, because the regular insert
+ // is already clipped to the editshell
+ StartAllAction();
+ StartUndo(UNDO_INSERT);
+ bStarted = true;
+ DelRight();
+ }
+ SwEditShell::AutoCorrect( rACorr, IsInsMode(), cChar );
+
+ if(bStarted)
+ {
+ EndAllAction();
+ EndUndo(UNDO_INSERT);
+ }
+ }
+}
+
+// Some kind of controlled copy ctor
+
+SwWrtShell::SwWrtShell( SwWrtShell& rSh, Window *_pWin, SwView &rShell )
+ : SwFEShell( rSh, _pWin ),
+ COMMON_INI_LIST
+{
+ BITFLD_INI_LIST
+ SET_CURR_SHELL( this );
+
+ SetSfxViewShell( (SfxViewShell *)&rShell );
+ SetFlyMacroLnk( LINK(this, SwWrtShell, ExecFlyMac) );
+
+ // place the cursor on the first field...
+ IFieldmark *pBM = NULL;
+ if ( IsFormProtected() && ( pBM = GetFieldmarkAfter( ) ) !=NULL ) {
+ GotoFieldmark(pBM);
+ }
+}
+
+SwWrtShell::SwWrtShell( SwDoc& rDoc, Window *_pWin, SwView &rShell,
+ const SwViewOption *pViewOpt )
+ : SwFEShell( rDoc, _pWin, pViewOpt),
+ COMMON_INI_LIST
+{
+ BITFLD_INI_LIST
+ SET_CURR_SHELL( this );
+ SetSfxViewShell( (SfxViewShell *)&rShell );
+ SetFlyMacroLnk( LINK(this, SwWrtShell, ExecFlyMac) );
+
+ // place the cursor on the first field...
+ IFieldmark *pBM = NULL;
+ if ( IsFormProtected() && ( pBM = GetFieldmarkAfter( ) ) !=NULL ) {
+ GotoFieldmark(pBM);
+ }
+}
+
+SwWrtShell::~SwWrtShell()
+{
+ SET_CURR_SHELL( this );
+ while(IsModePushed())
+ PopMode();
+ while(PopCrsr(false))
+ ;
+ SwTransferable::ClearSelection( *this );
+}
+
+bool SwWrtShell::Pop( bool bOldCrsr )
+{
+ bool bRet = SwCrsrShell::Pop( bOldCrsr );
+ if( bRet && IsSelection() )
+ {
+ fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
+ fnKillSel = &SwWrtShell::ResetSelect;
+ }
+ return bRet;
+}
+
+bool SwWrtShell::CanInsert()
+{
+ if(IsSelFrmMode())
+ {
+ return false;
+ }
+
+ if(IsObjSelected())
+ {
+ return false;
+ }
+
+ if(GetView().GetDrawFuncPtr())
+ {
+ return false;
+ }
+
+ if(GetView().GetPostItMgr()->GetActiveSidebarWin())
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void SwWrtShell::ChgDBData(const SwDBData& aDBData)
+{
+ SwEditShell::ChgDBData(aDBData);
+ //notify the db-beamer if available
+ GetView().NotifyDBChanged();
+}
+
+OUString SwWrtShell::GetSelDescr() const
+{
+ OUString aResult;
+
+ int nSelType = GetSelectionType();
+ switch (nSelType)
+ {
+ case nsSelectionType::SEL_GRF:
+ aResult = SW_RESSTR(STR_GRAPHIC);
+
+ break;
+ case nsSelectionType::SEL_FRM:
+ {
+ const SwFrmFmt * pFrmFmt = GetCurFrmFmt();
+
+ if (pFrmFmt)
+ aResult = pFrmFmt->GetDescription();
+ }
+ break;
+ case nsSelectionType::SEL_DRW:
+ {
+ aResult = SW_RESSTR(STR_DRAWING_OBJECTS);
+ }
+ break;
+ default:
+ if (0 != mpDoc)
+ aResult = GetCrsrDescr();
+ }
+
+ return aResult;
+}
+
+void SwWrtShell::ApplyViewOptions( const SwViewOption &rOpt )
+{
+ SwFEShell::ApplyViewOptions( rOpt );
+ //#i115062# invalidate meta character slot
+ GetView().GetViewFrame()->GetBindings().Invalidate( FN_VIEW_META_CHARS );
+}
+
+void SwWrtShell::SetReadonlyOption(bool bSet)
+{
+ GetView().GetEditWin().GetFrameControlsManager().SetReadonlyControls( bSet );
+ SwViewShell::SetReadonlyOption( bSet );
+}
+
+// Switch on/off header or footer of a page style - if an empty name is
+// given all styles are changed
+
+void SwWrtShell::ChangeHeaderOrFooter(
+ const OUString& rStyleName, bool bHeader, bool bOn, bool bShowWarning)
+{
+ addCurrentPosition();
+ StartAllAction();
+ StartUndo( UNDO_HEADER_FOOTER ); // #i7983#
+ bool bExecute = true;
+ bool bCrsrSet = false;
+ for( sal_uInt16 nFrom = 0, nTo = GetPageDescCnt();
+ nFrom < nTo; ++nFrom )
+ {
+ int bChgd = sal_False;
+ SwPageDesc aDesc( GetPageDesc( nFrom ));
+ OUString sTmp(aDesc.GetName());
+ if( rStyleName.isEmpty() || rStyleName == sTmp )
+ {
+ if( bShowWarning && !bOn && GetActiveView() && GetActiveView() == &GetView() &&
+ ( (bHeader && aDesc.GetMaster().GetHeader().IsActive()) ||
+ (!bHeader && aDesc.GetMaster().GetFooter().IsActive()) ) )
+ {
+ bShowWarning = false;
+ //Actions have to be closed while the dialog is showing
+ EndAllAction();
+
+ Window* pParent = &GetView().GetViewFrame()->GetWindow();
+ short nResult;
+ if (bHeader)
+ nResult = DeleteHeaderDialog(pParent).Execute();
+ else
+ nResult = DeleteFooterDialog(pParent).Execute();
+ bExecute = nResult == RET_YES;
+
+ StartAllAction();
+ }
+ if( bExecute )
+ {
+ bChgd = sal_True;
+ SwFrmFmt &rMaster = aDesc.GetMaster();
+ if(bHeader)
+ rMaster.SetFmtAttr( SwFmtHeader( bOn ));
+ else
+ rMaster.SetFmtAttr( SwFmtFooter( bOn ));
+ if( bOn )
+ {
+ SvxULSpaceItem aUL(bHeader ? 0 : MM50, bHeader ? MM50 : 0, RES_UL_SPACE );
+ SwFrmFmt* pFmt = bHeader ?
+ (SwFrmFmt*)rMaster.GetHeader().GetHeaderFmt() :
+ (SwFrmFmt*)rMaster.GetFooter().GetFooterFmt();
+ pFmt->SetFmtAttr( aUL );
+ }
+ }
+ if( bChgd )
+ {
+ ChgPageDesc( nFrom, aDesc );
+
+ if( !bCrsrSet && bOn )
+ {
+ if ( !IsHeaderFooterEdit() )
+ ToggleHeaderFooterEdit();
+ bCrsrSet = SetCrsrInHdFt(
+ rStyleName.isEmpty() ? (sal_uInt16)0xFFFF : nFrom,
+ bHeader );
+ }
+ }
+ }
+ }
+ EndUndo( UNDO_HEADER_FOOTER ); // #i7983#
+ EndAllAction();
+}
+
+void SwWrtShell::SetShowHeaderFooterSeparator( FrameControlType eControl, bool bShow )
+{
+ SwViewShell::SetShowHeaderFooterSeparator( eControl, bShow );
+ if ( !bShow )
+ GetView().GetEditWin().GetFrameControlsManager().HideControls( eControl );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/wrtsh/wrtsh2.cxx b/sw/source/uibase/wrtsh/wrtsh2.cxx
new file mode 100644
index 000000000000..ae1d19091d7d
--- /dev/null
+++ b/sw/source/uibase/wrtsh/wrtsh2.cxx
@@ -0,0 +1,542 @@
+/* -*- 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 <svl/macitem.hxx>
+#include <sfx2/frame.hxx>
+#include <vcl/msgbox.hxx>
+#include <svl/urihelper.hxx>
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <fmtinfmt.hxx>
+#include <frmatr.hxx>
+#include <swtypes.hxx>
+#include <wrtsh.hxx>
+#include <docsh.hxx>
+#include <fldbas.hxx>
+#include <expfld.hxx>
+#include <ddefld.hxx>
+#include <docufld.hxx>
+#include <reffld.hxx>
+#include <swundo.hxx>
+#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <viewopt.hxx>
+#include <frmfmt.hxx>
+#include <swtable.hxx>
+#include <mdiexp.hxx>
+#include <view.hxx>
+#include <swevent.hxx>
+#include <poolfmt.hxx>
+#include <section.hxx>
+#include <navicont.hxx>
+#include <navipi.hxx>
+#include <crsskip.hxx>
+#include <txtinet.hxx>
+#include <cmdid.h>
+#include <wrtsh.hrc>
+#include "swabstdlg.hxx"
+#include "fldui.hrc"
+#include <SwRewriter.hxx>
+
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+
+#include <xmloff/odffields.hxx>
+
+void SwWrtShell::Insert(SwField &rFld)
+{
+ ResetCursorStack();
+ if(!CanInsert())
+ return;
+ StartAllAction();
+
+ SwRewriter aRewriter;
+ aRewriter.AddRule(UndoArg1, rFld.GetDescription());
+
+ StartUndo(UNDO_INSERT, &aRewriter);
+
+ bool bDeleted = false;
+ const SwPaM* pAnnotationTextRange = NULL;
+ if ( HasSelection() )
+ {
+ if ( rFld.GetTyp()->Which() == RES_POSTITFLD )
+ {
+ // for annotation fields:
+ // - keep the current selection in order to create a corresponding annotation mark
+ // - collapse cursor to its end
+ if ( IsTableMode() )
+ {
+ GetTblCrs()->Normalize( false );
+ const SwPosition rStartPos( *(GetTblCrs()->GetMark()->nNode.GetNode().GetCntntNode()), 0 );
+ KillPams();
+ EndPara();
+ const SwPosition rEndPos( *GetCurrentShellCursor().GetPoint() );
+ pAnnotationTextRange = new SwPaM( rStartPos, rEndPos );
+ }
+ else
+ {
+ NormalizePam( false );
+ const SwPaM& rCurrPaM = GetCurrentShellCursor();
+ pAnnotationTextRange = new SwPaM( *rCurrPaM.GetPoint(), *rCurrPaM.GetMark() );
+ ClearMark();
+ }
+ }
+ else
+ {
+ bDeleted = DelRight() != 0;
+ }
+ }
+
+ SwEditShell::Insert2(rFld, bDeleted);
+
+ if ( pAnnotationTextRange != NULL )
+ {
+ if ( GetDoc() != NULL )
+ {
+ IDocumentMarkAccess* pMarksAccess = GetDoc()->getIDocumentMarkAccess();
+ pMarksAccess->makeAnnotationMark( *pAnnotationTextRange, ::rtl::OUString() );
+ }
+ delete pAnnotationTextRange;
+ }
+
+ EndUndo();
+ EndAllAction();
+}
+
+// Start the field update
+
+void SwWrtShell::UpdateInputFlds( SwInputFieldList* pLst )
+{
+ // Go through the list of fields and updating
+ SwInputFieldList* pTmp = pLst;
+ if( !pTmp )
+ pTmp = new SwInputFieldList( this );
+
+ const sal_uInt16 nCnt = pTmp->Count();
+ if(nCnt)
+ {
+ pTmp->PushCrsr();
+
+ bool bCancel = false;
+ OString aDlgPos;
+ for( sal_uInt16 i = 0; i < nCnt && !bCancel; ++i )
+ {
+ pTmp->GotoFieldPos( i );
+ SwField* pField = pTmp->GetField( i );
+ if(pField->GetTyp()->Which() == RES_DROPDOWN)
+ bCancel = StartDropDownFldDlg( pField, true, &aDlgPos );
+ else
+ bCancel = StartInputFldDlg( pField, true, 0, &aDlgPos);
+
+ if (!bCancel)
+ {
+ // Otherwise update error at multi-selection:
+ pTmp->GetField( i )->GetTyp()->UpdateFlds();
+ }
+ }
+ pTmp->PopCrsr();
+ }
+
+ if( !pLst )
+ delete pTmp;
+}
+
+// Listener class: will close InputField dialog if input field(s)
+// is(are) deleted (for instance, by an extension) after the dialog shows up.
+// Otherwise, the for loop in SwWrtShell::UpdateInputFlds will crash when doing:
+// 'pTmp->GetField( i )->GetTyp()->UpdateFlds();'
+// on a deleted field.
+class FieldDeletionModify : public SwModify
+{
+ public:
+ FieldDeletionModify(AbstractFldInputDlg* pInputFieldDlg) : mpInputFieldDlg(pInputFieldDlg) {}
+
+ void Modify( const SfxPoolItem* pOld, const SfxPoolItem *) SAL_OVERRIDE
+ {
+ // Input fields have been deleted: better to close the dialog
+ if (pOld->Which() == RES_FIELD_DELETED)
+ {
+ mpInputFieldDlg->EndDialog(RET_CANCEL);
+ }
+ }
+ private:
+ AbstractFldInputDlg* mpInputFieldDlg;
+};
+
+// Start input dialog for a specific field
+
+bool SwWrtShell::StartInputFldDlg( SwField* pFld, bool bNextButton,
+ Window* pParentWin, OString* pWindowState )
+{
+
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ OSL_ENSURE(pFact, "Dialogdiet fail!");
+ AbstractFldInputDlg* pDlg = pFact->CreateFldInputDlg(pParentWin, *this, pFld, bNextButton);
+ OSL_ENSURE(pDlg, "Dialogdiet fail!");
+ if(pWindowState && !pWindowState->isEmpty())
+ pDlg->SetWindowState(*pWindowState);
+
+ // Register for possible input field deletion while dialog is open
+ FieldDeletionModify aModify(pDlg);
+ GetDoc()->GetUnoCallBack()->Add(&aModify);
+
+ bool bRet = RET_CANCEL == pDlg->Execute();
+
+ // Dialog closed, remove modification listener
+ GetDoc()->GetUnoCallBack()->Remove(&aModify);
+
+ if(pWindowState)
+ *pWindowState = pDlg->GetWindowState();
+
+ delete pDlg;
+ GetWin()->Update();
+ return bRet;
+}
+
+bool SwWrtShell::StartDropDownFldDlg(SwField* pFld, bool bNextButton, OString* pWindowState)
+{
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ OSL_ENSURE(pFact, "SwAbstractDialogFactory fail!");
+
+ AbstractDropDownFieldDialog* pDlg = pFact->CreateDropDownFieldDialog(NULL, *this, pFld, bNextButton);
+ OSL_ENSURE(pDlg, "Dialogdiet fail!");
+ if(pWindowState && !pWindowState->isEmpty())
+ pDlg->SetWindowState(*pWindowState);
+ sal_uInt16 nRet = pDlg->Execute();
+ if(pWindowState)
+ *pWindowState = pDlg->GetWindowState();
+ delete pDlg;
+ bool bRet = RET_CANCEL == nRet;
+ GetWin()->Update();
+ if(RET_YES == nRet)
+ {
+ GetView().GetViewFrame()->GetDispatcher()->Execute(FN_EDIT_FIELD, SFX_CALLMODE_SYNCHRON);
+ }
+ return bRet;
+}
+
+// Insert directory - remove selection
+
+void SwWrtShell::InsertTableOf(const SwTOXBase& rTOX, const SfxItemSet* pSet)
+{
+ if(!CanInsert())
+ return;
+
+ if(HasSelection())
+ DelRight();
+
+ SwEditShell::InsertTableOf(rTOX, pSet);
+}
+
+// Update directory - remove selection
+
+bool SwWrtShell::UpdateTableOf(const SwTOXBase& rTOX, const SfxItemSet* pSet)
+{
+ bool bResult = false;
+
+ if(CanInsert())
+ {
+ bResult = SwEditShell::UpdateTableOf(rTOX, pSet);
+
+ if (pSet == NULL)
+ {
+ SwDoc *const pDoc_ = GetDoc();
+ if (pDoc_)
+ {
+ pDoc_->GetIDocumentUndoRedo().DelAllUndoObj();
+ }
+ }
+ }
+
+ return bResult;
+}
+
+// handler for click on the field given as parameter.
+// the cursor is positioned on the field.
+
+void SwWrtShell::ClickToField( const SwField& rFld )
+{
+ // cross reference field must not be selected because it moves the cursor
+ if (RES_GETREFFLD != rFld.GetTyp()->Which())
+ {
+ StartAllAction();
+ Right( CRSR_SKIP_CHARS, true, 1, false ); // Select the field.
+ NormalizePam();
+ EndAllAction();
+ }
+
+ bIsInClickToEdit = true;
+ switch( rFld.GetTyp()->Which() )
+ {
+ case RES_JUMPEDITFLD:
+ {
+ sal_uInt16 nSlotId = 0;
+ switch( rFld.GetFormat() )
+ {
+ case JE_FMT_TABLE:
+ nSlotId = FN_INSERT_TABLE;
+ break;
+
+ case JE_FMT_FRAME:
+ nSlotId = FN_INSERT_FRAME;
+ break;
+
+ case JE_FMT_GRAPHIC: nSlotId = SID_INSERT_GRAPHIC; break;
+ case JE_FMT_OLE: nSlotId = SID_INSERT_OBJECT; break;
+
+ }
+
+ if( nSlotId )
+ {
+ StartUndo( UNDO_START );
+ //#97295# immediately select the right shell
+ GetView().StopShellTimer();
+ GetView().GetViewFrame()->GetDispatcher()->Execute( nSlotId,
+ SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD );
+ EndUndo( UNDO_END );
+ }
+ }
+ break;
+
+ case RES_MACROFLD:
+ {
+ const SwMacroField *pFld = (const SwMacroField*)&rFld;
+ const OUString sText( rFld.GetPar2() );
+ OUString sRet( sText );
+ ExecMacro( pFld->GetSvxMacro(), &sRet );
+
+ // return value changed?
+ if( sRet != sText )
+ {
+ StartAllAction();
+ ((SwField&)rFld).SetPar2( sRet );
+ ((SwField&)rFld).GetTyp()->UpdateFlds();
+ EndAllAction();
+ }
+ }
+ break;
+
+ case RES_GETREFFLD:
+ StartAllAction();
+ SwCrsrShell::GotoRefMark( ((SwGetRefField&)rFld).GetSetRefName(),
+ ((SwGetRefField&)rFld).GetSubType(),
+ ((SwGetRefField&)rFld).GetSeqNo() );
+ EndAllAction();
+ break;
+
+ case RES_INPUTFLD:
+ {
+ const SwInputField* pInputField = dynamic_cast<const SwInputField*>(&rFld);
+ if ( pInputField == NULL )
+ {
+ StartInputFldDlg( (SwField*)&rFld, false );
+ }
+ }
+ break;
+
+ case RES_SETEXPFLD:
+ if( ((SwSetExpField&)rFld).GetInputFlag() )
+ StartInputFldDlg( (SwField*)&rFld, false );
+ break;
+ case RES_DROPDOWN :
+ StartDropDownFldDlg( (SwField*)&rFld, false );
+ break;
+ default:
+ SAL_WARN_IF(rFld.IsClickable(), "sw", "unhandled clickable field!");
+ }
+
+ bIsInClickToEdit = false;
+}
+
+void SwWrtShell::ClickToINetAttr( const SwFmtINetFmt& rItem, sal_uInt16 nFilter )
+{
+ if( rItem.GetValue().isEmpty() )
+ return ;
+
+ bIsInClickToEdit = true;
+
+ // At first run the possibly set ObjectSelect Macro
+ const SvxMacro* pMac = rItem.GetMacro( SFX_EVENT_MOUSECLICK_OBJECT );
+ if( pMac )
+ {
+ SwCallMouseEvent aCallEvent;
+ aCallEvent.Set( &rItem );
+ GetDoc()->CallEvent( SFX_EVENT_MOUSECLICK_OBJECT, aCallEvent, false );
+ }
+
+ // So that the implementation of templates is displayed immediately
+ ::LoadURL( *this, rItem.GetValue(), nFilter, rItem.GetTargetFrame() );
+ const SwTxtINetFmt* pTxtAttr = rItem.GetTxtINetFmt();
+ if( pTxtAttr )
+ {
+ const_cast<SwTxtINetFmt*>(pTxtAttr)->SetVisited( true );
+ const_cast<SwTxtINetFmt*>(pTxtAttr)->SetVisitedValid( true );
+ }
+
+ bIsInClickToEdit = false;
+}
+
+bool SwWrtShell::ClickToINetGrf( const Point& rDocPt, sal_uInt16 nFilter )
+{
+ bool bRet = false;
+ OUString sURL;
+ OUString sTargetFrameName;
+ const SwFrmFmt* pFnd = IsURLGrfAtPos( rDocPt, &sURL, &sTargetFrameName );
+ if( pFnd && !sURL.isEmpty() )
+ {
+ bRet = true;
+ // At first run the possibly set ObjectSelect Macro
+ const SvxMacro* pMac = &pFnd->GetMacro().GetMacro( SFX_EVENT_MOUSECLICK_OBJECT );
+ if( pMac )
+ {
+ SwCallMouseEvent aCallEvent;
+ aCallEvent.Set( EVENT_OBJECT_URLITEM, pFnd );
+ GetDoc()->CallEvent( SFX_EVENT_MOUSECLICK_OBJECT, aCallEvent, false );
+ }
+
+ ::LoadURL(*this, sURL, nFilter, sTargetFrameName);
+ }
+ return bRet;
+}
+
+void LoadURL( SwViewShell& rVSh, const OUString& rURL, sal_uInt16 nFilter,
+ const OUString& rTargetFrameName )
+{
+ OSL_ENSURE( !rURL.isEmpty(), "what should be loaded here?" );
+ if( rURL.isEmpty() )
+ return ;
+
+ // The shell could be 0 also!!!!!
+ if ( !rVSh.ISA(SwCrsrShell) )
+ return;
+
+ //A CrsrShell is always a WrtShell
+ SwWrtShell &rSh = (SwWrtShell&)rVSh;
+
+ SwDocShell* pDShell = rSh.GetView().GetDocShell();
+ OSL_ENSURE( pDShell, "No DocShell?!");
+ OUString sTargetFrame(rTargetFrameName);
+ if (sTargetFrame.isEmpty() && pDShell)
+ {
+ using namespace ::com::sun::star;
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ pDShell->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps
+ = xDPS->getDocumentProperties();
+ sTargetFrame = xDocProps->getDefaultTarget();
+ }
+
+ OUString sReferer;
+ if( pDShell && pDShell->GetMedium() )
+ sReferer = pDShell->GetMedium()->GetName();
+ SfxViewFrame* pViewFrm = rSh.GetView().GetViewFrame();
+ SfxFrameItem aView( SID_DOCFRAME, pViewFrm );
+ SfxStringItem aName( SID_FILE_NAME, rURL );
+ SfxStringItem aTargetFrameName( SID_TARGETNAME, sTargetFrame );
+ SfxStringItem aReferer( SID_REFERER, sReferer );
+
+ SfxBoolItem aNewView( SID_OPEN_NEW_VIEW, false );
+ //#39076# Silent can be removed accordingly to SFX.
+ SfxBoolItem aBrowse( SID_BROWSE, true );
+
+ if( nFilter & URLLOAD_NEWVIEW )
+ aTargetFrameName.SetValue( OUString("_blank") );
+
+ const SfxPoolItem* aArr[] = {
+ &aName,
+ &aNewView, /*&aSilent,*/
+ &aReferer,
+ &aView, &aTargetFrameName,
+ &aBrowse,
+ 0L
+ };
+
+ pViewFrm->GetDispatcher()->GetBindings()->Execute( SID_OPENDOC, aArr,
+ SFX_CALLMODE_ASYNCHRON|SFX_CALLMODE_RECORD );
+}
+
+void SwWrtShell::NavigatorPaste( const NaviContentBookmark& rBkmk,
+ const sal_uInt16 nAction )
+{
+ if( EXCHG_IN_ACTION_COPY == nAction )
+ {
+ // Insert
+ OUString sURL = rBkmk.GetURL();
+ // Is this is a jump within the current Doc?
+ const SwDocShell* pDocShell = GetView().GetDocShell();
+ if(pDocShell->HasName())
+ {
+ const OUString rName = pDocShell->GetMedium()->GetURLObject().GetURLNoMark();
+
+ if (sURL.startsWith(rName))
+ {
+ if (sURL.getLength()>rName.getLength())
+ {
+ sURL = sURL.copy(rName.getLength());
+ }
+ else
+ {
+ sURL = OUString();
+ }
+ }
+ }
+ SwFmtINetFmt aFmt( sURL, OUString() );
+ InsertURL( aFmt, rBkmk.GetDescription() );
+ }
+ else
+ {
+ SwSectionData aSection( FILE_LINK_SECTION, GetUniqueSectionName() );
+ OUString aLinkFile( rBkmk.GetURL().getToken(0, '#') );
+ aLinkFile += OUString(sfx2::cTokenSeparator);
+ aLinkFile += OUString(sfx2::cTokenSeparator);
+ aLinkFile += rBkmk.GetURL().getToken(1, '#');
+ aSection.SetLinkFileName( aLinkFile );
+ aSection.SetProtectFlag( true );
+ const SwSection* pIns = InsertSection( aSection );
+ if( EXCHG_IN_ACTION_MOVE == nAction && pIns )
+ {
+ aSection = SwSectionData(*pIns);
+ aSection.SetLinkFileName( OUString() );
+ aSection.SetType( CONTENT_SECTION );
+ aSection.SetProtectFlag( false );
+
+ // the update of content from linked section at time delete
+ // the undostack. Then the change of the section dont create
+ // any undoobject. - BUG 69145
+ bool bDoesUndo = DoesUndo();
+ SwUndoId nLastUndoId(UNDO_EMPTY);
+ if (GetLastUndoInfo(0, & nLastUndoId))
+ {
+ if (UNDO_INSSECTION != nLastUndoId)
+ {
+ DoUndo(false);
+ }
+ }
+ UpdateSection( GetSectionFmtPos( *pIns->GetFmt() ), aSection );
+ DoUndo( bDoesUndo );
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/wrtsh/wrtsh3.cxx b/sw/source/uibase/wrtsh/wrtsh3.cxx
new file mode 100644
index 000000000000..a5a1bb4a6119
--- /dev/null
+++ b/sw/source/uibase/wrtsh/wrtsh3.cxx
@@ -0,0 +1,227 @@
+/* -*- 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 <sfx2/app.hxx>
+#include <sfx2/childwin.hxx>
+#include <sfx2/bindings.hxx>
+#include <svx/svdmark.hxx>
+#include <svx/svdview.hxx>
+#include <svx/fmglob.hxx>
+#include <svx/svdouno.hxx>
+#include <com/sun/star/form/FormButtonType.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <sfx2/htmlmode.hxx>
+#include "wrtsh.hxx"
+#include "view.hxx"
+#include "IMark.hxx"
+#include "doc.hxx"
+#include "wrtsh.hrc"
+
+#include <unomid.h>
+
+using namespace ::com::sun::star;
+
+extern bool bNoInterrupt; // in mainwn.cxx
+
+bool SwWrtShell::MoveBookMark( BookMarkMove eFuncId, const ::sw::mark::IMark* const pMark)
+{
+ addCurrentPosition();
+ (this->*fnKillSel)( 0, false );
+
+ bool bRet = true;
+ switch(eFuncId)
+ {
+ case BOOKMARK_INDEX:bRet = SwCrsrShell::GotoMark( pMark );break;
+ case BOOKMARK_NEXT: bRet = SwCrsrShell::GoNextBookmark();break;
+ case BOOKMARK_PREV: bRet = SwCrsrShell::GoPrevBookmark();break;
+ default:;//prevent warning
+ }
+
+ if( bRet && IsSelFrmMode() )
+ {
+ UnSelectFrm();
+ LeaveSelFrmMode();
+ }
+ if( IsSelection() )
+ {
+ fnKillSel = &SwWrtShell::ResetSelect;
+ fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
+ }
+ return bRet;
+}
+
+bool SwWrtShell::GotoField( const SwFmtFld& rFld )
+{
+ (this->*fnKillSel)( 0, false );
+
+ bool bRet = SwCrsrShell::GotoFld( rFld );
+ if( bRet && IsSelFrmMode() )
+ {
+ UnSelectFrm();
+ LeaveSelFrmMode();
+ }
+
+ if( IsSelection() )
+ {
+ fnKillSel = &SwWrtShell::ResetSelect;
+ fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
+ }
+
+ return bRet;
+}
+
+bool SwWrtShell::GotoFieldmark(::sw::mark::IFieldmark const * const pMark)
+{
+ (this->*fnKillSel)( 0, false );
+ bool bRet = SwCrsrShell::GotoFieldmark(pMark);
+ if( bRet && IsSelFrmMode() )
+ {
+ UnSelectFrm();
+ LeaveSelFrmMode();
+ }
+ if( IsSelection() )
+ {
+ fnKillSel = &SwWrtShell::ResetSelect;
+ fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
+ }
+ return bRet;
+}
+
+// Invalidate FontWork-Slots
+
+void SwWrtShell::DrawSelChanged( )
+{
+ static sal_uInt16 const aInval[] =
+ {
+ SID_ATTR_FILL_STYLE, SID_ATTR_FILL_COLOR, SID_ATTR_LINE_STYLE,
+ SID_ATTR_LINE_WIDTH, SID_ATTR_LINE_COLOR,
+ /*AF: these may be needed for the sidebar.
+ SID_SVX_AREA_TRANSPARENCY, SID_SVX_AREA_TRANSP_GRADIENT,
+ SID_SVX_AREA_TRANS_TYPE,
+ */
+ 0
+ };
+
+ GetView().GetViewFrame()->GetBindings().Invalidate(aInval);
+
+ bool bOldVal = bNoInterrupt;
+ bNoInterrupt = true; // Trick to run AttrChangedNotify by timer.
+ GetView().AttrChangedNotify(this);
+ bNoInterrupt = bOldVal;
+}
+
+bool SwWrtShell::GotoMark( const OUString& rName )
+{
+ IDocumentMarkAccess::const_iterator_t ppMark = getIDocumentMarkAccess()->findMark( rName );
+ if(ppMark == getIDocumentMarkAccess()->getAllMarksEnd()) return false;
+ return MoveBookMark( BOOKMARK_INDEX, ppMark->get() );
+}
+
+bool SwWrtShell::GotoMark( const ::sw::mark::IMark* const pMark )
+{
+ return MoveBookMark( BOOKMARK_INDEX, pMark );
+}
+
+bool SwWrtShell::GoNextBookmark()
+{
+ return MoveBookMark( BOOKMARK_NEXT );
+}
+
+bool SwWrtShell::GoPrevBookmark()
+{
+ return MoveBookMark( BOOKMARK_PREV );
+}
+
+void SwWrtShell::ExecMacro( const SvxMacro& rMacro, OUString* pRet, SbxArray* pArgs )
+{
+ // OD 11.02.2003 #100556# - execute macro, if it is allowed.
+ if ( IsMacroExecAllowed() )
+ {
+ GetDoc()->ExecMacro( rMacro, pRet, pArgs );
+ }
+}
+
+sal_uInt16 SwWrtShell::CallEvent( sal_uInt16 nEvent, const SwCallMouseEvent& rCallEvent,
+ bool bChkPtr, SbxArray* pArgs,
+ const Link* pCallBack )
+{
+ return GetDoc()->CallEvent( nEvent, rCallEvent, bChkPtr, pArgs, pCallBack );
+}
+
+ // If a util::URL-Button is selected, return its util::URL
+ // otherwise an emtpy string.
+bool SwWrtShell::GetURLFromButton( OUString& rURL, OUString& rDescr ) const
+{
+ bool bRet = false;
+ const SdrView *pDView = GetDrawView();
+ if( pDView )
+ {
+ // A fly is precisely achievable if it is selected.
+ const SdrMarkList &rMarkList = pDView->GetMarkedObjectList();
+
+ if (rMarkList.GetMark(0))
+ {
+ SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, rMarkList.GetMark(0)->GetMarkedSdrObj());
+ if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor())
+ {
+ uno::Reference< awt::XControlModel > xControlModel = pUnoCtrl->GetUnoControlModel();
+
+ OSL_ENSURE( xControlModel.is(), "UNO-Control without Model" );
+ if( !xControlModel.is() )
+ return bRet;
+
+ uno::Reference< beans::XPropertySet > xPropSet(xControlModel, uno::UNO_QUERY);
+
+ uno::Any aTmp;
+
+ form::FormButtonType eButtonType = form::FormButtonType_URL;
+ uno::Reference< beans::XPropertySetInfo > xInfo = xPropSet->getPropertySetInfo();
+ if(xInfo->hasPropertyByName( "ButtonType" ))
+ {
+ aTmp = xPropSet->getPropertyValue( "ButtonType" );
+ form::FormButtonType eTmpButtonType;
+ aTmp >>= eTmpButtonType;
+ if( eButtonType == eTmpButtonType)
+ {
+ // Label
+ aTmp = xPropSet->getPropertyValue( "Label" );
+ OUString uTmp;
+ if( (aTmp >>= uTmp) && !uTmp.isEmpty())
+ {
+ rDescr = uTmp;
+ }
+
+ // util::URL
+ aTmp = xPropSet->getPropertyValue( "TargetURL" );
+ if( (aTmp >>= uTmp) && !uTmp.isEmpty())
+ {
+ rURL = uTmp;
+ }
+ bRet = true;
+ }
+ }
+ }
+ }
+ }
+
+ return bRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/wrtsh/wrtsh4.cxx b/sw/source/uibase/wrtsh/wrtsh4.cxx
new file mode 100644
index 000000000000..40c92d15343c
--- /dev/null
+++ b/sw/source/uibase/wrtsh/wrtsh4.cxx
@@ -0,0 +1,238 @@
+/* -*- 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 <wrtsh.hxx>
+#include <crsskip.hxx>
+
+// Private methods, which move the cursor over search.
+// The removal of the selection must be made on the level above.
+
+// The beginning of a word is the follow of a
+// non-delimiter to delimiter. Furthermore, the follow of
+// non-sentence separators on sentence separator.
+// The begin of paragraph is also the word beginning.
+
+bool SwWrtShell::_SttWrd()
+{
+ if ( IsSttPara() )
+ return true;
+ // Create temporary cursor without selection.
+ Push();
+ ClearMark();
+ if( !GoStartWord() )
+ // not found --> go to the beginning of the paragraph.
+ SwCrsrShell::MovePara( fnParaCurr, fnParaStart );
+ ClearMark();
+ // If Mark was previously set, summarize.
+ Combine();
+ return true;
+}
+
+// The end of a word is the follow of separator to nonseparator.
+// The end of a word is also the sequence of wordseparators to
+// punctuation marks.
+// The end of a paragraph is also the end of a word.
+
+bool SwWrtShell::_EndWrd()
+{
+ if ( IsEndWrd() )
+ return true;
+ // Create temporary cursor without selection.
+ Push();
+ ClearMark();
+ if( !GoEndWord() )
+ // not found --> go to the end of the paragraph.
+ SwCrsrShell::MovePara(fnParaCurr, fnParaEnd);
+ ClearMark();
+ // If Mark was previously set, summarize.
+ Combine();
+ return true;
+}
+
+bool SwWrtShell::_NxtWrd()
+{
+ bool bRet = false;
+ while( IsEndPara() ) // If already at the end, then the next???
+ {
+ if(!SwCrsrShell::Right(1,CRSR_SKIP_CHARS)) // Document - end ??
+ {
+ Pop( false );
+ return bRet;
+ }
+ bRet = IsStartWord();
+ }
+ Push();
+ ClearMark();
+ while( !bRet )
+ {
+ if( !GoNextWord() )
+ {
+ if( (!IsEndPara() && !SwCrsrShell::MovePara( fnParaCurr, fnParaEnd ) )
+ || !SwCrsrShell::Right(1,CRSR_SKIP_CHARS) )
+ break;
+ bRet = IsStartWord();
+ }
+ else
+ bRet = true;
+ }
+ ClearMark();
+ Combine();
+ return bRet;
+}
+
+bool SwWrtShell::_PrvWrd()
+{
+ bool bRet = false;
+ while( IsSttPara() )
+ { // if already at the beginning, then the next???
+ if(!SwCrsrShell::Left(1,CRSR_SKIP_CHARS))
+ { // Document - beginning ??
+ Pop( false );
+ return bRet;
+ }
+ bRet = IsStartWord();
+ }
+ Push();
+ ClearMark();
+ while( !bRet )
+ {
+ if( !GoPrevWord() )
+ {
+ if( (!IsSttPara() && !SwCrsrShell::MovePara( fnParaCurr, fnParaStart ) )
+ || !SwCrsrShell::Left(1,CRSR_SKIP_CHARS) )
+ break;
+ bRet = IsStartWord();
+ }
+ else
+ bRet = true;
+ }
+ ClearMark();
+ Combine();
+ return bRet;
+}
+
+// #i92468#
+// method code of <SwWrtShell::_NxtWrd()> before fix for issue i72162
+bool SwWrtShell::_NxtWrdForDelete()
+{
+ if ( IsEndPara() )
+ {
+ if ( !SwCrsrShell::Right(1,CRSR_SKIP_CHARS) )
+ {
+ Pop( false );
+ return false;
+ }
+ return true;
+ }
+ Push();
+ ClearMark();
+ if ( !GoNextWord() )
+ {
+ SwCrsrShell::MovePara( fnParaCurr, fnParaEnd );
+ }
+ ClearMark();
+ Combine();
+ return true;
+}
+
+// method code of <SwWrtShell::_PrvWrd()> before fix for issue i72162
+bool SwWrtShell::_PrvWrdForDelete()
+{
+ if ( IsSttPara() )
+ {
+ if ( !SwCrsrShell::Left(1,CRSR_SKIP_CHARS) )
+ {
+ Pop( false );
+ return false;
+ }
+ return true;
+ }
+ Push();
+ ClearMark();
+ if( !GoPrevWord() )
+ {
+ SwCrsrShell::MovePara( fnParaCurr, fnParaStart );
+ }
+ ClearMark();
+ Combine();
+ return true;
+}
+
+bool SwWrtShell::_FwdSentence()
+{
+ Push();
+ ClearMark();
+ if(!SwCrsrShell::Right(1,CRSR_SKIP_CHARS))
+ {
+ Pop(false);
+ return false;
+ }
+ if( !GoNextSentence() && !IsEndPara() )
+ SwCrsrShell::MovePara(fnParaCurr, fnParaEnd);
+
+ ClearMark();
+ Combine();
+ return true;
+}
+
+bool SwWrtShell::_BwdSentence()
+{
+ Push();
+ ClearMark();
+ if(!SwCrsrShell::Left(1,CRSR_SKIP_CHARS))
+ {
+ Pop(false);
+ return false;
+ }
+ if( !GoStartSentence() && !IsSttPara() )
+ // not found --> go to the beginning of the paragraph
+ SwCrsrShell::MovePara( fnParaCurr, fnParaStart );
+ ClearMark();
+ Combine();
+ return true;
+}
+
+bool SwWrtShell::_FwdPara()
+{
+ Push();
+ ClearMark();
+ bool bRet = SwCrsrShell::MovePara(fnParaNext, fnParaStart);
+
+ ClearMark();
+ Combine();
+ return bRet;
+}
+
+bool SwWrtShell::_BwdPara()
+{
+ Push();
+ ClearMark();
+
+ bool bRet = SwCrsrShell::MovePara(fnParaPrev, fnParaStart);
+ if ( !bRet && !IsSttOfPara() )
+ {
+ SttPara();
+ }
+
+ ClearMark();
+ Combine();
+ return bRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/wrtsh/wrtundo.cxx b/sw/source/uibase/wrtsh/wrtundo.cxx
new file mode 100644
index 000000000000..e8851d119f5a
--- /dev/null
+++ b/sw/source/uibase/wrtsh/wrtundo.cxx
@@ -0,0 +1,154 @@
+/* -*- 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 <tools/resid.hxx>
+#include <sfx2/app.hxx>
+#include <svl/slstitm.hxx>
+#include <wrtsh.hxx>
+#include <swundo.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <swdtflvr.hxx>
+#include <svtools/svtresid.hxx>
+#include <svtools/svtools.hrc>
+#include <wrtsh.hrc>
+#include <sfx2/sfx.hrc>
+
+// Undo ends all modes. If a selection is emerged by the Undo,
+// this must be considered for further action.
+
+void SwWrtShell::Do( DoType eDoType, sal_uInt16 nCnt )
+{
+ // #105332# save current state of DoesUndo()
+ bool bSaveDoesUndo = DoesUndo();
+
+ StartAllAction();
+ switch (eDoType)
+ {
+ case UNDO:
+ DoUndo(false); // #i21739#
+ // Reset modes
+ EnterStdMode();
+ SwEditShell::Undo(nCnt);
+ break;
+ case REDO:
+ DoUndo(false); // #i21739#
+ // Reset modes
+ EnterStdMode();
+ SwEditShell::Redo( nCnt );
+ break;
+ case REPEAT:
+ // #i21739# do not touch undo flag here !!!
+ SwEditShell::Repeat( nCnt );
+ break;
+ }
+ EndAllAction();
+ // #105332# restore undo state
+ DoUndo(bSaveDoesUndo);
+
+ bool bCreateXSelection = false;
+ const bool bFrmSelected = IsFrmSelected() || IsObjSelected();
+ if ( IsSelection() )
+ {
+ if ( bFrmSelected )
+ UnSelectFrm();
+
+ // Set the function pointer for canceling the selection at the
+ // cursor position.
+ fnKillSel = &SwWrtShell::ResetSelect;
+ fnSetCrsr = &SwWrtShell::SetCrsrKillSel;
+ bCreateXSelection = true;
+ }
+ else if ( bFrmSelected )
+ {
+ EnterSelFrmMode();
+ bCreateXSelection = true;
+ }
+ else if( (CNT_GRF | CNT_OLE ) & GetCntType() )
+ {
+ SelectObj( GetCharRect().Pos() );
+ EnterSelFrmMode();
+ bCreateXSelection = true;
+ }
+
+ if( bCreateXSelection )
+ SwTransferable::CreateSelection( *this );
+
+ // Bug 32918: After deleting of the numbering the object panel remains.
+ // Why is not here always a CallChgLink called?
+ CallChgLnk();
+}
+
+OUString SwWrtShell::GetDoString( DoType eDoType ) const
+{
+ OUString aUndoStr;
+ sal_uInt16 nResStr = STR_UNDO;
+ switch( eDoType )
+ {
+ case UNDO:
+ nResStr = STR_UNDO;
+ GetLastUndoInfo(& aUndoStr, 0);
+ break;
+ case REDO:
+ nResStr = STR_REDO;
+ GetFirstRedoInfo(& aUndoStr);
+ break;
+ default:;//prevent warning
+ }
+
+ return SvtResId( nResStr ).toString() + aUndoStr;
+}
+
+sal_uInt16 SwWrtShell::GetDoStrings( DoType eDoType, SfxStringListItem& rStrs ) const
+{
+ SwUndoComments_t comments;
+ switch( eDoType )
+ {
+ case UNDO:
+ comments = GetIDocumentUndoRedo().GetUndoComments();
+ break;
+ case REDO:
+ comments = GetIDocumentUndoRedo().GetRedoComments();
+ break;
+ default:;//prevent warning
+ }
+
+ OUString buf;
+ for (size_t i = 0; i < comments.size(); ++i)
+ {
+ OSL_ENSURE(!comments[i].isEmpty(), "no Undo/Redo Text set");
+ buf += comments[i] + "\n";
+ }
+ rStrs.SetString(buf);
+ return static_cast<sal_uInt16>(comments.size());
+}
+
+OUString SwWrtShell::GetRepeatString() const
+{
+ OUString str;
+ GetRepeatInfo(& str);
+
+ if (str.isEmpty())
+ {
+ return str;
+ }
+
+ return SvtResId(STR_REPEAT).toString() + str;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */