summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatteocam <matteo.campanelli@gmail.com>2015-09-06 11:30:31 +0200
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2015-09-20 13:05:14 +0200
commite59fca52399ab1f96b5bb525b56b444c5674ae6d (patch)
treeb7a9e910a4ebc016d570a2ce4a22831e4af4bed9
parent4c33aa61b3ea1fa170b9446fbfdffe85b659ff3b (diff)
chained editeng: Add TextChainCursor related files
Change-Id: I6c98a28ae800197d58df8791e72a00b6490a2e2e
-rw-r--r--include/svx/textchaincursor.hxx64
-rw-r--r--svx/Library_svxcore.mk1
-rw-r--r--svx/source/svdraw/textchaincursor.cxx210
3 files changed, 275 insertions, 0 deletions
diff --git a/include/svx/textchaincursor.hxx b/include/svx/textchaincursor.hxx
new file mode 100644
index 000000000000..61e6939701ac
--- /dev/null
+++ b/include/svx/textchaincursor.hxx
@@ -0,0 +1,64 @@
+/* -*- 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 INCLUDED_SVX_TEXTCHAINCURSOR_HXX
+#define INCLUDED_SVX_TEXTCHAINCURSOR_HXX
+
+#include <svx/svxdllapi.h>
+
+class SdrObjEditView;
+class SdrTextObj;
+class KeyEvent;
+class SdrOutliner;
+
+
+class SVX_DLLPUBLIC TextChainCursorManager
+{
+public:
+ TextChainCursorManager(SdrObjEditView *pEditView, const SdrTextObj *pTextObj);
+
+ bool HandleKeyEvent( const KeyEvent& rKEvt );
+
+ // Used by HandledKeyEvent and basic building block for handling cursor event
+ void HandleCursorEvent(const CursorChainingEvent aCurEvt,
+ const ESelection aNewSel);
+
+ // To be used after chaining event to deal with some nuisances
+ void HandleCursorEventAfterChaining(const CursorChainingEvent aCurEvt,
+ const ESelection aNewSel);
+
+private:
+ SdrObjEditView *mpEditView;
+ const SdrTextObj *mpTextObj;
+
+ // flag for handling of CANC which is kind of an exceptional case
+ bool mbHandlingDel;
+
+ void impChangeEditingTextObj(SdrTextObj *pTargetTextObj, ESelection aNewSel);
+ void impDetectEvent(const KeyEvent& rKEvt,
+ CursorChainingEvent *pOutCursorEvt,
+ ESelection *pOutSel,
+ bool *bOutHandled);
+};
+
+
+#endif // INCLUDED_SVX_TEXTCHAINCURSOR_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+
diff --git a/svx/Library_svxcore.mk b/svx/Library_svxcore.mk
index ffbcf013e0e2..ca9e5c5d0d0d 100644
--- a/svx/Library_svxcore.mk
+++ b/svx/Library_svxcore.mk
@@ -341,6 +341,7 @@ $(eval $(call gb_Library_add_exception_objects,svxcore,\
svx/source/svdraw/svdxcgv \
svx/source/svdraw/textchain \
svx/source/svdraw/textchainflow \
+ svx/source/svdraw/textchaincursor \
svx/source/styles/CommonStylePreviewRenderer \
svx/source/styles/CommonStyleManager \
svx/source/styles/ColorSets \
diff --git a/svx/source/svdraw/textchaincursor.cxx b/svx/source/svdraw/textchaincursor.cxx
new file mode 100644
index 000000000000..23bd8f54a0a3
--- /dev/null
+++ b/svx/source/svdraw/textchaincursor.cxx
@@ -0,0 +1,210 @@
+/* -*- 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/textchain.hxx>
+#include <svx/textchaincursor.hxx>
+#include <svx/svdedxv.hxx>
+#include <svx/svdoutl.hxx>
+
+// XXX: Possible duplication of code in behavior with stuff in ImpEditView (or ImpEditEngine) and OutlinerView
+
+// XXX: We violate Demeter's Law several times here, I'm afraid
+
+TextChainCursorManager::TextChainCursorManager(SdrObjEditView *pEditView, const SdrTextObj *pTextObj) :
+ mpEditView(pEditView),
+ mpTextObj(pTextObj),
+ mbHandlingDel(false)
+{
+ assert(mpEditView);
+ assert(mpTextObj);
+
+}
+
+bool TextChainCursorManager::HandleKeyEvent( const KeyEvent& rKEvt )
+{
+ ESelection aNewSel;
+ CursorChainingEvent aCursorEvent;
+
+ // check what the cursor/event situation looks like
+ bool bCompletelyHandled = false;
+ impDetectEvent(rKEvt, &aCursorEvent, &aNewSel, &bCompletelyHandled);
+
+ if (aCursorEvent == CursorChainingEvent::NULL_EVENT)
+ return false;
+ else {
+ HandleCursorEvent(aCursorEvent, aNewSel);
+ // return value depends on the situation we are in
+ return bCompletelyHandled;
+ }
+}
+
+void TextChainCursorManager::impDetectEvent(const KeyEvent& rKEvt,
+ CursorChainingEvent *pOutCursorEvt,
+ ESelection *pOutSel,
+ bool *bOutHandled)
+{
+ SdrOutliner *pOutl = mpEditView->GetTextEditOutliner();
+ OutlinerView *pOLV = mpEditView->GetTextEditOutlinerView();
+
+ SdrTextObj *pNextLink = mpTextObj->GetNextLinkInChain();
+ SdrTextObj *pPrevLink = mpTextObj->GetPrevLinkInChain();
+
+ KeyFuncType eFunc = rKEvt.GetKeyCode().GetFunction();
+
+ // We need to have this KeyFuncType
+ if (eFunc != KeyFuncType::DONTKNOW && eFunc != KeyFuncType::DELETE)
+ {
+ *pOutCursorEvt = CursorChainingEvent::NULL_EVENT;
+ return;
+ }
+
+ sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
+ ESelection aCurSel = pOLV->GetSelection();
+
+ ESelection aEndSelPrevBox(100000, 100000);
+
+ sal_Int32 nLastPara = pOutl->GetParagraphCount()-1;
+ OUString aLastParaText = pOutl->GetText(pOutl->GetParagraph(nLastPara));
+ sal_Int32 nLastParaLen = aLastParaText.getLength();
+
+ ESelection aEndSel = ESelection(nLastPara, nLastParaLen);
+ bool bAtEndOfTextContent = aCurSel.IsEqual(aEndSel);
+
+ // Possibility: Are we "pushing" at the end of the object?
+ if (nCode == KEY_RIGHT && bAtEndOfTextContent && pNextLink)
+ {
+ *pOutCursorEvt = CursorChainingEvent::TO_NEXT_LINK;
+ // Selection unchanged: we are at the beginning of the box
+ *bOutHandled = true; // Nothing more to do than move cursor
+ return;
+ }
+
+ // Possibility: Are we "pushing" at the end of the object?
+ if (eFunc == KeyFuncType::DELETE && bAtEndOfTextContent && pNextLink)
+ {
+ *pOutCursorEvt = CursorChainingEvent::TO_NEXT_LINK;
+ // Selection unchanged: we are at the beginning of the box
+ *bOutHandled = false; // We still need to delete the characters
+ mbHandlingDel = true;
+ return;
+ }
+
+ ESelection aStartSel = ESelection(0, 0);
+ bool bAtStartOfTextContent = aCurSel.IsEqual(aStartSel);
+
+ // Possibility: Are we "pushing" at the start of the object?
+ if (nCode == KEY_LEFT && bAtStartOfTextContent && pPrevLink)
+ {
+ *pOutCursorEvt = CursorChainingEvent::TO_PREV_LINK;
+ *pOutSel = aEndSelPrevBox; // Set at end of selection
+ *bOutHandled = true; // Nothing more to do than move cursor
+ return;
+ }
+
+ // Possibility: Are we "pushing" at the start of the object and deleting left?
+ if (nCode == KEY_BACKSPACE && bAtStartOfTextContent && pPrevLink)
+ {
+ *pOutCursorEvt = CursorChainingEvent::TO_PREV_LINK;
+ *pOutSel = aEndSelPrevBox; // Set at end of selection
+ *bOutHandled = false; // We need to delete characters after moving cursor
+ return;
+ }
+
+ // If arrived here there is no event detected
+ *pOutCursorEvt = CursorChainingEvent::NULL_EVENT;
+
+}
+
+void TextChainCursorManager::HandleCursorEventAfterChaining(
+ const CursorChainingEvent aCurEvt,
+ const ESelection aNewSel)
+
+{
+ // Special case for DELETE handling: we need to get back at the end of the prev box
+ if (mbHandlingDel) {
+ // reset flag
+ mbHandlingDel = false;
+
+ // Move to end of prev box
+ SdrTextObj *pPrevLink = mpTextObj->GetPrevLinkInChain();
+ ESelection aEndSel(100000, 100000);
+ impChangeEditingTextObj(pPrevLink, aEndSel);
+ return;
+ }
+
+ // Standard handling
+ HandleCursorEvent(aCurEvt, aNewSel);
+}
+
+
+void TextChainCursorManager::HandleCursorEvent(
+ const CursorChainingEvent aCurEvt,
+ const ESelection aNewSel)
+
+{
+
+ OutlinerView* pOLV = mpEditView->GetTextEditOutlinerView();
+ SdrTextObj *pNextLink = mpTextObj->GetNextLinkInChain();
+ SdrTextObj *pPrevLink = mpTextObj->GetPrevLinkInChain();
+
+
+
+ switch ( aCurEvt ) {
+ case CursorChainingEvent::UNCHANGED:
+ // Set same selection as before the chaining (which is saved as PostChainingSel)
+ // We need an explicit set because the Outliner is messed up
+ // after text transfer and otherwise it brings us at arbitrary positions.
+ pOLV->SetSelection(aNewSel);
+ break;
+ case CursorChainingEvent::TO_NEXT_LINK:
+ mpTextObj->GetTextChain()->SetSwitchingToNextBox(mpTextObj, true);
+ impChangeEditingTextObj(pNextLink, aNewSel);
+ break;
+ case CursorChainingEvent::TO_PREV_LINK:
+ impChangeEditingTextObj(pPrevLink, aNewSel);
+ break;
+ case CursorChainingEvent::NULL_EVENT:
+ // Do nothing here
+ break;
+ }
+
+}
+
+void TextChainCursorManager::impChangeEditingTextObj(SdrTextObj *pTargetTextObj, ESelection aNewSel)
+{
+ assert(pTargetTextObj);
+
+ // To ensure that we check for overflow in the next box // This is handled in SdrTextObj::EndTextEdit
+ SdrTextObj *pNextLink = mpTextObj->GetNextLinkInChain();
+ TextChain *pTextChain = mpTextObj->GetTextChain();
+ // If we are moving forward
+ if (pNextLink && pTargetTextObj == pNextLink)
+ pTextChain->SetPendingOverflowCheck(pNextLink, true);
+
+ mpEditView->SdrEndTextEdit();
+ mpEditView->SdrBeginTextEdit(pTargetTextObj);
+ // OutlinerView has changed, so we update the pointer
+ OutlinerView *pOLV = mpEditView->GetTextEditOutlinerView();
+ pOLV->SetSelection(aNewSel);
+
+ // Update reference text obj
+ mpTextObj = pTargetTextObj;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */