summaryrefslogtreecommitdiff
path: root/editeng/source
diff options
context:
space:
mode:
authorMathias Bauer <mba@openoffice.org>2010-01-06 19:26:54 +0100
committerMathias Bauer <mba@openoffice.org>2010-01-06 19:26:54 +0100
commit127e5f966ebebe604792f5707d543e8618c61c48 (patch)
tree6c08490489b6a0667308c28a52080619d6b82492 /editeng/source
parentf18f649faac191ddee68deb8c4d472a6b760614e (diff)
#i107450#: move code from svx to new module editeng
Diffstat (limited to 'editeng/source')
-rw-r--r--editeng/source/accessibility/AccessibleComponentBase.cxx240
-rw-r--r--editeng/source/accessibility/AccessibleContextBase.cxx718
-rw-r--r--editeng/source/accessibility/AccessibleEditableTextPara.cxx2204
-rw-r--r--editeng/source/accessibility/AccessibleEditableTextPara.hxx414
-rw-r--r--editeng/source/accessibility/AccessibleImageBullet.cxx654
-rw-r--r--editeng/source/accessibility/AccessibleImageBullet.hxx240
-rw-r--r--editeng/source/accessibility/AccessibleParaManager.cxx423
-rw-r--r--editeng/source/accessibility/AccessibleParaManager.hxx349
-rw-r--r--editeng/source/accessibility/AccessibleSelectionBase.cxx111
-rw-r--r--editeng/source/accessibility/AccessibleStaticTextBase.cxx1050
-rw-r--r--editeng/source/accessibility/AccessibleStringWrap.cxx103
-rw-r--r--editeng/source/accessibility/accessibility.src43
-rwxr-xr-xediteng/source/accessibility/makefile.mk58
-rw-r--r--editeng/source/editeng/editattr.cxx457
-rw-r--r--editeng/source/editeng/editattr.hxx429
-rw-r--r--editeng/source/editeng/editdbg.cxx589
-rw-r--r--editeng/source/editeng/editdbg.hxx60
-rw-r--r--editeng/source/editeng/editdoc.cxx2317
-rw-r--r--editeng/source/editeng/editdoc.hxx805
-rw-r--r--editeng/source/editeng/editdoc2.cxx547
-rw-r--r--editeng/source/editeng/editeng.cxx2944
-rw-r--r--editeng/source/editeng/editeng.src127
-rw-r--r--editeng/source/editeng/editobj.cxx1728
-rw-r--r--editeng/source/editeng/editobj2.hxx312
-rw-r--r--editeng/source/editeng/editsel.cxx124
-rw-r--r--editeng/source/editeng/editsel.hxx78
-rw-r--r--editeng/source/editeng/editstt2.hxx133
-rw-r--r--editeng/source/editeng/editundo.cxx753
-rw-r--r--editeng/source/editeng/editundo.hxx318
-rw-r--r--editeng/source/editeng/editview.cxx1598
-rw-r--r--editeng/source/editeng/edtspell.cxx749
-rw-r--r--editeng/source/editeng/edtspell.hxx188
-rw-r--r--editeng/source/editeng/eehtml.cxx853
-rw-r--r--editeng/source/editeng/eehtml.hxx101
-rw-r--r--editeng/source/editeng/eeng_pch.cxx33
-rw-r--r--editeng/source/editeng/eeng_pch.hxx37
-rw-r--r--editeng/source/editeng/eeobj.cxx115
-rw-r--r--editeng/source/editeng/eeobj.hxx75
-rw-r--r--editeng/source/editeng/eerdll.cxx240
-rw-r--r--editeng/source/editeng/eerdll2.hxx64
-rw-r--r--editeng/source/editeng/eertfpar.cxx635
-rw-r--r--editeng/source/editeng/eertfpar.hxx131
-rw-r--r--editeng/source/editeng/impedit.cxx2005
-rw-r--r--editeng/source/editeng/impedit.hxx1211
-rw-r--r--editeng/source/editeng/impedit2.cxx4635
-rw-r--r--editeng/source/editeng/impedit3.cxx4680
-rw-r--r--editeng/source/editeng/impedit4.cxx2958
-rw-r--r--editeng/source/editeng/impedit5.cxx914
-rw-r--r--editeng/source/editeng/makefile.mk84
-rw-r--r--editeng/source/editeng/textconv.cxx632
-rw-r--r--editeng/source/editeng/textconv.hxx125
-rw-r--r--editeng/source/items/bulitem.cxx537
-rw-r--r--editeng/source/items/charhiddenitem.cxx85
-rw-r--r--editeng/source/items/flditem.cxx1101
-rw-r--r--editeng/source/items/frmitems.cxx4470
-rw-r--r--editeng/source/items/itemtype.cxx242
-rw-r--r--editeng/source/items/makefile.mk78
-rw-r--r--editeng/source/items/numitem.cxx1276
-rw-r--r--editeng/source/items/page.src258
-rw-r--r--editeng/source/items/paperinf.cxx188
-rw-r--r--editeng/source/items/paraitem.cxx1761
-rw-r--r--editeng/source/items/svdfield.cxx65
-rw-r--r--editeng/source/items/svxfont.cxx860
-rw-r--r--editeng/source/items/svxitems.src1027
-rw-r--r--editeng/source/items/textitem.cxx3846
-rw-r--r--editeng/source/items/writingmodeitem.cxx156
-rw-r--r--editeng/source/items/xmlcnitm.cxx251
-rw-r--r--editeng/source/misc/SvXMLAutoCorrectExport.cxx120
-rw-r--r--editeng/source/misc/SvXMLAutoCorrectExport.hxx78
-rw-r--r--editeng/source/misc/SvXMLAutoCorrectImport.cxx269
-rw-r--r--editeng/source/misc/SvXMLAutoCorrectImport.hxx151
-rw-r--r--editeng/source/misc/acorrcfg.cxx681
-rw-r--r--editeng/source/misc/edtdlg.cxx39
-rw-r--r--editeng/source/misc/forbiddencharacterstable.cxx95
-rw-r--r--editeng/source/misc/hangulhanja.cxx1174
-rw-r--r--editeng/source/misc/lingu.src107
-rw-r--r--editeng/source/misc/makefile.mk71
-rw-r--r--editeng/source/misc/splwrap.cxx637
-rw-r--r--editeng/source/misc/svxacorr.cxx2706
-rw-r--r--editeng/source/misc/swafopt.cxx163
-rw-r--r--editeng/source/misc/txtrange.cxx722
-rw-r--r--editeng/source/misc/unolingu.cxx1377
-rw-r--r--editeng/source/outliner/makefile.mk64
-rw-r--r--editeng/source/outliner/outl_pch.cxx34
-rw-r--r--editeng/source/outliner/outl_pch.hxx36
-rw-r--r--editeng/source/outliner/outleeng.cxx247
-rw-r--r--editeng/source/outliner/outleeng.hxx96
-rw-r--r--editeng/source/outliner/outlin2.cxx816
-rw-r--r--editeng/source/outliner/outliner.cxx2184
-rw-r--r--editeng/source/outliner/outliner.src87
-rw-r--r--editeng/source/outliner/outlobj.cxx274
-rw-r--r--editeng/source/outliner/outlundo.cxx237
-rw-r--r--editeng/source/outliner/outlundo.hxx143
-rw-r--r--editeng/source/outliner/outlvw.cxx1663
-rw-r--r--editeng/source/outliner/paralist.cxx290
-rw-r--r--editeng/source/outliner/paralist.hxx74
-rw-r--r--editeng/source/rtf/makefile.mk55
-rw-r--r--editeng/source/rtf/rtfgrf.cxx561
-rw-r--r--editeng/source/rtf/rtfitem.cxx2104
-rw-r--r--editeng/source/rtf/segincr.asm43
-rw-r--r--editeng/source/rtf/svxrtf.cxx1517
-rw-r--r--editeng/source/uno/UnoForbiddenCharsTable.cxx148
-rw-r--r--editeng/source/uno/makefile.mk65
-rw-r--r--editeng/source/uno/unoedhlp.cxx200
-rw-r--r--editeng/source/uno/unoedprx.cxx1292
-rw-r--r--editeng/source/uno/unoedsrc.cxx93
-rw-r--r--editeng/source/uno/unofdesc.cxx269
-rw-r--r--editeng/source/uno/unofield.cxx1183
-rw-r--r--editeng/source/uno/unofored.cxx555
-rw-r--r--editeng/source/uno/unoforou.cxx613
-rw-r--r--editeng/source/uno/unoipset.cxx425
-rw-r--r--editeng/source/uno/unonrule.cxx618
-rw-r--r--editeng/source/uno/unopracc.cxx174
-rw-r--r--editeng/source/uno/unotext.cxx2720
-rw-r--r--editeng/source/uno/unotext2.cxx714
-rw-r--r--editeng/source/uno/unoviwed.cxx140
-rw-r--r--editeng/source/uno/unoviwou.cxx176
-rw-r--r--editeng/source/xml/editsource.hxx55
-rw-r--r--editeng/source/xml/makefile.mk50
-rw-r--r--editeng/source/xml/xmltxtexp.cxx503
-rw-r--r--editeng/source/xml/xmltxtimp.cxx263
121 files changed, 85763 insertions, 0 deletions
diff --git a/editeng/source/accessibility/AccessibleComponentBase.cxx b/editeng/source/accessibility/AccessibleComponentBase.cxx
new file mode 100644
index 0000000000..7d6d5205e0
--- /dev/null
+++ b/editeng/source/accessibility/AccessibleComponentBase.cxx
@@ -0,0 +1,240 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleComponentBase.cxx,v $
+ * $Revision: 1.17 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+
+#include <editeng/AccessibleComponentBase.hxx>
+
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/drawing/XShapeDescriptor.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+
+#include <tools/color.hxx>
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+namespace accessibility {
+
+//===== internal ============================================================
+
+AccessibleComponentBase::AccessibleComponentBase (void)
+{
+}
+
+
+
+
+AccessibleComponentBase::~AccessibleComponentBase (void)
+{
+}
+
+
+
+
+//===== XAccessibleComponent ================================================
+
+sal_Bool SAL_CALL AccessibleComponentBase::containsPoint (
+ const ::com::sun::star::awt::Point& aPoint)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ awt::Size aSize (getSize());
+ return (aPoint.X >= 0)
+ && (aPoint.X < aSize.Width)
+ && (aPoint.Y >= 0)
+ && (aPoint.Y < aSize.Height);
+}
+
+
+
+
+uno::Reference<XAccessible > SAL_CALL
+ AccessibleComponentBase::getAccessibleAtPoint (
+ const awt::Point& /*aPoint*/)
+ throw (uno::RuntimeException)
+{
+ return uno::Reference<XAccessible>();
+}
+
+
+
+
+awt::Rectangle SAL_CALL AccessibleComponentBase::getBounds (void)
+ throw (uno::RuntimeException)
+{
+ return awt::Rectangle();
+}
+
+
+
+
+awt::Point SAL_CALL AccessibleComponentBase::getLocation (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ awt::Rectangle aBBox (getBounds());
+ return awt::Point (aBBox.X, aBBox.Y);
+}
+
+
+
+
+awt::Point SAL_CALL AccessibleComponentBase::getLocationOnScreen (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return awt::Point();
+}
+
+
+
+
+::com::sun::star::awt::Size SAL_CALL AccessibleComponentBase::getSize (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ awt::Rectangle aBBox (getBounds());
+ return awt::Size (aBBox.Width, aBBox.Height);
+}
+
+
+
+
+void SAL_CALL AccessibleComponentBase::addFocusListener (
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::awt::XFocusListener >& /*xListener*/)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ // Ignored
+}
+
+
+
+
+void SAL_CALL AccessibleComponentBase::removeFocusListener (const ::com::sun::star::uno::Reference<
+ ::com::sun::star::awt::XFocusListener >& /*xListener*/ )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ // Ignored
+}
+
+
+
+
+void SAL_CALL AccessibleComponentBase::grabFocus (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ uno::Reference<XAccessibleContext> xContext (this, uno::UNO_QUERY);
+ uno::Reference<XAccessibleSelection> xSelection (
+ xContext->getAccessibleParent(), uno::UNO_QUERY);
+ if (xSelection.is())
+ {
+ // Do a single selection on this object.
+ xSelection->clearAccessibleSelection();
+ xSelection->selectAccessibleChild (xContext->getAccessibleIndexInParent());
+ }
+}
+
+
+
+
+sal_Int32 SAL_CALL AccessibleComponentBase::getForeground (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return Color(COL_BLACK).GetColor();
+}
+
+
+
+
+sal_Int32 SAL_CALL AccessibleComponentBase::getBackground (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return Color(COL_WHITE).GetColor();
+}
+
+
+
+
+//===== XAccessibleExtendedComponent ========================================
+
+::com::sun::star::uno::Reference< ::com::sun::star::awt::XFont > SAL_CALL
+ AccessibleComponentBase::getFont (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return uno::Reference<awt::XFont>();
+}
+
+
+
+
+::rtl::OUString SAL_CALL AccessibleComponentBase::getTitledBorderText (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return ::rtl::OUString::createFromAscii ("");
+}
+
+
+
+
+::rtl::OUString SAL_CALL AccessibleComponentBase::getToolTipText (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return ::rtl::OUString::createFromAscii ("");
+}
+
+
+
+
+//===== XTypeProvider ===================================================
+
+uno::Sequence<uno::Type> SAL_CALL
+ AccessibleComponentBase::getTypes (void)
+ throw (uno::RuntimeException)
+{
+ // Get list of types from the context base implementation...
+ uno::Sequence<uno::Type> aTypeList (2);
+ // ...and add the additional type for the component.
+ const uno::Type aComponentType =
+ ::getCppuType((const uno::Reference<XAccessibleComponent>*)0);
+ const uno::Type aExtendedComponentType =
+ ::getCppuType((const uno::Reference<XAccessibleExtendedComponent>*)0);
+ aTypeList[0] = aComponentType;
+ aTypeList[1] = aExtendedComponentType;
+
+ return aTypeList;
+}
+
+
+} // end of namespace accessibility
diff --git a/editeng/source/accessibility/AccessibleContextBase.cxx b/editeng/source/accessibility/AccessibleContextBase.cxx
new file mode 100644
index 0000000000..d3671624f4
--- /dev/null
+++ b/editeng/source/accessibility/AccessibleContextBase.cxx
@@ -0,0 +1,718 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleContextBase.cxx,v $
+ * $Revision: 1.28.144.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+
+#include <editeng/AccessibleContextBase.hxx>
+
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/beans/PropertyChangeEvent.hpp>
+#include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
+
+#include <unotools/accessiblestatesethelper.hxx>
+#include <unotools/accessiblerelationsethelper.hxx>
+#include <comphelper/accessibleeventnotifier.hxx>
+#include <rtl/uuid.h>
+#include <vos/mutex.hxx>
+//#include <vcl/svapp.hxx>
+
+#include <utility>
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+using ::com::sun::star::uno::Reference;
+
+namespace accessibility {
+
+//===== internal ============================================================
+
+// Define a shortcut for the somewhot longish base class name.
+typedef ::cppu::WeakComponentImplHelper4<
+ ::com::sun::star::accessibility::XAccessible,
+ ::com::sun::star::accessibility::XAccessibleContext,
+ ::com::sun::star::accessibility::XAccessibleEventBroadcaster,
+ ::com::sun::star::lang::XServiceInfo> BaseClass;
+
+AccessibleContextBase::AccessibleContextBase (
+ const uno::Reference<XAccessible>& rxParent,
+ const sal_Int16 aRole)
+ : BaseClass (MutexOwner::maMutex),
+ mxStateSet (NULL),
+ mxRelationSet (NULL),
+ mxParent(rxParent),
+ msDescription(),
+ meDescriptionOrigin(NotSet),
+ msName(),
+ meNameOrigin(NotSet),
+ mnClientId(0),
+ maRole(aRole)
+{
+ // Create the state set.
+ ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper ();
+ mxStateSet = pStateSet;
+
+ // Set some states. Don't use the SetState method because no events
+ // shall be broadcastet (that is not yet initialized anyway).
+ if (pStateSet != NULL)
+ {
+ pStateSet->AddState (AccessibleStateType::ENABLED);
+ pStateSet->AddState (AccessibleStateType::SENSITIVE);
+ pStateSet->AddState (AccessibleStateType::SHOWING);
+ pStateSet->AddState (AccessibleStateType::VISIBLE);
+ pStateSet->AddState (AccessibleStateType::FOCUSABLE);
+ pStateSet->AddState (AccessibleStateType::SELECTABLE);
+ }
+
+ // Create the relation set.
+ ::utl::AccessibleRelationSetHelper* pRelationSet = new ::utl::AccessibleRelationSetHelper ();
+ mxRelationSet = pRelationSet;
+}
+
+
+
+
+AccessibleContextBase::~AccessibleContextBase(void)
+{
+}
+
+
+
+
+sal_Bool AccessibleContextBase::SetState (sal_Int16 aState)
+{
+ ::osl::ClearableMutexGuard aGuard (maMutex);
+ ::utl::AccessibleStateSetHelper* pStateSet =
+ static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
+ if ((pStateSet != NULL) && !pStateSet->contains(aState))
+ {
+ pStateSet->AddState (aState);
+ // Clear the mutex guard so that it is not locked during calls to
+ // listeners.
+ aGuard.clear();
+
+ // Send event for all states except the DEFUNC state.
+ if (aState != AccessibleStateType::DEFUNC)
+ {
+ uno::Any aNewValue;
+ aNewValue <<= aState;
+ CommitChange(
+ AccessibleEventId::STATE_CHANGED,
+ aNewValue,
+ uno::Any());
+ }
+ return sal_True;
+ }
+ else
+ return sal_False;
+}
+
+
+
+
+sal_Bool AccessibleContextBase::ResetState (sal_Int16 aState)
+{
+ ::osl::ClearableMutexGuard aGuard (maMutex);
+ ::utl::AccessibleStateSetHelper* pStateSet =
+ static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
+ if ((pStateSet != NULL) && pStateSet->contains(aState))
+ {
+ pStateSet->RemoveState (aState);
+ // Clear the mutex guard so that it is not locked during calls to listeners.
+ aGuard.clear();
+
+ uno::Any aOldValue;
+ aOldValue <<= aState;
+ CommitChange(
+ AccessibleEventId::STATE_CHANGED,
+ uno::Any(),
+ aOldValue);
+ return sal_True;
+ }
+ else
+ return sal_False;
+}
+
+
+
+
+sal_Bool AccessibleContextBase::GetState (sal_Int16 aState)
+{
+ ::osl::MutexGuard aGuard (maMutex);
+ ::utl::AccessibleStateSetHelper* pStateSet =
+ static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
+ if (pStateSet != NULL)
+ return pStateSet->contains(aState);
+ else
+ // If there is no state set then return false as a default value.
+ return sal_False;
+}
+
+
+
+
+void AccessibleContextBase::SetRelationSet (
+ const uno::Reference<XAccessibleRelationSet>& rxNewRelationSet)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ OSL_TRACE ("setting relation set");
+
+ // Try to emit some meaningfull events indicating differing relations in
+ // both sets.
+ typedef std::pair<short int,short int> RD;
+ const RD aRelationDescriptors[] = {
+ RD(AccessibleRelationType::CONTROLLED_BY, AccessibleEventId::CONTROLLED_BY_RELATION_CHANGED),
+ RD(AccessibleRelationType::CONTROLLER_FOR, AccessibleEventId::CONTROLLER_FOR_RELATION_CHANGED),
+ RD(AccessibleRelationType::LABELED_BY, AccessibleEventId::LABELED_BY_RELATION_CHANGED),
+ RD(AccessibleRelationType::LABEL_FOR, AccessibleEventId::LABEL_FOR_RELATION_CHANGED),
+ RD(AccessibleRelationType::MEMBER_OF, AccessibleEventId::MEMBER_OF_RELATION_CHANGED),
+ RD(AccessibleRelationType::INVALID, -1),
+ };
+ for (int i=0; aRelationDescriptors[i].first!=AccessibleRelationType::INVALID; i++)
+ if (mxRelationSet->containsRelation(aRelationDescriptors[i].first)
+ != rxNewRelationSet->containsRelation(aRelationDescriptors[i].first))
+ CommitChange (aRelationDescriptors[i].second, uno::Any(), uno::Any());
+
+ mxRelationSet = rxNewRelationSet;
+}
+
+
+
+
+//===== XAccessible =========================================================
+
+uno::Reference< XAccessibleContext> SAL_CALL
+ AccessibleContextBase::getAccessibleContext (void)
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed ();
+ return this;
+}
+
+
+
+
+//===== XAccessibleContext ==================================================
+
+/** No children.
+*/
+sal_Int32 SAL_CALL
+ AccessibleContextBase::getAccessibleChildCount (void)
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed ();
+ return 0;
+}
+
+
+
+
+/** Forward the request to the shape. Return the requested shape or throw
+ an exception for a wrong index.
+*/
+uno::Reference<XAccessible> SAL_CALL
+ AccessibleContextBase::getAccessibleChild (sal_Int32 nIndex)
+ throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
+{
+ ThrowIfDisposed ();
+ throw lang::IndexOutOfBoundsException (
+ ::rtl::OUString::createFromAscii ("no child with index " + nIndex),
+ NULL);
+}
+
+
+
+
+uno::Reference<XAccessible> SAL_CALL
+ AccessibleContextBase::getAccessibleParent (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ThrowIfDisposed ();
+ return mxParent;
+}
+
+
+
+
+sal_Int32 SAL_CALL
+ AccessibleContextBase::getAccessibleIndexInParent (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ThrowIfDisposed ();
+ // Use a simple but slow solution for now. Optimize later.
+
+ // Iterate over all the parent's children and search for this object.
+ if (mxParent.is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext (
+ mxParent->getAccessibleContext());
+ if (xParentContext.is())
+ {
+ sal_Int32 nChildCount = xParentContext->getAccessibleChildCount();
+ for (sal_Int32 i=0; i<nChildCount; i++)
+ {
+ uno::Reference<XAccessible> xChild (xParentContext->getAccessibleChild (i));
+ if (xChild.is())
+ {
+ uno::Reference<XAccessibleContext> xChildContext = xChild->getAccessibleContext();
+ if (xChildContext == (XAccessibleContext*)this)
+ return i;
+ }
+ }
+ }
+ }
+
+ // Return -1 to indicate that this object's parent does not know about the
+ // object.
+ return -1;
+}
+
+
+
+
+sal_Int16 SAL_CALL
+ AccessibleContextBase::getAccessibleRole (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ThrowIfDisposed ();
+ return maRole;
+}
+
+
+
+
+::rtl::OUString SAL_CALL
+ AccessibleContextBase::getAccessibleDescription (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ThrowIfDisposed ();
+
+ return msDescription;
+}
+
+
+
+
+OUString SAL_CALL
+ AccessibleContextBase::getAccessibleName (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ThrowIfDisposed ();
+
+ if (meNameOrigin == NotSet)
+ {
+ // Do not send an event because this is the first time it has been
+ // requested.
+ msName = CreateAccessibleName();
+ meNameOrigin = AutomaticallyCreated;
+ }
+
+ return msName;
+}
+
+
+
+
+/** Return a copy of the relation set.
+*/
+uno::Reference<XAccessibleRelationSet> SAL_CALL
+ AccessibleContextBase::getAccessibleRelationSet (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ThrowIfDisposed ();
+
+ // Create a copy of the relation set and return it.
+ ::utl::AccessibleRelationSetHelper* pRelationSet =
+ static_cast< ::utl::AccessibleRelationSetHelper*>(mxRelationSet.get());
+ if (pRelationSet != NULL)
+ {
+ return uno::Reference<XAccessibleRelationSet> (
+ new ::utl::AccessibleRelationSetHelper (*pRelationSet));
+ }
+ else
+ return uno::Reference<XAccessibleRelationSet>(NULL);
+}
+
+
+
+
+/** Return a copy of the state set.
+ Possible states are:
+ ENABLED
+ SHOWING
+ VISIBLE
+*/
+uno::Reference<XAccessibleStateSet> SAL_CALL
+ AccessibleContextBase::getAccessibleStateSet (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ::utl::AccessibleStateSetHelper* pStateSet = NULL;
+
+ if (rBHelper.bDisposed)
+ {
+ // We are already disposed!
+ // Create a new state set that has only set the DEFUNC state.
+ pStateSet = new ::utl::AccessibleStateSetHelper ();
+ if (pStateSet != NULL)
+ pStateSet->AddState (AccessibleStateType::DEFUNC);
+ }
+ else
+ {
+ // Create a copy of the state set and return it.
+ pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
+
+ // Merge current focused state from edit engine.
+#if 0
+ if (aState == AccessibleStateType::FOCUSED
+ && pStateSet != NULL
+ && mpText != NULL)
+ {
+ if (mpText->GetFocusedState ())
+ pStateSet->AddState (aState);
+ else
+ pStateSet->RemoveState (aState);
+ }
+#endif
+ if (pStateSet != NULL)
+ pStateSet = new ::utl::AccessibleStateSetHelper (*pStateSet);
+ }
+
+ return uno::Reference<XAccessibleStateSet>(pStateSet);
+}
+
+
+
+
+lang::Locale SAL_CALL
+ AccessibleContextBase::getLocale (void)
+ throw (IllegalAccessibleComponentStateException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ ThrowIfDisposed ();
+ // Delegate request to parent.
+ if (mxParent.is())
+ {
+ uno::Reference<XAccessibleContext> xParentContext (
+ mxParent->getAccessibleContext());
+ if (xParentContext.is())
+ return xParentContext->getLocale ();
+ }
+
+ // No locale and no parent. Therefore throw exception to indicate this
+ // cluelessness.
+ throw IllegalAccessibleComponentStateException ();
+}
+
+
+
+
+//===== XAccessibleEventListener ============================================
+
+void SAL_CALL
+ AccessibleContextBase::addEventListener (
+ const uno::Reference<XAccessibleEventListener >& rxListener)
+ throw (uno::RuntimeException)
+{
+ if (rxListener.is())
+ {
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ uno::Reference<uno::XInterface> x ((lang::XComponent *)this, uno::UNO_QUERY);
+ rxListener->disposing (lang::EventObject (x));
+ }
+ else
+ {
+ if (!mnClientId)
+ mnClientId = comphelper::AccessibleEventNotifier::registerClient( );
+ comphelper::AccessibleEventNotifier::addEventListener( mnClientId, rxListener );
+ }
+ }
+}
+
+
+
+
+void SAL_CALL
+ AccessibleContextBase::removeEventListener (
+ const uno::Reference<XAccessibleEventListener >& rxListener )
+ throw (uno::RuntimeException)
+{
+ ThrowIfDisposed ();
+ if (rxListener.is())
+ {
+ sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, rxListener );
+ if ( !nListenerCount )
+ {
+ // no listeners anymore
+ // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
+ // and at least to us not firing any events anymore, in case somebody calls
+ // NotifyAccessibleEvent, again
+ comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
+ mnClientId = 0;
+ }
+ }
+}
+
+
+
+
+//===== XServiceInfo ========================================================
+
+::rtl::OUString SAL_CALL
+ AccessibleContextBase::getImplementationName (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ThrowIfDisposed ();
+ return OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleContextBase"));
+}
+
+
+
+
+sal_Bool SAL_CALL
+ AccessibleContextBase::supportsService (const OUString& sServiceName)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ThrowIfDisposed ();
+ // Iterate over all supported service names and return true if on of them
+ // matches the given name.
+ uno::Sequence< ::rtl::OUString> aSupportedServices (
+ getSupportedServiceNames ());
+ for (int i=0; i<aSupportedServices.getLength(); i++)
+ if (sServiceName == aSupportedServices[i])
+ return sal_True;
+ return sal_False;
+}
+
+
+
+
+uno::Sequence< ::rtl::OUString> SAL_CALL
+ AccessibleContextBase::getSupportedServiceNames (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ThrowIfDisposed ();
+ static const OUString sServiceNames[2] = {
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.accessibility.Accessible")),
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.accessibility.AccessibleContext"))
+ };
+ return uno::Sequence<OUString> (sServiceNames, 2);
+}
+
+
+
+
+//===== XTypeProvider =======================================================
+
+uno::Sequence< ::com::sun::star::uno::Type>
+ AccessibleContextBase::getTypes (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ThrowIfDisposed ();
+
+ // This class supports no interfaces on its own. Just return those
+ // supported by the base class.
+ return BaseClass::getTypes();
+}
+
+
+
+
+uno::Sequence<sal_Int8> SAL_CALL
+ AccessibleContextBase::getImplementationId (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ThrowIfDisposed ();
+ static uno::Sequence<sal_Int8> aId;
+ if (aId.getLength() == 0)
+ {
+ ::osl::MutexGuard aGuard (maMutex);
+ aId.realloc (16);
+ rtl_createUuid ((sal_uInt8 *)aId.getArray(), 0, sal_True);
+ }
+ return aId;
+}
+
+
+
+
+//===== internal ============================================================
+
+void SAL_CALL AccessibleContextBase::disposing (void)
+{
+ SetState (AccessibleStateType::DEFUNC);
+
+ ::osl::MutexGuard aGuard (maMutex);
+
+ // Send a disposing to all listeners.
+ if ( mnClientId )
+ {
+ comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this );
+ mnClientId = 0;
+ }
+}
+
+
+
+
+void AccessibleContextBase::SetAccessibleDescription (
+ const ::rtl::OUString& rDescription,
+ StringOrigin eDescriptionOrigin)
+ throw (uno::RuntimeException)
+{
+ if (eDescriptionOrigin < meDescriptionOrigin
+ || (eDescriptionOrigin == meDescriptionOrigin && msDescription != rDescription))
+ {
+ uno::Any aOldValue, aNewValue;
+ aOldValue <<= msDescription;
+ aNewValue <<= rDescription;
+
+ msDescription = rDescription;
+ meDescriptionOrigin = eDescriptionOrigin;
+
+ CommitChange(
+ AccessibleEventId::DESCRIPTION_CHANGED,
+ aNewValue,
+ aOldValue);
+ }
+}
+
+
+
+
+void AccessibleContextBase::SetAccessibleName (
+ const ::rtl::OUString& rName,
+ StringOrigin eNameOrigin)
+ throw (uno::RuntimeException)
+{
+ if (eNameOrigin < meNameOrigin
+ || (eNameOrigin == meNameOrigin && msName != rName))
+ {
+ uno::Any aOldValue, aNewValue;
+ aOldValue <<= msName;
+ aNewValue <<= rName;
+
+ msName = rName;
+ meNameOrigin = eNameOrigin;
+
+ CommitChange(
+ AccessibleEventId::NAME_CHANGED,
+ aNewValue,
+ aOldValue);
+ }
+}
+
+
+
+
+::rtl::OUString AccessibleContextBase::CreateAccessibleDescription (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return ::rtl::OUString::createFromAscii ("Empty Description");
+}
+
+
+
+
+::rtl::OUString AccessibleContextBase::CreateAccessibleName (void)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return ::rtl::OUString::createFromAscii ("Empty Name");
+}
+
+
+
+
+void AccessibleContextBase::CommitChange (
+ sal_Int16 nEventId,
+ const uno::Any& rNewValue,
+ const uno::Any& rOldValue)
+{
+ // Do not call FireEvent and do not even create the event object when no
+ // listener has been registered yet. Creating the event object can
+ // otherwise lead to a crash. See issue 93419 for details.
+ if (mnClientId != 0)
+ {
+ AccessibleEventObject aEvent (
+ static_cast<XAccessibleContext*>(this),
+ nEventId,
+ rNewValue,
+ rOldValue);
+
+ FireEvent (aEvent);
+ }
+}
+
+
+
+
+void AccessibleContextBase::FireEvent (const AccessibleEventObject& aEvent)
+{
+ if (mnClientId)
+ comphelper::AccessibleEventNotifier::addEvent( mnClientId, aEvent );
+}
+
+
+
+
+void AccessibleContextBase::ThrowIfDisposed (void)
+ throw (::com::sun::star::lang::DisposedException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ OSL_TRACE ("Calling disposed object. Throwing exception:");
+ throw lang::DisposedException (
+ OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")),
+ static_cast<uno::XWeak*>(this));
+ }
+}
+
+
+
+sal_Bool AccessibleContextBase::IsDisposed (void)
+{
+ return (rBHelper.bDisposed || rBHelper.bInDispose);
+}
+
+
+
+void AccessibleContextBase::SetAccessibleRole( sal_Int16 _nRole )
+{
+ maRole = _nRole;
+}
+
+
+} // end of namespace accessibility
diff --git a/editeng/source/accessibility/AccessibleEditableTextPara.cxx b/editeng/source/accessibility/AccessibleEditableTextPara.cxx
new file mode 100644
index 0000000000..7b32e6fe58
--- /dev/null
+++ b/editeng/source/accessibility/AccessibleEditableTextPara.cxx
@@ -0,0 +1,2204 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleEditableTextPara.cxx,v $
+ * $Revision: 1.53 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+//------------------------------------------------------------------------
+//
+// Global header
+//
+//------------------------------------------------------------------------
+
+#include <limits.h>
+#include <vector>
+#include <algorithm>
+#include <vos/mutex.hxx>
+#include <vcl/window.hxx>
+#include <vcl/svapp.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleTextType.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <comphelper/accessibleeventnotifier.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <unotools/accessiblestatesethelper.hxx>
+
+// --> OD 2006-01-11 #i27138#
+#include <unotools/accessiblerelationsethelper.hxx>
+#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
+// <--
+#include <vcl/unohelp.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/unoprnms.hxx>
+#include <editeng/unoipset.hxx>
+#include <editeng/outliner.hxx>
+
+//------------------------------------------------------------------------
+//
+// Project-local header
+//
+//------------------------------------------------------------------------
+
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <editeng/unolingu.hxx>
+#include <editeng/unopracc.hxx>
+#include "AccessibleEditableTextPara.hxx"
+#include <svtools/colorcfg.hxx>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::accessibility;
+
+
+//------------------------------------------------------------------------
+//
+// AccessibleEditableTextPara implementation
+//
+//------------------------------------------------------------------------
+
+namespace accessibility
+{
+
+ const SvxItemPropertySet* ImplGetSvxCharAndParaPropertiesSet()
+ {
+ // PropertyMap for character and paragraph properties
+ static const SfxItemPropertyMapEntry aPropMap[] =
+ {
+ SVX_UNOEDIT_CHAR_PROPERTIES,
+ SVX_UNOEDIT_PARA_PROPERTIES,
+ SVX_UNOEDIT_NUMBERING_PROPERTIE,
+ {MAP_CHAR_LEN("TextUserDefinedAttributes"), EE_CHAR_XMLATTRIBS, &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >*)0) , 0, 0},
+ {MAP_CHAR_LEN("ParaUserDefinedAttributes"), EE_PARA_XMLATTRIBS, &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >*)0) , 0, 0},
+ {0,0,0,0,0,0}
+ };
+ static SvxItemPropertySet aPropSet( aPropMap, EditEngine::GetGlobalItemPool() );
+ return &aPropSet;
+ }
+
+
+ DBG_NAME( AccessibleEditableTextPara )
+
+ // --> OD 2006-01-11 #i27138# - add parameter <_pParaManager>
+ AccessibleEditableTextPara::AccessibleEditableTextPara(
+ const uno::Reference< XAccessible >& rParent,
+ const AccessibleParaManager* _pParaManager )
+ : AccessibleTextParaInterfaceBase( m_aMutex ),
+ mnParagraphIndex( 0 ),
+ mnIndexInParent( 0 ),
+ mpEditSource( NULL ),
+ maEEOffset( 0, 0 ),
+ mxParent( rParent ),
+ // well, that's strictly (UNO) exception safe, though not
+ // really robust. We rely on the fact that this member is
+ // constructed last, and that the constructor body catches
+ // exceptions, thus no chance for exceptions once the Id is
+ // fetched. Nevertheless, normally should employ RAII here...
+ mnNotifierClientId(::comphelper::AccessibleEventNotifier::registerClient()),
+ // --> OD 2006-01-11 #i27138#
+ mpParaManager( _pParaManager )
+ // <--
+ {
+#ifdef DBG_UTIL
+ DBG_CTOR( AccessibleEditableTextPara, NULL );
+ OSL_TRACE( "AccessibleEditableTextPara received ID: %d\n", mnNotifierClientId );
+#endif
+
+ try
+ {
+ // Create the state set.
+ ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper ();
+ mxStateSet = pStateSet;
+
+ // these are always on
+ pStateSet->AddState( AccessibleStateType::MULTI_LINE );
+ pStateSet->AddState( AccessibleStateType::FOCUSABLE );
+ pStateSet->AddState( AccessibleStateType::VISIBLE );
+ pStateSet->AddState( AccessibleStateType::SHOWING );
+ pStateSet->AddState( AccessibleStateType::ENABLED );
+ pStateSet->AddState( AccessibleStateType::SENSITIVE );
+ }
+ catch( const uno::Exception& ) {}
+ }
+
+ AccessibleEditableTextPara::~AccessibleEditableTextPara()
+ {
+ DBG_DTOR( AccessibleEditableTextPara, NULL );
+
+ // sign off from event notifier
+ if( getNotifierClientId() != -1 )
+ {
+ try
+ {
+ ::comphelper::AccessibleEventNotifier::revokeClient( getNotifierClientId() );
+#ifdef DBG_UTIL
+ OSL_TRACE( "AccessibleEditableTextPara revoked ID: %d\n", mnNotifierClientId );
+#endif
+ }
+ catch( const uno::Exception& ) {}
+ }
+ }
+
+ ::rtl::OUString AccessibleEditableTextPara::implGetText()
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ return GetTextRange( 0, GetTextLen() );
+ }
+
+ ::com::sun::star::lang::Locale AccessibleEditableTextPara::implGetLocale()
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ lang::Locale aLocale;
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::getLocale: paragraph index value overflow");
+
+ // return locale of first character in the paragraph
+ return SvxLanguageToLocale(aLocale, GetTextForwarder().GetLanguage( static_cast< USHORT >( GetParagraphIndex() ), 0 ));
+ }
+
+ void AccessibleEditableTextPara::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ USHORT nStart, nEnd;
+
+ if( GetSelection( nStart, nEnd ) )
+ {
+ nStartIndex = nStart;
+ nEndIndex = nEnd;
+ }
+ else
+ {
+ // #102234# No exception, just set to 'invalid'
+ nStartIndex = -1;
+ nEndIndex = -1;
+ }
+ }
+
+ void AccessibleEditableTextPara::implGetParagraphBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 /*nIndex*/ )
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+ DBG_WARNING( "AccessibleEditableTextPara::implGetParagraphBoundary: only a base implementation, ignoring the index" );
+
+ rBoundary.startPos = 0;
+ rBoundary.endPos = GetTextLen();
+ }
+
+ void AccessibleEditableTextPara::implGetLineBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 nIndex )
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ SvxTextForwarder& rCacheTF = GetTextForwarder();
+ const sal_Int32 nParaIndex = GetParagraphIndex();
+
+ DBG_ASSERT(nParaIndex >= 0 && nParaIndex <= USHRT_MAX,
+ "AccessibleEditableTextPara::implGetLineBoundary: paragraph index value overflow");
+
+ const sal_Int32 nTextLen = rCacheTF.GetTextLen( static_cast< USHORT >( nParaIndex ) );
+
+ CheckPosition(nIndex);
+
+ rBoundary.startPos = rBoundary.endPos = -1;
+
+ const USHORT nLineCount=rCacheTF.GetLineCount( static_cast< USHORT >( nParaIndex ) );
+
+ if( nIndex == nTextLen )
+ {
+ // #i17014# Special-casing one-behind-the-end character
+ if( nLineCount <= 1 )
+ rBoundary.startPos = 0;
+ else
+ rBoundary.startPos = nTextLen - rCacheTF.GetLineLen( static_cast< USHORT >( nParaIndex ),
+ nLineCount-1 );
+
+ rBoundary.endPos = nTextLen;
+ }
+ else
+ {
+ // normal line search
+ USHORT nLine;
+ sal_Int32 nCurIndex;
+ for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine )
+ {
+ nCurIndex += rCacheTF.GetLineLen( static_cast< USHORT >( nParaIndex ), nLine);
+
+ if( nCurIndex > nIndex )
+ {
+ rBoundary.startPos = nCurIndex - rCacheTF.GetLineLen(static_cast< USHORT >( nParaIndex ), nLine);
+ rBoundary.endPos = nCurIndex;
+ break;
+ }
+ }
+ }
+ }
+
+ int AccessibleEditableTextPara::getNotifierClientId() const
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ return mnNotifierClientId;
+ }
+
+ void AccessibleEditableTextPara::SetIndexInParent( sal_Int32 nIndex )
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ mnIndexInParent = nIndex;
+ }
+
+ sal_Int32 AccessibleEditableTextPara::GetIndexInParent() const
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ return mnIndexInParent;
+ }
+
+ void AccessibleEditableTextPara::SetParagraphIndex( sal_Int32 nIndex )
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ sal_Int32 nOldIndex = mnParagraphIndex;
+
+ mnParagraphIndex = nIndex;
+
+ WeakBullet::HardRefType aChild( maImageBullet.get() );
+ if( aChild.is() )
+ aChild->SetParagraphIndex(mnParagraphIndex);
+
+ try
+ {
+ if( nOldIndex != nIndex )
+ {
+ uno::Any aOldDesc;
+ uno::Any aOldName;
+
+ try
+ {
+ aOldDesc <<= getAccessibleDescription();
+ aOldName <<= getAccessibleName();
+ }
+ catch( const uno::Exception& ) {} // optional behaviour
+ // index and therefore description changed
+ FireEvent( AccessibleEventId::DESCRIPTION_CHANGED, uno::makeAny( getAccessibleDescription() ), aOldDesc );
+ FireEvent( AccessibleEventId::NAME_CHANGED, uno::makeAny( getAccessibleName() ), aOldName );
+ }
+ }
+ catch( const uno::Exception& ) {} // optional behaviour
+ }
+
+ sal_Int32 AccessibleEditableTextPara::GetParagraphIndex() const SAL_THROW((uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ return mnParagraphIndex;
+ }
+
+ void AccessibleEditableTextPara::Dispose()
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ int nClientId( getNotifierClientId() );
+
+ // #108212# drop all references before notifying dispose
+ mxParent = NULL;
+ mnNotifierClientId = -1;
+ mpEditSource = NULL;
+
+ // notify listeners
+ if( nClientId != -1 )
+ {
+ try
+ {
+ uno::Reference < XAccessibleContext > xThis = getAccessibleContext();
+
+ // #106234# Delegate to EventNotifier
+ ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, xThis );
+#ifdef DBG_UTIL
+ OSL_TRACE( "Disposed ID: %d\n", nClientId );
+#endif
+ }
+ catch( const uno::Exception& ) {}
+ }
+ }
+
+ void AccessibleEditableTextPara::SetEditSource( SvxEditSourceAdapter* pEditSource )
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ mpEditSource = pEditSource;
+
+ WeakBullet::HardRefType aChild( maImageBullet.get() );
+ if( aChild.is() )
+ aChild->SetEditSource(pEditSource);
+
+ if( !mpEditSource )
+ {
+ // going defunc
+ UnSetState( AccessibleStateType::SHOWING );
+ UnSetState( AccessibleStateType::VISIBLE );
+ SetState( AccessibleStateType::INVALID );
+ SetState( AccessibleStateType::DEFUNC );
+
+ Dispose();
+ }
+
+ // #108900# Init last text content
+ try
+ {
+ TextChanged();
+ }
+ catch( const uno::RuntimeException& ) {}
+ }
+
+ ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nStartEEIndex, sal_Int32 nEndEEIndex )
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ // check overflow
+ DBG_ASSERT(nStartEEIndex >= 0 && nStartEEIndex <= USHRT_MAX &&
+ nEndEEIndex >= 0 && nEndEEIndex <= USHRT_MAX &&
+ GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::MakeSelection: index value overflow");
+
+ USHORT nParaIndex = static_cast< USHORT >( GetParagraphIndex() );
+ return ESelection( nParaIndex, static_cast< USHORT >( nStartEEIndex ),
+ nParaIndex, static_cast< USHORT >( nEndEEIndex ) );
+ }
+
+ ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nEEIndex )
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ return MakeSelection( nEEIndex, nEEIndex+1 );
+ }
+
+ ESelection AccessibleEditableTextPara::MakeCursor( sal_Int32 nEEIndex )
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ return MakeSelection( nEEIndex, nEEIndex );
+ }
+
+ void AccessibleEditableTextPara::CheckIndex( sal_Int32 nIndex ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ if( nIndex < 0 || nIndex >= getCharacterCount() )
+ throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleEditableTextPara: character index out of bounds")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* > (this) ) ); // disambiguate hierarchy
+ }
+
+ void AccessibleEditableTextPara::CheckPosition( sal_Int32 nIndex ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ if( nIndex < 0 || nIndex > getCharacterCount() )
+ throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleEditableTextPara: character position out of bounds")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* > (this) ) ); // disambiguate hierarchy
+ }
+
+ void AccessibleEditableTextPara::CheckRange( sal_Int32 nStart, sal_Int32 nEnd ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ CheckPosition( nStart );
+ CheckPosition( nEnd );
+ }
+
+ sal_Bool AccessibleEditableTextPara::GetSelection( USHORT& nStartPos, USHORT& nEndPos ) SAL_THROW((uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ESelection aSelection;
+ USHORT nPara = static_cast< USHORT > ( GetParagraphIndex() );
+ if( !GetEditViewForwarder().GetSelection( aSelection ) )
+ return sal_False;
+
+ if( aSelection.nStartPara < aSelection.nEndPara )
+ {
+ if( aSelection.nStartPara > nPara ||
+ aSelection.nEndPara < nPara )
+ return sal_False;
+
+ if( nPara == aSelection.nStartPara )
+ nStartPos = aSelection.nStartPos;
+ else
+ nStartPos = 0;
+
+ if( nPara == aSelection.nEndPara )
+ nEndPos = aSelection.nEndPos;
+ else
+ nEndPos = GetTextLen();
+ }
+ else
+ {
+ if( aSelection.nStartPara < nPara ||
+ aSelection.nEndPara > nPara )
+ return sal_False;
+
+ if( nPara == aSelection.nStartPara )
+ nStartPos = aSelection.nStartPos;
+ else
+ nStartPos = GetTextLen();
+
+ if( nPara == aSelection.nEndPara )
+ nEndPos = aSelection.nEndPos;
+ else
+ nEndPos = 0;
+ }
+
+ return sal_True;
+ }
+
+ String AccessibleEditableTextPara::GetText( sal_Int32 nIndex ) SAL_THROW((uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ return GetTextForwarder().GetText( MakeSelection(nIndex) );
+ }
+
+ String AccessibleEditableTextPara::GetTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) SAL_THROW((uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ return GetTextForwarder().GetText( MakeSelection(nStartIndex, nEndIndex) );
+ }
+
+ USHORT AccessibleEditableTextPara::GetTextLen() const SAL_THROW((uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ return GetTextForwarder().GetTextLen( static_cast< USHORT >( GetParagraphIndex() ) );
+ }
+
+ sal_Bool AccessibleEditableTextPara::IsVisible() const
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ return mpEditSource ? sal_True : sal_False ;
+ }
+
+ uno::Reference< XAccessibleText > AccessibleEditableTextPara::GetParaInterface( sal_Int32 nIndex )
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ uno::Reference< XAccessible > xParent = getAccessibleParent();
+ if( xParent.is() )
+ {
+ uno::Reference< XAccessibleContext > xParentContext = xParent->getAccessibleContext();
+ if( xParentContext.is() )
+ {
+ uno::Reference< XAccessible > xPara = xParentContext->getAccessibleChild( nIndex );
+ if( xPara.is() )
+ return uno::Reference< XAccessibleText > ( xPara, uno::UNO_QUERY );
+ }
+ }
+
+ return uno::Reference< XAccessibleText >();
+ }
+
+ SvxEditSourceAdapter& AccessibleEditableTextPara::GetEditSource() const SAL_THROW((uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ if( mpEditSource )
+ return *mpEditSource;
+ else
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No edit source, object is defunct")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* >
+ ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
+ }
+
+ SvxAccessibleTextAdapter& AccessibleEditableTextPara::GetTextForwarder() const SAL_THROW((uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ SvxEditSourceAdapter& rEditSource = GetEditSource();
+ SvxAccessibleTextAdapter* pTextForwarder = rEditSource.GetTextForwarderAdapter();
+
+ if( !pTextForwarder )
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch text forwarder, object is defunct")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* >
+ ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
+
+ if( pTextForwarder->IsValid() )
+ return *pTextForwarder;
+ else
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Text forwarder is invalid, object is defunct")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* >
+ ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
+ }
+
+ SvxViewForwarder& AccessibleEditableTextPara::GetViewForwarder() const SAL_THROW((uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ SvxEditSource& rEditSource = GetEditSource();
+ SvxViewForwarder* pViewForwarder = rEditSource.GetViewForwarder();
+
+ if( !pViewForwarder )
+ {
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch view forwarder, object is defunct")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* >
+ ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
+ }
+
+ if( pViewForwarder->IsValid() )
+ return *pViewForwarder;
+ else
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object is defunct")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* >
+ ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
+ }
+
+ SvxAccessibleTextEditViewAdapter& AccessibleEditableTextPara::GetEditViewForwarder( sal_Bool bCreate ) const SAL_THROW((uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ SvxEditSourceAdapter& rEditSource = GetEditSource();
+ SvxAccessibleTextEditViewAdapter* pTextEditViewForwarder = rEditSource.GetEditViewForwarderAdapter( bCreate );
+
+ if( !pTextEditViewForwarder )
+ {
+ if( bCreate )
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch view forwarder, object is defunct")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* >
+ ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
+ else
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No view forwarder, object not in edit mode")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* >
+ ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
+ }
+
+ if( pTextEditViewForwarder->IsValid() )
+ return *pTextEditViewForwarder;
+ else
+ {
+ if( bCreate )
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object is defunct")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* >
+ ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
+ else
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object not in edit mode")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* >
+ ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
+ }
+ }
+
+ sal_Bool AccessibleEditableTextPara::HaveEditView() const
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ SvxEditSource& rEditSource = GetEditSource();
+ SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder();
+
+ if( !pViewForwarder )
+ return sal_False;
+
+ if( !pViewForwarder->IsValid() )
+ return sal_False;
+
+ return sal_True;
+ }
+
+ sal_Bool AccessibleEditableTextPara::HaveChildren()
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::HaveChildren: paragraph index value overflow");
+
+ return GetTextForwarder().HaveImageBullet( static_cast< USHORT >(GetParagraphIndex()) );
+ }
+
+ sal_Bool AccessibleEditableTextPara::IsActive() const SAL_THROW((uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ SvxEditSource& rEditSource = GetEditSource();
+ SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder();
+
+ if( !pViewForwarder )
+ return sal_False;
+
+ if( pViewForwarder->IsValid() )
+ return sal_False;
+ else
+ return sal_True;
+ }
+
+ Rectangle AccessibleEditableTextPara::LogicToPixel( const Rectangle& rRect, const MapMode& rMapMode, SvxViewForwarder& rForwarder )
+ {
+ // convert to screen coordinates
+ return Rectangle( rForwarder.LogicToPixel( rRect.TopLeft(), rMapMode ),
+ rForwarder.LogicToPixel( rRect.BottomRight(), rMapMode ) );
+ }
+
+ const Point& AccessibleEditableTextPara::GetEEOffset() const
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ return maEEOffset;
+ }
+
+ void AccessibleEditableTextPara::SetEEOffset( const Point& rOffset )
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ WeakBullet::HardRefType aChild( maImageBullet.get() );
+ if( aChild.is() )
+ aChild->SetEEOffset(rOffset);
+
+ maEEOffset = rOffset;
+ }
+
+ void AccessibleEditableTextPara::FireEvent(const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue) const
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ uno::Reference < XAccessibleContext > xThis( const_cast< AccessibleEditableTextPara* > (this)->getAccessibleContext() );
+
+ AccessibleEventObject aEvent(xThis, nEventId, rNewValue, rOldValue);
+
+ // #102261# Call global queue for focus events
+ if( nEventId == AccessibleEventId::STATE_CHANGED )
+ vcl::unohelper::NotifyAccessibleStateEventGlobally( aEvent );
+
+ // #106234# Delegate to EventNotifier
+ if( getNotifierClientId() != -1 )
+ ::comphelper::AccessibleEventNotifier::addEvent( getNotifierClientId(),
+ aEvent );
+ }
+
+ void AccessibleEditableTextPara::GotPropertyEvent( const uno::Any& rNewValue, const sal_Int16 nEventId ) const
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ FireEvent( nEventId, rNewValue );
+ }
+
+ void AccessibleEditableTextPara::LostPropertyEvent( const uno::Any& rOldValue, const sal_Int16 nEventId ) const
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ FireEvent( nEventId, uno::Any(), rOldValue );
+ }
+
+ bool AccessibleEditableTextPara::HasState( const sal_Int16 nStateId )
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
+ if( pStateSet != NULL )
+ return pStateSet->contains(nStateId) ? true : false;
+
+ return false;
+ }
+
+ void AccessibleEditableTextPara::SetState( const sal_Int16 nStateId )
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
+ if( pStateSet != NULL &&
+ !pStateSet->contains(nStateId) )
+ {
+ pStateSet->AddState( nStateId );
+ GotPropertyEvent( uno::makeAny( nStateId ), AccessibleEventId::STATE_CHANGED );
+ }
+ }
+
+ void AccessibleEditableTextPara::UnSetState( const sal_Int16 nStateId )
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
+ if( pStateSet != NULL &&
+ pStateSet->contains(nStateId) )
+ {
+ pStateSet->RemoveState( nStateId );
+ LostPropertyEvent( uno::makeAny( nStateId ), AccessibleEventId::STATE_CHANGED );
+ }
+ }
+
+ void AccessibleEditableTextPara::TextChanged()
+ {
+ ::rtl::OUString aCurrentString( OCommonAccessibleText::getText() );
+ uno::Any aDeleted;
+ uno::Any aInserted;
+ if( OCommonAccessibleText::implInitTextChangedEvent( maLastTextString, aCurrentString,
+ aDeleted, aInserted) )
+ {
+ FireEvent( AccessibleEventId::TEXT_CHANGED, aInserted, aDeleted );
+ maLastTextString = aCurrentString;
+ }
+ }
+
+ sal_Bool AccessibleEditableTextPara::GetAttributeRun( USHORT& nStartIndex, USHORT& nEndIndex, sal_Int32 nIndex )
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ DBG_ASSERT(nIndex >= 0 && nIndex <= USHRT_MAX,
+ "AccessibleEditableTextPara::GetAttributeRun: index value overflow");
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::getLocale: paragraph index value overflow");
+
+ return GetTextForwarder().GetAttributeRun( nStartIndex,
+ nEndIndex,
+ static_cast< USHORT >(GetParagraphIndex()),
+ static_cast< USHORT >(nIndex) );
+ }
+
+ uno::Any SAL_CALL AccessibleEditableTextPara::queryInterface (const uno::Type & rType) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ uno::Any aRet;
+
+ // must provide XAccesibleText by hand, since it comes publicly inherited by XAccessibleEditableText
+ if ( rType == ::getCppuType((uno::Reference< XAccessibleText > *)0) )
+ {
+ uno::Reference< XAccessibleText > aAccText = static_cast< XAccessibleEditableText * >(this);
+ aRet <<= aAccText;
+ }
+ else if ( rType == ::getCppuType((uno::Reference< XAccessibleEditableText > *)0) )
+ {
+ uno::Reference< XAccessibleEditableText > aAccEditText = this;
+ aRet <<= aAccEditText;
+ }
+ else
+ {
+ aRet = AccessibleTextParaInterfaceBase::queryInterface(rType);
+ }
+
+ return aRet;
+ }
+
+ // XAccessible
+ uno::Reference< XAccessibleContext > SAL_CALL AccessibleEditableTextPara::getAccessibleContext() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ // We implement the XAccessibleContext interface in the same object
+ return uno::Reference< XAccessibleContext > ( this );
+ }
+
+ // XAccessibleContext
+ sal_Int32 SAL_CALL AccessibleEditableTextPara::getAccessibleChildCount() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ return HaveChildren() ? 1 : 0;
+ }
+
+ uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleChild( sal_Int32 i ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if( !HaveChildren() )
+ throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No childs available")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* > (this) ) ); // static_cast: disambiguate hierarchy
+
+ if( i != 0 )
+ throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid child index")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* > (this) ) ); // static_cast: disambiguate hierarchy
+
+ WeakBullet::HardRefType aChild( maImageBullet.get() );
+
+ if( !aChild.is() )
+ {
+ // there is no hard reference available, create object then
+ AccessibleImageBullet* pChild = new AccessibleImageBullet( uno::Reference< XAccessible >( this ) );
+ uno::Reference< XAccessible > xChild( static_cast< ::cppu::OWeakObject* > (pChild), uno::UNO_QUERY );
+
+ if( !xChild.is() )
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Child creation failed")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* > (this) ) );
+
+ aChild = WeakBullet::HardRefType( xChild, pChild );
+
+ aChild->SetEditSource( &GetEditSource() );
+ aChild->SetParagraphIndex( GetParagraphIndex() );
+ aChild->SetIndexInParent( i );
+
+ maImageBullet = aChild;
+ }
+
+ return aChild.getRef();
+ }
+
+ uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleParent() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+#ifdef DBG_UTIL
+ if( !mxParent.is() )
+ DBG_TRACE( "AccessibleEditableTextPara::getAccessibleParent: no frontend set, did somebody forgot to call AccessibleTextHelper::SetEventSource()?");
+#endif
+
+ return mxParent;
+ }
+
+ sal_Int32 SAL_CALL AccessibleEditableTextPara::getAccessibleIndexInParent() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ return mnIndexInParent;
+ }
+
+ sal_Int16 SAL_CALL AccessibleEditableTextPara::getAccessibleRole() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ return AccessibleRole::PARAGRAPH;
+ }
+
+ ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getAccessibleDescription() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+// ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ return ::rtl::OUString();
+ }
+
+ ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getAccessibleName() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+// ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ return ::rtl::OUString();
+ }
+
+ uno::Reference< XAccessibleRelationSet > SAL_CALL AccessibleEditableTextPara::getAccessibleRelationSet() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ // --> OD 2006-01-11 #i27138# - provide relations CONTENT_FLOWS_FROM
+ // and CONTENT_FLOWS_TO
+ if ( mpParaManager )
+ {
+ utl::AccessibleRelationSetHelper* pAccRelSetHelper =
+ new utl::AccessibleRelationSetHelper();
+ sal_Int32 nMyParaIndex( GetParagraphIndex() );
+ // relation CONTENT_FLOWS_FROM
+ if ( nMyParaIndex > 0 &&
+ mpParaManager->IsReferencable( nMyParaIndex - 1 ) )
+ {
+ uno::Sequence<uno::Reference<XInterface> > aSequence(1);
+ aSequence[0] =
+ mpParaManager->GetChild( nMyParaIndex - 1 ).first.get().getRef();
+ AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_FROM,
+ aSequence );
+ pAccRelSetHelper->AddRelation( aAccRel );
+ }
+
+ // relation CONTENT_FLOWS_TO
+ if ( (nMyParaIndex + 1) < (sal_Int32)mpParaManager->GetNum() &&
+ mpParaManager->IsReferencable( nMyParaIndex + 1 ) )
+ {
+ uno::Sequence<uno::Reference<XInterface> > aSequence(1);
+ aSequence[0] =
+ mpParaManager->GetChild( nMyParaIndex + 1 ).first.get().getRef();
+ AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_TO,
+ aSequence );
+ pAccRelSetHelper->AddRelation( aAccRel );
+ }
+
+ return pAccRelSetHelper;
+ }
+ else
+ {
+ // no relations, therefore empty
+ return uno::Reference< XAccessibleRelationSet >();
+ }
+ // <--
+ }
+
+ uno::Reference< XAccessibleStateSet > SAL_CALL AccessibleEditableTextPara::getAccessibleStateSet() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ // Create a copy of the state set and return it.
+ ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
+
+ if( !pStateSet )
+ return uno::Reference<XAccessibleStateSet>();
+
+ return uno::Reference<XAccessibleStateSet>( new ::utl::AccessibleStateSetHelper (*pStateSet) );
+ }
+
+ lang::Locale SAL_CALL AccessibleEditableTextPara::getLocale() throw (IllegalAccessibleComponentStateException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ return implGetLocale();
+ }
+
+ void SAL_CALL AccessibleEditableTextPara::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ if( getNotifierClientId() != -1 )
+ ::comphelper::AccessibleEventNotifier::addEventListener( getNotifierClientId(), xListener );
+ }
+
+ void SAL_CALL AccessibleEditableTextPara::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ if( getNotifierClientId() != -1 )
+ ::comphelper::AccessibleEventNotifier::removeEventListener( getNotifierClientId(), xListener );
+ }
+
+ // XAccessibleComponent
+ sal_Bool SAL_CALL AccessibleEditableTextPara::containsPoint( const awt::Point& aTmpPoint ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::contains: index value overflow");
+
+ awt::Rectangle aTmpRect = getBounds();
+ Rectangle aRect( Point(aTmpRect.X, aTmpRect.Y), Size(aTmpRect.Width, aTmpRect.Height) );
+ Point aPoint( aTmpPoint.X, aTmpPoint.Y );
+
+ return aRect.IsInside( aPoint );
+ }
+
+ uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleAtPoint( const awt::Point& _aPoint ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if( HaveChildren() )
+ {
+ // #103862# No longer need to make given position relative
+ Point aPoint( _aPoint.X, _aPoint.Y );
+
+ // respect EditEngine offset to surrounding shape/cell
+ aPoint -= GetEEOffset();
+
+ // convert to EditEngine coordinate system
+ SvxTextForwarder& rCacheTF = GetTextForwarder();
+ Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) );
+
+ EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< USHORT > (GetParagraphIndex()) );
+
+ if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
+ aBulletInfo.bVisible &&
+ aBulletInfo.nType == SVX_NUM_BITMAP )
+ {
+ Rectangle aRect = aBulletInfo.aBounds;
+
+ if( aRect.IsInside( aLogPoint ) )
+ return getAccessibleChild(0);
+ }
+ }
+
+ // no children at all, or none at given position
+ return uno::Reference< XAccessible >();
+ }
+
+ awt::Rectangle SAL_CALL AccessibleEditableTextPara::getBounds() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::getBounds: index value overflow");
+
+ SvxTextForwarder& rCacheTF = GetTextForwarder();
+ Rectangle aRect = rCacheTF.GetParaBounds( static_cast< USHORT >( GetParagraphIndex() ) );
+
+ // convert to screen coordinates
+ Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect,
+ rCacheTF.GetMapMode(),
+ GetViewForwarder() );
+
+ // offset from shape/cell
+ Point aOffset = GetEEOffset();
+
+ return awt::Rectangle( aScreenRect.Left() + aOffset.X(),
+ aScreenRect.Top() + aOffset.Y(),
+ aScreenRect.GetSize().Width(),
+ aScreenRect.GetSize().Height() );
+ }
+
+ awt::Point SAL_CALL AccessibleEditableTextPara::getLocation( ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ awt::Rectangle aRect = getBounds();
+
+ return awt::Point( aRect.X, aRect.Y );
+ }
+
+ awt::Point SAL_CALL AccessibleEditableTextPara::getLocationOnScreen( ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ // relate us to parent
+ uno::Reference< XAccessible > xParent = getAccessibleParent();
+ if( xParent.is() )
+ {
+ uno::Reference< XAccessibleComponent > xParentComponent( xParent, uno::UNO_QUERY );
+ if( xParentComponent.is() )
+ {
+ awt::Point aRefPoint = xParentComponent->getLocationOnScreen();
+ awt::Point aPoint = getLocation();
+ aPoint.X += aRefPoint.X;
+ aPoint.Y += aRefPoint.Y;
+
+ return aPoint;
+ }
+ }
+
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot access parent")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
+ }
+
+ awt::Size SAL_CALL AccessibleEditableTextPara::getSize( ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ awt::Rectangle aRect = getBounds();
+
+ return awt::Size( aRect.Width, aRect.Height );
+ }
+
+ void SAL_CALL AccessibleEditableTextPara::grabFocus( ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ // set cursor to this paragraph
+ setSelection(0,0);
+ }
+
+ sal_Int32 SAL_CALL AccessibleEditableTextPara::getForeground( ) throw (::com::sun::star::uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ // #104444# Added to XAccessibleComponent interface
+ svtools::ColorConfig aColorConfig;
+ UINT32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor;
+ return static_cast<sal_Int32>(nColor);
+ }
+
+ sal_Int32 SAL_CALL AccessibleEditableTextPara::getBackground( ) throw (::com::sun::star::uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ // #104444# Added to XAccessibleComponent interface
+ Color aColor( Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor() );
+
+ // the background is transparent
+ aColor.SetTransparency( 0xFF);
+
+ return static_cast<sal_Int32>( aColor.GetColor() );
+ }
+
+ // XAccessibleText
+ sal_Int32 SAL_CALL AccessibleEditableTextPara::getCaretPosition() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if( !HaveEditView() )
+ return -1;
+
+ ESelection aSelection;
+ if( GetEditViewForwarder().GetSelection( aSelection ) &&
+ GetParagraphIndex() == aSelection.nEndPara )
+ {
+ // caret is always nEndPara,nEndPos
+ return aSelection.nEndPos;
+ }
+
+ // not within this paragraph
+ return -1;
+ }
+
+ sal_Bool SAL_CALL AccessibleEditableTextPara::setCaretPosition( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ return setSelection(nIndex, nIndex);
+ }
+
+ sal_Unicode SAL_CALL AccessibleEditableTextPara::getCharacter( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::getCharacter: index value overflow");
+
+ return OCommonAccessibleText::getCharacter( nIndex );
+ }
+
+ uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rRequestedAttributes ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ CheckIndex(nIndex); // may throw IndexOutOfBoundsException
+
+ // get default attribues...
+ ::comphelper::SequenceAsHashMap aPropHashMap( getDefaultAttributes( rRequestedAttributes ) );
+
+ // ... and override them with the direct attributes from the specific position
+ uno::Sequence< beans::PropertyValue > aRunAttribs( getRunAttributes( nIndex, rRequestedAttributes ) );
+ sal_Int32 nRunAttribs = aRunAttribs.getLength();
+ const beans::PropertyValue *pRunAttrib = aRunAttribs.getConstArray();
+ for (sal_Int32 k = 0; k < nRunAttribs; ++k)
+ {
+ const beans::PropertyValue &rRunAttrib = pRunAttrib[k];
+ aPropHashMap[ rRunAttrib.Name ] = rRunAttrib.Value; //!! should not only be the value !!
+ }
+#ifdef TL_DEBUG
+ {
+ uno::Sequence< rtl::OUString > aNames(1);
+ aNames.getArray()[0] = rtl::OUString::createFromAscii("CharHeight");
+ const rtl::OUString *pNames = aNames.getConstArray();
+ const uno::Sequence< beans::PropertyValue > aAttribs( getRunAttributes( nIndex, aNames ) );
+ const beans::PropertyValue *pAttribs = aAttribs.getConstArray();
+ double d1 = -1.0;
+ float f1 = -1.0;
+ if (aAttribs.getLength())
+ {
+ uno::Any aAny( pAttribs[0].Value );
+ aAny >>= d1;
+ aAny >>= f1;
+ }
+ int i = 3;
+ }
+#endif
+
+ // get resulting sequence
+ uno::Sequence< beans::PropertyValue > aRes;
+ aPropHashMap >> aRes;
+
+ // since SequenceAsHashMap ignores property handles and property state
+ // we have to restore the property state here (property handles are
+ // of no use to the accessibility API).
+ sal_Int32 nRes = aRes.getLength();
+ beans::PropertyValue *pRes = aRes.getArray();
+ for (sal_Int32 i = 0; i < nRes; ++i)
+ {
+ beans::PropertyValue &rRes = pRes[i];
+ sal_Bool bIsDirectVal = sal_False;
+ for (sal_Int32 k = 0; k < nRunAttribs && !bIsDirectVal; ++k)
+ {
+ if (rRes.Name == pRunAttrib[k].Name)
+ bIsDirectVal = sal_True;
+ }
+ rRes.Handle = -1;
+ rRes.State = bIsDirectVal ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
+ }
+
+ return aRes;
+ }
+
+ awt::Rectangle SAL_CALL AccessibleEditableTextPara::getCharacterBounds( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::getCharacterBounds: index value overflow");
+
+ // #108900# Have position semantics now for nIndex, as
+ // one-past-the-end values are legal, too.
+ CheckPosition( nIndex );
+
+ SvxTextForwarder& rCacheTF = GetTextForwarder();
+ Rectangle aRect = rCacheTF.GetCharBounds( static_cast< USHORT >( GetParagraphIndex() ), static_cast< USHORT >( nIndex ) );
+
+ // convert to screen
+ Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect,
+ rCacheTF.GetMapMode(),
+ GetViewForwarder() );
+ // #109864# offset from parent (paragraph), but in screen
+ // coordinates. This makes sure the internal text offset in
+ // the outline view forwarder gets cancelled out here
+ awt::Rectangle aParaRect( getBounds() );
+ aScreenRect.Move( -aParaRect.X, -aParaRect.Y );
+
+ // offset from shape/cell
+ Point aOffset = GetEEOffset();
+
+ return awt::Rectangle( aScreenRect.Left() + aOffset.X(),
+ aScreenRect.Top() + aOffset.Y(),
+ aScreenRect.GetSize().Width(),
+ aScreenRect.GetSize().Height() );
+ }
+
+ sal_Int32 SAL_CALL AccessibleEditableTextPara::getCharacterCount() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::getCharacterCount: index value overflow");
+
+ return OCommonAccessibleText::getCharacterCount();
+ }
+
+ sal_Int32 SAL_CALL AccessibleEditableTextPara::getIndexAtPoint( const awt::Point& rPoint ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ USHORT nPara, nIndex;
+
+ // offset from surrounding cell/shape
+ Point aOffset( GetEEOffset() );
+ Point aPoint( rPoint.X - aOffset.X(), rPoint.Y - aOffset.Y() );
+
+ // convert to logical coordinates
+ SvxTextForwarder& rCacheTF = GetTextForwarder();
+ Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) );
+
+ // re-offset to parent (paragraph)
+ Rectangle aParaRect = rCacheTF.GetParaBounds( static_cast< USHORT >( GetParagraphIndex() ) );
+ aLogPoint.Move( aParaRect.Left(), aParaRect.Top() );
+
+ if( rCacheTF.GetIndexAtPoint( aLogPoint, nPara, nIndex ) &&
+ GetParagraphIndex() == nPara )
+ {
+ // #102259# Double-check if we're _really_ on the given character
+ try
+ {
+ awt::Rectangle aRect1( getCharacterBounds(nIndex) );
+ Rectangle aRect2( aRect1.X, aRect1.Y,
+ aRect1.Width + aRect1.X, aRect1.Height + aRect1.Y );
+ if( aRect2.IsInside( Point( rPoint.X, rPoint.Y ) ) )
+ return nIndex;
+ else
+ return -1;
+ }
+ catch( const lang::IndexOutOfBoundsException& )
+ {
+ // #103927# Don't throw for invalid nIndex values
+ return -1;
+ }
+ }
+ else
+ {
+ // not within our paragraph
+ return -1;
+ }
+ }
+
+ ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getSelectedText() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::getSelectedText: index value overflow");
+
+ if( !HaveEditView() )
+ return ::rtl::OUString();
+
+ return OCommonAccessibleText::getSelectedText();
+ }
+
+ sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionStart() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::getSelectionStart: index value overflow");
+
+ if( !HaveEditView() )
+ return -1;
+
+ return OCommonAccessibleText::getSelectionStart();
+ }
+
+ sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionEnd() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::getSelectionEnd: index value overflow");
+
+ if( !HaveEditView() )
+ return -1;
+
+ return OCommonAccessibleText::getSelectionEnd();
+ }
+
+ sal_Bool SAL_CALL AccessibleEditableTextPara::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::setSelection: paragraph index value overflow");
+
+ CheckRange(nStartIndex, nEndIndex);
+
+ try
+ {
+ SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
+ return rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
+ }
+ catch( const uno::RuntimeException& )
+ {
+ return sal_False;
+ }
+ }
+
+ ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getText() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::getText: paragraph index value overflow");
+
+ return OCommonAccessibleText::getText();
+ }
+
+ ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::getTextRange: paragraph index value overflow");
+
+ return OCommonAccessibleText::getTextRange(nStartIndex, nEndIndex);
+ }
+
+ ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::getTextAtIndex: paragraph index value overflow");
+
+ ::com::sun::star::accessibility::TextSegment aResult;
+ aResult.SegmentStart = -1;
+ aResult.SegmentEnd = -1;
+
+ switch( aTextType )
+ {
+ // Not yet handled by OCommonAccessibleText. Missing
+ // implGetAttributeRunBoundary() method there
+ case AccessibleTextType::ATTRIBUTE_RUN:
+ {
+ const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( static_cast< USHORT >( GetParagraphIndex() ) );
+
+ if( nIndex == nTextLen )
+ {
+ // #i17014# Special-casing one-behind-the-end character
+ aResult.SegmentStart = aResult.SegmentEnd = nTextLen;
+ }
+ else
+ {
+ USHORT nStartIndex, nEndIndex;
+
+ if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
+ {
+ aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
+ aResult.SegmentStart = nStartIndex;
+ aResult.SegmentEnd = nEndIndex;
+ }
+ }
+ break;
+ }
+
+ default:
+ aResult = OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
+ break;
+ } /* end of switch( aTextType ) */
+
+ return aResult;
+ }
+
+ ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::getTextBeforeIndex: paragraph index value overflow");
+
+ ::com::sun::star::accessibility::TextSegment aResult;
+ aResult.SegmentStart = -1;
+ aResult.SegmentEnd = -1;
+
+ switch( aTextType )
+ {
+ // Not yet handled by OCommonAccessibleText. Missing
+ // implGetAttributeRunBoundary() method there
+ case AccessibleTextType::ATTRIBUTE_RUN:
+ {
+ const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( static_cast< USHORT >( GetParagraphIndex() ) );
+ USHORT nStartIndex, nEndIndex;
+
+ if( nIndex == nTextLen )
+ {
+ // #i17014# Special-casing one-behind-the-end character
+ if( nIndex > 0 &&
+ GetAttributeRun(nStartIndex, nEndIndex, nIndex-1) )
+ {
+ aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
+ aResult.SegmentStart = nStartIndex;
+ aResult.SegmentEnd = nEndIndex;
+ }
+ }
+ else
+ {
+ if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
+ {
+ // already at the left border? If not, query
+ // one index further left
+ if( nStartIndex > 0 &&
+ GetAttributeRun(nStartIndex, nEndIndex, nStartIndex-1) )
+ {
+ aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
+ aResult.SegmentStart = nStartIndex;
+ aResult.SegmentEnd = nEndIndex;
+ }
+ }
+ }
+ break;
+ }
+
+ default:
+ aResult = OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
+ break;
+ } /* end of switch( aTextType ) */
+
+ return aResult;
+ }
+
+ ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::getTextBehindIndex: paragraph index value overflow");
+
+ ::com::sun::star::accessibility::TextSegment aResult;
+ aResult.SegmentStart = -1;
+ aResult.SegmentEnd = -1;
+
+ switch( aTextType )
+ {
+ case AccessibleTextType::ATTRIBUTE_RUN:
+ {
+ USHORT nStartIndex, nEndIndex;
+
+ if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
+ {
+ // already at the right border?
+ if( nEndIndex < GetTextLen() )
+ {
+ if( GetAttributeRun(nStartIndex, nEndIndex, nEndIndex) )
+ {
+ aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
+ aResult.SegmentStart = nStartIndex;
+ aResult.SegmentEnd = nEndIndex;
+ }
+ }
+ }
+ break;
+ }
+
+ default:
+ aResult = OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
+ break;
+ } /* end of switch( aTextType ) */
+
+ return aResult;
+ }
+
+ sal_Bool SAL_CALL AccessibleEditableTextPara::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ try
+ {
+ SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
+ #if OSL_DEBUG_LEVEL > 0
+ SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
+ (void)rCacheTF;
+ #else
+ GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
+ #endif
+
+ sal_Bool aRetVal;
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::copyText: index value overflow");
+
+ CheckRange(nStartIndex, nEndIndex);
+
+ // save current selection
+ ESelection aOldSelection;
+
+ rCacheVF.GetSelection( aOldSelection );
+ rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
+ aRetVal = rCacheVF.Copy();
+ rCacheVF.SetSelection( aOldSelection ); // restore
+
+ return aRetVal;
+ }
+ catch( const uno::RuntimeException& )
+ {
+ return sal_False;
+ }
+ }
+
+ // XAccessibleEditableText
+ sal_Bool SAL_CALL AccessibleEditableTextPara::cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ try
+ {
+ SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
+ SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::cutText: index value overflow");
+
+ CheckRange(nStartIndex, nEndIndex);
+
+ if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
+ return sal_False; // non-editable area selected
+
+ // don't save selection, might become invalid after cut!
+ rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
+
+ return rCacheVF.Cut();
+ }
+ catch( const uno::RuntimeException& )
+ {
+ return sal_False;
+ }
+ }
+
+ sal_Bool SAL_CALL AccessibleEditableTextPara::pasteText( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ try
+ {
+ SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
+ SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::pasteText: index value overflow");
+
+ CheckPosition(nIndex);
+
+ if( !rCacheTF.IsEditable( MakeSelection(nIndex) ) )
+ return sal_False; // non-editable area selected
+
+ // #104400# set empty selection (=> cursor) to given index
+ rCacheVF.SetSelection( MakeCursor(nIndex) );
+
+ return rCacheVF.Paste();
+ }
+ catch( const uno::RuntimeException& )
+ {
+ return sal_False;
+ }
+ }
+
+ sal_Bool SAL_CALL AccessibleEditableTextPara::deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ try
+ {
+ // #102710# Request edit view when doing changes
+ // AccessibleEmptyEditSource relies on this behaviour
+ GetEditViewForwarder( sal_True );
+ SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::deleteText: index value overflow");
+
+ CheckRange(nStartIndex, nEndIndex);
+
+ if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
+ return sal_False; // non-editable area selected
+
+ sal_Bool bRet = rCacheTF.Delete( MakeSelection(nStartIndex, nEndIndex) );
+
+ GetEditSource().UpdateData();
+
+ return bRet;
+ }
+ catch( const uno::RuntimeException& )
+ {
+ return sal_False;
+ }
+ }
+
+ sal_Bool SAL_CALL AccessibleEditableTextPara::insertText( const ::rtl::OUString& sText, sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ try
+ {
+ // #102710# Request edit view when doing changes
+ // AccessibleEmptyEditSource relies on this behaviour
+ GetEditViewForwarder( sal_True );
+ SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::insertText: index value overflow");
+
+ CheckPosition(nIndex);
+
+ if( !rCacheTF.IsEditable( MakeSelection(nIndex) ) )
+ return sal_False; // non-editable area selected
+
+ // #104400# insert given text at empty selection (=> cursor)
+ sal_Bool bRet = rCacheTF.InsertText( sText, MakeCursor(nIndex) );
+
+ rCacheTF.QuickFormatDoc();
+ GetEditSource().UpdateData();
+
+ return bRet;
+ }
+ catch( const uno::RuntimeException& )
+ {
+ return sal_False;
+ }
+ }
+
+ sal_Bool SAL_CALL AccessibleEditableTextPara::replaceText( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const ::rtl::OUString& sReplacement ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ try
+ {
+ // #102710# Request edit view when doing changes
+ // AccessibleEmptyEditSource relies on this behaviour
+ GetEditViewForwarder( sal_True );
+ SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::replaceText: index value overflow");
+
+ CheckRange(nStartIndex, nEndIndex);
+
+ if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
+ return sal_False; // non-editable area selected
+
+ // insert given text into given range => replace
+ sal_Bool bRet = rCacheTF.InsertText( sReplacement, MakeSelection(nStartIndex, nEndIndex) );
+
+ rCacheTF.QuickFormatDoc();
+ GetEditSource().UpdateData();
+
+ return bRet;
+ }
+ catch( const uno::RuntimeException& )
+ {
+ return sal_False;
+ }
+ }
+
+ sal_Bool SAL_CALL AccessibleEditableTextPara::setAttributes( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const uno::Sequence< beans::PropertyValue >& aAttributeSet ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ try
+ {
+ // #102710# Request edit view when doing changes
+ // AccessibleEmptyEditSource relies on this behaviour
+ GetEditViewForwarder( sal_True );
+ SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
+ USHORT nPara = static_cast< USHORT >( GetParagraphIndex() );
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::setAttributes: index value overflow");
+
+ CheckRange(nStartIndex, nEndIndex);
+
+ if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
+ return sal_False; // non-editable area selected
+
+ // do the indices span the whole paragraph? Then use the outliner map
+ // TODO: hold it as a member?
+ SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
+ 0 == nStartIndex &&
+ rCacheTF.GetTextLen(nPara) == nEndIndex ?
+ ImplGetSvxUnoOutlinerTextCursorSvxPropertySet() :
+ ImplGetSvxTextPortionSvxPropertySet() );
+
+ aPropSet.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
+
+ // convert from PropertyValue to Any
+ sal_Int32 i, nLength( aAttributeSet.getLength() );
+ const beans::PropertyValue* pPropArray = aAttributeSet.getConstArray();
+ for(i=0; i<nLength; ++i)
+ {
+ try
+ {
+ aPropSet.setPropertyValue(pPropArray->Name, pPropArray->Value);
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_ERROR("AccessibleEditableTextPara::setAttributes exception in setPropertyValue");
+ }
+
+ ++pPropArray;
+ }
+
+ rCacheTF.QuickFormatDoc();
+ GetEditSource().UpdateData();
+
+ return sal_True;
+ }
+ catch( const uno::RuntimeException& )
+ {
+ return sal_False;
+ }
+ }
+
+ sal_Bool SAL_CALL AccessibleEditableTextPara::setText( const ::rtl::OUString& sText ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ return replaceText(0, getCharacterCount(), sText);
+ }
+
+ // XAccessibleTextAttributes
+ uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getDefaultAttributes(
+ const uno::Sequence< ::rtl::OUString >& rRequestedAttributes )
+ throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ #if OSL_DEBUG_LEVEL > 0
+ SvxAccessibleTextAdapter& rCacheTF =
+ #endif
+ GetTextForwarder();
+
+ #if OSL_DEBUG_LEVEL > 0
+ (void)rCacheTF;
+ #endif
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::getCharacterAttributes: index value overflow");
+
+ // get XPropertySetInfo for paragraph attributes and
+ // character attributes that span all the paragraphs text.
+ SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
+ ImplGetSvxCharAndParaPropertiesSet() );
+ aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) );
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo();
+ if (!xPropSetInfo.is())
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot query XPropertySetInfo")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
+
+ // build sequence of available properties to check
+ sal_Int32 nLenReqAttr = rRequestedAttributes.getLength();
+ uno::Sequence< beans::Property > aProperties;
+ if (nLenReqAttr)
+ {
+ const rtl::OUString *pRequestedAttributes = rRequestedAttributes.getConstArray();
+
+ aProperties.realloc( nLenReqAttr );
+ beans::Property *pProperties = aProperties.getArray();
+ sal_Int32 nCurLen = 0;
+ for (sal_Int32 i = 0; i < nLenReqAttr; ++i)
+ {
+ beans::Property aProp;
+ try
+ {
+ aProp = xPropSetInfo->getPropertyByName( pRequestedAttributes[i] );
+ }
+ catch (beans::UnknownPropertyException &)
+ {
+ continue;
+ }
+ pProperties[ nCurLen++ ] = aProp;
+ }
+ aProperties.realloc( nCurLen );
+ }
+ else
+ aProperties = xPropSetInfo->getProperties();
+
+ sal_Int32 nLength = aProperties.getLength();
+ const beans::Property *pProperties = aProperties.getConstArray();
+
+ // build resulting sequence
+ uno::Sequence< beans::PropertyValue > aOutSequence( nLength );
+ beans::PropertyValue* pOutSequence = aOutSequence.getArray();
+ sal_Int32 nOutLen = 0;
+ for (sal_Int32 i = 0; i < nLength; ++i)
+ {
+ // calling implementation functions:
+ // _getPropertyState and _getPropertyValue (see below) to provide
+ // the proper paragraph number when retrieving paragraph attributes
+ PropertyState eState = aPropSet._getPropertyState( pProperties->Name, mnParagraphIndex );
+ if ( eState == PropertyState_AMBIGUOUS_VALUE )
+ {
+ OSL_ENSURE( false, "ambiguous property value encountered" );
+ }
+
+ //if (eState == PropertyState_DIRECT_VALUE)
+ // per definition all paragraph properties and all character
+ // properties spanning the whole paragraph should be returned
+ // and declared as default value
+ {
+ pOutSequence->Name = pProperties->Name;
+ pOutSequence->Handle = pProperties->Handle;
+ pOutSequence->Value = aPropSet._getPropertyValue( pProperties->Name, mnParagraphIndex );
+ pOutSequence->State = PropertyState_DEFAULT_VALUE;
+
+ ++pOutSequence;
+ ++nOutLen;
+ }
+ ++pProperties;
+ }
+ aOutSequence.realloc( nOutLen );
+
+ return aOutSequence;
+ }
+
+
+ uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getRunAttributes(
+ sal_Int32 nIndex,
+ const uno::Sequence< ::rtl::OUString >& rRequestedAttributes )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ #if OSL_DEBUG_LEVEL > 0
+ SvxAccessibleTextAdapter& rCacheTF =
+ #endif
+ GetTextForwarder();
+
+ #if OSL_DEBUG_LEVEL > 0
+ (void)rCacheTF;
+ #endif
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::getCharacterAttributes: index value overflow");
+
+ CheckIndex(nIndex);
+
+ SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
+ ImplGetSvxCharAndParaPropertiesSet() );
+ aPropSet.SetSelection( MakeSelection( nIndex ) );
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo();
+ if (!xPropSetInfo.is())
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot query XPropertySetInfo")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
+
+ // build sequence of available properties to check
+ sal_Int32 nLenReqAttr = rRequestedAttributes.getLength();
+ uno::Sequence< beans::Property > aProperties;
+ if (nLenReqAttr)
+ {
+ const rtl::OUString *pRequestedAttributes = rRequestedAttributes.getConstArray();
+
+ aProperties.realloc( nLenReqAttr );
+ beans::Property *pProperties = aProperties.getArray();
+ sal_Int32 nCurLen = 0;
+ for (sal_Int32 i = 0; i < nLenReqAttr; ++i)
+ {
+ beans::Property aProp;
+ try
+ {
+ aProp = xPropSetInfo->getPropertyByName( pRequestedAttributes[i] );
+ }
+ catch (beans::UnknownPropertyException &)
+ {
+ continue;
+ }
+ pProperties[ nCurLen++ ] = aProp;
+ }
+ aProperties.realloc( nCurLen );
+ }
+ else
+ aProperties = xPropSetInfo->getProperties();
+
+ sal_Int32 nLength = aProperties.getLength();
+ const beans::Property *pProperties = aProperties.getConstArray();
+
+ // build resulting sequence
+ uno::Sequence< beans::PropertyValue > aOutSequence( nLength );
+ beans::PropertyValue* pOutSequence = aOutSequence.getArray();
+ sal_Int32 nOutLen = 0;
+ for (sal_Int32 i = 0; i < nLength; ++i)
+ {
+ // calling 'regular' functions that will operate on the selection
+ PropertyState eState = aPropSet.getPropertyState( pProperties->Name );
+ if (eState == PropertyState_DIRECT_VALUE)
+ {
+ pOutSequence->Name = pProperties->Name;
+ pOutSequence->Handle = pProperties->Handle;
+ pOutSequence->Value = aPropSet.getPropertyValue( pProperties->Name );
+ pOutSequence->State = eState;
+
+ ++pOutSequence;
+ ++nOutLen;
+ }
+ ++pProperties;
+ }
+ aOutSequence.realloc( nOutLen );
+
+ return aOutSequence;
+ }
+
+ // XAccessibleMultiLineText
+ sal_Int32 SAL_CALL AccessibleEditableTextPara::getLineNumberAtIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ sal_Int32 nRes = -1;
+ sal_Int32 nPara = GetParagraphIndex();
+
+ SvxTextForwarder &rCacheTF = GetTextForwarder();
+ const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount();
+ DBG_ASSERT( bValidPara, "getLineNumberAtIndex: current paragraph index out of range" );
+ if (bValidPara)
+ {
+ // we explicitly allow for the index to point at the character right behind the text
+ if (0 <= nIndex && nIndex <= rCacheTF.GetTextLen( static_cast< USHORT >(nPara) ))
+ nRes = rCacheTF.GetLineNumberAtIndex( static_cast< USHORT >(nPara), static_cast< USHORT >(nIndex) );
+ else
+ throw lang::IndexOutOfBoundsException();
+ }
+ return nRes;
+ }
+
+ // XAccessibleMultiLineText
+ ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineNumber( sal_Int32 nLineNo ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::com::sun::star::accessibility::TextSegment aResult;
+ sal_Int32 nPara = GetParagraphIndex();
+ SvxTextForwarder &rCacheTF = GetTextForwarder();
+ const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount();
+ DBG_ASSERT( bValidPara, "getTextAtLineNumber: current paragraph index out of range" );
+ if (bValidPara)
+ {
+ if (0 <= nLineNo && nLineNo < rCacheTF.GetLineCount( static_cast< USHORT >(nPara) ))
+ {
+ USHORT nStart = 0, nEnd = 0;
+ rCacheTF.GetLineBoundaries( nStart, nEnd, static_cast< USHORT >(nPara), static_cast< USHORT >(nLineNo) );
+ if (nStart != 0xFFFF && nEnd != 0xFFFF)
+ {
+ try
+ {
+ aResult.SegmentText = getTextRange( nStart, nEnd );
+ aResult.SegmentStart = nStart;
+ aResult.SegmentEnd = nEnd;
+ }
+ catch (lang::IndexOutOfBoundsException)
+ {
+ // this is not the exception that should be raised in this function ...
+ DBG_ASSERT( 0, "unexpected exception" );
+ }
+ }
+ }
+ else
+ throw lang::IndexOutOfBoundsException();
+ }
+ return aResult;
+ }
+
+ // XAccessibleMultiLineText
+ ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineWithCaret( ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ ::com::sun::star::accessibility::TextSegment aResult;
+ try
+ {
+ aResult = getTextAtLineNumber( getNumberOfLineWithCaret() );
+ }
+ catch (lang::IndexOutOfBoundsException &)
+ {
+ // this one needs to be catched since this interface does not allow for it.
+ }
+ return aResult;
+ }
+
+ // XAccessibleMultiLineText
+ sal_Int32 SAL_CALL AccessibleEditableTextPara::getNumberOfLineWithCaret( ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ sal_Int32 nRes = -1;
+ try
+ {
+ nRes = getLineNumberAtIndex( getCaretPosition() );
+ }
+ catch (lang::IndexOutOfBoundsException &)
+ {
+ // this one needs to be catched since this interface does not allow for it.
+ }
+ return nRes;
+ }
+
+
+ // XServiceInfo
+ ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getImplementationName (void) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("AccessibleEditableTextPara"));
+ }
+
+ sal_Bool SAL_CALL AccessibleEditableTextPara::supportsService (const ::rtl::OUString& sServiceName) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ // Iterate over all supported service names and return true if on of them
+ // matches the given name.
+ uno::Sequence< ::rtl::OUString> aSupportedServices (
+ getSupportedServiceNames ());
+ for (int i=0; i<aSupportedServices.getLength(); i++)
+ if (sServiceName == aSupportedServices[i])
+ return sal_True;
+ return sal_False;
+ }
+
+ uno::Sequence< ::rtl::OUString> SAL_CALL AccessibleEditableTextPara::getSupportedServiceNames (void) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ const ::rtl::OUString sServiceName( getServiceName() );
+ return uno::Sequence< ::rtl::OUString > (&sServiceName, 1);
+ }
+
+ // XServiceName
+ ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getServiceName (void) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
+
+ // #105185# Using correct service now
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.AccessibleParagraphView"));
+ }
+
+} // end of namespace accessibility
+
+//------------------------------------------------------------------------
diff --git a/editeng/source/accessibility/AccessibleEditableTextPara.hxx b/editeng/source/accessibility/AccessibleEditableTextPara.hxx
new file mode 100644
index 0000000000..f78cbd4ad4
--- /dev/null
+++ b/editeng/source/accessibility/AccessibleEditableTextPara.hxx
@@ -0,0 +1,414 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleEditableTextPara.hxx,v $
+ * $Revision: 1.22 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVX_ACCESSIBLE_EDITABLE_TEXT_PARA_HXX
+#define _SVX_ACCESSIBLE_EDITABLE_TEXT_PARA_HXX
+
+#include <tools/gen.hxx>
+#include <tools/string.hxx>
+#include <cppuhelper/weakref.hxx>
+#include <cppuhelper/compbase8.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
+#include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
+#include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp>
+#include <com/sun/star/accessibility/XAccessibleMultiLineText.hpp>
+
+#include <comphelper/accessibletexthelper.hxx>
+#include <comphelper/broadcasthelper.hxx>
+#include "AccessibleParaManager.hxx"
+#include "AccessibleImageBullet.hxx"
+#include "unoedprx.hxx"
+
+namespace accessibility
+{
+ typedef ::cppu::WeakComponentImplHelper8< ::com::sun::star::accessibility::XAccessible,
+ ::com::sun::star::accessibility::XAccessibleContext,
+ ::com::sun::star::accessibility::XAccessibleComponent,
+ ::com::sun::star::accessibility::XAccessibleEditableText,
+ ::com::sun::star::accessibility::XAccessibleEventBroadcaster,
+ ::com::sun::star::accessibility::XAccessibleTextAttributes,
+ ::com::sun::star::accessibility::XAccessibleMultiLineText,
+ ::com::sun::star::lang::XServiceInfo > AccessibleTextParaInterfaceBase;
+
+ /** This class implements the actual text paragraphs for the EditEngine/Outliner UAA
+ */
+ class AccessibleEditableTextPara : public ::comphelper::OBaseMutex, public AccessibleTextParaInterfaceBase, public ::comphelper::OCommonAccessibleText
+ {
+
+ protected:
+ // override OCommonAccessibleText methods
+ virtual ::rtl::OUString implGetText();
+ virtual ::com::sun::star::lang::Locale implGetLocale();
+ virtual void implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex );
+ virtual void implGetParagraphBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 nIndex );
+ virtual void implGetLineBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 nIndex );
+
+ public:
+ /// Create accessible object for given parent
+ // --> OD 2006-01-11 #i27138#
+ // - add parameter <_pParaManager> (default value NULL)
+ // This has to be the the instance of <AccessibleParaManager>, which
+ // created and manages this accessible paragraph.
+ AccessibleEditableTextPara ( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& rParent,
+ const AccessibleParaManager* _pParaManager = NULL );
+ // <--
+
+ virtual ~AccessibleEditableTextPara ();
+
+ // XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface (const ::com::sun::star::uno::Type & rType) throw (::com::sun::star::uno::RuntimeException);
+
+ // XComponent
+
+ using WeakComponentImplHelperBase::addEventListener;
+ using WeakComponentImplHelperBase::removeEventListener;
+
+ // XAccessible
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleContext
+ virtual sal_Int32 SAL_CALL getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent() throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleIndexInParent() throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int16 SAL_CALL getAccessibleRole() throw (::com::sun::star::uno::RuntimeException);
+ /// Maximal length of text returned by getAccessibleDescription()
+ enum { MaxDescriptionLen = 40 };
+ virtual ::rtl::OUString SAL_CALL getAccessibleDescription() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleName() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::lang::Locale SAL_CALL getLocale() throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleEventBroadcaster
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleComponent
+ virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Point SAL_CALL getLocation( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Size SAL_CALL getSize( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL grabFocus( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getForeground( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getBackground( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleText (this comes implicitely inherited by XAccessibleEditableText AND by XAccessibleMultiLineText)
+ virtual sal_Int32 SAL_CALL getCaretPosition() throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL setCaretPosition( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aRequestedAttributes ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Rectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getCharacterCount() throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getIndexAtPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getSelectedText() throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getSelectionStart() throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getSelectionEnd() throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getText() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ /// Does not support AccessibleTextType::SENTENCE (missing feature in EditEngine)
+ virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ /// Does not support AccessibleTextType::SENTENCE (missing feature in EditEngine)
+ virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ /// Does not support AccessibleTextType::SENTENCE (missing feature in EditEngine)
+ virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleEditableText
+ virtual sal_Bool SAL_CALL cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL pasteText( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL insertText( const ::rtl::OUString& sText, sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL replaceText( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const ::rtl::OUString& sReplacement ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL setAttributes( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aAttributeSet ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL setText( const ::rtl::OUString& sText ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleTextAttributes
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getDefaultAttributes( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& RequestedAttributes ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getRunAttributes( ::sal_Int32 Index, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& RequestedAttributes ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleMultiLineText
+ virtual ::sal_Int32 SAL_CALL getLineNumberAtIndex( ::sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextAtLineNumber( ::sal_Int32 nLineNo ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextAtLineWithCaret( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getNumberOfLineWithCaret( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName (void) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService (const ::rtl::OUString& sServiceName) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL getSupportedServiceNames (void) throw (::com::sun::star::uno::RuntimeException);
+
+ // XServiceName
+ virtual ::rtl::OUString SAL_CALL getServiceName (void) throw (::com::sun::star::uno::RuntimeException);
+
+ /** Set the current index in the accessibility parent
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+ */
+ void SetIndexInParent( sal_Int32 nIndex );
+
+ /** Get the current index in the accessibility parent
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+ */
+ sal_Int32 GetIndexInParent() const;
+
+ /** Set the current paragraph number
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+ */
+ void SetParagraphIndex( sal_Int32 nIndex );
+
+ /** Query the current paragraph number (0 - nParas-1)
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+ */
+ sal_Int32 GetParagraphIndex() const SAL_THROW((::com::sun::star::uno::RuntimeException));
+
+ /** Set the edit engine offset
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+ */
+ void SetEEOffset( const Point& rOffset );
+
+ /** Set the EditEngine offset
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+ */
+ void SetEditSource( SvxEditSourceAdapter* pEditSource );
+
+ /** Dispose this object
+
+ Notifies and deregisters the listeners, drops all references.
+ */
+ void Dispose();
+
+ /// Calls all Listener objects to tell them the change. Don't hold locks when calling this!
+ virtual void FireEvent(const sal_Int16 nEventId, const ::com::sun::star::uno::Any& rNewValue = ::com::sun::star::uno::Any(), const ::com::sun::star::uno::Any& rOldValue = ::com::sun::star::uno::Any() ) const;
+
+ /// Queries the given state on the internal state set
+ bool HasState( const sal_Int16 nStateId );
+ /// Sets the given state on the internal state set and fires STATE_CHANGE event. Don't hold locks when calling this!
+ void SetState( const sal_Int16 nStateId );
+ /// Unsets the given state on the internal state set and fires STATE_CHANGE event. Don't hold locks when calling this!
+ void UnSetState( const sal_Int16 nStateId );
+
+ static Rectangle LogicToPixel( const Rectangle& rRect, const MapMode& rMapMode, SvxViewForwarder& rForwarder );
+
+ SvxEditSourceAdapter& GetEditSource() const SAL_THROW((::com::sun::star::uno::RuntimeException));
+
+ /** Query the SvxTextForwarder for EditEngine access.
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+ */
+ SvxAccessibleTextAdapter& GetTextForwarder() const SAL_THROW((::com::sun::star::uno::RuntimeException));
+
+ /** Query the SvxViewForwarder for EditEngine access.
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+ */
+ SvxViewForwarder& GetViewForwarder() const SAL_THROW((::com::sun::star::uno::RuntimeException));
+
+ /** Query whether a GetEditViewForwarder( sal_False ) will return a forwarder
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+ */
+ sal_Bool HaveEditView() const;
+
+ /** Query the SvxEditViewForwarder for EditEngine access.
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+ */
+ SvxAccessibleTextEditViewAdapter& GetEditViewForwarder( sal_Bool bCreate = sal_False ) const SAL_THROW((::com::sun::star::uno::RuntimeException));
+
+ /** Send a TEXT_CHANGED event for this paragraph
+
+ This method internally caters for calculating text
+ differences, and sends the appropriate Anys in the
+ Accessibility::TEXT_CHANGED event
+ */
+ void TextChanged();
+
+ private:
+
+ // declared, but not defined
+ AccessibleEditableTextPara( const AccessibleEditableTextPara& );
+ AccessibleEditableTextPara& operator= ( const AccessibleEditableTextPara& );
+
+ /** Calculate character range of similar attributes
+
+ @param nStartIndex
+ Therein, the start of the character range with the same attributes is returned
+
+ @param nEndIndex
+ Therein, the end (exclusively) of the character range with the same attributes is returned
+
+ @param nIndex
+ The character index at where to look for similar character attributes
+
+ @return sal_False, if the method was not able to determine the range
+ */
+ sal_Bool GetAttributeRun( USHORT& nStartIndex, USHORT& nEndIndex, sal_Int32 nIndex );
+
+ // syntactic sugar for FireEvent
+ void GotPropertyEvent( const ::com::sun::star::uno::Any& rNewValue, const sal_Int16 nEventId ) const;
+ void LostPropertyEvent( const ::com::sun::star::uno::Any& rOldValue, const sal_Int16 nEventId ) const;
+
+ /** Query the visibility state
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+
+ @return the visibility state. Per definition, a defunc object is no longer visible
+ */
+ sal_Bool IsVisible() const;
+
+ int getNotifierClientId() const;
+
+ // retrieve text interface for given paragraph index
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleText > GetParaInterface( sal_Int32 nIndex );
+
+ /// Do we have children? This is the case for image bullets
+ sal_Bool HaveChildren();
+
+ /// Is the underlying object in edit mode
+ sal_Bool IsActive() const SAL_THROW((::com::sun::star::uno::RuntimeException));
+
+ const Point& GetEEOffset() const;
+
+ // Get text from forwarder
+ String GetText( sal_Int32 nIndex ) SAL_THROW((::com::sun::star::uno::RuntimeException));
+ String GetTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) SAL_THROW((::com::sun::star::uno::RuntimeException));
+ USHORT GetTextLen() const SAL_THROW((::com::sun::star::uno::RuntimeException));
+
+ /** Get the current selection of this paragraph
+
+ @return sal_False, if nothing in this paragraph is selected
+ */
+ sal_Bool GetSelection( USHORT& nStartPos, USHORT& nEndPos ) SAL_THROW((::com::sun::star::uno::RuntimeException));
+
+ /** create selection from Accessible selection.
+
+ */
+ ESelection MakeSelection( sal_Int32 nStartEEIndex, sal_Int32 nEndEEIndex );
+ ESelection MakeSelection( sal_Int32 nEEIndex );
+ ESelection MakeCursor( sal_Int32 nEEIndex );
+
+ // check whether index value is within permitted range
+
+ /// Check whether 0<=nIndex<=n-1
+ void CheckIndex( sal_Int32 nIndex ) SAL_THROW((::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException));
+ /// Check whether 0<=nIndex<=n
+ void CheckPosition( sal_Int32 nIndex ) SAL_THROW((::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException));
+ /// Check whether 0<=nStart<=n and 0<=nEnd<=n
+ void CheckRange( sal_Int32 nStart, sal_Int32 nEnd ) SAL_THROW((::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException));
+
+ // the paragraph index in the edit engine (guarded by solar mutex)
+ sal_Int32 mnParagraphIndex;
+
+ // our current index in the parent (guarded by solar mutex)
+ sal_Int32 mnIndexInParent;
+
+ // the current edit source (guarded by solar mutex)
+ SvxEditSourceAdapter* mpEditSource;
+
+ // the possible child (for image bullets, guarded by solar mutex)
+ typedef WeakCppRef < ::com::sun::star::accessibility::XAccessible, AccessibleImageBullet > WeakBullet;
+ WeakBullet maImageBullet;
+
+ // the last string used for an Accessibility::TEXT_CHANGED event (guarded by solar mutex)
+ ::rtl::OUString maLastTextString;
+
+ // the offset of the underlying EditEngine from the shape/cell (guarded by solar mutex)
+ Point maEEOffset;
+
+ // the current state set (updated from SetState/UnSetState and guarded by solar mutex)
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > mxStateSet;
+
+ /// The shape we're the accessible for (unguarded)
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > mxParent;
+
+ /// Our listeners (guarded by maMutex)
+ int mnNotifierClientId;
+
+ // --> OD 2006-01-11 #i27138#
+ // the paragraph manager, which created this instance - is NULL, if
+ // instance isn't created by AccessibleParaManager.
+ // Needed for method <getAccessibleRelationSet()> to retrieve predecessor
+ // paragraph and the successor paragraph.
+ const AccessibleParaManager* mpParaManager;
+ };
+
+} // end of namespace accessibility
+
+#endif
+
diff --git a/editeng/source/accessibility/AccessibleImageBullet.cxx b/editeng/source/accessibility/AccessibleImageBullet.cxx
new file mode 100644
index 0000000000..064f196049
--- /dev/null
+++ b/editeng/source/accessibility/AccessibleImageBullet.cxx
@@ -0,0 +1,654 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleImageBullet.cxx,v $
+ * $Revision: 1.22 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <tools/gen.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleTextType.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <comphelper/accessibleeventnotifier.hxx>
+#include <unotools/accessiblestatesethelper.hxx>
+#include <editeng/unolingu.hxx>
+#include "AccessibleEditableTextPara.hxx"
+#include "AccessibleImageBullet.hxx"
+#include <editeng/eerdll.hxx>
+
+#include <editeng/editdata.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/outliner.hxx>
+#include "editeng.hrc"
+#include <svtools/colorcfg.hxx>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+namespace accessibility
+{
+ DBG_NAME( AccessibleImageBullet )
+
+ AccessibleImageBullet::AccessibleImageBullet ( const uno::Reference< XAccessible >& rParent ) :
+ mnParagraphIndex( 0 ),
+ mnIndexInParent( 0 ),
+ mpEditSource( NULL ),
+ maEEOffset( 0, 0 ),
+ mxParent( rParent ),
+ // well, that's strictly (UNO) exception safe, though not
+ // really robust. We rely on the fact that this member is
+ // constructed last, and that the constructor body catches
+ // exceptions, thus no chance for exceptions once the Id is
+ // fetched. Nevertheless, normally should employ RAII here...
+ mnNotifierClientId(::comphelper::AccessibleEventNotifier::registerClient())
+ {
+#ifdef DBG_UTIL
+ DBG_CTOR( AccessibleImageBullet, NULL );
+ OSL_TRACE( "Received ID: %d", mnNotifierClientId );
+#endif
+
+ try
+ {
+ // Create the state set.
+ ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper ();
+ mxStateSet = pStateSet;
+
+ // these are always on
+ pStateSet->AddState( AccessibleStateType::VISIBLE );
+ pStateSet->AddState( AccessibleStateType::SHOWING );
+ pStateSet->AddState( AccessibleStateType::ENABLED );
+ pStateSet->AddState( AccessibleStateType::SENSITIVE );
+ }
+ catch( const uno::Exception& ) {}
+ }
+
+ AccessibleImageBullet::~AccessibleImageBullet()
+ {
+ DBG_DTOR( AccessibleImageBullet, NULL );
+
+ // sign off from event notifier
+ if( getNotifierClientId() != -1 )
+ {
+ try
+ {
+ ::comphelper::AccessibleEventNotifier::revokeClient( getNotifierClientId() );
+#ifdef DBG_UTIL
+ OSL_TRACE( "AccessibleImageBullet revoked ID: %d\n", mnNotifierClientId );
+#endif
+ }
+ catch( const uno::Exception& ) {}
+ }
+ }
+
+ uno::Any SAL_CALL AccessibleImageBullet::queryInterface (const uno::Type & rType) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ return AccessibleImageBulletInterfaceBase::queryInterface(rType);
+ }
+
+ uno::Reference< XAccessibleContext > SAL_CALL AccessibleImageBullet::getAccessibleContext( ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ // We implement the XAccessibleContext interface in the same object
+ return uno::Reference< XAccessibleContext > ( this );
+ }
+
+ sal_Int32 SAL_CALL AccessibleImageBullet::getAccessibleChildCount() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ return 0;
+ }
+
+ uno::Reference< XAccessible > SAL_CALL AccessibleImageBullet::getAccessibleChild( sal_Int32 i ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+ (void)i;
+
+ throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No childs available")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* > (this) ) ); // static_cast: disambiguate hierarchy
+ }
+
+ uno::Reference< XAccessible > SAL_CALL AccessibleImageBullet::getAccessibleParent() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ return mxParent;
+ }
+
+ sal_Int32 SAL_CALL AccessibleImageBullet::getAccessibleIndexInParent() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ return mnIndexInParent;
+ }
+
+ sal_Int16 SAL_CALL AccessibleImageBullet::getAccessibleRole() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ return AccessibleRole::GRAPHIC;
+ }
+
+ ::rtl::OUString SAL_CALL AccessibleImageBullet::getAccessibleDescription() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ // Get the string from the resource for the specified id.
+ return ::rtl::OUString( String( EditResId (RID_SVXSTR_A11Y_IMAGEBULLET_DESCRIPTION) ) );
+ }
+
+ ::rtl::OUString SAL_CALL AccessibleImageBullet::getAccessibleName() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ // Get the string from the resource for the specified id.
+ return ::rtl::OUString( String ( EditResId (RID_SVXSTR_A11Y_IMAGEBULLET_NAME) ) );
+ }
+
+ uno::Reference< XAccessibleRelationSet > SAL_CALL AccessibleImageBullet::getAccessibleRelationSet() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ // no relations, therefore empty
+ return uno::Reference< XAccessibleRelationSet >();
+ }
+
+ uno::Reference< XAccessibleStateSet > SAL_CALL AccessibleImageBullet::getAccessibleStateSet() throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ // Create a copy of the state set and return it.
+ ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
+
+ if( !pStateSet )
+ return uno::Reference<XAccessibleStateSet>();
+
+ return uno::Reference<XAccessibleStateSet>( new ::utl::AccessibleStateSetHelper (*pStateSet) );
+ }
+
+ lang::Locale SAL_CALL AccessibleImageBullet::getLocale() throw (IllegalAccessibleComponentStateException, uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ lang::Locale aLocale;
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleImageBullet::getLocale: paragraph index value overflow");
+
+ // return locale of first character in the paragraph
+ return SvxLanguageToLocale(aLocale, GetTextForwarder().GetLanguage( static_cast< USHORT >( GetParagraphIndex() ), 0 ));
+ }
+
+ void SAL_CALL AccessibleImageBullet::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ if( getNotifierClientId() != -1 )
+ ::comphelper::AccessibleEventNotifier::addEventListener( getNotifierClientId(), xListener );
+ }
+
+ void SAL_CALL AccessibleImageBullet::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ if( getNotifierClientId() != -1 )
+ ::comphelper::AccessibleEventNotifier::removeEventListener( getNotifierClientId(), xListener );
+ }
+
+ sal_Bool SAL_CALL AccessibleImageBullet::containsPoint( const awt::Point& rPoint ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::contains: index value overflow");
+
+ awt::Rectangle aTmpRect = getBounds();
+ Rectangle aRect( Point(aTmpRect.X, aTmpRect.Y), Size(aTmpRect.Width, aTmpRect.Height) );
+ Point aPoint( rPoint.X, rPoint.Y );
+
+ return aRect.IsInside( aPoint );
+ }
+
+ uno::Reference< XAccessible > SAL_CALL AccessibleImageBullet::getAccessibleAtPoint( const awt::Point& /*aPoint*/ ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ // as we have no children, empty reference
+ return uno::Reference< XAccessible >();
+ }
+
+ awt::Rectangle SAL_CALL AccessibleImageBullet::getBounds( ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
+ "AccessibleEditableTextPara::getBounds: index value overflow");
+
+ SvxTextForwarder& rCacheTF = GetTextForwarder();
+ EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< USHORT > (GetParagraphIndex()) );
+ Rectangle aParentRect = rCacheTF.GetParaBounds( static_cast< USHORT >( GetParagraphIndex() ) );
+
+ if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
+ aBulletInfo.bVisible &&
+ aBulletInfo.nType == SVX_NUM_BITMAP )
+ {
+ Rectangle aRect = aBulletInfo.aBounds;
+
+ // subtract paragraph position (bullet pos is absolute in EditEngine/Outliner)
+ aRect.Move( -aParentRect.Left(), -aParentRect.Top() );
+
+ // convert to screen coordinates
+ Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect,
+ rCacheTF.GetMapMode(),
+ GetViewForwarder() );
+
+ // offset from shape/cell
+ Point aOffset = GetEEOffset();
+
+ return awt::Rectangle( aScreenRect.Left() + aOffset.X(),
+ aScreenRect.Top() + aOffset.Y(),
+ aScreenRect.GetSize().Width(),
+ aScreenRect.GetSize().Height() );
+ }
+
+ return awt::Rectangle();
+ }
+
+ awt::Point SAL_CALL AccessibleImageBullet::getLocation( ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ awt::Rectangle aRect = getBounds();
+
+ return awt::Point( aRect.X, aRect.Y );
+ }
+
+ awt::Point SAL_CALL AccessibleImageBullet::getLocationOnScreen( ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ // relate us to parent
+ uno::Reference< XAccessible > xParent = getAccessibleParent();
+ if( xParent.is() )
+ {
+ uno::Reference< XAccessibleComponent > xParentComponent( xParent, uno::UNO_QUERY );
+ if( xParentComponent.is() )
+ {
+ awt::Point aRefPoint = xParentComponent->getLocationOnScreen();
+ awt::Point aPoint = getLocation();
+ aPoint.X += aRefPoint.X;
+ aPoint.Y += aRefPoint.Y;
+
+ return aPoint;
+ }
+ }
+
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot access parent")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
+ }
+
+ awt::Size SAL_CALL AccessibleImageBullet::getSize( ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ awt::Rectangle aRect = getBounds();
+
+ return awt::Size( aRect.Width, aRect.Height );
+ }
+
+ void SAL_CALL AccessibleImageBullet::grabFocus( ) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Not focusable")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
+ }
+
+ sal_Int32 SAL_CALL AccessibleImageBullet::getForeground( ) throw (::com::sun::star::uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ // #104444# Added to XAccessibleComponent interface
+ svtools::ColorConfig aColorConfig;
+ UINT32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor;
+ return static_cast<sal_Int32>(nColor);
+ }
+
+ sal_Int32 SAL_CALL AccessibleImageBullet::getBackground( ) throw (::com::sun::star::uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ // #104444# Added to XAccessibleComponent interface
+ Color aColor( Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor() );
+
+ // the background is transparent
+ aColor.SetTransparency( 0xFF);
+
+ return static_cast<sal_Int32>( aColor.GetColor() );
+ }
+
+ ::rtl::OUString SAL_CALL AccessibleImageBullet::getImplementationName (void) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("AccessibleImageBullet"));
+ }
+
+ sal_Bool SAL_CALL AccessibleImageBullet::supportsService (const ::rtl::OUString& sServiceName) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ // Iterate over all supported service names and return true if on of them
+ // matches the given name.
+ uno::Sequence< ::rtl::OUString> aSupportedServices (
+ getSupportedServiceNames ());
+ for (int i=0; i<aSupportedServices.getLength(); i++)
+ if (sServiceName == aSupportedServices[i])
+ return sal_True;
+ return sal_False;
+ }
+
+ uno::Sequence< ::rtl::OUString> SAL_CALL AccessibleImageBullet::getSupportedServiceNames (void) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ const ::rtl::OUString sServiceName (RTL_CONSTASCII_USTRINGPARAM ("com.sun.star.accessibility.AccessibleContext"));
+ return uno::Sequence< ::rtl::OUString > (&sServiceName, 1);
+ }
+
+ ::rtl::OUString SAL_CALL AccessibleImageBullet::getServiceName (void) throw (uno::RuntimeException)
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleContext"));
+ }
+
+ void AccessibleImageBullet::SetIndexInParent( sal_Int32 nIndex )
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ mnIndexInParent = nIndex;
+ }
+
+ sal_Int32 AccessibleImageBullet::GetIndexInParent() const
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ return mnIndexInParent;
+ }
+
+ void AccessibleImageBullet::SetEEOffset( const Point& rOffset )
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ maEEOffset = rOffset;
+ }
+
+ void AccessibleImageBullet::Dispose()
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ int nClientId( getNotifierClientId() );
+
+ // #108212# drop all references before notifying dispose
+ mxParent = NULL;
+ mnNotifierClientId = -1;
+ mpEditSource = NULL;
+
+ // notify listeners
+ if( nClientId != -1 )
+ {
+ try
+ {
+ uno::Reference < XAccessibleContext > xThis = getAccessibleContext();
+
+ // #106234# Delegate to EventNotifier
+ ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, xThis );
+#ifdef DBG_UTIL
+ OSL_TRACE( "AccessibleImageBullet disposed ID: %d", nClientId );
+#endif
+ }
+ catch( const uno::Exception& ) {}
+ }
+ }
+
+ void AccessibleImageBullet::SetEditSource( SvxEditSource* pEditSource )
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ mpEditSource = pEditSource;
+
+ if( !mpEditSource )
+ {
+ // going defunc
+ UnSetState( AccessibleStateType::SHOWING );
+ UnSetState( AccessibleStateType::VISIBLE );
+ SetState( AccessibleStateType::INVALID );
+ SetState( AccessibleStateType::DEFUNC );
+
+ Dispose();
+ }
+ }
+
+ void AccessibleImageBullet::FireEvent(const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue ) const
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ uno::Reference < XAccessibleContext > xThis( const_cast< AccessibleImageBullet* > (this)->getAccessibleContext() );
+
+ AccessibleEventObject aEvent(xThis, nEventId, rNewValue, rOldValue);
+
+ // #106234# Delegate to EventNotifier
+ ::comphelper::AccessibleEventNotifier::addEvent( getNotifierClientId(),
+ aEvent );
+ }
+
+ void AccessibleImageBullet::GotPropertyEvent( const uno::Any& rNewValue, const sal_Int16 nEventId ) const
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ FireEvent( nEventId, rNewValue );
+ }
+
+ void AccessibleImageBullet::LostPropertyEvent( const uno::Any& rOldValue, const sal_Int16 nEventId ) const
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ FireEvent( nEventId, uno::Any(), rOldValue );
+ }
+
+ void AccessibleImageBullet::SetState( const sal_Int16 nStateId )
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
+ if( pStateSet != NULL &&
+ !pStateSet->contains(nStateId) )
+ {
+ pStateSet->AddState( nStateId );
+ GotPropertyEvent( uno::makeAny( nStateId ), AccessibleEventId::STATE_CHANGED );
+ }
+ }
+
+ void AccessibleImageBullet::UnSetState( const sal_Int16 nStateId )
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
+ if( pStateSet != NULL &&
+ pStateSet->contains(nStateId) )
+ {
+ pStateSet->RemoveState( nStateId );
+ LostPropertyEvent( uno::makeAny( nStateId ), AccessibleEventId::STATE_CHANGED );
+ }
+ }
+
+ int AccessibleImageBullet::getNotifierClientId() const
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ return mnNotifierClientId;
+ }
+
+ void AccessibleImageBullet::SetParagraphIndex( sal_Int32 nIndex )
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ uno::Any aOldDesc;
+ uno::Any aOldName;
+
+ try
+ {
+ aOldDesc <<= getAccessibleDescription();
+ aOldName <<= getAccessibleName();
+ }
+ catch( const uno::Exception& ) {} // optional behaviour
+
+ sal_Int32 nOldIndex = mnParagraphIndex;
+
+ mnParagraphIndex = nIndex;
+
+ try
+ {
+ if( nOldIndex != nIndex )
+ {
+ // index and therefore description changed
+ FireEvent( AccessibleEventId::DESCRIPTION_CHANGED, uno::makeAny( getAccessibleDescription() ), aOldDesc );
+ FireEvent( AccessibleEventId::NAME_CHANGED, uno::makeAny( getAccessibleName() ), aOldName );
+ }
+ }
+ catch( const uno::Exception& ) {} // optional behaviour
+ }
+
+ sal_Int32 AccessibleImageBullet::GetParagraphIndex() const SAL_THROW((uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ return mnParagraphIndex;
+ }
+
+ SvxEditSource& AccessibleImageBullet::GetEditSource() const SAL_THROW((uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ if( mpEditSource )
+ return *mpEditSource;
+ else
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No edit source, object is defunct")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* >
+ ( const_cast< AccessibleImageBullet* > (this) ) ) ); // disambiguate hierarchy
+ }
+
+ SvxTextForwarder& AccessibleImageBullet::GetTextForwarder() const SAL_THROW((uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ SvxEditSource& rEditSource = GetEditSource();
+ SvxTextForwarder* pTextForwarder = rEditSource.GetTextForwarder();
+
+ if( !pTextForwarder )
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch text forwarder, object is defunct")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* >
+ ( const_cast< AccessibleImageBullet* > (this) ) ) ); // disambiguate hierarchy
+
+ if( pTextForwarder->IsValid() )
+ return *pTextForwarder;
+ else
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Text forwarder is invalid, object is defunct")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* >
+ ( const_cast< AccessibleImageBullet* > (this) ) ) ); // disambiguate hierarchy
+ }
+
+ SvxViewForwarder& AccessibleImageBullet::GetViewForwarder() const SAL_THROW((uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ SvxEditSource& rEditSource = GetEditSource();
+ SvxViewForwarder* pViewForwarder = rEditSource.GetViewForwarder();
+
+ if( !pViewForwarder )
+ {
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch view forwarder, object is defunct")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* >
+ ( const_cast< AccessibleImageBullet* > (this) ) ) ); // disambiguate hierarchy
+ }
+
+ if( pViewForwarder->IsValid() )
+ return *pViewForwarder;
+ else
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object is defunct")),
+ uno::Reference< uno::XInterface >
+ ( static_cast< ::cppu::OWeakObject* >
+ ( const_cast< AccessibleImageBullet* > (this) ) ) ); // disambiguate hierarchy
+ }
+
+ const Point& AccessibleImageBullet::GetEEOffset() const
+ {
+ DBG_CHKTHIS( AccessibleImageBullet, NULL );
+
+ return maEEOffset;
+ }
+
+} // end of namespace accessibility
+
diff --git a/editeng/source/accessibility/AccessibleImageBullet.hxx b/editeng/source/accessibility/AccessibleImageBullet.hxx
new file mode 100644
index 0000000000..b1dc462021
--- /dev/null
+++ b/editeng/source/accessibility/AccessibleImageBullet.hxx
@@ -0,0 +1,240 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleImageBullet.hxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVX_ACCESSIBLE_IMAGE_BULLET_HXX
+#define _SVX_ACCESSIBLE_IMAGE_BULLET_HXX
+
+#include <tools/gen.hxx>
+#include <cppuhelper/weakref.hxx>
+#include <cppuhelper/implbase5.hxx>
+
+#ifndef _CPPUHELPER_INTERFACECONTAINER_H_
+#include <cppuhelper/interfacecontainer.hxx>
+#endif
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
+#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
+#include "AccessibleParaManager.hxx"
+#include <editeng/unoedsrc.hxx>
+
+namespace accessibility
+{
+ typedef ::cppu::WeakImplHelper5< ::com::sun::star::accessibility::XAccessible,
+ ::com::sun::star::accessibility::XAccessibleContext,
+ ::com::sun::star::accessibility::XAccessibleComponent,
+ ::com::sun::star::accessibility::XAccessibleEventBroadcaster,
+ ::com::sun::star::lang::XServiceInfo > AccessibleImageBulletInterfaceBase;
+
+ /** This class implements the image bullets for the EditEngine/Outliner UAA
+ */
+ class AccessibleImageBullet : public AccessibleImageBulletInterfaceBase
+ {
+
+ public:
+ /// Create accessible object for given parent
+ AccessibleImageBullet ( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& rParent );
+
+ virtual ~AccessibleImageBullet ();
+
+ // XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface (const ::com::sun::star::uno::Type & rType) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessible
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleContext
+ virtual sal_Int32 SAL_CALL getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent() throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleIndexInParent() throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int16 SAL_CALL getAccessibleRole() throw (::com::sun::star::uno::RuntimeException);
+ /// Maximal length of text returned by getAccessibleDescription()
+ enum { MaxDescriptionLen = 40 };
+ virtual ::rtl::OUString SAL_CALL getAccessibleDescription() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleName() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::lang::Locale SAL_CALL getLocale() throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleEventBroadcaster
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleComponent
+ virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Point SAL_CALL getLocation( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Size SAL_CALL getSize( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL grabFocus( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getForeground( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getBackground( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName (void) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService (const ::rtl::OUString& sServiceName) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL getSupportedServiceNames (void) throw (::com::sun::star::uno::RuntimeException);
+
+ // XServiceName
+ virtual ::rtl::OUString SAL_CALL getServiceName (void) throw (::com::sun::star::uno::RuntimeException);
+
+ /** Set the current index in the accessibility parent
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+ */
+ void SetIndexInParent( sal_Int32 nIndex );
+
+ /** Get the current index in the accessibility parent
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+ */
+ sal_Int32 GetIndexInParent() const;
+
+ /** Set the edit engine offset
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+ */
+ void SetEEOffset( const Point& rOffset );
+
+ /** Set the EditEngine offset
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+ */
+ void SetEditSource( SvxEditSource* pEditSource );
+
+ /** Dispose this object
+
+ Notifies and deregisters the listeners, drops all references.
+ */
+ void Dispose();
+
+ /** Set the current paragraph number
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+ */
+ void SetParagraphIndex( sal_Int32 nIndex );
+
+ /** Query the current paragraph number (0 - nParas-1)
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+ */
+ sal_Int32 GetParagraphIndex() const SAL_THROW((::com::sun::star::uno::RuntimeException));
+
+ /// Calls all Listener objects to tell them the change. Don't hold locks when calling this!
+ virtual void FireEvent(const sal_Int16 nEventId, const ::com::sun::star::uno::Any& rNewValue = ::com::sun::star::uno::Any(), const ::com::sun::star::uno::Any& rOldValue = ::com::sun::star::uno::Any() ) const;
+
+ private:
+
+ // declared, but not defined
+ AccessibleImageBullet( const AccessibleImageBullet& );
+ AccessibleImageBullet& operator= ( const AccessibleImageBullet& );
+
+ // syntactic sugar for FireEvent
+ void GotPropertyEvent( const ::com::sun::star::uno::Any& rNewValue, const sal_Int16 nEventId ) const;
+ void LostPropertyEvent( const ::com::sun::star::uno::Any& rOldValue, const sal_Int16 nEventId ) const;
+
+ // maintain state set and send STATE_CHANGE events
+ void SetState( const sal_Int16 nStateId );
+ void UnSetState( const sal_Int16 nStateId );
+
+ SvxEditSource& GetEditSource() const SAL_THROW((::com::sun::star::uno::RuntimeException));
+
+ int getNotifierClientId() const;
+
+ /** Query the SvxTextForwarder for EditEngine access.
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+ */
+ SvxTextForwarder& GetTextForwarder() const SAL_THROW((::com::sun::star::uno::RuntimeException));
+
+ /** Query the SvxViewForwarder for EditEngine access.
+
+ @attention This method does not lock the SolarMutex,
+ leaving that to the calling code. This is because only
+ there potential deadlock situations can be resolved. Thus,
+ make sure SolarMutex is locked when calling this.
+ */
+ SvxViewForwarder& GetViewForwarder() const SAL_THROW((::com::sun::star::uno::RuntimeException));
+
+ const Point& GetEEOffset() const;
+
+ // the paragraph index in the edit engine (guarded by solar mutex)
+ sal_Int32 mnParagraphIndex;
+
+ // our current index in the parent (guarded by solar mutex)
+ sal_Int32 mnIndexInParent;
+
+ // the current edit source (guarded by solar mutex)
+ SvxEditSource* mpEditSource;
+
+ // the offset of the underlying EditEngine from the shape/cell (guarded by solar mutex)
+ Point maEEOffset;
+
+ // the current state set (updated from SetState/UnSetState and guarded by solar mutex)
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > mxStateSet;
+
+ mutable osl::Mutex maMutex;
+
+ /// The shape we're the accessible for (unguarded)
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > mxParent;
+
+ /// Our listeners (guarded by maMutex)
+ int mnNotifierClientId;
+ };
+
+} // end of namespace accessibility
+
+#endif
+
diff --git a/editeng/source/accessibility/AccessibleParaManager.cxx b/editeng/source/accessibility/AccessibleParaManager.cxx
new file mode 100644
index 0000000000..0d8e75020c
--- /dev/null
+++ b/editeng/source/accessibility/AccessibleParaManager.cxx
@@ -0,0 +1,423 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleParaManager.cxx,v $
+ * $Revision: 1.16 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+//------------------------------------------------------------------------
+//
+// Global header
+//
+//------------------------------------------------------------------------
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <cppuhelper/weakref.hxx>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+
+//------------------------------------------------------------------------
+//
+// Project-local header
+//
+//------------------------------------------------------------------------
+
+#include <editeng/unoedhlp.hxx>
+#include <editeng/unopracc.hxx>
+#include <editeng/unoedsrc.hxx>
+#include "AccessibleParaManager.hxx"
+#include "AccessibleEditableTextPara.hxx"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+
+
+namespace accessibility
+{
+ AccessibleParaManager::AccessibleParaManager() :
+ maChildren(1),
+ maEEOffset( 0, 0 ),
+ mnFocusedChild( -1 ),
+ mbActive( sal_False )
+ {
+ }
+
+ AccessibleParaManager::~AccessibleParaManager()
+ {
+ // owner is responsible for possible child defuncs
+ }
+
+ void AccessibleParaManager::SetAdditionalChildStates( const VectorOfStates& rChildStates )
+ {
+ maChildStates = rChildStates;
+ }
+
+ const AccessibleParaManager::VectorOfStates& AccessibleParaManager::GetAdditionalChildStates() const
+ {
+ return maChildStates;
+ }
+
+ void AccessibleParaManager::SetNum( sal_Int32 nNumParas )
+ {
+ if( (size_t)nNumParas < maChildren.size() )
+ Release( nNumParas, maChildren.size() );
+
+ maChildren.resize( nNumParas );
+
+ if( mnFocusedChild >= nNumParas )
+ mnFocusedChild = -1;
+ }
+
+ sal_uInt32 AccessibleParaManager::GetNum() const
+ {
+ return maChildren.size();
+ }
+
+ AccessibleParaManager::VectorOfChildren::iterator AccessibleParaManager::begin()
+ {
+ return maChildren.begin();
+ }
+
+ AccessibleParaManager::VectorOfChildren::iterator AccessibleParaManager::end()
+ {
+ return maChildren.end();
+ }
+
+ AccessibleParaManager::VectorOfChildren::const_iterator AccessibleParaManager::begin() const
+ {
+ return maChildren.begin();
+ }
+
+ AccessibleParaManager::VectorOfChildren::const_iterator AccessibleParaManager::end() const
+ {
+ return maChildren.end();
+ }
+
+ void AccessibleParaManager::Release( sal_uInt32 nPara )
+ {
+ DBG_ASSERT( maChildren.size() > nPara, "AccessibleParaManager::Release: invalid index" );
+
+ if( maChildren.size() > nPara )
+ {
+ ShutdownPara( GetChild( nPara ) );
+
+ // clear reference and rect
+ maChildren[ nPara ] = WeakChild();
+ }
+ }
+
+ void AccessibleParaManager::FireEvent( sal_uInt32 nPara,
+ const sal_Int16 nEventId,
+ const uno::Any& rNewValue,
+ const uno::Any& rOldValue ) const
+ {
+ DBG_ASSERT( maChildren.size() > nPara, "AccessibleParaManager::FireEvent: invalid index" );
+
+ if( maChildren.size() > nPara )
+ {
+ WeakPara::HardRefType maChild( GetChild( nPara ).first.get() );
+ if( maChild.is() )
+ maChild->FireEvent( nEventId, rNewValue, rOldValue );
+ }
+ }
+
+ sal_Bool AccessibleParaManager::IsReferencable( WeakPara::HardRefType aChild )
+ {
+ return aChild.is();
+ }
+
+ sal_Bool AccessibleParaManager::IsReferencable( sal_uInt32 nChild ) const
+ {
+ DBG_ASSERT( maChildren.size() > nChild, "AccessibleParaManager::IsReferencable: invalid index" );
+
+ if( maChildren.size() > nChild )
+ {
+ // retrieve hard reference from weak one
+ return IsReferencable( GetChild( nChild ).first.get() );
+ }
+ else
+ {
+ return sal_False;
+ }
+ }
+
+ AccessibleParaManager::WeakChild AccessibleParaManager::GetChild( sal_uInt32 nParagraphIndex ) const
+ {
+ DBG_ASSERT( maChildren.size() > nParagraphIndex, "AccessibleParaManager::GetChild: invalid index" );
+
+ if( maChildren.size() > nParagraphIndex )
+ {
+ return maChildren[ nParagraphIndex ];
+ }
+ else
+ {
+ return WeakChild();
+ }
+ }
+
+ AccessibleParaManager::Child AccessibleParaManager::CreateChild( sal_Int32 nChild,
+ const uno::Reference< XAccessible >& xFrontEnd,
+ SvxEditSourceAdapter& rEditSource,
+ sal_uInt32 nParagraphIndex )
+ {
+ DBG_ASSERT( maChildren.size() > nParagraphIndex, "AccessibleParaManager::CreateChild: invalid index" );
+
+ if( maChildren.size() > nParagraphIndex )
+ {
+ // retrieve hard reference from weak one
+ WeakPara::HardRefType aChild( GetChild( nParagraphIndex ).first.get() );
+
+ if( !IsReferencable( nParagraphIndex ) )
+ {
+ // there is no hard reference available, create object then
+ // --> OD 2006-01-11 #i27138#
+ AccessibleEditableTextPara* pChild = new AccessibleEditableTextPara( xFrontEnd, this );
+ // <--
+ uno::Reference< XAccessible > xChild( static_cast< ::cppu::OWeakObject* > (pChild), uno::UNO_QUERY );
+
+ if( !xChild.is() )
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Child creation failed")), xFrontEnd);
+
+ aChild = WeakPara::HardRefType( xChild, pChild );
+
+ InitChild( *aChild, rEditSource, nChild, nParagraphIndex );
+
+ maChildren[ nParagraphIndex ] = WeakChild( aChild, pChild->getBounds() );
+ }
+
+ return Child( aChild.getRef(), GetChild( nParagraphIndex ).second );
+ }
+ else
+ {
+ return Child();
+ }
+ }
+
+ void AccessibleParaManager::SetEEOffset( const Point& rOffset )
+ {
+ maEEOffset = rOffset;
+
+ MemFunAdapter< const Point& > aAdapter( &::accessibility::AccessibleEditableTextPara::SetEEOffset, rOffset );
+ ::std::for_each( begin(), end(), aAdapter );
+ }
+
+ void AccessibleParaManager::SetActive( sal_Bool bActive )
+ {
+ mbActive = bActive;
+
+ if( bActive )
+ {
+ SetState( AccessibleStateType::ACTIVE );
+ SetState( AccessibleStateType::EDITABLE );
+ }
+ else
+ {
+ UnSetState( AccessibleStateType::ACTIVE );
+ UnSetState( AccessibleStateType::EDITABLE );
+ }
+ }
+
+ void AccessibleParaManager::SetFocus( sal_Int32 nChild )
+ {
+ if( mnFocusedChild != -1 )
+ UnSetState( mnFocusedChild, AccessibleStateType::FOCUSED );
+
+ mnFocusedChild = nChild;
+
+ if( mnFocusedChild != -1 )
+ SetState( mnFocusedChild, AccessibleStateType::FOCUSED );
+ }
+
+ void AccessibleParaManager::InitChild( AccessibleEditableTextPara& rChild,
+ SvxEditSourceAdapter& rEditSource,
+ sal_Int32 nChild,
+ sal_uInt32 nParagraphIndex ) const
+ {
+ rChild.SetEditSource( &rEditSource );
+ rChild.SetIndexInParent( nChild );
+ rChild.SetParagraphIndex( nParagraphIndex );
+
+ rChild.SetEEOffset( maEEOffset );
+
+ if( mbActive )
+ {
+ rChild.SetState( AccessibleStateType::ACTIVE );
+ rChild.SetState( AccessibleStateType::EDITABLE );
+ }
+
+ if( mnFocusedChild == static_cast<sal_Int32>(nParagraphIndex) )
+ rChild.SetState( AccessibleStateType::FOCUSED );
+
+ // add states passed from outside
+ for( VectorOfStates::const_iterator aIt = maChildStates.begin(), aEnd = maChildStates.end(); aIt != aEnd; ++aIt )
+ rChild.SetState( *aIt );
+ }
+
+ void AccessibleParaManager::SetState( sal_Int32 nChild, const sal_Int16 nStateId )
+ {
+ MemFunAdapter< const sal_Int16 > aFunc( &AccessibleEditableTextPara::SetState,
+ nStateId );
+ aFunc( GetChild(nChild) );
+ }
+
+ void AccessibleParaManager::SetState( const sal_Int16 nStateId )
+ {
+ ::std::for_each( begin(), end(),
+ MemFunAdapter< const sal_Int16 >( &AccessibleEditableTextPara::SetState,
+ nStateId ) );
+ }
+
+ void AccessibleParaManager::UnSetState( sal_Int32 nChild, const sal_Int16 nStateId )
+ {
+ MemFunAdapter< const sal_Int16 > aFunc( &AccessibleEditableTextPara::UnSetState,
+ nStateId );
+ aFunc( GetChild(nChild) );
+ }
+
+ void AccessibleParaManager::UnSetState( const sal_Int16 nStateId )
+ {
+ ::std::for_each( begin(), end(),
+ MemFunAdapter< const sal_Int16 >( &AccessibleEditableTextPara::UnSetState,
+ nStateId ) );
+ }
+
+ void AccessibleParaManager::SetEditSource( SvxEditSourceAdapter* pEditSource )
+ {
+ MemFunAdapter< SvxEditSourceAdapter* > aAdapter( &::accessibility::AccessibleEditableTextPara::SetEditSource, pEditSource );
+ ::std::for_each( begin(), end(), aAdapter );
+ }
+
+ // not generic yet, no arguments...
+ class AccessibleParaManager_DisposeChildren : public ::std::unary_function< ::accessibility::AccessibleEditableTextPara&, void >
+ {
+ public:
+ AccessibleParaManager_DisposeChildren() {}
+ void operator()( ::accessibility::AccessibleEditableTextPara& rPara )
+ {
+ rPara.Dispose();
+ }
+ };
+
+ void AccessibleParaManager::Dispose()
+ {
+ AccessibleParaManager_DisposeChildren aFunctor;
+
+ ::std::for_each( begin(), end(),
+ WeakChildAdapter< AccessibleParaManager_DisposeChildren > (aFunctor) );
+ }
+
+ // not generic yet, too many method arguments...
+ class StateChangeEvent : public ::std::unary_function< ::accessibility::AccessibleEditableTextPara&, void >
+ {
+ public:
+ typedef void return_type;
+ StateChangeEvent( const sal_Int16 nEventId,
+ const uno::Any& rNewValue,
+ const uno::Any& rOldValue ) :
+ mnEventId( nEventId ),
+ mrNewValue( rNewValue ),
+ mrOldValue( rOldValue ) {}
+ void operator()( ::accessibility::AccessibleEditableTextPara& rPara )
+ {
+ rPara.FireEvent( mnEventId, mrNewValue, mrOldValue );
+ }
+
+ private:
+ const sal_Int16 mnEventId;
+ const uno::Any& mrNewValue;
+ const uno::Any& mrOldValue;
+ };
+
+ void AccessibleParaManager::FireEvent( sal_uInt32 nStartPara,
+ sal_uInt32 nEndPara,
+ const sal_Int16 nEventId,
+ const uno::Any& rNewValue,
+ const uno::Any& rOldValue ) const
+ {
+ DBG_ASSERT( maChildren.size() > nStartPara &&
+ maChildren.size() >= nEndPara , "AccessibleParaManager::FireEvent: invalid index" );
+
+ if( maChildren.size() > nStartPara &&
+ maChildren.size() >= nEndPara )
+ {
+ VectorOfChildren::const_iterator front = maChildren.begin();
+ VectorOfChildren::const_iterator back = front;
+
+ ::std::advance( front, nStartPara );
+ ::std::advance( back, nEndPara );
+
+ StateChangeEvent aFunctor( nEventId, rNewValue, rOldValue );
+
+ ::std::for_each( front, back, AccessibleParaManager::WeakChildAdapter< StateChangeEvent >( aFunctor ) );
+ }
+ }
+
+ class ReleaseChild : public ::std::unary_function< const AccessibleParaManager::WeakChild&, AccessibleParaManager::WeakChild >
+ {
+ public:
+ AccessibleParaManager::WeakChild operator()( const AccessibleParaManager::WeakChild& rPara )
+ {
+ AccessibleParaManager::ShutdownPara( rPara );
+
+ // clear reference
+ return AccessibleParaManager::WeakChild();
+ }
+ };
+
+ void AccessibleParaManager::Release( sal_uInt32 nStartPara, sal_uInt32 nEndPara )
+ {
+ DBG_ASSERT( maChildren.size() > nStartPara &&
+ maChildren.size() >= nEndPara, "AccessibleParaManager::Release: invalid index" );
+
+ if( maChildren.size() > nStartPara &&
+ maChildren.size() >= nEndPara )
+ {
+ VectorOfChildren::iterator front = maChildren.begin();
+ VectorOfChildren::iterator back = front;
+
+ ::std::advance( front, nStartPara );
+ ::std::advance( back, nEndPara );
+
+ ::std::transform( front, back, front, ReleaseChild() );
+ }
+ }
+
+ void AccessibleParaManager::ShutdownPara( const WeakChild& rChild )
+ {
+ WeakPara::HardRefType aChild( rChild.first.get() );
+
+ if( IsReferencable( aChild ) )
+ aChild->SetEditSource( NULL );
+ }
+
+}
+
+//------------------------------------------------------------------------
diff --git a/editeng/source/accessibility/AccessibleParaManager.hxx b/editeng/source/accessibility/AccessibleParaManager.hxx
new file mode 100644
index 0000000000..17644c2b7a
--- /dev/null
+++ b/editeng/source/accessibility/AccessibleParaManager.hxx
@@ -0,0 +1,349 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleParaManager.hxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVX_ACCESSIBLE_PARA_MANAGER_HXX
+#define _SVX_ACCESSIBLE_PARA_MANAGER_HXX
+
+#include <vector>
+#include <algorithm>
+#include <functional>
+#include <utility>
+#include <tools/gen.hxx>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <cppuhelper/weakref.hxx>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+
+class SvxEditSourceAdapter;
+
+namespace accessibility
+{
+ class AccessibleEditableTextPara;
+
+ /** Helper class for WeakCppRef
+
+ This class is returned by WeakChild::get() and contains a hard
+ reference and a reference to the c++ object. This combination
+ prevents the c++ object from destruction during usage. Hold
+ this object only as long as absolutely necessary, prevents
+ referenced object from vanishing otherwise
+ */
+ template < class UnoType, class CppType > class HardCppRef
+ {
+ public:
+
+ typedef UnoType UnoInterfaceType;
+ typedef CppType InterfaceType;
+
+ HardCppRef( const ::com::sun::star::uno::WeakReference< UnoInterfaceType >& xRef, InterfaceType* rImpl ) :
+ mxRef( xRef ),
+ mpImpl( rImpl )
+ {
+ }
+
+ /** Query whether the reference is still valid.
+
+ Hands off also from the implementation pointer if this
+ returns sal_False!
+ */
+ sal_Bool is() const { return mxRef.is(); }
+ InterfaceType* operator->() const { return mpImpl; }
+ InterfaceType& operator*() const { return *mpImpl; }
+ ::com::sun::star::uno::Reference< UnoInterfaceType >& getRef() { return mxRef; }
+ const ::com::sun::star::uno::Reference< UnoInterfaceType >& getRef() const { return mxRef; }
+
+ // default copy constructor and assignment will do
+ // HardCppRef( const HardCppRef& );
+ // HardCppRef& operator= ( const HardCppRef& );
+
+ private:
+
+ // the interface, hard reference to prevent object from vanishing
+ ::com::sun::star::uno::Reference< UnoInterfaceType > mxRef;
+
+ // the c++ object, for our internal stuff
+ InterfaceType* mpImpl;
+
+ };
+
+ /** Helper class for weak object references plus implementation
+
+ This class combines a weak reference (to facilitate automatic
+ object disposal if user drops last reference) and hard
+ reference to the c++ class (for fast access and bypassing of
+ the UNO interface)
+ */
+ template < class UnoType, class CppType > class WeakCppRef
+ {
+ public:
+
+ typedef UnoType UnoInterfaceType;
+ typedef CppType InterfaceType;
+ typedef HardCppRef< UnoInterfaceType, InterfaceType > HardRefType;
+
+ WeakCppRef() : maWeakRef(), maUnsafeRef( NULL ) {}
+ WeakCppRef( InterfaceType& rImpl ) :
+ maWeakRef( ::com::sun::star::uno::Reference< UnoInterfaceType >( rImpl, ::com::sun::star::uno::UNO_QUERY ) ),
+ maUnsafeRef( &rImpl )
+ {
+ }
+
+ WeakCppRef( HardRefType& rImpl ) :
+ maWeakRef( rImpl.getRef() ),
+ maUnsafeRef( rImpl.operator->() )
+ {
+ }
+
+ // get object with c++ object and hard reference (which
+ // prevents the c++ object from destruction during use)
+ HardRefType get() const { return HardRefType( maWeakRef, maUnsafeRef ); }
+
+ // default copy constructor and assignment will do
+ // WeakCppRef( const WeakCppRef& );
+ // WeakCppRef& operator= ( const WeakCppRef& );
+
+ private:
+
+ // the interface, hold weakly
+ ::com::sun::star::uno::WeakReference< UnoInterfaceType > maWeakRef;
+
+ // hard ref to c++ class, _only_ valid if maWeakRef.is() is true
+ InterfaceType* maUnsafeRef;
+ };
+
+
+ /** This class manages the paragraphs of an AccessibleTextHelper
+
+ To facilitate automatic deletion of paragraphs no longer used,
+ this class uses the WeakCppRef helper to hold the objects weakly.
+ */
+ class AccessibleParaManager
+ {
+ public:
+ typedef WeakCppRef < ::com::sun::star::accessibility::XAccessible, AccessibleEditableTextPara > WeakPara;
+ typedef ::std::pair< WeakPara, ::com::sun::star::awt::Rectangle > WeakChild;
+ typedef ::std::pair< ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible > , ::com::sun::star::awt::Rectangle > Child;
+ typedef ::std::vector< WeakChild > VectorOfChildren;
+ typedef ::std::vector< sal_Int16 > VectorOfStates;
+
+ AccessibleParaManager();
+ ~AccessibleParaManager();
+
+ /** Sets a vector of additional accessible states.
+
+ The states are passed to every created child object
+ (text paragraph). The state values are defined in
+ com::sun::star::accessibility::AccessibleStateType.
+ */
+ void SetAdditionalChildStates( const VectorOfStates& rChildStates );
+
+ /** Returns the additional accessible states for children.
+ */
+ const VectorOfStates& GetAdditionalChildStates() const;
+
+ /** Set the number of paragraphs
+
+ @param nNumPara
+ The total number of paragraphs the EditEngine currently
+ has (_not_ the number of currently visible children)
+ */
+ void SetNum( sal_Int32 nNumParas );
+
+ /** Get the number of paragraphs currently possible */
+ sal_uInt32 GetNum() const;
+
+ // iterators
+ VectorOfChildren::iterator begin();
+ VectorOfChildren::iterator end();
+ VectorOfChildren::const_iterator begin() const;
+ VectorOfChildren::const_iterator end() const;
+
+ // dealing with single paragraphs (release reference, return reference etc)
+ void Release( sal_uInt32 nPara );
+ /// Set focus to given child
+ void SetFocus( sal_Int32 nChild );
+
+ void FireEvent( sal_uInt32 nPara,
+ const sal_Int16 nEventId,
+ const ::com::sun::star::uno::Any& rNewValue = ::com::sun::star::uno::Any(),
+ const ::com::sun::star::uno::Any& rOldValue = ::com::sun::star::uno::Any() ) const;
+
+ static sal_Bool IsReferencable( WeakPara::HardRefType aChild );
+ sal_Bool IsReferencable( sal_uInt32 nChild ) const;
+ static void ShutdownPara( const WeakChild& rChild );
+
+ Child CreateChild( sal_Int32 nChild,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& xFrontEnd,
+ SvxEditSourceAdapter& rEditSource,
+ sal_uInt32 nParagraphIndex );
+
+ WeakChild GetChild( sal_uInt32 nParagraphIndex ) const;
+
+ // forwarder to all paragraphs
+ /// Make all children active and editable (or off)
+ void SetActive( sal_Bool bActive = sal_True );
+ /// Set state of all children
+ void SetState( const sal_Int16 nStateId );
+ /// Unset state of all children
+ void UnSetState( const sal_Int16 nStateId );
+ /// Set offset to edit engine for all children
+ void SetEEOffset ( const Point& rOffset );
+ /// Change edit source on all living children
+ void SetEditSource ( SvxEditSourceAdapter* pEditSource );
+ /// Dispose all living children
+ void Dispose ();
+
+ // forwarder to given paragraphs
+ //------------------------------------------------------------------------
+ /** Release the given range of paragraphs
+
+ All ranges have the meaning [start,end), similar to STL
+
+ @param nStartPara
+ Index of paragraph to start with releasing
+
+ @param nEndPara
+ Index of first paragraph to stop with releasing
+ */
+ void Release( sal_uInt32 nStartPara, sal_uInt32 nEndPara );
+
+ /** Fire event for the given range of paragraphs
+
+ All ranges have the meaning [start,end), similar to STL
+
+ @param nStartPara
+ Index of paragraph to start with event firing
+
+ @param nEndPara
+ Index of first paragraph to stop with event firing
+ */
+ void FireEvent( sal_uInt32 nStartPara,
+ sal_uInt32 nEndPara,
+ const sal_Int16 nEventId,
+ const ::com::sun::star::uno::Any& rNewValue = ::com::sun::star::uno::Any(),
+ const ::com::sun::star::uno::Any& rOldValue = ::com::sun::star::uno::Any() ) const;
+
+ /** Functor adapter for ForEach template
+
+ Adapts giving functor such that only the paragraph objects
+ are accessed and the fact that our children are held
+ weakly is hidden
+
+ The functor must provide the following method:
+ void operator() ( AccessibleEditablePara& )
+
+ */
+ template < typename Functor > class WeakChildAdapter : public ::std::unary_function< const WeakChild&, void >
+ {
+ public:
+ WeakChildAdapter( Functor& rFunctor ) : mrFunctor(rFunctor) {}
+ void operator()( const WeakChild& rPara )
+ {
+ // retrieve hard reference from weak one
+ WeakPara::HardRefType aHardRef( rPara.first.get() );
+
+ if( aHardRef.is() )
+ mrFunctor( *aHardRef );
+ }
+
+ private:
+ Functor& mrFunctor;
+ };
+
+ /** Adapter for unary member functions
+
+ Since STL's binder don't work with const& arguments (and
+ BOOST's neither, at least on MSVC), have to provide our
+ own adapter for unary member functions.
+
+ Create with pointer to member function of
+ AccessibleEditableTextPara and the corresponding argument.
+ */
+ template < typename Argument > class MemFunAdapter : public ::std::unary_function< const WeakChild&, void >
+ {
+ public:
+ typedef void (::accessibility::AccessibleEditableTextPara::*FunctionPointer)( Argument );
+
+ MemFunAdapter( FunctionPointer aFunPtr, Argument aArg ) : maFunPtr(aFunPtr), maArg(aArg) {}
+ void operator()( const WeakChild& rPara )
+ {
+ // retrieve hard reference from weak one
+ WeakPara::HardRefType aHardRef( rPara.first.get() );
+
+ if( aHardRef.is() )
+ (*aHardRef.*maFunPtr)( maArg );
+ }
+
+ private:
+ FunctionPointer maFunPtr;
+ Argument maArg;
+ };
+
+ /** Generic algorithm on given paragraphs
+
+ Convenience method, that already adapts the given functor with WeakChildAdapter
+ */
+ template < typename Functor > void ForEach( Functor& rFunctor )
+ {
+ ::std::for_each( begin(), end(), WeakChildAdapter< Functor >(rFunctor) );
+ }
+
+ private:
+ /// Set state on given child
+ void SetState( sal_Int32 nChild, const sal_Int16 nStateId );
+ /// Unset state on given child
+ void UnSetState( sal_Int32 nChild, const sal_Int16 nStateId );
+ /// Init child with default state (as stored in previous SetFocus and SetActive calls)
+ void InitChild( AccessibleEditableTextPara& rChild,
+ SvxEditSourceAdapter& rEditSource,
+ sal_Int32 nChild,
+ sal_uInt32 nParagraphIndex ) const;
+
+ // vector the size of the paragraph number of the underlying EditEngine
+ VectorOfChildren maChildren;
+
+ /// Additional states that will be set at every created child object.
+ VectorOfStates maChildStates;
+
+ // cache EE offset for child creation
+ Point maEEOffset;
+
+ // which child currently has the focus (-1 for none)
+ sal_Int32 mnFocusedChild;
+
+ // whether children are active and editable
+ sal_Bool mbActive;
+ };
+
+} // end of namespace accessibility
+
+#endif
+
diff --git a/editeng/source/accessibility/AccessibleSelectionBase.cxx b/editeng/source/accessibility/AccessibleSelectionBase.cxx
new file mode 100644
index 0000000000..56054da0a8
--- /dev/null
+++ b/editeng/source/accessibility/AccessibleSelectionBase.cxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleSelectionBase.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <editeng/AccessibleSelectionBase.hxx>
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+namespace accessibility
+{
+ // ---------------------------
+ // - AccessibleSelectionBase -
+ // ---------------------------
+
+ AccessibleSelectionBase::AccessibleSelectionBase()
+ {
+ }
+
+ //--------------------------------------------------------------------
+
+ AccessibleSelectionBase::~AccessibleSelectionBase()
+ {
+ }
+
+ //--------------------------------------------------------------------
+
+ void SAL_CALL AccessibleSelectionBase::selectAccessibleChild( sal_Int32 nChildIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( implGetMutex() );
+ OCommonAccessibleSelection::selectAccessibleChild( nChildIndex );
+ }
+
+ //--------------------------------------------------------------------
+
+ sal_Bool SAL_CALL AccessibleSelectionBase::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( implGetMutex() );
+ return( OCommonAccessibleSelection::isAccessibleChildSelected( nChildIndex ) );
+ }
+
+ //--------------------------------------------------------------------
+
+ void SAL_CALL AccessibleSelectionBase::clearAccessibleSelection( ) throw (uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( implGetMutex() );
+ OCommonAccessibleSelection::clearAccessibleSelection();
+ }
+
+ //--------------------------------------------------------------------
+
+ void SAL_CALL AccessibleSelectionBase::selectAllAccessibleChildren( ) throw (uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( implGetMutex() );
+ OCommonAccessibleSelection::selectAllAccessibleChildren();
+ }
+
+ //--------------------------------------------------------------------
+
+ sal_Int32 SAL_CALL AccessibleSelectionBase::getSelectedAccessibleChildCount( ) throw (uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( implGetMutex() );
+ return( OCommonAccessibleSelection::getSelectedAccessibleChildCount() );
+ }
+
+ //--------------------------------------------------------------------
+
+ uno::Reference< XAccessible > SAL_CALL AccessibleSelectionBase::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( implGetMutex() );
+ return( OCommonAccessibleSelection::getSelectedAccessibleChild( nSelectedChildIndex ) );
+ }
+
+ //--------------------------------------------------------------------
+
+ void SAL_CALL AccessibleSelectionBase::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( implGetMutex() );
+ OCommonAccessibleSelection::deselectAccessibleChild( nSelectedChildIndex );
+ }
+}
diff --git a/editeng/source/accessibility/AccessibleStaticTextBase.cxx b/editeng/source/accessibility/AccessibleStaticTextBase.cxx
new file mode 100644
index 0000000000..1caa0e7392
--- /dev/null
+++ b/editeng/source/accessibility/AccessibleStaticTextBase.cxx
@@ -0,0 +1,1050 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleStaticTextBase.cxx,v $
+ * $Revision: 1.27 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+//------------------------------------------------------------------------
+//
+// Global header
+//
+//------------------------------------------------------------------------
+
+#include <limits.h>
+#include <vector>
+#include <algorithm>
+#include <boost/bind.hpp>
+#include <vos/mutex.hxx>
+#include <vcl/window.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/sequenceasvector.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/accessibility/AccessibleTextType.hpp>
+
+//------------------------------------------------------------------------
+//
+// Project-local header
+//
+//------------------------------------------------------------------------
+
+#include <editeng/editdata.hxx>
+#include <editeng/unopracc.hxx>
+#include "unoedprx.hxx"
+#include <editeng/AccessibleStaticTextBase.hxx>
+#include "AccessibleEditableTextPara.hxx"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+
+/* TODO:
+ =====
+
+ - separate adapter functionality from AccessibleStaticText class
+
+ - refactor common loops into templates, using mem_fun
+
+ */
+
+namespace accessibility
+{
+ typedef ::comphelper::SequenceAsVector< beans::PropertyValue > PropertyValueVector;
+
+ class PropertyValueEqualFunctor : public ::std::binary_function< beans::PropertyValue, beans::PropertyValue, bool >
+ {
+ public:
+ PropertyValueEqualFunctor()
+ {}
+ bool operator() ( const beans::PropertyValue& lhs, const beans::PropertyValue& rhs ) const
+ {
+ return ( lhs.Name == rhs.Name && lhs.Value == rhs.Value );
+ }
+ };
+
+ //------------------------------------------------------------------------
+ //
+ // Static Helper
+ //
+ //------------------------------------------------------------------------
+ ESelection MakeSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex,
+ sal_Int32 nEndPara, sal_Int32 nEndIndex )
+ {
+ DBG_ASSERT(nStartPara >= 0 && nStartPara <= USHRT_MAX &&
+ nStartIndex >= 0 && nStartIndex <= USHRT_MAX &&
+ nEndPara >= 0 && nEndPara <= USHRT_MAX &&
+ nEndIndex >= 0 && nEndIndex <= USHRT_MAX ,
+ "AccessibleStaticTextBase_Impl::MakeSelection: index value overflow");
+
+ return ESelection( static_cast< USHORT >(nStartPara), static_cast< USHORT >(nStartIndex),
+ static_cast< USHORT >(nEndPara), static_cast< USHORT >(nEndIndex) );
+ }
+
+ //------------------------------------------------------------------------
+ //
+ // AccessibleStaticTextBase_Impl declaration
+ //
+ //------------------------------------------------------------------------
+
+ DBG_NAME( AccessibleStaticTextBase_Impl );
+
+ /** AccessibleStaticTextBase_Impl
+
+ This class implements the AccessibleStaticTextBase
+ functionality, mainly by forwarding the calls to an aggregated
+ AccessibleEditableTextPara. As this is a therefore non-trivial
+ adapter, factoring out the common functionality from
+ AccessibleEditableTextPara might be a profitable future task.
+ */
+ class AccessibleStaticTextBase_Impl
+ {
+
+ public:
+
+ // receive pointer to our frontend class and view window
+ AccessibleStaticTextBase_Impl();
+ ~AccessibleStaticTextBase_Impl();
+
+ SvxEditSourceAdapter& GetEditSource() const SAL_THROW((uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
+
+ return maEditSource;
+ }
+ void SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((uno::RuntimeException));
+
+ void SetEventSource( const uno::Reference< XAccessible >& rInterface )
+ {
+ DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
+
+ mxThis = rInterface;
+ }
+ uno::Reference< XAccessible > GetEventSource() const
+ {
+ DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
+
+ return mxThis;
+ }
+
+ void SetOffset( const Point& );
+ Point GetOffset() const
+ {
+ DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
+
+ ::osl::MutexGuard aGuard( maMutex ); Point aPoint( maOffset );
+ return aPoint;
+ }
+
+ void UpdateChildren();
+ void Dispose();
+
+#ifdef DBG_UTIL
+ void CheckInvariants() const;
+#endif
+
+ AccessibleEditableTextPara& GetParagraph( sal_Int32 nPara ) const;
+ sal_Int32 GetParagraphCount() const;
+ sal_Int32 GetParagraphIndex() const;
+ sal_Int32 GetLineCount( sal_Int32 nParagraph ) const;
+
+ EPosition Index2Internal( sal_Int32 nFlatIndex ) const
+ {
+ DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
+
+ return ImpCalcInternal( nFlatIndex, false );
+ }
+
+ EPosition Range2Internal( sal_Int32 nFlatIndex ) const
+ {
+ DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
+
+ return ImpCalcInternal( nFlatIndex, true );
+ }
+
+ sal_Int32 Internal2Index( EPosition nEEIndex ) const;
+
+ void CorrectTextSegment( TextSegment& aTextSegment,
+ int nPara ) const;
+
+ sal_Bool SetSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex,
+ sal_Int32 nEndPara, sal_Int32 nEndIndex );
+ sal_Bool CopyText( sal_Int32 nStartPara, sal_Int32 nStartIndex,
+ sal_Int32 nEndPara, sal_Int32 nEndIndex );
+
+ Rectangle GetParagraphBoundingBox() const;
+
+ private:
+
+ EPosition ImpCalcInternal( sal_Int32 nFlatIndex, bool bExclusive ) const;
+
+ // our frontend class (the one implementing the actual
+ // interface). That's not necessarily the one containing the impl
+ // pointer
+ uno::Reference< XAccessible > mxThis;
+
+ // implements our functionality, we're just an adapter (guarded by solar mutex)
+ mutable AccessibleEditableTextPara* mpTextParagraph;
+
+ uno::Reference< XAccessible > mxParagraph;
+
+ // a wrapper for the text forwarders (guarded by solar mutex)
+ mutable SvxEditSourceAdapter maEditSource;
+
+ // guard for maOffset
+ mutable ::osl::Mutex maMutex;
+
+ /// our current offset to the containing shape/cell (guarded by maMutex)
+ Point maOffset;
+
+ };
+
+ //------------------------------------------------------------------------
+ //
+ // AccessibleStaticTextBase_Impl implementation
+ //
+ //------------------------------------------------------------------------
+
+ AccessibleStaticTextBase_Impl::AccessibleStaticTextBase_Impl() :
+ mxThis( NULL ),
+ mpTextParagraph( new AccessibleEditableTextPara(NULL) ),
+ mxParagraph( mpTextParagraph ),
+ maEditSource(),
+ maMutex(),
+ maOffset(0,0)
+ {
+ DBG_CTOR( AccessibleStaticTextBase_Impl, NULL );
+
+ // TODO: this is still somewhat of a hack, all the more since
+ // now the maTextParagraph has an empty parent reference set
+ }
+
+ AccessibleStaticTextBase_Impl::~AccessibleStaticTextBase_Impl()
+ {
+ DBG_DTOR( AccessibleStaticTextBase_Impl, NULL );
+ }
+
+ void AccessibleStaticTextBase_Impl::SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((uno::RuntimeException))
+ {
+ DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
+
+ maEditSource.SetEditSource( pEditSource );
+ if( mpTextParagraph )
+ mpTextParagraph->SetEditSource( &maEditSource );
+ }
+
+ void AccessibleStaticTextBase_Impl::SetOffset( const Point& rPoint )
+ {
+ DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
+
+ // guard against non-atomic access to maOffset data structure
+ {
+ ::osl::MutexGuard aGuard( maMutex );
+ maOffset = rPoint;
+ }
+
+ if( mpTextParagraph )
+ mpTextParagraph->SetEEOffset( rPoint );
+
+ // in all cases, check visibility afterwards.
+ UpdateChildren();
+ }
+
+ void AccessibleStaticTextBase_Impl::UpdateChildren()
+ {
+ DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
+
+ // currently no children
+ }
+
+ void AccessibleStaticTextBase_Impl::Dispose()
+ {
+ DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
+
+ // we're the owner of the paragraph, so destroy it, too
+ if( mpTextParagraph )
+ mpTextParagraph->Dispose();
+
+ // drop references
+ mxParagraph = NULL;
+ mxThis = NULL;
+ mpTextParagraph = NULL;
+ }
+
+#ifdef DBG_UTIL
+ void AccessibleStaticTextBase_Impl::CheckInvariants() const
+ {
+ // TODO
+ }
+#endif
+
+ AccessibleEditableTextPara& AccessibleStaticTextBase_Impl::GetParagraph( sal_Int32 nPara ) const
+ {
+ DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
+
+ if( !mpTextParagraph )
+ throw lang::DisposedException (
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")), mxThis );
+
+ // TODO: Have a differnt method on AccessibleEditableTextPara
+ // that does not care about state changes
+ mpTextParagraph->SetParagraphIndex( nPara );
+
+ return *mpTextParagraph;
+ }
+
+ sal_Int32 AccessibleStaticTextBase_Impl::GetParagraphCount() const
+ {
+ DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
+
+ if( !mpTextParagraph )
+ return 0;
+ else
+ return mpTextParagraph->GetTextForwarder().GetParagraphCount();
+ }
+
+ sal_Int32 AccessibleStaticTextBase_Impl::GetParagraphIndex() const
+ {
+ DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
+
+ sal_Int32 nIndex = -1;
+ if( mpTextParagraph )
+ nIndex = mpTextParagraph->GetParagraphIndex();
+ return nIndex;
+ }
+
+ sal_Int32 AccessibleStaticTextBase_Impl::GetLineCount( sal_Int32 nParagraph ) const
+ {
+ DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
+
+ sal_Int32 nIndex = 0;
+ if( mpTextParagraph )
+ nIndex = mpTextParagraph->GetTextForwarder().GetLineCount( static_cast< USHORT >(nParagraph) );
+ return nIndex;
+ }
+
+ sal_Int32 AccessibleStaticTextBase_Impl::Internal2Index( EPosition nEEIndex ) const
+ {
+ sal_Int32 aRes(0);
+ int i;
+ for(i=0; i<nEEIndex.nPara; ++i)
+ aRes += GetParagraph(i).getCharacterCount();
+
+ return aRes + nEEIndex.nIndex;
+ }
+
+ void AccessibleStaticTextBase_Impl::CorrectTextSegment( TextSegment& aTextSegment,
+ int nPara ) const
+ {
+ // Keep 'invalid' values at the TextSegment
+ if( aTextSegment.SegmentStart != -1 &&
+ aTextSegment.SegmentStart != -1 )
+ {
+ // #112814# Correct TextSegment by paragraph offset
+ sal_Int32 nOffset(0);
+ int i;
+ for(i=0; i<nPara; ++i)
+ nOffset += GetParagraph(i).getCharacterCount();
+
+ aTextSegment.SegmentStart += nOffset;
+ aTextSegment.SegmentEnd += nOffset;
+ }
+ }
+
+ EPosition AccessibleStaticTextBase_Impl::ImpCalcInternal( sal_Int32 nFlatIndex, bool bExclusive ) const
+ {
+ DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
+
+ if( nFlatIndex < 0 )
+ throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleStaticTextBase_Impl::Index2Internal: character index out of bounds")),
+ mxThis);
+ // gratuitously accepting larger indices here, AccessibleEditableTextPara will throw eventually
+
+ sal_Int32 nCurrPara, nCurrIndex, nParas, nCurrCount;
+ for( nCurrPara=0, nParas=GetParagraphCount(), nCurrCount=0, nCurrIndex=0; nCurrPara<nParas; ++nCurrPara )
+ {
+ nCurrCount = GetParagraph( nCurrPara ).getCharacterCount();
+ nCurrIndex += nCurrCount;
+
+ if( nCurrIndex > nFlatIndex )
+ {
+ // check overflow
+ DBG_ASSERT(nCurrPara >= 0 && nCurrPara <= USHRT_MAX &&
+ nFlatIndex - nCurrIndex + nCurrCount >= 0 && nFlatIndex - nCurrIndex + nCurrCount <= USHRT_MAX ,
+ "AccessibleStaticTextBase_Impl::Index2Internal: index value overflow");
+
+ return EPosition( static_cast< USHORT >(nCurrPara), static_cast< USHORT >(nFlatIndex - nCurrIndex + nCurrCount) );
+ }
+ }
+
+ // #102170# Allow one-past the end for ranges
+ if( bExclusive && nCurrIndex == nFlatIndex )
+ {
+ // check overflow
+ DBG_ASSERT(nCurrPara >= 0 && nCurrPara <= USHRT_MAX &&
+ nFlatIndex - nCurrIndex + nCurrCount >= 0 && nFlatIndex - nCurrIndex + nCurrCount <= USHRT_MAX ,
+ "AccessibleStaticTextBase_Impl::Index2Internal: index value overflow");
+
+ return EPosition( static_cast< USHORT >(nCurrPara-1), static_cast< USHORT >(nFlatIndex - nCurrIndex + nCurrCount) );
+ }
+
+ // not found? Out of bounds
+ throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleStaticTextBase_Impl::Index2Internal: character index out of bounds")),
+ mxThis);
+ }
+
+ sal_Bool AccessibleStaticTextBase_Impl::SetSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex,
+ sal_Int32 nEndPara, sal_Int32 nEndIndex )
+ {
+ DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
+
+ if( !mpTextParagraph )
+ return sal_False;
+
+ try
+ {
+ SvxEditViewForwarder& rCacheVF = mpTextParagraph->GetEditViewForwarder( sal_True );
+ return rCacheVF.SetSelection( MakeSelection(nStartPara, nStartIndex, nEndPara, nEndIndex) );
+ }
+ catch( const uno::RuntimeException& )
+ {
+ return sal_False;
+ }
+ }
+
+ sal_Bool AccessibleStaticTextBase_Impl::CopyText( sal_Int32 nStartPara, sal_Int32 nStartIndex,
+ sal_Int32 nEndPara, sal_Int32 nEndIndex )
+ {
+ DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
+
+ if( !mpTextParagraph )
+ return sal_False;
+
+ try
+ {
+ SvxEditViewForwarder& rCacheVF = mpTextParagraph->GetEditViewForwarder( sal_True );
+ mpTextParagraph->GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
+ sal_Bool aRetVal;
+
+ // save current selection
+ ESelection aOldSelection;
+
+ rCacheVF.GetSelection( aOldSelection );
+ rCacheVF.SetSelection( MakeSelection(nStartPara, nStartIndex, nEndPara, nEndIndex) );
+ aRetVal = rCacheVF.Copy();
+ rCacheVF.SetSelection( aOldSelection ); // restore
+
+ return aRetVal;
+ }
+ catch( const uno::RuntimeException& )
+ {
+ return sal_False;
+ }
+ }
+
+ Rectangle AccessibleStaticTextBase_Impl::GetParagraphBoundingBox() const
+ {
+ Rectangle aRect;
+ if( mpTextParagraph )
+ {
+ awt::Rectangle aAwtRect = mpTextParagraph->getBounds();
+ aRect = Rectangle( Point( aAwtRect.X, aAwtRect.Y ), Size( aAwtRect.Width, aAwtRect.Height ) );
+ }
+ else
+ {
+ aRect.SetEmpty();
+ }
+ return aRect;
+ }
+
+ //------------------------------------------------------------------------
+ //
+ // AccessibleStaticTextBase implementation
+ //
+ //------------------------------------------------------------------------
+
+ AccessibleStaticTextBase::AccessibleStaticTextBase( ::std::auto_ptr< SvxEditSource > pEditSource ) :
+ mpImpl( new AccessibleStaticTextBase_Impl() )
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ SetEditSource( pEditSource );
+ }
+
+ AccessibleStaticTextBase::~AccessibleStaticTextBase()
+ {
+ }
+
+ const SvxEditSource& AccessibleStaticTextBase::GetEditSource() const SAL_THROW((::com::sun::star::uno::RuntimeException))
+ {
+#ifdef DBG_UTIL
+ mpImpl->CheckInvariants();
+
+ const SvxEditSource& aEditSource = mpImpl->GetEditSource();
+
+ mpImpl->CheckInvariants();
+
+ return aEditSource;
+#else
+ return mpImpl->GetEditSource();
+#endif
+ }
+
+ void AccessibleStaticTextBase::SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((::com::sun::star::uno::RuntimeException))
+ {
+#ifdef DBG_UTIL
+ // precondition: solar mutex locked
+ DBG_TESTSOLARMUTEX();
+
+ mpImpl->CheckInvariants();
+
+ mpImpl->SetEditSource( pEditSource );
+
+ mpImpl->CheckInvariants();
+#else
+ mpImpl->SetEditSource( pEditSource );
+#endif
+ }
+
+ void AccessibleStaticTextBase::SetEventSource( const uno::Reference< XAccessible >& rInterface )
+ {
+#ifdef DBG_UTIL
+ mpImpl->CheckInvariants();
+#endif
+
+ mpImpl->SetEventSource( rInterface );
+
+#ifdef DBG_UTIL
+ mpImpl->CheckInvariants();
+#endif
+ }
+
+ uno::Reference< XAccessible > AccessibleStaticTextBase::GetEventSource() const
+ {
+#ifdef DBG_UTIL
+ mpImpl->CheckInvariants();
+
+ uno::Reference< XAccessible > xRet( mpImpl->GetEventSource() );
+
+ mpImpl->CheckInvariants();
+
+ return xRet;
+#else
+ return mpImpl->GetEventSource();
+#endif
+ }
+
+ void AccessibleStaticTextBase::SetOffset( const Point& rPoint )
+ {
+#ifdef DBG_UTIL
+ // precondition: solar mutex locked
+ DBG_TESTSOLARMUTEX();
+
+ mpImpl->CheckInvariants();
+
+ mpImpl->SetOffset( rPoint );
+
+ mpImpl->CheckInvariants();
+#else
+ mpImpl->SetOffset( rPoint );
+#endif
+ }
+
+ Point AccessibleStaticTextBase::GetOffset() const
+ {
+#ifdef DBG_UTIL
+ mpImpl->CheckInvariants();
+
+ Point aPoint( mpImpl->GetOffset() );
+
+ mpImpl->CheckInvariants();
+
+ return aPoint;
+#else
+ return mpImpl->GetOffset();
+#endif
+ }
+
+ void AccessibleStaticTextBase::UpdateChildren() SAL_THROW((::com::sun::star::uno::RuntimeException))
+ {
+#ifdef DBG_UTIL
+ // precondition: solar mutex locked
+ DBG_TESTSOLARMUTEX();
+
+ mpImpl->CheckInvariants();
+
+ mpImpl->UpdateChildren();
+
+ mpImpl->CheckInvariants();
+#else
+ mpImpl->UpdateChildren();
+#endif
+ }
+
+ void AccessibleStaticTextBase::Dispose()
+ {
+#ifdef DBG_UTIL
+ mpImpl->CheckInvariants();
+#endif
+
+ mpImpl->Dispose();
+
+#ifdef DBG_UTIL
+ mpImpl->CheckInvariants();
+#endif
+ }
+
+ // XAccessibleContext
+ sal_Int32 SAL_CALL AccessibleStaticTextBase::getAccessibleChildCount() throw (uno::RuntimeException)
+ {
+ // no children at all
+ return 0;
+ }
+
+ uno::Reference< XAccessible > SAL_CALL AccessibleStaticTextBase::getAccessibleChild( sal_Int32 /*i*/ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ // no children at all
+ return uno::Reference< XAccessible >();
+ }
+
+ uno::Reference< XAccessible > SAL_CALL AccessibleStaticTextBase::getAccessibleAtPoint( const awt::Point& /*_aPoint*/ ) throw (uno::RuntimeException)
+ {
+ // no children at all
+ return uno::Reference< XAccessible >();
+ }
+
+ // XAccessibleText
+ sal_Int32 SAL_CALL AccessibleStaticTextBase::getCaretPosition() throw (uno::RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ sal_Int32 i, nPos, nParas;
+ for( i=0, nPos=-1, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
+ {
+ if( (nPos=mpImpl->GetParagraph(i).getCaretPosition()) != -1 )
+ return nPos;
+ }
+
+ return nPos;
+ }
+
+ sal_Bool SAL_CALL AccessibleStaticTextBase::setCaretPosition( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ return setSelection(nIndex, nIndex);
+ }
+
+ sal_Unicode SAL_CALL AccessibleStaticTextBase::getCharacter( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ EPosition aPos( mpImpl->Index2Internal(nIndex) );
+
+ return mpImpl->GetParagraph( aPos.nPara ).getCharacter( aPos.nIndex );
+ }
+
+ uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleStaticTextBase::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aRequestedAttributes ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ EPosition aPos( mpImpl->Index2Internal(nIndex) );
+
+ return mpImpl->GetParagraph( aPos.nPara ).getCharacterAttributes( aPos.nIndex, aRequestedAttributes );
+ }
+
+ awt::Rectangle SAL_CALL AccessibleStaticTextBase::getCharacterBounds( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ // #108900# Allow ranges for nIndex, as one-past-the-end
+ // values are now legal, too.
+ EPosition aPos( mpImpl->Range2Internal(nIndex) );
+
+ // #i70916# Text in spread sheet cells return the wrong extents
+ AccessibleEditableTextPara& rPara = mpImpl->GetParagraph( aPos.nPara );
+ awt::Rectangle aParaBounds( rPara.getBounds() );
+ awt::Rectangle aBounds( rPara.getCharacterBounds( aPos.nIndex ) );
+ aBounds.X += aParaBounds.X;
+ aBounds.Y += aParaBounds.Y;
+
+ return aBounds;
+ }
+
+ sal_Int32 SAL_CALL AccessibleStaticTextBase::getCharacterCount() throw (uno::RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ sal_Int32 i, nCount, nParas;
+ for( i=0, nCount=0, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
+ nCount += mpImpl->GetParagraph(i).getCharacterCount();
+
+ return nCount;
+ }
+
+ sal_Int32 SAL_CALL AccessibleStaticTextBase::getIndexAtPoint( const awt::Point& rPoint ) throw (uno::RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const sal_Int32 nParas( mpImpl->GetParagraphCount() );
+ sal_Int32 nIndex;
+ int i;
+ for( i=0; i<nParas; ++i )
+ {
+ // TODO: maybe exploit the fact that paragraphs are
+ // ordered vertically for early exit
+
+ // #i70916# Text in spread sheet cells return the wrong extents
+ AccessibleEditableTextPara& rPara = mpImpl->GetParagraph( i );
+ awt::Rectangle aParaBounds( rPara.getBounds() );
+ awt::Point aPoint( rPoint );
+ aPoint.X -= aParaBounds.X;
+ aPoint.Y -= aParaBounds.Y;
+
+ // #112814# Use correct index offset
+ if ( ( nIndex = rPara.getIndexAtPoint( aPoint ) ) != -1 )
+ return mpImpl->Internal2Index( EPosition(sal::static_int_cast<USHORT>(i),
+ sal::static_int_cast<USHORT>(nIndex)) );
+ }
+
+ return -1;
+ }
+
+ ::rtl::OUString SAL_CALL AccessibleStaticTextBase::getSelectedText() throw (uno::RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ sal_Int32 nStart( getSelectionStart() );
+ sal_Int32 nEnd( getSelectionEnd() );
+
+ // #104481# Return the empty string for 'no selection'
+ if( nStart < 0 || nEnd < 0 )
+ return ::rtl::OUString();
+
+ return getTextRange( nStart, nEnd );
+ }
+
+ sal_Int32 SAL_CALL AccessibleStaticTextBase::getSelectionStart() throw (uno::RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ sal_Int32 i, nPos, nParas;
+ for( i=0, nPos=-1, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
+ {
+ if( (nPos=mpImpl->GetParagraph(i).getSelectionStart()) != -1 )
+ return nPos;
+ }
+
+ return nPos;
+ }
+
+ sal_Int32 SAL_CALL AccessibleStaticTextBase::getSelectionEnd() throw (uno::RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ sal_Int32 i, nPos, nParas;
+ for( i=0, nPos=-1, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
+ {
+ if( (nPos=mpImpl->GetParagraph(i).getSelectionEnd()) != -1 )
+ return nPos;
+ }
+
+ return nPos;
+ }
+
+ sal_Bool SAL_CALL AccessibleStaticTextBase::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ EPosition aStartIndex( mpImpl->Range2Internal(nStartIndex) );
+ EPosition aEndIndex( mpImpl->Range2Internal(nEndIndex) );
+
+ return mpImpl->SetSelection( aStartIndex.nPara, aStartIndex.nIndex,
+ aEndIndex.nPara, aEndIndex.nIndex );
+ }
+
+ ::rtl::OUString SAL_CALL AccessibleStaticTextBase::getText() throw (uno::RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ sal_Int32 i, nParas;
+ ::rtl::OUString aRes;
+ for( i=0, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
+ aRes += mpImpl->GetParagraph(i).getText();
+
+ return aRes;
+ }
+
+ ::rtl::OUString SAL_CALL AccessibleStaticTextBase::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if( nStartIndex > nEndIndex )
+ ::std::swap(nStartIndex, nEndIndex);
+
+ EPosition aStartIndex( mpImpl->Range2Internal(nStartIndex) );
+ EPosition aEndIndex( mpImpl->Range2Internal(nEndIndex) );
+
+ // #102170# Special case: start and end paragraph are identical
+ if( aStartIndex.nPara == aEndIndex.nPara )
+ {
+ return mpImpl->GetParagraph( aStartIndex.nPara ).getTextRange( aStartIndex.nIndex, aEndIndex.nIndex );
+ }
+ else
+ {
+ sal_Int32 i( aStartIndex.nPara );
+ ::rtl::OUString aRes( mpImpl->GetParagraph(i).getTextRange( aStartIndex.nIndex,
+ mpImpl->GetParagraph(i).getCharacterCount()-1) );
+ ++i;
+
+ // paragraphs inbetween are fully included
+ for( ; i<aEndIndex.nPara; ++i )
+ aRes += mpImpl->GetParagraph(i).getText();
+
+ if( i<=aEndIndex.nPara )
+ aRes += mpImpl->GetParagraph(i).getTextRange( 0, aEndIndex.nIndex );
+
+ return aRes;
+ }
+ }
+
+ ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ EPosition aPos( mpImpl->Range2Internal(nIndex) );
+
+ ::com::sun::star::accessibility::TextSegment aResult;
+
+ if( AccessibleTextType::PARAGRAPH == aTextType )
+ {
+ // #106393# Special casing one behind last paragraph is
+ // not necessary, since then, we return the content and
+ // boundary of that last paragraph. Range2Internal is
+ // tolerant against that, and returns the last paragraph
+ // in aPos.nPara.
+
+ // retrieve full text of the paragraph
+ aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara ).getText();
+
+ // #112814# Adapt the start index with the paragraph offset
+ aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara, 0 ) );
+ aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
+ }
+ else
+ {
+ // No special handling required, forward to wrapped class
+ aResult = mpImpl->GetParagraph( aPos.nPara ).getTextAtIndex( aPos.nIndex, aTextType );
+
+ // #112814# Adapt the start index with the paragraph offset
+ mpImpl->CorrectTextSegment( aResult, aPos.nPara );
+ }
+
+ return aResult;
+ }
+
+ ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ EPosition aPos( mpImpl->Range2Internal(nIndex) );
+
+ ::com::sun::star::accessibility::TextSegment aResult;
+
+ if( AccessibleTextType::PARAGRAPH == aTextType )
+ {
+ if( aPos.nIndex == mpImpl->GetParagraph( aPos.nPara ).getCharacterCount() )
+ {
+ // #103589# Special casing one behind the last paragraph
+ aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara ).getText();
+
+ // #112814# Adapt the start index with the paragraph offset
+ aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara, 0 ) );
+ }
+ else if( aPos.nPara > 0 )
+ {
+ aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara - 1 ).getText();
+
+ // #112814# Adapt the start index with the paragraph offset
+ aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara - 1, 0 ) );
+ }
+
+ aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
+ }
+ else
+ {
+ // No special handling required, forward to wrapped class
+ aResult = mpImpl->GetParagraph( aPos.nPara ).getTextBeforeIndex( aPos.nIndex, aTextType );
+
+ // #112814# Adapt the start index with the paragraph offset
+ mpImpl->CorrectTextSegment( aResult, aPos.nPara );
+ }
+
+ return aResult;
+ }
+
+ ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ EPosition aPos( mpImpl->Range2Internal(nIndex) );
+
+ ::com::sun::star::accessibility::TextSegment aResult;
+
+ if( AccessibleTextType::PARAGRAPH == aTextType )
+ {
+ // Special casing one behind the last paragraph is not
+ // necessary, this case is invalid here for
+ // getTextBehindIndex
+ if( aPos.nPara + 1 < mpImpl->GetParagraphCount() )
+ {
+ aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara + 1 ).getText();
+
+ // #112814# Adapt the start index with the paragraph offset
+ aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara + 1, 0 ) );
+ aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
+ }
+ }
+ else
+ {
+ // No special handling required, forward to wrapped class
+ aResult = mpImpl->GetParagraph( aPos.nPara ).getTextBehindIndex( aPos.nIndex, aTextType );
+
+ // #112814# Adapt the start index with the paragraph offset
+ mpImpl->CorrectTextSegment( aResult, aPos.nPara );
+ }
+
+ return aResult;
+ }
+
+ sal_Bool SAL_CALL AccessibleStaticTextBase::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if( nStartIndex > nEndIndex )
+ ::std::swap(nStartIndex, nEndIndex);
+
+ EPosition aStartIndex( mpImpl->Range2Internal(nStartIndex) );
+ EPosition aEndIndex( mpImpl->Range2Internal(nEndIndex) );
+
+ return mpImpl->CopyText( aStartIndex.nPara, aStartIndex.nIndex,
+ aEndIndex.nPara, aEndIndex.nIndex );
+ }
+
+ // XAccessibleTextAttributes
+ uno::Sequence< beans::PropertyValue > AccessibleStaticTextBase::getDefaultAttributes( const uno::Sequence< ::rtl::OUString >& RequestedAttributes ) throw (uno::RuntimeException)
+ {
+ // get the intersection of the default attributes of all paragraphs
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ PropertyValueVector aDefAttrVec( mpImpl->GetParagraph( 0 ).getDefaultAttributes( RequestedAttributes ) );
+
+ const sal_Int32 nParaCount = mpImpl->GetParagraphCount();
+ for ( sal_Int32 nPara = 1; nPara < nParaCount; ++nPara )
+ {
+ uno::Sequence< beans::PropertyValue > aSeq = mpImpl->GetParagraph( nPara ).getDefaultAttributes( RequestedAttributes );
+ PropertyValueVector aIntersectionVec;
+
+ PropertyValueVector::const_iterator aEnd = aDefAttrVec.end();
+ for ( PropertyValueVector::const_iterator aItr = aDefAttrVec.begin(); aItr != aEnd; ++aItr )
+ {
+ const beans::PropertyValue* pItr = aSeq.getConstArray();
+ const beans::PropertyValue* pEnd = pItr + aSeq.getLength();
+ const beans::PropertyValue* pFind = ::std::find_if( pItr, pEnd, ::std::bind2nd( PropertyValueEqualFunctor(), boost::cref( *aItr ) ) );
+ if ( pFind != pEnd )
+ {
+ aIntersectionVec.push_back( *pFind );
+ }
+ }
+
+ aDefAttrVec.swap( aIntersectionVec );
+
+ if ( aDefAttrVec.empty() )
+ {
+ break;
+ }
+ }
+
+ return aDefAttrVec.getAsConstList();
+ }
+
+ uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleStaticTextBase::getRunAttributes( sal_Int32 nIndex, const uno::Sequence< ::rtl::OUString >& RequestedAttributes ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+ {
+ // get those default attributes of the paragraph, which are not part
+ // of the intersection of all paragraphs and add them to the run attributes
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ EPosition aPos( mpImpl->Index2Internal( nIndex ) );
+ AccessibleEditableTextPara& rPara = mpImpl->GetParagraph( aPos.nPara );
+ uno::Sequence< beans::PropertyValue > aDefAttrSeq = rPara.getDefaultAttributes( RequestedAttributes );
+ uno::Sequence< beans::PropertyValue > aRunAttrSeq = rPara.getRunAttributes( aPos.nIndex, RequestedAttributes );
+ uno::Sequence< beans::PropertyValue > aIntersectionSeq = getDefaultAttributes( RequestedAttributes );
+ PropertyValueVector aDiffVec;
+
+ const beans::PropertyValue* pDefAttr = aDefAttrSeq.getConstArray();
+ const sal_Int32 nLength = aDefAttrSeq.getLength();
+ for ( sal_Int32 i = 0; i < nLength; ++i )
+ {
+ const beans::PropertyValue* pItr = aIntersectionSeq.getConstArray();
+ const beans::PropertyValue* pEnd = pItr + aIntersectionSeq.getLength();
+ const beans::PropertyValue* pFind = ::std::find_if( pItr, pEnd, ::std::bind2nd( PropertyValueEqualFunctor(), boost::cref( pDefAttr[i] ) ) );
+ if ( pFind == pEnd && pDefAttr[i].Handle != 0)
+ {
+ aDiffVec.push_back( pDefAttr[i] );
+ }
+ }
+
+ return ::comphelper::concatSequences( aRunAttrSeq, aDiffVec.getAsConstList() );
+ }
+
+ Rectangle AccessibleStaticTextBase::GetParagraphBoundingBox() const
+ {
+ return mpImpl->GetParagraphBoundingBox();
+ }
+
+ sal_Int32 AccessibleStaticTextBase::GetParagraphIndex() const
+ {
+ return mpImpl->GetParagraphIndex();
+ }
+
+ sal_Int32 AccessibleStaticTextBase::GetParagraphCount() const
+ {
+ return mpImpl->GetParagraphCount();
+ }
+
+ sal_Int32 AccessibleStaticTextBase::GetLineCount( sal_Int32 nParagraph ) const
+ {
+ return mpImpl->GetLineCount( nParagraph );
+ }
+
+} // end of namespace accessibility
+
+//------------------------------------------------------------------------
diff --git a/editeng/source/accessibility/AccessibleStringWrap.cxx b/editeng/source/accessibility/AccessibleStringWrap.cxx
new file mode 100644
index 0000000000..22cd0e1cf4
--- /dev/null
+++ b/editeng/source/accessibility/AccessibleStringWrap.cxx
@@ -0,0 +1,103 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleStringWrap.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <algorithm>
+#include <tools/debug.hxx>
+#include <vcl/outdev.hxx>
+
+#include <editeng/svxfont.hxx>
+#include <editeng/AccessibleStringWrap.hxx>
+
+//------------------------------------------------------------------------
+//
+// AccessibleStringWrap implementation
+//
+//------------------------------------------------------------------------
+
+AccessibleStringWrap::AccessibleStringWrap( OutputDevice& rDev, SvxFont& rFont, const String& rText ) :
+ mrDev( rDev ),
+ mrFont( rFont ),
+ maText( rText )
+{
+}
+
+sal_Bool AccessibleStringWrap::GetCharacterBounds( sal_Int32 nIndex, Rectangle& rRect )
+{
+ DBG_ASSERT(nIndex >= 0 && nIndex <= USHRT_MAX,
+ "SvxAccessibleStringWrap::GetCharacterBounds: index value overflow");
+
+ mrFont.SetPhysFont( &mrDev );
+
+ // #108900# Handle virtual position one-past-the end of the string
+ if( nIndex >= maText.Len() )
+ {
+ // create a caret bounding rect that has the height of the
+ // current font and is one pixel wide.
+ rRect.Left() = mrDev.GetTextWidth(maText);
+ rRect.Top() = 0;
+ rRect.SetSize( Size(mrDev.GetTextHeight(), 1) );
+ }
+ else
+ {
+ sal_Int32 aXArray[2];
+ mrDev.GetCaretPositions( maText, aXArray, static_cast< USHORT >(nIndex), 1 );
+ rRect.Left() = 0;
+ rRect.Top() = 0;
+ rRect.SetSize( Size(mrDev.GetTextHeight(), labs(aXArray[0] - aXArray[1])) );
+ rRect.Move( ::std::min(aXArray[0], aXArray[1]), 0 );
+ }
+
+ if( mrFont.IsVertical() )
+ {
+ // #101701# Rotate to vertical
+ rRect = Rectangle( Point(-rRect.Top(), rRect.Left()),
+ Point(-rRect.Bottom(), rRect.Right()));
+ }
+
+ return sal_True;
+}
+
+sal_Int32 AccessibleStringWrap::GetIndexAtPoint( const Point& rPoint )
+{
+ // search for character bounding box containing given point
+ Rectangle aRect;
+ sal_Int32 i, nLen = maText.Len();
+ for( i=0; i<nLen; ++i )
+ {
+ GetCharacterBounds(i, aRect);
+ if( aRect.IsInside(rPoint) )
+ return i;
+ }
+
+ return -1;
+}
diff --git a/editeng/source/accessibility/accessibility.src b/editeng/source/accessibility/accessibility.src
new file mode 100644
index 0000000000..51d2a49e6e
--- /dev/null
+++ b/editeng/source/accessibility/accessibility.src
@@ -0,0 +1,43 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: accessibility.src,v $
+ * $Revision: 1.34 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "editeng.hrc"
+
+String RID_SVXSTR_A11Y_IMAGEBULLET_DESCRIPTION
+{
+ Text [ en-US ] = "Image bullet in paragraph" ;
+};
+
+String RID_SVXSTR_A11Y_IMAGEBULLET_NAME
+{
+ Text [ en-US ] = "Image bullet" ;
+};
+
+
diff --git a/editeng/source/accessibility/makefile.mk b/editeng/source/accessibility/makefile.mk
new file mode 100755
index 0000000000..e29b6477f6
--- /dev/null
+++ b/editeng/source/accessibility/makefile.mk
@@ -0,0 +1,58 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.25 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=editeng
+TARGET=accessibility
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/AccessibleStringWrap.obj \
+ $(SLO)$/AccessibleContextBase.obj \
+ $(SLO)$/AccessibleComponentBase.obj \
+ $(SLO)$/AccessibleSelectionBase.obj \
+ $(SLO)$/AccessibleStaticTextBase.obj \
+ $(SLO)$/AccessibleParaManager.obj \
+ $(SLO)$/AccessibleEditableTextPara.obj \
+ $(SLO)$/AccessibleImageBullet.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/editeng/source/editeng/editattr.cxx b/editeng/source/editeng/editattr.cxx
new file mode 100644
index 0000000000..12b91d8f2d
--- /dev/null
+++ b/editeng/source/editeng/editattr.cxx
@@ -0,0 +1,457 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: editattr.cxx,v $
+ * $Revision: 1.16.212.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+//#include <eeng_pch.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+
+#include <editeng/svxfont.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/cscoitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/akrnitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/emphitem.hxx>
+#include <editeng/charscaleitem.hxx>
+#include <editeng/charreliefitem.hxx>
+
+#include "editattr.hxx"
+
+DBG_NAME( EE_EditAttrib )
+
+// -------------------------------------------------------------------------
+// class EditAttrib
+// -------------------------------------------------------------------------
+EditAttrib::EditAttrib( const SfxPoolItem& rAttr )
+{
+ DBG_CTOR( EE_EditAttrib, 0 );
+ pItem = &rAttr;
+}
+
+EditAttrib::~EditAttrib()
+{
+ DBG_DTOR( EE_EditAttrib, 0 );
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttrib
+// -------------------------------------------------------------------------
+EditCharAttrib::EditCharAttrib( const SfxPoolItem& rAttr, USHORT nS, USHORT nE )
+ : EditAttrib( rAttr )
+{
+ nStart = nS;
+ nEnd = nE;
+ bFeature = FALSE;
+ bEdge = FALSE;
+
+ DBG_ASSERT( ( rAttr.Which() >= EE_ITEMS_START ) && ( rAttr.Which() <= EE_ITEMS_END ), "EditCharAttrib CTOR: Invalid id!" );
+ DBG_ASSERT( ( rAttr.Which() < EE_FEATURE_START ) || ( rAttr.Which() > EE_FEATURE_END ) || ( nE == (nS+1) ), "EditCharAttrib CTOR: Invalid feature!" );
+}
+
+void EditCharAttrib::SetFont( SvxFont&, OutputDevice* )
+{
+}
+
+
+// -------------------------------------------------------------------------
+// class EditCharAttribFont
+// -------------------------------------------------------------------------
+EditCharAttribFont::EditCharAttribFont( const SvxFontItem& rAttr, USHORT _nStart, USHORT _nEnd )
+ : EditCharAttrib( rAttr, _nStart, _nEnd )
+{
+ DBG_ASSERT( rAttr.Which() == EE_CHAR_FONTINFO || rAttr.Which() == EE_CHAR_FONTINFO_CJK || rAttr.Which() == EE_CHAR_FONTINFO_CTL, "Kein Fontattribut!" );
+}
+
+void EditCharAttribFont::SetFont( SvxFont& rFont, OutputDevice* )
+{
+ const SvxFontItem& rAttr = (const SvxFontItem&)(*GetItem());
+
+ rFont.SetName( rAttr.GetFamilyName() );
+ rFont.SetFamily( rAttr.GetFamily() );
+ rFont.SetPitch( rAttr.GetPitch() );
+ rFont.SetCharSet( rAttr.GetCharSet() );
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribItalic
+// -------------------------------------------------------------------------
+EditCharAttribItalic::EditCharAttribItalic( const SvxPostureItem& rAttr, USHORT _nStart, USHORT _nEnd )
+ : EditCharAttrib( rAttr, _nStart, _nEnd )
+{
+ DBG_ASSERT( rAttr.Which() == EE_CHAR_ITALIC || rAttr.Which() == EE_CHAR_ITALIC_CJK || rAttr.Which() == EE_CHAR_ITALIC_CTL, "Kein Italicattribut!" );
+}
+
+void EditCharAttribItalic::SetFont( SvxFont& rFont, OutputDevice* )
+{
+ rFont.SetItalic( ((const SvxPostureItem*)GetItem())->GetPosture() );
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribWeight
+// -------------------------------------------------------------------------
+EditCharAttribWeight::EditCharAttribWeight( const SvxWeightItem& rAttr, USHORT _nStart, USHORT _nEnd )
+ : EditCharAttrib( rAttr, _nStart, _nEnd )
+{
+ DBG_ASSERT( rAttr.Which() == EE_CHAR_WEIGHT || rAttr.Which() == EE_CHAR_WEIGHT_CJK || rAttr.Which() == EE_CHAR_WEIGHT_CTL, "Kein Weightttribut!" );
+}
+
+void EditCharAttribWeight::SetFont( SvxFont& rFont, OutputDevice* )
+{
+ rFont.SetWeight( (FontWeight)((const SvxWeightItem*)GetItem())->GetValue() );
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribUnderline
+// -------------------------------------------------------------------------
+EditCharAttribUnderline::EditCharAttribUnderline( const SvxUnderlineItem& rAttr, USHORT _nStart, USHORT _nEnd )
+ : EditCharAttrib( rAttr, _nStart, _nEnd )
+{
+ DBG_ASSERT( rAttr.Which() == EE_CHAR_UNDERLINE, "Kein Underlineattribut!" );
+}
+
+void EditCharAttribUnderline::SetFont( SvxFont& rFont, OutputDevice* pOutDev )
+{
+ rFont.SetUnderline( (FontUnderline)((const SvxUnderlineItem*)GetItem())->GetValue() );
+ if ( pOutDev )
+ pOutDev->SetTextLineColor( ((const SvxUnderlineItem*)GetItem())->GetColor() );
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribOverline
+// -------------------------------------------------------------------------
+EditCharAttribOverline::EditCharAttribOverline( const SvxOverlineItem& rAttr, USHORT _nStart, USHORT _nEnd )
+ : EditCharAttrib( rAttr, _nStart, _nEnd )
+{
+ DBG_ASSERT( rAttr.Which() == EE_CHAR_OVERLINE, "Kein Overlineattribut!" );
+}
+
+void EditCharAttribOverline::SetFont( SvxFont& rFont, OutputDevice* pOutDev )
+{
+ rFont.SetOverline( (FontUnderline)((const SvxOverlineItem*)GetItem())->GetValue() );
+ if ( pOutDev )
+ pOutDev->SetOverlineColor( ((const SvxOverlineItem*)GetItem())->GetColor() );
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribFontHeight
+// -------------------------------------------------------------------------
+EditCharAttribFontHeight::EditCharAttribFontHeight( const SvxFontHeightItem& rAttr, USHORT _nStart, USHORT _nEnd )
+ : EditCharAttrib( rAttr, _nStart, _nEnd )
+{
+ DBG_ASSERT( rAttr.Which() == EE_CHAR_FONTHEIGHT || rAttr.Which() == EE_CHAR_FONTHEIGHT_CJK || rAttr.Which() == EE_CHAR_FONTHEIGHT_CTL, "Kein Heightattribut!" );
+}
+
+void EditCharAttribFontHeight::SetFont( SvxFont& rFont, OutputDevice* )
+{
+ // Prop wird ignoriert
+ rFont.SetSize( Size( rFont.GetSize().Width(), ((const SvxFontHeightItem*)GetItem())->GetHeight() ) );
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribFontWidth
+// -------------------------------------------------------------------------
+EditCharAttribFontWidth::EditCharAttribFontWidth( const SvxCharScaleWidthItem& rAttr, USHORT _nStart, USHORT _nEnd )
+ : EditCharAttrib( rAttr, _nStart, _nEnd )
+{
+ DBG_ASSERT( rAttr.Which() == EE_CHAR_FONTWIDTH, "Kein Widthattribut!" );
+}
+
+void EditCharAttribFontWidth::SetFont( SvxFont& /*rFont*/, OutputDevice* )
+{
+ // must be calculated outside, because f(device)...
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribStrikeout
+// -------------------------------------------------------------------------
+EditCharAttribStrikeout::EditCharAttribStrikeout( const SvxCrossedOutItem& rAttr, USHORT _nStart, USHORT _nEnd )
+ : EditCharAttrib( rAttr, _nStart, _nEnd )
+{
+ DBG_ASSERT( rAttr.Which() == EE_CHAR_STRIKEOUT, "Kein Sizeattribut!" );
+}
+
+void EditCharAttribStrikeout::SetFont( SvxFont& rFont, OutputDevice* )
+{
+ rFont.SetStrikeout( (FontStrikeout)((const SvxCrossedOutItem*)GetItem())->GetValue() );
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribColor
+// -------------------------------------------------------------------------
+EditCharAttribColor::EditCharAttribColor( const SvxColorItem& rAttr, USHORT _nStart, USHORT _nEnd )
+ : EditCharAttrib( rAttr, _nStart, _nEnd )
+{
+ DBG_ASSERT( rAttr.Which() == EE_CHAR_COLOR, "Kein Colorattribut!" );
+}
+
+void EditCharAttribColor::SetFont( SvxFont& rFont, OutputDevice* )
+{
+ rFont.SetColor( ((const SvxColorItem*)GetItem())->GetValue() );
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribLanguage
+// -------------------------------------------------------------------------
+EditCharAttribLanguage::EditCharAttribLanguage( const SvxLanguageItem& rAttr, USHORT _nStart, USHORT _nEnd )
+ : EditCharAttrib( rAttr, _nStart, _nEnd )
+{
+ DBG_ASSERT( ( rAttr.Which() == EE_CHAR_LANGUAGE ) || ( rAttr.Which() == EE_CHAR_LANGUAGE_CJK ) || ( rAttr.Which() == EE_CHAR_LANGUAGE_CTL ), "Kein Languageattribut!" );
+}
+
+void EditCharAttribLanguage::SetFont( SvxFont& rFont, OutputDevice* )
+{
+ rFont.SetLanguage( ((const SvxLanguageItem*)GetItem())->GetLanguage() );
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribShadow
+// -------------------------------------------------------------------------
+EditCharAttribShadow::EditCharAttribShadow( const SvxShadowedItem& rAttr, USHORT _nStart, USHORT _nEnd )
+ : EditCharAttrib( rAttr, _nStart, _nEnd )
+{
+ DBG_ASSERT( rAttr.Which() == EE_CHAR_SHADOW, "Kein Shadowattribut!" );
+}
+
+void EditCharAttribShadow::SetFont( SvxFont& rFont, OutputDevice* )
+{
+ rFont.SetShadow( (BOOL)((const SvxShadowedItem*)GetItem())->GetValue() );
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribEscapement
+// -------------------------------------------------------------------------
+EditCharAttribEscapement::EditCharAttribEscapement( const SvxEscapementItem& rAttr, USHORT _nStart, USHORT _nEnd )
+ : EditCharAttrib( rAttr, _nStart, _nEnd )
+{
+ DBG_ASSERT( rAttr.Which() == EE_CHAR_ESCAPEMENT, "Kein Escapementattribut!" );
+}
+
+#if defined( WIN ) && !defined( WNT )
+#pragma optimize ("", off)
+#endif
+
+void EditCharAttribEscapement::SetFont( SvxFont& rFont, OutputDevice* )
+{
+ USHORT nProp = ((const SvxEscapementItem*)GetItem())->GetProp();
+ rFont.SetPropr( (BYTE)nProp );
+
+ short nEsc = ((const SvxEscapementItem*)GetItem())->GetEsc();
+ if ( nEsc == DFLT_ESC_AUTO_SUPER )
+ nEsc = 100 - nProp;
+ else if ( nEsc == DFLT_ESC_AUTO_SUB )
+ nEsc = sal::static_int_cast< short >( -( 100 - nProp ) );
+ rFont.SetEscapement( nEsc );
+}
+
+#if defined( WIN ) && !defined( WNT )
+#pragma optimize ("", on)
+#endif
+
+
+// -------------------------------------------------------------------------
+// class EditCharAttribOutline
+// -------------------------------------------------------------------------
+EditCharAttribOutline::EditCharAttribOutline( const SvxContourItem& rAttr, USHORT _nStart, USHORT _nEnd )
+ : EditCharAttrib( rAttr, _nStart, _nEnd )
+{
+ DBG_ASSERT( rAttr.Which() == EE_CHAR_OUTLINE, "Kein Outlineattribut!" );
+}
+
+void EditCharAttribOutline::SetFont( SvxFont& rFont, OutputDevice* )
+{
+ rFont.SetOutline( (BOOL)((const SvxContourItem*)GetItem())->GetValue() );
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribTab
+// -------------------------------------------------------------------------
+EditCharAttribTab::EditCharAttribTab( const SfxVoidItem& rAttr, USHORT nPos )
+ : EditCharAttrib( rAttr, nPos, nPos+1 )
+{
+ SetFeature( TRUE );
+}
+
+void EditCharAttribTab::SetFont( SvxFont&, OutputDevice* )
+{
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribLineBreak
+// -------------------------------------------------------------------------
+EditCharAttribLineBreak::EditCharAttribLineBreak( const SfxVoidItem& rAttr, USHORT nPos )
+ : EditCharAttrib( rAttr, nPos, nPos+1 )
+{
+ SetFeature( TRUE );
+}
+
+void EditCharAttribLineBreak::SetFont( SvxFont&, OutputDevice* )
+{
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribField
+// -------------------------------------------------------------------------
+EditCharAttribField::EditCharAttribField( const SvxFieldItem& rAttr, USHORT nPos )
+ : EditCharAttrib( rAttr, nPos, nPos+1 )
+{
+ SetFeature( TRUE ); // !!!
+ pTxtColor = 0;
+ pFldColor = 0;
+}
+
+void EditCharAttribField::SetFont( SvxFont& rFont, OutputDevice* )
+{
+ if ( pFldColor )
+ {
+ rFont.SetFillColor( *pFldColor );
+ rFont.SetTransparent( FALSE );
+ }
+ if ( pTxtColor )
+ rFont.SetColor( *pTxtColor );
+}
+
+EditCharAttribField::EditCharAttribField( const EditCharAttribField& rAttr )
+ : EditCharAttrib( *rAttr.GetItem(), rAttr.GetStart(), rAttr.GetEnd() ),
+ aFieldValue( rAttr.aFieldValue )
+{
+ // Diesen CCTOR nur fuer temporaeres Object verwenden,
+ // Item wird nicht gepoolt.
+ pTxtColor = rAttr.pTxtColor ? new Color( *rAttr.pTxtColor ) : 0;
+ pFldColor = rAttr.pFldColor ? new Color( *rAttr.pFldColor ) : 0;
+}
+
+EditCharAttribField::~EditCharAttribField()
+{
+ Reset();
+}
+
+BOOL EditCharAttribField::operator == ( const EditCharAttribField& rAttr ) const
+{
+ if ( aFieldValue != rAttr.aFieldValue )
+ return FALSE;
+
+ if ( ( pTxtColor && !rAttr.pTxtColor ) || ( !pTxtColor && rAttr.pTxtColor ) )
+ return FALSE;
+ if ( ( pTxtColor && rAttr.pTxtColor ) && ( *pTxtColor != *rAttr.pTxtColor ) )
+ return FALSE;
+
+ if ( ( pFldColor && !rAttr.pFldColor ) || ( !pFldColor && rAttr.pFldColor ) )
+ return FALSE;
+ if ( ( pFldColor && rAttr.pFldColor ) && ( *pFldColor != *rAttr.pFldColor ) )
+ return FALSE;
+
+ return TRUE;
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribPairKerning
+// -------------------------------------------------------------------------
+EditCharAttribPairKerning::EditCharAttribPairKerning( const SvxAutoKernItem& rAttr, USHORT _nStart, USHORT _nEnd )
+: EditCharAttrib( rAttr, _nStart, _nEnd )
+{
+ DBG_ASSERT( rAttr.Which() == EE_CHAR_PAIRKERNING, "Kein PairKerning!" );
+}
+
+void EditCharAttribPairKerning::SetFont( SvxFont& rFont, OutputDevice* )
+{
+ rFont.SetKerning( ((const SvxAutoKernItem*)GetItem())->GetValue() );
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribKerning
+// -------------------------------------------------------------------------
+EditCharAttribKerning::EditCharAttribKerning( const SvxKerningItem& rAttr, USHORT _nStart, USHORT _nEnd )
+: EditCharAttrib( rAttr, _nStart, _nEnd )
+{
+ DBG_ASSERT( rAttr.Which() == EE_CHAR_KERNING, "Kein Kerning!" );
+}
+
+void EditCharAttribKerning::SetFont( SvxFont& rFont, OutputDevice* )
+{
+ rFont.SetFixKerning( ((const SvxKerningItem*)GetItem())->GetValue() );
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribWordLineMode
+// -------------------------------------------------------------------------
+EditCharAttribWordLineMode::EditCharAttribWordLineMode( const SvxWordLineModeItem& rAttr, USHORT _nStart, USHORT _nEnd )
+: EditCharAttrib( rAttr, _nStart, _nEnd )
+{
+ DBG_ASSERT( rAttr.Which() == EE_CHAR_WLM, "Kein Kerning!" );
+}
+
+void EditCharAttribWordLineMode::SetFont( SvxFont& rFont, OutputDevice* )
+{
+ rFont.SetWordLineMode( ((const SvxWordLineModeItem*)GetItem())->GetValue() );
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribEmphasisMark
+// -------------------------------------------------------------------------
+EditCharAttribEmphasisMark::EditCharAttribEmphasisMark( const SvxEmphasisMarkItem& rAttr, USHORT _nStart, USHORT _nEnd )
+ : EditCharAttrib( rAttr, _nStart, _nEnd )
+{
+ DBG_ASSERT( rAttr.Which() == EE_CHAR_EMPHASISMARK, "Kein Emphasisattribut!" );
+}
+
+void EditCharAttribEmphasisMark::SetFont( SvxFont& rFont, OutputDevice* )
+{
+ rFont.SetEmphasisMark( ((const SvxEmphasisMarkItem*)GetItem())->GetEmphasisMark() );
+}
+
+// -------------------------------------------------------------------------
+// class EditCharAttribRelief
+// -------------------------------------------------------------------------
+EditCharAttribRelief::EditCharAttribRelief( const SvxCharReliefItem& rAttr, USHORT _nStart, USHORT _nEnd )
+ : EditCharAttrib( rAttr, _nStart, _nEnd )
+{
+ DBG_ASSERT( rAttr.Which() == EE_CHAR_RELIEF, "Not a relief attribute!" );
+}
+
+void EditCharAttribRelief::SetFont( SvxFont& rFont, OutputDevice* )
+{
+ rFont.SetRelief( (FontRelief)((const SvxCharReliefItem*)GetItem())->GetValue() );
+}
diff --git a/editeng/source/editeng/editattr.hxx b/editeng/source/editeng/editattr.hxx
new file mode 100644
index 0000000000..4d1673653c
--- /dev/null
+++ b/editeng/source/editeng/editattr.hxx
@@ -0,0 +1,429 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: editattr.hxx,v $
+ * $Revision: 1.13.212.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _EDITATTR_HXX
+#define _EDITATTR_HXX
+
+#include <editeng/eeitem.hxx>
+
+class SvxFont;
+class SvxFontItem;
+class SvxWeightItem;
+class SvxPostureItem;
+class SvxShadowedItem;
+class SvxEscapementItem;
+class SvxContourItem;
+class SvxCrossedOutItem;
+class SvxUnderlineItem;
+class SvxOverlineItem;
+class SvxFontHeightItem;
+class SvxCharScaleWidthItem;
+class SvxColorItem;
+class SvxAutoKernItem;
+class SvxKerningItem;
+class SvxCharSetColorItem;
+class SvxWordLineModeItem;
+class SvxFieldItem;
+class SvxLanguageItem;
+class SvxEmphasisMarkItem;
+class SvxCharReliefItem;
+#include <svl/poolitem.hxx>
+
+
+class SfxVoidItem;
+
+#define CH_FEATURE_OLD (BYTE) 0xFF
+#define CH_FEATURE (sal_Unicode) 0x01
+
+// DEF_METRIC: Bei meinem Pool sollte immer die DefMetric bei
+// GetMetric( nWhich ) ankommen!
+// => Zum ermitteln der DefMetrik einfach ein GetMetric( 0 )
+#define DEF_METRIC 0
+
+ // -------------------------------------------------------------------------
+// class EditAttrib
+// -------------------------------------------------------------------------
+class EditAttrib
+{
+private:
+ EditAttrib() {;}
+ EditAttrib( const EditAttrib & ) {;}
+
+protected:
+ const SfxPoolItem* pItem;
+
+ EditAttrib( const SfxPoolItem& rAttr );
+ virtual ~EditAttrib();
+
+public:
+ // RemoveFromPool muss immer vorm DTOR Aufruf erfolgen!!
+ void RemoveFromPool( SfxItemPool& rPool );
+
+ USHORT Which() const { return pItem->Which(); }
+ const SfxPoolItem* GetItem() const { return pItem; }
+};
+
+ // -------------------------------------------------------------------------
+// class EditCharAttrib
+// -------------------------------------------------------------------------
+// bFeature: Attribut darf nicht expandieren/schrumfen, Laenge immer 1
+// bEdge: Attribut expandiert nicht, wenn genau an der Kante expandiert werden soll
+class EditCharAttrib : public EditAttrib
+{
+protected:
+
+ USHORT nStart;
+ USHORT nEnd;
+ BOOL bFeature :1;
+ BOOL bEdge :1;
+
+public:
+ EditCharAttrib( const SfxPoolItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ USHORT& GetStart() { return nStart; }
+ USHORT& GetEnd() { return nEnd; }
+
+ USHORT GetStart() const { return nStart; }
+ USHORT GetEnd() const { return nEnd; }
+
+ inline USHORT GetLen() const;
+
+ inline void MoveForward( USHORT nDiff );
+ inline void MoveBackward( USHORT nDiff );
+
+ inline void Expand( USHORT nDiff );
+ inline void Collaps( USHORT nDiff );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+
+ BOOL IsIn( USHORT nIndex )
+ { return ( ( nStart <= nIndex ) && ( nEnd >= nIndex ) ); }
+ BOOL IsInside( USHORT nIndex )
+ { return ( ( nStart < nIndex ) && ( nEnd > nIndex ) ); }
+ BOOL IsEmpty()
+ { return nStart == nEnd; }
+
+ BOOL IsFeature() const { return bFeature; }
+ void SetFeature( BOOL b) { bFeature = b; }
+
+ BOOL IsEdge() const { return bEdge; }
+ void SetEdge( BOOL b ) { bEdge = b; }
+};
+
+inline USHORT EditCharAttrib::GetLen() const
+{
+ DBG_ASSERT( nEnd >= nStart, "EditCharAttrib: nEnd < nStart!" );
+ return nEnd-nStart;
+}
+
+inline void EditCharAttrib::MoveForward( USHORT nDiff )
+{
+ DBG_ASSERT( ((long)nEnd + nDiff) <= 0xFFFF, "EditCharAttrib: MoveForward?!" );
+ nStart = nStart + nDiff;
+ nEnd = nEnd + nDiff;
+}
+
+inline void EditCharAttrib::MoveBackward( USHORT nDiff )
+{
+ DBG_ASSERT( ((long)nStart - nDiff) >= 0, "EditCharAttrib: MoveBackward?!" );
+ nStart = nStart - nDiff;
+ nEnd = nEnd - nDiff;
+}
+
+inline void EditCharAttrib::Expand( USHORT nDiff )
+{
+ DBG_ASSERT( ( ((long)nEnd + nDiff) <= (long)0xFFFF ), "EditCharAttrib: Expand?!" );
+ DBG_ASSERT( !bFeature, "Bitte keine Features expandieren!" );
+ nEnd = nEnd + nDiff;
+}
+
+inline void EditCharAttrib::Collaps( USHORT nDiff )
+{
+ DBG_ASSERT( (long)nEnd - nDiff >= (long)nStart, "EditCharAttrib: Collaps?!" );
+ DBG_ASSERT( !bFeature, "Bitte keine Features schrumpfen!" );
+ nEnd = nEnd - nDiff;
+}
+
+ // -------------------------------------------------------------------------
+// class EditCharAttribFont
+// -------------------------------------------------------------------------
+class EditCharAttribFont: public EditCharAttrib
+{
+public:
+ EditCharAttribFont( const SvxFontItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+ // -------------------------------------------------------------------------
+// class EditCharAttribWeight
+// -------------------------------------------------------------------------
+class EditCharAttribWeight : public EditCharAttrib
+{
+public:
+ EditCharAttribWeight( const SvxWeightItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+ // -------------------------------------------------------------------------
+// class EditCharAttribItalic
+// -------------------------------------------------------------------------
+class EditCharAttribItalic : public EditCharAttrib
+{
+public:
+ EditCharAttribItalic( const SvxPostureItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+ // -------------------------------------------------------------------------
+// class EditCharAttribShadow
+// -------------------------------------------------------------------------
+class EditCharAttribShadow : public EditCharAttrib
+{
+public:
+ EditCharAttribShadow( const SvxShadowedItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+ // -------------------------------------------------------------------------
+// class EditCharAttribEscapement
+// -------------------------------------------------------------------------
+class EditCharAttribEscapement : public EditCharAttrib
+{
+public:
+ EditCharAttribEscapement( const SvxEscapementItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+ // -------------------------------------------------------------------------
+// class EditCharAttribOutline
+// -------------------------------------------------------------------------
+class EditCharAttribOutline : public EditCharAttrib
+{
+public:
+ EditCharAttribOutline( const SvxContourItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+ // -------------------------------------------------------------------------
+// class EditCharAttribStrikeout
+// -------------------------------------------------------------------------
+class EditCharAttribStrikeout : public EditCharAttrib
+{
+public:
+ EditCharAttribStrikeout( const SvxCrossedOutItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+ // -------------------------------------------------------------------------
+// class EditCharAttribUnderline
+// -------------------------------------------------------------------------
+class EditCharAttribUnderline : public EditCharAttrib
+{
+public:
+ EditCharAttribUnderline( const SvxUnderlineItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+// -------------------------------------------------------------------------
+// class EditCharAttribOverline
+// -------------------------------------------------------------------------
+class EditCharAttribOverline : public EditCharAttrib
+{
+public:
+ EditCharAttribOverline( const SvxOverlineItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+// -------------------------------------------------------------------------
+// class EditCharAttribEmphasisMark
+// -------------------------------------------------------------------------
+class EditCharAttribEmphasisMark : public EditCharAttrib
+{
+public:
+ EditCharAttribEmphasisMark( const SvxEmphasisMarkItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+// -------------------------------------------------------------------------
+// class EditCharAttribRelief
+// -------------------------------------------------------------------------
+class EditCharAttribRelief : public EditCharAttrib
+{
+public:
+ EditCharAttribRelief( const SvxCharReliefItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+ // -------------------------------------------------------------------------
+// class EditCharAttribFontHeight
+// -------------------------------------------------------------------------
+class EditCharAttribFontHeight : public EditCharAttrib
+{
+public:
+ EditCharAttribFontHeight( const SvxFontHeightItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+ // -------------------------------------------------------------------------
+// class EditCharAttribFontWidth
+// -------------------------------------------------------------------------
+class EditCharAttribFontWidth : public EditCharAttrib
+{
+public:
+ EditCharAttribFontWidth( const SvxCharScaleWidthItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+ // -------------------------------------------------------------------------
+// class EditCharAttribColor
+// -------------------------------------------------------------------------
+class EditCharAttribColor : public EditCharAttrib
+{
+public:
+ EditCharAttribColor( const SvxColorItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+ // -------------------------------------------------------------------------
+// class EditCharAttribLanguage
+// -------------------------------------------------------------------------
+class EditCharAttribLanguage : public EditCharAttrib
+{
+public:
+ EditCharAttribLanguage( const SvxLanguageItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+ // -------------------------------------------------------------------------
+// class EditCharAttribTab
+// -------------------------------------------------------------------------
+class EditCharAttribTab : public EditCharAttrib
+{
+public:
+ EditCharAttribTab( const SfxVoidItem& rAttr, USHORT nPos );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+ // -------------------------------------------------------------------------
+// class EditCharAttribLineBreak
+// -------------------------------------------------------------------------
+class EditCharAttribLineBreak : public EditCharAttrib
+{
+public:
+ EditCharAttribLineBreak( const SfxVoidItem& rAttr, USHORT nPos );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+ // -------------------------------------------------------------------------
+// class EditCharAttribField
+// -------------------------------------------------------------------------
+class EditCharAttribField: public EditCharAttrib
+{
+ XubString aFieldValue;
+ Color* pTxtColor;
+ Color* pFldColor;
+
+ EditCharAttribField& operator = ( const EditCharAttribField& rAttr ) const;
+
+public:
+ EditCharAttribField( const SvxFieldItem& rAttr, USHORT nPos );
+ EditCharAttribField( const EditCharAttribField& rAttr );
+ ~EditCharAttribField();
+
+ BOOL operator == ( const EditCharAttribField& rAttr ) const;
+ BOOL operator != ( const EditCharAttribField& rAttr ) const
+ { return !(operator == ( rAttr ) ); }
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+ Color*& GetTxtColor() { return pTxtColor; }
+ Color*& GetFldColor() { return pFldColor; }
+
+ const XubString& GetFieldValue() const { return aFieldValue; }
+ XubString& GetFieldValue() { return aFieldValue; }
+
+ void Reset()
+ {
+ aFieldValue.Erase();
+ delete pTxtColor; pTxtColor = 0;
+ delete pFldColor; pFldColor = 0;
+ }
+};
+
+ // -------------------------------------------------------------------------
+// class EditCharAttribPairKerning
+// -------------------------------------------------------------------------
+class EditCharAttribPairKerning : public EditCharAttrib
+{
+public:
+ EditCharAttribPairKerning( const SvxAutoKernItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+ // -------------------------------------------------------------------------
+// class EditCharAttribKerning
+// -------------------------------------------------------------------------
+class EditCharAttribKerning : public EditCharAttrib
+{
+public:
+ EditCharAttribKerning( const SvxKerningItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+ // -------------------------------------------------------------------------
+// class EditCharAttribWordLineMode
+// -------------------------------------------------------------------------
+class EditCharAttribWordLineMode: public EditCharAttrib
+{
+public:
+ EditCharAttribWordLineMode( const SvxWordLineModeItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ virtual void SetFont( SvxFont& rFont, OutputDevice* pOutDev );
+};
+
+
+#endif // _EDITATTR_HXX
diff --git a/editeng/source/editeng/editdbg.cxx b/editeng/source/editeng/editdbg.cxx
new file mode 100644
index 0000000000..bb29ef46ee
--- /dev/null
+++ b/editeng/source/editeng/editdbg.cxx
@@ -0,0 +1,589 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: editdbg.cxx,v $
+ * $Revision: 1.22.148.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <vcl/wrkwin.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+
+#include <editeng/lspcitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/akrnitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/emphitem.hxx>
+#include <editeng/numitem.hxx>
+#include <editeng/tstpitem.hxx>
+#include <editeng/charscaleitem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <editeng/frmdiritem.hxx>
+
+#include <impedit.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editdoc.hxx>
+#include <editdbg.hxx>
+
+#if defined( DBG_UTIL ) || ( OSL_DEBUG_LEVEL > 1 )
+
+ByteString DbgOutItem( const SfxItemPool& rPool, const SfxPoolItem& rItem )
+{
+ ByteString aDebStr;
+ switch ( rItem.Which() )
+ {
+ case EE_PARA_WRITINGDIR:
+ aDebStr += "WritingDir=";
+ aDebStr += ByteString::CreateFromInt32( ((SvxFrameDirectionItem&)rItem).GetValue() );
+ break;
+ case EE_PARA_OUTLLRSPACE:
+ case EE_PARA_LRSPACE:
+ aDebStr += "FI=";
+ aDebStr += ByteString::CreateFromInt32( ((SvxLRSpaceItem&)rItem).GetTxtFirstLineOfst() );
+ aDebStr += ", LI=";
+ aDebStr += ByteString::CreateFromInt32( ((SvxLRSpaceItem&)rItem).GetTxtLeft() );
+ aDebStr += ", RI=";
+ aDebStr += ByteString::CreateFromInt32( ((SvxLRSpaceItem&)rItem).GetRight() );
+ break;
+ case EE_PARA_NUMBULLET:
+ {
+ aDebStr += "NumItem ";
+ for ( USHORT nLevel = 0; nLevel < 3; nLevel++ )
+ {
+ aDebStr += "Level";
+ aDebStr += ByteString::CreateFromInt32( nLevel );
+ aDebStr += "=";
+ const SvxNumberFormat* pFmt = ((const SvxNumBulletItem&)rItem).GetNumRule()->Get( nLevel );
+ if ( pFmt )
+ {
+ aDebStr += "(";
+ aDebStr += ByteString::CreateFromInt32( pFmt->GetFirstLineOffset() );
+ aDebStr += ",";
+ aDebStr += ByteString::CreateFromInt32( pFmt->GetAbsLSpace() );
+ aDebStr += ",";
+ if ( pFmt->GetNumberingType() == SVX_NUM_BITMAP )
+ {
+ aDebStr += "Bitmap";
+ }
+ else if( pFmt->GetNumberingType() != SVX_NUM_CHAR_SPECIAL )
+ {
+ aDebStr += "Number";
+ }
+ else
+ {
+ aDebStr += "Char=[";
+ aDebStr += ByteString::CreateFromInt32( pFmt->GetBulletChar() );
+ aDebStr += "]";
+ }
+ aDebStr += ") ";
+ }
+ }
+ }
+ break;
+ case EE_PARA_BULLETSTATE:
+ aDebStr += "ShowBullet=";
+ aDebStr += ByteString::CreateFromInt32( ((SfxBoolItem&)rItem).GetValue() );
+ break;
+ case EE_PARA_HYPHENATE:
+ aDebStr += "Hyphenate=";
+ aDebStr += ByteString::CreateFromInt32( ((SfxBoolItem&)rItem).GetValue() );
+ break;
+ case EE_PARA_OUTLLEVEL:
+ aDebStr += "Level=";
+ aDebStr += ByteString::CreateFromInt32( ((SfxInt16Item&)rItem).GetValue() );
+ break;
+ case EE_PARA_ULSPACE:
+ aDebStr += "SB=";
+ aDebStr += ByteString::CreateFromInt32( ((SvxULSpaceItem&)rItem).GetUpper() );
+ aDebStr += ", SA=";
+ aDebStr += ByteString::CreateFromInt32( ((SvxULSpaceItem&)rItem).GetLower() );
+ break;
+ case EE_PARA_SBL:
+ aDebStr += "SBL=";
+ if ( ((SvxLineSpacingItem&)rItem).GetLineSpaceRule() == SVX_LINE_SPACE_MIN )
+ {
+ aDebStr += "Min: ";
+ aDebStr += ByteString::CreateFromInt32( ((SvxLineSpacingItem&)rItem).GetInterLineSpace() );
+ }
+ else if ( ((SvxLineSpacingItem&)rItem).GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP )
+ {
+ aDebStr += "Prop: ";
+ aDebStr += ByteString::CreateFromInt32( (ULONG)((SvxLineSpacingItem&)rItem).GetPropLineSpace() );
+ }
+ else
+ aDebStr += "Unsupported Type!";
+ break;
+ case EE_PARA_JUST:
+ aDebStr += "SvxAdust=";
+ aDebStr += ByteString::CreateFromInt32( (USHORT)((SvxAdjustItem&)rItem).GetAdjust() );
+ break;
+ case EE_PARA_TABS:
+ {
+ aDebStr += "Tabs: ";
+ const SvxTabStopItem& rTabs = (const SvxTabStopItem&) rItem;
+ aDebStr += ByteString::CreateFromInt32( rTabs.Count() );
+ if ( rTabs.Count() )
+ {
+ aDebStr += "( ";
+ for ( USHORT i = 0; i < rTabs.Count(); i++ )
+ {
+ const SvxTabStop& rTab = rTabs[i];
+ aDebStr += ByteString::CreateFromInt32( rTab.GetTabPos() );
+ aDebStr += " ";
+ }
+ aDebStr += ")";
+ }
+ }
+ break;
+ case EE_CHAR_LANGUAGE:
+ case EE_CHAR_LANGUAGE_CJK:
+ case EE_CHAR_LANGUAGE_CTL:
+ aDebStr += "Language=";
+ aDebStr += ByteString::CreateFromInt32( (USHORT)((SvxLanguageItem&)rItem).GetLanguage() );
+ break;
+ case EE_CHAR_COLOR:
+ {
+ aDebStr += "Color= ";
+ Color aColor( ((SvxColorItem&)rItem).GetValue() );
+ aDebStr += ByteString::CreateFromInt32( (USHORT)aColor.GetRed() );
+ aDebStr += ", ";
+ aDebStr += ByteString::CreateFromInt32( (USHORT)aColor.GetGreen() );
+ aDebStr += ", ";
+ aDebStr += ByteString::CreateFromInt32( (USHORT)aColor.GetBlue() );
+ }
+ break;
+ case EE_CHAR_FONTINFO:
+ case EE_CHAR_FONTINFO_CJK:
+ case EE_CHAR_FONTINFO_CTL:
+ {
+ aDebStr += "Font=";
+ aDebStr += ByteString( ((SvxFontItem&)rItem).GetFamilyName(), RTL_TEXTENCODING_ASCII_US );
+ aDebStr += " (CharSet: ";
+ aDebStr += ByteString::CreateFromInt32( (USHORT)((SvxFontItem&)rItem).GetCharSet() );
+ aDebStr += ')';
+ }
+ break;
+ case EE_CHAR_FONTHEIGHT:
+ case EE_CHAR_FONTHEIGHT_CJK:
+ case EE_CHAR_FONTHEIGHT_CTL:
+ {
+ aDebStr += "Groesse=";
+ aDebStr += ByteString::CreateFromInt32( ((SvxFontHeightItem&)rItem).GetHeight() );
+ Size aSz( 0, ((SvxFontHeightItem&)rItem).GetHeight() );
+ SfxMapUnit eUnit = rPool.GetMetric( rItem.Which() );
+ MapMode aItemMapMode( (MapUnit) eUnit );
+ MapMode aPntMap( MAP_POINT );
+ aSz = OutputDevice::LogicToLogic( aSz, aItemMapMode, aPntMap );
+ aDebStr += " Points=";
+ aDebStr += ByteString::CreateFromInt32( aSz.Height() );
+ }
+ break;
+ case EE_CHAR_FONTWIDTH:
+ {
+ aDebStr += "Breite=";
+ aDebStr += ByteString::CreateFromInt32( ((SvxCharScaleWidthItem&)rItem).GetValue() );
+ aDebStr += "%";
+ }
+ break;
+ case EE_CHAR_WEIGHT:
+ case EE_CHAR_WEIGHT_CJK:
+ case EE_CHAR_WEIGHT_CTL:
+ aDebStr += "FontWeight=";
+ aDebStr += ByteString::CreateFromInt32( (USHORT)((SvxWeightItem&)rItem).GetWeight() );
+ break;
+ case EE_CHAR_UNDERLINE:
+ aDebStr += "FontUnderline=";
+ aDebStr += ByteString::CreateFromInt32( (USHORT)((SvxUnderlineItem&)rItem).GetLineStyle() );
+ break;
+ case EE_CHAR_OVERLINE:
+ aDebStr += "FontOverline=";
+ aDebStr += ByteString::CreateFromInt32( (USHORT)((SvxOverlineItem&)rItem).GetLineStyle() );
+ break;
+ case EE_CHAR_EMPHASISMARK:
+ aDebStr += "FontUnderline=";
+ aDebStr += ByteString::CreateFromInt32( (USHORT)((SvxEmphasisMarkItem&)rItem).GetEmphasisMark() );
+ break;
+ case EE_CHAR_RELIEF:
+ aDebStr += "FontRelief=";
+ aDebStr += ByteString::CreateFromInt32( (USHORT)((SvxCharReliefItem&)rItem).GetValue() );
+ break;
+ case EE_CHAR_STRIKEOUT:
+ aDebStr += "FontStrikeout=";
+ aDebStr +=ByteString::CreateFromInt32( (USHORT)((SvxCrossedOutItem&)rItem).GetStrikeout() );
+ break;
+ case EE_CHAR_ITALIC:
+ case EE_CHAR_ITALIC_CJK:
+ case EE_CHAR_ITALIC_CTL:
+ aDebStr += "FontPosture=";
+ aDebStr +=ByteString::CreateFromInt32( (USHORT)((SvxPostureItem&)rItem).GetPosture() );
+ break;
+ case EE_CHAR_OUTLINE:
+ aDebStr += "FontOutline=";
+ aDebStr += ByteString::CreateFromInt32( (USHORT)((SvxContourItem&)rItem).GetValue() );
+ break;
+ case EE_CHAR_SHADOW:
+ aDebStr += "FontShadowed=";
+ aDebStr += ByteString::CreateFromInt32( (USHORT)((SvxShadowedItem&)rItem).GetValue() );
+ break;
+ case EE_CHAR_ESCAPEMENT:
+ aDebStr += "Escape=";
+ aDebStr += ByteString::CreateFromInt32( (short)((SvxEscapementItem&)rItem).GetEsc() );
+ aDebStr += ", ";
+ aDebStr += ByteString::CreateFromInt32( (short)((SvxEscapementItem&)rItem).GetProp() );
+ break;
+ case EE_CHAR_PAIRKERNING:
+ aDebStr += "PairKerning=";
+ aDebStr += ByteString::CreateFromInt32( (USHORT)((SvxAutoKernItem&)rItem).GetValue() );
+ break;
+ case EE_CHAR_KERNING:
+ {
+ aDebStr += "Kerning=";
+ aDebStr += ByteString::CreateFromInt32( (short)((SvxKerningItem&)rItem).GetValue() );
+ Size aSz( 0, (short)((SvxKerningItem&)rItem).GetValue() );
+ SfxMapUnit eUnit = rPool.GetMetric( rItem.Which() );
+ MapMode aItemMapMode( (MapUnit) eUnit );
+ MapMode aPntMap( MAP_POINT );
+ aSz = OutputDevice::LogicToLogic( aSz, aItemMapMode, aPntMap );
+ aDebStr += " Points=";
+ aDebStr += ByteString::CreateFromInt32( aSz.Height() );
+ }
+ break;
+ case EE_CHAR_WLM:
+ aDebStr += "WordLineMode=";
+ aDebStr += ByteString::CreateFromInt32( (USHORT)((SvxWordLineModeItem&)rItem).GetValue() );
+ break;
+ case EE_CHAR_XMLATTRIBS:
+ aDebStr += "XMLAttribs=...";
+ break;
+ }
+ return aDebStr;
+}
+
+void DbgOutItemSet( FILE* fp, const SfxItemSet& rSet, BOOL bSearchInParent, BOOL bShowALL )
+{
+ for ( USHORT nWhich = EE_PARA_START; nWhich <= EE_CHAR_END; nWhich++ )
+ {
+ fprintf( fp, "\nWhich: %i\t", nWhich );
+ if ( rSet.GetItemState( nWhich, bSearchInParent ) == SFX_ITEM_OFF )
+ fprintf( fp, "ITEM_OFF " );
+ else if ( rSet.GetItemState( nWhich, bSearchInParent ) == SFX_ITEM_DONTCARE )
+ fprintf( fp, "ITEM_DC " );
+ else if ( rSet.GetItemState( nWhich, bSearchInParent ) == SFX_ITEM_ON )
+ fprintf( fp, "ITEM_ON *" );
+
+ if ( !bShowALL && ( rSet.GetItemState( nWhich, bSearchInParent ) != SFX_ITEM_ON ) )
+ continue;
+
+ const SfxPoolItem& rItem = rSet.Get( nWhich, bSearchInParent );
+ ByteString aDebStr = DbgOutItem( *rSet.GetPool(), rItem );
+ fprintf( fp, "%s", aDebStr.GetBuffer() );
+ }
+}
+
+void EditDbg::ShowEditEngineData( EditEngine* pEE, BOOL bInfoBox )
+{
+#if defined UNX
+ FILE* fp = fopen( "/tmp/debug.log", "w" );
+#else
+ FILE* fp = fopen( "d:\\debug.log", "w" );
+#endif
+ if ( fp == 0 )
+ {
+ DBG_ERROR( "Log-File konnte nicht angelegt werden!" );
+ return;
+ }
+
+ const SfxItemPool& rPool = *pEE->GetEmptyItemSet().GetPool();
+
+ fprintf( fp, "================================================================================" );
+ fprintf( fp, "\n================== Dokument ================================================" );
+ fprintf( fp, "\n================================================================================" );
+ for ( USHORT nPortion = 0; nPortion < pEE->pImpEditEngine->GetParaPortions(). Count(); nPortion++)
+ {
+
+ ParaPortion* pPPortion = pEE->pImpEditEngine->GetParaPortions().GetObject(nPortion );
+ fprintf( fp, " \nAbsatz %i: Laenge = %i, Invalid = %i\nText = '%s'", nPortion, pPPortion->GetNode()->Len(), pPPortion->IsInvalid(), ByteString( *pPPortion->GetNode(), RTL_TEXTENCODING_ASCII_US ).GetBuffer() );
+ fprintf( fp, "\nVorlage:" );
+ SfxStyleSheet* pStyle = pPPortion->GetNode()->GetStyleSheet();
+ if ( pStyle )
+ fprintf( fp, " %s", ByteString( pStyle->GetName(), RTL_TEXTENCODING_ASCII_US ).GetBuffer() );
+ fprintf( fp, "\nAbsatzattribute:" );
+ DbgOutItemSet( fp, pPPortion->GetNode()->GetContentAttribs().GetItems(), FALSE, FALSE );
+
+ fprintf( fp, "\nZeichenattribute:" );
+ BOOL bZeroAttr = FALSE;
+ USHORT z;
+ for ( z = 0; z < pPPortion->GetNode()->GetCharAttribs().Count(); z++ )
+ {
+ EditCharAttrib* pAttr = pPPortion->GetNode()->GetCharAttribs().GetAttribs().GetObject( z );
+ ByteString aCharAttribs;
+ aCharAttribs += "\nA";
+ aCharAttribs += ByteString::CreateFromInt32( nPortion );
+ aCharAttribs += ": ";
+ aCharAttribs += ByteString::CreateFromInt32( pAttr->GetItem()->Which() );
+ aCharAttribs += '\t';
+ aCharAttribs += ByteString::CreateFromInt32( pAttr->GetStart() );
+ aCharAttribs += '\t';
+ aCharAttribs += ByteString::CreateFromInt32( pAttr->GetEnd() );
+ if ( pAttr->IsEmpty() )
+ bZeroAttr = TRUE;
+ fprintf( fp, "%s => ", aCharAttribs.GetBuffer() );
+
+ ByteString aDebStr = DbgOutItem( rPool, *pAttr->GetItem() );
+ fprintf( fp, "%s", aDebStr.GetBuffer() );
+ }
+ if ( bZeroAttr )
+ fprintf( fp, "\nNULL-Attribute!" );
+
+ USHORT nTextPortions = pPPortion->GetTextPortions().Count();
+ ByteString aPortionStr("\nTextportions: #");
+ aPortionStr += ByteString::CreateFromInt32( nTextPortions );
+ aPortionStr += " \nA";
+ aPortionStr += ByteString::CreateFromInt32( nPortion );
+ aPortionStr += ": Absatzlaenge = ";
+ aPortionStr += ByteString::CreateFromInt32( pPPortion->GetNode()->Len() );
+ aPortionStr += "\nA";
+ aPortionStr += ByteString::CreateFromInt32( nPortion );
+ aPortionStr += ": ";
+ ULONG n = 0;
+ for ( z = 0; z < nTextPortions; z++ )
+ {
+ TextPortion* pPortion = pPPortion->GetTextPortions().GetObject( z );
+ aPortionStr += " ";
+ aPortionStr += ByteString::CreateFromInt32( pPortion->GetLen() );
+ aPortionStr += "(";
+ aPortionStr += ByteString::CreateFromInt32( pPortion->GetSize().Width() );
+ aPortionStr += ")";
+ aPortionStr += "[";
+ aPortionStr += ByteString::CreateFromInt32( (USHORT)pPortion->GetKind() );
+ aPortionStr += "]";
+ aPortionStr += ";";
+ n += pPortion->GetLen();
+ }
+ aPortionStr += "\nA";
+ aPortionStr += ByteString::CreateFromInt32( nPortion );
+ aPortionStr += ": Gesamtlaenge: ";
+ aPortionStr += ByteString::CreateFromInt32( n );
+ if ( pPPortion->GetNode()->Len() != n )
+ aPortionStr += " => Fehler !!!";
+ fprintf( fp, "%s", aPortionStr.GetBuffer() );
+
+
+ fprintf( fp, "\n\nZeilen:" );
+ // Erstmal die Inhalte...
+ USHORT nLine;
+ for ( nLine = 0; nLine < pPPortion->GetLines().Count(); nLine++ )
+ {
+ EditLine* pLine = pPPortion->GetLines().GetObject( nLine );
+
+ ByteString aLine( *(pPPortion->GetNode()), pLine->GetStart(), pLine->GetEnd() - pLine->GetStart(), RTL_TEXTENCODING_ASCII_US );
+ fprintf( fp, "\nZeile %i\t>%s<", nLine, aLine.GetBuffer() );
+ }
+ // dann die internen Daten...
+ for ( nLine = 0; nLine < pPPortion->GetLines().Count(); nLine++ )
+ {
+ EditLine* pLine = pPPortion->GetLines().GetObject( nLine );
+ fprintf( fp, "\nZeile %i:\tStart: %i,\tEnd: %i", nLine, pLine->GetStart(), pLine->GetEnd() );
+ fprintf( fp, "\t\tPortions: %i - %i.\tHoehe: %i, Ascent=%i", pLine->GetStartPortion(), pLine->GetEndPortion(), pLine->GetHeight(), pLine->GetMaxAscent() );
+ }
+
+ fprintf( fp, "\n-----------------------------------------------------------------------------" );
+ }
+
+ if ( pEE->pImpEditEngine->GetStyleSheetPool() )
+ {
+ ULONG nStyles = pEE->pImpEditEngine->GetStyleSheetPool() ? pEE->pImpEditEngine->GetStyleSheetPool()->Count() : 0;
+ fprintf( fp, "\n\n ================================================================================" );
+ fprintf( fp, "\n================== Stylesheets =============================================" );
+ fprintf( fp, "\n================================================================================" );
+ fprintf( fp, "\n#Vorlagen: %lu\n", nStyles );
+ SfxStyleSheetIterator aIter( pEE->pImpEditEngine->GetStyleSheetPool(), SFX_STYLE_FAMILY_ALL );
+ SfxStyleSheetBase* pStyle = aIter.First();
+ while ( pStyle )
+ {
+ fprintf( fp, "\nVorlage: %s", ByteString( pStyle->GetName(), RTL_TEXTENCODING_ASCII_US ).GetBuffer() );
+ fprintf( fp, "\nParent: %s", ByteString( pStyle->GetParent(), RTL_TEXTENCODING_ASCII_US ).GetBuffer() );
+ fprintf( fp, "\nFollow: %s", ByteString( pStyle->GetFollow(), RTL_TEXTENCODING_ASCII_US ).GetBuffer() );
+ DbgOutItemSet( fp, pStyle->GetItemSet(), FALSE, FALSE );
+ fprintf( fp, "\n----------------------------------" );
+
+ pStyle = aIter.Next();
+ }
+ }
+
+ fprintf( fp, "\n\n ================================================================================" );
+ fprintf( fp, "\n================== Defaults ================================================" );
+ fprintf( fp, "\n================================================================================" );
+ DbgOutItemSet( fp, pEE->pImpEditEngine->GetEmptyItemSet(), TRUE, TRUE );
+
+ fprintf( fp, "\n\n ================================================================================" );
+ fprintf( fp, "\n================== EditEngine & Views ======================================" );
+ fprintf( fp, "\n================================================================================" );
+ fprintf( fp, "\nControl: %lx", pEE->GetControlWord() );
+ fprintf( fp, "\nRefMapMode: %i", pEE->pImpEditEngine->pRefDev->GetMapMode().GetMapUnit() );
+ fprintf( fp, "\nPaperSize: %li x %li", pEE->GetPaperSize().Width(), pEE->GetPaperSize().Height() );
+ fprintf( fp, "\nMaxAutoPaperSize: %li x %li", pEE->GetMaxAutoPaperSize().Width(), pEE->GetMaxAutoPaperSize().Height() );
+ fprintf( fp, "\nMinAutoPaperSize: %li x %li", pEE->GetMinAutoPaperSize().Width(), pEE->GetMinAutoPaperSize().Height() );
+ fprintf( fp, "\nUpdate: %i", pEE->GetUpdateMode() );
+ fprintf( fp, "\nAnzahl der Views: %i", pEE->GetViewCount() );
+ for ( USHORT nView = 0; nView < pEE->GetViewCount(); nView++ )
+ {
+ EditView* pV = pEE->GetView( nView );
+ DBG_ASSERT( pV, "View nicht gefunden!" );
+ fprintf( fp, "\nView %i: Focus=%i", nView, pV->GetWindow()->HasFocus() );
+ Rectangle aR( pV->GetOutputArea() );
+ fprintf( fp, "\n OutputArea: nX=%li, nY=%li, dX=%li, dY=%li, MapMode = %i", aR.TopLeft().X(), aR.TopLeft().Y(), aR.GetSize().Width(), aR.GetSize().Height() , pV->GetWindow()->GetMapMode().GetMapUnit() );
+ aR = pV->GetVisArea();
+ fprintf( fp, "\n VisArea: nX=%li, nY=%li, dX=%li, dY=%li", aR.TopLeft().X(), aR.TopLeft().Y(), aR.GetSize().Width(), aR.GetSize().Height() );
+ ESelection aSel = pV->GetSelection();
+ fprintf( fp, "\n Selektion: Start=%u,%u, End=%u,%u", aSel.nStartPara, aSel.nStartPos, aSel.nEndPara, aSel.nEndPos );
+ }
+ if ( pEE->GetActiveView() )
+ {
+ fprintf( fp, "\n\n ================================================================================" );
+ fprintf( fp, "\n================== Aktuelle View ===========================================" );
+ fprintf( fp, "\n================================================================================" );
+ DbgOutItemSet( fp, pEE->GetActiveView()->GetAttribs(), TRUE, FALSE );
+ }
+ fclose( fp );
+ if ( bInfoBox )
+ InfoBox(0, String( RTL_CONSTASCII_USTRINGPARAM( "D:\\DEBUG.LOG !" ) ) ).Execute();
+}
+
+ByteString EditDbg::GetPortionInfo( ParaPortion* pPPortion )
+{
+ USHORT z;
+
+ ByteString aDebStr( "Absatzlaenge = " );
+ aDebStr += ByteString::CreateFromInt32( pPPortion->GetNode()->Len() );
+
+ aDebStr += "\nZeichenattribute:";
+ for ( z = 0; z < pPPortion->GetNode()->GetCharAttribs().Count(); z++ )
+ {
+ EditCharAttrib* pAttr = pPPortion->GetNode()->GetCharAttribs().GetAttribs().GetObject( z );
+ aDebStr += "\n ";
+ aDebStr += ByteString::CreateFromInt32( pAttr->GetItem()->Which() );
+ aDebStr += '\t';
+ aDebStr += ByteString::CreateFromInt32( pAttr->GetStart() );
+ aDebStr += '\t';
+ aDebStr += ByteString::CreateFromInt32( pAttr->GetEnd() );
+ }
+
+ aDebStr += "\nTextportions:";
+ USHORT n = 0;
+ for ( z = 0; z < pPPortion->GetTextPortions().Count(); z++ )
+ {
+ TextPortion* pPortion = pPPortion->GetTextPortions().GetObject( z );
+ aDebStr += " ";
+ aDebStr += ByteString::CreateFromInt32( pPortion->GetLen() );
+ aDebStr += "(";
+ aDebStr += ByteString::CreateFromInt32( pPortion->GetSize().Width() );
+ aDebStr += ")";
+ aDebStr += ";";
+ n = n + pPortion->GetLen();
+ }
+ aDebStr += "\nGesamtlaenge: ";
+ aDebStr += ByteString::CreateFromInt32( n );
+ aDebStr += "\nSortiert nach Start:";
+ for ( USHORT x = 0; x < pPPortion->GetNode()->GetCharAttribs().Count(); x++ )
+ {
+ EditCharAttrib* pCurAttrib = pPPortion->GetNode()->GetCharAttribs().GetAttribs().GetObject( x );
+ aDebStr += "\nStart: ";
+ aDebStr += ByteString::CreateFromInt32( pCurAttrib->GetStart() );
+ aDebStr += "\tEnde: ";
+ aDebStr += ByteString::CreateFromInt32( pCurAttrib->GetEnd() );
+ }
+ return aDebStr;
+}
+
+ByteString EditDbg::GetTextPortionInfo( TextPortionList& rPortions )
+{
+ ByteString aDebStr;
+ for ( USHORT z = 0; z < rPortions.Count(); z++ )
+ {
+ TextPortion* pPortion = rPortions.GetObject( z );
+ aDebStr += " ";
+ aDebStr += ByteString::CreateFromInt32( pPortion->GetLen() );
+ aDebStr += "(";
+ aDebStr += ByteString::CreateFromInt32( pPortion->GetSize().Width() );
+ aDebStr += ")";
+ aDebStr += ";";
+ }
+ return aDebStr;
+}
+
+void EditDbg::ShowPortionData( ParaPortion* pPortion )
+{
+ ByteString aDebStr( GetPortionInfo( pPortion ) );
+ InfoBox( 0, String( aDebStr, RTL_TEXTENCODING_ASCII_US ) ).Execute();
+}
+
+
+BOOL ParaPortion::DbgCheckTextPortions()
+{
+ // pruefen, ob Portionlaenge ok:
+ USHORT nXLen = 0;
+ for ( USHORT nPortion = 0; nPortion < aTextPortionList.Count(); nPortion++ )
+ nXLen = nXLen + aTextPortionList[nPortion]->GetLen();
+ return nXLen == pNode->Len() ? TRUE : FALSE;
+}
+
+BOOL CheckOrderedList( CharAttribArray& rAttribs, BOOL bStart )
+{
+ USHORT nPrev = 0;
+ for ( USHORT nAttr = 0; nAttr < rAttribs.Count(); nAttr++ )
+ {
+ EditCharAttrib* pAttr = rAttribs[nAttr];
+ USHORT nCur = bStart ? pAttr->GetStart() : pAttr->GetEnd();
+ if ( nCur < nPrev )
+ return FALSE;
+
+ nPrev = nCur;
+ }
+ return TRUE;
+}
+
+#endif
+
diff --git a/editeng/source/editeng/editdbg.hxx b/editeng/source/editeng/editdbg.hxx
new file mode 100644
index 0000000000..ceb0bad2b0
--- /dev/null
+++ b/editeng/source/editeng/editdbg.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: editdbg.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _EDITDBG_HXX
+#define _EDITDBG_HXX
+
+#include <svl/solar.hrc>
+#include <tools/string.hxx>
+#include <stdio.h>
+
+class EditEngine;
+class ParaPortion;
+class EditUndoList;
+class TextPortionList;
+class SfxItemSet;
+class SfxItemPool;
+class SfxPoolItem;
+
+ByteString DbgOutItem( const SfxItemPool& rPool, const SfxPoolItem& rItem );
+void DbgOutItemSet( FILE* fp, const SfxItemSet& rSet, BOOL bSearchInParent, BOOL bShowALL );
+
+class EditDbg
+{
+public:
+ static void ShowEditEngineData( EditEngine* pEditEngine, BOOL bInfoBox = TRUE );
+ static void ShowPortionData( ParaPortion* pPortion );
+ static ByteString GetPortionInfo( ParaPortion* pPPortion );
+ static ByteString GetTextPortionInfo( TextPortionList& rPortions );
+ static ByteString GetUndoDebStr( EditUndoList* pUndoList );
+};
+
+
+#endif // _EDITDBG_HXX
diff --git a/editeng/source/editeng/editdoc.cxx b/editeng/source/editeng/editdoc.cxx
new file mode 100644
index 0000000000..a5d58b9c6b
--- /dev/null
+++ b/editeng/source/editeng/editdoc.cxx
@@ -0,0 +1,2317 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: editdoc.cxx,v $
+ * $Revision: 1.48.148.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <vcl/wrkwin.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+
+#include <editeng/tstpitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/akrnitem.hxx>
+#include <editeng/cscoitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/emphitem.hxx>
+#include <editeng/charscaleitem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <editeng/xmlcnitm.hxx>
+#include <editeng/editids.hrc>
+
+#include <editdoc.hxx>
+#include <editdbg.hxx>
+#include <editeng/eerdll.hxx>
+#include <eerdll2.hxx>
+#include <tools/stream.hxx>
+#include <tools/debug.hxx>
+#include <tools/shl.hxx>
+#include <vcl/svapp.hxx>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <stdlib.h> // qsort
+
+using namespace ::com::sun::star;
+
+
+// ------------------------------------------------------------
+
+USHORT GetScriptItemId( USHORT nItemId, short nScriptType )
+{
+ USHORT nId = nItemId;
+
+ if ( ( nScriptType == i18n::ScriptType::ASIAN ) ||
+ ( nScriptType == i18n::ScriptType::COMPLEX ) )
+ {
+ switch ( nItemId )
+ {
+ case EE_CHAR_LANGUAGE:
+ nId = ( nScriptType == i18n::ScriptType::ASIAN ) ? EE_CHAR_LANGUAGE_CJK : EE_CHAR_LANGUAGE_CTL;
+ break;
+ case EE_CHAR_FONTINFO:
+ nId = ( nScriptType == i18n::ScriptType::ASIAN ) ? EE_CHAR_FONTINFO_CJK : EE_CHAR_FONTINFO_CTL;
+ break;
+ case EE_CHAR_FONTHEIGHT:
+ nId = ( nScriptType == i18n::ScriptType::ASIAN ) ? EE_CHAR_FONTHEIGHT_CJK : EE_CHAR_FONTHEIGHT_CTL;
+ break;
+ case EE_CHAR_WEIGHT:
+ nId = ( nScriptType == i18n::ScriptType::ASIAN ) ? EE_CHAR_WEIGHT_CJK : EE_CHAR_WEIGHT_CTL;
+ break;
+ case EE_CHAR_ITALIC:
+ nId = ( nScriptType == i18n::ScriptType::ASIAN ) ? EE_CHAR_ITALIC_CJK : EE_CHAR_ITALIC_CTL;
+ break;
+ }
+ }
+
+ return nId;
+}
+
+BOOL IsScriptItemValid( USHORT nItemId, short nScriptType )
+{
+ BOOL bValid = TRUE;
+
+ switch ( nItemId )
+ {
+ case EE_CHAR_LANGUAGE:
+ bValid = nScriptType == i18n::ScriptType::LATIN;
+ break;
+ case EE_CHAR_LANGUAGE_CJK:
+ bValid = nScriptType == i18n::ScriptType::ASIAN;
+ break;
+ case EE_CHAR_LANGUAGE_CTL:
+ bValid = nScriptType == i18n::ScriptType::COMPLEX;
+ break;
+ case EE_CHAR_FONTINFO:
+ bValid = nScriptType == i18n::ScriptType::LATIN;
+ break;
+ case EE_CHAR_FONTINFO_CJK:
+ bValid = nScriptType == i18n::ScriptType::ASIAN;
+ break;
+ case EE_CHAR_FONTINFO_CTL:
+ bValid = nScriptType == i18n::ScriptType::COMPLEX;
+ break;
+ case EE_CHAR_FONTHEIGHT:
+ bValid = nScriptType == i18n::ScriptType::LATIN;
+ break;
+ case EE_CHAR_FONTHEIGHT_CJK:
+ bValid = nScriptType == i18n::ScriptType::ASIAN;
+ break;
+ case EE_CHAR_FONTHEIGHT_CTL:
+ bValid = nScriptType == i18n::ScriptType::COMPLEX;
+ break;
+ case EE_CHAR_WEIGHT:
+ bValid = nScriptType == i18n::ScriptType::LATIN;
+ break;
+ case EE_CHAR_WEIGHT_CJK:
+ bValid = nScriptType == i18n::ScriptType::ASIAN;
+ break;
+ case EE_CHAR_WEIGHT_CTL:
+ bValid = nScriptType == i18n::ScriptType::COMPLEX;
+ break;
+ case EE_CHAR_ITALIC:
+ bValid = nScriptType == i18n::ScriptType::LATIN;
+ break;
+ case EE_CHAR_ITALIC_CJK:
+ bValid = nScriptType == i18n::ScriptType::ASIAN;
+ break;
+ case EE_CHAR_ITALIC_CTL:
+ bValid = nScriptType == i18n::ScriptType::COMPLEX;
+ break;
+ }
+
+ return bValid;
+}
+
+
+// ------------------------------------------------------------
+
+// Sollte spaeter zentral nach TOOLS/STRING (Aktuell: 303)
+// fuer Grep: WS_TARGET
+
+DBG_NAME( EE_TextPortion );
+DBG_NAME( EE_EditLine );
+DBG_NAME( EE_ContentNode );
+DBG_NAME( EE_CharAttribList );
+
+SfxItemInfo aItemInfos[EDITITEMCOUNT] = {
+ { SID_ATTR_FRAMEDIRECTION, SFX_ITEM_POOLABLE }, // EE_PARA_WRITINGDIR
+ { 0, SFX_ITEM_POOLABLE }, // EE_PARA_XMLATTRIBS
+ { SID_ATTR_PARA_HANGPUNCTUATION, SFX_ITEM_POOLABLE }, // EE_PARA_HANGINGPUNCTUATION
+ { SID_ATTR_PARA_FORBIDDEN_RULES, SFX_ITEM_POOLABLE },
+ { SID_ATTR_PARA_SCRIPTSPACE, SFX_ITEM_POOLABLE }, // EE_PARA_ASIANCJKSPACING
+ { SID_ATTR_NUMBERING_RULE, SFX_ITEM_POOLABLE }, // EE_PARA_NUMBULL
+ { 0, SFX_ITEM_POOLABLE }, // EE_PARA_HYPHENATE
+ { 0, SFX_ITEM_POOLABLE }, // EE_PARA_BULLETSTATE
+ { 0, SFX_ITEM_POOLABLE }, // EE_PARA_OUTLLRSPACE
+ { SID_ATTR_PARA_OUTLLEVEL, SFX_ITEM_POOLABLE },
+ { SID_ATTR_PARA_BULLET, SFX_ITEM_POOLABLE },
+ { SID_ATTR_LRSPACE, SFX_ITEM_POOLABLE },
+ { SID_ATTR_ULSPACE, SFX_ITEM_POOLABLE },
+ { SID_ATTR_PARA_LINESPACE, SFX_ITEM_POOLABLE },
+ { SID_ATTR_PARA_ADJUST, SFX_ITEM_POOLABLE },
+ { SID_ATTR_TABSTOP, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_COLOR, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_FONT, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_FONTHEIGHT, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_SCALEWIDTH, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_WEIGHT, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_UNDERLINE, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_STRIKEOUT, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_POSTURE, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_CONTOUR, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_SHADOWED, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_ESCAPEMENT, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_AUTOKERN, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_KERNING, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_WORDLINEMODE, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_LANGUAGE, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_CJK_LANGUAGE, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_CTL_LANGUAGE, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_CJK_FONT, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_CTL_FONT, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_CJK_FONTHEIGHT, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_CTL_FONTHEIGHT, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_CJK_WEIGHT, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_CTL_WEIGHT, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_CJK_POSTURE, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_CTL_POSTURE, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_EMPHASISMARK, SFX_ITEM_POOLABLE },
+ { SID_ATTR_CHAR_RELIEF, SFX_ITEM_POOLABLE },
+ { 0, SFX_ITEM_POOLABLE }, // EE_CHAR_RUBI_DUMMY
+ { 0, SFX_ITEM_POOLABLE }, // EE_CHAR_XMLATTRIBS
+ { SID_ATTR_CHAR_OVERLINE, SFX_ITEM_POOLABLE },
+ { 0, SFX_ITEM_POOLABLE }, // EE_FEATURE_TAB
+ { 0, SFX_ITEM_POOLABLE }, // EE_FEATURE_LINEBR
+ { SID_ATTR_CHAR_CHARSETCOLOR, SFX_ITEM_POOLABLE }, // EE_FEATURE_NOTCONV
+ { SID_FIELD, SFX_ITEM_POOLABLE }
+};
+
+USHORT aV1Map[] = {
+ 3999, 4001, 4002, 4003, 4004, 4005, 4006,
+ 4007, 4008, 4009, 4010, 4011, 4012, 4013, 4017, 4018, 4019 // MI: 4019?
+};
+
+USHORT aV2Map[] = {
+ 3999, 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, 4009,
+ 4010, 4011, 4012, 4013, 4014, 4015, 4016, 4018, 4019, 4020
+};
+
+USHORT aV3Map[] = {
+ 3997, 3998, 3999, 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007,
+ 4009, 4010, 4011, 4012, 4013, 4014, 4015, 4016, 4017, 4018, 4019,
+ 4020, 4021
+};
+
+USHORT aV4Map[] = {
+ 3994, 3995, 3996, 3997, 3998, 3999, 4000, 4001, 4002, 4003,
+ 4004, 4005, 4006, 4007, 4008, 4009, 4010, 4011, 4012, 4013,
+ 4014, 4015, 4016, 4017, 4018,
+ /* CJK Items inserted here: EE_CHAR_LANGUAGE - EE_CHAR_XMLATTRIBS */
+ 4034, 4035, 4036, 4037
+};
+
+USHORT aV5Map[] = {
+ 3994, 3995, 3996, 3997, 3998, 3999, 4000, 4001, 4002, 4003,
+ 4004, 4005, 4006, 4007, 4008, 4009, 4010, 4011, 4012, 4013,
+ 4014, 4015, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023,
+ 4024, 4025, 4026, 4027, 4028, 4029, 4030, 4031, 4032, 4033,
+ /* EE_CHAR_OVERLINE inserted here */
+ 4035, 4036, 4037, 4038
+};
+
+SV_IMPL_PTRARR( DummyContentList, ContentNode* );
+SV_IMPL_VARARR( ScriptTypePosInfos, ScriptTypePosInfo );
+SV_IMPL_VARARR( WritingDirectionInfos, WritingDirectionInfo );
+// SV_IMPL_VARARR( ExtraCharInfos, ExtraCharInfo );
+
+
+int SAL_CALL CompareStart( const void* pFirst, const void* pSecond )
+{
+ if ( (*((EditCharAttrib**)pFirst))->GetStart() < (*((EditCharAttrib**)pSecond))->GetStart() )
+ return (-1);
+ else if ( (*((EditCharAttrib**)pFirst))->GetStart() > (*((EditCharAttrib**)pSecond))->GetStart() )
+ return (1);
+ return 0;
+}
+
+EditCharAttrib* MakeCharAttrib( SfxItemPool& rPool, const SfxPoolItem& rAttr, USHORT nS, USHORT nE )
+{
+ // das neue Attribut im Pool anlegen
+ const SfxPoolItem& rNew = rPool.Put( rAttr );
+
+ EditCharAttrib* pNew = 0;
+ switch( rNew.Which() )
+ {
+ case EE_CHAR_LANGUAGE:
+ case EE_CHAR_LANGUAGE_CJK:
+ case EE_CHAR_LANGUAGE_CTL:
+ {
+ pNew = new EditCharAttribLanguage( (const SvxLanguageItem&)rNew, nS, nE );
+ }
+ break;
+ case EE_CHAR_COLOR:
+ {
+ pNew = new EditCharAttribColor( (const SvxColorItem&)rNew, nS, nE );
+ }
+ break;
+ case EE_CHAR_FONTINFO:
+ case EE_CHAR_FONTINFO_CJK:
+ case EE_CHAR_FONTINFO_CTL:
+ {
+ pNew = new EditCharAttribFont( (const SvxFontItem&)rNew, nS, nE );
+ }
+ break;
+ case EE_CHAR_FONTHEIGHT:
+ case EE_CHAR_FONTHEIGHT_CJK:
+ case EE_CHAR_FONTHEIGHT_CTL:
+ {
+ pNew = new EditCharAttribFontHeight( (const SvxFontHeightItem&)rNew, nS, nE );
+ }
+ break;
+ case EE_CHAR_FONTWIDTH:
+ {
+ pNew = new EditCharAttribFontWidth( (const SvxCharScaleWidthItem&)rNew, nS, nE );
+ }
+ break;
+ case EE_CHAR_WEIGHT:
+ case EE_CHAR_WEIGHT_CJK:
+ case EE_CHAR_WEIGHT_CTL:
+ {
+ pNew = new EditCharAttribWeight( (const SvxWeightItem&)rNew, nS, nE );
+ }
+ break;
+ case EE_CHAR_UNDERLINE:
+ {
+ pNew = new EditCharAttribUnderline( (const SvxUnderlineItem&)rNew, nS, nE );
+ }
+ break;
+ case EE_CHAR_OVERLINE:
+ {
+ pNew = new EditCharAttribOverline( (const SvxOverlineItem&)rNew, nS, nE );
+ }
+ break;
+ case EE_CHAR_EMPHASISMARK:
+ {
+ pNew = new EditCharAttribEmphasisMark( (const SvxEmphasisMarkItem&)rNew, nS, nE );
+ }
+ break;
+ case EE_CHAR_RELIEF:
+ {
+ pNew = new EditCharAttribRelief( (const SvxCharReliefItem&)rNew, nS, nE );
+ }
+ break;
+ case EE_CHAR_STRIKEOUT:
+ {
+ pNew = new EditCharAttribStrikeout( (const SvxCrossedOutItem&)rNew, nS, nE );
+ }
+ break;
+ case EE_CHAR_ITALIC:
+ case EE_CHAR_ITALIC_CJK:
+ case EE_CHAR_ITALIC_CTL:
+ {
+ pNew = new EditCharAttribItalic( (const SvxPostureItem&)rNew, nS, nE );
+ }
+ break;
+ case EE_CHAR_OUTLINE:
+ {
+ pNew = new EditCharAttribOutline( (const SvxContourItem&)rNew, nS, nE );
+ }
+ break;
+ case EE_CHAR_SHADOW:
+ {
+ pNew = new EditCharAttribShadow( (const SvxShadowedItem&)rNew, nS, nE );
+ }
+ break;
+ case EE_CHAR_ESCAPEMENT:
+ {
+ pNew = new EditCharAttribEscapement( (const SvxEscapementItem&)rNew, nS, nE );
+ }
+ break;
+ case EE_CHAR_PAIRKERNING:
+ {
+ pNew = new EditCharAttribPairKerning( (const SvxAutoKernItem&)rNew, nS, nE );
+ }
+ break;
+ case EE_CHAR_KERNING:
+ {
+ pNew = new EditCharAttribKerning( (const SvxKerningItem&)rNew, nS, nE );
+ }
+ break;
+ case EE_CHAR_WLM:
+ {
+ pNew = new EditCharAttribWordLineMode( (const SvxWordLineModeItem&)rNew, nS, nE );
+ }
+ break;
+ case EE_CHAR_XMLATTRIBS:
+ {
+ pNew = new EditCharAttrib( rNew, nS, nE ); // Attrib is only for holding XML information...
+ }
+ break;
+ case EE_FEATURE_TAB:
+ {
+ pNew = new EditCharAttribTab( (const SfxVoidItem&)rNew, nS );
+ }
+ break;
+ case EE_FEATURE_LINEBR:
+ {
+ pNew = new EditCharAttribLineBreak( (const SfxVoidItem&)rNew, nS );
+ }
+ break;
+ case EE_FEATURE_FIELD:
+ {
+ pNew = new EditCharAttribField( (const SvxFieldItem&)rNew, nS );
+ }
+ break;
+ default:
+ {
+ DBG_ERROR( "Ungueltiges Attribut!" );
+ }
+ }
+ return pNew;
+}
+
+// -------------------------------------------------------------------------
+// class EditLine
+// -------------------------------------------------------------------------
+
+EditLine::EditLine()
+{
+ DBG_CTOR( EE_EditLine, 0 );
+
+ nStart = nEnd = 0;
+ nStartPortion = 0; // damit in ungueltiger Zeile ohne Portions von einer gueltigen Zeile mit der Portion Nr0 unterscieden werden kann.
+ nEndPortion = 0;
+ nHeight = 0;
+ nStartPosX = 0;
+ nTxtHeight = 0;
+ nTxtWidth = 0;
+ nCrsrHeight = 0;
+ nMaxAscent = 0;
+ bHangingPunctuation = FALSE;
+ bInvalid = TRUE;
+}
+
+EditLine::EditLine( const EditLine& r )
+{
+ DBG_CTOR( EE_EditLine, 0 );
+
+ nEnd = r.nEnd;
+ nStart = r.nStart;
+ nStartPortion = r.nStartPortion;
+ nEndPortion = r.nEndPortion;
+ bHangingPunctuation = r.bHangingPunctuation;
+
+ nHeight = 0;
+ nStartPosX = 0;
+ nTxtHeight = 0;
+ nTxtWidth = 0;
+ nCrsrHeight = 0;
+ nMaxAscent = 0;
+ bInvalid = TRUE;
+}
+
+EditLine::~EditLine()
+{
+ DBG_DTOR( EE_EditLine, 0 );
+}
+
+EditLine* EditLine::Clone() const
+{
+ EditLine* pL = new EditLine;
+ if ( aPositions.Count() )
+ {
+ pL->aPositions.Insert (aPositions.GetData(), aPositions.Count(), 0);
+ }
+ pL->nStartPosX = nStartPosX;
+ pL->nStart = nStart;
+ pL->nEnd = nEnd;
+ pL->nStartPortion = nStartPortion;
+ pL->nEndPortion = nEndPortion;
+ pL->nHeight = nHeight;
+ pL->nTxtWidth = nTxtWidth;
+ pL->nTxtHeight = nTxtHeight;
+ pL->nCrsrHeight = nCrsrHeight;
+ pL->nMaxAscent = nMaxAscent;
+
+ return pL;
+}
+
+BOOL operator == ( const EditLine& r1, const EditLine& r2 )
+{
+ if ( r1.nStart != r2.nStart )
+ return FALSE;
+
+ if ( r1.nEnd != r2.nEnd )
+ return FALSE;
+
+ if ( r1.nStartPortion != r2.nStartPortion )
+ return FALSE;
+
+ if ( r1.nEndPortion != r2.nEndPortion )
+ return FALSE;
+
+ return TRUE;
+}
+
+EditLine& EditLine::operator = ( const EditLine& r )
+{
+ nEnd = r.nEnd;
+ nStart = r.nStart;
+ nEndPortion = r.nEndPortion;
+ nStartPortion = r.nStartPortion;
+ return *this;
+}
+
+
+BOOL operator != ( const EditLine& r1, const EditLine& r2 )
+{
+ return !( r1 == r2 );
+}
+
+Size EditLine::CalcTextSize( ParaPortion& rParaPortion )
+{
+ Size aSz;
+ Size aTmpSz;
+ TextPortion* pPortion;
+
+ USHORT nIndex = GetStart();
+
+ DBG_ASSERT( rParaPortion.GetTextPortions().Count(), "GetTextSize vor CreatePortions !" );
+
+ for ( USHORT n = nStartPortion; n <= nEndPortion; n++ )
+ {
+ pPortion = rParaPortion.GetTextPortions().GetObject(n);
+ switch ( pPortion->GetKind() )
+ {
+ case PORTIONKIND_TEXT:
+ case PORTIONKIND_FIELD:
+ case PORTIONKIND_HYPHENATOR:
+ {
+ aTmpSz = pPortion->GetSize();
+ aSz.Width() += aTmpSz.Width();
+ if ( aSz.Height() < aTmpSz.Height() )
+ aSz.Height() = aTmpSz.Height();
+ }
+ break;
+ case PORTIONKIND_TAB:
+// case PORTIONKIND_EXTRASPACE:
+ {
+ aSz.Width() += pPortion->GetSize().Width();
+ }
+ break;
+ }
+ nIndex = nIndex + pPortion->GetLen();
+ }
+
+ SetHeight( (USHORT)aSz.Height() );
+ return aSz;
+}
+
+ // -------------------------------------------------------------------------
+// class EditLineList
+// -------------------------------------------------------------------------
+EditLineList::EditLineList()
+{
+}
+
+EditLineList::~EditLineList()
+{
+ Reset();
+}
+
+void EditLineList::Reset()
+{
+ for ( USHORT nLine = 0; nLine < Count(); nLine++ )
+ delete GetObject(nLine);
+ Remove( 0, Count() );
+}
+
+void EditLineList::DeleteFromLine( USHORT nDelFrom )
+{
+ DBG_ASSERT( nDelFrom <= (Count() - 1), "DeleteFromLine: Out of range" );
+ for ( USHORT nL = nDelFrom; nL < Count(); nL++ )
+ delete GetObject(nL);
+ Remove( nDelFrom, Count()-nDelFrom );
+}
+
+USHORT EditLineList::FindLine( USHORT nChar, BOOL bInclEnd )
+{
+ for ( USHORT nLine = 0; nLine < Count(); nLine++ )
+ {
+ EditLine* pLine = GetObject( nLine );
+ if ( ( bInclEnd && ( pLine->GetEnd() >= nChar ) ) ||
+ ( pLine->GetEnd() > nChar ) )
+ {
+ return nLine;
+ }
+ }
+
+ DBG_ASSERT( !bInclEnd, "Zeile nicht gefunden: FindLine" );
+ return ( Count() - 1 );
+}
+
+ // -------------------------------------------------------------------------
+// class EditSelection
+// -------------------------------------------------------------------------
+BOOL EditPaM::DbgIsBuggy( EditDoc& rDoc )
+{
+ if ( !pNode )
+ return TRUE;
+ if ( rDoc.GetPos( pNode ) >= rDoc.Count() )
+ return TRUE;
+ if ( nIndex > pNode->Len() )
+ return TRUE;
+
+ return FALSE;
+}
+
+BOOL EditSelection::DbgIsBuggy( EditDoc& rDoc )
+{
+ if ( aStartPaM.DbgIsBuggy( rDoc ) )
+ return TRUE;
+ if ( aEndPaM.DbgIsBuggy( rDoc ) )
+ return TRUE;
+
+ return FALSE;
+}
+
+EditSelection::EditSelection()
+{
+}
+
+EditSelection::EditSelection( const EditPaM& rStartAndAnd )
+{
+ // koennte noch optimiert werden!
+ // nicht erst Def-CTOR vom PaM rufen!
+ aStartPaM = rStartAndAnd;
+ aEndPaM = rStartAndAnd;
+}
+
+EditSelection::EditSelection( const EditPaM& rStart, const EditPaM& rEnd )
+{
+ // koennte noch optimiert werden!
+ aStartPaM = rStart;
+ aEndPaM = rEnd;
+}
+
+EditSelection& EditSelection::operator = ( const EditPaM& rPaM )
+{
+ aStartPaM = rPaM;
+ aEndPaM = rPaM;
+ return *this;
+}
+
+BOOL EditSelection::IsInvalid() const
+{
+ EditPaM aEmptyPaM;
+
+ if ( aStartPaM == aEmptyPaM )
+ return TRUE;
+
+ if ( aEndPaM == aEmptyPaM )
+ return TRUE;
+
+ return FALSE;
+}
+
+BOOL EditSelection::Adjust( const ContentList& rNodes )
+{
+ DBG_ASSERT( aStartPaM.GetIndex() <= aStartPaM.GetNode()->Len(), "Index im Wald in Adjust(1)" );
+ DBG_ASSERT( aEndPaM.GetIndex() <= aEndPaM.GetNode()->Len(), "Index im Wald in Adjust(2)" );
+
+ ContentNode* pStartNode = aStartPaM.GetNode();
+ ContentNode* pEndNode = aEndPaM.GetNode();
+
+ USHORT nStartNode = rNodes.GetPos( pStartNode );
+ USHORT nEndNode = rNodes.GetPos( pEndNode );
+
+ DBG_ASSERT( nStartNode != USHRT_MAX, "Node im Wald in Adjust(1)" );
+ DBG_ASSERT( nEndNode != USHRT_MAX, "Node im Wald in Adjust(2)" );
+
+ BOOL bSwap = FALSE;
+ if ( nStartNode > nEndNode )
+ bSwap = TRUE;
+ else if ( ( nStartNode == nEndNode ) && ( aStartPaM.GetIndex() > aEndPaM.GetIndex() ) )
+ bSwap = TRUE;
+
+ if ( bSwap )
+ {
+ EditPaM aTmpPaM( aStartPaM );
+ aStartPaM = aEndPaM;
+ aEndPaM = aTmpPaM;
+ }
+
+ return bSwap;
+}
+
+
+ // -------------------------------------------------------------------------
+// class EditPaM
+// -------------------------------------------------------------------------
+BOOL operator == ( const EditPaM& r1, const EditPaM& r2 )
+{
+ if ( r1.GetNode() != r2.GetNode() )
+ return FALSE;
+
+ if ( r1.GetIndex() != r2.GetIndex() )
+ return FALSE;
+
+ return TRUE;
+}
+
+EditPaM& EditPaM::operator = ( const EditPaM& rPaM )
+{
+ nIndex = rPaM.nIndex;
+ pNode = rPaM.pNode;
+ return *this;
+}
+
+BOOL operator != ( const EditPaM& r1, const EditPaM& r2 )
+{
+ return !( r1 == r2 );
+}
+
+
+ // -------------------------------------------------------------------------
+// class ContentNode
+// -------------------------------------------------------------------------
+ContentNode::ContentNode( SfxItemPool& rPool ) : aContentAttribs( rPool )
+{
+ DBG_CTOR( EE_ContentNode, 0 );
+ pWrongList = NULL;
+}
+
+ContentNode::ContentNode( const XubString& rStr, const ContentAttribs& rContentAttribs ) :
+ XubString( rStr ), aContentAttribs( rContentAttribs )
+{
+ DBG_CTOR( EE_ContentNode, 0 );
+ pWrongList = NULL;
+}
+
+ContentNode::~ContentNode()
+{
+ DBG_DTOR( EE_ContentNode, 0 );
+#ifndef SVX_LIGHT
+ delete pWrongList;
+#endif
+}
+
+void ContentNode::ExpandAttribs( USHORT nIndex, USHORT nNew, SfxItemPool& rItemPool )
+{
+ if ( !nNew )
+ return;
+
+ // Da Features anders behandelt werden als normale Zeichenattribute,
+ // kann sich hier auch die Sortierung der Start-Liste aendern!
+ // In jedem if..., in dem weiter (n) Moeglichkeiten aufgrund von
+ // bFeature oder Spezialfall existieren,
+ // muessen (n-1) Moeglichkeiten mit bResort versehen werden.
+ // Die wahrscheinlichste Moeglichkeit erhaelt kein bResort,
+ // so dass nicht neu sortiert wird, wenn sich alle Attribute
+ // gleich verhalten.
+ BOOL bResort = FALSE;
+ BOOL bExpandedEmptyAtIndexNull = FALSE;
+
+ USHORT nAttr = 0;
+ EditCharAttrib* pAttrib = GetAttrib( aCharAttribList.GetAttribs(), nAttr );
+ while ( pAttrib )
+ {
+ if ( pAttrib->GetEnd() >= nIndex )
+ {
+ // Alle Attribute hinter der Einfuegeposition verschieben...
+ if ( pAttrib->GetStart() > nIndex )
+ {
+ pAttrib->MoveForward( nNew );
+ }
+ // 0: Leeres Attribut expandieren, wenn an Einfuegestelle
+ else if ( pAttrib->IsEmpty() )
+ {
+ // Index nicht pruefen, leeres durfte nur dort liegen.
+ // Wenn spaeter doch Ueberpruefung:
+ // Spezialfall: Start == 0; AbsLen == 1, nNew = 1 => Expand, weil durch Absatzumbruch!
+ // Start <= nIndex, End >= nIndex => Start=End=nIndex!
+// if ( pAttrib->GetStart() == nIndex )
+ pAttrib->Expand( nNew );
+ if ( pAttrib->GetStart() == 0 )
+ bExpandedEmptyAtIndexNull = TRUE;
+ }
+ // 1: Attribut startet davor, geht bis Index...
+ else if ( pAttrib->GetEnd() == nIndex ) // Start muss davor liegen
+ {
+ // Nur expandieren, wenn kein Feature,
+ // und wenn nicht in ExcludeListe!
+ // Sonst geht z.B. ein UL bis zum neuen ULDB, beide expandieren
+// if ( !pAttrib->IsFeature() && !rExclList.FindAttrib( pAttrib->Which() ) )
+ if ( !pAttrib->IsFeature() && !aCharAttribList.FindEmptyAttrib( pAttrib->Which(), nIndex ) )
+ {
+ if ( !pAttrib->IsEdge() )
+ pAttrib->Expand( nNew );
+ }
+ else
+ bResort = TRUE;
+ }
+ // 2: Attribut startet davor, geht hinter Index...
+ else if ( ( pAttrib->GetStart() < nIndex ) && ( pAttrib->GetEnd() > nIndex ) )
+ {
+ DBG_ASSERT( !pAttrib->IsFeature(), "Grosses Feature?!" );
+ pAttrib->Expand( nNew );
+ }
+ // 3: Attribut startet auf Index...
+ else if ( pAttrib->GetStart() == nIndex )
+ {
+ if ( pAttrib->IsFeature() )
+ {
+ pAttrib->MoveForward( nNew );
+ bResort = TRUE;
+ }
+ else
+ {
+ BOOL bExpand = FALSE;
+ if ( nIndex == 0 )
+ {
+ bExpand = TRUE;
+ if( bExpandedEmptyAtIndexNull )
+ {
+ // Check if this kind of attribut was empty and expanded here...
+ USHORT nW = pAttrib->GetItem()->Which();
+ for ( USHORT nA = 0; nA < nAttr; nA++ )
+ {
+ EditCharAttrib* pA = aCharAttribList.GetAttribs()[nA];
+ if ( ( pA->GetStart() == 0 ) && ( pA->GetItem()->Which() == nW ) )
+ {
+ bExpand = FALSE;
+ break;
+ }
+ }
+
+ }
+ }
+ if ( bExpand )
+ {
+ pAttrib->Expand( nNew );
+ bResort = TRUE;
+ }
+ else
+ {
+ pAttrib->MoveForward( nNew );
+ }
+ }
+ }
+ }
+
+ if ( pAttrib->IsEdge() )
+ pAttrib->SetEdge( FALSE );
+
+ DBG_ASSERT( !pAttrib->IsFeature() || ( pAttrib->GetLen() == 1 ), "Expand: FeaturesLen != 1" );
+
+ DBG_ASSERT( pAttrib->GetStart() <= pAttrib->GetEnd(), "Expand: Attribut verdreht!" );
+ DBG_ASSERT( ( pAttrib->GetEnd() <= Len() ), "Expand: Attrib groesser als Absatz!" );
+ if ( pAttrib->IsEmpty() )
+ {
+ DBG_ERROR( "Leeres Attribut nach ExpandAttribs?" );
+ bResort = TRUE;
+ aCharAttribList.GetAttribs().Remove( nAttr );
+ rItemPool.Remove( *pAttrib->GetItem() );
+ delete pAttrib;
+ nAttr--;
+ }
+ nAttr++;
+ pAttrib = GetAttrib( aCharAttribList.GetAttribs(), nAttr );
+ }
+
+ if ( bResort )
+ aCharAttribList.ResortAttribs();
+
+#ifndef SVX_LIGHT
+ if ( pWrongList )
+ {
+ BOOL bSep = ( GetChar( nIndex ) == ' ' ) || IsFeature( nIndex );
+ pWrongList->TextInserted( nIndex, nNew, bSep );
+ }
+#endif // !SVX_LIGHT
+
+#ifdef EDITDEBUG
+ DBG_ASSERT( CheckOrderedList( aCharAttribList.GetAttribs(), TRUE ), "Expand: Start-Liste verdreht" );
+#endif
+}
+
+void ContentNode::CollapsAttribs( USHORT nIndex, USHORT nDeleted, SfxItemPool& rItemPool )
+{
+ if ( !nDeleted )
+ return;
+
+ // Da Features anders behandelt werden als normale Zeichenattribute,
+ // kann sich hier auch die Sortierung der Start-Liste aendern!
+ BOOL bResort = FALSE;
+ BOOL bDelAttr = FALSE;
+ USHORT nEndChanges = nIndex+nDeleted;
+
+ USHORT nAttr = 0;
+ EditCharAttrib* pAttrib = GetAttrib( aCharAttribList.GetAttribs(), nAttr );
+ while ( pAttrib )
+ {
+ bDelAttr = FALSE;
+ if ( pAttrib->GetEnd() >= nIndex )
+ {
+ // Alles Attribute hinter der Einfuegeposition verschieben...
+ if ( pAttrib->GetStart() >= nEndChanges )
+ {
+ pAttrib->MoveBackward( nDeleted );
+ }
+ // 1. Innenliegende Attribute loeschen...
+ else if ( ( pAttrib->GetStart() >= nIndex ) && ( pAttrib->GetEnd() <= nEndChanges ) )
+ {
+ // Spezialfall: Attrubt deckt genau den Bereich ab
+ // => als leeres Attribut behalten.
+ if ( !pAttrib->IsFeature() && ( pAttrib->GetStart() == nIndex ) && ( pAttrib->GetEnd() == nEndChanges ) )
+ pAttrib->GetEnd() = nIndex; // leer
+ else
+ bDelAttr = TRUE;
+ }
+ // 2. Attribut beginnt davor, endet drinnen oder dahinter...
+ else if ( ( pAttrib->GetStart() <= nIndex ) && ( pAttrib->GetEnd() > nIndex ) )
+ {
+ DBG_ASSERT( !pAttrib->IsFeature(), "Collapsing Feature!" );
+ if ( pAttrib->GetEnd() <= nEndChanges ) // endet drinnen
+ pAttrib->GetEnd() = nIndex;
+ else
+ pAttrib->Collaps( nDeleted ); // endet dahinter
+ }
+ // 3. Attribut beginnt drinnen, endet dahinter...
+ else if ( ( pAttrib->GetStart() >= nIndex ) && ( pAttrib->GetEnd() > nEndChanges ) )
+ {
+ // Features duerfen nicht expandieren!
+ if ( pAttrib->IsFeature() )
+ {
+ pAttrib->MoveBackward( nDeleted );
+ bResort = TRUE;
+ }
+ else
+ {
+ pAttrib->GetStart() = nEndChanges;
+ pAttrib->MoveBackward( nDeleted );
+ }
+ }
+ }
+ DBG_ASSERT( !pAttrib->IsFeature() || ( pAttrib->GetLen() == 1 ), "Expand: FeaturesLen != 1" );
+
+ DBG_ASSERT( pAttrib->GetStart() <= pAttrib->GetEnd(), "Collaps: Attribut verdreht!" );
+ DBG_ASSERT( ( pAttrib->GetEnd() <= Len()) || bDelAttr, "Collaps: Attrib groesser als Absatz!" );
+ if ( bDelAttr /* || pAttrib->IsEmpty() */ )
+ {
+ bResort = TRUE;
+ aCharAttribList.GetAttribs().Remove( nAttr );
+ rItemPool.Remove( *pAttrib->GetItem() );
+ delete pAttrib;
+ nAttr--;
+ }
+ else if ( pAttrib->IsEmpty() )
+ aCharAttribList.HasEmptyAttribs() = TRUE;
+
+ nAttr++;
+ pAttrib = GetAttrib( aCharAttribList.GetAttribs(), nAttr );
+ }
+
+ if ( bResort )
+ aCharAttribList.ResortAttribs();
+
+#ifndef SVX_LIGHT
+ if ( pWrongList )
+ pWrongList->TextDeleted( nIndex, nDeleted );
+#endif // !SVX_LIGHT
+
+#ifdef EDITDEBUG
+ DBG_ASSERT( CheckOrderedList( aCharAttribList.GetAttribs(), TRUE ), "Collaps: Start-Liste verdreht" );
+#endif
+}
+
+void ContentNode::CopyAndCutAttribs( ContentNode* pPrevNode, SfxItemPool& rPool, BOOL bKeepEndingAttribs )
+{
+ DBG_ASSERT( pPrevNode, "kopieren von Attributen auf einen NULL-Pointer ?" );
+
+ xub_StrLen nCut = pPrevNode->Len();
+
+ USHORT nAttr = 0;
+ EditCharAttrib* pAttrib = GetAttrib( pPrevNode->GetCharAttribs().GetAttribs(), nAttr );
+ while ( pAttrib )
+ {
+ if ( pAttrib->GetEnd() < nCut )
+ {
+ // bleiben unveraendert....
+ ;
+ }
+ else if ( pAttrib->GetEnd() == nCut )
+ {
+ // muessen als leeres Attribut kopiert werden.
+ if ( bKeepEndingAttribs && !pAttrib->IsFeature() && !aCharAttribList.FindAttrib( pAttrib->GetItem()->Which(), 0 ) )
+ {
+ EditCharAttrib* pNewAttrib = MakeCharAttrib( rPool, *(pAttrib->GetItem()), 0, 0 );
+ DBG_ASSERT( pNewAttrib, "MakeCharAttrib fehlgeschlagen!" );
+ aCharAttribList.InsertAttrib( pNewAttrib );
+ }
+ }
+ else if ( pAttrib->IsInside( nCut ) || ( !nCut && !pAttrib->GetStart() && !pAttrib->IsFeature() ) )
+ {
+ // Wenn ganz vorne gecuttet wird, muss das Attribut erhalten bleiben!
+ // muessen kopiert und geaendert werden
+ EditCharAttrib* pNewAttrib = MakeCharAttrib( rPool, *(pAttrib->GetItem()), 0, pAttrib->GetEnd()-nCut );
+ DBG_ASSERT( pNewAttrib, "MakeCharAttrib fehlgeschlagen!" );
+ aCharAttribList.InsertAttrib( pNewAttrib );
+ // stutzen:
+ pAttrib->GetEnd() = nCut;
+ }
+ else
+ {
+ // alle dahinter verschieben in den neuen Node (this)
+// pPrevNode->GetCharAttribs().RemoveAttrib( pAttrib );
+ pPrevNode->GetCharAttribs().GetAttribs().Remove( nAttr );
+ aCharAttribList.InsertAttrib( pAttrib );
+ DBG_ASSERT( pAttrib->GetStart() >= nCut, "Start < nCut!" );
+ DBG_ASSERT( pAttrib->GetEnd() >= nCut, "End < nCut!" );
+ pAttrib->GetStart() = pAttrib->GetStart() - nCut;
+ pAttrib->GetEnd() = pAttrib->GetEnd() - nCut;
+ nAttr--;
+ }
+ nAttr++;
+ pAttrib = GetAttrib( pPrevNode->GetCharAttribs().GetAttribs(), nAttr );
+ }
+}
+
+void ContentNode::AppendAttribs( ContentNode* pNextNode )
+{
+ DBG_ASSERT( pNextNode, "kopieren von Attributen von einen NULL-Pointer ?" );
+
+ USHORT nNewStart = Len();
+
+#ifdef EDITDEBUG
+ DBG_ASSERT( aCharAttribList.DbgCheckAttribs(), "Attribute VOR AppendAttribs kaputt" );
+#endif
+
+ USHORT nAttr = 0;
+ EditCharAttrib* pAttrib = GetAttrib( pNextNode->GetCharAttribs().GetAttribs(), nAttr );
+ while ( pAttrib )
+ {
+ // alle Attribute verschieben in den aktuellen Node (this)
+ BOOL bMelted = FALSE;
+ if ( ( pAttrib->GetStart() == 0 ) && ( !pAttrib->IsFeature() ) )
+ {
+ // Evtl koennen Attribute zusammengefasst werden:
+ USHORT nTmpAttr = 0;
+ EditCharAttrib* pTmpAttrib = GetAttrib( aCharAttribList.GetAttribs(), nTmpAttr );
+ while ( !bMelted && pTmpAttrib )
+ {
+ if ( pTmpAttrib->GetEnd() == nNewStart )
+ {
+ if ( ( pTmpAttrib->Which() == pAttrib->Which() ) &&
+ ( *(pTmpAttrib->GetItem()) == *(pAttrib->GetItem() ) ) )
+ {
+ pTmpAttrib->GetEnd() =
+ pTmpAttrib->GetEnd() + pAttrib->GetLen();
+ pNextNode->GetCharAttribs().GetAttribs().Remove( nAttr );
+ // Vom Pool abmelden ?!
+ delete pAttrib;
+ bMelted = TRUE;
+ }
+ }
+ ++nTmpAttr;
+ pTmpAttrib = GetAttrib( aCharAttribList.GetAttribs(), nTmpAttr );
+ }
+ }
+
+ if ( !bMelted )
+ {
+ pAttrib->GetStart() = pAttrib->GetStart() + nNewStart;
+ pAttrib->GetEnd() = pAttrib->GetEnd() + nNewStart;
+ aCharAttribList.InsertAttrib( pAttrib );
+ ++nAttr;
+ }
+ pAttrib = GetAttrib( pNextNode->GetCharAttribs().GetAttribs(), nAttr );
+ }
+ // Fuer die Attribute, die nur ruebergewandert sind:
+ pNextNode->GetCharAttribs().Clear();
+
+#ifdef EDITDEBUG
+ DBG_ASSERT( aCharAttribList.DbgCheckAttribs(), "Attribute NACH AppendAttribs kaputt" );
+#endif
+}
+
+void ContentNode::CreateDefFont()
+{
+ // Erst alle Informationen aus dem Style verwenden...
+ SfxStyleSheet* pS = aContentAttribs.GetStyleSheet();
+ if ( pS )
+ CreateFont( GetCharAttribs().GetDefFont(), pS->GetItemSet() );
+
+ // ... dann die harte Absatzformatierung rueberbuegeln...
+ CreateFont( GetCharAttribs().GetDefFont(),
+ GetContentAttribs().GetItems(), pS == NULL );
+}
+
+void ContentNode::SetStyleSheet( SfxStyleSheet* pS, const SvxFont& rFontFromStyle )
+{
+ aContentAttribs.SetStyleSheet( pS );
+
+ // Erst alle Informationen aus dem Style verwenden...
+ GetCharAttribs().GetDefFont() = rFontFromStyle;
+ // ... dann die harte Absatzformatierung rueberbuegeln...
+ CreateFont( GetCharAttribs().GetDefFont(),
+ GetContentAttribs().GetItems(), pS == NULL );
+}
+
+void ContentNode::SetStyleSheet( SfxStyleSheet* pS, BOOL bRecalcFont )
+{
+ aContentAttribs.SetStyleSheet( pS );
+ if ( bRecalcFont )
+ CreateDefFont();
+}
+
+void ContentNode::DestroyWrongList()
+{
+#ifndef SVX_LIGHT
+ delete pWrongList;
+#endif
+ pWrongList = NULL;
+}
+
+void ContentNode::CreateWrongList()
+{
+ DBG_ASSERT( !pWrongList, "WrongList existiert schon!" );
+#ifndef SVX_LIGHT
+ pWrongList = new WrongList;
+#endif
+}
+
+void ContentNode::SetWrongList( WrongList* p )
+{
+ DBG_ASSERT( !pWrongList, "WrongList existiert schon!" );
+ pWrongList = p;
+}
+
+ // -------------------------------------------------------------------------
+// class ContentAttribs
+// -------------------------------------------------------------------------
+ContentAttribs::ContentAttribs( SfxItemPool& rPool ) :
+ aAttribSet( rPool, EE_PARA_START, EE_CHAR_END )
+{
+ pStyle = 0;
+}
+
+ContentAttribs::ContentAttribs( const ContentAttribs& rRef ) :
+ aAttribSet( rRef.aAttribSet )
+{
+ pStyle = rRef.pStyle;
+}
+
+ContentAttribs::~ContentAttribs()
+{
+}
+
+SvxTabStop ContentAttribs::FindTabStop( long nCurPos, USHORT nDefTab )
+{
+ const SvxTabStopItem& rTabs = (const SvxTabStopItem&) GetItem( EE_PARA_TABS );
+ for ( USHORT i = 0; i < rTabs.Count(); i++ )
+ {
+ const SvxTabStop& rTab = rTabs[i];
+ if ( rTab.GetTabPos() > nCurPos )
+ return rTab;
+ }
+
+ // DefTab ermitteln...
+ SvxTabStop aTabStop;
+ long x = nCurPos / nDefTab + 1;
+ aTabStop.GetTabPos() = nDefTab * x;
+ return aTabStop;
+}
+
+void ContentAttribs::SetStyleSheet( SfxStyleSheet* pS )
+{
+ BOOL bStyleChanged = ( pStyle != pS );
+ pStyle = pS;
+ // #104799# Only when other style sheet, not when current style sheet modified
+ if ( pStyle && bStyleChanged )
+ {
+ // Gezielt die Attribute aus der Absatzformatierung entfernen, die im Style
+ // spezifiziert sind, damit die Attribute des Styles wirken koennen.
+ const SfxItemSet& rStyleAttribs = pStyle->GetItemSet();
+ for ( USHORT nWhich = EE_PARA_START; nWhich <= EE_CHAR_END; nWhich++ )
+ {
+ // #99635# Don't change bullet on/off
+ if ( ( nWhich != EE_PARA_BULLETSTATE ) && ( rStyleAttribs.GetItemState( nWhich ) == SFX_ITEM_ON ) )
+ aAttribSet.ClearItem( nWhich );
+ }
+ }
+}
+
+const SfxPoolItem& ContentAttribs::GetItem( USHORT nWhich )
+{
+ // Harte Absatzattribute haben Vorrang!
+ SfxItemSet* pTakeFrom = &aAttribSet;
+ if ( pStyle && ( aAttribSet.GetItemState( nWhich, FALSE ) != SFX_ITEM_ON ) )
+ pTakeFrom = &pStyle->GetItemSet();
+
+ return pTakeFrom->Get( nWhich );
+}
+
+BOOL ContentAttribs::HasItem( USHORT nWhich )
+{
+ BOOL bHasItem = FALSE;
+ if ( aAttribSet.GetItemState( nWhich, FALSE ) == SFX_ITEM_ON )
+ bHasItem = TRUE;
+ else if ( pStyle && pStyle->GetItemSet().GetItemState( nWhich ) == SFX_ITEM_ON )
+ bHasItem = TRUE;
+
+ return bHasItem;
+}
+
+
+
+ // ----------------------------------------------------------------------
+// class ItemList
+// ----------------------------------------------------------------------
+const SfxPoolItem* ItemList::FindAttrib( USHORT nWhich )
+{
+ const SfxPoolItem* pItem = First();
+ while ( pItem && ( pItem->Which() != nWhich ) )
+ pItem = Next();
+
+ return pItem;
+}
+
+ // -------------------------------------------------------------------------
+// class EditDoc
+// -------------------------------------------------------------------------
+EditDoc::EditDoc( SfxItemPool* pPool )
+{
+ if ( pPool )
+ {
+ pItemPool = pPool;
+ bOwnerOfPool = FALSE;
+ }
+ else
+ {
+ pItemPool = new EditEngineItemPool( FALSE );
+ bOwnerOfPool = TRUE;
+ }
+
+ nDefTab = DEFTAB;
+ bIsVertical = FALSE;
+ bIsFixedCellHeight = FALSE;
+
+ // Don't create a empty node, Clear() will be called in EditEngine-CTOR
+
+ SetModified( FALSE );
+};
+
+EditDoc::~EditDoc()
+{
+ ImplDestroyContents();
+ if ( bOwnerOfPool )
+ SfxItemPool::Free(pItemPool);
+}
+
+void EditDoc::ImplDestroyContents()
+{
+ for ( USHORT nNode = Count(); nNode; )
+ RemoveItemsFromPool( GetObject( --nNode ) );
+ DeleteAndDestroy( 0, Count() );
+}
+
+void EditDoc::RemoveItemsFromPool( ContentNode* pNode )
+{
+ for ( USHORT nAttr = 0; nAttr < pNode->GetCharAttribs().Count(); nAttr++ )
+ {
+ EditCharAttrib* pAttr = pNode->GetCharAttribs().GetAttribs()[nAttr];
+ GetItemPool().Remove( *pAttr->GetItem() );
+ }
+}
+
+void CreateFont( SvxFont& rFont, const SfxItemSet& rSet, bool bSearchInParent, short nScriptType )
+{
+ Font aPrevFont( rFont );
+ rFont.SetAlign( ALIGN_BASELINE );
+ rFont.SetTransparent( TRUE );
+
+ USHORT nWhich_FontInfo = GetScriptItemId( EE_CHAR_FONTINFO, nScriptType );
+ USHORT nWhich_Language = GetScriptItemId( EE_CHAR_LANGUAGE, nScriptType );
+ USHORT nWhich_FontHeight = GetScriptItemId( EE_CHAR_FONTHEIGHT, nScriptType );
+ USHORT nWhich_Weight = GetScriptItemId( EE_CHAR_WEIGHT, nScriptType );
+ USHORT nWhich_Italic = GetScriptItemId( EE_CHAR_ITALIC, nScriptType );
+
+ if ( bSearchInParent || ( rSet.GetItemState( nWhich_FontInfo ) == SFX_ITEM_ON ) )
+ {
+ const SvxFontItem& rFontItem = (const SvxFontItem&)rSet.Get( nWhich_FontInfo );
+ rFont.SetName( rFontItem.GetFamilyName() );
+ rFont.SetFamily( rFontItem.GetFamily() );
+ rFont.SetPitch( rFontItem.GetPitch() );
+ rFont.SetCharSet( rFontItem.GetCharSet() );
+ }
+ if ( bSearchInParent || ( rSet.GetItemState( nWhich_Language ) == SFX_ITEM_ON ) )
+ rFont.SetLanguage( ((const SvxLanguageItem&)rSet.Get( nWhich_Language )).GetLanguage() );
+ if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_COLOR ) == SFX_ITEM_ON ) )
+ rFont.SetColor( ((const SvxColorItem&)rSet.Get( EE_CHAR_COLOR )).GetValue() );
+ if ( bSearchInParent || ( rSet.GetItemState( nWhich_FontHeight ) == SFX_ITEM_ON ) )
+ rFont.SetSize( Size( rFont.GetSize().Width(), ((const SvxFontHeightItem&)rSet.Get( nWhich_FontHeight ) ).GetHeight() ) );
+ if ( bSearchInParent || ( rSet.GetItemState( nWhich_Weight ) == SFX_ITEM_ON ) )
+ rFont.SetWeight( ((const SvxWeightItem&)rSet.Get( nWhich_Weight )).GetWeight() );
+ if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_UNDERLINE ) == SFX_ITEM_ON ) )
+ rFont.SetUnderline( ((const SvxUnderlineItem&)rSet.Get( EE_CHAR_UNDERLINE )).GetLineStyle() );
+ if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_OVERLINE ) == SFX_ITEM_ON ) )
+ rFont.SetOverline( ((const SvxOverlineItem&)rSet.Get( EE_CHAR_OVERLINE )).GetLineStyle() );
+ if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_STRIKEOUT ) == SFX_ITEM_ON ) )
+ rFont.SetStrikeout( ((const SvxCrossedOutItem&)rSet.Get( EE_CHAR_STRIKEOUT )).GetStrikeout() );
+ if ( bSearchInParent || ( rSet.GetItemState( nWhich_Italic ) == SFX_ITEM_ON ) )
+ rFont.SetItalic( ((const SvxPostureItem&)rSet.Get( nWhich_Italic )).GetPosture() );
+ if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_OUTLINE ) == SFX_ITEM_ON ) )
+ rFont.SetOutline( ((const SvxContourItem&)rSet.Get( EE_CHAR_OUTLINE )).GetValue() );
+ if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_SHADOW ) == SFX_ITEM_ON ) )
+ rFont.SetShadow( ((const SvxShadowedItem&)rSet.Get( EE_CHAR_SHADOW )).GetValue() );
+ if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_ESCAPEMENT ) == SFX_ITEM_ON ) )
+ {
+ const SvxEscapementItem& rEsc = (const SvxEscapementItem&) rSet.Get( EE_CHAR_ESCAPEMENT );
+
+ USHORT nProp = rEsc.GetProp();
+ rFont.SetPropr( (BYTE)nProp );
+
+ short nEsc = rEsc.GetEsc();
+ if ( nEsc == DFLT_ESC_AUTO_SUPER )
+ nEsc = 100 - nProp;
+ else if ( nEsc == DFLT_ESC_AUTO_SUB )
+ nEsc = sal::static_int_cast< short >( -( 100 - nProp ) );
+ rFont.SetEscapement( nEsc );
+ }
+ if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_PAIRKERNING ) == SFX_ITEM_ON ) )
+ rFont.SetKerning( ((const SvxAutoKernItem&)rSet.Get( EE_CHAR_PAIRKERNING )).GetValue() );
+ if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_KERNING ) == SFX_ITEM_ON ) )
+ rFont.SetFixKerning( ((const SvxKerningItem&)rSet.Get( EE_CHAR_KERNING )).GetValue() );
+ if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_WLM ) == SFX_ITEM_ON ) )
+ rFont.SetWordLineMode( ((const SvxWordLineModeItem&)rSet.Get( EE_CHAR_WLM )).GetValue() );
+ if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_EMPHASISMARK ) == SFX_ITEM_ON ) )
+ rFont.SetEmphasisMark( ((const SvxEmphasisMarkItem&)rSet.Get( EE_CHAR_EMPHASISMARK )).GetValue() );
+ if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_RELIEF ) == SFX_ITEM_ON ) )
+ rFont.SetRelief( (FontRelief)((const SvxCharReliefItem&)rSet.Get( EE_CHAR_RELIEF )).GetValue() );
+
+ // Ob ich jetzt den ganzen Font vergleiche, oder vor jeder Aenderung
+ // pruefe, ob der Wert sich aendert, bleibt sich relativ gleich.
+ // So ggf ein MakeUniqFont im Font mehr, dafuer bei Aenderung schnellerer
+ // Abbruch der Abfrage, oder ich musste noch jedesmal ein bChanged pflegen.
+ if ( rFont == aPrevFont )
+ rFont = aPrevFont; // => Gleicher ImpPointer fuer IsSameInstance
+}
+
+void EditDoc::CreateDefFont( BOOL bUseStyles )
+{
+ SfxItemSet aTmpSet( GetItemPool(), EE_PARA_START, EE_CHAR_END );
+ CreateFont( aDefFont, aTmpSet );
+ aDefFont.SetVertical( IsVertical() );
+ aDefFont.SetOrientation( IsVertical() ? 2700 : 0 );
+
+ for ( USHORT nNode = 0; nNode < Count(); nNode++ )
+ {
+ ContentNode* pNode = GetObject( nNode );
+ pNode->GetCharAttribs().GetDefFont() = aDefFont;
+ if ( bUseStyles )
+ pNode->CreateDefFont();
+ }
+}
+
+static const sal_Unicode aCR[] = { 0x0d, 0x00 };
+static const sal_Unicode aLF[] = { 0x0a, 0x00 };
+static const sal_Unicode aCRLF[] = { 0x0d, 0x0a, 0x00 };
+
+XubString EditDoc::GetSepStr( LineEnd eEnd )
+{
+ XubString aSep;
+ if ( eEnd == LINEEND_CR )
+ aSep = aCR;
+ else if ( eEnd == LINEEND_LF )
+ aSep = aLF;
+ else
+ aSep = aCRLF;
+ return aSep;
+}
+
+XubString EditDoc::GetText( LineEnd eEnd ) const
+{
+ ULONG nLen = GetTextLen();
+ USHORT nNodes = Count();
+
+ String aSep = EditDoc::GetSepStr( eEnd );
+ USHORT nSepSize = aSep.Len();
+
+ if ( nSepSize )
+ nLen += nNodes * nSepSize;
+ if ( nLen > 0xFFFb / sizeof(xub_Unicode) )
+ {
+ DBG_ERROR( "Text zu gross fuer String" );
+ return XubString();
+ }
+ xub_Unicode* pStr = new xub_Unicode[nLen+1];
+ xub_Unicode* pCur = pStr;
+ USHORT nLastNode = nNodes-1;
+ for ( USHORT nNode = 0; nNode < nNodes; nNode++ )
+ {
+ XubString aTmp( GetParaAsString( GetObject(nNode) ) );
+ memcpy( pCur, aTmp.GetBuffer(), aTmp.Len()*sizeof(sal_Unicode) );
+ pCur += aTmp.Len();
+ if ( nSepSize && ( nNode != nLastNode ) )
+ {
+ memcpy( pCur, aSep.GetBuffer(), nSepSize*sizeof(sal_Unicode ) );
+ pCur += nSepSize;
+ }
+ }
+ *pCur = '\0';
+ XubString aASCIIText( pStr );
+ delete[] pStr;
+ return aASCIIText;
+}
+
+XubString EditDoc::GetParaAsString( USHORT nNode ) const
+{
+ return GetParaAsString( SaveGetObject( nNode ) );
+}
+
+XubString EditDoc::GetParaAsString( ContentNode* pNode, USHORT nStartPos, USHORT nEndPos, BOOL bResolveFields ) const
+{
+ if ( nEndPos > pNode->Len() )
+ nEndPos = pNode->Len();
+
+ DBG_ASSERT( nStartPos <= nEndPos, "Start und Ende vertauscht?" );
+
+ USHORT nIndex = nStartPos;
+ XubString aStr;
+ EditCharAttrib* pNextFeature = pNode->GetCharAttribs().FindFeature( nIndex );
+ while ( nIndex < nEndPos )
+ {
+ USHORT nEnd = nEndPos;
+ if ( pNextFeature && ( pNextFeature->GetStart() < nEnd ) )
+ nEnd = pNextFeature->GetStart();
+ else
+ pNextFeature = 0; // Feature interessiert unten nicht
+
+ DBG_ASSERT( nEnd >= nIndex, "Ende vorm Index?" );
+ //!! beware of sub string length of -1 which is also defined as STRING_LEN and
+ //!! thus would result in adding the whole sub string up to the end of the node !!
+ if (nEnd > nIndex)
+ aStr += XubString( *pNode, nIndex, nEnd - nIndex );
+
+ if ( pNextFeature )
+ {
+ switch ( pNextFeature->GetItem()->Which() )
+ {
+ case EE_FEATURE_TAB: aStr += '\t';
+ break;
+ case EE_FEATURE_LINEBR: aStr += '\x0A';
+ break;
+ case EE_FEATURE_FIELD: if ( bResolveFields )
+ aStr += ((EditCharAttribField*)pNextFeature)->GetFieldValue();
+ break;
+ default: DBG_ERROR( "Was fuer ein Feature ?" );
+ }
+ pNextFeature = pNode->GetCharAttribs().FindFeature( ++nEnd );
+ }
+ nIndex = nEnd;
+ }
+ return aStr;
+}
+
+ULONG EditDoc::GetTextLen() const
+{
+ ULONG nLen = 0;
+ for ( USHORT nNode = 0; nNode < Count(); nNode++ )
+ {
+ ContentNode* pNode = GetObject( nNode );
+ nLen += pNode->Len();
+ // Felder k”nnen laenger sein als der Platzhalter im Node.
+ const CharAttribArray& rAttrs = pNode->GetCharAttribs().GetAttribs();
+ for ( USHORT nAttr = rAttrs.Count(); nAttr; )
+ {
+ EditCharAttrib* pAttr = rAttrs[--nAttr];
+ if ( pAttr->Which() == EE_FEATURE_FIELD )
+ {
+ USHORT nFieldLen = ((EditCharAttribField*)pAttr)->GetFieldValue().Len();
+ if ( !nFieldLen )
+ nLen--;
+ else
+ nLen += nFieldLen-1;
+ }
+ }
+ }
+ return nLen;
+}
+
+EditPaM EditDoc::Clear()
+{
+ ImplDestroyContents();
+
+ ContentNode* pNode = new ContentNode( GetItemPool() );
+ Insert( pNode, 0 );
+
+ CreateDefFont( FALSE );
+
+ SetModified( FALSE );
+
+ EditPaM aPaM( pNode, 0 );
+ return aPaM;
+}
+
+void EditDoc::SetModified( BOOL b )
+{
+ bModified = b;
+ if ( bModified )
+ {
+ aModifyHdl.Call( NULL );
+ }
+}
+
+EditPaM EditDoc::RemoveText()
+{
+ // Das alte ItemSetmerken, damit z.B. im Chart Font behalten bleibt
+ ContentNode* pPrevFirstNode = GetObject(0);
+ SfxStyleSheet* pPrevStyle = pPrevFirstNode->GetStyleSheet();
+ SfxItemSet aPrevSet( pPrevFirstNode->GetContentAttribs().GetItems() );
+ Font aPrevFont( pPrevFirstNode->GetCharAttribs().GetDefFont() );
+
+ ImplDestroyContents();
+
+ ContentNode* pNode = new ContentNode( GetItemPool() );
+ Insert( pNode, 0 );
+
+ pNode->SetStyleSheet( pPrevStyle, FALSE );
+ pNode->GetContentAttribs().GetItems().Set( aPrevSet );
+ pNode->GetCharAttribs().GetDefFont() = aPrevFont;
+
+ SetModified( TRUE );
+
+ EditPaM aPaM( pNode, 0 );
+ return aPaM;
+}
+
+void EditDoc::InsertText( const EditPaM& rPaM, xub_Unicode c )
+{
+ DBG_ASSERT( c != 0x0A, "EditDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
+ DBG_ASSERT( c != 0x0D, "EditDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
+ DBG_ASSERT( c != '\t', "EditDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
+
+ rPaM.GetNode()->Insert( c, rPaM.GetIndex() );
+ rPaM.GetNode()->ExpandAttribs( rPaM.GetIndex(), 1, GetItemPool() );
+
+ SetModified( TRUE );
+}
+
+EditPaM EditDoc::InsertText( EditPaM aPaM, const XubString& rStr )
+{
+ DBG_ASSERT( rStr.Search( 0x0A ) == STRING_NOTFOUND, "EditDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
+ DBG_ASSERT( rStr.Search( 0x0D ) == STRING_NOTFOUND, "EditDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
+ DBG_ASSERT( rStr.Search( '\t' ) == STRING_NOTFOUND, "EditDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
+ DBG_ASSERT( aPaM.GetNode(), "Blinder PaM in EditDoc::InsertText1" );
+
+ aPaM.GetNode()->Insert( rStr, aPaM.GetIndex() );
+ aPaM.GetNode()->ExpandAttribs( aPaM.GetIndex(), rStr.Len(), GetItemPool() );
+ aPaM.GetIndex() = aPaM.GetIndex() + rStr.Len();
+
+ SetModified( TRUE );
+
+ return aPaM;
+}
+
+EditPaM EditDoc::InsertParaBreak( EditPaM aPaM, BOOL bKeepEndingAttribs )
+{
+ DBG_ASSERT( aPaM.GetNode(), "Blinder PaM in EditDoc::InsertParaBreak" );
+ ContentNode* pCurNode = aPaM.GetNode();
+ USHORT nPos = GetPos( pCurNode );
+ XubString aStr = aPaM.GetNode()->Copy( aPaM.GetIndex() );
+ aPaM.GetNode()->Erase( aPaM.GetIndex() );
+
+ // the paragraph attributes...
+ ContentAttribs aContentAttribs( aPaM.GetNode()->GetContentAttribs() );
+
+ // for a new paragraph we like to have the bullet/numbering visible by default
+ aContentAttribs.GetItems().Put( SfxBoolItem( EE_PARA_BULLETSTATE, TRUE), EE_PARA_BULLETSTATE );
+
+ // ContenNode-CTOR kopiert auch die Absatzattribute
+ ContentNode* pNode = new ContentNode( aStr, aContentAttribs );
+
+ // Den Default-Font kopieren
+ pNode->GetCharAttribs().GetDefFont() = aPaM.GetNode()->GetCharAttribs().GetDefFont();
+ SfxStyleSheet* pStyle = aPaM.GetNode()->GetStyleSheet();
+ if ( pStyle )
+ {
+ XubString aFollow( pStyle->GetFollow() );
+ if ( aFollow.Len() && ( aFollow != pStyle->GetName() ) )
+ {
+ SfxStyleSheetBase* pNext = pStyle->GetPool().Find( aFollow, pStyle->GetFamily() );
+ pNode->SetStyleSheet( (SfxStyleSheet*)pNext );
+ }
+ }
+
+ // Zeichenattribute muessen ggf. kopiert bzw gestutzt werden:
+ pNode->CopyAndCutAttribs( aPaM.GetNode(), GetItemPool(), bKeepEndingAttribs );
+
+ Insert( pNode, nPos+1 );
+
+ SetModified( TRUE );
+
+ aPaM.SetNode( pNode );
+ aPaM.SetIndex( 0 );
+ return aPaM;
+}
+
+EditPaM EditDoc::InsertFeature( EditPaM aPaM, const SfxPoolItem& rItem )
+{
+ DBG_ASSERT( aPaM.GetNode(), "Blinder PaM in EditDoc::InsertFeature" );
+
+ aPaM.GetNode()->Insert( CH_FEATURE, aPaM.GetIndex() );
+ aPaM.GetNode()->ExpandAttribs( aPaM.GetIndex(), 1, GetItemPool() );
+
+ // Fuer das Feature ein Feature-Attribut anlegen...
+ EditCharAttrib* pAttrib = MakeCharAttrib( GetItemPool(), rItem, aPaM.GetIndex(), aPaM.GetIndex()+1 );
+ DBG_ASSERT( pAttrib, "Warum kann ich kein Feature anlegen ?" );
+ aPaM.GetNode()->GetCharAttribs().InsertAttrib( pAttrib );
+
+ SetModified( TRUE );
+
+ aPaM.GetIndex()++;
+ return aPaM;
+}
+
+EditPaM EditDoc::ConnectParagraphs( ContentNode* pLeft, ContentNode* pRight )
+{
+ const EditPaM aPaM( pLeft, pLeft->Len() );
+
+ // Erst die Attribute, da sonst nLen nicht stimmt!
+ pLeft->AppendAttribs( pRight );
+ // Dann den Text...
+ *pLeft += *pRight;
+
+ // der rechte verschwindet.
+ RemoveItemsFromPool( pRight );
+ USHORT nRight = GetPos( pRight );
+ Remove( nRight );
+ delete pRight;
+
+ SetModified( TRUE );
+
+ return aPaM;
+}
+
+EditPaM EditDoc::RemoveChars( EditPaM aPaM, USHORT nChars )
+{
+ // Evtl. Features entfernen!
+ aPaM.GetNode()->Erase( aPaM.GetIndex(), nChars );
+ aPaM.GetNode()->CollapsAttribs( aPaM.GetIndex(), nChars, GetItemPool() );
+
+ SetModified( TRUE );
+
+ return aPaM;
+}
+
+void EditDoc::InsertAttribInSelection( ContentNode* pNode, USHORT nStart, USHORT nEnd, const SfxPoolItem& rPoolItem )
+{
+ DBG_ASSERT( pNode, "Wohin mit dem Attribut?" );
+ DBG_ASSERT( nEnd <= pNode->Len(), "InsertAttrib: Attribut zu gross!" );
+
+ // fuer Optimierung:
+ // dieses endet am Anfang der Selektion => kann erweitert werden
+ EditCharAttrib* pEndingAttrib = 0;
+ // dieses startet am Ende der Selektion => kann erweitert werden
+ EditCharAttrib* pStartingAttrib = 0;
+
+ DBG_ASSERT( nStart <= nEnd, "Kleiner Rechenfehler in InsertAttribInSelection" );
+
+ RemoveAttribs( pNode, nStart, nEnd, pStartingAttrib, pEndingAttrib, rPoolItem.Which() );
+
+ if ( pStartingAttrib && pEndingAttrib &&
+ ( *(pStartingAttrib->GetItem()) == rPoolItem ) &&
+ ( *(pEndingAttrib->GetItem()) == rPoolItem ) )
+ {
+ // wird ein groesses Attribut.
+ pEndingAttrib->GetEnd() = pStartingAttrib->GetEnd();
+ GetItemPool().Remove( *(pStartingAttrib->GetItem()) );
+ pNode->GetCharAttribs().GetAttribs().Remove( pNode->GetCharAttribs().GetAttribs().GetPos( pStartingAttrib ) );
+ delete pStartingAttrib;
+ }
+ else if ( pStartingAttrib && ( *(pStartingAttrib->GetItem()) == rPoolItem ) )
+ pStartingAttrib->GetStart() = nStart;
+ else if ( pEndingAttrib && ( *(pEndingAttrib->GetItem()) == rPoolItem ) )
+ pEndingAttrib->GetEnd() = nEnd;
+ else
+ InsertAttrib( rPoolItem, pNode, nStart, nEnd );
+
+ if ( pStartingAttrib )
+ pNode->GetCharAttribs().ResortAttribs();
+
+ SetModified( TRUE );
+}
+
+BOOL EditDoc::RemoveAttribs( ContentNode* pNode, USHORT nStart, USHORT nEnd, USHORT nWhich )
+{
+ EditCharAttrib* pStarting;
+ EditCharAttrib* pEnding;
+ return RemoveAttribs( pNode, nStart, nEnd, pStarting, pEnding, nWhich );
+}
+
+BOOL EditDoc::RemoveAttribs( ContentNode* pNode, USHORT nStart, USHORT nEnd, EditCharAttrib*& rpStarting, EditCharAttrib*& rpEnding, USHORT nWhich )
+{
+ DBG_ASSERT( pNode, "Wohin mit dem Attribut?" );
+ DBG_ASSERT( nEnd <= pNode->Len(), "InsertAttrib: Attribut zu gross!" );
+
+ // dieses endet am Anfang der Selektion => kann erweitert werden
+ rpEnding = 0;
+ // dieses startet am Ende der Selektion => kann erweitert werden
+ rpStarting = 0;
+
+ BOOL bChanged = FALSE;
+
+ DBG_ASSERT( nStart <= nEnd, "Kleiner Rechenfehler in InsertAttribInSelection" );
+
+ // ueber die Attribute iterieren...
+ USHORT nAttr = 0;
+ EditCharAttrib* pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
+ while ( pAttr )
+ {
+ BOOL bRemoveAttrib = FALSE;
+ // MT 11.9.97:
+ // Ich denke dass in dieser Methode generell keine Features geloescht
+ // werden sollen.
+ // => Dann koennen die Feature-Abfragen weiter unten entfallen
+ USHORT nAttrWhich = pAttr->Which();
+ if ( ( nAttrWhich < EE_FEATURE_START ) && ( !nWhich || ( nAttrWhich == nWhich ) ) )
+ {
+ // Attribut beginnt in Selection
+ if ( ( pAttr->GetStart() >= nStart ) && ( pAttr->GetStart() <= nEnd ) )
+ {
+ bChanged = TRUE;
+ if ( pAttr->GetEnd() > nEnd )
+ {
+ pAttr->GetStart() = nEnd; // dann faengt es dahinter an
+ rpStarting = pAttr;
+ if ( nWhich )
+ break; // es kann kein weiteres Attrib hier liegen
+ }
+ else if ( !pAttr->IsFeature() || ( pAttr->GetStart() == nStart ) )
+ {
+ // Feature nur loeschen, wenn genau an der Stelle
+ bRemoveAttrib = TRUE;
+ }
+ }
+
+ // Attribut endet in Selection
+ else if ( ( pAttr->GetEnd() >= nStart ) && ( pAttr->GetEnd() <= nEnd ) )
+ {
+ bChanged = TRUE;
+ if ( ( pAttr->GetStart() < nStart ) && !pAttr->IsFeature() )
+ {
+ pAttr->GetEnd() = nStart; // dann hoert es hier auf
+ rpEnding = pAttr;
+ }
+ else if ( !pAttr->IsFeature() || ( pAttr->GetStart() == nStart ) )
+ {
+ // Feature nur loeschen, wenn genau an der Stelle
+ bRemoveAttrib = TRUE;
+ }
+ }
+ // Attribut ueberlappt die Selektion
+ else if ( ( pAttr->GetStart() <= nStart ) && ( pAttr->GetEnd() >= nEnd ) )
+ {
+ bChanged = TRUE;
+ if ( pAttr->GetStart() == nStart )
+ {
+ pAttr->GetStart() = nEnd;
+ rpStarting = pAttr;
+ if ( nWhich )
+ break; // es kann weitere Attribute geben!
+ }
+ else if ( pAttr->GetEnd() == nEnd )
+ {
+ pAttr->GetEnd() = nStart;
+ rpEnding = pAttr;
+ if ( nWhich )
+ break; // es kann weitere Attribute geben!
+ }
+ else // Attribut muss gesplittet werden...
+ {
+ USHORT nOldEnd = pAttr->GetEnd();
+ pAttr->GetEnd() = nStart;
+ rpEnding = pAttr;
+ InsertAttrib( *pAttr->GetItem(), pNode, nEnd, nOldEnd );
+ if ( nWhich )
+ break; // es kann weitere Attribute geben!
+ }
+ }
+ }
+ if ( bRemoveAttrib )
+ {
+ DBG_ASSERT( ( pAttr != rpStarting ) && ( pAttr != rpEnding ), "Loeschen und behalten des gleichen Attributs ?" );
+ DBG_ASSERT( !pAttr->IsFeature(), "RemoveAttribs: Remove a feature?!" );
+ pNode->GetCharAttribs().GetAttribs().Remove(nAttr);
+ GetItemPool().Remove( *pAttr->GetItem() );
+ delete pAttr;
+ nAttr--;
+ }
+ nAttr++;
+ pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
+ }
+
+ if ( bChanged )
+ {
+ // char attributes need to be sorted by start again
+ pNode->GetCharAttribs().ResortAttribs();
+
+ SetModified( TRUE );
+ }
+
+ return bChanged;
+}
+
+void EditDoc::InsertAttrib( const SfxPoolItem& rPoolItem, ContentNode* pNode, USHORT nStart, USHORT nEnd )
+{
+ // Diese Methode prueft nicht mehr, ob ein entspr. Attribut
+ // schon an der Stelle existiert!
+
+ EditCharAttrib* pAttrib = MakeCharAttrib( GetItemPool(), rPoolItem, nStart, nEnd );
+ DBG_ASSERT( pAttrib, "MakeCharAttrib fehlgeschlagen!" );
+ pNode->GetCharAttribs().InsertAttrib( pAttrib );
+
+ SetModified( TRUE );
+}
+
+void EditDoc::InsertAttrib( ContentNode* pNode, USHORT nStart, USHORT nEnd, const SfxPoolItem& rPoolItem )
+{
+ if ( nStart != nEnd )
+ {
+ InsertAttribInSelection( pNode, nStart, nEnd, rPoolItem );
+ }
+ else
+ {
+ // Pruefen, ob schon ein neues Attribut mit der WhichId an der Stelle:
+ EditCharAttrib* pAttr = pNode->GetCharAttribs().FindEmptyAttrib( rPoolItem.Which(), nStart );
+ if ( pAttr )
+ {
+ // Attribut entfernen....
+ pNode->GetCharAttribs().GetAttribs().Remove(
+ pNode->GetCharAttribs().GetAttribs().GetPos( pAttr ) );
+ }
+
+ // pruefen, ob ein 'gleiches' Attribut an der Stelle liegt.
+ pAttr = pNode->GetCharAttribs().FindAttrib( rPoolItem.Which(), nStart );
+ if ( pAttr )
+ {
+ if ( pAttr->IsInside( nStart ) ) // splitten
+ {
+ // ???????????????????????????????
+ // eigentlich noch pruefen, ob wirklich splittet, oder return !
+ // ???????????????????????????????
+ USHORT nOldEnd = pAttr->GetEnd();
+ pAttr->GetEnd() = nStart;
+ pAttr = MakeCharAttrib( GetItemPool(), *(pAttr->GetItem()), nStart, nOldEnd );
+ pNode->GetCharAttribs().InsertAttrib( pAttr );
+ }
+ else if ( pAttr->GetEnd() == nStart )
+ {
+ DBG_ASSERT( !pAttr->IsEmpty(), "Doch noch ein leeres Attribut?" );
+ // pruefen, ob genau das gleiche Attribut
+ if ( *(pAttr->GetItem()) == rPoolItem )
+ return;
+ }
+ }
+ InsertAttrib( rPoolItem, pNode, nStart, nStart );
+ }
+
+ SetModified( TRUE );
+}
+
+void EditDoc::FindAttribs( ContentNode* pNode, USHORT nStartPos, USHORT nEndPos, SfxItemSet& rCurSet )
+{
+ DBG_ASSERT( pNode, "Wo soll ich suchen ?" );
+ DBG_ASSERT( nStartPos <= nEndPos, "Ungueltiger Bereich!" );
+
+ USHORT nAttr = 0;
+ EditCharAttrib* pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
+ // keine Selection...
+ if ( nStartPos == nEndPos )
+ {
+ while ( pAttr && ( pAttr->GetStart() <= nEndPos) )
+ {
+ const SfxPoolItem* pItem = 0;
+ // Attribut liegt dadrueber...
+ if ( ( pAttr->GetStart() < nStartPos ) && ( pAttr->GetEnd() > nStartPos ) )
+ pItem = pAttr->GetItem();
+ // Attribut endet hier, ist nicht leer
+ else if ( ( pAttr->GetStart() < nStartPos ) && ( pAttr->GetEnd() == nStartPos ) )
+ {
+ if ( !pNode->GetCharAttribs().FindEmptyAttrib( pAttr->GetItem()->Which(), nStartPos ) )
+ pItem = pAttr->GetItem();
+ }
+ // Attribut endet hier, ist leer
+ else if ( ( pAttr->GetStart() == nStartPos ) && ( pAttr->GetEnd() == nStartPos ) )
+ {
+ pItem = pAttr->GetItem();
+ }
+ // Attribut beginnt hier
+ else if ( ( pAttr->GetStart() == nStartPos ) && ( pAttr->GetEnd() > nStartPos ) )
+ {
+ if ( nStartPos == 0 ) // Sonderfall
+ pItem = pAttr->GetItem();
+ }
+
+ if ( pItem )
+ {
+ USHORT nWhich = pItem->Which();
+ if ( rCurSet.GetItemState( nWhich ) == SFX_ITEM_OFF )
+ {
+ rCurSet.Put( *pItem );
+ }
+ else if ( rCurSet.GetItemState( nWhich ) == SFX_ITEM_ON )
+ {
+ const SfxPoolItem& rItem = rCurSet.Get( nWhich );
+ if ( rItem != *pItem )
+ {
+ rCurSet.InvalidateItem( nWhich );
+ }
+ }
+ }
+ nAttr++;
+ pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
+ }
+ }
+ else // Selektion
+ {
+ while ( pAttr && ( pAttr->GetStart() < nEndPos) )
+ {
+ const SfxPoolItem* pItem = 0;
+ // Attribut liegt dadrueber...
+ if ( ( pAttr->GetStart() <= nStartPos ) && ( pAttr->GetEnd() >= nEndPos ) )
+ pItem = pAttr->GetItem();
+ // Attribut startet mitten drin...
+ else if ( pAttr->GetStart() >= nStartPos )
+ {
+ // !!! pItem = pAttr->GetItem();
+ // einfach nur pItem reicht nicht, da ich z.B. bei Shadow
+ // niemals ein ungleiches Item finden wuerde, da ein solche
+ // seine Anwesenheit durch Abwesenheit repraesentiert!
+ // if ( ... )
+ // Es muesste geprueft werden, on genau das gleiche Attribut
+ // an der Bruchstelle aufsetzt, was recht aufwendig ist.
+ // Da ich beim Einfuegen von Attributen aber etwas optimiere
+ // tritt der Fall nicht so schnell auf...
+ // Also aus Geschwindigkeitsgruenden:
+ rCurSet.InvalidateItem( pAttr->GetItem()->Which() );
+
+ }
+ // Attribut endet mitten drin...
+ else if ( pAttr->GetEnd() > nStartPos )
+ {
+ // pItem = pAttr->GetItem();
+ // s.o.
+ /*-----------------31.05.95 16:01-------------------
+ Ist falsch, wenn das gleiche Attribut sofort wieder
+ eingestellt wird!
+ => Sollte am besten nicht vorkommen, also gleich beim
+ Setzen von Attributen richtig machen!
+ --------------------------------------------------*/
+ rCurSet.InvalidateItem( pAttr->GetItem()->Which() );
+ }
+
+ if ( pItem )
+ {
+ USHORT nWhich = pItem->Which();
+ if ( rCurSet.GetItemState( nWhich ) == SFX_ITEM_OFF )
+ {
+ rCurSet.Put( *pItem );
+ }
+ else if ( rCurSet.GetItemState( nWhich ) == SFX_ITEM_ON )
+ {
+ const SfxPoolItem& rItem = rCurSet.Get( nWhich );
+ if ( rItem != *pItem )
+ {
+ rCurSet.InvalidateItem( nWhich );
+ }
+ }
+ }
+ nAttr++;
+ pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
+ }
+ }
+}
+
+
+ // -------------------------------------------------------------------------
+// class EditCharAttribList
+// -------------------------------------------------------------------------
+
+CharAttribList::CharAttribList()
+{
+ DBG_CTOR( EE_CharAttribList, 0 );
+ bHasEmptyAttribs = FALSE;
+}
+
+CharAttribList::~CharAttribList()
+{
+ DBG_DTOR( EE_CharAttribList, 0 );
+
+ USHORT nAttr = 0;
+ EditCharAttrib* pAttr = GetAttrib( aAttribs, nAttr );
+ while ( pAttr )
+ {
+ delete pAttr;
+ ++nAttr;
+ pAttr = GetAttrib( aAttribs, nAttr );
+ }
+ Clear();
+}
+
+void CharAttribList::InsertAttrib( EditCharAttrib* pAttrib )
+{
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// optimieren: binaere Suche ? !
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ // MT: 26.11.98
+ // Vielleicht aber auch einfach nur rueckwaerts iterieren:
+ // Der haeufigste und kritischste Fall: Attribute kommen bereits
+ // sortiert an (InsertBinTextObject!)
+ // Hier waere auch binaere Suche nicht optimal.
+ // => Wuerde einiges bringen!
+
+ const USHORT nCount = Count();
+ const USHORT nStart = pAttrib->GetStart(); // vielleicht besser fuer Comp.Opt.
+
+ if ( pAttrib->IsEmpty() )
+ bHasEmptyAttribs = TRUE;
+
+ BOOL bInserted = FALSE;
+ for ( USHORT x = 0; x < nCount; x++ )
+ {
+ EditCharAttribPtr pCurAttrib = aAttribs[x];
+ if ( pCurAttrib->GetStart() > nStart )
+ {
+ aAttribs.Insert( pAttrib, x );
+ bInserted = TRUE;
+ break;
+ }
+ }
+ if ( !bInserted )
+ aAttribs.Insert( pAttrib, nCount );
+}
+
+void CharAttribList::ResortAttribs()
+{
+ if ( Count() )
+ {
+#if defined __SUNPRO_CC
+#pragma disable_warn
+#endif
+ qsort( (void*)aAttribs.GetData(), aAttribs.Count(), sizeof( EditCharAttrib* ), CompareStart );
+#if defined __SUNPRO_CC
+#pragma enable_warn
+#endif
+ }
+}
+
+void CharAttribList::OptimizeRanges( SfxItemPool& rItemPool )
+{
+ for ( USHORT n = 0; n < aAttribs.Count(); n++ )
+ {
+ EditCharAttrib* pAttr = aAttribs.GetObject( n );
+ for ( USHORT nNext = n+1; nNext < aAttribs.Count(); nNext++ )
+ {
+ EditCharAttrib* p = aAttribs.GetObject( nNext );
+ if ( !pAttr->IsFeature() && ( p->GetStart() == pAttr->GetEnd() ) && ( p->Which() == pAttr->Which() ) )
+ {
+ if ( *p->GetItem() == *pAttr->GetItem() )
+ {
+ pAttr->GetEnd() = p->GetEnd();
+ aAttribs.Remove( nNext );
+ rItemPool.Remove( *p->GetItem() );
+ delete p;
+ }
+ break; // only 1 attr with same which can start here.
+ }
+ else if ( p->GetStart() > pAttr->GetEnd() )
+ {
+ break;
+ }
+ }
+ }
+}
+
+EditCharAttrib* CharAttribList::FindAttrib( USHORT nWhich, USHORT nPos )
+{
+ // Rueckwaerts, falls eins dort endet, das naechste startet.
+ // => Das startende gilt...
+ USHORT nAttr = aAttribs.Count()-1;
+ EditCharAttrib* pAttr = GetAttrib( aAttribs, nAttr );
+ while ( pAttr )
+ {
+ if ( ( pAttr->Which() == nWhich ) && pAttr->IsIn(nPos) )
+ return pAttr;
+ pAttr = GetAttrib( aAttribs, --nAttr );
+ }
+ return 0;
+}
+
+EditCharAttrib* CharAttribList::FindNextAttrib( USHORT nWhich, USHORT nFromPos ) const
+{
+ DBG_ASSERT( nWhich, "FindNextAttrib: Which?" );
+ const USHORT nAttribs = aAttribs.Count();
+ for ( USHORT nAttr = 0; nAttr < nAttribs; nAttr++ )
+ {
+ EditCharAttrib* pAttr = aAttribs[ nAttr ];
+ if ( ( pAttr->GetStart() >= nFromPos ) && ( pAttr->Which() == nWhich ) )
+ return pAttr;
+ }
+ return 0;
+}
+
+BOOL CharAttribList::HasAttrib( USHORT nWhich ) const
+{
+ for ( USHORT nAttr = aAttribs.Count(); nAttr; )
+ {
+ const EditCharAttrib* pAttr = aAttribs[--nAttr];
+ if ( pAttr->Which() == nWhich )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL CharAttribList::HasAttrib( USHORT nStartPos, USHORT nEndPos ) const
+{
+ BOOL bAttr = FALSE;
+ for ( USHORT nAttr = aAttribs.Count(); nAttr && !bAttr; )
+ {
+ const EditCharAttrib* pAttr = aAttribs[--nAttr];
+ if ( ( pAttr->GetStart() < nEndPos ) && ( pAttr->GetEnd() > nStartPos ) )
+ return bAttr = TRUE;
+ }
+ return bAttr;
+}
+
+
+BOOL CharAttribList::HasBoundingAttrib( USHORT nBound )
+{
+ // Rueckwaerts, falls eins dort endet, das naechste startet.
+ // => Das startende gilt...
+ USHORT nAttr = aAttribs.Count()-1;
+ EditCharAttrib* pAttr = GetAttrib( aAttribs, nAttr );
+ while ( pAttr && ( pAttr->GetEnd() >= nBound ) )
+ {
+ if ( ( pAttr->GetStart() == nBound ) || ( pAttr->GetEnd() == nBound ) )
+ return TRUE;
+ pAttr = GetAttrib( aAttribs, --nAttr );
+ }
+ return FALSE;
+}
+
+EditCharAttrib* CharAttribList::FindEmptyAttrib( USHORT nWhich, USHORT nPos )
+{
+ if ( !bHasEmptyAttribs )
+ return 0;
+ USHORT nAttr = 0;
+ EditCharAttrib* pAttr = GetAttrib( aAttribs, nAttr );
+ while ( pAttr && ( pAttr->GetStart() <= nPos ) )
+ {
+ if ( ( pAttr->GetStart() == nPos ) && ( pAttr->GetEnd() == nPos ) && ( pAttr->Which() == nWhich ) )
+ return pAttr;
+ nAttr++;
+ pAttr = GetAttrib( aAttribs, nAttr );
+ }
+ return 0;
+}
+
+EditCharAttrib* CharAttribList::FindFeature( USHORT nPos ) const
+{
+
+ USHORT nAttr = 0;
+ EditCharAttrib* pNextAttrib = GetAttrib( aAttribs, nAttr );
+
+ // erstmal zur gewuenschten Position...
+ while ( pNextAttrib && ( pNextAttrib->GetStart() < nPos ) )
+ {
+ nAttr++;
+ pNextAttrib = GetAttrib( aAttribs, nAttr );
+ }
+
+ // jetzt das Feature suchen...
+ while ( pNextAttrib && !pNextAttrib->IsFeature() )
+ {
+ nAttr++;
+ pNextAttrib = GetAttrib( aAttribs, nAttr );
+ }
+
+ return pNextAttrib;
+}
+
+
+void CharAttribList::DeleteEmptyAttribs( SfxItemPool& rItemPool )
+{
+ for ( USHORT nAttr = 0; nAttr < aAttribs.Count(); nAttr++ )
+ {
+ EditCharAttrib* pAttr = aAttribs[nAttr];
+ if ( pAttr->IsEmpty() )
+ {
+ rItemPool.Remove( *pAttr->GetItem() );
+ aAttribs.Remove( nAttr );
+ delete pAttr;
+ nAttr--;
+ }
+ }
+ bHasEmptyAttribs = FALSE;
+}
+
+BOOL CharAttribList::DbgCheckAttribs()
+{
+#ifdef DBG_UTIL
+ BOOL bOK = TRUE;
+ for ( USHORT nAttr = 0; nAttr < aAttribs.Count(); nAttr++ )
+ {
+ EditCharAttrib* pAttr = aAttribs[nAttr];
+ if ( pAttr->GetStart() > pAttr->GetEnd() )
+ {
+ bOK = FALSE;
+ DBG_ERROR( "Attr verdreht" );
+ }
+ else if ( pAttr->IsFeature() && ( pAttr->GetLen() != 1 ) )
+ {
+ bOK = FALSE;
+ DBG_ERROR( "Feature, Len != 1" );
+ }
+ }
+ return bOK;
+#else
+ return TRUE;
+#endif
+}
+
+
+
+SvxFontTable::SvxFontTable()
+{
+}
+
+SvxFontTable::~SvxFontTable()
+{
+ SvxFontItem* pItem = First();
+ while( pItem )
+ {
+ delete pItem;
+ pItem = Next();
+ }
+}
+
+ULONG SvxFontTable::GetId( const SvxFontItem& rFontItem )
+{
+ SvxFontItem* pItem = First();
+ while ( pItem )
+ {
+ if ( *pItem == rFontItem )
+ return GetCurKey();
+ pItem = Next();
+ }
+ DBG_WARNING( "Font nicht gefunden: GetId()" );
+ return 0;
+}
+
+SvxColorList::SvxColorList()
+{
+}
+
+SvxColorList::~SvxColorList()
+{
+ SvxColorItem* pItem = First();
+ while( pItem )
+ {
+ delete pItem;
+ pItem = Next();
+ }
+}
+
+ULONG SvxColorList::GetId( const SvxColorItem& rColorItem )
+{
+ SvxColorItem* pItem = First();
+ while ( pItem )
+ {
+ if ( *pItem == rColorItem )
+ return GetCurPos();
+ pItem = Next();
+ }
+ DBG_WARNING( "Color nicht gefunden: GetId()" );
+ return 0;
+}
+
+EditEngineItemPool::EditEngineItemPool( BOOL bPersistenRefCounts )
+ : SfxItemPool( String( "EditEngineItemPool", RTL_TEXTENCODING_ASCII_US ), EE_ITEMS_START, EE_ITEMS_END,
+ aItemInfos, 0, bPersistenRefCounts )
+{
+ SetVersionMap( 1, 3999, 4015, aV1Map );
+ SetVersionMap( 2, 3999, 4019, aV2Map );
+ SetVersionMap( 3, 3997, 4020, aV3Map );
+ SetVersionMap( 4, 3994, 4022, aV4Map );
+ SetVersionMap( 5, 3994, 4037, aV5Map );
+
+ DBG_ASSERT( EE_DLL(), "EditDLL?!" );
+ SfxPoolItem** ppDefItems = EE_DLL()->GetGlobalData()->GetDefItems();
+ SetDefaults( ppDefItems );
+}
+
+EditEngineItemPool::~EditEngineItemPool()
+{
+}
+
+SvStream& EditEngineItemPool::Store( SvStream& rStream ) const
+{
+ // Bei einem 3.1-Export muess ein Hack eingebaut werden, da BUG im
+ // SfxItemSet::Load, aber nicht nachtraeglich in 3.1 fixbar.
+
+ // Der eingestellte Range muss nach Store erhalten bleiben, weil dann
+ // erst die ItemSets gespeichert werden...
+
+ long nVersion = rStream.GetVersion();
+ BOOL b31Format = ( nVersion && ( nVersion <= SOFFICE_FILEFORMAT_31 ) )
+ ? TRUE : FALSE;
+
+ EditEngineItemPool* pThis = (EditEngineItemPool*)this;
+ if ( b31Format )
+ pThis->SetStoringRange( 3997, 4022 );
+ else
+ pThis->SetStoringRange( EE_ITEMS_START, EE_ITEMS_END );
+
+ return SfxItemPool::Store( rStream );
+}
diff --git a/editeng/source/editeng/editdoc.hxx b/editeng/source/editeng/editdoc.hxx
new file mode 100644
index 0000000000..e95e08063e
--- /dev/null
+++ b/editeng/source/editeng/editdoc.hxx
@@ -0,0 +1,805 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: editdoc.hxx,v $
+ * $Revision: 1.29 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _EDITDOC_HXX
+#define _EDITDOC_HXX
+
+#ifndef _COM_SUN_STAR_I18N_XEXTENDEDINPUTSEQUENCECHECKER_HDL_
+#include <com/sun/star/i18n/XExtendedInputSequenceChecker.hpp>
+#endif
+
+#include <editattr.hxx>
+#include <edtspell.hxx>
+#include <editeng/svxfont.hxx>
+#include <svl/itemset.hxx>
+#include <svl/style.hxx>
+#include <svl/itempool.hxx>
+#include <tools/table.hxx>
+
+class ImpEditEngine;
+class SvxTabStop;
+class SvtCTLOptions;
+
+DBG_NAMEEX( EE_TextPortion )
+
+#define CHARPOSGROW 16
+#define DEFTAB 720
+
+void CreateFont( SvxFont& rFont, const SfxItemSet& rSet, bool bSearchInParent = true, short nScriptType = 0 );
+USHORT GetScriptItemId( USHORT nItemId, short nScriptType );
+BOOL IsScriptItemValid( USHORT nItemId, short nScriptType );
+
+EditCharAttrib* MakeCharAttrib( SfxItemPool& rPool, const SfxPoolItem& rAttr, USHORT nS, USHORT nE );
+
+class ContentNode;
+class EditDoc;
+
+struct EPaM
+{
+ USHORT nPara;
+ USHORT nIndex;
+
+ EPaM() { nPara = 0; nIndex = 0; }
+ EPaM( USHORT nP, USHORT nI ) { nPara = nP; nIndex = nI; }
+ EPaM( const EPaM& r) { nPara = r.nPara; nIndex = r.nIndex; }
+ EPaM& operator = ( const EPaM& r ) { nPara = r.nPara; nIndex = r.nIndex; return *this; }
+ inline BOOL operator == ( const EPaM& r ) const;
+ inline BOOL operator < ( const EPaM& r ) const;
+};
+
+inline BOOL EPaM::operator < ( const EPaM& r ) const
+{
+ return ( ( nPara < r.nPara ) ||
+ ( ( nPara == r.nPara ) && nIndex < r.nIndex ) ) ? TRUE : FALSE;
+}
+
+inline BOOL EPaM::operator == ( const EPaM& r ) const
+{
+ return ( ( nPara == r.nPara ) && ( nIndex == r.nIndex ) ) ? TRUE : FALSE;
+}
+
+struct ScriptTypePosInfo
+{
+ short nScriptType;
+ USHORT nStartPos;
+ USHORT nEndPos;
+
+ ScriptTypePosInfo( short _Type, USHORT _Start, USHORT _End )
+ {
+ nScriptType = _Type;
+ nStartPos = _Start;
+ nEndPos = _End;
+ }
+};
+
+SV_DECL_VARARR( ScriptTypePosInfos, ScriptTypePosInfo, 0, 4 )
+
+struct WritingDirectionInfo
+{
+ BYTE nType;
+ USHORT nStartPos;
+ USHORT nEndPos;
+
+ WritingDirectionInfo( BYTE _Type, USHORT _Start, USHORT _End )
+ {
+ nType = _Type;
+ nStartPos = _Start;
+ nEndPos = _End;
+ }
+};
+
+SV_DECL_VARARR( WritingDirectionInfos, WritingDirectionInfo, 0, 4 )
+
+typedef EditCharAttrib* EditCharAttribPtr;
+SV_DECL_PTRARR( CharAttribArray, EditCharAttribPtr, 0, 4 )
+
+class ContentAttribsInfo
+{
+private:
+ SfxItemSet aPrevParaAttribs;
+ CharAttribArray aPrevCharAttribs;
+
+public:
+ ContentAttribsInfo( const SfxItemSet& rParaAttribs );
+
+ const SfxItemSet& GetPrevParaAttribs() const { return aPrevParaAttribs; }
+ const CharAttribArray& GetPrevCharAttribs() const { return aPrevCharAttribs; }
+
+ CharAttribArray& GetPrevCharAttribs() { return aPrevCharAttribs; }
+};
+
+typedef ContentAttribsInfo* ContentAttribsInfoPtr;
+SV_DECL_PTRARR( ContentInfoArray, ContentAttribsInfoPtr, 1, 1 )
+
+// ----------------------------------------------------------------------
+// class SvxFontTable
+// ----------------------------------------------------------------------
+DECLARE_TABLE( DummyFontTable, SvxFontItem* )
+class SvxFontTable : public DummyFontTable
+{
+public:
+ SvxFontTable();
+ ~SvxFontTable();
+
+ ULONG GetId( const SvxFontItem& rFont );
+};
+
+// ----------------------------------------------------------------------
+// class SvxColorList
+// ----------------------------------------------------------------------
+typedef ContentNode* ContentNodePtr;
+DECLARE_LIST( DummyColorList, SvxColorItem* )
+class SvxColorList : public DummyColorList
+{
+public:
+ SvxColorList();
+ ~SvxColorList();
+
+ ULONG GetId( const SvxColorItem& rColor );
+};
+
+// ----------------------------------------------------------------------
+// class ItemList
+// ----------------------------------------------------------------------
+typedef const SfxPoolItem* ConstPoolItemPtr;
+DECLARE_LIST( DummyItemList, ConstPoolItemPtr )
+class ItemList : public DummyItemList
+{
+public:
+ const SfxPoolItem* FindAttrib( USHORT nWhich );
+};
+
+// -------------------------------------------------------------------------
+// class ContentAttribs
+// -------------------------------------------------------------------------
+class ContentAttribs
+{
+private:
+ SfxStyleSheet* pStyle;
+ SfxItemSet aAttribSet;
+
+public:
+ ContentAttribs( SfxItemPool& rItemPool );
+ ContentAttribs( const ContentAttribs& );
+ ~ContentAttribs(); // erst bei umfangreicheren Tabs
+
+ SvxTabStop FindTabStop( long nCurPos, USHORT nDefTab );
+ SfxItemSet& GetItems() { return aAttribSet; }
+ SfxStyleSheet* GetStyleSheet() const { return pStyle; }
+ void SetStyleSheet( SfxStyleSheet* pS );
+
+ const SfxPoolItem& GetItem( USHORT nWhich );
+ BOOL HasItem( USHORT nWhich );
+};
+
+// -------------------------------------------------------------------------
+// class CharAttribList
+// -------------------------------------------------------------------------
+class CharAttribList
+{
+private:
+ CharAttribArray aAttribs;
+ SvxFont aDefFont; // schneller, als jedesmal vom Pool!
+ BOOL bHasEmptyAttribs;
+
+ CharAttribList( const CharAttribList& ) {;}
+
+public:
+ CharAttribList();
+ ~CharAttribList();
+
+ void DeleteEmptyAttribs( SfxItemPool& rItemPool );
+ void RemoveItemsFromPool( SfxItemPool* pItemPool );
+
+ EditCharAttrib* FindAttrib( USHORT nWhich, USHORT nPos );
+ EditCharAttrib* FindNextAttrib( USHORT nWhich, USHORT nFromPos ) const;
+ EditCharAttrib* FindEmptyAttrib( USHORT nWhich, USHORT nPos );
+ EditCharAttrib* FindFeature( USHORT nPos ) const;
+
+
+ void ResortAttribs();
+ void OptimizeRanges( SfxItemPool& rItemPool );
+
+ USHORT Count() { return aAttribs.Count(); }
+ void Clear() { aAttribs.Remove( 0, aAttribs.Count()); }
+ void InsertAttrib( EditCharAttrib* pAttrib );
+
+ SvxFont& GetDefFont() { return aDefFont; }
+
+ BOOL HasEmptyAttribs() const { return bHasEmptyAttribs; }
+ BOOL& HasEmptyAttribs() { return bHasEmptyAttribs; }
+ BOOL HasBoundingAttrib( USHORT nBound );
+ BOOL HasAttrib( USHORT nWhich ) const;
+ BOOL HasAttrib( USHORT nStartPos, USHORT nEndPos ) const;
+
+ CharAttribArray& GetAttribs() { return aAttribs; }
+ const CharAttribArray& GetAttribs() const { return aAttribs; }
+
+ // Debug:
+ BOOL DbgCheckAttribs();
+};
+
+// -------------------------------------------------------------------------
+// class ContentNode
+// -------------------------------------------------------------------------
+class ContentNode : public XubString
+{
+private:
+ ContentAttribs aContentAttribs;
+ CharAttribList aCharAttribList;
+ WrongList* pWrongList;
+
+public:
+ ContentNode( SfxItemPool& rItemPool );
+ ContentNode( const XubString& rStr, const ContentAttribs& rContentAttribs );
+ ~ContentNode();
+
+ ContentAttribs& GetContentAttribs() { return aContentAttribs; }
+ CharAttribList& GetCharAttribs() { return aCharAttribList; }
+
+ void ExpandAttribs( USHORT nIndex, USHORT nNewChars, SfxItemPool& rItemPool );
+ void CollapsAttribs( USHORT nIndex, USHORT nDelChars, SfxItemPool& rItemPool );
+ void AppendAttribs( ContentNode* pNextNode );
+ void CopyAndCutAttribs( ContentNode* pPrevNode, SfxItemPool& rPool, BOOL bKeepEndingAttribs );
+
+ void SetStyleSheet( SfxStyleSheet* pS, BOOL bRecalcFont = TRUE );
+ void SetStyleSheet( SfxStyleSheet* pS, const SvxFont& rFontFromStyle );
+ SfxStyleSheet* GetStyleSheet() { return aContentAttribs.GetStyleSheet(); }
+
+ void CreateDefFont();
+
+ WrongList* GetWrongList() { return pWrongList; }
+ void SetWrongList( WrongList* p );
+
+ void CreateWrongList();
+ void DestroyWrongList();
+
+ BOOL IsFeature( USHORT nPos ) const { return ( GetChar( nPos ) == CH_FEATURE ); }
+};
+
+typedef ContentNode* ContentNodePtr;
+SV_DECL_PTRARR( DummyContentList, ContentNodePtr, 0, 4 )
+
+class ContentList : public DummyContentList
+{
+ USHORT nLastCache;
+public:
+ ContentList() : DummyContentList( 0, 4 ), nLastCache(0) {}
+ USHORT GetPos( const ContentNodePtr &rPtr ) const;
+};
+
+// -------------------------------------------------------------------------
+// class EditPaM
+// -------------------------------------------------------------------------
+class EditPaM
+{
+private:
+ ContentNode* pNode;
+ USHORT nIndex;
+
+public:
+ EditPaM() { pNode = NULL; nIndex = 0; }
+ EditPaM( ContentNode* p, USHORT n ) { pNode = p; nIndex = n; }
+
+ ContentNode* GetNode() const { return pNode; }
+ void SetNode( ContentNode* p) { pNode = p; }
+
+ USHORT GetIndex() const { return nIndex; }
+ USHORT& GetIndex() { return nIndex; }
+ void SetIndex( USHORT n ) { nIndex = n; }
+
+ BOOL IsParaStart() const { return nIndex == 0; }
+ BOOL IsParaEnd() const { return nIndex == pNode->Len(); }
+
+ BOOL DbgIsBuggy( EditDoc& rDoc );
+
+ EditPaM& operator = ( const EditPaM& rPaM );
+ friend BOOL operator == ( const EditPaM& r1, const EditPaM& r2 );
+ friend BOOL operator != ( const EditPaM& r1, const EditPaM& r2 );
+};
+
+#define PORTIONKIND_TEXT 0
+#define PORTIONKIND_TAB 1
+#define PORTIONKIND_LINEBREAK 2
+#define PORTIONKIND_FIELD 3
+#define PORTIONKIND_HYPHENATOR 4
+// #define PORTIONKIND_EXTRASPACE 5
+
+#define DELMODE_SIMPLE 0
+#define DELMODE_RESTOFWORD 1
+#define DELMODE_RESTOFCONTENT 2
+
+#define CHAR_NORMAL 0x00
+#define CHAR_KANA 0x01
+#define CHAR_PUNCTUATIONLEFT 0x02
+#define CHAR_PUNCTUATIONRIGHT 0x04
+
+// -------------------------------------------------------------------------
+// struct ExtraPortionInfos
+// -------------------------------------------------------------------------
+struct ExtraPortionInfo
+{
+ long nOrgWidth;
+ long nWidthFullCompression;
+
+ long nPortionOffsetX;
+
+ USHORT nMaxCompression100thPercent;
+
+ BYTE nAsianCompressionTypes;
+ BOOL bFirstCharIsRightPunktuation;
+ BOOL bCompressed;
+
+ sal_Int32* pOrgDXArray;
+
+
+ ExtraPortionInfo();
+ ~ExtraPortionInfo();
+
+ void SaveOrgDXArray( const sal_Int32* pDXArray, USHORT nLen );
+ void DestroyOrgDXArray();
+};
+
+
+// -------------------------------------------------------------------------
+// class TextPortion
+// -------------------------------------------------------------------------
+class TextPortion
+{
+private:
+ ExtraPortionInfo* pExtraInfos;
+ USHORT nLen;
+ Size aOutSz;
+ BYTE nKind;
+ BYTE nRightToLeft;
+ sal_Unicode nExtraValue;
+
+
+ TextPortion() { DBG_CTOR( EE_TextPortion, 0 );
+ pExtraInfos = NULL; nLen = 0; nKind = PORTIONKIND_TEXT; nExtraValue = 0; nRightToLeft = FALSE;}
+
+public:
+ TextPortion( USHORT nL ) : aOutSz( -1, -1 )
+ { DBG_CTOR( EE_TextPortion, 0 );
+ pExtraInfos = NULL; nLen = nL; nKind = PORTIONKIND_TEXT; nExtraValue = 0; nRightToLeft = FALSE;}
+ TextPortion( const TextPortion& r ) : aOutSz( r.aOutSz )
+ { DBG_CTOR( EE_TextPortion, 0 );
+ pExtraInfos = NULL; nLen = r.nLen; nKind = r.nKind; nExtraValue = r.nExtraValue; nRightToLeft = r.nRightToLeft; }
+
+ ~TextPortion() { DBG_DTOR( EE_TextPortion, 0 ); delete pExtraInfos; }
+
+ USHORT GetLen() const { return nLen; }
+ USHORT& GetLen() { return nLen; }
+ void SetLen( USHORT nL ) { nLen = nL; }
+
+ Size& GetSize() { return aOutSz; }
+ Size GetSize() const { return aOutSz; }
+
+ BYTE& GetKind() { return nKind; }
+ BYTE GetKind() const { return nKind; }
+
+ void SetRightToLeft( BYTE b ) { nRightToLeft = b; }
+ BYTE GetRightToLeft() const { return nRightToLeft; }
+ BOOL IsRightToLeft() const { return (nRightToLeft&1); }
+
+ sal_Unicode GetExtraValue() const { return nExtraValue; }
+ void SetExtraValue( sal_Unicode n ) { nExtraValue = n; }
+
+ BOOL HasValidSize() const { return aOutSz.Width() != (-1); }
+
+ ExtraPortionInfo* GetExtraInfos() const { return pExtraInfos; }
+ void SetExtraInfos( ExtraPortionInfo* p ) { delete pExtraInfos; pExtraInfos = p; }
+};
+
+// -------------------------------------------------------------------------
+// class TextPortionList
+// -------------------------------------------------------------------------
+typedef TextPortion* TextPortionPtr;
+SV_DECL_PTRARR( TextPortionArray, TextPortionPtr, 0, 8 )
+
+class TextPortionList : public TextPortionArray
+{
+public:
+ TextPortionList();
+ ~TextPortionList();
+
+ void Reset();
+ USHORT FindPortion( USHORT nCharPos, USHORT& rPortionStart, BOOL bPreferStartingPortion = FALSE );
+ USHORT GetStartPos( USHORT nPortion );
+ void DeleteFromPortion( USHORT nDelFrom );
+};
+
+class ParaPortion;
+
+SV_DECL_VARARR( CharPosArray, sal_Int32, 0, CHARPOSGROW )
+
+// ------------------------------------------------------------------------
+// class EditLine
+// -------------------------------------------------------------------------
+class EditLine
+{
+private:
+ CharPosArray aPositions;
+ long nTxtWidth;
+ USHORT nStartPosX;
+ USHORT nStart; // koennte durch nStartPortion ersetzt werden
+ USHORT nEnd; // koennte durch nEndPortion ersetzt werden
+ USHORT nStartPortion;
+ USHORT nEndPortion;
+ USHORT nHeight; // Gesamthoehe der Zeile
+ USHORT nTxtHeight; // Reine Texthoehe
+ USHORT nCrsrHeight; // Bei Konturfluss hohe Zeilen => Cursor zu groá.
+ USHORT nMaxAscent;
+ BOOL bHangingPunctuation;
+ BOOL bInvalid; // fuer geschickte Formatierung
+
+public:
+ EditLine();
+ EditLine( const EditLine& );
+ ~EditLine();
+
+ BOOL IsIn( USHORT nIndex ) const
+ { return ( (nIndex >= nStart ) && ( nIndex < nEnd ) ); }
+
+ BOOL IsIn( USHORT nIndex, BOOL bInclEnd ) const
+ { return ( ( nIndex >= nStart ) && ( bInclEnd ? ( nIndex <= nEnd ) : ( nIndex < nEnd ) ) ); }
+
+ void SetStart( USHORT n ) { nStart = n; }
+ USHORT GetStart() const { return nStart; }
+ USHORT& GetStart() { return nStart; }
+
+ void SetEnd( USHORT n ) { nEnd = n; }
+ USHORT GetEnd() const { return nEnd; }
+ USHORT& GetEnd() { return nEnd; }
+
+ void SetStartPortion( USHORT n ) { nStartPortion = n; }
+ USHORT GetStartPortion() const { return nStartPortion; }
+ USHORT& GetStartPortion() { return nStartPortion; }
+
+ void SetEndPortion( USHORT n ) { nEndPortion = n; }
+ USHORT GetEndPortion() const { return nEndPortion; }
+ USHORT& GetEndPortion() { return nEndPortion; }
+
+ void SetHeight( USHORT nH, USHORT nTxtH = 0, USHORT nCrsrH = 0 )
+ { nHeight = nH;
+ nTxtHeight = ( nTxtH ? nTxtH : nH );
+ nCrsrHeight = ( nCrsrH ? nCrsrH : nTxtHeight );
+ }
+ USHORT GetHeight() const { return nHeight; }
+ USHORT GetTxtHeight() const { return nTxtHeight; }
+ USHORT GetCrsrHeight() const { return nCrsrHeight; }
+
+ void SetTextWidth( long n ) { nTxtWidth = n; }
+ long GetTextWidth() const { return nTxtWidth; }
+
+ void SetMaxAscent( USHORT n ) { nMaxAscent = n; }
+ USHORT GetMaxAscent() const { return nMaxAscent; }
+
+ void SetHangingPunctuation( BOOL b ) { bHangingPunctuation = b; }
+ BOOL IsHangingPunctuation() const { return bHangingPunctuation; }
+
+ USHORT GetLen() const { return nEnd - nStart; }
+
+ USHORT GetStartPosX() const { return nStartPosX; }
+ void SetStartPosX( USHORT start ) { nStartPosX = start; }
+
+ Size CalcTextSize( ParaPortion& rParaPortion );
+
+ BOOL IsInvalid() const { return bInvalid; }
+ BOOL IsValid() const { return !bInvalid; }
+ void SetInvalid() { bInvalid = TRUE; }
+ void SetValid() { bInvalid = FALSE; }
+
+ BOOL IsEmpty() const { return (nEnd > nStart) ? FALSE : TRUE; }
+
+ CharPosArray& GetCharPosArray() { return aPositions; }
+
+ EditLine* Clone() const;
+
+ EditLine& operator = ( const EditLine& rLine );
+ friend BOOL operator == ( const EditLine& r1, const EditLine& r2 );
+ friend BOOL operator != ( const EditLine& r1, const EditLine& r2 );
+};
+
+
+// -------------------------------------------------------------------------
+// class LineList
+// -------------------------------------------------------------------------
+typedef EditLine* EditLinePtr;
+SV_DECL_PTRARR( LineArray, EditLinePtr, 0, 4 )
+
+class EditLineList : public LineArray
+{
+public:
+ EditLineList();
+ ~EditLineList();
+
+ void Reset();
+ void DeleteFromLine( USHORT nDelFrom );
+ USHORT FindLine( USHORT nChar, BOOL bInclEnd );
+};
+
+// -------------------------------------------------------------------------
+// class ParaPortion
+// -------------------------------------------------------------------------
+class ParaPortion
+{
+ friend class ImpEditEngine; // zum Einstellen der Hoehe
+private:
+ EditLineList aLineList;
+ TextPortionList aTextPortionList;
+ ContentNode* pNode;
+ long nHeight;
+
+ ScriptTypePosInfos aScriptInfos;
+ WritingDirectionInfos aWritingDirectionInfos;
+
+ USHORT nInvalidPosStart;
+ USHORT nFirstLineOffset; // Fuer Writer-LineSpacing-Interpretation
+ USHORT nBulletX;
+ short nInvalidDiff;
+
+ BOOL bInvalid : 1;
+ BOOL bSimple : 1; // nur lineares Tippen
+ BOOL bVisible : 1; // MT 05/00: Gehoert an den Node!!!
+ BOOL bForceRepaint : 1;
+
+ ParaPortion( const ParaPortion& );
+
+public:
+ ParaPortion( ContentNode* pNode );
+ ~ParaPortion();
+
+ USHORT GetLineNumber( USHORT nIndex );
+
+ EditLineList& GetLines() { return aLineList; }
+
+ BOOL IsInvalid() const { return bInvalid; }
+ BOOL IsSimpleInvalid() const { return bSimple; }
+ void SetValid() { bInvalid = FALSE; bSimple = TRUE;}
+
+ BOOL MustRepaint() const { return bForceRepaint; }
+ void SetMustRepaint( BOOL bRP ) { bForceRepaint = bRP; }
+
+ USHORT GetBulletX() const { return nBulletX; }
+ void SetBulletX( USHORT n ) { nBulletX = n; }
+
+ void MarkInvalid( USHORT nStart, short nDiff);
+ void MarkSelectionInvalid( USHORT nStart, USHORT nEnd );
+
+ void SetVisible( BOOL bVisible );
+ BOOL IsVisible() { return bVisible; }
+
+ long GetHeight() const { return ( bVisible ? nHeight : 0 ); }
+ USHORT GetFirstLineOffset() const { return ( bVisible ? nFirstLineOffset : 0 ); }
+ void ResetHeight() { nHeight = 0; nFirstLineOffset = 0; }
+
+ ContentNode* GetNode() const { return pNode; }
+ TextPortionList& GetTextPortions() { return aTextPortionList; }
+
+ USHORT GetInvalidPosStart() const { return nInvalidPosStart; }
+ short GetInvalidDiff() const { return nInvalidDiff; }
+
+ void CorrectValuesBehindLastFormattedLine( USHORT nLastFormattedLine );
+
+ BOOL DbgCheckTextPortions();
+};
+
+typedef ParaPortion* ParaPortionPtr;
+SV_DECL_PTRARR( DummyParaPortionList, ParaPortionPtr, 0, 4 )
+
+// -------------------------------------------------------------------------
+// class ParaPortionList
+// -------------------------------------------------------------------------
+class ParaPortionList : public DummyParaPortionList
+{
+ USHORT nLastCache;
+public:
+ ParaPortionList();
+ ~ParaPortionList();
+
+ void Reset();
+ long GetYOffset( ParaPortion* pPPortion );
+ USHORT FindParagraph( long nYOffset );
+
+ inline ParaPortion* SaveGetObject( USHORT nPos ) const
+ { return ( nPos < Count() ) ? GetObject( nPos ) : 0; }
+
+ USHORT GetPos( const ParaPortionPtr &rPtr ) const;
+
+ // temporaer:
+ void DbgCheck( EditDoc& rDoc );
+};
+
+// -------------------------------------------------------------------------
+// class EditSelection
+// -------------------------------------------------------------------------
+class EditSelection
+{
+private:
+ EditPaM aStartPaM;
+ EditPaM aEndPaM;
+
+public:
+ EditSelection(); // kein CCTOR und DTOR, geht autom. richtig!
+ EditSelection( const EditPaM& rStartAndAnd );
+ EditSelection( const EditPaM& rStart, const EditPaM& rEnd );
+
+ EditPaM& Min() { return aStartPaM; }
+ EditPaM& Max() { return aEndPaM; }
+
+ const EditPaM& Min() const { return aStartPaM; }
+ const EditPaM& Max() const { return aEndPaM; }
+
+ BOOL HasRange() const { return aStartPaM != aEndPaM; }
+ BOOL IsInvalid() const;
+ BOOL DbgIsBuggy( EditDoc& rDoc );
+
+ BOOL Adjust( const ContentList& rNodes );
+
+ EditSelection& operator = ( const EditPaM& r );
+ BOOL operator == ( const EditSelection& r ) const
+ { return ( ( aStartPaM == r.aStartPaM ) && ( aEndPaM == r.aEndPaM ) )
+ ? TRUE : FALSE; }
+ BOOL operator != ( const EditSelection& r ) const { return !( r == *this ); }
+};
+
+// -------------------------------------------------------------------------
+// class DeletedNodeInfo
+// -------------------------------------------------------------------------
+class DeletedNodeInfo
+{
+private:
+ ULONG nInvalidAdressPtr;
+ USHORT nInvalidParagraph;
+
+public:
+ DeletedNodeInfo( ULONG nInvAdr, USHORT nPos )
+ { nInvalidAdressPtr = nInvAdr;
+ nInvalidParagraph = nPos; }
+
+ ULONG GetInvalidAdress() { return nInvalidAdressPtr; }
+ USHORT GetPosition() { return nInvalidParagraph; }
+};
+
+typedef DeletedNodeInfo* DeletedNodeInfoPtr;
+SV_DECL_PTRARR( DeletedNodesList, DeletedNodeInfoPtr, 0, 4 )
+
+// -------------------------------------------------------------------------
+// class EditDoc
+// -------------------------------------------------------------------------
+class EditDoc : public ContentList
+{
+private:
+ SfxItemPool* pItemPool;
+ Link aModifyHdl;
+
+ SvxFont aDefFont; //schneller, als jedesmal vom Pool!
+ USHORT nDefTab;
+ BOOL bIsVertical;
+ BOOL bIsFixedCellHeight;
+
+ BOOL bOwnerOfPool;
+ BOOL bModified;
+
+protected:
+ void ImplDestroyContents();
+
+public:
+ EditDoc( SfxItemPool* pItemPool );
+ ~EditDoc();
+
+ BOOL IsModified() const { return bModified; }
+ void SetModified( BOOL b );
+
+ void SetModifyHdl( const Link& rLink ) { aModifyHdl = rLink; }
+ Link GetModifyHdl() const { return aModifyHdl; }
+
+ void CreateDefFont( BOOL bUseStyles );
+ const SvxFont& GetDefFont() { return aDefFont; }
+
+ void SetDefTab( USHORT nTab ) { nDefTab = nTab ? nTab : DEFTAB; }
+ USHORT GetDefTab() const { return nDefTab; }
+
+ void SetVertical( BOOL bVertical ) { bIsVertical = bVertical; }
+ BOOL IsVertical() const { return bIsVertical; }
+
+ void SetFixedCellHeight( BOOL bUseFixedCellHeight ) { bIsFixedCellHeight = bUseFixedCellHeight; }
+ BOOL IsFixedCellHeight() const { return bIsFixedCellHeight; }
+
+ EditPaM Clear();
+ EditPaM RemoveText();
+ EditPaM RemoveChars( EditPaM aPaM, USHORT nChars );
+ void InsertText( const EditPaM& rPaM, xub_Unicode c );
+ EditPaM InsertText( EditPaM aPaM, const XubString& rStr );
+ EditPaM InsertParaBreak( EditPaM aPaM, BOOL bKeepEndingAttribs );
+ EditPaM InsertFeature( EditPaM aPaM, const SfxPoolItem& rItem );
+ EditPaM ConnectParagraphs( ContentNode* pLeft, ContentNode* pRight );
+
+ String GetText( LineEnd eEnd ) const;
+ ULONG GetTextLen() const;
+
+ XubString GetParaAsString( USHORT nNode ) const;
+ XubString GetParaAsString( ContentNode* pNode, USHORT nStartPos = 0, USHORT nEndPos = 0xFFFF, BOOL bResolveFields = TRUE ) const;
+
+ inline EditPaM GetStartPaM() const;
+ inline EditPaM GetEndPaM() const;
+
+ SfxItemPool& GetItemPool() { return *pItemPool; }
+ const SfxItemPool& GetItemPool() const { return *pItemPool; }
+
+ void RemoveItemsFromPool( ContentNode* pNode );
+
+ void InsertAttrib( const SfxPoolItem& rItem, ContentNode* pNode, USHORT nStart, USHORT nEnd );
+ void InsertAttrib( ContentNode* pNode, USHORT nStart, USHORT nEnd, const SfxPoolItem& rPoolItem );
+ void InsertAttribInSelection( ContentNode* pNode, USHORT nStart, USHORT nEnd, const SfxPoolItem& rPoolItem );
+ BOOL RemoveAttribs( ContentNode* pNode, USHORT nStart, USHORT nEnd, USHORT nWhich = 0 );
+ BOOL RemoveAttribs( ContentNode* pNode, USHORT nStart, USHORT nEnd, EditCharAttrib*& rpStarting, EditCharAttrib*& rpEnding, USHORT nWhich = 0 );
+ void FindAttribs( ContentNode* pNode, USHORT nStartPos, USHORT nEndPos, SfxItemSet& rCurSet );
+
+ USHORT GetPos( ContentNode* pNode ) const { return ContentList::GetPos(pNode); }
+ ContentNode* SaveGetObject( USHORT nPos ) const { return ( nPos < Count() ) ? GetObject( nPos ) : 0; }
+
+ static XubString GetSepStr( LineEnd eEnd );
+};
+
+inline EditPaM EditDoc::GetStartPaM() const
+{
+ return EditPaM( GetObject( 0 ), 0 );
+}
+
+inline EditPaM EditDoc::GetEndPaM() const
+{
+ ContentNode* pLastNode = GetObject( Count()-1 );
+ return EditPaM( pLastNode, pLastNode->Len() );
+}
+
+inline EditCharAttrib* GetAttrib( const CharAttribArray& rAttribs, USHORT nAttr )
+{
+ return ( nAttr < rAttribs.Count() ) ? rAttribs[nAttr] : 0;
+}
+
+BOOL CheckOrderedList( CharAttribArray& rAttribs, BOOL bStart );
+
+// -------------------------------------------------------------------------
+// class EditEngineItemPool
+// -------------------------------------------------------------------------
+class EditEngineItemPool : public SfxItemPool
+{
+public:
+ EditEngineItemPool( BOOL bPersistenRefCounts );
+protected:
+ virtual ~EditEngineItemPool();
+public:
+
+ virtual SvStream& Store( SvStream& rStream ) const;
+};
+
+#endif // _EDITDOC_HXX
diff --git a/editeng/source/editeng/editdoc2.cxx b/editeng/source/editeng/editdoc2.cxx
new file mode 100644
index 0000000000..00fe509a19
--- /dev/null
+++ b/editeng/source/editeng/editdoc2.cxx
@@ -0,0 +1,547 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: editdoc2.cxx,v $
+ * $Revision: 1.19 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <vcl/wrkwin.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+#include <svl/smplhint.hxx>
+
+#include <tools/rtti.hxx>
+#include <editeng/lspcitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/tstpitem.hxx>
+
+#include <editdoc.hxx>
+#include <impedit.hxx>
+#include <editdbg.hxx>
+
+#include <editeng/numitem.hxx>
+
+#include <editeng/akrnitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/charscaleitem.hxx>
+
+#include <vcl/svapp.hxx> // Fuer AppWindow...
+
+DBG_NAME( EE_ParaPortion )
+
+SV_IMPL_VARARR( CharPosArray, sal_Int32 );
+
+/*
+
+BOOL EditStyleSheet::HasStyleAsAnyParent( SfxStyleSheet& rStyle )
+{
+ if ( GetParent() == rStyle.GetName() )
+ return TRUE;
+
+ if ( GetParent().Len() && ( GetParent() != GetName() ) )
+ {
+ EditStyleSheet* pS = (EditStyleSheet*)GetPool().Find( GetParent(), rStyle.GetFamily() );
+ if ( pS )
+ return pS->HasStyleAsAnyParent( rStyle );
+ }
+ return FALSE;
+}
+
+*/
+
+// -------------------------------------------------------------------------
+// class TextPortionList
+// -------------------------------------------------------------------------
+TextPortionList::TextPortionList()
+{
+}
+
+TextPortionList::~TextPortionList()
+{
+ Reset();
+}
+
+void TextPortionList::Reset()
+{
+ for ( USHORT nPortion = 0; nPortion < Count(); nPortion++ )
+ delete GetObject( nPortion );
+ Remove( 0, Count() );
+}
+
+void TextPortionList::DeleteFromPortion( USHORT nDelFrom )
+{
+ DBG_ASSERT( ( nDelFrom < Count() ) || ( (nDelFrom == 0) && (Count() == 0) ), "DeleteFromPortion: Out of range" );
+ for ( USHORT nP = nDelFrom; nP < Count(); nP++ )
+ delete GetObject( nP );
+ Remove( nDelFrom, Count()-nDelFrom );
+}
+
+USHORT TextPortionList::FindPortion( USHORT nCharPos, USHORT& nPortionStart, BOOL bPreferStartingPortion )
+{
+ // Bei nCharPos an Portion-Grenze wird die linke Portion gefunden
+ USHORT nTmpPos = 0;
+ for ( USHORT nPortion = 0; nPortion < Count(); nPortion++ )
+ {
+ TextPortion* pPortion = GetObject( nPortion );
+ nTmpPos = nTmpPos + pPortion->GetLen();
+ if ( nTmpPos >= nCharPos )
+ {
+ // take this one if we don't prefer the starting portion, or if it's the last one
+ if ( ( nTmpPos != nCharPos ) || !bPreferStartingPortion || ( nPortion == Count() - 1 ) )
+ {
+ nPortionStart = nTmpPos - pPortion->GetLen();
+ return nPortion;
+ }
+ }
+ }
+ DBG_ERROR( "FindPortion: Nicht gefunden!" );
+ return ( Count() - 1 );
+}
+
+USHORT TextPortionList::GetStartPos( USHORT nPortion )
+{
+ USHORT nPos = 0;
+ for ( USHORT n = 0; n < nPortion; n++ )
+ {
+ TextPortion* pPortion = GetObject( n );
+ nPos = nPos + pPortion->GetLen();
+ }
+ return nPos;
+}
+
+
+// -------------------------------------------------------------------------
+// class ExtraPortionInfo
+// -------------------------------------------------------------------------
+
+ExtraPortionInfo::ExtraPortionInfo()
+{
+ nOrgWidth = 0;
+ nWidthFullCompression = 0;
+ nMaxCompression100thPercent = 0;
+ nAsianCompressionTypes = 0;
+ nPortionOffsetX = 0;
+ bFirstCharIsRightPunktuation = FALSE;
+ bCompressed = FALSE;
+ pOrgDXArray = NULL;
+}
+
+ExtraPortionInfo::~ExtraPortionInfo()
+{
+ delete[] pOrgDXArray;
+}
+
+void ExtraPortionInfo::SaveOrgDXArray( const sal_Int32* pDXArray, USHORT nLen )
+{
+ delete[] pOrgDXArray;
+ pOrgDXArray = new sal_Int32[nLen];
+ memcpy( pOrgDXArray, pDXArray, nLen*sizeof(sal_Int32) );
+}
+
+void ExtraPortionInfo::DestroyOrgDXArray()
+{
+ delete[] pOrgDXArray;
+ pOrgDXArray = NULL;
+}
+
+
+// -------------------------------------------------------------------------
+// class ParaPortion
+// -------------------------------------------------------------------------
+ParaPortion::ParaPortion( ContentNode* pN )
+{
+ DBG_CTOR( EE_ParaPortion, 0 );
+
+ pNode = pN;
+ bInvalid = TRUE;
+ bVisible = TRUE;
+ bSimple = FALSE;
+ bForceRepaint = FALSE;
+ nInvalidPosStart = 0;
+ nInvalidDiff = 0;
+ nHeight = 0;
+ nFirstLineOffset = 0;
+ nBulletX = 0;
+}
+
+ParaPortion::~ParaPortion()
+{
+ DBG_DTOR( EE_ParaPortion, 0 );
+}
+
+void ParaPortion::MarkInvalid( USHORT nStart, short nDiff )
+{
+ if ( bInvalid == FALSE )
+ {
+// nInvalidPosEnd = nStart; // ??? => CreateLines
+ nInvalidPosStart = ( nDiff >= 0 ) ? nStart : ( nStart + nDiff );
+ nInvalidDiff = nDiff;
+ }
+ else
+ {
+ // Einfaches hintereinander tippen
+ if ( ( nDiff > 0 ) && ( nInvalidDiff > 0 ) &&
+ ( ( nInvalidPosStart+nInvalidDiff ) == nStart ) )
+ {
+ nInvalidDiff = nInvalidDiff + nDiff;
+ }
+ // Einfaches hintereinander loeschen
+ else if ( ( nDiff < 0 ) && ( nInvalidDiff < 0 ) && ( nInvalidPosStart == nStart ) )
+ {
+ nInvalidPosStart = nInvalidPosStart + nDiff;
+ nInvalidDiff = nInvalidDiff + nDiff;
+ }
+ else
+ {
+// nInvalidPosEnd = pNode->Len();
+ DBG_ASSERT( ( nDiff >= 0 ) || ( (nStart+nDiff) >= 0 ), "MarkInvalid: Diff out of Range" );
+ nInvalidPosStart = Min( nInvalidPosStart, (USHORT) ( nDiff < 0 ? nStart+nDiff : nDiff ) );
+ nInvalidDiff = 0;
+ bSimple = FALSE;
+ }
+ }
+ bInvalid = TRUE;
+ aScriptInfos.Remove( 0, aScriptInfos.Count() );
+ aWritingDirectionInfos.Remove( 0, aWritingDirectionInfos.Count() );
+// aExtraCharInfos.Remove( 0, aExtraCharInfos.Count() );
+}
+
+void ParaPortion::MarkSelectionInvalid( USHORT nStart, USHORT /* nEnd */ )
+{
+ if ( bInvalid == FALSE )
+ {
+ nInvalidPosStart = nStart;
+// nInvalidPosEnd = nEnd;
+ }
+ else
+ {
+ nInvalidPosStart = Min( nInvalidPosStart, nStart );
+// nInvalidPosEnd = pNode->Len();
+ }
+ nInvalidDiff = 0;
+ bInvalid = TRUE;
+ bSimple = FALSE;
+ aScriptInfos.Remove( 0, aScriptInfos.Count() );
+ aWritingDirectionInfos.Remove( 0, aWritingDirectionInfos.Count() );
+// aExtraCharInfos.Remove( 0, aExtraCharInfos.Count() );
+}
+
+USHORT ParaPortion::GetLineNumber( USHORT nIndex )
+{
+ DBG_ASSERTWARNING( aLineList.Count(), "Leere ParaPortion in GetLine!" );
+ DBG_ASSERT( bVisible, "Wozu GetLine() bei einem unsichtbaren Absatz?" );
+
+ for ( USHORT nLine = 0; nLine < aLineList.Count(); nLine++ )
+ {
+ if ( aLineList[nLine]->IsIn( nIndex ) )
+ return nLine;
+ }
+
+ // Dann sollte es am Ende der letzten Zeile sein!
+ DBG_ASSERT( nIndex == aLineList[ aLineList.Count() - 1 ]->GetEnd(), "Index voll daneben!" );
+ return (aLineList.Count()-1);
+}
+
+void ParaPortion::SetVisible( BOOL bMakeVisible )
+{
+ bVisible = bMakeVisible;
+}
+
+void ParaPortion::CorrectValuesBehindLastFormattedLine( USHORT nLastFormattedLine )
+{
+ USHORT nLines = aLineList.Count();
+ DBG_ASSERT( nLines, "CorrectPortionNumbersFromLine: Leere Portion?" );
+ if ( nLastFormattedLine < ( nLines - 1 ) )
+ {
+ const EditLine* pLastFormatted = aLineList[ nLastFormattedLine ];
+ const EditLine* pUnformatted = aLineList[ nLastFormattedLine+1 ];
+ short nPortionDiff = pUnformatted->GetStartPortion() - pLastFormatted->GetEndPortion();
+ short nTextDiff = pUnformatted->GetStart() - pLastFormatted->GetEnd();
+ nTextDiff++; // LastFormatted->GetEnd() war incl. => 1 zuviel abgezogen!
+
+ // Die erste unformatierte muss genau eine Portion hinter der letzten der
+ // formatierten beginnen:
+ // Wenn in der geaenderten Zeile eine Portion gesplittet wurde,
+ // kann nLastEnd > nNextStart sein!
+ int nPDiff = -( nPortionDiff-1 );
+ int nTDiff = -( nTextDiff-1 );
+ if ( nPDiff || nTDiff )
+ {
+ for ( USHORT nL = nLastFormattedLine+1; nL < nLines; nL++ )
+ {
+ EditLine* pLine = aLineList[ nL ];
+
+ pLine->GetStartPortion() = sal::static_int_cast< USHORT >(
+ pLine->GetStartPortion() + nPDiff);
+ pLine->GetEndPortion() = sal::static_int_cast< USHORT >(
+ pLine->GetEndPortion() + nPDiff);
+
+ pLine->GetStart() = sal::static_int_cast< USHORT >(
+ pLine->GetStart() + nTDiff);
+ pLine->GetEnd() = sal::static_int_cast< USHORT >(
+ pLine->GetEnd() + nTDiff);
+
+ pLine->SetValid();
+ }
+ }
+ }
+ DBG_ASSERT( aLineList[ aLineList.Count()-1 ]->GetEnd() == pNode->Len(), "CorrectLines: Ende stimmt nicht!" );
+}
+
+// Shared reverse lookup acceleration pieces ...
+
+static USHORT FastGetPos( const VoidPtr *pPtrArray, USHORT nPtrArrayLen,
+ VoidPtr pPtr, USHORT &rLastPos )
+{
+ // Through certain filter code-paths we do a lot of appends, which in
+ // turn call GetPos - creating some N^2 nightmares. If we have a
+ // non-trivially large list, do a few checks from the end first.
+ if( rLastPos > 16 )
+ {
+ USHORT nEnd;
+ if (rLastPos > nPtrArrayLen - 2)
+ nEnd = nPtrArrayLen;
+ else
+ nEnd = rLastPos + 2;
+
+ for( USHORT nIdx = rLastPos - 2; nIdx < nEnd; nIdx++ )
+ {
+ if( pPtrArray[ nIdx ] == pPtr )
+ {
+ rLastPos = nIdx;
+ return nIdx;
+ }
+ }
+ }
+ // The world's lamest linear search from svarray ...
+ for( USHORT nIdx = 0; nIdx < nPtrArrayLen; nIdx++ )
+ if (pPtrArray[ nIdx ] == pPtr )
+ return rLastPos = nIdx;
+ return USHRT_MAX;
+}
+
+// -------------------------------------------------------------------------
+// class ParaPortionList
+// -------------------------------------------------------------------------
+ParaPortionList::ParaPortionList() : nLastCache( 0 )
+{
+}
+
+ParaPortionList::~ParaPortionList()
+{
+ Reset();
+}
+
+USHORT ParaPortionList::GetPos( const ParaPortionPtr &rPtr ) const
+{
+ return FastGetPos( reinterpret_cast<const VoidPtr *>( GetData() ),
+ Count(), static_cast<VoidPtr>( rPtr ),
+ ((ParaPortionList *)this)->nLastCache );
+}
+
+USHORT ContentList::GetPos( const ContentNodePtr &rPtr ) const
+{
+ return FastGetPos( reinterpret_cast<const VoidPtr *>( GetData() ),
+ Count(), static_cast<VoidPtr>( rPtr ),
+ ((ContentList *)this)->nLastCache );
+}
+
+void ParaPortionList::Reset()
+{
+ for ( USHORT nPortion = 0; nPortion < Count(); nPortion++ )
+ delete GetObject( nPortion );
+ Remove( 0, Count() );
+}
+
+long ParaPortionList::GetYOffset( ParaPortion* pPPortion )
+{
+ long nHeight = 0;
+ for ( USHORT nPortion = 0; nPortion < Count(); nPortion++ )
+ {
+ ParaPortion* pTmpPortion = GetObject(nPortion);
+ if ( pTmpPortion == pPPortion )
+ return nHeight;
+ nHeight += pTmpPortion->GetHeight();
+ }
+ DBG_ERROR( "GetYOffset: Portion nicht gefunden" );
+ return nHeight;
+}
+
+USHORT ParaPortionList::FindParagraph( long nYOffset )
+{
+ long nY = 0;
+ for ( USHORT nPortion = 0; nPortion < Count(); nPortion++ )
+ {
+ nY += GetObject(nPortion)->GetHeight(); // sollte auch bei !bVisible richtig sein!
+ if ( nY > nYOffset )
+ return nPortion;
+ }
+ return 0xFFFF; // solte mal ueber EE_PARA_NOT_FOUND erreicht werden!
+}
+
+void ParaPortionList::DbgCheck( EditDoc&
+#ifdef DBG_UTIL
+ rDoc
+#endif
+ )
+{
+#ifdef DBG_UTIL
+ DBG_ASSERT( Count() == rDoc.Count(), "ParaPortionList::DbgCheck() - Count() ungleich!" );
+ for ( USHORT i = 0; i < Count(); i++ )
+ {
+ DBG_ASSERT( SaveGetObject(i), "ParaPortionList::DbgCheck() - Null-Pointer in Liste!" );
+ DBG_ASSERT( GetObject(i)->GetNode(), "ParaPortionList::DbgCheck() - Null-Pointer in Liste(2)!" );
+ DBG_ASSERT( GetObject(i)->GetNode() == rDoc.GetObject(i), "ParaPortionList::DbgCheck() - Eintraege kreuzen sich!" );
+ }
+#endif
+}
+
+
+ContentAttribsInfo::ContentAttribsInfo( const SfxItemSet& rParaAttribs ) :
+ aPrevParaAttribs( rParaAttribs)
+{
+}
+
+
+void ConvertItem( SfxPoolItem& rPoolItem, MapUnit eSourceUnit, MapUnit eDestUnit )
+{
+ DBG_ASSERT( eSourceUnit != eDestUnit, "ConvertItem - Why?!" );
+
+ switch ( rPoolItem.Which() )
+ {
+ case EE_PARA_LRSPACE:
+ {
+ DBG_ASSERT( rPoolItem.IsA( TYPE( SvxLRSpaceItem ) ), "ConvertItem: Ungueltiges Item!" );
+ SvxLRSpaceItem& rItem = (SvxLRSpaceItem&)rPoolItem;
+ rItem.SetTxtFirstLineOfst( sal::static_int_cast< short >( OutputDevice::LogicToLogic( rItem.GetTxtFirstLineOfst(), eSourceUnit, eDestUnit ) ) );
+ rItem.SetTxtLeft( OutputDevice::LogicToLogic( rItem.GetTxtLeft(), eSourceUnit, eDestUnit ) );
+// rItem.SetLeft( OutputDevice::LogicToLogic( rItem.GetLeft(), eSourceUnit, eDestUnit ) ); // #96298# SetLeft manipulates nTxtLeft!
+ rItem.SetRight( OutputDevice::LogicToLogic( rItem.GetRight(), eSourceUnit, eDestUnit ) );
+ }
+ break;
+ case EE_PARA_ULSPACE:
+ {
+ DBG_ASSERT( rPoolItem.IsA( TYPE( SvxULSpaceItem ) ), "ConvertItem: Ungueltiges Item!" );
+ SvxULSpaceItem& rItem = (SvxULSpaceItem&)rPoolItem;
+ rItem.SetUpper( sal::static_int_cast< USHORT >( OutputDevice::LogicToLogic( rItem.GetUpper(), eSourceUnit, eDestUnit ) ) );
+ rItem.SetLower( sal::static_int_cast< USHORT >( OutputDevice::LogicToLogic( rItem.GetLower(), eSourceUnit, eDestUnit ) ) );
+ }
+ break;
+ case EE_PARA_SBL:
+ {
+ DBG_ASSERT( rPoolItem.IsA( TYPE( SvxLineSpacingItem ) ), "ConvertItem: Ungueltiges Item!" );
+ SvxLineSpacingItem& rItem = (SvxLineSpacingItem&)rPoolItem;
+ // #96298# SetLineHeight changes also eLineSpace!
+ if ( rItem.GetLineSpaceRule() == SVX_LINE_SPACE_MIN )
+ rItem.SetLineHeight( sal::static_int_cast< USHORT >( OutputDevice::LogicToLogic( rItem.GetLineHeight(), eSourceUnit, eDestUnit ) ) );
+ }
+ break;
+ case EE_PARA_TABS:
+ {
+ DBG_ASSERT( rPoolItem.IsA( TYPE( SvxTabStopItem ) ), "ConvertItem: Ungueltiges Item!" );
+ SvxTabStopItem& rItem = (SvxTabStopItem&)rPoolItem;
+ SvxTabStopItem aNewItem( EE_PARA_TABS );
+ for ( USHORT i = 0; i < rItem.Count(); i++ )
+ {
+ const SvxTabStop& rTab = rItem[i];
+ SvxTabStop aNewStop( OutputDevice::LogicToLogic( rTab.GetTabPos(), eSourceUnit, eDestUnit ), rTab.GetAdjustment(), rTab.GetDecimal(), rTab.GetFill() );
+ aNewItem.Insert( aNewStop );
+ }
+ rItem = aNewItem;
+ }
+ break;
+ case EE_CHAR_FONTHEIGHT:
+ case EE_CHAR_FONTHEIGHT_CJK:
+ case EE_CHAR_FONTHEIGHT_CTL:
+ {
+ DBG_ASSERT( rPoolItem.IsA( TYPE( SvxFontHeightItem ) ), "ConvertItem: Ungueltiges Item!" );
+ SvxFontHeightItem& rItem = (SvxFontHeightItem&)rPoolItem;
+ rItem.SetHeight( OutputDevice::LogicToLogic( rItem.GetHeight(), eSourceUnit, eDestUnit ) );
+ }
+ break;
+ }
+}
+
+void ConvertAndPutItems( SfxItemSet& rDest, const SfxItemSet& rSource, const MapUnit* pSourceUnit, const MapUnit* pDestUnit )
+{
+ const SfxItemPool* pSourcePool = rSource.GetPool();
+ const SfxItemPool* pDestPool = rDest.GetPool();
+
+ for ( USHORT nWhich = EE_PARA_START; nWhich <= EE_CHAR_END; nWhich++ )
+ {
+ // Wenn moeglich ueber SlotID gehen...
+
+ USHORT nSourceWhich = nWhich;
+ USHORT nSlot = pDestPool->GetTrueSlotId( nWhich );
+ if ( nSlot )
+ {
+ USHORT nW = pSourcePool->GetTrueWhich( nSlot );
+ if ( nW )
+ nSourceWhich = nW;
+ }
+
+ if ( rSource.GetItemState( nSourceWhich, FALSE ) == SFX_ITEM_ON )
+ {
+ MapUnit eSourceUnit = pSourceUnit ? *pSourceUnit : (MapUnit)pSourcePool->GetMetric( nSourceWhich );
+ MapUnit eDestUnit = pDestUnit ? *pDestUnit : (MapUnit)pDestPool->GetMetric( nWhich );
+ if ( eSourceUnit != eDestUnit )
+ {
+ SfxPoolItem* pItem = rSource.Get( nSourceWhich ).Clone();
+// pItem->SetWhich( nWhich );
+ ConvertItem( *pItem, eSourceUnit, eDestUnit );
+ rDest.Put( *pItem, nWhich );
+ delete pItem;
+ }
+ else
+ {
+ rDest.Put( rSource.Get( nSourceWhich ), nWhich );
+ }
+ }
+ else
+ {
+ // MT 3.3.99: Waere so eigentlich richtig, aber schon seit Jahren nicht so...
+// rDest.ClearItem( nWhich );
+ }
+ }
+}
+
diff --git a/editeng/source/editeng/editeng.cxx b/editeng/source/editeng/editeng.cxx
new file mode 100644
index 0000000000..9efdc6b2fe
--- /dev/null
+++ b/editeng/source/editeng/editeng.cxx
@@ -0,0 +1,2944 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: editeng.cxx,v $
+ * $Revision: 1.117.12.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <vcl/wrkwin.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+
+#define USE_SVXFONT
+
+#define _SVSTDARR_USHORTS
+#include <svl/svstdarr.hxx>
+#include <svl/ctloptions.hxx>
+#include <svtools/ctrltool.hxx>
+
+#include <editeng/svxfont.hxx>
+#include <impedit.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/editstat.hxx>
+#include <editdbg.hxx>
+#include <eerdll2.hxx>
+#include <editeng/eerdll.hxx>
+#include <editeng.hrc>
+#include <editeng/flditem.hxx>
+#include <editeng/txtrange.hxx>
+#include <vcl/graph.hxx>
+
+#include <editeng/akrnitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/cscoitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/emphitem.hxx>
+#include <editeng/charscaleitem.hxx>
+#include <editeng/charreliefitem.hxx>
+
+#include <sot/exchange.hxx>
+#include <sot/formats.hxx>
+
+#include <editeng/numitem.hxx>
+#include <editeng/bulitem.hxx>
+#include <editeng/unolingu.hxx>
+#include <linguistic/lngprops.hxx>
+#include <i18npool/mslangid.hxx>
+#include <vcl/help.hxx>
+#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
+#include <com/sun/star/i18n/InputSequenceCheckMode.hpp>
+
+#include <svl/srchdefs.hxx>
+
+#if OSL_DEBUG_LEVEL > 1
+#include <editeng/frmdiritem.hxx>
+#endif
+#include <basegfx/polygon/b2dpolygon.hxx>
+
+// Spaeter -> TOOLS\STRING.H (fuer Grep: WS_TARGET)
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::linguistic2;
+
+
+DBG_NAME( EditEngine )
+DBG_NAMEEX( EditView )
+
+#if (OSL_DEBUG_LEVEL > 1) || defined ( DBG_UTIL )
+static sal_Bool bDebugPaint = sal_False;
+#endif
+
+SV_IMPL_VARARR( EECharAttribArray, EECharAttrib );
+
+static SfxItemPool* pGlobalPool=0;
+
+ // ----------------------------------------------------------------------
+// EditEngine
+// ----------------------------------------------------------------------
+EditEngine::EditEngine( SfxItemPool* pItemPool )
+{
+ DBG_CTOR( EditEngine, 0 );
+ pImpEditEngine = new ImpEditEngine( this, pItemPool );
+}
+
+EditEngine::~EditEngine()
+{
+ DBG_DTOR( EditEngine, 0 );
+ delete pImpEditEngine;
+}
+
+void EditEngine::EnableUndo( sal_Bool bEnable )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->EnableUndo( bEnable );
+}
+
+sal_Bool EditEngine::IsUndoEnabled()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->IsUndoEnabled();
+}
+
+sal_Bool EditEngine::IsInUndo()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->IsInUndo();
+}
+
+SfxUndoManager& EditEngine::GetUndoManager()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetUndoManager();
+}
+
+void EditEngine::UndoActionStart( sal_uInt16 nId )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ DBG_ASSERT( !pImpEditEngine->IsInUndo(), "Aufruf von UndoActionStart im Undomodus!" );
+ if ( !pImpEditEngine->IsInUndo() )
+ pImpEditEngine->UndoActionStart( nId );
+}
+
+void EditEngine::UndoActionEnd( sal_uInt16 nId )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ DBG_ASSERT( !pImpEditEngine->IsInUndo(), "Aufruf von UndoActionEnd im Undomodus!" );
+ if ( !pImpEditEngine->IsInUndo() )
+ pImpEditEngine->UndoActionEnd( nId );
+}
+
+BOOL EditEngine::HasTriedMergeOnLastAddUndo() const
+{
+ return pImpEditEngine->mbLastTryMerge;
+}
+
+void EditEngine::SetRefDevice( OutputDevice* pRefDev )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetRefDevice( pRefDev );
+}
+
+OutputDevice* EditEngine::GetRefDevice() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetRefDevice();
+}
+
+void EditEngine::SetRefMapMode( const MapMode& rMapMode )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetRefMapMode( rMapMode );
+}
+
+MapMode EditEngine::GetRefMapMode()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetRefMapMode();
+}
+
+void EditEngine::SetBackgroundColor( const Color& rColor )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetBackgroundColor( rColor );
+}
+
+Color EditEngine::GetBackgroundColor() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetBackgroundColor();
+}
+
+Color EditEngine::GetAutoColor() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetAutoColor();
+}
+
+void EditEngine::EnableAutoColor( BOOL b )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->EnableAutoColor( b );
+}
+
+BOOL EditEngine::IsAutoColorEnabled() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->IsAutoColorEnabled();
+}
+
+void EditEngine::ForceAutoColor( BOOL b )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->ForceAutoColor( b );
+}
+
+BOOL EditEngine::IsForceAutoColor() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->IsForceAutoColor();
+}
+
+const SfxItemSet& EditEngine::GetEmptyItemSet()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetEmptyItemSet();
+}
+
+void EditEngine::Draw( OutputDevice* pOutDev, const Rectangle& rOutRect )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ Draw( pOutDev, rOutRect, Point( 0, 0 ) );
+}
+
+void EditEngine::Draw( OutputDevice* pOutDev, const Point& rStartPos, short nOrientation )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ // Mit 2 Punkten erzeugen, da bei Positivem Punkt, LONGMAX als Size
+ // Bottom und Right im Bereich > LONGMAX landen.
+ Rectangle aBigRec( -0x3FFFFFFF, -0x3FFFFFFF, 0x3FFFFFFF, 0x3FFFFFFF );
+ if( pOutDev->GetConnectMetaFile() )
+ pOutDev->Push();
+ Point aStartPos( rStartPos );
+ if ( IsVertical() )
+ {
+ aStartPos.X() += GetPaperSize().Width();
+ aStartPos = Rotate( aStartPos, nOrientation, rStartPos );
+ }
+ pImpEditEngine->Paint( pOutDev, aBigRec, aStartPos, sal_False, nOrientation );
+ if( pOutDev->GetConnectMetaFile() )
+ pOutDev->Pop();
+}
+
+void EditEngine::Draw( OutputDevice* pOutDev, const Rectangle& rOutRect, const Point& rStartDocPos )
+{
+ Draw( pOutDev, rOutRect, rStartDocPos, sal_True );
+}
+
+void EditEngine::Draw( OutputDevice* pOutDev, const Rectangle& rOutRect, const Point& rStartDocPos, sal_Bool bClip )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+#if defined( DBG_UTIL ) || (OSL_DEBUG_LEVEL > 1)
+ if ( bDebugPaint )
+ EditDbg::ShowEditEngineData( this, sal_False );
+#endif
+
+ // Auf Pixelgrenze ausrichten, damit genau das gleiche
+ // wie bei Paint().
+ Rectangle aOutRect( pOutDev->LogicToPixel( rOutRect ) );
+ aOutRect = pOutDev->PixelToLogic( aOutRect );
+
+ Point aStartPos;
+ if ( !IsVertical() )
+ {
+ aStartPos.X() = aOutRect.Left() - rStartDocPos.X();
+ aStartPos.Y() = aOutRect.Top() - rStartDocPos.Y();
+ }
+ else
+ {
+ aStartPos.X() = aOutRect.Right() + rStartDocPos.Y();
+ aStartPos.Y() = aOutRect.Top() - rStartDocPos.X();
+ }
+
+ sal_Bool bClipRegion = pOutDev->IsClipRegion();
+ sal_Bool bMetafile = pOutDev->GetConnectMetaFile() ? sal_True : sal_False;
+ Region aOldRegion = pOutDev->GetClipRegion();
+
+#ifdef EDIT_PRINTER_LOG
+ if ( pOutDev->GetOutDevType() == OUTDEV_PRINTER )
+ {
+ SvFileStream aLog( "d:\\editprn.log", STREAM_WRITE );
+ aLog.Seek( STREAM_SEEK_TO_END );
+ aLog << ' ' << endl << "Printing: ";
+ aLog << GetText( "\n\r" ).GetStr();
+ aLog << endl << endl;
+ aLog << "Ref-Device: " << String( (sal_uInt32)GetRefDevice() ).GetStr() << " Type=" << String( (sal_uInt16)GetRefDevice()->GetOutDevType() ).GetStr() << ", MapX=" << String( GetRefDevice()->GetMapMode().GetScaleX().GetNumerator() ).GetStr() << "/" << String( GetRefDevice()->GetMapMode().GetScaleX().GetDenominator() ).GetStr() <<endl;
+ aLog << "Paper-Width: " << String( GetPaperSize().Width() ).GetStr() << ",\tOut-Width: " << String( rOutRect.GetWidth() ).GetStr() << ",\tCalculated: " << String( CalcTextWidth() ).GetStr() << endl;
+ aLog << "Paper-Height: " << String( GetPaperSize().Height() ).GetStr() << ",\tOut-Height: " << String( rOutRect.GetHeight() ).GetStr() << ",\tCalculated: " << String( GetTextHeight() ).GetStr() << endl;
+
+ aLog << endl;
+ }
+#endif
+
+ // Wenn es eine gab => Schnittmenge !
+ // Bei der Metafileaufzeichnung Push/Pop verwenden.
+ if ( bMetafile )
+ pOutDev->Push();
+
+ // Immer die Intersect-Methode, weil beim Metafile ein Muss!
+ if ( bClip )
+ {
+ // Clip only if neccesary...
+ if ( !rStartDocPos.X() && !rStartDocPos.Y() &&
+ ( rOutRect.GetHeight() >= (long)GetTextHeight() ) &&
+ ( rOutRect.GetWidth() >= (long)CalcTextWidth() ) )
+ {
+ bClip = FALSE;
+ }
+ else
+ {
+ // Einige Druckertreiber bereiten Probleme, wenn Buchstaben die
+ // ClipRegion streifen, deshalb lieber ein Pixel mehr...
+ Rectangle aClipRect( aOutRect );
+ if ( pOutDev->GetOutDevType() == OUTDEV_PRINTER )
+ {
+ Size aPixSz( 1, 0 );
+ aPixSz = pOutDev->PixelToLogic( aPixSz );
+ aClipRect.Right() += aPixSz.Width();
+ aClipRect.Bottom() += aPixSz.Width();
+ }
+ pOutDev->IntersectClipRegion( aClipRect );
+ }
+ }
+
+ pImpEditEngine->Paint( pOutDev, aOutRect, aStartPos );
+
+ if ( bMetafile )
+ pOutDev->Pop();
+ else if ( bClipRegion )
+ pOutDev->SetClipRegion( aOldRegion );
+ else
+ pOutDev->SetClipRegion();
+}
+
+void EditEngine::InsertView( EditView* pEditView, sal_uInt16 nIndex )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ DBG_CHKOBJ( pEditView, EditView, 0 );
+
+ if ( nIndex > pImpEditEngine->GetEditViews().Count() )
+ nIndex = pImpEditEngine->GetEditViews().Count();
+
+ pImpEditEngine->GetEditViews().Insert( pEditView, nIndex );
+ EditSelection aStartSel;
+ aStartSel = pImpEditEngine->GetEditDoc().GetStartPaM();
+ pEditView->pImpEditView->SetEditSelection( aStartSel );
+ if ( !pImpEditEngine->GetActiveView() )
+ pImpEditEngine->SetActiveView( pEditView );
+
+ pEditView->pImpEditView->AddDragAndDropListeners();
+}
+
+EditView* EditEngine::RemoveView( EditView* pView )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ DBG_CHKOBJ( pView, EditView, 0 );
+
+ pView->HideCursor();
+ EditView* pRemoved = 0;
+ sal_uInt16 nPos = pImpEditEngine->GetEditViews().GetPos( pView );
+ DBG_ASSERT( nPos != USHRT_MAX, "RemoveView mit ungueltigem Index" );
+ if ( nPos != USHRT_MAX )
+ {
+ pRemoved = pImpEditEngine->GetEditViews().GetObject( nPos );
+ pImpEditEngine->GetEditViews().Remove( nPos );
+ if ( pImpEditEngine->GetActiveView() == pView )
+ {
+ pImpEditEngine->SetActiveView( 0 );
+ pImpEditEngine->GetSelEngine().SetCurView( 0 );
+ }
+ pView->pImpEditView->RemoveDragAndDropListeners();
+
+ }
+ return pRemoved;
+}
+
+EditView* EditEngine::RemoveView( sal_uInt16 nIndex )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ EditView* pView = pImpEditEngine->GetEditViews().GetObject( nIndex );
+ if ( pView )
+ return RemoveView( pView );
+ return NULL;
+}
+
+EditView* EditEngine::GetView( sal_uInt16 nIndex ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetEditViews().GetObject( nIndex );
+}
+
+sal_uInt16 EditEngine::GetViewCount() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetEditViews().Count();
+}
+
+sal_Bool EditEngine::HasView( EditView* pView ) const
+{
+ return pImpEditEngine->GetEditViews().GetPos( pView ) != USHRT_MAX;
+}
+
+EditView* EditEngine::GetActiveView() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetActiveView();
+}
+
+void EditEngine::SetActiveView( EditView* pView )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ if ( pView )
+ {
+ DBG_CHKOBJ( pView, EditView, 0 );
+ }
+ pImpEditEngine->SetActiveView( pView );
+}
+
+void EditEngine::SetDefTab( sal_uInt16 nDefTab )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->GetEditDoc().SetDefTab( nDefTab );
+ if ( pImpEditEngine->IsFormatted() )
+ {
+ pImpEditEngine->FormatFullDoc();
+ pImpEditEngine->UpdateViews( (EditView*) 0 );
+ }
+}
+
+sal_uInt16 EditEngine::GetDefTab() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetEditDoc().GetDefTab();
+}
+
+void EditEngine::SetPaperSize( const Size& rNewSize )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ Size aOldSize( pImpEditEngine->GetPaperSize() );
+ pImpEditEngine->SetValidPaperSize( rNewSize );
+ Size aNewSize( pImpEditEngine->GetPaperSize() );
+
+ sal_Bool bAutoPageSize = pImpEditEngine->GetStatus().AutoPageSize();
+ if ( bAutoPageSize || ( aNewSize.Width() != aOldSize.Width() ) )
+ {
+ for ( sal_uInt16 nView = 0; nView < pImpEditEngine->aEditViews.Count(); nView++ )
+ {
+ EditView* pView = pImpEditEngine->aEditViews[nView];
+ DBG_CHKOBJ( pView, EditView, 0 );
+ if ( bAutoPageSize )
+ pView->pImpEditView->RecalcOutputArea();
+ else if ( pView->pImpEditView->DoAutoSize() )
+ {
+ pView->pImpEditView->ResetOutputArea( Rectangle(
+ pView->pImpEditView->GetOutputArea().TopLeft(), aNewSize ) );
+ }
+ }
+
+ if ( bAutoPageSize || pImpEditEngine->IsFormatted() )
+ {
+ // Aendern der Breite hat bei AutoPageSize keine Wirkung, da durch
+ // Textbreite bestimmt.
+ // Optimierung erst nach Vobis-Auslieferung aktivieren...
+// if ( !bAutoPageSize )
+ pImpEditEngine->FormatFullDoc();
+// else
+// {
+// pImpEditEngine->FormatDoc(); // PageSize, falls Aenderung
+// pImpEditEngine->CheckAutoPageSize(); // Falls nichts formatiert wurde
+// }
+
+ pImpEditEngine->UpdateViews( pImpEditEngine->GetActiveView() );
+
+ if ( pImpEditEngine->GetUpdateMode() && pImpEditEngine->GetActiveView() )
+ pImpEditEngine->pActiveView->ShowCursor( sal_False, sal_False );
+ }
+ }
+}
+
+const Size& EditEngine::GetPaperSize() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetPaperSize();
+}
+
+void EditEngine::SetVertical( BOOL bVertical )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetVertical( bVertical );
+}
+
+BOOL EditEngine::IsVertical() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->IsVertical();
+}
+
+void EditEngine::SetFixedCellHeight( BOOL bUseFixedCellHeight )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetFixedCellHeight( bUseFixedCellHeight );
+}
+
+BOOL EditEngine::IsFixedCellHeight() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->IsFixedCellHeight();
+}
+
+void EditEngine::SetDefaultHorizontalTextDirection( EEHorizontalTextDirection eHTextDir )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetDefaultHorizontalTextDirection( eHTextDir );
+}
+
+EEHorizontalTextDirection EditEngine::GetDefaultHorizontalTextDirection() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetDefaultHorizontalTextDirection();
+}
+
+USHORT EditEngine::GetScriptType( const ESelection& rSelection ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ EditSelection aSel( pImpEditEngine->CreateSel( rSelection ) );
+ return pImpEditEngine->GetScriptType( aSel );
+}
+
+LanguageType EditEngine::GetLanguage( USHORT nPara, USHORT nPos ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ ContentNode* pNode = pImpEditEngine->GetEditDoc().SaveGetObject( nPara );
+ DBG_ASSERT( pNode, "GetLanguage - nPara is invalid!" );
+ return pNode ? pImpEditEngine->GetLanguage( EditPaM( pNode, nPos ) ) : LANGUAGE_DONTKNOW;
+}
+
+
+void EditEngine::TransliterateText( const ESelection& rSelection, sal_Int32 nTransliterationMode )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ pImpEditEngine->TransliterateText( pImpEditEngine->CreateSel( rSelection ), nTransliterationMode );
+}
+
+void EditEngine::SetAsianCompressionMode( USHORT n )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ pImpEditEngine->SetAsianCompressionMode( n );
+}
+
+USHORT EditEngine::GetAsianCompressionMode() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ return pImpEditEngine->GetAsianCompressionMode();
+}
+
+void EditEngine::SetKernAsianPunctuation( BOOL b )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ pImpEditEngine->SetKernAsianPunctuation( b );
+}
+
+BOOL EditEngine::IsKernAsianPunctuation() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ return pImpEditEngine->IsKernAsianPunctuation();
+}
+
+void EditEngine::SetAddExtLeading( BOOL b )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetAddExtLeading( b );
+}
+
+BOOL EditEngine::IsAddExtLeading() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->IsAddExtLeading();
+}
+
+void EditEngine::SetPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ SetPolygon( rPolyPolygon, 0L );
+}
+
+void EditEngine::SetPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon, const basegfx::B2DPolyPolygon* pLinePolyPolygon)
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ sal_Bool bSimple(sal_False);
+
+ if(pLinePolyPolygon && 1L == rPolyPolygon.count())
+ {
+ if(rPolyPolygon.getB2DPolygon(0L).isClosed())
+ {
+ // open polygon
+ bSimple = sal_True;
+ }
+ }
+
+ TextRanger* pRanger = new TextRanger( rPolyPolygon, pLinePolyPolygon, 30, 2, 2, bSimple, sal_True );
+ pImpEditEngine->SetTextRanger( pRanger );
+ pImpEditEngine->SetPaperSize( pRanger->GetBoundRect().GetSize() );
+}
+
+void EditEngine::ClearPolygon()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetTextRanger( 0 );
+}
+
+const PolyPolygon* EditEngine::GetPolygon()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetTextRanger() ?
+ &pImpEditEngine->GetTextRanger()->GetPolyPolygon() : NULL;
+}
+
+const Size& EditEngine::GetMinAutoPaperSize() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetMinAutoPaperSize();
+}
+
+void EditEngine::SetMinAutoPaperSize( const Size& rSz )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetMinAutoPaperSize( rSz );
+}
+
+const Size& EditEngine::GetMaxAutoPaperSize() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetMaxAutoPaperSize();
+}
+
+void EditEngine::SetMaxAutoPaperSize( const Size& rSz )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetMaxAutoPaperSize( rSz );
+}
+
+XubString EditEngine::GetText( LineEnd eEnd ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetEditDoc().GetText( eEnd );
+}
+
+XubString EditEngine::GetText( const ESelection& rESelection, const LineEnd eEnd ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ EditSelection aSel( pImpEditEngine->CreateSel( rESelection ) );
+ return pImpEditEngine->GetSelected( aSel, eEnd );
+}
+
+sal_uInt32 EditEngine::GetTextLen() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetEditDoc().GetTextLen();
+}
+
+sal_uInt16 EditEngine::GetParagraphCount() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->aEditDoc.Count();
+}
+
+sal_uInt16 EditEngine::GetLineCount( sal_uInt16 nParagraph ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ if ( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatDoc();
+ return pImpEditEngine->GetLineCount( nParagraph );
+}
+
+sal_uInt16 EditEngine::GetLineLen( sal_uInt16 nParagraph, sal_uInt16 nLine ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ if ( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatDoc();
+ return pImpEditEngine->GetLineLen( nParagraph, nLine );
+}
+
+void EditEngine::GetLineBoundaries( /*out*/USHORT &rStart, /*out*/USHORT &rEnd, USHORT nParagraph, USHORT nLine ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ if ( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatDoc();
+ return pImpEditEngine->GetLineBoundaries( rStart, rEnd, nParagraph, nLine );
+}
+
+USHORT EditEngine::GetLineNumberAtIndex( USHORT nPara, USHORT nIndex ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ if ( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatDoc();
+ return pImpEditEngine->GetLineNumberAtIndex( nPara, nIndex );
+}
+
+sal_uInt32 EditEngine::GetLineHeight( sal_uInt16 nParagraph, sal_uInt16 nLine )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ // Falls jemand mit einer leeren Engine ein GetLineHeight() macht.
+ if ( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatDoc();
+ return pImpEditEngine->GetLineHeight( nParagraph, nLine );
+}
+
+sal_uInt16 EditEngine::GetFirstLineOffset( sal_uInt16 nParagraph )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ if ( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatDoc();
+ ParaPortion* pPortion = pImpEditEngine->GetParaPortions().SaveGetObject( nParagraph );
+ return ( pPortion ? pPortion->GetFirstLineOffset() : 0 );
+}
+
+sal_uInt32 EditEngine::GetTextHeight( sal_uInt16 nParagraph ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ if ( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatDoc();
+
+ sal_uInt32 nHeight = pImpEditEngine->GetParaHeight( nParagraph );
+ return nHeight;
+}
+
+XubString EditEngine::GetWord( sal_uInt16 nPara, sal_uInt16 nIndex )
+{
+ ESelection aESel( nPara, nIndex, nPara, nIndex );
+ EditSelection aSel( pImpEditEngine->CreateSel( aESel ) );
+ aSel = pImpEditEngine->SelectWord( aSel );
+ return pImpEditEngine->GetSelected( aSel );
+}
+
+ESelection EditEngine::GetWord( const ESelection& rSelection, USHORT nWordType ) const
+{
+ // ImpEditEngine-Iteration-Methods should be const!
+ EditEngine* pE = (EditEngine*)this;
+
+ EditSelection aSel( pE->pImpEditEngine->CreateSel( rSelection ) );
+ aSel = pE->pImpEditEngine->SelectWord( aSel, nWordType );
+ return pE->pImpEditEngine->CreateESel( aSel );
+}
+
+ESelection EditEngine::WordLeft( const ESelection& rSelection, USHORT nWordType ) const
+{
+ // ImpEditEngine-Iteration-Methods should be const!
+ EditEngine* pE = (EditEngine*)this;
+
+ EditSelection aSel( pE->pImpEditEngine->CreateSel( rSelection ) );
+ aSel = pE->pImpEditEngine->WordLeft( aSel.Min(), nWordType );
+ return pE->pImpEditEngine->CreateESel( aSel );
+}
+
+ESelection EditEngine::WordRight( const ESelection& rSelection, USHORT nWordType ) const
+{
+ // ImpEditEngine-Iteration-Methods should be const!
+ EditEngine* pE = (EditEngine*)this;
+
+ EditSelection aSel( pE->pImpEditEngine->CreateSel( rSelection ) );
+ aSel = pE->pImpEditEngine->WordRight( aSel.Max(), nWordType );
+ return pE->pImpEditEngine->CreateESel( aSel );
+}
+
+ESelection EditEngine::CursorLeft( const ESelection& rSelection, USHORT nCharacterIteratorMode ) const
+{
+ // ImpEditEngine-Iteration-Methods should be const!
+ EditEngine* pE = (EditEngine*)this;
+
+ EditSelection aSel( pE->pImpEditEngine->CreateSel( rSelection ) );
+ aSel = pE->pImpEditEngine->CursorLeft( aSel.Min(), nCharacterIteratorMode );
+ return pE->pImpEditEngine->CreateESel( aSel );
+}
+
+ESelection EditEngine::CursorRight( const ESelection& rSelection, USHORT nCharacterIteratorMode ) const
+{
+ // ImpEditEngine-Iteration-Methods should be const!
+ EditEngine* pE = (EditEngine*)this;
+
+ EditSelection aSel( pE->pImpEditEngine->CreateSel( rSelection ) );
+ aSel = pE->pImpEditEngine->CursorRight( aSel.Max(), nCharacterIteratorMode );
+ return pE->pImpEditEngine->CreateESel( aSel );
+}
+
+sal_Bool EditEngine::PostKeyEvent( const KeyEvent& rKeyEvent, EditView* pEditView )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ DBG_CHKOBJ( pEditView, EditView, 0 );
+ DBG_ASSERT( pEditView, "Keine View - keine Kekse !" );
+
+ sal_Bool bDone = sal_True;
+
+ sal_Bool bModified = sal_False;
+ sal_Bool bMoved = sal_False;
+ sal_Bool bAllowIdle = sal_True;
+ sal_Bool bReadOnly = pEditView->IsReadOnly();
+
+ USHORT nNewCursorFlags = 0;
+ BOOL bSetCursorFlags = TRUE;
+
+ EditSelection aCurSel( pEditView->pImpEditView->GetEditSelection() );
+ DBG_ASSERT( !aCurSel.IsInvalid(), "Blinde Selection in EditEngine::PostKeyEvent" );
+
+ String aAutoText( pImpEditEngine->GetAutoCompleteText() );
+ if ( pImpEditEngine->GetAutoCompleteText().Len() )
+ pImpEditEngine->SetAutoCompleteText( String(), sal_True );
+
+ sal_uInt16 nCode = rKeyEvent.GetKeyCode().GetCode();
+ KeyFuncType eFunc = rKeyEvent.GetKeyCode().GetFunction();
+ if ( eFunc != KEYFUNC_DONTKNOW )
+ {
+ switch ( eFunc )
+ {
+ case KEYFUNC_UNDO:
+ {
+ if ( !bReadOnly )
+ pEditView->Undo();
+ return sal_True;
+ }
+ // break;
+ case KEYFUNC_REDO:
+ {
+ if ( !bReadOnly )
+ pEditView->Redo();
+ return sal_True;
+ }
+ // break;
+
+ default: // wird dann evtl. unten bearbeitet.
+ eFunc = KEYFUNC_DONTKNOW;
+ }
+ }
+
+ pImpEditEngine->EnterBlockNotifications();
+
+ if ( GetNotifyHdl().IsSet() )
+ {
+ EENotify aNotify( EE_NOTIFY_INPUT_START );
+ aNotify.pEditEngine = this;
+ pImpEditEngine->CallNotify( aNotify );
+ }
+
+ if ( eFunc == KEYFUNC_DONTKNOW )
+ {
+ switch ( nCode )
+ {
+ #if defined( DBG_UTIL ) || (OSL_DEBUG_LEVEL > 1)
+ case KEY_F1:
+ {
+ if ( rKeyEvent.GetKeyCode().IsMod1() && rKeyEvent.GetKeyCode().IsMod2() )
+ {
+ USHORT nParas = GetParagraphCount();
+ Point aPos;
+ Point aViewStart( pEditView->GetOutputArea().TopLeft() );
+ long n20 = 40 * pImpEditEngine->nOnePixelInRef;
+ for ( USHORT n = 0; n < nParas; n++ )
+ {
+ long nH = GetTextHeight( n );
+ Point P1( aViewStart.X() + n20 + n20*(n%2), aViewStart.Y() + aPos.Y() );
+ Point P2( P1 );
+ P2.X() += n20;
+ P2.Y() += nH;
+ pEditView->GetWindow()->SetLineColor();
+ pEditView->GetWindow()->SetFillColor( Color( (n%2) ? COL_YELLOW : COL_LIGHTGREEN ) );
+ pEditView->GetWindow()->DrawRect( Rectangle( P1, P2 ) );
+ aPos.Y() += nH;
+ }
+ }
+ bDone = FALSE;
+ }
+ break;
+ case KEY_F11:
+ {
+ if ( rKeyEvent.GetKeyCode().IsMod1() && rKeyEvent.GetKeyCode().IsMod2() )
+ {
+ bDebugPaint = !bDebugPaint;
+ ByteString aInfo( "DebugPaint: " );
+ aInfo += bDebugPaint ? "On" : "Off";
+ InfoBox( NULL, String( aInfo, RTL_TEXTENCODING_ASCII_US ) ).Execute();
+ }
+ bDone = FALSE;
+ }
+ break;
+ case KEY_F12:
+ {
+ if ( rKeyEvent.GetKeyCode().IsMod1() && rKeyEvent.GetKeyCode().IsMod2() )
+ {
+ EditDbg::ShowEditEngineData( this );
+ #ifdef EDIT_PRINTER_LOG
+ SvFileStream aLog( "d:\\editprn.log", STREAM_WRITE );
+ aLog.Seek( STREAM_SEEK_TO_END );
+ aLog << ' ' << endl << "Debug: ";
+ aLog << GetText( "\n\r" ).GetStr();
+ aLog << endl << endl;
+ aLog << "Ref-Device: " << String( (sal_uInt32)GetRefDevice() ).GetStr() << " Type=" << String( (sal_uInt16)GetRefDevice()->GetOutDevType() ).GetStr() << ", MapX=" << String( GetRefDevice()->GetMapMode().GetScaleX().GetNumerator() ).GetStr() << "/" << String( GetRefDevice()->GetMapMode().GetScaleX().GetDenominator() ).GetStr() <<endl;
+ aLog << "Paper-Width: " << String( GetPaperSize().Width() ).GetStr() << ",\tCalculated: " << String( CalcTextWidth() ).GetStr() << endl;
+ aLog << "Paper-Height: " << String( GetPaperSize().Height() ).GetStr() << ",\tCalculated: " << String( GetTextHeight() ).GetStr() << endl;
+ aLog << endl;
+ #endif
+ }
+ bDone = FALSE;
+ }
+ break;
+ #endif
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ case KEY_HOME:
+ case KEY_END:
+ case KEY_PAGEUP:
+ case KEY_PAGEDOWN:
+ case com::sun::star::awt::Key::MOVE_WORD_FORWARD:
+ case com::sun::star::awt::Key::SELECT_WORD_FORWARD:
+ case com::sun::star::awt::Key::MOVE_WORD_BACKWARD:
+ case com::sun::star::awt::Key::SELECT_WORD_BACKWARD:
+ case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE:
+ case com::sun::star::awt::Key::MOVE_TO_END_OF_LINE:
+ case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE:
+ case com::sun::star::awt::Key::SELECT_TO_END_OF_LINE:
+ case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH:
+ case com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH:
+ case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH:
+ case com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH:
+ case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT:
+ case com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT:
+ case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT:
+ case com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT:
+ {
+ if ( !rKeyEvent.GetKeyCode().IsMod2() || ( nCode == KEY_LEFT ) || ( nCode == KEY_RIGHT ) )
+ {
+ if ( pImpEditEngine->DoVisualCursorTraveling( aCurSel.Max().GetNode() ) && ( ( nCode == KEY_LEFT ) || ( nCode == KEY_RIGHT ) /* || ( nCode == KEY_HOME ) || ( nCode == KEY_END ) */ ) )
+ bSetCursorFlags = FALSE; // Will be manipulated within visual cursor move
+
+ aCurSel = pImpEditEngine->MoveCursor( rKeyEvent, pEditView );
+
+ if ( aCurSel.HasRange() ) {
+ Reference<com::sun::star::datatransfer::clipboard::XClipboard> aSelection(pEditView->GetWindow()->GetPrimarySelection());
+ pEditView->pImpEditView->CutCopy( aSelection, FALSE );
+ }
+
+ bMoved = sal_True;
+ if ( nCode == KEY_HOME )
+ nNewCursorFlags |= GETCRSR_STARTOFLINE;
+ else if ( nCode == KEY_END )
+ nNewCursorFlags |= GETCRSR_ENDOFLINE;
+
+ }
+#if OSL_DEBUG_LEVEL > 1
+ GetLanguage( pImpEditEngine->GetEditDoc().GetPos( aCurSel.Max().GetNode() ), aCurSel.Max().GetIndex() );
+#endif
+ }
+ break;
+ case KEY_BACKSPACE:
+ case KEY_DELETE:
+ case com::sun::star::awt::Key::DELETE_WORD_BACKWARD:
+ case com::sun::star::awt::Key::DELETE_WORD_FORWARD:
+ case com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_PARAGRAPH:
+ case com::sun::star::awt::Key::DELETE_TO_END_OF_PARAGRAPH:
+ {
+ if ( !bReadOnly && !rKeyEvent.GetKeyCode().IsMod2() )
+ {
+ // check if we are behind a bullet and using the backspace key
+ ContentNode *pNode = aCurSel.Min().GetNode();
+ const SvxNumberFormat *pFmt = pImpEditEngine->GetNumberFormat( pNode );
+ if (pFmt && nCode == KEY_BACKSPACE &&
+ !aCurSel.HasRange() && aCurSel.Min().GetIndex() == 0)
+ {
+ // if the bullet is still visible just do not paint it from
+ // now on and that will be all. Otherwise continue as usual.
+ // ...
+
+ USHORT nPara = pImpEditEngine->GetEditDoc().GetPos( pNode );
+ SfxBoolItem aBulletState( (const SfxBoolItem&) pImpEditEngine->GetParaAttrib( nPara, EE_PARA_BULLETSTATE ) );
+ bool bBulletIsVisible = aBulletState.GetValue() ? true : false;
+
+ // just toggling EE_PARA_BULLETSTATE should be fine for both cases...
+ aBulletState.SetValue( !bBulletIsVisible );
+ SfxItemSet aSet( pImpEditEngine->GetParaAttribs( nPara ) );
+ aSet.Put( aBulletState );
+ pImpEditEngine->SetParaAttribs( nPara, aSet );
+
+ // have this and the following paragraphs formatted and repainted.
+ // (not painting a numbering in the list may cause the following
+ // numberings to have different numbers than before and thus the
+ // length may have changed as well )
+ pImpEditEngine->FormatAndUpdate( pImpEditEngine->GetActiveView() );
+
+ if (bBulletIsVisible) // bullet just turned invisible...
+ break;
+ }
+
+ BYTE nDel = 0, nMode = 0;
+ switch( nCode )
+ {
+ case com::sun::star::awt::Key::DELETE_WORD_BACKWARD:
+ nMode = DELMODE_RESTOFWORD;
+ nDel = DEL_LEFT;
+ break;
+ case com::sun::star::awt::Key::DELETE_WORD_FORWARD:
+ nMode = DELMODE_RESTOFWORD;
+ nDel = DEL_RIGHT;
+ break;
+ case com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_PARAGRAPH:
+ nMode = DELMODE_RESTOFCONTENT;
+ nDel = DEL_LEFT;
+ break;
+ case com::sun::star::awt::Key::DELETE_TO_END_OF_PARAGRAPH:
+ nMode = DELMODE_RESTOFCONTENT;
+ nDel = DEL_RIGHT;
+ break;
+ default:
+ nDel = ( nCode == KEY_DELETE ) ? DEL_RIGHT : DEL_LEFT;
+ nMode = rKeyEvent.GetKeyCode().IsMod1() ? DELMODE_RESTOFWORD : DELMODE_SIMPLE;
+ if ( ( nMode == DELMODE_RESTOFWORD ) && rKeyEvent.GetKeyCode().IsShift() )
+ nMode = DELMODE_RESTOFCONTENT;
+ break;
+ }
+
+ pEditView->pImpEditView->DrawSelection();
+ pImpEditEngine->UndoActionStart( EDITUNDO_DELETE );
+ aCurSel = pImpEditEngine->DeleteLeftOrRight( aCurSel, nDel, nMode );
+ pImpEditEngine->UndoActionEnd( EDITUNDO_DELETE );
+ bModified = sal_True;
+ bAllowIdle = sal_False;
+ }
+ }
+ break;
+ case KEY_TAB:
+ {
+ if ( !bReadOnly && !rKeyEvent.GetKeyCode().IsMod1() && !rKeyEvent.GetKeyCode().IsMod2() )
+ {
+ sal_Bool bShift = rKeyEvent.GetKeyCode().IsShift();
+ if ( pImpEditEngine->GetStatus().DoTabIndenting() &&
+ ( aCurSel.Min().GetNode() != aCurSel.Max().GetNode() ) )
+ {
+ pImpEditEngine->IndentBlock( pEditView, !bShift );
+ }
+ else if ( !bShift )
+ {
+ sal_Bool bSel = pEditView->HasSelection();
+ if ( bSel )
+ pImpEditEngine->UndoActionStart( EDITUNDO_INSERT );
+ if ( pImpEditEngine->GetStatus().DoAutoCorrect() )
+ aCurSel = pImpEditEngine->AutoCorrect( aCurSel, 0, !pEditView->IsInsertMode() );
+ aCurSel = pImpEditEngine->InsertTab( aCurSel );
+ if ( bSel )
+ pImpEditEngine->UndoActionEnd( EDITUNDO_INSERT );
+ bModified = sal_True;
+ }
+ }
+ else
+ bDone = sal_False;
+ }
+ break;
+ case KEY_RETURN:
+ {
+ if ( !bReadOnly )
+ {
+ pEditView->pImpEditView->DrawSelection();
+ if ( !rKeyEvent.GetKeyCode().IsMod1() && !rKeyEvent.GetKeyCode().IsMod2() )
+ {
+ pImpEditEngine->UndoActionStart( EDITUNDO_INSERT );
+ if ( rKeyEvent.GetKeyCode().IsShift() )
+ {
+ aCurSel = pImpEditEngine->AutoCorrect( aCurSel, 0, !pEditView->IsInsertMode() );
+ aCurSel = pImpEditEngine->InsertLineBreak( aCurSel );
+ }
+ else
+ {
+ if ( !aAutoText.Len() )
+ {
+ if ( pImpEditEngine->GetStatus().DoAutoCorrect() )
+ aCurSel = pImpEditEngine->AutoCorrect( aCurSel, 0, !pEditView->IsInsertMode() );
+ aCurSel = pImpEditEngine->InsertParaBreak( aCurSel );
+ }
+ else
+ {
+ DBG_ASSERT( !aCurSel.HasRange(), "Selektion bei Complete?!" );
+ EditPaM aStart( pImpEditEngine->WordLeft( aCurSel.Max() ) );
+ aCurSel = pImpEditEngine->InsertText(
+ EditSelection( aStart, aCurSel.Max() ), aAutoText );
+ pImpEditEngine->SetAutoCompleteText( String(), sal_True );
+ }
+ }
+ pImpEditEngine->UndoActionEnd( EDITUNDO_INSERT );
+ bModified = sal_True;
+ }
+ }
+ }
+ break;
+ case KEY_INSERT:
+ {
+ if ( !rKeyEvent.GetKeyCode().IsMod1() && !rKeyEvent.GetKeyCode().IsMod2() )
+ pEditView->SetInsertMode( !pEditView->IsInsertMode() );
+ }
+ break;
+ default:
+ {
+ #if (OSL_DEBUG_LEVEL > 1) && defined(DBG_UTIL)
+ if ( ( nCode == KEY_W ) && rKeyEvent.GetKeyCode().IsMod1() && rKeyEvent.GetKeyCode().IsMod2() )
+ {
+ SfxItemSet aAttribs = pEditView->GetAttribs();
+ const SvxFrameDirectionItem& rCurrentWritingMode = (const SvxFrameDirectionItem&)aAttribs.Get( EE_PARA_WRITINGDIR );
+ SvxFrameDirectionItem aNewItem( FRMDIR_HORI_LEFT_TOP, EE_PARA_WRITINGDIR );
+ if ( rCurrentWritingMode.GetValue() != FRMDIR_HORI_RIGHT_TOP )
+ aNewItem.SetValue( FRMDIR_HORI_RIGHT_TOP );
+ aAttribs.Put( aNewItem );
+ pEditView->SetAttribs( aAttribs );
+ }
+ #endif
+ if ( !bReadOnly && IsSimpleCharInput( rKeyEvent ) )
+ {
+ xub_Unicode nCharCode = rKeyEvent.GetCharCode();
+ pEditView->pImpEditView->DrawSelection();
+ // Autokorrektur ?
+ if ( ( pImpEditEngine->GetStatus().DoAutoCorrect() ) &&
+ ( ( nCharCode == ' ' ) || ( nCharCode == '*' ) ||
+ ( nCharCode == '\"' ) || ( nCharCode == '\'' ) ||
+ ( nCharCode == '_' ) ))
+ {
+ aCurSel = pImpEditEngine->AutoCorrect( aCurSel, nCharCode, !pEditView->IsInsertMode() );
+ }
+ else
+ {
+ aCurSel = pImpEditEngine->InsertText( (const EditSelection&)aCurSel, nCharCode, !pEditView->IsInsertMode(), sal_True );
+ }
+ // AutoComplete ???
+ if ( pImpEditEngine->GetStatus().DoAutoComplete() && ( nCharCode != ' ' ) )
+ {
+ // Aber nur wenn Wort-Ende...
+ sal_uInt16 nIndex = aCurSel.Max().GetIndex();
+ if ( ( nIndex >= aCurSel.Max().GetNode()->Len() ) ||
+ ( pImpEditEngine->aWordDelimiters.Search( aCurSel.Max().GetNode()->GetChar( nIndex ) ) != STRING_NOTFOUND ) )
+ {
+ EditPaM aStart( pImpEditEngine->WordLeft( aCurSel.Max() ) );
+ String aWord = pImpEditEngine->GetSelected( EditSelection( aStart, aCurSel.Max() ) );
+ if ( aWord.Len() >= 3 )
+ {
+ String aComplete;
+
+ LanguageType eLang = pImpEditEngine->GetLanguage( EditPaM( aStart.GetNode(), aStart.GetIndex()+1));
+ lang::Locale aLocale( MsLangId::convertLanguageToLocale( eLang));
+
+ if (!pImpEditEngine->xLocaleDataWrapper.isInitialized())
+ pImpEditEngine->xLocaleDataWrapper.init( SvtSysLocale().GetLocaleData().getServiceFactory(), aLocale, eLang);
+ else
+ pImpEditEngine->xLocaleDataWrapper.changeLocale( aLocale, eLang);
+
+ if (!pImpEditEngine->xTransliterationWrapper.isInitialized())
+ pImpEditEngine->xTransliterationWrapper.init( SvtSysLocale().GetLocaleData().getServiceFactory(), eLang, i18n::TransliterationModules_IGNORE_CASE);
+ else
+ pImpEditEngine->xTransliterationWrapper.changeLocale( eLang);
+
+ const ::utl::TransliterationWrapper* pTransliteration = pImpEditEngine->xTransliterationWrapper.get();
+ Sequence< i18n::CalendarItem > xItem = pImpEditEngine->xLocaleDataWrapper->getDefaultCalendarDays();
+ sal_Int32 nCount = xItem.getLength();
+ const i18n::CalendarItem* pArr = xItem.getArray();
+ for( sal_Int32 n = 0; n <= nCount; ++n )
+ {
+ const ::rtl::OUString& rDay = pArr[n].FullName;
+ if( pTransliteration->isMatch( aWord, rDay) )
+ {
+ aComplete = rDay;
+ break;
+ }
+ }
+
+ if ( !aComplete.Len() )
+ {
+ xItem = pImpEditEngine->xLocaleDataWrapper->getDefaultCalendarMonths();
+ sal_Int32 nMonthCount = xItem.getLength();
+ const i18n::CalendarItem* pMonthArr = xItem.getArray();
+ for( sal_Int32 n = 0; n <= nMonthCount; ++n )
+ {
+ const ::rtl::OUString& rMon = pMonthArr[n].FullName;
+ if( pTransliteration->isMatch( aWord, rMon) )
+ {
+ aComplete = rMon;
+ break;
+ }
+ }
+ }
+
+ if( aComplete.Len() && ( ( aWord.Len() + 1 ) < aComplete.Len() ) )
+ {
+ pImpEditEngine->SetAutoCompleteText( aComplete, sal_False );
+ Point aPos = pImpEditEngine->PaMtoEditCursor( aCurSel.Max() ).TopLeft();
+ aPos = pEditView->pImpEditView->GetWindowPos( aPos );
+ aPos = pEditView->pImpEditView->GetWindow()->LogicToPixel( aPos );
+ aPos = pEditView->GetWindow()->OutputToScreenPixel( aPos );
+ aPos.Y() -= 3;
+ Help::ShowQuickHelp( pEditView->GetWindow(), Rectangle( aPos, Size( 1, 1 ) ), aComplete, QUICKHELP_BOTTOM|QUICKHELP_LEFT );
+ }
+ }
+ }
+ }
+ bModified = sal_True;
+ }
+ else
+ bDone = sal_False;
+ }
+ }
+ }
+
+ pEditView->pImpEditView->SetEditSelection( aCurSel );
+ pImpEditEngine->UpdateSelections();
+
+ if ( ( !IsVertical() && ( nCode != KEY_UP ) && ( nCode != KEY_DOWN ) ) ||
+ ( IsVertical() && ( nCode != KEY_LEFT ) && ( nCode != KEY_RIGHT ) ))
+ {
+ pEditView->pImpEditView->nTravelXPos = TRAVEL_X_DONTKNOW;
+ }
+
+ if ( /* ( nCode != KEY_HOME ) && ( nCode != KEY_END ) && */
+ ( !IsVertical() && ( nCode != KEY_LEFT ) && ( nCode != KEY_RIGHT ) ) ||
+ ( IsVertical() && ( nCode != KEY_UP ) && ( nCode != KEY_DOWN ) ))
+ {
+ pEditView->pImpEditView->SetCursorBidiLevel( 0xFFFF );
+ }
+
+ if ( bSetCursorFlags )
+ pEditView->pImpEditView->nExtraCursorFlags = nNewCursorFlags;
+
+ if ( bModified )
+ {
+ DBG_ASSERT( !bReadOnly, "ReadOnly but modified???" );
+ // Idle-Formatter nur, wenn AnyInput.
+ if ( bAllowIdle && pImpEditEngine->GetStatus().UseIdleFormatter()
+ && Application::AnyInput( INPUT_KEYBOARD) )
+ pImpEditEngine->IdleFormatAndUpdate( pEditView );
+ else
+ pImpEditEngine->FormatAndUpdate( pEditView );
+ }
+ else if ( bMoved )
+ {
+ sal_Bool bGotoCursor = pEditView->pImpEditView->DoAutoScroll();
+ pEditView->pImpEditView->ShowCursor( bGotoCursor, sal_True );
+ pImpEditEngine->CallStatusHdl();
+ }
+
+ if ( GetNotifyHdl().IsSet() )
+ {
+ EENotify aNotify( EE_NOTIFY_INPUT_END );
+ aNotify.pEditEngine = this;
+ pImpEditEngine->CallNotify( aNotify );
+ }
+
+ pImpEditEngine->LeaveBlockNotifications();
+
+ return bDone;
+}
+
+sal_uInt32 EditEngine::GetTextHeight() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ if ( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatDoc();
+
+ sal_uInt32 nHeight = !IsVertical() ? pImpEditEngine->GetTextHeight() : pImpEditEngine->CalcTextWidth( TRUE );
+ return nHeight;
+}
+
+sal_uInt32 EditEngine::CalcTextWidth()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ if ( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatDoc();
+
+ sal_uInt32 nWidth = !IsVertical() ? pImpEditEngine->CalcTextWidth( TRUE ) : pImpEditEngine->GetTextHeight();
+ return nWidth;
+}
+
+void EditEngine::SetUpdateMode( sal_Bool bUpdate )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetUpdateMode( bUpdate );
+ if ( pImpEditEngine->pActiveView )
+ pImpEditEngine->pActiveView->ShowCursor( sal_False, sal_False );
+}
+
+sal_Bool EditEngine::GetUpdateMode() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetUpdateMode();
+}
+
+void EditEngine::Clear()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->Clear();
+}
+
+void EditEngine::SetText( const XubString& rText )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetText( rText );
+ if ( rText.Len() )
+ pImpEditEngine->FormatAndUpdate();
+}
+
+ULONG EditEngine::Read( SvStream& rInput, const String& rBaseURL, EETextFormat eFormat, SvKeyValueIterator* pHTTPHeaderAttrs /* = NULL */ )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ sal_Bool bUndoEnabled = pImpEditEngine->IsUndoEnabled();
+ pImpEditEngine->EnableUndo( sal_False );
+ pImpEditEngine->SetText( XubString() );
+ EditPaM aPaM( pImpEditEngine->GetEditDoc().GetStartPaM() );
+ pImpEditEngine->Read( rInput, rBaseURL, eFormat, EditSelection( aPaM, aPaM ), pHTTPHeaderAttrs );
+ pImpEditEngine->EnableUndo( bUndoEnabled );
+ return rInput.GetError();
+}
+
+ULONG EditEngine::Write( SvStream& rOutput, EETextFormat eFormat )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ EditPaM aStartPaM( pImpEditEngine->GetEditDoc().GetStartPaM() );
+ EditPaM aEndPaM( pImpEditEngine->GetEditDoc().GetEndPaM() );
+ pImpEditEngine->Write( rOutput, eFormat, EditSelection( aStartPaM, aEndPaM ) );
+ return rOutput.GetError();
+}
+
+EditTextObject* EditEngine::CreateTextObject()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->CreateTextObject();
+}
+
+EditTextObject* EditEngine::CreateTextObject( const ESelection& rESelection )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ EditSelection aSel( pImpEditEngine->CreateSel( rESelection ) );
+ return pImpEditEngine->CreateTextObject( aSel );
+}
+
+void EditEngine::SetText( const EditTextObject& rTextObject )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->EnterBlockNotifications();
+ pImpEditEngine->SetText( rTextObject );
+ pImpEditEngine->FormatAndUpdate();
+ pImpEditEngine->LeaveBlockNotifications();
+}
+
+void EditEngine::ShowParagraph( sal_uInt16 nParagraph, sal_Bool bShow )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->ShowParagraph( nParagraph, bShow );
+}
+
+sal_Bool EditEngine::IsParagraphVisible( sal_uInt16 nParagraph )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->IsParagraphVisible( nParagraph );
+}
+
+void EditEngine::SetNotifyHdl( const Link& rLink )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetNotifyHdl( rLink );
+}
+
+Link EditEngine::GetNotifyHdl() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetNotifyHdl();
+}
+
+void EditEngine::SetStatusEventHdl( const Link& rLink )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetStatusEventHdl( rLink );
+}
+
+Link EditEngine::GetStatusEventHdl() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetStatusEventHdl();
+}
+
+void EditEngine::SetImportHdl( const Link& rLink )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->aImportHdl = rLink;
+}
+
+Link EditEngine::GetImportHdl() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->aImportHdl;
+}
+
+void EditEngine::SetBeginMovingParagraphsHdl( const Link& rLink )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->aBeginMovingParagraphsHdl = rLink;
+}
+
+void EditEngine::SetEndMovingParagraphsHdl( const Link& rLink )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->aEndMovingParagraphsHdl = rLink;
+}
+
+void EditEngine::SetBeginPasteOrDropHdl( const Link& rLink )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ pImpEditEngine->aBeginPasteOrDropHdl = rLink;
+}
+
+void EditEngine::SetEndPasteOrDropHdl( const Link& rLink )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->aEndPasteOrDropHdl = rLink;
+}
+
+EditTextObject* EditEngine::CreateTextObject( sal_uInt16 nPara, sal_uInt16 nParas )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ DBG_ASSERT( nPara < pImpEditEngine->GetEditDoc().Count(), "CreateTextObject: Startpara out of Range" );
+ DBG_ASSERT( nPara+nParas-1 < pImpEditEngine->GetEditDoc().Count(), "CreateTextObject: Endpara out of Range" );
+
+ ContentNode* pStartNode = pImpEditEngine->GetEditDoc().SaveGetObject( nPara );
+ ContentNode* pEndNode = pImpEditEngine->GetEditDoc().SaveGetObject( nPara+nParas-1 );
+ DBG_ASSERT( pStartNode, "Start-Absatz existiert nicht: CreateTextObject" );
+ DBG_ASSERT( pEndNode, "End-Absatz existiert nicht: CreateTextObject" );
+
+ if ( pStartNode && pEndNode )
+ {
+ EditSelection aTmpSel;
+ aTmpSel.Min() = EditPaM( pStartNode, 0 );
+ aTmpSel.Max() = EditPaM( pEndNode, pEndNode->Len() );
+ return pImpEditEngine->CreateTextObject( aTmpSel );
+ }
+ return 0;
+}
+
+void EditEngine::RemoveParagraph( sal_uInt16 nPara )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ DBG_ASSERT( pImpEditEngine->GetEditDoc().Count() > 1, "Der erste Absatz darf nicht geloescht werden!" );
+ if( pImpEditEngine->GetEditDoc().Count() <= 1 )
+ return;
+
+ ContentNode* pNode = pImpEditEngine->GetEditDoc().SaveGetObject( nPara );
+ ParaPortion* pPortion = pImpEditEngine->GetParaPortions().SaveGetObject( nPara );
+ DBG_ASSERT( pPortion && pNode, "Absatz nicht gefunden: RemoveParagraph" );
+ if ( pNode && pPortion )
+ {
+ // Keine Undokappselung noetig.
+ pImpEditEngine->ImpRemoveParagraph( nPara );
+ pImpEditEngine->InvalidateFromParagraph( nPara );
+ pImpEditEngine->UpdateSelections();
+ pImpEditEngine->FormatAndUpdate();
+ }
+}
+
+sal_uInt16 EditEngine::GetTextLen( sal_uInt16 nPara ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ ContentNode* pNode = pImpEditEngine->GetEditDoc().SaveGetObject( nPara );
+ DBG_ASSERT( pNode, "Absatz nicht gefunden: GetTextLen" );
+ if ( pNode )
+ return pNode->Len();
+ return 0;
+}
+
+XubString EditEngine::GetText( sal_uInt16 nPara ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ XubString aStr;
+ if ( nPara < pImpEditEngine->GetEditDoc().Count() )
+ aStr = pImpEditEngine->GetEditDoc().GetParaAsString( nPara );
+ return aStr;
+}
+
+void EditEngine::SetModifyHdl( const Link& rLink )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetModifyHdl( rLink );
+}
+
+Link EditEngine::GetModifyHdl() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetModifyHdl();
+}
+
+
+void EditEngine::ClearModifyFlag()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetModifyFlag( sal_False );
+}
+
+void EditEngine::SetModified()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetModifyFlag( sal_True );
+}
+
+sal_Bool EditEngine::IsModified() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->IsModified();
+}
+
+sal_Bool EditEngine::IsInSelectionMode() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return ( pImpEditEngine->IsInSelectionMode() ||
+ pImpEditEngine->GetSelEngine().IsInSelection() );
+}
+
+void EditEngine::StopSelectionMode()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->StopSelectionMode();
+}
+
+void EditEngine::InsertParagraph( sal_uInt16 nPara, const EditTextObject& rTxtObj )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ if ( nPara > GetParagraphCount() )
+ {
+ DBG_ASSERTWARNING( nPara == USHRT_MAX, "AbsatzNr zu Gro???, aber nicht LIST_APPEND! " );
+ nPara = GetParagraphCount();
+ }
+
+ pImpEditEngine->UndoActionStart( EDITUNDO_INSERT );
+
+ // Keine Undoklammerung noetig.
+ EditPaM aPaM( pImpEditEngine->InsertParagraph( nPara ) );
+ // Bei einem InsertParagraph von aussen sollen keine Harten
+ // Attribute uebernommen werden !
+ pImpEditEngine->RemoveCharAttribs( nPara );
+ pImpEditEngine->InsertText( rTxtObj, EditSelection( aPaM, aPaM ) );
+
+ pImpEditEngine->UndoActionEnd( EDITUNDO_INSERT );
+
+ pImpEditEngine->FormatAndUpdate();
+}
+
+void EditEngine::InsertParagraph( sal_uInt16 nPara, const XubString& rTxt )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ if ( nPara > GetParagraphCount() )
+ {
+ DBG_ASSERTWARNING( nPara == USHRT_MAX, "AbsatzNr zu Gro???, aber nicht LIST_APPEND! " );
+ nPara = GetParagraphCount();
+ }
+
+ pImpEditEngine->UndoActionStart( EDITUNDO_INSERT );
+ EditPaM aPaM( pImpEditEngine->InsertParagraph( nPara ) );
+ // Bei einem InsertParagraph von aussen sollen keine Harten
+ // Attribute uebernommen werden !
+ pImpEditEngine->RemoveCharAttribs( nPara );
+ pImpEditEngine->UndoActionEnd( EDITUNDO_INSERT );
+ pImpEditEngine->ImpInsertText( EditSelection( aPaM, aPaM ), rTxt );
+ pImpEditEngine->FormatAndUpdate();
+}
+
+void EditEngine::SetText( sal_uInt16 nPara, const EditTextObject& rTxtObj )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ EditSelection* pSel = pImpEditEngine->SelectParagraph( nPara );
+ if ( pSel )
+ {
+ pImpEditEngine->UndoActionStart( EDITUNDO_INSERT );
+ pImpEditEngine->InsertText( rTxtObj, *pSel );
+ pImpEditEngine->UndoActionEnd( EDITUNDO_INSERT );
+ pImpEditEngine->FormatAndUpdate();
+ delete pSel;
+ }
+}
+
+void EditEngine::SetText( sal_uInt16 nPara, const XubString& rTxt )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ EditSelection* pSel = pImpEditEngine->SelectParagraph( nPara );
+ if ( pSel )
+ {
+ pImpEditEngine->UndoActionStart( EDITUNDO_INSERT );
+ pImpEditEngine->ImpInsertText( *pSel, rTxt );
+ pImpEditEngine->UndoActionEnd( EDITUNDO_INSERT );
+ pImpEditEngine->FormatAndUpdate();
+ delete pSel;
+ }
+}
+
+void EditEngine::SetParaAttribs( sal_uInt16 nPara, const SfxItemSet& rSet )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ // Keine Undoklammerung noetig.
+ pImpEditEngine->SetParaAttribs( nPara, rSet );
+ pImpEditEngine->FormatAndUpdate();
+}
+
+const SfxItemSet& EditEngine::GetParaAttribs( sal_uInt16 nPara ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetParaAttribs( nPara );
+}
+
+sal_Bool EditEngine::HasParaAttrib( sal_uInt16 nPara, sal_uInt16 nWhich ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->HasParaAttrib( nPara, nWhich );
+}
+
+const SfxPoolItem& EditEngine::GetParaAttrib( sal_uInt16 nPara, sal_uInt16 nWhich )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetParaAttrib( nPara, nWhich );
+}
+
+void EditEngine::GetCharAttribs( sal_uInt16 nPara, EECharAttribArray& rLst ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->GetCharAttribs( nPara, rLst );
+}
+
+SfxItemSet EditEngine::GetAttribs( const ESelection& rSel, BOOL bOnlyHardAttrib )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ EditSelection aSel( pImpEditEngine->
+ ConvertSelection( rSel.nStartPara, rSel.nStartPos, rSel.nEndPara, rSel.nEndPos ) );
+ return pImpEditEngine->GetAttribs( aSel, bOnlyHardAttrib );
+}
+
+SfxItemSet EditEngine::GetAttribs( USHORT nPara, USHORT nStart, USHORT nEnd, sal_uInt8 nFlags ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetAttribs( nPara, nStart, nEnd, nFlags );
+}
+
+void EditEngine::RemoveAttribs( const ESelection& rSelection, sal_Bool bRemoveParaAttribs, sal_uInt16 nWhich )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ pImpEditEngine->UndoActionStart( EDITUNDO_RESETATTRIBS );
+ EditSelection aSel( pImpEditEngine->ConvertSelection( rSelection.nStartPara, rSelection.nStartPos, rSelection.nEndPara, rSelection.nEndPos ) );
+ pImpEditEngine->RemoveCharAttribs( aSel, bRemoveParaAttribs, nWhich );
+ pImpEditEngine->UndoActionEnd( EDITUNDO_RESETATTRIBS );
+ pImpEditEngine->FormatAndUpdate();
+}
+
+// MT: Can be removed after 6.x?
+Font EditEngine::GetStandardFont( sal_uInt16 nPara )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return GetStandardSvxFont( nPara );
+}
+
+SvxFont EditEngine::GetStandardSvxFont( sal_uInt16 nPara )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ ContentNode* pNode = pImpEditEngine->GetEditDoc().SaveGetObject( nPara );
+ return pNode->GetCharAttribs().GetDefFont();
+}
+
+void EditEngine::StripPortions()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ VirtualDevice aTmpDev;
+ Rectangle aBigRec( Point( 0, 0 ), Size( 0x7FFFFFFF, 0x7FFFFFFF ) );
+ if ( IsVertical() )
+ {
+ aBigRec.Right() = 0;
+ aBigRec.Left() = -0x7FFFFFFF;
+ }
+ pImpEditEngine->Paint( &aTmpDev, aBigRec, Point(), sal_True );
+}
+
+void EditEngine::GetPortions( sal_uInt16 nPara, SvUShorts& rList )
+{
+ if ( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatFullDoc();
+
+ ParaPortion* pParaPortion = pImpEditEngine->GetParaPortions().SaveGetObject( nPara );
+ if ( pParaPortion )
+ {
+ sal_uInt16 nEnd = 0;
+ sal_uInt16 nTextPortions = pParaPortion->GetTextPortions().Count();
+ for ( sal_uInt16 n = 0; n < nTextPortions; n++ )
+ {
+ nEnd = nEnd + pParaPortion->GetTextPortions()[n]->GetLen();
+ rList.Insert( nEnd, rList.Count() );
+ }
+ }
+}
+
+void EditEngine::SetFlatMode( sal_Bool bFlat)
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetFlatMode( bFlat );
+}
+
+sal_Bool EditEngine::IsFlatMode() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return !( pImpEditEngine->aStatus.UseCharAttribs() );
+}
+
+void EditEngine::SetControlWord( sal_uInt32 nWord )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ if ( nWord != pImpEditEngine->aStatus.GetControlWord() )
+ {
+ sal_uInt32 nPrev = pImpEditEngine->aStatus.GetControlWord();
+ pImpEditEngine->aStatus.GetControlWord() = nWord;
+
+ sal_uInt32 nChanges = nPrev ^ nWord;
+ if ( pImpEditEngine->IsFormatted() )
+ {
+ // ggf. neu formatieren:
+ if ( ( nChanges & EE_CNTRL_USECHARATTRIBS ) ||
+ ( nChanges & EE_CNTRL_USEPARAATTRIBS ) ||
+ ( nChanges & EE_CNTRL_ONECHARPERLINE ) ||
+ ( nChanges & EE_CNTRL_STRETCHING ) ||
+ ( nChanges & EE_CNTRL_OUTLINER ) ||
+ ( nChanges & EE_CNTRL_NOCOLORS ) ||
+ ( nChanges & EE_CNTRL_OUTLINER2 ) )
+ {
+ if ( ( nChanges & EE_CNTRL_USECHARATTRIBS ) ||
+ ( nChanges & EE_CNTRL_USEPARAATTRIBS ) )
+ {
+ sal_Bool bUseCharAttribs = ( nWord & EE_CNTRL_USECHARATTRIBS ) ? sal_True : sal_False;
+ pImpEditEngine->GetEditDoc().CreateDefFont( bUseCharAttribs );
+ }
+
+ pImpEditEngine->FormatFullDoc();
+ pImpEditEngine->UpdateViews( pImpEditEngine->GetActiveView() );
+ }
+ }
+
+ sal_Bool bSpellingChanged = nChanges & EE_CNTRL_ONLINESPELLING ? sal_True : sal_False;
+
+ if ( bSpellingChanged )
+ {
+ pImpEditEngine->StopOnlineSpellTimer();
+ if ( bSpellingChanged && ( nWord & EE_CNTRL_ONLINESPELLING ) )
+ {
+ // WrongListen anlegen, Timer starten...
+ sal_uInt16 nNodes = pImpEditEngine->GetEditDoc().Count();
+ for ( sal_uInt16 n = 0; n < nNodes; n++ )
+ {
+ ContentNode* pNode = pImpEditEngine->GetEditDoc().GetObject( n );
+ pNode->CreateWrongList();
+ }
+ pImpEditEngine->StartOnlineSpellTimer();
+ }
+ else
+ {
+ long nY = 0;
+ sal_uInt16 nNodes = pImpEditEngine->GetEditDoc().Count();
+ for ( sal_uInt16 n = 0; n < nNodes; n++ )
+ {
+ ContentNode* pNode = pImpEditEngine->GetEditDoc().GetObject( n );
+ ParaPortion* pPortion = pImpEditEngine->GetParaPortions().GetObject( n );
+ sal_Bool bWrongs = ( bSpellingChanged || ( nWord & EE_CNTRL_ONLINESPELLING ) ) ? pNode->GetWrongList()->HasWrongs() : sal_False;
+ if ( bSpellingChanged ) // Also aus
+ pNode->DestroyWrongList(); // => vorm Paint weghaun.
+ if ( bWrongs )
+ {
+ pImpEditEngine->aInvalidRec.Left() = 0;
+ pImpEditEngine->aInvalidRec.Right() = pImpEditEngine->GetPaperSize().Width();
+ pImpEditEngine->aInvalidRec.Top() = nY+1;
+ pImpEditEngine->aInvalidRec.Bottom() = nY+pPortion->GetHeight()-1;
+ pImpEditEngine->UpdateViews( pImpEditEngine->pActiveView );
+ }
+ nY += pPortion->GetHeight();
+ }
+ }
+ }
+ }
+}
+
+sal_uInt32 EditEngine::GetControlWord() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->aStatus.GetControlWord();
+}
+
+long EditEngine::GetFirstLineStartX( sal_uInt16 nParagraph )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ long nX = 0;
+ ParaPortion* pPPortion = pImpEditEngine->GetParaPortions().SaveGetObject( nParagraph );
+ if ( pPPortion )
+ {
+ DBG_ASSERT( pImpEditEngine->IsFormatted() || !pImpEditEngine->IsFormatting(), "GetFirstLineStartX: Doc not formatted - unable to format!" );
+ if ( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatDoc();
+ EditLine* pFirstLine = pPPortion->GetLines()[0];
+ nX = pFirstLine->GetStartPosX();
+ }
+ return nX;
+}
+
+Point EditEngine::GetDocPos( const Point& rPaperPos ) const
+{
+ Point aDocPos( rPaperPos );
+ if ( IsVertical() )
+ {
+ aDocPos.X() = rPaperPos.Y();
+ aDocPos.Y() = GetPaperSize().Width() - rPaperPos.X();
+ }
+ return aDocPos;
+}
+
+Point EditEngine::GetDocPosTopLeft( sal_uInt16 nParagraph )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ ParaPortion* pPPortion = pImpEditEngine->GetParaPortions().SaveGetObject( nParagraph );
+ DBG_ASSERT( pPPortion, "Absatz nicht gefunden: GetWindowPosTopLeft" );
+ Point aPoint;
+ if ( pPPortion )
+ {
+ // Falls jemand mit einer leeren Engine ein GetLineHeight() macht.
+ DBG_ASSERT( pImpEditEngine->IsFormatted() || !pImpEditEngine->IsFormatting(), "GetDocPosTopLeft: Doc not formatted - unable to format!" );
+ if ( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatAndUpdate();
+ if ( pPPortion->GetLines().Count() )
+ {
+ // So richtiger, falls grosses Bullet.
+ EditLine* pFirstLine = pPPortion->GetLines()[0];
+ aPoint.X() = pFirstLine->GetStartPosX();
+ }
+ else
+ {
+ const SvxLRSpaceItem& rLRItem = pImpEditEngine->GetLRSpaceItem( pPPortion->GetNode() );
+// TL_NF_LR aPoint.X() = pImpEditEngine->GetXValue( (short)(rLRItem.GetTxtLeft() + rLRItem.GetTxtFirstLineOfst()) );
+ sal_Int32 nSpaceBefore = 0;
+ pImpEditEngine->GetSpaceBeforeAndMinLabelWidth( pPPortion->GetNode(), &nSpaceBefore );
+ short nX = (short)(rLRItem.GetTxtLeft()
+ + rLRItem.GetTxtFirstLineOfst()
+ + nSpaceBefore);
+ aPoint.X() = pImpEditEngine->GetXValue( nX
+ );
+ }
+ aPoint.Y() = pImpEditEngine->GetParaPortions().GetYOffset( pPPortion );
+ }
+ return aPoint;
+}
+
+const SvxNumberFormat* EditEngine::GetNumberFormat( USHORT nPara ) const
+{
+ // derived objects may overload this function to give access to
+ // bullet information (see Outliner)
+ (void) nPara;
+ return 0;
+}
+
+BOOL EditEngine::IsRightToLeft( USHORT nPara ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->IsRightToLeft( nPara );
+}
+
+sal_Bool EditEngine::IsTextPos( const Point& rPaperPos, sal_uInt16 nBorder )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ if ( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatDoc();
+
+ sal_Bool bTextPos = sal_False;
+ // #90780# take unrotated positions for calculation here
+ Point aDocPos = GetDocPos( rPaperPos );
+
+ if ( ( aDocPos.Y() > 0 ) && ( aDocPos.Y() < (long)pImpEditEngine->GetTextHeight() ) )
+ {
+ EditPaM aPaM = pImpEditEngine->GetPaM( aDocPos, sal_False );
+ if ( aPaM.GetNode() )
+ {
+ ParaPortion* pParaPortion = pImpEditEngine->FindParaPortion( aPaM.GetNode() );
+ DBG_ASSERT( pParaPortion, "ParaPortion?" );
+
+ sal_uInt16 nLine = pParaPortion->GetLineNumber( aPaM.GetIndex() );
+ EditLine* pLine = pParaPortion->GetLines().GetObject( nLine );
+ Range aLineXPosStartEnd = pImpEditEngine->GetLineXPosStartEnd( pParaPortion, pLine );
+ if ( ( aDocPos.X() >= aLineXPosStartEnd.Min() - nBorder ) &&
+ ( aDocPos.X() <= aLineXPosStartEnd.Max() + nBorder ) )
+ {
+ bTextPos = sal_True;
+ }
+ }
+ }
+ return bTextPos;
+}
+
+void EditEngine::SetEditTextObjectPool( SfxItemPool* pPool )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetEditTextObjectPool( pPool );
+}
+
+SfxItemPool* EditEngine::GetEditTextObjectPool() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetEditTextObjectPool();
+}
+
+void EditEngine::QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ EditSelection aSel( pImpEditEngine->
+ ConvertSelection( rSel.nStartPara, rSel.nStartPos, rSel.nEndPara, rSel.nEndPos ) );
+
+ pImpEditEngine->SetAttribs( aSel, rSet );
+}
+
+void EditEngine::QuickMarkInvalid( const ESelection& rSel )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ DBG_ASSERT( rSel.nStartPara < pImpEditEngine->GetEditDoc().Count(), "MarkInvalid: Start out of Range!" );
+ DBG_ASSERT( rSel.nEndPara < pImpEditEngine->GetEditDoc().Count(), "MarkInvalid: End out of Range!" );
+ for ( sal_uInt16 nPara = rSel.nStartPara; nPara <= rSel.nEndPara; nPara++ )
+ {
+ ParaPortion* pPortion = pImpEditEngine->GetParaPortions().SaveGetObject( nPara );
+ if ( pPortion )
+ pPortion->MarkSelectionInvalid( 0, pPortion->GetNode()->Len() );
+ }
+}
+
+void EditEngine::QuickInsertText( const XubString& rText, const ESelection& rSel )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ EditSelection aSel( pImpEditEngine->
+ ConvertSelection( rSel.nStartPara, rSel.nStartPos, rSel.nEndPara, rSel.nEndPos ) );
+
+ pImpEditEngine->ImpInsertText( aSel, rText );
+}
+
+void EditEngine::QuickDelete( const ESelection& rSel )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ EditSelection aSel( pImpEditEngine->
+ ConvertSelection( rSel.nStartPara, rSel.nStartPos, rSel.nEndPara, rSel.nEndPos ) );
+
+ pImpEditEngine->ImpDeleteSelection( aSel );
+}
+
+void EditEngine::QuickMarkToBeRepainted( sal_uInt16 nPara )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ ParaPortion* pPortion = pImpEditEngine->GetParaPortions().SaveGetObject( nPara );
+ if ( pPortion )
+ pPortion->SetMustRepaint( sal_True );
+}
+
+void EditEngine::QuickInsertLineBreak( const ESelection& rSel )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ EditSelection aSel( pImpEditEngine->
+ ConvertSelection( rSel.nStartPara, rSel.nStartPos, rSel.nEndPara, rSel.nEndPos ) );
+
+ pImpEditEngine->InsertLineBreak( aSel );
+}
+
+void EditEngine::QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ EditSelection aSel( pImpEditEngine->
+ ConvertSelection( rSel.nStartPara, rSel.nStartPos, rSel.nEndPara, rSel.nEndPos ) );
+
+ pImpEditEngine->ImpInsertFeature( aSel, rFld );
+}
+
+void EditEngine::QuickFormatDoc( sal_Bool bFull )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ if ( bFull )
+ pImpEditEngine->FormatFullDoc();
+ else
+ pImpEditEngine->FormatDoc();
+
+ // #111072# Don't pass active view, maybe selection is not updated yet...
+ pImpEditEngine->UpdateViews( NULL );
+}
+
+void EditEngine::QuickRemoveCharAttribs( sal_uInt16 nPara, sal_uInt16 nWhich )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->RemoveCharAttribs( nPara, nWhich );
+}
+
+void EditEngine::SetStyleSheet( sal_uInt16 nPara, SfxStyleSheet* pStyle )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetStyleSheet( nPara, pStyle );
+}
+
+SfxStyleSheet* EditEngine::GetStyleSheet( sal_uInt16 nPara ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetStyleSheet( nPara );
+}
+
+void EditEngine::SetStyleSheetPool( SfxStyleSheetPool* pSPool )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetStyleSheetPool( pSPool );
+}
+
+SfxStyleSheetPool* EditEngine::GetStyleSheetPool()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetStyleSheetPool();
+}
+
+void EditEngine::SetWordDelimiters( const XubString& rDelimiters )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->aWordDelimiters = rDelimiters;
+ if ( pImpEditEngine->aWordDelimiters.Search( CH_FEATURE ) == STRING_NOTFOUND )
+ pImpEditEngine->aWordDelimiters.Insert( CH_FEATURE );
+}
+
+XubString EditEngine::GetWordDelimiters() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->aWordDelimiters;
+}
+
+void EditEngine::SetGroupChars( const XubString& rChars )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ DBG_ASSERT( ( rChars.Len() % 2 ) == 0, "SetGroupChars: Ungerade Anzahl!" );
+ pImpEditEngine->aGroupChars = rChars;
+}
+
+XubString EditEngine::GetGroupChars() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->aGroupChars;
+}
+
+void EditEngine::EnablePasteSpecial( sal_Bool bEnable )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ if ( bEnable )
+ pImpEditEngine->GetStatus().TurnOnFlags( EE_CNTRL_PASTESPECIAL );
+ else
+ pImpEditEngine->GetStatus().TurnOffFlags( EE_CNTRL_PASTESPECIAL );
+}
+
+sal_Bool EditEngine::IsPasteSpecialEnabled() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetStatus().AllowPasteSpecial();
+}
+
+void EditEngine::EnableIdleFormatter( sal_Bool bEnable )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ if ( bEnable )
+ pImpEditEngine->GetStatus().TurnOnFlags( EE_CNTRL_DOIDLEFORMAT );
+ else
+ pImpEditEngine->GetStatus().TurnOffFlags( EE_CNTRL_DOIDLEFORMAT);
+}
+
+sal_Bool EditEngine::IsIdleFormatterEnabled() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetStatus().UseIdleFormatter();
+}
+
+void EditEngine::EraseVirtualDevice()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->EraseVirtualDevice();
+}
+
+void EditEngine::SetSpeller( Reference< XSpellChecker1 > &xSpeller )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetSpeller( xSpeller );
+}
+Reference< XSpellChecker1 > EditEngine::GetSpeller()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetSpeller();
+}
+Reference< XHyphenator > EditEngine::GetHyphenator() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetHyphenator();
+}
+
+void EditEngine::SetHyphenator( Reference< XHyphenator > & xHyph )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetHyphenator( xHyph );
+}
+
+void EditEngine::SetForbiddenCharsTable( vos::ORef<SvxForbiddenCharactersTable> xForbiddenChars )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetForbiddenCharsTable( xForbiddenChars );
+}
+
+vos::ORef<SvxForbiddenCharactersTable> EditEngine::GetForbiddenCharsTable() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetForbiddenCharsTable( FALSE );
+}
+
+
+void EditEngine::SetDefaultLanguage( LanguageType eLang )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetDefaultLanguage( eLang );
+}
+
+LanguageType EditEngine::GetDefaultLanguage() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetDefaultLanguage();
+}
+
+sal_Bool __EXPORT EditEngine::SpellNextDocument()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return sal_False;
+}
+
+EESpellState EditEngine::HasSpellErrors()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ if ( !pImpEditEngine->GetSpeller().is() )
+ return EE_SPELL_NOSPELLER;
+
+ return pImpEditEngine->HasSpellErrors();
+}
+/*-- 13.10.2003 16:56:23---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void EditEngine::StartSpelling(EditView& rEditView, sal_Bool bMultipleDoc)
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->StartSpelling(rEditView, bMultipleDoc);
+}
+/*-- 13.10.2003 16:56:23---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void EditEngine::EndSpelling()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->EndSpelling();
+}
+
+/*-- 13.10.2003 16:43:27---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+bool EditEngine::SpellSentence(EditView& rView, ::svx::SpellPortions& rToFill, bool bIsGrammarChecking )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->SpellSentence( rView, rToFill, bIsGrammarChecking );
+}
+/*-- 08.09.2008 11:38:32---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void EditEngine::PutSpellingToSentenceStart( EditView& rEditView )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->PutSpellingToSentenceStart( rEditView );
+}
+/*-- 13.10.2003 16:43:27---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void EditEngine::ApplyChangedSentence(EditView& rEditView, const ::svx::SpellPortions& rNewPortions, bool bIsGrammarChecking )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->ApplyChangedSentence( rEditView, rNewPortions, bIsGrammarChecking );
+}
+
+sal_Bool EditEngine::HasConvertibleTextPortion( LanguageType nLang )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->HasConvertibleTextPortion( nLang );
+}
+
+sal_Bool __EXPORT EditEngine::ConvertNextDocument()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return sal_False;
+}
+
+sal_Bool EditEngine::HasText( const SvxSearchItem& rSearchItem )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->HasText( rSearchItem );
+}
+
+void EditEngine::SetGlobalCharStretching( sal_uInt16 nX, sal_uInt16 nY )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetCharStretching( nX, nY );
+}
+
+void EditEngine::GetGlobalCharStretching( sal_uInt16& rX, sal_uInt16& rY )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->GetCharStretching( rX, rY );
+}
+
+void EditEngine::DoStretchChars( sal_uInt16 nX, sal_uInt16 nY )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->DoStretchChars( nX, nY );
+}
+
+void EditEngine::SetBigTextObjectStart( sal_uInt16 nStartAtPortionCount )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ pImpEditEngine->SetBigTextObjectStart( nStartAtPortionCount );
+}
+
+sal_uInt16 EditEngine::GetBigTextObjectStart() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return pImpEditEngine->GetBigTextObjectStart();
+}
+
+sal_Bool EditEngine::ShouldCreateBigTextObject() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ sal_uInt16 nTextPortions = 0;
+ sal_uInt16 nParas = pImpEditEngine->GetEditDoc().Count();
+ for ( sal_uInt16 nPara = 0; nPara < nParas; nPara++ )
+ {
+ ParaPortion* pParaPortion = pImpEditEngine->GetParaPortions()[nPara];
+ nTextPortions = nTextPortions + pParaPortion->GetTextPortions().Count();
+ }
+ return ( nTextPortions >= pImpEditEngine->GetBigTextObjectStart() ) ? sal_True : sal_False;
+}
+
+USHORT EditEngine::GetFieldCount( USHORT nPara ) const
+{
+ USHORT nFields = 0;
+ ContentNode* pNode = pImpEditEngine->GetEditDoc().SaveGetObject( nPara );
+ if ( pNode )
+ {
+ const CharAttribArray& rAttrs = pNode->GetCharAttribs().GetAttribs();
+ for ( sal_uInt16 nAttr = 0; nAttr < rAttrs.Count(); nAttr++ )
+ {
+ EditCharAttrib* pAttr = rAttrs[nAttr];
+ if ( pAttr->Which() == EE_FEATURE_FIELD )
+ nFields++;
+ }
+ }
+
+ return nFields;
+}
+
+EFieldInfo EditEngine::GetFieldInfo( USHORT nPara, USHORT nField ) const
+{
+ ContentNode* pNode = pImpEditEngine->GetEditDoc().SaveGetObject( nPara );
+ if ( pNode )
+ {
+ USHORT nCurrentField = 0;
+ const CharAttribArray& rAttrs = pNode->GetCharAttribs().GetAttribs();
+ for ( sal_uInt16 nAttr = 0; nAttr < rAttrs.Count(); nAttr++ )
+ {
+ EditCharAttrib* pAttr = rAttrs[nAttr];
+ if ( pAttr->Which() == EE_FEATURE_FIELD )
+ {
+ if ( nCurrentField == nField )
+ {
+ EFieldInfo aInfo( *(const SvxFieldItem*)pAttr->GetItem(), nPara, pAttr->GetStart() );
+ aInfo.aCurrentText = ((EditCharAttribField*)pAttr)->GetFieldValue();
+ return aInfo;
+ }
+
+ nCurrentField++;
+ }
+ }
+ }
+ return EFieldInfo();
+}
+
+
+sal_Bool EditEngine::UpdateFields()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ sal_Bool bChanges = pImpEditEngine->UpdateFields();
+ if ( bChanges )
+ pImpEditEngine->FormatAndUpdate();
+ return bChanges;
+}
+
+void EditEngine::RemoveFields( sal_Bool bKeepFieldText, TypeId aType )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ if ( bKeepFieldText )
+ pImpEditEngine->UpdateFields();
+
+ sal_uInt16 nParas = pImpEditEngine->GetEditDoc().Count();
+ for ( sal_uInt16 nPara = 0; nPara < nParas; nPara++ )
+ {
+ ContentNode* pNode = pImpEditEngine->GetEditDoc().GetObject( nPara );
+ const CharAttribArray& rAttrs = pNode->GetCharAttribs().GetAttribs();
+ for ( sal_uInt16 nAttr = rAttrs.Count(); nAttr; )
+ {
+ const EditCharAttrib* pAttr = rAttrs[--nAttr];
+ if ( pAttr->Which() == EE_FEATURE_FIELD )
+ {
+ const SvxFieldData* pFldData = ((const SvxFieldItem*)pAttr->GetItem())->GetField();
+ if ( pFldData && ( !aType || ( pFldData->IsA( aType ) ) ) )
+ {
+ DBG_ASSERT( pAttr->GetItem()->ISA( SvxFieldItem ), "Kein FeldItem..." );
+ EditSelection aSel( EditPaM( pNode, pAttr->GetStart() ), EditPaM( pNode, pAttr->GetEnd() ) );
+ String aFieldText = ((EditCharAttribField*)pAttr)->GetFieldValue();
+ pImpEditEngine->ImpInsertText( aSel, aFieldText );
+ }
+ }
+ }
+ }
+}
+
+sal_Bool EditEngine::HasOnlineSpellErrors() const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ sal_uInt16 nNodes = pImpEditEngine->GetEditDoc().Count();
+ for ( sal_uInt16 n = 0; n < nNodes; n++ )
+ {
+ ContentNode* pNode = pImpEditEngine->GetEditDoc().GetObject( n );
+ if ( pNode->GetWrongList() && pNode->GetWrongList()->Count() )
+ return sal_True;
+ }
+ return sal_False;
+}
+
+void EditEngine::CompleteOnlineSpelling()
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ if ( pImpEditEngine->GetStatus().DoOnlineSpelling() )
+ {
+ if( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatAndUpdate();
+
+ pImpEditEngine->StopOnlineSpellTimer();
+ pImpEditEngine->DoOnlineSpelling( 0, sal_True, sal_False );
+ }
+}
+
+USHORT EditEngine::FindParagraph( long nDocPosY )
+{
+ return pImpEditEngine->GetParaPortions().FindParagraph( nDocPosY );
+}
+
+EPosition EditEngine::FindDocPosition( const Point& rDocPos ) const
+{
+ EPosition aPos;
+ // From the point of the API, this is const....
+ EditPaM aPaM = ((EditEngine*)this)->pImpEditEngine->GetPaM( rDocPos, FALSE );
+ if ( aPaM.GetNode() )
+ {
+ aPos.nPara = pImpEditEngine->aEditDoc.GetPos( aPaM.GetNode() );
+ aPos.nIndex = aPaM.GetIndex();
+ }
+ return aPos;
+}
+
+Rectangle EditEngine::GetCharacterBounds( const EPosition& rPos ) const
+{
+ Rectangle aBounds;
+ ContentNode* pNode = pImpEditEngine->GetEditDoc().SaveGetObject( rPos.nPara );
+
+ // #109151# Check against index, not paragraph
+ if ( pNode && ( rPos.nIndex < pNode->Len() ) )
+ {
+ aBounds = pImpEditEngine->PaMtoEditCursor( EditPaM( pNode, rPos.nIndex ), GETCRSR_TXTONLY );
+ Rectangle aR2 = pImpEditEngine->PaMtoEditCursor( EditPaM( pNode, rPos.nIndex+1 ), GETCRSR_TXTONLY|GETCRSR_ENDOFLINE );
+ if ( aR2.Right() > aBounds.Right() )
+ aBounds.Right() = aR2.Right();
+ }
+ return aBounds;
+}
+
+ParagraphInfos EditEngine::GetParagraphInfos( sal_uInt16 nPara )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ // Funktioniert nur, wenn nicht bereits in der Formatierung...
+ if ( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatDoc();
+
+ ParagraphInfos aInfos;
+ aInfos.bValid = pImpEditEngine->IsFormatted();
+ if ( pImpEditEngine->IsFormatted() )
+ {
+ ParaPortion* pParaPortion = pImpEditEngine->GetParaPortions()[nPara];
+ EditLine* pLine = (pParaPortion && pParaPortion->GetLines().Count()) ?
+ pParaPortion->GetLines().GetObject( 0 ) : NULL;
+ DBG_ASSERT( pParaPortion && pLine, "GetParagraphInfos - Paragraph out of range" );
+ if ( pParaPortion && pLine )
+ {
+ aInfos.nParaHeight = (USHORT)pParaPortion->GetHeight();
+ aInfos.nLines = pParaPortion->GetLines().Count();
+ aInfos.nFirstLineStartX = pLine->GetStartPosX();
+ aInfos.nFirstLineOffset = pParaPortion->GetFirstLineOffset();
+ aInfos.nFirstLineHeight = pLine->GetHeight();
+ aInfos.nFirstLineTextHeight = pLine->GetTxtHeight();
+ aInfos.nFirstLineMaxAscent = pLine->GetMaxAscent();
+ }
+ }
+ return aInfos;
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >
+ EditEngine::CreateTransferable( const ESelection& rSelection ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ EditSelection aSel( pImpEditEngine->CreateSel( rSelection ) );
+ return pImpEditEngine->CreateTransferable( aSel );
+}
+
+// =====================================================================
+// ====================== Virtuelle Methoden =======================
+// =====================================================================
+void __EXPORT EditEngine::DrawingText( const Point&, const XubString&, USHORT, USHORT,
+ const sal_Int32*, const SvxFont&, sal_uInt16, sal_uInt16, BYTE,
+ const EEngineData::WrongSpellVector*, const SvxFieldData*, bool, bool, bool,
+ const ::com::sun::star::lang::Locale*, const Color&, const Color&)
+
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+}
+
+void __EXPORT EditEngine::PaintingFirstLine( sal_uInt16, const Point&, long, const Point&, short, OutputDevice* )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+}
+
+void __EXPORT EditEngine::ParagraphInserted( sal_uInt16 nPara )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ if ( GetNotifyHdl().IsSet() )
+ {
+ EENotify aNotify( EE_NOTIFY_PARAGRAPHINSERTED );
+ aNotify.pEditEngine = this;
+ aNotify.nParagraph = nPara;
+ pImpEditEngine->CallNotify( aNotify );
+ }
+}
+
+void __EXPORT EditEngine::ParagraphDeleted( sal_uInt16 nPara )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ if ( GetNotifyHdl().IsSet() )
+ {
+ EENotify aNotify( EE_NOTIFY_PARAGRAPHREMOVED );
+ aNotify.pEditEngine = this;
+ aNotify.nParagraph = nPara;
+ pImpEditEngine->CallNotify( aNotify );
+ }
+}
+void EditEngine::ParagraphConnected( USHORT /*nLeftParagraph*/, USHORT /*nRightParagraph*/ )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+}
+
+sal_Bool __EXPORT EditEngine::FormattingParagraph( sal_uInt16 )
+{
+ // return sal_True, wenn die Attribute geaendert wurden...
+ DBG_CHKTHIS( EditEngine, 0 );
+ return sal_False;
+}
+
+void __EXPORT EditEngine::ParaAttribsChanged( sal_uInt16 /* nParagraph */ )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+}
+
+void __EXPORT EditEngine::StyleSheetChanged( SfxStyleSheet* /* pStyle */ )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+}
+
+void __EXPORT EditEngine::ParagraphHeightChanged( sal_uInt16 nPara )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+
+ if ( GetNotifyHdl().IsSet() )
+ {
+ EENotify aNotify( EE_NOTIFY_TEXTHEIGHTCHANGED );
+ aNotify.pEditEngine = this;
+ aNotify.nParagraph = nPara;
+ pImpEditEngine->CallNotify( aNotify );
+ }
+}
+
+XubString __EXPORT EditEngine::GetUndoComment( sal_uInt16 nId ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ XubString aComment;
+ switch ( nId )
+ {
+ case EDITUNDO_REMOVECHARS:
+ case EDITUNDO_CONNECTPARAS:
+ case EDITUNDO_REMOVEFEATURE:
+ case EDITUNDO_DELCONTENT:
+ case EDITUNDO_DELETE:
+ case EDITUNDO_CUT:
+ aComment = XubString( EditResId( RID_EDITUNDO_DEL ) );
+ break;
+ case EDITUNDO_MOVEPARAGRAPHS:
+ case EDITUNDO_MOVEPARAS:
+ case EDITUNDO_DRAGANDDROP:
+ aComment = XubString( EditResId( RID_EDITUNDO_MOVE ) );
+ break;
+ case EDITUNDO_INSERTFEATURE:
+ case EDITUNDO_SPLITPARA:
+ case EDITUNDO_INSERTCHARS:
+ case EDITUNDO_PASTE:
+ case EDITUNDO_INSERT:
+ case EDITUNDO_READ:
+ aComment = XubString( EditResId( RID_EDITUNDO_INSERT ) );
+ break;
+ case EDITUNDO_SRCHANDREPL:
+ case EDITUNDO_REPLACEALL:
+ aComment = XubString( EditResId( RID_EDITUNDO_REPLACE ) );
+ break;
+ case EDITUNDO_ATTRIBS:
+ case EDITUNDO_PARAATTRIBS:
+ case EDITUNDO_STRETCH:
+ aComment = XubString( EditResId( RID_EDITUNDO_SETATTRIBS ) );
+ break;
+ case EDITUNDO_RESETATTRIBS:
+ aComment = XubString( EditResId( RID_EDITUNDO_RESETATTRIBS ) );
+ break;
+ case EDITUNDO_STYLESHEET:
+ aComment = XubString( EditResId( RID_EDITUNDO_SETSTYLE ) );
+ break;
+ case EDITUNDO_TRANSLITERATE:
+ aComment = XubString( EditResId( RID_EDITUNDO_TRANSLITERATE ) );
+ break;
+ case EDITUNDO_INDENTBLOCK:
+ case EDITUNDO_UNINDENTBLOCK:
+ aComment = XubString( EditResId( RID_EDITUNDO_INDENT ) );
+ break;
+ }
+ return aComment;
+}
+
+Rectangle EditEngine::GetBulletArea( sal_uInt16 )
+{
+ return Rectangle( Point(), Point() );
+}
+
+XubString __EXPORT EditEngine::CalcFieldValue( const SvxFieldItem&, sal_uInt16, sal_uInt16, Color*&, Color*& )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ return ' ';
+}
+
+void __EXPORT EditEngine::FieldClicked( const SvxFieldItem&, sal_uInt16, sal_uInt16 )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+}
+
+void __EXPORT EditEngine::FieldSelected( const SvxFieldItem&, sal_uInt16, sal_uInt16 )
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+}
+
+ // =====================================================================
+// ====================== Statische Methoden =======================
+// =====================================================================
+SfxItemPool* EditEngine::CreatePool( sal_Bool bPersistentRefCounts )
+{
+ SfxItemPool* pPool = new EditEngineItemPool( bPersistentRefCounts );
+ return pPool;
+}
+
+SfxItemPool& EditEngine::GetGlobalItemPool()
+{
+ if ( !pGlobalPool )
+ pGlobalPool = CreatePool();
+ return *pGlobalPool;
+}
+
+sal_uInt32 EditEngine::RegisterClipboardFormatName()
+{
+ static sal_uInt32 nFormat = 0;
+ if ( !nFormat )
+ nFormat = SotExchange::RegisterFormatName( String( RTL_CONSTASCII_USTRINGPARAM( "EditEngineFormat" ) ) );
+ return nFormat;
+}
+
+sal_uInt16 EditEngine::GetAvailableSearchOptions()
+{
+ return SEARCH_OPTIONS_SEARCH | SEARCH_OPTIONS_REPLACE |
+ SEARCH_OPTIONS_REPLACE_ALL | SEARCH_OPTIONS_WHOLE_WORDS |
+ SEARCH_OPTIONS_BACKWARDS | SEARCH_OPTIONS_REG_EXP |
+ SEARCH_OPTIONS_EXACT | SEARCH_OPTIONS_SELECTION;
+}
+
+void EditEngine::SetFontInfoInItemSet( SfxItemSet& rSet, const Font& rFont )
+{
+ SvxFont aSvxFont( rFont );
+ SetFontInfoInItemSet( rSet, aSvxFont );
+
+}
+
+void EditEngine::SetFontInfoInItemSet( SfxItemSet& rSet, const SvxFont& rFont )
+{
+ rSet.Put( SvxLanguageItem( rFont.GetLanguage(), EE_CHAR_LANGUAGE ) );
+ rSet.Put( SvxFontItem( rFont.GetFamily(), rFont.GetName(), XubString(), rFont.GetPitch(), rFont.GetCharSet(), EE_CHAR_FONTINFO ) );
+ rSet.Put( SvxFontHeightItem( rFont.GetSize().Height(), 100, EE_CHAR_FONTHEIGHT ) );
+ rSet.Put( SvxCharScaleWidthItem( 100, EE_CHAR_FONTWIDTH ) );
+ rSet.Put( SvxShadowedItem( rFont.IsShadow(), EE_CHAR_SHADOW ) );
+ rSet.Put( SvxEscapementItem( rFont.GetEscapement(), rFont.GetPropr(), EE_CHAR_ESCAPEMENT ) );
+ rSet.Put( SvxWeightItem( rFont.GetWeight(), EE_CHAR_WEIGHT ) );
+ rSet.Put( SvxColorItem( rFont.GetColor(), EE_CHAR_COLOR ) );
+ rSet.Put( SvxUnderlineItem( rFont.GetUnderline(), EE_CHAR_UNDERLINE ) );
+ rSet.Put( SvxOverlineItem( rFont.GetOverline(), EE_CHAR_OVERLINE ) );
+ rSet.Put( SvxCrossedOutItem( rFont.GetStrikeout(), EE_CHAR_STRIKEOUT ) );
+ rSet.Put( SvxPostureItem( rFont.GetItalic(), EE_CHAR_ITALIC ) );
+ rSet.Put( SvxContourItem( rFont.IsOutline(), EE_CHAR_OUTLINE ) );
+ rSet.Put( SvxAutoKernItem( rFont.IsKerning(), EE_CHAR_PAIRKERNING ) );
+ rSet.Put( SvxKerningItem( rFont.GetFixKerning(), EE_CHAR_KERNING ) );
+ rSet.Put( SvxWordLineModeItem( rFont.IsWordLineMode(), EE_CHAR_WLM ) );
+ rSet.Put( SvxEmphasisMarkItem( rFont.GetEmphasisMark(), EE_CHAR_EMPHASISMARK ) );
+ rSet.Put( SvxCharReliefItem( rFont.GetRelief(), EE_CHAR_RELIEF ) );
+}
+
+Font EditEngine::CreateFontFromItemSet( const SfxItemSet& rItemSet, USHORT nScriptType )
+{
+ SvxFont aFont;
+ CreateFont( aFont, rItemSet, true, nScriptType );
+ return aFont;
+}
+
+// Maybe we can remove the next two methods, check after 6.x
+Font EditEngine::CreateFontFromItemSet( const SfxItemSet& rItemSet )
+{
+ return CreateSvxFontFromItemSet( rItemSet );
+}
+
+SvxFont EditEngine::CreateSvxFontFromItemSet( const SfxItemSet& rItemSet )
+{
+ SvxFont aFont;
+ CreateFont( aFont, rItemSet );
+ return aFont;
+}
+
+sal_Bool EditEngine::DoesKeyMoveCursor( const KeyEvent& rKeyEvent )
+{
+ sal_Bool bDoesMove = sal_False;
+
+ switch ( rKeyEvent.GetKeyCode().GetCode() )
+ {
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ case KEY_HOME:
+ case KEY_END:
+ case KEY_PAGEUP:
+ case KEY_PAGEDOWN:
+ {
+ if ( !rKeyEvent.GetKeyCode().IsMod2() )
+ bDoesMove = sal_True;
+ }
+ break;
+ }
+ return bDoesMove;
+}
+
+sal_Bool EditEngine::DoesKeyChangeText( const KeyEvent& rKeyEvent )
+{
+ sal_Bool bDoesChange = sal_False;
+
+ KeyFuncType eFunc = rKeyEvent.GetKeyCode().GetFunction();
+ if ( eFunc != KEYFUNC_DONTKNOW )
+ {
+ switch ( eFunc )
+ {
+ case KEYFUNC_UNDO:
+ case KEYFUNC_REDO:
+ case KEYFUNC_CUT:
+ case KEYFUNC_PASTE: bDoesChange = sal_True;
+ break;
+ default: // wird dann evtl. unten bearbeitet.
+ eFunc = KEYFUNC_DONTKNOW;
+ }
+ }
+ if ( eFunc == KEYFUNC_DONTKNOW )
+ {
+ switch ( rKeyEvent.GetKeyCode().GetCode() )
+ {
+ case KEY_DELETE:
+ case KEY_BACKSPACE: bDoesChange = sal_True;
+ break;
+ case KEY_RETURN:
+ case KEY_TAB:
+ {
+ if ( !rKeyEvent.GetKeyCode().IsMod1() && !rKeyEvent.GetKeyCode().IsMod2() )
+ bDoesChange = sal_True;
+ }
+ break;
+ default:
+ {
+ bDoesChange = IsSimpleCharInput( rKeyEvent );
+ }
+ }
+ }
+ return bDoesChange;
+}
+
+sal_Bool EditEngine::IsSimpleCharInput( const KeyEvent& rKeyEvent )
+{
+ if( EditEngine::IsPrintable( rKeyEvent.GetCharCode() ) &&
+ ( KEY_MOD2 != (rKeyEvent.GetKeyCode().GetModifier() & ~KEY_SHIFT ) ) &&
+ ( KEY_MOD1 != (rKeyEvent.GetKeyCode().GetModifier() & ~KEY_SHIFT ) ) )
+ {
+ return sal_True;
+ }
+ return sal_False;
+}
+
+// Mal in den Outliner schieben...
+void EditEngine::ImportBulletItem( SvxNumBulletItem& /*rNumBullet*/, sal_uInt16 /*nLevel*/,
+ const SvxBulletItem* /*pOldBullet*/, const SvxLRSpaceItem* /*pOldLRSpace*/ )
+{
+/* TL_NFLR
+ if ( pOldBullet || pOldLRSpace )
+ {
+ // Numberformat dynamisch, weil Zuweisungsoperator nicht implementiert.
+
+ // Altes NumBulletItem nur uebernehmen, wenn kein altes BulletItem
+ const SvxNumberFormat* pFmt = ( !pOldBullet && ( rNumBullet.GetNumRule()->GetLevelCount() > nLevel ) ) ?
+ rNumBullet.GetNumRule()->Get( nLevel ) : NULL;
+ SvxNumberFormat* pNumberFormat = pFmt
+ ? new SvxNumberFormat( *pFmt )
+ : new SvxNumberFormat( SVX_NUM_NUMBER_NONE );
+ if ( pOldBullet )
+ {
+ // Style
+ SvxExtNumType eNumType;
+ switch( pOldBullet->GetStyle() )
+ {
+ case BS_BMP: eNumType = SVX_NUM_BITMAP; break;
+ case BS_BULLET: eNumType = SVX_NUM_CHAR_SPECIAL; break;
+ case BS_ROMAN_BIG: eNumType = SVX_NUM_ROMAN_UPPER; break;
+ case BS_ROMAN_SMALL: eNumType = SVX_NUM_ROMAN_LOWER; break;
+ case BS_ABC_BIG: eNumType = SVX_NUM_CHARS_UPPER_LETTER; break;
+ case BS_ABC_SMALL: eNumType = SVX_NUM_CHARS_LOWER_LETTER; break;
+ case BS_123: eNumType = SVX_NUM_ARABIC; break;
+ default: eNumType = SVX_NUM_NUMBER_NONE; break;
+ }
+ pNumberFormat->SetNumberingType(
+ sal::static_int_cast< sal_Int16 >( eNumType ) );
+
+ // Justification
+ SvxAdjust eAdjust;
+ switch( pOldBullet->GetJustification() & (BJ_HRIGHT|BJ_HCENTER|BJ_HLEFT) )
+ {
+ case BJ_HRIGHT: eAdjust = SVX_ADJUST_RIGHT; break;
+ case BJ_HCENTER: eAdjust = SVX_ADJUST_CENTER; break;
+ default: eAdjust = SVX_ADJUST_LEFT; break;
+ }
+ pNumberFormat->SetNumAdjust(eAdjust);
+
+ // Prefix/Suffix
+ pNumberFormat->SetPrefix( pOldBullet->GetPrevText() );
+ pNumberFormat->SetSuffix( pOldBullet->GetFollowText() );
+
+ //Font
+ if ( eNumType != SVX_NUM_BITMAP )
+ {
+ Font aTmpFont = pOldBullet->GetFont();
+ pNumberFormat->SetBulletFont( &aTmpFont );
+ }
+
+ // Color
+ pNumberFormat->SetBulletColor( pOldBullet->GetFont().GetColor() );
+
+ // Start
+ pNumberFormat->SetStart( pOldBullet->GetStart() );
+
+ // Scale
+ pNumberFormat->SetBulletRelSize( pOldBullet->GetScale() );
+
+ // Bullet/Bitmap
+ if( eNumType == SVX_NUM_CHAR_SPECIAL )
+ {
+ pNumberFormat->SetBulletChar( pOldBullet->GetSymbol() );
+ }
+ else if( eNumType == SVX_NUM_BITMAP )
+ {
+ SvxBrushItem aBItem( Graphic( pOldBullet->GetBitmap() ), GPOS_NONE, SID_ATTR_BRUSH );
+ pNumberFormat->SetGraphicBrush( &aBItem );
+ }
+ }
+
+ // Einzug und Erstzeileneinzug
+//TL_NFLR if ( pOldLRSpace )
+//TL_NFLR {
+//TL_NFLR short nLSpace = (short)pOldLRSpace->GetTxtLeft();
+//TL_NFLR pNumberFormat->SetLSpace( nLSpace );
+//TL_NFLR pNumberFormat->SetAbsLSpace( nLSpace );
+//TL_NFLR pNumberFormat->SetFirstLineOffset( pOldLRSpace->GetTxtFirstLineOfst() );
+//TL_NFLR }
+
+ rNumBullet.GetNumRule()->SetLevel( nLevel, *pNumberFormat );
+ delete pNumberFormat;
+ }
+*/
+}
+
+BOOL EditEngine::HasValidData( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& rTransferable )
+{
+ BOOL bValidData = FALSE;
+
+ if ( rTransferable.is() )
+ {
+ // Every application that copies rtf or any other text format also copies plain text into the clipboard....
+ datatransfer::DataFlavor aFlavor;
+ SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aFlavor );
+ bValidData = rTransferable->isDataFlavorSupported( aFlavor );
+ }
+
+ return bValidData;
+}
+
+/** sets a link that is called at the beginning of a drag operation at an edit view */
+void EditEngine::SetBeginDropHdl( const Link& rLink )
+{
+ pImpEditEngine->SetBeginDropHdl( rLink );
+}
+
+Link EditEngine::GetBeginDropHdl() const
+{
+ return pImpEditEngine->GetBeginDropHdl();
+}
+
+/** sets a link that is called at the end of a drag operation at an edit view */
+void EditEngine::SetEndDropHdl( const Link& rLink )
+{
+ pImpEditEngine->SetEndDropHdl( rLink );
+}
+
+Link EditEngine::GetEndDropHdl() const
+{
+ return pImpEditEngine->GetEndDropHdl();
+}
+
+void EditEngine::SetFirstWordCapitalization( BOOL bCapitalize )
+{
+ pImpEditEngine->SetFirstWordCapitalization( bCapitalize );
+}
+
+BOOL EditEngine::IsFirstWordCapitalization() const
+{
+ return pImpEditEngine->IsFirstWordCapitalization();
+}
+
+
+// ---------------------------------------------------
+
+
+EFieldInfo::EFieldInfo()
+{
+ pFieldItem = NULL;
+}
+
+
+EFieldInfo::EFieldInfo( const SvxFieldItem& rFieldItem, USHORT nPara, USHORT nPos ) : aPosition( nPara, nPos )
+{
+ pFieldItem = new SvxFieldItem( rFieldItem );
+}
+
+EFieldInfo::~EFieldInfo()
+{
+ delete pFieldItem;
+}
+
+EFieldInfo::EFieldInfo( const EFieldInfo& rFldInfo )
+{
+ *this = rFldInfo;
+}
+
+EFieldInfo& EFieldInfo::operator= ( const EFieldInfo& rFldInfo )
+{
+ if( this == &rFldInfo )
+ return *this;
+
+ pFieldItem = rFldInfo.pFieldItem ? new SvxFieldItem( *rFldInfo.pFieldItem ) : 0;
+ aCurrentText = rFldInfo.aCurrentText;
+ aPosition = rFldInfo.aPosition;
+
+ return *this;
+}
diff --git a/editeng/source/editeng/editeng.src b/editeng/source/editeng/editeng.src
new file mode 100644
index 0000000000..1204ba1661
--- /dev/null
+++ b/editeng/source/editeng/editeng.src
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: editeng.src,v $
+ * $Revision: 1.47 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <editeng.hrc>
+#include <helpid.hrc>
+
+String RID_EDITUNDO_DEL
+{
+ Text [ en-US ] = "Delete" ;
+};
+
+String RID_EDITUNDO_MOVE
+{
+ Text [ en-US ] = "Move" ;
+};
+
+String RID_EDITUNDO_INSERT
+{
+ Text [ en-US ] = "Insert" ;
+};
+
+String RID_EDITUNDO_REPLACE
+{
+ Text [ en-US ] = "Replace" ;
+};
+
+String RID_EDITUNDO_SETATTRIBS
+{
+ Text [ en-US ] = "Apply attributes" ;
+};
+
+String RID_EDITUNDO_RESETATTRIBS
+{
+ Text [ en-US ] = "Reset attributes" ;
+};
+
+String RID_EDITUNDO_INDENT
+{
+ Text [ en-US ] = "Indent" ;
+};
+
+String RID_EDITUNDO_SETSTYLE
+{
+ Text [ en-US ] = "Apply Styles" ;
+};
+
+String RID_EDITUNDO_TRANSLITERATE
+{
+ Text [ en-US ] = "Case/Characters";
+};
+
+
+Menu RID_MENU_SPELL
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = MN_SPELLING ;
+ HelpId = HID_EDITENG_SPELLER_START;
+ Text [ en-US ] = "~Spellcheck..." ;
+ };
+ MenuItem
+ {
+ Identifier = MN_INSERT ;
+ HelpId = HID_EDITENG_SPELLER_ADDWORD;
+ SubMenu = Menu
+ {
+ };
+ Text [ en-US ] = "~Add" ;
+ };
+ MenuItem
+ {
+ Identifier = MN_IGNORE ;
+ HelpId = HID_EDITENG_SPELLER_IGNORE;
+ Text [ en-US ] = "Ignore All" ;
+ };
+ MenuItem
+ {
+ Identifier = MN_AUTOCORR ;
+ HelpId = HID_EDITENG_SPELLER_AUTOCORRECT;
+ SubMenu = Menu
+ {
+ };
+ Text [ en-US ] = "AutoCorrect" ;
+ };
+ };
+};
+
+
+String RID_STR_WORD
+{
+ Text [ en-US ] = "Word is %x";
+};
+
+String RID_STR_PARAGRAPH
+{
+ Text [ en-US ] = "Paragraph is %x";
+};
+
diff --git a/editeng/source/editeng/editobj.cxx b/editeng/source/editeng/editobj.cxx
new file mode 100644
index 0000000000..c224410ca0
--- /dev/null
+++ b/editeng/source/editeng/editobj.cxx
@@ -0,0 +1,1728 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: editobj.cxx,v $
+ * $Revision: 1.30 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <vcl/wrkwin.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+
+#define ENABLE_STRING_STREAM_OPERATORS
+#include <tools/stream.hxx>
+
+#include <editobj2.hxx>
+#include <editeng/editdata.hxx>
+#include <editattr.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/cscoitem.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/tstpitem.hxx>
+#include <editeng/bulitem.hxx>
+#include <editeng/numitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <vcl/graph.hxx>
+#include <svl/intitem.hxx>
+#include <unotools/fontcvt.hxx>
+#include <tools/tenccvt.hxx>
+
+DBG_NAME( EE_EditTextObject )
+DBG_NAME( XEditAttribute )
+
+//--------------------------------------------------------------
+
+BOOL lcl_CreateBulletItem( const SvxNumBulletItem& rNumBullet, USHORT nLevel, SvxBulletItem& rBullet )
+{
+ const SvxNumberFormat* pFmt = rNumBullet.GetNumRule()->Get( nLevel );
+ if ( pFmt )
+ {
+ rBullet.SetWidth( (-pFmt->GetFirstLineOffset()) + pFmt->GetCharTextDistance() );
+ rBullet.SetSymbol( pFmt->GetBulletChar() );
+ rBullet.SetPrevText( pFmt->GetPrefix() );
+ rBullet.SetFollowText( pFmt->GetSuffix() );
+ rBullet.SetStart( pFmt->GetStart() );
+ rBullet.SetScale( pFmt->GetBulletRelSize() );
+
+ Font aBulletFont( rBullet.GetFont() );
+ if ( pFmt->GetBulletFont() )
+ aBulletFont = *pFmt->GetBulletFont();
+ aBulletFont.SetColor( pFmt->GetBulletColor() );
+ rBullet.SetFont( aBulletFont );
+
+ if ( pFmt->GetBrush() && pFmt->GetBrush()->GetGraphic() )
+ {
+ Bitmap aBmp( pFmt->GetBrush()->GetGraphic()->GetBitmap() );
+ aBmp.SetPrefSize( pFmt->GetGraphicSize() );
+ aBmp.SetPrefMapMode( MAP_100TH_MM );
+ rBullet.SetBitmap( aBmp );
+ }
+
+ switch ( pFmt->GetNumberingType() )
+ {
+ case SVX_NUM_CHARS_UPPER_LETTER:
+ case SVX_NUM_CHARS_UPPER_LETTER_N:
+ rBullet.SetStyle( BS_ABC_BIG );
+ break;
+ case SVX_NUM_CHARS_LOWER_LETTER:
+ case SVX_NUM_CHARS_LOWER_LETTER_N:
+ rBullet.SetStyle( BS_ABC_SMALL );
+ break;
+ case SVX_NUM_ROMAN_UPPER:
+ rBullet.SetStyle( BS_ROMAN_BIG );
+ break;
+ case SVX_NUM_ROMAN_LOWER:
+ rBullet.SetStyle( BS_ROMAN_SMALL );
+ break;
+ case SVX_NUM_ARABIC:
+ rBullet.SetStyle( BS_123 );
+ break;
+ case SVX_NUM_NUMBER_NONE:
+ rBullet.SetStyle( BS_NONE );
+ break;
+ case SVX_NUM_CHAR_SPECIAL:
+ rBullet.SetStyle( BS_BULLET );
+ break;
+ case SVX_NUM_PAGEDESC:
+ DBG_ERROR( "Unknown: SVX_NUM_PAGEDESC" );
+ rBullet.SetStyle( BS_BULLET );
+ break;
+ case SVX_NUM_BITMAP:
+ rBullet.SetStyle( BS_BMP );
+ break;
+ default:
+ DBG_ERROR( "Unknown NumType" );
+ }
+
+ switch ( pFmt->GetNumAdjust() )
+ {
+ case SVX_ADJUST_LEFT:
+ rBullet.SetJustification( BJ_VCENTER|BJ_HLEFT );
+ break;
+ case SVX_ADJUST_RIGHT:
+ rBullet.SetJustification( BJ_VCENTER|BJ_HRIGHT );
+ break;
+ case SVX_ADJUST_CENTER:
+ rBullet.SetJustification( BJ_VCENTER|BJ_HCENTER );
+ break;
+ default:
+ DBG_ERROR( "Unknown or invalid NumAdjust" );
+ }
+ }
+ return pFmt ? TRUE : FALSE;
+}
+
+
+XEditAttribute* MakeXEditAttribute( SfxItemPool& rPool, const SfxPoolItem& rItem, USHORT nStart, USHORT nEnd )
+{
+ // das neue Attribut im Pool anlegen
+ const SfxPoolItem& rNew = rPool.Put( rItem );
+
+ XEditAttribute* pNew = new XEditAttribute( rNew, nStart, nEnd );
+ return pNew;
+}
+
+
+XEditAttribute::XEditAttribute( const SfxPoolItem& rAttr )
+{
+ DBG_CTOR( XEditAttribute, 0 );
+ pItem = &rAttr;
+ nStart = 0;
+ nEnd = 0;
+}
+
+XEditAttribute::XEditAttribute( const SfxPoolItem& rAttr, USHORT nS, USHORT nE )
+{
+ DBG_CTOR( XEditAttribute, 0 );
+ pItem = &rAttr;
+ nStart = nS;
+ nEnd = nE;
+}
+
+XEditAttribute::~XEditAttribute()
+{
+ DBG_DTOR( XEditAttribute, 0 );
+ pItem = 0; // Gehoert dem Pool.
+}
+
+XEditAttribute* XEditAttributeList::FindAttrib( USHORT _nWhich, USHORT nChar ) const
+{
+ for ( USHORT n = Count(); n; )
+ {
+ XEditAttribute* pAttr = GetObject( --n );
+ if( ( pAttr->GetItem()->Which() == _nWhich ) && ( pAttr->GetStart() <= nChar ) && ( pAttr->GetEnd() > nChar ) )
+ return pAttr;
+ }
+ return NULL;
+}
+
+ContentInfo::ContentInfo( SfxItemPool& rPool ) : aParaAttribs( rPool, EE_PARA_START, EE_CHAR_END )
+{
+ eFamily = SFX_STYLE_FAMILY_PARA;
+ pWrongs = NULL;
+/* cl removed because not needed anymore since binfilter
+ pTempLoadStoreInfos = NULL;
+*/
+}
+
+// Richtiger CopyCTOR unsinning, weil ich mit einem anderen Pool arbeiten muss!
+ContentInfo::ContentInfo( const ContentInfo& rCopyFrom, SfxItemPool& rPoolToUse )
+ : aParaAttribs( rPoolToUse, EE_PARA_START, EE_CHAR_END )
+{
+ pWrongs = NULL;
+/* cl removed because not needed anymore since binfilter
+ pTempLoadStoreInfos = NULL;
+*/
+ if ( rCopyFrom.GetWrongList() )
+ pWrongs = rCopyFrom.GetWrongList()->Clone();
+ // So sollten die Items im richtigen Pool landen!
+ aParaAttribs.Set( rCopyFrom.GetParaAttribs() );
+ aText = rCopyFrom.GetText();
+ aStyle = rCopyFrom.GetStyle();
+ eFamily = rCopyFrom.GetFamily();
+
+ // Attribute kopieren...
+ for ( USHORT n = 0; n < rCopyFrom.GetAttribs().Count(); n++ )
+ {
+ XEditAttribute* pAttr = rCopyFrom.GetAttribs().GetObject( n );
+ XEditAttribute* pMyAttr = MakeXEditAttribute( rPoolToUse, *pAttr->GetItem(), pAttr->GetStart(), pAttr->GetEnd() );
+ aAttribs.Insert( pMyAttr, aAttribs.Count() );
+ }
+
+ // Wrongs
+ pWrongs = NULL;
+#ifndef SVX_LIGHT
+ if ( rCopyFrom.GetWrongList() )
+ pWrongs = rCopyFrom.GetWrongList()->Clone();
+#endif // !SVX_LIGHT
+}
+
+ContentInfo::~ContentInfo()
+{
+ for ( USHORT nAttr = 0; nAttr < aAttribs.Count(); nAttr++ )
+ {
+ XEditAttribute* pAttr = aAttribs.GetObject(nAttr);
+ // Item aus Pool entfernen!
+ aParaAttribs.GetPool()->Remove( *pAttr->GetItem() );
+ delete pAttr;
+ }
+ aAttribs.Remove( 0, aAttribs.Count() );
+#ifndef SVX_LIGHT
+ delete pWrongs;
+#endif
+}
+
+/* cl removed because not needed anymore since binfilter
+void ContentInfo::CreateLoadStoreTempInfos()
+{
+ delete pTempLoadStoreInfos;
+ pTempLoadStoreInfos = new LoadStoreTempInfos;
+}
+
+void ContentInfo::DestroyLoadStoreTempInfos()
+{
+ delete pTempLoadStoreInfos;
+ pTempLoadStoreInfos = NULL;
+}
+*/
+
+// #i102062#
+bool ContentInfo::isWrongListEqual(const ContentInfo& rCompare) const
+{
+ if(GetWrongList() == rCompare.GetWrongList())
+ return true;
+
+ if(!GetWrongList() || !rCompare.GetWrongList())
+ return false;
+
+ return (*GetWrongList() == *rCompare.GetWrongList());
+}
+
+bool ContentInfo::operator==( const ContentInfo& rCompare ) const
+{
+ if( (aText == rCompare.aText) &&
+ (aStyle == rCompare.aStyle ) &&
+ (aAttribs.Count() == rCompare.aAttribs.Count() ) &&
+ (eFamily == rCompare.eFamily ) &&
+ (aParaAttribs == rCompare.aParaAttribs ) )
+ {
+ const USHORT nCount = aAttribs.Count();
+ if( nCount == rCompare.aAttribs.Count() )
+ {
+ USHORT n;
+ for( n = 0; n < nCount; n++ )
+ {
+ if( !(*aAttribs.GetObject(n) == *rCompare.aAttribs.GetObject(n)) )
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+EditTextObject::EditTextObject( USHORT n)
+{
+ DBG_CTOR( EE_EditTextObject, 0 );
+ nWhich = n;
+}
+
+EditTextObject::EditTextObject( const EditTextObject& r )
+{
+ DBG_CTOR( EE_EditTextObject, 0 );
+ nWhich = r.nWhich;
+}
+
+__EXPORT EditTextObject::~EditTextObject()
+{
+ DBG_DTOR( EE_EditTextObject, 0 );
+}
+
+USHORT EditTextObject::GetParagraphCount() const
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return 0;
+}
+
+XubString EditTextObject::GetText( USHORT /* nParagraph */ ) const
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return XubString();
+}
+
+void EditTextObject::Insert( const EditTextObject& /* rObj */, USHORT /* nPara */)
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+}
+
+EditTextObject* EditTextObject::CreateTextObject( USHORT /*nPara*/, USHORT /*nParas*/ ) const
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return 0;
+}
+
+void EditTextObject::RemoveParagraph( USHORT /*nPara*/ )
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+}
+
+BOOL EditTextObject::HasPortionInfo() const
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return FALSE;
+}
+
+void EditTextObject::ClearPortionInfo()
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+}
+
+BOOL EditTextObject::HasOnlineSpellErrors() const
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return FALSE;
+}
+
+BOOL EditTextObject::HasCharAttribs( USHORT ) const
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return FALSE;
+}
+
+void EditTextObject::GetCharAttribs( USHORT /*nPara*/, EECharAttribArray& /*rLst*/ ) const
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+}
+
+void EditTextObject::MergeParaAttribs( const SfxItemSet& /*rAttribs*/, USHORT /*nStart*/, USHORT /*nEnd*/ )
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+}
+
+BOOL EditTextObject::IsFieldObject() const
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return FALSE;
+}
+
+const SvxFieldItem* EditTextObject::GetField() const
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return 0;
+}
+
+BOOL EditTextObject::HasField( TypeId /*aType*/ ) const
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return FALSE;
+}
+
+SfxItemSet EditTextObject::GetParaAttribs( USHORT /*nPara*/ ) const
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return SfxItemSet( *(SfxItemPool*)NULL );
+}
+
+void EditTextObject::SetParaAttribs( USHORT /*nPara*/, const SfxItemSet& /*rAttribs*/ )
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+}
+
+BOOL EditTextObject::RemoveCharAttribs( USHORT /*nWhich*/ )
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return FALSE;
+}
+
+BOOL EditTextObject::RemoveParaAttribs( USHORT /*nWhich*/ )
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return FALSE;
+}
+
+BOOL EditTextObject::HasStyleSheet( const XubString& /*rName*/, SfxStyleFamily /*eFamily*/ ) const
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return FALSE;
+}
+
+void EditTextObject::GetStyleSheet( USHORT /*nPara*/, XubString& /*rName*/, SfxStyleFamily& /*eFamily*/ ) const
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+}
+
+void EditTextObject::SetStyleSheet( USHORT /*nPara*/, const XubString& /*rName*/, const SfxStyleFamily& /*eFamily*/ )
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+}
+
+BOOL __EXPORT EditTextObject::ChangeStyleSheets( const XubString&, SfxStyleFamily,
+ const XubString&, SfxStyleFamily )
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return FALSE;
+}
+
+void __EXPORT EditTextObject::ChangeStyleSheetName( SfxStyleFamily /*eFamily*/,
+ const XubString& /*rOldName*/, const XubString& /*rNewName*/ )
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+}
+
+USHORT EditTextObject::GetUserType() const
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return 0;
+}
+
+void EditTextObject::SetUserType( USHORT )
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+}
+
+ULONG EditTextObject::GetObjectSettings() const
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return 0;
+}
+
+void EditTextObject::SetObjectSettings( ULONG )
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+}
+
+BOOL EditTextObject::IsVertical() const
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return FALSE;
+}
+
+void EditTextObject::SetVertical( BOOL bVertical )
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ ((BinTextObject*)this)->SetVertical( bVertical );
+}
+
+USHORT EditTextObject::GetScriptType() const
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return ((const BinTextObject*)this)->GetScriptType();
+}
+
+
+BOOL EditTextObject::Store( SvStream& rOStream ) const
+{
+ if ( rOStream.GetError() )
+ return FALSE;
+
+ // Vorspann:
+ sal_Size nStartPos = rOStream.Tell();
+
+ rOStream << (USHORT)Which();
+
+ sal_uInt32 nStructSz = 0;
+ rOStream << nStructSz;
+
+ // Eigene Daten:
+ StoreData( rOStream );
+
+ // Nachspann:
+ sal_Size nEndPos = rOStream.Tell();
+ nStructSz = nEndPos - nStartPos - sizeof( nWhich ) - sizeof( nStructSz );
+ rOStream.Seek( nStartPos + sizeof( nWhich ) );
+ rOStream << nStructSz;
+ rOStream.Seek( nEndPos );
+
+ return rOStream.GetError() ? FALSE : TRUE;
+}
+
+EditTextObject* EditTextObject::Create( SvStream& rIStream, SfxItemPool* pGlobalTextObjectPool )
+{
+ ULONG nStartPos = rIStream.Tell();
+
+ // Ertmal sehen, was fuer ein Object...
+ USHORT nWhich;
+ rIStream >> nWhich;
+
+ sal_uInt32 nStructSz;
+ rIStream >> nStructSz;
+
+ DBG_ASSERT( ( nWhich == 0x22 /*EE_FORMAT_BIN300*/ ) || ( nWhich == EE_FORMAT_BIN ), "CreateTextObject: Unbekanntes Objekt!" );
+
+ if ( rIStream.GetError() )
+ return NULL;
+
+ EditTextObject* pTxtObj = NULL;
+ switch ( nWhich )
+ {
+ case 0x22 /*BIN300*/: pTxtObj = new BinTextObject( 0 );
+ ((BinTextObject*)pTxtObj)->CreateData300( rIStream );
+ break;
+ case EE_FORMAT_BIN: pTxtObj = new BinTextObject( pGlobalTextObjectPool );
+ pTxtObj->CreateData( rIStream );
+ break;
+ default:
+ {
+ // Wenn ich das Format nicht kenne, ueberlese ich den Inhalt:
+ rIStream.SetError( EE_READWRITE_WRONGFORMAT );
+ }
+ }
+
+ // Sicherstellen, dass der Stream an der richtigen Stelle hinterlassen wird.
+ sal_Size nFullSz = sizeof( nWhich ) + sizeof( nStructSz ) + nStructSz;
+ rIStream.Seek( nStartPos + nFullSz );
+ return pTxtObj;
+}
+
+void EditTextObject::Skip( SvStream& rIStream )
+{
+ sal_Size nStartPos = rIStream.Tell();
+
+ USHORT _nWhich;
+ rIStream >> _nWhich;
+
+ sal_uInt32 nStructSz;
+ rIStream >> nStructSz;
+
+ sal_Size nFullSz = sizeof( _nWhich ) + sizeof( nStructSz ) + nStructSz;
+ rIStream.Seek( nStartPos + nFullSz );
+}
+
+void __EXPORT EditTextObject::StoreData( SvStream& ) const
+{
+ DBG_ERROR( "StoreData: Basisklasse!" );
+}
+
+void __EXPORT EditTextObject::CreateData( SvStream& )
+{
+ DBG_ERROR( "CreateData: Basisklasse!" );
+}
+
+USHORT EditTextObject::GetVersion() const
+{
+ DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
+ return 0;
+}
+
+bool EditTextObject::operator==( const EditTextObject& rCompare ) const
+{
+ return static_cast< const BinTextObject* >( this )->operator==( static_cast< const BinTextObject& >( rCompare ) );
+}
+
+// #i102062#
+bool EditTextObject::isWrongListEqual(const EditTextObject& rCompare) const
+{
+ return static_cast< const BinTextObject* >(this)->isWrongListEqual(static_cast< const BinTextObject& >(rCompare));
+}
+
+// from SfxItemPoolUser
+void BinTextObject::ObjectInDestruction(const SfxItemPool& rSfxItemPool)
+{
+ if(!bOwnerOfPool && pPool && pPool == &rSfxItemPool)
+ {
+ // The pool we are based on gets destructed; get owner of pool by creating own one.
+ // No need to call RemoveSfxItemPoolUser(), this is done from the pool's destructor
+ // Base new pool on EditEnginePool; it would also be possible to clone the used
+ // pool if needed, but only text attributes should be used.
+ SfxItemPool* pNewPool = EditEngine::CreatePool();
+
+ if(pPool)
+ {
+ pNewPool->SetDefaultMetric(pPool->GetMetric(DEF_METRIC));
+ }
+
+ for(sal_uInt16 n(0); n < aContents.Count(); n++)
+ {
+ // clone ContentInfos for new pool
+ ContentInfo* pOrg = aContents.GetObject(n);
+ DBG_ASSERT(pOrg, "NULL-Pointer in ContentList!");
+
+ ContentInfo* pNew = new ContentInfo(*pOrg, *pNewPool);
+ aContents.Replace(pNew, n);
+ delete pOrg;
+ }
+
+ // set local variables
+ pPool = pNewPool;
+ bOwnerOfPool = TRUE;
+ }
+}
+
+EditEngineItemPool* getEditEngineItemPool(SfxItemPool* pPool)
+{
+ EditEngineItemPool* pRetval = dynamic_cast< EditEngineItemPool* >(pPool);
+
+ while(!pRetval && pPool && pPool->GetSecondaryPool())
+ {
+ pPool = pPool->GetSecondaryPool();
+
+ if(pPool)
+ {
+ pRetval = dynamic_cast< EditEngineItemPool* >(pPool);
+ }
+ }
+
+ return pRetval;
+}
+
+BinTextObject::BinTextObject( SfxItemPool* pP ) :
+ EditTextObject( EE_FORMAT_BIN ),
+ SfxItemPoolUser()
+{
+ nVersion = 0;
+ nMetric = 0xFFFF;
+ nUserType = 0;
+ nObjSettings = 0;
+ pPortionInfo = 0;
+
+ // #i101239# ensure target is a EditEngineItemPool, else
+ // fallback to pool ownership. This is needed to ensure that at
+ // pool destruction time of an alien pool, the pool is still alive.
+ // When registering would happen at an alien pool which just uses an
+ // EditEngineItemPool as some sub-pool, that pool could already
+ // be decoupled and deleted whcih would lead to crashes.
+ pPool = getEditEngineItemPool(pP);
+
+ if ( pPool )
+ {
+ bOwnerOfPool = FALSE;
+ }
+ else
+ {
+ pPool = EditEngine::CreatePool();
+ bOwnerOfPool = TRUE;
+ }
+
+ if(!bOwnerOfPool && pPool)
+ {
+ // it is sure now that the pool is an EditEngineItemPool
+ pPool->AddSfxItemPoolUser(*this);
+ }
+
+ bVertical = FALSE;
+ bStoreUnicodeStrings = FALSE;
+ nScriptType = 0;
+}
+
+BinTextObject::BinTextObject( const BinTextObject& r ) :
+ EditTextObject( r ),
+ SfxItemPoolUser()
+{
+ nVersion = r.nVersion;
+ nMetric = r.nMetric;
+ nUserType = r.nUserType;
+ nObjSettings = r.nObjSettings;
+ bVertical = r.bVertical;
+ nScriptType = r.nScriptType;
+ pPortionInfo = NULL; // PortionInfo nicht kopieren
+ bStoreUnicodeStrings = FALSE;
+
+ if ( !r.bOwnerOfPool )
+ {
+ // reuse alien pool; this must be a EditEngineItemPool
+ // since there is no other way to construct a BinTextObject
+ // than it's regular constructor where that is ensured
+ pPool = r.pPool;
+ bOwnerOfPool = FALSE;
+ }
+ else
+ {
+ pPool = EditEngine::CreatePool();
+ bOwnerOfPool = TRUE;
+
+ }
+
+ if(!bOwnerOfPool && pPool)
+ {
+ // it is sure now that the pool is an EditEngineItemPool
+ pPool->AddSfxItemPoolUser(*this);
+ }
+
+ if ( bOwnerOfPool && pPool && r.pPool )
+ pPool->SetDefaultMetric( r.pPool->GetMetric( DEF_METRIC ) );
+
+ for ( USHORT n = 0; n < r.aContents.Count(); n++ )
+ {
+ ContentInfo* pOrg = r.aContents.GetObject( n );
+ DBG_ASSERT( pOrg, "NULL-Pointer in ContentList!" );
+ ContentInfo* pNew = new ContentInfo( *pOrg, *pPool );
+ aContents.Insert( pNew, aContents.Count() );
+ }
+}
+
+__EXPORT BinTextObject::~BinTextObject()
+{
+ if(!bOwnerOfPool && pPool)
+ {
+ pPool->RemoveSfxItemPoolUser(*this);
+ }
+
+ ClearPortionInfo();
+ DeleteContents();
+ if ( bOwnerOfPool )
+ {
+ // Nicht mehr, wegen 1xDefItems.
+ // siehe auch ~EditDoc().
+// pPool->ReleaseDefaults( TRUE /* bDelete */ );
+ SfxItemPool::Free(pPool);
+ }
+}
+
+USHORT BinTextObject::GetUserType() const
+{
+ return nUserType;
+}
+
+void BinTextObject::SetUserType( USHORT n )
+{
+ nUserType = n;
+}
+
+ULONG BinTextObject::GetObjectSettings() const
+{
+ return nObjSettings;
+}
+
+void BinTextObject::SetObjectSettings( ULONG n )
+{
+ nObjSettings = n;
+}
+
+BOOL BinTextObject::IsVertical() const
+{
+ return bVertical;
+}
+
+void BinTextObject::SetVertical( BOOL b )
+{
+ if ( b != bVertical )
+ {
+ bVertical = b;
+ ClearPortionInfo();
+ }
+}
+
+USHORT BinTextObject::GetScriptType() const
+{
+ return nScriptType;
+}
+
+void BinTextObject::SetScriptType( USHORT nType )
+{
+ nScriptType = nType;
+}
+
+
+void BinTextObject::DeleteContents()
+{
+ for ( USHORT n = 0; n < aContents.Count(); n++ )
+ {
+ ContentInfo* p = aContents.GetObject( n );
+ DBG_ASSERT( p, "NULL-Pointer in ContentList!" );
+ delete p;
+ }
+ aContents.Remove( 0, aContents.Count() );
+}
+
+EditTextObject* __EXPORT BinTextObject::Clone() const
+{
+ return new BinTextObject( *this );
+}
+
+XEditAttribute* BinTextObject::CreateAttrib( const SfxPoolItem& rItem, USHORT nStart, USHORT nEnd )
+{
+ return MakeXEditAttribute( *pPool, rItem, nStart, nEnd );
+}
+
+void BinTextObject::DestroyAttrib( XEditAttribute* pAttr )
+{
+ pPool->Remove( *pAttr->GetItem() );
+ delete pAttr;
+}
+
+ContentInfo* BinTextObject::CreateAndInsertContent()
+{
+ ContentInfo* pC = new ContentInfo( *pPool );
+ aContents.Insert( pC, aContents.Count() );
+ return pC;
+}
+
+USHORT BinTextObject::GetParagraphCount() const
+{
+ return aContents.Count();
+}
+
+XubString BinTextObject::GetText( USHORT nPara ) const
+{
+ DBG_ASSERT( nPara < aContents.Count(), "BinTextObject::GetText: Absatz existiert nicht!" );
+ if ( nPara < aContents.Count() )
+ {
+ ContentInfo* pC = aContents[ nPara ];
+ return pC->GetText();
+ }
+ return XubString();
+}
+
+void BinTextObject::Insert( const EditTextObject& rObj, USHORT nDestPara )
+{
+ DBG_ASSERT( rObj.Which() == EE_FORMAT_BIN, "UTO: Unbekanntes Textobjekt" );
+
+ const BinTextObject& rBinObj = (const BinTextObject&)rObj;
+
+ if ( nDestPara > aContents.Count() )
+ nDestPara = aContents.Count();
+
+ const USHORT nParas = rBinObj.GetContents().Count();
+ for ( USHORT nP = 0; nP < nParas; nP++ )
+ {
+ ContentInfo* pC = rBinObj.GetContents()[ nP ];
+ ContentInfo* pNew = new ContentInfo( *pC, *GetPool() );
+ aContents.Insert( pNew, nDestPara+nP );
+ }
+ ClearPortionInfo();
+}
+
+EditTextObject* BinTextObject::CreateTextObject( USHORT nPara, USHORT nParas ) const
+{
+ if ( ( nPara >= aContents.Count() ) || !nParas )
+ return NULL;
+
+ // Pool nur teilen, wenn von aussen eingestellter Pool.
+ BinTextObject* pObj = new BinTextObject( bOwnerOfPool ? 0 : pPool );
+ if ( bOwnerOfPool && pPool )
+ pObj->GetPool()->SetDefaultMetric( pPool->GetMetric( DEF_METRIC ) );
+
+ // If complete text is only one ScriptType, this is valid.
+ // If text contains different ScriptTypes, this shouldn't be a problem...
+ pObj->nScriptType = nScriptType;
+
+ const USHORT nEndPara = nPara+nParas-1;
+ for ( USHORT nP = nPara; nP <= nEndPara; nP++ )
+ {
+ ContentInfo* pC = aContents[ nP ];
+ ContentInfo* pNew = new ContentInfo( *pC, *pObj->GetPool() );
+ pObj->GetContents().Insert( pNew, pObj->GetContents().Count() );
+ }
+ return pObj;
+}
+
+void BinTextObject::RemoveParagraph( USHORT nPara )
+{
+ DBG_ASSERT( nPara < aContents.Count(), "BinTextObject::GetText: Absatz existiert nicht!" );
+ if ( nPara < aContents.Count() )
+ {
+ ContentInfo* pC = aContents[ nPara ];
+ aContents.Remove( nPara );
+ delete pC;
+ ClearPortionInfo();
+ }
+}
+
+BOOL BinTextObject::HasPortionInfo() const
+{
+ return pPortionInfo ? TRUE : FALSE;
+}
+
+void BinTextObject::ClearPortionInfo()
+{
+ if ( pPortionInfo )
+ {
+ for ( USHORT n = pPortionInfo->Count(); n; )
+ delete pPortionInfo->GetObject( --n );
+ delete pPortionInfo;
+ pPortionInfo = NULL;
+ }
+}
+
+BOOL BinTextObject::HasOnlineSpellErrors() const
+{
+#ifndef SVX_LIGHT
+ for ( USHORT n = 0; n < aContents.Count(); n++ )
+ {
+ ContentInfo* p = aContents.GetObject( n );
+ if ( p->GetWrongList() && p->GetWrongList()->Count() )
+ return TRUE;
+ }
+#endif // !SVX_LIGHT
+ return FALSE;
+
+}
+
+BOOL BinTextObject::HasCharAttribs( USHORT _nWhich ) const
+{
+ for ( USHORT nPara = GetContents().Count(); nPara; )
+ {
+ ContentInfo* pC = GetContents().GetObject( --nPara );
+
+ USHORT nAttribs = pC->GetAttribs().Count();
+ if ( nAttribs && !_nWhich )
+ return TRUE;
+
+ for ( USHORT nAttr = nAttribs; nAttr; )
+ {
+ XEditAttribute* pX = pC->GetAttribs().GetObject( --nAttr );
+ if ( pX->GetItem()->Which() == _nWhich )
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void BinTextObject::GetCharAttribs( USHORT nPara, EECharAttribArray& rLst ) const
+{
+ rLst.Remove( 0, rLst.Count() );
+ ContentInfo* pC = GetContents().GetObject( nPara );
+ if ( pC )
+ {
+ for ( USHORT nAttr = 0; nAttr < pC->GetAttribs().Count(); nAttr++ )
+ {
+ XEditAttribute* pAttr = pC->GetAttribs().GetObject( nAttr );
+ EECharAttrib aEEAttr;
+ aEEAttr.pAttr = pAttr->GetItem();
+ aEEAttr.nPara = nPara;
+ aEEAttr.nStart = pAttr->GetStart();
+ aEEAttr.nEnd = pAttr->GetEnd();
+ rLst.Insert( aEEAttr, rLst.Count() );
+ }
+ }
+}
+
+void BinTextObject::MergeParaAttribs( const SfxItemSet& rAttribs, USHORT nStart, USHORT nEnd )
+{
+ BOOL bChanged = FALSE;
+
+ for ( USHORT nPara = GetContents().Count(); nPara; )
+ {
+ ContentInfo* pC = GetContents().GetObject( --nPara );
+
+ for ( USHORT nW = nStart; nW <= nEnd; nW++ )
+ {
+ if ( ( pC->GetParaAttribs().GetItemState( nW, FALSE ) != SFX_ITEM_ON )
+ && ( rAttribs.GetItemState( nW, FALSE ) == SFX_ITEM_ON ) )
+ {
+ pC->GetParaAttribs().Put( rAttribs.Get( nW ) );
+ bChanged = TRUE;
+ }
+ }
+ }
+
+ if ( bChanged )
+ ClearPortionInfo();
+}
+
+BOOL BinTextObject::IsFieldObject() const
+{
+ return BinTextObject::GetField() ? TRUE : FALSE;
+}
+
+const SvxFieldItem* BinTextObject::GetField() const
+{
+ if ( GetContents().Count() == 1 )
+ {
+ ContentInfo* pC = GetContents()[0];
+ if ( pC->GetText().Len() == 1 )
+ {
+ USHORT nAttribs = pC->GetAttribs().Count();
+ for ( USHORT nAttr = nAttribs; nAttr; )
+ {
+ XEditAttribute* pX = pC->GetAttribs().GetObject( --nAttr );
+ if ( pX->GetItem()->Which() == EE_FEATURE_FIELD )
+ return (const SvxFieldItem*)pX->GetItem();
+ }
+ }
+ }
+ return 0;
+}
+
+BOOL BinTextObject::HasField( TypeId aType ) const
+{
+ USHORT nParagraphs = GetContents().Count();
+ for ( USHORT nPara = 0; nPara < nParagraphs; nPara++ )
+ {
+ ContentInfo* pC = GetContents().GetObject( nPara );
+ USHORT nAttrs = pC->GetAttribs().Count();
+ for ( USHORT nAttr = 0; nAttr < nAttrs; nAttr++ )
+ {
+ XEditAttribute* pAttr = pC->GetAttribs()[nAttr];
+ if ( pAttr->GetItem()->Which() == EE_FEATURE_FIELD )
+ {
+ if ( !aType )
+ return TRUE;
+
+ const SvxFieldData* pFldData = ((const SvxFieldItem*)pAttr->GetItem())->GetField();
+ if ( pFldData && pFldData->IsA( aType ) )
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+SfxItemSet BinTextObject::GetParaAttribs( USHORT nPara ) const
+{
+ ContentInfo* pC = GetContents().GetObject( nPara );
+ return pC->GetParaAttribs();
+}
+
+void BinTextObject::SetParaAttribs( USHORT nPara, const SfxItemSet& rAttribs )
+{
+ ContentInfo* pC = GetContents().GetObject( nPara );
+ pC->GetParaAttribs().Set( rAttribs );
+ ClearPortionInfo();
+}
+
+BOOL BinTextObject::RemoveCharAttribs( USHORT _nWhich )
+{
+ BOOL bChanged = FALSE;
+
+ for ( USHORT nPara = GetContents().Count(); nPara; )
+ {
+ ContentInfo* pC = GetContents().GetObject( --nPara );
+
+ for ( USHORT nAttr = pC->GetAttribs().Count(); nAttr; )
+ {
+ XEditAttribute* pAttr = pC->GetAttribs().GetObject( --nAttr );
+ if ( !_nWhich || ( pAttr->GetItem()->Which() == _nWhich ) )
+ {
+ pC->GetAttribs().Remove( nAttr );
+ DestroyAttrib( pAttr );
+ bChanged = TRUE;
+ }
+ }
+ }
+
+ if ( bChanged )
+ ClearPortionInfo();
+
+ return bChanged;
+}
+
+BOOL BinTextObject::RemoveParaAttribs( USHORT _nWhich )
+{
+ BOOL bChanged = FALSE;
+
+ for ( USHORT nPara = GetContents().Count(); nPara; )
+ {
+ ContentInfo* pC = GetContents().GetObject( --nPara );
+
+ if ( !_nWhich )
+ {
+ if( pC->GetParaAttribs().Count() )
+ bChanged = TRUE;
+ pC->GetParaAttribs().ClearItem();
+ }
+ else
+ {
+ if ( pC->GetParaAttribs().GetItemState( _nWhich ) == SFX_ITEM_ON )
+ {
+ pC->GetParaAttribs().ClearItem( _nWhich );
+ bChanged = TRUE;
+ }
+ }
+ }
+
+ if ( bChanged )
+ ClearPortionInfo();
+
+ return bChanged;
+}
+
+BOOL BinTextObject::HasStyleSheet( const XubString& rName, SfxStyleFamily eFamily ) const
+{
+ USHORT nParagraphs = GetContents().Count();
+ for ( USHORT nPara = 0; nPara < nParagraphs; nPara++ )
+ {
+ ContentInfo* pC = GetContents().GetObject( nPara );
+ if ( ( pC->GetFamily() == eFamily ) && ( pC->GetStyle() == rName ) )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void BinTextObject::GetStyleSheet( USHORT nPara, XubString& rName, SfxStyleFamily& rFamily ) const
+{
+ if ( nPara < aContents.Count() )
+ {
+ ContentInfo* pC = aContents[ nPara ];
+ rName = pC->GetStyle();
+ rFamily = pC->GetFamily();
+ }
+}
+
+void BinTextObject::SetStyleSheet( USHORT nPara, const XubString& rName, const SfxStyleFamily& rFamily )
+{
+ if ( nPara < aContents.Count() )
+ {
+ ContentInfo* pC = aContents[ nPara ];
+ pC->GetStyle() = rName;
+ pC->GetFamily() = rFamily;
+ }
+}
+
+BOOL BinTextObject::ImpChangeStyleSheets(
+ const XubString& rOldName, SfxStyleFamily eOldFamily,
+ const XubString& rNewName, SfxStyleFamily eNewFamily )
+{
+ const USHORT nParagraphs = GetContents().Count();
+ BOOL bChanges = FALSE;
+
+ for ( USHORT nPara = 0; nPara < nParagraphs; nPara++ )
+ {
+ ContentInfo* pC = GetContents().GetObject( nPara );
+ if ( pC->GetFamily() == eOldFamily )
+ {
+ if ( pC->GetStyle() == rOldName )
+ {
+ pC->GetStyle() = rNewName;
+ pC->GetFamily() = eNewFamily;
+ bChanges = TRUE;
+ }
+ }
+ }
+ return bChanges;
+}
+
+BOOL __EXPORT BinTextObject::ChangeStyleSheets(
+ const XubString& rOldName, SfxStyleFamily eOldFamily,
+ const XubString& rNewName, SfxStyleFamily eNewFamily )
+{
+ BOOL bChanges = ImpChangeStyleSheets( rOldName, eOldFamily, rNewName, eNewFamily );
+ if ( bChanges )
+ ClearPortionInfo();
+
+ return bChanges;
+}
+
+void __EXPORT BinTextObject::ChangeStyleSheetName( SfxStyleFamily eFamily,
+ const XubString& rOldName, const XubString& rNewName )
+{
+ ImpChangeStyleSheets( rOldName, eFamily, rNewName, eFamily );
+}
+
+void __EXPORT BinTextObject::StoreData( SvStream& rOStream ) const
+{
+ USHORT nVer = 602;
+ rOStream << nVer;
+
+ rOStream << bOwnerOfPool;
+
+ // Erst den Pool speichern, spaeter nur noch Surregate
+ if ( bOwnerOfPool )
+ {
+ GetPool()->SetFileFormatVersion( SOFFICE_FILEFORMAT_50 );
+ GetPool()->Store( rOStream );
+ }
+
+ // Aktuelle Zeichensatz speichern...
+ // #90477# GetSOStoreTextEncoding: Bug in 5.2, when default char set is multi byte text encoding
+ rtl_TextEncoding eEncoding = GetSOStoreTextEncoding( gsl_getSystemTextEncoding(), (USHORT) rOStream.GetVersion() );
+ rOStream << (USHORT) eEncoding;
+
+ // Die Anzahl der Absaetze...
+ USHORT nParagraphs = GetContents().Count();
+ rOStream << nParagraphs;
+
+ char cFeatureConverted = ByteString( CH_FEATURE, eEncoding ).GetChar(0);
+
+ // Die einzelnen Absaetze...
+ for ( USHORT nPara = 0; nPara < nParagraphs; nPara++ )
+ {
+ ContentInfo* pC = GetContents().GetObject( nPara );
+
+ // Text...
+ ByteString aText( pC->GetText(), eEncoding );
+
+ // Symbols?
+ BOOL bSymbolPara = FALSE;
+ if ( pC->GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SFX_ITEM_ON )
+ {
+ const SvxFontItem& rFontItem = (const SvxFontItem&)pC->GetParaAttribs().Get( EE_CHAR_FONTINFO );
+ if ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
+ {
+ aText = ByteString( pC->GetText(), RTL_TEXTENCODING_SYMBOL );
+ bSymbolPara = TRUE;
+ }
+ }
+ for ( USHORT nA = 0; nA < pC->GetAttribs().Count(); nA++ )
+ {
+ XEditAttribute* pAttr = pC->GetAttribs().GetObject( nA );
+
+ if ( pAttr->GetItem()->Which() == EE_CHAR_FONTINFO )
+ {
+ const SvxFontItem& rFontItem = (const SvxFontItem&)*pAttr->GetItem();
+ if ( ( !bSymbolPara && ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL ) )
+ || ( bSymbolPara && ( rFontItem.GetCharSet() != RTL_TEXTENCODING_SYMBOL ) ) )
+ {
+ // Not correctly converted
+ String aPart( pC->GetText(), pAttr->GetStart(), pAttr->GetEnd() - pAttr->GetStart() );
+ ByteString aNew( aPart, rFontItem.GetCharSet() );
+ aText.Erase( pAttr->GetStart(), pAttr->GetEnd() - pAttr->GetStart() );
+ aText.Insert( aNew, pAttr->GetStart() );
+ }
+
+ // #88414# Convert StarSymbol back to StarBats
+ FontToSubsFontConverter hConv = CreateFontToSubsFontConverter( rFontItem.GetFamilyName(), FONTTOSUBSFONT_EXPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
+ if ( hConv )
+ {
+ // Don't create a new Attrib with StarBats font, MBR changed the
+ // SvxFontItem::Store() to store StarBats instead of StarSymbol!
+ for ( USHORT nChar = pAttr->GetStart(); nChar < pAttr->GetEnd(); nChar++ )
+ {
+ sal_Unicode cOld = pC->GetText().GetChar( nChar );
+ char cConv = ByteString::ConvertFromUnicode( ConvertFontToSubsFontChar( hConv, cOld ), RTL_TEXTENCODING_SYMBOL );
+ if ( cConv )
+ aText.SetChar( nChar, cConv );
+ }
+
+ DestroyFontToSubsFontConverter( hConv );
+ }
+ }
+ }
+
+ // #88414# Convert StarSymbol back to StarBats
+ // StarSymbol as paragraph attribute or in StyleSheet?
+
+ FontToSubsFontConverter hConv = NULL;
+ if ( pC->GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SFX_ITEM_ON )
+ {
+ hConv = CreateFontToSubsFontConverter( ((const SvxFontItem&)pC->GetParaAttribs().Get( EE_CHAR_FONTINFO )).GetFamilyName(), FONTTOSUBSFONT_EXPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
+ }
+/* cl removed because not needed anymore since binfilter
+
+ else if ( pC->GetStyle().Len() && pC->GetLoadStoreTempInfos() )
+ {
+ hConv = pC->GetLoadStoreTempInfos()->hOldSymbolConv_Store;
+ }
+*/
+ if ( hConv )
+ {
+ for ( USHORT nChar = 0; nChar < pC->GetText().Len(); nChar++ )
+ {
+ if ( !pC->GetAttribs().FindAttrib( EE_CHAR_FONTINFO, nChar ) )
+ {
+ sal_Unicode cOld = pC->GetText().GetChar( nChar );
+ char cConv = ByteString::ConvertFromUnicode( ConvertFontToSubsFontChar( hConv, cOld ), RTL_TEXTENCODING_SYMBOL );
+ if ( cConv )
+ aText.SetChar( nChar, cConv );
+ }
+ }
+
+ DestroyFontToSubsFontConverter( hConv );
+
+ }
+
+
+ // Convert CH_FEATURE to CH_FEATURE_OLD
+ aText.SearchAndReplaceAll( cFeatureConverted, CH_FEATURE_OLD );
+ rOStream.WriteByteString( aText );
+
+ // StyleName und Family...
+ rOStream.WriteByteString( ByteString( pC->GetStyle(), eEncoding ) );
+ rOStream << (USHORT)pC->GetFamily();
+
+ // Absatzattribute...
+ pC->GetParaAttribs().Store( rOStream );
+
+ // Die Anzahl der Attribute...
+ USHORT nAttribs = pC->GetAttribs().Count();
+ rOStream << nAttribs;
+
+ // Und die einzelnen Attribute
+ // Items als Surregate => immer 8 Byte pro Attrib
+ // Which = 2; Surregat = 2; Start = 2; End = 2;
+ for ( USHORT nAttr = 0; nAttr < nAttribs; nAttr++ )
+ {
+ XEditAttribute* pX = pC->GetAttribs().GetObject( nAttr );
+
+ rOStream << pX->GetItem()->Which();
+ GetPool()->StoreSurrogate( rOStream, pX->GetItem() );
+ rOStream << pX->GetStart();
+ rOStream << pX->GetEnd();
+ }
+ }
+
+ // Ab 400:
+ rOStream << nMetric;
+
+ // Ab 600
+ rOStream << nUserType;
+ rOStream << nObjSettings;
+
+ // Ab 601
+ rOStream << bVertical;
+
+ // Ab 602
+ rOStream << nScriptType;
+
+ rOStream << bStoreUnicodeStrings;
+ if ( bStoreUnicodeStrings )
+ {
+ for ( USHORT nPara = 0; nPara < nParagraphs; nPara++ )
+ {
+ ContentInfo* pC = GetContents().GetObject( nPara );
+ USHORT nL = pC->GetText().Len();
+ rOStream << nL;
+ rOStream.Write( pC->GetText().GetBuffer(), nL*sizeof(sal_Unicode) );
+
+ // #91575# StyleSheetName must be Unicode too!
+ // Copy/Paste from EA3 to BETA or from BETA to EA3 not possible, not needed...
+ // If needed, change nL back to ULONG and increase version...
+ nL = pC->GetStyle().Len();
+ rOStream << nL;
+ rOStream.Write( pC->GetStyle().GetBuffer(), nL*sizeof(sal_Unicode) );
+ }
+ }
+}
+
+void __EXPORT BinTextObject::CreateData( SvStream& rIStream )
+{
+ rIStream >> nVersion;
+
+ // Das Textobject wurde erstmal mit der aktuellen Einstellung
+ // von pTextObjectPool erzeugt.
+ BOOL bOwnerOfCurrent = bOwnerOfPool;
+ rIStream >> bOwnerOfPool;
+
+ if ( bOwnerOfCurrent && !bOwnerOfPool )
+ {
+ // Es wurde ein globaler Pool verwendet, mir jetzt nicht uebergeben,
+ // aber ich brauche ihn!
+ DBG_ERROR( "Man gebe mir den globalen TextObjectPool!" );
+ return;
+ }
+ else if ( !bOwnerOfCurrent && bOwnerOfPool )
+ {
+ // Es soll ein globaler Pool verwendet werden, aber dieses
+ // Textobject hat einen eigenen.
+ pPool = EditEngine::CreatePool();
+ }
+
+ if ( bOwnerOfPool )
+ GetPool()->Load( rIStream );
+
+ // CharSet, in dem gespeichert wurde:
+ USHORT nCharSet;
+ rIStream >> nCharSet;
+
+ rtl_TextEncoding eSrcEncoding = GetSOLoadTextEncoding( (rtl_TextEncoding)nCharSet, (USHORT)rIStream.GetVersion() );
+
+ // Die Anzahl der Absaetze...
+ USHORT nParagraphs;
+ rIStream >> nParagraphs;
+
+ // Die einzelnen Absaetze...
+ for ( ULONG nPara = 0; nPara < nParagraphs; nPara++ )
+ {
+ ContentInfo* pC = CreateAndInsertContent();
+
+ // Der Text...
+ ByteString aByteString;
+ rIStream.ReadByteString( aByteString );
+ pC->GetText() = String( aByteString, eSrcEncoding );
+
+ // StyleName und Family...
+ rIStream.ReadByteString( pC->GetStyle(), eSrcEncoding );
+ USHORT nStyleFamily;
+ rIStream >> nStyleFamily;
+ pC->GetFamily() = (SfxStyleFamily)nStyleFamily;
+
+ // Absatzattribute...
+ pC->GetParaAttribs().Load( rIStream );
+
+ // Die Anzahl der Attribute...
+ USHORT nAttribs;
+ rIStream >> nAttribs;
+
+ // Und die einzelnen Attribute
+ // Items als Surregate => immer 8 Byte pro Attrib
+ // Which = 2; Surregat = 2; Start = 2; End = 2;
+ USHORT nAttr;
+ for ( nAttr = 0; nAttr < nAttribs; nAttr++ )
+ {
+ USHORT _nWhich, nStart, nEnd;
+ const SfxPoolItem* pItem;
+
+ rIStream >> _nWhich;
+ _nWhich = pPool->GetNewWhich( _nWhich );
+ pItem = pPool->LoadSurrogate( rIStream, _nWhich, 0 );
+ rIStream >> nStart;
+ rIStream >> nEnd;
+ if ( pItem )
+ {
+ if ( pItem->Which() == EE_FEATURE_NOTCONV )
+ {
+ pC->GetText().SetChar( nStart, ByteString::ConvertToUnicode( aByteString.GetChar( nStart ), ((SvxCharSetColorItem*)pItem)->GetCharSet() ) );
+ }
+ else
+ {
+ XEditAttribute* pAttr = new XEditAttribute( *pItem, nStart, nEnd );
+ pC->GetAttribs().Insert( pAttr, pC->GetAttribs().Count() );
+
+ if ( ( _nWhich >= EE_FEATURE_START ) && ( _nWhich <= EE_FEATURE_END ) )
+ {
+ // Convert CH_FEATURE to CH_FEATURE_OLD
+ DBG_ASSERT( (BYTE) aByteString.GetChar( nStart ) == CH_FEATURE_OLD, "CreateData: CH_FEATURE expected!" );
+ if ( (BYTE) aByteString.GetChar( nStart ) == CH_FEATURE_OLD )
+ pC->GetText().SetChar( nStart, CH_FEATURE );
+ }
+ }
+ }
+ }
+
+ // But check for paragraph and character symbol attribs here,
+ // FinishLoad will not be called in OpenOffice Calc, no StyleSheets...
+
+ BOOL bSymbolPara = FALSE;
+ if ( pC->GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SFX_ITEM_ON )
+ {
+ const SvxFontItem& rFontItem = (const SvxFontItem&)pC->GetParaAttribs().Get( EE_CHAR_FONTINFO );
+ if ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
+ {
+ pC->GetText() = String( aByteString, RTL_TEXTENCODING_SYMBOL );
+ bSymbolPara = TRUE;
+ }
+ }
+
+ for ( nAttr = pC->GetAttribs().Count(); nAttr; )
+ {
+ XEditAttribute* pAttr = pC->GetAttribs().GetObject( --nAttr );
+ if ( pAttr->GetItem()->Which() == EE_CHAR_FONTINFO )
+ {
+ const SvxFontItem& rFontItem = (const SvxFontItem&)*pAttr->GetItem();
+ if ( ( !bSymbolPara && ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL ) )
+ || ( bSymbolPara && ( rFontItem.GetCharSet() != RTL_TEXTENCODING_SYMBOL ) ) )
+ {
+ // Not correctly converted
+ ByteString aPart( aByteString, pAttr->GetStart(), pAttr->GetEnd()-pAttr->GetStart() );
+ String aNew( aPart, rFontItem.GetCharSet() );
+ pC->GetText().Erase( pAttr->GetStart(), pAttr->GetEnd()-pAttr->GetStart() );
+ pC->GetText().Insert( aNew, pAttr->GetStart() );
+ }
+
+ // #88414# Convert StarMath and StarBats to StarSymbol
+ FontToSubsFontConverter hConv = CreateFontToSubsFontConverter( rFontItem.GetFamilyName(), FONTTOSUBSFONT_IMPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
+ if ( hConv )
+ {
+ SvxFontItem aNewFontItem( rFontItem );
+ aNewFontItem.GetFamilyName() = GetFontToSubsFontName( hConv );
+
+ pC->GetAttribs().Remove( nAttr );
+ XEditAttribute* pNewAttr = CreateAttrib( aNewFontItem, pAttr->GetStart(), pAttr->GetEnd() );
+ pC->GetAttribs().Insert( pNewAttr, nAttr );
+ DestroyAttrib( pAttr );
+
+ for ( USHORT nChar = pNewAttr->GetStart(); nChar < pNewAttr->GetEnd(); nChar++ )
+ {
+ sal_Unicode cOld = pC->GetText().GetChar( nChar );
+ DBG_ASSERT( cOld >= 0xF000, "cOld not converted?!" );
+ sal_Unicode cConv = ConvertFontToSubsFontChar( hConv, cOld );
+ if ( cConv )
+ pC->GetText().SetChar( nChar, cConv );
+ }
+
+ DestroyFontToSubsFontConverter( hConv );
+ }
+ }
+ }
+
+
+ // #88414# Convert StarMath and StarBats to StarSymbol
+ // Maybe old symbol font as paragraph attribute?
+ if ( pC->GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SFX_ITEM_ON )
+ {
+ const SvxFontItem& rFontItem = (const SvxFontItem&)pC->GetParaAttribs().Get( EE_CHAR_FONTINFO );
+ FontToSubsFontConverter hConv = CreateFontToSubsFontConverter( rFontItem.GetFamilyName(), FONTTOSUBSFONT_IMPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
+ if ( hConv )
+ {
+ SvxFontItem aNewFontItem( rFontItem );
+ aNewFontItem.GetFamilyName() = GetFontToSubsFontName( hConv );
+ pC->GetParaAttribs().Put( aNewFontItem );
+
+ for ( USHORT nChar = 0; nChar < pC->GetText().Len(); nChar++ )
+ {
+ if ( !pC->GetAttribs().FindAttrib( EE_CHAR_FONTINFO, nChar ) )
+ {
+ sal_Unicode cOld = pC->GetText().GetChar( nChar );
+ DBG_ASSERT( cOld >= 0xF000, "cOld not converted?!" );
+ sal_Unicode cConv = ConvertFontToSubsFontChar( hConv, cOld );
+ if ( cConv )
+ pC->GetText().SetChar( nChar, cConv );
+ }
+ }
+
+ DestroyFontToSubsFontConverter( hConv );
+ }
+ }
+ }
+
+ // Ab 400 auch die DefMetric:
+ if ( nVersion >= 400 )
+ {
+ USHORT nTmpMetric;
+ rIStream >> nTmpMetric;
+ if ( nVersion >= 401 )
+ {
+ // In der 400 gab es noch einen Bug bei Textobjekten mit eigenem
+ // Pool, deshalb erst ab 401 auswerten.
+ nMetric = nTmpMetric;
+ if ( bOwnerOfPool && pPool && ( nMetric != 0xFFFF ) )
+ pPool->SetDefaultMetric( (SfxMapUnit)nMetric );
+ }
+ }
+
+ if ( nVersion >= 600 )
+ {
+ rIStream >> nUserType;
+ rIStream >> nObjSettings;
+ }
+
+ if ( nVersion >= 601 )
+ {
+ rIStream >> bVertical;
+ }
+
+ if ( nVersion >= 602 )
+ {
+ rIStream >> nScriptType;
+
+ BOOL bUnicodeStrings;
+ rIStream >> bUnicodeStrings;
+ if ( bUnicodeStrings )
+ {
+ for ( USHORT nPara = 0; nPara < nParagraphs; nPara++ )
+ {
+ ContentInfo* pC = GetContents().GetObject( nPara );
+ USHORT nL;
+
+ // Text
+ rIStream >> nL;
+ if ( nL )
+ {
+ pC->GetText().AllocBuffer( nL );
+ rIStream.Read( pC->GetText().GetBufferAccess(), nL*sizeof(sal_Unicode) );
+ pC->GetText().ReleaseBufferAccess( (USHORT)nL );
+ }
+
+ // StyleSheetName
+ rIStream >> nL;
+ if ( nL )
+ {
+ pC->GetStyle().AllocBuffer( nL );
+ rIStream.Read( pC->GetStyle().GetBufferAccess(), nL*sizeof(sal_Unicode) );
+ pC->GetStyle().ReleaseBufferAccess( (USHORT)nL );
+ }
+ }
+ }
+ }
+
+
+ // Ab 500 werden die Tabs anders interpretiert: TabPos + LI, vorher nur TabPos.
+ // Wirkt nur wenn auch Tab-Positionen eingestellt wurden, nicht beim DefTab.
+ if ( nVersion < 500 )
+ {
+ for ( USHORT n = 0; n < aContents.Count(); n++ )
+ {
+ ContentInfo* pC = aContents.GetObject( n );
+ const SvxLRSpaceItem& rLRSpace = (const SvxLRSpaceItem&) pC->GetParaAttribs().Get( EE_PARA_LRSPACE );
+ if ( rLRSpace.GetTxtLeft() && ( pC->GetParaAttribs().GetItemState( EE_PARA_TABS ) == SFX_ITEM_ON ) )
+ {
+ const SvxTabStopItem& rTabs = (const SvxTabStopItem&) pC->GetParaAttribs().Get( EE_PARA_TABS );
+ SvxTabStopItem aNewTabs( 0, 0, SVX_TAB_ADJUST_LEFT, EE_PARA_TABS );
+ for ( USHORT t = 0; t < rTabs.Count(); t++ )
+ {
+ const SvxTabStop& rT = rTabs[ t ];
+ aNewTabs.Insert( SvxTabStop( rT.GetTabPos() - rLRSpace.GetTxtLeft(),
+ rT.GetAdjustment(), rT.GetDecimal(), rT.GetFill() ) );
+ }
+ pC->GetParaAttribs().Put( aNewTabs );
+ }
+ }
+ }
+}
+
+USHORT BinTextObject::GetVersion() const
+{
+ return nVersion;
+}
+
+bool BinTextObject::operator==( const BinTextObject& rCompare ) const
+{
+ if( this == &rCompare )
+ return true;
+
+ if( ( aContents.Count() != rCompare.aContents.Count() ) ||
+ ( pPool != rCompare.pPool ) ||
+ ( nMetric != rCompare.nMetric ) ||
+ ( nUserType!= rCompare.nUserType ) ||
+ ( nScriptType != rCompare.nScriptType ) ||
+ ( bVertical != rCompare.bVertical ) )
+ return false;
+
+ USHORT n;
+ for( n = 0; n < aContents.Count(); n++ )
+ {
+ if( !( *aContents.GetObject( n ) == *rCompare.aContents.GetObject( n ) ) )
+ return false;
+ }
+
+ return true;
+}
+
+// #i102062#
+bool BinTextObject::isWrongListEqual(const BinTextObject& rCompare) const
+{
+ if(GetContents().Count() != rCompare.GetContents().Count())
+ {
+ return false;
+ }
+
+ for(USHORT a(0); a < GetContents().Count(); a++)
+ {
+ const ContentInfo& rCandA(*GetContents().GetObject(a));
+ const ContentInfo& rCandB(*rCompare.GetContents().GetObject(a));
+
+ if(!rCandA.isWrongListEqual(rCandB))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+#define CHARSETMARKER 0x9999
+
+void __EXPORT BinTextObject::CreateData300( SvStream& rIStream )
+{
+ // Fuer Aufwaertskompatibilitaet.
+
+ // Erst den Pool laden...
+ // Ist in der 300 immer gespeichert worden!
+ GetPool()->Load( rIStream );
+
+ // Die Anzahl der Absaetze...
+ sal_uInt32 nParagraphs;
+ rIStream >> nParagraphs;
+
+ // Die einzelnen Absaetze...
+ for ( ULONG nPara = 0; nPara < nParagraphs; nPara++ )
+ {
+ ContentInfo* pC = CreateAndInsertContent();
+
+ // Der Text...
+ rIStream.ReadByteString( pC->GetText() );
+
+ // StyleName und Family...
+ rIStream.ReadByteString( pC->GetStyle() );
+ USHORT nStyleFamily;
+ rIStream >> nStyleFamily;
+ pC->GetFamily() = (SfxStyleFamily)nStyleFamily;
+
+ // Absatzattribute...
+ pC->GetParaAttribs().Load( rIStream );
+
+ // Die Anzahl der Attribute...
+ sal_uInt32 nAttribs;
+ rIStream >> nAttribs;
+
+ // Und die einzelnen Attribute
+ // Items als Surregate => immer 8 Byte pro Attrib
+ // Which = 2; Surregat = 2; Start = 2; End = 2;
+ for ( ULONG nAttr = 0; nAttr < nAttribs; nAttr++ )
+ {
+ USHORT _nWhich, nStart, nEnd;
+ const SfxPoolItem* pItem;
+
+ rIStream >> _nWhich;
+ _nWhich = pPool->GetNewWhich( _nWhich );
+ pItem = pPool->LoadSurrogate( rIStream, _nWhich, 0 );
+ rIStream >> nStart;
+ rIStream >> nEnd;
+ if ( pItem )
+ {
+ XEditAttribute* pAttr = new XEditAttribute( *pItem, nStart, nEnd );
+ pC->GetAttribs().Insert( pAttr, pC->GetAttribs().Count() );
+ }
+ }
+ }
+
+ // Prueffen, ob ein Zeichensatz gespeichert wurde
+ USHORT nCharSetMarker;
+ rIStream >> nCharSetMarker;
+ if ( nCharSetMarker == CHARSETMARKER )
+ {
+ USHORT nCharSet;
+ rIStream >> nCharSet;
+ }
+}
diff --git a/editeng/source/editeng/editobj2.hxx b/editeng/source/editeng/editobj2.hxx
new file mode 100644
index 0000000000..4ba6b8b8d9
--- /dev/null
+++ b/editeng/source/editeng/editobj2.hxx
@@ -0,0 +1,312 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: editobj2.hxx,v $
+ * $Revision: 1.14 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _EDITOBJ2_HXX
+#define _EDITOBJ2_HXX
+
+#include <editeng/editobj.hxx>
+#include <editdoc.hxx>
+
+#include <unotools/fontcvt.hxx>
+
+
+class SfxStyleSheetPool;
+
+class XEditAttribute
+{
+ friend class ContentInfo; // fuer DTOR
+ friend class BinTextObject; // fuer DTOR
+
+private:
+ const SfxPoolItem* pItem;
+ USHORT nStart;
+ USHORT nEnd;
+
+ XEditAttribute();
+ XEditAttribute( const XEditAttribute& rCopyFrom );
+
+ ~XEditAttribute();
+
+public:
+ XEditAttribute( const SfxPoolItem& rAttr );
+ XEditAttribute( const SfxPoolItem& rAttr, USHORT nStart, USHORT nEnd );
+
+ const SfxPoolItem* GetItem() const { return pItem; }
+
+ USHORT& GetStart() { return nStart; }
+ USHORT& GetEnd() { return nEnd; }
+
+ USHORT GetStart() const { return nStart; }
+ USHORT GetEnd() const { return nEnd; }
+
+ USHORT GetLen() const { return nEnd-nStart; }
+
+ inline BOOL IsFeature();
+
+ inline bool operator==( const XEditAttribute& rCompare );
+};
+
+inline bool XEditAttribute::operator==( const XEditAttribute& rCompare )
+{
+ return (nStart == rCompare.nStart) &&
+ (nEnd == rCompare.nEnd) &&
+ ( (pItem == rCompare.pItem) ||
+ ( pItem->Which() != rCompare.pItem->Which()) ||
+ (*pItem == *rCompare.pItem));
+}
+
+inline BOOL XEditAttribute::IsFeature()
+{
+ USHORT nWhich = pItem->Which();
+ return ( ( nWhich >= EE_FEATURE_START ) &&
+ ( nWhich <= EE_FEATURE_END ) );
+}
+
+typedef XEditAttribute* XEditAttributePtr;
+SV_DECL_PTRARR( XEditAttributeListImpl, XEditAttributePtr, 0, 4 )
+
+class XEditAttributeList : public XEditAttributeListImpl
+{
+public:
+ XEditAttribute* FindAttrib( USHORT nWhich, USHORT nChar ) const;
+};
+
+struct XParaPortion
+{
+ long nHeight;
+ USHORT nFirstLineOffset;
+
+ EditLineList aLines;
+ TextPortionList aTextPortions;
+};
+
+typedef XParaPortion* XParaPortionPtr;
+SV_DECL_PTRARR( XBaseParaPortionList, XParaPortionPtr, 0, 4 )
+
+class XParaPortionList : public XBaseParaPortionList
+{
+ ULONG nRefDevPtr;
+ OutDevType eRefDevType;
+ MapMode aRefMapMode;
+ ULONG nPaperWidth;
+
+
+public:
+ XParaPortionList( OutputDevice* pRefDev, ULONG nPW ) :
+ aRefMapMode( pRefDev->GetMapMode() )
+ {
+ nRefDevPtr = (ULONG)pRefDev; nPaperWidth = nPW;
+ eRefDevType = pRefDev->GetOutDevType();
+ }
+
+ ULONG GetRefDevPtr() const { return nRefDevPtr; }
+ ULONG GetPaperWidth() const { return nPaperWidth; }
+ OutDevType GetRefDevType() const { return eRefDevType; }
+ const MapMode& GetRefMapMode() const { return aRefMapMode; }
+};
+
+/* cl removed because not needed anymore since binfilter
+struct LoadStoreTempInfos
+{
+ ByteString aOrgString_Load;
+
+ FontToSubsFontConverter hOldSymbolConv_Store;
+ BOOL bSymbolParagraph_Store;
+
+
+ LoadStoreTempInfos() { bSymbolParagraph_Store = FALSE; hOldSymbolConv_Store = NULL; }
+};
+*/
+
+class ContentInfo
+{
+ friend class BinTextObject;
+
+private:
+ String aText;
+ String aStyle;
+ XEditAttributeList aAttribs;
+ SfxStyleFamily eFamily;
+ SfxItemSet aParaAttribs;
+ WrongList* pWrongs;
+
+/* cl removed because not needed anymore since binfilter
+ LoadStoreTempInfos* pTempLoadStoreInfos;
+*/
+
+ ContentInfo( SfxItemPool& rPool );
+ ContentInfo( const ContentInfo& rCopyFrom, SfxItemPool& rPoolToUse );
+
+public:
+ ~ContentInfo();
+
+ const String& GetText() const { return aText; }
+ const String& GetStyle() const { return aStyle; }
+ const XEditAttributeList& GetAttribs() const { return aAttribs; }
+ const SfxItemSet& GetParaAttribs() const { return aParaAttribs; }
+ SfxStyleFamily GetFamily() const { return eFamily; }
+
+ String& GetText() { return aText; }
+ String& GetStyle() { return aStyle; }
+ XEditAttributeList& GetAttribs() { return aAttribs; }
+ SfxItemSet& GetParaAttribs() { return aParaAttribs; }
+ SfxStyleFamily& GetFamily() { return eFamily; }
+
+ WrongList* GetWrongList() const { return pWrongs; }
+ void SetWrongList( WrongList* p ) { pWrongs = p; }
+ bool operator==( const ContentInfo& rCompare ) const;
+
+ // #i102062#
+ bool isWrongListEqual(const ContentInfo& rCompare) const;
+};
+
+typedef ContentInfo* ContentInfoPtr;
+SV_DECL_PTRARR( ContentInfoList, ContentInfoPtr, 1, 4 )
+
+// MT 05/00: Sollte mal direkt EditTextObjekt werden => keine virtuellen Methoden mehr.
+
+class BinTextObject : public EditTextObject, public SfxItemPoolUser
+{
+ using EditTextObject::operator==;
+ using EditTextObject::isWrongListEqual;
+
+private:
+ ContentInfoList aContents;
+ SfxItemPool* pPool;
+ BOOL bOwnerOfPool;
+ XParaPortionList* pPortionInfo;
+
+ sal_uInt32 nObjSettings;
+ USHORT nMetric;
+ USHORT nVersion;
+ USHORT nUserType;
+ USHORT nScriptType;
+
+ BOOL bVertical;
+ BOOL bStoreUnicodeStrings;
+
+protected:
+ void DeleteContents();
+ virtual void StoreData( SvStream& rOStream ) const;
+ virtual void CreateData( SvStream& rIStream );
+ BOOL ImpChangeStyleSheets( const String& rOldName, SfxStyleFamily eOldFamily,
+ const String& rNewName, SfxStyleFamily eNewFamily );
+
+public:
+ BinTextObject( SfxItemPool* pPool );
+ BinTextObject( const BinTextObject& );
+ virtual ~BinTextObject();
+
+ virtual EditTextObject* Clone() const;
+
+ USHORT GetUserType() const;
+ void SetUserType( USHORT n );
+
+ ULONG GetObjectSettings() const;
+ void SetObjectSettings( ULONG n );
+
+ BOOL IsVertical() const;
+ void SetVertical( BOOL b );
+
+ USHORT GetScriptType() const;
+ void SetScriptType( USHORT nType );
+
+ USHORT GetVersion() const; // Solange der Outliner keine Recordlaenge speichert
+
+ ContentInfo* CreateAndInsertContent();
+ XEditAttribute* CreateAttrib( const SfxPoolItem& rItem, USHORT nStart, USHORT nEnd );
+ void DestroyAttrib( XEditAttribute* pAttr );
+
+ ContentInfoList& GetContents() { return aContents; }
+ const ContentInfoList& GetContents() const { return aContents; }
+ SfxItemPool* GetPool() const { return pPool; }
+ XParaPortionList* GetPortionInfo() const { return pPortionInfo; }
+ void SetPortionInfo( XParaPortionList* pP )
+ { pPortionInfo = pP; }
+
+ virtual USHORT GetParagraphCount() const;
+ virtual String GetText( USHORT nParagraph ) const;
+ virtual void Insert( const EditTextObject& rObj, USHORT nPara );
+ virtual EditTextObject* CreateTextObject( USHORT nPara, USHORT nParas = 1 ) const;
+ virtual void RemoveParagraph( USHORT nPara );
+
+ virtual BOOL HasPortionInfo() const;
+ virtual void ClearPortionInfo();
+
+ virtual BOOL HasOnlineSpellErrors() const;
+
+ virtual BOOL HasCharAttribs( USHORT nWhich = 0 ) const;
+ virtual void GetCharAttribs( USHORT nPara, EECharAttribArray& rLst ) const;
+
+ virtual BOOL RemoveCharAttribs( USHORT nWhich = 0 );
+ virtual BOOL RemoveParaAttribs( USHORT nWhich = 0 );
+
+ virtual void MergeParaAttribs( const SfxItemSet& rAttribs, USHORT nStart, USHORT nEnd );
+
+ virtual BOOL IsFieldObject() const;
+ virtual const SvxFieldItem* GetField() const;
+ virtual BOOL HasField( TypeId Type = NULL ) const;
+
+ SfxItemSet GetParaAttribs( USHORT nPara ) const;
+ void SetParaAttribs( USHORT nPara, const SfxItemSet& rAttribs );
+
+ virtual BOOL HasStyleSheet( const XubString& rName, SfxStyleFamily eFamily ) const;
+ virtual void GetStyleSheet( USHORT nPara, XubString& rName, SfxStyleFamily& eFamily ) const;
+ virtual void SetStyleSheet( USHORT nPara, const XubString& rName, const SfxStyleFamily& eFamily );
+ virtual BOOL ChangeStyleSheets( const XubString& rOldName, SfxStyleFamily eOldFamily,
+ const String& rNewName, SfxStyleFamily eNewFamily );
+ virtual void ChangeStyleSheetName( SfxStyleFamily eFamily, const XubString& rOldName, const XubString& rNewName );
+
+ void CreateData300( SvStream& rIStream );
+
+ BOOL HasMetric() const { return nMetric != 0xFFFF; }
+ USHORT GetMetric() const { return nMetric; }
+ void SetMetric( USHORT n ) { nMetric = n; }
+
+ BOOL IsOwnerOfPool() const { return bOwnerOfPool; }
+ void StoreUnicodeStrings( BOOL b ) { bStoreUnicodeStrings = b; }
+
+/* cl removed because not needed anymore since binfilter
+ void PrepareStore( SfxStyleSheetPool* pStyleSheetPool );
+ void FinishStore();
+ void FinishLoad( SfxStyleSheetPool* pStyleSheetPool );
+*/
+
+ bool operator==( const BinTextObject& rCompare ) const;
+
+ // #i102062#
+ bool isWrongListEqual(const BinTextObject& rCompare) const;
+
+ // from SfxItemPoolUser
+ virtual void ObjectInDestruction(const SfxItemPool& rSfxItemPool);
+};
+
+#endif // _EDITOBJ2_HXX
+
diff --git a/editeng/source/editeng/editsel.cxx b/editeng/source/editeng/editsel.cxx
new file mode 100644
index 0000000000..603b12ef87
--- /dev/null
+++ b/editeng/source/editeng/editsel.cxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: editsel.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <eeng_pch.hxx>
+
+#include <editsel.hxx>
+#include <impedit.hxx>
+#include <editeng/editview.hxx>
+
+// ----------------------------------------------------------------------
+// class EditSelFunctionSet
+// ----------------------------------------------------------------------
+EditSelFunctionSet::EditSelFunctionSet()
+{
+ pCurView = NULL;
+}
+
+void __EXPORT EditSelFunctionSet::CreateAnchor()
+{
+ if ( pCurView )
+ pCurView->pImpEditView->CreateAnchor();
+}
+
+void __EXPORT EditSelFunctionSet::DestroyAnchor()
+{
+ // Nur bei Mehrfachselektion
+}
+
+BOOL __EXPORT EditSelFunctionSet::SetCursorAtPoint( const Point& rPointPixel, BOOL )
+{
+ if ( pCurView )
+ return pCurView->pImpEditView->SetCursorAtPoint( rPointPixel );
+
+ return FALSE;
+}
+
+BOOL __EXPORT EditSelFunctionSet::IsSelectionAtPoint( const Point& rPointPixel )
+{
+ if ( pCurView )
+ return pCurView->pImpEditView->IsSelectionAtPoint( rPointPixel );
+
+ return FALSE;
+}
+
+void __EXPORT EditSelFunctionSet::DeselectAtPoint( const Point& )
+{
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// ! Implementieren, wenn Mehrfachselektion moeglich !
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+}
+
+void __EXPORT EditSelFunctionSet::BeginDrag()
+{
+ // Nur bei Mehrfachselektion
+}
+
+
+void __EXPORT EditSelFunctionSet::DeselectAll()
+{
+ if ( pCurView )
+ pCurView->pImpEditView->DeselectAll();
+}
+
+// ----------------------------------------------------------------------
+// class EditSelectionEngine
+// ----------------------------------------------------------------------
+EditSelectionEngine::EditSelectionEngine() : SelectionEngine( (Window*)0 )
+{
+ // Wegen Bug OV: (1994)
+ // 1995: RangeSelection lassen, SingleSelection nur fuer ListBoxen geeignet!
+ SetSelectionMode( RANGE_SELECTION );
+ EnableDrag( TRUE );
+}
+
+void EditSelectionEngine::SetCurView( EditView* pNewView )
+{
+ if ( GetFunctionSet() )
+ ((EditSelFunctionSet*)GetFunctionSet())->SetCurView( pNewView );
+
+ if ( pNewView )
+ SetWindow( pNewView->GetWindow() );
+ else
+ SetWindow( (Window*)0 );
+}
+
+EditView* EditSelectionEngine::GetCurView()
+{
+ EditView* pView = 0;
+ if ( GetFunctionSet() )
+ pView = ((EditSelFunctionSet*)GetFunctionSet())->GetCurView();
+
+ return pView;
+}
+
diff --git a/editeng/source/editeng/editsel.hxx b/editeng/source/editeng/editsel.hxx
new file mode 100644
index 0000000000..bc4b78bb1d
--- /dev/null
+++ b/editeng/source/editeng/editsel.hxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: editsel.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _EDITSEL_HXX
+#define _EDITSEL_HXX
+
+#include <vcl/seleng.hxx>
+
+class EditView;
+
+// ----------------------------------------------------------------------
+// class EditSelFunctionSet
+// ----------------------------------------------------------------------
+class EditSelFunctionSet: public FunctionSet
+{
+private:
+ EditView* pCurView;
+
+public:
+ EditSelFunctionSet();
+
+ virtual void BeginDrag();
+
+ virtual void CreateAnchor();
+ virtual void DestroyAnchor();
+
+ virtual BOOL SetCursorAtPoint( const Point& rPointPixel, BOOL bDontSelectAtCursor = FALSE );
+
+ virtual BOOL IsSelectionAtPoint( const Point& rPointPixel );
+ virtual void DeselectAtPoint( const Point& rPointPixel );
+ virtual void DeselectAll();
+
+ void SetCurView( EditView* pView ) { pCurView = pView; }
+ EditView* GetCurView() { return pCurView; }
+};
+
+ // ----------------------------------------------------------------------
+// class EditSelectionEngine
+// ----------------------------------------------------------------------
+class EditSelectionEngine : public SelectionEngine
+{
+private:
+
+public:
+ EditSelectionEngine();
+
+ void SetCurView( EditView* pNewView );
+ EditView* GetCurView();
+};
+
+#endif // _EDITSEL_HXX
diff --git a/editeng/source/editeng/editstt2.hxx b/editeng/source/editeng/editstt2.hxx
new file mode 100644
index 0000000000..ac70d4e2ec
--- /dev/null
+++ b/editeng/source/editeng/editstt2.hxx
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: editstt2.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _EDITSTT2_HXX
+#define _EDITSTT2_HXX
+
+#include <editeng/editstat.hxx>
+
+class InternalEditStatus : public EditStatus
+{
+
+public:
+ InternalEditStatus() { ; }
+
+ void TurnOnFlags( ULONG nFlags )
+ { nControlBits |= nFlags; }
+
+ void TurnOffFlags( ULONG nFlags )
+ { nControlBits &= ~nFlags; }
+
+ void TurnOnStatusBits( ULONG nBits )
+ { nStatusBits |= nBits; }
+
+ void TurnOffStatusBits( ULONG nBits )
+ { nStatusBits &= ~nBits; }
+
+
+ BOOL UseCharAttribs() const
+ { return ( ( nControlBits & EE_CNTRL_USECHARATTRIBS ) != 0 ); }
+
+ BOOL NotifyCursorMovements() const
+ { return ( ( nControlBits & EE_CNTRL_CRSRLEFTPARA ) != 0 ); }
+
+ BOOL UseIdleFormatter() const
+ { return ( ( nControlBits & EE_CNTRL_DOIDLEFORMAT) != 0 ); }
+
+ BOOL AllowPasteSpecial() const
+ { return ( ( nControlBits & EE_CNTRL_PASTESPECIAL ) != 0 ); }
+
+ BOOL DoAutoIndenting() const
+ { return ( ( nControlBits & EE_CNTRL_AUTOINDENTING ) != 0 ); }
+
+ BOOL DoUndoAttribs() const
+ { return ( ( nControlBits & EE_CNTRL_UNDOATTRIBS ) != 0 ); }
+
+ BOOL OneCharPerLine() const
+ { return ( ( nControlBits & EE_CNTRL_ONECHARPERLINE ) != 0 ); }
+
+ BOOL IsOutliner() const
+ { return ( ( nControlBits & EE_CNTRL_OUTLINER ) != 0 ); }
+
+ BOOL IsOutliner2() const
+ { return ( ( nControlBits & EE_CNTRL_OUTLINER2 ) != 0 ); }
+
+ BOOL IsAnyOutliner() const
+ { return IsOutliner() || IsOutliner2(); }
+
+ BOOL DoNotUseColors() const
+ { return ( ( nControlBits & EE_CNTRL_NOCOLORS ) != 0 ); }
+
+ BOOL AllowBigObjects() const
+ { return ( ( nControlBits & EE_CNTRL_ALLOWBIGOBJS ) != 0 ); }
+
+ BOOL DoOnlineSpelling() const
+ { return ( ( nControlBits & EE_CNTRL_ONLINESPELLING ) != 0 ); }
+
+ BOOL DoStretch() const
+ { return ( ( nControlBits & EE_CNTRL_STRETCHING ) != 0 ); }
+
+ BOOL AutoPageSize() const
+ { return ( ( nControlBits & EE_CNTRL_AUTOPAGESIZE ) != 0 ); }
+ BOOL AutoPageWidth() const
+ { return ( ( nControlBits & EE_CNTRL_AUTOPAGESIZEX ) != 0 ); }
+ BOOL AutoPageHeight() const
+ { return ( ( nControlBits & EE_CNTRL_AUTOPAGESIZEY ) != 0 ); }
+
+ BOOL MarkFields() const
+ { return ( ( nControlBits & EE_CNTRL_MARKFIELDS ) != 0 ); }
+
+ BOOL DoRestoreFont() const
+ { return ( ( nControlBits & EE_CNTRL_RESTOREFONT ) != 0 ); }
+
+ BOOL DoImportRTFStyleSheets() const
+ { return ( ( nControlBits & EE_CNTRL_RTFSTYLESHEETS ) != 0 ); }
+
+ BOOL DoAutoCorrect() const
+ { return ( ( nControlBits & EE_CNTRL_AUTOCORRECT ) != 0 ); }
+
+ BOOL DoAutoComplete() const
+ { return ( ( nControlBits & EE_CNTRL_AUTOCOMPLETE ) != 0 ); }
+
+ BOOL DoTabIndenting() const
+ { return ( ( nControlBits & EE_CNTRL_TABINDENTING ) != 0 ); }
+
+ BOOL DoFormat100() const
+ { return ( ( nControlBits & EE_CNTRL_FORMAT100 ) != 0 ); }
+
+ BOOL ULSpaceSummation() const
+ { return ( ( nControlBits & EE_CNTRL_ULSPACESUMMATION ) != 0 ); }
+
+ BOOL ULSpaceFirstParagraph() const
+ { return ( ( nControlBits & EE_CNTRL_ULSPACEFIRSTPARA ) != 0 ); }
+};
+
+#endif // _EDITSTT2_HXX
+
diff --git a/editeng/source/editeng/editundo.cxx b/editeng/source/editeng/editundo.cxx
new file mode 100644
index 0000000000..8eb74bf9f0
--- /dev/null
+++ b/editeng/source/editeng/editundo.cxx
@@ -0,0 +1,753 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: editundo.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <eeng_pch.hxx>
+
+#include <impedit.hxx>
+#include <editundo.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/editeng.hxx>
+
+DBG_NAME( EditUndo )
+
+#define MAX_UNDOS 100 // ab dieser Menge darf geloescht werden....
+#define MIN_UNDOS 50 // soviel muss stehen bleiben...
+
+#define NO_UNDO 0xFFFF
+#define GROUP_NOTFOUND 0xFFFF
+
+TYPEINIT1( EditUndo, SfxUndoAction );
+TYPEINIT1( EditUndoDelContent, EditUndo );
+TYPEINIT1( EditUndoConnectParas, EditUndo );
+TYPEINIT1( EditUndoSplitPara, EditUndo );
+TYPEINIT1( EditUndoInsertChars, EditUndo );
+TYPEINIT1( EditUndoRemoveChars, EditUndo );
+TYPEINIT1( EditUndoInsertFeature, EditUndo );
+TYPEINIT1( EditUndoMoveParagraphs, EditUndo );
+TYPEINIT1( EditUndoSetStyleSheet, EditUndo );
+TYPEINIT1( EditUndoSetParaAttribs, EditUndo );
+TYPEINIT1( EditUndoSetAttribs, EditUndo );
+TYPEINIT1( EditUndoTransliteration, EditUndo );
+TYPEINIT1( EditUndoMarkSelection, EditUndo );
+
+void lcl_DoSetSelection( EditView* pView, USHORT nPara )
+{
+ EPaM aEPaM( nPara, 0 );
+ EditPaM aPaM( pView->GetImpEditEngine()->CreateEditPaM( aEPaM ) );
+ aPaM.SetIndex( aPaM.GetNode()->Len() );
+ EditSelection aSel( aPaM, aPaM );
+ pView->GetImpEditView()->SetEditSelection( aSel );
+}
+
+ // -----------------------------------------------------------------------
+// EditUndoManager
+// ------------------------------------------------------------------------
+EditUndoManager::EditUndoManager( ImpEditEngine* p )
+{
+ pImpEE = p;
+}
+
+BOOL __EXPORT EditUndoManager::Undo( USHORT nCount )
+{
+ if ( GetUndoActionCount() == 0 )
+ return FALSE;
+
+ DBG_ASSERT( pImpEE->GetActiveView(), "Active View?" );
+
+ if ( !pImpEE->GetActiveView() )
+ {
+ if ( pImpEE->GetEditViews().Count() )
+ pImpEE->SetActiveView( pImpEE->GetEditViews().GetObject(0) );
+ else
+ {
+ DBG_ERROR( "Undo in Engine ohne View nicht moeglich!" );
+ return FALSE;
+ }
+ }
+
+ pImpEE->GetActiveView()->GetImpEditView()->DrawSelection(); // alte Selektion entfernen
+
+ pImpEE->SetUndoMode( TRUE );
+ BOOL bDone = SfxUndoManager::Undo( nCount );
+ pImpEE->SetUndoMode( FALSE );
+
+ EditSelection aNewSel( pImpEE->GetActiveView()->GetImpEditView()->GetEditSelection() );
+ DBG_ASSERT( !aNewSel.IsInvalid(), "Ungueltige Selektion nach Undo()" );
+ DBG_ASSERT( !aNewSel.DbgIsBuggy( pImpEE->GetEditDoc() ), "Kaputte Selektion nach Undo()" );
+
+ aNewSel.Min() = aNewSel.Max();
+ pImpEE->GetActiveView()->GetImpEditView()->SetEditSelection( aNewSel );
+ pImpEE->FormatAndUpdate( pImpEE->GetActiveView() );
+
+ return bDone;
+}
+
+BOOL __EXPORT EditUndoManager::Redo( USHORT nCount )
+{
+ if ( GetRedoActionCount() == 0 )
+ return FALSE;
+
+ DBG_ASSERT( pImpEE->GetActiveView(), "Active View?" );
+
+ if ( !pImpEE->GetActiveView() )
+ {
+ if ( pImpEE->GetEditViews().Count() )
+ pImpEE->SetActiveView( pImpEE->GetEditViews().GetObject(0) );
+ else
+ {
+ DBG_ERROR( "Redo in Engine ohne View nicht moeglich!" );
+ return FALSE;
+ }
+ }
+
+ pImpEE->GetActiveView()->GetImpEditView()->DrawSelection(); // alte Selektion entfernen
+
+ pImpEE->SetUndoMode( TRUE );
+ BOOL bDone = SfxUndoManager::Redo( nCount );
+ pImpEE->SetUndoMode( FALSE );
+
+ EditSelection aNewSel( pImpEE->GetActiveView()->GetImpEditView()->GetEditSelection() );
+ DBG_ASSERT( !aNewSel.IsInvalid(), "Ungueltige Selektion nach Undo()" );
+ DBG_ASSERT( !aNewSel.DbgIsBuggy( pImpEE->GetEditDoc() ), "Kaputte Selektion nach Redo()" );
+
+ aNewSel.Min() = aNewSel.Max();
+ pImpEE->GetActiveView()->GetImpEditView()->SetEditSelection( aNewSel );
+ pImpEE->FormatAndUpdate( pImpEE->GetActiveView() );
+
+ return bDone;
+}
+
+ // -----------------------------------------------------------------------
+// EditUndo
+// ------------------------------------------------------------------------
+EditUndo::EditUndo( USHORT nI, ImpEditEngine* p )
+{
+ DBG_CTOR( EditUndo, 0 );
+ nId = nI;
+ pImpEE = p;
+}
+
+EditUndo::~EditUndo()
+{
+ DBG_DTOR( EditUndo, 0 );
+}
+
+USHORT __EXPORT EditUndo::GetId() const
+{
+ DBG_CHKTHIS( EditUndo, 0 );
+ return nId;
+}
+
+BOOL __EXPORT EditUndo::CanRepeat(SfxRepeatTarget&) const
+{
+ return FALSE;
+}
+
+XubString __EXPORT EditUndo::GetComment() const
+{
+ XubString aComment;
+ if ( pImpEE )
+ {
+ EditEngine* pEditEng = pImpEE->GetEditEnginePtr();
+ aComment = pEditEng->GetUndoComment( GetId() );
+ }
+ return aComment;
+}
+
+ // -----------------------------------------------------------------------
+// EditUndoDelContent
+// ------------------------------------------------------------------------
+EditUndoDelContent::EditUndoDelContent( ImpEditEngine* _pImpEE, ContentNode* pNode, USHORT n )
+ : EditUndo( EDITUNDO_DELCONTENT, _pImpEE )
+{
+ pContentNode = pNode;
+ nNode = n;
+ bDelObject = TRUE;
+}
+
+EditUndoDelContent::~EditUndoDelContent()
+{
+ if ( bDelObject )
+ delete pContentNode;
+}
+
+void __EXPORT EditUndoDelContent::Undo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ GetImpEditEngine()->InsertContent( pContentNode, nNode );
+ bDelObject = FALSE; // gehoert wieder der Engine
+ EditSelection aSel( EditPaM( pContentNode, 0 ), EditPaM( pContentNode, pContentNode->Len() ) );
+ GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aSel );
+}
+
+void __EXPORT EditUndoDelContent::Redo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+
+ ImpEditEngine* _pImpEE = GetImpEditEngine();
+
+ // pNode stimmt nicht mehr, falls zwischendurch Undos, in denen
+ // Absaetze verschmolzen sind.
+ pContentNode = _pImpEE->GetEditDoc().SaveGetObject( nNode );
+ DBG_ASSERT( pContentNode, "EditUndoDelContent::Redo(): Node?!" );
+
+ delete _pImpEE->GetParaPortions()[nNode];
+ _pImpEE->GetParaPortions().Remove( nNode );
+
+ // Node nicht loeschen, haengt im Undo!
+ _pImpEE->GetEditDoc().Remove( nNode );
+ if( _pImpEE->IsCallParaInsertedOrDeleted() )
+ _pImpEE->GetEditEnginePtr()->ParagraphDeleted( nNode );
+
+ DeletedNodeInfo* pInf = new DeletedNodeInfo( (ULONG)pContentNode, nNode );
+ _pImpEE->aDeletedNodes.Insert( pInf, _pImpEE->aDeletedNodes.Count() );
+ _pImpEE->UpdateSelections();
+
+ ContentNode* pN = ( nNode < _pImpEE->GetEditDoc().Count() )
+ ? _pImpEE->GetEditDoc().SaveGetObject( nNode )
+ : _pImpEE->GetEditDoc().SaveGetObject( nNode-1 );
+ DBG_ASSERT( pN && ( pN != pContentNode ), "?! RemoveContent !? " );
+ EditPaM aPaM( pN, pN->Len() );
+
+ bDelObject = TRUE; // gehoert wieder dem Undo
+
+ _pImpEE->GetActiveView()->GetImpEditView()->SetEditSelection( EditSelection( aPaM, aPaM ) );
+}
+
+ // -----------------------------------------------------------------------
+// EditUndoConnectParas
+// ------------------------------------------------------------------------
+EditUndoConnectParas::EditUndoConnectParas( ImpEditEngine* _pImpEE, USHORT nN, USHORT nSP,
+ const SfxItemSet& rLeftParaAttribs, const SfxItemSet& rRightParaAttribs,
+ const SfxStyleSheet* pLeftStyle, const SfxStyleSheet* pRightStyle, BOOL bBkwrd )
+ : EditUndo( EDITUNDO_CONNECTPARAS, _pImpEE ),
+ aLeftParaAttribs( rLeftParaAttribs ),
+ aRightParaAttribs( rRightParaAttribs )
+{
+ nNode = nN;
+ nSepPos = nSP;
+
+ if ( pLeftStyle )
+ {
+ aLeftStyleName = pLeftStyle->GetName();
+ eLeftStyleFamily = pLeftStyle->GetFamily();
+ }
+ if ( pRightStyle )
+ {
+ aRightStyleName = pRightStyle->GetName();
+ eRightStyleFamily = pRightStyle->GetFamily();
+ }
+
+ bBackward = bBkwrd;
+}
+
+EditUndoConnectParas::~EditUndoConnectParas()
+{
+}
+
+void __EXPORT EditUndoConnectParas::Undo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+
+ // Bei SplitContent darf noch kein ParagraphInserted gerufen werden,
+ // weil der Outliner sich auf die Attribute verlaesst um die Tiefe
+ // des Absatzes zu initialisieren
+
+ BOOL bCall = GetImpEditEngine()->IsCallParaInsertedOrDeleted();
+ GetImpEditEngine()->SetCallParaInsertedOrDeleted( FALSE );
+
+ EditPaM aPaM = GetImpEditEngine()->SplitContent( nNode, nSepPos );
+ GetImpEditEngine()->SetParaAttribs( nNode, aLeftParaAttribs );
+ GetImpEditEngine()->SetParaAttribs( nNode+1, aRightParaAttribs );
+
+ GetImpEditEngine()->SetCallParaInsertedOrDeleted( bCall );
+ if ( GetImpEditEngine()->IsCallParaInsertedOrDeleted() )
+ GetImpEditEngine()->GetEditEnginePtr()->ParagraphInserted( nNode+1 );
+
+ if ( GetImpEditEngine()->GetStyleSheetPool() )
+ {
+ if ( aLeftStyleName.Len() )
+ GetImpEditEngine()->SetStyleSheet( (USHORT)nNode, (SfxStyleSheet*)GetImpEditEngine()->GetStyleSheetPool()->Find( aLeftStyleName, eLeftStyleFamily ) );
+ if ( aRightStyleName.Len() )
+ GetImpEditEngine()->SetStyleSheet( nNode+1, (SfxStyleSheet*)GetImpEditEngine()->GetStyleSheetPool()->Find( aRightStyleName, eRightStyleFamily ) );
+ }
+
+ GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( EditSelection( aPaM, aPaM ) );
+}
+
+void __EXPORT EditUndoConnectParas::Redo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ EditPaM aPaM = GetImpEditEngine()->ConnectContents( nNode, bBackward );
+
+ GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( EditSelection( aPaM, aPaM ) );
+}
+
+ // -----------------------------------------------------------------------
+// EditUndoSplitPara
+// ------------------------------------------------------------------------
+EditUndoSplitPara::EditUndoSplitPara( ImpEditEngine* _pImpEE, USHORT nN, USHORT nSP )
+ : EditUndo( EDITUNDO_SPLITPARA, _pImpEE )
+{
+ nNode = nN;
+ nSepPos = nSP;
+}
+
+EditUndoSplitPara::~EditUndoSplitPara()
+{
+}
+
+void __EXPORT EditUndoSplitPara::Undo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ EditPaM aPaM = GetImpEditEngine()->ConnectContents( nNode, FALSE );
+ GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( EditSelection( aPaM, aPaM ) );
+}
+
+void __EXPORT EditUndoSplitPara::Redo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ EditPaM aPaM = GetImpEditEngine()->SplitContent( nNode, nSepPos );
+ GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( EditSelection( aPaM, aPaM ) );
+}
+
+ // -----------------------------------------------------------------------
+// EditUndoInsertChars
+// ------------------------------------------------------------------------
+EditUndoInsertChars::EditUndoInsertChars( ImpEditEngine* _pImpEE, const EPaM& rEPaM, const XubString& rStr )
+ : EditUndo( EDITUNDO_INSERTCHARS, _pImpEE ),
+ aEPaM( rEPaM ), aText( rStr )
+{
+}
+
+void __EXPORT EditUndoInsertChars::Undo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ EditPaM aPaM( GetImpEditEngine()->CreateEditPaM( aEPaM ) );
+ EditSelection aSel( aPaM, aPaM );
+ aSel.Max().GetIndex() = aSel.Max().GetIndex() + aText.Len();
+ EditPaM aNewPaM( GetImpEditEngine()->ImpDeleteSelection( aSel ) );
+ GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( EditSelection( aNewPaM, aNewPaM ) );
+}
+
+void __EXPORT EditUndoInsertChars::Redo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ EditPaM aPaM( GetImpEditEngine()->CreateEditPaM( aEPaM ) );
+ GetImpEditEngine()->ImpInsertText( EditSelection( aPaM, aPaM ), aText );
+ EditPaM aNewPaM( aPaM );
+ aNewPaM.GetIndex() = aNewPaM.GetIndex() + aText.Len();
+ GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( EditSelection( aPaM, aNewPaM ) );
+}
+
+BOOL __EXPORT EditUndoInsertChars::Merge( SfxUndoAction* pNextAction )
+{
+ if ( !pNextAction->ISA( EditUndoInsertChars ) )
+ return FALSE;
+
+ EditUndoInsertChars* pNext = (EditUndoInsertChars*)pNextAction;
+
+ if ( aEPaM.nPara != pNext->aEPaM.nPara )
+ return FALSE;
+
+ if ( ( aEPaM.nIndex + aText.Len() ) == pNext->aEPaM.nIndex )
+ {
+ aText += pNext->aText;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+ // -----------------------------------------------------------------------
+// EditUndoRemoveChars
+// ------------------------------------------------------------------------
+EditUndoRemoveChars::EditUndoRemoveChars( ImpEditEngine* _pImpEE, const EPaM& rEPaM, const XubString& rStr )
+ : EditUndo( EDITUNDO_REMOVECHARS, _pImpEE ),
+ aEPaM( rEPaM ), aText( rStr )
+{
+}
+
+void __EXPORT EditUndoRemoveChars::Undo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ EditPaM aPaM( GetImpEditEngine()->CreateEditPaM( aEPaM ) );
+ EditSelection aSel( aPaM, aPaM );
+ GetImpEditEngine()->ImpInsertText( aSel, aText );
+ aSel.Max().GetIndex() = aSel.Max().GetIndex() + aText.Len();
+ GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aSel );
+}
+
+void __EXPORT EditUndoRemoveChars::Redo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ EditPaM aPaM( GetImpEditEngine()->CreateEditPaM( aEPaM ) );
+ EditSelection aSel( aPaM, aPaM );
+ aSel.Max().GetIndex() = aSel.Max().GetIndex() + aText.Len();
+ EditPaM aNewPaM = GetImpEditEngine()->ImpDeleteSelection( aSel );
+ GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aNewPaM );
+}
+
+ // -----------------------------------------------------------------------
+// EditUndoInsertFeature
+// ------------------------------------------------------------------------
+EditUndoInsertFeature::EditUndoInsertFeature( ImpEditEngine* _pImpEE, const EPaM& rEPaM, const SfxPoolItem& rFeature)
+ : EditUndo( EDITUNDO_INSERTFEATURE, _pImpEE ), aEPaM( rEPaM )
+{
+ pFeature = rFeature.Clone();
+ DBG_ASSERT( pFeature, "Feature konnte nicht dupliziert werden: EditUndoInsertFeature" );
+}
+
+EditUndoInsertFeature::~EditUndoInsertFeature()
+{
+ delete pFeature;
+}
+
+void __EXPORT EditUndoInsertFeature::Undo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ EditPaM aPaM( GetImpEditEngine()->CreateEditPaM( aEPaM ) );
+ EditSelection aSel( aPaM, aPaM );
+ // Attribute werden dort implizit vom Dokument korrigiert...
+ aSel.Max().GetIndex()++;
+ EditPaM aNewPaM = GetImpEditEngine()->ImpDeleteSelection( aSel );
+ aSel.Max().GetIndex()--; // Fuer Selektion
+ GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aSel );
+}
+
+void __EXPORT EditUndoInsertFeature::Redo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ EditPaM aPaM( GetImpEditEngine()->CreateEditPaM( aEPaM ) );
+ EditSelection aSel( aPaM, aPaM );
+ GetImpEditEngine()->ImpInsertFeature( aSel, *pFeature );
+ if ( pFeature->Which() == EE_FEATURE_FIELD )
+ GetImpEditEngine()->UpdateFields();
+ aSel.Max().GetIndex()++;
+ GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aSel );
+}
+
+ // -----------------------------------------------------------------------
+// EditUndoMoveParagraphs
+// ------------------------------------------------------------------------
+EditUndoMoveParagraphs::EditUndoMoveParagraphs
+ ( ImpEditEngine* _pImpEE, const Range& rParas, USHORT n )
+ : EditUndo( EDITUNDO_MOVEPARAGRAPHS, _pImpEE ),
+ nParagraphs( rParas )
+{
+ nDest = n;
+}
+
+EditUndoMoveParagraphs::~EditUndoMoveParagraphs()
+{
+}
+
+void __EXPORT EditUndoMoveParagraphs::Undo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ Range aTmpRange( nParagraphs );
+ long nTmpDest = aTmpRange.Min();
+
+ long nDiff = ( nDest - aTmpRange.Min() );
+ aTmpRange.Min() += nDiff;
+ aTmpRange.Max() += nDiff;
+
+ if ( nParagraphs.Min() < (long)nDest )
+ {
+ long nLen = aTmpRange.Len();
+ aTmpRange.Min() -= nLen;
+ aTmpRange.Max() -= nLen;
+ }
+ else
+ nTmpDest += aTmpRange.Len();
+
+ EditSelection aNewSel( GetImpEditEngine()->MoveParagraphs( aTmpRange, (USHORT)nTmpDest, 0 ) );
+ GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aNewSel );
+}
+
+void __EXPORT EditUndoMoveParagraphs::Redo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ EditSelection aNewSel( GetImpEditEngine()->MoveParagraphs( nParagraphs, nDest, 0 ) );
+ GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aNewSel );
+}
+
+ // -----------------------------------------------------------------------
+// EditUndoSetStyleSheet
+// ------------------------------------------------------------------------
+EditUndoSetStyleSheet::EditUndoSetStyleSheet( ImpEditEngine* _pImpEE, USHORT nP,
+ const XubString& rPrevName, SfxStyleFamily ePrevFam,
+ const XubString& rNewName, SfxStyleFamily eNewFam,
+ const SfxItemSet& rPrevParaAttribs )
+ : EditUndo( EDITUNDO_STYLESHEET, _pImpEE ), aPrevName( rPrevName ), aNewName( rNewName ),
+ aPrevParaAttribs( rPrevParaAttribs )
+{
+ ePrevFamily = ePrevFam;
+ eNewFamily = eNewFam;
+ nPara = nP;
+}
+
+EditUndoSetStyleSheet::~EditUndoSetStyleSheet()
+{
+}
+
+void __EXPORT EditUndoSetStyleSheet::Undo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ GetImpEditEngine()->SetStyleSheet( nPara, (SfxStyleSheet*)GetImpEditEngine()->GetStyleSheetPool()->Find( aPrevName, ePrevFamily ) );
+ GetImpEditEngine()->SetParaAttribs( nPara, aPrevParaAttribs );
+ lcl_DoSetSelection( GetImpEditEngine()->GetActiveView(), nPara );
+}
+
+void __EXPORT EditUndoSetStyleSheet::Redo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ GetImpEditEngine()->SetStyleSheet( nPara, (SfxStyleSheet*)GetImpEditEngine()->GetStyleSheetPool()->Find( aNewName, eNewFamily ) );
+ lcl_DoSetSelection( GetImpEditEngine()->GetActiveView(), nPara );
+}
+
+ // -----------------------------------------------------------------------
+// EditUndoSetParaAttribs
+// ------------------------------------------------------------------------
+EditUndoSetParaAttribs::EditUndoSetParaAttribs( ImpEditEngine* _pImpEE, USHORT nP, const SfxItemSet& rPrevItems, const SfxItemSet& rNewItems )
+ : EditUndo( EDITUNDO_PARAATTRIBS, _pImpEE ),
+ aPrevItems( rPrevItems ),
+ aNewItems(rNewItems )
+{
+ nPara = nP;
+}
+
+EditUndoSetParaAttribs::~EditUndoSetParaAttribs()
+{
+}
+
+void __EXPORT EditUndoSetParaAttribs::Undo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ GetImpEditEngine()->SetParaAttribs( nPara, aPrevItems );
+ lcl_DoSetSelection( GetImpEditEngine()->GetActiveView(), nPara );
+}
+
+void __EXPORT EditUndoSetParaAttribs::Redo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ GetImpEditEngine()->SetParaAttribs( nPara, aNewItems );
+ lcl_DoSetSelection( GetImpEditEngine()->GetActiveView(), nPara );
+}
+
+ // -----------------------------------------------------------------------
+// EditUndoSetAttribs
+// ------------------------------------------------------------------------
+EditUndoSetAttribs::EditUndoSetAttribs( ImpEditEngine* _pImpEE, const ESelection& rESel, const SfxItemSet& rNewItems )
+ : EditUndo( EDITUNDO_ATTRIBS, _pImpEE ),
+ aESel( rESel ),
+ aNewAttribs( rNewItems )
+{
+ // Wenn das EditUndoSetAttribs eigentlich ein RemoveAttribs ist, koennte
+ // man das eigentlich an einem leeren ItemSet erkennen, aber dann muesste
+ // an einigen Stellen abgefangen werden, das ggf. ein SetAttribs mit einem
+ // leeren ItemSet gemacht wird.
+ // => Ich habe lieber diesen Member spendiert...
+ bSetIsRemove = FALSE;
+ bRemoveParaAttribs = FALSE;
+ nRemoveWhich = 0;
+ nSpecial = 0;
+}
+
+EditUndoSetAttribs::~EditUndoSetAttribs()
+{
+ // Items aus Pool holen...
+ SfxItemPool* pPool = aNewAttribs.GetPool();
+ USHORT nContents = aPrevAttribs.Count();
+ for ( USHORT n = 0; n < nContents; n++ )
+ {
+ ContentAttribsInfo* pInf = aPrevAttribs[n];
+ DBG_ASSERT( pInf, "Undo_DTOR (SetAttribs): pInf = NULL!" );
+ for ( USHORT nAttr = 0; nAttr < pInf->GetPrevCharAttribs().Count(); nAttr++ )
+ {
+ EditCharAttrib* pX = pInf->GetPrevCharAttribs()[nAttr];
+ DBG_ASSERT( pX, "Undo_DTOR (SetAttribs): pX = NULL!" );
+ pPool->Remove( *pX->GetItem() );
+ delete pX;
+ }
+ delete pInf;
+ }
+}
+
+void __EXPORT EditUndoSetAttribs::Undo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ ImpEditEngine* _pImpEE = GetImpEditEngine();
+ BOOL bFields = FALSE;
+ for ( USHORT nPara = aESel.nStartPara; nPara <= aESel.nEndPara; nPara++ )
+ {
+ ContentAttribsInfo* pInf = aPrevAttribs[ (USHORT)(nPara-aESel.nStartPara) ];
+ DBG_ASSERT( pInf, "Undo (SetAttribs): pInf = NULL!" );
+
+ // erstmal die Absatzattribute...
+ _pImpEE->SetParaAttribs( nPara, pInf->GetPrevParaAttribs() );
+
+ // Dann die Zeichenattribute...
+ // Alle Attribute inkl. Features entfernen, werden wieder neu eingestellt.
+ _pImpEE->RemoveCharAttribs( nPara, 0, TRUE );
+ DBG_ASSERT( _pImpEE->GetEditDoc().SaveGetObject( nPara ), "Undo (SetAttribs): pNode = NULL!" );
+ ContentNode* pNode = _pImpEE->GetEditDoc().GetObject( nPara );
+ for ( USHORT nAttr = 0; nAttr < pInf->GetPrevCharAttribs().Count(); nAttr++ )
+ {
+ EditCharAttrib* pX = pInf->GetPrevCharAttribs()[nAttr];
+ DBG_ASSERT( pX, "Redo (SetAttribs): pX = NULL!" );
+ // wird autom. 'eingepoolt'.
+ _pImpEE->GetEditDoc().InsertAttrib( pNode, pX->GetStart(), pX->GetEnd(), *pX->GetItem() );
+ if ( pX->Which() == EE_FEATURE_FIELD )
+ bFields = TRUE;
+ }
+ }
+ if ( bFields )
+ _pImpEE->UpdateFields();
+ ImpSetSelection( GetImpEditEngine()->GetActiveView() );
+}
+
+void __EXPORT EditUndoSetAttribs::Redo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ ImpEditEngine* _pImpEE = GetImpEditEngine();
+
+ EditSelection aSel( _pImpEE->CreateSel( aESel ) );
+ if ( !bSetIsRemove )
+ _pImpEE->SetAttribs( aSel, aNewAttribs, nSpecial );
+ else
+ _pImpEE->RemoveCharAttribs( aSel, bRemoveParaAttribs, nRemoveWhich );
+
+ ImpSetSelection( GetImpEditEngine()->GetActiveView() );
+}
+
+void EditUndoSetAttribs::ImpSetSelection( EditView* /*pView*/ )
+{
+ ImpEditEngine* _pImpEE = GetImpEditEngine();
+ EditSelection aSel( _pImpEE->CreateSel( aESel ) );
+ GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aSel );
+}
+
+ // -----------------------------------------------------------------------
+// EditUndoTransliteration
+// ------------------------------------------------------------------------
+EditUndoTransliteration::EditUndoTransliteration( ImpEditEngine* _pImpEE, const ESelection& rESel, sal_Int32 nM )
+ : EditUndo( EDITUNDO_TRANSLITERATE, _pImpEE ), aOldESel( rESel )
+{
+ nMode = nM;
+ pTxtObj = NULL;
+}
+
+EditUndoTransliteration::~EditUndoTransliteration()
+{
+ delete pTxtObj;
+}
+
+void __EXPORT EditUndoTransliteration::Undo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+
+ ImpEditEngine* _pImpEE = GetImpEditEngine();
+
+ EditSelection aSel( _pImpEE->CreateSel( aNewESel ) );
+
+ // Insert text, but don't expand Atribs at the current position:
+ aSel = _pImpEE->DeleteSelected( aSel );
+ EditSelection aDelSel( aSel );
+ aSel = _pImpEE->InsertParaBreak( aSel );
+ aDelSel.Max() = aSel.Min();
+ aDelSel.Max().GetNode()->GetCharAttribs().DeleteEmptyAttribs( _pImpEE->GetEditDoc().GetItemPool() );
+ EditSelection aNewSel;
+ if ( pTxtObj )
+ {
+ aNewSel = _pImpEE->InsertText( *pTxtObj, aSel );
+ }
+ else
+ {
+ aNewSel = _pImpEE->InsertText( aSel, aText );
+ }
+ if ( aNewSel.Min().GetNode() == aDelSel.Max().GetNode() )
+ {
+ aNewSel.Min().SetNode( aDelSel.Min().GetNode() );
+ aNewSel.Min().GetIndex() =
+ aNewSel.Min().GetIndex() + aDelSel.Min().GetIndex();
+ }
+ if ( aNewSel.Max().GetNode() == aDelSel.Max().GetNode() )
+ {
+ aNewSel.Max().SetNode( aDelSel.Min().GetNode() );
+ aNewSel.Max().GetIndex() =
+ aNewSel.Max().GetIndex() + aDelSel.Min().GetIndex();
+ }
+ _pImpEE->DeleteSelected( aDelSel );
+
+ GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aNewSel );
+}
+
+void __EXPORT EditUndoTransliteration::Redo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ ImpEditEngine* _pImpEE = GetImpEditEngine();
+
+ EditSelection aSel( _pImpEE->CreateSel( aOldESel ) );
+ EditSelection aNewSel = _pImpEE->TransliterateText( aSel, nMode );
+ GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( aNewSel );
+}
+
+ // -----------------------------------------------------------------------
+// EditUndoMarkSelection
+// ------------------------------------------------------------------------
+EditUndoMarkSelection::EditUndoMarkSelection( ImpEditEngine* _pImpEE, const ESelection& rSel )
+ : EditUndo( EDITUNDO_MARKSELECTION, _pImpEE ), aSelection( rSel )
+{
+}
+
+EditUndoMarkSelection::~EditUndoMarkSelection()
+{
+}
+
+void __EXPORT EditUndoMarkSelection::Undo()
+{
+ DBG_ASSERT( GetImpEditEngine()->GetActiveView(), "Undo/Redo: Keine Active View!" );
+ if ( GetImpEditEngine()->GetActiveView() )
+ {
+ if ( GetImpEditEngine()->IsFormatted() )
+ GetImpEditEngine()->GetActiveView()->SetSelection( aSelection );
+ else
+ GetImpEditEngine()->GetActiveView()->GetImpEditView()->SetEditSelection( GetImpEditEngine()->CreateSel( aSelection ) );
+ }
+}
+
+void __EXPORT EditUndoMarkSelection::Redo()
+{
+ // Fuer Redo unwichtig, weil am Anfang der Undo-Klammerung
+}
+
diff --git a/editeng/source/editeng/editundo.hxx b/editeng/source/editeng/editundo.hxx
new file mode 100644
index 0000000000..571e873adc
--- /dev/null
+++ b/editeng/source/editeng/editundo.hxx
@@ -0,0 +1,318 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: editundo.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _EDITUNDO_HXX
+#define _EDITUNDO_HXX
+
+#include <editdoc.hxx>
+#include <editeng/editund2.hxx>
+#include <editeng/editdata.hxx>
+
+#define UNDO_NOACTION 0
+#define UNDO_NEWUNDO 1
+#define UNDO_UNDOSDELETED 2
+#define UNDO_EMPTYGROUPDELETED 3
+#define UNDO_INVALIDEND 4
+
+class ImpEditEngine;
+class EditView;
+
+// -----------------------------------------------------------------------
+// EditUndoDelContent
+// ------------------------------------------------------------------------
+class EditUndoDelContent : public EditUndo
+{
+private:
+ BOOL bDelObject;
+ USHORT nNode;
+ ContentNode* pContentNode; // Zeigt auf das gueltige,
+ // nicht zerstoerte Objekt!
+
+public:
+ TYPEINFO();
+ EditUndoDelContent( ImpEditEngine* pImpEE, ContentNode* pNode, USHORT nPortio );
+ ~EditUndoDelContent();
+
+ virtual void Undo();
+ virtual void Redo();
+};
+
+// -----------------------------------------------------------------------
+// EditUndoConnectParas
+// ------------------------------------------------------------------------
+class EditUndoConnectParas : public EditUndo
+{
+private:
+ USHORT nNode;
+ USHORT nSepPos;
+ SfxItemSet aLeftParaAttribs;
+ SfxItemSet aRightParaAttribs;
+
+ // 2 Pointer waeren schoener, aber dann muesste es ein SfxListener sein.
+ String aLeftStyleName;
+ String aRightStyleName;
+ SfxStyleFamily eLeftStyleFamily;
+ SfxStyleFamily eRightStyleFamily;
+
+ BOOL bBackward;
+
+public:
+ TYPEINFO();
+ EditUndoConnectParas( ImpEditEngine* pImpEE, USHORT nNode, USHORT nSepPos,
+ const SfxItemSet& rLeftParaAttribs, const SfxItemSet& rRightParaAttribs,
+ const SfxStyleSheet* pLeftStyle, const SfxStyleSheet* pRightStyle, BOOL bBackward );
+ ~EditUndoConnectParas();
+
+ virtual void Undo();
+ virtual void Redo();
+};
+
+// -----------------------------------------------------------------------
+// EditUndoSplitPara
+// ------------------------------------------------------------------------
+class EditUndoSplitPara : public EditUndo
+{
+private:
+ USHORT nNode;
+ USHORT nSepPos;
+
+public:
+ TYPEINFO();
+ EditUndoSplitPara( ImpEditEngine* pImpEE, USHORT nNode, USHORT nSepPos );
+ ~EditUndoSplitPara();
+
+ virtual void Undo();
+ virtual void Redo();
+};
+
+// -----------------------------------------------------------------------
+// EditUndoInsertChars
+// ------------------------------------------------------------------------
+class EditUndoInsertChars : public EditUndo
+{
+private:
+ EPaM aEPaM;
+ String aText;
+
+public:
+ TYPEINFO();
+ EditUndoInsertChars( ImpEditEngine* pImpEE, const EPaM& rEPaM, const String& rStr );
+
+ const EPaM& GetEPaM() { return aEPaM; }
+ String& GetStr() { return aText; }
+
+ virtual void Undo();
+ virtual void Redo();
+
+ virtual BOOL Merge( SfxUndoAction *pNextAction );
+};
+
+// -----------------------------------------------------------------------
+// EditUndoRemoveChars
+// ------------------------------------------------------------------------
+class EditUndoRemoveChars : public EditUndo
+{
+private:
+ EPaM aEPaM;
+ String aText;
+
+public:
+ TYPEINFO();
+ EditUndoRemoveChars( ImpEditEngine* pImpEE, const EPaM& rEPaM, const String& rStr );
+
+ const EPaM& GetEPaM() { return aEPaM; }
+ String& GetStr() { return aText; }
+
+ virtual void Undo();
+ virtual void Redo();
+};
+
+// -----------------------------------------------------------------------
+// EditUndoInsertFeature
+// ------------------------------------------------------------------------
+class EditUndoInsertFeature : public EditUndo
+{
+private:
+ EPaM aEPaM;
+ SfxPoolItem* pFeature;
+
+public:
+ TYPEINFO();
+ EditUndoInsertFeature( ImpEditEngine* pImpEE, const EPaM& rEPaM,
+ const SfxPoolItem& rFeature);
+ ~EditUndoInsertFeature();
+
+ virtual void Undo();
+ virtual void Redo();
+};
+
+// -----------------------------------------------------------------------
+// EditUndoMoveParagraphs
+// ------------------------------------------------------------------------
+class EditUndoMoveParagraphs: public EditUndo
+{
+private:
+ Range nParagraphs;
+ USHORT nDest;
+
+public:
+ TYPEINFO();
+ EditUndoMoveParagraphs( ImpEditEngine* pImpEE, const Range& rParas, USHORT nDest );
+ ~EditUndoMoveParagraphs();
+
+ virtual void Undo();
+ virtual void Redo();
+};
+
+// -----------------------------------------------------------------------
+// EditUndoSetStyleSheet
+// ------------------------------------------------------------------------
+class EditUndoSetStyleSheet: public EditUndo
+{
+private:
+ USHORT nPara;
+ XubString aPrevName;
+ XubString aNewName;
+ SfxStyleFamily ePrevFamily;
+ SfxStyleFamily eNewFamily;
+ SfxItemSet aPrevParaAttribs;
+
+public:
+ TYPEINFO();
+
+ EditUndoSetStyleSheet( ImpEditEngine* pImpEE, USHORT nPara,
+ const XubString& rPrevName, SfxStyleFamily ePrevFamily,
+ const XubString& rNewName, SfxStyleFamily eNewFamily,
+ const SfxItemSet& rPrevParaAttribs );
+ ~EditUndoSetStyleSheet();
+
+ virtual void Undo();
+ virtual void Redo();
+};
+
+// -----------------------------------------------------------------------
+// EditUndoSetParaAttribs
+// ------------------------------------------------------------------------
+class EditUndoSetParaAttribs: public EditUndo
+{
+private:
+ USHORT nPara;
+ SfxItemSet aPrevItems;
+ SfxItemSet aNewItems;
+
+public:
+ TYPEINFO();
+ EditUndoSetParaAttribs( ImpEditEngine* pImpEE, USHORT nPara, const SfxItemSet& rPrevItems, const SfxItemSet& rNewItems );
+ ~EditUndoSetParaAttribs();
+
+ virtual void Undo();
+ virtual void Redo();
+};
+
+// -----------------------------------------------------------------------
+// EditUndoSetAttribs
+// ------------------------------------------------------------------------
+class EditUndoSetAttribs: public EditUndo
+{
+private:
+ ESelection aESel;
+ SfxItemSet aNewAttribs;
+ ContentInfoArray aPrevAttribs;
+
+ BYTE nSpecial;
+ BOOL bSetIsRemove;
+ BOOL bRemoveParaAttribs;
+ USHORT nRemoveWhich;
+
+ void ImpSetSelection( EditView* pView );
+
+
+public:
+ TYPEINFO();
+ EditUndoSetAttribs( ImpEditEngine* pImpEE, const ESelection& rESel, const SfxItemSet& rNewItems );
+ ~EditUndoSetAttribs();
+
+ ContentInfoArray& GetContentInfos() { return aPrevAttribs; }
+ SfxItemSet& GetNewAttribs() { return aNewAttribs; }
+
+ void SetSpecial( BYTE n ) { nSpecial = n; }
+ void SetRemoveAttribs( BOOL b ) { bSetIsRemove = b; }
+ void SetRemoveParaAttribs( BOOL b ) { bRemoveParaAttribs = b; }
+ void SetRemoveWhich( USHORT n ) { nRemoveWhich = n; }
+
+ virtual void Undo();
+ virtual void Redo();
+};
+
+// -----------------------------------------------------------------------
+// EditUndoTransliteration
+// ------------------------------------------------------------------------
+class EditUndoTransliteration: public EditUndo
+{
+private:
+ ESelection aOldESel;
+ ESelection aNewESel;
+
+ sal_Int32 nMode;
+ EditTextObject* pTxtObj;
+ String aText;
+
+public:
+ TYPEINFO();
+ EditUndoTransliteration( ImpEditEngine* pImpEE, const ESelection& rESel, sal_Int32 nMode );
+ ~EditUndoTransliteration();
+
+ void SetText( const String& rText ) { aText = rText; }
+ void SetText( EditTextObject* pObj ) { pTxtObj = pObj; }
+ void SetNewSelection( const ESelection& rSel ) { aNewESel = rSel; }
+
+ virtual void Undo();
+ virtual void Redo();
+};
+
+// -----------------------------------------------------------------------
+// EditUndoMarkSelection
+// ------------------------------------------------------------------------
+class EditUndoMarkSelection: public EditUndo
+{
+private:
+ ESelection aSelection;
+
+public:
+ TYPEINFO();
+ EditUndoMarkSelection( ImpEditEngine* pImpEE, const ESelection& rSel );
+ ~EditUndoMarkSelection();
+
+ virtual void Undo();
+ virtual void Redo();
+};
+
+
+#endif // _EDITUNDO_HXX
diff --git a/editeng/source/editeng/editview.cxx b/editeng/source/editeng/editview.cxx
new file mode 100644
index 0000000000..1fe7fc5c38
--- /dev/null
+++ b/editeng/source/editeng/editview.cxx
@@ -0,0 +1,1598 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: editview.cxx,v $
+ * $Revision: 1.52.74.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <vcl/wrkwin.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+
+#include <com/sun/star/i18n/WordType.hpp>
+#include <vcl/metric.hxx>
+
+#include <i18npool/mslangid.hxx>
+#include <svl/languageoptions.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svtools/langtab.hxx>
+
+#include <svl/srchitem.hxx>
+
+#define _SVSTDARR_USHORTS
+#include <svl/svstdarr.hxx>
+
+#include <impedit.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/svxacorr.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/eerdll.hxx>
+#include <eerdll2.hxx>
+#include <editeng.hrc>
+#include <helpid.hrc>
+#include <i18npool/lang.h>
+#include <vcl/menu.hxx>
+#include <editeng/acorrcfg.hxx>
+#include <editeng/unolingu.hxx>
+#include <editeng/fontitem.hxx>
+
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/beans/PropertyValues.hdl>
+#include <com/sun/star/lang/Locale.hpp>
+#include <linguistic/lngprops.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <unotools/lingucfg.hxx>
+
+using ::rtl::OUString;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::linguistic2;
+
+
+DBG_NAME( EditView )
+
+
+// From SW => Create common method
+LanguageType lcl_CheckLanguage(
+ const OUString &rText,
+ Reference< XSpellChecker1 > xSpell,
+ Reference< linguistic2::XLanguageGuessing > xLangGuess,
+ sal_Bool bIsParaText )
+{
+ LanguageType nLang = LANGUAGE_NONE;
+ if (bIsParaText) // check longer texts with language-guessing...
+ {
+ if (!xLangGuess.is())
+ return nLang;
+
+ lang::Locale aLocale( xLangGuess->guessPrimaryLanguage( rText, 0, rText.getLength()) );
+
+ // get language as from "Tools/Options - Language Settings - Languages: Locale setting"
+ LanguageType nTmpLang = Application::GetSettings().GetLanguage();
+
+ // if the result from language guessing does not provide a 'Country' part
+ // try to get it by looking up the locale setting of the office.
+ if (aLocale.Country.getLength() == 0)
+ {
+ lang::Locale aTmpLocale = SvxCreateLocale( nTmpLang );
+ if (aTmpLocale.Language == aLocale.Language)
+ nLang = nTmpLang;
+ }
+ if (nLang == LANGUAGE_NONE) // language not found by looking up the sytem language...
+ nLang = MsLangId::convertLocaleToLanguageWithFallback( aLocale );
+ if (nLang == LANGUAGE_SYSTEM)
+ nLang = nTmpLang;
+ if (nLang == LANGUAGE_DONTKNOW)
+ nLang = LANGUAGE_NONE;
+ }
+ else // check single word
+ {
+ if (!xSpell.is())
+ return nLang;
+
+ //
+ // build list of languages to check
+ //
+ LanguageType aLangList[4];
+ const AllSettings& rSettings = Application::GetSettings();
+ SvtLinguOptions aLinguOpt;
+ SvtLinguConfig().GetOptions( aLinguOpt );
+ // The default document language from "Tools/Options - Language Settings - Languages: Western"
+ aLangList[0] = aLinguOpt.nDefaultLanguage;
+ // The one from "Tools/Options - Language Settings - Languages: User interface"
+ aLangList[1] = rSettings.GetUILanguage();
+ // The one from "Tools/Options - Language Settings - Languages: Locale setting"
+ aLangList[2] = rSettings.GetLanguage();
+ // en-US
+ aLangList[3] = LANGUAGE_ENGLISH_US;
+#ifdef DEBUG
+ lang::Locale a0( SvxCreateLocale( aLangList[0] ) );
+ lang::Locale a1( SvxCreateLocale( aLangList[1] ) );
+ lang::Locale a2( SvxCreateLocale( aLangList[2] ) );
+ lang::Locale a3( SvxCreateLocale( aLangList[3] ) );
+#endif
+
+ INT32 nCount = sizeof(aLangList) / sizeof(aLangList[0]);
+ for (INT32 i = 0; i < nCount; i++)
+ {
+ INT16 nTmpLang = aLangList[i];
+ if (nTmpLang != LANGUAGE_NONE && nTmpLang != LANGUAGE_DONTKNOW)
+ {
+ if (xSpell->hasLanguage( nTmpLang ) &&
+ xSpell->isValid( rText, nTmpLang, Sequence< PropertyValue >() ))
+ {
+ nLang = nTmpLang;
+ break;
+ }
+ }
+ }
+ }
+
+ return nLang;
+}
+
+
+ // ----------------------------------------------------------------------
+// class EditView
+// ----------------------------------------------------------------------
+EditView::EditView( EditEngine* pEng, Window* pWindow )
+{
+ DBG_CTOR( EditView, 0 );
+ pImpEditView = new ImpEditView( this, pEng, pWindow );
+}
+
+EditView::~EditView()
+{
+ DBG_DTOR( EditView, 0 );
+ delete pImpEditView;
+}
+
+ImpEditEngine* EditView::GetImpEditEngine() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ return pImpEditView->pEditEngine->pImpEditEngine;
+}
+
+EditEngine* EditView::GetEditEngine() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ return pImpEditView->pEditEngine;
+}
+
+void EditView::Invalidate()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ if ( !pImpEditView->DoInvalidateMore() )
+ pImpEditView->GetWindow()->Invalidate( pImpEditView->aOutArea );
+ else
+ {
+ Rectangle aRect( pImpEditView->aOutArea );
+ long nMore = pImpEditView->GetWindow()->PixelToLogic( Size( pImpEditView->GetInvalidateMore(), 0 ) ).Width();
+ aRect.Left() -= nMore;
+ aRect.Right() += nMore;
+ aRect.Top() -= nMore;
+ aRect.Bottom() += nMore;
+ pImpEditView->GetWindow()->Invalidate( aRect );
+ }
+}
+
+void EditView::SetReadOnly( sal_Bool bReadOnly )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ pImpEditView->bReadOnly = bReadOnly;
+}
+
+sal_Bool EditView::IsReadOnly() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ return pImpEditView->bReadOnly;
+}
+
+void EditView::SetSelection( const ESelection& rESel )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+
+ // Falls jemand gerade ein leeres Attribut hinterlassen hat,
+ // und dann der Outliner die Selektion manipulitert:
+ if ( !pImpEditView->GetEditSelection().HasRange() )
+ {
+ ContentNode* pNode = pImpEditView->GetEditSelection().Max().GetNode();
+ PIMPEE->CursorMoved( pNode );
+ }
+ EditSelection aNewSelection( PIMPEE->ConvertSelection( rESel.nStartPara, rESel.nStartPos, rESel.nEndPara, rESel.nEndPos ) );
+
+ // Wenn nach einem KeyInput die Selection manipuliert wird:
+ PIMPEE->CheckIdleFormatter();
+
+ // Selektion darf nicht bei einem unsichtbaren Absatz Starten/Enden:
+ ParaPortion* pPortion = PIMPEE->FindParaPortion( aNewSelection.Min().GetNode() );
+ if ( !pPortion->IsVisible() )
+ {
+ pPortion = PIMPEE->GetPrevVisPortion( pPortion );
+ ContentNode* pNode = pPortion ? pPortion->GetNode() : PIMPEE->GetEditDoc().GetObject( 0 );
+ aNewSelection.Min() = EditPaM( pNode, pNode->Len() );
+ }
+ pPortion = PIMPEE->FindParaPortion( aNewSelection.Max().GetNode() );
+ if ( !pPortion->IsVisible() )
+ {
+ pPortion = PIMPEE->GetPrevVisPortion( pPortion );
+ ContentNode* pNode = pPortion ? pPortion->GetNode() : PIMPEE->GetEditDoc().GetObject( 0 );
+ aNewSelection.Max() = EditPaM( pNode, pNode->Len() );
+ }
+
+ pImpEditView->DrawSelection(); // alte Selektion 'weg-zeichnen'
+ pImpEditView->SetEditSelection( aNewSelection );
+ pImpEditView->DrawSelection();
+ sal_Bool bGotoCursor = pImpEditView->DoAutoScroll();
+ ShowCursor( bGotoCursor );
+}
+
+ESelection EditView::GetSelection() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+
+ ESelection aSelection;
+
+ aSelection.nStartPara = PIMPEE->GetEditDoc().GetPos( pImpEditView->GetEditSelection().Min().GetNode() );
+ aSelection.nEndPara = PIMPEE->GetEditDoc().GetPos( pImpEditView->GetEditSelection().Max().GetNode() );
+
+ aSelection.nStartPos = pImpEditView->GetEditSelection().Min().GetIndex();
+ aSelection.nEndPos = pImpEditView->GetEditSelection().Max().GetIndex();
+
+ return aSelection;
+}
+
+sal_Bool EditView::HasSelection() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ return pImpEditView->HasSelection();
+}
+
+void EditView::DeleteSelected()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ pImpEditView->DeleteSelected();
+}
+
+USHORT EditView::GetSelectedScriptType() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ return PIMPEE->GetScriptType( pImpEditView->GetEditSelection() );
+}
+
+void EditView::Paint( const Rectangle& rRect )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ PIMPEE->Paint( pImpEditView, rRect );
+}
+
+void EditView::SetEditEngine( EditEngine* pEditEng )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ pImpEditView->pEditEngine = pEditEng;
+ EditSelection aStartSel;
+ aStartSel = PIMPEE->GetEditDoc().GetStartPaM();
+ pImpEditView->SetEditSelection( aStartSel );
+}
+
+void EditView::SetWindow( Window* pWin )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ pImpEditView->pOutWin = pWin;
+ PIMPEE->GetSelEngine().Reset();
+}
+
+Window* EditView::GetWindow() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ return pImpEditView->pOutWin;
+}
+
+void EditView::SetVisArea( const Rectangle& rRec )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ pImpEditView->SetVisDocStartPos( rRec.TopLeft() );
+}
+
+const Rectangle& EditView::GetVisArea() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ // Change return value to Rectangle in next incompatible build !!!
+ static Rectangle aRect;
+ aRect = pImpEditView->GetVisDocArea();
+ return aRect;
+}
+
+void EditView::SetOutputArea( const Rectangle& rRec )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ pImpEditView->SetOutputArea( rRec );
+
+ // Rest nur hier, wenn API-Aufruf:
+ pImpEditView->CalcAnchorPoint();
+ if ( PIMPEE->GetStatus().AutoPageSize() )
+ pImpEditView->RecalcOutputArea();
+ pImpEditView->ShowCursor( sal_False, sal_False );
+}
+
+const Rectangle& EditView::GetOutputArea() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ return pImpEditView->GetOutputArea();
+}
+
+void EditView::SetPointer( const Pointer& rPointer )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ pImpEditView->SetPointer( rPointer );
+}
+
+const Pointer& EditView::GetPointer() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ return pImpEditView->GetPointer();
+}
+
+void EditView::SetCursor( const Cursor& rCursor )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ delete pImpEditView->pCursor;
+ pImpEditView->pCursor = new Cursor( rCursor );
+}
+
+Cursor* EditView::GetCursor() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ return pImpEditView->pCursor;
+}
+
+void EditView::InsertText( const XubString& rStr, sal_Bool bSelect )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+
+ ImpEditEngine* pImpEE = PIMPEE;
+ pImpEditView->DrawSelection();
+
+ EditPaM aPaM1;
+ if ( bSelect )
+ {
+ EditSelection aTmpSel( pImpEditView->GetEditSelection() );
+ aTmpSel.Adjust( pImpEE->GetEditDoc() );
+ aPaM1 = aTmpSel.Min();
+ }
+
+ pImpEE->UndoActionStart( EDITUNDO_INSERT );
+ EditPaM aPaM2( pImpEE->InsertText( pImpEditView->GetEditSelection(), rStr ) );
+ pImpEE->UndoActionEnd( EDITUNDO_INSERT );
+
+ if ( bSelect )
+ {
+ DBG_ASSERT( !aPaM1.DbgIsBuggy( pImpEE->GetEditDoc() ), "Insert: PaM kaputt" );
+ pImpEditView->SetEditSelection( EditSelection( aPaM1, aPaM2 ) );
+ }
+ else
+ pImpEditView->SetEditSelection( EditSelection( aPaM2, aPaM2 ) );
+
+ pImpEE->FormatAndUpdate( this );
+}
+
+sal_Bool EditView::PostKeyEvent( const KeyEvent& rKeyEvent )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ return pImpEditView->PostKeyEvent( rKeyEvent );
+}
+
+sal_Bool EditView::MouseButtonUp( const MouseEvent& rMouseEvent )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ return pImpEditView->MouseButtonUp( rMouseEvent );
+}
+
+sal_Bool EditView::MouseButtonDown( const MouseEvent& rMouseEvent )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ return pImpEditView->MouseButtonDown( rMouseEvent );
+}
+
+sal_Bool EditView::MouseMove( const MouseEvent& rMouseEvent )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ return pImpEditView->MouseMove( rMouseEvent );
+}
+
+void EditView::Command( const CommandEvent& rCEvt )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ pImpEditView->Command( rCEvt );
+}
+
+void EditView::ShowCursor( sal_Bool bGotoCursor, sal_Bool bForceVisCursor )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+
+// Draw vertraegt die Assertion nicht, spaeter mal aktivieren
+// DBG_ASSERT( pImpEditView->pEditEngine->HasView( this ), "ShowCursor - View nicht angemeldet!" );
+// DBG_ASSERT( !GetWindow()->IsInPaint(), "ShowCursor - Why in Paint ?!" );
+
+ if ( pImpEditView->pEditEngine->HasView( this ) )
+ {
+ // Das ControlWord hat mehr Gewicht:
+ if ( !pImpEditView->DoAutoScroll() )
+ bGotoCursor = sal_False;
+ pImpEditView->ShowCursor( bGotoCursor, bForceVisCursor );
+ }
+}
+
+void EditView::HideCursor()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ pImpEditView->GetCursor()->Hide();
+}
+
+Pair EditView::Scroll( long ndX, long ndY, BYTE nRangeCheck )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ return pImpEditView->Scroll( ndX, ndY, nRangeCheck );
+}
+
+const SfxItemSet& EditView::GetEmptyItemSet()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ return PIMPEE->GetEmptyItemSet();
+}
+
+void EditView::SetAttribs( const SfxItemSet& rSet )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ DBG_ASSERT( !pImpEditView->aEditSelection.IsInvalid(), "Blinde Selection in ...." );
+
+ // Kein Undo-Kappseln noetig...
+ pImpEditView->DrawSelection();
+ PIMPEE->SetAttribs( pImpEditView->GetEditSelection(), rSet, ATTRSPECIAL_WHOLEWORD );
+ PIMPEE->FormatAndUpdate( this );
+}
+
+void EditView::SetParaAttribs( const SfxItemSet& rSet, sal_uInt16 nPara )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ // Kein Undo-Kappseln noetig...
+ PIMPEE->SetParaAttribs( nPara, rSet );
+ // Beim Aendern von Absatzattributen muss immer formatiert werden...
+ PIMPEE->FormatAndUpdate( this );
+}
+
+void EditView::RemoveAttribsKeepLanguages( sal_Bool bRemoveParaAttribs )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+
+ pImpEditView->DrawSelection();
+ PIMPEE->UndoActionStart( EDITUNDO_RESETATTRIBS );
+ EditSelection aSelection( pImpEditView->GetEditSelection() );
+
+ for (sal_uInt16 nWID = EE_ITEMS_START; nWID <= EE_ITEMS_END; ++nWID)
+ {
+ bool bIsLang = EE_CHAR_LANGUAGE == nWID ||
+ EE_CHAR_LANGUAGE_CJK == nWID ||
+ EE_CHAR_LANGUAGE_CTL == nWID;
+ if (!bIsLang)
+ PIMPEE->RemoveCharAttribs( aSelection, bRemoveParaAttribs, nWID );
+ }
+
+ PIMPEE->UndoActionEnd( EDITUNDO_RESETATTRIBS );
+ PIMPEE->FormatAndUpdate( this );
+}
+
+void EditView::RemoveAttribs( sal_Bool bRemoveParaAttribs, sal_uInt16 nWhich )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+
+ pImpEditView->DrawSelection();
+ PIMPEE->UndoActionStart( EDITUNDO_RESETATTRIBS );
+ PIMPEE->RemoveCharAttribs( pImpEditView->GetEditSelection(), bRemoveParaAttribs, nWhich );
+ PIMPEE->UndoActionEnd( EDITUNDO_RESETATTRIBS );
+ PIMPEE->FormatAndUpdate( this );
+}
+
+void EditView::RemoveCharAttribs( sal_uInt16 nPara, sal_uInt16 nWhich )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ PIMPEE->UndoActionStart( EDITUNDO_RESETATTRIBS );
+ PIMPEE->RemoveCharAttribs( nPara, nWhich );
+ PIMPEE->UndoActionEnd( EDITUNDO_RESETATTRIBS );
+ PIMPEE->FormatAndUpdate( this );
+}
+
+SfxItemSet EditView::GetAttribs()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ DBG_ASSERT( !pImpEditView->aEditSelection.IsInvalid(), "Blinde Selection in ...." );
+ return PIMPEE->GetAttribs( pImpEditView->GetEditSelection() );
+}
+
+void EditView::Undo()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ PIMPEE->Undo( this );
+}
+
+void EditView::Redo()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ PIMPEE->Redo( this );
+}
+
+ULONG EditView::Read( SvStream& rInput, const String& rBaseURL, EETextFormat eFormat, sal_Bool bSelect, SvKeyValueIterator* pHTTPHeaderAttrs )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ EditSelection aOldSel( pImpEditView->GetEditSelection() );
+ pImpEditView->DrawSelection();
+ PIMPEE->UndoActionStart( EDITUNDO_READ );
+ EditPaM aEndPaM = PIMPEE->Read( rInput, rBaseURL, eFormat, aOldSel, pHTTPHeaderAttrs );
+ PIMPEE->UndoActionEnd( EDITUNDO_READ );
+ EditSelection aNewSel( aEndPaM, aEndPaM );
+ if ( bSelect )
+ {
+ aOldSel.Adjust( PIMPEE->GetEditDoc() );
+ aNewSel.Min() = aOldSel.Min();
+ }
+
+ pImpEditView->SetEditSelection( aNewSel );
+ sal_Bool bGotoCursor = pImpEditView->DoAutoScroll();
+ ShowCursor( bGotoCursor );
+
+ return rInput.GetError();
+}
+
+#ifndef SVX_LIGHT
+ULONG EditView::Write( SvStream& rOutput, EETextFormat eFormat )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ PIMPEE->Write( rOutput, eFormat, pImpEditView->GetEditSelection() );
+ ShowCursor();
+ return rOutput.GetError();
+}
+#endif
+
+void EditView::Cut()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
+ pImpEditView->CutCopy( aClipBoard, sal_True );
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > EditView::GetTransferable()
+{
+ uno::Reference< datatransfer::XTransferable > xData = GetEditEngine()->pImpEditEngine->CreateTransferable( pImpEditView->GetEditSelection() );
+ return xData;
+}
+
+void EditView::Copy()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
+ pImpEditView->CutCopy( aClipBoard, sal_False );
+}
+
+void EditView::Paste()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
+ pImpEditView->Paste( aClipBoard, sal_False );
+}
+
+void EditView::PasteSpecial()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
+ pImpEditView->Paste(aClipBoard, sal_True );
+}
+
+void EditView::EnablePaste( sal_Bool bEnable )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ pImpEditView->EnablePaste( bEnable );
+}
+
+sal_Bool EditView::IsPasteEnabled() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ return pImpEditView->IsPasteEnabled();
+}
+
+Point EditView::GetWindowPosTopLeft( sal_uInt16 nParagraph )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ Point aDocPos( pImpEditView->pEditEngine->GetDocPosTopLeft( nParagraph ) );
+ return pImpEditView->GetWindowPos( aDocPos );
+}
+
+sal_uInt16 EditView::GetParagraph( const Point& rMousePosPixel )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ Point aMousePos( rMousePosPixel );
+ aMousePos = GetWindow()->PixelToLogic( aMousePos );
+ Point aDocPos( pImpEditView->GetDocPos( aMousePos ) );
+ sal_uInt16 nParagraph = PIMPEE->GetParaPortions().FindParagraph( aDocPos.Y() );
+ return nParagraph;
+}
+
+void EditView::IndentBlock()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+
+ PIMPEE->IndentBlock( this, sal_True );
+}
+
+void EditView::UnindentBlock()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+
+ PIMPEE->IndentBlock( this, sal_False );
+}
+
+EESelectionMode EditView::GetSelectionMode() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ return pImpEditView->GetSelectionMode();
+}
+
+void EditView::SetSelectionMode( EESelectionMode eMode )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ pImpEditView->SetSelectionMode( eMode );
+}
+
+XubString EditView::GetSelected()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ return PIMPEE->GetSelected( pImpEditView->GetEditSelection() );
+}
+
+void EditView::MoveParagraphs( Range aParagraphs, sal_uInt16 nNewPos )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ PIMPEE->UndoActionStart( EDITUNDO_MOVEPARAS );
+ PIMPEE->MoveParagraphs( aParagraphs, nNewPos, this );
+ PIMPEE->UndoActionEnd( EDITUNDO_MOVEPARAS );
+}
+
+void EditView::MoveParagraphs( long nDiff )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ ESelection aSel = GetSelection();
+ Range aRange( aSel.nStartPara, aSel.nEndPara );
+ aRange.Justify();
+ long nDest = ( nDiff > 0 ? aRange.Max() : aRange.Min() ) + nDiff;
+ if ( nDiff > 0 )
+ nDest++;
+ DBG_ASSERT( ( nDest >= 0 ) && ( nDest <= pImpEditView->pEditEngine->GetParagraphCount() ), "MoveParagraphs - wrong Parameters!" );
+ MoveParagraphs( aRange,
+ sal::static_int_cast< USHORT >( nDest ) );
+}
+
+void EditView::SetBackgroundColor( const Color& rColor )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ pImpEditView->SetBackgroundColor( rColor );
+}
+
+Color EditView::GetBackgroundColor() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ return pImpEditView->GetBackgroundColor();
+}
+
+void EditView::SetControlWord( sal_uInt32 nWord )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ pImpEditView->nControl = nWord;
+}
+
+sal_uInt32 EditView::GetControlWord() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ return pImpEditView->nControl;
+}
+
+EditTextObject* EditView::CreateTextObject()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ return PIMPEE->CreateTextObject( pImpEditView->GetEditSelection() );
+}
+
+void EditView::InsertText( const EditTextObject& rTextObject )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ pImpEditView->DrawSelection();
+
+ PIMPEE->UndoActionStart( EDITUNDO_INSERT );
+ EditSelection aTextSel( PIMPEE->InsertText( rTextObject, pImpEditView->GetEditSelection() ) );
+ PIMPEE->UndoActionEnd( EDITUNDO_INSERT );
+
+ aTextSel.Min() = aTextSel.Max(); // Selektion nicht behalten.
+ pImpEditView->SetEditSelection( aTextSel );
+ PIMPEE->FormatAndUpdate( this );
+}
+
+void EditView::InsertText( ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > xDataObj, const String& rBaseURL, BOOL bUseSpecial )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+
+ PIMPEE->UndoActionStart( EDITUNDO_INSERT );
+ pImpEditView->DeleteSelected();
+ EditSelection aTextSel( PIMPEE->InsertText( xDataObj, rBaseURL, pImpEditView->GetEditSelection().Max(), bUseSpecial ) );
+ PIMPEE->UndoActionEnd( EDITUNDO_INSERT );
+
+ aTextSel.Min() = aTextSel.Max(); // Selektion nicht behalten.
+ pImpEditView->SetEditSelection( aTextSel );
+ PIMPEE->FormatAndUpdate( this );
+}
+
+sal_Bool EditView::Drop( const DropEvent& )
+{
+ return FALSE;
+}
+
+ESelection EditView::GetDropPos()
+{
+ DBG_ERROR( "GetDropPos - Why?!" );
+ return ESelection();
+}
+
+sal_Bool EditView::QueryDrop( DropEvent& )
+{
+ return FALSE;
+}
+
+void EditView::SetEditEngineUpdateMode( sal_Bool bUpdate )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ PIMPEE->SetUpdateMode( bUpdate, this );
+}
+
+void EditView::ForceUpdate()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ PIMPEE->SetUpdateMode( sal_True, this, sal_True );
+}
+
+void EditView::SetStyleSheet( SfxStyleSheet* pStyle )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+
+ EditSelection aSel( pImpEditView->GetEditSelection() );
+ PIMPEE->UndoActionStart( EDITUNDO_STYLESHEET );
+ PIMPEE->SetStyleSheet( aSel, pStyle );
+ PIMPEE->UndoActionEnd( EDITUNDO_STYLESHEET );
+}
+
+SfxStyleSheet* EditView::GetStyleSheet() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+
+
+ EditSelection aSel( pImpEditView->GetEditSelection() );
+ aSel.Adjust( PIMPEE->GetEditDoc() );
+ sal_uInt16 nStartPara = PIMPEE->GetEditDoc().GetPos( aSel.Min().GetNode() );
+ sal_uInt16 nEndPara = PIMPEE->GetEditDoc().GetPos( aSel.Max().GetNode() );
+
+ SfxStyleSheet* pStyle = NULL;
+ for ( sal_uInt16 n = nStartPara; n <= nEndPara; n++ )
+ {
+ SfxStyleSheet* pTmpStyle = PIMPEE->GetStyleSheet( n );
+ if ( ( n != nStartPara ) && ( pStyle != pTmpStyle ) )
+ return NULL; // Nicht eindeutig.
+ pStyle = pTmpStyle;
+ }
+ return pStyle;
+}
+
+sal_Bool EditView::IsInsertMode() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ return pImpEditView->IsInsertMode();
+}
+
+void EditView::SetInsertMode( sal_Bool bInsert )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ pImpEditView->SetInsertMode( bInsert );
+}
+
+void EditView::SetAnchorMode( EVAnchorMode eMode )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ pImpEditView->SetAnchorMode( eMode );
+}
+
+EVAnchorMode EditView::GetAnchorMode() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ return pImpEditView->GetAnchorMode();
+}
+
+void EditView::TransliterateText( sal_Int32 nTransliterationMode )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ EditSelection aOldSel( pImpEditView->GetEditSelection() );
+ EditSelection aNewSel = PIMPEE->TransliterateText( pImpEditView->GetEditSelection(), nTransliterationMode );
+ if ( aNewSel != aOldSel )
+ {
+ pImpEditView->DrawSelection(); // alte Selektion 'weg-zeichnen'
+ pImpEditView->SetEditSelection( aNewSel );
+ pImpEditView->DrawSelection();
+ }
+}
+
+
+sal_Bool EditView::MatchGroup()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ EditSelection aNewSel( PIMPEE->MatchGroup( pImpEditView->GetEditSelection() ) );
+ if ( aNewSel.HasRange() )
+ {
+ pImpEditView->DrawSelection();
+ pImpEditView->SetEditSelection( aNewSel );
+ pImpEditView->DrawSelection();
+ ShowCursor();
+ return sal_True;
+ }
+ return sal_False;
+}
+
+void EditView::CompleteAutoCorrect()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ if ( !pImpEditView->HasSelection() && PIMPEE->GetStatus().DoAutoCorrect() )
+ {
+ pImpEditView->DrawSelection();
+ EditSelection aSel = pImpEditView->GetEditSelection();
+ aSel = PIMPEE->EndOfWord( aSel.Max() );
+ // MT 06/00: Why pass EditSelection to AutoCorrect, not EditPaM?!
+ aSel = PIMPEE->AutoCorrect( aSel, 0, !IsInsertMode() );
+ pImpEditView->SetEditSelection( aSel );
+ if ( PIMPEE->IsModified() )
+ PIMPEE->FormatAndUpdate( this );
+ }
+}
+
+EESpellState EditView::StartSpeller( sal_Bool bMultipleDoc )
+{
+#ifdef SVX_LIGHT
+ return EE_SPELL_NOSPELLER;
+#else
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ if ( !PIMPEE->GetSpeller().is() )
+ return EE_SPELL_NOSPELLER;
+
+ return PIMPEE->Spell( this, bMultipleDoc );
+#endif
+}
+
+EESpellState EditView::StartThesaurus()
+{
+#ifdef SVX_LIGHT
+ return EE_SPELL_NOSPELLER;
+#else
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ if ( !PIMPEE->GetSpeller().is() )
+ return EE_SPELL_NOSPELLER;
+
+ return PIMPEE->StartThesaurus( this );
+#endif
+}
+
+
+void EditView::StartTextConversion(
+ LanguageType nSrcLang, LanguageType nDestLang, const Font *pDestFont,
+ INT32 nOptions, BOOL bIsInteractive, BOOL bMultipleDoc )
+{
+#ifdef SVX_LIGHT
+#else
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ PIMPEE->Convert( this, nSrcLang, nDestLang, pDestFont, nOptions, bIsInteractive, bMultipleDoc );
+#endif
+}
+
+
+sal_uInt16 EditView::StartSearchAndReplace( const SvxSearchItem& rSearchItem )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ return PIMPEE->StartSearchAndReplace( this, rSearchItem );
+}
+
+sal_Bool EditView::IsCursorAtWrongSpelledWord( sal_Bool bMarkIfWrong )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ sal_Bool bIsWrong = sal_False;
+ if ( !HasSelection() )
+ {
+ EditPaM aPaM = pImpEditView->GetEditSelection().Max();
+ bIsWrong = pImpEditView->IsWrongSpelledWord( aPaM, bMarkIfWrong );
+ }
+ return bIsWrong;
+}
+
+sal_Bool EditView::IsWrongSpelledWordAtPos( const Point& rPosPixel, sal_Bool bMarkIfWrong )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ Point aPos ( pImpEditView->GetWindow()->PixelToLogic( rPosPixel ) );
+ aPos = pImpEditView->GetDocPos( aPos );
+ EditPaM aPaM = pImpEditView->pEditEngine->pImpEditEngine->GetPaM( aPos, sal_False );
+ return pImpEditView->IsWrongSpelledWord( aPaM , bMarkIfWrong );
+}
+
+void EditView::ExecuteSpellPopup( const Point& rPosPixel, Link* pCallBack )
+{
+#ifndef SVX_LIGHT
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+
+ Point aPos ( pImpEditView->GetWindow()->PixelToLogic( rPosPixel ) );
+ aPos = pImpEditView->GetDocPos( aPos );
+ EditPaM aPaM = pImpEditView->pEditEngine->pImpEditEngine->GetPaM( aPos, sal_False );
+ Reference< XSpellChecker1 > xSpeller( PIMPEE->GetSpeller() );
+ ESelection aOldSel = GetSelection();
+ if ( xSpeller.is() && pImpEditView->IsWrongSpelledWord( aPaM, sal_True ) )
+ {
+ PopupMenu aPopupMenu( EditResId( RID_MENU_SPELL ) );
+ PopupMenu *pAutoMenu = aPopupMenu.GetPopupMenu( MN_AUTOCORR );
+ PopupMenu *pInsertMenu = aPopupMenu.GetPopupMenu( MN_INSERT );
+
+ EditPaM aPaM2( aPaM );
+ aPaM2.GetIndex()++;
+
+ // Gibt es Replace-Vorschlaege?
+ String aSelected( GetSelected() );
+ //
+ // restrict the maximal number of suggestions displayed
+ // in the context menu.
+ // Note: That could of course be done by clipping the
+ // resulting sequence but the current third party
+ // implementations result differs greatly if the number of
+ // suggestions to be retuned gets changed. Statistically
+ // it gets much better if told to return e.g. only 7 strings
+ // than returning e.g. 16 suggestions and using only the
+ // first 7. Thus we hand down the value to use to that
+ // implementation here by providing an additional parameter.
+ Sequence< PropertyValue > aPropVals(1);
+ PropertyValue &rVal = aPropVals.getArray()[0];
+ rVal.Name = OUString::createFromAscii( UPN_MAX_NUMBER_OF_SUGGESTIONS );
+ rVal.Value <<= (INT16) 7;
+ //
+ // Gibt es Replace-Vorschlaege?
+ Reference< XSpellAlternatives > xSpellAlt =
+ xSpeller->spell( aSelected, PIMPEE->GetLanguage( aPaM2 ), aPropVals );
+
+ Reference< XLanguageGuessing > xLangGuesser( EE_DLL()->GetGlobalData()->GetLanguageGuesser() );
+
+ // check if text might belong to a different language...
+ LanguageType nGuessLangWord = LANGUAGE_NONE;
+ LanguageType nGuessLangPara = LANGUAGE_NONE;
+ if (xSpellAlt.is() && xLangGuesser.is())
+ {
+ String aParaText;
+ ContentNode *pNode = aPaM.GetNode();
+ if (pNode)
+ {
+ aParaText = *pNode;
+ }
+ else
+ {
+ DBG_ERROR( "content node is NULL" );
+ }
+
+ nGuessLangWord = lcl_CheckLanguage( xSpellAlt->getWord(), xSpeller, xLangGuesser, sal_False );
+ nGuessLangPara = lcl_CheckLanguage( aParaText, xSpeller, xLangGuesser, sal_True );
+ }
+ if (nGuessLangWord != LANGUAGE_NONE || nGuessLangPara != LANGUAGE_NONE)
+ {
+ // make sure LANGUAGE_NONE gets not used as menu entry
+ if (nGuessLangWord == LANGUAGE_NONE)
+ nGuessLangWord = nGuessLangPara;
+ if (nGuessLangPara == LANGUAGE_NONE)
+ nGuessLangPara = nGuessLangWord;
+
+ aPopupMenu.InsertSeparator();
+ String aTmpWord( SvtLanguageTable::GetLanguageString( nGuessLangWord ) );
+ String aTmpPara( SvtLanguageTable::GetLanguageString( nGuessLangPara ) );
+ String aWordStr( EditResId( RID_STR_WORD ) );
+ aWordStr.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%x" ) ), aTmpWord );
+ String aParaStr( EditResId( RID_STR_PARAGRAPH ) );
+ aParaStr.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%x" ) ), aTmpPara );
+ aPopupMenu.InsertItem( MN_WORDLANGUAGE, aWordStr );
+ aPopupMenu.SetHelpId( MN_WORDLANGUAGE, HID_EDITENG_SPELLER_WORDLANGUAGE );
+ aPopupMenu.InsertItem( MN_PARALANGUAGE, aParaStr );
+ aPopupMenu.SetHelpId( MN_PARALANGUAGE, HID_EDITENG_SPELLER_PARALANGUAGE );
+ }
+
+ // ## Create mnemonics here
+ if ( Application::IsAutoMnemonicEnabled() )
+ {
+ aPopupMenu.CreateAutoMnemonics();
+ aPopupMenu.SetMenuFlags( aPopupMenu.GetMenuFlags() | MENU_FLAG_NOAUTOMNEMONICS );
+ }
+
+ // Replace suggestions...
+ Sequence< OUString > aAlt;
+ if (xSpellAlt.is())
+ aAlt = xSpellAlt->getAlternatives();
+ const OUString *pAlt = aAlt.getConstArray();
+ sal_uInt16 nWords = (USHORT) aAlt.getLength();
+ if ( nWords )
+ {
+ for ( sal_uInt16 nW = 0; nW < nWords; nW++ )
+ {
+ String aAlternate( pAlt[nW] );
+ aPopupMenu.InsertItem( MN_ALTSTART+nW, aAlternate, 0, nW );
+ pAutoMenu->InsertItem( MN_AUTOSTART+nW, aAlternate, 0, nW );
+ }
+ aPopupMenu.InsertSeparator( nWords );
+ }
+ else
+ aPopupMenu.RemoveItem( MN_AUTOCORR ); // Loeschen?
+
+ Reference< XDictionaryList > xDicList( SvxGetDictionaryList() );
+
+ Sequence< Reference< XDictionary > > aDics;
+ if (xDicList.is())
+ aDics = xDicList->getDictionaries();
+ const Reference< XDictionary > *pDic = aDics.getConstArray();
+ sal_uInt16 nLanguage = PIMPEE->GetLanguage( aPaM2 );
+ sal_uInt16 nDicCount = (USHORT)aDics.getLength();
+ for ( sal_uInt16 i = 0; i < nDicCount; i++ )
+ {
+ Reference< XDictionary > xDic( pDic[i], UNO_QUERY );
+ if (xDic.is())
+ {
+ sal_uInt16 nActLanguage = SvxLocaleToLanguage( xDic->getLocale() );
+ if( xDic->isActive() &&
+ xDic->getDictionaryType() == DictionaryType_POSITIVE &&
+ (nLanguage == nActLanguage || LANGUAGE_NONE == nActLanguage ) )
+ {
+ pInsertMenu->InsertItem( MN_DICTSTART + i, xDic->getName() );
+ }
+ }
+ }
+
+ if ( !pInsertMenu->GetItemCount() )
+ aPopupMenu.EnableItem( MN_INSERT, sal_False );
+
+ aPopupMenu.RemoveDisabledEntries( sal_True, sal_True );
+
+ Rectangle aTempRect = PIMPEE->PaMtoEditCursor( aPaM, GETCRSR_TXTONLY );
+ Point aScreenPos = pImpEditView->GetWindowPos( aTempRect.TopLeft() );
+ aScreenPos = pImpEditView->GetWindow()->OutputToScreenPixel( aScreenPos );
+ aTempRect = pImpEditView->GetWindow()->LogicToPixel( Rectangle(aScreenPos, aTempRect.GetSize() ));
+
+ sal_uInt16 nId = aPopupMenu.Execute( pImpEditView->GetWindow(), aTempRect, POPUPMENU_NOMOUSEUPCLOSE );
+ if ( nId == MN_IGNORE )
+ {
+ String aWord = pImpEditView->SpellIgnoreOrAddWord( sal_False );
+ if ( pCallBack )
+ {
+ SpellCallbackInfo aInf( SPELLCMD_IGNOREWORD, aWord );
+ pCallBack->Call( &aInf );
+ }
+ SetSelection( aOldSel );
+ }
+ else if ( ( nId == MN_WORDLANGUAGE ) || ( nId == MN_PARALANGUAGE ) )
+ {
+ LanguageType nLangToUse = (nId == MN_WORDLANGUAGE) ? nGuessLangWord : nGuessLangPara;
+ sal_uInt16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( nLangToUse );
+
+ SfxItemSet aAttrs = GetEditEngine()->GetEmptyItemSet();
+ if (nScriptType == SCRIPTTYPE_LATIN)
+ aAttrs.Put( SvxLanguageItem( nLangToUse, EE_CHAR_LANGUAGE ) );
+ if (nScriptType == SCRIPTTYPE_COMPLEX)
+ aAttrs.Put( SvxLanguageItem( nLangToUse, EE_CHAR_LANGUAGE_CTL ) );
+ if (nScriptType == SCRIPTTYPE_ASIAN)
+ aAttrs.Put( SvxLanguageItem( nLangToUse, EE_CHAR_LANGUAGE_CJK ) );
+ if ( nId == MN_PARALANGUAGE )
+ {
+ ESelection aSel = GetSelection();
+ aSel.nStartPos = 0;
+ aSel.nEndPos = 0xFFFF;
+ SetSelection( aSel );
+ }
+ SetAttribs( aAttrs );
+ PIMPEE->StartOnlineSpellTimer();
+
+ if ( pCallBack )
+ {
+ SpellCallbackInfo aInf( ( nId == MN_WORDLANGUAGE ) ? SPELLCMD_WORDLANGUAGE : SPELLCMD_PARALANGUAGE, nLangToUse );
+ pCallBack->Call( &aInf );
+ }
+ SetSelection( aOldSel );
+ }
+ else if ( nId == MN_SPELLING )
+ {
+ if ( !pCallBack )
+ {
+ // Cursor vor das Wort setzen...
+ EditPaM aCursor = pImpEditView->GetEditSelection().Min();
+ pImpEditView->DrawSelection(); // alte Selektion 'weg-zeichnen'
+ pImpEditView->SetEditSelection( EditSelection( aCursor, aCursor ) );
+ pImpEditView->DrawSelection();
+ // Stuerzt ab, wenn keine SfxApp
+ PIMPEE->Spell( this, sal_False );
+ }
+ else
+ {
+ SpellCallbackInfo aInf( SPELLCMD_STARTSPELLDLG, String() );
+ pCallBack->Call( &aInf );
+ }
+ }
+ else if ( nId >= MN_DICTSTART )
+ {
+ Reference< XDictionary > xDic( pDic[nId - MN_DICTSTART], UNO_QUERY );
+ if (xDic.is())
+ xDic->add( aSelected, sal_False, String() );
+ // save modified user-dictionary if it is persistent
+ Reference< frame::XStorable > xSavDic( xDic, UNO_QUERY );
+ if (xSavDic.is())
+ xSavDic->store();
+
+ aPaM.GetNode()->GetWrongList()->GetInvalidStart() = 0;
+ aPaM.GetNode()->GetWrongList()->GetInvalidEnd() = aPaM.GetNode()->Len();
+ PIMPEE->StartOnlineSpellTimer();
+
+ if ( pCallBack )
+ {
+ SpellCallbackInfo aInf( SPELLCMD_ADDTODICTIONARY, aSelected );
+ pCallBack->Call( &aInf );
+ }
+ SetSelection( aOldSel );
+ }
+ else if ( nId >= MN_AUTOSTART )
+ {
+ DBG_ASSERT(nId - MN_AUTOSTART < aAlt.getLength(), "index out of range");
+ String aWord = pAlt[nId - MN_AUTOSTART];
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get()->GetAutoCorrect();
+ if ( pAutoCorrect )
+ pAutoCorrect->PutText( aSelected, aWord, PIMPEE->GetLanguage( aPaM2 ) );
+ InsertText( aWord );
+ }
+ else if ( nId >= MN_ALTSTART ) // Replace
+ {
+ DBG_ASSERT(nId - MN_ALTSTART < aAlt.getLength(), "index out of range");
+ String aWord = pAlt[nId - MN_ALTSTART];
+ InsertText( aWord );
+ }
+ else
+ {
+ SetSelection( aOldSel );
+ }
+ }
+#endif
+}
+
+void EditView::SpellIgnoreWord()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ pImpEditView->SpellIgnoreOrAddWord( sal_False );
+}
+
+sal_Bool EditView::SelectCurrentWord()
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ EditSelection aCurSel( pImpEditView->GetEditSelection() );
+ pImpEditView->DrawSelection();
+ aCurSel = PIMPEE->SelectWord( aCurSel.Max() );
+ pImpEditView->SetEditSelection( aCurSel );
+ pImpEditView->DrawSelection();
+ ShowCursor( sal_True, sal_False );
+ return aCurSel.HasRange() ? sal_True : sal_False;
+}
+
+void EditView::InsertField( const SvxFieldItem& rFld )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+
+ ImpEditEngine* pImpEE = PIMPEE;
+ pImpEditView->DrawSelection();
+ pImpEE->UndoActionStart( EDITUNDO_INSERT );
+ EditPaM aPaM( pImpEE->InsertField( pImpEditView->GetEditSelection(), rFld ) );
+ pImpEE->UndoActionEnd( EDITUNDO_INSERT );
+ pImpEditView->SetEditSelection( EditSelection( aPaM, aPaM ) );
+ pImpEE->UpdateFields();
+ pImpEE->FormatAndUpdate( this );
+}
+
+const SvxFieldItem* EditView::GetFieldUnderMousePointer() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ sal_uInt16 nPara, nPos;
+ return GetFieldUnderMousePointer( nPara, nPos );
+}
+
+const SvxFieldItem* EditView::GetField( const Point& rPos, sal_uInt16* pPara, sal_uInt16* pPos ) const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ return pImpEditView->GetField( rPos, pPara, pPos );
+}
+
+const SvxFieldItem* EditView::GetFieldUnderMousePointer( sal_uInt16& nPara, sal_uInt16& nPos ) const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+ Point aPos = pImpEditView->GetWindow()->GetPointerPosPixel();
+ aPos = pImpEditView->GetWindow()->PixelToLogic( aPos );
+ return GetField( aPos, &nPara, &nPos );
+}
+
+const SvxFieldItem* EditView::GetFieldAtSelection() const
+{
+ EditSelection aSel( pImpEditView->GetEditSelection() );
+ aSel.Adjust( pImpEditView->pEditEngine->pImpEditEngine->GetEditDoc() );
+ // Nur wenn Cursor vor Feld, keine Selektion, oder nur Feld selektiert
+ if ( ( aSel.Min().GetNode() == aSel.Max().GetNode() ) &&
+ ( ( aSel.Max().GetIndex() == aSel.Min().GetIndex() ) ||
+ ( aSel.Max().GetIndex() == aSel.Min().GetIndex()+1 ) ) )
+ {
+ EditPaM aPaM = aSel.Min();
+ const CharAttribArray& rAttrs = aPaM.GetNode()->GetCharAttribs().GetAttribs();
+ sal_uInt16 nXPos = aPaM.GetIndex();
+ for ( sal_uInt16 nAttr = rAttrs.Count(); nAttr; )
+ {
+ EditCharAttrib* pAttr = rAttrs[--nAttr];
+ if ( pAttr->GetStart() == nXPos )
+ if ( pAttr->Which() == EE_FEATURE_FIELD )
+ {
+ DBG_ASSERT( pAttr->GetItem()->ISA( SvxFieldItem ), "Kein FeldItem..." );
+ return (const SvxFieldItem*)pAttr->GetItem();
+ }
+ }
+ }
+ return 0;
+}
+
+XubString EditView::GetWordUnderMousePointer() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+
+ Rectangle aRect;
+ return GetWordUnderMousePointer( aRect );
+}
+
+XubString EditView::GetWordUnderMousePointer( Rectangle& rWordRect ) const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+
+ Point aPos = pImpEditView->GetWindow()->GetPointerPosPixel();
+ aPos = pImpEditView->GetWindow()->PixelToLogic( aPos );
+
+ XubString aWord;
+
+ if( GetOutputArea().IsInside( aPos ) )
+ {
+ ImpEditEngine* pImpEE = pImpEditView->pEditEngine->pImpEditEngine;
+ Point aDocPos( pImpEditView->GetDocPos( aPos ) );
+ EditPaM aPaM = pImpEE->GetPaM( aDocPos, sal_False );
+ EditSelection aWordSel = pImpEE->SelectWord( aPaM );
+
+ Rectangle aTopLeftRec( pImpEE->PaMtoEditCursor( aWordSel.Min() ) );
+ Rectangle aBottomRightRec( pImpEE->PaMtoEditCursor( aWordSel.Max() ) );
+
+#if OSL_DEBUG_LEVEL > 1
+ DBG_ASSERT( aTopLeftRec.Top() == aBottomRightRec.Top(), "Top() in einer Zeile unterschiedlich?" );
+#endif
+
+ Point aPnt1( pImpEditView->GetWindowPos( aTopLeftRec.TopLeft() ) );
+ Point aPnt2( pImpEditView->GetWindowPos( aBottomRightRec.BottomRight()) );
+ rWordRect = Rectangle( aPnt1, aPnt2 );
+ aWord = pImpEE->GetSelected( aWordSel );
+ }
+
+ return aWord;
+}
+
+void EditView::SetInvalidateMore( sal_uInt16 nPixel )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ pImpEditView->SetInvalidateMore( nPixel );
+}
+
+sal_uInt16 EditView::GetInvalidateMore() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ return (sal_uInt16)pImpEditView->GetInvalidateMore();
+}
+
+static void ChangeFontSizeImpl( EditView* pEditView, bool bGrow, const ESelection& rSel, const FontList* pFontList )
+{
+ pEditView->SetSelection( rSel );
+
+ SfxItemSet aSet( pEditView->GetAttribs() );
+ if( EditView::ChangeFontSize( bGrow, aSet, pFontList ) )
+ {
+ SfxItemSet aNewSet( pEditView->GetEmptyItemSet() );
+ aNewSet.Put( aSet.Get( EE_CHAR_FONTHEIGHT ), EE_CHAR_FONTHEIGHT );
+ aNewSet.Put( aSet.Get( EE_CHAR_FONTHEIGHT_CJK ), EE_CHAR_FONTHEIGHT_CJK );
+ aNewSet.Put( aSet.Get( EE_CHAR_FONTHEIGHT_CTL ), EE_CHAR_FONTHEIGHT_CTL );
+ pEditView->SetAttribs( aNewSet );
+ }
+}
+
+void EditView::ChangeFontSize( bool bGrow, const FontList* pFontList )
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+
+ EditEngine& rEditEngine = *pImpEditView->pEditEngine;
+
+ ESelection aSel( GetSelection() );
+ ESelection aOldSelection( aSel );
+ aSel.Adjust();
+
+ if( !aSel.HasRange() )
+ {
+ aSel = rEditEngine.GetWord( aSel, com::sun::star::i18n::WordType::DICTIONARY_WORD );
+ }
+
+ if( aSel.HasRange() )
+ {
+ for( USHORT nPara = aSel.nStartPara; nPara <= aSel.nEndPara; nPara++ )
+ {
+ SvUShorts aPortions;
+ rEditEngine.GetPortions( nPara, aPortions );
+
+ if( aPortions.Count() == 0 )
+ aPortions.Insert( rEditEngine.GetTextLen(nPara), 0 );
+
+ const USHORT nBeginPos = (nPara == aSel.nStartPara) ? aSel.nStartPos : 0;
+ const USHORT nEndPos = (nPara == aSel.nEndPara) ? aSel.nEndPos : 0xffff;
+
+ for ( USHORT nPos = 0; nPos < aPortions.Count(); ++nPos )
+ {
+ USHORT nPortionEnd = aPortions.GetObject( nPos );
+ USHORT nPortionStart = nPos > 0 ? aPortions.GetObject( nPos - 1 ) : 0;
+
+ if( (nPortionEnd < nBeginPos) || (nPortionStart > nEndPos) )
+ continue;
+
+ if( nPortionStart < nBeginPos )
+ nPortionStart = nBeginPos;
+ if( nPortionEnd > nEndPos )
+ nPortionEnd = nEndPos;
+
+ if( nPortionStart == nPortionEnd )
+ continue;
+
+ ESelection aPortionSel( nPara, nPortionStart, nPara, nPortionEnd );
+ ChangeFontSizeImpl( this, bGrow, aPortionSel, pFontList );
+ }
+ }
+ }
+ else
+ {
+ ChangeFontSizeImpl( this, bGrow, aSel, pFontList );
+ }
+
+ SetSelection( aOldSelection );
+}
+
+bool EditView::ChangeFontSize( bool bGrow, SfxItemSet& rSet, const FontList* pFontList )
+{
+ static const sal_uInt16 gFontSizeWichMap[] = { EE_CHAR_FONTHEIGHT, EE_CHAR_FONTHEIGHT_CJK, EE_CHAR_FONTHEIGHT_CTL, 0 };
+
+ const SvxFontItem* pFontItem = static_cast<const SvxFontItem*>(&rSet.Get( EE_CHAR_FONTINFO ));
+ if( !pFontItem || !pFontList )
+ return false;
+
+ bool bRet = false;
+
+ const sal_uInt16* pWhich = gFontSizeWichMap;
+ while( *pWhich )
+ {
+ SvxFontHeightItem aFontHeightItem( static_cast<const SvxFontHeightItem&>(rSet.Get( *pWhich )) );
+ long nHeight = aFontHeightItem.GetHeight();
+ const SfxMapUnit eUnit = rSet.GetPool()->GetMetric( *pWhich );
+ nHeight = OutputDevice::LogicToLogic( nHeight * 10, (MapUnit)eUnit, MAP_POINT );
+
+ FontInfo aFontInfo = pFontList->Get( pFontItem->GetFamilyName(), pFontItem->GetStyleName() );
+ const long* pAry = pFontList->GetSizeAry( aFontInfo );
+
+ if( bGrow )
+ {
+ while( *pAry )
+ {
+ if( *pAry > nHeight )
+ {
+ nHeight = *pAry;
+ break;
+ }
+ pAry++;
+ }
+
+ if( *pAry == 0 )
+ {
+ nHeight += (nHeight + 5) / 10;
+ if( nHeight > 9999 )
+ nHeight = 9999;
+ }
+
+ }
+ else if( *pAry )
+ {
+ bool bFound = false;
+ if( *pAry < nHeight )
+ {
+ pAry++;
+ while( *pAry )
+ {
+ if( *pAry >= nHeight )
+ {
+ nHeight = pAry[-1];
+ bFound = true;
+ break;
+ }
+ pAry++;
+ }
+ }
+
+ if( !bFound )
+ {
+ nHeight -= (nHeight + 5) / 10;
+ if( nHeight < 2 )
+ nHeight = 2;
+ }
+ }
+
+ if( (nHeight >= 2) && (nHeight <= 9999 ) )
+ {
+ nHeight = OutputDevice::LogicToLogic( nHeight, MAP_POINT, (MapUnit)eUnit ) / 10;
+
+ if( nHeight != (long)aFontHeightItem.GetHeight() )
+ {
+ aFontHeightItem.SetHeight( nHeight );
+ rSet.Put( aFontHeightItem, *pWhich );
+ bRet = true;
+ }
+ }
+ pWhich++;
+ }
+ return bRet;
+}
+
+String EditView::GetSurroundingText() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+
+ EditSelection aSel( pImpEditView->GetEditSelection() );
+ aSel.Adjust( PIMPEE->GetEditDoc() );
+
+ if( HasSelection() )
+ {
+ XubString aStr = PIMPEE->GetSelected( aSel );
+
+ // Stop reconversion if the selected text includes a line break.
+ if ( aStr.Search( 0x0A ) == STRING_NOTFOUND )
+ return aStr;
+ else
+ return String();
+ }
+ else
+ {
+ aSel.Min().SetIndex( 0 );
+ aSel.Max().SetIndex( aSel.Max().GetNode()->Len() );
+ return PIMPEE->GetSelected( aSel );
+ }
+}
+
+Selection EditView::GetSurroundingTextSelection() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+
+ ESelection aSelection( GetSelection() );
+ aSelection.Adjust();
+
+ if( HasSelection() )
+ {
+ EditSelection aSel( pImpEditView->GetEditSelection() );
+ aSel.Adjust( PIMPEE->GetEditDoc() );
+ XubString aStr = PIMPEE->GetSelected( aSel );
+
+ // Stop reconversion if the selected text includes a line break.
+ if ( aStr.Search( 0x0A ) == STRING_NOTFOUND )
+ return Selection( 0, aSelection.nEndPos - aSelection.nStartPos );
+ else
+ return Selection( 0, 0 );
+ }
+ else
+ {
+ return Selection( aSelection.nStartPos, aSelection.nEndPos );
+ }
+}
diff --git a/editeng/source/editeng/edtspell.cxx b/editeng/source/editeng/edtspell.cxx
new file mode 100644
index 0000000000..9578f523ab
--- /dev/null
+++ b/editeng/source/editeng/edtspell.cxx
@@ -0,0 +1,749 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: edtspell.cxx,v $
+ * $Revision: 1.16 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <vcl/wrkwin.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+
+#include <impedit.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/editeng.hxx>
+#include <edtspell.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/fontitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/eitem.hxx>
+#include <editeng/unolingu.hxx>
+#include <linguistic/lngprops.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+using ::rtl::OUString;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::linguistic2;
+
+
+EditSpellWrapper::EditSpellWrapper( Window* _pWin,
+ Reference< XSpellChecker1 > &xChecker,
+ sal_Bool bIsStart, sal_Bool bIsAllRight, EditView* pView ) :
+ SvxSpellWrapper( _pWin, xChecker, bIsStart, bIsAllRight )
+{
+ DBG_ASSERT( pView, "Es muss eine View uebergeben werden!" );
+ // IgnoreList behalten, ReplaceList loeschen...
+ if (SvxGetChangeAllList().is())
+ SvxGetChangeAllList()->clear();
+ pEditView = pView;
+}
+
+void __EXPORT EditSpellWrapper::SpellStart( SvxSpellArea eArea )
+{
+ ImpEditEngine* pImpEE = pEditView->GetImpEditEngine();
+ SpellInfo* pSpellInfo = pImpEE->GetSpellInfo();
+
+ if ( eArea == SVX_SPELL_BODY_START )
+ {
+ // Wird gerufen, wenn
+ // a) Spell-Forwad ist am Ende angekomment und soll von vorne beginnen
+ // IsEndDone() liefert auch sal_True, wenn Rueckwaerts-Spelling am Ende gestartet wird!
+ if ( IsEndDone() )
+ {
+ pSpellInfo->bSpellToEnd = sal_False;
+ pSpellInfo->aSpellTo = pSpellInfo->aSpellStart;
+ pEditView->GetImpEditView()->SetEditSelection(
+ pImpEE->GetEditDoc().GetStartPaM() );
+ }
+ else
+ {
+ pSpellInfo->bSpellToEnd = sal_True;
+ pSpellInfo->aSpellTo = pImpEE->CreateEPaM(
+ pImpEE->GetEditDoc().GetStartPaM() );
+ }
+ }
+ else if ( eArea == SVX_SPELL_BODY_END )
+ {
+ // Wird gerufen, wenn
+ // a) Spell-Forwad wird gestartet
+ // IsStartDone() liefert auch sal_True, wenn Vorwaerts-Spelling am Anfang gestartet wird!
+ if ( !IsStartDone() )
+ {
+ pSpellInfo->bSpellToEnd = sal_True;
+ pSpellInfo->aSpellTo = pImpEE->CreateEPaM(
+ pImpEE->GetEditDoc().GetEndPaM() );
+ }
+ else
+ {
+ pSpellInfo->bSpellToEnd = sal_False;
+ pSpellInfo->aSpellTo = pSpellInfo->aSpellStart;
+ pEditView->GetImpEditView()->SetEditSelection(
+ pImpEE->GetEditDoc().GetEndPaM() );
+ }
+ }
+ else if ( eArea == SVX_SPELL_BODY )
+ {
+ ; // Wird ueber SpellNextDocument von App gehandelt
+
+ // pSpellInfo->bSpellToEnd = sal_True;
+ // pSpellInfo->aSpellTo = pImpEE->CreateEPaM( pImpEE->GetEditDoc().GetEndPaM() );
+ }
+ else
+ {
+ DBG_ERROR( "SpellStart: Unknown Area!" );
+ }
+}
+
+sal_Bool EditSpellWrapper::SpellContinue()
+{
+ SetLast( pEditView->GetImpEditEngine()->ImpSpell( pEditView ) );
+ return GetLast().is();
+}
+
+void __EXPORT EditSpellWrapper::SpellEnd()
+{
+ // Base class will show language errors...
+ SvxSpellWrapper::SpellEnd();
+}
+
+sal_Bool __EXPORT EditSpellWrapper::HasOtherCnt()
+{
+ return sal_False;
+}
+
+sal_Bool __EXPORT EditSpellWrapper::SpellMore()
+{
+ ImpEditEngine* pImpEE = pEditView->GetImpEditEngine();
+ SpellInfo* pSpellInfo = pImpEE->GetSpellInfo();
+ sal_Bool bMore = sal_False;
+ if ( pSpellInfo->bMultipleDoc )
+ {
+ bMore = pImpEE->GetEditEnginePtr()->SpellNextDocument();
+ if ( bMore )
+ {
+ // Der Text wurde in diese Engine getreten, bei Rueckwaerts
+ // muss die Selektion hinten sein.
+ Reference< XPropertySet > xProp( SvxGetLinguPropertySet() );
+ pEditView->GetImpEditView()->SetEditSelection(
+ pImpEE->GetEditDoc().GetStartPaM() );
+ }
+ }
+ return bMore;
+}
+
+void __EXPORT EditSpellWrapper::ScrollArea()
+{
+ // Keine weitere Aktion noetig...
+ // Es sei denn, der Bereich soll in die Mitte gescrollt werden,
+ // und nicht irgendwo stehen.
+}
+
+void __EXPORT EditSpellWrapper::ReplaceAll( const String &rNewText,
+ sal_Int16 )
+{
+ // Wird gerufen, wenn Wort in ReplaceList des SpellCheckers
+ pEditView->InsertText( rNewText );
+ CheckSpellTo();
+}
+
+void __EXPORT EditSpellWrapper::ChangeWord( const String& rNewWord,
+ const sal_uInt16 )
+{
+ // Wird gerufen, wenn Wort Button Change
+ // bzw. intern von mir bei ChangeAll
+
+ // Wenn Punkt hinterm Wort, wird dieser nicht mitgegeben.
+ // Falls '"' => PreStripped.
+ String aNewWord( rNewWord );
+ pEditView->InsertText( aNewWord );
+ CheckSpellTo();
+}
+
+void __EXPORT EditSpellWrapper::ChangeThesWord( const String& rNewWord )
+{
+ pEditView->InsertText( rNewWord );
+ CheckSpellTo();
+}
+
+void __EXPORT EditSpellWrapper::AutoCorrect( const String&, const String& )
+{
+}
+
+void EditSpellWrapper::CheckSpellTo()
+{
+ ImpEditEngine* pImpEE = pEditView->GetImpEditEngine();
+ SpellInfo* pSpellInfo = pImpEE->GetSpellInfo();
+ EditPaM aPaM( pEditView->GetImpEditView()->GetEditSelection().Max() );
+ EPaM aEPaM = pImpEE->CreateEPaM( aPaM );
+ if ( aEPaM.nPara == pSpellInfo->aSpellTo.nPara )
+ {
+ // prueffen, ob SpellToEnd noch gueltiger Index, falls in dem Absatz
+ // ersetzt wurde.
+ if ( pSpellInfo->aSpellTo.nIndex > aPaM.GetNode()->Len() )
+ pSpellInfo->aSpellTo.nIndex = aPaM.GetNode()->Len();
+ }
+}
+SV_IMPL_VARARR( WrongRanges, WrongRange );
+
+WrongList::WrongList()
+{
+ nInvalidStart = 0;
+ nInvalidEnd = 0xFFFF;
+}
+
+WrongList::~WrongList()
+{
+}
+
+void WrongList::TextInserted( sal_uInt16 nPos, sal_uInt16 nNew, sal_Bool bPosIsSep )
+{
+ if ( !IsInvalid() )
+ {
+ nInvalidStart = nPos;
+ nInvalidEnd = nPos+nNew;
+ }
+ else
+ {
+ if ( nInvalidStart > nPos )
+ nInvalidStart = nPos;
+ if ( nInvalidEnd >= nPos )
+ nInvalidEnd = nInvalidEnd + nNew;
+ else
+ nInvalidEnd = nPos+nNew;
+ }
+
+ for ( sal_uInt16 n = 0; n < Count(); n++ )
+ {
+ WrongRange& rWrong = GetObject( n );
+ sal_Bool bRefIsValid = sal_True;
+ if ( rWrong.nEnd >= nPos )
+ {
+ // Alle Wrongs hinter der Einfuegeposition verschieben...
+ if ( rWrong.nStart > nPos )
+ {
+ rWrong.nStart = rWrong.nStart + nNew;
+ rWrong.nEnd = rWrong.nEnd + nNew;
+ }
+ // 1: Startet davor, geht bis nPos...
+ else if ( rWrong.nEnd == nPos )
+ {
+ // Sollte bei einem Blank unterbunden werden!
+ if ( !bPosIsSep )
+ rWrong.nEnd = rWrong.nEnd + nNew;
+ }
+ // 2: Startet davor, geht hinter Pos...
+ else if ( ( rWrong.nStart < nPos ) && ( rWrong.nEnd > nPos ) )
+ {
+ rWrong.nEnd = rWrong.nEnd + nNew;
+ // Bei einem Trenner das Wrong entfernen und neu pruefen
+ if ( bPosIsSep )
+ {
+ // Wrong aufteilen...
+ WrongRange aNewWrong( rWrong.nStart, nPos );
+ rWrong.nStart = nPos+1;
+ Insert( aNewWrong, n );
+ bRefIsValid = sal_False; // Referenz nach Insert nicht mehr gueltig, der andere wurde davor an dessen Position eingefuegt
+ n++; // Diesen nicht nochmal...
+ }
+ }
+ // 3: Attribut startet auf Pos...
+ else if ( rWrong.nStart == nPos )
+ {
+ rWrong.nEnd = rWrong.nEnd + nNew;
+ if ( bPosIsSep )
+ rWrong.nStart++;
+ }
+ }
+ DBG_ASSERT( !bRefIsValid || ( rWrong.nStart < rWrong.nEnd ),
+ "TextInserted, WrongRange: Start >= End?!" );
+ }
+
+ DBG_ASSERT( !DbgIsBuggy(), "InsertWrong: WrongList kaputt!" );
+}
+
+void WrongList::TextDeleted( sal_uInt16 nPos, sal_uInt16 nDeleted )
+{
+ sal_uInt16 nEndChanges = nPos+nDeleted;
+ if ( !IsInvalid() )
+ {
+ sal_uInt16 nNewInvalidStart = nPos ? nPos - 1 : 0;
+ nInvalidStart = nNewInvalidStart;
+ nInvalidEnd = nNewInvalidStart + 1;
+ }
+ else
+ {
+ if ( nInvalidStart > nPos )
+ nInvalidStart = nPos;
+ if ( nInvalidEnd > nPos )
+ {
+ if ( nInvalidEnd > nEndChanges )
+ nInvalidEnd = nInvalidEnd - nDeleted;
+ else
+ nInvalidEnd = nPos+1;
+ }
+ }
+
+ for ( sal_uInt16 n = 0; n < Count(); n++ )
+ {
+ WrongRange& rWrong = GetObject( n );
+ sal_Bool bDelWrong = sal_False;
+ if ( rWrong.nEnd >= nPos )
+ {
+ // Alles Wrongs hinter der Einfuegeposition verschieben...
+ if ( rWrong.nStart >= nEndChanges )
+ {
+ rWrong.nStart = rWrong.nStart - nDeleted;
+ rWrong.nEnd = rWrong.nEnd - nDeleted;
+ }
+ // 1. Innenliegende Wrongs loeschen...
+ else if ( ( rWrong.nStart >= nPos ) && ( rWrong.nEnd <= nEndChanges ) )
+ {
+ bDelWrong = sal_True;
+ }
+ // 2. Wrong beginnt davor, endet drinnen oder dahinter...
+ else if ( ( rWrong.nStart <= nPos ) && ( rWrong.nEnd > nPos ) )
+ {
+ if ( rWrong.nEnd <= nEndChanges ) // endet drinnen
+ rWrong.nEnd = nPos;
+ else
+ rWrong.nEnd = rWrong.nEnd - nDeleted; // endet dahinter
+ }
+ // 3. Wrong beginnt drinnen, endet dahinter...
+ else if ( ( rWrong.nStart >= nPos ) && ( rWrong.nEnd > nEndChanges ) )
+ {
+ rWrong.nStart = nEndChanges;
+ rWrong.nStart = rWrong.nStart - nDeleted;
+ rWrong.nEnd = rWrong.nEnd - nDeleted;
+ }
+ }
+ DBG_ASSERT( rWrong.nStart < rWrong.nEnd,
+ "TextInserted, WrongRange: Start >= End?!" );
+ if ( bDelWrong )
+ {
+ Remove( n, 1 );
+ n--;
+ }
+ }
+
+ DBG_ASSERT( !DbgIsBuggy(), "InsertWrong: WrongList kaputt!" );
+}
+
+sal_Bool WrongList::NextWrong( sal_uInt16& rnStart, sal_uInt16& rnEnd ) const
+{
+ /*
+ rnStart enthaelt die Startposition, wird ggf. auf Wrong-Start korrigiert
+ rnEnd braucht nicht inizialisiert sein.
+ */
+ for ( sal_uInt16 n = 0; n < Count(); n++ )
+ {
+ WrongRange& rWrong = GetObject( n );
+ if ( rWrong.nEnd > rnStart )
+ {
+ rnStart = rWrong.nStart;
+ rnEnd = rWrong.nEnd;
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+
+sal_Bool WrongList::HasWrong( sal_uInt16 nStart, sal_uInt16 nEnd ) const
+{
+ for ( sal_uInt16 n = 0; n < Count(); n++ )
+ {
+ WrongRange& rWrong = GetObject( n );
+ if ( ( rWrong.nStart == nStart ) && ( rWrong.nEnd == nEnd ) )
+ return sal_True;
+ else if ( rWrong.nStart >= nStart )
+ break;
+ }
+ return sal_False;
+}
+
+sal_Bool WrongList::HasAnyWrong( sal_uInt16 nStart, sal_uInt16 nEnd ) const
+{
+ for ( sal_uInt16 n = 0; n < Count(); n++ )
+ {
+ WrongRange& rWrong = GetObject( n );
+ if ( ( rWrong.nEnd >= nStart ) && ( rWrong.nStart < nEnd ) )
+ return sal_True;
+ else if ( rWrong.nStart >= nEnd )
+ break;
+ }
+ return sal_False;
+}
+
+void WrongList::ClearWrongs( sal_uInt16 nStart, sal_uInt16 nEnd,
+ const ContentNode* pNode )
+{
+ for ( sal_uInt16 n = 0; n < Count(); n++ )
+ {
+ WrongRange& rWrong = GetObject( n );
+ if ( ( rWrong.nEnd > nStart ) && ( rWrong.nStart < nEnd ) )
+ {
+ if ( rWrong.nEnd > nEnd ) // // Laeuft raus
+ {
+ rWrong.nStart = nEnd;
+ // Blanks?
+ while ( ( rWrong.nStart < pNode->Len() ) &&
+ ( ( pNode->GetChar( rWrong.nStart ) == ' ' ) ||
+ ( pNode->IsFeature( rWrong.nStart ) ) ) )
+ {
+ rWrong.nStart++;
+ }
+ }
+ else
+ {
+ Remove( n, 1 );
+ n--;
+ }
+ }
+ }
+
+ DBG_ASSERT( !DbgIsBuggy(), "InsertWrong: WrongList kaputt!" );
+}
+
+void WrongList::InsertWrong( sal_uInt16 nStart, sal_uInt16 nEnd,
+ sal_Bool bClearRange )
+{
+ sal_uInt16 nPos = Count();
+ for ( sal_uInt16 n = 0; n < Count(); n++ )
+ {
+ WrongRange& rWrong = GetObject( n );
+ if ( rWrong.nStart >= nStart )
+ {
+ nPos = n;
+ if ( bClearRange )
+ {
+ // Es kann eigentlich nur Passieren, dass der Wrong genau
+ // hier beginnt und weiter rauslauft, aber nicht, dass hier
+ // mehrere im Bereich liegen...
+ // Genau im Bereich darf keiner liegen, sonst darf diese Methode
+ // garnicht erst gerufen werden!
+ DBG_ASSERT( ( ( rWrong.nStart == nStart ) && ( rWrong.nEnd > nEnd ) )
+ || ( rWrong.nStart > nEnd ), "InsertWrong: RangeMismatch!" );
+ if ( ( rWrong.nStart == nStart ) && ( rWrong.nEnd > nEnd ) )
+ rWrong.nStart = nEnd+1;
+ }
+ break;
+ }
+ }
+ Insert( WrongRange( nStart, nEnd ), nPos );
+
+ DBG_ASSERT( !DbgIsBuggy(), "InsertWrong: WrongList kaputt!" );
+}
+
+void WrongList::MarkWrongsInvalid()
+{
+ if ( Count() )
+ MarkInvalid( GetObject( 0 ).nStart, GetObject( Count()-1 ).nEnd );
+}
+
+WrongList* WrongList::Clone() const
+{
+ WrongList* pNew = new WrongList;
+ for ( sal_uInt16 n = 0; n < Count(); n++ )
+ {
+ WrongRange& rWrong = GetObject( n );
+ pNew->Insert( rWrong, pNew->Count() );
+ }
+
+ return pNew;
+}
+
+// #i102062#
+bool WrongList::operator==(const WrongList& rCompare) const
+{
+ // cleck direct members
+ if(GetInvalidStart() != rCompare.GetInvalidStart()
+ || GetInvalidEnd() != rCompare.GetInvalidEnd()
+ || Count() != rCompare.Count())
+ {
+ return false;
+ }
+
+ for(USHORT a(0); a < Count(); a++)
+ {
+ const WrongRange& rCandA(GetObject(a));
+ const WrongRange& rCandB(rCompare.GetObject(a));
+
+ if(rCandA.nStart != rCandB.nStart
+ || rCandA.nEnd != rCandB.nEnd)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+#ifdef DBG_UTIL
+sal_Bool WrongList::DbgIsBuggy() const
+{
+ // Pruefen, ob sich Bereiche ueberlappen
+ sal_Bool bError = sal_False;
+ for ( sal_uInt16 _nA = 0; !bError && ( _nA < Count() ); _nA++ )
+ {
+ WrongRange& rWrong = GetObject( _nA );
+ for ( sal_uInt16 nB = _nA+1; !bError && ( nB < Count() ); nB++ )
+ {
+ WrongRange& rNextWrong = GetObject( nB );
+ // 1) Start davor, End hinterm anderen Start
+ if ( ( rWrong.nStart <= rNextWrong.nStart )
+ && ( rWrong.nEnd >= rNextWrong.nStart ) )
+ bError = sal_True;
+ // 2) Start hinter anderen Start, aber noch vorm anderen End
+ else if ( ( rWrong.nStart >= rNextWrong.nStart)
+ && ( rWrong.nStart <= rNextWrong.nEnd ) )
+ bError = sal_True;
+ }
+ }
+ return bError;
+}
+#endif
+
+
+EdtAutoCorrDoc::EdtAutoCorrDoc( ImpEditEngine* pE, ContentNode* pN,
+ sal_uInt16 nCrsr, xub_Unicode cIns )
+{
+ pImpEE = pE;
+ pCurNode = pN;
+ nCursor = nCrsr;
+
+ bUndoAction = sal_False;
+ bAllowUndoAction = cIns ? sal_True : sal_False;
+}
+
+EdtAutoCorrDoc::~EdtAutoCorrDoc()
+{
+ if ( bUndoAction )
+ pImpEE->UndoActionEnd( EDITUNDO_INSERT );
+}
+
+sal_Bool EdtAutoCorrDoc::Delete( sal_uInt16 nStt, sal_uInt16 nEnd )
+{
+ EditSelection aSel( EditPaM( pCurNode, nStt ), EditPaM( pCurNode, nEnd ) );
+ pImpEE->ImpDeleteSelection( aSel );
+ DBG_ASSERT( nCursor >= nEnd, "Cursor mitten im Geschehen ?!" );
+ nCursor -= ( nEnd-nStt );
+ bAllowUndoAction = sal_False;
+ return sal_True;
+}
+
+sal_Bool EdtAutoCorrDoc::Insert( sal_uInt16 nPos, const String& rTxt )
+{
+ EditSelection aSel = EditPaM( pCurNode, nPos );
+ pImpEE->ImpInsertText( aSel, rTxt );
+ DBG_ASSERT( nCursor >= nPos, "Cursor mitten im Geschehen ?!" );
+ nCursor = nCursor + rTxt.Len();
+
+ if ( bAllowUndoAction && ( rTxt.Len() == 1 ) )
+ ImplStartUndoAction();
+ bAllowUndoAction = sal_False;
+
+ return sal_True;
+}
+
+sal_Bool EdtAutoCorrDoc::Replace( sal_uInt16 nPos, const String& rTxt )
+{
+ // Eigentlich ein Replace einfuehren => Entspr. UNDO
+ sal_uInt16 nEnd = nPos+rTxt.Len();
+ if ( nEnd > pCurNode->Len() )
+ nEnd = pCurNode->Len();
+
+ // #i5925# First insert new text behind to be deleted text, for keeping attributes.
+ pImpEE->ImpInsertText( EditSelection( EditPaM( pCurNode, nEnd ) ), rTxt );
+ pImpEE->ImpDeleteSelection( EditSelection( EditPaM( pCurNode, nPos ), EditPaM( pCurNode, nEnd ) ) );
+
+ if ( nPos == nCursor )
+ nCursor = nCursor + rTxt.Len();
+
+ if ( bAllowUndoAction && ( rTxt.Len() == 1 ) )
+ ImplStartUndoAction();
+
+ bAllowUndoAction = sal_False;
+
+ return sal_True;
+}
+
+sal_Bool EdtAutoCorrDoc::SetAttr( sal_uInt16 nStt, sal_uInt16 nEnd,
+ sal_uInt16 nSlotId, SfxPoolItem& rItem )
+{
+ SfxItemPool* pPool = &pImpEE->GetEditDoc().GetItemPool();
+ while ( pPool->GetSecondaryPool() &&
+ !pPool->GetName().EqualsAscii( "EditEngineItemPool" ) )
+ {
+ pPool = pPool->GetSecondaryPool();
+
+ }
+ sal_uInt16 nWhich = pPool->GetWhich( nSlotId );
+ if ( nWhich )
+ {
+ rItem.SetWhich( nWhich );
+
+ SfxItemSet aSet( pImpEE->GetEmptyItemSet() );
+ aSet.Put( rItem );
+
+ EditSelection aSel( EditPaM( pCurNode, nStt ), EditPaM( pCurNode, nEnd ) );
+ aSel.Max().SetIndex( nEnd ); // ???
+ pImpEE->SetAttribs( aSel, aSet, ATTRSPECIAL_EDGE );
+ bAllowUndoAction = sal_False;
+ }
+ return sal_True;
+}
+
+sal_Bool EdtAutoCorrDoc::SetINetAttr( sal_uInt16 nStt, sal_uInt16 nEnd,
+ const String& rURL )
+{
+ // Aus dem Text ein Feldbefehl machen...
+ EditSelection aSel( EditPaM( pCurNode, nStt ), EditPaM( pCurNode, nEnd ) );
+ String aText = pImpEE->GetSelected( aSel );
+ aSel = pImpEE->ImpDeleteSelection( aSel );
+ DBG_ASSERT( nCursor >= nEnd, "Cursor mitten im Geschehen ?!" );
+ nCursor -= ( nEnd-nStt );
+ SvxFieldItem aField( SvxURLField( rURL, aText, SVXURLFORMAT_REPR ),
+ EE_FEATURE_FIELD );
+ pImpEE->InsertField( aSel, aField );
+ nCursor++;
+ pImpEE->UpdateFields();
+ bAllowUndoAction = sal_False;
+ return sal_True;
+}
+
+sal_Bool EdtAutoCorrDoc::HasSymbolChars( sal_uInt16 nStt, sal_uInt16 nEnd )
+{
+ USHORT nScriptType = pImpEE->GetScriptType( EditPaM( pCurNode, nStt ) );
+ USHORT nScriptFontInfoItemId = GetScriptItemId( EE_CHAR_FONTINFO, nScriptType );
+
+ CharAttribArray& rAttribs = pCurNode->GetCharAttribs().GetAttribs();
+ sal_uInt16 nAttrs = rAttribs.Count();
+ for ( sal_uInt16 n = 0; n < nAttrs; n++ )
+ {
+ EditCharAttrib* pAttr = rAttribs.GetObject( n );
+ if ( pAttr->GetStart() >= nEnd )
+ return sal_False;
+
+ if ( ( pAttr->Which() == nScriptFontInfoItemId ) &&
+ ( ((SvxFontItem*)pAttr->GetItem())->GetCharSet() == RTL_TEXTENCODING_SYMBOL ) )
+ {
+ // Pruefen, ob das Attribt im Bereich liegt...
+ if ( pAttr->GetEnd() >= nStt )
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+
+const String* EdtAutoCorrDoc::GetPrevPara( sal_Bool )
+{
+ // Vorherigen Absatz zurueck geben, damit ermittel werden kann,
+ // ob es sich beim aktuellen Wort um einen Satzanfang handelt.
+
+ bAllowUndoAction = sal_False; // Jetzt nicht mehr...
+
+ ContentList& rNodes = pImpEE->GetEditDoc();
+ sal_uInt16 nPos = rNodes.GetPos( pCurNode );
+
+ // Sonderbehandlung: Bullet => Absatzanfang => einfach NULL returnen...
+ const SfxBoolItem& rBulletState = (const SfxBoolItem&)
+ pImpEE->GetParaAttrib( nPos, EE_PARA_BULLETSTATE );
+ sal_Bool bBullet = rBulletState.GetValue() ? sal_True : sal_False;
+ if ( !bBullet && ( pImpEE->aStatus.GetControlWord() & EE_CNTRL_OUTLINER ) )
+ {
+ // Der Outliner hat im Gliederungsmodus auf Ebene 0 immer ein Bullet.
+ const SfxInt16Item& rLevel = (const SfxInt16Item&)
+ pImpEE->GetParaAttrib( nPos, EE_PARA_OUTLLEVEL );
+ if ( rLevel.GetValue() == 0 )
+ bBullet = sal_True;
+ }
+ if ( bBullet )
+ return NULL;
+
+ for ( sal_uInt16 n = nPos; n; )
+ {
+ n--;
+ ContentNode* pNode = rNodes[n];
+ if ( pNode->Len() )
+ return pNode;
+ }
+ return NULL;
+
+}
+
+sal_Bool EdtAutoCorrDoc::ChgAutoCorrWord( sal_uInt16& rSttPos,
+ sal_uInt16 nEndPos, SvxAutoCorrect& rACorrect,
+ const String** ppPara )
+{
+ // Absatz-Anfang oder ein Blank gefunden, suche nach dem Wort
+ // Kuerzel im Auto
+
+ bAllowUndoAction = sal_False; // Jetzt nicht mehr...
+
+ String aShort( pCurNode->Copy( rSttPos, nEndPos - rSttPos ) );
+ sal_Bool bRet = sal_False;
+
+ if( !aShort.Len() )
+ return bRet;
+
+ LanguageType eLang = pImpEE->GetLanguage( EditPaM( pCurNode, rSttPos+1 ) );
+ const SvxAutocorrWord* pFnd = rACorrect.SearchWordsInList( *pCurNode, rSttPos, nEndPos, *this, eLang );
+ if( pFnd && pFnd->IsTextOnly() )
+ {
+ // dann mal ersetzen
+ EditSelection aSel( EditPaM( pCurNode, rSttPos ),
+ EditPaM( pCurNode, nEndPos ) );
+ aSel = pImpEE->ImpDeleteSelection( aSel );
+ DBG_ASSERT( nCursor >= nEndPos, "Cursor mitten im Geschehen ?!" );
+ nCursor -= ( nEndPos-rSttPos );
+ pImpEE->ImpInsertText( aSel, pFnd->GetLong() );
+ nCursor = nCursor + pFnd->GetLong().Len();
+ if( ppPara )
+ *ppPara = pCurNode;
+ bRet = sal_True;
+ }
+
+ return bRet;
+}
+
+LanguageType EdtAutoCorrDoc::GetLanguage( sal_uInt16 nPos, sal_Bool ) const
+{
+ return pImpEE->GetLanguage( EditPaM( pCurNode, nPos+1 ) );
+}
+
+void EdtAutoCorrDoc::ImplStartUndoAction()
+{
+ sal_uInt16 nPara = pImpEE->GetEditDoc().GetPos( pCurNode );
+ ESelection aSel( nPara, nCursor, nPara, nCursor );
+ pImpEE->UndoActionStart( EDITUNDO_INSERT, aSel );
+ bUndoAction = sal_True;
+ bAllowUndoAction = sal_False;
+}
+
diff --git a/editeng/source/editeng/edtspell.hxx b/editeng/source/editeng/edtspell.hxx
new file mode 100644
index 0000000000..b2b6072e2f
--- /dev/null
+++ b/editeng/source/editeng/edtspell.hxx
@@ -0,0 +1,188 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: edtspell.hxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _EDTSPELL_HXX
+#define _EDTSPELL_HXX
+
+#include <svtools/svxbox.hxx>
+#include <editeng/svxenum.hxx>
+#include <editeng/splwrap.hxx>
+#include <editeng/svxacorr.hxx>
+#include <com/sun/star/uno/Reference.h>
+#include <editeng/editengdllapi.h>
+
+namespace com { namespace sun { namespace star { namespace linguistic2 {
+ class XSpellChecker1;
+}}}}
+
+
+class EditView;
+class ImpEditEngine;
+class ContentNode;
+
+class EditSpellWrapper : public SvxSpellWrapper
+{
+private:
+ EditView* pEditView;
+ void CheckSpellTo();
+
+protected:
+ virtual void SpellStart( SvxSpellArea eArea );
+ virtual BOOL SpellContinue(); // Bereich pruefen
+ virtual void ReplaceAll( const String &rNewText, INT16 nLanguage );
+ virtual void SpellEnd();
+ virtual BOOL SpellMore();
+ virtual BOOL HasOtherCnt();
+ virtual void ScrollArea();
+ virtual void ChangeWord( const String& rNewWord, const USHORT nLang );
+ virtual void ChangeThesWord( const String& rNewWord );
+ virtual void AutoCorrect( const String& rOldWord, const String& rNewWord );
+
+public:
+ EditSpellWrapper( Window* pWin,
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::linguistic2::XSpellChecker1 > &xChecker,
+ BOOL bIsStart,
+ BOOL bIsAllRight, EditView* pView );
+
+};
+
+
+struct WrongRange
+{
+ USHORT nStart;
+ USHORT nEnd;
+
+ WrongRange( USHORT nS, USHORT nE ) { nStart = nS; nEnd = nE; }
+};
+
+SV_DECL_VARARR( WrongRanges, WrongRange, 4, 4 )
+#define NOT_INVALID 0xFFFF
+
+class WrongList : private WrongRanges
+{
+private:
+ USHORT nInvalidStart;
+ USHORT nInvalidEnd;
+
+ BOOL DbgIsBuggy() const;
+
+public:
+ WrongList();
+ ~WrongList();
+
+ BOOL IsInvalid() const { return nInvalidStart != NOT_INVALID; }
+ void SetValid() { nInvalidStart = NOT_INVALID; nInvalidEnd = 0; }
+ void MarkInvalid( USHORT nS, USHORT nE )
+ {
+ if ( ( nInvalidStart == NOT_INVALID ) || ( nInvalidStart > nS ) )
+ nInvalidStart = nS;
+ if ( nInvalidEnd < nE )
+ nInvalidEnd = nE;
+ }
+
+ USHORT Count() const { return WrongRanges::Count(); }
+
+ // Wenn man weiss was man tut:
+ WrongRange& GetObject( USHORT n ) const { return WrongRanges::GetObject( n ); }
+ void InsertWrong( const WrongRange& rWrong, USHORT nPos );
+
+ USHORT GetInvalidStart() const { return nInvalidStart; }
+ USHORT& GetInvalidStart() { return nInvalidStart; }
+
+ USHORT GetInvalidEnd() const { return nInvalidEnd; }
+ USHORT& GetInvalidEnd() { return nInvalidEnd; }
+
+ void TextInserted( USHORT nPos, USHORT nChars, BOOL bPosIsSep );
+ void TextDeleted( USHORT nPos, USHORT nChars );
+
+ void ResetRanges() { Remove( 0, Count() ); }
+ BOOL HasWrongs() const { return Count() != 0; }
+ void InsertWrong( USHORT nStart, USHORT nEnd, BOOL bClearRange );
+ BOOL NextWrong( USHORT& rnStart, USHORT& rnEnd ) const;
+ BOOL HasWrong( USHORT nStart, USHORT nEnd ) const;
+ BOOL HasAnyWrong( USHORT nStart, USHORT nEnd ) const;
+ void ClearWrongs( USHORT nStart, USHORT nEnd, const ContentNode* pNode );
+ void MarkWrongsInvalid();
+
+ WrongList* Clone() const;
+
+ // #i102062#
+ bool operator==(const WrongList& rCompare) const;
+};
+
+inline void WrongList::InsertWrong( const WrongRange& rWrong, USHORT nPos )
+{
+ WrongRanges::Insert( rWrong, nPos );
+#ifdef DBG_UTIL
+ DBG_ASSERT( !DbgIsBuggy(), "Insert: WrongList kaputt!" );
+#endif
+}
+
+
+
+class EdtAutoCorrDoc : public SvxAutoCorrDoc
+{
+ ImpEditEngine* pImpEE;
+ ContentNode* pCurNode;
+ USHORT nCursor;
+
+ BOOL bAllowUndoAction;
+ BOOL bUndoAction;
+
+protected:
+ void ImplStartUndoAction();
+
+public:
+ EdtAutoCorrDoc( ImpEditEngine* pImpEE, ContentNode* pCurNode, USHORT nCrsr, xub_Unicode cIns );
+ ~EdtAutoCorrDoc();
+
+ virtual BOOL Delete( USHORT nStt, USHORT nEnd );
+ virtual BOOL Insert( USHORT nPos, const String& rTxt );
+ virtual BOOL Replace( USHORT nPos, const String& rTxt );
+
+ virtual BOOL SetAttr( USHORT nStt, USHORT nEnd, USHORT nSlotId, SfxPoolItem& );
+ virtual BOOL SetINetAttr( USHORT nStt, USHORT nEnd, const String& rURL );
+
+ virtual BOOL HasSymbolChars( USHORT nStt, USHORT nEnd );
+
+ virtual const String* GetPrevPara( BOOL bAtNormalPos );
+
+ virtual BOOL ChgAutoCorrWord( USHORT& rSttPos, USHORT nEndPos,
+ SvxAutoCorrect& rACorrect, const String** ppPara );
+
+ virtual LanguageType GetLanguage( USHORT nPos, BOOL bPrevPara = FALSE ) const;
+
+ USHORT GetCursor() const { return nCursor; }
+
+};
+
+#endif // EDTSPELL
+
diff --git a/editeng/source/editeng/eehtml.cxx b/editeng/source/editeng/eehtml.cxx
new file mode 100644
index 0000000000..2edfda4381
--- /dev/null
+++ b/editeng/source/editeng/eehtml.cxx
@@ -0,0 +1,853 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: eehtml.cxx,v $
+ * $Revision: 1.20 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <vcl/wrkwin.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+#include <eehtml.hxx>
+#include <impedit.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/flditem.hxx>
+#include <tools/urlobj.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <svtools/htmltokn.h>
+#include <svtools/htmlkywd.hxx>
+
+
+#define ACTION_INSERTTEXT 1
+#define ACTION_INSERTPARABRK 2
+
+#define STYLE_PRE 101
+
+EditHTMLParser::EditHTMLParser( SvStream& rIn, const String& rBaseURL, SvKeyValueIterator* pHTTPHeaderAttrs )
+ : HTMLParser( rIn, true )
+ , aBaseURL( rBaseURL )
+{
+ pImpEditEngine = 0;
+ pCurAnchor = 0;
+ bInPara = FALSE;
+ bWasInPara = FALSE;
+ nInTable = 0;
+ nInCell = 0;
+ nDefListLevel = 0;
+ nBulletLevel = 0;
+ nNumberingLevel = 0;
+ bFieldsInserted = FALSE;
+
+ if ( pHTTPHeaderAttrs )
+ SetEncodingByHTTPHeader( pHTTPHeaderAttrs );
+}
+
+EditHTMLParser::~EditHTMLParser()
+{
+ delete pCurAnchor;
+}
+
+SvParserState EditHTMLParser::CallParser( ImpEditEngine* pImpEE, const EditPaM& rPaM )
+{
+ DBG_ASSERT( pImpEE, "CallParser: ImpEditEngine ?!" );
+ pImpEditEngine = pImpEE;
+ SvParserState _eState = SVPAR_NOTSTARTED;
+ if ( pImpEditEngine )
+ {
+ // Umbrechmimik vom RTF-Import einbauen?
+ aCurSel = EditSelection( rPaM, rPaM );
+
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ ImportInfo aImportInfo( HTMLIMP_START, this, pImpEditEngine->CreateESel( aCurSel ) );
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+
+ ImpSetStyleSheet( 0 );
+ _eState = HTMLParser::CallParser();
+
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ ImportInfo aImportInfo( HTMLIMP_END, this, pImpEditEngine->CreateESel( aCurSel ) );
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+
+ if ( bFieldsInserted )
+ pImpEditEngine->UpdateFields();
+ }
+ return _eState;
+}
+
+void EditHTMLParser::NextToken( int nToken )
+{
+ #ifdef DBG_UTIL
+ HTML_TOKEN_IDS xID = (HTML_TOKEN_IDS)nToken;
+ (void)xID;
+ #endif
+
+ switch( nToken )
+ {
+ case HTML_META:
+ {
+ const HTMLOptions *_pOptions = GetOptions();
+ USHORT nArrLen = _pOptions->Count();
+ BOOL bEquiv = FALSE;
+ for ( USHORT i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption *pOption = (*_pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_HTTPEQUIV:
+ {
+ bEquiv = TRUE;
+ }
+ break;
+ case HTML_O_CONTENT:
+ {
+ if ( bEquiv )
+ {
+ rtl_TextEncoding eEnc = GetEncodingByMIME( pOption->GetString() );
+ if ( eEnc != RTL_TEXTENCODING_DONTKNOW )
+ SetSrcEncoding( eEnc );
+ }
+ }
+ break;
+ }
+ }
+
+ }
+ break;
+ case HTML_PLAINTEXT_ON:
+ case HTML_PLAINTEXT2_ON:
+ bInPara = TRUE;
+ break;
+ case HTML_PLAINTEXT_OFF:
+ case HTML_PLAINTEXT2_OFF:
+ bInPara = FALSE;
+ break;
+
+ case HTML_LINEBREAK:
+ case HTML_NEWPARA:
+ {
+ if ( ( bInPara || nInTable ) &&
+ ( ( nToken == HTML_LINEBREAK ) || HasTextInCurrentPara() ) )
+ {
+ ImpInsertParaBreak();
+ }
+ }
+ break;
+ case HTML_HORZRULE:
+ {
+ if ( HasTextInCurrentPara() )
+ ImpInsertParaBreak();
+ ImpInsertParaBreak();
+ }
+ case HTML_NONBREAKSPACE:
+ {
+ if ( bInPara )
+ {
+ ImpInsertText( String( RTL_CONSTASCII_USTRINGPARAM( " " ) ) );
+ }
+ }
+ break;
+ case HTML_TEXTTOKEN:
+ {
+ if ( !bInPara )
+ StartPara( FALSE );
+
+// if ( bInPara || pCurAnchor )
+ {
+ String aText = aToken;
+ if ( aText.Len() && ( aText.GetChar( 0 ) == ' ' )
+ && ThrowAwayBlank() && !IsReadPRE() )
+ aText.Erase( 0, 1 );
+
+ if ( pCurAnchor )
+ {
+ pCurAnchor->aText += aText;
+ }
+ else
+ {
+ // Nur bis HTML mit 319 geschrieben ?!
+ if ( IsReadPRE() )
+ {
+ USHORT nTabPos = aText.Search( '\t', 0 );
+ while ( nTabPos != STRING_NOTFOUND )
+ {
+ aText.Erase( nTabPos, 1 );
+ aText.Insert( String( RTL_CONSTASCII_USTRINGPARAM( " " ) ), nTabPos );
+ nTabPos = aText.Search( '\t', nTabPos+8 );
+ }
+ }
+ ImpInsertText( aText );
+ }
+ }
+ }
+ break;
+
+ case HTML_CENTER_ON:
+ case HTML_CENTER_OFF: // if ( bInPara )
+ {
+ USHORT nNode = pImpEditEngine->GetEditDoc().GetPos( aCurSel.Max().GetNode() );
+ SfxItemSet aItems( aCurSel.Max().GetNode()->GetContentAttribs().GetItems() );
+ aItems.ClearItem( EE_PARA_JUST );
+ if ( nToken == HTML_CENTER_ON )
+ aItems.Put( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) );
+ pImpEditEngine->SetParaAttribs( nNode, aItems );
+ }
+ break;
+
+ case HTML_ANCHOR_ON: AnchorStart();
+ break;
+ case HTML_ANCHOR_OFF: AnchorEnd();
+ break;
+
+ case HTML_PARABREAK_ON:
+ if( bInPara && HasTextInCurrentPara() )
+ EndPara( TRUE );
+ StartPara( TRUE );
+ break;
+
+ case HTML_PARABREAK_OFF:
+ if( bInPara )
+ EndPara( TRUE );
+ break;
+
+ case HTML_HEAD1_ON:
+ case HTML_HEAD2_ON:
+ case HTML_HEAD3_ON:
+ case HTML_HEAD4_ON:
+ case HTML_HEAD5_ON:
+ case HTML_HEAD6_ON:
+ {
+ HeadingStart( nToken );
+ }
+ break;
+
+ case HTML_HEAD1_OFF:
+ case HTML_HEAD2_OFF:
+ case HTML_HEAD3_OFF:
+ case HTML_HEAD4_OFF:
+ case HTML_HEAD5_OFF:
+ case HTML_HEAD6_OFF:
+ {
+ HeadingEnd( nToken );
+ }
+ break;
+
+ case HTML_PREFORMTXT_ON:
+ case HTML_XMP_ON:
+ case HTML_LISTING_ON:
+ {
+ StartPara( TRUE );
+ ImpSetStyleSheet( STYLE_PRE );
+ }
+ break;
+
+ case HTML_DEFLIST_ON:
+ {
+ nDefListLevel++;
+ }
+ break;
+
+ case HTML_DEFLIST_OFF:
+ {
+ if( nDefListLevel )
+ nDefListLevel--;
+ }
+ break;
+
+ case HTML_TABLE_ON: nInTable++;
+ break;
+ case HTML_TABLE_OFF: DBG_ASSERT( nInTable, "Nicht in Table, aber TABLE_OFF?" );
+ nInTable--;
+ break;
+
+ case HTML_TABLEHEADER_ON:
+ case HTML_TABLEDATA_ON:
+ nInCell++;
+ // fallthru
+ case HTML_BLOCKQUOTE_ON:
+ case HTML_BLOCKQUOTE_OFF:
+ case HTML_BLOCKQUOTE30_ON:
+ case HTML_BLOCKQUOTE30_OFF:
+ case HTML_LISTHEADER_ON:
+ case HTML_LI_ON:
+ case HTML_DD_ON:
+ case HTML_DT_ON:
+ case HTML_ORDERLIST_ON:
+ case HTML_UNORDERLIST_ON:
+ {
+ BOOL bHasText = HasTextInCurrentPara();
+ if ( bHasText )
+ ImpInsertParaBreak();
+ StartPara( FALSE );
+ }
+ break;
+
+ case HTML_TABLEHEADER_OFF:
+ case HTML_TABLEDATA_OFF:
+ {
+ if ( nInCell )
+ nInCell--;
+ }
+ // fallthru
+ case HTML_LISTHEADER_OFF:
+ case HTML_LI_OFF:
+ case HTML_DD_OFF:
+ case HTML_DT_OFF:
+ case HTML_ORDERLIST_OFF:
+ case HTML_UNORDERLIST_OFF: EndPara( FALSE );
+ break;
+
+ case HTML_TABLEROW_ON:
+ case HTML_TABLEROW_OFF: // Nur nach einem CELL ein RETURN, fuer Calc
+
+ case HTML_COL_ON:
+ case HTML_COLGROUP_ON:
+ case HTML_COLGROUP_OFF: break;
+
+ case HTML_FONT_ON: // ...
+ break;
+ case HTML_FONT_OFF: // ...
+ break;
+
+
+ // #58335# kein SkipGroup on/off auf inline markup etc.
+
+ // globals
+ case HTML_HTML_ON:
+ case HTML_HTML_OFF:
+ case HTML_BODY_ON:
+ case HTML_BODY_OFF:
+ case HTML_HEAD_ON:
+ case HTML_HEAD_OFF:
+ case HTML_FORM_ON:
+ case HTML_FORM_OFF:
+ case HTML_THEAD_ON:
+ case HTML_THEAD_OFF:
+ case HTML_TBODY_ON:
+ case HTML_TBODY_OFF:
+ case HTML_TITLE_ON:
+ case HTML_TITLE_OFF:
+ // inline elements, structural markup
+ // HTML 3.0
+ case HTML_BANNER_ON:
+ case HTML_BANNER_OFF:
+ case HTML_DIVISION_ON:
+ case HTML_DIVISION_OFF:
+// case HTML_LISTHEADER_ON: //! special handling
+// case HTML_LISTHEADER_OFF:
+ case HTML_NOTE_ON:
+ case HTML_NOTE_OFF:
+ // inline elements, logical markup
+ // HTML 2.0
+ case HTML_ADDRESS_ON:
+ case HTML_ADDRESS_OFF:
+// case HTML_BLOCKQUOTE_ON: //! extra Behandlung
+// case HTML_BLOCKQUOTE_OFF:
+ case HTML_CITIATION_ON:
+ case HTML_CITIATION_OFF:
+ case HTML_CODE_ON:
+ case HTML_CODE_OFF:
+ case HTML_DEFINSTANCE_ON:
+ case HTML_DEFINSTANCE_OFF:
+ case HTML_EMPHASIS_ON:
+ case HTML_EMPHASIS_OFF:
+ case HTML_KEYBOARD_ON:
+ case HTML_KEYBOARD_OFF:
+ case HTML_SAMPLE_ON:
+ case HTML_SAMPLE_OFF:
+ case HTML_STRIKE_ON:
+ case HTML_STRIKE_OFF:
+ case HTML_STRONG_ON:
+ case HTML_STRONG_OFF:
+ case HTML_VARIABLE_ON:
+ case HTML_VARIABLE_OFF:
+ // HTML 3.0
+ case HTML_ABBREVIATION_ON:
+ case HTML_ABBREVIATION_OFF:
+ case HTML_ACRONYM_ON:
+ case HTML_ACRONYM_OFF:
+ case HTML_AUTHOR_ON:
+ case HTML_AUTHOR_OFF:
+// case HTML_BLOCKQUOTE30_ON: //! extra Behandlung
+// case HTML_BLOCKQUOTE30_OFF:
+ case HTML_DELETEDTEXT_ON:
+ case HTML_DELETEDTEXT_OFF:
+ case HTML_INSERTEDTEXT_ON:
+ case HTML_INSERTEDTEXT_OFF:
+ case HTML_LANGUAGE_ON:
+ case HTML_LANGUAGE_OFF:
+ case HTML_PERSON_ON:
+ case HTML_PERSON_OFF:
+ case HTML_SHORTQUOTE_ON:
+ case HTML_SHORTQUOTE_OFF:
+ case HTML_SUBSCRIPT_ON:
+ case HTML_SUBSCRIPT_OFF:
+ case HTML_SUPERSCRIPT_ON:
+ case HTML_SUPERSCRIPT_OFF:
+ // inline elements, visual markup
+ // HTML 2.0
+ case HTML_BOLD_ON:
+ case HTML_BOLD_OFF:
+ case HTML_ITALIC_ON:
+ case HTML_ITALIC_OFF:
+ case HTML_TELETYPE_ON:
+ case HTML_TELETYPE_OFF:
+ case HTML_UNDERLINE_ON:
+ case HTML_UNDERLINE_OFF:
+ // HTML 3.0
+ case HTML_BIGPRINT_ON:
+ case HTML_BIGPRINT_OFF:
+ case HTML_STRIKETHROUGH_ON:
+ case HTML_STRIKETHROUGH_OFF:
+ case HTML_SMALLPRINT_ON:
+ case HTML_SMALLPRINT_OFF:
+ // figures
+ case HTML_FIGURE_ON:
+ case HTML_FIGURE_OFF:
+ case HTML_CAPTION_ON:
+ case HTML_CAPTION_OFF:
+ case HTML_CREDIT_ON:
+ case HTML_CREDIT_OFF:
+ // misc
+ case HTML_DIRLIST_ON:
+ case HTML_DIRLIST_OFF:
+ case HTML_FOOTNOTE_ON: //! landen so im Text
+ case HTML_FOOTNOTE_OFF:
+ case HTML_MENULIST_ON:
+ case HTML_MENULIST_OFF:
+// case HTML_PLAINTEXT_ON: //! extra Behandlung
+// case HTML_PLAINTEXT_OFF:
+// case HTML_PREFORMTXT_ON: //! extra Behandlung
+// case HTML_PREFORMTXT_OFF:
+ case HTML_SPAN_ON:
+ case HTML_SPAN_OFF:
+ // obsolete
+// case HTML_XMP_ON: //! extra Behandlung
+// case HTML_XMP_OFF:
+// case HTML_LISTING_ON: //! extra Behandlung
+// case HTML_LISTING_OFF:
+ // Netscape
+ case HTML_BLINK_ON:
+ case HTML_BLINK_OFF:
+ case HTML_NOBR_ON:
+ case HTML_NOBR_OFF:
+ case HTML_NOEMBED_ON:
+ case HTML_NOEMBED_OFF:
+ case HTML_NOFRAMES_ON:
+ case HTML_NOFRAMES_OFF:
+ // Internet Explorer
+ case HTML_MARQUEE_ON:
+ case HTML_MARQUEE_OFF:
+// case HTML_PLAINTEXT2_ON: //! extra Behandlung
+// case HTML_PLAINTEXT2_OFF:
+ break;
+
+ default:
+ {
+ if ( nToken & HTML_TOKEN_ONOFF )
+ {
+ if ( ( nToken == HTML_UNKNOWNCONTROL_ON ) || ( nToken == HTML_UNKNOWNCONTROL_OFF ) )
+ {
+ ;
+ }
+ else if ( !(nToken & 1) )
+ {
+ DBG_ASSERT( !( nToken & 1 ), "Kein Start-Token ?!" );
+ SkipGroup( nToken + 1 );
+ }
+ }
+ }
+ } // SWITCH
+
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ ImportInfo aImportInfo( HTMLIMP_NEXTTOKEN, this, pImpEditEngine->CreateESel( aCurSel ) );
+ aImportInfo.nToken = nToken;
+ aImportInfo.nTokenValue = (short)nTokenValue;
+ if ( nToken == HTML_TEXTTOKEN )
+ aImportInfo.aText = aToken;
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+
+}
+
+void EditHTMLParser::ImpInsertParaBreak()
+{
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ ImportInfo aImportInfo( HTMLIMP_INSERTPARA, this, pImpEditEngine->CreateESel( aCurSel ) );
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+ aCurSel = pImpEditEngine->ImpInsertParaBreak( aCurSel );
+ nLastAction = ACTION_INSERTPARABRK;
+}
+
+void EditHTMLParser::ImpSetAttribs( const SfxItemSet& rItems, EditSelection* pSel )
+{
+ // pSel, wenn Zeichenattribute, sonst Absatzattribute fuer den
+ // aktuellen Absatz.
+ DBG_ASSERT( pSel || ( aCurSel.Min().GetNode() == aCurSel.Max().GetNode() ), "ImpInsertAttribs: Selektion?" );
+
+ EditPaM aStartPaM( pSel ? pSel->Min() : aCurSel.Min() );
+ EditPaM aEndPaM( pSel ? pSel->Max() : aCurSel.Max() );
+
+ if ( !pSel )
+ {
+ aStartPaM.SetIndex( 0 );
+ aEndPaM.SetIndex( aEndPaM.GetNode()->Len() );
+ }
+
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ EditSelection aSel( aStartPaM, aEndPaM );
+ ImportInfo aImportInfo( HTMLIMP_SETATTR, this, pImpEditEngine->CreateESel( aSel ) );
+ aImportInfo.pAttrs = (void*)&rItems;
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+
+ ContentNode* pSN = aStartPaM.GetNode();
+ USHORT nStartNode = pImpEditEngine->GetEditDoc().GetPos( pSN );
+
+ // Wenn ein Attribut von 0 bis aktuelle Absatzlaenge geht,
+ // soll es ein Absatz-Attribut sein!
+
+ // Achtung: Selektion kann ueber mehrere Absaetze gehen.
+ // Alle vollstaendigen Absaetze sind Absatzattribute...
+
+ // HTML eigentlich nicht:
+#ifdef DBG_UTIL
+ ContentNode* pEN = aEndPaM.GetNode();
+ USHORT nEndNode = pImpEditEngine->GetEditDoc().GetPos( pEN );
+ DBG_ASSERT( nStartNode == nEndNode, "ImpSetAttribs: Mehrere Absaetze?" );
+#endif
+
+/*
+ for ( USHORT z = nStartNode+1; z < nEndNode; z++ )
+ {
+ DBG_ASSERT( pImpEditEngine->GetEditDoc().SaveGetObject( z ), "Node existiert noch nicht(RTF)" );
+ pImpEditEngine->SetParaAttribs( z, rSet.GetAttrSet() );
+ }
+
+ if ( aStartPaM.GetNode() != aEndPaM.GetNode() )
+ {
+ // Den Rest des StartNodes...
+ if ( aStartPaM.GetIndex() == 0 )
+ pImpEditEngine->SetParaAttribs( nStartNode, rSet.GetAttrSet() );
+ else
+ pImpEditEngine->SetAttribs( EditSelection( aStartPaM, EditPaM( aStartPaM.GetNode(), aStartPaM.GetNode()->Len() ) ), rSet.GetAttrSet() );
+
+ // Den Anfang des EndNodes....
+ if ( aEndPaM.GetIndex() == aEndPaM.GetNode()->Len() )
+ pImpEditEngine->SetParaAttribs( nEndNode, rSet.GetAttrSet() );
+ else
+ pImpEditEngine->SetAttribs( EditSelection( EditPaM( aEndPaM.GetNode(), 0 ), aEndPaM ), rSet.GetAttrSet() );
+ }
+ else
+*/
+ {
+ if ( ( aStartPaM.GetIndex() == 0 ) && ( aEndPaM.GetIndex() == aEndPaM.GetNode()->Len() ) )
+ {
+ // Muesse gemergt werden:
+ SfxItemSet aItems( pImpEditEngine->GetParaAttribs( nStartNode ) );
+ aItems.Put( rItems );
+ pImpEditEngine->SetParaAttribs( nStartNode, aItems );
+ }
+ else
+ pImpEditEngine->SetAttribs( EditSelection( aStartPaM, aEndPaM ), rItems );
+ }
+}
+
+void EditHTMLParser::ImpSetStyleSheet( USHORT nHLevel )
+{
+ /*
+ nHLevel: 0: Ausschalten
+ 1-6: Heading
+ STYLE_PRE: Preformatted
+ */
+
+// if ( pImpEditEngine->GetStatus().DoImportRTFStyleSheets() )
+// {
+// SvxRTFStyleType* pS = GetStyleTbl().Get( rSet.StyleNo() );
+// DBG_ASSERT( pS, "Vorlage in RTF nicht definiert!" );
+// if ( pS )
+// pImpEditEngine->SetStyleSheet( EditSelection( aStartPaM, aEndPaM ), pS->sName, SFX_STYLE_FAMILY_ALL );
+// }
+// else
+ {
+ // Harte Attribute erzeugen...
+ // Reicht fuer Calc, bei StyleSheets muesste noch geklaert werden,
+ // dass diese auch in der App liegen sollten, damit sie beim
+ // fuettern in eine andere Engine auch noch da sind...
+
+ USHORT nNode = pImpEditEngine->GetEditDoc().GetPos( aCurSel.Max().GetNode() );
+// SfxItemSet aItems( pImpEditEngine->GetEmptyItemSet() );
+ SfxItemSet aItems( aCurSel.Max().GetNode()->GetContentAttribs().GetItems() );
+
+ aItems.ClearItem( EE_PARA_ULSPACE );
+ aItems.ClearItem( EE_CHAR_FONTHEIGHT );
+ aItems.ClearItem( EE_CHAR_FONTINFO );
+ aItems.ClearItem( EE_CHAR_WEIGHT );
+
+ // Fett in den ersten 3 Headings
+ if ( ( nHLevel >= 1 ) && ( nHLevel <= 3 ) )
+ {
+ SvxWeightItem aWeightItem( WEIGHT_BOLD, EE_CHAR_WEIGHT );
+ aItems.Put( aWeightItem );
+ }
+
+ // Fonthoehe und Abstaende, wenn LogicToLogic moeglich:
+ MapUnit eUnit = pImpEditEngine->GetRefMapMode().GetMapUnit();
+ if ( ( eUnit != MAP_PIXEL ) && ( eUnit != MAP_SYSFONT ) &&
+ ( eUnit != MAP_APPFONT ) && ( eUnit != MAP_RELATIVE ) )
+ {
+ long nPoints = 10;
+ if ( nHLevel == 1 )
+ nPoints = 22;
+ else if ( nHLevel == 2 )
+ nPoints = 16;
+ else if ( nHLevel == 3 )
+ nPoints = 12;
+ else if ( nHLevel == 4 )
+ nPoints = 11;
+
+ nPoints = OutputDevice::LogicToLogic( nPoints, MAP_POINT, eUnit );
+ SvxFontHeightItem aHeightItem( nPoints, 100, EE_CHAR_FONTHEIGHT );
+ aItems.Put( aHeightItem );
+
+ // Absatzabstaende, wenn Heading:
+ if ( !nHLevel || ((nHLevel >= 1) && (nHLevel <= 6)) )
+ {
+ SvxULSpaceItem aULSpaceItem( EE_PARA_ULSPACE );
+ aULSpaceItem.SetUpper( (USHORT)OutputDevice::LogicToLogic( 42, MAP_10TH_MM, eUnit ) );
+ aULSpaceItem.SetLower( (USHORT)OutputDevice::LogicToLogic( 35, MAP_10TH_MM, eUnit ) );
+ aItems.Put( aULSpaceItem );
+ }
+ }
+
+ // Bei Pre einen proportionalen Font waehlen
+ if ( nHLevel == STYLE_PRE )
+ {
+ Font aFont = OutputDevice::GetDefaultFont( DEFAULTFONT_FIXED, LANGUAGE_SYSTEM, 0 );
+ SvxFontItem aFontItem( aFont.GetFamily(), aFont.GetName(), XubString(), aFont.GetPitch(), aFont.GetCharSet(), EE_CHAR_FONTINFO );
+ aItems.Put( aFontItem );
+ }
+
+ pImpEditEngine->SetParaAttribs( nNode, aItems );
+ }
+}
+
+void EditHTMLParser::ImpInsertText( const String& rText )
+{
+ String aText( rText );
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ ImportInfo aImportInfo( HTMLIMP_INSERTTEXT, this, pImpEditEngine->CreateESel( aCurSel ) );
+ aImportInfo.aText = aText;
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+
+ aCurSel = pImpEditEngine->ImpInsertText( aCurSel, aText );
+ nLastAction = ACTION_INSERTTEXT;
+}
+
+void EditHTMLParser::SkipGroup( int nEndToken )
+{
+ // #69109# groups in cells are closed upon leaving the cell, because those
+ // ******* web authors don't know their job
+ // for example: <td><form></td> lacks a closing </form>
+ BYTE nCellLevel = nInCell;
+ int nToken;
+ while( nCellLevel <= nInCell && ( (nToken = GetNextToken() ) != nEndToken ) && nToken )
+ {
+ switch ( nToken )
+ {
+ case HTML_TABLEHEADER_ON:
+ case HTML_TABLEDATA_ON:
+ nInCell++;
+ break;
+ case HTML_TABLEHEADER_OFF:
+ case HTML_TABLEDATA_OFF:
+ if ( nInCell )
+ nInCell--;
+ break;
+ }
+ }
+}
+
+void EditHTMLParser::StartPara( BOOL bReal )
+{
+ if ( bReal )
+ {
+ const HTMLOptions *_pOptions = GetOptions();
+ USHORT nArrLen = _pOptions->Count();
+ SvxAdjust eAdjust = SVX_ADJUST_LEFT;
+ for ( USHORT i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption *pOption = (*_pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ALIGN:
+ {
+ if ( pOption->GetString().CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_AL_right ) == COMPARE_EQUAL )
+ eAdjust = SVX_ADJUST_RIGHT;
+ else if ( pOption->GetString().CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_AL_middle ) == COMPARE_EQUAL )
+ eAdjust = SVX_ADJUST_CENTER;
+ else if ( pOption->GetString().CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_AL_center ) == COMPARE_EQUAL )
+ eAdjust = SVX_ADJUST_CENTER;
+ else
+ eAdjust = SVX_ADJUST_LEFT;
+ }
+ break;
+ }
+ }
+ SfxItemSet aItemSet( pImpEditEngine->GetEmptyItemSet() );
+ aItemSet.Put( SvxAdjustItem( eAdjust, EE_PARA_JUST ) );
+ ImpSetAttribs( aItemSet );
+ }
+ bInPara = TRUE;
+}
+
+void EditHTMLParser::EndPara( BOOL )
+{
+ if ( bInPara )
+ {
+ BOOL bHasText = HasTextInCurrentPara();
+ if ( bHasText )
+ ImpInsertParaBreak();
+ // Nur, wenn ohne Absatzabstaende gearbeitet wird...
+// if ( !nInTable && bReal && (nNumberingLevel<=1) && (nBulletLevel<=1) )
+// ImpInsertParaBreak();
+ }
+ bInPara = FALSE;
+}
+
+BOOL EditHTMLParser::ThrowAwayBlank()
+{
+ // Ein Blank muss weggeschmissen werden, wenn der neue Text mit einem
+ // Blank beginnt und der aktuelle Absatz leer ist oder mit einem
+ // Blank endet...
+ ContentNode* pNode = aCurSel.Max().GetNode();
+ if ( pNode->Len() && ( pNode->GetChar( pNode->Len()-1 ) != ' ' ) )
+ return FALSE;
+ return TRUE;
+}
+
+BOOL EditHTMLParser::HasTextInCurrentPara()
+{
+ return aCurSel.Max().GetNode()->Len() ? TRUE : FALSE;
+}
+
+void EditHTMLParser::AnchorStart()
+{
+ // Anker im Anker ignoriern
+ if ( !pCurAnchor )
+ {
+ const HTMLOptions* _pOptions = GetOptions();
+ USHORT nArrLen = _pOptions->Count();
+
+ String aRef;
+
+ for ( USHORT i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption* pOption = (*_pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_HREF:
+ aRef = pOption->GetString();
+ break;
+ }
+ }
+
+ if ( aRef.Len() )
+ {
+ String aURL = aRef;
+ if ( aURL.Len() && ( aURL.GetChar( 0 ) != '#' ) )
+ {
+ INetURLObject aTargetURL;
+ INetURLObject aRootURL( aBaseURL );
+ aRootURL.GetNewAbsURL( aRef, &aTargetURL );
+ aURL = aTargetURL.GetMainURL( INetURLObject::DECODE_TO_IURI );
+ }
+ pCurAnchor = new AnchorInfo;
+ pCurAnchor->aHRef = aURL;
+ }
+ }
+}
+
+void EditHTMLParser::AnchorEnd()
+{
+ if ( pCurAnchor )
+ {
+ // Als URL-Feld einfuegen...
+ SvxFieldItem aFld( SvxURLField( pCurAnchor->aHRef, pCurAnchor->aText, SVXURLFORMAT_REPR ), EE_FEATURE_FIELD );
+ aCurSel = pImpEditEngine->InsertField( aCurSel, aFld );
+ bFieldsInserted = TRUE;
+ delete pCurAnchor;
+ pCurAnchor = 0;
+
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ ImportInfo aImportInfo( HTMLIMP_INSERTFIELD, this, pImpEditEngine->CreateESel( aCurSel ) );
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+ }
+}
+
+void EditHTMLParser::HeadingStart( int nToken )
+{
+ bWasInPara = bInPara;
+ StartPara( FALSE );
+
+ if ( bWasInPara && HasTextInCurrentPara() )
+ ImpInsertParaBreak();
+
+ USHORT nId = sal::static_int_cast< USHORT >(
+ 1 + ( ( nToken - HTML_HEAD1_ON ) / 2 ) );
+ DBG_ASSERT( (nId >= 1) && (nId <= 9), "HeadingStart: ID kann nicht stimmen!" );
+ ImpSetStyleSheet( nId );
+}
+
+void EditHTMLParser::HeadingEnd( int )
+{
+ EndPara( FALSE );
+ ImpSetStyleSheet( 0 );
+
+ if ( bWasInPara )
+ {
+ bInPara = TRUE;
+ bWasInPara = FALSE;
+ }
+}
diff --git a/editeng/source/editeng/eehtml.hxx b/editeng/source/editeng/eehtml.hxx
new file mode 100644
index 0000000000..f6c7bd6247
--- /dev/null
+++ b/editeng/source/editeng/eehtml.hxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: eehtml.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _EEHTML_HXX
+#define _EEHTML_HXX
+
+#include <svl/svarray.hxx>
+
+#include <editdoc.hxx>
+#include <svtools/parhtml.hxx>
+
+class ImpEditEngine;
+
+#define MAX_NUMBERLEVEL 10
+
+struct AnchorInfo
+{
+ String aHRef;
+ String aText;
+};
+
+class EditHTMLParser : public HTMLParser
+{
+ using HTMLParser::CallParser;
+private:
+ EditSelection aCurSel;
+ String aBaseURL;
+ ImpEditEngine* pImpEditEngine;
+ AnchorInfo* pCurAnchor;
+
+ BOOL bInPara;
+ BOOL bWasInPara; // bInPara vor HeadingStart merken, weil sonst hinterher weg
+ BOOL bFieldsInserted;
+ BYTE nInTable;
+ BYTE nInCell;
+
+ BYTE nDefListLevel;
+ BYTE nBulletLevel;
+ BYTE nNumberingLevel;
+
+ BYTE nLastAction;
+
+ void StartPara( BOOL bReal );
+ void EndPara( BOOL bReal );
+ void AnchorStart();
+ void AnchorEnd();
+ void HeadingStart( int nToken );
+ void HeadingEnd( int nToken );
+ void SkipGroup( int nEndToken );
+ BOOL ThrowAwayBlank();
+ BOOL HasTextInCurrentPara();
+ void ProcessUnknownControl( BOOL bOn );
+
+ void ImpInsertParaBreak();
+ void ImpInsertText( const String& rText );
+ void ImpSetAttribs( const SfxItemSet& rItems, EditSelection* pSel = 0 );
+ void ImpSetStyleSheet( USHORT nHeadingLevel );
+
+protected:
+ virtual void NextToken( int nToken );
+
+public:
+ EditHTMLParser( SvStream& rIn, const String& rBaseURL, SvKeyValueIterator* pHTTPHeaderAttrs );
+ ~EditHTMLParser();
+
+ virtual SvParserState CallParser( ImpEditEngine* pImpEE, const EditPaM& rPaM );
+
+ const EditSelection& GetCurSelection() const { return aCurSel; }
+};
+
+SV_DECL_REF( EditHTMLParser )
+SV_IMPL_REF( EditHTMLParser );
+
+#endif // _EEHTML_HXX
diff --git a/editeng/source/editeng/eeng_pch.cxx b/editeng/source/editeng/eeng_pch.cxx
new file mode 100644
index 0000000000..9bd54072fb
--- /dev/null
+++ b/editeng/source/editeng/eeng_pch.cxx
@@ -0,0 +1,33 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: eeng_pch.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <eeng_pch.hxx>
diff --git a/editeng/source/editeng/eeng_pch.hxx b/editeng/source/editeng/eeng_pch.hxx
new file mode 100644
index 0000000000..355085cc98
--- /dev/null
+++ b/editeng/source/editeng/eeng_pch.hxx
@@ -0,0 +1,37 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: eeng_pch.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#define _STD_VAR_ARRAYS
+
+#include <vcl/wrkwin.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+
+
diff --git a/editeng/source/editeng/eeobj.cxx b/editeng/source/editeng/eeobj.cxx
new file mode 100644
index 0000000000..2b0b403fe0
--- /dev/null
+++ b/editeng/source/editeng/eeobj.cxx
@@ -0,0 +1,115 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: eeobj.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+
+#include <eeng_pch.hxx>
+
+#include <eeobj.hxx>
+#include <sot/exchange.hxx>
+#include <sot/formats.hxx>
+#include <editeng/editeng.hxx>
+#include <svl/itempool.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+using namespace ::com::sun::star;
+
+
+EditDataObject::EditDataObject()
+{
+}
+
+EditDataObject::~EditDataObject()
+{
+}
+
+// uno::XInterface
+uno::Any EditDataObject::queryInterface( const uno::Type & rType ) throw(uno::RuntimeException)
+{
+ uno::Any aRet = ::cppu::queryInterface( rType, SAL_STATIC_CAST( datatransfer::XTransferable*, this ) );
+ return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ));
+}
+
+// datatransfer::XTransferable
+uno::Any EditDataObject::getTransferData( const datatransfer::DataFlavor& rFlavor ) throw(datatransfer::UnsupportedFlavorException, io::IOException, uno::RuntimeException)
+{
+ uno::Any aAny;
+
+ ULONG nT = SotExchange::GetFormat( rFlavor );
+ if ( nT == SOT_FORMAT_STRING )
+ {
+ aAny <<= (::rtl::OUString)GetString();
+ }
+ else if ( ( nT == SOT_FORMATSTR_ID_EDITENGINE ) || ( nT == SOT_FORMAT_RTF ) )
+ {
+ // MT 01/2002: No RTF on demand any more:
+ // 1) Was not working, because I had to flush() the clipboard immediately anyway
+ // 2) Don't have the old pool defaults and the StyleSheetPool here.
+
+ SvMemoryStream* pStream = ( nT == SOT_FORMATSTR_ID_EDITENGINE ) ? &GetStream() : &GetRTFStream();
+ pStream->Seek( STREAM_SEEK_TO_END );
+ ULONG nLen = pStream->Tell();
+ pStream->Seek(0);
+
+ uno::Sequence< sal_Int8 > aSeq( nLen );
+ memcpy( aSeq.getArray(), pStream->GetData(), nLen );
+ aAny <<= aSeq;
+ }
+ else
+ {
+ datatransfer::UnsupportedFlavorException aException;
+ throw( aException );
+ }
+
+ return aAny;
+}
+
+uno::Sequence< datatransfer::DataFlavor > EditDataObject::getTransferDataFlavors( ) throw(uno::RuntimeException)
+{
+ uno::Sequence< datatransfer::DataFlavor > aDataFlavors(3);
+ SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EDITENGINE, aDataFlavors.getArray()[0] );
+ SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aDataFlavors.getArray()[1] );
+ SotExchange::GetFormatDataFlavor( SOT_FORMAT_RTF, aDataFlavors.getArray()[2] );
+
+ return aDataFlavors;
+}
+
+sal_Bool EditDataObject::isDataFlavorSupported( const datatransfer::DataFlavor& rFlavor ) throw(uno::RuntimeException)
+{
+ sal_Bool bSupported = sal_False;
+
+ ULONG nT = SotExchange::GetFormat( rFlavor );
+ if ( ( nT == SOT_FORMAT_STRING ) || ( nT == SOT_FORMAT_RTF ) /* || ( nT == SOT_FORMAT_XML ) */ || ( nT == SOT_FORMATSTR_ID_EDITENGINE ) )
+ bSupported = sal_True;
+
+ return bSupported;
+}
diff --git a/editeng/source/editeng/eeobj.hxx b/editeng/source/editeng/eeobj.hxx
new file mode 100644
index 0000000000..c013d040b3
--- /dev/null
+++ b/editeng/source/editeng/eeobj.hxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: eeobj.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DATAOBJ_HXX
+#define _DATAOBJ_HXX
+
+#include <cppuhelper/weak.hxx>
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+
+#include <tools/stream.hxx>
+
+class EditDataObject : public ::com::sun::star::datatransfer::XTransferable,
+ public ::cppu::OWeakObject
+
+{
+private:
+ SvMemoryStream maBinData;
+ SvMemoryStream maRTFData;
+ String maText;
+
+ String maOfficeBookmark;
+
+// String maNetscapeBookmark;
+// SvMemoryStream maRTFData;
+
+public:
+ EditDataObject();
+ ~EditDataObject();
+
+ SvMemoryStream& GetStream() { return maBinData; }
+ SvMemoryStream& GetRTFStream() { return maRTFData; }
+ String& GetString() { return maText; }
+ String& GetURL() { return maOfficeBookmark; }
+
+
+ // ::com::sun::star::uno::XInterface
+ ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL acquire() throw() { OWeakObject::acquire(); }
+ void SAL_CALL release() throw() { OWeakObject::release(); }
+
+ // ::com::sun::star::datatransfer::XTransferable
+ ::com::sun::star::uno::Any SAL_CALL getTransferData( const ::com::sun::star::datatransfer::DataFlavor& aFlavor ) throw(::com::sun::star::datatransfer::UnsupportedFlavorException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Sequence< ::com::sun::star::datatransfer::DataFlavor > SAL_CALL getTransferDataFlavors( ) throw(::com::sun::star::uno::RuntimeException);
+ sal_Bool SAL_CALL isDataFlavorSupported( const ::com::sun::star::datatransfer::DataFlavor& aFlavor ) throw(::com::sun::star::uno::RuntimeException);
+};
+
+#endif // _DATAOBJ_HXX
+
diff --git a/editeng/source/editeng/eerdll.cxx b/editeng/source/editeng/eerdll.cxx
new file mode 100644
index 0000000000..6cde40721e
--- /dev/null
+++ b/editeng/source/editeng/eerdll.cxx
@@ -0,0 +1,240 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: eerdll.cxx,v $
+ * $Revision: 1.31.148.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <vcl/wrkwin.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+#include <com/sun/star/linguistic2/XLanguageGuessing.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <comphelper/processfactory.hxx>
+
+#include <svl/solar.hrc>
+#include <editeng/eerdll.hxx>
+#include <eerdll2.hxx>
+#include <editeng/lspcitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/tstpitem.hxx>
+#include <editeng/bulitem.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/emphitem.hxx>
+#include <editeng/scriptspaceitem.hxx>
+#include <svl/itempool.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/svapp.hxx>
+
+#include <editeng/akrnitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/cscoitem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/numitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/charscaleitem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/xmlcnitm.hxx>
+#include <editeng/forbiddencharacterstable.hxx>
+#include <comphelper/processfactory.hxx>
+
+static EditDLL* pDLL=0;
+
+using namespace ::com::sun::star;
+
+EditDLL* EditDLL::Get()
+{
+ if ( !pDLL )
+ pDLL = new EditDLL;
+ return pDLL;
+}
+
+GlobalEditData::GlobalEditData()
+{
+ ppDefItems = NULL;
+ pStdRefDevice = NULL;
+}
+
+GlobalEditData::~GlobalEditData()
+{
+ // DefItems zerstoeren...
+ // Oder einfach stehen lassen, da sowieso App-Ende?!
+ if ( ppDefItems )
+ SfxItemPool::ReleaseDefaults( ppDefItems, EDITITEMCOUNT, TRUE );
+ delete pStdRefDevice;
+}
+
+SfxPoolItem** GlobalEditData::GetDefItems()
+{
+ if ( !ppDefItems )
+ {
+ ppDefItems = new SfxPoolItem*[EDITITEMCOUNT];
+
+ // Absatzattribute:
+ SvxNumRule aTmpNumRule( 0, 0, FALSE );
+
+ ppDefItems[0] = new SvxFrameDirectionItem( FRMDIR_HORI_LEFT_TOP, EE_PARA_WRITINGDIR );
+ ppDefItems[1] = new SvXMLAttrContainerItem( EE_PARA_XMLATTRIBS );
+ ppDefItems[2] = new SfxBoolItem( EE_PARA_HANGINGPUNCTUATION, FALSE );
+ ppDefItems[3] = new SfxBoolItem( EE_PARA_FORBIDDENRULES, TRUE );
+ ppDefItems[4] = new SvxScriptSpaceItem( TRUE, EE_PARA_ASIANCJKSPACING );
+ ppDefItems[5] = new SvxNumBulletItem( aTmpNumRule, EE_PARA_NUMBULLET );
+ ppDefItems[6] = new SfxBoolItem( EE_PARA_HYPHENATE, FALSE );
+ ppDefItems[7] = new SfxBoolItem( EE_PARA_BULLETSTATE, TRUE );
+ ppDefItems[8] = new SvxLRSpaceItem( EE_PARA_OUTLLRSPACE );
+ ppDefItems[9] = new SfxInt16Item( EE_PARA_OUTLLEVEL, -1 );
+ ppDefItems[10] = new SvxBulletItem( EE_PARA_BULLET );
+ ppDefItems[11] = new SvxLRSpaceItem( EE_PARA_LRSPACE );
+ ppDefItems[12] = new SvxULSpaceItem( EE_PARA_ULSPACE );
+ ppDefItems[13] = new SvxLineSpacingItem( 0, EE_PARA_SBL );
+ ppDefItems[14] = new SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST );
+ ppDefItems[15] = new SvxTabStopItem( 0, 0, SVX_TAB_ADJUST_LEFT, EE_PARA_TABS );
+
+ // Zeichenattribute:
+ ppDefItems[16] = new SvxColorItem( Color( COL_AUTO ), EE_CHAR_COLOR );
+ ppDefItems[17] = new SvxFontItem( EE_CHAR_FONTINFO );
+ ppDefItems[18] = new SvxFontHeightItem( 240, 100, EE_CHAR_FONTHEIGHT );
+ ppDefItems[19] = new SvxCharScaleWidthItem( 100, EE_CHAR_FONTWIDTH );
+ ppDefItems[20] = new SvxWeightItem( WEIGHT_NORMAL, EE_CHAR_WEIGHT );
+ ppDefItems[21] = new SvxUnderlineItem( UNDERLINE_NONE, EE_CHAR_UNDERLINE );
+ ppDefItems[22] = new SvxCrossedOutItem( STRIKEOUT_NONE, EE_CHAR_STRIKEOUT );
+ ppDefItems[23] = new SvxPostureItem( ITALIC_NONE, EE_CHAR_ITALIC );
+ ppDefItems[24] = new SvxContourItem( FALSE, EE_CHAR_OUTLINE );
+ ppDefItems[25] = new SvxShadowedItem( FALSE, EE_CHAR_SHADOW );
+ ppDefItems[26] = new SvxEscapementItem( 0, 100, EE_CHAR_ESCAPEMENT );
+ ppDefItems[27] = new SvxAutoKernItem( FALSE, EE_CHAR_PAIRKERNING );
+ ppDefItems[28] = new SvxKerningItem( 0, EE_CHAR_KERNING );
+ ppDefItems[29] = new SvxWordLineModeItem( FALSE, EE_CHAR_WLM );
+ ppDefItems[30] = new SvxLanguageItem( LANGUAGE_DONTKNOW, EE_CHAR_LANGUAGE );
+ ppDefItems[31] = new SvxLanguageItem( LANGUAGE_DONTKNOW, EE_CHAR_LANGUAGE_CJK );
+ ppDefItems[32] = new SvxLanguageItem( LANGUAGE_DONTKNOW, EE_CHAR_LANGUAGE_CTL );
+ ppDefItems[33] = new SvxFontItem( EE_CHAR_FONTINFO_CJK );
+ ppDefItems[34] = new SvxFontItem( EE_CHAR_FONTINFO_CTL );
+ ppDefItems[35] = new SvxFontHeightItem( 240, 100, EE_CHAR_FONTHEIGHT_CJK );
+ ppDefItems[36] = new SvxFontHeightItem( 240, 100, EE_CHAR_FONTHEIGHT_CTL );
+ ppDefItems[37] = new SvxWeightItem( WEIGHT_NORMAL, EE_CHAR_WEIGHT_CJK );
+ ppDefItems[38] = new SvxWeightItem( WEIGHT_NORMAL, EE_CHAR_WEIGHT_CTL );
+ ppDefItems[39] = new SvxPostureItem( ITALIC_NONE, EE_CHAR_ITALIC_CJK );
+ ppDefItems[40] = new SvxPostureItem( ITALIC_NONE, EE_CHAR_ITALIC_CTL );
+ ppDefItems[41] = new SvxEmphasisMarkItem( EMPHASISMARK_NONE, EE_CHAR_EMPHASISMARK );
+ ppDefItems[42] = new SvxCharReliefItem( RELIEF_NONE, EE_CHAR_RELIEF );
+ ppDefItems[43] = new SfxVoidItem( EE_CHAR_RUBI_DUMMY );
+#ifndef SVX_LIGHT
+ ppDefItems[44] = new SvXMLAttrContainerItem( EE_CHAR_XMLATTRIBS );
+#else
+ // no need to have alien attributes persistent
+ ppDefItems[44] = new SfxVoidItem( EE_CHAR_XMLATTRIBS );
+#endif // #ifndef SVX_LIGHT
+ ppDefItems[45] = new SvxOverlineItem( UNDERLINE_NONE, EE_CHAR_OVERLINE );
+
+ // Features
+ ppDefItems[46] = new SfxVoidItem( EE_FEATURE_TAB );
+ ppDefItems[47] = new SfxVoidItem( EE_FEATURE_LINEBR );
+ ppDefItems[48] = new SvxCharSetColorItem( Color( COL_RED ), RTL_TEXTENCODING_DONTKNOW, EE_FEATURE_NOTCONV );
+ ppDefItems[49] = new SvxFieldItem( SvxFieldData(), EE_FEATURE_FIELD );
+
+ DBG_ASSERT( EDITITEMCOUNT == 50, "ITEMCOUNT geaendert, DefItems nicht angepasst!" );
+
+ // Init DefFonts:
+ GetDefaultFonts( *(SvxFontItem*)ppDefItems[EE_CHAR_FONTINFO - EE_ITEMS_START],
+ *(SvxFontItem*)ppDefItems[EE_CHAR_FONTINFO_CJK - EE_ITEMS_START],
+ *(SvxFontItem*)ppDefItems[EE_CHAR_FONTINFO_CTL - EE_ITEMS_START] );
+ }
+
+ return ppDefItems;
+}
+
+vos::ORef<SvxForbiddenCharactersTable> GlobalEditData::GetForbiddenCharsTable()
+{
+ if ( !xForbiddenCharsTable.isValid() )
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
+ xForbiddenCharsTable = new SvxForbiddenCharactersTable( xMSF );
+ }
+ return xForbiddenCharsTable;
+}
+
+uno::Reference< linguistic2::XLanguageGuessing > GlobalEditData::GetLanguageGuesser()
+{
+ if (!xLanguageGuesser.is())
+ {
+ uno::Reference< lang::XMultiServiceFactory > xMgr ( comphelper::getProcessServiceFactory() );
+ if (xMgr.is())
+ {
+ xLanguageGuesser = uno::Reference< linguistic2::XLanguageGuessing >(
+ xMgr->createInstance(
+ rtl::OUString::createFromAscii( "com.sun.star.linguistic2.LanguageGuessing" ) ),
+ uno::UNO_QUERY );
+ }
+ }
+ return xLanguageGuesser;
+}
+
+OutputDevice* GlobalEditData::GetStdRefDevice()
+{
+ if ( !pStdRefDevice )
+ {
+ pStdRefDevice = new VirtualDevice;
+ pStdRefDevice->SetMapMode( MAP_TWIP );
+ }
+ return pStdRefDevice;
+}
+
+EditResId::EditResId( USHORT nId ):
+ ResId( nId, *EE_DLL()->GetResMgr() )
+{
+}
+
+EditDLL::EditDLL()
+{
+ pGlobalData = new GlobalEditData;
+ ByteString aResMgrName( "svx" );
+ pResMgr = ResMgr::CreateResMgr(
+ aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
+}
+
+EditDLL::~EditDLL()
+{
+ delete pResMgr;
+ delete pGlobalData;
+}
diff --git a/editeng/source/editeng/eerdll2.hxx b/editeng/source/editeng/eerdll2.hxx
new file mode 100644
index 0000000000..eb9af0cad1
--- /dev/null
+++ b/editeng/source/editeng/eerdll2.hxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: eerdll2.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _EERDLL2_HXX
+#define _EERDLL2_HXX
+
+#include <com/sun/star/linguistic2/XLanguageGuessing.hpp>
+#include <editeng/forbiddencharacterstable.hxx>
+#include <vos/ref.hxx>
+
+class SfxPoolItem;
+
+class GlobalEditData
+{
+private:
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::linguistic2::XLanguageGuessing > xLanguageGuesser;
+ SfxPoolItem** ppDefItems;
+ OutputDevice* pStdRefDevice;
+
+ vos::ORef<SvxForbiddenCharactersTable> xForbiddenCharsTable;
+
+public:
+ GlobalEditData();
+ ~GlobalEditData();
+
+ SfxPoolItem** GetDefItems();
+ OutputDevice* GetStdRefDevice();
+
+ vos::ORef<SvxForbiddenCharactersTable> GetForbiddenCharsTable();
+ void SetForbiddenCharsTable( vos::ORef<SvxForbiddenCharactersTable> xForbiddenChars ) { xForbiddenCharsTable = xForbiddenChars; }
+ ::com::sun::star::uno::Reference< ::com::sun::star::linguistic2::XLanguageGuessing > GetLanguageGuesser();
+};
+
+
+#endif //_EERDLL2_HXX
+
diff --git a/editeng/source/editeng/eertfpar.cxx b/editeng/source/editeng/eertfpar.cxx
new file mode 100644
index 0000000000..45bc347057
--- /dev/null
+++ b/editeng/source/editeng/eertfpar.cxx
@@ -0,0 +1,635 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: eertfpar.cxx,v $
+ * $Revision: 1.16 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <vcl/wrkwin.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+
+#include <eertfpar.hxx>
+#include <impedit.hxx>
+#include <svl/intitem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/flditem.hxx>
+
+#include <svtools/rtftoken.h>
+
+// alle Werte auf default; wird nach einlesen der Bitmap aufgerufen !
+void SvxRTFPictureType::ResetValues()
+{ // setze alle Werte RTF-Defaults
+ eStyle = RTF_BITMAP;
+ nMode = HEX_MODE;
+ nType = nGoalWidth = nGoalHeight = 0;
+ nWidth = nHeight = nWidthBytes = 0;
+ uPicLen = 0;
+ nBitsPerPixel = nPlanes = 1;
+ nScalX = nScalY = 100; // Skalierung in Prozent
+ nCropT = nCropB = nCropL = nCropR = 0;
+}
+
+ImportInfo::ImportInfo( ImportState eSt, SvParser* pPrsrs, const ESelection& rSel )
+ : aSelection( rSel )
+{
+ pParser = pPrsrs,
+ eState = eSt;
+
+ nToken = 0;
+ nTokenValue = 0;
+ pAttrs = NULL;
+}
+
+ImportInfo::~ImportInfo()
+{
+}
+
+EditRTFParser::EditRTFParser( SvStream& rIn, EditSelection aSel, SfxItemPool& rAttrPool, ImpEditEngine* pImpEE )
+ : SvxRTFParser( rAttrPool, rIn, 0 ), aRTFMapMode( MAP_TWIP )
+{
+
+ pImpEditEngine = pImpEE;
+ aCurSel = aSel;
+ eDestCharSet = RTL_TEXTENCODING_DONTKNOW;
+ nDefFont = 0;
+ nDefTab = 0;
+ nLastAction = 0;
+ nDefFontHeight = 0;
+
+ SetInsPos( EditPosition( pImpEditEngine, &aCurSel ) );
+
+ // Umwandeln der Twips-Werte...
+ SetCalcValue( TRUE );
+ SetChkStyleAttr( pImpEE->GetStatus().DoImportRTFStyleSheets() );
+ SetNewDoc( FALSE ); // damit die Pool-Defaults nicht
+ // ueberschrieben werden...
+ aEditMapMode = MapMode( pImpEE->GetRefDevice()->GetMapMode().GetMapUnit() );
+}
+
+EditRTFParser::~EditRTFParser()
+{
+}
+
+SvParserState __EXPORT EditRTFParser::CallParser()
+{
+ DBG_ASSERT( !aCurSel.HasRange(), "Selection bei CallParser!" );
+ // Den Teil, in den importiert wird, vom Rest abtrennen.
+ // Diese Mimik sollte fuer alle Imports verwendet werden.
+ // aStart1PaM: Letzte Position vor dem importierten Inhalt
+ // aEnd1PaM: Erste Position nach dem importierten Inhalt
+ // aStart2PaM: Erste Position des importierten Inhaltes
+ // aEnd2PaM: Letzte Position des importierten Inhaltes
+ EditPaM aStart1PaM( aCurSel.Min().GetNode(), aCurSel.Min().GetIndex() );
+ aCurSel = pImpEditEngine->ImpInsertParaBreak( aCurSel );
+ EditPaM aStart2PaM = aCurSel.Min();
+ // Sinnvoll oder nicht?:
+ aStart2PaM.GetNode()->GetContentAttribs().GetItems().ClearItem();
+ AddRTFDefaultValues( aStart2PaM, aStart2PaM );
+ EditPaM aEnd1PaM( pImpEditEngine->ImpInsertParaBreak( aCurSel.Max() ) );
+ // aCurCel zeigt jetzt auf den Zwischenraum
+
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ ImportInfo aImportInfo( RTFIMP_START, this, pImpEditEngine->CreateESel( aCurSel ) );
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+
+ SvParserState _eState = SvxRTFParser::CallParser();
+
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ ImportInfo aImportInfo( RTFIMP_END, this, pImpEditEngine->CreateESel( aCurSel ) );
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+
+ if ( nLastAction == ACTION_INSERTPARABRK )
+ {
+ ContentNode* pCurNode = aCurSel.Max().GetNode();
+ USHORT nPara = pImpEditEngine->GetEditDoc().GetPos( pCurNode );
+ ContentNode* pPrevNode = pImpEditEngine->GetEditDoc().SaveGetObject( nPara-1 );
+ DBG_ASSERT( pPrevNode, "Ungueltiges RTF-Dokument ?!" );
+ EditSelection aSel;
+ aSel.Min() = EditPaM( pPrevNode, pPrevNode->Len() );
+ aSel.Max() = EditPaM( pCurNode, 0 );
+ aCurSel.Max() = pImpEditEngine->ImpDeleteSelection( aSel );
+ }
+ EditPaM aEnd2PaM( aCurSel.Max() );
+ //AddRTFDefaultValues( aStart2PaM, aEnd2PaM );
+ BOOL bOnlyOnePara = ( aEnd2PaM.GetNode() == aStart2PaM.GetNode() );
+ // Den Brocken wieder einfuegen...
+ // Problem: Absatzattribute duerfen ggf. nicht uebernommen werden
+ // => Zeichenattribute machen.
+
+ BOOL bSpecialBackward = aStart1PaM.GetNode()->Len() ? FALSE : TRUE;
+ if ( bOnlyOnePara || aStart1PaM.GetNode()->Len() )
+ pImpEditEngine->ParaAttribsToCharAttribs( aStart2PaM.GetNode() );
+ aCurSel.Min() = pImpEditEngine->ImpConnectParagraphs(
+ aStart1PaM.GetNode(), aStart2PaM.GetNode(), bSpecialBackward );
+ bSpecialBackward = aEnd1PaM.GetNode()->Len() ? TRUE : FALSE;
+ // wenn bOnlyOnePara, dann ist der Node beim Connect verschwunden.
+ if ( !bOnlyOnePara && aEnd1PaM.GetNode()->Len() )
+ pImpEditEngine->ParaAttribsToCharAttribs( aEnd2PaM.GetNode() );
+ aCurSel.Max() = pImpEditEngine->ImpConnectParagraphs(
+ ( bOnlyOnePara ? aStart1PaM.GetNode() : aEnd2PaM.GetNode() ),
+ aEnd1PaM.GetNode(), bSpecialBackward );
+
+ return _eState;
+}
+
+void EditRTFParser::AddRTFDefaultValues( const EditPaM& rStart, const EditPaM& rEnd )
+{
+ // Problem: DefFont und DefFontHeight
+ Size aSz( 12, 0 );
+ MapMode aPntMode( MAP_POINT );
+ MapMode _aEditMapMode( pImpEditEngine->GetRefDevice()->GetMapMode().GetMapUnit() );
+ aSz = pImpEditEngine->GetRefDevice()->LogicToLogic( aSz, &aPntMode, &_aEditMapMode );
+ SvxFontHeightItem aFontHeightItem( aSz.Width(), 100, EE_CHAR_FONTHEIGHT );
+ Font aDefFont( GetDefFont() );
+ SvxFontItem aFontItem( aDefFont.GetFamily(), aDefFont.GetName(),
+ aDefFont.GetStyleName(), aDefFont.GetPitch(), aDefFont.GetCharSet(), EE_CHAR_FONTINFO );
+
+ USHORT nStartPara = pImpEditEngine->GetEditDoc().GetPos( rStart.GetNode() );
+ USHORT nEndPara = pImpEditEngine->GetEditDoc().GetPos( rEnd.GetNode() );
+ for ( USHORT nPara = nStartPara; nPara <= nEndPara; nPara++ )
+ {
+ ContentNode* pNode = pImpEditEngine->GetEditDoc().SaveGetObject( nPara );
+ DBG_ASSERT( pNode, "AddRTFDefaultValues - Kein Absatz ?!" );
+ if ( !pNode->GetContentAttribs().HasItem( EE_CHAR_FONTINFO ) )
+ pNode->GetContentAttribs().GetItems().Put( aFontItem );
+ if ( !pNode->GetContentAttribs().HasItem( EE_CHAR_FONTHEIGHT ) )
+ pNode->GetContentAttribs().GetItems().Put( aFontHeightItem );
+ }
+}
+
+void __EXPORT EditRTFParser::NextToken( int nToken )
+{
+ switch( nToken )
+ {
+ case RTF_DEFF:
+ {
+ nDefFont = USHORT(nTokenValue);
+ }
+ break;
+ case RTF_DEFTAB:
+ {
+ nDefTab = USHORT(nTokenValue);
+ }
+ break;
+ case RTF_CELL:
+ {
+ aCurSel = pImpEditEngine->ImpInsertParaBreak( aCurSel );
+ }
+ break;
+ case RTF_LINE:
+ {
+ aCurSel = pImpEditEngine->InsertLineBreak( aCurSel );
+ }
+ break;
+ case RTF_FIELD:
+ {
+ ReadField();
+ }
+ break;
+ case RTF_PGDSCTBL: // #i29453# ignore \*\pgdsctbl destination
+ case RTF_LISTTEXT:
+ {
+ SkipGroup();
+ }
+ break;
+ default:
+ {
+ SvxRTFParser::NextToken( nToken );
+ if ( nToken == RTF_STYLESHEET )
+ CreateStyleSheets();
+ }
+ break;
+ }
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ ImportInfo aImportInfo( RTFIMP_NEXTTOKEN, this, pImpEditEngine->CreateESel( aCurSel ) );
+ aImportInfo.nToken = nToken;
+ aImportInfo.nTokenValue = short(nTokenValue);
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+}
+
+void __EXPORT EditRTFParser::UnknownAttrToken( int nToken, SfxItemSet* )
+{
+ // fuer Tokens, die im ReadAttr nicht ausgewertet werden
+ // Eigentlich nur fuer Calc (RTFTokenHdl), damit RTF_INTBL
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ ImportInfo aImportInfo( RTFIMP_UNKNOWNATTR, this, pImpEditEngine->CreateESel( aCurSel ) );
+ aImportInfo.nToken = nToken;
+ aImportInfo.nTokenValue = short(nTokenValue);
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+}
+
+void __EXPORT EditRTFParser::InsertText()
+{
+ String aText( aToken );
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ ImportInfo aImportInfo( RTFIMP_INSERTTEXT, this, pImpEditEngine->CreateESel( aCurSel ) );
+ aImportInfo.aText = aText;
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+ aCurSel = pImpEditEngine->ImpInsertText( aCurSel, aText );
+ nLastAction = ACTION_INSERTTEXT;
+}
+
+void __EXPORT EditRTFParser::InsertPara()
+{
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ ImportInfo aImportInfo( RTFIMP_INSERTPARA, this, pImpEditEngine->CreateESel( aCurSel ) );
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+ aCurSel = pImpEditEngine->ImpInsertParaBreak( aCurSel );
+ nLastAction = ACTION_INSERTPARABRK;
+}
+
+void __EXPORT EditRTFParser::MovePos( int bForward )
+{
+ if( bForward )
+ aCurSel = pImpEditEngine->CursorRight( aCurSel.Max(), ::com::sun::star::i18n::CharacterIteratorMode::SKIPCHARACTER );
+ else
+ aCurSel = pImpEditEngine->CursorLeft( aCurSel.Max(), ::com::sun::star::i18n::CharacterIteratorMode::SKIPCHARACTER );
+}
+
+void __EXPORT EditRTFParser::SetEndPrevPara( SvxNodeIdx*& rpNodePos,
+ USHORT& rCntPos )
+{
+ // Gewollt ist: von der aktuellen Einfuegeposition den vorherigen
+ // Absatz bestimmen und von dem das Ende setzen.
+ // Dadurch wird "\pard" immer auf den richtigen Absatz
+ // angewendet.
+
+ ContentNode* pN = aCurSel.Max().GetNode();
+ USHORT nCurPara = pImpEditEngine->GetEditDoc().GetPos( pN );
+ DBG_ASSERT( nCurPara != 0, "Absatz gleich 0: SetEnfPrevPara" );
+ if ( nCurPara )
+ nCurPara--;
+ ContentNode* pPrevNode = pImpEditEngine->GetEditDoc().SaveGetObject( nCurPara );
+ DBG_ASSERT( pPrevNode, "pPrevNode = 0!" );
+ rpNodePos = new EditNodeIdx( pImpEditEngine, pPrevNode );
+ rCntPos = pPrevNode->Len();
+}
+
+int __EXPORT EditRTFParser::IsEndPara( SvxNodeIdx* pNd, USHORT nCnt ) const
+{
+ return ( nCnt == ( ((EditNodeIdx*)pNd)->GetNode()->Len()) );
+}
+
+void __EXPORT EditRTFParser::SetAttrInDoc( SvxRTFItemStackType &rSet )
+{
+ ContentNode* pSttNode = ((EditNodeIdx&)rSet.GetSttNode()).GetNode();
+ ContentNode* pEndNode = ((EditNodeIdx&)rSet.GetEndNode()).GetNode();
+
+ EditPaM aStartPaM( pSttNode, rSet.GetSttCnt() );
+ EditPaM aEndPaM( pEndNode, rSet.GetEndCnt() );
+
+ // ggf. noch das Escapemant-Item umbiegen:
+ const SfxPoolItem* pItem;
+
+ // #i66167# adapt font heights to destination MapUnit if necessary
+ const MapUnit eDestUnit = ( MapUnit )( pImpEditEngine->GetEditDoc().GetItemPool().GetMetric(0) );
+ const MapUnit eSrcUnit = aRTFMapMode.GetMapUnit();
+ if (eDestUnit != eSrcUnit)
+ {
+ USHORT aFntHeightIems[3] = { EE_CHAR_FONTHEIGHT, EE_CHAR_FONTHEIGHT_CJK, EE_CHAR_FONTHEIGHT_CTL };
+ for (int i = 0; i < 2; ++i)
+ {
+ if (SFX_ITEM_SET == rSet.GetAttrSet().GetItemState( aFntHeightIems[i], FALSE, &pItem ))
+ {
+ UINT32 nHeight = ((SvxFontHeightItem*)pItem)->GetHeight();
+ long nNewHeight;
+ nNewHeight = pImpEditEngine->GetRefDevice()->LogicToLogic( (long)nHeight, eSrcUnit, eDestUnit );
+
+ SvxFontHeightItem aFntHeightItem( nNewHeight, ((SvxFontHeightItem*)pItem)->GetProp(), aFntHeightIems[i] );
+ rSet.GetAttrSet().Put( aFntHeightItem );
+ }
+ }
+ }
+
+ if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState( EE_CHAR_ESCAPEMENT, FALSE, &pItem ))
+ {
+ // die richtige
+ long nEsc = ((SvxEscapementItem*)pItem)->GetEsc();
+
+ if( ( DFLT_ESC_AUTO_SUPER != nEsc ) && ( DFLT_ESC_AUTO_SUB != nEsc ) )
+ {
+ nEsc *= 10; //HalPoints => Twips wurde in RTFITEM.CXX unterschlagen!
+ SvxFont aFont;
+ pImpEditEngine->SeekCursor( aStartPaM.GetNode(), aStartPaM.GetIndex()+1, aFont );
+ nEsc = nEsc * 100 / aFont.GetSize().Height();
+
+ SvxEscapementItem aEscItem( (short) nEsc, ((SvxEscapementItem*)pItem)->GetProp(), EE_CHAR_ESCAPEMENT );
+ rSet.GetAttrSet().Put( aEscItem );
+ }
+ }
+
+ if ( pImpEditEngine->aImportHdl.IsSet() )
+ {
+ EditSelection aSel( aStartPaM, aEndPaM );
+ ImportInfo aImportInfo( RTFIMP_SETATTR, this, pImpEditEngine->CreateESel( aSel ) );
+ aImportInfo.pAttrs = &rSet;
+ pImpEditEngine->aImportHdl.Call( &aImportInfo );
+ }
+
+ ContentNode* pSN = aStartPaM.GetNode();
+ ContentNode* pEN = aEndPaM.GetNode();
+ USHORT nStartNode = pImpEditEngine->GetEditDoc().GetPos( pSN );
+ USHORT nEndNode = pImpEditEngine->GetEditDoc().GetPos( pEN );
+ sal_Int16 nOutlLevel = 0xff;
+
+ if ( rSet.StyleNo() && pImpEditEngine->GetStyleSheetPool() && pImpEditEngine->GetStatus().DoImportRTFStyleSheets() )
+ {
+ SvxRTFStyleType* pS = GetStyleTbl().Get( rSet.StyleNo() );
+ DBG_ASSERT( pS, "Vorlage in RTF nicht definiert!" );
+ if ( pS )
+ {
+ pImpEditEngine->SetStyleSheet( EditSelection( aStartPaM, aEndPaM ), (SfxStyleSheet*)pImpEditEngine->GetStyleSheetPool()->Find( pS->sName, SFX_STYLE_FAMILY_ALL ) );
+ nOutlLevel = pS->nOutlineNo;
+ }
+ }
+
+ // Wenn ein Attribut von 0 bis aktuelle Absatzlaenge geht,
+ // soll es ein Absatz-Attribut sein!
+
+ // Achtung: Selektion kann ueber mehrere Absaetze gehen.
+ // Alle vollstaendigen Absaetze sind Absatzattribute...
+ for ( USHORT z = nStartNode+1; z < nEndNode; z++ )
+ {
+ DBG_ASSERT( pImpEditEngine->GetEditDoc().SaveGetObject( z ), "Node existiert noch nicht(RTF)" );
+ pImpEditEngine->SetParaAttribs( z, rSet.GetAttrSet() );
+ }
+
+ if ( aStartPaM.GetNode() != aEndPaM.GetNode() )
+ {
+ // Den Rest des StartNodes...
+ if ( aStartPaM.GetIndex() == 0 )
+ pImpEditEngine->SetParaAttribs( nStartNode, rSet.GetAttrSet() );
+ else
+ pImpEditEngine->SetAttribs( EditSelection( aStartPaM, EditPaM( aStartPaM.GetNode(), aStartPaM.GetNode()->Len() ) ), rSet.GetAttrSet() );
+
+ // Den Anfang des EndNodes....
+ if ( aEndPaM.GetIndex() == aEndPaM.GetNode()->Len() )
+ pImpEditEngine->SetParaAttribs( nEndNode, rSet.GetAttrSet() );
+ else
+ pImpEditEngine->SetAttribs( EditSelection( EditPaM( aEndPaM.GetNode(), 0 ), aEndPaM ), rSet.GetAttrSet() );
+ }
+ else
+ {
+ if ( ( aStartPaM.GetIndex() == 0 ) && ( aEndPaM.GetIndex() == aEndPaM.GetNode()->Len() ) )
+ {
+ // #96298# When settings char attribs as para attribs, we must merge with existing attribs, not overwrite the ItemSet!
+ SfxItemSet aAttrs = pImpEditEngine->GetParaAttribs( nStartNode );
+ aAttrs.Put( rSet.GetAttrSet() );
+ pImpEditEngine->SetParaAttribs( nStartNode, aAttrs );
+ }
+ else
+ {
+ pImpEditEngine->SetAttribs( EditSelection( aStartPaM, aEndPaM ), rSet.GetAttrSet() );
+ }
+ }
+
+ // OutlLevel...
+ if ( nOutlLevel != 0xff )
+ {
+ for ( USHORT n = nStartNode; n <= nEndNode; n++ )
+ {
+ ContentNode* pNode = pImpEditEngine->GetEditDoc().SaveGetObject( n );
+ pNode->GetContentAttribs().GetItems().Put( SfxInt16Item( EE_PARA_OUTLLEVEL, nOutlLevel ) );
+ }
+ }
+}
+
+SvxRTFStyleType* EditRTFParser::FindStyleSheet( const XubString& rName )
+{
+ SvxRTFStyleType* pS = GetStyleTbl().First();
+ while ( pS && ( pS->sName != rName ) )
+ pS = GetStyleTbl().Next();
+
+ return pS;
+}
+
+SfxStyleSheet* EditRTFParser::CreateStyleSheet( SvxRTFStyleType* pRTFStyle )
+{
+ // Prueffen, ob so eine Vorlage existiert....
+ // dann wird sie auch nicht geaendert!
+ SfxStyleSheet* pStyle = (SfxStyleSheet*)pImpEditEngine->GetStyleSheetPool()->Find( pRTFStyle->sName, SFX_STYLE_FAMILY_ALL );
+ if ( pStyle )
+ return pStyle;
+
+ String aName( pRTFStyle->sName );
+ String aParent;
+ if ( pRTFStyle->nBasedOn )
+ {
+ SvxRTFStyleType* pS = GetStyleTbl().Get( pRTFStyle->nBasedOn );
+ if ( pS && ( pS !=pRTFStyle ) )
+ aParent = pS->sName;
+ }
+
+ pStyle = (SfxStyleSheet*) &pImpEditEngine->GetStyleSheetPool()->Make( aName, SFX_STYLE_FAMILY_PARA );
+
+ // 1) Items konvertieren und uebernehmen...
+ ConvertAndPutItems( pStyle->GetItemSet(), pRTFStyle->aAttrSet );
+
+ // 2) Solange Parent nicht im Pool, auch diesen kreieren...
+ if ( aParent.Len() && ( aParent != aName ) )
+ {
+ SfxStyleSheet* pS = (SfxStyleSheet*)pImpEditEngine->GetStyleSheetPool()->Find( aParent, SFX_STYLE_FAMILY_ALL );
+ if ( !pS )
+ {
+ // Wenn nirgendwo gefunden, aus RTF erzeugen...
+ SvxRTFStyleType* _pRTFStyle = FindStyleSheet( aParent );
+ if ( _pRTFStyle )
+ pS = CreateStyleSheet( _pRTFStyle );
+ }
+ // 2b) ItemSet mit Parent verknuepfen...
+ if ( pS )
+ pStyle->GetItemSet().SetParent( &pS->GetItemSet() );
+ }
+ return pStyle;
+}
+
+void EditRTFParser::CreateStyleSheets()
+{
+ // der SvxRTFParser hat jetzt die Vorlagen erzeugt...
+ if ( pImpEditEngine->GetStyleSheetPool() && pImpEditEngine->GetStatus().DoImportRTFStyleSheets() )
+ {
+ SvxRTFStyleType* pRTFStyle = GetStyleTbl().First();
+ while ( pRTFStyle )
+ {
+ CreateStyleSheet( pRTFStyle );
+
+ pRTFStyle = GetStyleTbl().Next();
+ }
+ }
+}
+
+void __EXPORT EditRTFParser::CalcValue()
+{
+ const MapUnit eDestUnit = static_cast< MapUnit >( aEditMapMode.GetMapUnit() );
+ const MapUnit eSrcUnit = aRTFMapMode.GetMapUnit();
+ if (eDestUnit != eSrcUnit)
+ nTokenValue = OutputDevice::LogicToLogic( (long)nTokenValue, eSrcUnit, eDestUnit );
+}
+
+void EditRTFParser::ReadField()
+{
+ // Aus SwRTFParser::ReadField()
+ int _nOpenBrakets = 1; // die erste wurde schon vorher erkannt
+ BOOL bFldInst = FALSE;
+ BOOL bFldRslt = FALSE;
+ String aFldInst;
+ String aFldRslt;
+
+ while( _nOpenBrakets && IsParserWorking() )
+ {
+ switch( GetNextToken() )
+ {
+ case '}':
+ {
+ _nOpenBrakets--;
+ if ( _nOpenBrakets == 1 )
+ {
+ bFldInst = FALSE;
+ bFldRslt = FALSE;
+ }
+ }
+ break;
+
+ case '{': _nOpenBrakets++;
+ break;
+
+ case RTF_FIELD: SkipGroup();
+ break;
+
+ case RTF_FLDINST: bFldInst = TRUE;
+ break;
+
+ case RTF_FLDRSLT: bFldRslt = TRUE;
+ break;
+
+ case RTF_TEXTTOKEN:
+ {
+ if ( bFldInst )
+ aFldInst += aToken;
+ else if ( bFldRslt )
+ aFldRslt += aToken;
+ }
+ break;
+ }
+ }
+ if ( aFldInst.Len() )
+ {
+ String aHyperLinkMarker( RTL_CONSTASCII_USTRINGPARAM( "HYPERLINK " ) );
+ if ( aFldInst.CompareIgnoreCaseToAscii( aHyperLinkMarker, aHyperLinkMarker.Len() ) == COMPARE_EQUAL )
+ {
+ aFldInst.Erase( 0, aHyperLinkMarker.Len() );
+ aFldInst.EraseLeadingChars();
+ aFldInst.EraseTrailingChars();
+ aFldInst.Erase( 0, 1 ); // "
+ aFldInst.Erase( aFldInst.Len()-1, 1 ); // "
+
+ if ( !aFldRslt.Len() )
+ aFldRslt = aFldInst;
+
+ SvxFieldItem aField( SvxURLField( aFldInst, aFldRslt, SVXURLFORMAT_REPR ), EE_FEATURE_FIELD );
+ aCurSel = pImpEditEngine->InsertField( aCurSel, aField );
+ pImpEditEngine->UpdateFields();
+ nLastAction = ACTION_INSERTTEXT;
+ }
+ }
+
+ SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
+}
+
+void EditRTFParser::SkipGroup()
+{
+ int _nOpenBrakets = 1; // die erste wurde schon vorher erkannt
+
+ while( _nOpenBrakets && IsParserWorking() )
+ {
+ switch( GetNextToken() )
+ {
+ case '}':
+ {
+ _nOpenBrakets--;
+ }
+ break;
+
+ case '{':
+ {
+ _nOpenBrakets++;
+ }
+ break;
+ }
+ }
+
+ SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
+}
+
+ULONG __EXPORT EditNodeIdx::GetIdx() const
+{
+ return pImpEditEngine->GetEditDoc().GetPos( pNode );
+}
+
+SvxNodeIdx* __EXPORT EditNodeIdx::Clone() const
+{
+ return new EditNodeIdx( pImpEditEngine, pNode );
+}
+
+SvxPosition* __EXPORT EditPosition::Clone() const
+{
+ return new EditPosition( pImpEditEngine, pCurSel );
+}
+
+SvxNodeIdx* __EXPORT EditPosition::MakeNodeIdx() const
+{
+ return new EditNodeIdx( pImpEditEngine, pCurSel->Max().GetNode() );
+}
+
+ULONG __EXPORT EditPosition::GetNodeIdx() const
+{
+ ContentNode* pN = pCurSel->Max().GetNode();
+ return pImpEditEngine->GetEditDoc().GetPos( pN );
+}
+
+USHORT __EXPORT EditPosition::GetCntIdx() const
+{
+ return pCurSel->Max().GetIndex();
+}
diff --git a/editeng/source/editeng/eertfpar.hxx b/editeng/source/editeng/eertfpar.hxx
new file mode 100644
index 0000000000..5e1341a39f
--- /dev/null
+++ b/editeng/source/editeng/eertfpar.hxx
@@ -0,0 +1,131 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: eertfpar.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _EERTFPAR_HXX
+#define _EERTFPAR_HXX
+
+#include <editeng/svxrtf.hxx>
+
+#include <editdoc.hxx>
+#include <impedit.hxx>
+
+#ifndef SVX_LIGHT
+
+class EditNodeIdx : public SvxNodeIdx
+{
+private:
+ ContentNode* pNode;
+ ImpEditEngine* pImpEditEngine;
+
+public:
+ EditNodeIdx( ImpEditEngine* pIEE, ContentNode* pNd = 0)
+ { pImpEditEngine = pIEE; pNode = pNd; }
+ virtual ULONG GetIdx() const;
+ virtual SvxNodeIdx* Clone() const;
+ ContentNode* GetNode() { return pNode; }
+};
+
+class EditPosition : public SvxPosition
+{
+private:
+ EditSelection* pCurSel;
+ ImpEditEngine* pImpEditEngine;
+
+public:
+ EditPosition( ImpEditEngine* pIEE, EditSelection* pSel )
+ { pImpEditEngine = pIEE; pCurSel = pSel; }
+
+ virtual ULONG GetNodeIdx() const;
+ virtual USHORT GetCntIdx() const;
+
+ // erzeuge von sich selbst eine Kopie
+ virtual SvxPosition* Clone() const;
+
+ // erzeuge vom NodeIndex eine Kopie
+ virtual SvxNodeIdx* MakeNodeIdx() const;
+};
+
+#define ACTION_INSERTTEXT 1
+#define ACTION_INSERTPARABRK 2
+
+class EditRTFParser : public SvxRTFParser
+{
+private:
+ EditSelection aCurSel;
+ ImpEditEngine* pImpEditEngine;
+ CharSet eDestCharSet;
+ MapMode aRTFMapMode;
+ MapMode aEditMapMode;
+
+ USHORT nDefFont;
+ USHORT nDefTab;
+ USHORT nDefFontHeight;
+ BYTE nLastAction;
+
+protected:
+ virtual void InsertPara();
+ virtual void InsertText();
+ virtual void MovePos( int bForward = TRUE );
+ virtual void SetEndPrevPara( SvxNodeIdx*& rpNodePos,
+ USHORT& rCntPos );
+
+ virtual void UnknownAttrToken( int nToken, SfxItemSet* pSet );
+ virtual void NextToken( int nToken );
+ virtual void SetAttrInDoc( SvxRTFItemStackType &rSet );
+ virtual int IsEndPara( SvxNodeIdx* pNd, USHORT nCnt ) const;
+ virtual void CalcValue();
+ void CreateStyleSheets();
+ SfxStyleSheet* CreateStyleSheet( SvxRTFStyleType* pRTFStyle );
+ SvxRTFStyleType* FindStyleSheet( const String& rName );
+ void AddRTFDefaultValues( const EditPaM& rStart, const EditPaM& rEnd );
+ void ReadField();
+ void SkipGroup();
+
+public:
+ EditRTFParser( SvStream& rIn, EditSelection aCurSel, SfxItemPool& rAttrPool, ImpEditEngine* pImpEditEngine );
+ ~EditRTFParser();
+
+ virtual SvParserState CallParser();
+
+
+ void SetDestCharSet( CharSet eCharSet ) { eDestCharSet = eCharSet; }
+ CharSet GetDestCharSet() const { return eDestCharSet; }
+
+ USHORT GetDefTab() const { return nDefTab; }
+ Font GetDefFont() { return GetFont( nDefFont ); }
+
+ EditPaM GetCurPaM() const { return aCurSel.Max(); }
+};
+
+SV_DECL_REF( EditRTFParser )
+SV_IMPL_REF( EditRTFParser );
+
+
+#endif // !SVX_LIGH
+#endif //_EERTFPAR_HXX
diff --git a/editeng/source/editeng/impedit.cxx b/editeng/source/editeng/impedit.cxx
new file mode 100644
index 0000000000..648c582c3c
--- /dev/null
+++ b/editeng/source/editeng/impedit.cxx
@@ -0,0 +1,2005 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: impedit.cxx,v $
+ * $Revision: 1.64 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <eeng_pch.hxx>
+
+#include <impedit.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <tools/poly.hxx>
+#include <editeng/unolingu.hxx>
+#include <com/sun/star/linguistic2/XDictionaryEntry.hpp>
+#include <com/sun/star/linguistic2/DictionaryType.hpp>
+#include <com/sun/star/linguistic2/DictionaryEvent.hpp>
+#include <com/sun/star/linguistic2/XDictionaryEventListener.hpp>
+#include <com/sun/star/linguistic2/DictionaryEventFlags.hpp>
+#include <com/sun/star/linguistic2/XDictionary.hpp>
+#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
+#include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
+#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
+#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
+#include <vos/mutex.hxx>
+#include <editeng/flditem.hxx>
+#include <svl/intitem.hxx>
+#include <svtools/transfer.hxx>
+#include <sot/exchange.hxx>
+#include <sot/formats.hxx>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::linguistic2;
+
+#define SCRLRANGE 20 // 1/20 der Breite/Hoehe scrollen, wenn im QueryDrop
+
+inline void lcl_AllignToPixel( Point& rPoint, OutputDevice* pOutDev, short nDiffX, short nDiffY )
+{
+ rPoint = pOutDev->LogicToPixel( rPoint );
+
+ if ( nDiffX )
+ rPoint.X() += nDiffX;
+ if ( nDiffY )
+ rPoint.Y() += nDiffY;
+
+ rPoint = pOutDev->PixelToLogic( rPoint );
+}
+
+ // ----------------------------------------------------------------------
+// class ImpEditView
+// ----------------------------------------------------------------------
+ImpEditView::ImpEditView( EditView* pView, EditEngine* pEng, Window* pWindow ) :
+ aOutArea( Point(), pEng->GetPaperSize() )
+{
+ pEditView = pView;
+ pEditEngine = pEng;
+ pOutWin = pWindow;
+ pPointer = NULL;
+ pBackgroundColor = NULL;
+ nScrollDiffX = 0;
+ nExtraCursorFlags = 0;
+ nCursorBidiLevel = CURSOR_BIDILEVEL_DONTKNOW;
+ pCursor = NULL;
+ pDragAndDropInfo = NULL;
+ bReadOnly = sal_False;
+ bClickedInSelection = sal_False;
+ eSelectionMode = EE_SELMODE_TXTONLY;
+ eAnchorMode = ANCHOR_TOP_LEFT;
+ nInvMore = 1;
+ nTravelXPos = TRAVEL_X_DONTKNOW;
+ nControl = EV_CNTRL_AUTOSCROLL | EV_CNTRL_ENABLEPASTE;
+ bActiveDragAndDropListener = FALSE;
+
+ aEditSelection.Min() = pEng->pImpEditEngine->GetEditDoc().GetStartPaM();
+ aEditSelection.Max() = pEng->pImpEditEngine->GetEditDoc().GetEndPaM();
+}
+
+ImpEditView::~ImpEditView()
+{
+ RemoveDragAndDropListeners();
+
+ if ( pOutWin && ( pOutWin->GetCursor() == pCursor ) )
+ pOutWin->SetCursor( NULL );
+
+ delete pCursor;
+ delete pBackgroundColor;
+ delete pPointer;
+ delete pDragAndDropInfo;
+}
+
+void ImpEditView::SetBackgroundColor( const Color& rColor )
+{
+ delete pBackgroundColor;
+ pBackgroundColor = new Color( rColor );
+}
+
+void ImpEditView::SetEditSelection( const EditSelection& rEditSelection )
+{
+ // #100856# set state before notification
+ aEditSelection = rEditSelection;
+
+ if ( pEditEngine->pImpEditEngine->GetNotifyHdl().IsSet() )
+ {
+ EENotify aNotify( EE_NOTIFY_TEXTVIEWSELECTIONCHANGED );
+ aNotify.pEditEngine = pEditEngine;
+ aNotify.pEditView = GetEditViewPtr();
+ pEditEngine->pImpEditEngine->CallNotify( aNotify );
+ }
+}
+
+
+void ImpEditView::DrawSelection( EditSelection aTmpSel, Region* pRegion )
+{
+ if ( GetSelectionMode() == EE_SELMODE_HIDDEN )
+ return;
+
+ // Vor dem Zeichnen der Selektion muss sichergestellt werden,
+ // das der Fensterinhalt komplett gueltig ist!
+ // Muss hier stehen, damit auf jeden Fall weg wenn lerr, nicht spaeter
+ // zwei Paint-Events!
+ // 19.10: Muss sogar vor Abfrage von bUpdate, falls nach Invalidate
+ // noch Paints in der Queue, aber jemand schaltet den UpdateMode um!
+
+ // pRegion: Wenn nicht NULL, dann nur Region berechnen.
+ PolyPolygon* pPolyPoly = NULL;
+ if ( pRegion )
+ pPolyPoly = new PolyPolygon;
+
+ sal_Bool bClipRegion = pOutWin->IsClipRegion();
+ Region aOldRegion = pOutWin->GetClipRegion();
+
+ if ( !pRegion )
+ {
+ if ( pEditEngine->pImpEditEngine->GetUpdateMode() == sal_False )
+ return;
+ if ( pEditEngine->pImpEditEngine->IsInUndo() )
+ return;
+
+ if ( !aTmpSel.HasRange() )
+ return;
+
+ // aTmpOutArea: Falls OutputArea > Papierbreite und
+ // Text > Papierbreite ( uebergrosse Felder )
+ Rectangle aTmpOutArea( aOutArea );
+ if ( aTmpOutArea.GetWidth() > pEditEngine->pImpEditEngine->GetPaperSize().Width() )
+ aTmpOutArea.Right() = aTmpOutArea.Left() + pEditEngine->pImpEditEngine->GetPaperSize().Width();
+ pOutWin->IntersectClipRegion( aTmpOutArea );
+
+ if ( pOutWin->GetCursor() )
+ pOutWin->GetCursor()->Hide();
+ }
+
+ DBG_ASSERT( !pEditEngine->pImpEditEngine->aIdleFormatter.IsActive(), "DrawSelection: Not formatted!" );
+ aTmpSel.Adjust( pEditEngine->pImpEditEngine->GetEditDoc() );
+
+ ContentNode* pStartNode = aTmpSel.Min().GetNode();
+ ContentNode* pEndNode = aTmpSel.Max().GetNode();
+ sal_uInt16 nStartPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( pStartNode );
+ sal_uInt16 nEndPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( pEndNode );
+ // ueber die Absaetze iterieren....
+ for ( sal_uInt16 nPara = nStartPara; nPara <= nEndPara; nPara++ )
+ {
+ ParaPortion* pTmpPortion = pEditEngine->pImpEditEngine->GetParaPortions().SaveGetObject( nPara );
+ DBG_ASSERT( pTmpPortion, "Portion in Selektion nicht gefunden!" );
+ DBG_ASSERT( !pTmpPortion->IsInvalid(), "Portion in Selektion nicht formatiert!" );
+
+ if ( !pTmpPortion->IsVisible() || pTmpPortion->IsInvalid() )
+ continue;
+
+ long nParaStart = pEditEngine->pImpEditEngine->GetParaPortions().GetYOffset( pTmpPortion );
+ if ( ( nParaStart + pTmpPortion->GetHeight() ) < GetVisDocTop() )
+ continue;
+ if ( nParaStart > GetVisDocBottom() )
+ break;
+
+ sal_uInt16 nStartLine = 0;
+ sal_uInt16 nEndLine = pTmpPortion->GetLines().Count() -1;
+ if ( nPara == nStartPara )
+ nStartLine = pTmpPortion->GetLines().FindLine( aTmpSel.Min().GetIndex(), sal_False );
+ if ( nPara == nEndPara )
+ nEndLine = pTmpPortion->GetLines().FindLine( aTmpSel.Max().GetIndex(), sal_True );
+
+ // ueber die Zeilen iterieren....
+ for ( sal_uInt16 nLine = nStartLine; nLine <= nEndLine; nLine++ )
+ {
+ EditLine* pLine = pTmpPortion->GetLines().GetObject( nLine );
+ DBG_ASSERT( pLine, "Zeile nicht gefunden: DrawSelection()" );
+
+ BOOL bPartOfLine = FALSE;
+ sal_uInt16 nStartIndex = pLine->GetStart();
+ sal_uInt16 nEndIndex = pLine->GetEnd();
+ if ( ( nPara == nStartPara ) && ( nLine == nStartLine ) && ( nStartIndex != aTmpSel.Min().GetIndex() ) )
+ {
+ nStartIndex = aTmpSel.Min().GetIndex();
+ bPartOfLine = TRUE;
+ }
+ if ( ( nPara == nEndPara ) && ( nLine == nEndLine ) && ( nEndIndex != aTmpSel.Max().GetIndex() ) )
+ {
+ nEndIndex = aTmpSel.Max().GetIndex();
+ bPartOfLine = TRUE;
+ }
+
+ // Kann passieren, wenn am Anfang einer umgebrochenen Zeile.
+ if ( nEndIndex < nStartIndex )
+ nEndIndex = nStartIndex;
+
+ Rectangle aTmpRec( pEditEngine->pImpEditEngine->GetEditCursor( pTmpPortion, nStartIndex ) );
+ Point aTopLeft( aTmpRec.TopLeft() );
+ Point aBottomRight( aTmpRec.BottomRight() );
+
+ aTopLeft.Y() += nParaStart;
+ aBottomRight.Y() += nParaStart;
+
+ // Nur Painten, wenn im sichtbaren Bereich...
+ if ( aTopLeft.Y() > GetVisDocBottom() )
+ break;
+
+ if ( aBottomRight.Y() < GetVisDocTop() )
+ continue;
+
+ // Now that we have Bidi, the first/last index doesn't have to be the 'most outside' postion
+ if ( !bPartOfLine )
+ {
+ Range aLineXPosStartEnd = pEditEngine->pImpEditEngine->GetLineXPosStartEnd( pTmpPortion, pLine );
+ aTopLeft.X() = aLineXPosStartEnd.Min();
+ aBottomRight.X() = aLineXPosStartEnd.Max();
+ ImplDrawHighlightRect( pOutWin, aTopLeft, aBottomRight, pPolyPoly );
+ }
+ else
+ {
+ USHORT nTmpStartIndex = nStartIndex;
+ USHORT nWritingDirStart, nTmpEndIndex;
+
+ while ( nTmpStartIndex < nEndIndex )
+ {
+ pEditEngine->pImpEditEngine->GetRightToLeft( nPara, nTmpStartIndex+1, &nWritingDirStart, &nTmpEndIndex );
+ if ( nTmpEndIndex > nEndIndex )
+ nTmpEndIndex = nEndIndex;
+
+ DBG_ASSERT( nTmpEndIndex > nTmpStartIndex, "DrawSelection, Start >= End?" );
+
+ long nX1 = pEditEngine->pImpEditEngine->GetXPos( pTmpPortion, pLine, nTmpStartIndex, TRUE );
+ long nX2 = pEditEngine->pImpEditEngine->GetXPos( pTmpPortion, pLine, nTmpEndIndex );
+
+ Point aPt1( Min( nX1, nX2 ), aTopLeft.Y() );
+ Point aPt2( Max( nX1, nX2 ), aBottomRight.Y() );
+
+ ImplDrawHighlightRect( pOutWin, aPt1, aPt2, pPolyPoly );
+
+ nTmpStartIndex = nTmpEndIndex;
+ }
+ }
+
+ }
+ }
+
+ if ( pRegion )
+ {
+ *pRegion = Region( *pPolyPoly );
+ delete pPolyPoly;
+ }
+ else
+ {
+ if ( pOutWin->GetCursor() )
+ pOutWin->GetCursor()->Show();
+
+ if ( bClipRegion )
+ pOutWin->SetClipRegion( aOldRegion );
+ else
+ pOutWin->SetClipRegion();
+ }
+}
+
+void ImpEditView::ImplDrawHighlightRect( Window* _pOutWin, const Point& rDocPosTopLeft, const Point& rDocPosBottomRight, PolyPolygon* pPolyPoly )
+{
+ if ( rDocPosTopLeft.X() != rDocPosBottomRight.X() )
+ {
+ sal_Bool bPixelMode = _pOutWin->GetMapMode() == MAP_PIXEL;
+
+ Point aPnt1( GetWindowPos( rDocPosTopLeft ) );
+ Point aPnt2( GetWindowPos( rDocPosBottomRight ) );
+
+ if ( !IsVertical() )
+ {
+ lcl_AllignToPixel( aPnt1, _pOutWin, +1, 0 );
+ lcl_AllignToPixel( aPnt2, _pOutWin, 0, ( bPixelMode ? 0 : -1 ) );
+ }
+ else
+ {
+ lcl_AllignToPixel( aPnt1, _pOutWin, 0, +1 );
+ lcl_AllignToPixel( aPnt2, _pOutWin, ( bPixelMode ? 0 : +1 ), 0 );
+ }
+
+ Rectangle aRect( aPnt1, aPnt2 );
+ if ( pPolyPoly )
+ {
+ Polygon aTmpPoly( 4 );
+ aTmpPoly[0] = aRect.TopLeft();
+ aTmpPoly[1] = aRect.TopRight();
+ aTmpPoly[2] = aRect.BottomRight();
+ aTmpPoly[3] = aRect.BottomLeft();
+ pPolyPoly->Insert( aTmpPoly );
+ }
+ else
+ {
+ _pOutWin->Invert( aRect );
+ }
+ }
+}
+
+
+BOOL ImpEditView::IsVertical() const
+{
+ return pEditEngine->pImpEditEngine->IsVertical();
+}
+
+Rectangle ImpEditView::GetVisDocArea() const
+{
+ return Rectangle( GetVisDocLeft(), GetVisDocTop(), GetVisDocRight(), GetVisDocBottom() );
+}
+
+Point ImpEditView::GetDocPos( const Point& rWindowPos ) const
+{
+ // Fensterposition => Dokumentposition
+ Point aPoint;
+
+ if ( !pEditEngine->pImpEditEngine->IsVertical() )
+ {
+ aPoint.X() = rWindowPos.X() - aOutArea.Left() + GetVisDocLeft();
+ aPoint.Y() = rWindowPos.Y() - aOutArea.Top() + GetVisDocTop();
+ }
+ else
+ {
+ aPoint.X() = rWindowPos.Y() - aOutArea.Top() + GetVisDocLeft();
+ aPoint.Y() = aOutArea.Right() - rWindowPos.X() + GetVisDocTop();
+ }
+
+ return aPoint;
+}
+
+Point ImpEditView::GetWindowPos( const Point& rDocPos ) const
+{
+ // Dokumentposition => Fensterposition
+ Point aPoint;
+
+ if ( !pEditEngine->pImpEditEngine->IsVertical() )
+ {
+ aPoint.X() = rDocPos.X() + aOutArea.Left() - GetVisDocLeft();
+ aPoint.Y() = rDocPos.Y() + aOutArea.Top() - GetVisDocTop();
+ }
+ else
+ {
+ aPoint.X() = aOutArea.Right() - rDocPos.Y() + GetVisDocTop();
+ aPoint.Y() = rDocPos.X() + aOutArea.Top() - GetVisDocLeft();
+ }
+
+ return aPoint;
+}
+
+Rectangle ImpEditView::GetWindowPos( const Rectangle& rDocRect ) const
+{
+ // Dokumentposition => Fensterposition
+ Point aPos( GetWindowPos( rDocRect.TopLeft() ) );
+ Size aSz = rDocRect.GetSize();
+ Rectangle aRect;
+ if ( !pEditEngine->pImpEditEngine->IsVertical() )
+ {
+ aRect = Rectangle( aPos, aSz );
+ }
+ else
+ {
+ Point aNewPos( aPos.X()-aSz.Height(), aPos.Y() );
+ aRect = Rectangle( aNewPos, Size( aSz.Height(), aSz.Width() ) );
+ }
+ return aRect;
+}
+
+
+Region* ImpEditView::CalcSelectedRegion()
+{
+ Region* pRegion = new Region;
+ DrawSelection( GetEditSelection(), pRegion );
+ return pRegion;
+}
+
+void ImpEditView::SetSelectionMode( EESelectionMode eNewMode )
+{
+ if ( eSelectionMode != eNewMode )
+ {
+ DrawSelection(); // 'Wegmalen' ...
+ eSelectionMode = eNewMode;
+ DrawSelection(); // und neu zeichnen.
+ }
+}
+
+void ImpEditView::SetOutputArea( const Rectangle& rRec )
+{
+ // sollte besser auf Pixel allignt sein!
+ Rectangle aNewRec( pOutWin->LogicToPixel( rRec ) );
+ aNewRec = pOutWin->PixelToLogic( aNewRec );
+ aOutArea = aNewRec;
+ if ( aOutArea.Right() < aOutArea.Left() )
+ aOutArea.Right() = aOutArea.Left();
+ if ( aOutArea.Bottom() < aOutArea.Top() )
+ aOutArea.Bottom() = aOutArea.Top();
+
+ if ( DoBigScroll() )
+ SetScrollDiffX( (sal_uInt16)aOutArea.GetWidth() * 3 / 10 );
+ else
+ SetScrollDiffX( (sal_uInt16)aOutArea.GetWidth() * 2 / 10 );
+}
+
+void ImpEditView::ResetOutputArea( const Rectangle& rRec )
+{
+ Rectangle aCurArea( aOutArea );
+ SetOutputArea( rRec );
+ // Umliegende Bereiche invalidieren, wenn UpdateMode der Engine auf sal_True
+ if ( !aCurArea.IsEmpty() && pEditEngine->pImpEditEngine->GetUpdateMode() )
+ {
+ long nMore = 0;
+ if ( DoInvalidateMore() )
+ nMore = GetWindow()->PixelToLogic( Size( nInvMore, 0 ) ).Width();
+ if ( aCurArea.Left() < aOutArea.Left() )
+ {
+ Rectangle aRect( aCurArea.TopLeft(),
+ Size( aOutArea.Left()-aCurArea.Left(), aCurArea.GetHeight() ) );
+ if ( nMore )
+ {
+ aRect.Left() -= nMore;
+ aRect.Top() -= nMore;
+ aRect.Bottom() += nMore;
+ }
+ GetWindow()->Invalidate( aRect );
+ }
+ if ( aCurArea.Right() > aOutArea.Right() )
+ {
+ long nW = aCurArea.Right() - aOutArea.Right();
+ Point aPos( aCurArea.TopRight() );
+ aPos.X() -= nW;
+ Rectangle aRect( aPos, Size( nW, aCurArea.GetHeight() ) );
+ if ( nMore )
+ {
+ aRect.Right() += nMore;
+ aRect.Top() -= nMore;
+ aRect.Bottom() += nMore;
+ }
+ GetWindow()->Invalidate( aRect );
+ }
+ if ( aCurArea.Top() < aOutArea.Top() )
+ {
+ Rectangle aRect( aCurArea.TopLeft(), Size( aCurArea.GetWidth(), aOutArea.Top() - aCurArea.Top() ) );
+ if ( nMore )
+ {
+ aRect.Top() -= nMore;
+ aRect.Left() -= nMore;
+ aRect.Right() += nMore;
+ }
+ GetWindow()->Invalidate( aRect );
+ }
+ if ( aCurArea.Bottom() > aOutArea.Bottom() )
+ {
+ long nH = aCurArea.Bottom() - aOutArea.Bottom();
+ Point aPos( aCurArea.BottomLeft() );
+ aPos.Y() -= nH;
+ Rectangle aRect( aPos, Size( aCurArea.GetWidth(), nH ) );
+ if ( nMore )
+ {
+ aRect.Bottom() += nMore;
+ aRect.Left() -= nMore;
+ aRect.Right() += nMore;
+ }
+
+ GetWindow()->Invalidate( aRect );
+ }
+ }
+}
+
+void ImpEditView::RecalcOutputArea()
+{
+ Rectangle aOldArea( aOutArea );
+ Point aNewTopLeft( aOutArea.TopLeft() );
+ Size aNewSz( aOutArea.GetSize() );
+
+ // X:
+ if ( DoAutoWidth() )
+ {
+ if ( pEditEngine->pImpEditEngine->GetStatus().AutoPageWidth() )
+ aNewSz.Width() = pEditEngine->pImpEditEngine->GetPaperSize().Width();
+ switch ( eAnchorMode )
+ {
+ case ANCHOR_TOP_LEFT:
+ case ANCHOR_VCENTER_LEFT:
+ case ANCHOR_BOTTOM_LEFT:
+ {
+ aNewTopLeft.X() = aAnchorPoint.X();
+ }
+ break;
+ case ANCHOR_TOP_HCENTER:
+ case ANCHOR_VCENTER_HCENTER:
+ case ANCHOR_BOTTOM_HCENTER:
+ {
+ aNewTopLeft.X() = aAnchorPoint.X() - aNewSz.Width() / 2;
+ }
+ break;
+ case ANCHOR_TOP_RIGHT:
+ case ANCHOR_VCENTER_RIGHT:
+ case ANCHOR_BOTTOM_RIGHT:
+ {
+ aNewTopLeft.X() = aAnchorPoint.X() - aNewSz.Width() - 1;
+ }
+ break;
+ }
+ }
+
+ // Y:
+ if ( DoAutoHeight() )
+ {
+ if ( pEditEngine->pImpEditEngine->GetStatus().AutoPageHeight() )
+ aNewSz.Height() = pEditEngine->pImpEditEngine->GetPaperSize().Height();
+ switch ( eAnchorMode )
+ {
+ case ANCHOR_TOP_LEFT:
+ case ANCHOR_TOP_HCENTER:
+ case ANCHOR_TOP_RIGHT:
+ {
+ aNewTopLeft.Y() = aAnchorPoint.Y();
+ }
+ break;
+ case ANCHOR_VCENTER_LEFT:
+ case ANCHOR_VCENTER_HCENTER:
+ case ANCHOR_VCENTER_RIGHT:
+ {
+ aNewTopLeft.Y() = aAnchorPoint.Y() - aNewSz.Height() / 2;
+ }
+ break;
+ case ANCHOR_BOTTOM_LEFT:
+ case ANCHOR_BOTTOM_HCENTER:
+ case ANCHOR_BOTTOM_RIGHT:
+ {
+ aNewTopLeft.Y() = aAnchorPoint.Y() - aNewSz.Height() - 1;
+ }
+ break;
+ }
+ }
+ ResetOutputArea( Rectangle( aNewTopLeft, aNewSz ) );
+}
+
+void ImpEditView::SetAnchorMode( EVAnchorMode eMode )
+{
+ eAnchorMode = eMode;
+ CalcAnchorPoint();
+}
+
+void ImpEditView::CalcAnchorPoint()
+{
+ // GetHeight() und GetWidth() -1, da Rectangle-Berechnung nicht erwuenscht.
+
+ // X:
+ switch ( eAnchorMode )
+ {
+ case ANCHOR_TOP_LEFT:
+ case ANCHOR_VCENTER_LEFT:
+ case ANCHOR_BOTTOM_LEFT:
+ {
+ aAnchorPoint.X() = aOutArea.Left();
+ }
+ break;
+ case ANCHOR_TOP_HCENTER:
+ case ANCHOR_VCENTER_HCENTER:
+ case ANCHOR_BOTTOM_HCENTER:
+ {
+ aAnchorPoint.X() = aOutArea.Left() + (aOutArea.GetWidth()-1) / 2;
+ }
+ break;
+ case ANCHOR_TOP_RIGHT:
+ case ANCHOR_VCENTER_RIGHT:
+ case ANCHOR_BOTTOM_RIGHT:
+ {
+ aAnchorPoint.X() = aOutArea.Right();
+ }
+ break;
+ }
+
+ // Y:
+ switch ( eAnchorMode )
+ {
+ case ANCHOR_TOP_LEFT:
+ case ANCHOR_TOP_HCENTER:
+ case ANCHOR_TOP_RIGHT:
+ {
+ aAnchorPoint.Y() = aOutArea.Top();
+ }
+ break;
+ case ANCHOR_VCENTER_LEFT:
+ case ANCHOR_VCENTER_HCENTER:
+ case ANCHOR_VCENTER_RIGHT:
+ {
+ aAnchorPoint.Y() = aOutArea.Top() + (aOutArea.GetHeight()-1) / 2;
+ }
+ break;
+ case ANCHOR_BOTTOM_LEFT:
+ case ANCHOR_BOTTOM_HCENTER:
+ case ANCHOR_BOTTOM_RIGHT:
+ {
+ aAnchorPoint.Y() = aOutArea.Bottom() - 1;
+ }
+ break;
+ }
+}
+
+void ImpEditView::ShowCursor( sal_Bool bGotoCursor, sal_Bool bForceVisCursor, USHORT nShowCursorFlags )
+{
+ // Kein ShowCursor bei einer leeren View...
+ if ( ( aOutArea.Left() >= aOutArea.Right() ) && ( aOutArea.Top() >= aOutArea.Bottom() ) )
+ return;
+
+ pEditEngine->pImpEditEngine->CheckIdleFormatter();
+ if ( !pEditEngine->pImpEditEngine->IsFormatted() )
+ pEditEngine->pImpEditEngine->FormatDoc();
+
+ // Aus irgendwelchen Gruenden lande ich waehrend der Formatierung hier,
+ // wenn sich der Outiner im Paint initialisiert, weil kein SetPool();
+ if ( pEditEngine->pImpEditEngine->IsFormatting() )
+ return;
+ if ( pEditEngine->pImpEditEngine->GetUpdateMode() == sal_False )
+ return;
+ if ( pEditEngine->pImpEditEngine->IsInUndo() )
+ return;
+
+ if ( pOutWin->GetCursor() != GetCursor() )
+ pOutWin->SetCursor( GetCursor() );
+
+ EditPaM aPaM( aEditSelection.Max() );
+
+ USHORT nTextPortionStart = 0;
+ USHORT nPara = pEditEngine->pImpEditEngine->aEditDoc.GetPos( aPaM.GetNode() );
+ if (nPara == USHRT_MAX) // #i94322
+ return;
+ ParaPortion* pParaPortion = pEditEngine->pImpEditEngine->GetParaPortions().GetObject( nPara );
+
+ nShowCursorFlags |= nExtraCursorFlags;
+
+ nShowCursorFlags |= GETCRSR_TXTONLY;
+
+ // Use CursorBidiLevel 0/1 in meaning of
+ // 0: prefer portion end, normal mode
+ // 1: prefer portion start
+
+ if ( ( GetCursorBidiLevel() != CURSOR_BIDILEVEL_DONTKNOW ) && GetCursorBidiLevel() )
+ {
+ nShowCursorFlags |= GETCRSR_PREFERPORTIONSTART;
+ }
+
+ Rectangle aEditCursor = pEditEngine->pImpEditEngine->PaMtoEditCursor( aPaM, nShowCursorFlags );
+ if ( !IsInsertMode() && !aEditSelection.HasRange() )
+ {
+ if ( aPaM.GetNode()->Len() && ( aPaM.GetIndex() < aPaM.GetNode()->Len() ) )
+ {
+ // If we are behind a portion, and the next portion has other direction, we must change position...
+ aEditCursor.Left() = aEditCursor.Right() = pEditEngine->pImpEditEngine->PaMtoEditCursor( aPaM, GETCRSR_TXTONLY|GETCRSR_PREFERPORTIONSTART ).Left();
+
+ USHORT nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nTextPortionStart, TRUE );
+ TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
+ if ( pTextPortion->GetKind() == PORTIONKIND_TAB )
+ {
+ aEditCursor.Right() += pTextPortion->GetSize().Width();
+ }
+ else
+ {
+ EditPaM aNext = pEditEngine->pImpEditEngine->CursorRight( aPaM, (USHORT)i18n::CharacterIteratorMode::SKIPCELL );
+ Rectangle aTmpRect = pEditEngine->pImpEditEngine->PaMtoEditCursor( aNext, GETCRSR_TXTONLY );
+ if ( aTmpRect.Top() != aEditCursor.Top() )
+ aTmpRect = pEditEngine->pImpEditEngine->PaMtoEditCursor( aNext, GETCRSR_TXTONLY|GETCRSR_ENDOFLINE );
+ aEditCursor.Right() = aTmpRect.Left();
+ }
+ }
+ }
+ long nMaxHeight = !IsVertical() ? aOutArea.GetHeight() : aOutArea.GetWidth();
+ if ( aEditCursor.GetHeight() > nMaxHeight )
+ {
+ aEditCursor.Bottom() = aEditCursor.Top() + nMaxHeight - 1;
+ }
+ if ( bGotoCursor ) // && (!pEditEngine->pImpEditEngine->GetStatus().AutoPageSize() ) )
+ {
+ // pruefen, ob scrollen notwendig...
+ // wenn scrollen, dann Update() und Scroll() !
+ long nDocDiffX = 0;
+ long nDocDiffY = 0;
+
+ Rectangle aTmpVisArea( GetVisDocArea() );
+ // aTmpOutArea: Falls OutputArea > Papierbreite und
+ // Text > Papierbreite ( uebergrosse Felder )
+ long nMaxTextWidth = !IsVertical() ? pEditEngine->pImpEditEngine->GetPaperSize().Width() : pEditEngine->pImpEditEngine->GetPaperSize().Height();
+ if ( aTmpVisArea.GetWidth() > nMaxTextWidth )
+ aTmpVisArea.Right() = aTmpVisArea.Left() + nMaxTextWidth;
+
+ if ( aEditCursor.Bottom() > aTmpVisArea.Bottom() )
+ { // hochscrollen, hier positiv
+ nDocDiffY = aEditCursor.Bottom() - aTmpVisArea.Bottom();
+ }
+ else if ( aEditCursor.Top() < aTmpVisArea.Top() )
+ { // runterscrollen, negativ
+ nDocDiffY = aEditCursor.Top() - aTmpVisArea.Top();
+ }
+
+ if ( aEditCursor.Right() > aTmpVisArea.Right() )
+ {
+ // linksscrollen, positiv
+ nDocDiffX = aEditCursor.Right() - aTmpVisArea.Right();
+ // Darfs ein bischen mehr sein?
+ if ( aEditCursor.Right() < ( nMaxTextWidth - GetScrollDiffX() ) )
+ nDocDiffX += GetScrollDiffX();
+ else
+ {
+ long n = nMaxTextWidth - aEditCursor.Right();
+ // Bei einem MapMode != RefMapMode kann der EditCursor auch mal ueber
+ // die Papierbreite Wandern!
+ nDocDiffX += ( n > 0 ? n : -n );
+ }
+ }
+ else if ( aEditCursor.Left() < aTmpVisArea.Left() )
+ { // rechtsscrollen
+ // negativ:
+ nDocDiffX = aEditCursor.Left() - aTmpVisArea.Left();
+ // Darfs ein bischen mehr sein?
+ if ( aEditCursor.Left() > ( - (long)GetScrollDiffX() ) )
+ nDocDiffX -= GetScrollDiffX();
+ else
+ nDocDiffX -= aEditCursor.Left();
+ }
+ if ( aPaM.GetIndex() == 0 ) // braucht Olli fuer den Outliner
+ {
+ // Aber sicherstellen, dass dadurch der Cursor nicht den
+ // sichtbaren bereich verlaesst!
+ if ( aEditCursor.Left() < aTmpVisArea.GetWidth() )
+ {
+ nDocDiffX = -aTmpVisArea.Left();
+ }
+ }
+
+ if ( nDocDiffX | nDocDiffY )
+ {
+ long nDiffX = !IsVertical() ? nDocDiffX : -nDocDiffY;
+ long nDiffY = !IsVertical() ? nDocDiffY : nDocDiffX;
+
+ // Negativ: Zum Anfang bzw. linken Rand
+ if ( ( Abs( nDiffY ) > pEditEngine->pImpEditEngine->nOnePixelInRef ) && DoBigScroll() )
+ {
+ long nH = aOutArea.GetHeight() / 4;
+ if ( ( nH > aEditCursor.GetHeight() ) && ( Abs( nDiffY ) < nH ) )
+ {
+ if ( nDiffY < 0 )
+ nDiffY -= nH;
+ else
+ nDiffY += nH;
+ }
+ }
+
+ if ( ( Abs( nDiffX ) > pEditEngine->pImpEditEngine->nOnePixelInRef ) && DoBigScroll() )
+ {
+ long nW = aOutArea.GetWidth() / 4;
+ if ( Abs( nDiffX ) < nW )
+ {
+ if ( nDiffY < 0 )
+ nDiffY -= nW;
+ else
+ nDiffY += nW;
+ }
+ }
+
+ if ( nDiffX )
+ pEditEngine->pImpEditEngine->aStatus.GetStatusWord() = pEditEngine->pImpEditEngine->aStatus.GetStatusWord() | EE_STAT_HSCROLL;
+ if ( nDiffY )
+ pEditEngine->pImpEditEngine->aStatus.GetStatusWord() = pEditEngine->pImpEditEngine->aStatus.GetStatusWord() | EE_STAT_VSCROLL;
+ Scroll( -nDiffX, -nDiffY );
+ pEditEngine->pImpEditEngine->DelayedCallStatusHdl();
+ }
+ }
+
+ // Cursor evtl. etwas stutzen...
+ if ( ( aEditCursor.Bottom() > GetVisDocTop() ) &&
+ ( aEditCursor.Top() < GetVisDocBottom() ) )
+ {
+ if ( aEditCursor.Bottom() > GetVisDocBottom() )
+ aEditCursor.Bottom() = GetVisDocBottom();
+ if ( aEditCursor.Top() < GetVisDocTop() )
+ aEditCursor.Top() = GetVisDocTop();
+ }
+
+ long nOnePixel = pOutWin->PixelToLogic( Size( 1, 0 ) ).Width();
+
+ if ( /* pEditEngine->pImpEditEngine->GetStatus().AutoPageSize() || */
+ ( ( aEditCursor.Top() + nOnePixel >= GetVisDocTop() ) &&
+ ( aEditCursor.Bottom() - nOnePixel <= GetVisDocBottom() ) &&
+ ( aEditCursor.Left() + nOnePixel >= GetVisDocLeft() ) &&
+ ( aEditCursor.Right() - nOnePixel <= GetVisDocRight() ) ) )
+ {
+ Rectangle aCursorRect = GetWindowPos( aEditCursor );
+ GetCursor()->SetPos( aCursorRect.TopLeft() );
+ Size aCursorSz( aCursorRect.GetSize() );
+ // Rectangle is inclusive
+ aCursorSz.Width()--;
+ aCursorSz.Height()--;
+ if ( !aCursorSz.Width() || !aCursorSz.Height() )
+ {
+ long nCursorSz = pOutWin->GetSettings().GetStyleSettings().GetCursorSize();
+ nCursorSz = pOutWin->PixelToLogic( Size( nCursorSz, 0 ) ).Width();
+ if ( !aCursorSz.Width() )
+ aCursorSz.Width() = nCursorSz;
+ if ( !aCursorSz.Height() )
+ aCursorSz.Height() = nCursorSz;
+ }
+ // #111036# Let VCL do orientation for cursor, otherwise problem when cursor has direction flag
+ if ( IsVertical() )
+ {
+ Size aOldSz( aCursorSz );
+ aCursorSz.Width() = aOldSz.Height();
+ aCursorSz.Height() = aOldSz.Width();
+ GetCursor()->SetPos( aCursorRect.TopRight() );
+ GetCursor()->SetOrientation( 2700 );
+ }
+ else
+ // --> FME 2004-10-18 #i32593#
+ // Reset correct orientation in horizontal layout
+ GetCursor()->SetOrientation( 0 );
+ // <--
+
+ GetCursor()->SetSize( aCursorSz );
+
+ unsigned char nCursorDir = CURSOR_DIRECTION_NONE;
+ if ( IsInsertMode() && !aEditSelection.HasRange() && ( pEditEngine->pImpEditEngine->HasDifferentRTLLevels( aPaM.GetNode() ) ) )
+ {
+ USHORT nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nTextPortionStart, nShowCursorFlags & GETCRSR_PREFERPORTIONSTART ? TRUE : FALSE );
+ TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
+ USHORT nRTLLevel = pTextPortion->GetRightToLeft();
+ if ( nRTLLevel%2 )
+ nCursorDir = CURSOR_DIRECTION_RTL;
+ else
+ nCursorDir = CURSOR_DIRECTION_LTR;
+
+ }
+ GetCursor()->SetDirection( nCursorDir );
+
+ if ( bForceVisCursor )
+ GetCursor()->Show();
+
+ // #102936# Call SetInputContext every time, otherwise we may have the wrong font
+ // if ( !pEditEngine->pImpEditEngine->mpIMEInfos )
+ {
+ SvxFont aFont;
+ pEditEngine->pImpEditEngine->SeekCursor( aPaM.GetNode(), aPaM.GetIndex()+1, aFont );
+ ULONG nContextFlags = INPUTCONTEXT_TEXT|INPUTCONTEXT_EXTTEXTINPUT;
+ GetWindow()->SetInputContext( InputContext( aFont, nContextFlags ) );
+ }
+ }
+ else
+ {
+ pEditEngine->pImpEditEngine->GetStatus().GetStatusWord() = pEditEngine->pImpEditEngine->GetStatus().GetStatusWord() | EE_STAT_CURSOROUT;
+ GetCursor()->Hide();
+ GetCursor()->SetPos( Point( -1, -1 ) );
+ GetCursor()->SetSize( Size( 0, 0 ) );
+ }
+}
+
+Pair ImpEditView::Scroll( long ndX, long ndY, BYTE nRangeCheck )
+{
+ DBG_ASSERT( pEditEngine->pImpEditEngine->IsFormatted(), "Scroll: Nicht formatiert!" );
+ if ( !ndX && !ndY )
+ return Range( 0, 0 );
+
+#ifdef DBG_UTIL
+ Rectangle aR( aOutArea );
+ aR = pOutWin->LogicToPixel( aR );
+ aR = pOutWin->PixelToLogic( aR );
+ DBG_ASSERTWARNING( aR == aOutArea, "OutArea vor Scroll nicht aligned" );
+#endif
+
+ Rectangle aNewVisArea( GetVisDocArea() );
+ Size aPaperSz( pEditEngine->pImpEditEngine->GetPaperSize() );
+
+ // Vertical:
+ if ( !IsVertical() )
+ {
+ aNewVisArea.Top() -= ndY;
+ aNewVisArea.Bottom() -= ndY;
+ }
+ else
+ {
+ aNewVisArea.Top() += ndX;
+ aNewVisArea.Bottom() += ndX;
+ }
+ if ( ( nRangeCheck == RGCHK_PAPERSZ1 ) && ( aNewVisArea.Bottom() > (long)pEditEngine->pImpEditEngine->GetTextHeight() ) )
+ {
+ // GetTextHeight noch optimieren!
+ long nDiff = pEditEngine->pImpEditEngine->GetTextHeight() - aNewVisArea.Bottom(); // negativ
+ aNewVisArea.Move( 0, nDiff ); // koennte im neg. Bereich landen...
+ }
+ if ( ( aNewVisArea.Top() < 0 ) && ( nRangeCheck != RGCHK_NONE ) )
+ aNewVisArea.Move( 0, -aNewVisArea.Top() );
+
+ // Horizontal:
+ if ( !IsVertical() )
+ {
+ aNewVisArea.Left() -= ndX;
+ aNewVisArea.Right() -= ndX;
+ }
+ else
+ {
+ aNewVisArea.Left() -= ndY;
+ aNewVisArea.Right() -= ndY;
+ }
+ if ( ( nRangeCheck == RGCHK_PAPERSZ1 ) && ( aNewVisArea.Right() > (long)pEditEngine->pImpEditEngine->CalcTextWidth( FALSE ) ) )
+ {
+ long nDiff = pEditEngine->pImpEditEngine->CalcTextWidth( FALSE ) - aNewVisArea.Right(); // negativ
+ aNewVisArea.Move( nDiff, 0 ); // koennte im neg. Bereich landen...
+ }
+ if ( ( aNewVisArea.Left() < 0 ) && ( nRangeCheck != RGCHK_NONE ) )
+ aNewVisArea.Move( -aNewVisArea.Left(), 0 );
+
+ // Die Differenz muss auf Pixel alignt sein (wegen Scroll!)
+ long nDiffX = !IsVertical() ? ( GetVisDocLeft() - aNewVisArea.Left() ) : -( GetVisDocTop() - aNewVisArea.Top() );
+ long nDiffY = !IsVertical() ? ( GetVisDocTop() - aNewVisArea.Top() ) : ( GetVisDocLeft() - aNewVisArea.Left() );
+
+ Size aDiffs( nDiffX, nDiffY );
+ aDiffs = pOutWin->LogicToPixel( aDiffs );
+ aDiffs = pOutWin->PixelToLogic( aDiffs );
+
+ long nRealDiffX = aDiffs.Width();
+ long nRealDiffY = aDiffs.Height();
+
+
+ if ( nRealDiffX || nRealDiffY )
+ {
+ Cursor* pCrsr = GetCursor();
+ sal_Bool bVisCursor = pCrsr->IsVisible();
+ pCrsr->Hide();
+ pOutWin->Update();
+ if ( !IsVertical() )
+ aVisDocStartPos.Move( -nRealDiffX, -nRealDiffY );
+ else
+ aVisDocStartPos.Move( -nRealDiffY, nRealDiffX );
+ // Das Move um den allignten Wert ergibt nicht unbedingt ein
+ // alligntes Rechteck...
+ // MT 11/00: Align VisArea???
+ aVisDocStartPos = pOutWin->LogicToPixel( aVisDocStartPos );
+ aVisDocStartPos = pOutWin->PixelToLogic( aVisDocStartPos );
+ Rectangle aRec( aOutArea );
+ pOutWin->Scroll( nRealDiffX, nRealDiffY, aRec, sal_True );
+ pOutWin->Update();
+ pCrsr->SetPos( pCrsr->GetPos() + Point( nRealDiffX, nRealDiffY ) );
+ if ( bVisCursor )
+ {
+ Rectangle aCursorRec( pCrsr->GetPos(), pCrsr->GetSize() );
+ if ( aOutArea.IsInside( aCursorRec ) )
+ pCrsr->Show();
+ }
+
+ if ( pEditEngine->pImpEditEngine->GetNotifyHdl().IsSet() )
+ {
+ EENotify aNotify( EE_NOTIFY_TEXTVIEWSCROLLED );
+ aNotify.pEditEngine = pEditEngine;
+ aNotify.pEditView = GetEditViewPtr();
+ pEditEngine->pImpEditEngine->CallNotify( aNotify );
+ }
+ }
+
+ return Pair( nRealDiffX, nRealDiffY );
+}
+
+sal_Bool ImpEditView::PostKeyEvent( const KeyEvent& rKeyEvent )
+{
+ BOOL bDone = FALSE;
+
+ KeyFuncType eFunc = rKeyEvent.GetKeyCode().GetFunction();
+ if ( eFunc != KEYFUNC_DONTKNOW )
+ {
+ switch ( eFunc )
+ {
+ case KEYFUNC_CUT:
+ {
+ if ( !bReadOnly )
+ {
+ Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
+ CutCopy( aClipBoard, sal_True );
+ bDone = sal_True;
+ }
+ }
+ break;
+ case KEYFUNC_COPY:
+ {
+ Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
+ CutCopy( aClipBoard, sal_False );
+ bDone = TRUE;
+ }
+ break;
+ case KEYFUNC_PASTE:
+ {
+ if ( !bReadOnly && IsPasteEnabled() )
+ {
+ pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_PASTE );
+ Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
+ Paste( aClipBoard, pEditEngine->pImpEditEngine->GetStatus().AllowPasteSpecial() );
+ pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_PASTE );
+ bDone = sal_True;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if( !bDone )
+ bDone = pEditEngine->PostKeyEvent( rKeyEvent, GetEditViewPtr() );
+
+ return bDone;
+}
+
+sal_Bool ImpEditView::MouseButtonUp( const MouseEvent& rMouseEvent )
+{
+ if ( pEditEngine->pImpEditEngine->aStatus.NotifyCursorMovements() )
+ {
+ if ( pEditEngine->pImpEditEngine->aStatus.GetPrevParagraph() != pEditEngine->pImpEditEngine->GetEditDoc().GetPos( GetEditSelection().Max().GetNode() ) )
+ {
+ pEditEngine->pImpEditEngine->aStatus.GetStatusWord() = pEditEngine->pImpEditEngine->aStatus.GetStatusWord() | EE_STAT_CRSRLEFTPARA;
+ pEditEngine->pImpEditEngine->CallStatusHdl();
+ }
+ }
+ nTravelXPos = TRAVEL_X_DONTKNOW;
+ nCursorBidiLevel = CURSOR_BIDILEVEL_DONTKNOW;
+ nExtraCursorFlags = 0;
+ bClickedInSelection = sal_False;
+
+ if ( rMouseEvent.IsMiddle() && !bReadOnly &&
+ ( GetWindow()->GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION ) )
+ {
+ Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetPrimarySelection());
+ Paste( aClipBoard );
+ }
+ else if ( rMouseEvent.IsLeft() && GetEditSelection().HasRange() )
+ {
+ Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetPrimarySelection());
+ CutCopy( aClipBoard, FALSE );
+ }
+
+ return pEditEngine->pImpEditEngine->MouseButtonUp( rMouseEvent, GetEditViewPtr() );
+}
+
+sal_Bool ImpEditView::MouseButtonDown( const MouseEvent& rMouseEvent )
+{
+ pEditEngine->pImpEditEngine->CheckIdleFormatter(); // Falls schnelles Tippen und MouseButtonDown
+ if ( pEditEngine->pImpEditEngine->aStatus.NotifyCursorMovements() )
+ pEditEngine->pImpEditEngine->aStatus.GetPrevParagraph() = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( GetEditSelection().Max().GetNode() );
+ nTravelXPos = TRAVEL_X_DONTKNOW;
+ nExtraCursorFlags = 0;
+ nCursorBidiLevel = CURSOR_BIDILEVEL_DONTKNOW;
+ bClickedInSelection = IsSelectionAtPoint( rMouseEvent.GetPosPixel() );
+ return pEditEngine->pImpEditEngine->MouseButtonDown( rMouseEvent, GetEditViewPtr() );
+}
+
+sal_Bool ImpEditView::MouseMove( const MouseEvent& rMouseEvent )
+{
+ return pEditEngine->pImpEditEngine->MouseMove( rMouseEvent, GetEditViewPtr() );
+}
+
+void ImpEditView::Command( const CommandEvent& rCEvt )
+{
+ pEditEngine->pImpEditEngine->CheckIdleFormatter(); // Falls schnelles Tippen und MouseButtonDown
+ pEditEngine->pImpEditEngine->Command( rCEvt, GetEditViewPtr() );
+}
+
+
+void ImpEditView::SetInsertMode( sal_Bool bInsert )
+{
+ if ( bInsert != IsInsertMode() )
+ {
+ SetFlags( nControl, EV_CNTRL_OVERWRITE, !bInsert );
+ ShowCursor( DoAutoScroll(), sal_False );
+ }
+}
+
+sal_Bool ImpEditView::IsWrongSpelledWord( const EditPaM& rPaM, sal_Bool bMarkIfWrong )
+{
+ sal_Bool bIsWrong = sal_False;
+#ifndef SVX_LIGHT
+ if ( rPaM.GetNode()->GetWrongList() )
+ {
+ EditSelection aSel = pEditEngine->pImpEditEngine->SelectWord( rPaM, ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
+ bIsWrong = rPaM.GetNode()->GetWrongList()->HasWrong( aSel.Min().GetIndex(), aSel.Max().GetIndex() );
+ if ( bIsWrong && bMarkIfWrong )
+ {
+ DrawSelection(); // alte Selektion 'weg-zeichnen'
+ SetEditSelection( aSel );
+ DrawSelection();
+ }
+ }
+#endif // !SVX_LIGHT
+ return bIsWrong;
+}
+
+String ImpEditView::SpellIgnoreOrAddWord( sal_Bool bAdd )
+{
+ String aWord;
+#ifndef SVX_LIGHT
+ if ( pEditEngine->pImpEditEngine->GetSpeller().is() )
+ {
+ EditPaM aPaM = GetEditSelection().Max();
+ if ( !HasSelection() )
+ {
+ EditSelection aSel = pEditEngine->pImpEditEngine->SelectWord( aPaM );
+ aWord = pEditEngine->pImpEditEngine->GetSelected( aSel );
+ }
+ else
+ {
+ aWord = pEditEngine->pImpEditEngine->GetSelected( GetEditSelection() );
+ // Und deselektieren
+ DrawSelection(); // alte Selektion 'weg-zeichnen'
+ SetEditSelection( EditSelection( aPaM, aPaM ) );
+ DrawSelection();
+ }
+
+ if ( aWord.Len() )
+ {
+ if ( bAdd )
+ {
+ DBG_ERROR( "Sorry, AddWord not implemented" );
+ }
+ else // Ignore
+ {
+ Reference< XDictionary > xDic( SvxGetIgnoreAllList(), UNO_QUERY );
+ if (xDic.is())
+ xDic->add( aWord, sal_False, String() );
+ }
+ const EditDoc& rDoc = pEditEngine->pImpEditEngine->GetEditDoc();
+ sal_uInt16 nNodes = rDoc.Count();
+ for ( sal_uInt16 n = 0; n < nNodes; n++ )
+ {
+ ContentNode* pNode = rDoc.GetObject( n );
+ pNode->GetWrongList()->MarkWrongsInvalid();
+ }
+ pEditEngine->pImpEditEngine->DoOnlineSpelling( aPaM.GetNode() );
+ pEditEngine->pImpEditEngine->StartOnlineSpellTimer();
+ }
+ }
+#endif // !SVX_LIGHT
+ return aWord;
+}
+
+void ImpEditView::DeleteSelected()
+{
+ DrawSelection();
+
+ pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_DELETE );
+
+ EditPaM aPaM = pEditEngine->pImpEditEngine->DeleteSelected( GetEditSelection() );
+
+ pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_DELETE );
+
+ SetEditSelection( EditSelection( aPaM, aPaM ) );
+ pEditEngine->pImpEditEngine->FormatAndUpdate( GetEditViewPtr() );
+ ShowCursor( DoAutoScroll(), TRUE );
+}
+
+const SvxFieldItem* ImpEditView::GetField( const Point& rPos, sal_uInt16* pPara, sal_uInt16* pPos ) const
+{
+ if( !GetOutputArea().IsInside( rPos ) )
+ return 0;
+
+ Point aDocPos( GetDocPos( rPos ) );
+ EditPaM aPaM = pEditEngine->pImpEditEngine->GetPaM( aDocPos, sal_False );
+
+ if ( aPaM.GetIndex() == aPaM.GetNode()->Len() )
+ {
+ // Sonst immer, wenn Feld ganz am Schluss und Mouse unter Text
+ return 0;
+ }
+
+ const CharAttribArray& rAttrs = aPaM.GetNode()->GetCharAttribs().GetAttribs();
+ sal_uInt16 nXPos = aPaM.GetIndex();
+ for ( sal_uInt16 nAttr = rAttrs.Count(); nAttr; )
+ {
+ EditCharAttrib* pAttr = rAttrs[--nAttr];
+ if ( pAttr->GetStart() == nXPos )
+ if ( pAttr->Which() == EE_FEATURE_FIELD )
+ {
+ DBG_ASSERT( pAttr->GetItem()->ISA( SvxFieldItem ), "Kein FeldItem..." );
+ if ( pPara )
+ *pPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aPaM.GetNode() );
+ if ( pPos )
+ *pPos = pAttr->GetStart();
+ return (const SvxFieldItem*)pAttr->GetItem();
+ }
+ }
+ return NULL;
+}
+
+BOOL ImpEditView::IsBulletArea( const Point& rPos, sal_uInt16* pPara )
+{
+ if ( pPara )
+ *pPara = 0xFFFF;
+
+ if( !GetOutputArea().IsInside( rPos ) )
+ return FALSE;
+
+ Point aDocPos( GetDocPos( rPos ) );
+ EditPaM aPaM = pEditEngine->pImpEditEngine->GetPaM( aDocPos, sal_False );
+
+ if ( aPaM.GetIndex() == 0 )
+ {
+ USHORT nPara = pEditEngine->pImpEditEngine->aEditDoc.GetPos( aPaM.GetNode() );
+ Rectangle aBulletArea = pEditEngine->GetBulletArea( nPara );
+ long nY = pEditEngine->GetDocPosTopLeft( nPara ).Y();
+ ParaPortion* pParaPortion = pEditEngine->pImpEditEngine->GetParaPortions().GetObject( nPara );
+ nY += pParaPortion->GetFirstLineOffset();
+ if ( ( aDocPos.Y() > ( nY + aBulletArea.Top() ) ) &&
+ ( aDocPos.Y() < ( nY + aBulletArea.Bottom() ) ) &&
+ ( aDocPos.X() > ( aBulletArea.Left() ) ) &&
+ ( aDocPos.X() < ( aBulletArea.Right() ) ) )
+ {
+ if ( pPara )
+ *pPara = nPara;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+void ImpEditView::CutCopy( ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard >& rxClipboard, BOOL bCut )
+{
+ if ( rxClipboard.is() && GetEditSelection().HasRange() )
+ {
+ uno::Reference< datatransfer::XTransferable > xData = pEditEngine->pImpEditEngine->CreateTransferable( GetEditSelection() );
+
+ const sal_uInt32 nRef = Application::ReleaseSolarMutex();
+
+ try
+ {
+ rxClipboard->setContents( xData, NULL );
+
+ // #87756# FlushClipboard, but it would be better to become a TerminateListener to the Desktop and flush on demand...
+ uno::Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( rxClipboard, uno::UNO_QUERY );
+ if( xFlushableClipboard.is() )
+ xFlushableClipboard->flushClipboard();
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ Application::AcquireSolarMutex( nRef );
+
+ if ( bCut )
+ {
+ pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_CUT );
+ DeleteSelected();
+ pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_CUT );
+
+ }
+ }
+}
+
+void ImpEditView::Paste( ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard >& rxClipboard, BOOL bUseSpecial )
+{
+ if ( rxClipboard.is() )
+ {
+ uno::Reference< datatransfer::XTransferable > xDataObj;
+
+ const sal_uInt32 nRef = Application::ReleaseSolarMutex();
+
+ try
+ {
+ xDataObj = rxClipboard->getContents();
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ Application::AcquireSolarMutex( nRef );
+
+ if ( xDataObj.is() && EditEngine::HasValidData( xDataObj ) )
+ {
+ pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_PASTE );
+
+ EditSelection aSel( GetEditSelection() );
+ if ( aSel.HasRange() )
+ {
+ DrawSelection();
+ aSel = pEditEngine->pImpEditEngine->ImpDeleteSelection( aSel );
+ }
+
+ PasteOrDropInfos aPasteOrDropInfos;
+ aPasteOrDropInfos.nAction = EE_ACTION_PASTE;
+ aPasteOrDropInfos.nStartPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aSel.Min().GetNode() );
+ pEditEngine->pImpEditEngine->aBeginPasteOrDropHdl.Call( &aPasteOrDropInfos );
+
+ if ( DoSingleLinePaste() )
+ {
+ datatransfer::DataFlavor aFlavor;
+ SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aFlavor );
+ if ( xDataObj->isDataFlavorSupported( aFlavor ) )
+ {
+ try
+ {
+ uno::Any aData = xDataObj->getTransferData( aFlavor );
+ ::rtl::OUString aTmpText;
+ aData >>= aTmpText;
+ String aText( aTmpText );
+ aText.ConvertLineEnd( LINEEND_LF );
+ aText.SearchAndReplaceAll( LINE_SEP, ' ' );
+ aSel = pEditEngine->pImpEditEngine->ImpInsertText( aSel, aText );
+ }
+ catch( ... )
+ {
+ ; // #i9286# can happen, even if isDataFlavorSupported returns true...
+ }
+ }
+ }
+ else
+ {
+ aSel = pEditEngine->pImpEditEngine->InsertText( xDataObj, String(), aSel.Min(), bUseSpecial && pEditEngine->pImpEditEngine->GetStatus().AllowPasteSpecial() );
+ }
+
+ aPasteOrDropInfos.nEndPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aSel.Max().GetNode() );
+ pEditEngine->pImpEditEngine->aEndPasteOrDropHdl.Call( &aPasteOrDropInfos );
+
+ pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_PASTE );
+ SetEditSelection( aSel );
+ pEditEngine->pImpEditEngine->UpdateSelections();
+ pEditEngine->pImpEditEngine->FormatAndUpdate( GetEditViewPtr() );
+ ShowCursor( DoAutoScroll(), TRUE );
+ }
+ }
+}
+
+
+BOOL ImpEditView::IsInSelection( const EditPaM& rPaM )
+{
+ EditSelection aSel = GetEditSelection();
+ if ( !aSel.HasRange() )
+ return FALSE;
+
+ aSel.Adjust( pEditEngine->pImpEditEngine->GetEditDoc() );
+
+ USHORT nStartNode = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aSel.Min().GetNode() );
+ USHORT nEndNode = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aSel.Max().GetNode() );
+ USHORT nCurNode = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( rPaM.GetNode() );
+
+ if ( ( nCurNode > nStartNode ) && ( nCurNode < nEndNode ) )
+ return TRUE;
+
+ if ( nStartNode == nEndNode )
+ {
+ if ( nCurNode == nStartNode )
+ if ( ( rPaM.GetIndex() >= aSel.Min().GetIndex() ) && ( rPaM.GetIndex() < aSel.Max().GetIndex() ) )
+ return TRUE;
+ }
+ else if ( ( nCurNode == nStartNode ) && ( rPaM.GetIndex() >= aSel.Min().GetIndex() ) )
+ return TRUE;
+ else if ( ( nCurNode == nEndNode ) && ( rPaM.GetIndex() < aSel.Max().GetIndex() ) )
+ return TRUE;
+
+ return FALSE;
+}
+
+void ImpEditView::CreateAnchor()
+{
+ pEditEngine->pImpEditEngine->bInSelection = TRUE;
+ GetEditSelection().Min() = GetEditSelection().Max();
+}
+
+void ImpEditView::DeselectAll()
+{
+ pEditEngine->pImpEditEngine->bInSelection = FALSE;
+ DrawSelection();
+ GetEditSelection().Min() = GetEditSelection().Max();
+}
+
+BOOL ImpEditView::IsSelectionAtPoint( const Point& rPosPixel )
+{
+ if ( pDragAndDropInfo && pDragAndDropInfo->pField )
+ return TRUE;
+
+ Point aMousePos( rPosPixel );
+
+ // Logische Einheiten...
+ aMousePos = GetWindow()->PixelToLogic( aMousePos );
+
+ if ( ( !GetOutputArea().IsInside( aMousePos ) ) && !pEditEngine->pImpEditEngine->IsInSelectionMode() )
+ {
+ return FALSE;
+ }
+
+ Point aDocPos( GetDocPos( aMousePos ) );
+ EditPaM aPaM = pEditEngine->pImpEditEngine->GetPaM( aDocPos, FALSE );
+ return IsInSelection( aPaM );
+}
+
+BOOL ImpEditView::SetCursorAtPoint( const Point& rPointPixel )
+{
+ pEditEngine->pImpEditEngine->CheckIdleFormatter();
+
+ Point aMousePos( rPointPixel );
+
+ // Logische Einheiten...
+ aMousePos = GetWindow()->PixelToLogic( aMousePos );
+
+ if ( ( !GetOutputArea().IsInside( aMousePos ) ) && !pEditEngine->pImpEditEngine->IsInSelectionMode() )
+ {
+ return FALSE;
+ }
+
+ Point aDocPos( GetDocPos( aMousePos ) );
+
+ // Kann optimiert werden: Erst innerhalb eines Absatzes die Zeilen
+ // fuer den PaM durchwuehlen, dann nochmal mit dem PaM fuer das Rect,
+ // obwohl die Zeile schon bekannt ist....
+ // Das muss doch nicht sein !
+
+ EditPaM aPaM = pEditEngine->pImpEditEngine->GetPaM( aDocPos );
+ BOOL bGotoCursor = DoAutoScroll();
+
+ // aTmpNewSel: Diff zwischen alt und neu, nicht die neue Selektion
+ EditSelection aTmpNewSel( GetEditSelection().Max(), aPaM );
+
+ // --> OD 2005-12-16 #i27299#
+ // work on copy of current selection and set new selection, if it has changed.
+ EditSelection aNewEditSelection( GetEditSelection() );
+
+ aNewEditSelection.Max() = aPaM;
+ if ( !pEditEngine->pImpEditEngine->aSelEngine.HasAnchor() )
+ {
+ if ( aNewEditSelection.Min() != aPaM )
+ pEditEngine->pImpEditEngine->CursorMoved( aNewEditSelection.Min().GetNode() );
+ aNewEditSelection.Min() = aPaM;
+ }
+ else
+ {
+ DrawSelection( aTmpNewSel );
+ }
+
+ // set changed text selection
+ if ( GetEditSelection() != aNewEditSelection )
+ {
+ SetEditSelection( aNewEditSelection );
+ }
+ // <--
+
+ BOOL bForceCursor = ( pDragAndDropInfo ? FALSE : TRUE ) && !pEditEngine->pImpEditEngine->IsInSelectionMode();
+ ShowCursor( bGotoCursor, bForceCursor );
+ return TRUE;
+}
+
+
+void ImpEditView::HideDDCursor()
+{
+ if ( pDragAndDropInfo && pDragAndDropInfo->bVisCursor )
+ {
+ GetWindow()->DrawOutDev( pDragAndDropInfo->aCurSavedCursor.TopLeft(), pDragAndDropInfo->aCurSavedCursor.GetSize(),
+ Point(0,0), pDragAndDropInfo->aCurSavedCursor.GetSize(),*pDragAndDropInfo->pBackground );
+ pDragAndDropInfo->bVisCursor = sal_False;
+ }
+}
+
+void ImpEditView::ShowDDCursor( const Rectangle& rRect )
+{
+ if ( !pDragAndDropInfo->bVisCursor )
+ {
+ if ( pOutWin->GetCursor() )
+ pOutWin->GetCursor()->Hide();
+
+ Color aOldFillColor = GetWindow()->GetFillColor();
+ GetWindow()->SetFillColor( Color(4210752) ); // GRAY BRUSH_50, OLDSV, change to DDCursor!
+
+ // Hintergrund sichern...
+ Rectangle aSaveRec( GetWindow()->LogicToPixel( rRect ) );
+ // lieber etwas mehr sichern...
+ aSaveRec.Right() += 1;
+ aSaveRec.Bottom() += 1;
+
+ Size aNewSzPx( aSaveRec.GetSize() );
+ if ( !pDragAndDropInfo->pBackground )
+ {
+ pDragAndDropInfo->pBackground = new VirtualDevice( *GetWindow() );
+ MapMode aMapMode( GetWindow()->GetMapMode() );
+ aMapMode.SetOrigin( Point( 0, 0 ) );
+ pDragAndDropInfo->pBackground->SetMapMode( aMapMode );
+
+ }
+
+#ifdef DBG_UTIL
+ Size aCurSzPx( pDragAndDropInfo->pBackground->GetOutputSizePixel() );
+ if ( ( aCurSzPx.Width() < aNewSzPx.Width() ) ||( aCurSzPx.Height() < aNewSzPx.Height() ) )
+ {
+ sal_Bool bDone = pDragAndDropInfo->pBackground->SetOutputSizePixel( aNewSzPx );
+ DBG_ASSERT( bDone, "Virtuelles Device kaputt?" );
+ }
+#endif
+
+ aSaveRec = GetWindow()->PixelToLogic( aSaveRec );
+
+ pDragAndDropInfo->pBackground->DrawOutDev( Point(0,0), aSaveRec.GetSize(),
+ aSaveRec.TopLeft(), aSaveRec.GetSize(), *GetWindow() );
+ pDragAndDropInfo->aCurSavedCursor = aSaveRec;
+
+ // Cursor malen...
+ GetWindow()->DrawRect( rRect );
+
+ pDragAndDropInfo->bVisCursor = sal_True;
+ pDragAndDropInfo->aCurCursor = rRect;
+
+ GetWindow()->SetFillColor( aOldFillColor );
+ }
+}
+
+void ImpEditView::dragGestureRecognized( const ::com::sun::star::datatransfer::dnd::DragGestureEvent& rDGE ) throw (::com::sun::star::uno::RuntimeException)
+{
+ DBG_ASSERT( !pDragAndDropInfo, "dragGestureRecognized - DragAndDropInfo exist!" );
+
+ vos::OGuard aVclGuard( Application::GetSolarMutex() );
+
+ Point aMousePosPixel( rDGE.DragOriginX, rDGE.DragOriginY );
+
+ EditSelection aCopySel( GetEditSelection() );
+ aCopySel.Adjust( pEditEngine->pImpEditEngine->GetEditDoc() );
+
+ if ( GetEditSelection().HasRange() && bClickedInSelection )
+ {
+ pDragAndDropInfo = new DragAndDropInfo();
+ }
+ else
+ {
+ // Field?!
+ USHORT nPara, nPos;
+ Point aMousePos = GetWindow()->PixelToLogic( aMousePosPixel );
+ const SvxFieldItem* pField = GetField( aMousePos, &nPara, &nPos );
+ if ( pField )
+ {
+ pDragAndDropInfo = new DragAndDropInfo();
+ pDragAndDropInfo->pField = pField;
+ ContentNode* pNode = pEditEngine->pImpEditEngine->GetEditDoc().GetObject( nPara );
+ aCopySel = EditSelection( EditPaM( pNode, nPos ), EditPaM( pNode, nPos+1 ) );
+ GetEditSelection() = aCopySel;
+ DrawSelection();
+ BOOL bGotoCursor = DoAutoScroll();
+ BOOL bForceCursor = ( pDragAndDropInfo ? FALSE : TRUE ) && !pEditEngine->pImpEditEngine->IsInSelectionMode();
+ ShowCursor( bGotoCursor, bForceCursor );
+ }
+ else if ( IsBulletArea( aMousePos, &nPara ) )
+ {
+ pDragAndDropInfo = new DragAndDropInfo();
+ pDragAndDropInfo->bOutlinerMode = TRUE;
+ EditPaM aStartPaM( pEditEngine->pImpEditEngine->GetEditDoc().GetObject( nPara ), 0 );
+ EditPaM aEndPaM( aStartPaM );
+ const SfxInt16Item& rLevel = (const SfxInt16Item&) pEditEngine->GetParaAttrib( nPara, EE_PARA_OUTLLEVEL );
+ for ( USHORT n = nPara +1; n < pEditEngine->pImpEditEngine->GetEditDoc().Count(); n++ )
+ {
+ const SfxInt16Item& rL = (const SfxInt16Item&) pEditEngine->GetParaAttrib( n, EE_PARA_OUTLLEVEL );
+ if ( rL.GetValue() > rLevel.GetValue() )
+ {
+ aEndPaM.SetNode( pEditEngine->pImpEditEngine->GetEditDoc().GetObject( n ) );
+ }
+ else
+ {
+ break;
+ }
+ }
+ aEndPaM.GetIndex() = aEndPaM.GetNode()->Len();
+ SetEditSelection( EditSelection( aStartPaM, aEndPaM ) );
+ }
+ }
+
+ if ( pDragAndDropInfo )
+ {
+
+ pDragAndDropInfo->bStarterOfDD = sal_True;
+
+ // Sensibler Bereich, wo gescrollt werden soll.
+ Size aSz( 5, 0 );
+ aSz = GetWindow()->PixelToLogic( aSz );
+ pDragAndDropInfo->nSensibleRange = (sal_uInt16) aSz.Width();
+ pDragAndDropInfo->nCursorWidth = (sal_uInt16) aSz.Width() / 2;
+ pDragAndDropInfo->aBeginDragSel = pEditEngine->pImpEditEngine->CreateESel( aCopySel );
+
+ uno::Reference< datatransfer::XTransferable > xData = pEditEngine->pImpEditEngine->CreateTransferable( aCopySel );
+
+ sal_Int8 nActions = bReadOnly ? datatransfer::dnd::DNDConstants::ACTION_COPY : datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE;
+
+ rDGE.DragSource->startDrag( rDGE, nActions, 0 /*cursor*/, 0 /*image*/, xData, mxDnDListener );
+ // Falls Drag&Move in einer Engine, muessen Copy&Del geklammert sein!
+ GetCursor()->Hide();
+
+ }
+}
+
+void ImpEditView::dragDropEnd( const ::com::sun::star::datatransfer::dnd::DragSourceDropEvent& rDSDE ) throw (::com::sun::star::uno::RuntimeException)
+{
+ vos::OGuard aVclGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT( pDragAndDropInfo, "ImpEditView::dragDropEnd: pDragAndDropInfo is NULL!" );
+
+ // #123688# Shouldn't happen, but seems to happen...
+ if ( pDragAndDropInfo )
+ {
+ if ( !bReadOnly && rDSDE.DropSuccess && !pDragAndDropInfo->bOutlinerMode && ( rDSDE.DropAction & datatransfer::dnd::DNDConstants::ACTION_MOVE ) )
+ {
+ if ( pDragAndDropInfo->bStarterOfDD && pDragAndDropInfo->bDroppedInMe )
+ {
+ // DropPos: Wohin wurde gedroppt, unabhaengig von laenge.
+ ESelection aDropPos( pDragAndDropInfo->aDropSel.nStartPara, pDragAndDropInfo->aDropSel.nStartPos, pDragAndDropInfo->aDropSel.nStartPara, pDragAndDropInfo->aDropSel.nStartPos );
+ ESelection aToBeDelSel = pDragAndDropInfo->aBeginDragSel;
+ ESelection aNewSel( pDragAndDropInfo->aDropSel.nEndPara, pDragAndDropInfo->aDropSel.nEndPos,
+ pDragAndDropInfo->aDropSel.nEndPara, pDragAndDropInfo->aDropSel.nEndPos );
+ sal_Bool bBeforeSelection = aDropPos.IsLess( pDragAndDropInfo->aBeginDragSel );
+ sal_uInt16 nParaDiff = pDragAndDropInfo->aBeginDragSel.nEndPara - pDragAndDropInfo->aBeginDragSel.nStartPara;
+ if ( bBeforeSelection )
+ {
+ // aToBeDelSel anpassen.
+ DBG_ASSERT( pDragAndDropInfo->aBeginDragSel.nStartPara >= pDragAndDropInfo->aDropSel.nStartPara, "Doch nicht davor?" );
+ aToBeDelSel.nStartPara = aToBeDelSel.nStartPara + nParaDiff;
+ aToBeDelSel.nEndPara = aToBeDelSel.nEndPara + nParaDiff;
+ // Zeichen korrigieren?
+ if ( aToBeDelSel.nStartPara == pDragAndDropInfo->aDropSel.nEndPara )
+ {
+ sal_uInt16 nMoreChars;
+ if ( pDragAndDropInfo->aDropSel.nStartPara == pDragAndDropInfo->aDropSel.nEndPara )
+ nMoreChars = pDragAndDropInfo->aDropSel.nEndPos - pDragAndDropInfo->aDropSel.nStartPos;
+ else
+ nMoreChars = pDragAndDropInfo->aDropSel.nEndPos;
+ aToBeDelSel.nStartPos =
+ aToBeDelSel.nStartPos + nMoreChars;
+ if ( aToBeDelSel.nStartPara == aToBeDelSel.nEndPara )
+ aToBeDelSel.nEndPos =
+ aToBeDelSel.nEndPos + nMoreChars;
+ }
+ }
+ else
+ {
+ // aToBeDelSel ist ok, aber Selektion der View
+ // muss angepasst werden, wenn davor geloescht wird!
+ DBG_ASSERT( pDragAndDropInfo->aBeginDragSel.nStartPara <= pDragAndDropInfo->aDropSel.nStartPara, "Doch nicht davor?" );
+ aNewSel.nStartPara = aNewSel.nStartPara - nParaDiff;
+ aNewSel.nEndPara = aNewSel.nEndPara - nParaDiff;
+ // Zeichen korrigieren?
+ if ( pDragAndDropInfo->aBeginDragSel.nEndPara == pDragAndDropInfo->aDropSel.nStartPara )
+ {
+ sal_uInt16 nLessChars;
+ if ( pDragAndDropInfo->aBeginDragSel.nStartPara == pDragAndDropInfo->aBeginDragSel.nEndPara )
+ nLessChars = pDragAndDropInfo->aBeginDragSel.nEndPos - pDragAndDropInfo->aBeginDragSel.nStartPos;
+ else
+ nLessChars = pDragAndDropInfo->aBeginDragSel.nEndPos;
+ aNewSel.nStartPos = aNewSel.nStartPos - nLessChars;
+ if ( aNewSel.nStartPara == aNewSel.nEndPara )
+ aNewSel.nEndPos = aNewSel.nEndPos - nLessChars;
+ }
+ }
+
+ DrawSelection();
+ EditSelection aDelSel( pEditEngine->pImpEditEngine->CreateSel( aToBeDelSel ) );
+ DBG_ASSERT( !aDelSel.DbgIsBuggy( pEditEngine->pImpEditEngine->aEditDoc ), "ToBeDel ist buggy!" );
+ pEditEngine->pImpEditEngine->ImpDeleteSelection( aDelSel );
+ if ( !bBeforeSelection )
+ {
+ DBG_ASSERT( !pEditEngine->pImpEditEngine->CreateSel( aNewSel ).DbgIsBuggy(pEditEngine->pImpEditEngine->aEditDoc), "Bad" );
+ SetEditSelection( pEditEngine->pImpEditEngine->CreateSel( aNewSel ) );
+ }
+ pEditEngine->pImpEditEngine->FormatAndUpdate( pEditEngine->pImpEditEngine->GetActiveView() );
+ DrawSelection();
+ }
+ else
+ {
+ // andere EditEngine...
+ if ( pEditEngine->pImpEditEngine->ImplHasText() ) // #88630# SC ist removing the content when switching the task
+ DeleteSelected();
+ }
+ }
+
+ if ( pDragAndDropInfo->bUndoAction )
+ pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_DRAGANDDROP );
+
+ HideDDCursor();
+ ShowCursor( DoAutoScroll(), TRUE );
+ delete pDragAndDropInfo;
+ pDragAndDropInfo = NULL;
+ pEditEngine->GetEndDropHdl().Call(GetEditViewPtr());
+ }
+}
+
+void ImpEditView::drop( const ::com::sun::star::datatransfer::dnd::DropTargetDropEvent& rDTDE ) throw (::com::sun::star::uno::RuntimeException)
+{
+ vos::OGuard aVclGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT( pDragAndDropInfo, "Drop - No Drag&Drop info?!" );
+
+ if ( pDragAndDropInfo->bDragAccepted )
+ {
+ pEditEngine->GetBeginDropHdl().Call(GetEditViewPtr());
+ BOOL bChanges = FALSE;
+
+ HideDDCursor();
+
+ if ( pDragAndDropInfo->bStarterOfDD )
+ {
+ pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_DRAGANDDROP );
+ pDragAndDropInfo->bUndoAction = TRUE;
+ }
+
+ if ( pDragAndDropInfo->bOutlinerMode )
+ {
+ bChanges = TRUE;
+ GetEditViewPtr()->MoveParagraphs( Range( pDragAndDropInfo->aBeginDragSel.nStartPara, pDragAndDropInfo->aBeginDragSel.nEndPara ), pDragAndDropInfo->nOutlinerDropDest );
+ }
+ else
+ {
+ uno::Reference< datatransfer::XTransferable > xDataObj = rDTDE.Transferable;
+ if ( xDataObj.is() )
+ {
+ bChanges = TRUE;
+ // Selektion wegmalen...
+ DrawSelection();
+ EditPaM aPaM( pDragAndDropInfo->aDropDest );
+
+ PasteOrDropInfos aPasteOrDropInfos;
+ aPasteOrDropInfos.nAction = EE_ACTION_DROP;
+ aPasteOrDropInfos.nStartPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aPaM.GetNode() );
+ pEditEngine->pImpEditEngine->aBeginPasteOrDropHdl.Call( &aPasteOrDropInfos );
+
+ EditSelection aNewSel = pEditEngine->pImpEditEngine->InsertText( xDataObj, String(), aPaM, pEditEngine->pImpEditEngine->GetStatus().AllowPasteSpecial() );
+
+ aPasteOrDropInfos.nEndPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aNewSel.Max().GetNode() );
+ pEditEngine->pImpEditEngine->aEndPasteOrDropHdl.Call( &aPasteOrDropInfos );
+
+ SetEditSelection( aNewSel );
+ pEditEngine->pImpEditEngine->FormatAndUpdate( pEditEngine->pImpEditEngine->GetActiveView() );
+ if ( pDragAndDropInfo->bStarterOfDD )
+ {
+ // Nur dann setzen, wenn in gleicher Engine!
+ pDragAndDropInfo->aDropSel.nStartPara = pEditEngine->pImpEditEngine->aEditDoc.GetPos( aPaM.GetNode() );
+ pDragAndDropInfo->aDropSel.nStartPos = aPaM.GetIndex();
+ pDragAndDropInfo->aDropSel.nEndPara = pEditEngine->pImpEditEngine->aEditDoc.GetPos( aNewSel.Max().GetNode() );
+ pDragAndDropInfo->aDropSel.nEndPos = aNewSel.Max().GetIndex();
+ pDragAndDropInfo->bDroppedInMe = sal_True;
+ }
+ }
+ }
+
+ if ( bChanges )
+ {
+ rDTDE.Context->acceptDrop( rDTDE.DropAction );
+ }
+
+ if ( !pDragAndDropInfo->bStarterOfDD )
+ {
+ delete pDragAndDropInfo;
+ pDragAndDropInfo = NULL;
+ }
+
+ rDTDE.Context->dropComplete( bChanges );
+ }
+}
+
+void ImpEditView::dragEnter( const ::com::sun::star::datatransfer::dnd::DropTargetDragEnterEvent& rDTDEE ) throw (::com::sun::star::uno::RuntimeException)
+{
+ vos::OGuard aVclGuard( Application::GetSolarMutex() );
+
+ if ( !pDragAndDropInfo )
+ pDragAndDropInfo = new DragAndDropInfo( );
+
+ pDragAndDropInfo->bHasValidData = sal_False;
+
+ // Check for supported format...
+ // Only check for text, will also be there if bin or rtf
+ datatransfer::DataFlavor aTextFlavor;
+ SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aTextFlavor );
+ const ::com::sun::star::datatransfer::DataFlavor* pFlavors = rDTDEE.SupportedDataFlavors.getConstArray();
+ int nFlavors = rDTDEE.SupportedDataFlavors.getLength();
+ for ( int n = 0; n < nFlavors; n++ )
+ {
+ if( TransferableDataHelper::IsEqual( pFlavors[n], aTextFlavor ) )
+ {
+ pDragAndDropInfo->bHasValidData = sal_True;
+ break;
+ }
+ }
+
+ dragOver( rDTDEE );
+}
+
+void ImpEditView::dragExit( const ::com::sun::star::datatransfer::dnd::DropTargetEvent& ) throw (::com::sun::star::uno::RuntimeException)
+{
+ vos::OGuard aVclGuard( Application::GetSolarMutex() );
+
+ HideDDCursor();
+
+ if ( !pDragAndDropInfo->bStarterOfDD )
+ {
+ delete pDragAndDropInfo;
+ pDragAndDropInfo = NULL;
+ }
+}
+
+void ImpEditView::dragOver( const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent& rDTDE ) throw (::com::sun::star::uno::RuntimeException)
+{
+ vos::OGuard aVclGuard( Application::GetSolarMutex() );
+
+ Point aMousePos( rDTDE.LocationX, rDTDE.LocationY );
+ aMousePos = GetWindow()->PixelToLogic( aMousePos );
+
+ sal_Bool bAccept = sal_False;
+
+ if ( GetOutputArea().IsInside( aMousePos ) && !bReadOnly )
+ {
+// sal_Int8 nSupportedActions = bReadOnly ? datatransfer::dnd::DNDConstants::ACTION_COPY : datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE;
+
+ if ( pDragAndDropInfo->bHasValidData /* && ( nSupportedActions & rDTDE.DropAction ) MT: Default = 0x80 ?! */ )
+ {
+ bAccept = sal_True;
+
+ sal_Bool bAllowScroll = DoAutoScroll();
+ if ( bAllowScroll )
+ {
+ long nScrollX = 0;
+ long nScrollY = 0;
+ // pruefen, ob im sensitiven Bereich
+ if ( ( (aMousePos.X()-pDragAndDropInfo->nSensibleRange) < GetOutputArea().Left() ) && ( ( aMousePos.X() + pDragAndDropInfo->nSensibleRange ) > GetOutputArea().Left() ) )
+ nScrollX = GetOutputArea().GetWidth() / SCRLRANGE;
+ else if ( ( (aMousePos.X()+pDragAndDropInfo->nSensibleRange) > GetOutputArea().Right() ) && ( ( aMousePos.X() - pDragAndDropInfo->nSensibleRange ) < GetOutputArea().Right() ) )
+ nScrollX = -( GetOutputArea().GetWidth() / SCRLRANGE );
+
+ if ( ( (aMousePos.Y()-pDragAndDropInfo->nSensibleRange) < GetOutputArea().Top() ) && ( ( aMousePos.Y() + pDragAndDropInfo->nSensibleRange ) > GetOutputArea().Top() ) )
+ nScrollY = GetOutputArea().GetHeight() / SCRLRANGE;
+ else if ( ( (aMousePos.Y()+pDragAndDropInfo->nSensibleRange) > GetOutputArea().Bottom() ) && ( ( aMousePos.Y() - pDragAndDropInfo->nSensibleRange ) < GetOutputArea().Bottom() ) )
+ nScrollY = -( GetOutputArea().GetHeight() / SCRLRANGE );
+
+ if ( nScrollX || nScrollY )
+ {
+ HideDDCursor();
+ Scroll( nScrollX, nScrollY, RGCHK_PAPERSZ1 );
+ }
+ }
+
+ Point aDocPos( GetDocPos( aMousePos ) );
+ EditPaM aPaM = pEditEngine->pImpEditEngine->GetPaM( aDocPos );
+ pDragAndDropInfo->aDropDest = aPaM;
+ if ( pDragAndDropInfo->bOutlinerMode )
+ {
+ USHORT nPara = pEditEngine->pImpEditEngine->aEditDoc.GetPos( aPaM.GetNode() );
+ ParaPortion* pPPortion = pEditEngine->pImpEditEngine->GetParaPortions().SaveGetObject( nPara );
+ long nDestParaStartY = pEditEngine->pImpEditEngine->GetParaPortions().GetYOffset( pPPortion );
+ long nRel = aDocPos.Y() - nDestParaStartY;
+ if ( nRel < ( pPPortion->GetHeight() / 2 ) )
+ {
+ pDragAndDropInfo->nOutlinerDropDest = nPara;
+ }
+ else
+ {
+ pDragAndDropInfo->nOutlinerDropDest = nPara+1;
+ }
+
+ if( ( pDragAndDropInfo->nOutlinerDropDest >= pDragAndDropInfo->aBeginDragSel.nStartPara ) &&
+ ( pDragAndDropInfo->nOutlinerDropDest <= (pDragAndDropInfo->aBeginDragSel.nEndPara+1) ) )
+ {
+ bAccept = FALSE;
+ }
+ }
+ else if ( HasSelection() )
+ {
+ // es darf nicht in eine Selektion gedroppt werden
+ EPaM aP = pEditEngine->pImpEditEngine->CreateEPaM( aPaM );
+ ESelection aDestSel( aP.nPara, aP.nIndex, aP.nPara, aP.nIndex);
+ ESelection aCurSel = pEditEngine->pImpEditEngine->CreateESel( GetEditSelection() );
+ aCurSel.Adjust();
+ if ( !aDestSel.IsLess( aCurSel ) && !aDestSel.IsGreater( aCurSel ) )
+ {
+ bAccept = FALSE;
+ }
+ }
+ if ( bAccept )
+ {
+ Rectangle aEditCursor;
+ if ( pDragAndDropInfo->bOutlinerMode )
+ {
+ long nDDYPos;
+ if ( pDragAndDropInfo->nOutlinerDropDest < pEditEngine->pImpEditEngine->GetEditDoc().Count() )
+ {
+ ParaPortion* pPPortion = pEditEngine->pImpEditEngine->GetParaPortions().SaveGetObject( pDragAndDropInfo->nOutlinerDropDest );
+ nDDYPos = pEditEngine->pImpEditEngine->GetParaPortions().GetYOffset( pPPortion );
+ }
+ else
+ {
+ nDDYPos = pEditEngine->pImpEditEngine->GetTextHeight();
+ }
+ Point aStartPos( 0, nDDYPos );
+ aStartPos = GetWindowPos( aStartPos );
+ Point aEndPos( GetOutputArea().GetWidth(), nDDYPos );
+ aEndPos = GetWindowPos( aEndPos );
+ aEditCursor = GetWindow()->LogicToPixel( Rectangle( aStartPos, aEndPos ) );
+ if ( !pEditEngine->IsVertical() )
+ {
+ aEditCursor.Top()--;
+ aEditCursor.Bottom()++;
+ }
+ else
+ {
+ aEditCursor.Left()--;
+ aEditCursor.Right()++;
+ }
+ aEditCursor = GetWindow()->PixelToLogic( aEditCursor );
+ }
+ else
+ {
+ aEditCursor = pEditEngine->pImpEditEngine->PaMtoEditCursor( aPaM );
+ Point aTopLeft( GetWindowPos( aEditCursor.TopLeft() ) );
+ aEditCursor.SetPos( aTopLeft );
+ aEditCursor.Right() = aEditCursor.Left() + pDragAndDropInfo->nCursorWidth;
+ aEditCursor = GetWindow()->LogicToPixel( aEditCursor );
+ aEditCursor = GetWindow()->PixelToLogic( aEditCursor );
+ }
+
+ sal_Bool bCursorChanged = !pDragAndDropInfo->bVisCursor || ( pDragAndDropInfo->aCurCursor != aEditCursor );
+ if ( bCursorChanged )
+ {
+ HideDDCursor();
+ ShowDDCursor(aEditCursor );
+ }
+ pDragAndDropInfo->bDragAccepted = TRUE;
+ rDTDE.Context->acceptDrag( rDTDE.DropAction );
+ }
+ }
+ }
+
+ if ( !bAccept )
+ {
+ HideDDCursor();
+ pDragAndDropInfo->bDragAccepted = FALSE;
+ rDTDE.Context->rejectDrag();
+ }
+}
+
+void ImpEditView::AddDragAndDropListeners()
+{
+ Window* pWindow = GetWindow();
+ if ( !bActiveDragAndDropListener && pWindow && pWindow->GetDragGestureRecognizer().is() )
+ {
+ vcl::unohelper::DragAndDropWrapper* pDnDWrapper = new vcl::unohelper::DragAndDropWrapper( this );
+ mxDnDListener = pDnDWrapper;
+
+ uno::Reference< datatransfer::dnd::XDragGestureListener> xDGL( mxDnDListener, uno::UNO_QUERY );
+ pWindow->GetDragGestureRecognizer()->addDragGestureListener( xDGL );
+ uno::Reference< datatransfer::dnd::XDropTargetListener> xDTL( xDGL, uno::UNO_QUERY );
+ pWindow->GetDropTarget()->addDropTargetListener( xDTL );
+ pWindow->GetDropTarget()->setActive( sal_True );
+ pWindow->GetDropTarget()->setDefaultActions( datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE );
+
+ bActiveDragAndDropListener = TRUE;
+ }
+}
+
+void ImpEditView::RemoveDragAndDropListeners()
+{
+ if ( bActiveDragAndDropListener && GetWindow() && GetWindow()->GetDragGestureRecognizer().is() )
+ {
+ uno::Reference< datatransfer::dnd::XDragGestureListener> xDGL( mxDnDListener, uno::UNO_QUERY );
+ GetWindow()->GetDragGestureRecognizer()->removeDragGestureListener( xDGL );
+ uno::Reference< datatransfer::dnd::XDropTargetListener> xDTL( xDGL, uno::UNO_QUERY );
+ GetWindow()->GetDropTarget()->removeDropTargetListener( xDTL );
+
+ if ( mxDnDListener.is() )
+ {
+ uno::Reference< lang::XEventListener> xEL( mxDnDListener, uno::UNO_QUERY );
+ xEL->disposing( lang::EventObject() ); // #95154# Empty Source means it's the Client
+ mxDnDListener.clear();
+ }
+
+ bActiveDragAndDropListener = FALSE;
+ }
+}
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
new file mode 100644
index 0000000000..1dfd4690c0
--- /dev/null
+++ b/editeng/source/editeng/impedit.hxx
@@ -0,0 +1,1211 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: impedit.hxx,v $
+ * $Revision: 1.89.40.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _IMPEDIT_HXX
+#define _IMPEDIT_HXX
+
+#include <editdoc.hxx>
+#include <editsel.hxx>
+#include <editundo.hxx>
+#include <editobj2.hxx>
+#include <editstt2.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/svxacorr.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/gdimtf.hxx>
+#include <vcl/cursor.hxx>
+
+#include <vcl/dndhelp.hxx>
+#include <svl/ondemand.hxx>
+#include <com/sun/star/linguistic2/XSpellAlternatives.hpp>
+#include <com/sun/star/linguistic2/SpellFailure.hpp>
+#include <com/sun/star/linguistic2/XSpellChecker.hpp>
+#include <com/sun/star/linguistic2/XSpellChecker1.hpp>
+#include <com/sun/star/linguistic2/XHyphenator.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#include <com/sun/star/i18n/CharacterIteratorMode.hpp>
+#include <com/sun/star/i18n/WordType.hpp>
+#include <com/sun/star/i18n/XExtendedInputSequenceChecker.hpp>
+
+#include <i18npool/lang.h>
+#include <vos/ref.hxx>
+
+DBG_NAMEEX( EditView )
+DBG_NAMEEX( EditEngine )
+
+#define PIMPEE pImpEditView->pEditEngine->pImpEditEngine
+
+#define DEL_LEFT 1
+#define DEL_RIGHT 2
+#define TRAVEL_X_DONTKNOW 0xFFFFFFFF
+#define CURSOR_BIDILEVEL_DONTKNOW 0xFFFF
+#define MAXCHARSINPARA 0x3FFF-CHARPOSGROW // Max 16K, because WYSIWYG array
+
+#define ATTRSPECIAL_WHOLEWORD 1
+#define ATTRSPECIAL_EDGE 2
+
+#define GETCRSR_TXTONLY 0x0001
+#define GETCRSR_STARTOFLINE 0x0002
+#define GETCRSR_ENDOFLINE 0x0004
+#define GETCRSR_PREFERPORTIONSTART 0x0008
+
+#define LINE_SEP 0x0A
+
+typedef EENotify* EENotifyPtr;
+SV_DECL_PTRARR_DEL( NotifyList, EENotifyPtr, 1, 1 ) // IMPL is in outliner.cxx, move to EE later and share declaration, or use BlockNotifications from EE directly
+
+
+class EditView;
+class EditEngine;
+class SvxFontTable;
+class SvxColorList;
+
+class SvxSearchItem;
+class SvxLRSpaceItem;
+class TextRanger;
+class SvKeyValueIterator;
+class SvxForbiddenCharactersTable;
+class SvtCTLOptions;
+#include <editeng/SpellPortions.hxx>
+
+#include <editeng/eedata.hxx>
+
+class SvUShorts;
+class SvxNumberFormat;
+
+
+namespace com {
+namespace sun {
+namespace star {
+namespace datatransfer {
+namespace clipboard {
+ class XClipboard;
+}}}}}
+
+namespace svtools {
+ class ColorConfig;
+}
+
+struct DragAndDropInfo
+{
+ Rectangle aCurCursor;
+ Rectangle aCurSavedCursor;
+ sal_uInt16 nSensibleRange;
+ sal_uInt16 nCursorWidth;
+ ESelection aBeginDragSel;
+ EditPaM aDropDest;
+ USHORT nOutlinerDropDest;
+ ESelection aDropSel;
+ VirtualDevice* pBackground;
+ const SvxFieldItem* pField;
+ sal_Bool bVisCursor : 1;
+ sal_Bool bDroppedInMe : 1;
+ sal_Bool bStarterOfDD : 1;
+ sal_Bool bHasValidData : 1;
+ sal_Bool bUndoAction : 1;
+ sal_Bool bOutlinerMode : 1;
+ sal_Bool bDragAccepted : 1;
+
+ DragAndDropInfo()
+ {
+ pBackground = NULL; bVisCursor = sal_False; bDroppedInMe = sal_False; bStarterOfDD = sal_False;
+ bHasValidData = sal_False; bUndoAction = sal_False; bOutlinerMode = sal_False;
+ nSensibleRange = 0; nCursorWidth = 0; pField = 0; nOutlinerDropDest = 0; bDragAccepted = sal_False;
+ }
+};
+
+struct ImplIMEInfos
+{
+ String aOldTextAfterStartPos;
+ sal_uInt16* pAttribs;
+ EditPaM aPos;
+ sal_uInt16 nLen;
+ sal_Bool bCursor;
+ sal_Bool bWasCursorOverwrite;
+
+ ImplIMEInfos( const EditPaM& rPos, const String& rOldTextAfterStartPos );
+ ~ImplIMEInfos();
+
+ void CopyAttribs( const sal_uInt16* pA, sal_uInt16 nL );
+ void DestroyAttribs();
+};
+
+// #i18881# to be able to identify the postions of changed words
+// the positions of each portion need to be saved
+typedef std::vector<EditSelection> SpellContentSelections;
+
+struct SpellInfo
+{
+ EESpellState eState;
+ EPaM aSpellStart;
+ EPaM aSpellTo;
+ sal_Bool bSpellToEnd;
+ sal_Bool bMultipleDoc;
+ ::svx::SpellPortions aLastSpellPortions;
+ SpellContentSelections aLastSpellContentSelections;
+ SpellInfo()
+ { bSpellToEnd = sal_True; eState = EE_SPELL_OK; bMultipleDoc = sal_False; }
+};
+
+// used for text conversion
+struct ConvInfo
+{
+ EPaM aConvStart;
+ EPaM aConvTo;
+ EPaM aConvContinue; // position to start search for next text portion (word) with
+ sal_Bool bConvToEnd;
+ sal_Bool bMultipleDoc;
+
+ ConvInfo() { bConvToEnd = sal_True; bMultipleDoc = sal_False; }
+};
+
+struct FormatterFontMetric
+{
+ sal_uInt16 nMaxAscent;
+ sal_uInt16 nMaxDescent;
+
+ FormatterFontMetric() { nMaxAscent = 0; nMaxDescent = 0; /* nMinLeading = 0xFFFF; */ }
+ sal_uInt16 GetHeight() const { return nMaxAscent+nMaxDescent; }
+};
+
+class IdleFormattter : public Timer
+{
+private:
+ EditView* pView;
+ int nRestarts;
+
+public:
+ IdleFormattter();
+ ~IdleFormattter();
+
+ void DoIdleFormat( EditView* pV );
+ void ForceTimeout();
+ void ResetRestarts() { nRestarts = 0; }
+ EditView* GetView() { return pView; }
+};
+
+ // ----------------------------------------------------------------------
+// class ImpEditView
+// ----------------------------------------------------------------------
+class ImpEditView : public vcl::unohelper::DragAndDropClient
+{
+ friend class EditView;
+ friend class EditEngine;
+ friend class ImpEditEngine;
+ using vcl::unohelper::DragAndDropClient::dragEnter;
+ using vcl::unohelper::DragAndDropClient::dragExit;
+ using vcl::unohelper::DragAndDropClient::dragOver;
+
+private:
+ EditView* pEditView;
+ Cursor* pCursor;
+ Color* pBackgroundColor;
+ EditEngine* pEditEngine;
+ Window* pOutWin;
+ Pointer* pPointer;
+ DragAndDropInfo* pDragAndDropInfo;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragSourceListener > mxDnDListener;
+
+
+ long nInvMore;
+ ULONG nControl;
+ sal_uInt32 nTravelXPos;
+ sal_uInt16 nExtraCursorFlags;
+ sal_uInt16 nCursorBidiLevel;
+ sal_uInt16 nScrollDiffX;
+ sal_Bool bReadOnly;
+ sal_Bool bClickedInSelection;
+ sal_Bool bActiveDragAndDropListener;
+
+ Point aAnchorPoint;
+ Rectangle aOutArea;
+ Point aVisDocStartPos;
+ EESelectionMode eSelectionMode;
+ EditSelection aEditSelection;
+ EVAnchorMode eAnchorMode;
+
+protected:
+
+ // DragAndDropClient
+ void dragGestureRecognized( const ::com::sun::star::datatransfer::dnd::DragGestureEvent& dge ) throw (::com::sun::star::uno::RuntimeException);
+ void dragDropEnd( const ::com::sun::star::datatransfer::dnd::DragSourceDropEvent& dsde ) throw (::com::sun::star::uno::RuntimeException);
+ void drop( const ::com::sun::star::datatransfer::dnd::DropTargetDropEvent& dtde ) throw (::com::sun::star::uno::RuntimeException);
+ void dragEnter( const ::com::sun::star::datatransfer::dnd::DropTargetDragEnterEvent& dtdee ) throw (::com::sun::star::uno::RuntimeException);
+ void dragExit( const ::com::sun::star::datatransfer::dnd::DropTargetEvent& dte ) throw (::com::sun::star::uno::RuntimeException);
+ void dragOver( const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent& dtde ) throw (::com::sun::star::uno::RuntimeException);
+
+ void ShowDDCursor( const Rectangle& rRect );
+ void HideDDCursor();
+
+ void ImplDrawHighlightRect( Window* pOutWin, const Point& rDocPosTopLeft, const Point& rDocPosBottomRight, PolyPolygon* pPolyPoly );
+
+public:
+ ImpEditView( EditView* pView, EditEngine* pEng, Window* pWindow );
+ ~ImpEditView();
+
+ EditView* GetEditViewPtr() { return pEditView; }
+
+ sal_uInt16 GetScrollDiffX() const { return nScrollDiffX; }
+ void SetScrollDiffX( sal_uInt16 n ) { nScrollDiffX = n; }
+
+ sal_uInt16 GetCursorBidiLevel() const { return nCursorBidiLevel; }
+ void SetCursorBidiLevel( sal_uInt16 n ) { nCursorBidiLevel = n; }
+
+ Point GetDocPos( const Point& rWindowPos ) const;
+ Point GetWindowPos( const Point& rDocPos ) const;
+ Rectangle GetWindowPos( const Rectangle& rDocPos ) const;
+
+ void SetOutputArea( const Rectangle& rRec );
+ void ResetOutputArea( const Rectangle& rRec );
+ const Rectangle& GetOutputArea() const { return aOutArea; }
+
+ BOOL IsVertical() const;
+
+ BOOL PostKeyEvent( const KeyEvent& rKeyEvent );
+
+ BOOL MouseButtonUp( const MouseEvent& rMouseEvent );
+ BOOL MouseButtonDown( const MouseEvent& rMouseEvent );
+ BOOL MouseMove( const MouseEvent& rMouseEvent );
+ void Command( const CommandEvent& rCEvt );
+
+ void CutCopy( ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard >& rxClipboard, sal_Bool bCut );
+ void Paste( ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard >& rxClipboard, sal_Bool bUseSpecial = sal_False );
+
+ void SetVisDocStartPos( const Point& rPos ) { aVisDocStartPos = rPos; }
+ const Point& GetVisDocStartPos() const { return aVisDocStartPos; }
+
+ long GetVisDocLeft() const { return aVisDocStartPos.X(); }
+ long GetVisDocTop() const { return aVisDocStartPos.Y(); }
+ long GetVisDocRight() const { return aVisDocStartPos.X() + ( !IsVertical() ? aOutArea.GetWidth() : aOutArea.GetHeight() ); }
+ long GetVisDocBottom() const { return aVisDocStartPos.Y() + ( !IsVertical() ? aOutArea.GetHeight() : aOutArea.GetWidth() ); }
+ Rectangle GetVisDocArea() const;
+
+ EditSelection& GetEditSelection() { return aEditSelection; }
+ void SetEditSelection( const EditSelection& rEditSelection );
+ sal_Bool HasSelection() const { return aEditSelection.HasRange(); }
+
+ void DrawSelection() { DrawSelection( aEditSelection ); }
+ void DrawSelection( EditSelection, Region* pRegion = NULL );
+ Region* CalcSelectedRegion();
+
+ Window* GetWindow() const { return pOutWin; }
+
+ EESelectionMode GetSelectionMode() const { return eSelectionMode; }
+ void SetSelectionMode( EESelectionMode eMode );
+
+ inline void SetPointer( const Pointer& rPointer );
+ inline const Pointer& GetPointer();
+
+ inline void SetCursor( const Cursor& rCursor );
+ inline Cursor* GetCursor();
+
+ void AddDragAndDropListeners();
+ void RemoveDragAndDropListeners();
+
+ BOOL IsBulletArea( const Point& rPos, sal_uInt16* pPara );
+
+// Fuer die SelectionEngine...
+ void CreateAnchor();
+ void DeselectAll();
+ sal_Bool SetCursorAtPoint( const Point& rPointPixel );
+ sal_Bool IsSelectionAtPoint( const Point& rPosPixel );
+ sal_Bool IsInSelection( const EditPaM& rPaM );
+
+
+ void SetAnchorMode( EVAnchorMode eMode );
+ EVAnchorMode GetAnchorMode() const { return eAnchorMode; }
+ void CalcAnchorPoint();
+ void RecalcOutputArea();
+
+ void ShowCursor( sal_Bool bGotoCursor, sal_Bool bForceVisCursor, BOOL test );
+ void ShowCursor( sal_Bool bGotoCursor, sal_Bool bForceVisCursor, USHORT nShowCursorFlags = 0 );
+ Pair Scroll( long ndX, long ndY, BYTE nRangeCheck = RGCHK_NEG );
+
+ void SetInsertMode( sal_Bool bInsert );
+ sal_Bool IsInsertMode() const { return ( ( nControl & EV_CNTRL_OVERWRITE ) == 0 ); }
+
+ void EnablePaste( sal_Bool bEnable ) { SetFlags( nControl, EV_CNTRL_ENABLEPASTE, bEnable ); }
+ sal_Bool IsPasteEnabled() const { return ( ( nControl & EV_CNTRL_ENABLEPASTE ) != 0 ); }
+
+ sal_Bool DoSingleLinePaste() const { return ( ( nControl & EV_CNTRL_SINGLELINEPASTE ) != 0 ); }
+ sal_Bool DoAutoScroll() const { return ( ( nControl & EV_CNTRL_AUTOSCROLL ) != 0 ); }
+ sal_Bool DoBigScroll() const { return ( ( nControl & EV_CNTRL_BIGSCROLL ) != 0 ); }
+ sal_Bool DoAutoSize() const { return ( ( nControl & EV_CNTRL_AUTOSIZE ) != 0 ); }
+ sal_Bool DoAutoWidth() const { return ( ( nControl & EV_CNTRL_AUTOSIZEX) != 0 ); }
+ sal_Bool DoAutoHeight() const { return ( ( nControl & EV_CNTRL_AUTOSIZEY) != 0 ); }
+ sal_Bool DoInvalidateMore() const { return ( ( nControl & EV_CNTRL_INVONEMORE ) != 0 ); }
+
+ void SetBackgroundColor( const Color& rColor );
+ const Color& GetBackgroundColor() const {
+ return ( pBackgroundColor ? *pBackgroundColor : pOutWin->GetBackground().GetColor() ); }
+
+ sal_Bool IsWrongSpelledWord( const EditPaM& rPaM, sal_Bool bMarkIfWrong );
+ String SpellIgnoreOrAddWord( sal_Bool bAdd );
+
+ const SvxFieldItem* GetField( const Point& rPos, sal_uInt16* pPara, sal_uInt16* pPos ) const;
+ void DeleteSelected();
+
+ // Ggf. mehr als OutputArea invalidieren, fuer den DrawingEngine-Textrahmen...
+ void SetInvalidateMore( sal_uInt16 nPixel ) { nInvMore = nPixel; }
+ sal_uInt16 GetInvalidateMore() const { return (sal_uInt16)nInvMore; }
+};
+
+// ----------------------------------------------------------------------
+// ImpEditEngine
+// ----------------------------------------------------------------------
+
+typedef EditView* EditViewPtr;
+SV_DECL_PTRARR( EditViews, EditViewPtr, 0, 1 )
+
+class ImpEditEngine : public SfxListener
+{
+ // Die Undos muessen direkt manipulieren ( private-Methoden ),
+ // damit keine neues Undos eingefuegt werden!
+ friend class EditUndoInsertChars;
+ friend class EditUndoRemoveChars;
+ friend class EditUndoDelContent;
+ friend class EditUndoConnectParas;
+ friend class EditUndoSplitPara;
+ friend class EditUndoInsertFeature;
+ friend class EditUndoMoveParagraphs;
+
+ friend class EditView;
+ friend class ImpEditView;
+ friend class EditEngine; // Fuer Zugriff auf Imp-Methoden
+ friend class EditRTFParser; // Fuer Zugriff auf Imp-Methoden
+ friend class EditHTMLParser; // Fuer Zugriff auf Imp-Methoden
+ friend class EdtAutoCorrDoc; // Fuer Zugriff auf Imp-Methoden
+ friend class EditDbg; // DebugRoutinen
+
+private:
+
+ // ================================================================
+ // Daten...
+ // ================================================================
+
+ // Dokument-Spezifische Daten...
+ ParaPortionList aParaPortionList; // Formatierung
+ Size aPaperSize; // Layout
+ Size aMinAutoPaperSize; // Layout ?
+ Size aMaxAutoPaperSize; // Layout ?
+ EditDoc aEditDoc; // Dokumenteninhalt
+
+ // Engine-Spezifische Daten....
+ EditEngine* pEditEngine;
+ EditViews aEditViews;
+ EditView* pActiveView;
+ TextRanger* pTextRanger;
+
+ SfxStyleSheetPool* pStylePool;
+ SfxItemPool* pTextObjectPool;
+
+ VirtualDevice* pVirtDev;
+ OutputDevice* pRefDev;
+
+ svtools::ColorConfig* pColorConfig;
+ mutable SvtCTLOptions* pCTLOptions;
+
+ SfxItemSet* pEmptyItemSet;
+ EditUndoManager* pUndoManager;
+ ESelection* pUndoMarkSelection;
+
+ ImplIMEInfos* mpIMEInfos;
+
+ NotifyList aNotifyCache;
+
+ XubString aWordDelimiters;
+ XubString aGroupChars;
+
+ EditSelFunctionSet aSelFuncSet;
+ EditSelectionEngine aSelEngine;
+
+ Color maBackgroundColor;
+
+ sal_uInt32 nBlockNotifications;
+ sal_uInt16 nStretchX;
+ sal_uInt16 nStretchY;
+
+ USHORT nAsianCompressionMode;
+ BOOL bKernAsianPunctuation;
+ BOOL bAddExtLeading;
+
+ EEHorizontalTextDirection eDefaultHorizontalTextDirection;
+
+ sal_uInt16 nBigTextObjectStart;
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::linguistic2::XSpellChecker1 > xSpeller;
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::linguistic2::XHyphenator > xHyphenator;
+ SpellInfo* pSpellInfo;
+ mutable ::com::sun::star::uno::Reference < ::com::sun::star::i18n::XBreakIterator > xBI;
+ mutable ::com::sun::star::uno::Reference < ::com::sun::star::i18n::XExtendedInputSequenceChecker > xISC;
+
+ ConvInfo * pConvInfo;
+
+ XubString aAutoCompleteText;
+
+ InternalEditStatus aStatus;
+
+ LanguageType eDefLanguage;
+
+ OnDemandLocaleDataWrapper xLocaleDataWrapper;
+ OnDemandTransliterationWrapper xTransliterationWrapper;
+
+ sal_Bool bIsFormatting;
+ sal_Bool bFormatted;
+ sal_Bool bInSelection;
+ sal_Bool bIsInUndo;
+ sal_Bool bUpdate;
+ sal_Bool bUndoEnabled;
+ sal_Bool bOwnerOfRefDev;
+ sal_Bool bDowning;
+ sal_Bool bUseAutoColor;
+ sal_Bool bForceAutoColor;
+ sal_Bool bCallParaInsertedOrDeleted;
+ sal_Bool bImpConvertFirstCall; // specifies if ImpConvert is called the very first time after Convert was called
+ sal_Bool bFirstWordCapitalization; // specifies if auto-correction should capitalize the first word or not
+
+ // Fuer Formatierung / Update....
+ DeletedNodesList aDeletedNodes;
+ Rectangle aInvalidRec;
+ sal_uInt32 nCurTextHeight;
+ sal_uInt16 nOnePixelInRef;
+
+ IdleFormattter aIdleFormatter;
+
+ Timer aOnlineSpellTimer;
+
+ // Wenn an einer Stelle erkannt wird, dass der StatusHdl gerufen werden
+ // muss, dies aber nicht sofort geschehen darf (kritischer Abschnitt):
+ Timer aStatusTimer;
+ Link aStatusHdlLink;
+ Link aNotifyHdl;
+ Link aImportHdl;
+ Link aBeginMovingParagraphsHdl;
+ Link aEndMovingParagraphsHdl;
+ Link aBeginPasteOrDropHdl;
+ Link aEndPasteOrDropHdl;
+ Link aModifyHdl;
+ Link maBeginDropHdl;
+ Link maEndDropHdl;
+
+ vos::ORef<SvxForbiddenCharactersTable> xForbiddenCharsTable;
+
+
+ // ================================================================
+ // Methoden...
+ // ================================================================
+
+ void CursorMoved( ContentNode* pPrevNode );
+ void ParaAttribsChanged( ContentNode* pNode );
+ void TextModified();
+ void CalcHeight( ParaPortion* pPortion );
+
+ // ggf. lieber inline, aber so einiges...
+ void InsertUndo( EditUndo* pUndo, sal_Bool bTryMerge = sal_False );
+ void ResetUndoManager();
+ sal_Bool HasUndoManager() const { return pUndoManager ? sal_True : sal_False; }
+
+ EditUndoSetAttribs* CreateAttribUndo( EditSelection aSel, const SfxItemSet& rSet );
+
+ EditPaM GetPaM( Point aDocPos, sal_Bool bSmart = sal_True );
+ EditPaM GetPaM( ParaPortion* pPortion, Point aPos, sal_Bool bSmart = sal_True );
+ long GetXPos( ParaPortion* pParaPortion, EditLine* pLine, USHORT nIndex, BOOL bPreferPortionStart = FALSE );
+ long GetPortionXOffset( ParaPortion* pParaPortion, EditLine* pLine, USHORT nTextPortion );
+ USHORT GetChar( ParaPortion* pParaPortion, EditLine* pLine, long nX, BOOL bSmart = TRUE );
+ Range GetInvalidYOffsets( ParaPortion* pPortion );
+ Range GetLineXPosStartEnd( ParaPortion* pParaPortion, EditLine* pLine );
+
+ void SetParaAttrib( BYTE nFunc, EditSelection aSel, sal_uInt16 nValue );
+ sal_uInt16 GetParaAttrib( BYTE nFunc, EditSelection aSel );
+ void SetCharAttrib( EditSelection aSel, const SfxPoolItem& rItem );
+ void ParaAttribsToCharAttribs( ContentNode* pNode );
+ void GetCharAttribs( sal_uInt16 nPara, EECharAttribArray& rLst ) const;
+
+ EditTextObject* CreateBinTextObject( EditSelection aSelection, SfxItemPool*, sal_Bool bAllowBigObjects = sal_False, sal_uInt16 nBigObjStart = 0 ) const;
+ void StoreBinTextObject( SvStream& rOStream, BinTextObject& rTextObject );
+ EditSelection InsertBinTextObject( BinTextObject&, EditPaM aPaM );
+ EditSelection InsertText( ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& rxDataObj, const String& rBaseURL, const EditPaM& rPaM, BOOL bUseSpecial );
+
+ EditPaM Clear();
+ EditPaM RemoveText();
+ EditPaM RemoveText( EditSelection aEditSelection );
+ sal_Bool CreateLines( USHORT nPara, sal_uInt32 nStartPosY );
+ void CreateAndInsertEmptyLine( ParaPortion* pParaPortion, sal_uInt32 nStartPosY );
+ sal_Bool FinishCreateLines( ParaPortion* pParaPortion );
+ void CalcCharPositions( ParaPortion* pParaPortion );
+ void CreateTextPortions( ParaPortion* pParaPortion, sal_uInt16& rStartPos /*, sal_Bool bCreateBlockPortions */ );
+ void RecalcTextPortion( ParaPortion* pParaPortion, sal_uInt16 nStartPos, short nNewChars );
+ sal_uInt16 SplitTextPortion( ParaPortion* pParaPortion, sal_uInt16 nPos, EditLine* pCurLine = 0 );
+ void SeekCursor( ContentNode* pNode, sal_uInt16 nPos, SvxFont& rFont, OutputDevice* pOut = NULL, sal_uInt16 nIgnoreWhich = 0 );
+ void RecalcFormatterFontMetrics( FormatterFontMetric& rCurMetrics, SvxFont& rFont );
+ void CheckAutoPageSize();
+
+ void ImpBreakLine( ParaPortion* pParaPortion, EditLine* pLine, TextPortion* pPortion, sal_uInt16 nPortionStart, long nRemainingWidth, sal_Bool bCanHyphenate );
+ void ImpAdjustBlocks( ParaPortion* pParaPortion, EditLine* pLine, long nRemainingSpace );
+ EditPaM ImpConnectParagraphs( ContentNode* pLeft, ContentNode* pRight, sal_Bool bBackward = sal_False );
+ EditPaM ImpDeleteSelection( EditSelection aEditSelection);
+ EditPaM ImpInsertParaBreak( const EditPaM& rPaM, sal_Bool bKeepEndingAttribs = sal_True );
+ EditPaM ImpInsertParaBreak( const EditSelection& rEditSelection, sal_Bool bKeepEndingAttribs = sal_True );
+ EditPaM ImpInsertText( EditSelection aCurEditSelection, const String& rStr );
+ EditPaM ImpInsertFeature( EditSelection aEditSelection, const SfxPoolItem& rItem );
+ void ImpRemoveChars( const EditPaM& rPaM, sal_uInt16 nChars, EditUndoRemoveChars* pCurUndo = 0 );
+ void ImpRemoveParagraph( sal_uInt16 nPara );
+ EditSelection ImpMoveParagraphs( Range aParagraphs, sal_uInt16 nNewPos );
+
+ EditPaM ImpFastInsertText( EditPaM aPaM, const String& rStr );
+ EditPaM ImpFastInsertParagraph( sal_uInt16 nPara );
+
+ sal_Bool ImpCheckRefMapMode();
+
+ BOOL ImplHasText() const;
+
+ void ImpFindKashidas( ContentNode* pNode, USHORT nStart, USHORT nEnd, SvUShorts& rArray );
+
+ void InsertContent( ContentNode* pNode, sal_uInt16 nPos );
+ EditPaM SplitContent( sal_uInt16 nNode, sal_uInt16 nSepPos );
+ EditPaM ConnectContents( sal_uInt16 nLeftNode, sal_Bool bBackward );
+
+ void ShowParagraph( sal_uInt16 nParagraph, sal_Bool bShow );
+ sal_Bool IsParagraphVisible( sal_uInt16 nParagraph );
+
+ EditPaM PageUp( const EditPaM& rPaM, EditView* pView);
+ EditPaM PageDown( const EditPaM& rPaM, EditView* pView);
+ EditPaM CursorUp( const EditPaM& rPaM, EditView* pEditView );
+ EditPaM CursorDown( const EditPaM& rPaM, EditView* pEditView );
+ EditPaM CursorLeft( const EditPaM& rPaM, USHORT nCharacterIteratorMode = ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL );
+ EditPaM CursorRight( const EditPaM& rPaM, USHORT nCharacterIteratorMode = ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL );
+ EditPaM CursorStartOfLine( const EditPaM& rPaM );
+ EditPaM CursorEndOfLine( const EditPaM& rPaM );
+ EditPaM CursorStartOfParagraph( const EditPaM& rPaM );
+ EditPaM CursorEndOfParagraph( const EditPaM& rPaM );
+ EditPaM CursorStartOfDoc();
+ EditPaM CursorEndOfDoc();
+ EditPaM WordLeft( const EditPaM& rPaM, sal_Int16 nWordType = ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES );
+ EditPaM WordRight( const EditPaM& rPaM, sal_Int16 nWordType = ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES );
+ EditPaM StartOfWord( const EditPaM& rPaM, sal_Int16 nWordType = ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES );
+ EditPaM EndOfWord( const EditPaM& rPaM, sal_Int16 nWordType = ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES );
+ EditSelection SelectWord( const EditSelection& rCurSelection, sal_Int16 nWordType = ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES, BOOL bAcceptStartOfWord = TRUE );
+ EditSelection SelectSentence( const EditSelection& rCurSel );
+ EditPaM CursorVisualLeftRight( EditView* pEditView, const EditPaM& rPaM, USHORT nCharacterIteratorMode, BOOL bToLeft );
+ EditPaM CursorVisualStartEnd( EditView* pEditView, const EditPaM& rPaM, BOOL bStart );
+
+
+ void InitScriptTypes( USHORT nPara );
+ USHORT GetScriptType( const EditPaM& rPaM, USHORT* pEndPos = NULL ) const;
+ USHORT GetScriptType( const EditSelection& rSel ) const;
+ BOOL IsScriptChange( const EditPaM& rPaM ) const;
+ BOOL HasScriptType( USHORT nPara, USHORT nType ) const;
+
+ BOOL ImplCalcAsianCompression( ContentNode* pNode, TextPortion* pTextPortion, USHORT nStartPos, sal_Int32* pDXArray, USHORT n100thPercentFromMax, BOOL bManipulateDXArray );
+ void ImplExpandCompressedPortions( EditLine* pLine, ParaPortion* pParaPortion, long nRemainingWidth );
+
+ void ImplInitLayoutMode( OutputDevice* pOutDev, USHORT nPara, USHORT nIndex );
+ void ImplInitDigitMode( OutputDevice* pOutDev, String* pString, xub_StrLen nStt, xub_StrLen nLen, LanguageType eLang );
+
+ EditPaM ReadText( SvStream& rInput, EditSelection aSel );
+ EditPaM ReadRTF( SvStream& rInput, EditSelection aSel );
+ EditPaM ReadXML( SvStream& rInput, EditSelection aSel );
+ EditPaM ReadHTML( SvStream& rInput, const String& rBaseURL, EditSelection aSel, SvKeyValueIterator* pHTTPHeaderAttrs );
+ EditPaM ReadBin( SvStream& rInput, EditSelection aSel );
+ sal_uInt32 WriteText( SvStream& rOutput, EditSelection aSel );
+ sal_uInt32 WriteRTF( SvStream& rOutput, EditSelection aSel );
+ sal_uInt32 WriteXML( SvStream& rOutput, EditSelection aSel );
+ sal_uInt32 WriteHTML( SvStream& rOutput, EditSelection aSel );
+ sal_uInt32 WriteBin( SvStream& rOutput, EditSelection aSel, BOOL bStoreUnicode = FALSE ) const;
+
+ void WriteItemAsRTF( const SfxPoolItem& rItem, SvStream& rOutput, sal_uInt16 nPara, sal_uInt16 nPos,
+ SvxFontTable& rFontTable, SvxColorList& rColorList );
+ sal_Bool WriteItemListAsRTF( ItemList& rLst, SvStream& rOutput, sal_uInt16 nPara, sal_uInt16 nPos,
+ SvxFontTable& rFontTable, SvxColorList& rColorList );
+ long LogicToTwips( long n );
+
+ inline short GetXValue( short nXValue ) const;
+ inline sal_uInt16 GetXValue( sal_uInt16 nXValue ) const;
+ inline long GetXValue( long nXValue ) const;
+
+ inline short GetYValue( short nYValue ) const;
+ inline sal_uInt16 GetYValue( sal_uInt16 nYValue ) const;
+
+ ContentNode* GetPrevVisNode( ContentNode* pCurNode );
+ ContentNode* GetNextVisNode( ContentNode* pCurNode );
+
+ ParaPortion* GetPrevVisPortion( ParaPortion* pCurPortion );
+ ParaPortion* GetNextVisPortion( ParaPortion* pCurPortion );
+
+ void SetBackgroundColor( const Color& rColor ) { maBackgroundColor = rColor; }
+ Color GetBackgroundColor() const { return maBackgroundColor; }
+
+ Color GetAutoColor() const;
+ void EnableAutoColor( BOOL b ) { bUseAutoColor = b; }
+ BOOL IsAutoColorEnabled() const { return bUseAutoColor; }
+ void ForceAutoColor( BOOL b ) { bForceAutoColor = b; }
+ BOOL IsForceAutoColor() const { return bForceAutoColor; }
+
+ inline VirtualDevice* GetVirtualDevice( const MapMode& rMapMode, ULONG nDrawMode );
+ inline void EraseVirtualDevice();
+
+ DECL_LINK( StatusTimerHdl, Timer * );
+ DECL_LINK( IdleFormatHdl, Timer * );
+ DECL_LINK( OnlineSpellHdl, Timer * );
+ DECL_LINK( DocModified, void* );
+
+ void CheckIdleFormatter();
+
+ inline ParaPortion* FindParaPortion( ContentNode* pNode ) const;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > CreateTransferable( const EditSelection& rSelection ) const;
+
+ void SetValidPaperSize( const Size& rSz );
+
+ ::com::sun::star::uno::Reference < ::com::sun::star::i18n::XBreakIterator > ImplGetBreakIterator() const;
+ ::com::sun::star::uno::Reference < ::com::sun::star::i18n::XExtendedInputSequenceChecker > ImplGetInputSequenceChecker() const;
+
+ /** Decorate metafile output with verbose text comments
+
+ This method is used to wrap SvxFont::QuickDrawText, to
+ determine character-by-character wise, which logical text
+ units like characters, words and sentences are contained in
+ the output string at hand. This is necessary for slideshow
+ text effects.
+ */
+ void ImplFillTextMarkingVector(const ::com::sun::star::lang::Locale& rLocale, EEngineData::TextMarkingVector& rTextMarkingVector, const String& rTxt, const USHORT nIdx, const USHORT nLen) const;
+
+protected:
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+public:
+ ImpEditEngine( EditEngine* pEditEngine, SfxItemPool* pPool );
+ ~ImpEditEngine();
+
+ void InitDoc( BOOL bKeepParaAttribs );
+ EditDoc& GetEditDoc() { return aEditDoc; }
+ const EditDoc& GetEditDoc() const { return aEditDoc; }
+
+ inline EditUndoManager& GetUndoManager();
+
+ void SetUpdateMode( sal_Bool bUp, EditView* pCurView = 0, sal_Bool bForceUpdate = sal_False );
+ sal_Bool GetUpdateMode() const { return bUpdate; }
+
+ const ParaPortionList& GetParaPortions() const { return aParaPortionList; }
+ ParaPortionList& GetParaPortions() { return aParaPortionList; }
+ EditViews& GetEditViews() { return aEditViews; }
+
+ const Size& GetPaperSize() const { return aPaperSize; }
+ void SetPaperSize( const Size& rSz ) { aPaperSize = rSz; }
+
+ void SetVertical( BOOL bVertical );
+ BOOL IsVertical() const { return GetEditDoc().IsVertical(); }
+
+ void SetFixedCellHeight( BOOL bUseFixedCellHeight );
+ BOOL IsFixedCellHeight() const { return GetEditDoc().IsFixedCellHeight(); }
+
+ void SetDefaultHorizontalTextDirection( EEHorizontalTextDirection eHTextDir ) { eDefaultHorizontalTextDirection = eHTextDir; }
+ EEHorizontalTextDirection GetDefaultHorizontalTextDirection() const { return eDefaultHorizontalTextDirection; }
+
+
+ void InitWritingDirections( USHORT nPara );
+ BOOL IsRightToLeft( USHORT nPara ) const;
+ BYTE GetRightToLeft( USHORT nPara, USHORT nChar, USHORT* pStart = NULL, USHORT* pEnd = NULL );
+ BOOL HasDifferentRTLLevels( const ContentNode* pNode );
+
+ void SetTextRanger( TextRanger* pRanger );
+ TextRanger* GetTextRanger() const { return pTextRanger; }
+
+ const Size& GetMinAutoPaperSize() const { return aMinAutoPaperSize; }
+ void SetMinAutoPaperSize( const Size& rSz ) { aMinAutoPaperSize = rSz; }
+
+ const Size& GetMaxAutoPaperSize() const { return aMaxAutoPaperSize; }
+ void SetMaxAutoPaperSize( const Size& rSz ) { aMaxAutoPaperSize = rSz; }
+
+ void FormatDoc();
+ void FormatFullDoc();
+ void UpdateViews( EditView* pCurView = 0 );
+ void Paint( ImpEditView* pView, const Rectangle& rRect, sal_Bool bUseVirtDev = sal_False );
+ void Paint( OutputDevice* pOutDev, Rectangle aClipRec, Point aStartPos, sal_Bool bStripOnly = sal_False, short nOrientation = 0 );
+
+ sal_Bool MouseButtonUp( const MouseEvent& rMouseEvent, EditView* pView );
+ sal_Bool MouseButtonDown( const MouseEvent& rMouseEvent, EditView* pView );
+ sal_Bool MouseMove( const MouseEvent& rMouseEvent, EditView* pView );
+ void Command( const CommandEvent& rCEvt, EditView* pView );
+
+ EditSelectionEngine& GetSelEngine() { return aSelEngine; }
+ XubString GetSelected( const EditSelection& rSel, const LineEnd eParaSep = LINEEND_LF ) const;
+
+ const SfxItemSet& GetEmptyItemSet();
+
+ void UpdateSelections();
+
+ void EnableUndo( sal_Bool bEnable );
+ sal_Bool IsUndoEnabled() { return bUndoEnabled; }
+ void SetUndoMode( sal_Bool b ) { bIsInUndo = b; }
+ sal_Bool IsInUndo() { return bIsInUndo; }
+
+ void SetCallParaInsertedOrDeleted( sal_Bool b ) { bCallParaInsertedOrDeleted = b; }
+ sal_Bool IsCallParaInsertedOrDeleted() const { return bCallParaInsertedOrDeleted; }
+
+ sal_Bool IsFormatted() const { return bFormatted; }
+ sal_Bool IsFormatting() const { return bIsFormatting; }
+
+ void SetText( const String& rText );
+ EditPaM DeleteSelected( EditSelection aEditSelection);
+ EditPaM InsertText( const EditSelection& rCurEditSelection, sal_Unicode c, sal_Bool bOverwrite, sal_Bool bIsUserInput = sal_False );
+ EditPaM InsertText( EditSelection aCurEditSelection, const String& rStr );
+ EditPaM AutoCorrect( const EditSelection& rCurEditSelection, sal_Unicode c, sal_Bool bOverwrite );
+ EditPaM DeleteLeftOrRight( const EditSelection& rEditSelection, BYTE nMode, BYTE nDelMode = DELMODE_SIMPLE );
+ EditPaM InsertParaBreak( EditSelection aEditSelection );
+ EditPaM InsertLineBreak( EditSelection aEditSelection );
+ EditPaM InsertTab( EditSelection aEditSelection );
+ EditPaM InsertField( EditSelection aEditSelection, const SvxFieldItem& rFld );
+ sal_Bool UpdateFields();
+
+ EditPaM Read( SvStream& rInput, const String& rBaseURL, EETextFormat eFormat, EditSelection aSel, SvKeyValueIterator* pHTTPHeaderAttrs = NULL );
+ void Write( SvStream& rOutput, EETextFormat eFormat, EditSelection aSel );
+
+ EditTextObject* CreateTextObject();
+ EditTextObject* CreateTextObject( EditSelection aSel );
+ void SetText( const EditTextObject& rTextObject );
+ EditSelection InsertText( const EditTextObject& rTextObject, EditSelection aSel );
+
+ EditSelection MoveCursor( const KeyEvent& rKeyEvent, EditView* pEditView );
+
+ EditSelection MoveParagraphs( Range aParagraphs, sal_uInt16 nNewPos, EditView* pCurView );
+
+ sal_uInt32 CalcTextHeight();
+ sal_uInt32 GetTextHeight() const;
+ sal_uInt32 CalcTextWidth( BOOL bIgnoreExtraSpace );
+ sal_uInt32 CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, BOOL bIgnoreExtraSpace );
+ sal_uInt16 GetLineCount( sal_uInt16 nParagraph ) const;
+ sal_uInt16 GetLineLen( sal_uInt16 nParagraph, sal_uInt16 nLine ) const;
+ void GetLineBoundaries( /*out*/USHORT &rStart, /*out*/USHORT &rEnd, USHORT nParagraph, USHORT nLine ) const;
+ USHORT GetLineNumberAtIndex( USHORT nPara, USHORT nIndex ) const;
+ sal_uInt16 GetLineHeight( sal_uInt16 nParagraph, sal_uInt16 nLine );
+ sal_uInt32 GetParaHeight( sal_uInt16 nParagraph );
+
+ SfxItemSet GetAttribs( USHORT nPara, USHORT nStart, USHORT nEnd, sal_uInt8 nFlags = 0xFF ) const;
+ SfxItemSet GetAttribs( EditSelection aSel, BOOL bOnlyHardAttrib = FALSE );
+ void SetAttribs( EditSelection aSel, const SfxItemSet& rSet, BYTE nSpecial = 0 );
+ void RemoveCharAttribs( EditSelection aSel, sal_Bool bRemoveParaAttribs, sal_uInt16 nWhich = 0 );
+ void RemoveCharAttribs( sal_uInt16 nPara, sal_uInt16 nWhich = 0, sal_Bool bRemoveFeatures = sal_False );
+ void SetFlatMode( sal_Bool bFlat );
+
+ void SetParaAttribs( sal_uInt16 nPara, const SfxItemSet& rSet );
+ const SfxItemSet& GetParaAttribs( sal_uInt16 nPara ) const;
+
+ sal_Bool HasParaAttrib( sal_uInt16 nPara, sal_uInt16 nWhich ) const;
+ const SfxPoolItem& GetParaAttrib( sal_uInt16 nPara, sal_uInt16 nWhich ) const;
+
+ Rectangle PaMtoEditCursor( EditPaM aPaM, sal_uInt16 nFlags = 0 );
+ Rectangle GetEditCursor( ParaPortion* pPortion, sal_uInt16 nIndex, sal_uInt16 nFlags = 0 );
+
+ sal_Bool IsModified() const { return aEditDoc.IsModified(); }
+ void SetModifyFlag( sal_Bool b ) { aEditDoc.SetModified( b ); }
+ void SetModifyHdl( const Link& rLink ) { aModifyHdl = rLink; }
+ Link GetModifyHdl() const { return aModifyHdl; }
+
+
+ sal_Bool IsInSelectionMode() { return bInSelection; }
+ void StopSelectionMode();
+
+ void IndentBlock( EditView* pView, sal_Bool bRight );
+
+// Fuer Undo/Redo
+ sal_Bool Undo( EditView* pView );
+ sal_Bool Redo( EditView* pView );
+ sal_Bool Repeat( EditView* pView );
+
+// OV-Special
+ void InvalidateFromParagraph( sal_uInt16 nFirstInvPara );
+ EditPaM InsertParagraph( sal_uInt16 nPara );
+ EditSelection* SelectParagraph( sal_uInt16 nPara );
+
+ void SetStatusEventHdl( const Link& rLink ) { aStatusHdlLink = rLink; }
+ Link GetStatusEventHdl() const { return aStatusHdlLink; }
+
+ void SetNotifyHdl( const Link& rLink ) { aNotifyHdl = rLink; }
+ Link GetNotifyHdl() const { return aNotifyHdl; }
+
+ void FormatAndUpdate( EditView* pCurView = 0 );
+ inline void IdleFormatAndUpdate( EditView* pCurView = 0 );
+
+ svtools::ColorConfig& GetColorConfig();
+ BOOL IsVisualCursorTravelingEnabled();
+ BOOL DoVisualCursorTraveling( const ContentNode* pNode );
+
+ EditSelection ConvertSelection( sal_uInt16 nStartPara, sal_uInt16 nStartPos, sal_uInt16 nEndPara, sal_uInt16 nEndPos ) const;
+ inline EPaM CreateEPaM( const EditPaM& rPaM );
+ inline EditPaM CreateEditPaM( const EPaM& rEPaM );
+ inline ESelection CreateESel( const EditSelection& rSel );
+ inline EditSelection CreateSel( const ESelection& rSel );
+
+
+ void SetStyleSheetPool( SfxStyleSheetPool* pSPool );
+ SfxStyleSheetPool* GetStyleSheetPool() const { return pStylePool; }
+
+ void SetStyleSheet( EditSelection aSel, SfxStyleSheet* pStyle );
+ void SetStyleSheet( sal_uInt16 nPara, SfxStyleSheet* pStyle );
+ SfxStyleSheet* GetStyleSheet( sal_uInt16 nPara ) const;
+
+ void UpdateParagraphsWithStyleSheet( SfxStyleSheet* pStyle );
+ void RemoveStyleFromParagraphs( SfxStyleSheet* pStyle );
+
+ OutputDevice* GetRefDevice() const { return pRefDev; }
+ void SetRefDevice( OutputDevice* pRefDef );
+
+ const MapMode& GetRefMapMode() { return pRefDev->GetMapMode(); }
+ void SetRefMapMode( const MapMode& rMapMode );
+
+ InternalEditStatus& GetStatus() { return aStatus; }
+ void CallStatusHdl();
+ void DelayedCallStatusHdl() { aStatusTimer.Start(); }
+
+ void CallNotify( EENotify& rNotify );
+ void EnterBlockNotifications();
+ void LeaveBlockNotifications();
+
+
+ EditSelection MatchGroup( const EditSelection& rSel );
+
+ void UndoActionStart( sal_uInt16 nId );
+ void UndoActionStart( sal_uInt16 nId, const ESelection& rSel );
+ void UndoActionEnd( sal_uInt16 nId );
+
+ EditView* GetActiveView() const { return pActiveView; }
+ void SetActiveView( EditView* pView );
+
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::linguistic2::XSpellChecker1 >
+ GetSpeller();
+ void SetSpeller( ::com::sun::star::uno::Reference<
+ ::com::sun::star::linguistic2::XSpellChecker1 > &xSpl )
+ { xSpeller = xSpl; }
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::linguistic2::XHyphenator >
+ GetHyphenator() const { return xHyphenator; }
+ void SetHyphenator( ::com::sun::star::uno::Reference<
+ ::com::sun::star::linguistic2::XHyphenator > &xHyph )
+ { xHyphenator = xHyph; }
+ SpellInfo* GetSpellInfo() const { return pSpellInfo; }
+
+ void SetDefaultLanguage( LanguageType eLang ) { eDefLanguage = eLang; }
+ LanguageType GetDefaultLanguage() const { return eDefLanguage; }
+
+
+ LanguageType GetLanguage( const EditSelection rSelection ) const;
+ LanguageType GetLanguage( const EditPaM& rPaM, USHORT* pEndPos = NULL ) const;
+ ::com::sun::star::lang::Locale GetLocale( const EditPaM& rPaM ) const;
+
+ void DoOnlineSpelling( ContentNode* pThisNodeOnly = 0, sal_Bool bSpellAtCursorPos = sal_False, sal_Bool bInteruptable = sal_True );
+ EESpellState Spell( EditView* pEditView, sal_Bool bMultipleDoc );
+ EESpellState HasSpellErrors();
+ EESpellState StartThesaurus( EditView* pEditView );
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::linguistic2::XSpellAlternatives >
+ ImpSpell( EditView* pEditView );
+
+ // text conversion functions
+ void Convert( EditView* pEditView, LanguageType nSrcLang, LanguageType nDestLang, const Font *pDestFont, INT32 nOptions, sal_Bool bIsInteractive, sal_Bool bMultipleDoc );
+ void ImpConvert( rtl::OUString &rConvTxt, LanguageType &rConvTxtLang, EditView* pEditView, LanguageType nSrcLang, const ESelection &rConvRange,
+ sal_Bool bAllowImplicitChangesForNotConvertibleText, LanguageType nTargetLang, const Font *pTargetFont );
+ ConvInfo * GetConvInfo() const { return pConvInfo; }
+ sal_Bool HasConvertibleTextPortion( LanguageType nLang );
+ void SetLanguageAndFont( const ESelection &rESel,
+ LanguageType nLang, USHORT nLangWhichId,
+ const Font *pFont, USHORT nFontWhichId );
+
+ // returns true if input sequence checking should be applied
+ sal_Bool IsInputSequenceCheckingRequired( sal_Unicode nChar, const EditSelection& rCurSel ) const;
+
+ //find the next error within the given selection - forward only!
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::linguistic2::XSpellAlternatives >
+ ImpFindNextError(EditSelection& rSelection);
+ //initialize sentence spelling
+ void StartSpelling(EditView& rEditView, sal_Bool bMultipleDoc);
+ //spell and return a sentence
+ bool SpellSentence(EditView& rView, ::svx::SpellPortions& rToFill, bool bIsGrammarChecking );
+ //put spelling back to start of current sentence - needed after switch of grammar support
+ void PutSpellingToSentenceStart( EditView& rEditView );
+ //applies a changed sentence
+ void ApplyChangedSentence(EditView& rEditView, const ::svx::SpellPortions& rNewPortions, bool bIsGrammarChecking );
+ //deinitialize sentence spelling
+ void EndSpelling();
+ //adds one or more portions of text to the SpellPortions depending on language changes
+ void AddPortionIterated(
+ EditView& rEditView,
+ const EditSelection rSel,
+ ::com::sun::star::uno::Reference< ::com::sun::star::linguistic2::XSpellAlternatives > xAlt,
+ ::svx::SpellPortions& rToFill);
+ //adds one portion to the SpellPortions
+ void AddPortion(
+ const EditSelection rSel,
+ ::com::sun::star::uno::Reference< ::com::sun::star::linguistic2::XSpellAlternatives > xAlt,
+ ::svx::SpellPortions& rToFill,
+ bool bIsField );
+
+ sal_Bool Search( const SvxSearchItem& rSearchItem, EditView* pView );
+ sal_Bool ImpSearch( const SvxSearchItem& rSearchItem, const EditSelection& rSearchSelection, const EditPaM& rStartPos, EditSelection& rFoundSel );
+ sal_uInt16 StartSearchAndReplace( EditView* pEditView, const SvxSearchItem& rSearchItem );
+ sal_Bool HasText( const SvxSearchItem& rSearchItem );
+
+ void SetEditTextObjectPool( SfxItemPool* pP ) { pTextObjectPool = pP; }
+ SfxItemPool* GetEditTextObjectPool() const { return pTextObjectPool; }
+
+ const SvxNumberFormat * GetNumberFormat( const ContentNode* pNode ) const;
+ sal_Int32 GetSpaceBeforeAndMinLabelWidth( const ContentNode *pNode, sal_Int32 *pnSpaceBefore = 0, sal_Int32 *pnMinLabelWidth = 0 ) const;
+
+ const SvxLRSpaceItem& GetLRSpaceItem( ContentNode* pNode );
+ SvxAdjust GetJustification( USHORT nPara ) const;
+
+ void SetCharStretching( sal_uInt16 nX, sal_uInt16 nY );
+ inline void GetCharStretching( sal_uInt16& rX, sal_uInt16& rY );
+ void DoStretchChars( sal_uInt16 nX, sal_uInt16 nY );
+
+ void SetBigTextObjectStart( sal_uInt16 nStartAtPortionCount ) { nBigTextObjectStart = nStartAtPortionCount; }
+ sal_uInt16 GetBigTextObjectStart() const { return nBigTextObjectStart; }
+
+ inline EditEngine* GetEditEnginePtr() const { return pEditEngine; }
+
+ void StartOnlineSpellTimer() { aOnlineSpellTimer.Start(); }
+ void StopOnlineSpellTimer() { aOnlineSpellTimer.Stop(); }
+
+ const XubString& GetAutoCompleteText() const { return aAutoCompleteText; }
+ void SetAutoCompleteText( const String& rStr, sal_Bool bUpdateTipWindow );
+
+ EditSelection TransliterateText( const EditSelection& rSelection, sal_Int32 nTransliterationMode );
+
+ void SetAsianCompressionMode( USHORT n );
+ USHORT GetAsianCompressionMode() const { return nAsianCompressionMode; }
+
+ void SetKernAsianPunctuation( BOOL b );
+ BOOL IsKernAsianPunctuation() const { return bKernAsianPunctuation; }
+
+ void SetAddExtLeading( BOOL b );
+ BOOL IsAddExtLeading() const { return bAddExtLeading; }
+
+ vos::ORef<SvxForbiddenCharactersTable> GetForbiddenCharsTable( BOOL bGetInternal = TRUE ) const;
+ void SetForbiddenCharsTable( vos::ORef<SvxForbiddenCharactersTable> xForbiddenChars );
+
+ BOOL mbLastTryMerge;
+
+ /** sets a link that is called at the beginning of a drag operation at an edit view */
+ void SetBeginDropHdl( const Link& rLink ) { maBeginDropHdl = rLink; }
+ Link GetBeginDropHdl() const { return maBeginDropHdl; }
+
+ /** sets a link that is called at the end of a drag operation at an edit view */
+ void SetEndDropHdl( const Link& rLink ) { maEndDropHdl = rLink; }
+ Link GetEndDropHdl() const { return maEndDropHdl; }
+
+ /// specifies if auto-correction should capitalize the first word or not (default is on)
+ void SetFirstWordCapitalization( BOOL bCapitalize ) { bFirstWordCapitalization = bCapitalize; }
+ BOOL IsFirstWordCapitalization() const { return bFirstWordCapitalization; }
+};
+
+inline EPaM ImpEditEngine::CreateEPaM( const EditPaM& rPaM )
+{
+ ContentNode* pNode = rPaM.GetNode();
+ return EPaM( aEditDoc.GetPos( pNode ), rPaM.GetIndex() );
+}
+
+inline EditPaM ImpEditEngine::CreateEditPaM( const EPaM& rEPaM )
+{
+ DBG_ASSERT( rEPaM.nPara < aEditDoc.Count(), "CreateEditPaM: Ungueltiger Absatz" );
+ DBG_ASSERT( aEditDoc[ rEPaM.nPara ]->Len() >= rEPaM.nIndex, "CreateEditPaM: Ungueltiger Index" );
+ return EditPaM( aEditDoc[ rEPaM.nPara], rEPaM.nIndex );
+}
+
+inline ESelection ImpEditEngine::CreateESel( const EditSelection& rSel )
+{
+ ContentNode* pStartNode = rSel.Min().GetNode();
+ ContentNode* pEndNode = rSel.Max().GetNode();
+ ESelection aESel;
+ aESel.nStartPara = aEditDoc.GetPos( pStartNode );
+ aESel.nStartPos = rSel.Min().GetIndex();
+ aESel.nEndPara = aEditDoc.GetPos( pEndNode );
+ aESel.nEndPos = rSel.Max().GetIndex();
+ return aESel;
+}
+
+inline EditSelection ImpEditEngine::CreateSel( const ESelection& rSel )
+{
+ DBG_ASSERT( rSel.nStartPara < aEditDoc.Count(), "CreateSel: Ungueltiger Start-Absatz" );
+ DBG_ASSERT( rSel.nEndPara < aEditDoc.Count(), "CreateSel: Ungueltiger End-Absatz" );
+ EditSelection aSel;
+ aSel.Min().SetNode( aEditDoc[ rSel.nStartPara ] );
+ aSel.Min().SetIndex( rSel.nStartPos );
+ aSel.Max().SetNode( aEditDoc[ rSel.nEndPara ] );
+ aSel.Max().SetIndex( rSel.nEndPos );
+ DBG_ASSERT( !aSel.DbgIsBuggy( aEditDoc ), "CreateSel: Fehlerhafte Selektion!" );
+ return aSel;
+}
+
+inline VirtualDevice* ImpEditEngine::GetVirtualDevice( const MapMode& rMapMode, ULONG nDrawMode )
+{
+ if ( !pVirtDev )
+ pVirtDev = new VirtualDevice;
+
+ if ( ( pVirtDev->GetMapMode().GetMapUnit() != rMapMode.GetMapUnit() ) ||
+ ( pVirtDev->GetMapMode().GetScaleX() != rMapMode.GetScaleX() ) ||
+ ( pVirtDev->GetMapMode().GetScaleY() != rMapMode.GetScaleY() ) )
+ {
+ MapMode aMapMode( rMapMode );
+ aMapMode.SetOrigin( Point( 0, 0 ) );
+ pVirtDev->SetMapMode( aMapMode );
+ }
+
+ pVirtDev->SetDrawMode( nDrawMode );
+
+ return pVirtDev;
+}
+
+inline void ImpEditEngine::EraseVirtualDevice()
+{
+ delete pVirtDev;
+ pVirtDev = 0;
+}
+
+inline void ImpEditEngine::IdleFormatAndUpdate( EditView* pCurView )
+{
+ aIdleFormatter.DoIdleFormat( pCurView );
+}
+
+#ifndef SVX_LIGHT
+inline EditUndoManager& ImpEditEngine::GetUndoManager()
+{
+ if ( !pUndoManager )
+ pUndoManager = new EditUndoManager( this );
+ return *pUndoManager;
+}
+#endif
+
+inline ParaPortion* ImpEditEngine::FindParaPortion( ContentNode* pNode ) const
+{
+ sal_uInt16 nPos = aEditDoc.GetPos( pNode );
+ DBG_ASSERT( nPos < GetParaPortions().Count(), "Portionloser Node?" );
+ return GetParaPortions()[ nPos ];
+}
+
+inline void ImpEditEngine::GetCharStretching( sal_uInt16& rX, sal_uInt16& rY )
+{
+ rX = nStretchX;
+ rY = nStretchY;
+}
+
+inline short ImpEditEngine::GetXValue( short nXValue ) const
+{
+ if ( !aStatus.DoStretch() || ( nStretchX == 100 ) )
+ return nXValue;
+
+ return (short) ((long)nXValue*nStretchX/100);
+}
+
+inline sal_uInt16 ImpEditEngine::GetXValue( sal_uInt16 nXValue ) const
+{
+ if ( !aStatus.DoStretch() || ( nStretchX == 100 ) )
+ return nXValue;
+
+ return (sal_uInt16) ((long)nXValue*nStretchX/100);
+}
+
+inline long ImpEditEngine::GetXValue( long nXValue ) const
+{
+ if ( !aStatus.DoStretch() || ( nStretchX == 100 ) )
+ return nXValue;
+
+ return nXValue*nStretchX/100;
+}
+
+inline short ImpEditEngine::GetYValue( short nYValue ) const
+{
+ if ( !aStatus.DoStretch() || ( nStretchY == 100 ) )
+ return nYValue;
+
+ return (short) ((long)nYValue*nStretchY/100);
+}
+
+inline sal_uInt16 ImpEditEngine::GetYValue( sal_uInt16 nYValue ) const
+{
+ if ( !aStatus.DoStretch() || ( nStretchY == 100 ) )
+ return nYValue;
+
+ return (sal_uInt16) ((long)nYValue*nStretchY/100);
+}
+
+inline void ImpEditView::SetPointer( const Pointer& rPointer )
+{
+ delete pPointer;
+ pPointer = new Pointer( rPointer );
+}
+
+inline const Pointer& ImpEditView::GetPointer()
+{
+ if ( !pPointer )
+ {
+ pPointer = new Pointer( IsVertical() ? POINTER_TEXT_VERTICAL : POINTER_TEXT );
+ return *pPointer;
+ }
+
+ if(POINTER_TEXT == pPointer->GetStyle() && IsVertical())
+ {
+ delete pPointer;
+ pPointer = new Pointer(POINTER_TEXT_VERTICAL);
+ }
+ else if(POINTER_TEXT_VERTICAL == pPointer->GetStyle() && !IsVertical())
+ {
+ delete pPointer;
+ pPointer = new Pointer(POINTER_TEXT);
+ }
+
+ return *pPointer;
+}
+
+inline void ImpEditView::SetCursor( const Cursor& rCursor )
+{
+ delete pCursor;
+ pCursor = new Cursor( rCursor );
+}
+
+inline Cursor* ImpEditView::GetCursor()
+{
+ if ( !pCursor )
+ pCursor = new Cursor;
+ return pCursor;
+}
+
+void ConvertItem( SfxPoolItem& rPoolItem, MapUnit eSourceUnit, MapUnit eDestUnit );
+void ConvertAndPutItems( SfxItemSet& rDest, const SfxItemSet& rSource, const MapUnit* pSourceUnit = NULL, const MapUnit* pDestUnit = NULL );
+BYTE GetCharTypeForCompression( xub_Unicode cChar );
+Point Rotate( const Point& rPoint, short nOrientation, const Point& rOrigin );
+
+#endif // _IMPEDIT_HXX
+
+
diff --git a/editeng/source/editeng/impedit2.cxx b/editeng/source/editeng/impedit2.cxx
new file mode 100644
index 0000000000..d6f8a54876
--- /dev/null
+++ b/editeng/source/editeng/impedit2.cxx
@@ -0,0 +1,4635 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: impedit2.cxx,v $
+ * $Revision: 1.124.40.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <vcl/wrkwin.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+
+#include <editeng/lspcitem.hxx>
+#include <editeng/flditem.hxx>
+#include <impedit.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editdbg.hxx>
+#include <eerdll2.hxx>
+#include <editeng/eerdll.hxx>
+#include <edtspell.hxx>
+#include <eeobj.hxx>
+#include <editeng/txtrange.hxx>
+#include <svl/urlbmk.hxx>
+#include <svtools/colorcfg.hxx>
+#include <svl/ctloptions.hxx>
+#include <editeng/acorrcfg.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/fontitem.hxx>
+#include <vcl/cmdevt.h>
+
+#include <com/sun/star/i18n/CharacterIteratorMode.hpp>
+#include <com/sun/star/i18n/WordType.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/text/CharacterCompressionType.hpp>
+#include <com/sun/star/i18n/InputSequenceCheckMode.hpp>
+
+#include <comphelper/processfactory.hxx>
+
+#include <sot/formats.hxx>
+
+#include <unicode/ubidi.h>
+
+using namespace ::com::sun::star;
+
+USHORT lcl_CalcExtraSpace( ParaPortion*, const SvxLineSpacingItem& rLSItem )
+{
+ USHORT nExtra = 0;
+ /* if ( ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP )
+ && ( rLSItem.GetPropLineSpace() != 100 ) )
+ {
+ // ULONG nH = pPortion->GetNode()->GetCharAttribs().GetDefFont().GetSize().Height();
+ ULONG nH = pPortion->GetLines().GetObject( 0 )->GetHeight();
+ long n = nH * rLSItem.GetPropLineSpace();
+ n /= 100;
+ n -= nH; // nur den Abstand
+ if ( n > 0 )
+ nExtra = (USHORT)n;
+ }
+ else */
+ if ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX )
+ {
+ nExtra = rLSItem.GetInterLineSpace();
+ }
+
+ return nExtra;
+}
+
+ // ----------------------------------------------------------------------
+// class ImpEditEngine
+// ----------------------------------------------------------------------
+
+ImpEditEngine::ImpEditEngine( EditEngine* pEE, SfxItemPool* pItemPool ) :
+ aPaperSize( 0x7FFFFFFF, 0x7FFFFFFF ),
+ aMinAutoPaperSize( 0x0, 0x0 ),
+ aMaxAutoPaperSize( 0x7FFFFFFF, 0x7FFFFFFF ),
+ aEditDoc( pItemPool ),
+ aWordDelimiters( RTL_CONSTASCII_USTRINGPARAM( " .,;:-'`'?!_=\"{}()[]\0xFF" ) ),
+ aGroupChars( RTL_CONSTASCII_USTRINGPARAM( "{}()[]" ) )
+{
+ pEditEngine = pEE;
+ pRefDev = NULL;
+ pVirtDev = NULL;
+ pEmptyItemSet = NULL;
+ pActiveView = NULL;
+ pSpellInfo = NULL;
+ pConvInfo = NULL;
+ pTextObjectPool = NULL;
+ mpIMEInfos = NULL;
+ pStylePool = NULL;
+ pUndoManager = NULL;
+ pUndoMarkSelection = NULL;
+ pTextRanger = NULL;
+ pColorConfig = NULL;
+ pCTLOptions = NULL;
+
+ nCurTextHeight = 0;
+ nBlockNotifications = 0;
+ nBigTextObjectStart = 20;
+
+ nStretchX = 100;
+ nStretchY = 100;
+
+ bInSelection = FALSE;
+ bOwnerOfRefDev = FALSE;
+ bDowning = FALSE;
+ bIsInUndo = FALSE;
+ bIsFormatting = FALSE;
+ bFormatted = FALSE;
+ bUpdate = TRUE;
+ bUseAutoColor = TRUE;
+ bForceAutoColor = FALSE;
+ bAddExtLeading = FALSE;
+ bUndoEnabled = TRUE;
+ bCallParaInsertedOrDeleted = FALSE;
+ bImpConvertFirstCall= FALSE;
+ bFirstWordCapitalization = TRUE;
+
+ eDefLanguage = LANGUAGE_DONTKNOW;
+ maBackgroundColor = COL_AUTO;
+
+ nAsianCompressionMode = text::CharacterCompressionType::NONE;
+ bKernAsianPunctuation = FALSE;
+
+ eDefaultHorizontalTextDirection = EE_HTEXTDIR_DEFAULT;
+
+
+ aStatus.GetControlWord() = EE_CNTRL_USECHARATTRIBS | EE_CNTRL_DOIDLEFORMAT |
+ EE_CNTRL_PASTESPECIAL | EE_CNTRL_UNDOATTRIBS |
+ EE_CNTRL_ALLOWBIGOBJS | EE_CNTRL_RTFSTYLESHEETS |
+ EE_CNTRL_FORMAT100;
+
+ aSelEngine.SetFunctionSet( &aSelFuncSet );
+
+ aStatusTimer.SetTimeout( 200 );
+ aStatusTimer.SetTimeoutHdl( LINK( this, ImpEditEngine, StatusTimerHdl ) );
+
+ aIdleFormatter.SetTimeout( 5 );
+ aIdleFormatter.SetTimeoutHdl( LINK( this, ImpEditEngine, IdleFormatHdl ) );
+
+ aOnlineSpellTimer.SetTimeout( 100 );
+ aOnlineSpellTimer.SetTimeoutHdl( LINK( this, ImpEditEngine, OnlineSpellHdl ) );
+
+ pRefDev = EE_DLL()->GetGlobalData()->GetStdRefDevice();
+
+ // Ab hier wird schon auf Daten zugegriffen!
+ SetRefDevice( pRefDev );
+ InitDoc( FALSE );
+
+ bCallParaInsertedOrDeleted = TRUE;
+
+ aEditDoc.SetModifyHdl( LINK( this, ImpEditEngine, DocModified ) );
+
+ mbLastTryMerge = FALSE;
+}
+
+ImpEditEngine::~ImpEditEngine()
+{
+ aStatusTimer.Stop();
+ aOnlineSpellTimer.Stop();
+ aIdleFormatter.Stop();
+
+ // das Zerstoeren von Vorlagen kann sonst unnoetiges Formatieren ausloesen,
+ // wenn eine Parent-Vorlage zerstoert wird.
+ // Und das nach dem Zerstoeren der Daten!
+ bDowning = TRUE;
+ SetUpdateMode( FALSE );
+
+ delete pVirtDev;
+ delete pEmptyItemSet;
+ delete pUndoManager;
+ delete pTextRanger;
+ delete mpIMEInfos;
+ delete pColorConfig;
+ delete pCTLOptions;
+ if ( bOwnerOfRefDev )
+ delete pRefDev;
+ delete pSpellInfo;
+}
+
+void ImpEditEngine::SetRefDevice( OutputDevice* pRef )
+{
+ if ( bOwnerOfRefDev )
+ delete pRefDev;
+
+ pRefDev = pRef;
+ bOwnerOfRefDev = FALSE;
+
+ if ( !pRef )
+ pRefDev = EE_DLL()->GetGlobalData()->GetStdRefDevice();
+
+ nOnePixelInRef = (USHORT)pRefDev->PixelToLogic( Size( 1, 0 ) ).Width();
+
+ if ( IsFormatted() )
+ {
+ FormatFullDoc();
+ UpdateViews( (EditView*) 0);
+ }
+}
+
+void ImpEditEngine::SetRefMapMode( const MapMode& rMapMode )
+{
+ if ( GetRefDevice()->GetMapMode() == rMapMode )
+ return;
+
+ // Wenn RefDev == GlobalRefDev => eigenes anlegen!
+ if ( !bOwnerOfRefDev && ( pRefDev == EE_DLL()->GetGlobalData()->GetStdRefDevice() ) )
+ {
+ pRefDev = new VirtualDevice;
+ pRefDev->SetMapMode( MAP_TWIP );
+ SetRefDevice( pRefDev );
+ bOwnerOfRefDev = TRUE;
+ }
+ pRefDev->SetMapMode( rMapMode );
+ nOnePixelInRef = (USHORT)pRefDev->PixelToLogic( Size( 1, 0 ) ).Width();
+ if ( IsFormatted() )
+ {
+ FormatFullDoc();
+ UpdateViews( (EditView*) 0);
+ }
+}
+
+void ImpEditEngine::InitDoc( BOOL bKeepParaAttribs )
+{
+ USHORT nParas = aEditDoc.Count();
+ for ( USHORT n = bKeepParaAttribs ? 1 : 0; n < nParas; n++ )
+ {
+ if ( aEditDoc[n]->GetStyleSheet() )
+ EndListening( *aEditDoc[n]->GetStyleSheet(), FALSE );
+ }
+
+ if ( bKeepParaAttribs )
+ aEditDoc.RemoveText();
+ else
+ aEditDoc.Clear();
+
+ GetParaPortions().Reset();
+
+ ParaPortion* pIniPortion = new ParaPortion( aEditDoc[0] );
+ GetParaPortions().Insert( pIniPortion, 0 );
+
+ bFormatted = FALSE;
+
+ if ( IsCallParaInsertedOrDeleted() )
+ {
+ GetEditEnginePtr()->ParagraphDeleted( EE_PARA_ALL );
+ GetEditEnginePtr()->ParagraphInserted( 0 );
+ }
+
+#ifndef SVX_LIGHT
+ if ( GetStatus().DoOnlineSpelling() )
+ aEditDoc.GetObject( 0 )->CreateWrongList();
+#endif // !SVX_LIGHT
+}
+
+EditPaM ImpEditEngine::DeleteSelected( EditSelection aSel )
+{
+ EditPaM aPaM ( ImpDeleteSelection( aSel ) );
+ return aPaM;
+}
+
+XubString ImpEditEngine::GetSelected( const EditSelection& rSel, const LineEnd eEnd ) const
+{
+ XubString aText;
+ if ( !rSel.HasRange() )
+ return aText;
+
+ String aSep = EditDoc::GetSepStr( eEnd );
+
+ EditSelection aSel( rSel );
+ aSel.Adjust( aEditDoc );
+
+ ContentNode* pStartNode = aSel.Min().GetNode();
+ ContentNode* pEndNode = aSel.Max().GetNode();
+ USHORT nStartNode = aEditDoc.GetPos( pStartNode );
+ USHORT nEndNode = aEditDoc.GetPos( pEndNode );
+
+ DBG_ASSERT( nStartNode <= nEndNode, "Selektion nicht sortiert ?" );
+
+ // ueber die Absaetze iterieren...
+ for ( USHORT nNode = nStartNode; nNode <= nEndNode; nNode++ )
+ {
+ DBG_ASSERT( aEditDoc.SaveGetObject( nNode ), "Node nicht gefunden: GetSelected" );
+ ContentNode* pNode = aEditDoc.GetObject( nNode );
+
+ xub_StrLen nStartPos = 0;
+ xub_StrLen nEndPos = pNode->Len();
+ if ( nNode == nStartNode )
+ nStartPos = aSel.Min().GetIndex();
+ if ( nNode == nEndNode ) // kann auch == nStart sein!
+ nEndPos = aSel.Max().GetIndex();
+
+ aText += aEditDoc.GetParaAsString( pNode, nStartPos, nEndPos );
+ if ( nNode < nEndNode )
+ aText += aSep;
+ }
+ return aText;
+}
+
+BOOL ImpEditEngine::MouseButtonDown( const MouseEvent& rMEvt, EditView* pView )
+{
+ GetSelEngine().SetCurView( pView );
+ SetActiveView( pView );
+
+ if ( GetAutoCompleteText().Len() )
+ SetAutoCompleteText( String(), TRUE );
+
+ GetSelEngine().SelMouseButtonDown( rMEvt );
+ // Sonderbehandlungen
+ EditSelection aCurSel( pView->pImpEditView->GetEditSelection() );
+ if ( !rMEvt.IsShift() )
+ {
+ if ( rMEvt.GetClicks() == 2 )
+ {
+ // damit die SelectionEngine weiss, dass Anker.
+ aSelEngine.CursorPosChanging( TRUE, FALSE );
+
+ EditSelection aNewSelection( SelectWord( aCurSel ) );
+ pView->pImpEditView->DrawSelection();
+ pView->pImpEditView->SetEditSelection( aNewSelection );
+ pView->pImpEditView->DrawSelection();
+ pView->ShowCursor( TRUE, TRUE );
+ }
+ else if ( rMEvt.GetClicks() == 3 )
+ {
+ // damit die SelectionEngine weiss, dass Anker.
+ aSelEngine.CursorPosChanging( TRUE, FALSE );
+
+ EditSelection aNewSelection( aCurSel );
+ aNewSelection.Min().SetIndex( 0 );
+ aNewSelection.Max().SetIndex( aCurSel.Min().GetNode()->Len() );
+ pView->pImpEditView->DrawSelection();
+ pView->pImpEditView->SetEditSelection( aNewSelection );
+ pView->pImpEditView->DrawSelection();
+ pView->ShowCursor( TRUE, TRUE );
+ }
+ }
+ return TRUE;
+}
+
+void ImpEditEngine::Command( const CommandEvent& rCEvt, EditView* pView )
+{
+ GetSelEngine().SetCurView( pView );
+ SetActiveView( pView );
+ if ( rCEvt.GetCommand() == COMMAND_VOICE )
+ {
+ const CommandVoiceData* pData = rCEvt.GetVoiceData();
+ if ( pData->GetType() == VOICECOMMANDTYPE_DICTATION )
+ {
+ // Funktionen auf KeyEvents umbiegen, wenn keine entsprechende
+ // Methode an EditView/EditEngine, damit Undo konsistent bleibt.
+
+ SfxPoolItem* pNewAttr = NULL;
+
+ switch ( pData->GetCommand() )
+ {
+ case DICTATIONCOMMAND_UNKNOWN:
+ {
+ pView->InsertText( pData->GetText() );
+ }
+ break;
+ case DICTATIONCOMMAND_NEWPARAGRAPH:
+ {
+ pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_RETURN, 0 ) ) );
+ }
+ break;
+ case DICTATIONCOMMAND_NEWLINE:
+ {
+ pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_RETURN, KEY_SHIFT ) ) );
+ }
+ break;
+ case DICTATIONCOMMAND_TAB:
+ {
+ pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_TAB, 0 ) ) );
+ }
+ break;
+ case DICTATIONCOMMAND_LEFT:
+ {
+ pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_LEFT, KEY_MOD1 ) ) );
+ }
+ break;
+ case DICTATIONCOMMAND_RIGHT:
+ {
+ pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_RIGHT, KEY_MOD1 ) ) );
+ }
+ break;
+ case DICTATIONCOMMAND_UP:
+ {
+ pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_UP, 0 ) ) );
+ }
+ break;
+ case DICTATIONCOMMAND_DOWN:
+ {
+ pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_UP, 0 ) ) );
+ }
+ break;
+ case DICTATIONCOMMAND_UNDO:
+ {
+ pView->Undo();
+ }
+ break;
+ case DICTATIONCOMMAND_DEL:
+ {
+ pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_LEFT, KEY_MOD1|KEY_SHIFT ) ) );
+ pView->DeleteSelected();
+ }
+ break;
+ case DICTATIONCOMMAND_BOLD_ON:
+ {
+ pNewAttr = new SvxWeightItem( WEIGHT_BOLD, EE_CHAR_WEIGHT );
+ }
+ break;
+ case DICTATIONCOMMAND_BOLD_OFF:
+ {
+ pNewAttr = new SvxWeightItem( WEIGHT_NORMAL, EE_CHAR_WEIGHT );
+ }
+ break;
+ case DICTATIONCOMMAND_ITALIC_ON:
+ {
+ pNewAttr = new SvxPostureItem( ITALIC_NORMAL, EE_CHAR_ITALIC );
+ }
+ break;
+ case DICTATIONCOMMAND_ITALIC_OFF:
+ {
+ pNewAttr = new SvxPostureItem( ITALIC_NORMAL, EE_CHAR_ITALIC );
+ }
+ break;
+ case DICTATIONCOMMAND_UNDERLINE_ON:
+ {
+ pNewAttr = new SvxUnderlineItem( UNDERLINE_SINGLE, EE_CHAR_UNDERLINE );
+ }
+ break;
+ case DICTATIONCOMMAND_UNDERLINE_OFF:
+ {
+ pNewAttr = new SvxUnderlineItem( UNDERLINE_NONE, EE_CHAR_UNDERLINE );
+ }
+ break;
+ }
+
+ if ( pNewAttr )
+ {
+ SfxItemSet aSet( GetEmptyItemSet() );
+ aSet.Put( *pNewAttr );
+ pView->SetAttribs( aSet );
+ delete pNewAttr;
+ }
+ }
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_STARTEXTTEXTINPUT )
+ {
+ pView->DeleteSelected();
+ delete mpIMEInfos;
+ EditPaM aPaM = pView->GetImpEditView()->GetEditSelection().Max();
+ String aOldTextAfterStartPos = aPaM.GetNode()->Copy( aPaM.GetIndex() );
+ USHORT nMax = aOldTextAfterStartPos.Search( CH_FEATURE );
+ if ( nMax != STRING_NOTFOUND ) // don't overwrite features!
+ aOldTextAfterStartPos.Erase( nMax );
+ mpIMEInfos = new ImplIMEInfos( aPaM, aOldTextAfterStartPos );
+ mpIMEInfos->bWasCursorOverwrite = !pView->IsInsertMode();
+ UndoActionStart( EDITUNDO_INSERT );
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_ENDEXTTEXTINPUT )
+ {
+ DBG_ASSERT( mpIMEInfos, "COMMAND_ENDEXTTEXTINPUT => Kein Start ?" );
+ if( mpIMEInfos )
+ {
+ // #102812# convert quotes in IME text
+ // works on the last input character, this is escpecially in Korean text often done
+ // quotes that are inside of the string are not replaced!
+ // Borrowed from sw: edtwin.cxx
+ if ( mpIMEInfos->nLen )
+ {
+ EditSelection aSel( mpIMEInfos->aPos );
+ aSel.Min().GetIndex() += mpIMEInfos->nLen-1;
+ aSel.Max().GetIndex() =
+ aSel.Max().GetIndex() + mpIMEInfos->nLen;
+ // #102812# convert quotes in IME text
+ // works on the last input character, this is escpecially in Korean text often done
+ // quotes that are inside of the string are not replaced!
+ const sal_Unicode nCharCode = aSel.Min().GetNode()->GetChar( aSel.Min().GetIndex() );
+ if ( ( GetStatus().DoAutoCorrect() ) && ( ( nCharCode == '\"' ) || ( nCharCode == '\'' ) ) )
+ {
+ aSel = DeleteSelected( aSel );
+ aSel = AutoCorrect( aSel, nCharCode, mpIMEInfos->bWasCursorOverwrite );
+ pView->pImpEditView->SetEditSelection( aSel );
+ }
+ }
+
+ ParaPortion* pPortion = FindParaPortion( mpIMEInfos->aPos.GetNode() );
+ pPortion->MarkSelectionInvalid( mpIMEInfos->aPos.GetIndex(), 0 );
+
+ BOOL bWasCursorOverwrite = mpIMEInfos->bWasCursorOverwrite;
+
+ delete mpIMEInfos;
+ mpIMEInfos = NULL;
+
+ FormatAndUpdate( pView );
+
+ pView->SetInsertMode( !bWasCursorOverwrite );
+ }
+ UndoActionEnd( EDITUNDO_INSERT );
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_EXTTEXTINPUT )
+ {
+ DBG_ASSERT( mpIMEInfos, "COMMAND_EXTTEXTINPUT => Kein Start ?" );
+ if( mpIMEInfos )
+ {
+ const CommandExtTextInputData* pData = rCEvt.GetExtTextInputData();
+
+ if ( !pData->IsOnlyCursorChanged() )
+ {
+ EditSelection aSel( mpIMEInfos->aPos );
+ aSel.Max().GetIndex() =
+ aSel.Max().GetIndex() + mpIMEInfos->nLen;
+ aSel = DeleteSelected( aSel );
+ aSel = ImpInsertText( aSel, pData->GetText() );
+
+ if ( mpIMEInfos->bWasCursorOverwrite )
+ {
+ USHORT nOldIMETextLen = mpIMEInfos->nLen;
+ USHORT nNewIMETextLen = pData->GetText().Len();
+
+ if ( ( nOldIMETextLen > nNewIMETextLen ) &&
+ ( nNewIMETextLen < mpIMEInfos->aOldTextAfterStartPos.Len() ) )
+ {
+ // restore old characters
+ USHORT nRestore = nOldIMETextLen - nNewIMETextLen;
+ EditPaM aPaM( mpIMEInfos->aPos );
+ aPaM.GetIndex() = aPaM.GetIndex() + nNewIMETextLen;
+ ImpInsertText( aPaM, mpIMEInfos->aOldTextAfterStartPos.Copy( nNewIMETextLen, nRestore ) );
+ }
+ else if ( ( nOldIMETextLen < nNewIMETextLen ) &&
+ ( nOldIMETextLen < mpIMEInfos->aOldTextAfterStartPos.Len() ) )
+ {
+ // overwrite
+ USHORT nOverwrite = nNewIMETextLen - nOldIMETextLen;
+ if ( ( nOldIMETextLen + nOverwrite ) > mpIMEInfos->aOldTextAfterStartPos.Len() )
+ nOverwrite = mpIMEInfos->aOldTextAfterStartPos.Len() - nOldIMETextLen;
+ DBG_ASSERT( nOverwrite && (nOverwrite < 0xFF00), "IME Overwrite?!" );
+ EditPaM aPaM( mpIMEInfos->aPos );
+ aPaM.GetIndex() = aPaM.GetIndex() + nNewIMETextLen;
+ EditSelection _aSel( aPaM );
+ _aSel.Max().GetIndex() =
+ _aSel.Max().GetIndex() + nOverwrite;
+ DeleteSelected( _aSel );
+ }
+ }
+ if ( pData->GetTextAttr() )
+ {
+ mpIMEInfos->CopyAttribs( pData->GetTextAttr(), pData->GetText().Len() );
+ mpIMEInfos->bCursor = pData->IsCursorVisible();
+ }
+ else
+ {
+ mpIMEInfos->DestroyAttribs();
+ mpIMEInfos->nLen = pData->GetText().Len();
+ }
+
+ ParaPortion* pPortion = FindParaPortion( mpIMEInfos->aPos.GetNode() );
+ pPortion->MarkSelectionInvalid( mpIMEInfos->aPos.GetIndex(), 0 );
+ FormatAndUpdate( pView );
+ }
+
+ EditSelection aNewSel = EditPaM( mpIMEInfos->aPos.GetNode(), mpIMEInfos->aPos.GetIndex()+pData->GetCursorPos() );
+ pView->SetSelection( CreateESel( aNewSel ) );
+ pView->SetInsertMode( !pData->IsCursorOverwrite() );
+
+ if ( pData->IsCursorVisible() )
+ pView->ShowCursor();
+ else
+ pView->HideCursor();
+ }
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_INPUTCONTEXTCHANGE )
+ {
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_CURSORPOS )
+ {
+ if ( mpIMEInfos && mpIMEInfos->nLen )
+ {
+ EditPaM aPaM( pView->pImpEditView->GetEditSelection().Max() );
+ Rectangle aR1 = PaMtoEditCursor( aPaM, 0 );
+
+ USHORT nInputEnd = mpIMEInfos->aPos.GetIndex() + mpIMEInfos->nLen;
+
+ if ( !IsFormatted() )
+ FormatDoc();
+
+ ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( GetEditDoc().GetPos( aPaM.GetNode() ) );
+ USHORT nLine = pParaPortion->GetLines().FindLine( aPaM.GetIndex(), sal_True );
+ EditLine* pLine = pParaPortion->GetLines().GetObject( nLine );
+ if ( pLine && ( nInputEnd > pLine->GetEnd() ) )
+ nInputEnd = pLine->GetEnd();
+ Rectangle aR2 = PaMtoEditCursor( EditPaM( aPaM.GetNode(), nInputEnd ), GETCRSR_ENDOFLINE );
+ Rectangle aRect = pView->GetImpEditView()->GetWindowPos( aR1 );
+ pView->GetWindow()->SetCursorRect( &aRect, aR2.Left()-aR1.Right() );
+ }
+ else
+ {
+ pView->GetWindow()->SetCursorRect();
+ }
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_SELECTIONCHANGE )
+ {
+ const CommandSelectionChangeData *pData = rCEvt.GetSelectionChangeData();
+
+ ESelection aSelection = pView->GetSelection();
+ aSelection.Adjust();
+
+ if( pView->HasSelection() )
+ {
+ aSelection.nEndPos = aSelection.nStartPos;
+ aSelection.nStartPos += pData->GetStart();
+ aSelection.nEndPos += pData->GetEnd();
+ }
+ else
+ {
+ aSelection.nStartPos = pData->GetStart();
+ aSelection.nEndPos = pData->GetEnd();
+ }
+ pView->SetSelection( aSelection );
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_PREPARERECONVERSION )
+ {
+ if ( pView->HasSelection() )
+ {
+ ESelection aSelection = pView->GetSelection();
+ aSelection.Adjust();
+
+ if ( aSelection.nStartPara != aSelection.nEndPara )
+ {
+ xub_StrLen aParaLen = pEditEngine->GetTextLen( aSelection.nStartPara );
+ aSelection.nEndPara = aSelection.nStartPara;
+ aSelection.nEndPos = aParaLen;
+ pView->SetSelection( aSelection );
+ }
+ }
+ }
+
+ GetSelEngine().Command( rCEvt );
+}
+
+BOOL ImpEditEngine::MouseButtonUp( const MouseEvent& rMEvt, EditView* pView )
+{
+ GetSelEngine().SetCurView( pView );
+ GetSelEngine().SelMouseButtonUp( rMEvt );
+ bInSelection = FALSE;
+ // Sonderbehandlungen
+ EditSelection aCurSel( pView->pImpEditView->GetEditSelection() );
+ if ( !aCurSel.HasRange() )
+ {
+ if ( ( rMEvt.GetClicks() == 1 ) && rMEvt.IsLeft() && !rMEvt.IsMod2() )
+ {
+ const SvxFieldItem* pFld = pView->GetFieldUnderMousePointer();
+ if ( pFld )
+ {
+ EditPaM aPaM( aCurSel.Max() );
+ USHORT nPara = GetEditDoc().GetPos( aPaM.GetNode() );
+ GetEditEnginePtr()->FieldClicked( *pFld, nPara, aPaM.GetIndex() );
+ }
+ }
+ }
+ return TRUE;
+}
+
+BOOL ImpEditEngine::MouseMove( const MouseEvent& rMEvt, EditView* pView )
+{
+ // MouseMove wird sofort nach ShowQuickHelp() gerufen!
+// if ( GetAutoCompleteText().Len() )
+// SetAutoCompleteText( String(), TRUE );
+ GetSelEngine().SetCurView( pView );
+ GetSelEngine().SelMouseMove( rMEvt );
+ return TRUE;
+}
+
+EditPaM ImpEditEngine::InsertText( EditSelection aSel, const XubString& rStr )
+{
+ EditPaM aPaM = ImpInsertText( aSel, rStr );
+ return aPaM;
+}
+
+EditPaM ImpEditEngine::Clear()
+{
+ InitDoc( FALSE );
+
+ EditPaM aPaM = aEditDoc.GetStartPaM();
+ EditSelection aSel( aPaM );
+
+ nCurTextHeight = 0;
+
+ ResetUndoManager();
+
+ for ( USHORT nView = aEditViews.Count(); nView; )
+ {
+ EditView* pView = aEditViews[--nView];
+ DBG_CHKOBJ( pView, EditView, 0 );
+ pView->pImpEditView->SetEditSelection( aSel );
+ }
+
+ return aPaM;
+}
+
+EditPaM ImpEditEngine::RemoveText()
+{
+ InitDoc( TRUE );
+
+ EditPaM aStartPaM = aEditDoc.GetStartPaM();
+ EditSelection aEmptySel( aStartPaM, aStartPaM );
+ for ( USHORT nView = 0; nView < aEditViews.Count(); nView++ )
+ {
+ EditView* pView = aEditViews.GetObject(nView);
+ DBG_CHKOBJ( pView, EditView, 0 );
+ pView->pImpEditView->SetEditSelection( aEmptySel );
+ }
+ ResetUndoManager();
+ return aEditDoc.GetStartPaM();
+}
+
+
+void ImpEditEngine::SetText( const XubString& rText )
+{
+ // RemoveText loescht die Undo-Liste!
+ EditPaM aStartPaM = RemoveText();
+ BOOL bUndoCurrentlyEnabled = IsUndoEnabled();
+ // Der von Hand reingesteckte Text kann nicht vom Anwender rueckgaengig gemacht werden.
+ EnableUndo( FALSE );
+
+ EditSelection aEmptySel( aStartPaM, aStartPaM );
+ EditPaM aPaM = aStartPaM;
+ if ( rText.Len() )
+ aPaM = ImpInsertText( aEmptySel, rText );
+
+ for ( USHORT nView = 0; nView < aEditViews.Count(); nView++ )
+ {
+ EditView* pView = aEditViews[nView];
+ DBG_CHKOBJ( pView, EditView, 0 );
+ pView->pImpEditView->SetEditSelection( EditSelection( aPaM, aPaM ) );
+ // Wenn kein Text, dann auch Kein Format&Update
+ // => Der Text bleibt stehen.
+ if ( !rText.Len() && GetUpdateMode() )
+ {
+ Rectangle aTmpRec( pView->GetOutputArea().TopLeft(),
+ Size( aPaperSize.Width(), nCurTextHeight ) );
+ aTmpRec.Intersection( pView->GetOutputArea() );
+ pView->GetWindow()->Invalidate( aTmpRec );
+ }
+ }
+ if( !rText.Len() ) // sonst muss spaeter noch invalidiert werden, !bFormatted reicht.
+ nCurTextHeight = 0;
+ EnableUndo( bUndoCurrentlyEnabled );
+#ifndef SVX_LIGHT
+ DBG_ASSERT( !HasUndoManager() || !GetUndoManager().GetUndoActionCount(), "Undo nach SetText?" );
+#endif
+}
+
+
+const SfxItemSet& ImpEditEngine::GetEmptyItemSet()
+{
+ if ( !pEmptyItemSet )
+ {
+ pEmptyItemSet = new SfxItemSet( aEditDoc.GetItemPool(), EE_ITEMS_START, EE_ITEMS_END );
+ for ( USHORT nWhich = EE_ITEMS_START; nWhich <= EE_CHAR_END; nWhich++)
+ {
+ pEmptyItemSet->ClearItem( nWhich );
+ }
+ }
+ return *pEmptyItemSet;
+}
+
+// ----------------------------------------------------------------------
+// MISC
+// ----------------------------------------------------------------------
+void ImpEditEngine::CursorMoved( ContentNode* pPrevNode )
+{
+ // Leere Attribute loeschen, aber nur, wenn Absatz nicht leer!
+ if ( pPrevNode->GetCharAttribs().HasEmptyAttribs() && pPrevNode->Len() )
+ pPrevNode->GetCharAttribs().DeleteEmptyAttribs( aEditDoc.GetItemPool() );
+}
+
+void ImpEditEngine::TextModified()
+{
+ bFormatted = FALSE;
+
+ if ( GetNotifyHdl().IsSet() )
+ {
+ EENotify aNotify( EE_NOTIFY_TEXTMODIFIED );
+ aNotify.pEditEngine = GetEditEnginePtr();
+ CallNotify( aNotify );
+ }
+}
+
+
+void ImpEditEngine::ParaAttribsChanged( ContentNode* pNode )
+{
+ DBG_ASSERT( pNode, "ParaAttribsChanged: Welcher?" );
+
+ aEditDoc.SetModified( TRUE );
+ bFormatted = FALSE;
+
+ ParaPortion* pPortion = FindParaPortion( pNode );
+ DBG_ASSERT( pPortion, "ParaAttribsChanged: Portion?" );
+ pPortion->MarkSelectionInvalid( 0, pNode->Len() );
+
+ USHORT nPara = aEditDoc.GetPos( pNode );
+ pEditEngine->ParaAttribsChanged( nPara );
+
+ ParaPortion* pNextPortion = GetParaPortions().SaveGetObject( nPara+1 );
+ // => wird sowieso noch formatiert, wenn Invalid.
+ if ( pNextPortion && !pNextPortion->IsInvalid() )
+ CalcHeight( pNextPortion );
+}
+
+// ----------------------------------------------------------------------
+// Cursorbewegungen
+// ----------------------------------------------------------------------
+
+EditSelection ImpEditEngine::MoveCursor( const KeyEvent& rKeyEvent, EditView* pEditView )
+{
+ // Eigentlich nur bei Up/Down noetig, aber was solls.
+ CheckIdleFormatter();
+
+ EditPaM aPaM( pEditView->pImpEditView->GetEditSelection().Max() );
+
+ EditPaM aOldPaM( aPaM );
+
+ TextDirectionality eTextDirection = TextDirectionality_LeftToRight_TopToBottom;
+ if ( IsVertical() )
+ eTextDirection = TextDirectionality_TopToBottom_RightToLeft;
+ else if ( IsRightToLeft( GetEditDoc().GetPos( aPaM.GetNode() ) ) )
+ eTextDirection = TextDirectionality_RightToLeft_TopToBottom;
+
+ KeyEvent aTranslatedKeyEvent = rKeyEvent.LogicalTextDirectionality( eTextDirection );
+
+ BOOL bCtrl = aTranslatedKeyEvent.GetKeyCode().IsMod1() ? TRUE : FALSE;
+ USHORT nCode = aTranslatedKeyEvent.GetKeyCode().GetCode();
+
+ if ( DoVisualCursorTraveling( aPaM.GetNode() ) )
+ {
+ // Only for simple cursor movement...
+ if ( !bCtrl && ( ( nCode == KEY_LEFT ) || ( nCode == KEY_RIGHT ) ) )
+ {
+ aPaM = CursorVisualLeftRight( pEditView, aPaM, rKeyEvent.GetKeyCode().IsMod2() ? i18n::CharacterIteratorMode::SKIPCHARACTER : i18n::CharacterIteratorMode::SKIPCELL, rKeyEvent.GetKeyCode().GetCode() == KEY_LEFT );
+ nCode = 0; // skip switch statement
+ }
+ /*
+ else if ( !bCtrl && ( ( nCode == KEY_HOME ) || ( nCode == KEY_END ) ) )
+ {
+ aPaM = CursorVisualStartEnd( pEditView, aPaM, nCode == KEY_HOME );
+ nCode = 0; // skip switch statement
+ }
+ */
+ }
+
+ bool bKeyModifySelection = aTranslatedKeyEvent.GetKeyCode().IsShift();
+ switch ( nCode )
+ {
+ case KEY_UP: aPaM = CursorUp( aPaM, pEditView );
+ break;
+ case KEY_DOWN: aPaM = CursorDown( aPaM, pEditView );
+ break;
+ case KEY_LEFT: aPaM = bCtrl ? WordLeft( aPaM ) : CursorLeft( aPaM, aTranslatedKeyEvent.GetKeyCode().IsMod2() ? i18n::CharacterIteratorMode::SKIPCHARACTER : i18n::CharacterIteratorMode::SKIPCELL );
+ break;
+ case KEY_RIGHT: aPaM = bCtrl ? WordRight( aPaM ) : CursorRight( aPaM, aTranslatedKeyEvent.GetKeyCode().IsMod2() ? i18n::CharacterIteratorMode::SKIPCHARACTER : i18n::CharacterIteratorMode::SKIPCELL );
+ break;
+ case KEY_HOME: aPaM = bCtrl ? CursorStartOfDoc() : CursorStartOfLine( aPaM );
+ break;
+ case KEY_END: aPaM = bCtrl ? CursorEndOfDoc() : CursorEndOfLine( aPaM );
+ break;
+ case KEY_PAGEUP: aPaM = bCtrl ? CursorStartOfDoc() : PageUp( aPaM, pEditView );
+ break;
+ case KEY_PAGEDOWN: aPaM = bCtrl ? CursorEndOfDoc() : PageDown( aPaM, pEditView );
+ break;
+ case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE:
+ aPaM = CursorStartOfLine( aPaM );
+ bKeyModifySelection = false;
+ break;
+ case com::sun::star::awt::Key::MOVE_TO_END_OF_LINE:
+ aPaM = CursorEndOfLine( aPaM );
+ bKeyModifySelection = false;
+ break;
+ case com::sun::star::awt::Key::MOVE_WORD_BACKWARD:
+ aPaM = WordLeft( aPaM );
+ bKeyModifySelection = false;
+ break;
+ case com::sun::star::awt::Key::MOVE_WORD_FORWARD:
+ aPaM = WordRight( aPaM );
+ bKeyModifySelection = false;
+ break;
+ case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH:
+ aPaM = CursorStartOfParagraph( aPaM );
+ if( aPaM == aOldPaM )
+ {
+ aPaM = CursorLeft( aPaM, i18n::CharacterIteratorMode::SKIPCELL );
+ aPaM = CursorStartOfParagraph( aPaM );
+ }
+ bKeyModifySelection = false;
+ break;
+ case com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH:
+ aPaM = CursorEndOfParagraph( aPaM );
+ if( aPaM == aOldPaM )
+ {
+ aPaM = CursorRight( aPaM, i18n::CharacterIteratorMode::SKIPCELL );
+ aPaM = CursorEndOfParagraph( aPaM );
+ }
+ bKeyModifySelection = false;
+ break;
+ case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT:
+ aPaM = CursorStartOfDoc();
+ bKeyModifySelection = false;
+ break;
+ case com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT:
+ aPaM = CursorEndOfDoc();
+ bKeyModifySelection = false;
+ break;
+ case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE:
+ aPaM = CursorStartOfLine( aPaM );
+ bKeyModifySelection = true;
+ break;
+ case com::sun::star::awt::Key::SELECT_TO_END_OF_LINE:
+ aPaM = CursorEndOfLine( aPaM );
+ bKeyModifySelection = true;
+ break;
+ case com::sun::star::awt::Key::SELECT_BACKWARD:
+ aPaM = CursorLeft( aPaM, i18n::CharacterIteratorMode::SKIPCELL );
+ bKeyModifySelection = true;
+ break;
+ case com::sun::star::awt::Key::SELECT_FORWARD:
+ aPaM = CursorRight( aPaM, i18n::CharacterIteratorMode::SKIPCELL );
+ bKeyModifySelection = true;
+ break;
+ case com::sun::star::awt::Key::SELECT_WORD_BACKWARD:
+ aPaM = WordLeft( aPaM );
+ bKeyModifySelection = true;
+ break;
+ case com::sun::star::awt::Key::SELECT_WORD_FORWARD:
+ aPaM = WordRight( aPaM );
+ bKeyModifySelection = true;
+ break;
+ case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH:
+ aPaM = CursorStartOfParagraph( aPaM );
+ if( aPaM == aOldPaM )
+ {
+ aPaM = CursorLeft( aPaM, i18n::CharacterIteratorMode::SKIPCELL );
+ aPaM = CursorStartOfParagraph( aPaM );
+ }
+ bKeyModifySelection = true;
+ break;
+ case com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH:
+ aPaM = CursorEndOfParagraph( aPaM );
+ if( aPaM == aOldPaM )
+ {
+ aPaM = CursorRight( aPaM, i18n::CharacterIteratorMode::SKIPCELL );
+ aPaM = CursorEndOfParagraph( aPaM );
+ }
+ bKeyModifySelection = true;
+ break;
+ case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT:
+ aPaM = CursorStartOfDoc();
+ bKeyModifySelection = true;
+ break;
+ case com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT:
+ aPaM = CursorEndOfDoc();
+ bKeyModifySelection = true;
+ break;
+ }
+
+ if ( aOldPaM != aPaM )
+ {
+ CursorMoved( aOldPaM.GetNode() );
+ if ( aStatus.NotifyCursorMovements() && ( aOldPaM.GetNode() != aPaM.GetNode() ) )
+ {
+ aStatus.GetStatusWord() = aStatus.GetStatusWord() | EE_STAT_CRSRLEFTPARA;
+ aStatus.GetPrevParagraph() = aEditDoc.GetPos( aOldPaM.GetNode() );
+ }
+ }
+ else
+ aStatus.GetStatusWord() = aStatus.GetStatusWord() | EE_STAT_CRSRMOVEFAIL;
+
+ // Bewirkt evtl. ein CreateAnchor oder Deselection all
+ aSelEngine.SetCurView( pEditView );
+ aSelEngine.CursorPosChanging( bKeyModifySelection, aTranslatedKeyEvent.GetKeyCode().IsMod1() );
+ EditPaM aOldEnd( pEditView->pImpEditView->GetEditSelection().Max() );
+ pEditView->pImpEditView->GetEditSelection().Max() = aPaM;
+ if ( bKeyModifySelection )
+ {
+ // Dann wird die Selektion erweitert...
+ EditSelection aTmpNewSel( aOldEnd, aPaM );
+ pEditView->pImpEditView->DrawSelection( aTmpNewSel );
+ }
+ else
+ pEditView->pImpEditView->GetEditSelection().Min() = aPaM;
+
+ return pEditView->pImpEditView->GetEditSelection();
+}
+
+EditPaM ImpEditEngine::CursorVisualStartEnd( EditView* pEditView, const EditPaM& rPaM, BOOL bStart )
+{
+ EditPaM aPaM( rPaM );
+
+ USHORT nPara = GetEditDoc().GetPos( aPaM.GetNode() );
+ ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
+
+ USHORT nLine = pParaPortion->GetLines().FindLine( aPaM.GetIndex(), sal_False );
+ EditLine* pLine = pParaPortion->GetLines().GetObject( nLine );
+ BOOL bEmptyLine = pLine->GetStart() == pLine->GetEnd();
+
+ pEditView->pImpEditView->nExtraCursorFlags = 0;
+
+ if ( !bEmptyLine )
+ {
+ String aLine( *aPaM.GetNode(), pLine->GetStart(), pLine->GetEnd() - pLine->GetStart() );
+// USHORT nPosInLine = aPaM.GetIndex() - pLine->GetStart();
+
+ const sal_Unicode* pLineString = aLine.GetBuffer();
+
+ UErrorCode nError = U_ZERO_ERROR;
+ UBiDi* pBidi = ubidi_openSized( aLine.Len(), 0, &nError );
+
+ const UBiDiLevel nBidiLevel = IsRightToLeft( nPara ) ? 1 /*RTL*/ : 0 /*LTR*/;
+ ubidi_setPara( pBidi, reinterpret_cast<const UChar *>(pLineString), aLine.Len(), nBidiLevel, NULL, &nError ); // UChar != sal_Unicode in MinGW
+
+ USHORT nVisPos = bStart ? 0 : aLine.Len()-1;
+ USHORT nLogPos = (USHORT)ubidi_getLogicalIndex( pBidi, nVisPos, &nError );
+
+ ubidi_close( pBidi );
+
+ aPaM.GetIndex() = nLogPos + pLine->GetStart();
+
+ USHORT nTmp;
+ USHORT nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nTmp, TRUE );
+ TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
+ USHORT nRTLLevel = pTextPortion->GetRightToLeft();
+// BOOL bParaRTL = IsRightToLeft( nPara );
+ BOOL bPortionRTL = nRTLLevel%2 ? TRUE : FALSE;
+
+ if ( bStart )
+ {
+ pEditView->pImpEditView->SetCursorBidiLevel( bPortionRTL ? 0 : 1 );
+ // Maybe we must be *behind* the character
+ if ( bPortionRTL && pEditView->IsInsertMode() )
+ aPaM.GetIndex()++;
+ }
+ else
+ {
+ pEditView->pImpEditView->SetCursorBidiLevel( bPortionRTL ? 1 : 0 );
+ if ( !bPortionRTL && pEditView->IsInsertMode() )
+ aPaM.GetIndex()++;
+ }
+ }
+
+ return aPaM;
+}
+
+EditPaM ImpEditEngine::CursorVisualLeftRight( EditView* pEditView, const EditPaM& rPaM, USHORT nCharacterIteratorMode, BOOL bVisualToLeft )
+{
+ EditPaM aPaM( rPaM );
+
+ USHORT nPara = GetEditDoc().GetPos( aPaM.GetNode() );
+ ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
+
+ USHORT nLine = pParaPortion->GetLines().FindLine( aPaM.GetIndex(), sal_False );
+ EditLine* pLine = pParaPortion->GetLines().GetObject( nLine );
+ BOOL bEmptyLine = pLine->GetStart() == pLine->GetEnd();
+
+// USHORT nCurrentCursorFlags = pEditView->pImpEditView->nExtraCursorFlags;
+ pEditView->pImpEditView->nExtraCursorFlags = 0;
+
+ BOOL bParaRTL = IsRightToLeft( nPara );
+
+ BOOL bDone = FALSE;
+
+ if ( bEmptyLine )
+ {
+ if ( bVisualToLeft )
+ {
+ aPaM = CursorUp( aPaM, pEditView );
+ if ( aPaM != rPaM )
+ aPaM = CursorVisualStartEnd( pEditView, aPaM, FALSE );
+ }
+ else
+ {
+ aPaM = CursorDown( aPaM, pEditView );
+ if ( aPaM != rPaM )
+ aPaM = CursorVisualStartEnd( pEditView, aPaM, TRUE );
+ }
+
+ bDone = TRUE;
+ }
+
+ BOOL bLogicalBackward = bParaRTL ? !bVisualToLeft : bVisualToLeft;
+
+ if ( !bDone && pEditView->IsInsertMode() )
+ {
+ // Check if we are within a portion and don't have overwrite mode, then it's easy...
+ USHORT nPortionStart;
+ USHORT nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nPortionStart, FALSE );
+ TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
+
+ BOOL bPortionBoundary = ( aPaM.GetIndex() == nPortionStart ) || ( aPaM.GetIndex() == (nPortionStart+pTextPortion->GetLen()) );
+ USHORT nRTLLevel = pTextPortion->GetRightToLeft();
+
+ // Portion boundary doesn't matter if both have same RTL level
+ USHORT nRTLLevelNextPortion = 0xFFFF;
+ if ( bPortionBoundary && aPaM.GetIndex() && ( aPaM.GetIndex() < aPaM.GetNode()->Len() ) )
+ {
+ USHORT nTmp;
+ USHORT nNextTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex()+1, nTmp, bLogicalBackward ? FALSE : TRUE );
+ TextPortion* pNextTextPortion = pParaPortion->GetTextPortions().GetObject( nNextTextPortion );
+ nRTLLevelNextPortion = pNextTextPortion->GetRightToLeft();
+ }
+
+ if ( !bPortionBoundary || ( nRTLLevel == nRTLLevelNextPortion ) )
+ {
+ if ( ( bVisualToLeft && !(nRTLLevel%2) ) || ( !bVisualToLeft && (nRTLLevel%2) ) )
+ {
+ aPaM = CursorLeft( aPaM, nCharacterIteratorMode );
+ pEditView->pImpEditView->SetCursorBidiLevel( 1 );
+ }
+ else
+ {
+ aPaM = CursorRight( aPaM, nCharacterIteratorMode );
+ pEditView->pImpEditView->SetCursorBidiLevel( 0 );
+ }
+ bDone = TRUE;
+ }
+ }
+
+ if ( !bDone )
+ {
+ BOOL bGotoStartOfNextLine = FALSE;
+ BOOL bGotoEndOfPrevLine = FALSE;
+
+ String aLine( *aPaM.GetNode(), pLine->GetStart(), pLine->GetEnd() - pLine->GetStart() );
+ USHORT nPosInLine = aPaM.GetIndex() - pLine->GetStart();
+
+ const sal_Unicode* pLineString = aLine.GetBuffer();
+
+ UErrorCode nError = U_ZERO_ERROR;
+ UBiDi* pBidi = ubidi_openSized( aLine.Len(), 0, &nError );
+
+ const UBiDiLevel nBidiLevel = IsRightToLeft( nPara ) ? 1 /*RTL*/ : 0 /*LTR*/;
+ ubidi_setPara( pBidi, reinterpret_cast<const UChar *>(pLineString), aLine.Len(), nBidiLevel, NULL, &nError ); // UChar != sal_Unicode in MinGW
+
+ if ( !pEditView->IsInsertMode() )
+ {
+ BOOL bEndOfLine = nPosInLine == aLine.Len();
+ USHORT nVisPos = (USHORT)ubidi_getVisualIndex( pBidi, !bEndOfLine ? nPosInLine : nPosInLine-1, &nError );
+ if ( bVisualToLeft )
+ {
+ bGotoEndOfPrevLine = nVisPos == 0;
+ if ( !bEndOfLine )
+ nVisPos--;
+ }
+ else
+ {
+ bGotoStartOfNextLine = nVisPos == (aLine.Len() - 1);
+ if ( !bEndOfLine )
+ nVisPos++;
+ }
+
+ if ( !bGotoEndOfPrevLine && !bGotoStartOfNextLine )
+ {
+ USHORT nLogPos = (USHORT)ubidi_getLogicalIndex( pBidi, nVisPos, &nError );
+ aPaM.GetIndex() = pLine->GetStart() + nLogPos;
+ pEditView->pImpEditView->SetCursorBidiLevel( 0 );
+ }
+ }
+ else
+ {
+ BOOL bWasBehind = FALSE;
+ BOOL bBeforePortion = !nPosInLine || pEditView->pImpEditView->GetCursorBidiLevel() == 1;
+ if ( nPosInLine && ( !bBeforePortion ) ) // before the next portion
+ bWasBehind = TRUE; // step one back, otherwise visual will be unusable when rtl portion follows.
+
+ USHORT nPortionStart;
+ USHORT nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nPortionStart, bBeforePortion );
+ TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
+ BOOL bRTLPortion = (pTextPortion->GetRightToLeft() % 2) != 0;
+
+ // -1: We are 'behind' the character
+ long nVisPos = (long)ubidi_getVisualIndex( pBidi, bWasBehind ? nPosInLine-1 : nPosInLine, &nError );
+ if ( bVisualToLeft )
+ {
+ if ( !bWasBehind || bRTLPortion )
+ nVisPos--;
+ }
+ else
+ {
+ if ( bWasBehind || bRTLPortion || bBeforePortion )
+ nVisPos++;
+// if ( bWasBehind && bRTLPortion )
+// nVisPos++;
+ }
+
+ bGotoEndOfPrevLine = nVisPos < 0;
+ bGotoStartOfNextLine = nVisPos >= aLine.Len();
+
+ if ( !bGotoEndOfPrevLine && !bGotoStartOfNextLine )
+ {
+ USHORT nLogPos = (USHORT)ubidi_getLogicalIndex( pBidi, nVisPos, &nError );
+
+/*
+ if ( nLogPos == aPaM.GetIndex() )
+ {
+ if ( bVisualToLeft )
+ bGotoEndOfPrevLine = TRUE;
+ else
+ bGotoStartOfNextLine = TRUE;
+ }
+ else
+*/
+ {
+ aPaM.GetIndex() = pLine->GetStart() + nLogPos;
+
+ // RTL portion, stay visually on the left side.
+ USHORT _nPortionStart;
+ // USHORT nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nPortionStart, !bRTLPortion );
+ USHORT _nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), _nPortionStart, TRUE );
+ TextPortion* _pTextPortion = pParaPortion->GetTextPortions().GetObject( _nTextPortion );
+ if ( bVisualToLeft && !bRTLPortion && ( _pTextPortion->GetRightToLeft() % 2 ) )
+ aPaM.GetIndex()++;
+ else if ( !bVisualToLeft && bRTLPortion && ( bWasBehind || !(_pTextPortion->GetRightToLeft() % 2 )) )
+ aPaM.GetIndex()++;
+
+ pEditView->pImpEditView->SetCursorBidiLevel( _nPortionStart );
+ }
+ }
+ }
+
+ ubidi_close( pBidi );
+
+ if ( bGotoEndOfPrevLine )
+ {
+ aPaM = CursorUp( aPaM, pEditView );
+ if ( aPaM != rPaM )
+ aPaM = CursorVisualStartEnd( pEditView, aPaM, FALSE );
+ }
+ else if ( bGotoStartOfNextLine )
+ {
+ aPaM = CursorDown( aPaM, pEditView );
+ if ( aPaM != rPaM )
+ aPaM = CursorVisualStartEnd( pEditView, aPaM, TRUE );
+ }
+ }
+ return aPaM;
+}
+
+
+EditPaM ImpEditEngine::CursorLeft( const EditPaM& rPaM, USHORT nCharacterIteratorMode )
+{
+ EditPaM aCurPaM( rPaM );
+ EditPaM aNewPaM( aCurPaM );
+
+ if ( aCurPaM.GetIndex() )
+ {
+ sal_Int32 nCount = 1;
+ uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
+ aNewPaM.SetIndex( (USHORT)_xBI->previousCharacters( *aNewPaM.GetNode(), aNewPaM.GetIndex(), GetLocale( aNewPaM ), nCharacterIteratorMode, nCount, nCount ) );
+ }
+ else
+ {
+ ContentNode* pNode = aCurPaM.GetNode();
+ pNode = GetPrevVisNode( pNode );
+ if ( pNode )
+ {
+ aNewPaM.SetNode( pNode );
+ aNewPaM.SetIndex( pNode->Len() );
+ }
+ }
+
+ return aNewPaM;
+}
+
+EditPaM ImpEditEngine::CursorRight( const EditPaM& rPaM, USHORT nCharacterIteratorMode )
+{
+ EditPaM aCurPaM( rPaM );
+ EditPaM aNewPaM( aCurPaM );
+
+ if ( aCurPaM.GetIndex() < aCurPaM.GetNode()->Len() )
+ {
+ uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
+ sal_Int32 nCount = 1;
+ aNewPaM.SetIndex( (USHORT)_xBI->nextCharacters( *aNewPaM.GetNode(), aNewPaM.GetIndex(), GetLocale( aNewPaM ), nCharacterIteratorMode, nCount, nCount ) );
+ }
+ else
+ {
+ ContentNode* pNode = aCurPaM.GetNode();
+ pNode = GetNextVisNode( pNode );
+ if ( pNode )
+ {
+ aNewPaM.SetNode( pNode );
+ aNewPaM.SetIndex( 0 );
+ }
+ }
+
+ return aNewPaM;
+}
+
+EditPaM ImpEditEngine::CursorUp( const EditPaM& rPaM, EditView* pView )
+{
+ DBG_ASSERT( pView, "Keine View - Keine Cursorbewegung!" );
+
+ ParaPortion* pPPortion = FindParaPortion( rPaM.GetNode() );
+ DBG_ASSERT( pPPortion, "Keine passende Portion gefunden: CursorUp" );
+ USHORT nLine = pPPortion->GetLineNumber( rPaM.GetIndex() );
+ EditLine* pLine = pPPortion->GetLines().GetObject( nLine );
+
+ long nX;
+ if ( pView->pImpEditView->nTravelXPos == TRAVEL_X_DONTKNOW )
+ {
+ nX = GetXPos( pPPortion, pLine, rPaM.GetIndex() );
+ pView->pImpEditView->nTravelXPos = nX+nOnePixelInRef;
+ }
+ else
+ nX = pView->pImpEditView->nTravelXPos;
+
+ EditPaM aNewPaM( rPaM );
+ if ( nLine ) // gleicher Absatz
+ {
+ EditLine* pPrevLine = pPPortion->GetLines().GetObject(nLine-1);
+ aNewPaM.SetIndex( GetChar( pPPortion, pPrevLine, nX ) );
+ // Wenn davor eine autom.Umgebrochene Zeile, und ich muss genau an das
+ // Ende dieser Zeile, landet der Cursor in der aktuellen Zeile am Anfang
+ // Siehe Problem: Letztes Zeichen einer autom.umgebr. Zeile = Cursor
+ if ( aNewPaM.GetIndex() && ( aNewPaM.GetIndex() == pLine->GetStart() ) )
+ aNewPaM = CursorLeft( aNewPaM );
+ }
+ else // vorheriger Absatz
+ {
+ ParaPortion* pPrevPortion = GetPrevVisPortion( pPPortion );
+ if ( pPrevPortion )
+ {
+ pLine = pPrevPortion->GetLines().GetObject( pPrevPortion->GetLines().Count()-1 );
+ DBG_ASSERT( pLine, "Zeile davor nicht gefunden: CursorUp" );
+ aNewPaM.SetNode( pPrevPortion->GetNode() );
+ aNewPaM.SetIndex( GetChar( pPrevPortion, pLine, nX+nOnePixelInRef ) );
+ }
+ }
+
+ return aNewPaM;
+}
+
+EditPaM ImpEditEngine::CursorDown( const EditPaM& rPaM, EditView* pView )
+{
+ DBG_ASSERT( pView, "Keine View - Keine Cursorbewegung!" );
+
+ ParaPortion* pPPortion = FindParaPortion( rPaM.GetNode() );
+ DBG_ASSERT( pPPortion, "Keine passende Portion gefunden: CursorDown" );
+ USHORT nLine = pPPortion->GetLineNumber( rPaM.GetIndex() );
+
+ long nX;
+ if ( pView->pImpEditView->nTravelXPos == TRAVEL_X_DONTKNOW )
+ {
+ EditLine* pLine = pPPortion->GetLines().GetObject(nLine);
+ nX = GetXPos( pPPortion, pLine, rPaM.GetIndex() );
+ pView->pImpEditView->nTravelXPos = nX+nOnePixelInRef;
+ }
+ else
+ nX = pView->pImpEditView->nTravelXPos;
+
+ EditPaM aNewPaM( rPaM );
+ if ( nLine < pPPortion->GetLines().Count()-1 )
+ {
+ EditLine* pNextLine = pPPortion->GetLines().GetObject(nLine+1);
+ aNewPaM.SetIndex( GetChar( pPPortion, pNextLine, nX ) );
+ // Sonderbehandlung siehe CursorUp...
+ if ( ( aNewPaM.GetIndex() == pNextLine->GetEnd() ) && ( aNewPaM.GetIndex() > pNextLine->GetStart() ) && ( aNewPaM.GetIndex() < pPPortion->GetNode()->Len() ) )
+ aNewPaM = CursorLeft( aNewPaM );
+ }
+ else // naechster Absatz
+ {
+ ParaPortion* pNextPortion = GetNextVisPortion( pPPortion );
+ if ( pNextPortion )
+ {
+ EditLine* pLine = pNextPortion->GetLines().GetObject(0);
+ DBG_ASSERT( pLine, "Zeile davor nicht gefunden: CursorUp" );
+ aNewPaM.SetNode( pNextPortion->GetNode() );
+ // Nie ganz ans Ende wenn mehrere Zeilen, da dann eine
+ // Zeile darunter der Cursor angezeigt wird.
+ aNewPaM.SetIndex( GetChar( pNextPortion, pLine, nX+nOnePixelInRef ) );
+ if ( ( aNewPaM.GetIndex() == pLine->GetEnd() ) && ( aNewPaM.GetIndex() > pLine->GetStart() ) && ( pNextPortion->GetLines().Count() > 1 ) )
+ aNewPaM = CursorLeft( aNewPaM );
+ }
+ }
+
+ return aNewPaM;
+}
+
+EditPaM ImpEditEngine::CursorStartOfLine( const EditPaM& rPaM )
+{
+ ParaPortion* pCurPortion = FindParaPortion( rPaM.GetNode() );
+ DBG_ASSERT( pCurPortion, "Keine Portion fuer den PaM ?" );
+ USHORT nLine = pCurPortion->GetLineNumber( rPaM.GetIndex() );
+ EditLine* pLine = pCurPortion->GetLines().GetObject(nLine);
+ DBG_ASSERT( pLine, "Aktuelle Zeile nicht gefunden ?!" );
+
+ EditPaM aNewPaM( rPaM );
+ aNewPaM.SetIndex( pLine->GetStart() );
+ return aNewPaM;
+}
+
+EditPaM ImpEditEngine::CursorEndOfLine( const EditPaM& rPaM )
+{
+ ParaPortion* pCurPortion = FindParaPortion( rPaM.GetNode() );
+ DBG_ASSERT( pCurPortion, "Keine Portion fuer den PaM ?" );
+ USHORT nLine = pCurPortion->GetLineNumber( rPaM.GetIndex() );
+ EditLine* pLine = pCurPortion->GetLines().GetObject(nLine);
+ DBG_ASSERT( pLine, "Aktuelle Zeile nicht gefunden ?!" );
+
+ EditPaM aNewPaM( rPaM );
+ aNewPaM.SetIndex( pLine->GetEnd() );
+ if ( pLine->GetEnd() > pLine->GetStart() )
+ {
+// xub_Unicode cLastChar = aNewPaM.GetNode()->GetChar( aNewPaM.GetIndex()-1 );
+ if ( aNewPaM.GetNode()->IsFeature( aNewPaM.GetIndex() - 1 ) )
+ {
+ // Bei einem weichen Umbruch muss ich davor stehen!
+ EditCharAttrib* pNextFeature = aNewPaM.GetNode()->GetCharAttribs().FindFeature( aNewPaM.GetIndex()-1 );
+ if ( pNextFeature && ( pNextFeature->GetItem()->Which() == EE_FEATURE_LINEBR ) )
+ aNewPaM = CursorLeft( aNewPaM );
+ }
+ else if ( ( aNewPaM.GetNode()->GetChar( aNewPaM.GetIndex() - 1 ) == ' ' ) && ( aNewPaM.GetIndex() != aNewPaM.GetNode()->Len() ) )
+ {
+ // Bei einem Blank in einer autom. umgebrochenen Zeile macht es Sinn,
+ // davor zu stehen, da der Anwender hinter das Wort will.
+ // Wenn diese geaendert wird, Sonderbehandlung fuer Pos1 nach End!
+ aNewPaM = CursorLeft( aNewPaM );
+ }
+ }
+ return aNewPaM;
+}
+
+EditPaM ImpEditEngine::CursorStartOfParagraph( const EditPaM& rPaM )
+{
+ EditPaM aPaM( rPaM.GetNode(), 0 );
+ return aPaM;
+}
+
+EditPaM ImpEditEngine::CursorEndOfParagraph( const EditPaM& rPaM )
+{
+ EditPaM aPaM( rPaM.GetNode(), rPaM.GetNode()->Len() );
+ return aPaM;
+}
+
+EditPaM ImpEditEngine::CursorStartOfDoc()
+{
+ EditPaM aPaM( aEditDoc.SaveGetObject( 0 ), 0 );
+ return aPaM;
+}
+
+EditPaM ImpEditEngine::CursorEndOfDoc()
+{
+ ContentNode* pLastNode = aEditDoc.SaveGetObject( aEditDoc.Count()-1 );
+ ParaPortion* pLastPortion = GetParaPortions().SaveGetObject( aEditDoc.Count()-1 );
+ DBG_ASSERT( pLastNode && pLastPortion, "CursorEndOfDoc: Node oder Portion nicht gefunden" );
+
+ if ( !pLastPortion->IsVisible() )
+ {
+ pLastNode = GetPrevVisNode( pLastPortion->GetNode() );
+ DBG_ASSERT( pLastNode, "Kein sichtbarer Absatz?" );
+ if ( !pLastNode )
+ pLastNode = aEditDoc.SaveGetObject( aEditDoc.Count()-1 );
+ }
+
+ EditPaM aPaM( pLastNode, pLastNode->Len() );
+ return aPaM;
+}
+
+EditPaM ImpEditEngine::PageUp( const EditPaM& rPaM, EditView* pView )
+{
+ Rectangle aRec = PaMtoEditCursor( rPaM );
+ Point aTopLeft = aRec.TopLeft();
+ aTopLeft.Y() -= pView->GetVisArea().GetHeight() *9/10;
+ aTopLeft.X() += nOnePixelInRef;
+ if ( aTopLeft.Y() < 0 )
+ {
+ aTopLeft.Y() = 0;
+ }
+ return GetPaM( aTopLeft );
+}
+
+EditPaM ImpEditEngine::PageDown( const EditPaM& rPaM, EditView* pView )
+{
+ Rectangle aRec = PaMtoEditCursor( rPaM );
+ Point aBottomRight = aRec.BottomRight();
+ aBottomRight.Y() += pView->GetVisArea().GetHeight() *9/10;
+ aBottomRight.X() += nOnePixelInRef;
+ long nHeight = GetTextHeight();
+ if ( aBottomRight.Y() > nHeight )
+ {
+ aBottomRight.Y() = nHeight-2;
+ }
+ return GetPaM( aBottomRight );
+}
+
+EditPaM ImpEditEngine::WordLeft( const EditPaM& rPaM, sal_Int16 nWordType )
+{
+ USHORT nCurrentPos = rPaM.GetIndex();
+ EditPaM aNewPaM( rPaM );
+ if ( nCurrentPos == 0 )
+ {
+ // Vorheriger Absatz...
+ USHORT nCurPara = aEditDoc.GetPos( aNewPaM.GetNode() );
+ ContentNode* pPrevNode = aEditDoc.SaveGetObject( --nCurPara );
+ if ( pPrevNode )
+ {
+ aNewPaM.SetNode( pPrevNode );
+ aNewPaM.SetIndex( pPrevNode->Len() );
+ }
+ }
+ else
+ {
+ // we need to increase the position by 1 when retrieving the locale
+ // since the attribute for the char left to the cursor position is returned
+ EditPaM aTmpPaM( aNewPaM );
+ xub_StrLen nMax = rPaM.GetNode()->Len();
+ if ( aTmpPaM.GetIndex() < nMax )
+ aTmpPaM.SetIndex( aTmpPaM.GetIndex() + 1 );
+ lang::Locale aLocale( GetLocale( aTmpPaM ) );
+
+ uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
+ i18n::Boundary aBoundary = _xBI->getWordBoundary( *aNewPaM.GetNode(), nCurrentPos, aLocale, nWordType, sal_True );
+ if ( aBoundary.startPos >= nCurrentPos )
+ aBoundary = _xBI->previousWord( *aNewPaM.GetNode(), nCurrentPos, aLocale, nWordType );
+ aNewPaM.SetIndex( ( aBoundary.startPos != (-1) ) ? (USHORT)aBoundary.startPos : 0 );
+ }
+
+ return aNewPaM;
+}
+
+EditPaM ImpEditEngine::WordRight( const EditPaM& rPaM, sal_Int16 nWordType )
+{
+ xub_StrLen nMax = rPaM.GetNode()->Len();
+ EditPaM aNewPaM( rPaM );
+ if ( aNewPaM.GetIndex() < nMax )
+ {
+ // we need to increase the position by 1 when retrieving the locale
+ // since the attribute for the char left to the cursor position is returned
+ EditPaM aTmpPaM( aNewPaM );
+ aTmpPaM.SetIndex( aTmpPaM.GetIndex() + 1 );
+ lang::Locale aLocale( GetLocale( aTmpPaM ) );
+
+ uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
+ i18n::Boundary aBoundary = _xBI->nextWord( *aNewPaM.GetNode(), aNewPaM.GetIndex(), aLocale, nWordType );
+ aNewPaM.SetIndex( (USHORT)aBoundary.startPos );
+ }
+ // not 'else', maybe the index reached nMax now...
+ if ( aNewPaM.GetIndex() >= nMax )
+ {
+ // Naechster Absatz...
+ USHORT nCurPara = aEditDoc.GetPos( aNewPaM.GetNode() );
+ ContentNode* pNextNode = aEditDoc.SaveGetObject( ++nCurPara );
+ if ( pNextNode )
+ {
+ aNewPaM.SetNode( pNextNode );
+ aNewPaM.SetIndex( 0 );
+ }
+ }
+ return aNewPaM;
+}
+
+EditPaM ImpEditEngine::StartOfWord( const EditPaM& rPaM, sal_Int16 nWordType )
+{
+ EditPaM aNewPaM( rPaM );
+
+ // we need to increase the position by 1 when retrieving the locale
+ // since the attribute for the char left to the cursor position is returned
+ EditPaM aTmpPaM( aNewPaM );
+ xub_StrLen nMax = rPaM.GetNode()->Len();
+ if ( aTmpPaM.GetIndex() < nMax )
+ aTmpPaM.SetIndex( aTmpPaM.GetIndex() + 1 );
+ lang::Locale aLocale( GetLocale( aTmpPaM ) );
+
+ uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
+ i18n::Boundary aBoundary = _xBI->getWordBoundary( *rPaM.GetNode(), rPaM.GetIndex(), aLocale, nWordType, sal_True );
+ aNewPaM.SetIndex( (USHORT)aBoundary.startPos );
+ return aNewPaM;
+}
+
+EditPaM ImpEditEngine::EndOfWord( const EditPaM& rPaM, sal_Int16 nWordType )
+{
+ EditPaM aNewPaM( rPaM );
+
+ // we need to increase the position by 1 when retrieving the locale
+ // since the attribute for the char left to the cursor position is returned
+ EditPaM aTmpPaM( aNewPaM );
+ xub_StrLen nMax = rPaM.GetNode()->Len();
+ if ( aTmpPaM.GetIndex() < nMax )
+ aTmpPaM.SetIndex( aTmpPaM.GetIndex() + 1 );
+ lang::Locale aLocale( GetLocale( aTmpPaM ) );
+
+ uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
+ i18n::Boundary aBoundary = _xBI->getWordBoundary( *rPaM.GetNode(), rPaM.GetIndex(), aLocale, nWordType, sal_True );
+ aNewPaM.SetIndex( (USHORT)aBoundary.endPos );
+ return aNewPaM;
+}
+
+EditSelection ImpEditEngine::SelectWord( const EditSelection& rCurSel, sal_Int16 nWordType, BOOL bAcceptStartOfWord )
+{
+ EditSelection aNewSel( rCurSel );
+ EditPaM aPaM( rCurSel.Max() );
+
+ // we need to increase the position by 1 when retrieving the locale
+ // since the attribute for the char left to the cursor position is returned
+ EditPaM aTmpPaM( aPaM );
+ xub_StrLen nMax = aPaM.GetNode()->Len();
+ if ( aTmpPaM.GetIndex() < nMax )
+ aTmpPaM.SetIndex( aTmpPaM.GetIndex() + 1 );
+ lang::Locale aLocale( GetLocale( aTmpPaM ) );
+
+ uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
+ sal_Int16 nType = _xBI->getWordType( *aPaM.GetNode(), aPaM.GetIndex(), aLocale );
+ if ( nType == i18n::WordType::ANY_WORD )
+ {
+ i18n::Boundary aBoundary = _xBI->getWordBoundary( *aPaM.GetNode(), aPaM.GetIndex(), aLocale, nWordType, sal_True );
+ // don't select when curser at end of word
+ if ( ( aBoundary.endPos > aPaM.GetIndex() ) &&
+ ( ( aBoundary.startPos < aPaM.GetIndex() ) || ( bAcceptStartOfWord && ( aBoundary.startPos == aPaM.GetIndex() ) ) ) )
+ {
+ aNewSel.Min().SetIndex( (USHORT)aBoundary.startPos );
+ aNewSel.Max().SetIndex( (USHORT)aBoundary.endPos );
+ }
+ }
+
+ return aNewSel;
+}
+
+EditSelection ImpEditEngine::SelectSentence( const EditSelection& rCurSel )
+{
+ uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
+ const EditPaM& rPaM = rCurSel.Min();
+ const ContentNode* pNode = rPaM.GetNode();
+ // #i50710# line breaks are marked with 0x01 - the break iterator prefers 0x0a for that
+ String sParagraph(*pNode);
+ sParagraph.SearchAndReplaceAll(0x01,0x0a);
+ //return Null if search starts at the beginning of the string
+ long nStart = rPaM.GetIndex() ? _xBI->beginOfSentence( sParagraph, rPaM.GetIndex(), GetLocale( rPaM ) ) : 0;
+
+ long nEnd = _xBI->endOfSentence( *pNode, rPaM.GetIndex(), GetLocale( rPaM ) );
+ EditSelection aNewSel( rCurSel );
+ DBG_ASSERT(nStart < pNode->Len() && nEnd <= pNode->Len(), "sentence indices out of range");
+ aNewSel.Min().SetIndex( (USHORT)nStart );
+ aNewSel.Max().SetIndex( (USHORT)nEnd );
+ return aNewSel;
+}
+
+sal_Bool ImpEditEngine::IsInputSequenceCheckingRequired( sal_Unicode nChar, const EditSelection& rCurSel ) const
+{
+ uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
+ if (!pCTLOptions)
+ pCTLOptions = new SvtCTLOptions;
+
+ // get the index that really is first
+ USHORT nFirstPos = rCurSel.Min().GetIndex();
+ USHORT nMaxPos = rCurSel.Max().GetIndex();
+ if (nMaxPos < nFirstPos)
+ nFirstPos = nMaxPos;
+
+ sal_Bool bIsSequenceChecking =
+ pCTLOptions->IsCTLFontEnabled() &&
+ pCTLOptions->IsCTLSequenceChecking() &&
+ nFirstPos != 0 && /* first char needs not to be checked */
+ _xBI.is() && i18n::ScriptType::COMPLEX == _xBI->getScriptType( rtl::OUString( nChar ), 0 );
+
+ return bIsSequenceChecking;
+}
+
+/*************************************************************************
+ * lcl_HasStrongLTR
+ *************************************************************************/
+ bool lcl_HasStrongLTR ( const String& rTxt, xub_StrLen nStart, xub_StrLen nEnd )
+ {
+ for ( xub_StrLen nCharIdx = nStart; nCharIdx < nEnd; ++nCharIdx )
+ {
+ const UCharDirection nCharDir = u_charDirection ( rTxt.GetChar ( nCharIdx ));
+ if ( nCharDir == U_LEFT_TO_RIGHT ||
+ nCharDir == U_LEFT_TO_RIGHT_EMBEDDING ||
+ nCharDir == U_LEFT_TO_RIGHT_OVERRIDE )
+ return true;
+ }
+ return false;
+ }
+
+
+
+void ImpEditEngine::InitScriptTypes( USHORT nPara )
+{
+ ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
+ ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
+ rTypes.Remove( 0, rTypes.Count() );
+
+// pParaPortion->aExtraCharInfos.Remove( 0, pParaPortion->aExtraCharInfos.Count() );
+
+ ContentNode* pNode = pParaPortion->GetNode();
+ if ( pNode->Len() )
+ {
+ uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
+
+ String aText( *pNode );
+
+ // To handle fields put the character from the field in the string,
+ // because endOfScript( ... ) will skip the CH_FEATURE, because this is WEAK
+ EditCharAttrib* pField = pNode->GetCharAttribs().FindNextAttrib( EE_FEATURE_FIELD, 0 );
+ while ( pField )
+ {
+ ::rtl::OUString aFldText( ((EditCharAttribField*)pField)->GetFieldValue() );
+ if ( aFldText.getLength() )
+ {
+ aText.SetChar( pField->GetStart(), aFldText.getStr()[0] );
+ short nFldScriptType = _xBI->getScriptType( aFldText, 0 );
+
+ for ( USHORT nCharInField = 1; nCharInField < aFldText.getLength(); nCharInField++ )
+ {
+ short nTmpType = _xBI->getScriptType( aFldText, nCharInField );
+
+ // First char from field wins...
+ if ( nFldScriptType == i18n::ScriptType::WEAK )
+ {
+ nFldScriptType = nTmpType;
+ aText.SetChar( pField->GetStart(), aFldText.getStr()[nCharInField] );
+ }
+
+ // ... but if the first one is LATIN, and there are CJK or CTL chars too,
+ // we prefer that ScripType because we need an other font.
+ if ( ( nTmpType == i18n::ScriptType::ASIAN ) || ( nTmpType == i18n::ScriptType::COMPLEX ) )
+ {
+ aText.SetChar( pField->GetStart(), aFldText.getStr()[nCharInField] );
+ break;
+ }
+ }
+ }
+ // #112831# Last Field might go from 0xffff to 0x0000
+ pField = pField->GetEnd() ? pNode->GetCharAttribs().FindNextAttrib( EE_FEATURE_FIELD, pField->GetEnd() ) : NULL;
+ }
+
+ ::rtl::OUString aOUText( aText );
+ USHORT nTextLen = (USHORT)aOUText.getLength();
+
+ sal_Int32 nPos = 0;
+ short nScriptType = _xBI->getScriptType( aOUText, nPos );
+ rTypes.Insert( ScriptTypePosInfo( nScriptType, (USHORT)nPos, nTextLen ), rTypes.Count() );
+ nPos = _xBI->endOfScript( aOUText, nPos, nScriptType );
+ while ( ( nPos != (-1) ) && ( nPos < nTextLen ) )
+ {
+ rTypes[rTypes.Count()-1].nEndPos = (USHORT)nPos;
+
+ nScriptType = _xBI->getScriptType( aOUText, nPos );
+ long nEndPos = _xBI->endOfScript( aOUText, nPos, nScriptType );
+
+ if ( ( nScriptType == i18n::ScriptType::WEAK ) || ( nScriptType == rTypes[rTypes.Count()-1].nScriptType ) )
+ {
+ // Expand last ScriptTypePosInfo, don't create weak or unecessary portions
+ rTypes[rTypes.Count()-1].nEndPos = (USHORT)nEndPos;
+ }
+ else
+ {
+ if ( _xBI->getScriptType( aOUText, nPos - 1 ) == i18n::ScriptType::WEAK )
+ {
+ switch ( u_charType(aOUText.iterateCodePoints(&nPos, 0) ) ) {
+ case U_NON_SPACING_MARK:
+ case U_ENCLOSING_MARK:
+ case U_COMBINING_SPACING_MARK:
+ --nPos;
+ rTypes[rTypes.Count()-1].nEndPos--;
+ break;
+ }
+ }
+ rTypes.Insert( ScriptTypePosInfo( nScriptType, (USHORT)nPos, nTextLen ), rTypes.Count() );
+ }
+
+ nPos = nEndPos;
+ }
+
+ if ( rTypes[0].nScriptType == i18n::ScriptType::WEAK )
+ rTypes[0].nScriptType = ( rTypes.Count() > 1 ) ? rTypes[1].nScriptType : GetI18NScriptTypeOfLanguage( GetDefaultLanguage() );
+
+ // create writing direction information:
+ if ( !pParaPortion->aWritingDirectionInfos.Count() )
+ InitWritingDirections( nPara );
+
+ // i89825: Use CTL font for numbers embedded into an RTL run:
+ WritingDirectionInfos& rDirInfos = pParaPortion->aWritingDirectionInfos;
+ for ( USHORT n = 0; n < rDirInfos.Count(); ++n )
+ {
+ const xub_StrLen nStart = rDirInfos[n].nStartPos;
+ const xub_StrLen nEnd = rDirInfos[n].nEndPos;
+ const BYTE nCurrDirType = rDirInfos[n].nType;
+
+ if ( nCurrDirType % 2 == UBIDI_RTL || // text in RTL run
+ ( nCurrDirType > UBIDI_LTR && !lcl_HasStrongLTR( aText, nStart, nEnd ) ) ) // non-strong text in embedded LTR run
+ {
+ USHORT nIdx = 0;
+
+ // Skip entries in ScriptArray which are not inside the RTL run:
+ while ( nIdx < rTypes.Count() && rTypes[nIdx].nStartPos < nStart )
+ ++nIdx;
+
+ // Remove any entries *inside* the current run:
+ while ( nIdx < rTypes.Count() && rTypes[nIdx].nEndPos <= nEnd )
+ rTypes.Remove( nIdx );
+
+ // special case:
+ if(nIdx < rTypes.Count() && rTypes[nIdx].nStartPos < nStart && rTypes[nIdx].nEndPos > nEnd)
+ {
+ rTypes.Insert( ScriptTypePosInfo( rTypes[nIdx].nScriptType, (USHORT)nEnd, rTypes[nIdx].nEndPos ), nIdx );
+ rTypes[nIdx].nEndPos = nStart;
+ }
+
+ if( nIdx )
+ rTypes[nIdx - 1].nEndPos = nStart;
+
+ rTypes.Insert( ScriptTypePosInfo( i18n::ScriptType::COMPLEX, (USHORT)nStart, (USHORT)nEnd), nIdx );
+ ++nIdx;
+
+ if( nIdx < rTypes.Count() )
+ rTypes[nIdx].nStartPos = nEnd;
+ }
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ USHORT nDebugStt = 0;
+ USHORT nDebugEnd = 0;
+ short nDebugType = 0;
+ for ( USHORT n = 0; n < rTypes.Count(); ++n )
+ {
+ nDebugStt = rTypes[n].nStartPos;
+ nDebugEnd = rTypes[n].nEndPos;
+ nDebugType = rTypes[n].nScriptType;
+ }
+#endif
+ }
+}
+
+USHORT ImpEditEngine::GetScriptType( const EditPaM& rPaM, USHORT* pEndPos ) const
+{
+ USHORT nScriptType = 0;
+
+ if ( pEndPos )
+ *pEndPos = rPaM.GetNode()->Len();
+
+ if ( rPaM.GetNode()->Len() )
+ {
+ USHORT nPara = GetEditDoc().GetPos( rPaM.GetNode() );
+ ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
+ if ( !pParaPortion->aScriptInfos.Count() )
+ ((ImpEditEngine*)this)->InitScriptTypes( nPara );
+
+ ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
+ USHORT nPos = rPaM.GetIndex();
+ for ( USHORT n = 0; n < rTypes.Count(); n++ )
+ {
+ if ( ( rTypes[n].nStartPos <= nPos ) && ( rTypes[n].nEndPos >= nPos ) )
+ {
+ nScriptType = rTypes[n].nScriptType;
+ if( pEndPos )
+ *pEndPos = rTypes[n].nEndPos;
+ break;
+ }
+ }
+ }
+ return nScriptType ? nScriptType : GetI18NScriptTypeOfLanguage( GetDefaultLanguage() );
+}
+
+USHORT ImpEditEngine::GetScriptType( const EditSelection& rSel ) const
+{
+ EditSelection aSel( rSel );
+ aSel.Adjust( aEditDoc );
+
+ short nScriptType = 0;
+
+ USHORT nStartPara = GetEditDoc().GetPos( aSel.Min().GetNode() );
+ USHORT nEndPara = GetEditDoc().GetPos( aSel.Max().GetNode() );
+
+ for ( USHORT nPara = nStartPara; nPara <= nEndPara; nPara++ )
+ {
+ ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
+ if ( !pParaPortion->aScriptInfos.Count() )
+ ((ImpEditEngine*)this)->InitScriptTypes( nPara );
+
+ ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
+
+ // find the first(!) script type position that holds the
+ // complete selection. Thus it will work for selections as
+ // well as with just moving the cursor from char to char.
+ USHORT nS = ( nPara == nStartPara ) ? aSel.Min().GetIndex() : 0;
+ USHORT nE = ( nPara == nEndPara ) ? aSel.Max().GetIndex() : pParaPortion->GetNode()->Len();
+ for ( USHORT n = 0; n < rTypes.Count(); n++ )
+ {
+ if (rTypes[n].nStartPos <= nS && nE <= rTypes[n].nEndPos)
+ {
+ if ( rTypes[n].nScriptType != i18n::ScriptType::WEAK )
+ {
+ nScriptType |= GetItemScriptType ( rTypes[n].nScriptType );
+ }
+ else
+ {
+ if ( !nScriptType && n )
+ {
+ // #93548# When starting with WEAK, use prev ScriptType...
+ nScriptType = rTypes[n-1].nScriptType;
+ }
+ }
+ break;
+ }
+ }
+ }
+ return nScriptType ? nScriptType : GetI18NScriptTypeOfLanguage( GetDefaultLanguage() );
+}
+
+BOOL ImpEditEngine::IsScriptChange( const EditPaM& rPaM ) const
+{
+ BOOL bScriptChange = FALSE;
+
+ if ( rPaM.GetNode()->Len() )
+ {
+ USHORT nPara = GetEditDoc().GetPos( rPaM.GetNode() );
+ ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
+ if ( !pParaPortion->aScriptInfos.Count() )
+ ((ImpEditEngine*)this)->InitScriptTypes( nPara );
+
+ ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
+ USHORT nPos = rPaM.GetIndex();
+ for ( USHORT n = 0; n < rTypes.Count(); n++ )
+ {
+ if ( rTypes[n].nStartPos == nPos )
+ {
+ bScriptChange = TRUE;
+ break;
+ }
+ }
+ }
+ return bScriptChange;
+}
+
+BOOL ImpEditEngine::HasScriptType( USHORT nPara, USHORT nType ) const
+{
+ BOOL bTypeFound = FALSE;
+
+ ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
+ if ( !pParaPortion->aScriptInfos.Count() )
+ ((ImpEditEngine*)this)->InitScriptTypes( nPara );
+
+ ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
+ for ( USHORT n = rTypes.Count(); n && !bTypeFound; )
+ {
+ if ( rTypes[--n].nScriptType == nType )
+ bTypeFound = TRUE;
+ }
+ return bTypeFound;
+}
+
+void ImpEditEngine::InitWritingDirections( USHORT nPara )
+{
+ ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
+ WritingDirectionInfos& rInfos = pParaPortion->aWritingDirectionInfos;
+ rInfos.Remove( 0, rInfos.Count() );
+
+ BOOL bCTL = FALSE;
+ ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
+ for ( USHORT n = 0; n < rTypes.Count(); n++ )
+ {
+ if ( rTypes[n].nScriptType == i18n::ScriptType::COMPLEX )
+ {
+ bCTL = TRUE;
+ break;
+ }
+ }
+
+ const UBiDiLevel nBidiLevel = IsRightToLeft( nPara ) ? 1 /*RTL*/ : 0 /*LTR*/;
+ if ( ( bCTL || ( nBidiLevel == 1 /*RTL*/ ) ) && pParaPortion->GetNode()->Len() )
+ {
+
+ String aText( *pParaPortion->GetNode() );
+
+ //
+ // Bidi functions from icu 2.0
+ //
+ UErrorCode nError = U_ZERO_ERROR;
+ UBiDi* pBidi = ubidi_openSized( aText.Len(), 0, &nError );
+ nError = U_ZERO_ERROR;
+
+ ubidi_setPara( pBidi, reinterpret_cast<const UChar *>(aText.GetBuffer()), aText.Len(), nBidiLevel, NULL, &nError ); // UChar != sal_Unicode in MinGW
+ nError = U_ZERO_ERROR;
+
+ long nCount = ubidi_countRuns( pBidi, &nError );
+
+ int32_t nStart = 0;
+ int32_t nEnd;
+ UBiDiLevel nCurrDir;
+
+ for ( USHORT nIdx = 0; nIdx < nCount; ++nIdx )
+ {
+ ubidi_getLogicalRun( pBidi, nStart, &nEnd, &nCurrDir );
+ rInfos.Insert( WritingDirectionInfo( nCurrDir, (USHORT)nStart, (USHORT)nEnd ), rInfos.Count() );
+ nStart = nEnd;
+ }
+
+ ubidi_close( pBidi );
+ }
+
+ // No infos mean no CTL and default dir is L2R...
+ if ( !rInfos.Count() )
+ rInfos.Insert( WritingDirectionInfo( 0, 0, (USHORT)pParaPortion->GetNode()->Len() ), rInfos.Count() );
+
+}
+
+BOOL ImpEditEngine::IsRightToLeft( USHORT nPara ) const
+{
+ BOOL bR2L = FALSE;
+ const SvxFrameDirectionItem* pFrameDirItem = NULL;
+
+ if ( !IsVertical() )
+ {
+ bR2L = GetDefaultHorizontalTextDirection() == EE_HTEXTDIR_R2L;
+ pFrameDirItem = &(const SvxFrameDirectionItem&)GetParaAttrib( nPara, EE_PARA_WRITINGDIR );
+ if ( pFrameDirItem->GetValue() == FRMDIR_ENVIRONMENT )
+ {
+ // #103045# if DefaultHorizontalTextDirection is set, use that value, otherwise pool default.
+ if ( GetDefaultHorizontalTextDirection() != EE_HTEXTDIR_DEFAULT )
+ {
+ pFrameDirItem = NULL; // bR2L allready set to default horizontal text direction
+ }
+ else
+ {
+ // Use pool default
+ pFrameDirItem = &(const SvxFrameDirectionItem&)((ImpEditEngine*)this)->GetEmptyItemSet().Get( EE_PARA_WRITINGDIR );
+ }
+ }
+ }
+
+ if ( pFrameDirItem )
+ bR2L = pFrameDirItem->GetValue() == FRMDIR_HORI_RIGHT_TOP;
+
+ return bR2L;
+}
+
+BOOL ImpEditEngine::HasDifferentRTLLevels( const ContentNode* pNode )
+{
+ USHORT nPara = GetEditDoc().GetPos( (ContentNode*)pNode );
+ ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
+
+ BOOL bHasDifferentRTLLevels = FALSE;
+
+ USHORT nRTLLevel = IsRightToLeft( nPara ) ? 1 : 0;
+ for ( USHORT n = 0; n < pParaPortion->GetTextPortions().Count(); n++ )
+ {
+ TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject( n );
+ if ( pTextPortion->GetRightToLeft() != nRTLLevel )
+ {
+ bHasDifferentRTLLevels = TRUE;
+ break;
+ }
+ }
+ return bHasDifferentRTLLevels;
+}
+
+
+BYTE ImpEditEngine::GetRightToLeft( USHORT nPara, USHORT nPos, USHORT* pStart, USHORT* pEnd )
+{
+// BYTE nRightToLeft = IsRightToLeft( nPara ) ? 1 : 0;
+ BYTE nRightToLeft = 0;
+
+ ContentNode* pNode = aEditDoc.SaveGetObject( nPara );
+ if ( pNode && pNode->Len() )
+ {
+ ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
+ if ( !pParaPortion->aWritingDirectionInfos.Count() )
+ InitWritingDirections( nPara );
+
+// BYTE nType = 0;
+ WritingDirectionInfos& rDirInfos = pParaPortion->aWritingDirectionInfos;
+ for ( USHORT n = 0; n < rDirInfos.Count(); n++ )
+ {
+ if ( ( rDirInfos[n].nStartPos <= nPos ) && ( rDirInfos[n].nEndPos >= nPos ) )
+ {
+ nRightToLeft = rDirInfos[n].nType;
+ if ( pStart )
+ *pStart = rDirInfos[n].nStartPos;
+ if ( pEnd )
+ *pEnd = rDirInfos[n].nEndPos;
+ break;
+ }
+ }
+ }
+ return nRightToLeft;
+}
+
+SvxAdjust ImpEditEngine::GetJustification( USHORT nPara ) const
+{
+ SvxAdjust eJustification = SVX_ADJUST_LEFT;
+
+ if ( !aStatus.IsOutliner() )
+ {
+ eJustification = ((const SvxAdjustItem&) GetParaAttrib( nPara, EE_PARA_JUST )).GetAdjust();
+
+ if ( IsRightToLeft( nPara ) )
+ {
+ if ( eJustification == SVX_ADJUST_LEFT )
+ eJustification = SVX_ADJUST_RIGHT;
+ else if ( eJustification == SVX_ADJUST_RIGHT )
+ eJustification = SVX_ADJUST_LEFT;
+ }
+ }
+ return eJustification;
+}
+
+
+// ----------------------------------------------------------------------
+// Textaenderung
+// ----------------------------------------------------------------------
+
+void ImpEditEngine::ImpRemoveChars( const EditPaM& rPaM, USHORT nChars, EditUndoRemoveChars* pCurUndo )
+{
+ if ( IsUndoEnabled() && !IsInUndo() )
+ {
+ XubString aStr( rPaM.GetNode()->Copy( rPaM.GetIndex(), nChars ) );
+
+ // Pruefen, ob Attribute geloescht oder geaendert werden:
+ USHORT nStart = rPaM.GetIndex();
+ USHORT nEnd = nStart + nChars;
+ CharAttribArray& rAttribs = rPaM.GetNode()->GetCharAttribs().GetAttribs();
+// USHORT nAttrs = rAttribs.Count();
+ for ( USHORT nAttr = 0; nAttr < rAttribs.Count(); nAttr++ )
+ {
+ EditCharAttrib* pAttr = rAttribs[nAttr];
+ if ( ( pAttr->GetEnd() >= nStart ) && ( pAttr->GetStart() < nEnd ) )
+ {
+#ifndef SVX_LIGHT
+ EditSelection aSel( rPaM );
+ aSel.Max().GetIndex() = aSel.Max().GetIndex() + nChars;
+ EditUndoSetAttribs* pAttrUndo = CreateAttribUndo( aSel, GetEmptyItemSet() );
+ InsertUndo( pAttrUndo );
+#endif
+ break; // for
+ }
+ }
+ if ( pCurUndo && ( CreateEditPaM( pCurUndo->GetEPaM() ) == rPaM ) )
+ pCurUndo->GetStr() += aStr;
+#ifndef SVX_LIGHT
+ else
+ InsertUndo( new EditUndoRemoveChars( this, CreateEPaM( rPaM ), aStr ) );
+#endif
+ }
+
+ aEditDoc.RemoveChars( rPaM, nChars );
+ TextModified();
+}
+
+EditSelection ImpEditEngine::ImpMoveParagraphs( Range aOldPositions, USHORT nNewPos )
+{
+ aOldPositions.Justify();
+ BOOL bValidAction = ( (long)nNewPos < aOldPositions.Min() ) || ( (long)nNewPos > aOldPositions.Max() );
+ DBG_ASSERT( bValidAction, "Move in sich selbst ?" );
+ DBG_ASSERT( aOldPositions.Max() <= (long)GetParaPortions().Count(), "Voll drueber weg: MoveParagraphs" );
+
+ EditSelection aSelection;
+
+ if ( !bValidAction )
+ {
+ aSelection = aEditDoc.GetStartPaM();
+ return aSelection;
+ }
+
+ ULONG nParaCount = GetParaPortions().Count();
+
+ if ( nNewPos >= nParaCount )
+ nNewPos = GetParaPortions().Count();
+
+ // Height may change when moving first or last Paragraph
+ ParaPortion* pRecalc1 = NULL;
+ ParaPortion* pRecalc2 = NULL;
+ ParaPortion* pRecalc3 = NULL;
+ ParaPortion* pRecalc4 = NULL;
+
+ if ( nNewPos == 0 ) // Move to Start
+ {
+ pRecalc1 = GetParaPortions().GetObject( 0 );
+ pRecalc2 = GetParaPortions().GetObject( (USHORT)aOldPositions.Min() );
+
+ }
+ else if ( nNewPos == nParaCount )
+ {
+ pRecalc1 = GetParaPortions().GetObject( (USHORT)(nParaCount-1) );
+ pRecalc2 = GetParaPortions().GetObject( (USHORT)aOldPositions.Max() );
+ }
+
+ if ( aOldPositions.Min() == 0 ) // Move from Start
+ {
+ pRecalc3 = GetParaPortions().GetObject( 0 );
+ pRecalc4 = GetParaPortions().GetObject(
+ sal::static_int_cast< USHORT >( aOldPositions.Max()+1 ) );
+ }
+ else if ( (USHORT)aOldPositions.Max() == (nParaCount-1) )
+ {
+ pRecalc3 = GetParaPortions().GetObject( (USHORT)aOldPositions.Max() );
+ pRecalc4 = GetParaPortions().GetObject( (USHORT)(aOldPositions.Min()-1) );
+ }
+
+ MoveParagraphsInfo aMoveParagraphsInfo( sal::static_int_cast< USHORT >(aOldPositions.Min()), sal::static_int_cast< USHORT >(aOldPositions.Max()), nNewPos );
+ aBeginMovingParagraphsHdl.Call( &aMoveParagraphsInfo );
+
+ if ( IsUndoEnabled() && !IsInUndo())
+ InsertUndo( new EditUndoMoveParagraphs( this, aOldPositions, nNewPos ) );
+
+ // Position nicht aus dem Auge verlieren!
+ ParaPortion* pDestPortion = GetParaPortions().SaveGetObject( nNewPos );
+
+ ParaPortionList aTmpPortionList;
+ USHORT i;
+ for ( i = (USHORT)aOldPositions.Min(); i <= (USHORT)aOldPositions.Max(); i++ )
+ {
+ // Immer aOldPositions.Min(), da Remove().
+ ParaPortion* pTmpPortion = GetParaPortions().GetObject( (USHORT)aOldPositions.Min() );
+ GetParaPortions().Remove( (USHORT)aOldPositions.Min() );
+ aEditDoc.Remove( (USHORT)aOldPositions.Min() );
+ aTmpPortionList.Insert( pTmpPortion, aTmpPortionList.Count() );
+ }
+
+ USHORT nRealNewPos = pDestPortion ? GetParaPortions().GetPos( pDestPortion ) : GetParaPortions().Count();
+ DBG_ASSERT( nRealNewPos != USHRT_MAX, "ImpMoveParagraphs: Ungueltige Position!" );
+
+ for ( i = 0; i < (USHORT)aTmpPortionList.Count(); i++ )
+ {
+ ParaPortion* pTmpPortion = aTmpPortionList.GetObject( i );
+ if ( i == 0 )
+ aSelection.Min().SetNode( pTmpPortion->GetNode() );
+
+ aSelection.Max().SetNode( pTmpPortion->GetNode() );
+ aSelection.Max().SetIndex( pTmpPortion->GetNode()->Len() );
+
+ ContentNode* pN = pTmpPortion->GetNode();
+ aEditDoc.Insert( pN, nRealNewPos+i );
+
+ GetParaPortions().Insert( pTmpPortion, nRealNewPos+i );
+ }
+
+ aEndMovingParagraphsHdl.Call( &aMoveParagraphsInfo );
+
+ if ( GetNotifyHdl().IsSet() )
+ {
+ EENotify aNotify( EE_NOTIFY_PARAGRAPHSMOVED );
+ aNotify.pEditEngine = GetEditEnginePtr();
+ aNotify.nParagraph = nNewPos;
+ aNotify.nParam1 = sal::static_int_cast< USHORT >(aOldPositions.Min());
+ aNotify.nParam2 = sal::static_int_cast< USHORT >(aOldPositions.Max());
+ CallNotify( aNotify );
+ }
+
+ aEditDoc.SetModified( TRUE );
+
+ if ( pRecalc1 )
+ CalcHeight( pRecalc1 );
+ if ( pRecalc2 )
+ CalcHeight( pRecalc2 );
+ if ( pRecalc3 )
+ CalcHeight( pRecalc3 );
+ if ( pRecalc4 )
+ CalcHeight( pRecalc4 );
+
+ aTmpPortionList.Remove( 0, aTmpPortionList.Count() ); // wichtig !
+
+#ifdef EDITDEBUG
+ GetParaPortions().DbgCheck(aEditDoc);
+#endif
+ return aSelection;
+}
+
+
+EditPaM ImpEditEngine::ImpConnectParagraphs( ContentNode* pLeft, ContentNode* pRight, BOOL bBackward )
+{
+ DBG_ASSERT( pLeft != pRight, "Den gleichen Absatz zusammenfuegen ?" );
+ DBG_ASSERT( aEditDoc.GetPos( pLeft ) != USHRT_MAX, "Einzufuegenden Node nicht gefunden(1)" );
+ DBG_ASSERT( aEditDoc.GetPos( pRight ) != USHRT_MAX, "Einzufuegenden Node nicht gefunden(2)" );
+
+ USHORT nParagraphTobeDeleted = aEditDoc.GetPos( pRight );
+ DeletedNodeInfo* pInf = new DeletedNodeInfo( (ULONG)pRight, nParagraphTobeDeleted );
+ aDeletedNodes.Insert( pInf, aDeletedNodes.Count() );
+
+ GetEditEnginePtr()->ParagraphConnected( aEditDoc.GetPos( pLeft ), aEditDoc.GetPos( pRight ) );
+
+#ifndef SVX_LIGHT
+ if ( IsUndoEnabled() && !IsInUndo() )
+ {
+ InsertUndo( new EditUndoConnectParas( this,
+ aEditDoc.GetPos( pLeft ), pLeft->Len(),
+ pLeft->GetContentAttribs().GetItems(), pRight->GetContentAttribs().GetItems(),
+ pLeft->GetStyleSheet(), pRight->GetStyleSheet(), bBackward ) );
+ }
+#endif
+
+ if ( bBackward )
+ {
+ pLeft->SetStyleSheet( pRight->GetStyleSheet(), TRUE );
+ pLeft->GetContentAttribs().GetItems().Set( pRight->GetContentAttribs().GetItems() );
+ pLeft->GetCharAttribs().GetDefFont() = pRight->GetCharAttribs().GetDefFont();
+ }
+
+ ParaAttribsChanged( pLeft );
+
+ // Erstmal Portions suchen, da pRight nach ConnectParagraphs weg.
+ ParaPortion* pLeftPortion = FindParaPortion( pLeft );
+ ParaPortion* pRightPortion = FindParaPortion( pRight );
+ DBG_ASSERT( pLeftPortion, "Blinde Portion in ImpConnectParagraphs(1)" );
+ DBG_ASSERT( pRightPortion, "Blinde Portion in ImpConnectParagraphs(2)" );
+ DBG_ASSERT( nParagraphTobeDeleted == GetParaPortions().GetPos( pRightPortion ), "NodePos != PortionPos?" );
+
+#ifndef SVX_LIGHT
+ if ( GetStatus().DoOnlineSpelling() )
+ {
+ xub_StrLen nEnd = pLeft->Len();
+ xub_StrLen nInv = nEnd ? nEnd-1 : nEnd;
+ pLeft->GetWrongList()->ClearWrongs( nInv, 0xFFFF, pLeft ); // Evtl. einen wegnehmen
+ pLeft->GetWrongList()->MarkInvalid( nInv, nEnd+1 );
+ // Falschgeschriebene Woerter ruebernehmen:
+ USHORT nRWrongs = pRight->GetWrongList()->Count();
+ for ( USHORT nW = 0; nW < nRWrongs; nW++ )
+ {
+ WrongRange aWrong = pRight->GetWrongList()->GetObject( nW );
+ if ( aWrong.nStart != 0 ) // Nicht ein anschliessender
+ {
+ aWrong.nStart = aWrong.nStart + nEnd;
+ aWrong.nEnd = aWrong.nEnd + nEnd;
+ pLeft->GetWrongList()->InsertWrong( aWrong, pLeft->GetWrongList()->Count() );
+ }
+ }
+ }
+#endif
+
+ if ( IsCallParaInsertedOrDeleted() )
+ GetEditEnginePtr()->ParagraphDeleted( nParagraphTobeDeleted );
+
+ EditPaM aPaM = aEditDoc.ConnectParagraphs( pLeft, pRight );
+ GetParaPortions().Remove( nParagraphTobeDeleted );
+ delete pRightPortion;
+
+ pLeftPortion->MarkSelectionInvalid( aPaM.GetIndex(), pLeft->Len() );
+
+ // der rechte Node wird von EditDoc::ConnectParagraphs() geloescht.
+
+ if ( GetTextRanger() )
+ {
+ // Durch das zusammenfuegen wird der linke zwar neu formatiert, aber
+ // wenn sich dessen Hoehe nicht aendert bekommt die Formatierung die
+ // Aenderung der Gesaamthoehe des Textes zu spaet mit...
+ for ( USHORT n = nParagraphTobeDeleted; n < GetParaPortions().Count(); n++ )
+ {
+ ParaPortion* pPP = GetParaPortions().GetObject( n );
+ pPP->MarkSelectionInvalid( 0, pPP->GetNode()->Len() );
+ pPP->GetLines().Reset();
+ }
+ }
+
+ TextModified();
+
+ return aPaM;
+}
+
+EditPaM ImpEditEngine::DeleteLeftOrRight( const EditSelection& rSel, BYTE nMode, BYTE nDelMode )
+{
+ DBG_ASSERT( !EditSelection( rSel ).DbgIsBuggy( aEditDoc ), "Index im Wald in DeleteLeftOrRight" );
+
+ if ( rSel.HasRange() ) // dann nur Sel. loeschen
+ return ImpDeleteSelection( rSel );
+
+ const EditPaM aCurPos( rSel.Max() );
+ EditPaM aDelStart( aCurPos );
+ EditPaM aDelEnd( aCurPos );
+ if ( nMode == DEL_LEFT )
+ {
+ if ( nDelMode == DELMODE_SIMPLE )
+ {
+ aDelStart = CursorLeft( aCurPos, i18n::CharacterIteratorMode::SKIPCHARACTER );
+ }
+ else if ( nDelMode == DELMODE_RESTOFWORD )
+ {
+ aDelStart = StartOfWord( aCurPos );
+ if ( aDelStart.GetIndex() == aCurPos.GetIndex() )
+ aDelStart = WordLeft( aCurPos );
+ }
+ else // DELMODE_RESTOFCONTENT
+ {
+ aDelStart.SetIndex( 0 );
+ if ( aDelStart == aCurPos )
+ {
+ // kompletter Absatz davor
+ ContentNode* pPrev = GetPrevVisNode( aCurPos.GetNode() );
+ if ( pPrev )
+ aDelStart = EditPaM( pPrev, 0 );
+ }
+ }
+ }
+ else
+ {
+ if ( nDelMode == DELMODE_SIMPLE )
+ {
+ aDelEnd = CursorRight( aCurPos );
+ }
+ else if ( nDelMode == DELMODE_RESTOFWORD )
+ {
+ aDelEnd = EndOfWord( aCurPos );
+ if (aDelEnd.GetIndex() == aCurPos.GetIndex())
+ {
+ xub_StrLen nLen = aCurPos.GetNode()->Len();
+ // end of para?
+ if (aDelEnd.GetIndex() == nLen)
+ aDelEnd = WordLeft( aCurPos );
+ else // there's still sth to delete on the right
+ {
+ aDelEnd = EndOfWord( WordRight( aCurPos ) );
+ // if there'n no next word...
+ if (aDelEnd.GetIndex() == nLen )
+ aDelEnd.SetIndex( nLen );
+ }
+ }
+ }
+ else // DELMODE_RESTOFCONTENT
+ {
+ aDelEnd.SetIndex( aCurPos.GetNode()->Len() );
+ if ( aDelEnd == aCurPos )
+ {
+ // kompletter Absatz dahinter
+ ContentNode* pNext = GetNextVisNode( aCurPos.GetNode() );
+ if ( pNext )
+ aDelEnd = EditPaM( pNext, pNext->Len() );
+ }
+ }
+ }
+
+ // Bei DELMODE_RESTOFCONTENT reicht bei verschiedenen Nodes
+ // kein ConnectParagraphs.
+ if ( ( nDelMode == DELMODE_RESTOFCONTENT ) || ( aDelStart.GetNode() == aDelEnd.GetNode() ) )
+ return ImpDeleteSelection( EditSelection( aDelStart, aDelEnd ) );
+
+ // Jetzt entscheiden, ob noch Selektion loeschen (RESTOFCONTENTS)
+ BOOL bSpecialBackward = ( ( nMode == DEL_LEFT ) && ( nDelMode == DELMODE_SIMPLE ) )
+ ? TRUE : FALSE;
+ if ( aStatus.IsAnyOutliner() )
+ bSpecialBackward = FALSE;
+
+ return ImpConnectParagraphs( aDelStart.GetNode(), aDelEnd.GetNode(), bSpecialBackward );
+}
+
+EditPaM ImpEditEngine::ImpDeleteSelection( EditSelection aSel )
+{
+ if ( !aSel.HasRange() )
+ return aSel.Min();
+
+ aSel.Adjust( aEditDoc );
+ EditPaM aStartPaM( aSel.Min() );
+ EditPaM aEndPaM( aSel.Max() );
+
+ CursorMoved( aStartPaM.GetNode() ); // nur damit neu eingestellte Attribute verschwinden...
+ CursorMoved( aEndPaM.GetNode() ); // nur damit neu eingestellte Attribute verschwinden...
+
+ DBG_ASSERT( aStartPaM.GetIndex() <= aStartPaM.GetNode()->Len(), "Index im Wald in ImpDeleteSelection" );
+ DBG_ASSERT( aEndPaM.GetIndex() <= aEndPaM.GetNode()->Len(), "Index im Wald in ImpDeleteSelection" );
+
+ USHORT nStartNode = aEditDoc.GetPos( aStartPaM.GetNode() );
+ USHORT nEndNode = aEditDoc.GetPos( aEndPaM.GetNode() );
+
+ DBG_ASSERT( nEndNode != USHRT_MAX, "Start > End ?!" );
+ DBG_ASSERT( nStartNode <= nEndNode, "Start > End ?!" );
+
+ // Alle Nodes dazwischen entfernen....
+ for ( ULONG z = nStartNode+1; z < nEndNode; z++ )
+ {
+ // Immer nStartNode+1, wegen Remove()!
+ ImpRemoveParagraph( nStartNode+1 );
+ }
+
+ if ( aStartPaM.GetNode() != aEndPaM.GetNode() )
+ {
+ // Den Rest des StartNodes...
+ USHORT nChars;
+ nChars = aStartPaM.GetNode()->Len() - aStartPaM.GetIndex();
+ ImpRemoveChars( aStartPaM, nChars );
+ ParaPortion* pPortion = FindParaPortion( aStartPaM.GetNode() );
+ DBG_ASSERT( pPortion, "Blinde Portion in ImpDeleteSelection(3)" );
+ pPortion->MarkSelectionInvalid( aStartPaM.GetIndex(), aStartPaM.GetNode()->Len() );
+
+ // Den Anfang des EndNodes....
+ nChars = aEndPaM.GetIndex();
+ aEndPaM.SetIndex( 0 );
+ ImpRemoveChars( aEndPaM, nChars );
+ pPortion = FindParaPortion( aEndPaM.GetNode() );
+ DBG_ASSERT( pPortion, "Blinde Portion in ImpDeleteSelection(4)" );
+ pPortion->MarkSelectionInvalid( 0, aEndPaM.GetNode()->Len() );
+ // Zusammenfuegen....
+ aStartPaM = ImpConnectParagraphs( aStartPaM.GetNode(), aEndPaM.GetNode() );
+ }
+ else
+ {
+ USHORT nChars;
+ nChars = aEndPaM.GetIndex() - aStartPaM.GetIndex();
+ ImpRemoveChars( aStartPaM, nChars );
+ ParaPortion* pPortion = FindParaPortion( aStartPaM.GetNode() );
+ DBG_ASSERT( pPortion, "Blinde Portion in ImpDeleteSelection(5)" );
+ pPortion->MarkInvalid( aEndPaM.GetIndex(), aStartPaM.GetIndex() - aEndPaM.GetIndex() );
+ }
+
+ UpdateSelections();
+ TextModified();
+ return aStartPaM;
+}
+
+void ImpEditEngine::ImpRemoveParagraph( USHORT nPara )
+{
+ ContentNode* pNode = aEditDoc.SaveGetObject( nPara );
+ ContentNode* pNextNode = aEditDoc.SaveGetObject( nPara+1 );
+ ParaPortion* pPortion = GetParaPortions().SaveGetObject( nPara );
+
+ DBG_ASSERT( pNode, "Blinder Node in ImpRemoveParagraph" );
+ DBG_ASSERT( pPortion, "Blinde Portion in ImpRemoveParagraph(2)" );
+
+ DeletedNodeInfo* pInf = new DeletedNodeInfo( (ULONG)pNode, nPara );
+ aDeletedNodes.Insert( pInf, aDeletedNodes.Count() );
+
+ // Der Node wird vom Undo verwaltet und ggf. zerstoert!
+ /* delete */ aEditDoc.Remove( nPara );
+ GetParaPortions().Remove( nPara );
+ delete pPortion;
+
+ if ( IsCallParaInsertedOrDeleted() )
+ {
+ GetEditEnginePtr()->ParagraphDeleted( nPara );
+ }
+
+ // Im folgenden muss ggf. Extra-Space neu ermittelt werden.
+ // Bei ParaAttribsChanged wird leider der Absatz neu formatiert,
+ // aber diese Methode sollte nicht Zeitkritsch sein!
+ if ( pNextNode )
+ ParaAttribsChanged( pNextNode );
+
+#ifndef SVX_LIGHT
+ if ( IsUndoEnabled() && !IsInUndo() )
+ InsertUndo( new EditUndoDelContent( this, pNode, nPara ) );
+ else
+#endif
+ {
+ aEditDoc.RemoveItemsFromPool( pNode );
+ if ( pNode->GetStyleSheet() )
+ EndListening( *pNode->GetStyleSheet(), FALSE );
+ delete pNode;
+ }
+}
+
+EditPaM ImpEditEngine::AutoCorrect( const EditSelection& rCurSel, xub_Unicode c, BOOL bOverwrite )
+{
+ EditSelection aSel( rCurSel );
+#ifndef SVX_LIGHT
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get()->GetAutoCorrect();
+ if ( pAutoCorrect )
+ {
+ if ( aSel.HasRange() )
+ aSel = ImpDeleteSelection( rCurSel );
+
+ // #i78661 allow application to turn off capitalization of
+ // start sentence explicitly.
+ // (This is done by setting IsFirstWordCapitalization to FALSE.)
+ BOOL bOldCptlSttSntnc = pAutoCorrect->IsAutoCorrFlag( CptlSttSntnc );
+ if (!IsFirstWordCapitalization())
+ {
+ ESelection aESel( CreateESel(aSel) );
+ EditSelection aFirstWordSel;
+ EditSelection aSecondWordSel;
+ if (aESel.nEndPara == 0) // is this the first para?
+ {
+ // select first word...
+ // start by checking if para starts with word.
+ aFirstWordSel = SelectWord( CreateSel(ESelection()) );
+ if (aFirstWordSel.Min().GetIndex() == 0 && aFirstWordSel.Max().GetIndex() == 0)
+ {
+ // para does not start with word -> select next/first word
+ EditPaM aRightWord( WordRight( aFirstWordSel.Max(), 1 ) );
+ aFirstWordSel = SelectWord( EditSelection( aRightWord ) );
+ }
+
+ // select second word
+ // (sometimes aSel mightnot point to the end of the first word
+ // but to some following char like '.'. ':', ...
+ // In those cases we need aSecondWordSel to see if aSel
+ // will actually effect the first word.)
+ EditPaM aRight2Word( WordRight( aFirstWordSel.Max(), 1 ) );
+ aSecondWordSel = SelectWord( EditSelection( aRight2Word ) );
+ }
+ BOOL bIsFirstWordInFirstPara = aESel.nEndPara == 0 &&
+ aFirstWordSel.Max().GetIndex() <= aSel.Max().GetIndex() &&
+ aSel.Max().GetIndex() <= aSecondWordSel.Min().GetIndex();
+
+ if (bIsFirstWordInFirstPara)
+ pAutoCorrect->SetAutoCorrFlag( CptlSttSntnc, IsFirstWordCapitalization() );
+ }
+
+ ContentNode* pNode = aSel.Max().GetNode();
+ USHORT nIndex = aSel.Max().GetIndex();
+ EdtAutoCorrDoc aAuto( this, pNode, nIndex, c );
+ pAutoCorrect->AutoCorrect( aAuto, *pNode, nIndex, c, !bOverwrite );
+ aSel.Max().SetIndex( aAuto.GetCursor() );
+
+ // #i78661 since the SvxAutoCorrect object used here is
+ // shared we need to reset the value to it's original state.
+ pAutoCorrect->SetAutoCorrFlag( CptlSttSntnc, bOldCptlSttSntnc );
+ }
+#endif // !SVX_LIGHT
+ return aSel.Max();
+}
+
+
+EditPaM ImpEditEngine::InsertText( const EditSelection& rCurSel,
+ xub_Unicode c, BOOL bOverwrite, sal_Bool bIsUserInput )
+{
+ DBG_ASSERT( c != '\t', "Tab bei InsertText ?" );
+ DBG_ASSERT( c != '\n', "Zeilenumbruch bei InsertText ?" );
+
+ EditPaM aPaM( rCurSel.Min() );
+
+ BOOL bDoOverwrite = ( bOverwrite &&
+ ( aPaM.GetIndex() < aPaM.GetNode()->Len() ) ) ? TRUE : FALSE;
+
+ BOOL bUndoAction = ( rCurSel.HasRange() || bDoOverwrite );
+
+ if ( bUndoAction )
+ UndoActionStart( EDITUNDO_INSERT );
+
+ if ( rCurSel.HasRange() )
+ {
+ aPaM = ImpDeleteSelection( rCurSel );
+ }
+ else if ( bDoOverwrite )
+ {
+ // Wenn Selektion, dann nicht auch noch ein Zeichen ueberschreiben!
+ EditSelection aTmpSel( aPaM );
+ aTmpSel.Max().GetIndex()++;
+ DBG_ASSERT( !aTmpSel.DbgIsBuggy( aEditDoc ), "Overwrite: Fehlerhafte Selektion!" );
+ ImpDeleteSelection( aTmpSel );
+ }
+
+ if ( aPaM.GetNode()->Len() < MAXCHARSINPARA )
+ {
+ if (bIsUserInput && IsInputSequenceCheckingRequired( c, rCurSel ))
+ {
+ uno::Reference < i18n::XExtendedInputSequenceChecker > _xISC( ImplGetInputSequenceChecker() );
+ if (!pCTLOptions)
+ pCTLOptions = new SvtCTLOptions;
+
+ if (_xISC.is() || pCTLOptions)
+ {
+ xub_StrLen nTmpPos = aPaM.GetIndex();
+ sal_Int16 nCheckMode = pCTLOptions->IsCTLSequenceCheckingRestricted() ?
+ i18n::InputSequenceCheckMode::STRICT : i18n::InputSequenceCheckMode::BASIC;
+
+ // the text that needs to be checked is only the one
+ // before the current cursor position
+ rtl::OUString aOldText( aPaM.GetNode()->Copy(0, nTmpPos) );
+ rtl::OUString aNewText( aOldText );
+ if (pCTLOptions->IsCTLSequenceCheckingTypeAndReplace())
+ {
+ /*const xub_StrLen nPrevPos = static_cast< xub_StrLen >*/( _xISC->correctInputSequence( aNewText, nTmpPos - 1, c, nCheckMode ) );
+
+ // find position of first character that has changed
+ sal_Int32 nOldLen = aOldText.getLength();
+ sal_Int32 nNewLen = aNewText.getLength();
+ const sal_Unicode *pOldTxt = aOldText.getStr();
+ const sal_Unicode *pNewTxt = aNewText.getStr();
+ sal_Int32 nChgPos = 0;
+ while ( nChgPos < nOldLen && nChgPos < nNewLen &&
+ pOldTxt[nChgPos] == pNewTxt[nChgPos] )
+ ++nChgPos;
+
+ xub_StrLen nChgLen = static_cast< xub_StrLen >( nNewLen - nChgPos );
+ String aChgText( aNewText.copy( nChgPos ), nChgLen );
+
+ // select text from first pos to be changed to current pos
+ EditSelection aSel( EditPaM( aPaM.GetNode(), (USHORT) nChgPos ), aPaM );
+
+ if (aChgText.Len())
+ return InsertText( aSel, aChgText ); // implicitly handles undo
+ else
+ return aPaM;
+ }
+ else
+ {
+ // should the character be ignored (i.e. not get inserted) ?
+ if (!_xISC->checkInputSequence( aOldText, nTmpPos - 1, c, nCheckMode ))
+ return aPaM; // nothing to be done -> no need for undo
+ }
+ }
+
+ // at this point now we will insert the character 'normally' some lines below...
+ }
+
+ if ( IsUndoEnabled() && !IsInUndo() )
+ {
+ EditUndoInsertChars* pNewUndo = new EditUndoInsertChars( this, CreateEPaM( aPaM ), c );
+ BOOL bTryMerge = ( !bDoOverwrite && ( c != ' ' ) ) ? TRUE : FALSE;
+ InsertUndo( pNewUndo, bTryMerge );
+ }
+
+ aEditDoc.InsertText( (const EditPaM&)aPaM, c );
+ ParaPortion* pPortion = FindParaPortion( aPaM.GetNode() );
+ DBG_ASSERT( pPortion, "Blinde Portion in InsertText" );
+ pPortion->MarkInvalid( aPaM.GetIndex(), 1 );
+ aPaM.GetIndex()++; // macht EditDoc-Methode nicht mehr
+ }
+
+ TextModified();
+
+ if ( bUndoAction )
+ UndoActionEnd( EDITUNDO_INSERT );
+
+ return aPaM;
+}
+
+EditPaM ImpEditEngine::ImpInsertText( EditSelection aCurSel, const XubString& rStr )
+{
+ UndoActionStart( EDITUNDO_INSERT );
+
+ EditPaM aPaM;
+ if ( aCurSel.HasRange() )
+ aPaM = ImpDeleteSelection( aCurSel );
+ else
+ aPaM = aCurSel.Max();
+
+ EditPaM aCurPaM( aPaM ); // fuers Invalidieren
+
+ XubString aText( rStr );
+ aText.ConvertLineEnd( LINEEND_LF );
+ SfxVoidItem aTabItem( EE_FEATURE_TAB );
+
+ // Konvertiert nach LineSep = \n
+ // Token mit LINE_SEP abfragen,
+ // da der MAC-Compiler aus \n etwas anderes macht!
+
+ USHORT nStart = 0;
+ while ( nStart < aText.Len() )
+ {
+ USHORT nEnd = aText.Search( LINE_SEP, nStart );
+ if ( nEnd == STRING_NOTFOUND )
+ nEnd = aText.Len(); // nicht dereferenzieren!
+
+ // Start == End => Leerzeile
+ if ( nEnd > nStart )
+ {
+ XubString aLine( aText, nStart, nEnd-nStart );
+ xub_StrLen nChars = aPaM.GetNode()->Len() + aLine.Len();
+ if ( nChars > MAXCHARSINPARA )
+ {
+ USHORT nMaxNewChars = MAXCHARSINPARA-aPaM.GetNode()->Len();
+ nEnd -= ( aLine.Len() - nMaxNewChars ); // Dann landen die Zeichen im naechsten Absatz.
+ aLine.Erase( nMaxNewChars ); // Del Rest...
+ }
+#ifndef SVX_LIGHT
+ if ( IsUndoEnabled() && !IsInUndo() )
+ InsertUndo( new EditUndoInsertChars( this, CreateEPaM( aPaM ), aLine ) );
+#endif
+ // Tabs ?
+ if ( aLine.Search( '\t' ) == STRING_NOTFOUND )
+ aPaM = aEditDoc.InsertText( aPaM, aLine );
+ else
+ {
+ USHORT nStart2 = 0;
+ while ( nStart2 < aLine.Len() )
+ {
+ USHORT nEnd2 = aLine.Search( '\t', nStart2 );
+ if ( nEnd2 == STRING_NOTFOUND )
+ nEnd2 = aLine.Len(); // nicht dereferenzieren!
+
+ if ( nEnd2 > nStart2 )
+ aPaM = aEditDoc.InsertText( aPaM, XubString( aLine, nStart2, nEnd2-nStart2 ) );
+ if ( nEnd2 < aLine.Len() )
+ {
+ // aPaM = ImpInsertFeature( EditSelection( aPaM, aPaM ), );
+ aPaM = aEditDoc.InsertFeature( aPaM, aTabItem );
+ }
+ nStart2 = nEnd2+1;
+ }
+ }
+ ParaPortion* pPortion = FindParaPortion( aPaM.GetNode() );
+ DBG_ASSERT( pPortion, "Blinde Portion in InsertText" );
+ pPortion->MarkInvalid( aCurPaM.GetIndex(), aLine.Len() );
+ }
+ if ( nEnd < aText.Len() )
+ aPaM = ImpInsertParaBreak( aPaM );
+
+ nStart = nEnd+1;
+ }
+
+ UndoActionEnd( EDITUNDO_INSERT );
+
+ TextModified();
+ return aPaM;
+}
+
+EditPaM ImpEditEngine::ImpFastInsertText( EditPaM aPaM, const XubString& rStr )
+{
+ DBG_ASSERT( rStr.Search( 0x0A ) == STRING_NOTFOUND, "FastInsertText: Zeilentrenner nicht erlaubt!" );
+ DBG_ASSERT( rStr.Search( 0x0D ) == STRING_NOTFOUND, "FastInsertText: Zeilentrenner nicht erlaubt!" );
+ DBG_ASSERT( rStr.Search( '\t' ) == STRING_NOTFOUND, "FastInsertText: Features nicht erlaubt!" );
+
+ if ( ( aPaM.GetNode()->Len() + rStr.Len() ) < MAXCHARSINPARA )
+ {
+#ifndef SVX_LIGHT
+ if ( IsUndoEnabled() && !IsInUndo() )
+ InsertUndo( new EditUndoInsertChars( this, CreateEPaM( aPaM ), rStr ) );
+#endif
+
+ aPaM = aEditDoc.InsertText( aPaM, rStr );
+ TextModified();
+ }
+ else
+ {
+ aPaM = ImpInsertText( aPaM, rStr );
+ }
+
+ return aPaM;
+}
+
+EditPaM ImpEditEngine::ImpInsertFeature( EditSelection aCurSel, const SfxPoolItem& rItem )
+{
+ EditPaM aPaM;
+ if ( aCurSel.HasRange() )
+ aPaM = ImpDeleteSelection( aCurSel );
+ else
+ aPaM = aCurSel.Max();
+
+ if ( aPaM.GetIndex() >= 0xfffe )
+ return aPaM;
+
+#ifndef SVX_LIGHT
+ if ( IsUndoEnabled() && !IsInUndo() )
+ InsertUndo( new EditUndoInsertFeature( this, CreateEPaM( aPaM ), rItem ) );
+#endif
+ aPaM = aEditDoc.InsertFeature( aPaM, rItem );
+
+ ParaPortion* pPortion = FindParaPortion( aPaM.GetNode() );
+ DBG_ASSERT( pPortion, "Blinde Portion in InsertFeature" );
+ pPortion->MarkInvalid( aPaM.GetIndex()-1, 1 );
+
+ TextModified();
+
+ return aPaM;
+}
+
+EditPaM ImpEditEngine::ImpInsertParaBreak( const EditSelection& rCurSel, BOOL bKeepEndingAttribs )
+{
+ EditPaM aPaM;
+ if ( rCurSel.HasRange() )
+ aPaM = ImpDeleteSelection( rCurSel );
+ else
+ aPaM = rCurSel.Max();
+
+ return ImpInsertParaBreak( aPaM, bKeepEndingAttribs );
+}
+
+EditPaM ImpEditEngine::ImpInsertParaBreak( const EditPaM& rPaM, BOOL bKeepEndingAttribs )
+{
+ if ( aEditDoc.Count() >= 0xFFFE )
+ {
+ DBG_ERROR( "Can't process more than 64K paragraphs!" );
+ return rPaM;
+ }
+
+#ifndef SVX_LIGHT
+ if ( IsUndoEnabled() && !IsInUndo() )
+ InsertUndo( new EditUndoSplitPara( this, aEditDoc.GetPos( rPaM.GetNode() ), rPaM.GetIndex() ) );
+#endif
+
+ EditPaM aPaM( aEditDoc.InsertParaBreak( rPaM, bKeepEndingAttribs ) );
+
+#ifndef SVX_LIGHT
+ if ( GetStatus().DoOnlineSpelling() )
+ {
+ xub_StrLen nEnd = rPaM.GetNode()->Len();
+ aPaM.GetNode()->CreateWrongList();
+ WrongList* pLWrongs = rPaM.GetNode()->GetWrongList();
+ WrongList* pRWrongs = aPaM.GetNode()->GetWrongList();
+ // Falschgeschriebene Woerter ruebernehmen:
+ USHORT nLWrongs = pLWrongs->Count();
+ for ( USHORT nW = 0; nW < nLWrongs; nW++ )
+ {
+ WrongRange& rWrong = pLWrongs->GetObject( nW );
+ // Nur wenn wirklich dahinter, ein ueberlappendes wird beim Spell korrigiert
+ if ( rWrong.nStart > nEnd )
+ {
+ pRWrongs->InsertWrong( rWrong, pRWrongs->Count() );
+ WrongRange& rRWrong = pRWrongs->GetObject( pRWrongs->Count() - 1 );
+ rRWrong.nStart = rRWrong.nStart - nEnd;
+ rRWrong.nEnd = rRWrong.nEnd - nEnd;
+ }
+ else if ( ( rWrong.nStart < nEnd ) && ( rWrong.nEnd > nEnd ) )
+ rWrong.nEnd = nEnd;
+ }
+ USHORT nInv = nEnd ? nEnd-1 : nEnd;
+ if ( nEnd )
+ pLWrongs->MarkInvalid( nInv, nEnd );
+ else
+ pLWrongs->SetValid();
+ pRWrongs->SetValid(); // sonst 0 - 0xFFFF
+ pRWrongs->MarkInvalid( 0, 1 ); // Nur das erste Wort testen
+ }
+#endif // !SVX_LIGHT
+
+
+ ParaPortion* pPortion = FindParaPortion( rPaM.GetNode() );
+ DBG_ASSERT( pPortion, "Blinde Portion in ImpInsertParaBreak" );
+ pPortion->MarkInvalid( rPaM.GetIndex(), 0 );
+
+ // Optimieren: Nicht unnoetig viele GetPos auf die Listen ansetzen!
+ // Hier z.B. bei Undo, aber auch in allen anderen Methoden.
+ USHORT nPos = GetParaPortions().GetPos( pPortion );
+ ParaPortion* pNewPortion = new ParaPortion( aPaM.GetNode() );
+ GetParaPortions().Insert( pNewPortion, nPos + 1 );
+ ParaAttribsChanged( pNewPortion->GetNode() );
+ if ( IsCallParaInsertedOrDeleted() )
+ GetEditEnginePtr()->ParagraphInserted( nPos+1 );
+
+ CursorMoved( rPaM.GetNode() ); // falls leeres Attribut entstanden.
+ TextModified();
+ return aPaM;
+}
+
+EditPaM ImpEditEngine::ImpFastInsertParagraph( USHORT nPara )
+{
+#ifndef SVX_LIGHT
+ if ( IsUndoEnabled() && !IsInUndo() )
+ {
+ if ( nPara )
+ {
+ DBG_ASSERT( aEditDoc.SaveGetObject( nPara-1 ), "FastInsertParagraph: Prev existiert nicht" );
+ InsertUndo( new EditUndoSplitPara( this, nPara-1, aEditDoc.GetObject( nPara-1 )->Len() ) );
+ }
+ else
+ InsertUndo( new EditUndoSplitPara( this, 0, 0 ) );
+ }
+#endif
+
+ ContentNode* pNode = new ContentNode( aEditDoc.GetItemPool() );
+ // Falls FlatMode, wird spaeter kein Font eingestellt:
+ pNode->GetCharAttribs().GetDefFont() = aEditDoc.GetDefFont();
+
+#ifndef SVX_LIGHT
+ if ( GetStatus().DoOnlineSpelling() )
+ pNode->CreateWrongList();
+#endif // !SVX_LIGHT
+
+ aEditDoc.Insert( pNode, nPara );
+
+ ParaPortion* pNewPortion = new ParaPortion( pNode );
+ GetParaPortions().Insert( pNewPortion, nPara );
+ if ( IsCallParaInsertedOrDeleted() )
+ GetEditEnginePtr()->ParagraphInserted( nPara );
+
+ return EditPaM( pNode, 0 );
+}
+
+EditPaM ImpEditEngine::InsertParaBreak( EditSelection aCurSel )
+{
+ EditPaM aPaM( ImpInsertParaBreak( aCurSel ) );
+ if ( aStatus.DoAutoIndenting() )
+ {
+ USHORT nPara = aEditDoc.GetPos( aPaM.GetNode() );
+ DBG_ASSERT( nPara > 0, "AutoIndenting: Fehler!" );
+ XubString aPrevParaText( GetEditDoc().GetParaAsString( nPara-1 ) );
+ USHORT n = 0;
+ while ( ( n < aPrevParaText.Len() ) &&
+ ( ( aPrevParaText.GetChar(n) == ' ' ) || ( aPrevParaText.GetChar(n) == '\t' ) ) )
+ {
+ if ( aPrevParaText.GetChar(n) == '\t' )
+ aPaM = ImpInsertFeature( aPaM, SfxVoidItem( EE_FEATURE_TAB ) );
+ else
+ aPaM = ImpInsertText( aPaM, aPrevParaText.GetChar(n) );
+ n++;
+ }
+
+ }
+ return aPaM;
+}
+
+EditPaM ImpEditEngine::InsertTab( EditSelection aCurSel )
+{
+ EditPaM aPaM( ImpInsertFeature( aCurSel, SfxVoidItem( EE_FEATURE_TAB ) ) );
+ return aPaM;
+}
+
+EditPaM ImpEditEngine::InsertField( EditSelection aCurSel, const SvxFieldItem& rFld )
+{
+ EditPaM aPaM( ImpInsertFeature( aCurSel, rFld ) );
+ return aPaM;
+}
+
+BOOL ImpEditEngine::UpdateFields()
+{
+ BOOL bChanges = FALSE;
+ USHORT nParas = GetEditDoc().Count();
+ for ( USHORT nPara = 0; nPara < nParas; nPara++ )
+ {
+ BOOL bChangesInPara = FALSE;
+ ContentNode* pNode = GetEditDoc().GetObject( nPara );
+ DBG_ASSERT( pNode, "NULL-Pointer im Doc" );
+ CharAttribArray& rAttribs = pNode->GetCharAttribs().GetAttribs();
+// USHORT nAttrs = rAttribs.Count();
+ for ( USHORT nAttr = 0; nAttr < rAttribs.Count(); nAttr++ )
+ {
+ EditCharAttrib* pAttr = rAttribs[nAttr];
+ if ( pAttr->Which() == EE_FEATURE_FIELD )
+ {
+ EditCharAttribField* pField = (EditCharAttribField*)pAttr;
+ EditCharAttribField* pCurrent = new EditCharAttribField( *pField );
+ pField->Reset();
+
+ if ( aStatus.MarkFields() )
+ pField->GetFldColor() = new Color( GetColorConfig().GetColorValue( svtools::WRITERFIELDSHADINGS ).nColor );
+
+ XubString aFldValue = GetEditEnginePtr()->CalcFieldValue(
+ (const SvxFieldItem&)*pField->GetItem(),
+ nPara, pField->GetStart(),
+ pField->GetTxtColor(), pField->GetFldColor() );
+ pField->GetFieldValue() = aFldValue;
+ if ( *pField != *pCurrent )
+ {
+ bChanges = TRUE;
+ bChangesInPara = TRUE;
+ }
+ delete pCurrent;
+ }
+ }
+ if ( bChangesInPara )
+ {
+ // ggf. etwas genauer invalidieren.
+ ParaPortion* pPortion = GetParaPortions().GetObject( nPara );
+ DBG_ASSERT( pPortion, "NULL-Pointer im Doc" );
+ pPortion->MarkSelectionInvalid( 0, pNode->Len() );
+ }
+ }
+ return bChanges;
+}
+
+EditPaM ImpEditEngine::InsertLineBreak( EditSelection aCurSel )
+{
+ EditPaM aPaM( ImpInsertFeature( aCurSel, SfxVoidItem( EE_FEATURE_LINEBR ) ) );
+ return aPaM;
+}
+
+// ----------------------------------------------------------------------
+// Hilfsfunktionen
+// ----------------------------------------------------------------------
+Rectangle ImpEditEngine::PaMtoEditCursor( EditPaM aPaM, USHORT nFlags )
+{
+ DBG_ASSERT( GetUpdateMode(), "Darf bei Update=FALSE nicht erreicht werden: PaMtoEditCursor" );
+
+ Rectangle aEditCursor;
+ long nY = 0;
+ for ( USHORT nPortion = 0; nPortion < GetParaPortions().Count(); nPortion++ )
+ {
+ ParaPortion* pPortion = GetParaPortions().GetObject(nPortion);
+ ContentNode* pNode = pPortion->GetNode();
+ DBG_ASSERT( pNode, "Ungueltiger Node in Portion!" );
+ if ( pNode != aPaM.GetNode() )
+ {
+ nY += pPortion->GetHeight();
+ }
+ else
+ {
+ aEditCursor = GetEditCursor( pPortion, aPaM.GetIndex(), nFlags );
+ aEditCursor.Top() += nY;
+ aEditCursor.Bottom() += nY;
+ return aEditCursor;
+ }
+ }
+ DBG_ERROR( "Portion nicht gefunden!" );
+ return aEditCursor;
+}
+
+EditPaM ImpEditEngine::GetPaM( Point aDocPos, BOOL bSmart )
+{
+ DBG_ASSERT( GetUpdateMode(), "Darf bei Update=FALSE nicht erreicht werden: GetPaM" );
+
+ long nY = 0;
+ long nTmpHeight;
+ EditPaM aPaM;
+ USHORT nPortion;
+ for ( nPortion = 0; nPortion < GetParaPortions().Count(); nPortion++ )
+ {
+ ParaPortion* pPortion = GetParaPortions().GetObject(nPortion);
+ nTmpHeight = pPortion->GetHeight(); // sollte auch bei !bVisible richtig sein!
+ nY += nTmpHeight;
+ if ( nY > aDocPos.Y() )
+ {
+ nY -= nTmpHeight;
+ aDocPos.Y() -= nY;
+ // unsichtbare Portions ueberspringen:
+ while ( pPortion && !pPortion->IsVisible() )
+ {
+ nPortion++;
+ pPortion = GetParaPortions().SaveGetObject( nPortion );
+ }
+ DBG_ASSERT( pPortion, "Keinen sichtbaren Absatz gefunden: GetPaM" );
+ aPaM = GetPaM( pPortion, aDocPos, bSmart );
+ return aPaM;
+
+ }
+ }
+ // Dann den letzten sichtbaren Suchen:
+ nPortion = GetParaPortions().Count()-1;
+ while ( nPortion && !GetParaPortions()[nPortion]->IsVisible() )
+ nPortion--;
+
+ DBG_ASSERT( GetParaPortions()[nPortion]->IsVisible(), "Keinen sichtbaren Absatz gefunden: GetPaM" );
+ aPaM.SetNode( GetParaPortions()[nPortion]->GetNode() );
+ aPaM.SetIndex( GetParaPortions()[nPortion]->GetNode()->Len() );
+ return aPaM;
+}
+
+sal_uInt32 ImpEditEngine::GetTextHeight() const
+{
+ DBG_ASSERT( GetUpdateMode(), "Sollte bei Update=FALSE nicht verwendet werden: GetTextHeight" );
+ DBG_ASSERT( IsFormatted() || IsFormatting(), "GetTextHeight: Nicht formatiert" );
+ return nCurTextHeight;
+}
+
+sal_uInt32 ImpEditEngine::CalcTextWidth( BOOL bIgnoreExtraSpace )
+{
+ // Wenn noch nicht formatiert und nicht gerade dabei.
+ // Wird in der Formatierung bei AutoPageSize gerufen.
+ if ( !IsFormatted() && !IsFormatting() )
+ FormatDoc();
+
+ EditLine* pLine;
+
+ long nMaxWidth = 0;
+ long nCurWidth = 0;
+
+ // --------------------------------------------------
+ // Ueber alle Absaetze...
+ // --------------------------------------------------
+ USHORT nParas = GetParaPortions().Count();
+// USHORT nBiggestPara = 0;
+// USHORT nBiggestLine = 0;
+ for ( USHORT nPara = 0; nPara < nParas; nPara++ )
+ {
+ ParaPortion* pPortion = GetParaPortions().GetObject( nPara );
+ if ( pPortion->IsVisible() )
+ {
+ const SvxLRSpaceItem& rLRItem = GetLRSpaceItem( pPortion->GetNode() );
+ sal_Int32 nSpaceBeforeAndMinLabelWidth = GetSpaceBeforeAndMinLabelWidth( pPortion->GetNode() );
+
+ // --------------------------------------------------
+ // Ueber die Zeilen des Absatzes...
+ // --------------------------------------------------
+ ULONG nLines = pPortion->GetLines().Count();
+ for ( USHORT nLine = 0; nLine < nLines; nLine++ )
+ {
+ pLine = pPortion->GetLines().GetObject( nLine );
+ DBG_ASSERT( pLine, "NULL-Pointer im Zeileniterator in CalcWidth" );
+ // nCurWidth = pLine->GetStartPosX();
+ // Bei Center oder Right haengt die breite von der
+ // Papierbreite ab, hier nicht erwuenscht.
+ // Am besten generell nicht auf StartPosX verlassen,
+ // es muss auch die rechte Einrueckung beruecksichtigt werden!
+ nCurWidth = GetXValue( rLRItem.GetTxtLeft() + nSpaceBeforeAndMinLabelWidth );
+ if ( nLine == 0 )
+ {
+ long nFI = GetXValue( rLRItem.GetTxtFirstLineOfst() );
+ nCurWidth -= nFI;
+ if ( pPortion->GetBulletX() > nCurWidth )
+ {
+ nCurWidth += nFI; // LI?
+ if ( pPortion->GetBulletX() > nCurWidth )
+ nCurWidth = pPortion->GetBulletX();
+ }
+ }
+ nCurWidth += GetXValue( rLRItem.GetRight() );
+ nCurWidth += CalcLineWidth( pPortion, pLine, bIgnoreExtraSpace );
+ if ( nCurWidth > nMaxWidth )
+ {
+ nMaxWidth = nCurWidth;
+ }
+ }
+ }
+ }
+ if ( nMaxWidth < 0 )
+ nMaxWidth = 0;
+
+ nMaxWidth++; // Ein breiter, da in CreateLines bei >= umgebrochen wird.
+ return (sal_uInt32)nMaxWidth;
+}
+
+sal_uInt32 ImpEditEngine::CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, BOOL bIgnoreExtraSpace )
+{
+ USHORT nPara = GetEditDoc().GetPos( pPortion->GetNode() );
+
+ // #114278# Saving both layout mode and language (since I'm
+ // potentially changing both)
+ GetRefDevice()->Push( PUSH_TEXTLAYOUTMODE|PUSH_TEXTLANGUAGE );
+
+ ImplInitLayoutMode( GetRefDevice(), nPara, 0xFFFF );
+
+ SvxAdjust eJustification = GetJustification( nPara );
+
+ // Berechnung der Breite ohne die Indents...
+ sal_uInt32 nWidth = 0;
+ USHORT nPos = pLine->GetStart();
+ for ( USHORT nTP = pLine->GetStartPortion(); nTP <= pLine->GetEndPortion(); nTP++ )
+ {
+ TextPortion* pTextPortion = pPortion->GetTextPortions().GetObject( nTP );
+ switch ( pTextPortion->GetKind() )
+ {
+ case PORTIONKIND_FIELD:
+ case PORTIONKIND_HYPHENATOR:
+ case PORTIONKIND_TAB:
+ {
+ nWidth += pTextPortion->GetSize().Width();
+ }
+ break;
+ case PORTIONKIND_TEXT:
+ {
+ if ( ( eJustification != SVX_ADJUST_BLOCK ) || ( !bIgnoreExtraSpace ) )
+ {
+ nWidth += pTextPortion->GetSize().Width();
+ }
+ else
+ {
+ SvxFont aTmpFont( pPortion->GetNode()->GetCharAttribs().GetDefFont() );
+ SeekCursor( pPortion->GetNode(), nPos+1, aTmpFont );
+ aTmpFont.SetPhysFont( GetRefDevice() );
+ ImplInitDigitMode( GetRefDevice(), 0, 0, 0, aTmpFont.GetLanguage() );
+ nWidth += aTmpFont.QuickGetTextSize( GetRefDevice(), *pPortion->GetNode(), nPos, pTextPortion->GetLen(), NULL ).Width();
+ }
+ }
+ break;
+ }
+ nPos = nPos + pTextPortion->GetLen();
+ }
+
+ GetRefDevice()->Pop();
+
+ return nWidth;
+}
+
+sal_uInt32 ImpEditEngine::CalcTextHeight()
+{
+ DBG_ASSERT( GetUpdateMode(), "Sollte bei Update=FALSE nicht verwendet werden: CalcTextHeight" );
+ sal_uInt32 nY = 0;
+ for ( USHORT nPortion = 0; nPortion < GetParaPortions().Count(); nPortion++ )
+ nY += GetParaPortions()[nPortion]->GetHeight();
+ return nY;
+}
+
+USHORT ImpEditEngine::GetLineCount( USHORT nParagraph ) const
+{
+ DBG_ASSERT( nParagraph < GetParaPortions().Count(), "GetLineCount: Out of range" );
+ ParaPortion* pPPortion = GetParaPortions().SaveGetObject( nParagraph );
+ DBG_ASSERT( pPPortion, "Absatz nicht gefunden: GetLineCount" );
+ if ( pPPortion )
+ return pPPortion->GetLines().Count();
+
+ return 0xFFFF;
+}
+
+xub_StrLen ImpEditEngine::GetLineLen( USHORT nParagraph, USHORT nLine ) const
+{
+ DBG_ASSERT( nParagraph < GetParaPortions().Count(), "GetLineLen: Out of range" );
+ ParaPortion* pPPortion = GetParaPortions().SaveGetObject( nParagraph );
+ DBG_ASSERT( pPPortion, "Absatz nicht gefunden: GetLineLen" );
+ if ( pPPortion && ( nLine < pPPortion->GetLines().Count() ) )
+ {
+ EditLine* pLine = pPPortion->GetLines().GetObject( nLine );
+ DBG_ASSERT( pLine, "Zeile nicht gefunden: GetLineHeight" );
+ return pLine->GetLen();
+ }
+
+ return 0xFFFF;
+}
+
+void ImpEditEngine::GetLineBoundaries( /*out*/USHORT &rStart, /*out*/USHORT &rEnd, USHORT nParagraph, USHORT nLine ) const
+{
+ DBG_ASSERT( nParagraph < GetParaPortions().Count(), "GetLineCount: Out of range" );
+ ParaPortion* pPPortion = GetParaPortions().SaveGetObject( nParagraph );
+ DBG_ASSERT( pPPortion, "Absatz nicht gefunden: GetLineBoundaries" );
+ rStart = rEnd = 0xFFFF; // default values in case of error
+ if ( pPPortion && ( nLine < pPPortion->GetLines().Count() ) )
+ {
+ EditLine* pLine = pPPortion->GetLines().GetObject( nLine );
+ DBG_ASSERT( pLine, "Zeile nicht gefunden: GetLineBoundaries" );
+ rStart = pLine->GetStart();
+ rEnd = pLine->GetEnd();
+ }
+}
+
+USHORT ImpEditEngine::GetLineNumberAtIndex( USHORT nPara, USHORT nIndex ) const
+{
+ USHORT nLineNo = 0xFFFF;
+ ContentNode* pNode = GetEditDoc().SaveGetObject( nPara );
+ DBG_ASSERT( pNode, "GetLineNumberAtIndex: invalid paragraph index" );
+ if (pNode)
+ {
+ // we explicitly allow for the index to point at the character right behind the text
+ const bool bValidIndex = /*0 <= nIndex &&*/ nIndex <= pNode->Len();
+ DBG_ASSERT( bValidIndex, "GetLineNumberAtIndex: invalid index" );
+ const USHORT nLineCount = GetLineCount( nPara );
+ if (nIndex == pNode->Len())
+ nLineNo = nLineCount > 0 ? nLineCount - 1 : 0;
+ else if (bValidIndex) // nIndex < pNode->Len()
+ {
+ USHORT nStart = USHRT_MAX, nEnd = USHRT_MAX;
+ for (USHORT i = 0; i < nLineCount && nLineNo == 0xFFFF; ++i)
+ {
+ GetLineBoundaries( nStart, nEnd, nPara, i );
+ if (nStart <= nIndex && nIndex < nEnd)
+ nLineNo = i;
+ }
+ }
+ }
+ return nLineNo;
+}
+
+USHORT ImpEditEngine::GetLineHeight( USHORT nParagraph, USHORT nLine )
+{
+ DBG_ASSERT( nParagraph < GetParaPortions().Count(), "GetLineCount: Out of range" );
+ ParaPortion* pPPortion = GetParaPortions().SaveGetObject( nParagraph );
+ DBG_ASSERT( pPPortion, "Absatz nicht gefunden: GetLineHeight" );
+ if ( pPPortion && ( nLine < pPPortion->GetLines().Count() ) )
+ {
+ EditLine* pLine = pPPortion->GetLines().GetObject( nLine );
+ DBG_ASSERT( pLine, "Zeile nicht gefunden: GetLineHeight" );
+ return pLine->GetHeight();
+ }
+
+ return 0xFFFF;
+}
+
+sal_uInt32 ImpEditEngine::GetParaHeight( USHORT nParagraph )
+{
+ sal_uInt32 nHeight = 0;
+
+ ParaPortion* pPPortion = GetParaPortions().SaveGetObject( nParagraph );
+ DBG_ASSERT( pPPortion, "Absatz nicht gefunden: GetParaHeight" );
+
+ if ( pPPortion )
+ nHeight = pPPortion->GetHeight();
+
+ return nHeight;
+}
+
+void ImpEditEngine::UpdateSelections()
+{
+ USHORT nInvNodes = aDeletedNodes.Count();
+
+ // Pruefen, ob eine der Selektionen auf einem geloeschten Node steht...
+ // Wenn der Node gueltig ist, muss noch der Index geprueft werden!
+ for ( USHORT nView = 0; nView < aEditViews.Count(); nView++ )
+ {
+ EditView* pView = aEditViews.GetObject(nView);
+ DBG_CHKOBJ( pView, EditView, 0 );
+ EditSelection aCurSel( pView->pImpEditView->GetEditSelection() );
+ BOOL bChanged = FALSE;
+ for ( USHORT n = 0; n < nInvNodes; n++ )
+ {
+ DeletedNodeInfo* pInf = aDeletedNodes.GetObject( n );
+ if ( ( ( ULONG )(aCurSel.Min().GetNode()) == pInf->GetInvalidAdress() ) ||
+ ( ( ULONG )(aCurSel.Max().GetNode()) == pInf->GetInvalidAdress() ) )
+ {
+ // ParaPortions verwenden, da jetzt auch versteckte
+ // Absaetze beruecksichtigt werden muessen!
+ USHORT nPara = pInf->GetPosition();
+ ParaPortion* pPPortion = GetParaPortions().SaveGetObject( nPara );
+ if ( !pPPortion ) // letzter Absatz
+ {
+ nPara = GetParaPortions().Count()-1;
+ pPPortion = GetParaPortions().GetObject( nPara );
+ }
+ DBG_ASSERT( pPPortion, "Leeres Document in UpdateSelections ?" );
+ // Nicht aus einem verstecktem Absatz landen:
+ USHORT nCurPara = nPara;
+ USHORT nLastPara = GetParaPortions().Count()-1;
+ while ( nPara <= nLastPara && !GetParaPortions()[nPara]->IsVisible() )
+ nPara++;
+ if ( nPara > nLastPara ) // dann eben rueckwaerts...
+ {
+ nPara = nCurPara;
+ while ( nPara && !GetParaPortions()[nPara]->IsVisible() )
+ nPara--;
+ }
+ DBG_ASSERT( GetParaPortions()[nPara]->IsVisible(), "Keinen sichtbaren Absatz gefunden: UpdateSelections" );
+
+ ParaPortion* pParaPortion = GetParaPortions()[nPara];
+ EditSelection aTmpSelection( EditPaM( pParaPortion->GetNode(), 0 ) );
+ pView->pImpEditView->SetEditSelection( aTmpSelection );
+ bChanged=TRUE;
+ break; // for-Schleife
+ }
+ }
+ if ( !bChanged )
+ {
+ // Index prueffen, falls Node geschrumpft.
+ if ( aCurSel.Min().GetIndex() > aCurSel.Min().GetNode()->Len() )
+ {
+ aCurSel.Min().GetIndex() = aCurSel.Min().GetNode()->Len();
+ pView->pImpEditView->SetEditSelection( aCurSel );
+ }
+ if ( aCurSel.Max().GetIndex() > aCurSel.Max().GetNode()->Len() )
+ {
+ aCurSel.Max().GetIndex() = aCurSel.Max().GetNode()->Len();
+ pView->pImpEditView->SetEditSelection( aCurSel );
+ }
+ }
+ }
+
+ // Loeschen...
+ for ( USHORT n = 0; n < nInvNodes; n++ )
+ {
+ DeletedNodeInfo* pInf = aDeletedNodes.GetObject( n );
+ delete pInf;
+ }
+ aDeletedNodes.Remove( 0, aDeletedNodes.Count() );
+}
+
+EditSelection ImpEditEngine::ConvertSelection( USHORT nStartPara, USHORT nStartPos,
+ USHORT nEndPara, USHORT nEndPos ) const
+{
+ EditSelection aNewSelection;
+
+ // Start...
+ ContentNode* pNode = aEditDoc.SaveGetObject( nStartPara );
+ USHORT nIndex = nStartPos;
+ if ( !pNode )
+ {
+ pNode = aEditDoc[ aEditDoc.Count()-1 ];
+ nIndex = pNode->Len();
+ }
+ else if ( nIndex > pNode->Len() )
+ nIndex = pNode->Len();
+
+ aNewSelection.Min().SetNode( pNode );
+ aNewSelection.Min().SetIndex( nIndex );
+
+ // End...
+ pNode = aEditDoc.SaveGetObject( nEndPara );
+ nIndex = nEndPos;
+ if ( !pNode )
+ {
+ pNode = aEditDoc[ aEditDoc.Count()-1 ];
+ nIndex = pNode->Len();
+ }
+ else if ( nIndex > pNode->Len() )
+ nIndex = pNode->Len();
+
+ aNewSelection.Max().SetNode( pNode );
+ aNewSelection.Max().SetIndex( nIndex );
+
+ return aNewSelection;
+}
+
+EditSelection ImpEditEngine::MatchGroup( const EditSelection& rSel )
+{
+ EditSelection aMatchSel;
+ EditSelection aTmpSel( rSel );
+ aTmpSel.Adjust( GetEditDoc() );
+ if ( ( aTmpSel.Min().GetNode() != aTmpSel.Max().GetNode() ) ||
+ ( ( aTmpSel.Max().GetIndex() - aTmpSel.Min().GetIndex() ) > 1 ) )
+ {
+ return aMatchSel;
+ }
+
+ USHORT nPos = aTmpSel.Min().GetIndex();
+ ContentNode* pNode = aTmpSel.Min().GetNode();
+ if ( nPos >= pNode->Len() )
+ return aMatchSel;
+
+ USHORT nMatchChar = aGroupChars.Search( pNode->GetChar( nPos ) );
+ if ( nMatchChar != STRING_NOTFOUND )
+ {
+ USHORT nNode = aEditDoc.GetPos( pNode );
+ if ( ( nMatchChar % 2 ) == 0 )
+ {
+ // Vorwaerts suchen...
+ xub_Unicode nSC = aGroupChars.GetChar( nMatchChar );
+ DBG_ASSERT( aGroupChars.Len() > (nMatchChar+1), "Ungueltige Gruppe von MatchChars!" );
+ xub_Unicode nEC = aGroupChars.GetChar( nMatchChar+1 );
+
+ USHORT nCur = aTmpSel.Min().GetIndex()+1;
+ USHORT nLevel = 1;
+ while ( pNode && nLevel )
+ {
+ XubString& rStr = *pNode;
+ while ( nCur < rStr.Len() )
+ {
+ if ( rStr.GetChar( nCur ) == nSC )
+ nLevel++;
+ else if ( rStr.GetChar( nCur ) == nEC )
+ {
+ nLevel--;
+ if ( !nLevel )
+ break; // while nCur...
+ }
+ nCur++;
+ }
+
+ if ( nLevel )
+ {
+ nNode++;
+ pNode = nNode < aEditDoc.Count() ? aEditDoc.GetObject( nNode ) : 0;
+ nCur = 0;
+ }
+ }
+ if ( nLevel == 0 ) // gefunden
+ {
+ aMatchSel.Min() = aTmpSel.Min();
+ aMatchSel.Max() = EditPaM( pNode, nCur+1 );
+ }
+ }
+ else
+ {
+ // Rueckwaerts suchen...
+ xub_Unicode nEC = aGroupChars.GetChar( nMatchChar );
+ xub_Unicode nSC = aGroupChars.GetChar( nMatchChar-1 );
+
+ USHORT nCur = aTmpSel.Min().GetIndex()-1;
+ USHORT nLevel = 1;
+ while ( pNode && nLevel )
+ {
+ if ( pNode->Len() )
+ {
+ XubString& rStr = *pNode;
+ while ( nCur )
+ {
+ if ( rStr.GetChar( nCur ) == nSC )
+ {
+ nLevel--;
+ if ( !nLevel )
+ break; // while nCur...
+ }
+ else if ( rStr.GetChar( nCur ) == nEC )
+ nLevel++;
+
+ nCur--;
+ }
+ }
+
+ if ( nLevel )
+ {
+ pNode = nNode ? aEditDoc.GetObject( --nNode ) : 0;
+ if ( pNode )
+ nCur = pNode->Len()-1; // egal ob negativ, weil if Len()
+ }
+ }
+
+ if ( nLevel == 0 ) // gefunden
+ {
+ aMatchSel.Min() = aTmpSel.Min();
+ aMatchSel.Min().GetIndex()++; // hinter das Zeichen
+ aMatchSel.Max() = EditPaM( pNode, nCur );
+ }
+ }
+ }
+ return aMatchSel;
+}
+
+void ImpEditEngine::StopSelectionMode()
+{
+ if ( ( IsInSelectionMode() || aSelEngine.IsInSelection() ) && pActiveView )
+ {
+ pActiveView->pImpEditView->DrawSelection(); // Wegzeichnen...
+ EditSelection aSel( pActiveView->pImpEditView->GetEditSelection() );
+ aSel.Min() = aSel.Max();
+ pActiveView->pImpEditView->SetEditSelection( aSel );
+ pActiveView->ShowCursor();
+ aSelEngine.Reset();
+ bInSelection = FALSE;
+ }
+}
+
+void ImpEditEngine::SetActiveView( EditView* pView )
+{
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ // Eigentlich waere jetzt ein bHasVisSel und HideSelection notwendig !!!
+
+ if ( pView == pActiveView )
+ return;
+
+ if ( pActiveView && pActiveView->HasSelection() )
+ pActiveView->pImpEditView->DrawSelection(); // Wegzeichnen...
+
+ pActiveView = pView;
+
+ if ( pActiveView && pActiveView->HasSelection() )
+ pActiveView->pImpEditView->DrawSelection(); // Wegzeichnen...
+
+ // NN: Quick fix for #78668#:
+ // When editing of a cell in Calc is ended, the edit engine is not deleted,
+ // only the edit views are removed. If mpIMEInfos is still set in that case,
+ // mpIMEInfos->aPos points to an invalid selection.
+ // -> reset mpIMEInfos now
+ // (probably something like this is necessary whenever the content is modified
+ // from the outside)
+
+ if ( !pView && mpIMEInfos )
+ {
+ delete mpIMEInfos;
+ mpIMEInfos = NULL;
+ }
+}
+
+uno::Reference< datatransfer::XTransferable > ImpEditEngine::CreateTransferable( const EditSelection& rSelection ) const
+{
+#ifndef SVX_LIGHT
+ EditSelection aSelection( rSelection );
+ aSelection.Adjust( GetEditDoc() );
+
+ EditDataObject* pDataObj = new EditDataObject;
+ uno::Reference< datatransfer::XTransferable > xDataObj;
+ xDataObj = pDataObj;
+
+ XubString aText( GetSelected( aSelection ) );
+ aText.ConvertLineEnd(); // Systemspezifisch
+ pDataObj->GetString() = aText;
+
+ SvxFontItem::EnableStoreUnicodeNames( TRUE );
+ WriteBin( pDataObj->GetStream(), aSelection, TRUE );
+ pDataObj->GetStream().Seek( 0 );
+ SvxFontItem::EnableStoreUnicodeNames( FALSE );
+
+ ((ImpEditEngine*)this)->WriteRTF( pDataObj->GetRTFStream(), aSelection );
+ pDataObj->GetRTFStream().Seek( 0 );
+
+ if ( ( aSelection.Min().GetNode() == aSelection.Max().GetNode() )
+ && ( aSelection.Max().GetIndex() == (aSelection.Min().GetIndex()+1) ) )
+ {
+ const EditCharAttrib* pAttr = aSelection.Min().GetNode()->GetCharAttribs().
+ FindFeature( aSelection.Min().GetIndex() );
+ if ( pAttr &&
+ ( pAttr->GetStart() == aSelection.Min().GetIndex() ) &&
+ ( pAttr->Which() == EE_FEATURE_FIELD ) )
+ {
+ const SvxFieldItem* pField = (const SvxFieldItem*)pAttr->GetItem();
+ const SvxFieldData* pFld = pField->GetField();
+ if ( pFld && pFld->ISA( SvxURLField ) )
+ {
+ // Office-Bookmark
+ String aURL( ((const SvxURLField*)pFld)->GetURL() );
+ String aTxt( ((const SvxURLField*)pFld)->GetRepresentation() );
+ pDataObj->GetURL() = aURL;
+ }
+ }
+ }
+
+ return xDataObj;
+#else
+ return uno::Reference< datatransfer::XTransferable >();
+#endif
+}
+
+EditSelection ImpEditEngine::InsertText( uno::Reference< datatransfer::XTransferable >& rxDataObj, const String& rBaseURL, const EditPaM& rPaM, BOOL bUseSpecial )
+{
+ EditSelection aNewSelection( rPaM );
+
+ if ( rxDataObj.is() )
+ {
+ datatransfer::DataFlavor aFlavor;
+ BOOL bDone = FALSE;
+
+ if ( bUseSpecial )
+ {
+ // BIN
+ SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EDITENGINE, aFlavor );
+ if ( rxDataObj->isDataFlavorSupported( aFlavor ) )
+ {
+ try
+ {
+ uno::Any aData = rxDataObj->getTransferData( aFlavor );
+ uno::Sequence< sal_Int8 > aSeq;
+ aData >>= aSeq;
+ {
+ SvMemoryStream aBinStream( aSeq.getArray(), aSeq.getLength(), STREAM_READ );
+ aNewSelection = Read( aBinStream, rBaseURL, EE_FORMAT_BIN, rPaM );
+ }
+ bDone = TRUE;
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ if ( !bDone )
+ {
+ // Bookmark
+ /*
+ String aURL = ...;
+ String aTxt = ...;
+ // Feld nur einfuegen, wenn Factory vorhanden.
+ if ( ITEMDATA() && ITEMDATA()->GetClassManager().Get( SVX_URLFIELD ) )
+ {
+ SvxFieldItem aField( SvxURLField( aURL, aTxt, SVXURLFORMAT_URL ), EE_FEATURE_FIELD );
+ aNewSelection = InsertField( aPaM, aField );
+ UpdateFields();
+ }
+ else
+ aNewSelection = ImpInsertText( aPaM, aURL );
+ }
+ */
+ }
+ if ( !bDone )
+ {
+ // RTF
+ SotExchange::GetFormatDataFlavor( SOT_FORMAT_RTF, aFlavor );
+ if ( rxDataObj->isDataFlavorSupported( aFlavor ) )
+ {
+ try
+ {
+ uno::Any aData = rxDataObj->getTransferData( aFlavor );
+ uno::Sequence< sal_Int8 > aSeq;
+ aData >>= aSeq;
+ {
+ SvMemoryStream aRTFStream( aSeq.getArray(), aSeq.getLength(), STREAM_READ );
+ aNewSelection = Read( aRTFStream, rBaseURL, EE_FORMAT_RTF, rPaM );
+ }
+ bDone = TRUE;
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ }
+ if ( !bDone )
+ {
+ // XML ?
+ // Currently, there is nothing like "The" XML format, StarOffice doesn't offer plain XML in Clipboard...
+ }
+ }
+ if ( !bDone )
+ {
+ SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aFlavor );
+ if ( rxDataObj->isDataFlavorSupported( aFlavor ) )
+ {
+ try
+ {
+ uno::Any aData = rxDataObj->getTransferData( aFlavor );
+ ::rtl::OUString aText;
+ aData >>= aText;
+ aNewSelection = ImpInsertText( rPaM, aText );
+ bDone = TRUE;
+ }
+ catch( ... )
+ {
+ ; // #i9286# can happen, even if isDataFlavorSupported returns true...
+ }
+ }
+ }
+ }
+
+ return aNewSelection;
+}
+
+Range ImpEditEngine::GetInvalidYOffsets( ParaPortion* pPortion )
+{
+ Range aRange( 0, 0 );
+
+ if ( pPortion->IsVisible() )
+ {
+ const SvxULSpaceItem& rULSpace = (const SvxULSpaceItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
+ const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
+ USHORT nSBL = ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX )
+ ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
+
+ // erst von vorne...
+ USHORT nFirstInvalid = 0xFFFF;
+ USHORT nLine;
+ for ( nLine = 0; nLine < pPortion->GetLines().Count(); nLine++ )
+ {
+ EditLine* pL = pPortion->GetLines().GetObject( nLine );
+ if ( pL->IsInvalid() )
+ {
+ nFirstInvalid = nLine;
+ break;
+ }
+ if ( nLine && !aStatus.IsOutliner() ) // nicht die erste Zeile
+ aRange.Min() += nSBL;
+ aRange.Min() += pL->GetHeight();
+ }
+ DBG_ASSERT( nFirstInvalid != 0xFFFF, "Keine ungueltige Zeile gefunden in GetInvalidYOffset(1)" );
+
+
+ // Abgleichen und weiter...
+ aRange.Max() = aRange.Min();
+ aRange.Max() += pPortion->GetFirstLineOffset();
+ if ( nFirstInvalid != 0 ) // Nur wenn nicht die erste Zeile ungueltig
+ aRange.Min() = aRange.Max();
+
+ USHORT nLastInvalid = pPortion->GetLines().Count()-1;
+ for ( nLine = nFirstInvalid; nLine < pPortion->GetLines().Count(); nLine++ )
+ {
+ EditLine* pL = pPortion->GetLines().GetObject( nLine );
+ if ( pL->IsValid() )
+ {
+ nLastInvalid = nLine;
+ break;
+ }
+
+ if ( nLine && !aStatus.IsOutliner() )
+ aRange.Max() += nSBL;
+ aRange.Max() += pL->GetHeight();
+ }
+
+ // MT 07/00 SBL kann jetzt kleiner 100% sein => ggf. die Zeile davor neu ausgeben.
+ if( ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP ) && rLSItem.GetPropLineSpace() &&
+ ( rLSItem.GetPropLineSpace() < 100 ) )
+ {
+ EditLine* pL = pPortion->GetLines().GetObject( nFirstInvalid );
+ long n = pL->GetTxtHeight() * ( 100 - rLSItem.GetPropLineSpace() );
+ n /= 100;
+ aRange.Min() -= n;
+ aRange.Max() += n;
+ }
+
+ if ( ( nLastInvalid == pPortion->GetLines().Count()-1 ) && ( !aStatus.IsOutliner() ) )
+ aRange.Max() += GetYValue( rULSpace.GetLower() );
+ }
+ return aRange;
+}
+
+EditPaM ImpEditEngine::GetPaM( ParaPortion* pPortion, Point aDocPos, BOOL bSmart )
+{
+ DBG_ASSERT( pPortion->IsVisible(), "Wozu GetPaM() bei einem unsichtbaren Absatz?" );
+ DBG_ASSERT( IsFormatted(), "GetPaM: Nicht formatiert" );
+
+ USHORT nCurIndex = 0;
+ EditPaM aPaM;
+ aPaM.SetNode( pPortion->GetNode() );
+
+ const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
+ USHORT nSBL = ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX )
+ ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
+
+ long nY = pPortion->GetFirstLineOffset();
+
+ DBG_ASSERT( pPortion->GetLines().Count(), "Leere ParaPortion in GetPaM!" );
+
+ EditLine* pLine = 0;
+ for ( USHORT nLine = 0; nLine < pPortion->GetLines().Count(); nLine++ )
+ {
+ EditLine* pTmpLine = pPortion->GetLines().GetObject( nLine );
+ nY += pTmpLine->GetHeight();
+ if ( !aStatus.IsOutliner() )
+ nY += nSBL;
+ if ( nY > aDocPos.Y() ) // das war 'se
+ {
+ pLine = pTmpLine;
+ break; // richtige Y-Position intressiert nicht
+ }
+
+ nCurIndex = nCurIndex + pTmpLine->GetLen();
+ }
+
+ if ( !pLine ) // darf nur im Bereich von SA passieren!
+ {
+ #ifdef DBG_UTIL
+ const SvxULSpaceItem& rULSpace =(const SvxULSpaceItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
+ DBG_ASSERT( nY+GetYValue( rULSpace.GetLower() ) >= aDocPos.Y() , "Index in keiner Zeile, GetPaM ?" );
+ #endif
+ aPaM.SetIndex( pPortion->GetNode()->Len() );
+ return aPaM;
+ }
+
+ // Wenn Zeile gefunden, nur noch X-Position => Index
+ nCurIndex = GetChar( pPortion, pLine, aDocPos.X(), bSmart );
+ aPaM.SetIndex( nCurIndex );
+
+ if ( nCurIndex && ( nCurIndex == pLine->GetEnd() ) &&
+ ( pLine != pPortion->GetLines().GetObject( pPortion->GetLines().Count()-1) ) )
+ {
+ aPaM = CursorLeft( aPaM, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL );
+ }
+
+ return aPaM;
+}
+
+USHORT ImpEditEngine::GetChar( ParaPortion* pParaPortion, EditLine* pLine, long nXPos, BOOL bSmart )
+{
+ DBG_ASSERT( pLine, "Keine Zeile erhalten: GetChar" );
+
+ USHORT nChar = 0xFFFF;
+ USHORT nCurIndex = pLine->GetStart();
+
+
+ // Search best matching portion with GetPortionXOffset()
+ for ( USHORT i = pLine->GetStartPortion(); i <= pLine->GetEndPortion(); i++ )
+ {
+ TextPortion* pPortion = pParaPortion->GetTextPortions().GetObject( i );
+ long nXLeft = GetPortionXOffset( pParaPortion, pLine, i );
+ long nXRight = nXLeft + pPortion->GetSize().Width();
+ if ( ( nXLeft <= nXPos ) && ( nXRight >= nXPos ) )
+ {
+ nChar = nCurIndex;
+
+ // Search within Portion...
+
+ // Don't search within special portions...
+ if ( pPortion->GetKind() != PORTIONKIND_TEXT )
+ {
+ // ...but check on which side
+ if ( bSmart )
+ {
+ long nLeftDiff = nXPos-nXLeft;
+ long nRightDiff = nXRight-nXPos;
+ if ( nRightDiff < nLeftDiff )
+ nChar++;
+ }
+ }
+ else
+ {
+ USHORT nMax = pPortion->GetLen();
+ USHORT nOffset = 0xFFFF;
+ USHORT nTmpCurIndex = nChar - pLine->GetStart();
+
+ long nXInPortion = nXPos - nXLeft;
+ if ( pPortion->IsRightToLeft() )
+ nXInPortion = nXRight - nXPos;
+
+ // Search in Array...
+ for ( USHORT x = 0; x < nMax; x++ )
+ {
+ long nTmpPosMax = pLine->GetCharPosArray().GetObject( nTmpCurIndex+x );
+ if ( nTmpPosMax > nXInPortion )
+ {
+ // pruefen, ob dieser oder der davor...
+ long nTmpPosMin = x ? pLine->GetCharPosArray().GetObject( nTmpCurIndex+x-1 ) : 0;
+ long nDiffLeft = nXInPortion - nTmpPosMin;
+ long nDiffRight = nTmpPosMax - nXInPortion;
+ DBG_ASSERT( nDiffLeft >= 0, "DiffLeft negativ" );
+ DBG_ASSERT( nDiffRight >= 0, "DiffRight negativ" );
+ nOffset = ( bSmart && ( nDiffRight < nDiffLeft ) ) ? x+1 : x;
+ // I18N: If there are character position with the length of 0,
+ // they belong to the same character, we can not use this position as an index.
+ // Skip all 0-positions, cheaper than using XBreakIterator:
+ if ( nOffset < nMax )
+ {
+ const long nX = pLine->GetCharPosArray().GetObject(nOffset);
+ while ( ( (nOffset+1) < nMax ) && ( pLine->GetCharPosArray().GetObject(nOffset+1) == nX ) )
+ nOffset++;
+ }
+ break;
+ }
+ }
+
+ // Bei Verwendung des CharPosArray duerfte es keine Ungenauigkeiten geben!
+ // Vielleicht bei Kerning ?
+ // 0xFFF passiert z.B. bei Outline-Font, wenn ganz hinten.
+ if ( nOffset == 0xFFFF )
+ nOffset = nMax;
+
+ DBG_ASSERT( nOffset <= nMax, "nOffset > nMax" );
+
+ nChar = nChar + nOffset;
+
+ // Check if index is within a cell:
+ if ( nChar && ( nChar < pParaPortion->GetNode()->Len() ) )
+ {
+ EditPaM aPaM( pParaPortion->GetNode(), nChar+1 );
+ USHORT nScriptType = GetScriptType( aPaM );
+ if ( nScriptType == i18n::ScriptType::COMPLEX )
+ {
+ uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
+ sal_Int32 nCount = 1;
+ lang::Locale aLocale = GetLocale( aPaM );
+ USHORT nRight = (USHORT)_xBI->nextCharacters( *pParaPortion->GetNode(), nChar, aLocale, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, nCount, nCount );
+ USHORT nLeft = (USHORT)_xBI->previousCharacters( *pParaPortion->GetNode(), nRight, aLocale, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, nCount, nCount );
+ if ( ( nLeft != nChar ) && ( nRight != nChar ) )
+ {
+ nChar = ( Abs( nRight - nChar ) < Abs( nLeft - nChar ) ) ? nRight : nLeft;
+ }
+ }
+ }
+ }
+ }
+
+ nCurIndex = nCurIndex + pPortion->GetLen();
+ }
+
+ if ( nChar == 0xFFFF )
+ {
+ nChar = ( nXPos <= pLine->GetStartPosX() ) ? pLine->GetStart() : pLine->GetEnd();
+ }
+
+ return nChar;
+}
+
+Range ImpEditEngine::GetLineXPosStartEnd( ParaPortion* pParaPortion, EditLine* pLine )
+{
+ Range aLineXPosStartEnd;
+
+ USHORT nPara = GetEditDoc().GetPos( pParaPortion->GetNode() );
+ if ( !IsRightToLeft( nPara ) )
+ {
+ aLineXPosStartEnd.Min() = pLine->GetStartPosX();
+ aLineXPosStartEnd.Max() = pLine->GetStartPosX() + pLine->GetTextWidth();
+ }
+ else
+ {
+ aLineXPosStartEnd.Min() = GetPaperSize().Width() - ( pLine->GetStartPosX() + pLine->GetTextWidth() );
+ aLineXPosStartEnd.Max() = GetPaperSize().Width() - pLine->GetStartPosX();
+ }
+
+
+ return aLineXPosStartEnd;
+}
+
+long ImpEditEngine::GetPortionXOffset( ParaPortion* pParaPortion, EditLine* pLine, USHORT nTextPortion )
+{
+ long nX = pLine->GetStartPosX();
+
+ for ( USHORT i = pLine->GetStartPortion(); i < nTextPortion; i++ )
+ {
+ TextPortion* pPortion = pParaPortion->GetTextPortions().GetObject( i );
+ switch ( pPortion->GetKind() )
+ {
+ case PORTIONKIND_FIELD:
+ case PORTIONKIND_TEXT:
+ case PORTIONKIND_HYPHENATOR:
+ case PORTIONKIND_TAB:
+// case PORTIONKIND_EXTRASPACE:
+ {
+ nX += pPortion->GetSize().Width();
+ }
+ break;
+ }
+ }
+
+ USHORT nPara = GetEditDoc().GetPos( pParaPortion->GetNode() );
+ BOOL bR2LPara = IsRightToLeft( nPara );
+
+ TextPortion* pDestPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
+ if ( pDestPortion->GetKind() != PORTIONKIND_TAB )
+ {
+ if ( !bR2LPara && pDestPortion->GetRightToLeft() )
+ {
+ // Portions behind must be added, visual before this portion
+ sal_uInt16 nTmpPortion = nTextPortion+1;
+ while ( nTmpPortion <= pLine->GetEndPortion() )
+ {
+ TextPortion* pNextTextPortion = pParaPortion->GetTextPortions().GetObject( nTmpPortion );
+ if ( pNextTextPortion->GetRightToLeft() && ( pNextTextPortion->GetKind() != PORTIONKIND_TAB ) )
+ nX += pNextTextPortion->GetSize().Width();
+ else
+ break;
+ nTmpPortion++;
+ }
+ // Portions before must be removed, visual behind this portion
+ nTmpPortion = nTextPortion;
+ while ( nTmpPortion > pLine->GetStartPortion() )
+ {
+ --nTmpPortion;
+ TextPortion* pPrevTextPortion = pParaPortion->GetTextPortions().GetObject( nTmpPortion );
+ if ( pPrevTextPortion->GetRightToLeft() && ( pPrevTextPortion->GetKind() != PORTIONKIND_TAB ) )
+ nX -= pPrevTextPortion->GetSize().Width();
+ else
+ break;
+ }
+ }
+ else if ( bR2LPara && !pDestPortion->IsRightToLeft() )
+ {
+ // Portions behind must be ermoved, visual behind this portion
+ sal_uInt16 nTmpPortion = nTextPortion+1;
+ while ( nTmpPortion <= pLine->GetEndPortion() )
+ {
+ TextPortion* pNextTextPortion = pParaPortion->GetTextPortions().GetObject( nTmpPortion );
+ if ( !pNextTextPortion->IsRightToLeft() && ( pNextTextPortion->GetKind() != PORTIONKIND_TAB ) )
+ nX += pNextTextPortion->GetSize().Width();
+ else
+ break;
+ nTmpPortion++;
+ }
+ // Portions before must be added, visual before this portion
+ nTmpPortion = nTextPortion;
+ while ( nTmpPortion > pLine->GetStartPortion() )
+ {
+ --nTmpPortion;
+ TextPortion* pPrevTextPortion = pParaPortion->GetTextPortions().GetObject( nTmpPortion );
+ if ( !pPrevTextPortion->IsRightToLeft() && ( pPrevTextPortion->GetKind() != PORTIONKIND_TAB ) )
+ nX -= pPrevTextPortion->GetSize().Width();
+ else
+ break;
+ }
+ }
+ }
+ if ( bR2LPara )
+ {
+ // Switch X postions...
+ DBG_ASSERT( GetTextRanger() || GetPaperSize().Width(), "GetPortionXOffset - paper size?!" );
+ DBG_ASSERT( GetTextRanger() || (nX <= GetPaperSize().Width()), "GetPortionXOffset - position out of paper size!" );
+ nX = GetPaperSize().Width() - nX;
+ nX -= pDestPortion->GetSize().Width();
+ }
+
+ return nX;
+}
+
+long ImpEditEngine::GetXPos( ParaPortion* pParaPortion, EditLine* pLine, USHORT nIndex, BOOL bPreferPortionStart )
+{
+ DBG_ASSERT( pLine, "Keine Zeile erhalten: GetXPos" );
+ DBG_ASSERT( ( nIndex >= pLine->GetStart() ) && ( nIndex <= pLine->GetEnd() ) , "GetXPos muss richtig gerufen werden!" );
+
+ BOOL bDoPreferPortionStart = bPreferPortionStart;
+ // Assure that the portion belongs to this line:
+ if ( nIndex == pLine->GetStart() )
+ bDoPreferPortionStart = TRUE;
+ else if ( nIndex == pLine->GetEnd() )
+ bDoPreferPortionStart = FALSE;
+
+ USHORT nTextPortionStart = 0;
+ USHORT nTextPortion = pParaPortion->GetTextPortions().FindPortion( nIndex, nTextPortionStart, bDoPreferPortionStart );
+
+ DBG_ASSERT( ( nTextPortion >= pLine->GetStartPortion() ) && ( nTextPortion <= pLine->GetEndPortion() ), "GetXPos: Portion not in current line! " );
+
+ TextPortion* pPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
+
+ long nX = GetPortionXOffset( pParaPortion, pLine, nTextPortion );
+
+ // calc text width, portion size may include CJK/CTL spacing...
+ // But the array migh not be init yet, if using text ranger this method is called within CreateLines()...
+ long nPortionTextWidth = pPortion->GetSize().Width();
+ if ( ( pPortion->GetKind() == PORTIONKIND_TEXT ) && pPortion->GetLen() && !GetTextRanger() )
+ nPortionTextWidth = pLine->GetCharPosArray().GetObject( nTextPortionStart + pPortion->GetLen() - 1 - pLine->GetStart() );
+
+ if ( nTextPortionStart != nIndex )
+ {
+ // Search within portion...
+ if ( nIndex == ( nTextPortionStart + pPortion->GetLen() ) )
+ {
+ // End of Portion
+ if ( pPortion->GetKind() == PORTIONKIND_TAB )
+ {
+ if ( (nTextPortion+1) < pParaPortion->GetTextPortions().Count() )
+ {
+ TextPortion* pNextPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion+1 );
+ if ( pNextPortion->GetKind() != PORTIONKIND_TAB )
+ {
+ // DBG_ASSERT( !bPreferPortionStart, "GetXPos - How can we this tab portion here???" );
+ // #109879# We loop if nIndex == pLine->GetEnd, because bPreferPortionStart will be reset
+ if ( !bPreferPortionStart )
+ nX = GetXPos( pParaPortion, pLine, nIndex, TRUE );
+ else if ( !IsRightToLeft( GetEditDoc().GetPos( pParaPortion->GetNode() ) ) )
+ nX += nPortionTextWidth;
+ }
+ }
+ else if ( !IsRightToLeft( GetEditDoc().GetPos( pParaPortion->GetNode() ) ) )
+ {
+ nX += nPortionTextWidth;
+ }
+ }
+ else if ( !pPortion->IsRightToLeft() )
+ {
+ nX += nPortionTextWidth;
+ }
+ }
+ else if ( pPortion->GetKind() == PORTIONKIND_TEXT )
+ {
+ DBG_ASSERT( nIndex != pLine->GetStart(), "Strange behavior in new GetXPos()" );
+ DBG_ASSERT( pLine && pLine->GetCharPosArray().Count(), "svx::ImpEditEngine::GetXPos(), portion in an empty line?" );
+
+ if( pLine->GetCharPosArray().Count() )
+ {
+ USHORT nPos = nIndex - 1 - pLine->GetStart();
+ if( nPos >= pLine->GetCharPosArray().Count() )
+ {
+ nPos = pLine->GetCharPosArray().Count()-1;
+ DBG_ERROR("svx::ImpEditEngine::GetXPos(), index out of range!");
+ }
+
+ long nPosInPortion = pLine->GetCharPosArray().GetObject( nPos );
+
+ if ( !pPortion->IsRightToLeft() )
+ {
+ nX += nPosInPortion;
+ }
+ else
+ {
+ nX += nPortionTextWidth - nPosInPortion;
+ }
+
+ if ( pPortion->GetExtraInfos() && pPortion->GetExtraInfos()->bCompressed )
+ {
+ nX += pPortion->GetExtraInfos()->nPortionOffsetX;
+ if ( pPortion->GetExtraInfos()->nAsianCompressionTypes & CHAR_PUNCTUATIONRIGHT )
+ {
+ BYTE nType = GetCharTypeForCompression( pParaPortion->GetNode()->GetChar( nIndex ) );
+ if ( nType == CHAR_PUNCTUATIONRIGHT )
+ {
+ USHORT n = nIndex - nTextPortionStart;
+ const sal_Int32* pDXArray = pLine->GetCharPosArray().GetData()+( nTextPortionStart-pLine->GetStart() );
+ sal_Int32 nCharWidth = ( ( (n+1) < pPortion->GetLen() ) ? pDXArray[n] : pPortion->GetSize().Width() )
+ - ( n ? pDXArray[n-1] : 0 );
+ if ( (n+1) < pPortion->GetLen() )
+ {
+ // smaller, when char behind is CHAR_PUNCTUATIONRIGHT also
+ nType = GetCharTypeForCompression( pParaPortion->GetNode()->GetChar( nIndex+1 ) );
+ if ( nType == CHAR_PUNCTUATIONRIGHT )
+ {
+ sal_Int32 nNextCharWidth = ( ( (n+2) < pPortion->GetLen() ) ? pDXArray[n+1] : pPortion->GetSize().Width() )
+ - pDXArray[n];
+ sal_Int32 nCompressed = nNextCharWidth/2;
+ nCompressed *= pPortion->GetExtraInfos()->nMaxCompression100thPercent;
+ nCompressed /= 10000;
+ nCharWidth += nCompressed;
+ }
+ }
+ else
+ {
+ nCharWidth *= 2; // last char pos to portion end is only compressed size
+ }
+ nX += nCharWidth/2; // 50% compression
+ }
+ }
+ }
+ }
+ }
+ }
+ else // if ( nIndex == pLine->GetStart() )
+ {
+ if ( pPortion->IsRightToLeft() )
+ {
+ nX += nPortionTextWidth;
+ }
+ }
+
+ return nX;
+}
+
+void ImpEditEngine::CalcHeight( ParaPortion* pPortion )
+{
+ pPortion->nHeight = 0;
+ pPortion->nFirstLineOffset = 0;
+
+ if ( pPortion->IsVisible() )
+ {
+ DBG_ASSERT( pPortion->GetLines().Count(), "Absatz ohne Zeilen in ParaPortion::CalcHeight" );
+ for ( USHORT nLine = 0; nLine < pPortion->GetLines().Count(); nLine++ )
+ pPortion->nHeight += pPortion->GetLines().GetObject( nLine )->GetHeight();
+
+ if ( !aStatus.IsOutliner() )
+ {
+ const SvxULSpaceItem& rULItem = (const SvxULSpaceItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
+ const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
+ USHORT nSBL = ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX ) ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
+
+ if ( nSBL )
+ {
+ if ( pPortion->GetLines().Count() > 1 )
+ pPortion->nHeight += ( pPortion->GetLines().Count() - 1 ) * nSBL;
+ if ( aStatus.ULSpaceSummation() )
+ pPortion->nHeight += nSBL;
+ }
+
+ USHORT nPortion = GetParaPortions().GetPos( pPortion );
+ if ( nPortion || aStatus.ULSpaceFirstParagraph() )
+ {
+ USHORT nUpper = GetYValue( rULItem.GetUpper() );
+ pPortion->nHeight += nUpper;
+ pPortion->nFirstLineOffset = nUpper;
+ }
+
+ if ( ( nPortion != (GetParaPortions().Count()-1) ) )
+ {
+ pPortion->nHeight += GetYValue( rULItem.GetLower() ); // nicht in letzter
+ }
+
+
+ if ( nPortion && !aStatus.ULSpaceSummation() )
+ {
+ ParaPortion* pPrev = GetParaPortions().SaveGetObject( nPortion-1 );
+ const SvxULSpaceItem& rPrevULItem = (const SvxULSpaceItem&)pPrev->GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
+ const SvxLineSpacingItem& rPrevLSItem = (const SvxLineSpacingItem&)pPrev->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
+
+ // Verhalten WinWord6/Writer3:
+ // Bei einem proportionalen Zeilenabstand wird auch der Absatzabstand
+ // manipuliert.
+ // Nur Writer3: Nicht aufaddieren, sondern Mindestabstand.
+
+ // Pruefen, ob Abstand durch LineSpacing > Upper:
+ USHORT nExtraSpace = GetYValue( lcl_CalcExtraSpace( pPortion, rLSItem ) );
+ if ( nExtraSpace > pPortion->nFirstLineOffset )
+ {
+ // Absatz wird 'groesser':
+ pPortion->nHeight += ( nExtraSpace - pPortion->nFirstLineOffset );
+ pPortion->nFirstLineOffset = nExtraSpace;
+ }
+
+ // nFirstLineOffset jetzt f(pNode) => jetzt f(pNode, pPrev) ermitteln:
+ USHORT nPrevLower = GetYValue( rPrevULItem.GetLower() );
+
+ // Dieser PrevLower steckt noch in der Hoehe der PrevPortion...
+ if ( nPrevLower > pPortion->nFirstLineOffset )
+ {
+ // Absatz wird 'kleiner':
+ pPortion->nHeight -= pPortion->nFirstLineOffset;
+ pPortion->nFirstLineOffset = 0;
+ }
+ else if ( nPrevLower )
+ {
+ // Absatz wird 'etwas kleiner':
+ pPortion->nHeight -= nPrevLower;
+ pPortion->nFirstLineOffset =
+ pPortion->nFirstLineOffset - nPrevLower;
+ }
+
+ // Finde ich zwar nicht so gut, aber Writer3-Feature:
+ // Pruefen, ob Abstand durch LineSpacing > Lower:
+ // Dieser Wert steckt nicht in der Hoehe der PrevPortion.
+ if ( !pPrev->IsInvalid() )
+ {
+ nExtraSpace = GetYValue( lcl_CalcExtraSpace( pPrev, rPrevLSItem ) );
+ if ( nExtraSpace > nPrevLower )
+ {
+ USHORT nMoreLower = nExtraSpace - nPrevLower;
+ // Absatz wird 'groesser', 'waechst' nach unten:
+ if ( nMoreLower > pPortion->nFirstLineOffset )
+ {
+ pPortion->nHeight += ( nMoreLower - pPortion->nFirstLineOffset );
+ pPortion->nFirstLineOffset = nMoreLower;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+Rectangle ImpEditEngine::GetEditCursor( ParaPortion* pPortion, USHORT nIndex, USHORT nFlags )
+{
+ DBG_ASSERT( pPortion->IsVisible(), "Wozu GetEditCursor() bei einem unsichtbaren Absatz?" );
+ DBG_ASSERT( IsFormatted() || GetTextRanger(), "GetEditCursor: Nicht formatiert" );
+
+ /*
+ GETCRSR_ENDOFLINE: Wenn hinter dem letzten Zeichen einer umgebrochenen Zeile,
+ am Ende der Zeile bleiben, nicht am Anfang der naechsten.
+ Zweck: - END => wirklich hinter das letzte Zeichen
+ - Selektion....
+ */
+
+ long nY = pPortion->GetFirstLineOffset();
+
+ const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
+ USHORT nSBL = ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX )
+ ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
+
+ USHORT nCurIndex = 0;
+ DBG_ASSERT( pPortion->GetLines().Count(), "Leere ParaPortion in GetEditCursor!" );
+ EditLine* pLine = 0;
+ BOOL bEOL = ( nFlags & GETCRSR_ENDOFLINE ) ? TRUE : FALSE;
+ for ( USHORT nLine = 0; nLine < pPortion->GetLines().Count(); nLine++ )
+ {
+ EditLine* pTmpLine = pPortion->GetLines().GetObject( nLine );
+ if ( ( pTmpLine->GetStart() == nIndex ) || ( pTmpLine->IsIn( nIndex, bEOL ) ) )
+ {
+ pLine = pTmpLine;
+ break;
+ }
+
+ nCurIndex = nCurIndex + pTmpLine->GetLen();
+ nY += pTmpLine->GetHeight();
+ if ( !aStatus.IsOutliner() )
+ nY += nSBL;
+ }
+ if ( !pLine )
+ {
+ // Cursor am Ende des Absatzes.
+ DBG_ASSERT( nIndex == nCurIndex, "Index voll daneben in GetEditCursor!" );
+
+ pLine = pPortion->GetLines().GetObject( pPortion->GetLines().Count()-1 );
+ nY -= pLine->GetHeight();
+ if ( !aStatus.IsOutliner() )
+ nY -= nSBL;
+ nCurIndex = nCurIndex - pLine->GetLen();
+ }
+
+ Rectangle aEditCursor;
+
+ aEditCursor.Top() = nY;
+ nY += pLine->GetHeight();
+ aEditCursor.Bottom() = nY-1;
+
+ // innerhalb der Zeile suchen...
+ long nX;
+
+ if ( ( nIndex == pLine->GetStart() ) && ( nFlags & GETCRSR_STARTOFLINE ) )
+ {
+ Range aXRange = GetLineXPosStartEnd( pPortion, pLine );
+ nX = !IsRightToLeft( GetEditDoc().GetPos( pPortion->GetNode() ) ) ? aXRange.Min() : aXRange.Max();
+ }
+ else if ( ( nIndex == pLine->GetEnd() ) && ( nFlags & GETCRSR_ENDOFLINE ) )
+ {
+ Range aXRange = GetLineXPosStartEnd( pPortion, pLine );
+ nX = !IsRightToLeft( GetEditDoc().GetPos( pPortion->GetNode() ) ) ? aXRange.Max() : aXRange.Min();
+ }
+ else
+ {
+ nX = GetXPos( pPortion, pLine, nIndex, ( nFlags & GETCRSR_PREFERPORTIONSTART ) ? TRUE : FALSE );
+ }
+
+ aEditCursor.Left() = aEditCursor.Right() = nX;
+
+ if ( nFlags & GETCRSR_TXTONLY )
+ aEditCursor.Top() = aEditCursor.Bottom() - pLine->GetTxtHeight() + 1;
+ else
+ aEditCursor.Top() = aEditCursor.Bottom() - Min( pLine->GetTxtHeight(), pLine->GetHeight() ) + 1;
+
+ return aEditCursor;
+}
+
+void ImpEditEngine::SetValidPaperSize( const Size& rNewSz )
+{
+ aPaperSize = rNewSz;
+
+ long nMinWidth = aStatus.AutoPageWidth() ? aMinAutoPaperSize.Width() : 0;
+ long nMaxWidth = aStatus.AutoPageWidth() ? aMaxAutoPaperSize.Width() : 0x7FFFFFFF;
+ long nMinHeight = aStatus.AutoPageHeight() ? aMinAutoPaperSize.Height() : 0;
+ long nMaxHeight = aStatus.AutoPageHeight() ? aMaxAutoPaperSize.Height() : 0x7FFFFFFF;
+
+ // Minimale/Maximale Breite:
+ if ( aPaperSize.Width() < nMinWidth )
+ aPaperSize.Width() = nMinWidth;
+ else if ( aPaperSize.Width() > nMaxWidth )
+ aPaperSize.Width() = nMaxWidth;
+
+ // Minimale/Maximale Hoehe:
+ if ( aPaperSize.Height() < nMinHeight )
+ aPaperSize.Height() = nMinHeight;
+ else if ( aPaperSize.Height() > nMaxHeight )
+ aPaperSize.Height() = nMaxHeight;
+}
+
+void ImpEditEngine::IndentBlock( EditView* pEditView, BOOL bRight )
+{
+ ESelection aESel( CreateESel( pEditView->pImpEditView->GetEditSelection() ) );
+ aESel.Adjust();
+
+ // Nur wenn mehrere selektierte Absaetze...
+ if ( aESel.nEndPara > aESel.nStartPara )
+ {
+ ESelection aNewSel = aESel;
+ aNewSel.nStartPos = 0;
+ aNewSel.nEndPos = 0xFFFF;
+
+ if ( aESel.nEndPos == 0 )
+ {
+ aESel.nEndPara--; // dann diesen Absatz nicht...
+ aNewSel.nEndPos = 0;
+ }
+
+ pEditView->pImpEditView->DrawSelection();
+ pEditView->pImpEditView->SetEditSelection(
+ pEditView->pImpEditView->GetEditSelection().Max() );
+ UndoActionStart( bRight ? EDITUNDO_INDENTBLOCK : EDITUNDO_UNINDENTBLOCK );
+
+ for ( USHORT nPara = aESel.nStartPara; nPara <= aESel.nEndPara; nPara++ )
+ {
+ ContentNode* pNode = GetEditDoc().GetObject( nPara );
+ if ( bRight )
+ {
+ // Tabs hinzufuegen
+ EditPaM aPaM( pNode, 0 );
+ InsertTab( aPaM );
+ }
+ else
+ {
+ // Tabs entfernen
+ EditCharAttrib* pFeature = pNode->GetCharAttribs().FindFeature( 0 );
+ if ( pFeature && ( pFeature->GetStart() == 0 ) &&
+ ( pFeature->GetItem()->Which() == EE_FEATURE_TAB ) )
+ {
+ EditPaM aStartPaM( pNode, 0 );
+ EditPaM aEndPaM( pNode, 1 );
+ ImpDeleteSelection( EditSelection( aStartPaM, aEndPaM ) );
+ }
+ }
+ }
+
+ UndoActionEnd( bRight ? EDITUNDO_INDENTBLOCK : EDITUNDO_UNINDENTBLOCK );
+ UpdateSelections();
+ FormatAndUpdate( pEditView );
+
+ ContentNode* pLastNode = GetEditDoc().GetObject( aNewSel.nEndPara );
+ if ( pLastNode->Len() < aNewSel.nEndPos )
+ aNewSel.nEndPos = pLastNode->Len();
+ pEditView->pImpEditView->SetEditSelection( CreateSel( aNewSel ) );
+ pEditView->pImpEditView->DrawSelection();
+ pEditView->pImpEditView->ShowCursor( FALSE, TRUE );
+ }
+}
+
+vos::ORef<SvxForbiddenCharactersTable> ImpEditEngine::GetForbiddenCharsTable( BOOL bGetInternal ) const
+{
+ vos::ORef<SvxForbiddenCharactersTable> xF = xForbiddenCharsTable;
+ if ( !xF.isValid() && bGetInternal )
+ xF = EE_DLL()->GetGlobalData()->GetForbiddenCharsTable();
+ return xF;
+}
+
+void ImpEditEngine::SetForbiddenCharsTable( vos::ORef<SvxForbiddenCharactersTable> xForbiddenChars )
+{
+ EE_DLL()->GetGlobalData()->SetForbiddenCharsTable( xForbiddenChars );
+}
+
+svtools::ColorConfig& ImpEditEngine::GetColorConfig()
+{
+ if ( !pColorConfig )
+ pColorConfig = new svtools::ColorConfig;
+
+ return *pColorConfig;
+}
+
+BOOL ImpEditEngine::IsVisualCursorTravelingEnabled()
+{
+ BOOL bVisualCursorTravaling = FALSE;
+
+ if( !pCTLOptions )
+ pCTLOptions = new SvtCTLOptions;
+
+ if ( pCTLOptions->IsCTLFontEnabled() && ( pCTLOptions->GetCTLCursorMovement() == SvtCTLOptions::MOVEMENT_VISUAL ) )
+ {
+ bVisualCursorTravaling = TRUE;
+ }
+
+ return bVisualCursorTravaling;
+
+}
+
+BOOL ImpEditEngine::DoVisualCursorTraveling( const ContentNode* )
+{
+ // Don't check if it's necessary, because we also need it when leaving the paragraph
+ return IsVisualCursorTravelingEnabled();
+/*
+ BOOL bDoVisualCursorTraveling = FALSE;
+
+ if ( IsVisualCursorTravelingEnabled() && pNode->Len() )
+ {
+ // Only necessary when RTL text in LTR para or LTR text in RTL para
+ bDoVisualCursorTraveling = HasDifferentRTLLevels( pNode );
+ }
+
+ return bDoVisualCursorTraveling;
+*/
+}
+
+
+void ImpEditEngine::CallNotify( EENotify& rNotify )
+{
+ if ( !nBlockNotifications )
+ {
+ GetNotifyHdl().Call( &rNotify );
+ }
+ else
+ {
+ EENotify* pNewNotify = new EENotify( rNotify );
+ aNotifyCache.Insert( pNewNotify, aNotifyCache.Count() );
+ }
+}
+
+void ImpEditEngine::EnterBlockNotifications()
+{
+ if( !nBlockNotifications )
+ {
+ // #109864# Send out START notification immediately, to allow
+ // external, non-queued events to be captured as well from
+ // client side
+ EENotify aNotify( EE_NOTIFY_BLOCKNOTIFICATION_START );
+ aNotify.pEditEngine = GetEditEnginePtr();
+ GetNotifyHdl().Call( &aNotify );
+ }
+
+ nBlockNotifications++;
+}
+
+void ImpEditEngine::LeaveBlockNotifications()
+{
+ DBG_ASSERT( nBlockNotifications, "LeaveBlockNotifications - Why?" );
+
+ nBlockNotifications--;
+ if ( !nBlockNotifications )
+ {
+ // Call blocked notify events...
+ while ( aNotifyCache.Count() )
+ {
+ EENotify* pNotify = aNotifyCache[0];
+ // Remove from list before calling, maybe we enter LeaveBlockNotifications while calling the handler...
+ aNotifyCache.Remove( 0 );
+ GetNotifyHdl().Call( pNotify );
+ delete pNotify;
+ }
+
+ EENotify aNotify( EE_NOTIFY_BLOCKNOTIFICATION_END );
+ aNotify.pEditEngine = GetEditEnginePtr();
+ GetNotifyHdl().Call( &aNotify );
+ }
+}
+
+IMPL_LINK( ImpEditEngine, DocModified, void*, EMPTYARG )
+{
+ aModifyHdl.Call( NULL /*GetEditEnginePtr()*/ ); // NULL, because also used for Outliner
+ return 0;
+}
diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx
new file mode 100644
index 0000000000..ab3bbc0fc2
--- /dev/null
+++ b/editeng/source/editeng/impedit3.cxx
@@ -0,0 +1,4680 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: impedit3.cxx,v $
+ * $Revision: 1.124.82.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <vcl/wrkwin.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/metaact.hxx>
+#include <vcl/gdimtf.hxx>
+
+#define _SVSTDARR_USHORTS
+#include <svl/svstdarr.hxx>
+
+#include <vcl/wrkwin.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/tstpitem.hxx>
+#include <editeng/lspcitem.hxx>
+#include <editeng/flditem.hxx>
+#include <impedit.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/txtrange.hxx>
+#include <editeng/cscoitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/scriptspaceitem.hxx>
+#include <editeng/charscaleitem.hxx>
+#include <editeng/numitem.hxx>
+
+#include <svtools/colorcfg.hxx>
+#include <svl/ctloptions.hxx>
+
+#include <editeng/forbiddencharacterstable.hxx>
+
+#include <unotools/localedatawrapper.hxx>
+
+#include <editeng/unolingu.hxx>
+
+#include <math.h>
+#include <vcl/svapp.hxx>
+#include <vcl/metric.hxx>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <com/sun/star/text/CharacterCompressionType.hpp>
+#include <vcl/pdfextoutdevdata.hxx>
+#include <i18npool/mslangid.hxx>
+
+#include <comphelper/processfactory.hxx>
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::linguistic2;
+
+SV_DECL_VARARR_SORT( SortedPositions, sal_uInt32, 16, 8 )
+SV_IMPL_VARARR_SORT( SortedPositions, sal_uInt32 );
+
+#define CH_HYPH '-'
+
+#define RESDIFF 10
+
+#define WRONG_SHOW_MIN 5
+#define WRONG_SHOW_SMALL 11
+#define WRONG_SHOW_MEDIUM 15
+
+struct TabInfo
+{
+ BOOL bValid;
+
+ SvxTabStop aTabStop;
+ xub_StrLen nCharPos;
+ USHORT nTabPortion;
+ long nStartPosX;
+ long nTabPos;
+
+ TabInfo() { bValid = FALSE; }
+};
+
+Point Rotate( const Point& rPoint, short nOrientation, const Point& rOrigin )
+{
+ double nRealOrientation = nOrientation*F_PI1800;
+ double nCos = cos( nRealOrientation );
+ double nSin = sin( nRealOrientation );
+
+ Point aRotatedPos;
+ Point aTranslatedPos( rPoint );
+
+ // Translation
+ aTranslatedPos -= rOrigin;
+
+ // Rotation...
+ aRotatedPos.X() = (long) ( nCos*aTranslatedPos.X() + nSin*aTranslatedPos.Y() );
+ aRotatedPos.Y() = (long) - ( nSin*aTranslatedPos.X() - nCos*aTranslatedPos.Y() );
+ aTranslatedPos = aRotatedPos;
+
+ // Translation...
+ aTranslatedPos += rOrigin;
+ return aTranslatedPos;
+}
+
+BYTE GetCharTypeForCompression( xub_Unicode cChar )
+{
+ switch ( cChar )
+ {
+ case 0x3008: case 0x300A: case 0x300C: case 0x300E:
+ case 0x3010: case 0x3014: case 0x3016: case 0x3018:
+ case 0x301A: case 0x301D:
+ {
+ return CHAR_PUNCTUATIONRIGHT;
+ }
+ case 0x3001: case 0x3002: case 0x3009: case 0x300B:
+ case 0x300D: case 0x300F: case 0x3011: case 0x3015:
+ case 0x3017: case 0x3019: case 0x301B: case 0x301E:
+ case 0x301F:
+ {
+ return CHAR_PUNCTUATIONLEFT;
+ }
+ default:
+ {
+ return ( ( 0x3040 <= cChar ) && ( 0x3100 > cChar ) ) ? CHAR_KANA : CHAR_NORMAL;
+ }
+ }
+}
+
+void lcl_DrawRedLines(
+ OutputDevice* pOutDev,
+ long nFontHeight,
+ const Point& rPnt,
+ sal_uInt16 nIndex,
+ sal_uInt16 nMaxEnd,
+ const sal_Int32* pDXArray,
+ WrongList* pWrongs,
+ short nOrientation,
+ const Point& rOrigin,
+ BOOL bVertical,
+ BOOL bIsRightToLeft )
+{
+#ifndef SVX_LIGHT
+ // Aber nur, wenn Font nicht zu klein...
+ long nHght = pOutDev->LogicToPixel( Size( 0, nFontHeight ) ).Height();
+ if( WRONG_SHOW_MIN < nHght )
+ {
+ sal_uInt16 nStyle;
+ if( WRONG_SHOW_MEDIUM < nHght )
+ nStyle = WAVE_NORMAL;
+ else if( WRONG_SHOW_SMALL < nHght )
+ nStyle = WAVE_SMALL;
+ else
+ nStyle = WAVE_FLAT;
+
+ sal_uInt16 nEnd, nStart = nIndex;
+ sal_Bool bWrong = pWrongs->NextWrong( nStart, nEnd );
+ while ( bWrong )
+ {
+ if ( nStart >= nMaxEnd )
+ break;
+
+ if ( nStart < nIndex ) // Wurde korrigiert
+ nStart = nIndex;
+ if ( nEnd > nMaxEnd )
+ nEnd = nMaxEnd;
+ Point aPnt1( rPnt );
+ if ( bVertical && ( nStyle != WAVE_FLAT ) )
+ {
+ // VCL doesn't know that the text is vertical, and is manipulating
+ // the positions a little bit in y direction...
+ long nOnePixel = pOutDev->PixelToLogic( Size( 0, 1 ) ).Height();
+ long nCorrect = ( nStyle == WAVE_NORMAL ) ? 2*nOnePixel : nOnePixel;
+ aPnt1.Y() -= nCorrect;
+ aPnt1.X() -= nCorrect;
+ }
+ if ( nStart > nIndex )
+ {
+ if ( !bVertical )
+ {
+ // since for RTL portions rPnt is on the visual right end of the portion
+ // (i.e. at the start of the first RTL char) we need to subtract the offset
+ // for RTL portions...
+ aPnt1.X() += (bIsRightToLeft ? -1 : 1) * pDXArray[ nStart - nIndex - 1 ];
+ }
+ else
+ aPnt1.Y() += pDXArray[ nStart - nIndex - 1 ];
+ }
+ Point aPnt2( rPnt );
+ DBG_ASSERT( nEnd > nIndex, "RedLine: aPnt2?" );
+ if ( !bVertical )
+ {
+ // since for RTL portions rPnt is on the visual right end of the portion
+ // (i.e. at the start of the first RTL char) we need to subtract the offset
+ // for RTL portions...
+ aPnt2.X() += (bIsRightToLeft ? -1 : 1) * pDXArray[ nEnd - nIndex - 1 ];
+ }
+ else
+ aPnt2.Y() += pDXArray[ nEnd - nIndex - 1 ];
+ if ( nOrientation )
+ {
+ aPnt1 = Rotate( aPnt1, nOrientation, rOrigin );
+ aPnt2 = Rotate( aPnt2, nOrientation, rOrigin );
+ }
+
+ pOutDev->DrawWaveLine( aPnt1, aPnt2, nStyle );
+
+ nStart = nEnd+1;
+ if ( nEnd < nMaxEnd )
+ bWrong = pWrongs->NextWrong( nStart, nEnd );
+ else
+ bWrong = sal_False;
+ }
+ }
+#endif // !SVX_LIGHT
+}
+
+Point lcl_ImplCalcRotatedPos( Point rPos, Point rOrigin, double nSin, double nCos )
+{
+ Point aRotatedPos;
+ // Translation...
+ Point aTranslatedPos( rPos);
+ aTranslatedPos -= rOrigin;
+
+ aRotatedPos.X() = (long) ( nCos*aTranslatedPos.X() + nSin*aTranslatedPos.Y() );
+ aRotatedPos.Y() = (long) - ( nSin*aTranslatedPos.X() - nCos*aTranslatedPos.Y() );
+ aTranslatedPos = aRotatedPos;
+ // Translation...
+ aTranslatedPos += rOrigin;
+
+ return aTranslatedPos;
+}
+
+sal_Bool lcl_IsLigature( xub_Unicode cCh, xub_Unicode cNextCh ) // For Kashidas from sw/source/core/text/porlay.txt
+{
+ // Lam + Alef
+ return ( 0x644 == cCh && 0x627 == cNextCh ) ||
+ // Beh + Reh
+ ( 0x628 == cCh && 0x631 == cNextCh );
+}
+
+sal_Bool lcl_ConnectToPrev( xub_Unicode cCh, xub_Unicode cPrevCh ) // For Kashidas from sw/source/core/text/porlay.txt
+{
+ // Alef, Dal, Thal, Reh, Zain, and Waw do not connect to the left
+ sal_Bool bRet = 0x627 != cPrevCh && 0x62F != cPrevCh && 0x630 != cPrevCh &&
+ 0x631 != cPrevCh && 0x632 != cPrevCh && 0x648 != cPrevCh;
+
+ // check for ligatures cPrevChar + cChar
+ if ( bRet )
+ bRet = ! lcl_IsLigature( cPrevCh, cCh );
+
+ return bRet;
+}
+
+
+// ----------------------------------------------------------------------
+// class ImpEditEngine
+// ----------------------------------------------------------------------
+void ImpEditEngine::UpdateViews( EditView* pCurView )
+{
+ if ( !GetUpdateMode() || IsFormatting() || aInvalidRec.IsEmpty() )
+ return;
+
+ DBG_ASSERT( IsFormatted(), "UpdateViews: Doc nicht formatiert!" );
+
+ for ( sal_uInt16 nView = 0; nView < aEditViews.Count(); nView++ )
+ {
+ EditView* pView = aEditViews[nView];
+ DBG_CHKOBJ( pView, EditView, 0 );
+ pView->HideCursor();
+
+ Rectangle aClipRec( aInvalidRec );
+ Rectangle aVisArea( pView->GetVisArea() );
+ aClipRec.Intersection( aVisArea );
+
+ if ( !aClipRec.IsEmpty() )
+ {
+ // in Fensterkoordinaten umwandeln....
+ aClipRec = pView->pImpEditView->GetWindowPos( aClipRec );
+
+ if ( ( pView == pCurView ) )
+ Paint( pView->pImpEditView, aClipRec, sal_True );
+ else
+ pView->GetWindow()->Invalidate( aClipRec );
+ }
+ }
+
+ if ( pCurView )
+ {
+ sal_Bool bGotoCursor = pCurView->pImpEditView->DoAutoScroll();
+ pCurView->ShowCursor( bGotoCursor );
+ }
+
+ aInvalidRec = Rectangle();
+ CallStatusHdl();
+}
+
+IMPL_LINK( ImpEditEngine, OnlineSpellHdl, Timer *, EMPTYARG )
+{
+ if ( !Application::AnyInput( INPUT_KEYBOARD ) && GetUpdateMode() && IsFormatted() )
+ DoOnlineSpelling();
+ else
+ aOnlineSpellTimer.Start();
+
+ return 0;
+}
+
+IMPL_LINK_INLINE_START( ImpEditEngine, IdleFormatHdl, Timer *, EMPTYARG )
+{
+ aIdleFormatter.ResetRestarts();
+
+ // #i97146# check if that view is still available
+ // else probably the idle format timer fired while we're already
+ // downing
+ EditView* pView = aIdleFormatter.GetView();
+ for( sal_uInt16 nView = 0; nView < aEditViews.Count(); nView++ )
+ {
+ if( aEditViews[nView] == pView )
+ {
+ FormatAndUpdate( pView );
+ break;
+ }
+ }
+ return 0;
+}
+IMPL_LINK_INLINE_END( ImpEditEngine, IdleFormatHdl, Timer *, EMPTYARG )
+
+void ImpEditEngine::CheckIdleFormatter()
+{
+ aIdleFormatter.ForceTimeout();
+ // Falls kein Idle, aber trotzdem nicht formatiert:
+ if ( !IsFormatted() )
+ FormatDoc();
+}
+
+void ImpEditEngine::FormatFullDoc()
+{
+ for ( sal_uInt16 nPortion = 0; nPortion < GetParaPortions().Count(); nPortion++ )
+ GetParaPortions()[nPortion]->MarkSelectionInvalid( 0, GetParaPortions()[nPortion]->GetNode()->Len() );
+ FormatDoc();
+}
+
+void ImpEditEngine::FormatDoc()
+{
+ if ( !GetUpdateMode() || IsFormatting() )
+ return;
+
+ EnterBlockNotifications();
+
+ bIsFormatting = sal_True;
+
+ // Dann kann ich auch den Spell-Timer starten...
+ if ( GetStatus().DoOnlineSpelling() )
+ StartOnlineSpellTimer();
+
+ long nY = 0;
+ sal_Bool bGrow = sal_False;
+
+ Font aOldFont( GetRefDevice()->GetFont() );
+
+ // Hier schon, damit nicht jedesmal in CreateLines...
+ sal_Bool bMapChanged = ImpCheckRefMapMode();
+
+ aInvalidRec = Rectangle(); // leermachen
+ for ( sal_uInt16 nPara = 0; nPara < GetParaPortions().Count(); nPara++ )
+ {
+ ParaPortion* pParaPortion = GetParaPortions().GetObject( nPara );
+ if ( pParaPortion->MustRepaint() || ( pParaPortion->IsInvalid() && pParaPortion->IsVisible() ) )
+ {
+ if ( pParaPortion->IsInvalid() )
+ {
+ sal_Bool bChangedByDerivedClass = GetEditEnginePtr()->FormattingParagraph( nPara );
+ if ( bChangedByDerivedClass )
+ {
+ pParaPortion->GetTextPortions().Reset();
+ pParaPortion->MarkSelectionInvalid( 0, pParaPortion->GetNode()->Len() );
+ }
+ }
+ // bei MustRepaint() sollte keine Formatierung noetig sein!
+ // 23.1.95: Evtl. ist sie durch eine andere Aktion aber doch
+ // ungueltig geworden!
+// if ( pParaPortion->MustRepaint() || CreateLines( nPara ) )
+ if ( ( pParaPortion->MustRepaint() && !pParaPortion->IsInvalid() )
+ || CreateLines( nPara, nY ) )
+ {
+ if ( !bGrow && GetTextRanger() )
+ {
+ // Bei einer Aenderung der Hoehe muss alles weiter unten
+ // neu formatiert werden...
+ for ( sal_uInt16 n = nPara+1; n < GetParaPortions().Count(); n++ )
+ {
+ ParaPortion* pPP = GetParaPortions().GetObject( n );
+ pPP->MarkSelectionInvalid( 0, pPP->GetNode()->Len() );
+ pPP->GetLines().Reset();
+ }
+ }
+ bGrow = sal_True;
+ if ( IsCallParaInsertedOrDeleted() )
+ GetEditEnginePtr()->ParagraphHeightChanged( nPara );
+ pParaPortion->SetMustRepaint( sal_False );
+ }
+
+ // InvalidRec nur einmal setzen...
+ if ( aInvalidRec.IsEmpty() )
+ {
+ // Bei Paperwidth 0 (AutoPageSize) bleibt es sonst Empty()...
+ long nWidth = Max( (long)1, ( !IsVertical() ? aPaperSize.Width() : aPaperSize.Height() ) );
+ Range aInvRange( GetInvalidYOffsets( pParaPortion ) );
+ aInvalidRec = Rectangle( Point( 0, nY+aInvRange.Min() ),
+ Size( nWidth, aInvRange.Len() ) );
+ }
+ else
+ {
+ aInvalidRec.Bottom() = nY + pParaPortion->GetHeight();
+ }
+ }
+ else if ( bGrow )
+ {
+ aInvalidRec.Bottom() = nY + pParaPortion->GetHeight();
+ }
+ nY += pParaPortion->GetHeight();
+ }
+
+ // Man kann auch durch UpdateMode An=>AUS=>AN in die Formatierung gelangen...
+ // Optimierung erst nach Vobis-Auslieferung aktivieren...
+// if ( !aInvalidRec.IsEmpty() )
+ {
+ sal_uInt32 nNewHeight = CalcTextHeight();
+ long nDiff = nNewHeight - nCurTextHeight;
+ if ( nDiff )
+ aStatus.GetStatusWord() |= !IsVertical() ? EE_STAT_TEXTHEIGHTCHANGED : EE_STAT_TEXTWIDTHCHANGED;
+ if ( nNewHeight < nCurTextHeight )
+ {
+ aInvalidRec.Bottom() = (long)Max( nNewHeight, nCurTextHeight );
+ if ( aInvalidRec.IsEmpty() )
+ {
+ aInvalidRec.Top() = 0;
+ // Left und Right werden nicht ausgewertet, aber wegen IsEmpty gesetzt.
+ aInvalidRec.Left() = 0;
+ aInvalidRec.Right() = !IsVertical() ? aPaperSize.Width() : aPaperSize.Height();
+ }
+ }
+
+ nCurTextHeight = nNewHeight;
+
+ if ( aStatus.AutoPageSize() )
+ CheckAutoPageSize();
+ else if ( nDiff )
+ {
+ for ( sal_uInt16 nView = 0; nView < aEditViews.Count(); nView++ )
+ {
+ EditView* pView = aEditViews[nView];
+ ImpEditView* pImpView = pView->pImpEditView;
+ if ( pImpView->DoAutoHeight() )
+ {
+ Size aSz( pImpView->GetOutputArea().GetWidth(), nCurTextHeight );
+ if ( aSz.Height() > aMaxAutoPaperSize.Height() )
+ aSz.Height() = aMaxAutoPaperSize.Height();
+ else if ( aSz.Height() < aMinAutoPaperSize.Height() )
+ aSz.Height() = aMinAutoPaperSize.Height();
+ pImpView->ResetOutputArea( Rectangle(
+ pImpView->GetOutputArea().TopLeft(), aSz ) );
+ }
+ }
+ }
+ }
+
+ if ( aStatus.DoRestoreFont() )
+ GetRefDevice()->SetFont( aOldFont );
+ bIsFormatting = sal_False;
+ bFormatted = sal_True;
+
+ if ( bMapChanged )
+ GetRefDevice()->Pop();
+
+ CallStatusHdl(); // Falls Modified...
+
+ LeaveBlockNotifications();
+}
+
+sal_Bool ImpEditEngine::ImpCheckRefMapMode()
+{
+ sal_Bool bChange = sal_False;
+
+ if ( aStatus.DoFormat100() )
+ {
+ MapMode aMapMode( GetRefDevice()->GetMapMode() );
+ if ( aMapMode.GetScaleX().GetNumerator() != aMapMode.GetScaleX().GetDenominator() )
+ bChange = sal_True;
+ else if ( aMapMode.GetScaleY().GetNumerator() != aMapMode.GetScaleY().GetDenominator() )
+ bChange = sal_True;
+
+ if ( bChange )
+ {
+ Fraction Scale1( 1, 1 );
+ aMapMode.SetScaleX( Scale1 );
+ aMapMode.SetScaleY( Scale1 );
+ GetRefDevice()->Push();
+ GetRefDevice()->SetMapMode( aMapMode );
+ }
+ }
+
+ return bChange;
+}
+
+void ImpEditEngine::CheckAutoPageSize()
+{
+ Size aPrevPaperSize( GetPaperSize() );
+ if ( GetStatus().AutoPageWidth() )
+ aPaperSize.Width() = (long) !IsVertical() ? CalcTextWidth( TRUE ) : GetTextHeight();
+ if ( GetStatus().AutoPageHeight() )
+ aPaperSize.Height() = (long) !IsVertical() ? GetTextHeight() : CalcTextWidth( TRUE );
+
+ SetValidPaperSize( aPaperSize ); //Min, Max beruecksichtigen
+
+ if ( aPaperSize != aPrevPaperSize )
+ {
+ if ( ( !IsVertical() && ( aPaperSize.Width() != aPrevPaperSize.Width() ) )
+ || ( IsVertical() && ( aPaperSize.Height() != aPrevPaperSize.Height() ) ) )
+ {
+ // Falls davor zentriert/rechts oder Tabs...
+ aStatus.GetStatusWord() |= !IsVertical() ? EE_STAT_TEXTWIDTHCHANGED : EE_STAT_TEXTHEIGHTCHANGED;
+ for ( sal_uInt16 nPara = 0; nPara < GetParaPortions().Count(); nPara++ )
+ {
+ // Es brauchen nur Absaetze neu formatiert werden,
+ // die nicht linksbuendig sind.
+ // Die Hoehe kann sich hier nicht mehr aendern.
+ ParaPortion* pParaPortion = GetParaPortions().GetObject( nPara );
+ ContentNode* pNode = pParaPortion->GetNode();
+ SvxAdjust eJustification = GetJustification( nPara );
+ if ( eJustification != SVX_ADJUST_LEFT )
+ {
+ pParaPortion->MarkSelectionInvalid( 0, pNode->Len() );
+ CreateLines( nPara, 0 ); // 0: Bei AutoPageSize kein TextRange!
+ }
+ }
+ }
+
+ Size aInvSize = aPaperSize;
+ if ( aPaperSize.Width() < aPrevPaperSize.Width() )
+ aInvSize.Width() = aPrevPaperSize.Width();
+ if ( aPaperSize.Height() < aPrevPaperSize.Height() )
+ aInvSize.Height() = aPrevPaperSize.Height();
+
+ Size aSz( aInvSize );
+ if ( IsVertical() )
+ {
+ aSz.Width() = aInvSize.Height();
+ aSz.Height() = aInvSize.Width();
+ }
+ aInvalidRec = Rectangle( Point(), aSz );
+
+
+ for ( sal_uInt16 nView = 0; nView < aEditViews.Count(); nView++ )
+ {
+ EditView* pView = aEditViews[nView];
+ pView->pImpEditView->RecalcOutputArea();
+ }
+ }
+}
+
+static sal_Int32 ImplCalculateFontIndependentLineSpacing( const sal_Int32 nFontHeight )
+{
+ return ( nFontHeight * 12 ) / 10; // + 20%
+}
+
+sal_Bool ImpEditEngine::CreateLines( USHORT nPara, sal_uInt32 nStartPosY )
+{
+ ParaPortion* pParaPortion = GetParaPortions().GetObject( nPara );
+
+ // sal_Bool: Aenderung der Hoehe des Absatzes Ja/Nein - sal_True/sal_False
+ DBG_ASSERT( pParaPortion->GetNode(), "Portion ohne Node in CreateLines" );
+ DBG_ASSERT( pParaPortion->IsVisible(), "Unsichtbare Absaetze nicht formatieren!" );
+ DBG_ASSERT( pParaPortion->IsInvalid(), "CreateLines: Portion nicht invalid!" );
+
+ BOOL bProcessingEmptyLine = ( pParaPortion->GetNode()->Len() == 0 );
+ BOOL bEmptyNodeWithPolygon = ( pParaPortion->GetNode()->Len() == 0 ) && GetTextRanger();
+
+ // ---------------------------------------------------------------
+ // Schnelle Sonderbehandlung fuer leere Absaetze...
+ // ---------------------------------------------------------------
+ if ( ( pParaPortion->GetNode()->Len() == 0 ) && !GetTextRanger() )
+ {
+ // schnelle Sonderbehandlung...
+ if ( pParaPortion->GetTextPortions().Count() )
+ pParaPortion->GetTextPortions().Reset();
+ if ( pParaPortion->GetLines().Count() )
+ pParaPortion->GetLines().Reset();
+ CreateAndInsertEmptyLine( pParaPortion, nStartPosY );
+ return FinishCreateLines( pParaPortion );
+ }
+
+ // ---------------------------------------------------------------
+ // Initialisierung......
+ // ---------------------------------------------------------------
+
+ // Immer fuer 100% formatieren:
+ sal_Bool bMapChanged = ImpCheckRefMapMode();
+
+ if ( pParaPortion->GetLines().Count() == 0 )
+ {
+ EditLine* pL = new EditLine;
+ pParaPortion->GetLines().Insert( pL, 0 );
+ }
+
+ // ---------------------------------------------------------------
+ // Absatzattribute holen......
+ // ---------------------------------------------------------------
+ ContentNode* const pNode = pParaPortion->GetNode();
+
+ BOOL bRightToLeftPara = IsRightToLeft( nPara );
+
+ SvxAdjust eJustification = GetJustification( nPara );
+ sal_Bool bHyphenatePara = ((const SfxBoolItem&)pNode->GetContentAttribs().GetItem( EE_PARA_HYPHENATE )).GetValue();
+ sal_Int32 nSpaceBefore = 0;
+ sal_Int32 nMinLabelWidth = 0;
+ sal_Int32 nSpaceBeforeAndMinLabelWidth = GetSpaceBeforeAndMinLabelWidth( pNode, &nSpaceBefore, &nMinLabelWidth );
+ const SvxLRSpaceItem& rLRItem = GetLRSpaceItem( pNode );
+ const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&) pNode->GetContentAttribs().GetItem( EE_PARA_SBL );
+ const BOOL bScriptSpace = ((const SvxScriptSpaceItem&) pNode->GetContentAttribs().GetItem( EE_PARA_ASIANCJKSPACING )).GetValue();
+
+// const sal_uInt16 nInvalidEnd = ( pParaPortion->GetInvalidDiff() > 0 )
+// ? pParaPortion->GetInvalidPosStart() + pParaPortion->GetInvalidDiff()
+// : pNode->Len();
+ const short nInvalidDiff = pParaPortion->GetInvalidDiff();
+ const sal_uInt16 nInvalidStart = pParaPortion->GetInvalidPosStart();
+ const sal_uInt16 nInvalidEnd = nInvalidStart + Abs( nInvalidDiff );
+
+ sal_Bool bQuickFormat = sal_False;
+ if ( !bEmptyNodeWithPolygon && !HasScriptType( nPara, i18n::ScriptType::COMPLEX ) )
+ {
+ if ( ( pParaPortion->IsSimpleInvalid() ) && ( nInvalidDiff > 0 ) &&
+ ( pNode->Search( CH_FEATURE, nInvalidStart ) > nInvalidEnd ) )
+ {
+ bQuickFormat = sal_True;
+ }
+ else if ( ( pParaPortion->IsSimpleInvalid() ) && ( nInvalidDiff < 0 ) )
+ {
+ // pruefen, ob loeschen ueber Portiongrenzen erfolgte...
+ sal_uInt16 nStart = nInvalidStart; // DOPPELT !!!!!!!!!!!!!!!
+ sal_uInt16 nEnd = nStart - nInvalidDiff; // neg.
+ bQuickFormat = sal_True;
+ sal_uInt16 nPos = 0;
+ sal_uInt16 nPortions = pParaPortion->GetTextPortions().Count();
+ for ( sal_uInt16 nTP = 0; nTP < nPortions; nTP++ )
+ {
+ // Es darf kein Start/Ende im geloeschten Bereich liegen.
+ TextPortion* const pTP = pParaPortion->GetTextPortions()[ nTP ];
+ nPos = nPos + pTP->GetLen();
+ if ( ( nPos > nStart ) && ( nPos < nEnd ) )
+ {
+ bQuickFormat = sal_False;
+ break;
+ }
+ }
+ }
+ }
+
+ // SW disables TEXT_LAYOUT_COMPLEX_DISABLED, so maybe I have to enable it...
+
+ // #114278# Saving both layout mode and language (since I'm
+ // potentially changing both)
+
+ GetRefDevice()->Push( PUSH_TEXTLAYOUTMODE|PUSH_TEXTLANGUAGE );
+
+ ImplInitLayoutMode( GetRefDevice(), nPara, 0xFFFF );
+
+ sal_uInt16 nRealInvalidStart = nInvalidStart;
+
+ if ( bEmptyNodeWithPolygon )
+ {
+ TextPortion* pDummyPortion = new TextPortion( 0 );
+ pParaPortion->GetTextPortions().Reset();
+ pParaPortion->GetTextPortions().Insert( pDummyPortion, 0 );
+ }
+ else if ( bQuickFormat )
+ {
+ // schnellere Methode:
+ RecalcTextPortion( pParaPortion, nInvalidStart, nInvalidDiff );
+ }
+ else // nRealInvalidStart kann vor InvalidStart liegen, weil Portions geloescht....
+ {
+ CreateTextPortions( pParaPortion, nRealInvalidStart );
+ }
+
+
+ // ---------------------------------------------------------------
+ // Zeile mit InvalidPos suchen, eine Zeile davor beginnen...
+ // Zeilen flaggen => nicht removen !
+ // ---------------------------------------------------------------
+
+ sal_uInt16 nLine = pParaPortion->GetLines().Count()-1;
+ for ( sal_uInt16 nL = 0; nL <= nLine; nL++ )
+ {
+ EditLine* pLine = pParaPortion->GetLines().GetObject( nL );
+ if ( pLine->GetEnd() > nRealInvalidStart ) // nicht nInvalidStart!
+ {
+ nLine = nL;
+ break;
+ }
+ pLine->SetValid();
+ }
+ // Eine Zeile davor beginnen...
+ // Wenn ganz hinten getippt wird, kann sich die Zeile davor nicht aendern.
+ if ( nLine && ( !pParaPortion->IsSimpleInvalid() || ( nInvalidEnd < pNode->Len() ) || ( nInvalidDiff <= 0 ) ) )
+ nLine--;
+
+ EditLine* pLine = pParaPortion->GetLines().GetObject( nLine );
+
+ static Rectangle aZeroArea = Rectangle( Point(), Point() );
+ Rectangle aBulletArea( aZeroArea );
+ if ( !nLine )
+ {
+ aBulletArea = GetEditEnginePtr()->GetBulletArea( GetParaPortions().GetPos( pParaPortion ) );
+ if ( aBulletArea.Right() > 0 )
+ pParaPortion->SetBulletX( (sal_uInt16) GetXValue( aBulletArea.Right() ) );
+ else
+ pParaPortion->SetBulletX( 0 ); // Falls Bullet falsch eingestellt.
+ }
+
+ // ---------------------------------------------------------------
+ // Ab hier alle Zeilen durchformatieren...
+ // ---------------------------------------------------------------
+ sal_uInt16 nDelFromLine = 0xFFFF;
+ sal_Bool bLineBreak = sal_False;
+
+ sal_uInt16 nIndex = pLine->GetStart();
+ EditLine aSaveLine( *pLine );
+ SvxFont aTmpFont( pNode->GetCharAttribs().GetDefFont() );
+
+ sal_Bool bCalcCharPositions = sal_True;
+ sal_Int32* pBuf = new sal_Int32[ pNode->Len() ];
+
+ sal_Bool bSameLineAgain = sal_False; // Fuer TextRanger, wenn sich die Hoehe aendert.
+ TabInfo aCurrentTab;
+
+ BOOL bForceOneRun = bEmptyNodeWithPolygon;
+ BOOL bCompressedChars = FALSE;
+
+ while ( ( nIndex < pNode->Len() ) || bForceOneRun )
+ {
+ bForceOneRun = FALSE;
+
+ sal_Bool bEOL = sal_False;
+ sal_Bool bEOC = sal_False;
+ sal_uInt16 nPortionStart = 0;
+ sal_uInt16 nPortionEnd = 0;
+
+ long nStartX = GetXValue( rLRItem.GetTxtLeft() + nSpaceBeforeAndMinLabelWidth );
+ if ( nIndex == 0 )
+ {
+ long nFI = GetXValue( rLRItem.GetTxtFirstLineOfst() );
+ nStartX += nFI;
+
+ if ( !nLine && ( pParaPortion->GetBulletX() > nStartX ) )
+ {
+// TL_NFLR nStartX += nFI; // Vielleicht reicht der LI?
+// TL_NFLR if ( pParaPortion->GetBulletX() > nStartX )
+ nStartX = pParaPortion->GetBulletX();
+ }
+ }
+
+ long nMaxLineWidth;
+ if ( !IsVertical() )
+ nMaxLineWidth = aStatus.AutoPageWidth() ? aMaxAutoPaperSize.Width() : aPaperSize.Width();
+ else
+ nMaxLineWidth = aStatus.AutoPageHeight() ? aMaxAutoPaperSize.Height() : aPaperSize.Height();
+
+ nMaxLineWidth -= GetXValue( rLRItem.GetRight() );
+ nMaxLineWidth -= nStartX;
+
+ // Wenn PaperSize == long_max, kann ich keinen neg. Erstzeileneinzug
+ // abziehen (Overflow)
+ if ( ( nMaxLineWidth < 0 ) && ( nStartX < 0 ) )
+ nMaxLineWidth = ( !IsVertical() ? aPaperSize.Width() : aPaperSize.Height() ) - GetXValue( rLRItem.GetRight() );
+
+ // Wenn jetzt noch kleiner 0, kann es nur der rechte Rand sein.
+ if ( nMaxLineWidth <= 0 )
+ nMaxLineWidth = 1;
+
+ // Problem: Da eine Zeile _vor_ der ungueltigen Position mit der
+ // Formatierung begonnen wird, werden hier leider auch die Positionen
+ // neu bestimmt...
+ // Loesungsansatz:
+ // Die Zeile davor kann nur groesser werden, nicht kleiner
+ // => ...
+ if ( bCalcCharPositions )
+ pLine->GetCharPosArray().Remove( 0, pLine->GetCharPosArray().Count() );
+
+ sal_uInt16 nTmpPos = nIndex;
+ sal_uInt16 nTmpPortion = pLine->GetStartPortion();
+ long nTmpWidth = 0;
+ long nXWidth = nMaxLineWidth;
+ if ( nXWidth <= nTmpWidth ) // while muss 1x durchlaufen werden
+ nXWidth = nTmpWidth+1;
+
+ SvLongsPtr pTextRanges = 0;
+ long nTextExtraYOffset = 0;
+ long nTextXOffset = 0;
+ long nTextLineHeight = 0;
+ if ( GetTextRanger() )
+ {
+ GetTextRanger()->SetVertical( IsVertical() );
+
+ long nTextY = nStartPosY + GetEditCursor( pParaPortion, pLine->GetStart() ).Top();
+ if ( !bSameLineAgain )
+ {
+ SeekCursor( pNode, nTmpPos+1, aTmpFont );
+ aTmpFont.SetPhysFont( GetRefDevice() );
+ ImplInitDigitMode( GetRefDevice(), 0, 0, 0, aTmpFont.GetLanguage() );
+
+ if ( IsFixedCellHeight() )
+ nTextLineHeight = ImplCalculateFontIndependentLineSpacing( aTmpFont.GetHeight() );
+ else
+ nTextLineHeight = aTmpFont.GetPhysTxtSize( GetRefDevice(), String() ).Height();
+ // Metriken koennen groesser sein
+ FormatterFontMetric aTempFormatterMetrics;
+ RecalcFormatterFontMetrics( aTempFormatterMetrics, aTmpFont );
+ sal_uInt16 nLineHeight = aTempFormatterMetrics.GetHeight();
+ if ( nLineHeight > nTextLineHeight )
+ nTextLineHeight = nLineHeight;
+ }
+ else
+ nTextLineHeight = pLine->GetHeight();
+
+ nXWidth = 0;
+ while ( !nXWidth )
+ {
+ long nYOff = nTextY + nTextExtraYOffset;
+ long nYDiff = nTextLineHeight;
+ if ( IsVertical() )
+ {
+ long nMaxPolygonX = GetTextRanger()->GetBoundRect().Right();
+ nYOff = nMaxPolygonX-nYOff;
+ nYDiff = -nTextLineHeight;
+ }
+ pTextRanges = GetTextRanger()->GetTextRanges( Range( nYOff, nYOff + nYDiff ) );
+ DBG_ASSERT( pTextRanges, "GetTextRanges?!" );
+ long nMaxRangeWidth = 0;
+ // Den breitesten Bereich verwenden...
+ // Der breiteste Bereich koennte etwas verwirren, also
+ // generell den ersten. Am besten mal richtig mit Luecken.
+// for ( sal_uInt16 n = 0; n < pTextRanges->Count(); )
+ if ( pTextRanges->Count() )
+ {
+ sal_uInt16 n = 0;
+ long nA = pTextRanges->GetObject( n++ );
+ long nB = pTextRanges->GetObject( n++ );
+ DBG_ASSERT( nA <= nB, "TextRange verdreht?" );
+ long nW = nB - nA;
+ if ( nW > nMaxRangeWidth )
+ {
+ nMaxRangeWidth = nW;
+ nTextXOffset = nA;
+ }
+ }
+ nXWidth = nMaxRangeWidth;
+ if ( nXWidth )
+ nMaxLineWidth = nXWidth - nStartX - GetXValue( rLRItem.GetRight() );
+ else
+ {
+ // Weiter unten im Polygon versuchen.
+ // Unterhalb des Polygons die Paperbreite verwenden.
+ nTextExtraYOffset += Max( (long)(nTextLineHeight / 10), (long)1 );
+ if ( ( nTextY + nTextExtraYOffset ) > GetTextRanger()->GetBoundRect().Bottom() )
+ {
+ nXWidth = !IsVertical() ? GetPaperSize().Width() : GetPaperSize().Height();
+ if ( !nXWidth ) // AutoPaperSize
+ nXWidth = 0x7FFFFFFF;
+ }
+ }
+ }
+ }
+
+ // Portion suchen, die nicht mehr in Zeile passt....
+ TextPortion* pPortion = 0;
+ sal_Bool bBrokenLine = sal_False;
+ bLineBreak = sal_False;
+ EditCharAttrib* pNextFeature = pNode->GetCharAttribs().FindFeature( pLine->GetStart() );
+ while ( ( nTmpWidth < nXWidth ) && !bEOL && ( nTmpPortion < pParaPortion->GetTextPortions().Count() ) )
+ {
+ nPortionStart = nTmpPos;
+ pPortion = pParaPortion->GetTextPortions().GetObject( nTmpPortion );
+ if ( pPortion->GetKind() == PORTIONKIND_HYPHENATOR )
+ {
+ // Portion wegschmeissen, ggf. die davor korrigieren, wenn
+ // die Hyph-Portion ein Zeichen geschluckt hat...
+ pParaPortion->GetTextPortions().Remove( nTmpPortion );
+ if ( nTmpPortion && pPortion->GetLen() )
+ {
+ nTmpPortion--;
+ TextPortion* pPrev = pParaPortion->GetTextPortions().GetObject( nTmpPortion );
+ DBG_ASSERT( pPrev->GetKind() == PORTIONKIND_TEXT, "Portion?!" );
+ nTmpWidth -= pPrev->GetSize().Width();
+ nTmpPos = nTmpPos - pPrev->GetLen();
+ pPrev->SetLen( pPrev->GetLen() + pPortion->GetLen() );
+ pPrev->GetSize().Width() = (-1);
+ }
+ delete pPortion;
+ DBG_ASSERT( nTmpPortion < pParaPortion->GetTextPortions().Count(), "Keine Portion mehr da!" );
+ pPortion = pParaPortion->GetTextPortions().GetObject( nTmpPortion );
+ }
+ DBG_ASSERT( pPortion->GetKind() != PORTIONKIND_HYPHENATOR, "CreateLines: Hyphenator-Portion!" );
+ DBG_ASSERT( pPortion->GetLen() || bProcessingEmptyLine, "Leere Portion in CreateLines ?!" );
+ if ( pNextFeature && ( pNextFeature->GetStart() == nTmpPos ) )
+ {
+ sal_uInt16 nWhich = pNextFeature->GetItem()->Which();
+ switch ( nWhich )
+ {
+ case EE_FEATURE_TAB:
+ {
+ long nOldTmpWidth = nTmpWidth;
+
+ // Tab-Pos suchen...
+ long nCurPos = nTmpWidth+nStartX;
+// nCurPos -= rLRItem.GetTxtLeft(); // Tabs relativ zu LI
+ // Skalierung rausrechnen
+ if ( aStatus.DoStretch() && ( nStretchX != 100 ) )
+ nCurPos = nCurPos*100/nStretchX;
+
+ short nAllSpaceBeforeText = static_cast< short >(rLRItem.GetTxtLeft()/* + rLRItem.GetTxtLeft()*/ + nSpaceBeforeAndMinLabelWidth);
+ aCurrentTab.aTabStop = pNode->GetContentAttribs().FindTabStop( nCurPos - nAllSpaceBeforeText /*rLRItem.GetTxtLeft()*/, aEditDoc.GetDefTab() );
+ aCurrentTab.nTabPos = GetXValue( (long) ( aCurrentTab.aTabStop.GetTabPos() + nAllSpaceBeforeText /*rLRItem.GetTxtLeft()*/ ) );
+ aCurrentTab.bValid = FALSE;
+
+ // Switch direction in R2L para...
+ if ( bRightToLeftPara )
+ {
+ if ( aCurrentTab.aTabStop.GetAdjustment() == SVX_TAB_ADJUST_RIGHT )
+ aCurrentTab.aTabStop.GetAdjustment() = SVX_TAB_ADJUST_LEFT;
+ else if ( aCurrentTab.aTabStop.GetAdjustment() == SVX_TAB_ADJUST_LEFT )
+ aCurrentTab.aTabStop.GetAdjustment() = SVX_TAB_ADJUST_RIGHT;
+ }
+
+ if ( ( aCurrentTab.aTabStop.GetAdjustment() == SVX_TAB_ADJUST_RIGHT ) ||
+ ( aCurrentTab.aTabStop.GetAdjustment() == SVX_TAB_ADJUST_CENTER ) ||
+ ( aCurrentTab.aTabStop.GetAdjustment() == SVX_TAB_ADJUST_DECIMAL ) )
+ {
+ // Bei LEFT/DEFAULT wird dieses Tab nicht mehr betrachtet.
+ aCurrentTab.bValid = TRUE;
+ aCurrentTab.nStartPosX = nTmpWidth;
+ aCurrentTab.nCharPos = nTmpPos;
+ aCurrentTab.nTabPortion = nTmpPortion;
+ }
+
+ pPortion->GetKind() = PORTIONKIND_TAB;
+ pPortion->SetExtraValue( aCurrentTab.aTabStop.GetFill() );
+ pPortion->GetSize().Width() = aCurrentTab.nTabPos - (nTmpWidth+nStartX);
+
+ // #90520# Height needed...
+ SeekCursor( pNode, nTmpPos+1, aTmpFont );
+ pPortion->GetSize().Height() = aTmpFont.QuickGetTextSize( GetRefDevice(), String(), 0, 0, NULL ).Height();
+
+ DBG_ASSERT( pPortion->GetSize().Width() >= 0, "Tab falsch berechnet!" );
+
+ nTmpWidth = aCurrentTab.nTabPos-nStartX;
+
+ // Wenn dies das erste Token in der Zeile ist,
+ // und nTmpWidth > aPaperSize.Width, habe ich eine
+ // Endlos-Schleife!
+ if ( ( nTmpWidth >= nXWidth ) && ( nTmpPortion == pLine->GetStartPortion() ) )
+ {
+ // Aber was jetzt ?
+ // Tab passend machen
+ pPortion->GetSize().Width() = nXWidth-nOldTmpWidth;
+ nTmpWidth = nXWidth-1;
+ bEOL = sal_True;
+ bBrokenLine = sal_True;
+ }
+ pLine->GetCharPosArray().Insert( pPortion->GetSize().Width(), nTmpPos-pLine->GetStart() );
+ bCompressedChars = FALSE;
+ }
+ break;
+ case EE_FEATURE_LINEBR:
+ {
+ DBG_ASSERT( pPortion, "?!" );
+ pPortion->GetSize().Width() = 0;
+ bEOL = sal_True;
+ bLineBreak = sal_True;
+ pPortion->GetKind() = PORTIONKIND_LINEBREAK;
+ bCompressedChars = FALSE;
+ pLine->GetCharPosArray().Insert( pPortion->GetSize().Width(), nTmpPos-pLine->GetStart() );
+ }
+ break;
+ case EE_FEATURE_FIELD:
+ {
+// long nCurWidth = nTmpWidth;
+ SeekCursor( pNode, nTmpPos+1, aTmpFont );
+ sal_Unicode cChar = 0; // later: NBS?
+ aTmpFont.SetPhysFont( GetRefDevice() );
+ ImplInitDigitMode( GetRefDevice(), 0, 0, 0, aTmpFont.GetLanguage() );
+
+ String aFieldValue = cChar ? String(cChar) : ((EditCharAttribField*)pNextFeature)->GetFieldValue();
+ if ( bCalcCharPositions || !pPortion->HasValidSize() )
+ {
+ pPortion->GetSize() = aTmpFont.QuickGetTextSize( GetRefDevice(), aFieldValue, 0, aFieldValue.Len(), 0 );
+ // Damit kein Scrollen bei ueberlangen Feldern
+ if ( pPortion->GetSize().Width() > nXWidth )
+ pPortion->GetSize().Width() = nXWidth;
+ }
+ nTmpWidth += pPortion->GetSize().Width();
+ pLine->GetCharPosArray().Insert( pPortion->GetSize().Width(), nTmpPos-pLine->GetStart() );
+ pPortion->GetKind() = cChar ? PORTIONKIND_TEXT : PORTIONKIND_FIELD;
+ // Wenn dies das erste Token in der Zeile ist,
+ // und nTmpWidth > aPaperSize.Width, habe ich eine
+ // Endlos-Schleife!
+ if ( ( nTmpWidth >= nXWidth ) && ( nTmpPortion == pLine->GetStartPortion() ) )
+ {
+ nTmpWidth = nXWidth-1;
+ bEOL = sal_True;
+ bBrokenLine = sal_True;
+ }
+ // Compression in Fields????
+ // I think this could be a little bit difficult and is not very usefull
+ bCompressedChars = FALSE;
+ }
+ break;
+ default: DBG_ERROR( "Was fuer ein Feature ?" );
+ }
+ pNextFeature = pNode->GetCharAttribs().FindFeature( pNextFeature->GetStart() + 1 );
+ }
+ else
+ {
+ DBG_ASSERT( pPortion->GetLen() || bProcessingEmptyLine, "Empty Portion - Extra Space?!" );
+ SeekCursor( pNode, nTmpPos+1, aTmpFont );
+ aTmpFont.SetPhysFont( GetRefDevice() );
+ ImplInitDigitMode( GetRefDevice(), 0, 0, 0, aTmpFont.GetLanguage() );
+
+ if ( bCalcCharPositions || !pPortion->HasValidSize() )
+ {
+ pPortion->GetSize() = aTmpFont.QuickGetTextSize( GetRefDevice(), *pParaPortion->GetNode(), nTmpPos, pPortion->GetLen(), pBuf );
+
+ // #i9050# Do Kerning also behind portions...
+ if ( ( aTmpFont.GetFixKerning() > 0 ) && ( ( nTmpPos + pPortion->GetLen() ) < pNode->Len() ) )
+ pPortion->GetSize().Width() += aTmpFont.GetFixKerning();
+ if ( IsFixedCellHeight() )
+ pPortion->GetSize().Height() = ImplCalculateFontIndependentLineSpacing( aTmpFont.GetHeight() );
+ }
+ if ( bCalcCharPositions )
+ {
+ sal_uInt16 nLen = pPortion->GetLen();
+ // Es wird am Anfang generell das Array geplaettet
+ // => Immer einfach schnelles insert.
+ sal_uInt16 nPos = nTmpPos - pLine->GetStart();
+ pLine->GetCharPosArray().Insert( pBuf, nLen, nPos );
+ }
+
+ // And now check for Compression:
+ if ( pPortion->GetLen() && GetAsianCompressionMode() )
+ bCompressedChars |= ImplCalcAsianCompression( pNode, pPortion, nTmpPos, (sal_Int32*)pLine->GetCharPosArray().GetData() + (nTmpPos-pLine->GetStart()), 10000, FALSE );
+
+ nTmpWidth += pPortion->GetSize().Width();
+
+ pPortion->SetRightToLeft( GetRightToLeft( nPara, nTmpPos+1 ) );
+
+ USHORT _nPortionEnd = nTmpPos + pPortion->GetLen();
+ if( bScriptSpace && ( _nPortionEnd < pNode->Len() ) && ( nTmpWidth < nXWidth ) && IsScriptChange( EditPaM( pNode, _nPortionEnd ) ) )
+ {
+ BOOL bAllow = FALSE;
+ USHORT nScriptTypeLeft = GetScriptType( EditPaM( pNode, _nPortionEnd ) );
+ USHORT nScriptTypeRight = GetScriptType( EditPaM( pNode, _nPortionEnd+1 ) );
+ if ( ( nScriptTypeLeft == i18n::ScriptType::ASIAN ) || ( nScriptTypeRight == i18n::ScriptType::ASIAN ) )
+ bAllow = TRUE;
+
+ // No spacing within L2R/R2L nesting
+ if ( bAllow )
+ {
+ long nExtraSpace = pPortion->GetSize().Height()/5;
+ nExtraSpace = GetXValue( nExtraSpace );
+ pPortion->GetSize().Width() += nExtraSpace;
+ nTmpWidth += nExtraSpace;
+ }
+ }
+ }
+
+ if ( aCurrentTab.bValid && ( nTmpPortion != aCurrentTab.nTabPortion ) )
+ {
+ long nWidthAfterTab = 0;
+ for ( USHORT n = aCurrentTab.nTabPortion+1; n <= nTmpPortion; n++ )
+ {
+ TextPortion* pTP = pParaPortion->GetTextPortions().GetObject( n );
+ nWidthAfterTab += pTP->GetSize().Width();
+ }
+ long nW = nWidthAfterTab; // Length before tab position
+ if ( aCurrentTab.aTabStop.GetAdjustment() == SVX_TAB_ADJUST_RIGHT )
+ {
+// nW = nWidthAfterTab;
+ }
+ else if ( aCurrentTab.aTabStop.GetAdjustment() == SVX_TAB_ADJUST_CENTER )
+ {
+ nW = nWidthAfterTab/2;
+ }
+ else if ( aCurrentTab.aTabStop.GetAdjustment() == SVX_TAB_ADJUST_DECIMAL )
+ {
+// nW = nWidthAfterTab;
+ String aText = GetSelected( EditSelection( EditPaM( pParaPortion->GetNode(), nTmpPos ),
+ EditPaM( pParaPortion->GetNode(), nTmpPos + pPortion->GetLen() ) ) );
+ USHORT nDecPos = aText.Search( aCurrentTab.aTabStop.GetDecimal() );
+ if ( nDecPos != STRING_NOTFOUND )
+ {
+ nW -= pParaPortion->GetTextPortions().GetObject( nTmpPortion )->GetSize().Width();
+ nW += aTmpFont.QuickGetTextSize( GetRefDevice(), *pParaPortion->GetNode(), nTmpPos, nDecPos, NULL ).Width();
+ aCurrentTab.bValid = FALSE;
+ }
+ }
+ else
+ {
+ DBG_ERROR( "CreateLines: Tab not handled!" );
+ }
+ long nMaxW = aCurrentTab.nTabPos - aCurrentTab.nStartPosX - nStartX;
+ if ( nW >= nMaxW )
+ {
+ nW = nMaxW;
+ aCurrentTab.bValid = FALSE;
+ }
+ TextPortion* pTabPortion = pParaPortion->GetTextPortions().GetObject( aCurrentTab.nTabPortion );
+ pTabPortion->GetSize().Width() = aCurrentTab.nTabPos - aCurrentTab.nStartPosX - nW - nStartX;
+ nTmpWidth = aCurrentTab.nStartPosX + pTabPortion->GetSize().Width() + nWidthAfterTab;
+ }
+
+ nTmpPos = nTmpPos + pPortion->GetLen();
+ nPortionEnd = nTmpPos;
+ nTmpPortion++;
+ if ( aStatus.OneCharPerLine() )
+ bEOL = sal_True;
+ }
+
+ DBG_ASSERT( pPortion, "no portion!?" );
+
+ aCurrentTab.bValid = FALSE;
+
+ // das war evtl. eine Portion zu weit:
+ sal_Bool bFixedEnd = sal_False;
+ if ( aStatus.OneCharPerLine() )
+ {
+ // Zustand vor Portion: ( bis auf nTmpWidth )
+ nPortionEnd = nTmpPos;
+ nTmpPos -= pPortion ? pPortion->GetLen() : 0;
+ nPortionStart = nTmpPos;
+ nTmpPortion--;
+
+ bEOL = sal_True;
+ bEOC = sal_False;
+
+ // Und jetzt genau ein Zeichen:
+ nTmpPos++;
+ nTmpPortion++;
+ nPortionEnd = nTmpPortion;
+ // Eine Nicht-Feature-Portion muss gebrochen werden
+ if ( pPortion->GetLen() > 1 )
+ {
+ DBG_ASSERT( pPortion && (pPortion->GetKind() == PORTIONKIND_TEXT), "Len>1, aber keine TextPortion?" );
+ nTmpWidth -= pPortion ? pPortion->GetSize().Width() : 0;
+ sal_uInt16 nP = SplitTextPortion( pParaPortion, nTmpPos, pLine );
+ TextPortion* p = pParaPortion->GetTextPortions().GetObject( nP );
+ DBG_ASSERT( p, "Portion ?!" );
+ nTmpWidth += p->GetSize().Width();
+ }
+ }
+ else if ( nTmpWidth >= nXWidth )
+ {
+ nPortionEnd = nTmpPos;
+ nTmpPos -= pPortion ? pPortion->GetLen() : 0;
+ nPortionStart = nTmpPos;
+ nTmpPortion--;
+ bEOL = sal_False;
+ bEOC = sal_False;
+ if( pPortion ) switch ( pPortion->GetKind() )
+ {
+ case PORTIONKIND_TEXT:
+ {
+ nTmpWidth -= pPortion->GetSize().Width();
+ }
+ break;
+ case PORTIONKIND_FIELD:
+ case PORTIONKIND_TAB:
+ {
+ nTmpWidth -= pPortion->GetSize().Width();
+ bEOL = sal_True;
+ bFixedEnd = sal_True;
+ }
+ break;
+ default:
+ {
+ // Ein Feature wird nicht umgebrochen:
+ DBG_ASSERT( ( pPortion->GetKind() == PORTIONKIND_LINEBREAK ), "Was fuer ein Feature ?" );
+ bEOL = sal_True;
+ bFixedEnd = sal_True;
+ }
+ }
+ }
+ else
+ {
+ bEOL = sal_True;
+ bEOC = sal_True;
+ pLine->SetEnd( nPortionEnd );
+ DBG_ASSERT( pParaPortion->GetTextPortions().Count(), "Keine TextPortions?" );
+ pLine->SetEndPortion( (sal_uInt16)pParaPortion->GetTextPortions().Count() - 1 );
+ }
+
+ if ( aStatus.OneCharPerLine() )
+ {
+ pLine->SetEnd( nPortionEnd );
+ pLine->SetEndPortion( nTmpPortion-1 );
+ }
+ else if ( bFixedEnd )
+ {
+ pLine->SetEnd( nPortionStart );
+ pLine->SetEndPortion( nTmpPortion-1 );
+ }
+ else if ( bLineBreak || bBrokenLine )
+ {
+ pLine->SetEnd( nPortionStart+1 );
+ pLine->SetEndPortion( nTmpPortion-1 );
+ bEOC = sal_False; // wurde oben gesetzt, vielleich mal die if's umstellen?
+ }
+ else if ( !bEOL )
+ {
+ DBG_ASSERT( pPortion && ((nPortionEnd-nPortionStart) == pPortion->GetLen()), "Doch eine andere Portion?!" );
+ long nRemainingWidth = nMaxLineWidth - nTmpWidth;
+ sal_Bool bCanHyphenate = ( aTmpFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL );
+ if ( bCompressedChars && pPortion && ( pPortion->GetLen() > 1 ) && pPortion->GetExtraInfos() && pPortion->GetExtraInfos()->bCompressed )
+ {
+ // I need the manipulated DXArray for determining the break postion...
+ ImplCalcAsianCompression( pNode, pPortion, nPortionStart, const_cast<sal_Int32*>(( pLine->GetCharPosArray().GetData() + (nPortionStart-pLine->GetStart()) )), 10000, TRUE );
+ }
+ if( pPortion )
+ ImpBreakLine( pParaPortion, pLine, pPortion, nPortionStart,
+ nRemainingWidth, bCanHyphenate && bHyphenatePara );
+ }
+
+ // ------------------------------------------------------------------
+ // Zeile fertig => justieren
+ // ------------------------------------------------------------------
+
+ // CalcTextSize sollte besser durch ein kontinuierliches
+ // Registrieren ersetzt werden !
+ Size aTextSize = pLine->CalcTextSize( *pParaPortion );
+
+ if ( aTextSize.Height() == 0 )
+ {
+ SeekCursor( pNode, pLine->GetStart()+1, aTmpFont );
+ aTmpFont.SetPhysFont( pRefDev );
+ ImplInitDigitMode( pRefDev, 0, 0, 0, aTmpFont.GetLanguage() );
+
+ if ( IsFixedCellHeight() )
+ aTextSize.Height() = ImplCalculateFontIndependentLineSpacing( aTmpFont.GetHeight() );
+ else
+ aTextSize.Height() = aTmpFont.GetPhysTxtSize( pRefDev, String() ).Height();
+ pLine->SetHeight( (sal_uInt16)aTextSize.Height() );
+ }
+
+ // Die Fontmetriken koennen nicht kontinuierlich berechnet werden,
+ // wenn der Font sowieso eingestellt ist, weil ggf. ein grosser Font
+ // erst nach dem Umbrechen ploetzlich in der naechsten Zeile landet
+ // => Font-Metriken zu gross.
+ FormatterFontMetric aFormatterMetrics;
+ sal_uInt16 nTPos = pLine->GetStart();
+ for ( sal_uInt16 nP = pLine->GetStartPortion(); nP <= pLine->GetEndPortion(); nP++ )
+ {
+ TextPortion* pTP = pParaPortion->GetTextPortions().GetObject( nP );
+ // #95819# problem with hard font height attribute, when everthing but the line break has this attribute
+ if ( pTP->GetKind() != PORTIONKIND_LINEBREAK )
+ {
+ SeekCursor( pNode, nTPos+1, aTmpFont );
+ aTmpFont.SetPhysFont( GetRefDevice() );
+ ImplInitDigitMode( GetRefDevice(), 0, 0, 0, aTmpFont.GetLanguage() );
+ RecalcFormatterFontMetrics( aFormatterMetrics, aTmpFont );
+ }
+ nTPos = nTPos + pTP->GetLen();
+ }
+ sal_uInt16 nLineHeight = aFormatterMetrics.GetHeight();
+ if ( nLineHeight > pLine->GetHeight() )
+ pLine->SetHeight( nLineHeight );
+ pLine->SetMaxAscent( aFormatterMetrics.nMaxAscent );
+
+ bSameLineAgain = sal_False;
+ if ( GetTextRanger() && ( pLine->GetHeight() > nTextLineHeight ) )
+ {
+ // Nochmal mit der anderen Groesse aufsetzen!
+ bSameLineAgain = sal_True;
+ }
+
+
+ if ( !bSameLineAgain && !aStatus.IsOutliner() )
+ {
+ if ( rLSItem.GetLineSpaceRule() == SVX_LINE_SPACE_MIN )
+ {
+ sal_uInt16 nMinHeight = GetYValue( rLSItem.GetLineHeight() );
+ sal_uInt16 nTxtHeight = pLine->GetHeight();
+ if ( nTxtHeight < nMinHeight )
+ {
+ // Der Ascent muss um die Differenz angepasst werden:
+ long nDiff = nMinHeight - nTxtHeight;
+ pLine->SetMaxAscent( (sal_uInt16)(pLine->GetMaxAscent() + nDiff) );
+ pLine->SetHeight( nMinHeight, nTxtHeight );
+ }
+ }
+ else if ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP )
+ {
+ if ( nPara || IsFixedCellHeight() || pLine->GetStartPortion() ) // Nicht die aller erste Zeile
+ {
+ // #100508# There are documents with PropLineSpace 0, why?
+ // (cmc: re above question :-) such documents can be seen by importing a .ppt
+ if ( rLSItem.GetPropLineSpace() && ( rLSItem.GetPropLineSpace() != 100 ) )
+ {
+ sal_uInt16 nTxtHeight = pLine->GetHeight();
+ sal_Int32 nH = nTxtHeight;
+ nH *= rLSItem.GetPropLineSpace();
+ nH /= 100;
+ // Der Ascent muss um die Differenz angepasst werden:
+ long nDiff = pLine->GetHeight() - nH;
+ if ( nDiff > pLine->GetMaxAscent() )
+ nDiff = pLine->GetMaxAscent();
+ pLine->SetMaxAscent( (sal_uInt16)(pLine->GetMaxAscent() - nDiff) );
+ pLine->SetHeight( (sal_uInt16)nH, nTxtHeight );
+ }
+ }
+ }
+ }
+
+
+ // #80582# - Bullet should not influence line height
+// if ( !nLine )
+// {
+// long nBulletHeight = aBulletArea.GetHeight();
+// if ( nBulletHeight > (long)pLine->GetHeight() )
+// {
+// long nDiff = nBulletHeight - (long)pLine->GetHeight();
+// // nDiff auf oben und unten verteilen.
+// pLine->SetMaxAscent( (sal_uInt16)(pLine->GetMaxAscent() + nDiff/2) );
+// pLine->SetHeight( (sal_uInt16)nBulletHeight );
+// }
+// }
+
+ if ( ( !IsVertical() && aStatus.AutoPageWidth() ) ||
+ ( IsVertical() && aStatus.AutoPageHeight() ) )
+ {
+ // Wenn die Zeile in die aktuelle Papierbreite passt, muss
+ // diese Breite fuer die Ausrichting verwendet werden.
+ // Wenn sie nicht passt oder sie die Papierbreite aendert,
+ // wird bei Justification != LEFT sowieso noch mal formatiert.
+ long nMaxLineWidthFix = ( !IsVertical() ? aPaperSize.Width() : aPaperSize.Height() )
+ - GetXValue( rLRItem.GetRight() ) - nStartX;
+ if ( aTextSize.Width() < nMaxLineWidthFix )
+ nMaxLineWidth = nMaxLineWidthFix;
+ }
+
+ if ( bCompressedChars )
+ {
+ long nRemainingWidth = nMaxLineWidth - aTextSize.Width();
+ if ( nRemainingWidth > 0 )
+ {
+ ImplExpandCompressedPortions( pLine, pParaPortion, nRemainingWidth );
+ aTextSize = pLine->CalcTextSize( *pParaPortion );
+ }
+ }
+
+ if ( pLine->IsHangingPunctuation() )
+ {
+ // Width from HangingPunctuation was set to 0 in ImpBreakLine,
+ // check for rel width now, maybe create compression...
+ long n = nMaxLineWidth - aTextSize.Width();
+ TextPortion* pTP = pParaPortion->GetTextPortions().GetObject( pLine->GetEndPortion() );
+ sal_uInt16 nPosInArray = pLine->GetEnd()-1-pLine->GetStart();
+ long nNewValue = ( nPosInArray ? pLine->GetCharPosArray()[ nPosInArray-1 ] : 0 ) + n;
+ pLine->GetCharPosArray()[ nPosInArray ] = nNewValue;
+ pTP->GetSize().Width() += n;
+ }
+
+ pLine->SetTextWidth( aTextSize.Width() );
+ switch ( eJustification )
+ {
+ case SVX_ADJUST_CENTER:
+ {
+ long n = ( nMaxLineWidth - aTextSize.Width() ) / 2;
+ n += nStartX; // Einrueckung bleibt erhalten.
+ if ( n > 0 )
+ pLine->SetStartPosX( (sal_uInt16)n );
+ else
+ pLine->SetStartPosX( 0 );
+
+ }
+ break;
+ case SVX_ADJUST_RIGHT:
+ {
+ // Bei automatisch umgebrochenen Zeilen, die ein Blank
+ // am Ende enthalten, darf das Blank nicht ausgegeben werden!
+
+ long n = nMaxLineWidth - aTextSize.Width();
+ n += nStartX; // Einrueckung bleibt erhalten.
+ if ( n > 0 )
+ pLine->SetStartPosX( (sal_uInt16)n );
+ else
+ pLine->SetStartPosX( 0 );
+ }
+ break;
+ case SVX_ADJUST_BLOCK:
+ {
+ long nRemainingSpace = nMaxLineWidth - aTextSize.Width();
+ pLine->SetStartPosX( (sal_uInt16)nStartX );
+ if ( !bEOC && ( nRemainingSpace > 0 ) ) // nicht die letzte Zeile...
+ ImpAdjustBlocks( pParaPortion, pLine, nRemainingSpace );
+ }
+ break;
+ default:
+ {
+ pLine->SetStartPosX( (sal_uInt16)nStartX ); // FI, LI
+ }
+ break;
+ }
+
+ // -----------------------------------------------------------------
+ // pruefen, ob die Zeile neu ausgegeben werden muss...
+ // -----------------------------------------------------------------
+ pLine->SetInvalid();
+
+ // Wenn eine Portion umgebrochen wurde sind ggf. viel zu viele Positionen
+ // im CharPosArray:
+ if ( bCalcCharPositions )
+ {
+ sal_uInt16 nLen = pLine->GetLen();
+ sal_uInt16 nCount = pLine->GetCharPosArray().Count();
+ if ( nCount > nLen )
+ pLine->GetCharPosArray().Remove( nLen, nCount-nLen );
+ }
+
+ if ( GetTextRanger() )
+ {
+ if ( nTextXOffset )
+ pLine->SetStartPosX( (sal_uInt16) ( pLine->GetStartPosX() + nTextXOffset ) );
+ if ( nTextExtraYOffset )
+ {
+ pLine->SetHeight( (sal_uInt16) ( pLine->GetHeight() + nTextExtraYOffset ), 0, pLine->GetHeight() );
+ pLine->SetMaxAscent( (sal_uInt16) ( pLine->GetMaxAscent() + nTextExtraYOffset ) );
+ }
+ }
+
+ // Fuer kleiner 0 noch ueberlegen!
+ if ( pParaPortion->IsSimpleInvalid() /* && ( nInvalidDiff > 0 ) */ )
+ {
+ // Aenderung durch einfache Textaenderung...
+ // Formatierung nicht abbrechen, da Portions evtl. wieder
+ // gesplittet werden muessen!
+ // Wenn irgendwann mal abbrechbar, dann fogende Zeilen Validieren!
+ // Aber ggf. als Valid markieren, damit weniger Ausgabe...
+ if ( pLine->GetEnd() < nInvalidStart )
+ {
+ if ( *pLine == aSaveLine )
+ {
+ pLine->SetValid();
+ }
+ }
+ else
+ {
+ sal_uInt16 nStart = pLine->GetStart();
+ sal_uInt16 nEnd = pLine->GetEnd();
+
+ if ( nStart > nInvalidEnd )
+ {
+ if ( ( ( nStart-nInvalidDiff ) == aSaveLine.GetStart() ) &&
+ ( ( nEnd-nInvalidDiff ) == aSaveLine.GetEnd() ) )
+ {
+ pLine->SetValid();
+ if ( bCalcCharPositions && bQuickFormat )
+ {
+ bCalcCharPositions = sal_False;
+ bLineBreak = sal_False;
+ pParaPortion->CorrectValuesBehindLastFormattedLine( nLine );
+ break;
+ }
+ }
+ }
+ else if ( bCalcCharPositions && bQuickFormat && ( nEnd > nInvalidEnd) )
+ {
+ // Wenn die ungueltige Zeile so endet, dass die naechste an
+ // der 'gleichen' Textstelle wie vorher beginnt, also nicht
+ // anders umgebrochen wird, brauche ich dort auch nicht die
+ // textbreiten neu bestimmen:
+ if ( nEnd == ( aSaveLine.GetEnd() + nInvalidDiff ) )
+ {
+ bCalcCharPositions = sal_False;
+ bLineBreak = sal_False;
+ pParaPortion->CorrectValuesBehindLastFormattedLine( nLine );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !bSameLineAgain )
+ {
+ nIndex = pLine->GetEnd(); // naechste Zeile Start = letzte Zeile Ende
+ // weil nEnd hinter das letzte Zeichen zeigt!
+
+ sal_uInt16 nEndPortion = pLine->GetEndPortion();
+
+ // Naechste Zeile oder ggf. neue Zeile....
+ pLine = 0;
+ if ( nLine < pParaPortion->GetLines().Count()-1 )
+ pLine = pParaPortion->GetLines().GetObject( ++nLine );
+ if ( pLine && ( nIndex >= pNode->Len() ) )
+ {
+ nDelFromLine = nLine;
+ break;
+ }
+ if ( !pLine )
+ {
+ if ( nIndex < pNode->Len() )
+ {
+ pLine = new EditLine;
+ pParaPortion->GetLines().Insert( pLine, ++nLine );
+ }
+ else if ( nIndex && bLineBreak && GetTextRanger() )
+ {
+ // normaly CreateAndInsertEmptyLine would be called, but I want to use
+ // CreateLines, so I need Polygon code only here...
+ TextPortion* pDummyPortion = new TextPortion( 0 );
+ pParaPortion->GetTextPortions().Insert( pDummyPortion, pParaPortion->GetTextPortions().Count() );
+ pLine = new EditLine;
+ pParaPortion->GetLines().Insert( pLine, ++nLine );
+ bForceOneRun = TRUE;
+ bProcessingEmptyLine = TRUE;
+ }
+ }
+ if ( pLine )
+ {
+ aSaveLine = *pLine;
+ pLine->SetStart( nIndex );
+ pLine->SetEnd( nIndex );
+ pLine->SetStartPortion( nEndPortion+1 );
+ pLine->SetEndPortion( nEndPortion+1 );
+ }
+ }
+ } // while ( Index < Len )
+
+ if ( nDelFromLine != 0xFFFF )
+ pParaPortion->GetLines().DeleteFromLine( nDelFromLine );
+
+ DBG_ASSERT( pParaPortion->GetLines().Count(), "Keine Zeile nach CreateLines!" );
+
+ if ( bLineBreak == sal_True )
+ CreateAndInsertEmptyLine( pParaPortion, nStartPosY );
+
+ delete[] pBuf;
+
+ sal_Bool bHeightChanged = FinishCreateLines( pParaPortion );
+
+ if ( bMapChanged )
+ GetRefDevice()->Pop();
+
+ GetRefDevice()->Pop();
+
+ return bHeightChanged;
+}
+
+void ImpEditEngine::CreateAndInsertEmptyLine( ParaPortion* pParaPortion, sal_uInt32 )
+{
+ DBG_ASSERT( !GetTextRanger(), "Don't use CreateAndInsertEmptyLine with a polygon!" );
+
+ EditLine* pTmpLine = new EditLine;
+ pTmpLine->SetStart( pParaPortion->GetNode()->Len() );
+ pTmpLine->SetEnd( pParaPortion->GetNode()->Len() );
+ pParaPortion->GetLines().Insert( pTmpLine, pParaPortion->GetLines().Count() );
+
+ sal_Bool bLineBreak = pParaPortion->GetNode()->Len() ? sal_True : sal_False;
+ sal_Int32 nSpaceBefore = 0;
+ sal_Int32 nSpaceBeforeAndMinLabelWidth = GetSpaceBeforeAndMinLabelWidth( pParaPortion->GetNode(), &nSpaceBefore );
+ const SvxLRSpaceItem& rLRItem = GetLRSpaceItem( pParaPortion->GetNode() );
+ const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&)pParaPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
+ short nStartX = GetXValue( (short)(rLRItem.GetTxtLeft() + rLRItem.GetTxtFirstLineOfst() + nSpaceBefore));
+
+ Rectangle aBulletArea = Rectangle( Point(), Point() );
+ if ( bLineBreak == sal_True )
+ {
+ nStartX = (short)GetXValue( rLRItem.GetTxtLeft() + rLRItem.GetTxtFirstLineOfst() + nSpaceBeforeAndMinLabelWidth );
+ }
+ else
+ {
+ aBulletArea = GetEditEnginePtr()->GetBulletArea( GetParaPortions().GetPos( pParaPortion ) );
+ if ( aBulletArea.Right() > 0 )
+ pParaPortion->SetBulletX( (sal_uInt16) GetXValue( aBulletArea.Right() ) );
+ else
+ pParaPortion->SetBulletX( 0 ); // Falls Bullet falsch eingestellt.
+ if ( pParaPortion->GetBulletX() > nStartX )
+ {
+ nStartX = (short)GetXValue( rLRItem.GetTxtLeft() + rLRItem.GetTxtFirstLineOfst() + nSpaceBeforeAndMinLabelWidth );
+ if ( pParaPortion->GetBulletX() > nStartX )
+ nStartX = pParaPortion->GetBulletX();
+ }
+ }
+
+ SvxFont aTmpFont;
+ SeekCursor( pParaPortion->GetNode(), bLineBreak ? pParaPortion->GetNode()->Len() : 0, aTmpFont );
+ aTmpFont.SetPhysFont( pRefDev );
+
+ TextPortion* pDummyPortion = new TextPortion( 0 );
+ pDummyPortion->GetSize() = aTmpFont.GetPhysTxtSize( pRefDev, String() );
+ if ( IsFixedCellHeight() )
+ pDummyPortion->GetSize().Height() = ImplCalculateFontIndependentLineSpacing( aTmpFont.GetHeight() );
+ pParaPortion->GetTextPortions().Insert( pDummyPortion, pParaPortion->GetTextPortions().Count() );
+ FormatterFontMetric aFormatterMetrics;
+ RecalcFormatterFontMetrics( aFormatterMetrics, aTmpFont );
+ pTmpLine->SetMaxAscent( aFormatterMetrics.nMaxAscent );
+ pTmpLine->SetHeight( (sal_uInt16) pDummyPortion->GetSize().Height() );
+ sal_uInt16 nLineHeight = aFormatterMetrics.GetHeight();
+ if ( nLineHeight > pTmpLine->GetHeight() )
+ pTmpLine->SetHeight( nLineHeight );
+
+ if ( !aStatus.IsOutliner() )
+ {
+ USHORT nPara = GetParaPortions().GetPos( pParaPortion );
+ SvxAdjust eJustification = GetJustification( nPara );
+ long nMaxLineWidth = !IsVertical() ? aPaperSize.Width() : aPaperSize.Height();
+ nMaxLineWidth -= GetXValue( rLRItem.GetRight() );
+ long nTextXOffset = 0;
+ if ( nMaxLineWidth < 0 )
+ nMaxLineWidth = 1;
+ if ( eJustification == SVX_ADJUST_CENTER )
+ nStartX = sal::static_int_cast< short >(nMaxLineWidth / 2);
+ else if ( eJustification == SVX_ADJUST_RIGHT )
+ nStartX = sal::static_int_cast< short >(nMaxLineWidth);
+
+ nStartX = sal::static_int_cast< short >(nStartX + nTextXOffset);
+ }
+
+ pTmpLine->SetStartPosX( nStartX );
+
+ if ( !aStatus.IsOutliner() )
+ {
+ if ( rLSItem.GetLineSpaceRule() == SVX_LINE_SPACE_MIN )
+ {
+ sal_uInt16 nMinHeight = rLSItem.GetLineHeight();
+ sal_uInt16 nTxtHeight = pTmpLine->GetHeight();
+ if ( nTxtHeight < nMinHeight )
+ {
+ // Der Ascent muss um die Differenz angepasst werden:
+ long nDiff = nMinHeight - nTxtHeight;
+ pTmpLine->SetMaxAscent( (sal_uInt16)(pTmpLine->GetMaxAscent() + nDiff) );
+ pTmpLine->SetHeight( nMinHeight, nTxtHeight );
+ }
+ }
+ else if ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP )
+ {
+ USHORT nPara = GetParaPortions().GetPos( pParaPortion );
+ if ( nPara || IsFixedCellHeight() || pTmpLine->GetStartPortion() ) // Nicht die aller erste Zeile
+ {
+ // #100508# There are documents with PropLineSpace 0, why?
+ // (cmc: re above question :-) such documents can be seen by importing a .ppt
+ if ( rLSItem.GetPropLineSpace() && ( rLSItem.GetPropLineSpace() != 100 ) )
+ {
+ sal_uInt16 nTxtHeight = pTmpLine->GetHeight();
+ sal_Int32 nH = nTxtHeight;
+ nH *= rLSItem.GetPropLineSpace();
+ nH /= 100;
+ // Der Ascent muss um die Differenz angepasst werden:
+ long nDiff = pTmpLine->GetHeight() - nH;
+ if ( nDiff > pTmpLine->GetMaxAscent() )
+ nDiff = pTmpLine->GetMaxAscent();
+ pTmpLine->SetMaxAscent( (sal_uInt16)(pTmpLine->GetMaxAscent() - nDiff) );
+ pTmpLine->SetHeight( (sal_uInt16)nH, nTxtHeight );
+ }
+ }
+ }
+ }
+
+ if ( !bLineBreak )
+ {
+ long nMinHeight = aBulletArea.GetHeight();
+ if ( nMinHeight > (long)pTmpLine->GetHeight() )
+ {
+ long nDiff = nMinHeight - (long)pTmpLine->GetHeight();
+ // nDiff auf oben und unten verteilen.
+ pTmpLine->SetMaxAscent( (sal_uInt16)(pTmpLine->GetMaxAscent() + nDiff/2) );
+ pTmpLine->SetHeight( (sal_uInt16)nMinHeight );
+ }
+ }
+ else
+ {
+ // -2: Die neue ist bereits eingefuegt.
+#ifdef DBG_UTIL
+ EditLine* pLastLine = pParaPortion->GetLines().GetObject( pParaPortion->GetLines().Count()-2 );
+ DBG_ASSERT( pLastLine, "Weicher Umbruch, keine Zeile ?!" );
+ DBG_ASSERT( pLastLine->GetEnd() == pParaPortion->GetNode()->Len(), "Doch anders?" );
+#endif
+// pTmpLine->SetStart( pLastLine->GetEnd() );
+// pTmpLine->SetEnd( pLastLine->GetEnd() );
+ sal_uInt16 nPos = (sal_uInt16) pParaPortion->GetTextPortions().Count() - 1 ;
+ pTmpLine->SetStartPortion( nPos );
+ pTmpLine->SetEndPortion( nPos );
+ }
+}
+
+sal_Bool ImpEditEngine::FinishCreateLines( ParaPortion* pParaPortion )
+{
+// CalcCharPositions( pParaPortion );
+ pParaPortion->SetValid();
+ long nOldHeight = pParaPortion->GetHeight();
+// sal_uInt16 nPos = GetParaPortions().GetPos( pParaPortion );
+// DBG_ASSERT( nPos != USHRT_MAX, "FinishCreateLines: Portion nicht in Liste!" );
+// ParaPortion* pPrev = nPos ? GetParaPortions().GetObject( nPos-1 ) : 0;
+ CalcHeight( pParaPortion );
+
+ DBG_ASSERT( pParaPortion->GetTextPortions().Count(), "FinishCreateLines: Keine Text-Portion?" );
+ sal_Bool bRet = ( pParaPortion->GetHeight() != nOldHeight );
+ return bRet;
+}
+
+void ImpEditEngine::ImpBreakLine( ParaPortion* pParaPortion, EditLine* pLine, TextPortion* pPortion, sal_uInt16 nPortionStart, long nRemainingWidth, sal_Bool bCanHyphenate )
+{
+ ContentNode* const pNode = pParaPortion->GetNode();
+
+ sal_uInt16 nBreakInLine = nPortionStart - pLine->GetStart();
+ sal_uInt16 nMax = nBreakInLine + pPortion->GetLen();
+ while ( ( nBreakInLine < nMax ) && ( pLine->GetCharPosArray()[nBreakInLine] < nRemainingWidth ) )
+ nBreakInLine++;
+
+ sal_uInt16 nMaxBreakPos = nBreakInLine + pLine->GetStart();
+ sal_uInt16 nBreakPos = 0xFFFF;
+
+ sal_Bool bCompressBlank = sal_False;
+ sal_Bool bHyphenated = sal_False;
+ sal_Bool bHangingPunctuation = sal_False;
+ sal_Unicode cAlternateReplChar = 0;
+ sal_Unicode cAlternateExtraChar = 0;
+
+ if ( ( nMaxBreakPos < ( nMax + pLine->GetStart() ) ) && ( pNode->GetChar( nMaxBreakPos ) == ' ' ) )
+ {
+ // Break behind the blank, blank will be compressed...
+ nBreakPos = nMaxBreakPos + 1;
+ bCompressBlank = sal_True;
+ }
+ else
+ {
+ sal_uInt16 nMinBreakPos = pLine->GetStart();
+ USHORT nAttrs = pNode->GetCharAttribs().GetAttribs().Count();
+ for ( USHORT nAttr = nAttrs; nAttr; )
+ {
+ EditCharAttrib* pAttr = pNode->GetCharAttribs().GetAttribs()[--nAttr];
+ if ( pAttr->IsFeature() && ( pAttr->GetEnd() > nMinBreakPos ) && ( pAttr->GetEnd() <= nMaxBreakPos ) )
+ {
+ nMinBreakPos = pAttr->GetEnd();
+ break;
+ }
+ }
+
+ lang::Locale aLocale = GetLocale( EditPaM( pNode, nMaxBreakPos ) );
+
+ Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
+ OUString aText( *pNode );
+ Reference< XHyphenator > xHyph;
+ if ( bCanHyphenate )
+ xHyph = GetHyphenator();
+ i18n::LineBreakHyphenationOptions aHyphOptions( xHyph, Sequence< PropertyValue >(), 1 );
+ i18n::LineBreakUserOptions aUserOptions;
+
+ const i18n::ForbiddenCharacters* pForbidden = GetForbiddenCharsTable()->GetForbiddenCharacters( SvxLocaleToLanguage( aLocale ), TRUE );
+ aUserOptions.forbiddenBeginCharacters = pForbidden->beginLine;
+ aUserOptions.forbiddenEndCharacters = pForbidden->endLine;
+ aUserOptions.applyForbiddenRules = ((const SfxBoolItem&)pNode->GetContentAttribs().GetItem( EE_PARA_FORBIDDENRULES )).GetValue();
+ aUserOptions.allowPunctuationOutsideMargin = ((const SfxBoolItem&)pNode->GetContentAttribs().GetItem( EE_PARA_HANGINGPUNCTUATION )).GetValue();
+ aUserOptions.allowHyphenateEnglish = FALSE;
+
+ i18n::LineBreakResults aLBR = _xBI->getLineBreak( *pNode, nMaxBreakPos, aLocale, nMinBreakPos, aHyphOptions, aUserOptions );
+ nBreakPos = (USHORT)aLBR.breakIndex;
+
+ // BUG in I18N - under special condition (break behind field, #87327#) breakIndex is < nMinBreakPos
+ if ( nBreakPos < nMinBreakPos )
+ {
+ nBreakPos = nMinBreakPos;
+ }
+ else if ( ( nBreakPos > nMaxBreakPos ) && !aUserOptions.allowPunctuationOutsideMargin )
+ {
+ DBG_ERROR( "I18N: XBreakIterator::getLineBreak returns position > Max" );
+ nBreakPos = nMaxBreakPos;
+ }
+
+ // #101795# nBreakPos can never be outside the portion, even not with hangig punctuation
+ if ( nBreakPos > nMaxBreakPos )
+ nBreakPos = nMaxBreakPos;
+
+ // BUG in I18N - the japanese dot is in the next line!
+ // !!! Testen!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ if ( (nBreakPos + ( aUserOptions.allowPunctuationOutsideMargin ? 0 : 1 ) ) <= nMaxBreakPos )
+ {
+ sal_Unicode cFirstInNextLine = ( (nBreakPos+1) < pNode->Len() ) ? pNode->GetChar( nBreakPos ) : 0;
+ if ( cFirstInNextLine == 12290 )
+ nBreakPos++;
+ }
+
+ bHangingPunctuation = ( nBreakPos > nMaxBreakPos ) ? sal_True : sal_False;
+ pLine->SetHangingPunctuation( bHangingPunctuation );
+
+ #ifndef SVX_LIGHT
+ // Egal ob Trenner oder nicht: Das Wort nach dem Trenner durch
+ // die Silbentrennung jagen...
+ // nMaxBreakPos ist das letzte Zeichen was in die Zeile passt,
+ // nBreakPos ist der Wort-Anfang
+ // Ein Problem gibt es, wenn das Dok so schmal ist, dass ein Wort
+ // auf mehr als Zwei Zeilen gebrochen wird...
+ if ( !bHangingPunctuation && bCanHyphenate && GetHyphenator().is() )
+ {
+ i18n::Boundary aBoundary = _xBI->getWordBoundary( *pNode, nBreakPos, GetLocale( EditPaM( pNode, nBreakPos ) ), ::com::sun::star::i18n::WordType::DICTIONARY_WORD, sal_True );
+// sal_uInt16 nWordStart = nBreakPos;
+// sal_uInt16 nBreakPos_OLD = nBreakPos;
+ sal_uInt16 nWordStart = nBreakPos;
+ sal_uInt16 nWordEnd = (USHORT) aBoundary.endPos;
+ DBG_ASSERT( nWordEnd > nWordStart, "ImpBreakLine: Start >= End?" );
+
+ USHORT nWordLen = nWordEnd - nWordStart;
+ if ( ( nWordEnd >= nMaxBreakPos ) && ( nWordLen > 3 ) )
+ {
+ // #104415# May happen, because getLineBreak may differ from getWordBoudary with DICTIONARY_WORD
+ // DBG_ASSERT( nWordEnd >= nMaxBreakPos, "Hyph: Break?" );
+ String aWord( *pNode, nWordStart, nWordLen );
+ sal_uInt16 nMinTrail = nWordEnd-nMaxBreakPos+1; //+1: Vor dem angeknacksten Buchstaben
+ Reference< XHyphenatedWord > xHyphWord;
+ if (xHyphenator.is())
+ xHyphWord = xHyphenator->hyphenate( aWord, aLocale, aWord.Len() - nMinTrail, Sequence< PropertyValue >() );
+ if (xHyphWord.is())
+ {
+ sal_Bool bAlternate = xHyphWord->isAlternativeSpelling();
+ sal_uInt16 _nWordLen = 1 + xHyphWord->getHyphenPos();
+
+ if ( ( _nWordLen >= 2 ) && ( (nWordStart+_nWordLen) >= (pLine->GetStart() + 2 ) ) )
+ {
+ if ( !bAlternate )
+ {
+ bHyphenated = sal_True;
+ nBreakPos = nWordStart + _nWordLen;
+ }
+ else
+ {
+ String aAlt( xHyphWord->getHyphenatedWord() );
+
+ // Wir gehen von zwei Faellen aus, die nun
+ // vorliegen koennen:
+ // 1) packen wird zu pak-ken
+ // 2) Schiffahrt wird zu Schiff-fahrt
+ // In Fall 1 muss ein Zeichen ersetzt werden,
+ // in Fall 2 wird ein Zeichen hinzugefuegt.
+ // Die Identifikation wird erschwert durch Worte wie
+ // "Schiffahrtsbrennesseln", da der Hyphenator alle
+ // Position des Wortes auftrennt und "Schifffahrtsbrennnesseln"
+ // ermittelt. Wir koennen also eigentlich nicht unmittelbar vom
+ // Index des AlternativWord auf aWord schliessen.
+
+ // Das ganze geraffel wird durch eine Funktion am
+ // Hyphenator vereinfacht werden, sobald AMA sie einbaut...
+ sal_uInt16 nAltStart = _nWordLen - 1;
+ sal_uInt16 nTxtStart = nAltStart - (aAlt.Len() - aWord.Len());
+ sal_uInt16 nTxtEnd = nTxtStart;
+ sal_uInt16 nAltEnd = nAltStart;
+
+ // Die Bereiche zwischen den nStart und nEnd ist
+ // die Differenz zwischen Alternativ- und OriginalString.
+ while( nTxtEnd < aWord.Len() && nAltEnd < aAlt.Len() &&
+ aWord.GetChar(nTxtEnd) != aAlt.GetChar(nAltEnd) )
+ {
+ ++nTxtEnd;
+ ++nAltEnd;
+ }
+
+ // Wenn ein Zeichen hinzugekommen ist, dann bemerken wir es jetzt:
+ if( nAltEnd > nTxtEnd && nAltStart == nAltEnd &&
+ aWord.GetChar( nTxtEnd ) == aAlt.GetChar(nAltEnd) )
+ {
+ ++nAltEnd;
+ ++nTxtStart;
+ ++nTxtEnd;
+ }
+
+ DBG_ASSERT( ( nAltEnd - nAltStart ) == 1, "Alternate: Falsche Annahme!" );
+
+ if ( nTxtEnd > nTxtStart )
+ cAlternateReplChar = aAlt.GetChar( nAltStart );
+ else
+ cAlternateExtraChar = aAlt.GetChar( nAltStart );
+
+ bHyphenated = sal_True;
+ nBreakPos = nWordStart + nTxtStart;
+ if ( cAlternateReplChar )
+ nBreakPos++;
+ }
+ }
+ }
+ }
+ }
+
+ #endif // !SVX_LIGHT
+
+ if ( nBreakPos <= pLine->GetStart() )
+ {
+ // keine Trenner in Zeile => abhacken !
+ nBreakPos = nMaxBreakPos;
+ // MT: I18N nextCharacters !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ if ( nBreakPos <= pLine->GetStart() )
+ nBreakPos = pLine->GetStart() + 1; // Sonst Endlosschleife!
+ }
+ }
+
+ // die angeknackste Portion ist die End-Portion
+ pLine->SetEnd( nBreakPos );
+
+ sal_uInt16 nEndPortion = SplitTextPortion( pParaPortion, nBreakPos, pLine );
+
+ if ( !bCompressBlank && !bHangingPunctuation )
+ {
+ // #96187# When justification is not SVX_ADJUST_LEFT, it's important to compress
+ // the trailing space even if there is enough room for the space...
+ // Don't check for SVX_ADJUST_LEFT, doesn't matter to compress in this case too...
+ DBG_ASSERT( nBreakPos > pLine->GetStart(), "ImpBreakLines - BreakPos not expected!" );
+ if ( pNode->GetChar( nBreakPos-1 ) == ' ' )
+ bCompressBlank = sal_True;
+ }
+
+ if ( bCompressBlank || bHangingPunctuation )
+ {
+ TextPortion* pTP = pParaPortion->GetTextPortions().GetObject( nEndPortion );
+ DBG_ASSERT( pTP->GetKind() == PORTIONKIND_TEXT, "BlankRubber: Keine TextPortion!" );
+ DBG_ASSERT( nBreakPos > pLine->GetStart(), "SplitTextPortion am Anfang der Zeile?" );
+ sal_uInt16 nPosInArray = nBreakPos - 1 - pLine->GetStart();
+ pTP->GetSize().Width() = ( nPosInArray && ( pTP->GetLen() > 1 ) ) ? pLine->GetCharPosArray()[ nPosInArray-1 ] : 0;
+ pLine->GetCharPosArray()[ nPosInArray ] = pTP->GetSize().Width();
+ }
+ else if ( bHyphenated )
+ {
+ // Eine Portion fuer den Trenner einbauen...
+ TextPortion* pHyphPortion = new TextPortion( 0 );
+ pHyphPortion->GetKind() = PORTIONKIND_HYPHENATOR;
+ String aHyphText( CH_HYPH );
+ if ( cAlternateReplChar )
+ {
+ TextPortion* pPrev = pParaPortion->GetTextPortions().GetObject( nEndPortion );
+ DBG_ASSERT( pPrev && pPrev->GetLen(), "Hyphenate: Prev portion?!" );
+ pPrev->SetLen( pPrev->GetLen() - 1 );
+ pHyphPortion->SetLen( 1 );
+ pHyphPortion->SetExtraValue( cAlternateReplChar );
+ // Breite der Portion davor korrigieren:
+ pPrev->GetSize().Width() =
+ pLine->GetCharPosArray()[ nBreakPos-1 - pLine->GetStart() - 1 ];
+ }
+ else if ( cAlternateExtraChar )
+ {
+ pHyphPortion->SetExtraValue( cAlternateExtraChar );
+ aHyphText.Insert( cAlternateExtraChar, 0 );
+ }
+
+ // Breite der Hyph-Portion ermitteln:
+ SvxFont aFont;
+ SeekCursor( pParaPortion->GetNode(), nBreakPos, aFont );
+ aFont.SetPhysFont( GetRefDevice() );
+ pHyphPortion->GetSize().Height() = GetRefDevice()->GetTextHeight();
+ pHyphPortion->GetSize().Width() = GetRefDevice()->GetTextWidth( aHyphText );
+
+ pParaPortion->GetTextPortions().Insert( pHyphPortion, ++nEndPortion );
+ }
+ pLine->SetEndPortion( nEndPortion );
+}
+
+void ImpEditEngine::ImpAdjustBlocks( ParaPortion* pParaPortion, EditLine* pLine, long nRemainingSpace )
+{
+ DBG_ASSERT( nRemainingSpace > 0, "AdjustBlocks: Etwas zuwenig..." );
+ DBG_ASSERT( pLine, "AdjustBlocks: Zeile ?!" );
+ if ( ( nRemainingSpace < 0 ) || pLine->IsEmpty() )
+ return ;
+
+ const USHORT nFirstChar = pLine->GetStart();
+ const USHORT nLastChar = pLine->GetEnd() -1; // Last zeigt dahinter
+ ContentNode* pNode = pParaPortion->GetNode();
+
+ DBG_ASSERT( nLastChar < pNode->Len(), "AdjustBlocks: Out of range!" );
+
+ // Search blanks or Kashidas...
+ SvUShorts aPositions;
+ USHORT nChar;
+ for ( nChar = nFirstChar; nChar <= nLastChar; nChar++ )
+ {
+ if ( pNode->GetChar(nChar) == ' ' )
+ {
+ // Don't use blank if language is arabic
+ LanguageType eLang = GetLanguage( EditPaM( pNode, nChar ) );
+ if ( MsLangId::getPrimaryLanguage( eLang) != LANGUAGE_ARABIC_PRIMARY_ONLY )
+ aPositions.Insert( nChar, aPositions.Count() );
+ }
+ }
+
+ // Kashidas ?
+ ImpFindKashidas( pNode, nFirstChar, nLastChar, aPositions );
+
+
+ if ( !aPositions.Count() )
+ return;
+
+ // Wenn das letzte Zeichen ein Blank ist, will ich es nicht haben!
+ // Die Breite muss auf die Blocker davor verteilt werden...
+ // Aber nicht, wenn es das einzige ist
+ if ( ( pNode->GetChar( nLastChar ) == ' ' ) && ( aPositions.Count() > 1 ) && ( MsLangId::getPrimaryLanguage( GetLanguage( EditPaM( pNode, nLastChar ) ) ) != LANGUAGE_ARABIC_PRIMARY_ONLY ) )
+ {
+ aPositions.Remove( aPositions.Count()-1, 1 );
+ USHORT nPortionStart, nPortion;
+ nPortion = pParaPortion->GetTextPortions().FindPortion( nLastChar+1, nPortionStart );
+ TextPortion* pLastPortion = pParaPortion->GetTextPortions()[ nPortion ];
+ long nRealWidth = pLine->GetCharPosArray()[nLastChar-nFirstChar];
+ long nBlankWidth = nRealWidth;
+ if ( nLastChar > nPortionStart )
+ nBlankWidth -= pLine->GetCharPosArray()[nLastChar-nFirstChar-1];
+ // Evtl. ist das Blank schon in ImpBreakLine abgezogen worden:
+ if ( nRealWidth == pLastPortion->GetSize().Width() )
+ {
+ // Beim letzten Zeichen muss die Portion hinter dem Blank aufhoeren
+ // => Korrektur vereinfachen:
+ DBG_ASSERT( ( nPortionStart + pLastPortion->GetLen() ) == ( nLastChar+1 ), "Blank doch nicht am Portion-Ende?!" );
+ pLastPortion->GetSize().Width() -= nBlankWidth;
+ nRemainingSpace += nBlankWidth;
+ }
+ pLine->GetCharPosArray()[nLastChar-nFirstChar] -= nBlankWidth;
+ }
+
+ USHORT nGaps = aPositions.Count();
+ const long nMore4Everyone = nRemainingSpace / nGaps;
+ long nSomeExtraSpace = nRemainingSpace - nMore4Everyone*nGaps;
+
+ DBG_ASSERT( nSomeExtraSpace < (long)nGaps, "AdjustBlocks: ExtraSpace zu gross" );
+ DBG_ASSERT( nSomeExtraSpace >= 0, "AdjustBlocks: ExtraSpace < 0 " );
+
+ // Die Positionen im Array und die Portion-Breiten korrigieren:
+ // Letztes Zeichen wird schon nicht mehr beachtet...
+ for ( USHORT n = 0; n < aPositions.Count(); n++ )
+ {
+ nChar = aPositions[n];
+ if ( nChar < nLastChar )
+ {
+ USHORT nPortionStart, nPortion;
+ nPortion = pParaPortion->GetTextPortions().FindPortion( nChar, nPortionStart );
+ TextPortion* pLastPortion = pParaPortion->GetTextPortions()[ nPortion ];
+
+ // Die Breite der Portion:
+ pLastPortion->GetSize().Width() += nMore4Everyone;
+ if ( nSomeExtraSpace )
+ pLastPortion->GetSize().Width()++;
+
+ // Correct positions in array
+ // Even for kashidas just change positions, VCL will then draw the kashida automaticly
+ USHORT nPortionEnd = nPortionStart + pLastPortion->GetLen();
+ for ( USHORT _n = nChar; _n < nPortionEnd; _n++ )
+ {
+ pLine->GetCharPosArray()[_n-nFirstChar] += nMore4Everyone;
+ if ( nSomeExtraSpace )
+ pLine->GetCharPosArray()[_n-nFirstChar]++;
+ }
+
+ if ( nSomeExtraSpace )
+ nSomeExtraSpace--;
+ }
+ }
+
+ // Now the text width contains the extra width...
+ pLine->SetTextWidth( pLine->GetTextWidth() + nRemainingSpace );
+}
+
+void ImpEditEngine::ImpFindKashidas( ContentNode* pNode, USHORT nStart, USHORT nEnd, SvUShorts& rArray )
+{
+ // the search has to be performed on a per word base
+
+ EditSelection aWordSel( EditPaM( pNode, nStart ) );
+ aWordSel = SelectWord( aWordSel, ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
+ if ( aWordSel.Min().GetIndex() < nStart )
+ aWordSel.Min().GetIndex() = nStart;
+
+ while ( ( aWordSel.Min().GetNode() == pNode ) && ( aWordSel.Min().GetIndex() < nEnd ) )
+ {
+ USHORT nSavPos = aWordSel.Max().GetIndex();
+ if ( aWordSel.Max().GetIndex() > nEnd )
+ aWordSel.Max().GetIndex() = nEnd;
+
+ String aWord = GetSelected( aWordSel );
+
+ // restore selection for proper iteration at the end of the function
+ aWordSel.Max().GetIndex() = nSavPos;
+
+ xub_StrLen nIdx = 0;
+ xub_StrLen nKashidaPos = STRING_LEN;
+ xub_Unicode cCh;
+ xub_Unicode cPrevCh = 0;
+
+ while ( nIdx < aWord.Len() )
+ {
+ cCh = aWord.GetChar( nIdx );
+
+ // 1. Priority:
+ // after user inserted kashida
+ if ( 0x640 == cCh )
+ {
+ nKashidaPos = aWordSel.Min().GetIndex() + nIdx;
+ break;
+ }
+
+ // 2. Priority:
+ // after a Seen or Sad
+ if ( nIdx + 1 < aWord.Len() &&
+ ( 0x633 == cCh || 0x635 == cCh ) )
+ {
+ nKashidaPos = aWordSel.Min().GetIndex() + nIdx;
+ break;
+ }
+
+ // 3. Priority:
+ // before final form of Teh Marbuta, Hah, Dal
+ // 4. Priority:
+ // before final form of Alef, Lam or Kaf
+ if ( nIdx && nIdx + 1 == aWord.Len() &&
+ ( 0x629 == cCh || 0x62D == cCh || 0x62F == cCh ||
+ 0x627 == cCh || 0x644 == cCh || 0x643 == cCh ) )
+ {
+ DBG_ASSERT( 0 != cPrevCh, "No previous character" );
+
+ // check if character is connectable to previous character,
+ if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
+ {
+ nKashidaPos = aWordSel.Min().GetIndex() + nIdx - 1;
+ break;
+ }
+ }
+
+ // 5. Priority:
+ // before media Bah
+ if ( nIdx && nIdx + 1 < aWord.Len() && 0x628 == cCh )
+ {
+ DBG_ASSERT( 0 != cPrevCh, "No previous character" );
+
+ // check if next character is Reh, Yeh or Alef Maksura
+ xub_Unicode cNextCh = aWord.GetChar( nIdx + 1 );
+
+ if ( 0x631 == cNextCh || 0x64A == cNextCh ||
+ 0x649 == cNextCh )
+ {
+ // check if character is connectable to previous character,
+ if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
+ nKashidaPos = aWordSel.Min().GetIndex() + nIdx - 1;
+ }
+ }
+
+ // 6. Priority:
+ // other connecting possibilities
+ if ( nIdx && nIdx + 1 == aWord.Len() &&
+ 0x60C <= cCh && 0x6FE >= cCh )
+ {
+ DBG_ASSERT( 0 != cPrevCh, "No previous character" );
+
+ // check if character is connectable to previous character,
+ if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
+ {
+ // only choose this position if we did not find
+ // a better one:
+ if ( STRING_LEN == nKashidaPos )
+ nKashidaPos = aWordSel.Min().GetIndex() + nIdx - 1;
+ break;
+ }
+ }
+
+ // Do not consider Fathatan, Dammatan, Kasratan, Fatha,
+ // Damma, Kasra, Shadda and Sukun when checking if
+ // a character can be connected to previous character.
+ if ( cCh < 0x64B || cCh > 0x652 )
+ cPrevCh = cCh;
+
+ ++nIdx;
+ } // end of current word
+
+ if ( STRING_LEN != nKashidaPos )
+ rArray.Insert( nKashidaPos, rArray.Count() );
+
+ aWordSel = WordRight( aWordSel.Max(), ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
+ aWordSel = SelectWord( aWordSel, ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
+ }
+}
+
+sal_uInt16 ImpEditEngine::SplitTextPortion( ParaPortion* pPortion, sal_uInt16 nPos, EditLine* pCurLine )
+{
+ DBG_ASSERT( pPortion, "SplitTextPortion: Welche ?" );
+
+ // Die Portion bei nPos wird geplittet, wenn bei nPos nicht
+ // sowieso ein Wechsel ist
+ if ( nPos == 0 )
+ return 0;
+
+ sal_uInt16 nSplitPortion;
+ sal_uInt16 nTmpPos = 0;
+ TextPortion* pTextPortion = 0;
+ sal_uInt16 nPortions = pPortion->GetTextPortions().Count();
+ for ( nSplitPortion = 0; nSplitPortion < nPortions; nSplitPortion++ )
+ {
+ TextPortion* pTP = pPortion->GetTextPortions().GetObject(nSplitPortion);
+ nTmpPos = nTmpPos + pTP->GetLen();
+ if ( nTmpPos >= nPos )
+ {
+ if ( nTmpPos == nPos ) // dann braucht nichts geteilt werden
+ {
+ // Skip Portions with ExtraSpace
+// while ( ( (nSplitPortion+1) < nPortions ) && (pPortion->GetTextPortions().GetObject(nSplitPortion+1)->GetKind() == PORTIONKIND_EXTRASPACE ) )
+// nSplitPortion++;
+
+ return nSplitPortion;
+ }
+ pTextPortion = pTP;
+ break;
+ }
+ }
+
+ DBG_ASSERT( pTextPortion, "Position ausserhalb des Bereichs!" );
+ DBG_ASSERT( pTextPortion->GetKind() == PORTIONKIND_TEXT, "SplitTextPortion: Keine TextPortion!" );
+
+ sal_uInt16 nOverlapp = nTmpPos - nPos;
+ pTextPortion->GetLen() = pTextPortion->GetLen() - nOverlapp;
+ TextPortion* pNewPortion = new TextPortion( nOverlapp );
+ pPortion->GetTextPortions().Insert( pNewPortion, nSplitPortion+1 );
+ // Groessen setzen:
+ if ( pCurLine )
+ {
+ // Kein neues GetTextSize, sondern Werte aus Array verwenden:
+ DBG_ASSERT( nPos > pCurLine->GetStart(), "SplitTextPortion am Anfang der Zeile?" );
+ pTextPortion->GetSize().Width() = pCurLine->GetCharPosArray()[ nPos-pCurLine->GetStart()-1 ];
+
+ if ( pTextPortion->GetExtraInfos() && pTextPortion->GetExtraInfos()->bCompressed )
+ {
+ // We need the original size from the portion
+ USHORT nTxtPortionStart = pPortion->GetTextPortions().GetStartPos( nSplitPortion );
+ SvxFont aTmpFont( pPortion->GetNode()->GetCharAttribs().GetDefFont() );
+ SeekCursor( pPortion->GetNode(), nTxtPortionStart+1, aTmpFont );
+ aTmpFont.SetPhysFont( GetRefDevice() );
+ GetRefDevice()->Push( PUSH_TEXTLANGUAGE );
+ ImplInitDigitMode( GetRefDevice(), 0, 0, 0, aTmpFont.GetLanguage() );
+ Size aSz = aTmpFont.QuickGetTextSize( GetRefDevice(), *pPortion->GetNode(), nTxtPortionStart, pTextPortion->GetLen(), NULL );
+ GetRefDevice()->Pop();
+ pTextPortion->GetExtraInfos()->nOrgWidth = aSz.Width();
+ }
+ }
+ else
+ pTextPortion->GetSize().Width() = (-1);
+
+ return nSplitPortion;
+}
+
+void ImpEditEngine::CreateTextPortions( ParaPortion* pParaPortion, sal_uInt16& rStart /* , sal_Bool bCreateBlockPortions */ )
+{
+ sal_uInt16 nStartPos = rStart;
+ ContentNode* pNode = pParaPortion->GetNode();
+ DBG_ASSERT( pNode->Len(), "CreateTextPortions sollte nicht fuer leere Absaetze verwendet werden!" );
+
+ SortedPositions aPositions;
+ aPositions.Insert( (sal_uInt32) 0 );
+
+ sal_uInt16 nAttr = 0;
+ EditCharAttrib* pAttrib = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
+ while ( pAttrib )
+ {
+ // Start und Ende in das Array eintragen...
+ // Die InsertMethode laesst keine doppelten Werte zu....
+ aPositions.Insert( pAttrib->GetStart() );
+ aPositions.Insert( pAttrib->GetEnd() );
+ nAttr++;
+ pAttrib = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
+ }
+ aPositions.Insert( pNode->Len() );
+
+ if ( !pParaPortion->aScriptInfos.Count() )
+ ((ImpEditEngine*)this)->InitScriptTypes( GetParaPortions().GetPos( pParaPortion ) );
+
+ const ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
+ for ( USHORT nT = 0; nT < rTypes.Count(); nT++ )
+ aPositions.Insert( rTypes[nT].nStartPos );
+
+ const WritingDirectionInfos& rWritingDirections = pParaPortion->aWritingDirectionInfos;
+ for ( USHORT nD = 0; nD < rWritingDirections.Count(); nD++ )
+ aPositions.Insert( rWritingDirections[nD].nStartPos );
+
+ if ( mpIMEInfos && mpIMEInfos->nLen && mpIMEInfos->pAttribs && ( mpIMEInfos->aPos.GetNode() == pNode ) )
+ {
+ sal_uInt16 nLastAttr = 0xFFFF;
+ for( sal_uInt16 n = 0; n < mpIMEInfos->nLen; n++ )
+ {
+ if ( mpIMEInfos->pAttribs[n] != nLastAttr )
+ {
+ aPositions.Insert( mpIMEInfos->aPos.GetIndex() + n );
+ nLastAttr = mpIMEInfos->pAttribs[n];
+ }
+ }
+ aPositions.Insert( mpIMEInfos->aPos.GetIndex() + mpIMEInfos->nLen );
+ }
+
+ // Ab ... loeschen:
+ // Leider muss die Anzahl der TextPortions mit aPositions.Count()
+ // nicht uebereinstimmen, da evtl. Zeilenumbrueche...
+ sal_uInt16 nPortionStart = 0;
+ sal_uInt16 nInvPortion = 0;
+ sal_uInt16 nP;
+ for ( nP = 0; nP < pParaPortion->GetTextPortions().Count(); nP++ )
+ {
+ TextPortion* pTmpPortion = pParaPortion->GetTextPortions().GetObject(nP);
+ nPortionStart = nPortionStart + pTmpPortion->GetLen();
+ if ( nPortionStart >= nStartPos )
+ {
+ nPortionStart = nPortionStart - pTmpPortion->GetLen();
+ rStart = nPortionStart;
+ nInvPortion = nP;
+ break;
+ }
+ }
+ DBG_ASSERT( nP < pParaPortion->GetTextPortions().Count() || !pParaPortion->GetTextPortions().Count(), "Nichts zum loeschen: CreateTextPortions" );
+ if ( nInvPortion && ( nPortionStart+pParaPortion->GetTextPortions().GetObject(nInvPortion)->GetLen() > nStartPos ) )
+ {
+ // lieber eine davor...
+ // Aber nur wenn es mitten in der Portion war, sonst ist es evtl.
+ // die einzige in der Zeile davor !
+ nInvPortion--;
+ nPortionStart = nPortionStart - pParaPortion->GetTextPortions().GetObject(nInvPortion)->GetLen();
+ }
+ pParaPortion->GetTextPortions().DeleteFromPortion( nInvPortion );
+
+ // Eine Portion kann auch durch einen Zeilenumbruch entstanden sein:
+ aPositions.Insert( nPortionStart );
+
+ sal_uInt16 nInvPos;
+#ifdef DBG_UTIL
+ sal_Bool bFound =
+#endif
+ aPositions.Seek_Entry( nPortionStart, &nInvPos );
+
+ DBG_ASSERT( bFound && ( nInvPos < (aPositions.Count()-1) ), "InvPos ?!" );
+ for ( sal_uInt16 i = nInvPos+1; i < aPositions.Count(); i++ )
+ {
+ TextPortion* pNew = new TextPortion( (sal_uInt16)aPositions[i] - (sal_uInt16)aPositions[i-1] );
+ pParaPortion->GetTextPortions().Insert( pNew, pParaPortion->GetTextPortions().Count());
+ }
+
+ DBG_ASSERT( pParaPortion->GetTextPortions().Count(), "Keine Portions?!" );
+#ifdef EDITDEBUG
+ DBG_ASSERT( pParaPortion->DbgCheckTextPortions(), "Portions kaputt?" );
+#endif
+}
+
+void ImpEditEngine::RecalcTextPortion( ParaPortion* pParaPortion, sal_uInt16 nStartPos, short nNewChars )
+{
+ DBG_ASSERT( pParaPortion->GetTextPortions().Count(), "Keine Portions!" );
+ DBG_ASSERT( nNewChars, "RecalcTextPortion mit Diff == 0" );
+
+ ContentNode* const pNode = pParaPortion->GetNode();
+ if ( nNewChars > 0 )
+ {
+ // Wenn an nStartPos ein Attribut beginnt/endet, faengt eine neue Portion
+ // an, ansonsten wird die Portion an nStartPos erweitert.
+
+ if ( pNode->GetCharAttribs().HasBoundingAttrib( nStartPos ) || IsScriptChange( EditPaM( pNode, nStartPos ) ) )
+ {
+ sal_uInt16 nNewPortionPos = 0;
+ if ( nStartPos )
+ nNewPortionPos = SplitTextPortion( pParaPortion, nStartPos ) + 1;
+
+ // Eine leere Portion kann hier stehen, wenn der Absatz leer war,
+ // oder eine Zeile durch einen harten Zeilenumbruch entstanden ist.
+ if ( ( nNewPortionPos < pParaPortion->GetTextPortions().Count() ) &&
+ !pParaPortion->GetTextPortions()[nNewPortionPos]->GetLen() )
+ {
+ DBG_ASSERT( pParaPortion->GetTextPortions()[nNewPortionPos]->GetKind() == PORTIONKIND_TEXT, "Leere Portion war keine TextPortion!" );
+ USHORT & r =
+ pParaPortion->GetTextPortions()[nNewPortionPos]->GetLen();
+ r = r + nNewChars;
+ }
+ else
+ {
+ TextPortion* pNewPortion = new TextPortion( nNewChars );
+ pParaPortion->GetTextPortions().Insert( pNewPortion, nNewPortionPos );
+ }
+ }
+ else
+ {
+ sal_uInt16 nPortionStart;
+ const sal_uInt16 nTP = pParaPortion->GetTextPortions().
+ FindPortion( nStartPos, nPortionStart );
+ TextPortion* const pTP = pParaPortion->GetTextPortions()[ nTP ];
+ DBG_ASSERT( pTP, "RecalcTextPortion: Portion nicht gefunden" );
+ pTP->GetLen() = pTP->GetLen() + nNewChars;
+ pTP->GetSize().Width() = (-1);
+ }
+ }
+ else
+ {
+ // Portion schrumpfen oder ggf. entfernen.
+ // Vor Aufruf dieser Methode muss sichergestellt sein, dass
+ // keine Portions in dem geloeschten Bereich lagen!
+
+ // Es darf keine reinragende oder im Bereich startende Portion geben,
+ // also muss nStartPos <= nPos <= nStartPos - nNewChars(neg.) sein
+ sal_uInt16 nPortion = 0;
+ sal_uInt16 nPos = 0;
+ sal_uInt16 nEnd = nStartPos-nNewChars;
+ sal_uInt16 nPortions = pParaPortion->GetTextPortions().Count();
+ TextPortion* pTP = 0;
+ for ( nPortion = 0; nPortion < nPortions; nPortion++ )
+ {
+ pTP = pParaPortion->GetTextPortions()[ nPortion ];
+ if ( ( nPos+pTP->GetLen() ) > nStartPos )
+ {
+ DBG_ASSERT( nPos <= nStartPos, "Start falsch!" );
+ DBG_ASSERT( nPos+pTP->GetLen() >= nEnd, "End falsch!" );
+ break;
+ }
+ nPos = nPos + pTP->GetLen();
+ }
+ DBG_ASSERT( pTP, "RecalcTextPortion: Portion nicht gefunden" );
+ if ( ( nPos == nStartPos ) && ( (nPos+pTP->GetLen()) == nEnd ) )
+ {
+ // Portion entfernen;
+ BYTE nType = pTP->GetKind();
+ pParaPortion->GetTextPortions().Remove( nPortion );
+ delete pTP;
+ if ( nType == PORTIONKIND_LINEBREAK )
+ {
+ TextPortion* pNext = pParaPortion->GetTextPortions()[ nPortion ];
+ if ( pNext && !pNext->GetLen() )
+ {
+ // Dummy-Portion entfernen
+ pParaPortion->GetTextPortions().Remove( nPortion );
+ delete pNext;
+ }
+ }
+ }
+ else
+ {
+ DBG_ASSERT( pTP->GetLen() > (-nNewChars), "Portion zu klein zum schrumpfen!" );
+ pTP->GetLen() = pTP->GetLen() + nNewChars;
+ }
+
+ // ganz am Schluss darf keine HYPHENATOR-Portion stehen bleiben...
+ DBG_ASSERT( pParaPortion->GetTextPortions().Count(), "RecalcTextPortions: Keine mehr da!" );
+ sal_uInt16 nLastPortion = pParaPortion->GetTextPortions().Count() - 1;
+ pTP = pParaPortion->GetTextPortions().GetObject( nLastPortion );
+ if ( pTP->GetKind() == PORTIONKIND_HYPHENATOR )
+ {
+ // Portion wegschmeissen, ggf. die davor korrigieren, wenn
+ // die Hyph-Portion ein Zeichen geschluckt hat...
+ pParaPortion->GetTextPortions().Remove( nLastPortion );
+ if ( nLastPortion && pTP->GetLen() )
+ {
+ TextPortion* pPrev = pParaPortion->GetTextPortions().GetObject( nLastPortion - 1 );
+ DBG_ASSERT( pPrev->GetKind() == PORTIONKIND_TEXT, "Portion?!" );
+ pPrev->SetLen( pPrev->GetLen() + pTP->GetLen() );
+ pPrev->GetSize().Width() = (-1);
+ }
+ delete pTP;
+ }
+ }
+#ifdef EDITDEBUG
+ DBG_ASSERT( pParaPortion->DbgCheckTextPortions(), "Portions kaputt?" );
+#endif
+}
+
+void ImpEditEngine::SetTextRanger( TextRanger* pRanger )
+{
+ if ( pTextRanger != pRanger )
+ {
+ delete pTextRanger;
+ pTextRanger = pRanger;
+
+ for ( sal_uInt16 nPara = 0; nPara < GetParaPortions().Count(); nPara++ )
+ {
+ ParaPortion* pParaPortion = GetParaPortions().GetObject( nPara );
+ pParaPortion->MarkSelectionInvalid( 0, pParaPortion->GetNode()->Len() );
+ pParaPortion->GetLines().Reset();
+ }
+
+ FormatFullDoc();
+ UpdateViews( GetActiveView() );
+ if ( GetUpdateMode() && GetActiveView() )
+ pActiveView->ShowCursor( sal_False, sal_False );
+ }
+}
+
+void ImpEditEngine::SetVertical( BOOL bVertical )
+{
+ if ( IsVertical() != bVertical )
+ {
+ GetEditDoc().SetVertical( bVertical );
+ sal_Bool bUseCharAttribs = ( aStatus.GetControlWord() & EE_CNTRL_USECHARATTRIBS ) ? sal_True : sal_False;
+ GetEditDoc().CreateDefFont( bUseCharAttribs );
+ if ( IsFormatted() )
+ {
+ FormatFullDoc();
+ UpdateViews( GetActiveView() );
+ }
+ }
+}
+
+void ImpEditEngine::SetFixedCellHeight( BOOL bUseFixedCellHeight )
+{
+ if ( IsFixedCellHeight() != bUseFixedCellHeight )
+ {
+ GetEditDoc().SetFixedCellHeight( bUseFixedCellHeight );
+ if ( IsFormatted() )
+ {
+ FormatFullDoc();
+ UpdateViews( GetActiveView() );
+ }
+ }
+}
+
+void ImpEditEngine::SeekCursor( ContentNode* pNode, sal_uInt16 nPos, SvxFont& rFont, OutputDevice* pOut, sal_uInt16 nIgnoreWhich )
+{
+ // Es war mal geplant, SeekCursor( nStartPos, nEndPos, ... ), damit nur
+ // ab der StartPosition neu gesucht wird.
+ // Problem: Es mussten zwei Listen beruecksichtigt/gefuehrt werden:
+ // OrderedByStart,OrderedByEnd.
+
+ if ( nPos > pNode->Len() )
+ nPos = pNode->Len();
+
+ rFont = pNode->GetCharAttribs().GetDefFont();
+
+ short nScriptType = GetScriptType( EditPaM( pNode, nPos ) );
+ if ( ( nScriptType == i18n::ScriptType::ASIAN ) || ( nScriptType == i18n::ScriptType::COMPLEX ) )
+ {
+ const SvxFontItem& rFontItem = (const SvxFontItem&)pNode->GetContentAttribs().GetItem( GetScriptItemId( EE_CHAR_FONTINFO, nScriptType ) );
+ rFont.SetName( rFontItem.GetFamilyName() );
+ rFont.SetFamily( rFontItem.GetFamily() );
+ rFont.SetPitch( rFontItem.GetPitch() );
+ rFont.SetCharSet( rFontItem.GetCharSet() );
+ Size aSz( rFont.GetSize() );
+ aSz.Height() = ((const SvxFontHeightItem&)pNode->GetContentAttribs().GetItem( GetScriptItemId( EE_CHAR_FONTHEIGHT, nScriptType ) ) ).GetHeight();
+ rFont.SetSize( aSz );
+ rFont.SetWeight( ((const SvxWeightItem&)pNode->GetContentAttribs().GetItem( GetScriptItemId( EE_CHAR_WEIGHT, nScriptType ))).GetWeight() );
+ rFont.SetItalic( ((const SvxPostureItem&)pNode->GetContentAttribs().GetItem( GetScriptItemId( EE_CHAR_ITALIC, nScriptType ))).GetPosture() );
+ rFont.SetLanguage( ((const SvxLanguageItem&)pNode->GetContentAttribs().GetItem( GetScriptItemId( EE_CHAR_LANGUAGE, nScriptType ))).GetLanguage() );
+ }
+
+ sal_uInt16 nRelWidth = ((const SvxCharScaleWidthItem&)pNode->GetContentAttribs().GetItem( EE_CHAR_FONTWIDTH)).GetValue();
+
+ if ( pOut )
+ {
+ const SvxUnderlineItem& rTextLineColor = (const SvxUnderlineItem&)pNode->GetContentAttribs().GetItem( EE_CHAR_UNDERLINE );
+ if ( rTextLineColor.GetColor() != COL_TRANSPARENT )
+ pOut->SetTextLineColor( rTextLineColor.GetColor() );
+ else
+ pOut->SetTextLineColor();
+ }
+
+ if ( pOut )
+ {
+ const SvxOverlineItem& rOverlineColor = (const SvxOverlineItem&)pNode->GetContentAttribs().GetItem( EE_CHAR_OVERLINE );
+ if ( rOverlineColor.GetColor() != COL_TRANSPARENT )
+ pOut->SetOverlineColor( rOverlineColor.GetColor() );
+ else
+ pOut->SetOverlineColor();
+ }
+
+ const SvxLanguageItem* pCJKLanguageItem = NULL;
+
+ if ( aStatus.UseCharAttribs() )
+ {
+ const CharAttribArray& rAttribs = pNode->GetCharAttribs().GetAttribs();
+ sal_uInt16 nAttr = 0;
+ EditCharAttrib* pAttrib = GetAttrib( rAttribs, nAttr );
+ while ( pAttrib && ( pAttrib->GetStart() <= nPos ) )
+ {
+ // Beim Seeken nicht die Attr beruecksichtigen, die dort beginnen!
+ // Leere Attribute werden beruecksichtigt( verwendet), da diese
+ // gerade eingestellt wurden.
+ // 12.4.95: Doch keine Leeren Attribute verwenden:
+ // - Wenn gerade eingestellt und leer => keine Auswirkung auf Font
+ // In einem leeren Absatz eingestellte Zeichen werden sofort wirksam.
+ if ( ( pAttrib->Which() != nIgnoreWhich ) &&
+ ( ( ( pAttrib->GetStart() < nPos ) && ( pAttrib->GetEnd() >= nPos ) )
+ || ( !pNode->Len() ) ) )
+ {
+ DBG_ASSERT( ( pAttrib->Which() >= EE_CHAR_START ) && ( pAttrib->Which() <= EE_FEATURE_END ), "Unglueltiges Attribut in Seek() " );
+ if ( IsScriptItemValid( pAttrib->Which(), nScriptType ) )
+ {
+ pAttrib->SetFont( rFont, pOut );
+ // #i1550# hard color attrib should win over text color from field
+ if ( pAttrib->Which() == EE_FEATURE_FIELD )
+ {
+ EditCharAttrib* pColorAttr = pNode->GetCharAttribs().FindAttrib( EE_CHAR_COLOR, nPos );
+ if ( pColorAttr )
+ pColorAttr->SetFont( rFont, pOut );
+ }
+ }
+ if ( pAttrib->Which() == EE_CHAR_FONTWIDTH )
+ nRelWidth = ((const SvxCharScaleWidthItem*)pAttrib->GetItem())->GetValue();
+ if ( pAttrib->Which() == EE_CHAR_LANGUAGE_CJK )
+ pCJKLanguageItem = (const SvxLanguageItem*) pAttrib->GetItem();
+ }
+ pAttrib = GetAttrib( rAttribs, ++nAttr );
+ }
+ }
+
+ if ( !pCJKLanguageItem )
+ pCJKLanguageItem = (const SvxLanguageItem*) &pNode->GetContentAttribs().GetItem( EE_CHAR_LANGUAGE_CJK );
+
+ rFont.SetCJKContextLanguage( pCJKLanguageItem->GetLanguage() );
+
+ if ( rFont.GetKerning() && IsKernAsianPunctuation() && ( nScriptType == i18n::ScriptType::ASIAN ) )
+ rFont.SetKerning( rFont.GetKerning() | KERNING_ASIAN );
+
+ if ( aStatus.DoNotUseColors() )
+ {
+ // Hack fuer DL,weil JOE staendig die Pooldefaults verbiegt!
+ // const SvxColorItem& rColorItem = (const SvxColorItem&)aEditDoc.GetItemPool().GetDefaultItem( EE_CHAR_COLOR );
+ rFont.SetColor( /* rColorItem.GetValue() */ COL_BLACK );
+ }
+
+ if ( aStatus.DoStretch() || ( nRelWidth != 100 ) )
+ {
+ // Fuer das aktuelle Ausgabegeraet, weil es sonst bei einem
+ // Drucker als RefDev auf dem Bildschirm #?!@' aussieht!
+ OutputDevice* pDev = pOut ? pOut : GetRefDevice();
+ rFont.SetPhysFont( pDev );
+ FontMetric aMetric( pDev->GetFontMetric() );
+ // Fuer die Hoehe nicht die Metriken nehmen, da das bei
+ // Hoch-/Tiefgestellt schief geht.
+ Size aRealSz( aMetric.GetSize().Width(), rFont.GetSize().Height() );
+ if ( aStatus.DoStretch() )
+ {
+ if ( nStretchY != 100 )
+ {
+ aRealSz.Height() *= nStretchY;
+ aRealSz.Height() /= 100;
+ }
+ if ( nStretchX != 100 )
+ {
+ aRealSz.Width() *= nStretchX;
+ aRealSz.Width() /= 100;
+
+ // Auch das Kerning: (long wegen Zwischenergebnis)
+ long nKerning = rFont.GetFixKerning();
+/*
+ Die Ueberlegung war: Wenn neg. Kerning, aber StretchX = 200
+ => Nicht das Kerning verdoppelt, also die Buchstaben weiter
+ zusammenziehen
+ ---------------------------
+ Kern StretchX =>Kern
+ ---------------------------
+ >0 <100 < (Proportional)
+ <0 <100 < (Proportional)
+ >0 >100 > (Proportional)
+ <0 >100 < (Der Betrag, also Antiprop)
+*/
+ if ( ( nKerning < 0 ) && ( nStretchX > 100 ) )
+ {
+ // Antiproportional
+ nKerning *= 100;
+ nKerning /= nStretchX;
+ }
+ else if ( nKerning )
+ {
+ // Proportional
+ nKerning *= nStretchX;
+ nKerning /= 100;
+ }
+ rFont.SetFixKerning( (short)nKerning );
+ }
+ }
+ if ( nRelWidth != 100 )
+ {
+ aRealSz.Width() *= nRelWidth;
+ aRealSz.Width() /= 100;
+ }
+ rFont.SetSize( aRealSz );
+ // Font wird nicht restauriert...
+ }
+
+ if ( ( ( rFont.GetColor() == COL_AUTO ) || ( IsForceAutoColor() ) ) && pOut )
+ {
+ // #i75566# Do not use AutoColor when printing OR Pdf export
+ const bool bPrinting(OUTDEV_PRINTER == pOut->GetOutDevType());
+ const bool bPDFExporting(0 != pOut->GetPDFWriter());
+
+ if ( IsAutoColorEnabled() && !bPrinting && !bPDFExporting)
+ {
+ // Never use WindowTextColor on the printer
+ rFont.SetColor( GetAutoColor() );
+ }
+ else
+ {
+ if ( ( GetBackgroundColor() != COL_AUTO ) && GetBackgroundColor().IsDark() )
+ rFont.SetColor( COL_WHITE );
+ else
+ rFont.SetColor( COL_BLACK );
+ }
+ }
+
+ if ( mpIMEInfos && mpIMEInfos->pAttribs && ( mpIMEInfos->aPos.GetNode() == pNode ) &&
+ ( nPos > mpIMEInfos->aPos.GetIndex() ) && ( nPos <= ( mpIMEInfos->aPos.GetIndex() + mpIMEInfos->nLen ) ) )
+ {
+ sal_uInt16 nAttr = mpIMEInfos->pAttribs[ nPos - mpIMEInfos->aPos.GetIndex() - 1 ];
+ if ( nAttr & EXTTEXTINPUT_ATTR_UNDERLINE )
+ rFont.SetUnderline( UNDERLINE_SINGLE );
+ else if ( nAttr & EXTTEXTINPUT_ATTR_BOLDUNDERLINE )
+ rFont.SetUnderline( UNDERLINE_BOLD );
+ else if ( nAttr & EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE )
+ rFont.SetUnderline( UNDERLINE_DOTTED );
+ else if ( nAttr & EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE )
+ rFont.SetUnderline( UNDERLINE_DOTTED );
+ else if ( nAttr & EXTTEXTINPUT_ATTR_REDTEXT )
+ rFont.SetColor( Color( COL_RED ) );
+ else if ( nAttr & EXTTEXTINPUT_ATTR_HALFTONETEXT )
+ rFont.SetColor( Color( COL_LIGHTGRAY ) );
+ if ( nAttr & EXTTEXTINPUT_ATTR_HIGHLIGHT )
+ {
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ rFont.SetColor( rStyleSettings.GetHighlightTextColor() );
+ rFont.SetFillColor( rStyleSettings.GetHighlightColor() );
+ rFont.SetTransparent( FALSE );
+ }
+ else if ( nAttr & EXTTEXTINPUT_ATTR_GRAYWAVELINE )
+ {
+ rFont.SetUnderline( UNDERLINE_WAVE );
+ if( pOut )
+ pOut->SetTextLineColor( Color( COL_LIGHTGRAY ) );
+ }
+ }
+}
+
+void ImpEditEngine::RecalcFormatterFontMetrics( FormatterFontMetric& rCurMetrics, SvxFont& rFont )
+{
+ // Fuer Zeilenhoehe bei Hoch/Tief erstmal ohne Propr!
+ sal_uInt16 nPropr = rFont.GetPropr();
+ DBG_ASSERT( ( nPropr == 100 ) || rFont.GetEscapement(), "Propr ohne Escape?!" );
+ if ( nPropr != 100 )
+ {
+ rFont.SetPropr( 100 );
+ rFont.SetPhysFont( pRefDev );
+ }
+ sal_uInt16 nAscent, nDescent;
+
+ FontMetric aMetric( pRefDev->GetFontMetric() );
+ nAscent = (sal_uInt16)aMetric.GetAscent();
+ if ( IsAddExtLeading() )
+ nAscent = sal::static_int_cast< sal_uInt16 >(
+ nAscent + aMetric.GetExtLeading() );
+ nDescent = (sal_uInt16)aMetric.GetDescent();
+
+ if ( IsFixedCellHeight() )
+ {
+/* creating correct proportional ascent and descent values lead to problems if different fonts are used
+ in the same portion, it results in a bigger linespacing.
+ sal_Int32 f = nAscent + nDescent;
+ if ( f )
+ {
+ sal_Int32 nHeight = ImplCalculateFontIndependentLineSpacing( rFont.GetHeight() );
+ nAscent = (sal_Int16)(( nHeight * nAscent ) / f );
+ nDescent = (sal_Int16)(nHeight - nAscent);
+ }
+*/
+ nAscent = sal::static_int_cast< sal_uInt16 >( rFont.GetHeight() );
+ nDescent= sal::static_int_cast< sal_uInt16 >( ImplCalculateFontIndependentLineSpacing( rFont.GetHeight() ) - nAscent );
+ }
+ else
+ {
+ sal_uInt16 nIntLeading = ( aMetric.GetIntLeading() > 0 ) ? (sal_uInt16)aMetric.GetIntLeading() : 0;
+ // Fonts ohne Leading bereiten Probleme
+ if ( ( nIntLeading == 0 ) && ( pRefDev->GetOutDevType() == OUTDEV_PRINTER ) )
+ {
+ // Da schaun wir mal, was fuer eine Leading ich auf dem
+ // Bildschirm erhalte
+ VirtualDevice* pVDev = GetVirtualDevice( pRefDev->GetMapMode(), pRefDev->GetDrawMode() );
+ rFont.SetPhysFont( pVDev );
+ aMetric = pVDev->GetFontMetric();
+
+ // Damit sich die Leading nicht wieder rausrechnet,
+ // wenn die ganze Zeile den Font hat, nTmpLeading.
+
+ // 4/96: Kommt bei HP Laserjet 4V auch nicht hin
+ // => Werte komplett vom Bildschirm holen.
+ // sal_uInt16 nTmpLeading = (sal_uInt16)aMetric.GetLeading();
+ // nAscent += nTmpLeading;
+ nAscent = (sal_uInt16)aMetric.GetAscent();
+ nDescent = (sal_uInt16)aMetric.GetDescent();
+ // nLeading = (sal_uInt16)aMetric.GetLeading();
+ }
+ }
+ if ( nAscent > rCurMetrics.nMaxAscent )
+ rCurMetrics.nMaxAscent = nAscent;
+ if ( nDescent > rCurMetrics.nMaxDescent )
+ rCurMetrics.nMaxDescent= nDescent;
+ // Sonderbehandlung Hoch/Tief:
+ if ( rFont.GetEscapement() )
+ {
+ // Jetzt unter Beruecksichtigung von Escape/Propr
+ // Ascent oder Descent ggf vergroessern
+ short nDiff = (short)(rFont.GetSize().Height()*rFont.GetEscapement()/100L);
+ if ( rFont.GetEscapement() > 0 )
+ {
+ nAscent = (sal_uInt16) (((long)nAscent)*nPropr/100 + nDiff);
+ if ( nAscent > rCurMetrics.nMaxAscent )
+ rCurMetrics.nMaxAscent = nAscent;
+ }
+ else // muss < 0 sein
+ {
+ nDescent = (sal_uInt16) (((long)nDescent)*nPropr/100 - nDiff);
+ if ( nDescent > rCurMetrics.nMaxDescent )
+ rCurMetrics.nMaxDescent= nDescent;
+ }
+ }
+}
+
+void ImpEditEngine::Paint( OutputDevice* pOutDev, Rectangle aClipRec, Point aStartPos, sal_Bool bStripOnly, short nOrientation )
+{
+ if ( !GetUpdateMode() && !bStripOnly )
+ return;
+
+ if ( !IsFormatted() )
+ FormatDoc();
+
+ long nFirstVisXPos = - pOutDev->GetMapMode().GetOrigin().X();
+ long nFirstVisYPos = - pOutDev->GetMapMode().GetOrigin().Y();
+
+ EditLine* pLine;
+ Point aTmpPos;
+ Point aRedLineTmpPos;
+ DBG_ASSERT( GetParaPortions().Count(), "Keine ParaPortion?!" );
+ SvxFont aTmpFont( GetParaPortions()[0]->GetNode()->GetCharAttribs().GetDefFont() );
+ Font aOldFont( pOutDev->GetFont() );
+ vcl::PDFExtOutDevData* pPDFExtOutDevData = PTR_CAST( vcl::PDFExtOutDevData, pOutDev->GetExtOutDevData() );
+
+ // Bei gedrehtem Text wird aStartPos als TopLeft angesehen, da andere
+ // Informationen fehlen, und sowieso das ganze Object ungescrollt
+ // dargestellt wird.
+ // Das Rechteck ist unendlich gross.
+ Point aOrigin( aStartPos );
+ double nCos = 0.0, nSin = 0.0;
+ if ( nOrientation )
+ {
+ double nRealOrientation = nOrientation*F_PI1800;
+ nCos = cos( nRealOrientation );
+ nSin = sin( nRealOrientation );
+ }
+
+ // #110496# Added some more optional metafile comments. This
+ // change: factored out some duplicated code.
+ GDIMetaFile* pMtf = pOutDev->GetConnectMetaFile();
+ const bool bMetafileValid( pMtf != NULL );
+
+ // Fuer OnlineSpelling:
+// EditPaM aCursorPos;
+// if( GetStatus().DoOnlineSpelling() && pActiveView )
+// aCurPos = pActiveView->pImpEditView->GetEditSelections().Max();
+
+ // --------------------------------------------------
+ // Ueber alle Absaetze...
+ // --------------------------------------------------
+ for ( sal_uInt16 n = 0; n < GetParaPortions().Count(); n++ )
+ {
+ ParaPortion* pPortion = GetParaPortions().GetObject( n );
+ DBG_ASSERT( pPortion, "NULL-Pointer in TokenList in Paint" );
+ // falls beim Tippen Idle-Formatierung, asynchrones Paint.
+ // Unsichtbare Portions koennen ungueltig sein.
+ if ( pPortion->IsVisible() && pPortion->IsInvalid() )
+ return;
+
+ if ( pPDFExtOutDevData )
+ pPDFExtOutDevData->BeginStructureElement( vcl::PDFWriter::Paragraph );
+
+ long nParaHeight = pPortion->GetHeight();
+ sal_uInt16 nIndex = 0;
+ if ( pPortion->IsVisible() && (
+ ( !IsVertical() && ( ( aStartPos.Y() + nParaHeight ) > aClipRec.Top() ) ) ||
+ ( IsVertical() && ( ( aStartPos.X() - nParaHeight ) < aClipRec.Right() ) ) ) )
+
+ {
+ // --------------------------------------------------
+ // Ueber die Zeilen des Absatzes...
+ // --------------------------------------------------
+ sal_uInt16 nLines = pPortion->GetLines().Count();
+ sal_uInt16 nLastLine = nLines-1;
+
+ if ( !IsVertical() )
+ aStartPos.Y() += pPortion->GetFirstLineOffset();
+ else
+ aStartPos.X() -= pPortion->GetFirstLineOffset();
+
+ Point aParaStart( aStartPos );
+
+ const SvxLineSpacingItem& rLSItem = ((const SvxLineSpacingItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL ));
+ sal_uInt16 nSBL = ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX )
+ ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
+ for ( sal_uInt16 nLine = 0; nLine < nLines; nLine++ )
+ {
+ pLine = pPortion->GetLines().GetObject(nLine);
+ DBG_ASSERT( pLine, "NULL-Pointer im Zeileniterator in UpdateViews" );
+ aTmpPos = aStartPos;
+ if ( !IsVertical() )
+ {
+ aTmpPos.X() += pLine->GetStartPosX();
+ aTmpPos.Y() += pLine->GetMaxAscent();
+ aStartPos.Y() += pLine->GetHeight();
+ }
+ else
+ {
+ aTmpPos.Y() += pLine->GetStartPosX();
+ aTmpPos.X() -= pLine->GetMaxAscent();
+ aStartPos.X() -= pLine->GetHeight();
+ }
+
+ if ( ( !IsVertical() && ( aStartPos.Y() > aClipRec.Top() ) )
+ || ( IsVertical() && aStartPos.X() < aClipRec.Right() ) )
+ {
+ // Why not just also call when stripping portions? This will give the correct values
+ // and needs no position corrections in OutlinerEditEng::DrawingText which tries to call
+ // PaintBullet correctly; exactly what GetEditEnginePtr()->PaintingFirstLine
+ // does, too. No change for not-layouting (painting).
+ if(0 == nLine) // && !bStripOnly)
+ {
+ // VERT???
+ GetEditEnginePtr()->PaintingFirstLine( n, aParaStart, aTmpPos.Y(), aOrigin, nOrientation, pOutDev );
+ }
+
+ // --------------------------------------------------
+ // Ueber die Portions der Zeile...
+ // --------------------------------------------------
+ nIndex = pLine->GetStart();
+ for ( sal_uInt16 y = pLine->GetStartPortion(); y <= pLine->GetEndPortion(); y++ )
+ {
+ DBG_ASSERT( pPortion->GetTextPortions().Count(), "Zeile ohne Textportion im Paint!" );
+ TextPortion* pTextPortion = pPortion->GetTextPortions().GetObject( y );
+ DBG_ASSERT( pTextPortion, "NULL-Pointer im Portioniterator in UpdateViews" );
+
+ long nPortionXOffset = GetPortionXOffset( pPortion, pLine, y );
+ if ( !IsVertical() )
+ {
+ aTmpPos.X() = aStartPos.X() + nPortionXOffset;
+ if ( aTmpPos.X() > aClipRec.Right() )
+ break; // Keine weitere Ausgabe in Zeile noetig
+ }
+ else
+ {
+ aTmpPos.Y() = aStartPos.Y() + nPortionXOffset;
+ if ( aTmpPos.Y() > aClipRec.Bottom() )
+ break; // Keine weitere Ausgabe in Zeile noetig
+ }
+
+ // R2L replaces with obove...
+ // New position after processing R2L text...
+// R2L if ( nR2LWidth && !pTextPortion->GetRightToLeft() )
+// R2L {
+// R2L if ( !IsVertical() )
+// R2L aTmpPos.X() += nR2LWidth;
+// R2L else
+// R2L aTmpPos.Y() += nR2LWidth;
+// R2L
+// R2L nR2LWidth = 0;
+// R2L }
+
+ switch ( pTextPortion->GetKind() )
+ {
+ case PORTIONKIND_TEXT:
+ case PORTIONKIND_FIELD:
+ case PORTIONKIND_HYPHENATOR:
+ {
+ SeekCursor( pPortion->GetNode(), nIndex+1, aTmpFont, pOutDev );
+
+ BOOL bDrawFrame = FALSE;
+
+ if ( ( pTextPortion->GetKind() == PORTIONKIND_FIELD ) && !aTmpFont.IsTransparent() &&
+ ( GetBackgroundColor() != COL_AUTO ) && GetBackgroundColor().IsDark() &&
+ ( IsAutoColorEnabled() && ( pOutDev->GetOutDevType() != OUTDEV_PRINTER ) ) )
+ {
+ aTmpFont.SetTransparent( TRUE );
+ pOutDev->SetFillColor();
+ pOutDev->SetLineColor( GetAutoColor() );
+ bDrawFrame = TRUE;
+ }
+
+#ifdef EDITDEBUG
+ if ( pTextPortion->GetKind() == PORTIONKIND_HYPHENATOR )
+ {
+ aTmpFont.SetFillColor( COL_LIGHTGRAY );
+ aTmpFont.SetTransparent( sal_False );
+ }
+ if ( pTextPortion->GetRightToLeft() )
+ {
+ aTmpFont.SetFillColor( COL_LIGHTGRAY );
+ aTmpFont.SetTransparent( sal_False );
+ }
+ else if ( GetScriptType( EditPaM( pPortion->GetNode(), nIndex+1 ) ) == i18n::ScriptType::COMPLEX )
+ {
+ aTmpFont.SetFillColor( COL_LIGHTCYAN );
+ aTmpFont.SetTransparent( sal_False );
+ }
+#endif
+ aTmpFont.SetPhysFont( pOutDev );
+
+ // #114278# Saving both layout mode and language (since I'm
+ // potentially changing both)
+ pOutDev->Push( PUSH_TEXTLAYOUTMODE|PUSH_TEXTLANGUAGE );
+ ImplInitLayoutMode( pOutDev, n, nIndex );
+ ImplInitDigitMode( pOutDev, 0, 0, 0, aTmpFont.GetLanguage() );
+
+ XubString aText;
+ USHORT nTextStart = 0;
+ USHORT nTextLen = 0;
+ const sal_Int32* pDXArray = 0;
+ sal_Int32* pTmpDXArray = 0;
+
+ if ( pTextPortion->GetKind() == PORTIONKIND_TEXT )
+ {
+ aText = *pPortion->GetNode();
+ nTextStart = nIndex;
+ nTextLen = pTextPortion->GetLen();
+ pDXArray = pLine->GetCharPosArray().GetData()+( nIndex-pLine->GetStart() );
+
+ // --> FME 2005-10-18 #i55716# Paint control characters
+ if ( aStatus.MarkFields() )
+ {
+ xub_StrLen nTmpIdx;
+ const xub_StrLen nTmpEnd = nTextStart + pTextPortion->GetLen();
+
+ for ( nTmpIdx = nTextStart; nTmpIdx <= nTmpEnd ; ++nTmpIdx )
+ {
+ const sal_Unicode cChar = ( nTmpIdx != aText.Len() && ( nTmpIdx != nTextStart || 0 == nTextStart ) ) ?
+ aText.GetChar( nTmpIdx ) :
+ 0;
+
+ if ( 0x200B == cChar || 0x2060 == cChar )
+ {
+ const String aBlank( ' ' );
+ long nHalfBlankWidth = aTmpFont.QuickGetTextSize( pOutDev, aBlank, 0, 1, 0 ).Width() / 2;
+
+ const long nAdvanceX = ( nTmpIdx == nTmpEnd ?
+ pTextPortion->GetSize().Width() :
+ pDXArray[ nTmpIdx - nTextStart ] ) - nHalfBlankWidth;
+ const long nAdvanceY = -pLine->GetMaxAscent();
+
+ Point aTopLeftRectPos( aTmpPos );
+ if ( !IsVertical() )
+ {
+ aTopLeftRectPos.X() += nAdvanceX;
+ aTopLeftRectPos.Y() += nAdvanceY;
+ }
+ else
+ {
+ aTopLeftRectPos.Y() += nAdvanceX;
+ aTopLeftRectPos.X() -= nAdvanceY;
+ }
+
+ Point aBottomRightRectPos( aTopLeftRectPos );
+ if ( !IsVertical() )
+ {
+ aBottomRightRectPos.X() += 2 * nHalfBlankWidth;
+ aBottomRightRectPos.Y() += pLine->GetHeight();
+ }
+ else
+ {
+ aBottomRightRectPos.X() -= pLine->GetHeight();
+ aBottomRightRectPos.Y() += 2 * nHalfBlankWidth;
+ }
+
+ pOutDev->Push( PUSH_FILLCOLOR );
+ pOutDev->Push( PUSH_LINECOLOR );
+ pOutDev->SetFillColor( COL_LIGHTGRAY );
+ pOutDev->SetLineColor( COL_LIGHTGRAY );
+
+ const Rectangle aBackRect( aTopLeftRectPos, aBottomRightRectPos );
+ pOutDev->DrawRect( aBackRect );
+
+ pOutDev->Pop();
+ pOutDev->Pop();
+
+ if ( 0x200B == cChar )
+ {
+ const String aSlash( '/' );
+ const short nOldEscapement = aTmpFont.GetEscapement();
+ const BYTE nOldPropr = aTmpFont.GetPropr();
+
+ aTmpFont.SetEscapement( -20 );
+ aTmpFont.SetPropr( 25 );
+ aTmpFont.SetPhysFont( pOutDev );
+
+ const Size aSlashSize = aTmpFont.QuickGetTextSize( pOutDev, aSlash, 0, 1, 0 );
+ Point aSlashPos( aTmpPos );
+ const long nAddX = nHalfBlankWidth - aSlashSize.Width() / 2;
+ if ( !IsVertical() )
+ {
+ aSlashPos.X() = aTopLeftRectPos.X() + nAddX;
+ }
+ else
+ {
+ aSlashPos.Y() = aTopLeftRectPos.Y() + nAddX;
+ }
+
+ aTmpFont.QuickDrawText( pOutDev, aSlashPos, aSlash, 0, 1, 0 );
+
+ aTmpFont.SetEscapement( nOldEscapement );
+ aTmpFont.SetPropr( nOldPropr );
+ aTmpFont.SetPhysFont( pOutDev );
+ }
+ }
+ }
+ }
+ // <--
+ }
+ else if ( pTextPortion->GetKind() == PORTIONKIND_FIELD )
+ {
+ EditCharAttrib* pAttr = pPortion->GetNode()->GetCharAttribs().FindFeature( nIndex );
+ DBG_ASSERT( pAttr, "Feld nicht gefunden" );
+ DBG_ASSERT( pAttr && pAttr->GetItem()->ISA( SvxFieldItem ), "Feld vom falschen Typ!" );
+ aText = ((EditCharAttribField*)pAttr)->GetFieldValue();
+ nTextStart = 0;
+ nTextLen = aText.Len();
+
+ pTmpDXArray = new sal_Int32[ aText.Len() ];
+ pDXArray = pTmpDXArray;
+ Font _aOldFont( GetRefDevice()->GetFont() );
+ aTmpFont.SetPhysFont( GetRefDevice() );
+ aTmpFont.QuickGetTextSize( GetRefDevice(), aText, 0, aText.Len(), pTmpDXArray );
+ if ( aStatus.DoRestoreFont() )
+ GetRefDevice()->SetFont( _aOldFont );
+
+ // add a meta file comment if we record to a metafile
+ if( bMetafileValid )
+ {
+ SvxFieldItem* pFieldItem = PTR_CAST( SvxFieldItem, pAttr->GetItem() );
+ if( pFieldItem )
+ {
+ const SvxFieldData* pFieldData = pFieldItem->GetField();
+ if( pFieldData )
+ pMtf->AddAction( pFieldData->createBeginComment() );
+ }
+ }
+
+ }
+ else if ( pTextPortion->GetKind() == PORTIONKIND_HYPHENATOR )
+ {
+ if ( pTextPortion->GetExtraValue() )
+ aText = pTextPortion->GetExtraValue();
+ aText += CH_HYPH;
+ nTextStart = 0;
+ nTextLen = aText.Len();
+
+ // #b6668980# crash when accessing 0 pointer in pDXArray
+ pTmpDXArray = new sal_Int32[ aText.Len() ];
+ pDXArray = pTmpDXArray;
+ Font _aOldFont( GetRefDevice()->GetFont() );
+ aTmpFont.SetPhysFont( GetRefDevice() );
+ aTmpFont.QuickGetTextSize( GetRefDevice(), aText, 0, aText.Len(), pTmpDXArray );
+ if ( aStatus.DoRestoreFont() )
+ GetRefDevice()->SetFont( _aOldFont );
+ }
+
+ long nTxtWidth = pTextPortion->GetSize().Width();
+
+ Point aOutPos( aTmpPos );
+ aRedLineTmpPos = aTmpPos;
+ // In RTL portions spell markup pos should be at the start of the
+ // first chara as well. That is on the right end of the portion
+ if (pTextPortion->IsRightToLeft())
+ aRedLineTmpPos.X() += pTextPortion->GetSize().Width();
+
+//L2R if ( pTextPortion->GetRightToLeft() )
+//L2R {
+//L2R sal_uInt16 nNextPortion = y+1;
+//L2R while ( nNextPortion <= pLine->GetEndPortion() )
+//L2R {
+//L2R TextPortion* pNextTextPortion = pPortion->GetTextPortions().GetObject( nNextPortion );
+//L2R if ( pNextTextPortion->GetRightToLeft() )
+//L2R {
+//L2R if ( !IsVertical() )
+//L2R aOutPos.X() += pNextTextPortion->GetSize().Width();
+//L2R else
+//L2R aOutPos.Y() += pNextTextPortion->GetSize().Width();
+//L2R }
+//L2R else
+//L2R break;
+//L2R nNextPortion++;
+//L2R }
+//L2R }
+ if ( bStripOnly )
+ {
+ EEngineData::WrongSpellVector aWrongSpellVector;
+
+ if(GetStatus().DoOnlineSpelling() && pTextPortion->GetLen())
+ {
+ WrongList* pWrongs = pPortion->GetNode()->GetWrongList();
+
+ if(pWrongs && pWrongs->HasWrongs())
+ {
+ sal_uInt16 nStart(nIndex);
+ sal_uInt16 nEnd(0);
+ sal_Bool bWrong(pWrongs->NextWrong(nStart, nEnd));
+ const sal_uInt16 nMaxEnd(nIndex + pTextPortion->GetLen());
+
+ while(bWrong)
+ {
+ if(nStart >= nMaxEnd)
+ {
+ break;
+ }
+
+ if(nStart < nIndex)
+ {
+ nStart = nIndex;
+ }
+
+ if(nEnd > nMaxEnd)
+ {
+ nEnd = nMaxEnd;
+ }
+
+ // add to vector
+ aWrongSpellVector.push_back(EEngineData::WrongSpellClass(nStart, nEnd));
+
+ // goto next index
+ nStart = nEnd + 1;
+
+ if(nEnd < nMaxEnd)
+ {
+ bWrong = pWrongs->NextWrong(nStart, nEnd);
+ }
+ else
+ {
+ bWrong = sal_False;
+ }
+ }
+ }
+ }
+
+ const SvxFieldData* pFieldData = 0;
+
+ if(PORTIONKIND_FIELD == pTextPortion->GetKind())
+ {
+ EditCharAttrib* pAttr = pPortion->GetNode()->GetCharAttribs().FindFeature(nIndex);
+ SvxFieldItem* pFieldItem = PTR_CAST(SvxFieldItem, pAttr->GetItem());
+
+ if(pFieldItem)
+ {
+ pFieldData = pFieldItem->GetField();
+ }
+ }
+
+ // support for EOC, EOW, EOS TEXT comments. To support that,
+ // the locale is needed. With the locale and a XBreakIterator it is
+ // possible to re-create the text marking info on primitive level
+ const lang::Locale aLocale(GetLocale(EditPaM(pPortion->GetNode(), nIndex + 1)));
+
+ // create EOL and EOP bools
+ const bool bEndOfLine(y == pLine->GetEndPortion());
+ const bool bEndOfParagraph(bEndOfLine && nLine + 1 == nLines);
+
+ // get Overline color (from ((const SvxOverlineItem*)GetItem())->GetColor() in
+ // consequence, but also already set at pOutDev)
+ const Color aOverlineColor(pOutDev->GetOverlineColor());
+
+ // get TextLine color (from ((const SvxUnderlineItem*)GetItem())->GetColor() in
+ // consequence, but also already set at pOutDev)
+ const Color aTextLineColor(pOutDev->GetTextLineColor());
+
+ // Unicode code points conversion according to ctl text numeral setting
+ ImplInitDigitMode( 0, &aText, nTextStart, nTextLen, aTmpFont.GetLanguage() );
+
+ // StripPortions() data callback
+ GetEditEnginePtr()->DrawingText( aOutPos, aText, nTextStart, nTextLen, pDXArray,
+ aTmpFont, n, nIndex, pTextPortion->GetRightToLeft(),
+ aWrongSpellVector.size() ? &aWrongSpellVector : 0,
+ pFieldData,
+ bEndOfLine, bEndOfParagraph, false, // support for EOL/EOP TEXT comments
+ &aLocale,
+ aOverlineColor,
+ aTextLineColor);
+ }
+ else
+ {
+ short nEsc = aTmpFont.GetEscapement();
+ if ( nOrientation )
+ {
+ // Bei Hoch/Tief selbst Hand anlegen:
+ if ( aTmpFont.GetEscapement() )
+ {
+ long nDiff = aTmpFont.GetSize().Height() * aTmpFont.GetEscapement() / 100L;
+ if ( !IsVertical() )
+ aOutPos.Y() -= nDiff;
+ else
+ aOutPos.X() += nDiff;
+ aRedLineTmpPos = aOutPos;
+ aTmpFont.SetEscapement( 0 );
+ }
+
+ aOutPos = lcl_ImplCalcRotatedPos( aOutPos, aOrigin, nSin, nCos );
+ aTmpFont.SetOrientation( aTmpFont.GetOrientation()+nOrientation );
+ aTmpFont.SetPhysFont( pOutDev );
+
+ }
+ // nur ausgeben, was im sichtbaren Bereich beginnt:
+ // Wichtig, weil Bug bei einigen Grafikkarten bei transparentem Font, Ausgabe bei neg.
+ if ( nOrientation || ( !IsVertical() && ( ( aTmpPos.X() + nTxtWidth ) >= nFirstVisXPos ) )
+ || ( IsVertical() && ( ( aTmpPos.Y() + nTxtWidth ) >= nFirstVisYPos ) ) )
+ {
+ if ( nEsc && ( ( aTmpFont.GetUnderline() != UNDERLINE_NONE ) ) )
+ {
+ // Das Hoch/Tief ohne Underline malen, das Underline
+ // auf der BaseLine der Original-Fonthoehe ausgeben...
+
+ // Aber nur, wenn davor auch Unterstrichen!
+ sal_Bool bSpecialUnderline = sal_False;
+ EditCharAttrib* pPrev = pPortion->GetNode()->GetCharAttribs().FindAttrib( EE_CHAR_ESCAPEMENT, nIndex );
+ if ( pPrev )
+ {
+ SvxFont aDummy;
+ // Unterstreichung davor?
+ if ( pPrev->GetStart() )
+ {
+ SeekCursor( pPortion->GetNode(), pPrev->GetStart(), aDummy );
+ if ( aDummy.GetUnderline() != UNDERLINE_NONE )
+ bSpecialUnderline = sal_True;
+ }
+ if ( !bSpecialUnderline && ( pPrev->GetEnd() < pPortion->GetNode()->Len() ) )
+ {
+ SeekCursor( pPortion->GetNode(), pPrev->GetEnd()+1, aDummy );
+ if ( aDummy.GetUnderline() != UNDERLINE_NONE )
+ bSpecialUnderline = sal_True;
+ }
+ }
+ if ( bSpecialUnderline )
+ {
+ Size aSz = aTmpFont.GetPhysTxtSize( pOutDev, aText, nTextStart, nTextLen );
+ BYTE nProp = aTmpFont.GetPropr();
+ aTmpFont.SetEscapement( 0 );
+ aTmpFont.SetPropr( 100 );
+ aTmpFont.SetPhysFont( pOutDev );
+ String aBlanks;
+ aBlanks.Fill( nTextLen, ' ' );
+ Point aUnderlinePos( aOutPos );
+ if ( nOrientation )
+ aUnderlinePos = lcl_ImplCalcRotatedPos( aTmpPos, aOrigin, nSin, nCos );
+ pOutDev->DrawStretchText( aUnderlinePos, aSz.Width(), aBlanks, 0, nTextLen );
+
+ aTmpFont.SetUnderline( UNDERLINE_NONE );
+ if ( !nOrientation )
+ aTmpFont.SetEscapement( nEsc );
+ aTmpFont.SetPropr( nProp );
+ aTmpFont.SetPhysFont( pOutDev );
+ }
+ }
+ Point aRealOutPos( aOutPos );
+ if ( ( pTextPortion->GetKind() == PORTIONKIND_TEXT )
+ && pTextPortion->GetExtraInfos() && pTextPortion->GetExtraInfos()->bCompressed
+ && pTextPortion->GetExtraInfos()->bFirstCharIsRightPunktuation )
+ {
+ aRealOutPos.X() += pTextPortion->GetExtraInfos()->nPortionOffsetX;
+ }
+
+ // --> FME 2005-06-17 #i37132# RTL portions with
+ // compressed blank should not paint this blank:
+ if ( pTextPortion->IsRightToLeft() && nTextLen >= 2 &&
+ pDXArray[ nTextLen - 1 ] ==
+ pDXArray[ nTextLen - 2 ] &&
+ ' ' == aText.GetChar( nTextStart + nTextLen - 1 ) )
+ --nTextLen;
+ // <--
+
+ // output directly
+ aTmpFont.QuickDrawText( pOutDev, aRealOutPos, aText, nTextStart, nTextLen, pDXArray );
+
+ if ( bDrawFrame )
+ {
+ Point aTopLeft( aTmpPos );
+ aTopLeft.Y() -= pLine->GetMaxAscent();
+ if ( nOrientation )
+ aTopLeft = lcl_ImplCalcRotatedPos( aTopLeft, aOrigin, nSin, nCos );
+ Rectangle aRect( aTopLeft, pTextPortion->GetSize() );
+ pOutDev->DrawRect( aRect );
+ }
+
+
+ // PDF export:
+ if ( pPDFExtOutDevData )
+ {
+ if ( pTextPortion->GetKind() == PORTIONKIND_FIELD )
+ {
+ EditCharAttrib* pAttr = pPortion->GetNode()->GetCharAttribs().FindFeature( nIndex );
+ SvxFieldItem* pFieldItem = PTR_CAST( SvxFieldItem, pAttr->GetItem() );
+ if( pFieldItem )
+ {
+ const SvxFieldData* pFieldData = pFieldItem->GetField();
+ if ( pFieldData->ISA( SvxURLField ) )
+ {
+ Point aTopLeft( aTmpPos );
+ aTopLeft.Y() -= pLine->GetMaxAscent();
+// if ( nOrientation )
+// aTopLeft = lcl_ImplCalcRotatedPos( aTopLeft, aOrigin, nSin, nCos );
+
+ Rectangle aRect( aTopLeft, pTextPortion->GetSize() );
+ vcl::PDFExtOutDevBookmarkEntry aBookmark;
+ aBookmark.nLinkId = pPDFExtOutDevData->CreateLink( aRect );
+ aBookmark.aBookmark = ((SvxURLField*)pFieldData)->GetURL();
+ std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFExtOutDevData->GetBookmarks();
+ rBookmarks.push_back( aBookmark );
+ }
+ }
+ }
+ }
+
+ // comment
+
+
+
+
+ }
+
+#ifndef SVX_LIGHT
+ if ( GetStatus().DoOnlineSpelling() && pPortion->GetNode()->GetWrongList()->HasWrongs() && pTextPortion->GetLen() )
+ {
+ {//#105750# adjust LinePos for superscript or subscript text
+ short _nEsc = aTmpFont.GetEscapement();
+ if( _nEsc )
+ {
+ long nShift = ((_nEsc*long(aTmpFont.GetSize().Height()))/ 100L);
+ if( !IsVertical() )
+ aRedLineTmpPos.Y() -= nShift;
+ else
+ aRedLineTmpPos.X() += nShift;
+ }
+ }
+ Color aOldColor( pOutDev->GetLineColor() );
+ pOutDev->SetLineColor( Color( GetColorConfig().GetColorValue( svtools::SPELL ).nColor ) );
+ lcl_DrawRedLines( pOutDev, aTmpFont.GetSize().Height(), aRedLineTmpPos, nIndex, nIndex + pTextPortion->GetLen(), pDXArray, pPortion->GetNode()->GetWrongList(), nOrientation, aOrigin, IsVertical(), pTextPortion->IsRightToLeft() );
+ pOutDev->SetLineColor( aOldColor );
+ }
+#endif // !SVX_LIGHT
+ }
+
+ pOutDev->Pop();
+
+ if ( pTmpDXArray )
+ delete[] pTmpDXArray;
+
+// R2L if ( !pTextPortion->GetRightToLeft() )
+// R2L {
+// R2L if ( !IsVertical() )
+// R2L aTmpPos.X() += nTxtWidth;
+// R2L else
+// R2L aTmpPos.Y() += nTxtWidth;
+// R2L }
+// R2L else
+// R2L {
+// R2L nR2LWidth += nTxtWidth;
+// R2L }
+
+ if ( pTextPortion->GetKind() == PORTIONKIND_FIELD )
+ {
+ EditCharAttrib* pAttr = pPortion->GetNode()->GetCharAttribs().FindFeature( nIndex );
+ DBG_ASSERT( pAttr, "Feld nicht gefunden" );
+ DBG_ASSERT( pAttr && pAttr->GetItem()->ISA( SvxFieldItem ), "Feld vom falschen Typ!" );
+
+ // add a meta file comment if we record to a metafile
+ if( bMetafileValid )
+ {
+ SvxFieldItem* pFieldItem = PTR_CAST( SvxFieldItem, pAttr->GetItem() );
+
+ if( pFieldItem )
+ {
+ const SvxFieldData* pFieldData = pFieldItem->GetField();
+ if( pFieldData )
+ pMtf->AddAction( pFieldData->createEndComment() );
+ }
+ }
+
+ }
+
+ }
+ break;
+// case PORTIONKIND_EXTRASPACE:
+ case PORTIONKIND_TAB:
+ {
+ if ( pTextPortion->GetExtraValue() && ( pTextPortion->GetExtraValue() != ' ' ) )
+ {
+ SeekCursor( pPortion->GetNode(), nIndex+1, aTmpFont, pOutDev );
+ aTmpFont.SetTransparent( sal_False );
+ aTmpFont.SetEscapement( 0 );
+ aTmpFont.SetPhysFont( pOutDev );
+ long nCharWidth = aTmpFont.QuickGetTextSize( pOutDev, pTextPortion->GetExtraValue(), 0, 1, NULL ).Width();
+ long nChars = 2;
+ if( nCharWidth )
+ nChars = pTextPortion->GetSize().Width() / nCharWidth;
+ if ( nChars < 2 )
+ nChars = 2; // wird durch DrawStretchText gestaucht.
+ else if ( nChars == 2 )
+ nChars = 3; // sieht besser aus
+
+ String aText;
+ aText.Fill( (USHORT)nChars, pTextPortion->GetExtraValue() );
+ pOutDev->DrawStretchText( aTmpPos, pTextPortion->GetSize().Width(), aText );
+ }
+ }
+ break;
+ }
+ nIndex = nIndex + pTextPortion->GetLen();
+ }
+ }
+
+ if ( ( nLine != nLastLine ) && !aStatus.IsOutliner() )
+ {
+ if ( !IsVertical() )
+ aStartPos.Y() += nSBL;
+ else
+ aStartPos.X() -= nSBL;
+ }
+
+ // keine sichtbaren Aktionen mehr?
+ if ( !IsVertical() && ( aStartPos.Y() >= aClipRec.Bottom() ) )
+ break;
+ else if ( IsVertical() && ( aStartPos.X() <= aClipRec.Left() ) )
+ break;
+ }
+
+ if ( !aStatus.IsOutliner() )
+ {
+ const SvxULSpaceItem& rULItem = (const SvxULSpaceItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
+ long nUL = GetYValue( rULItem.GetLower() );
+ if ( !IsVertical() )
+ aStartPos.Y() += nUL;
+ else
+ aStartPos.X() -= nUL;
+ }
+ }
+ else
+ {
+ if ( !IsVertical() )
+ aStartPos.Y() += nParaHeight;
+ else
+ aStartPos.X() -= nParaHeight;
+ }
+
+ if ( pPDFExtOutDevData )
+ pPDFExtOutDevData->EndStructureElement();
+
+ // keine sichtbaren Aktionen mehr?
+ if ( !IsVertical() && ( aStartPos.Y() > aClipRec.Bottom() ) )
+ break;
+ if ( IsVertical() && ( aStartPos.X() < aClipRec.Left() ) )
+ break;
+ }
+ if ( aStatus.DoRestoreFont() )
+ pOutDev->SetFont( aOldFont );
+}
+
+void ImpEditEngine::Paint( ImpEditView* pView, const Rectangle& rRec, sal_Bool bUseVirtDev )
+{
+ DBG_ASSERT( pView, "Keine View - Kein Paint!" );
+ DBG_CHKOBJ( GetEditEnginePtr(), EditEngine, 0 );
+
+ if ( !GetUpdateMode() || IsInUndo() )
+ return;
+
+ // Schnittmenge aus Paintbereich und OutputArea.
+ Rectangle aClipRec( pView->GetOutputArea() );
+ aClipRec.Intersection( rRec );
+
+ Window* pOutWin = pView->GetWindow();
+
+ if ( bUseVirtDev )
+ {
+ Rectangle aClipRecPixel( pOutWin->LogicToPixel( aClipRec ) );
+ if ( !IsVertical() )
+ {
+ // etwas mehr, falls abgerundet!
+ aClipRecPixel.Right() += 1;
+ aClipRecPixel.Bottom() += 1;
+ }
+ else
+ {
+ aClipRecPixel.Left() -= 1;
+ aClipRecPixel.Bottom() += 1;
+ }
+
+ // Wenn aClipRecPixel > XXXX, dann invalidieren ?!
+
+ VirtualDevice* pVDev = GetVirtualDevice( pOutWin->GetMapMode(), pOutWin->GetDrawMode() );
+ pVDev->SetDigitLanguage( GetRefDevice()->GetDigitLanguage() );
+
+ {
+ Color aBackgroundColor( pView->GetBackgroundColor() );
+ // #i47161# Check if text is visible on background
+ SvxFont aTmpFont;
+ ContentNode* pNode = GetEditDoc().SaveGetObject( 0 );
+ SeekCursor( pNode, 1, aTmpFont );
+ Color aFontColor( aTmpFont.GetColor() );
+ if( aFontColor == COL_AUTO )
+ aFontColor = GetAutoColor();
+
+ // #i69346# check for reverse color of input method attribute
+ if( mpIMEInfos && (mpIMEInfos->aPos.GetNode() == pNode &&
+ mpIMEInfos->pAttribs))
+ {
+ sal_uInt16 nAttr = mpIMEInfos->pAttribs[ 0 ];
+ if ( nAttr & EXTTEXTINPUT_ATTR_HIGHLIGHT )
+ {
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ aFontColor = rStyleSettings.GetHighlightColor() ;
+ }
+ }
+
+ UINT8 nColorDiff = aFontColor.GetColorError( aBackgroundColor );
+ if( nColorDiff < 8 )
+ aBackgroundColor = aFontColor.IsDark() ? COL_WHITE : COL_BLACK;
+ pVDev->SetBackground( aBackgroundColor );
+ }
+
+ sal_Bool bVDevValid = sal_True;
+ Size aOutSz( pVDev->GetOutputSizePixel() );
+ if ( ( aOutSz.Width() < aClipRecPixel.GetWidth() ) ||
+ ( aOutSz.Height() < aClipRecPixel.GetHeight() ) )
+ {
+ bVDevValid = pVDev->SetOutputSizePixel( aClipRecPixel.GetSize() );
+ }
+ else
+ {
+ // Das VirtDev kann bei einem Resize sehr gross werden =>
+ // irgendwann mal kleiner machen!
+ if ( ( aOutSz.Height() > ( aClipRecPixel.GetHeight() + RESDIFF ) ) ||
+ ( aOutSz.Width() > ( aClipRecPixel.GetWidth() + RESDIFF ) ) )
+ {
+ bVDevValid = pVDev->SetOutputSizePixel( aClipRecPixel.GetSize() );
+ }
+ else
+ {
+ pVDev->Erase();
+ }
+ }
+ DBG_ASSERT( bVDevValid, "VDef konnte nicht vergroessert werden!" );
+ if ( !bVDevValid )
+ {
+ Paint( pView, rRec, sal_False /* ohne VDev */ );
+ return;
+ }
+
+ // PaintRect fuer VDev nicht mit alignter Groesse,
+ // da sonst die Zeile darunter auch ausgegeben werden muss:
+ Rectangle aTmpRec( Point( 0, 0 ), aClipRec.GetSize() );
+
+ aClipRec = pOutWin->PixelToLogic( aClipRecPixel );
+ Point aStartPos;
+ if ( !IsVertical() )
+ {
+ aStartPos = aClipRec.TopLeft();
+ aStartPos = pView->GetDocPos( aStartPos );
+ aStartPos.X() *= (-1);
+ aStartPos.Y() *= (-1);
+ }
+ else
+ {
+ aStartPos = aClipRec.TopRight();
+ Point aDocPos( pView->GetDocPos( aStartPos ) );
+ aStartPos.X() = aClipRec.GetSize().Width() + aDocPos.Y();
+ aStartPos.Y() = -aDocPos.X();
+ }
+
+ Paint( pVDev, aTmpRec, aStartPos );
+
+ sal_Bool bClipRegion = sal_False;
+ Region aOldRegion;
+ MapMode aOldMapMode;
+ if ( GetTextRanger() )
+ {
+ // Some problems here with push/pop, why?!
+// pOutWin->Push( PUSH_CLIPREGION|PUSH_MAPMODE );
+ bClipRegion = pOutWin->IsClipRegion();
+ aOldRegion = pOutWin->GetClipRegion();
+ // Wie bekomme ich das Polygon an die richtige Stelle????
+ // Das Polygon bezieht sich auf die View, nicht auf das Window
+ // => Origin umsetzen...
+ aOldMapMode = pOutWin->GetMapMode();
+ Point aOrigin = aOldMapMode.GetOrigin();
+ Point aViewPos = pView->GetOutputArea().TopLeft();
+ aOrigin.Move( aViewPos.X(), aViewPos.Y() );
+ aClipRec.Move( -aViewPos.X(), -aViewPos.Y() );
+ MapMode aNewMapMode( aOldMapMode );
+ aNewMapMode.SetOrigin( aOrigin );
+ pOutWin->SetMapMode( aNewMapMode );
+ pOutWin->SetClipRegion( Region( GetTextRanger()->GetPolyPolygon() ) );
+ }
+
+ pOutWin->DrawOutDev( aClipRec.TopLeft(), aClipRec.GetSize(),
+ Point(0,0), aClipRec.GetSize(), *pVDev );
+
+ if ( GetTextRanger() )
+ {
+// pOutWin->Pop();
+ if ( bClipRegion )
+ pOutWin->SetClipRegion( aOldRegion );
+ else
+ pOutWin->SetClipRegion();
+ pOutWin->SetMapMode( aOldMapMode );
+ }
+
+
+ pView->DrawSelection();
+ }
+ else
+ {
+ Point aStartPos;
+ if ( !IsVertical() )
+ {
+ aStartPos = pView->GetOutputArea().TopLeft();
+ aStartPos.X() -= pView->GetVisDocLeft();
+ aStartPos.Y() -= pView->GetVisDocTop();
+ }
+ else
+ {
+ aStartPos = pView->GetOutputArea().TopRight();
+ aStartPos.X() += pView->GetVisDocTop();
+ aStartPos.Y() -= pView->GetVisDocLeft();
+ }
+
+ // Wenn Doc-Breite < OutputArea,Width, nicht umgebrochene Felder,
+ // stehen die Felder sonst �ber, wenn > Zeile.
+ // ( Oben nicht, da dort bereits Doc-Breite von Formatierung mit drin )
+ if ( !IsVertical() && ( pView->GetOutputArea().GetWidth() > GetPaperSize().Width() ) )
+ {
+ long nMaxX = pView->GetOutputArea().Left() + GetPaperSize().Width();
+ if ( aClipRec.Left() > nMaxX )
+ return;
+ if ( aClipRec.Right() > nMaxX )
+ aClipRec.Right() = nMaxX;
+ }
+
+ sal_Bool bClipRegion = pOutWin->IsClipRegion();
+ Region aOldRegion = pOutWin->GetClipRegion();
+ pOutWin->IntersectClipRegion( aClipRec );
+
+ Paint( pOutWin, aClipRec, aStartPos );
+
+ if ( bClipRegion )
+ pOutWin->SetClipRegion( aOldRegion );
+ else
+ pOutWin->SetClipRegion();
+
+ pView->DrawSelection();
+ }
+
+}
+
+void ImpEditEngine::InsertContent( ContentNode* pNode, sal_uInt16 nPos )
+{
+ DBG_ASSERT( pNode, "NULL-Poointer in InsertContent! " );
+ DBG_ASSERT( IsInUndo(), "InsertContent nur fuer Undo()!" );
+ ParaPortion* pNew = new ParaPortion( pNode );
+ GetParaPortions().Insert( pNew, nPos );
+ aEditDoc.Insert( pNode, nPos );
+ if ( IsCallParaInsertedOrDeleted() )
+ GetEditEnginePtr()->ParagraphInserted( nPos );
+}
+
+EditPaM ImpEditEngine::SplitContent( sal_uInt16 nNode, sal_uInt16 nSepPos )
+{
+ ContentNode* pNode = aEditDoc.SaveGetObject( nNode );
+ DBG_ASSERT( pNode, "Ungueltiger Node in SplitContent" );
+ DBG_ASSERT( IsInUndo(), "SplitContent nur fuer Undo()!" );
+ DBG_ASSERT( nSepPos <= pNode->Len(), "Index im Wald: SplitContent" );
+ EditPaM aPaM( pNode, nSepPos );
+ return ImpInsertParaBreak( aPaM );
+}
+
+EditPaM ImpEditEngine::ConnectContents( sal_uInt16 nLeftNode, sal_Bool bBackward )
+{
+ ContentNode* pLeftNode = aEditDoc.SaveGetObject( nLeftNode );
+ ContentNode* pRightNode = aEditDoc.SaveGetObject( nLeftNode+1 );
+ DBG_ASSERT( pLeftNode, "Ungueltiger linker Node in ConnectContents" );
+ DBG_ASSERT( pRightNode, "Ungueltiger rechter Node in ConnectContents" );
+ DBG_ASSERT( IsInUndo(), "ConnectContent nur fuer Undo()!" );
+ return ImpConnectParagraphs( pLeftNode, pRightNode, bBackward );
+}
+
+void ImpEditEngine::SetUpdateMode( sal_Bool bUp, EditView* pCurView, sal_Bool bForceUpdate )
+{
+ sal_Bool bChanged = ( GetUpdateMode() != bUp );
+
+ // Beim Umschalten von sal_True auf sal_False waren alle Selektionen sichtbar,
+ // => Wegmalen
+ // Umgekehrt waren alle unsichtbar => malen
+
+// DrawAllSelections(); sieht im Outliner schlecht aus !
+// EditView* pView = aEditViewList.First();
+// while ( pView )
+// {
+// DBG_CHKOBJ( pView, EditView, 0 );
+// pView->pImpEditView->DrawSelection();
+// pView = aEditViewList.Next();
+// }
+
+ // Wenn !bFormatted, also z.B. nach SetText, braucht bei UpdateMode sal_True
+ // nicht sofort formatiert werden, weil warscheinlich noch Text kommt.
+ // Spaetestens bei einem Paint / CalcTextWidth wird formatiert.
+
+ bUpdate = bUp;
+ if ( bUpdate && ( bChanged || bForceUpdate ) )
+ FormatAndUpdate( pCurView );
+}
+
+void ImpEditEngine::ShowParagraph( sal_uInt16 nParagraph, sal_Bool bShow )
+{
+ ParaPortion* pPPortion = GetParaPortions().SaveGetObject( nParagraph );
+ DBG_ASSERT( pPPortion, "ShowParagraph: Absatz existiert nicht!" );
+ if ( pPPortion && ( pPPortion->IsVisible() != bShow ) )
+ {
+ pPPortion->SetVisible( bShow );
+
+ if ( !bShow )
+ {
+ // Als deleted kenzeichnen, damit keine Selektion auf diesem
+ // Absatz beginnt oder endet...
+ DeletedNodeInfo* pDelInfo = new DeletedNodeInfo( (sal_uIntPtr)pPPortion->GetNode(), nParagraph );
+ aDeletedNodes.Insert( pDelInfo, aDeletedNodes.Count() );
+ UpdateSelections();
+ // Dann kriege ich den unteren Bereich nicht invalidiert,
+ // wenn UpdateMode = sal_False!
+ // Wenn doch, dann vor SetVisible auf sal_False merken!
+// nCurTextHeight -= pPPortion->GetHeight();
+ }
+
+ if ( bShow && ( pPPortion->IsInvalid() || !pPPortion->nHeight ) )
+ {
+ if ( !GetTextRanger() )
+ {
+ if ( pPPortion->IsInvalid() )
+ {
+ Font aOldFont( GetRefDevice()->GetFont() );
+ CreateLines( nParagraph, 0 ); // 0: Kein TextRanger
+ if ( aStatus.DoRestoreFont() )
+ GetRefDevice()->SetFont( aOldFont );
+ }
+ else
+ {
+ CalcHeight( pPPortion );
+ }
+ nCurTextHeight += pPPortion->GetHeight();
+ }
+ else
+ {
+ nCurTextHeight = 0x7fffffff;
+ }
+ }
+
+ pPPortion->SetMustRepaint( sal_True );
+ if ( GetUpdateMode() && !IsInUndo() && !GetTextRanger() )
+ {
+ aInvalidRec = Rectangle( Point( 0, GetParaPortions().GetYOffset( pPPortion ) ),
+ Point( GetPaperSize().Width(), nCurTextHeight ) );
+ UpdateViews( GetActiveView() );
+ }
+ }
+}
+
+sal_Bool ImpEditEngine::IsParagraphVisible( sal_uInt16 nParagraph )
+{
+ ParaPortion* pPPortion = GetParaPortions().SaveGetObject( nParagraph );
+ DBG_ASSERT( pPPortion, "IsParagraphVisible: Absatz existiert nicht!" );
+ if ( pPPortion )
+ return pPPortion->IsVisible();
+ return sal_False;
+}
+
+EditSelection ImpEditEngine::MoveParagraphs( Range aOldPositions, sal_uInt16 nNewPos, EditView* pCurView )
+{
+ DBG_ASSERT( GetParaPortions().Count() != 0, "Keine Absaetze gefunden: MoveParagraphs" );
+ if ( GetParaPortions().Count() == 0 )
+ return EditSelection();
+ aOldPositions.Justify();
+
+ EditSelection aSel( ImpMoveParagraphs( aOldPositions, nNewPos ) );
+
+ if ( nNewPos >= GetParaPortions().Count() )
+ nNewPos = GetParaPortions().Count() - 1;
+
+ // Dort, wo der Absatz eingefuegt wurde, muss richtig gepainted werden:
+ // Dort, wo der Absatz entfernt wurde, muss richtig gepainted werden:
+ // ( Und dazwischen entsprechend auch...)
+ if ( pCurView && ( GetUpdateMode() == sal_True ) )
+ {
+ // in diesem Fall kann ich direkt neu malen, ohne die
+ // Portions zu Invalidieren.
+ sal_uInt16 nFirstPortion = Min( (sal_uInt16)aOldPositions.Min(), nNewPos );
+ sal_uInt16 nLastPortion = Max( (sal_uInt16)aOldPositions.Max(), nNewPos );
+
+ ParaPortion* pUpperPortion = GetParaPortions().SaveGetObject( nFirstPortion );
+ ParaPortion* pLowerPortion = GetParaPortions().SaveGetObject( nLastPortion );
+
+ aInvalidRec = Rectangle(); // leermachen
+ aInvalidRec.Left() = 0;
+ aInvalidRec.Right() = aPaperSize.Width();
+ aInvalidRec.Top() = GetParaPortions().GetYOffset( pUpperPortion );
+ aInvalidRec.Bottom() = GetParaPortions().GetYOffset( pLowerPortion ) + pLowerPortion->GetHeight();
+
+ UpdateViews( pCurView );
+ }
+ else
+ {
+ // aber der oberen ungueltigen Position neu painten...
+ sal_uInt16 nFirstInvPara = Min( (sal_uInt16)aOldPositions.Min(), nNewPos );
+ InvalidateFromParagraph( nFirstInvPara );
+ }
+ return aSel;
+}
+
+void ImpEditEngine::InvalidateFromParagraph( sal_uInt16 nFirstInvPara )
+{
+ // Es werden nicht die folgenden Absaetze invalidiert,
+ // da ResetHeight() => Groessenanderung => alles folgende wird
+ // sowieso neu ausgegeben.
+ ParaPortion* pTmpPortion;
+ if ( nFirstInvPara != 0 )
+ {
+ pTmpPortion = GetParaPortions().GetObject( nFirstInvPara-1 );
+ pTmpPortion->MarkInvalid( pTmpPortion->GetNode()->Len(), 0 );
+ }
+ else
+ {
+ pTmpPortion = GetParaPortions().GetObject( 0 );
+ pTmpPortion->MarkSelectionInvalid( 0, pTmpPortion->GetNode()->Len() );
+ }
+ pTmpPortion->ResetHeight();
+}
+
+IMPL_LINK_INLINE_START( ImpEditEngine, StatusTimerHdl, Timer *, EMPTYARG )
+{
+ CallStatusHdl();
+ return 0;
+}
+IMPL_LINK_INLINE_END( ImpEditEngine, StatusTimerHdl, Timer *, EMPTYARG )
+
+void ImpEditEngine::CallStatusHdl()
+{
+ if ( aStatusHdlLink.IsSet() && aStatus.GetStatusWord() )
+ {
+ // Der Status muss vor Call zurueckgesetzt werden,
+ // da im Hdl evtl. weitere Fags gesetzt werden...
+ EditStatus aTmpStatus( aStatus );
+ aStatus.Clear();
+ aStatusHdlLink.Call( &aTmpStatus );
+ aStatusTimer.Stop(); // Falls von Hand gerufen...
+ }
+}
+
+ContentNode* ImpEditEngine::GetPrevVisNode( ContentNode* pCurNode )
+{
+ ParaPortion* pPortion = FindParaPortion( pCurNode );
+ DBG_ASSERT( pPortion, "GetPrevVisibleNode: Keine passende Portion!" );
+ pPortion = GetPrevVisPortion( pPortion );
+ if ( pPortion )
+ return pPortion->GetNode();
+ return 0;
+}
+
+ContentNode* ImpEditEngine::GetNextVisNode( ContentNode* pCurNode )
+{
+ ParaPortion* pPortion = FindParaPortion( pCurNode );
+ DBG_ASSERT( pPortion, "GetNextVisibleNode: Keine passende Portion!" );
+ pPortion = GetNextVisPortion( pPortion );
+ if ( pPortion )
+ return pPortion->GetNode();
+ return 0;
+}
+
+ParaPortion* ImpEditEngine::GetPrevVisPortion( ParaPortion* pCurPortion )
+{
+ sal_uInt16 nPara = GetParaPortions().GetPos( pCurPortion );
+ DBG_ASSERT( nPara < GetParaPortions().Count() , "Portion nicht gefunden: GetPrevVisPortion" );
+ ParaPortion* pPortion = nPara ? GetParaPortions()[--nPara] : 0;
+ while ( pPortion && !pPortion->IsVisible() )
+ pPortion = nPara ? GetParaPortions()[--nPara] : 0;
+
+ return pPortion;
+}
+
+ParaPortion* ImpEditEngine::GetNextVisPortion( ParaPortion* pCurPortion )
+{
+ sal_uInt16 nPara = GetParaPortions().GetPos( pCurPortion );
+ DBG_ASSERT( nPara < GetParaPortions().Count() , "Portion nicht gefunden: GetPrevVisNode" );
+ ParaPortion* pPortion = GetParaPortions().SaveGetObject( ++nPara );
+ while ( pPortion && !pPortion->IsVisible() )
+ pPortion = GetParaPortions().SaveGetObject( ++nPara );
+
+ return pPortion;
+}
+
+EditPaM ImpEditEngine::InsertParagraph( sal_uInt16 nPara )
+{
+ EditPaM aPaM;
+ if ( nPara != 0 )
+ {
+ ContentNode* pNode = GetEditDoc().SaveGetObject( nPara-1 );
+ if ( !pNode )
+ pNode = GetEditDoc().SaveGetObject( GetEditDoc().Count() - 1 );
+ DBG_ASSERT( pNode, "Kein einziger Absatz in InsertParagraph ?" );
+ aPaM = EditPaM( pNode, pNode->Len() );
+ }
+ else
+ {
+ ContentNode* pNode = GetEditDoc().SaveGetObject( 0 );
+ aPaM = EditPaM( pNode, 0 );
+ }
+
+ return ImpInsertParaBreak( aPaM );
+}
+
+EditSelection* ImpEditEngine::SelectParagraph( sal_uInt16 nPara )
+{
+ EditSelection* pSel = 0;
+ ContentNode* pNode = GetEditDoc().SaveGetObject( nPara );
+ DBG_ASSERTWARNING( pNode, "Absatz existiert nicht: SelectParagraph" );
+ if ( pNode )
+ pSel = new EditSelection( EditPaM( pNode, 0 ), EditPaM( pNode, pNode->Len() ) );
+
+ return pSel;
+}
+
+void ImpEditEngine::FormatAndUpdate( EditView* pCurView )
+{
+ if ( bDowning )
+ return ;
+
+ if ( IsInUndo() )
+ IdleFormatAndUpdate( pCurView );
+ else
+ {
+ FormatDoc();
+ UpdateViews( pCurView );
+ }
+}
+
+void ImpEditEngine::SetFlatMode( sal_Bool bFlat )
+{
+ if ( bFlat != aStatus.UseCharAttribs() )
+ return;
+
+ if ( !bFlat )
+ aStatus.TurnOnFlags( EE_CNTRL_USECHARATTRIBS );
+ else
+ aStatus.TurnOffFlags( EE_CNTRL_USECHARATTRIBS );
+
+ aEditDoc.CreateDefFont( !bFlat );
+
+ FormatFullDoc();
+ UpdateViews( (EditView*) 0);
+ if ( pActiveView )
+ pActiveView->ShowCursor();
+}
+
+void ImpEditEngine::SetCharStretching( sal_uInt16 nX, sal_uInt16 nY )
+{
+ if ( !IsVertical() )
+ {
+ nStretchX = nX;
+ nStretchY = nY;
+ }
+ else
+ {
+ nStretchX = nY;
+ nStretchY = nX;
+ }
+
+ if ( aStatus.DoStretch() )
+ {
+ FormatFullDoc();
+ UpdateViews( GetActiveView() );
+ }
+}
+
+void ImpEditEngine::DoStretchChars( sal_uInt16 nX, sal_uInt16 nY )
+{
+ UndoActionStart( EDITUNDO_STRETCH );
+ sal_uInt16 nParas = GetEditDoc().Count();
+ for ( sal_uInt16 nPara = 0; nPara < nParas; nPara++ )
+ {
+ ContentNode* pNode = GetEditDoc()[nPara];
+ SfxItemSet aTmpSet( pNode->GetContentAttribs().GetItems() );
+
+ if ( nX != 100 )
+ {
+ // Fontbreite
+ SvxCharScaleWidthItem* pNewWidth = (SvxCharScaleWidthItem*) pNode->GetContentAttribs().GetItem( EE_CHAR_FONTWIDTH ).Clone();
+ sal_uInt32 nProp = pNewWidth->GetValue(); // sal_uInt32, kann temporaer gross werden
+ nProp *= nX;
+ nProp /= 100;
+ pNewWidth->SetValue( (sal_uInt16)nProp );
+ aTmpSet.Put( *pNewWidth );
+ delete pNewWidth;
+
+ // Kerning:
+ const SvxKerningItem& rKerningItem =
+ (const SvxKerningItem&)pNode->GetContentAttribs().GetItem( EE_CHAR_KERNING );
+ SvxKerningItem* pNewKerning = (SvxKerningItem*)rKerningItem.Clone();
+ long nKerning = pNewKerning->GetValue();
+ if ( nKerning > 0 )
+ {
+ nKerning *= nX;
+ nKerning /= 100;
+ }
+ else if ( nKerning < 0 )
+ {
+ // Bei Negativen Werten:
+ // Bei Stretching > 100 muessen die Werte kleiner werden und umgekehrt.
+ nKerning *= 100;
+ nKerning /= nX;
+ }
+ pNewKerning->SetValue( (short)nKerning );
+ aTmpSet.Put( *pNewKerning);
+ delete pNewKerning;
+ }
+ else
+ aTmpSet.ClearItem( EE_CHAR_FONTWIDTH );
+
+ if ( nY != 100 )
+ {
+ // Fonthoehe
+ for ( int nItem = 0; nItem < 3; nItem++ )
+ {
+ USHORT nItemId = EE_CHAR_FONTHEIGHT;
+ if ( nItem == 1 )
+ nItemId = EE_CHAR_FONTHEIGHT_CJK;
+ else if ( nItem == 2 )
+ nItemId = EE_CHAR_FONTHEIGHT_CTL;
+
+ const SvxFontHeightItem& rHeightItem =
+ (const SvxFontHeightItem&)pNode->GetContentAttribs().GetItem( nItemId );
+ SvxFontHeightItem* pNewHeight = (SvxFontHeightItem*)rHeightItem.Clone();
+ sal_uInt32 nHeight = pNewHeight->GetHeight();
+ nHeight *= nY;
+ nHeight /= 100;
+ pNewHeight->SetHeightValue( nHeight );
+ aTmpSet.Put( *pNewHeight );
+ delete pNewHeight;
+ }
+
+ // Absatzabstaende
+ const SvxULSpaceItem& rULSpaceItem =
+ (const SvxULSpaceItem&)pNode->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
+ SvxULSpaceItem* pNewUL = (SvxULSpaceItem*)rULSpaceItem.Clone();
+ sal_uInt32 nUpper = pNewUL->GetUpper();
+ nUpper *= nY;
+ nUpper /= 100;
+ pNewUL->SetUpper( (sal_uInt16)nUpper );
+ sal_uInt32 nLower = pNewUL->GetLower();
+ nLower *= nY;
+ nLower /= 100;
+ pNewUL->SetLower( (sal_uInt16)nLower );
+ aTmpSet.Put( *pNewUL );
+ delete pNewUL;
+ }
+ else
+ aTmpSet.ClearItem( EE_CHAR_FONTHEIGHT );
+
+ SetParaAttribs( nPara, aTmpSet );
+
+ // harte Attribute:
+ sal_uInt16 nLastEnd = 0; // damit nach entfernen und neu nicht nochmal
+ CharAttribArray& rAttribs = pNode->GetCharAttribs().GetAttribs();
+ sal_uInt16 nAttribs = rAttribs.Count();
+ for ( sal_uInt16 nAttr = 0; nAttr < nAttribs; nAttr++ )
+ {
+ EditCharAttrib* pAttr = rAttribs[nAttr];
+ if ( pAttr->GetStart() >= nLastEnd )
+ {
+ sal_uInt16 nWhich = pAttr->Which();
+ SfxPoolItem* pNew = 0;
+ if ( nWhich == EE_CHAR_FONTHEIGHT )
+ {
+ SvxFontHeightItem* pNewHeight = (SvxFontHeightItem*)pAttr->GetItem()->Clone();
+ sal_uInt32 nHeight = pNewHeight->GetHeight();
+ nHeight *= nY;
+ nHeight /= 100;
+ pNewHeight->SetHeightValue( nHeight );
+ pNew = pNewHeight;
+ }
+ else if ( nWhich == EE_CHAR_FONTWIDTH )
+ {
+ SvxCharScaleWidthItem* pNewWidth = (SvxCharScaleWidthItem*)pAttr->GetItem()->Clone();
+ sal_uInt32 nProp = pNewWidth->GetValue();
+ nProp *= nX;
+ nProp /= 100;
+ pNewWidth->SetValue( (sal_uInt16)nProp );
+ pNew = pNewWidth;
+ }
+ else if ( nWhich == EE_CHAR_KERNING )
+ {
+ SvxKerningItem* pNewKerning = (SvxKerningItem*)pAttr->GetItem()->Clone();
+ long nKerning = pNewKerning->GetValue();
+ if ( nKerning > 0 )
+ {
+ nKerning *= nX;
+ nKerning /= 100;
+ }
+ else if ( nKerning < 0 )
+ {
+ // Bei Negativen Werten:
+ // Bei Stretching > 100 muessen die Werte kleiner werden und umgekehrt.
+ nKerning *= 100;
+ nKerning /= nX;
+ }
+ pNewKerning->SetValue( (short)nKerning );
+ pNew = pNewKerning;
+ }
+ if ( pNew )
+ {
+ SfxItemSet _aTmpSet( GetEmptyItemSet() );
+ _aTmpSet.Put( *pNew );
+ SetAttribs( EditSelection( EditPaM( pNode, pAttr->GetStart() ),
+ EditPaM( pNode, pAttr->GetEnd() ) ), _aTmpSet );
+
+ nLastEnd = pAttr->GetEnd();
+ delete pNew;
+ }
+ }
+ }
+ }
+ UndoActionEnd( EDITUNDO_STRETCH );
+}
+
+const SvxNumberFormat* ImpEditEngine::GetNumberFormat( const ContentNode *pNode ) const
+{
+ const SvxNumberFormat *pRes = 0;
+
+ if (pNode)
+ {
+ // get index of paragraph
+ USHORT nPara = GetEditDoc().GetPos( const_cast< ContentNode * >(pNode) );
+ DBG_ASSERT( nPara < USHRT_MAX, "node not found in array" );
+ if (nPara < USHRT_MAX)
+ {
+ // the called function may be overloaded by an OutlinerEditEng object to provide
+ // access to the SvxNumberFormat of the Outliner.
+ // The EditEngine implementation will just return 0.
+ pRes = pEditEngine->GetNumberFormat( nPara );
+ }
+ }
+
+ return pRes;
+}
+
+sal_Int32 ImpEditEngine::GetSpaceBeforeAndMinLabelWidth(
+ const ContentNode *pNode,
+ sal_Int32 *pnSpaceBefore, sal_Int32 *pnMinLabelWidth ) const
+{
+ // nSpaceBefore matches the ODF attribut text:space-before
+ // nMinLabelWidth matches the ODF attribut text:min-label-width
+
+ const SvxNumberFormat *pNumFmt = GetNumberFormat( pNode );
+
+ // if no number format was found we have no Outliner or the numbering level
+ // within the Outliner is -1 which means no number format should be applied.
+ // Thus the default values to be returned are 0.
+ sal_Int32 nSpaceBefore = 0;
+ sal_Int32 nMinLabelWidth = 0;
+
+ if (pNumFmt)
+ {
+ nMinLabelWidth = -pNumFmt->GetFirstLineOffset();
+ nSpaceBefore = pNumFmt->GetAbsLSpace() - nMinLabelWidth;
+ DBG_ASSERT( nMinLabelWidth >= 0, "ImpEditEngine::GetSpaceBeforeAndMinLabelWidth: min-label-width < 0 encountered" );
+ }
+ if (pnSpaceBefore)
+ *pnSpaceBefore = nSpaceBefore;
+ if (pnMinLabelWidth)
+ *pnMinLabelWidth = nMinLabelWidth;
+
+ return nSpaceBefore + nMinLabelWidth;
+}
+
+const SvxLRSpaceItem& ImpEditEngine::GetLRSpaceItem( ContentNode* pNode )
+{
+ return (const SvxLRSpaceItem&)pNode->GetContentAttribs().GetItem( aStatus.IsOutliner() ? EE_PARA_OUTLLRSPACE : EE_PARA_LRSPACE );
+}
+
+// Either sets the digit mode at the output device or
+// modifies the passed string according to the text numeral setting:
+void ImpEditEngine::ImplInitDigitMode( OutputDevice* pOutDev, String* pString, xub_StrLen nStt, xub_StrLen nLen, LanguageType eCurLang )
+{
+ // #114278# Also setting up digit language from Svt options
+ // (cannot reliably inherit the outdev's setting)
+ if( !pCTLOptions )
+ pCTLOptions = new SvtCTLOptions;
+
+ LanguageType eLang = eCurLang;
+ const SvtCTLOptions::TextNumerals nCTLTextNumerals = pCTLOptions->GetCTLTextNumerals();
+
+ if ( SvtCTLOptions::NUMERALS_HINDI == nCTLTextNumerals )
+ eLang = LANGUAGE_ARABIC_SAUDI_ARABIA;
+ else if ( SvtCTLOptions::NUMERALS_ARABIC == nCTLTextNumerals )
+ eLang = LANGUAGE_ENGLISH;
+ else if ( SvtCTLOptions::NUMERALS_SYSTEM == nCTLTextNumerals )
+ eLang = (LanguageType) Application::GetSettings().GetLanguage();
+
+ if(pOutDev)
+ {
+ pOutDev->SetDigitLanguage( eLang );
+ }
+ else if (pString)
+ {
+ // see sallayout.cxx in vcl
+ int nOffset;
+ switch( eLang & LANGUAGE_MASK_PRIMARY )
+ {
+ default:
+ nOffset = 0;
+ break;
+ case LANGUAGE_ARABIC_SAUDI_ARABIA & LANGUAGE_MASK_PRIMARY:
+ nOffset = 0x0660 - '0'; // arabic-indic digits
+ break;
+ case LANGUAGE_URDU & LANGUAGE_MASK_PRIMARY:
+ case LANGUAGE_PUNJABI & LANGUAGE_MASK_PRIMARY: //???
+ case LANGUAGE_SINDHI & LANGUAGE_MASK_PRIMARY:
+ nOffset = 0x06F0 - '0'; // eastern arabic-indic digits
+ break;
+ }
+ if (nOffset)
+ {
+ const xub_StrLen nEnd = nStt + nLen;
+ for( xub_StrLen nIdx = nStt; nIdx < nEnd; ++nIdx )
+ {
+ sal_Unicode nChar = pString->GetChar( nIdx );
+ if( (nChar < '0') || ('9' < nChar) )
+ continue;
+ nChar = (sal_Unicode)(nChar + nOffset);
+ pString->SetChar( nIdx, nChar );
+ }
+ }
+ }
+}
+
+void ImpEditEngine::ImplInitLayoutMode( OutputDevice* pOutDev, USHORT nPara, USHORT nIndex )
+{
+ BOOL bCTL = FALSE;
+ BYTE bR2L = FALSE;
+ if ( nIndex == 0xFFFF )
+ {
+ bCTL = HasScriptType( nPara, i18n::ScriptType::COMPLEX );
+ bR2L = IsRightToLeft( nPara );
+ }
+ else
+ {
+ ContentNode* pNode = GetEditDoc().SaveGetObject( nPara );
+ short nScriptType = GetScriptType( EditPaM( pNode, nIndex+1 ) );
+ bCTL = nScriptType == i18n::ScriptType::COMPLEX;
+ bR2L = GetRightToLeft( nPara, nIndex + 1); // this change was discussed in issue 37190
+ // it also works for issue 55927
+ }
+
+ ULONG nLayoutMode = pOutDev->GetLayoutMode();
+
+ // We always use the left postion for DrawText()
+ nLayoutMode &= ~(TEXT_LAYOUT_BIDI_RTL);
+
+ if ( !bCTL && !bR2L)
+ {
+ // No CTL/Bidi checking neccessary
+ nLayoutMode |= ( TEXT_LAYOUT_COMPLEX_DISABLED | TEXT_LAYOUT_BIDI_STRONG );
+ }
+ else
+ {
+ // CTL/Bidi checking neccessary
+ // Don't use BIDI_STRONG, VCL must do some checks.
+ nLayoutMode &= ~( TEXT_LAYOUT_COMPLEX_DISABLED | TEXT_LAYOUT_BIDI_STRONG );
+
+ if ( bR2L )
+ nLayoutMode |= TEXT_LAYOUT_BIDI_RTL|TEXT_LAYOUT_TEXTORIGIN_LEFT;
+ }
+
+ pOutDev->SetLayoutMode( nLayoutMode );
+
+ // #114278# Also setting up digit language from Svt options
+ // (cannot reliably inherit the outdev's setting)
+ LanguageType eLang;
+
+ if( !pCTLOptions )
+ pCTLOptions = new SvtCTLOptions;
+
+ if ( SvtCTLOptions::NUMERALS_HINDI == pCTLOptions->GetCTLTextNumerals() )
+ eLang = LANGUAGE_ARABIC_SAUDI_ARABIA;
+ else if ( SvtCTLOptions::NUMERALS_ARABIC == pCTLOptions->GetCTLTextNumerals() )
+ eLang = LANGUAGE_ENGLISH;
+ else
+ eLang = (LanguageType) Application::GetSettings().GetLanguage();
+
+ pOutDev->SetDigitLanguage( eLang );
+}
+
+Reference < i18n::XBreakIterator > ImpEditEngine::ImplGetBreakIterator() const
+{
+ if ( !xBI.is() )
+ {
+ Reference< lang::XMultiServiceFactory > xMSF( ::comphelper::getProcessServiceFactory() );
+ xBI.set( xMSF->createInstance( OUString::createFromAscii( "com.sun.star.i18n.BreakIterator" ) ), UNO_QUERY );
+ }
+ return xBI;
+}
+
+Reference < i18n::XExtendedInputSequenceChecker > ImpEditEngine::ImplGetInputSequenceChecker() const
+{
+ if ( !xISC.is() )
+ {
+ Reference< lang::XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
+ Reference < XInterface > xI = xMSF->createInstance( OUString::createFromAscii( "com.sun.star.i18n.InputSequenceChecker" ) );
+ if ( xI.is() )
+ {
+ Any x = xI->queryInterface( ::getCppuType((const Reference< i18n::XExtendedInputSequenceChecker >*)0) );
+ x >>= xISC;
+ }
+ }
+ return xISC;
+}
+
+Color ImpEditEngine::GetAutoColor() const
+{
+ Color aColor = const_cast<ImpEditEngine*>(this)->GetColorConfig().GetColorValue( svtools::FONTCOLOR ).nColor;
+
+ if ( GetBackgroundColor() != COL_AUTO )
+ {
+ if ( GetBackgroundColor().IsDark() && aColor.IsDark() )
+ aColor = COL_WHITE;
+ else if ( GetBackgroundColor().IsBright() && aColor.IsBright() )
+ aColor = COL_BLACK;
+ }
+
+ return aColor;
+}
+
+
+BOOL ImpEditEngine::ImplCalcAsianCompression( ContentNode* pNode, TextPortion* pTextPortion, USHORT nStartPos, sal_Int32* pDXArray, USHORT n100thPercentFromMax, BOOL bManipulateDXArray )
+{
+ DBG_ASSERT( GetAsianCompressionMode(), "ImplCalcAsianCompression - Why?" );
+ DBG_ASSERT( pTextPortion->GetLen(), "ImplCalcAsianCompression - Empty Portion?" );
+
+ // Percent is 1/100 Percent...
+
+ if ( n100thPercentFromMax == 10000 )
+ pTextPortion->SetExtraInfos( NULL );
+
+ BOOL bCompressed = FALSE;
+
+ if ( GetScriptType( EditPaM( pNode, nStartPos+1 ) ) == i18n::ScriptType::ASIAN )
+ {
+ long nNewPortionWidth = pTextPortion->GetSize().Width();
+ USHORT nPortionLen = pTextPortion->GetLen();
+ for ( USHORT n = 0; n < nPortionLen; n++ )
+ {
+ BYTE nType = GetCharTypeForCompression( pNode->GetChar( n+nStartPos ) );
+
+ BOOL bCompressPunctuation = ( nType == CHAR_PUNCTUATIONLEFT ) || ( nType == CHAR_PUNCTUATIONRIGHT );
+ BOOL bCompressKana = ( nType == CHAR_KANA ) && ( GetAsianCompressionMode() == text::CharacterCompressionType::PUNCTUATION_AND_KANA );
+
+ // create Extra infos only if needed...
+ if ( bCompressPunctuation || bCompressKana )
+ {
+ if ( !pTextPortion->GetExtraInfos() )
+ {
+ ExtraPortionInfo* pExtraInfos = new ExtraPortionInfo;
+ pTextPortion->SetExtraInfos( pExtraInfos );
+ pExtraInfos->nOrgWidth = pTextPortion->GetSize().Width();
+ pExtraInfos->nAsianCompressionTypes = CHAR_NORMAL;
+ }
+ pTextPortion->GetExtraInfos()->nMaxCompression100thPercent = n100thPercentFromMax;
+ pTextPortion->GetExtraInfos()->nAsianCompressionTypes |= nType;
+// pTextPortion->GetExtraInfos()->nCompressedChars++;
+
+ long nOldCharWidth;
+ if ( (n+1) < nPortionLen )
+ {
+ nOldCharWidth = pDXArray[n];
+ }
+ else
+ {
+ if ( bManipulateDXArray )
+ nOldCharWidth = nNewPortionWidth - pTextPortion->GetExtraInfos()->nPortionOffsetX;
+ else
+ nOldCharWidth = pTextPortion->GetExtraInfos()->nOrgWidth;
+ }
+ nOldCharWidth -= ( n ? pDXArray[n-1] : 0 );
+
+ long nCompress = 0;
+
+ if ( bCompressPunctuation )
+ {
+ // pTextPortion->GetExtraInfos()->nComressionWeight += 5;
+ nCompress = nOldCharWidth / 2;
+ }
+ else // Kana
+ {
+ // pTextPortion->GetExtraInfos()->nComressionWeight += 1;
+ nCompress = nOldCharWidth / 10;
+ }
+
+ if ( n100thPercentFromMax != 10000 )
+ {
+ nCompress *= n100thPercentFromMax;
+ nCompress /= 10000;
+ }
+
+ if ( nCompress )
+ {
+ bCompressed = TRUE;
+ nNewPortionWidth -= nCompress;
+ pTextPortion->GetExtraInfos()->bCompressed = TRUE;
+
+
+ // Special handling for rightpunctuation: For the 'compression' we must
+ // start th eoutput before the normal char position....
+ if ( bManipulateDXArray && ( pTextPortion->GetLen() > 1 ) )
+ {
+ if ( !pTextPortion->GetExtraInfos()->pOrgDXArray )
+ pTextPortion->GetExtraInfos()->SaveOrgDXArray( pDXArray, pTextPortion->GetLen()-1 );
+
+ if ( nType == CHAR_PUNCTUATIONRIGHT )
+ {
+ // If it's the first char, I must handle it in Paint()...
+ if ( n )
+ {
+ // -1: No entry for the last character
+ for ( USHORT i = n-1; i < (nPortionLen-1); i++ )
+ pDXArray[i] -= nCompress;
+ }
+ else
+ {
+ pTextPortion->GetExtraInfos()->bFirstCharIsRightPunktuation = TRUE;
+ pTextPortion->GetExtraInfos()->nPortionOffsetX = -nCompress;
+ }
+ }
+ else
+ {
+ // -1: No entry for the last character
+ for ( USHORT i = n; i < (nPortionLen-1); i++ )
+ pDXArray[i] -= nCompress;
+ }
+ }
+ }
+ }
+ }
+
+ if ( bCompressed && ( n100thPercentFromMax == 10000 ) )
+ pTextPortion->GetExtraInfos()->nWidthFullCompression = nNewPortionWidth;
+
+ pTextPortion->GetSize().Width() = nNewPortionWidth;
+
+ if ( pTextPortion->GetExtraInfos() && ( n100thPercentFromMax != 10000 ) )
+ {
+ // Maybe rounding errors in nNewPortionWidth, assure that width not bigger than expected
+ long nShrink = pTextPortion->GetExtraInfos()->nOrgWidth - pTextPortion->GetExtraInfos()->nWidthFullCompression;
+ nShrink *= n100thPercentFromMax;
+ nShrink /= 10000;
+ long nNewWidth = pTextPortion->GetExtraInfos()->nOrgWidth - nShrink;
+ if ( nNewWidth < pTextPortion->GetSize().Width() )
+ pTextPortion->GetSize().Width() = nNewWidth;
+ }
+ }
+ return bCompressed;
+}
+
+
+void ImpEditEngine::ImplExpandCompressedPortions( EditLine* pLine, ParaPortion* pParaPortion, long nRemainingWidth )
+{
+ BOOL bFoundCompressedPortion = FALSE;
+ long nCompressed = 0;
+// long nCompressWeight = 0;
+ TextPortionList aCompressedPortions;
+
+ USHORT nPortion = pLine->GetEndPortion();
+ TextPortion* pTP = pParaPortion->GetTextPortions()[ nPortion ];
+ while ( pTP && ( pTP->GetKind() == PORTIONKIND_TEXT ) )
+ {
+ if ( pTP->GetExtraInfos() && pTP->GetExtraInfos()->bCompressed )
+ {
+ bFoundCompressedPortion = TRUE;
+ nCompressed += pTP->GetExtraInfos()->nOrgWidth - pTP->GetSize().Width();
+ aCompressedPortions.Insert( pTP, aCompressedPortions.Count() );
+ }
+ pTP = ( nPortion > pLine->GetStartPortion() ) ? pParaPortion->GetTextPortions()[ --nPortion ] : NULL;
+ }
+
+ if ( bFoundCompressedPortion )
+ {
+ long nCompressPercent = 0;
+ if ( nCompressed > nRemainingWidth )
+ {
+ nCompressPercent = nCompressed - nRemainingWidth;
+ DBG_ASSERT( nCompressPercent < 200000, "ImplExpandCompressedPortions - Overflow!" );
+ nCompressPercent *= 10000;
+ nCompressPercent /= nCompressed;
+ }
+
+ for ( USHORT n = 0; n < aCompressedPortions.Count(); n++ )
+ {
+ pTP = aCompressedPortions[n];
+ pTP->GetExtraInfos()->bCompressed = FALSE;
+ pTP->GetSize().Width() = pTP->GetExtraInfos()->nOrgWidth;
+ if ( nCompressPercent )
+ {
+ USHORT nTxtPortion = pParaPortion->GetTextPortions().GetPos( pTP );
+ USHORT nTxtPortionStart = pParaPortion->GetTextPortions().GetStartPos( nTxtPortion );
+ DBG_ASSERT( nTxtPortionStart >= pLine->GetStart(), "Portion doesn't belong to the line!!!" );
+ sal_Int32* pDXArray = const_cast< sal_Int32* >( pLine->GetCharPosArray().GetData()+( nTxtPortionStart-pLine->GetStart() ) );
+ if ( pTP->GetExtraInfos()->pOrgDXArray )
+ memcpy( pDXArray, pTP->GetExtraInfos()->pOrgDXArray, (pTP->GetLen()-1)*sizeof(sal_Int32) );
+ ImplCalcAsianCompression( pParaPortion->GetNode(), pTP, nTxtPortionStart, pDXArray, (USHORT)nCompressPercent, TRUE );
+ }
+ }
+ }
+
+ aCompressedPortions.Remove( 0, aCompressedPortions.Count() );
+}
+
+// redesigned to work with TextMarkingVector
+void ImpEditEngine::ImplFillTextMarkingVector(const lang::Locale& rLocale, EEngineData::TextMarkingVector& rTextMarkingVector, const String& rTxt, const USHORT nIdx, const USHORT nLen) const
+{
+ // determine relevant logical text elements for the just-rendered
+ // string of characters.
+ Reference< i18n::XBreakIterator > _xBI(ImplGetBreakIterator());
+
+ if(_xBI.is())
+ {
+ sal_Int32 nDone;
+ sal_Int32 nNextCellBreak(_xBI->nextCharacters(rTxt, nIdx, rLocale, i18n::CharacterIteratorMode::SKIPCELL, 0, nDone));
+ i18n::Boundary nNextWordBoundary(_xBI->getWordBoundary(rTxt, nIdx, rLocale, i18n::WordType::ANY_WORD, sal_True));
+ sal_Int32 nNextSentenceBreak(_xBI->endOfSentence(rTxt, nIdx, rLocale));
+
+ const sal_Int32 nEndPos(nIdx + nLen);
+ sal_Int32 i;
+
+ for(i = nIdx; i < nEndPos; i++)
+ {
+ // create the entries for the respective break positions
+ if(i == nNextCellBreak)
+ {
+ rTextMarkingVector.push_back(EEngineData::TextMarkingClass(EEngineData::EndOfCaracter, i - nIdx));
+ nNextCellBreak = _xBI->nextCharacters(rTxt, i, rLocale, i18n::CharacterIteratorMode::SKIPCELL, 1, nDone);
+ }
+ if(i == nNextWordBoundary.endPos)
+ {
+ rTextMarkingVector.push_back(EEngineData::TextMarkingClass(EEngineData::EndOfWord, i - nIdx));
+ nNextWordBoundary = _xBI->getWordBoundary(rTxt, i + 1, rLocale, i18n::WordType::ANY_WORD, sal_True);
+ }
+ if(i == nNextSentenceBreak)
+ {
+ rTextMarkingVector.push_back(EEngineData::TextMarkingClass(EEngineData::EndOfSentence, i - nIdx));
+ nNextSentenceBreak = _xBI->endOfSentence(rTxt, i + 1, rLocale);
+ }
+ }
+ }
+}
+
+// eof
diff --git a/editeng/source/editeng/impedit4.cxx b/editeng/source/editeng/impedit4.cxx
new file mode 100644
index 0000000000..1280fecdfd
--- /dev/null
+++ b/editeng/source/editeng/impedit4.cxx
@@ -0,0 +1,2958 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: impedit4.cxx,v $
+ * $Revision: 1.78.54.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <vcl/wrkwin.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+
+#include <svl/srchitem.hxx>
+#include <editeng/lspcitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/tstpitem.hxx>
+
+#include <eertfpar.hxx>
+#include <editeng/editeng.hxx>
+#include <impedit.hxx>
+#include <editeng/editview.hxx>
+#include <eehtml.hxx>
+#include <editobj2.hxx>
+#include <i18npool/lang.h>
+
+#include "editxml.hxx"
+
+#include <editeng/akrnitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/emphitem.hxx>
+#include <textconv.hxx>
+#include <rtl/tencinfo.h>
+#include <svtools/rtfout.hxx>
+#include <edtspell.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <editeng/unolingu.hxx>
+#include <linguistic/lngprops.hxx>
+#include <com/sun/star/linguistic2/XThesaurus.hpp>
+#include <com/sun/star/linguistic2/XMeaning.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <unotools/transliterationwrapper.hxx>
+#include <unotools/textsearch.hxx>
+#include <comphelper/processfactory.hxx>
+#include <vcl/help.hxx>
+#include <svtools/rtfkeywd.hxx>
+#include <editeng/edtdlg.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::linguistic2;
+
+void SwapUSHORTs( sal_uInt16& rX, sal_uInt16& rY )
+{
+ sal_uInt16 n = rX;
+ rX = rY;
+ rY = n;
+}
+
+EditPaM ImpEditEngine::Read( SvStream& rInput, const String& rBaseURL, EETextFormat eFormat, EditSelection aSel, SvKeyValueIterator* pHTTPHeaderAttrs )
+{
+ sal_Bool _bUpdate = GetUpdateMode();
+ SetUpdateMode( sal_False );
+ EditPaM aPaM;
+ if ( eFormat == EE_FORMAT_TEXT )
+ aPaM = ReadText( rInput, aSel );
+ else if ( eFormat == EE_FORMAT_RTF )
+ aPaM = ReadRTF( rInput, aSel );
+ else if ( eFormat == EE_FORMAT_XML )
+ aPaM = ReadXML( rInput, aSel );
+ else if ( eFormat == EE_FORMAT_HTML )
+ aPaM = ReadHTML( rInput, rBaseURL, aSel, pHTTPHeaderAttrs );
+ else if ( eFormat == EE_FORMAT_BIN)
+ aPaM = ReadBin( rInput, aSel );
+ else
+ {
+ DBG_ERROR( "Read: Unbekanntes Format" );
+ }
+
+ FormatFullDoc(); // reicht vielleicht auch ein einfaches Format?
+ SetUpdateMode( _bUpdate );
+
+ return aPaM;
+}
+
+EditPaM ImpEditEngine::ReadText( SvStream& rInput, EditSelection aSel )
+{
+ if ( aSel.HasRange() )
+ aSel = ImpDeleteSelection( aSel );
+ EditPaM aPaM = aSel.Max();
+
+ XubString aTmpStr, aStr;
+ sal_Bool bDone = rInput.ReadByteStringLine( aTmpStr );
+ while ( bDone )
+ {
+ aTmpStr.Erase( MAXCHARSINPARA );
+ aPaM = ImpInsertText( EditSelection( aPaM, aPaM ), aTmpStr );
+ aPaM = ImpInsertParaBreak( aPaM );
+ bDone = rInput.ReadByteStringLine( aTmpStr );
+ }
+ return aPaM;
+}
+
+EditPaM ImpEditEngine::ReadXML( SvStream& rInput, EditSelection aSel )
+{
+#ifndef SVX_LIGHT
+ if ( aSel.HasRange() )
+ aSel = ImpDeleteSelection( aSel );
+
+ ESelection aESel = CreateESel( aSel );
+
+ ::SvxReadXML( *GetEditEnginePtr(), rInput, aESel );
+
+ return aSel.Max();
+#else
+ return EditPaM();
+#endif
+}
+
+EditPaM ImpEditEngine::ReadRTF( SvStream& rInput, EditSelection aSel )
+{
+#ifndef SVX_LIGHT
+
+#if defined (EDITDEBUG) && !defined( UNX )
+ SvFileStream aRTFOut( String( RTL_CONSTASCII_USTRINGPARAM ( "d:\\rtf_in.rtf" ) ), STREAM_WRITE );
+ aRTFOut << rInput;
+ aRTFOut.Close();
+ rInput.Seek( 0 );
+#endif
+ if ( aSel.HasRange() )
+ aSel = ImpDeleteSelection( aSel );
+
+// sal_Bool bCharsBeforeInsertPos = ( aSel.Min().GetIndex() ) ? sal_True : sal_False;
+// sal_Bool bCharsBehindInsertPos = ( aSel.Min().GetIndex() < aSel.Min().GetNode()->Len() ) ? sal_True : sal_False;
+
+ // Der SvRTF-Parser erwartet, dass das Which-Mapping am uebergebenen Pool,
+ // nicht an einem Secondary haengt.
+ SfxItemPool* pPool = &aEditDoc.GetItemPool();
+ while ( pPool->GetSecondaryPool() && !pPool->GetName().EqualsAscii( "EditEngineItemPool" ) )
+ {
+ pPool = pPool->GetSecondaryPool();
+
+ }
+ DBG_ASSERT( pPool && pPool->GetName().EqualsAscii( "EditEngineItemPool" ), "ReadRTF: Kein EditEnginePool!" );
+
+ EditRTFParserRef xPrsr = new EditRTFParser( rInput, aSel, *pPool, this );
+ SvParserState eState = xPrsr->CallParser();
+ if ( ( eState != SVPAR_ACCEPTED ) && ( !rInput.GetError() ) )
+ {
+ rInput.SetError( EE_READWRITE_WRONGFORMAT );
+ return aSel.Min();
+ }
+ return xPrsr->GetCurPaM();
+#else
+ return EditPaM();
+#endif
+}
+
+EditPaM ImpEditEngine::ReadHTML( SvStream& rInput, const String& rBaseURL, EditSelection aSel, SvKeyValueIterator* pHTTPHeaderAttrs )
+{
+#ifndef SVX_LIGHT
+
+ if ( aSel.HasRange() )
+ aSel = ImpDeleteSelection( aSel );
+
+// sal_Bool bCharsBeforeInsertPos = ( aSel.Min().GetIndex() ) ? sal_True : sal_False;
+// sal_Bool bCharsBehindInsertPos = ( aSel.Min().GetIndex() < aSel.Min().GetNode()->Len() ) ? sal_True : sal_False;
+
+ EditHTMLParserRef xPrsr = new EditHTMLParser( rInput, rBaseURL, pHTTPHeaderAttrs );
+ SvParserState eState = xPrsr->CallParser( this, aSel.Max() );
+ if ( ( eState != SVPAR_ACCEPTED ) && ( !rInput.GetError() ) )
+ {
+ rInput.SetError( EE_READWRITE_WRONGFORMAT );
+ return aSel.Min();
+ }
+ return xPrsr->GetCurSelection().Max();
+#else
+ return EditPaM();
+#endif
+}
+
+EditPaM ImpEditEngine::ReadBin( SvStream& rInput, EditSelection aSel )
+{
+ // Einfach ein temporaeres TextObject missbrauchen...
+ EditTextObject* pObj = EditTextObject::Create( rInput, NULL );
+
+ EditPaM aLastPaM = aSel.Max();
+ if ( pObj )
+ aLastPaM = InsertText( *pObj, aSel ).Max();
+
+ delete pObj;
+ return aLastPaM;
+}
+
+#ifndef SVX_LIGHT
+void ImpEditEngine::Write( SvStream& rOutput, EETextFormat eFormat, EditSelection aSel )
+{
+ if ( !rOutput.IsWritable() )
+ rOutput.SetError( SVSTREAM_WRITE_ERROR );
+
+ if ( !rOutput.GetError() )
+ {
+ if ( eFormat == EE_FORMAT_TEXT )
+ WriteText( rOutput, aSel );
+ else if ( eFormat == EE_FORMAT_RTF )
+ WriteRTF( rOutput, aSel );
+ else if ( eFormat == EE_FORMAT_XML )
+ WriteXML( rOutput, aSel );
+ else if ( eFormat == EE_FORMAT_HTML )
+ WriteHTML( rOutput, aSel );
+ else if ( eFormat == EE_FORMAT_BIN)
+ WriteBin( rOutput, aSel );
+ else
+ {
+ DBG_ERROR( "Write: Unbekanntes Format" );
+ }
+ }
+}
+#endif
+
+sal_uInt32 ImpEditEngine::WriteText( SvStream& rOutput, EditSelection aSel )
+{
+ sal_uInt16 nStartNode, nEndNode;
+ sal_Bool bRange = aSel.HasRange();
+ if ( bRange )
+ {
+ aSel.Adjust( aEditDoc );
+ nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
+ nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
+ }
+ else
+ {
+ nStartNode = 0;
+ nEndNode = aEditDoc.Count()-1;
+ }
+
+ // ueber die Absaetze iterieren...
+ for ( sal_uInt16 nNode = nStartNode; nNode <= nEndNode; nNode++ )
+ {
+ ContentNode* pNode = aEditDoc.GetObject( nNode );
+ DBG_ASSERT( pNode, "Node nicht gefunden: Search&Replace" );
+
+ sal_uInt16 nStartPos = 0;
+ sal_uInt16 nEndPos = pNode->Len();
+ if ( bRange )
+ {
+ if ( nNode == nStartNode )
+ nStartPos = aSel.Min().GetIndex();
+ if ( nNode == nEndNode ) // kann auch == nStart sein!
+ nEndPos = aSel.Max().GetIndex();
+ }
+ XubString aTmpStr = aEditDoc.GetParaAsString( pNode, nStartPos, nEndPos );
+ rOutput.WriteByteStringLine( aTmpStr );
+ }
+
+ return rOutput.GetError();
+}
+
+sal_Bool ImpEditEngine::WriteItemListAsRTF( ItemList& rLst, SvStream& rOutput, sal_uInt16 nPara, sal_uInt16 nPos,
+ SvxFontTable& rFontTable, SvxColorList& rColorList )
+{
+ const SfxPoolItem* pAttrItem = rLst.First();
+ while ( pAttrItem )
+ {
+ WriteItemAsRTF( *pAttrItem, rOutput, nPara, nPos,rFontTable, rColorList );
+ pAttrItem = rLst.Next();
+ }
+ return ( rLst.Count() ? sal_True : sal_False );
+}
+
+void lcl_FindValidAttribs( ItemList& rLst, ContentNode* pNode, sal_uInt16 nIndex, USHORT nScriptType )
+{
+ sal_uInt16 nAttr = 0;
+ EditCharAttrib* pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
+ while ( pAttr && ( pAttr->GetStart() <= nIndex ) )
+ {
+ // Start wird in While ueberprueft...
+ if ( pAttr->GetEnd() > nIndex )
+ {
+ if ( IsScriptItemValid( pAttr->GetItem()->Which(), nScriptType ) )
+ rLst.Insert( pAttr->GetItem(), LIST_APPEND );
+ }
+ nAttr++;
+ pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
+ }
+}
+
+sal_uInt32 ImpEditEngine::WriteBin( SvStream& rOutput, EditSelection aSel, BOOL bStoreUnicodeStrings ) const
+{
+ BinTextObject* pObj = (BinTextObject*)CreateBinTextObject( aSel, NULL );
+ pObj->StoreUnicodeStrings( bStoreUnicodeStrings );
+ pObj->Store( rOutput );
+ delete pObj;
+ return 0;
+}
+
+#ifndef SVX_LIGHT
+sal_uInt32 ImpEditEngine::WriteXML( SvStream& rOutput, EditSelection aSel )
+{
+ ESelection aESel = CreateESel( aSel );
+
+ SvxWriteXML( *GetEditEnginePtr(), rOutput, aESel );
+
+ return 0;
+}
+#endif
+
+static sal_uInt16 getStylePos( const SfxStyles& rStyles, SfxStyleSheet* pSheet )
+{
+ sal_uInt16 nNumber = 0;
+ SfxStyles::const_iterator iter( rStyles.begin() );
+ while( iter != rStyles.end() )
+ {
+ if( (*iter++).get() == pSheet )
+ return nNumber;
+ ++nNumber;
+ }
+ return 0;
+}
+
+sal_uInt32 ImpEditEngine::WriteRTF( SvStream& rOutput, EditSelection aSel )
+{
+#ifndef SVX_LIGHT
+ DBG_ASSERT( GetUpdateMode(), "WriteRTF bei UpdateMode = sal_False!" );
+ CheckIdleFormatter();
+ if ( !IsFormatted() )
+ FormatDoc();
+
+ sal_uInt16 nStartNode, nEndNode;
+ aSel.Adjust( aEditDoc );
+
+ nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
+ nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
+
+ // RTF-Vorspann...
+ rOutput << '{' ;
+
+ rOutput << OOO_STRING_SVTOOLS_RTF_RTF;
+
+ rOutput << OOO_STRING_SVTOOLS_RTF_ANSI;
+ rtl_TextEncoding eDestEnc = RTL_TEXTENCODING_MS_1252;
+
+ // Fonttabelle erzeugen und rausschreiben...
+ SvxFontTable aFontTable;
+ // DefaultFont muss ganz vorne stehen, damit DEF-Font im RTF
+ aFontTable.Insert( 0, new SvxFontItem( (const SvxFontItem&)aEditDoc.GetItemPool().GetDefaultItem( EE_CHAR_FONTINFO ) ) );
+ aFontTable.Insert( 1, new SvxFontItem( (const SvxFontItem&)aEditDoc.GetItemPool().GetDefaultItem( EE_CHAR_FONTINFO_CJK ) ) );
+ aFontTable.Insert( 2, new SvxFontItem( (const SvxFontItem&)aEditDoc.GetItemPool().GetDefaultItem( EE_CHAR_FONTINFO_CTL ) ) );
+ for ( USHORT nScriptType = 0; nScriptType < 3; nScriptType++ )
+ {
+ USHORT nWhich = EE_CHAR_FONTINFO;
+ if ( nScriptType == 1 )
+ nWhich = EE_CHAR_FONTINFO_CJK;
+ else if ( nScriptType == 2 )
+ nWhich = EE_CHAR_FONTINFO_CTL;
+
+ sal_uInt16 i = 0;
+ SvxFontItem* pFontItem = (SvxFontItem*)aEditDoc.GetItemPool().GetItem( nWhich, i );
+ while ( pFontItem )
+ {
+ bool bAlreadyExist = false;
+ ULONG nTestMax = nScriptType ? aFontTable.Count() : 1;
+ for ( ULONG nTest = 0; !bAlreadyExist && ( nTest < nTestMax ); nTest++ )
+ {
+ bAlreadyExist = *aFontTable.Get( nTest ) == *pFontItem;
+ }
+
+ if ( !bAlreadyExist )
+ aFontTable.Insert( aFontTable.Count(), new SvxFontItem( *pFontItem ) );
+
+ pFontItem = (SvxFontItem*)aEditDoc.GetItemPool().GetItem( nWhich, ++i );
+ }
+ }
+
+ rOutput << endl << '{' << OOO_STRING_SVTOOLS_RTF_FONTTBL;
+ sal_uInt16 j;
+ for ( j = 0; j < aFontTable.Count(); j++ )
+ {
+ SvxFontItem* pFontItem = aFontTable.Get( j );
+ rOutput << '{';
+ rOutput << OOO_STRING_SVTOOLS_RTF_F;
+ rOutput.WriteNumber( j );
+ switch ( pFontItem->GetFamily() )
+ {
+ case FAMILY_DONTKNOW: rOutput << OOO_STRING_SVTOOLS_RTF_FNIL;
+ break;
+ case FAMILY_DECORATIVE: rOutput << OOO_STRING_SVTOOLS_RTF_FDECOR;
+ break;
+ case FAMILY_MODERN: rOutput << OOO_STRING_SVTOOLS_RTF_FMODERN;
+ break;
+ case FAMILY_ROMAN: rOutput << OOO_STRING_SVTOOLS_RTF_FROMAN;
+ break;
+ case FAMILY_SCRIPT: rOutput << OOO_STRING_SVTOOLS_RTF_FSCRIPT;
+ break;
+ case FAMILY_SWISS: rOutput << OOO_STRING_SVTOOLS_RTF_FSWISS;
+ break;
+ default:
+ break;
+ }
+ rOutput << OOO_STRING_SVTOOLS_RTF_FPRQ;
+ sal_uInt16 nVal = 0;
+ switch( pFontItem->GetPitch() )
+ {
+ case PITCH_FIXED: nVal = 1; break;
+ case PITCH_VARIABLE: nVal = 2; break;
+ default:
+ break;
+ }
+ rOutput.WriteNumber( nVal );
+
+ CharSet eChrSet = pFontItem->GetCharSet();
+ DBG_ASSERT( eChrSet != 9, "SystemCharSet?!" );
+ if( RTL_TEXTENCODING_DONTKNOW == eChrSet )
+ eChrSet = gsl_getSystemTextEncoding();
+ rOutput << OOO_STRING_SVTOOLS_RTF_FCHARSET;
+ rOutput.WriteNumber( rtl_getBestWindowsCharsetFromTextEncoding( eChrSet ) );
+
+ rOutput << ' ';
+ RTFOutFuncs::Out_String( rOutput, pFontItem->GetFamilyName(), eDestEnc );
+ rOutput << ";}";
+ }
+ rOutput << '}';
+ rOutput << endl;
+
+ // ColorList rausschreiben...
+ SvxColorList aColorList;
+ sal_uInt16 i = 0;
+ SvxColorItem* pColorItem = (SvxColorItem*)aEditDoc.GetItemPool().GetItem( EE_CHAR_COLOR, i );
+ while ( pColorItem )
+ {
+ USHORT nPos = i;
+ if ( pColorItem->GetValue() == COL_AUTO )
+ nPos = 0;
+ aColorList.Insert( new SvxColorItem( *pColorItem ), nPos );
+ pColorItem = (SvxColorItem*)aEditDoc.GetItemPool().GetItem( EE_CHAR_COLOR, ++i );
+ }
+ aColorList.Insert( new SvxColorItem( (const SvxColorItem&)aEditDoc.GetItemPool().GetDefaultItem( EE_CHAR_COLOR) ), (sal_uInt32)i );
+
+ rOutput << '{' << OOO_STRING_SVTOOLS_RTF_COLORTBL;
+ for ( j = 0; j < aColorList.Count(); j++ )
+ {
+ pColorItem = aColorList.GetObject( j );
+ if ( !j || ( pColorItem->GetValue() != COL_AUTO ) )
+ {
+ rOutput << OOO_STRING_SVTOOLS_RTF_RED;
+ rOutput.WriteNumber( pColorItem->GetValue().GetRed() );
+ rOutput << OOO_STRING_SVTOOLS_RTF_GREEN;
+ rOutput.WriteNumber( pColorItem->GetValue().GetGreen() );
+ rOutput << OOO_STRING_SVTOOLS_RTF_BLUE;
+ rOutput.WriteNumber( pColorItem->GetValue().GetBlue() );
+ }
+ rOutput << ';';
+ }
+ rOutput << '}';
+ rOutput << endl;
+
+ // StyleSheets...
+ if ( GetStyleSheetPool() )
+ {
+ sal_uInt16 nStyles = (sal_uInt16)GetStyleSheetPool()->GetStyles().size();
+ if ( nStyles )
+ {
+ rOutput << '{' << OOO_STRING_SVTOOLS_RTF_STYLESHEET;
+
+ for ( sal_uInt16 nStyle = 0; nStyle < nStyles; nStyle++ )
+ {
+
+ SfxStyleSheet* pStyle = (SfxStyleSheet*)GetStyleSheetPool()->GetStyles()[ nStyle ].get();
+
+ rOutput << endl << '{' << OOO_STRING_SVTOOLS_RTF_S;
+ sal_uInt16 nNumber = (sal_uInt16) (nStyle + 1);
+ rOutput.WriteNumber( nNumber );
+
+ // Attribute, auch aus Parent!
+ for ( sal_uInt16 nParAttr = EE_PARA_START; nParAttr <= EE_CHAR_END; nParAttr++ )
+ {
+ if ( pStyle->GetItemSet().GetItemState( nParAttr ) == SFX_ITEM_ON )
+ {
+ const SfxPoolItem& rItem = pStyle->GetItemSet().Get( nParAttr );
+ WriteItemAsRTF( rItem, rOutput, 0, 0, aFontTable, aColorList );
+ }
+ }
+
+ // Parent...(nur wenn noetig)
+ if ( pStyle->GetParent().Len() && ( pStyle->GetParent() != pStyle->GetName() ) )
+ {
+ SfxStyleSheet* pParent = (SfxStyleSheet*)GetStyleSheetPool()->Find( pStyle->GetParent(), pStyle->GetFamily() );
+ DBG_ASSERT( pParent, "Parent nicht gefunden!" );
+ rOutput << OOO_STRING_SVTOOLS_RTF_SBASEDON;
+ nNumber = (sal_uInt16) getStylePos( GetStyleSheetPool()->GetStyles(), pParent ) + 1;
+ rOutput.WriteNumber( nNumber );
+ }
+
+ // Folgevorlage...(immer)
+ SfxStyleSheet* pNext = pStyle;
+ if ( pStyle->GetFollow().Len() && ( pStyle->GetFollow() != pStyle->GetName() ) )
+ pNext = (SfxStyleSheet*)GetStyleSheetPool()->Find( pStyle->GetFollow(), pStyle->GetFamily() );
+
+ DBG_ASSERT( pNext, "Naechsten nicht gefunden!" );
+ rOutput << OOO_STRING_SVTOOLS_RTF_SNEXT;
+ nNumber = (sal_uInt16) getStylePos( GetStyleSheetPool()->GetStyles(), pNext ) + 1;
+ rOutput.WriteNumber( nNumber );
+
+ // Namen der Vorlage...
+ rOutput << " " << ByteString( pStyle->GetName(), eDestEnc ).GetBuffer();
+ rOutput << ";}";
+ }
+ rOutput << '}';
+ rOutput << endl;
+ }
+ }
+
+ // Die Pool-Defaults vorweg schreiben...
+ rOutput << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << "\\EditEnginePoolDefaults";
+ for ( sal_uInt16 nPoolDefItem = EE_PARA_START; nPoolDefItem <= EE_CHAR_END; nPoolDefItem++)
+ {
+ const SfxPoolItem& rItem = aEditDoc.GetItemPool().GetDefaultItem( nPoolDefItem );
+ WriteItemAsRTF( rItem, rOutput, 0, 0, aFontTable, aColorList );
+ }
+ rOutput << '}' << endl;
+
+ // Def-Hoehe vorweg, da sonst 12Pt
+ // Doch nicht, onst in jedem Absatz hart!
+ // SfxItemSet aTmpSet( GetEmptyItemSet() );
+ // const SvxFontHeightItem& rDefFontHeight = (const SvxFontHeightItem&)aTmpSet.Get( EE_CHAR_FONTHEIGHT );
+ // WriteItemAsRTF( rDefFontHeight, rOutput, aFontTable, aColorList );
+ // rOutput << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << "\\EditEnginePoolDefaultHeight}" << endl;
+
+ // DefTab:
+ MapMode aTwpMode( MAP_TWIP );
+ sal_uInt16 nDefTabTwps = (sal_uInt16) GetRefDevice()->LogicToLogic(
+ Point( aEditDoc.GetDefTab(), 0 ),
+ &GetRefMapMode(), &aTwpMode ).X();
+ rOutput << OOO_STRING_SVTOOLS_RTF_DEFTAB;
+ rOutput.WriteNumber( nDefTabTwps );
+ rOutput << endl;
+
+ // ueber die Absaetze iterieren...
+ rOutput << '{' << endl;
+ for ( sal_uInt16 nNode = nStartNode; nNode <= nEndNode; nNode++ )
+ {
+ ContentNode* pNode = aEditDoc.SaveGetObject( nNode );
+ DBG_ASSERT( pNode, "Node nicht gefunden: Search&Replace" );
+
+ // Die Absatzattribute vorweg...
+ sal_Bool bAttr = sal_False;
+
+ // Vorlage ?
+ if ( pNode->GetStyleSheet() )
+ {
+ // Nummer der Vorlage
+ rOutput << OOO_STRING_SVTOOLS_RTF_S;
+ sal_uInt16 nNumber = (sal_uInt16) getStylePos( GetStyleSheetPool()->GetStyles(), pNode->GetStyleSheet() ) + 1;
+ rOutput.WriteNumber( nNumber );
+
+ // Alle Attribute
+ // Attribute, auch aus Parent!
+ for ( sal_uInt16 nParAttr = EE_PARA_START; nParAttr <= EE_CHAR_END; nParAttr++ )
+ {
+ if ( pNode->GetStyleSheet()->GetItemSet().GetItemState( nParAttr ) == SFX_ITEM_ON )
+ {
+ const SfxPoolItem& rItem = pNode->GetStyleSheet()->GetItemSet().Get( nParAttr );
+ WriteItemAsRTF( rItem, rOutput, nNode, 0, aFontTable, aColorList );
+ bAttr = sal_True;
+ }
+ }
+ }
+
+ for ( sal_uInt16 nParAttr = EE_PARA_START; nParAttr <= EE_CHAR_END; nParAttr++ )
+ {
+// const SfxPoolItem& rItem = pNode->GetContentAttribs().GetItem( nParAttr );
+ // Jetzt, wo StyleSheet-Verarbeitung, nur noch harte Absatzattribute!
+ if ( pNode->GetContentAttribs().GetItems().GetItemState( nParAttr ) == SFX_ITEM_ON )
+ {
+ const SfxPoolItem& rItem = pNode->GetContentAttribs().GetItems().Get( nParAttr );
+ WriteItemAsRTF( rItem, rOutput, nNode, 0, aFontTable, aColorList );
+ bAttr = sal_True;
+ }
+ }
+ if ( bAttr )
+ rOutput << ' '; // Separator
+
+ ItemList aAttribItems;
+ ParaPortion* pParaPortion = FindParaPortion( pNode );
+ DBG_ASSERT( pParaPortion, "Portion nicht gefunden: WriteRTF" );
+
+ sal_uInt16 nIndex = 0;
+ sal_uInt16 nStartPos = 0;
+ sal_uInt16 nEndPos = pNode->Len();
+ sal_uInt16 nStartPortion = 0;
+ sal_uInt16 nEndPortion = (sal_uInt16)pParaPortion->GetTextPortions().Count() - 1;
+ sal_Bool bFinishPortion = sal_False;
+ sal_uInt16 nPortionStart;
+
+ if ( nNode == nStartNode )
+ {
+ nStartPos = aSel.Min().GetIndex();
+ nStartPortion = pParaPortion->GetTextPortions().FindPortion( nStartPos, nPortionStart );
+ if ( nStartPos != 0 )
+ {
+ aAttribItems.Clear();
+ lcl_FindValidAttribs( aAttribItems, pNode, nStartPos, GetScriptType( EditPaM( pNode, 0 ) ) );
+ if ( aAttribItems.Count() )
+ {
+ // Diese Attribute duerfen nicht fuer den gesamten
+ // Absatz gelten:
+ rOutput << '{';
+ WriteItemListAsRTF( aAttribItems, rOutput, nNode, nStartPos, aFontTable, aColorList );
+ bFinishPortion = sal_True;
+ }
+ aAttribItems.Clear();
+ }
+ }
+ if ( nNode == nEndNode ) // kann auch == nStart sein!
+ {
+ nEndPos = aSel.Max().GetIndex();
+ nEndPortion = pParaPortion->GetTextPortions().FindPortion( nEndPos, nPortionStart );
+ }
+
+ EditCharAttrib* pNextFeature = pNode->GetCharAttribs().FindFeature( nIndex );
+ // Bei 0 anfangen, damit der Index richtig ist...
+
+ for ( sal_uInt16 n = 0; n <= nEndPortion; n++ )
+ {
+ TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject(n);
+ if ( n < nStartPortion )
+ {
+ nIndex = nIndex + pTextPortion->GetLen();
+ continue;
+ }
+
+ if ( pNextFeature && ( pNextFeature->GetStart() == nIndex ) && ( pNextFeature->GetItem()->Which() != EE_FEATURE_FIELD ) )
+ {
+ WriteItemAsRTF( *pNextFeature->GetItem(), rOutput, nNode, nIndex, aFontTable, aColorList );
+ pNextFeature = pNode->GetCharAttribs().FindFeature( pNextFeature->GetStart() + 1 );
+ }
+ else
+ {
+ aAttribItems.Clear();
+ USHORT nScriptType = GetScriptType( EditPaM( pNode, nIndex+1 ) );
+ if ( !n || IsScriptChange( EditPaM( pNode, nIndex ) ) )
+ {
+ SfxItemSet aAttribs = GetAttribs( nNode, nIndex+1, nIndex+1 );
+ aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_FONTINFO, nScriptType ) ), LIST_APPEND );
+ aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_FONTHEIGHT, nScriptType ) ), LIST_APPEND );
+ aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_WEIGHT, nScriptType ) ), LIST_APPEND );
+ aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_ITALIC, nScriptType ) ), LIST_APPEND );
+ aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_LANGUAGE, nScriptType ) ), LIST_APPEND );
+ }
+ // #96298# Insert hard attribs AFTER CJK attribs...
+ lcl_FindValidAttribs( aAttribItems, pNode, nIndex, nScriptType );
+
+ rOutput << '{';
+ if ( WriteItemListAsRTF( aAttribItems, rOutput, nNode, nIndex, aFontTable, aColorList ) )
+ rOutput << ' ';
+
+ USHORT nS = nIndex;
+ USHORT nE = nIndex + pTextPortion->GetLen();
+ if ( n == nStartPortion )
+ nS = nStartPos;
+ if ( n == nEndPortion )
+ nE = nEndPos;
+
+ XubString aRTFStr = aEditDoc.GetParaAsString( pNode, nS, nE);
+ RTFOutFuncs::Out_String( rOutput, aRTFStr, eDestEnc );
+ rOutput << '}';
+ }
+ if ( bFinishPortion )
+ {
+ rOutput << '}';
+ bFinishPortion = sal_False;
+ }
+
+ nIndex = nIndex + pTextPortion->GetLen();
+ }
+
+ rOutput << OOO_STRING_SVTOOLS_RTF_PAR << OOO_STRING_SVTOOLS_RTF_PARD << OOO_STRING_SVTOOLS_RTF_PLAIN;;
+ rOutput << endl;
+ }
+ // RTF-Nachspann...
+ rOutput << "}}"; // 1xKlammerung Absaetze, 1x Klammerung RTF-Dokument
+ rOutput.Flush();
+
+#if defined (EDITDEBUG) && !defined( UNX )
+ {
+ SvFileStream aStream( String( RTL_CONSTASCII_USTRINGPARAM ( "d:\\rtf_out.rtf" ) ), STREAM_WRITE|STREAM_TRUNC );
+ ULONG nP = rOutput.Tell();
+ rOutput.Seek( 0 );
+ aStream << rOutput;
+ rOutput.Seek( nP );
+ }
+#endif
+
+ return rOutput.GetError();
+#else
+ return 0;
+#endif
+}
+
+
+void ImpEditEngine::WriteItemAsRTF( const SfxPoolItem& rItem, SvStream& rOutput, sal_uInt16 nPara, sal_uInt16 nPos,
+ SvxFontTable& rFontTable, SvxColorList& rColorList )
+{
+ sal_uInt16 nWhich = rItem.Which();
+ switch ( nWhich )
+ {
+ case EE_PARA_WRITINGDIR:
+ {
+ const SvxFrameDirectionItem& rWritingMode = (const SvxFrameDirectionItem&)rItem;
+ if ( rWritingMode.GetValue() == FRMDIR_HORI_RIGHT_TOP )
+ rOutput << "\\rtlpar";
+ else
+ rOutput << "\\ltrpar";
+ }
+ break;
+ case EE_PARA_OUTLLEVEL:
+ {
+ sal_Int16 nLevel = ((const SfxInt16Item&)rItem).GetValue();
+ if( nLevel >= 0 )
+ {
+ rOutput << "\\level";
+ rOutput.WriteNumber( nLevel );
+ }
+ }
+ break;
+ case EE_PARA_OUTLLRSPACE:
+ case EE_PARA_LRSPACE:
+ {
+// const ContentNode *pNode = aEditDoc.GetObject( nPara );
+
+ rOutput << OOO_STRING_SVTOOLS_RTF_FI;
+ short nTxtFirst = ((const SvxLRSpaceItem&)rItem).GetTxtFirstLineOfst();
+ nTxtFirst = (short)LogicToTwips( nTxtFirst );
+ rOutput.WriteNumber( nTxtFirst );
+ rOutput << OOO_STRING_SVTOOLS_RTF_LI;
+ sal_uInt16 nTxtLeft = static_cast< sal_uInt16 >(((const SvxLRSpaceItem&)rItem).GetTxtLeft());
+ nTxtLeft = (sal_uInt16)LogicToTwips( nTxtLeft );
+ rOutput.WriteNumber( nTxtLeft );
+ rOutput << OOO_STRING_SVTOOLS_RTF_RI;
+ sal_uInt32 nTxtRight = ((const SvxLRSpaceItem&)rItem).GetRight();
+ nTxtRight = LogicToTwips( nTxtRight);
+ rOutput.WriteNumber( nTxtRight );
+ }
+ break;
+ case EE_PARA_ULSPACE:
+ {
+ rOutput << OOO_STRING_SVTOOLS_RTF_SB;
+ sal_uInt16 nUpper = ((const SvxULSpaceItem&)rItem).GetUpper();
+ nUpper = (sal_uInt16)LogicToTwips( nUpper );
+ rOutput.WriteNumber( nUpper );
+ rOutput << OOO_STRING_SVTOOLS_RTF_SA;
+ sal_uInt16 nLower = ((const SvxULSpaceItem&)rItem).GetLower();
+ nLower = (sal_uInt16)LogicToTwips( nLower );
+ rOutput.WriteNumber( nLower );
+ }
+ break;
+ case EE_PARA_SBL:
+ {
+ rOutput << OOO_STRING_SVTOOLS_RTF_SL;
+ long nVal = ((const SvxLineSpacingItem&)rItem).GetLineHeight();
+ char cMult = '0';
+ if ( ((const SvxLineSpacingItem&)rItem).GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP )
+ {
+ // Woher kriege ich jetzt den Wert?
+ // Der SwRTF-Parser geht von einem 240er Font aus!
+ nVal = ((const SvxLineSpacingItem&)rItem).GetPropLineSpace();
+ nVal *= 240;
+ nVal /= 100;
+ cMult = '1';
+ }
+ rOutput.WriteNumber( nVal );
+ rOutput << OOO_STRING_SVTOOLS_RTF_SLMULT << cMult;
+ }
+ break;
+ case EE_PARA_JUST:
+ {
+ SvxAdjust eJustification = ((const SvxAdjustItem&)rItem).GetAdjust();
+ switch ( eJustification )
+ {
+ case SVX_ADJUST_CENTER: rOutput << OOO_STRING_SVTOOLS_RTF_QC;
+ break;
+ case SVX_ADJUST_RIGHT: rOutput << OOO_STRING_SVTOOLS_RTF_QR;
+ break;
+ default: rOutput << OOO_STRING_SVTOOLS_RTF_QL;
+ break;
+ }
+ }
+ break;
+ case EE_PARA_TABS:
+ {
+ const SvxTabStopItem& rTabs = (const SvxTabStopItem&) rItem;
+ for ( sal_uInt16 i = 0; i < rTabs.Count(); i++ )
+ {
+ const SvxTabStop& rTab = rTabs[i];
+ rOutput << OOO_STRING_SVTOOLS_RTF_TX;
+ rOutput.WriteNumber( LogicToTwips( rTab.GetTabPos() ) );
+ }
+ }
+ break;
+ case EE_CHAR_COLOR:
+ {
+ sal_uInt32 n = rColorList.GetId( (const SvxColorItem&)rItem );
+ rOutput << OOO_STRING_SVTOOLS_RTF_CF;
+ rOutput.WriteNumber( n );
+ }
+ break;
+ case EE_CHAR_FONTINFO:
+ case EE_CHAR_FONTINFO_CJK:
+ case EE_CHAR_FONTINFO_CTL:
+ {
+ sal_uInt32 n = rFontTable.GetId( (const SvxFontItem&)rItem );
+ rOutput << OOO_STRING_SVTOOLS_RTF_F;
+ rOutput.WriteNumber( n );
+ }
+ break;
+ case EE_CHAR_FONTHEIGHT:
+ case EE_CHAR_FONTHEIGHT_CJK:
+ case EE_CHAR_FONTHEIGHT_CTL:
+ {
+ rOutput << OOO_STRING_SVTOOLS_RTF_FS;
+ long nHeight = ((const SvxFontHeightItem&)rItem).GetHeight();
+ nHeight = LogicToTwips( nHeight );
+ // Twips => HalfPoints
+ nHeight /= 10;
+ rOutput.WriteNumber( nHeight );
+ }
+ break;
+ case EE_CHAR_WEIGHT:
+ case EE_CHAR_WEIGHT_CJK:
+ case EE_CHAR_WEIGHT_CTL:
+ {
+ FontWeight e = ((const SvxWeightItem&)rItem).GetWeight();
+ switch ( e )
+ {
+ case WEIGHT_BOLD: rOutput << OOO_STRING_SVTOOLS_RTF_B; break;
+ default: rOutput << OOO_STRING_SVTOOLS_RTF_B << '0'; break;
+ }
+ }
+ break;
+ case EE_CHAR_UNDERLINE:
+ {
+ // muesste bei WordLineMode ggf. ulw werden,
+ // aber die Information fehlt hier
+ FontUnderline e = ((const SvxUnderlineItem&)rItem).GetLineStyle();
+ switch ( e )
+ {
+ case UNDERLINE_NONE: rOutput << OOO_STRING_SVTOOLS_RTF_ULNONE; break;
+ case UNDERLINE_SINGLE: rOutput << OOO_STRING_SVTOOLS_RTF_UL; break;
+ case UNDERLINE_DOUBLE: rOutput << OOO_STRING_SVTOOLS_RTF_ULDB; break;
+ case UNDERLINE_DOTTED: rOutput << OOO_STRING_SVTOOLS_RTF_ULD; break;
+ default:
+ break;
+ }
+ }
+ break;
+ case EE_CHAR_OVERLINE:
+ {
+ FontUnderline e = ((const SvxOverlineItem&)rItem).GetLineStyle();
+ switch ( e )
+ {
+ case UNDERLINE_NONE: rOutput << OOO_STRING_SVTOOLS_RTF_OLNONE; break;
+ case UNDERLINE_SINGLE: rOutput << OOO_STRING_SVTOOLS_RTF_OL; break;
+ case UNDERLINE_DOUBLE: rOutput << OOO_STRING_SVTOOLS_RTF_OLDB; break;
+ case UNDERLINE_DOTTED: rOutput << OOO_STRING_SVTOOLS_RTF_OLD; break;
+ default:
+ break;
+ }
+ }
+ break;
+ case EE_CHAR_STRIKEOUT:
+ {
+ FontStrikeout e = ((const SvxCrossedOutItem&)rItem).GetStrikeout();
+ switch ( e )
+ {
+ case STRIKEOUT_SINGLE:
+ case STRIKEOUT_DOUBLE: rOutput << OOO_STRING_SVTOOLS_RTF_STRIKE; break;
+ case STRIKEOUT_NONE: rOutput << OOO_STRING_SVTOOLS_RTF_STRIKE << '0'; break;
+ default:
+ break;
+ }
+ }
+ break;
+ case EE_CHAR_ITALIC:
+ case EE_CHAR_ITALIC_CJK:
+ case EE_CHAR_ITALIC_CTL:
+ {
+ FontItalic e = ((const SvxPostureItem&)rItem).GetPosture();
+ switch ( e )
+ {
+ case ITALIC_OBLIQUE:
+ case ITALIC_NORMAL: rOutput << OOO_STRING_SVTOOLS_RTF_I; break;
+ case ITALIC_NONE: rOutput << OOO_STRING_SVTOOLS_RTF_I << '0'; break;
+ default:
+ break;
+ }
+ }
+ break;
+ case EE_CHAR_OUTLINE:
+ {
+ rOutput << OOO_STRING_SVTOOLS_RTF_OUTL;
+ if ( ((const SvxContourItem&)rItem).GetValue() == 0 )
+ rOutput << '0';
+ }
+ break;
+ case EE_CHAR_RELIEF:
+ {
+ USHORT nRelief = ((const SvxCharReliefItem&)rItem).GetValue();
+ if ( nRelief == RELIEF_EMBOSSED )
+ rOutput << OOO_STRING_SVTOOLS_RTF_EMBO;
+ if ( nRelief == RELIEF_ENGRAVED )
+ rOutput << OOO_STRING_SVTOOLS_RTF_IMPR;
+ }
+ break;
+ case EE_CHAR_EMPHASISMARK:
+ {
+ USHORT nMark = ((const SvxEmphasisMarkItem&)rItem).GetValue();
+ if ( nMark == EMPHASISMARK_NONE )
+ rOutput << OOO_STRING_SVTOOLS_RTF_ACCNONE;
+ else if ( nMark == EMPHASISMARK_SIDE_DOTS )
+ rOutput << OOO_STRING_SVTOOLS_RTF_ACCCOMMA;
+ else
+ rOutput << OOO_STRING_SVTOOLS_RTF_ACCDOT;
+ }
+ break;
+ case EE_CHAR_SHADOW:
+ {
+ rOutput << OOO_STRING_SVTOOLS_RTF_SHAD;
+ if ( ((const SvxShadowedItem&)rItem).GetValue() == 0 )
+ rOutput << '0';
+ }
+ break;
+ case EE_FEATURE_TAB:
+ {
+ rOutput << OOO_STRING_SVTOOLS_RTF_TAB;
+ }
+ break;
+ case EE_FEATURE_LINEBR:
+ {
+ rOutput << OOO_STRING_SVTOOLS_RTF_SL;
+ }
+ break;
+ case EE_CHAR_KERNING:
+ {
+ rOutput << OOO_STRING_SVTOOLS_RTF_EXPNDTW;
+ rOutput.WriteNumber( LogicToTwips(
+ ((const SvxKerningItem&)rItem).GetValue() ) );
+ }
+ break;
+ case EE_CHAR_PAIRKERNING:
+ {
+ rOutput << OOO_STRING_SVTOOLS_RTF_KERNING;
+ rOutput.WriteNumber( ((const SvxAutoKernItem&)rItem).GetValue() ? 1 : 0 );
+ }
+ break;
+ case EE_CHAR_ESCAPEMENT:
+ {
+ SvxFont aFont;
+ ContentNode* pNode = aEditDoc.GetObject( nPara );
+ SeekCursor( pNode, nPos, aFont );
+ MapMode aPntMode( MAP_POINT );
+ long nFontHeight = GetRefDevice()->LogicToLogic(
+ aFont.GetSize(), &GetRefMapMode(), &aPntMode ).Height();
+ nFontHeight *=2; // HalfPoints
+ sal_uInt16 nProp = ((const SvxEscapementItem&)rItem).GetProp();
+ sal_uInt16 nProp100 = nProp*100; // Fuer SWG-Token Prop in 100tel Prozent.
+ short nEsc = ((const SvxEscapementItem&)rItem).GetEsc();
+ if ( nEsc == DFLT_ESC_AUTO_SUPER )
+ {
+ nEsc = 100 - nProp;
+ nProp100++; // Eine 1 hinten bedeutet 'automatisch'.
+ }
+ else if ( nEsc == DFLT_ESC_AUTO_SUB )
+ {
+ nEsc = sal::static_int_cast< short >( -( 100 - nProp ) );
+ nProp100++;
+ }
+ // SWG:
+ if ( nEsc )
+ rOutput << "{\\*\\updnprop" << ByteString::CreateFromInt32( nProp100 ).GetBuffer() << '}';
+ long nUpDown = nFontHeight * Abs( nEsc ) / 100;
+ ByteString aUpDown = ByteString::CreateFromInt32( nUpDown );
+ if ( nEsc < 0 )
+ rOutput << OOO_STRING_SVTOOLS_RTF_DN << aUpDown.GetBuffer();
+ else if ( nEsc > 0 )
+ rOutput << OOO_STRING_SVTOOLS_RTF_UP << aUpDown.GetBuffer();
+ }
+ break;
+ }
+}
+
+sal_uInt32 ImpEditEngine::WriteHTML( SvStream&, EditSelection )
+{
+ return 0;
+}
+
+
+EditTextObject* ImpEditEngine::CreateTextObject()
+{
+ EditSelection aCompleteSelection;
+ aCompleteSelection.Min() = aEditDoc.GetStartPaM();
+ aCompleteSelection.Max() = aEditDoc.GetEndPaM();
+
+ return CreateTextObject( aCompleteSelection );
+}
+
+EditTextObject* ImpEditEngine::CreateTextObject( EditSelection aSel )
+{
+ return CreateBinTextObject( aSel, GetEditTextObjectPool(), aStatus.AllowBigObjects(), nBigTextObjectStart );
+}
+
+EditTextObject* ImpEditEngine::CreateBinTextObject( EditSelection aSel, SfxItemPool* pPool, sal_Bool bAllowBigObjects, sal_uInt16 nBigObjectStart ) const
+{
+ BinTextObject* pTxtObj = new BinTextObject( pPool );
+ pTxtObj->SetVertical( IsVertical() );
+ MapUnit eMapUnit = (MapUnit)aEditDoc.GetItemPool().GetMetric( DEF_METRIC );
+ pTxtObj->SetMetric( (sal_uInt16) eMapUnit );
+ if ( pTxtObj->IsOwnerOfPool() )
+ pTxtObj->GetPool()->SetDefaultMetric( (SfxMapUnit) eMapUnit );
+
+ sal_uInt16 nStartNode, nEndNode;
+ sal_uInt32 nTextPortions = 0;
+
+ aSel.Adjust( aEditDoc );
+ nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
+ nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
+
+ sal_Bool bOnlyFullParagraphs = ( aSel.Min().GetIndex() ||
+ ( aSel.Max().GetIndex() < aSel.Max().GetNode()->Len() ) ) ?
+ sal_False : sal_True;
+
+ // Vorlagen werden nicht gespeichert!
+ // ( Nur Name und Familie, Vorlage selbst muss in App stehen! )
+
+ pTxtObj->SetScriptType( GetScriptType( aSel ) );
+
+ // ueber die Absaetze iterieren...
+ sal_uInt16 nNode;
+ for ( nNode = nStartNode; nNode <= nEndNode; nNode++ )
+ {
+ ContentNode* pNode = aEditDoc.SaveGetObject( nNode );
+ DBG_ASSERT( pNode, "Node nicht gefunden: Search&Replace" );
+
+ if ( bOnlyFullParagraphs )
+ {
+ ParaPortion* pParaPortion = GetParaPortions()[nNode];
+ nTextPortions += pParaPortion->GetTextPortions().Count();
+ }
+
+ sal_uInt16 nStartPos = 0;
+ sal_uInt16 nEndPos = pNode->Len();
+
+ sal_Bool bEmptyPara = nEndPos ? sal_False : sal_True;
+
+ if ( ( nNode == nStartNode ) && !bOnlyFullParagraphs )
+ nStartPos = aSel.Min().GetIndex();
+ if ( ( nNode == nEndNode ) && !bOnlyFullParagraphs )
+ nEndPos = aSel.Max().GetIndex();
+
+
+ ContentInfo* pC = pTxtObj->CreateAndInsertContent();
+
+ // Die Absatzattribute...
+ pC->GetParaAttribs().Set( pNode->GetContentAttribs().GetItems() );
+
+ // Das StyleSheet...
+ if ( pNode->GetStyleSheet() )
+ {
+ pC->GetStyle() = pNode->GetStyleSheet()->GetName();
+ pC->GetFamily() = pNode->GetStyleSheet()->GetFamily();
+ }
+
+ // Der Text...
+ pC->GetText() = pNode->Copy( nStartPos, nEndPos-nStartPos );
+
+ // und die Attribute...
+ sal_uInt16 nAttr = 0;
+ EditCharAttrib* pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
+ while ( pAttr )
+ {
+ // In einem leeren Absatz die Attribute behalten!
+ if ( bEmptyPara ||
+ ( ( pAttr->GetEnd() > nStartPos ) && ( pAttr->GetStart() < nEndPos ) ) )
+ {
+ XEditAttribute* pX = pTxtObj->CreateAttrib( *pAttr->GetItem(), pAttr->GetStart(), pAttr->GetEnd() );
+ // Evtl. korrigieren...
+ if ( ( nNode == nStartNode ) && ( nStartPos != 0 ) )
+ {
+ pX->GetStart() = ( pX->GetStart() > nStartPos ) ? pX->GetStart()-nStartPos : 0;
+ pX->GetEnd() = pX->GetEnd() - nStartPos;
+
+ }
+ if ( nNode == nEndNode )
+ {
+ if ( pX->GetEnd() > (nEndPos-nStartPos) )
+ pX->GetEnd() = nEndPos-nStartPos;
+ }
+ DBG_ASSERT( pX->GetEnd() <= (nEndPos-nStartPos), "CreateBinTextObject: Attribut zu lang!" );
+ if ( !pX->GetLen() && !bEmptyPara )
+ pTxtObj->DestroyAttrib( pX );
+ else
+ pC->GetAttribs().Insert( pX, pC->GetAttribs().Count() );
+ }
+ nAttr++;
+ pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
+ }
+
+#ifndef SVX_LIGHT
+ // ggf. Online-Spelling
+ if ( bAllowBigObjects && bOnlyFullParagraphs && pNode->GetWrongList() )
+ pC->SetWrongList( pNode->GetWrongList()->Clone() );
+#endif // !SVX_LIGHT
+
+ }
+
+ // Bei grossen Textobjekten die PortionInfos merken:
+ // Schwelle rauf setzen, wenn Olli die Absaetze nicht mehr zerhackt!
+ if ( bAllowBigObjects && bOnlyFullParagraphs && IsFormatted() && GetUpdateMode() && ( nTextPortions >= nBigObjectStart ) )
+ {
+ XParaPortionList* pXList = new XParaPortionList( GetRefDevice(), aPaperSize.Width() );
+ pTxtObj->SetPortionInfo( pXList );
+ for ( nNode = nStartNode; nNode <= nEndNode; nNode++ )
+ {
+ ParaPortion* pParaPortion = GetParaPortions()[nNode];
+ XParaPortion* pX = new XParaPortion;
+ pXList->Insert( pX, pXList->Count() );
+
+ pX->nHeight = pParaPortion->GetHeight();
+ pX->nFirstLineOffset = pParaPortion->GetFirstLineOffset();
+
+ // Die TextPortions
+ sal_uInt16 nCount = pParaPortion->GetTextPortions().Count();
+ sal_uInt16 n;
+ for ( n = 0; n < nCount; n++ )
+ {
+ TextPortion* pTextPortion = pParaPortion->GetTextPortions()[n];
+ TextPortion* pNew = new TextPortion( *pTextPortion );
+ pX->aTextPortions.Insert( pNew, pX->aTextPortions.Count() );
+ }
+
+ // Die Zeilen
+ nCount = pParaPortion->GetLines().Count();
+ for ( n = 0; n < nCount; n++ )
+ {
+ EditLine* pLine = pParaPortion->GetLines()[n];
+ EditLine* pNew = pLine->Clone();
+ pX->aLines.Insert( pNew, pX->aLines.Count() );
+ }
+#ifdef DBG_UTIL
+ USHORT nTest;
+ int nTPLen = 0, nTxtLen = 0;
+ for ( nTest = pParaPortion->GetTextPortions().Count(); nTest; )
+ nTPLen += pParaPortion->GetTextPortions().GetObject( --nTest )->GetLen();
+ for ( nTest = pParaPortion->GetLines().Count(); nTest; )
+ nTxtLen += pParaPortion->GetLines().GetObject( --nTest )->GetLen();
+ DBG_ASSERT( ( nTPLen == pParaPortion->GetNode()->Len() ) && ( nTxtLen == pParaPortion->GetNode()->Len() ), "CreateBinTextObject: ParaPortion not completely formatted!" );
+#endif
+ }
+ }
+ return pTxtObj;
+}
+
+void ImpEditEngine::SetText( const EditTextObject& rTextObject )
+{
+ // Da Setzen eines TextObject ist nicht Undo-faehig!
+ ResetUndoManager();
+ sal_Bool _bUpdate = GetUpdateMode();
+ sal_Bool _bUndo = IsUndoEnabled();
+
+ SetText( XubString() );
+ EditPaM aPaM = aEditDoc.GetStartPaM();
+
+ SetUpdateMode( sal_False );
+ EnableUndo( sal_False );
+
+ InsertText( rTextObject, EditSelection( aPaM, aPaM ) );
+ SetVertical( rTextObject.IsVertical() );
+
+#ifndef SVX_LIGHT
+ DBG_ASSERT( !HasUndoManager() || !GetUndoManager().GetUndoActionCount(), "Woher kommt das Undo in SetText ?!" );
+#endif
+ SetUpdateMode( _bUpdate );
+ EnableUndo( _bUndo );
+}
+
+EditSelection ImpEditEngine::InsertText( const EditTextObject& rTextObject, EditSelection aSel )
+{
+ EnterBlockNotifications();
+ aSel.Adjust( aEditDoc );
+ if ( aSel.HasRange() )
+ aSel = ImpDeleteSelection( aSel );
+ EditSelection aNewSel = InsertBinTextObject( (BinTextObject&)rTextObject, aSel.Max() );
+ LeaveBlockNotifications();
+ return aNewSel;
+
+ // MT 05/00: InsertBinTextObject direkt hier machen...
+}
+
+EditSelection ImpEditEngine::InsertBinTextObject( BinTextObject& rTextObject, EditPaM aPaM )
+{
+ // Optimieren:
+ // Kein GetPos undFindParaportion, sondern Index berechnen!
+ EditSelection aSel( aPaM, aPaM );
+ DBG_ASSERT( !aSel.DbgIsBuggy( aEditDoc ), "InsertBibTextObject: Selektion kaput!(1)" );
+
+ sal_Bool bUsePortionInfo = sal_False;
+// sal_Bool bFields = sal_False;
+ XParaPortionList* pPortionInfo = rTextObject.GetPortionInfo();
+
+ if ( pPortionInfo && ( (long)pPortionInfo->GetPaperWidth() == aPaperSize.Width() )
+ && ( pPortionInfo->GetRefMapMode() == GetRefDevice()->GetMapMode() ) )
+ {
+ if ( ( pPortionInfo->GetRefDevPtr() == (sal_uIntPtr)GetRefDevice() ) ||
+ ( ( pPortionInfo->GetRefDevType() == OUTDEV_VIRDEV ) &&
+ ( GetRefDevice()->GetOutDevType() == OUTDEV_VIRDEV ) ) )
+ bUsePortionInfo = sal_True;
+ }
+
+ sal_Bool bConvertItems = sal_False;
+ MapUnit eSourceUnit = MapUnit(), eDestUnit = MapUnit();
+ if ( rTextObject.HasMetric() )
+ {
+ eSourceUnit = (MapUnit)rTextObject.GetMetric();
+ eDestUnit = (MapUnit)aEditDoc.GetItemPool().GetMetric( DEF_METRIC );
+ if ( eSourceUnit != eDestUnit )
+ bConvertItems = sal_True;
+ }
+
+ sal_uInt16 nContents = rTextObject.GetContents().Count();
+ sal_uInt16 nPara = aEditDoc.GetPos( aPaM.GetNode() );
+
+ for ( sal_uInt16 n = 0; n < nContents; n++, nPara++ )
+ {
+ ContentInfo* pC = rTextObject.GetContents().GetObject( n );
+ sal_Bool bNewContent = aPaM.GetNode()->Len() ? sal_False: sal_True;
+ sal_uInt16 nStartPos = aPaM.GetIndex();
+
+ aPaM = ImpFastInsertText( aPaM, pC->GetText() );
+
+ ParaPortion* pPortion = FindParaPortion( aPaM.GetNode() );
+ DBG_ASSERT( pPortion, "Blinde Portion in FastInsertText" );
+ pPortion->MarkInvalid( nStartPos, pC->GetText().Len() );
+
+ // Zeicheattribute...
+ sal_Bool bAllreadyHasAttribs = aPaM.GetNode()->GetCharAttribs().Count() ? sal_True : sal_False;
+ sal_uInt16 nNewAttribs = pC->GetAttribs().Count();
+ if ( nNewAttribs )
+ {
+ BOOL bUpdateFields = FALSE;
+ for ( sal_uInt16 nAttr = 0; nAttr < nNewAttribs; nAttr++ )
+ {
+ XEditAttribute* pX = pC->GetAttribs().GetObject( nAttr );
+ // Kann passieren wenn Absaetze >16K entstehen, dann wird einfach umgebrochen.
+ if ( pX->GetEnd() <= aPaM.GetNode()->Len() )
+ {
+ if ( !bAllreadyHasAttribs || pX->IsFeature() )
+ {
+ // Normale Attribute gehen dann schneller...
+ // Features duerfen nicht ueber EditDoc::InsertAttrib
+ // eingefuegt werden, sie sind bei FastInsertText schon im TextFluss
+ DBG_ASSERT( pX->GetEnd() <= aPaM.GetNode()->Len(), "InsertBinTextObject: Attribut zu gross!" );
+ EditCharAttrib* pAttr;
+ if ( !bConvertItems )
+ pAttr = MakeCharAttrib( aEditDoc.GetItemPool(), *(pX->GetItem()), pX->GetStart()+nStartPos, pX->GetEnd()+nStartPos );
+ else
+ {
+ SfxPoolItem* pNew = pX->GetItem()->Clone();
+ ConvertItem( *pNew, eSourceUnit, eDestUnit );
+ pAttr = MakeCharAttrib( aEditDoc.GetItemPool(), *pNew, pX->GetStart()+nStartPos, pX->GetEnd()+nStartPos );
+ delete pNew;
+ }
+ DBG_ASSERT( pAttr->GetEnd() <= aPaM.GetNode()->Len(), "InsertBinTextObject: Attribut passt nicht! (1)" );
+ aPaM.GetNode()->GetCharAttribs().InsertAttrib( pAttr );
+ if ( pAttr->Which() == EE_FEATURE_FIELD )
+ bUpdateFields = TRUE;
+ }
+ else
+ {
+ DBG_ASSERT( pX->GetEnd()+nStartPos <= aPaM.GetNode()->Len(), "InsertBinTextObject: Attribut passt nicht! (2)" );
+ // Tabs und andere Features koennen nicht ueber InsertAttrib eingefuegt werden:
+ aEditDoc.InsertAttrib( aPaM.GetNode(), pX->GetStart()+nStartPos, pX->GetEnd()+nStartPos, *pX->GetItem() );
+ }
+ }
+ }
+ if ( bUpdateFields )
+ UpdateFields();
+
+ // Sonst QuickFormat => Keine Attribute!
+ pPortion->MarkSelectionInvalid( nStartPos, pC->GetText().Len() );
+ }
+
+ DBG_ASSERT( CheckOrderedList( aPaM.GetNode()->GetCharAttribs().GetAttribs(), sal_True ), "InsertBinTextObject: Start-Liste verdreht" );
+
+ sal_Bool bParaAttribs = sal_False;
+ if ( bNewContent || ( ( n > 0 ) && ( n < (nContents-1) ) ) )
+ {
+ bParaAttribs = sal_False;
+ // #101512# Don't overwrite level/style from existing paragraph in OutlineView
+ // MT 10/2002: Removed because of #103874#, handled in Outliner::EndPasteOrDropHdl now.
+// if ( !aStatus.IsOutliner() || n )
+ {
+ // nur dann Style und ParaAttribs, wenn neuer Absatz, oder
+ // komplett inneliegender...
+ bParaAttribs = pC->GetParaAttribs().Count() ? sal_True : sal_False;
+ if ( GetStyleSheetPool() && pC->GetStyle().Len() )
+ {
+ SfxStyleSheet* pStyle = (SfxStyleSheet*)GetStyleSheetPool()->Find( pC->GetStyle(), pC->GetFamily() );
+ DBG_ASSERT( pStyle, "InsertBinTextObject - Style not found!" );
+ SetStyleSheet( nPara, pStyle );
+ }
+ if ( !bConvertItems )
+ SetParaAttribs( aEditDoc.GetPos( aPaM.GetNode() ), pC->GetParaAttribs() );
+ else
+ {
+ SfxItemSet aAttribs( GetEmptyItemSet() );
+ ConvertAndPutItems( aAttribs, pC->GetParaAttribs(), &eSourceUnit, &eDestUnit );
+ SetParaAttribs( aEditDoc.GetPos( aPaM.GetNode() ), aAttribs );
+ }
+ }
+ if ( bNewContent && bUsePortionInfo )
+ {
+ XParaPortion* pXP = pPortionInfo->GetObject( n );
+ DBG_ASSERT( pXP, "InsertBinTextObject: PortionInfo?" );
+ ParaPortion* pParaPortion = GetParaPortions()[ nPara ];
+ DBG_ASSERT( pParaPortion, "InsertBinTextObject: ParaPortion?" );
+ pParaPortion->nHeight = pXP->nHeight;
+ pParaPortion->nFirstLineOffset = pXP->nFirstLineOffset;
+ pParaPortion->bForceRepaint = sal_True;
+ pParaPortion->SetValid(); // Nicht formatieren
+
+ // Die TextPortions
+ pParaPortion->GetTextPortions().Reset();
+ sal_uInt16 nCount = pXP->aTextPortions.Count();
+ for ( sal_uInt16 _n = 0; _n < nCount; _n++ )
+ {
+ TextPortion* pTextPortion = pXP->aTextPortions[_n];
+ TextPortion* pNew = new TextPortion( *pTextPortion );
+ pParaPortion->GetTextPortions().Insert( pNew, _n );
+ }
+
+ // Die Zeilen
+ pParaPortion->GetLines().Reset();
+ nCount = pXP->aLines.Count();
+ for ( sal_uInt16 m = 0; m < nCount; m++ )
+ {
+ EditLine* pLine = pXP->aLines[m];
+ EditLine* pNew = pLine->Clone();
+ pNew->SetInvalid(); // neu Painten!
+ pParaPortion->GetLines().Insert( pNew, m );
+ }
+#ifdef DBG_UTIL
+ USHORT nTest;
+ int nTPLen = 0, nTxtLen = 0;
+ for ( nTest = pParaPortion->GetTextPortions().Count(); nTest; )
+ nTPLen += pParaPortion->GetTextPortions().GetObject( --nTest )->GetLen();
+ for ( nTest = pParaPortion->GetLines().Count(); nTest; )
+ nTxtLen += pParaPortion->GetLines().GetObject( --nTest )->GetLen();
+ DBG_ASSERT( ( nTPLen == pParaPortion->GetNode()->Len() ) && ( nTxtLen == pParaPortion->GetNode()->Len() ), "InsertBinTextObject: ParaPortion not completely formatted!" );
+#endif
+ }
+ }
+ if ( !bParaAttribs ) // DefFont wird bei FastInsertParagraph nicht berechnet
+ {
+ aPaM.GetNode()->GetCharAttribs().GetDefFont() = aEditDoc.GetDefFont();
+ if ( aStatus.UseCharAttribs() )
+ aPaM.GetNode()->CreateDefFont();
+ }
+
+#ifndef SVX_LIGHT
+ if ( bNewContent && GetStatus().DoOnlineSpelling() && pC->GetWrongList() )
+ {
+ aPaM.GetNode()->DestroyWrongList(); // otherwise MLK, if list exists...
+ aPaM.GetNode()->SetWrongList( pC->GetWrongList()->Clone() );
+ }
+#endif // !SVX_LIGHT
+
+ // Zeilenumbruch, wenn weitere folgen...
+ if ( n < ( nContents-1) )
+ {
+ if ( bNewContent )
+ aPaM = ImpFastInsertParagraph( nPara+1 );
+ else
+ aPaM = ImpInsertParaBreak( aPaM, sal_False );
+ }
+ }
+
+ aSel.Max() = aPaM;
+ DBG_ASSERT( !aSel.DbgIsBuggy( aEditDoc ), "InsertBibTextObject: Selektion kaput!(1)" );
+ return aSel;
+}
+
+LanguageType ImpEditEngine::GetLanguage( const EditPaM& rPaM, USHORT* pEndPos ) const
+{
+ short nScriptType = GetScriptType( rPaM, pEndPos ); // pEndPos will be valid now, pointing to ScriptChange or NodeLen
+ USHORT nLangId = GetScriptItemId( EE_CHAR_LANGUAGE, nScriptType );
+ const SvxLanguageItem* pLangItem = &(const SvxLanguageItem&)rPaM.GetNode()->GetContentAttribs().GetItem( nLangId );
+ EditCharAttrib* pAttr = rPaM.GetNode()->GetCharAttribs().FindAttrib( nLangId, rPaM.GetIndex() );
+ if ( pAttr )
+ pLangItem = (const SvxLanguageItem*)pAttr->GetItem();
+
+ if ( pEndPos && pAttr && ( pAttr->GetEnd() < *pEndPos ) )
+ *pEndPos = pAttr->GetEnd();
+
+ return pLangItem->GetLanguage();
+}
+
+::com::sun::star::lang::Locale ImpEditEngine::GetLocale( const EditPaM& rPaM ) const
+{
+ return SvxCreateLocale( GetLanguage( rPaM ) );
+}
+
+Reference< XSpellChecker1 > ImpEditEngine::GetSpeller()
+{
+#ifndef SVX_LIGHT
+ if ( !xSpeller.is() )
+ xSpeller = SvxGetSpellChecker();
+#endif
+ return xSpeller;
+}
+
+EESpellState ImpEditEngine::Spell( EditView* pEditView, sal_Bool bMultipleDoc )
+{
+#ifdef SVX_LIGHT
+ return EE_SPELL_NOSPELLER;
+#else
+
+ DBG_ASSERTWARNING( xSpeller.is(), "Kein Speller gesetzt!" );
+
+ if ( !xSpeller.is() )
+ return EE_SPELL_NOSPELLER;
+
+ aOnlineSpellTimer.Stop();
+
+ // Bei MultipleDoc immer von vorne/hinten...
+ if ( bMultipleDoc )
+ {
+ pEditView->pImpEditView->SetEditSelection( aEditDoc.GetStartPaM() );
+ }
+
+ EditSelection aCurSel( pEditView->pImpEditView->GetEditSelection() );
+ pSpellInfo = new SpellInfo;
+ pSpellInfo->bMultipleDoc = bMultipleDoc;
+ pSpellInfo->aSpellStart = CreateEPaM( SelectWord( aCurSel, ::com::sun::star::i18n::WordType::DICTIONARY_WORD ).Min() );
+
+ sal_Bool bIsStart = sal_False;
+ if ( bMultipleDoc )
+ bIsStart = sal_True; // Immer von Vorne bzw. von hinten...
+ else if ( ( CreateEPaM( aEditDoc.GetStartPaM() ) == pSpellInfo->aSpellStart ) )
+ bIsStart = sal_True;
+
+ EditSpellWrapper* pWrp = new EditSpellWrapper( Application::GetDefDialogParent(),
+ xSpeller, bIsStart, sal_False, pEditView );
+ pWrp->SpellDocument();
+ delete pWrp;
+
+ if ( !bMultipleDoc )
+ {
+ pEditView->pImpEditView->DrawSelection();
+ if ( aCurSel.Max().GetIndex() > aCurSel.Max().GetNode()->Len() )
+ aCurSel.Max().GetIndex() = aCurSel.Max().GetNode()->Len();
+ aCurSel.Min() = aCurSel.Max();
+ pEditView->pImpEditView->SetEditSelection( aCurSel );
+ pEditView->pImpEditView->DrawSelection();
+ pEditView->ShowCursor( sal_True, sal_False );
+ }
+ EESpellState eState = pSpellInfo->eState;
+ delete pSpellInfo;
+ pSpellInfo = 0;
+ return eState;
+#endif
+}
+
+
+sal_Bool ImpEditEngine::HasConvertibleTextPortion( LanguageType nSrcLang )
+{
+#ifdef SVX_LIGHT
+ return sal_False;
+#else
+ sal_Bool bHasConvTxt = sal_False;
+
+ USHORT nParas = pEditEngine->GetParagraphCount();
+ for (USHORT k = 0; k < nParas; ++k)
+ {
+ SvUShorts aPortions;
+ pEditEngine->GetPortions( k, aPortions );
+ for ( USHORT nPos = 0; nPos < aPortions.Count(); ++nPos )
+ {
+ USHORT nEnd = aPortions.GetObject( nPos );
+ USHORT nStart = nPos > 0 ? aPortions.GetObject( nPos - 1 ) : 0;
+
+ // if the paragraph is not empty we need to increase the index
+ // by one since the attribute of the character left to the
+ // specified position is evaluated.
+ if (nEnd > nStart) // empty para?
+ ++nStart;
+ LanguageType nLangFound = pEditEngine->GetLanguage( k, nStart );
+#ifdef DEBUG
+ lang::Locale aLocale( SvxCreateLocale( nLangFound ) );
+#endif
+ bHasConvTxt = (nSrcLang == nLangFound) ||
+ (editeng::HangulHanjaConversion::IsChinese( nLangFound ) &&
+ editeng::HangulHanjaConversion::IsChinese( nSrcLang ));
+ if (bHasConvTxt)
+ return bHasConvTxt;
+ }
+ }
+
+#endif
+ return bHasConvTxt;
+}
+
+
+void ImpEditEngine::Convert( EditView* pEditView,
+ LanguageType nSrcLang, LanguageType nDestLang, const Font *pDestFont,
+ INT32 nOptions, sal_Bool bIsInteractive, sal_Bool bMultipleDoc )
+{
+ // modified version of ImpEditEngine::Spell
+
+#ifdef SVX_LIGHT
+#else
+
+ // Bei MultipleDoc immer von vorne/hinten...
+ if ( bMultipleDoc )
+ pEditView->pImpEditView->SetEditSelection( aEditDoc.GetStartPaM() );
+
+ //
+ // initialize pConvInfo
+ //
+ EditSelection aCurSel( pEditView->pImpEditView->GetEditSelection() );
+ aCurSel.Adjust( aEditDoc );
+ pConvInfo = new ConvInfo;
+ pConvInfo->bMultipleDoc = bMultipleDoc;
+ pConvInfo->aConvStart = CreateEPaM( aCurSel.Min() );
+ //
+ // if it is not just a selection and we are about to begin
+ // with the current conversion for the very first time
+ // we need to find the start of the current (initial)
+ // convertible unit in order for the text conversion to give
+ // the correct result for that. Since it is easier to obtain
+ // the start of the word we use that though.
+ if (!aCurSel.HasRange() && ImplGetBreakIterator().is())
+ {
+ EditPaM aWordStartPaM( SelectWord( aCurSel, i18n::WordType::DICTIONARY_WORD ).Min() );
+
+ // since #118246 / #117803 still occurs if the cursor is placed
+ // between the two chinese characters to be converted (because both
+ // of them are words on their own!) using the word boundary here does
+ // not work. Thus since chinese conversion is not interactive we start
+ // at the begin of the paragraph to solve the problem, i.e. have the
+ // TextConversion service get those characters together in the same call.
+ USHORT nStartIdx = ( editeng::HangulHanjaConversion::IsChinese( nSrcLang ) ) ?
+ 0 : aWordStartPaM.GetIndex();
+ pConvInfo->aConvStart.nIndex = nStartIdx;
+ }
+ //
+ pConvInfo->aConvContinue = pConvInfo->aConvStart;
+
+ sal_Bool bIsStart = sal_False;
+ if ( bMultipleDoc )
+ bIsStart = sal_True; // Immer von Vorne bzw. von hinten...
+ else if ( CreateEPaM( aEditDoc.GetStartPaM() ) == pConvInfo->aConvStart )
+ bIsStart = sal_True;
+
+ bImpConvertFirstCall = sal_True; // next ImpConvert call is the very first in this conversion turn
+
+ Reference< lang::XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
+ TextConvWrapper aWrp( Application::GetDefDialogParent(), xMSF,
+ SvxCreateLocale( nSrcLang ), SvxCreateLocale( nDestLang ),
+ pDestFont,
+ nOptions, bIsInteractive,
+ bIsStart, pEditView );
+
+ //
+ //!! optimization does not work since when update mode is false
+ //!! the object is 'lying' about it portions, paragraphs,
+ //!! EndPaM... later on.
+ //!! Should not be a great problem since text boxes or cells in
+ //!! Calc usually have only a rather short text.
+ //
+ // disallow formatting, updating the view, ... while
+ // non-interactively converting the document. (saves time)
+ //if (!bIsInteractive)
+ // SetUpdateMode( FALSE );
+
+ aWrp.Convert();
+
+ //if (!bIsInteractive)
+ //SetUpdateMode( TRUE, 0, TRUE );
+
+ if ( !bMultipleDoc )
+ {
+ pEditView->pImpEditView->DrawSelection();
+ if ( aCurSel.Max().GetIndex() > aCurSel.Max().GetNode()->Len() )
+ aCurSel.Max().GetIndex() = aCurSel.Max().GetNode()->Len();
+ aCurSel.Min() = aCurSel.Max();
+ pEditView->pImpEditView->SetEditSelection( aCurSel );
+ pEditView->pImpEditView->DrawSelection();
+ pEditView->ShowCursor( sal_True, sal_False );
+ }
+ delete pConvInfo;
+ pConvInfo = 0;
+#endif
+}
+
+
+void ImpEditEngine::SetLanguageAndFont(
+ const ESelection &rESel,
+ LanguageType nLang, USHORT nLangWhichId,
+ const Font *pFont, USHORT nFontWhichId )
+{
+ ESelection aOldSel = pActiveView->GetSelection();
+ pActiveView->SetSelection( rESel );
+
+ // set new language attribute
+ SfxItemSet aNewSet( pActiveView->GetEmptyItemSet() );
+ aNewSet.Put( SvxLanguageItem( nLang, nLangWhichId ) );
+
+ // new font to be set?
+ DBG_ASSERT( pFont, "target font missing?" );
+ if (pFont)
+ {
+ // set new font attribute
+ SvxFontItem aFontItem = (SvxFontItem&) aNewSet.Get( nFontWhichId );
+ aFontItem.GetFamilyName() = pFont->GetName();
+ aFontItem.GetFamily() = pFont->GetFamily();
+ aFontItem.GetStyleName() = pFont->GetStyleName();
+ aFontItem.GetPitch() = pFont->GetPitch();
+ aFontItem.GetCharSet() = pFont->GetCharSet();
+ aNewSet.Put( aFontItem );
+ }
+
+ // apply new attributes
+ pActiveView->SetAttribs( aNewSet );
+
+ pActiveView->SetSelection( aOldSel );
+}
+
+
+void ImpEditEngine::ImpConvert( rtl::OUString &rConvTxt, LanguageType &rConvTxtLang,
+ EditView* pEditView, LanguageType nSrcLang, const ESelection &rConvRange,
+ sal_Bool bAllowImplicitChangesForNotConvertibleText,
+ LanguageType nTargetLang, const Font *pTargetFont )
+{
+ // modified version of ImpEditEngine::ImpSpell
+
+ // looks for next convertible text portion to be passed on to the wrapper
+
+ String aRes;
+ LanguageType nResLang = LANGUAGE_NONE;
+
+#ifdef SVX_LIGHT
+ rConvTxt = rtl::OUString();
+ rConvTxtLang = LANGUAGE_NONE;
+#else
+
+ /* ContentNode* pLastNode = */ aEditDoc.SaveGetObject( aEditDoc.Count()-1 );
+
+ EditPaM aPos( CreateEditPaM( pConvInfo->aConvContinue ) );
+ EditSelection aCurSel = EditSelection( aPos, aPos );
+
+ String aWord;
+
+ while (!aRes.Len())
+ {
+ // empty paragraph found that needs to have language and font set?
+ if (bAllowImplicitChangesForNotConvertibleText &&
+ !pEditEngine->GetText( pConvInfo->aConvContinue.nPara ).Len())
+ {
+ USHORT nPara = pConvInfo->aConvContinue.nPara;
+ ESelection aESel( nPara, 0, nPara, 0 );
+ // see comment for below same function call
+ SetLanguageAndFont( aESel,
+ nTargetLang, EE_CHAR_LANGUAGE_CJK,
+ pTargetFont, EE_CHAR_FONTINFO_CJK );
+ }
+
+
+ if (pConvInfo->aConvContinue.nPara == pConvInfo->aConvTo.nPara &&
+ pConvInfo->aConvContinue.nIndex >= pConvInfo->aConvTo.nIndex)
+ break;
+
+/*
+ // Bekannter (wahrscheinlicher) Bug: Wenn SpellToCurrent, muss
+ // Current bei jeder Ersetzung korrigiert werden, sonst passt
+ // das Ende evtl. nicht mehr genau...
+ if ( pConvInfo->bConvToEnd || pConvInfo->bMultipleDoc )
+ {
+ if ( aCurSel.Max().GetNode() == pLastNode &&
+ aCurSel.Max().GetIndex() >= pLastNode->Len() )
+ break;
+ }
+*/
+
+ USHORT nAttribStart = USHRT_MAX;
+ USHORT nAttribEnd = USHRT_MAX;
+ USHORT nCurPos = USHRT_MAX;
+ EPaM aCurStart = CreateEPaM( aCurSel.Min() );
+ SvUShorts aPortions;
+ pEditEngine->GetPortions( (USHORT)aCurStart.nPara, aPortions );
+ for ( USHORT nPos = 0; nPos < aPortions.Count(); ++nPos )
+ {
+ USHORT nEnd = aPortions.GetObject( nPos );
+ USHORT nStart = nPos > 0 ? aPortions.GetObject( nPos - 1 ) : 0;
+
+ // the language attribute is obtained from the left character
+ // (like usually all other attributes)
+ // thus we usually have to add 1 in order to get the language
+ // of the text right to the cursor position
+ USHORT nLangIdx = nEnd > nStart ? nStart + 1 : nStart;
+ LanguageType nLangFound = pEditEngine->GetLanguage( aCurStart.nPara, nLangIdx );
+#ifdef DEBUG
+ lang::Locale aLocale( SvxCreateLocale( nLangFound ) );
+#endif
+ sal_Bool bLangOk = (nLangFound == nSrcLang) ||
+ (editeng::HangulHanjaConversion::IsChinese( nLangFound ) &&
+ editeng::HangulHanjaConversion::IsChinese( nSrcLang ));
+
+ if (nAttribEnd != USHRT_MAX) // start already found?
+ {
+ DBG_ASSERT(nEnd >= aCurStart.nIndex, "error while scanning attributes (a)" );
+ DBG_ASSERT(nEnd >= nAttribEnd, "error while scanning attributes (b)" );
+ if (/*nEnd >= aCurStart.nIndex &&*/ nLangFound == nResLang)
+ nAttribEnd = nEnd;
+ else // language attrib has changed
+ break;
+ }
+ if (nAttribStart == USHRT_MAX && // start not yet found?
+ nEnd > aCurStart.nIndex && bLangOk)
+ {
+ nAttribStart = nStart;
+ nAttribEnd = nEnd;
+ nResLang = nLangFound;
+ }
+ //! the list of portions may have changed compared to the previous
+ //! call to this function (because of possibly changed language
+ //! attribute!)
+ //! But since we don't want to start in the already processed part
+ //! we clip the start accordingly.
+ if (nAttribStart < aCurStart.nIndex)
+ {
+ nAttribStart = aCurStart.nIndex;
+ }
+
+ // check script type to the right of the start of the current portion
+ EditPaM aPaM( CreateEditPaM( EPaM(aCurStart.nPara, nLangIdx) ) );
+ sal_Bool bIsAsianScript = (i18n::ScriptType::ASIAN == GetScriptType( aPaM ));
+ // not yet processed text part with for conversion
+ // not suitable language found that needs to be changed?
+ if (bAllowImplicitChangesForNotConvertibleText &&
+ !bLangOk && !bIsAsianScript && nEnd > aCurStart.nIndex)
+ {
+ ESelection aESel( aCurStart.nPara, nStart, aCurStart.nPara, nEnd );
+ // set language and font to target language and font of conversion
+ //! Now this especially includes all non convertible text e.g.
+ //! spaces, empty paragraphs and western text.
+ // This is in order for every *new* text entered at *any* position to
+ // have the correct language and font attributes set.
+ SetLanguageAndFont( aESel,
+ nTargetLang, EE_CHAR_LANGUAGE_CJK,
+ pTargetFont, EE_CHAR_FONTINFO_CJK );
+ }
+
+ nCurPos = nEnd;
+ }
+
+ if (nAttribStart != USHRT_MAX && nAttribEnd != USHRT_MAX)
+ {
+ aCurSel.Min().SetIndex( nAttribStart );
+ aCurSel.Max().SetIndex( nAttribEnd );
+ }
+ else if (nCurPos != USHRT_MAX)
+ {
+ // set selection to end of scanned text
+ // (used to set the position where to continue from later on)
+ aCurSel.Min().SetIndex( nCurPos );
+ aCurSel.Max().SetIndex( nCurPos );
+ }
+
+ if ( !pConvInfo->bConvToEnd )
+ {
+ EPaM aEPaM( CreateEPaM( aCurSel.Min() ) );
+ if ( !( aEPaM < pConvInfo->aConvTo ) )
+ break;
+ }
+
+ // clip selected word to the converted area
+ // (main use when conversion starts/ends **within** a word)
+ EditPaM aPaM( CreateEditPaM( pConvInfo->aConvStart ) );
+ if (pConvInfo->bConvToEnd &&
+ aCurSel.Min().GetNode() == aPaM.GetNode() &&
+ aCurSel.Min().GetIndex() < aPaM.GetIndex())
+ aCurSel.Min().SetIndex( aPaM.GetIndex() );
+ aPaM = CreateEditPaM( pConvInfo->aConvContinue );
+ if (aCurSel.Min().GetNode() == aPaM.GetNode() &&
+ aCurSel.Min().GetIndex() < aPaM.GetIndex())
+ aCurSel.Min().SetIndex( aPaM.GetIndex() );
+ aPaM = CreateEditPaM( pConvInfo->aConvTo );
+ if ((!pConvInfo->bConvToEnd || rConvRange.HasRange())&&
+ aCurSel.Max().GetNode() == aPaM.GetNode() &&
+ aCurSel.Max().GetIndex() > aPaM.GetIndex())
+ aCurSel.Max().SetIndex( aPaM.GetIndex() );
+
+ aWord = GetSelected( aCurSel );
+
+ if ( aWord.Len() > 0 /* && bLangOk */)
+ aRes = aWord;
+
+ // move to next word/paragraph if necessary
+ if ( !aRes.Len() )
+ aCurSel = WordRight( aCurSel.Min(), ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
+
+ pConvInfo->aConvContinue = CreateEPaM( aCurSel.Max() );
+ }
+
+ pEditView->pImpEditView->DrawSelection();
+ pEditView->pImpEditView->SetEditSelection( aCurSel );
+ pEditView->pImpEditView->DrawSelection();
+ pEditView->ShowCursor( sal_True, sal_False );
+
+ rConvTxt = aRes;
+ if (rConvTxt.getLength())
+ rConvTxtLang = nResLang;
+#endif
+}
+
+
+Reference< XSpellAlternatives > ImpEditEngine::ImpSpell( EditView* pEditView )
+{
+#ifdef SVX_LIGHT
+ return Reference< XSpellAlternatives >();
+#else
+
+ DBG_ASSERT( xSpeller.is(), "Kein Speller gesetzt!" );
+
+ ContentNode* pLastNode = aEditDoc.SaveGetObject( (aEditDoc.Count()-1) );
+ EditSelection aCurSel( pEditView->pImpEditView->GetEditSelection() );
+ aCurSel.Min() = aCurSel.Max();
+
+ String aWord;
+ Reference< XSpellAlternatives > xSpellAlt;
+ Sequence< PropertyValue > aEmptySeq;
+ while (!xSpellAlt.is())
+ {
+
+ // Bekannter (wahrscheinlicher) Bug: Wenn SpellToCurrent, muss
+ // Current bei jeder Ersetzung korrigiert werden, sonst passt
+ // das Ende evtl. nicht mehr genau...
+ if ( pSpellInfo->bSpellToEnd || pSpellInfo->bMultipleDoc )
+ {
+ if ( aCurSel.Max().GetNode() == pLastNode )
+ {
+ if ( ( aCurSel.Max().GetIndex() >= pLastNode->Len() ) )
+ break;
+ }
+ }
+ else if ( !pSpellInfo->bSpellToEnd )
+ {
+ EPaM aEPaM( CreateEPaM( aCurSel.Max() ) );
+ if ( !( aEPaM < pSpellInfo->aSpellTo ) )
+ break;
+ }
+
+ aCurSel = SelectWord( aCurSel, ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
+ aWord = GetSelected( aCurSel );
+
+ // Wenn Punkt dahinter, muss dieser mit uebergeben werden !
+ // Falls Abkuerzung...
+ if ( aWord.Len() && ( aCurSel.Max().GetIndex() < aCurSel.Max().GetNode()->Len() ) )
+ {
+ sal_Unicode cNext = aCurSel.Max().GetNode()->GetChar( aCurSel.Max().GetIndex() );
+ if ( cNext == '.' )
+ {
+ aCurSel.Max().GetIndex()++;
+ aWord += cNext;
+ }
+ }
+
+ if ( aWord.Len() > 0 )
+ {
+ LanguageType eLang = GetLanguage( aCurSel.Max() );
+ SvxSpellWrapper::CheckSpellLang( xSpeller, eLang );
+ xSpellAlt = xSpeller->spell( aWord, eLang, aEmptySeq );
+ }
+
+ if ( !xSpellAlt.is() )
+ aCurSel = WordRight( aCurSel.Min(), ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
+ else
+ pSpellInfo->eState = EE_SPELL_ERRORFOUND;
+ }
+
+ pEditView->pImpEditView->DrawSelection();
+ pEditView->pImpEditView->SetEditSelection( aCurSel );
+ pEditView->pImpEditView->DrawSelection();
+ pEditView->ShowCursor( sal_True, sal_False );
+ return xSpellAlt;
+#endif
+}
+/*-- 13.10.2003 16:43:27---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void ImpEditEngine::EndSpelling()
+{
+ DELETEZ(pSpellInfo);
+}
+/*-- 13.10.2003 16:43:27---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void ImpEditEngine::StartSpelling(EditView& rEditView, sal_Bool bMultipleDoc)
+{
+ DBG_ASSERT(!pSpellInfo, "pSpellInfo already set?");
+ pSpellInfo = new SpellInfo;
+ pSpellInfo->bMultipleDoc = bMultipleDoc;
+ rEditView.pImpEditView->SetEditSelection( aEditDoc.GetStartPaM() );
+ EditSelection aCurSel( rEditView.pImpEditView->GetEditSelection() );
+ pSpellInfo->aSpellStart = CreateEPaM( SelectWord( aCurSel, ::com::sun::star::i18n::WordType::DICTIONARY_WORD ).Min() );
+}
+/*-- 13.10.2003 16:43:27---------------------------------------------------
+ Search for the next wrong word within the given selection
+ -----------------------------------------------------------------------*/
+Reference< XSpellAlternatives > ImpEditEngine::ImpFindNextError(EditSelection& rSelection)
+{
+ /* ContentNode* pLastNode = */ aEditDoc.SaveGetObject( (aEditDoc.Count()-1) );
+ EditSelection aCurSel( rSelection.Min() );
+
+ String aWord;
+ Reference< XSpellAlternatives > xSpellAlt;
+ Sequence< PropertyValue > aEmptySeq;
+ while (!xSpellAlt.is())
+ {
+ //check if the end of the selection has been reached
+ {
+ EPaM aEPaM( CreateEPaM( aCurSel.Max() ) );
+ if ( !( aEPaM < CreateEPaM( rSelection.Max()) ) )
+ break;
+ }
+
+ aCurSel = SelectWord( aCurSel, ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
+ aWord = GetSelected( aCurSel );
+
+ // Wenn Punkt dahinter, muss dieser mit uebergeben werden !
+ // Falls Abkuerzung...
+ if ( aWord.Len() && ( aCurSel.Max().GetIndex() < aCurSel.Max().GetNode()->Len() ) )
+ {
+ sal_Unicode cNext = aCurSel.Max().GetNode()->GetChar( aCurSel.Max().GetIndex() );
+ if ( cNext == '.' )
+ {
+ aCurSel.Max().GetIndex()++;
+ aWord += cNext;
+ }
+ }
+
+ if ( aWord.Len() > 0 )
+ xSpellAlt = xSpeller->spell( aWord, GetLanguage( aCurSel.Max() ), aEmptySeq );
+
+ if ( !xSpellAlt.is() )
+ aCurSel = WordRight( aCurSel.Min(), ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
+ else
+ {
+ pSpellInfo->eState = EE_SPELL_ERRORFOUND;
+ rSelection = aCurSel;
+ }
+ }
+ return xSpellAlt;
+}
+/*-- 13.10.2003 16:43:27---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+bool ImpEditEngine::SpellSentence(EditView& rEditView, ::svx::SpellPortions& rToFill, bool /*bIsGrammarChecking*/ )
+{
+#ifdef SVX_LIGHT
+#else
+ bool bRet = false;
+ //the pSpellInfo has to be created on demand
+ if(!pSpellInfo)
+ {
+ pSpellInfo = new SpellInfo;
+ pSpellInfo->bMultipleDoc = sal_True;
+ rEditView.pImpEditView->SetEditSelection( aEditDoc.GetStartPaM() );
+ EditSelection aCurSel( rEditView.pImpEditView->GetEditSelection() );
+ pSpellInfo->aSpellStart = CreateEPaM( SelectWord( aCurSel, ::com::sun::star::i18n::WordType::DICTIONARY_WORD ).Min() );
+ }
+ DBG_ASSERT( xSpeller.is(), "Kein Speller gesetzt!" );
+ pSpellInfo->aLastSpellPortions.clear();
+ pSpellInfo->aLastSpellContentSelections.clear();
+ rToFill.clear();
+ EditSelection aCurSel( rEditView.pImpEditView->GetEditSelection() );
+ //if no selection previously exists the range is extended to the end of the object
+ if(aCurSel.Min() == aCurSel.Max())
+ {
+ ContentNode* pLastNode = aEditDoc.SaveGetObject( aEditDoc.Count()-1);
+ aCurSel.Max() = EditPaM(pLastNode, pLastNode->Len());
+ }
+ Reference< XSpellAlternatives > xAlt = ImpFindNextError(aCurSel);
+ if(xAlt.is())
+ {
+ bRet = true;
+ //find the sentence boundaries
+ EditSelection aSentencePaM = SelectSentence(aCurSel);
+ //make sure that the sentence is never smaller than the error range!
+ if(aSentencePaM.Max().GetIndex() < aCurSel.Max().GetIndex())
+ aSentencePaM.Max() = aCurSel.Max();
+ //add the portion preceeding the error
+ EditSelection aStartSelection(aSentencePaM.Min(), aCurSel.Min());
+ if(aStartSelection.HasRange())
+ AddPortionIterated(rEditView, aStartSelection, 0, rToFill);
+ //add the error portion
+ AddPortionIterated(rEditView, aCurSel, xAlt, rToFill);
+ //find the end of the sentence
+ //search for all errors in the rest of the sentence and add all the portions
+ do
+ {
+ EditSelection aNextSel = EditSelection(aCurSel.Max(), aSentencePaM.Max());
+ xAlt = ImpFindNextError(aNextSel);
+ if(xAlt.is())
+ {
+ //add the part between the previous and the current error
+ AddPortionIterated(rEditView, EditSelection(aCurSel.Max(), aNextSel.Min()), 0, rToFill);
+ //add the current error
+ AddPortionIterated(rEditView, aNextSel, xAlt, rToFill);
+ }
+ else
+ AddPortionIterated(rEditView, EditSelection(aCurSel.Max(), aSentencePaM.Max()), xAlt, rToFill);
+ aCurSel = aNextSel;
+ }
+ while( xAlt.is() );
+ //set the selection to the end of the current sentence
+ rEditView.pImpEditView->SetEditSelection(aSentencePaM.Max());
+ }
+#endif
+ return bRet;
+}
+
+/*-- 15.10.2003 16:09:12---------------------------------------------------
+ adds one portion to the SpellPortions
+ -----------------------------------------------------------------------*/
+void ImpEditEngine::AddPortion(
+ const EditSelection rSel,
+ uno::Reference< XSpellAlternatives > xAlt,
+ ::svx::SpellPortions& rToFill,
+ bool bIsField)
+{
+#ifdef SVX_LIGHT
+#else
+ if(rSel.HasRange())
+ {
+ svx::SpellPortion aPortion;
+ aPortion.sText = GetSelected( rSel );
+ aPortion.eLanguage = GetLanguage( rSel.Min() );
+ aPortion.xAlternatives = xAlt;
+ aPortion.bIsField = bIsField;
+ rToFill.push_back(aPortion);
+
+ //save the spelled portions for later use
+ pSpellInfo->aLastSpellPortions.push_back(aPortion);
+ pSpellInfo->aLastSpellContentSelections.push_back(rSel);
+
+ }
+#endif
+}
+
+/*-- 15.10.2003 16:07:47---------------------------------------------------
+ adds one or more portions of text to the SpellPortions depending on language changes
+ -----------------------------------------------------------------------*/
+void ImpEditEngine::AddPortionIterated(
+ EditView& rEditView,
+ const EditSelection rSel,
+ Reference< XSpellAlternatives > xAlt,
+ ::svx::SpellPortions& rToFill)
+{
+#ifdef SVX_LIGHT
+#else
+ if(rSel.Min() != rSel.Max())
+ {
+ if(xAlt.is())
+ {
+ AddPortion(rSel, xAlt, rToFill, false);
+ }
+ else
+ {
+ //iterate and search for language attribute changes
+ //save the start and end positions
+ bool bTest = rSel.Min().GetIndex() <= rSel.Max().GetIndex();
+ EditPaM aStart(bTest ? rSel.Min() : rSel.Max());
+ EditPaM aEnd(bTest ? rSel.Max() : rSel.Min());
+ //iterate over the text to find changes in language
+ //set the mark equal to the point
+ EditPaM aCursor(aStart);
+ rEditView.pImpEditView->SetEditSelection( aCursor );
+ LanguageType eStartLanguage = GetLanguage( aCursor );
+ //search for a field attribute at the beginning - only the end position
+ //of this field is kept to end a portion at that position
+ const EditCharAttrib* pFieldAttr = aCursor.GetNode()->GetCharAttribs().
+ FindFeature( aCursor.GetIndex() );
+ bool bIsField = pFieldAttr &&
+ pFieldAttr->GetStart() == aCursor.GetIndex() &&
+ pFieldAttr->GetStart() != pFieldAttr->GetEnd() &&
+ pFieldAttr->Which() == EE_FEATURE_FIELD;
+ USHORT nEndField = bIsField ? pFieldAttr->GetEnd() : USHRT_MAX;
+ bool bIsEndField = false;
+ do
+ {
+ aCursor = CursorRight( aCursor);
+ //determine whether a field and has been reached
+ bIsEndField = nEndField == aCursor.GetIndex();
+ //search for a new field attribute
+ EditCharAttrib* _pFieldAttr = aCursor.GetNode()->GetCharAttribs().
+ FindFeature( aCursor.GetIndex() );
+ bIsField = _pFieldAttr &&
+ _pFieldAttr->GetStart() == aCursor.GetIndex() &&
+ _pFieldAttr->GetStart() != _pFieldAttr->GetEnd() &&
+ _pFieldAttr->Which() == EE_FEATURE_FIELD;
+ //on every new field move the end position
+ if(bIsField)
+ nEndField = bIsField ? _pFieldAttr->GetEnd() : USHRT_MAX;
+
+ LanguageType eCurLanguage = GetLanguage( aCursor );
+ if(eCurLanguage != eStartLanguage || bIsField || bIsEndField)
+ {
+ eStartLanguage = eCurLanguage;
+ //go one step back - the cursor currently selects the first character
+ //with a different language
+ //create a selection from start to the current Cursor
+ EditSelection aSelection(aStart, aCursor);
+ AddPortion(aSelection, xAlt, rToFill, bIsEndField);
+ aStart = aCursor;
+ }
+ }
+ while(aCursor.GetIndex() < aEnd.GetIndex());
+ EditSelection aSelection(aStart, aCursor);
+ AddPortion(aSelection, xAlt, rToFill, bIsField);
+ }
+ }
+#endif
+}
+
+/*-- 13.10.2003 16:43:33---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void ImpEditEngine::ApplyChangedSentence(EditView& rEditView, const ::svx::SpellPortions& rNewPortions, bool /*bIsGrammarChecking*/ )
+{
+#ifdef SVX_LIGHT
+#else
+ DBG_ASSERT(pSpellInfo, "pSpellInfo not initialized");
+ if(pSpellInfo)
+ {
+ UndoActionStart( EDITUNDO_INSERT );
+ if(pSpellInfo->aLastSpellPortions.size() == rNewPortions.size())
+ {
+ //the simple case: the same number of elements on both sides
+ //each changed element has to be applied to the corresponding source element
+ svx::SpellPortions::const_iterator aCurrentNewPortion = rNewPortions.end();
+ svx::SpellPortions::const_iterator aCurrentOldPortion = pSpellInfo->aLastSpellPortions.end();
+ SpellContentSelections::const_iterator aCurrentOldPosition = pSpellInfo->aLastSpellContentSelections.end();
+ bool bSetToEnd = false;
+ do
+ {
+ --aCurrentNewPortion;
+ --aCurrentOldPortion;
+ --aCurrentOldPosition;
+ //set the cursor to the end of the sentence - necessary to
+ //resume there at the next step
+ if(!bSetToEnd)
+ {
+ bSetToEnd = true;
+ rEditView.pImpEditView->SetEditSelection( aCurrentOldPosition->Max() );
+ }
+
+ USHORT nScriptType = GetI18NScriptTypeOfLanguage( aCurrentNewPortion->eLanguage );
+// LanguageType eTextLanguage = GetLanguage( aCurrentOldPosition->Min() );
+
+ USHORT nLangWhichId = EE_CHAR_LANGUAGE;
+ switch(nScriptType)
+ {
+ case SCRIPTTYPE_ASIAN : nLangWhichId = EE_CHAR_LANGUAGE_CJK; break;
+ case SCRIPTTYPE_COMPLEX : nLangWhichId = EE_CHAR_LANGUAGE_CTL; break;
+ }
+ if(aCurrentNewPortion->sText != aCurrentOldPortion->sText)
+ {
+ //change text and apply language
+ SfxItemSet aSet( aEditDoc.GetItemPool(), nLangWhichId, nLangWhichId);
+ aSet.Put(SvxLanguageItem(aCurrentNewPortion->eLanguage, nLangWhichId));
+ SetAttribs( *aCurrentOldPosition, aSet );
+ ImpInsertText( *aCurrentOldPosition, aCurrentNewPortion->sText );
+ }
+ else if(aCurrentNewPortion->eLanguage != aCurrentOldPortion->eLanguage)
+ {
+ //apply language
+ SfxItemSet aSet( aEditDoc.GetItemPool(), nLangWhichId, nLangWhichId);
+ aSet.Put(SvxLanguageItem(aCurrentNewPortion->eLanguage, nLangWhichId));
+ SetAttribs( *aCurrentOldPosition, aSet );
+ }
+ if(aCurrentNewPortion == rNewPortions.begin())
+ break;
+ }
+ while(aCurrentNewPortion != rNewPortions.begin());
+ }
+ else
+ {
+ //select the complete sentence
+ SpellContentSelections::const_iterator aCurrentEndPosition = pSpellInfo->aLastSpellContentSelections.end();
+ --aCurrentEndPosition;
+ SpellContentSelections::const_iterator aCurrentStartPosition = pSpellInfo->aLastSpellContentSelections.begin();
+ EditSelection aAllSentence(aCurrentStartPosition->Min(), aCurrentEndPosition->Max());
+
+ //delete the sentence completely
+ ImpDeleteSelection( aAllSentence );
+ svx::SpellPortions::const_iterator aCurrentNewPortion = rNewPortions.begin();
+ EditPaM aCurrentPaM = aAllSentence.Min();
+ while(aCurrentNewPortion != rNewPortions.end())
+ {
+ //set the language attribute
+ LanguageType eCurLanguage = GetLanguage( aCurrentPaM );
+ if(eCurLanguage != aCurrentNewPortion->eLanguage)
+ {
+ USHORT nScriptType = GetI18NScriptTypeOfLanguage( aCurrentNewPortion->eLanguage );
+ USHORT nLangWhichId = EE_CHAR_LANGUAGE;
+ switch(nScriptType)
+ {
+ case SCRIPTTYPE_ASIAN : nLangWhichId = EE_CHAR_LANGUAGE_CJK; break;
+ case SCRIPTTYPE_COMPLEX : nLangWhichId = EE_CHAR_LANGUAGE_CTL; break;
+ }
+ SfxItemSet aSet( aEditDoc.GetItemPool(), nLangWhichId, nLangWhichId);
+ aSet.Put(SvxLanguageItem(aCurrentNewPortion->eLanguage, nLangWhichId));
+ SetAttribs( aCurrentPaM, aSet );
+ }
+ //insert the new string and set the cursor to the end of the inserted string
+ aCurrentPaM = ImpInsertText( aCurrentPaM , aCurrentNewPortion->sText );
+ ++aCurrentNewPortion;
+ }
+ }
+ UndoActionEnd( EDITUNDO_INSERT );
+ }
+ FormatAndUpdate();
+ aEditDoc.SetModified(TRUE);
+#endif
+}
+/*-- 08.09.2008 11:33:02---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void ImpEditEngine::PutSpellingToSentenceStart( EditView& rEditView )
+{
+#ifdef SVX_LIGHT
+#else
+ if( pSpellInfo && pSpellInfo->aLastSpellContentSelections.size() )
+ {
+ rEditView.pImpEditView->SetEditSelection( pSpellInfo->aLastSpellContentSelections.begin()->Min() );
+ }
+
+#endif
+}
+
+
+void ImpEditEngine::DoOnlineSpelling( ContentNode* pThisNodeOnly, sal_Bool bSpellAtCursorPos, sal_Bool bInteruptable )
+{
+#ifndef SVX_LIGHT
+ /*
+ Er wird ueber alle Absaetze iteriert, nur Absaetze mit invalidierter
+ WrongList werden geprueft...
+
+ Es werden alle Woerter im invalidierten Bereich geprueft.
+ Ist ein Wort falsch, aber noch nicht in der WrongList, oder umgekehrt,
+ wird der Bereich des Wortes invalidiert
+ ( kein Invalidate, sondern wenn nur Uebergaenge von richtig=>falsch,
+ einfaches Paint, bei Uebergaengen von falsch=>richtig mit VDev
+ ueberplaetten )
+ */
+
+ if ( !xSpeller.is() )
+ return;
+
+ EditPaM aCursorPos;
+ if( pActiveView && !bSpellAtCursorPos )
+ {
+ DBG_CHKOBJ( pActiveView, EditView, 0 );
+ aCursorPos = pActiveView->pImpEditView->GetEditSelection().Max();
+ }
+ sal_Bool bRestartTimer = sal_False;
+
+ ContentNode* pLastNode = aEditDoc.SaveGetObject( aEditDoc.Count() - 1 );
+ sal_uInt16 nNodes = GetEditDoc().Count();
+ sal_uInt16 nInvalids = 0;
+ Sequence< PropertyValue > aEmptySeq;
+ for ( sal_uInt16 n = 0; n < nNodes; n++ )
+ {
+ ContentNode* pNode = GetEditDoc().GetObject( n );
+ if ( pThisNodeOnly )
+ pNode = pThisNodeOnly;
+
+ if ( pNode->GetWrongList()->IsInvalid() )
+ {
+ WrongList* pWrongList = pNode->GetWrongList();
+ sal_uInt16 nInvStart = pWrongList->GetInvalidStart();
+ sal_uInt16 nInvEnd = pWrongList->GetInvalidEnd();
+
+ sal_uInt16 nWrongs = 0; // Auch im Absatz mal die Kontrolle abgeben...
+// sal_Bool bStop = sal_False;
+
+ sal_uInt16 nPaintFrom = 0xFFFF, nPaintTo = 0;
+ sal_Bool bSimpleRepaint = sal_True;
+
+ pWrongList->SetValid();
+
+ EditPaM aPaM( pNode, nInvStart );
+ EditSelection aSel( aPaM, aPaM );
+ while ( ( aSel.Max().GetNode() == pNode ) /* && !bStop */ )
+ {
+ if ( ( aSel.Min().GetIndex() > nInvEnd )
+ || ( ( aSel.Max().GetNode() == pLastNode ) && ( aSel.Max().GetIndex() >= pLastNode->Len() ) ) )
+ break; // Dokument- oder Ungueltigkeitsbereich-Ende
+
+ aSel = SelectWord( aSel, ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
+ String aWord( GetSelected( aSel ) );
+ // Wenn Punkt dahinter, muss dieser mit uebergeben werden !
+ // Falls Abkuerzung...
+ sal_Bool bDottAdded = sal_False;
+ if ( aSel.Max().GetIndex() < aSel.Max().GetNode()->Len() )
+ {
+ sal_Unicode cNext = aSel.Max().GetNode()->GetChar( aSel.Max().GetIndex() );
+ if ( cNext == '.' )
+ {
+ aSel.Max().GetIndex()++;
+ aWord += cNext;
+ bDottAdded = sal_True;
+ }
+ }
+
+
+ sal_Bool bChanged = sal_False;
+ if ( aWord.Len() > 0 )
+ {
+ sal_uInt16 nWStart = aSel.Min().GetIndex();
+ sal_uInt16 nWEnd= aSel.Max().GetIndex();
+ if ( !xSpeller->isValid( aWord, GetLanguage( EditPaM( aSel.Min().GetNode(), nWStart+1 ) ), aEmptySeq ) )
+ {
+ // Pruefen, ob schon richtig markiert...
+ nWrongs++;
+ // Nur bei SimpleRepaint stoppen, sonst zu oft VDev
+ // if ( ( nWrongs > 8 ) && bSimpleRepaint )
+ // {
+ // bStop = sal_True;
+ // pWrongList->MarkInvalid( aSel.Max().GetIndex(), nInvEnd );
+ // }
+ sal_uInt16 nXEnd = bDottAdded ? nWEnd -1 : nWEnd;
+ if ( !pWrongList->HasWrong( nWStart, nXEnd ) )
+ {
+ // Wort als falsch markieren...
+ // Aber nur, wenn nicht an Cursor-Position...
+ sal_Bool bCursorPos = sal_False;
+ if ( aCursorPos.GetNode() == pNode )
+ {
+ if ( ( nWStart <= aCursorPos.GetIndex() ) && nWEnd >= aCursorPos.GetIndex() )
+ bCursorPos = sal_True;
+ }
+ if ( bCursorPos )
+ {
+ // Dann weiter als ungueltig markieren...
+ pWrongList->GetInvalidStart() = nWStart;
+ pWrongList->GetInvalidEnd() = nWEnd;
+ bRestartTimer = sal_True;
+ }
+ else
+ {
+ // Es kann sein, dass die Wrongs in der Liste nicht
+ // genau ueber Woerter aufgespannt sind, weil die
+ // WordDelimiters beim Expandieren nicht ausgewrtet werden.
+ pWrongList->InsertWrong( nWStart, nXEnd, sal_True );
+ bChanged = sal_True;
+ }
+ }
+ }
+ else
+ {
+ // Pruefen, ob nicht als als falsch markiert....
+ if ( pWrongList->HasAnyWrong( nWStart, nWEnd ) )
+ {
+ pWrongList->ClearWrongs( nWStart, nWEnd, pNode );
+ bSimpleRepaint = sal_False;
+ bChanged = sal_True;
+ }
+ }
+ if ( bChanged )
+ {
+ if ( nPaintFrom == 0xFFFF )
+ nPaintFrom = nWStart;
+ nPaintTo = nWEnd;
+ }
+ }
+
+ EditPaM aLastEnd( aSel.Max() );
+ aSel = WordRight( aSel.Max(), ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
+ if ( bChanged && ( aSel.Min().GetNode() == pNode ) &&
+ ( ( aSel.Min().GetIndex()-aLastEnd.GetIndex() > 1 ) ) )
+ {
+ // Wenn zwei Worte durch mehr Zeichen als ein Blank getrennt
+ // sind, kann es passieren, dass beim Aufsplitten eines Wrongs
+ // der Start den zweiten Wortes vor dem tatsaechlich Wort liegt
+ pWrongList->ClearWrongs( aLastEnd.GetIndex(), aSel.Min().GetIndex(), pNode );
+ }
+ }
+
+ // Invalidieren?
+ if ( ( nPaintFrom != 0xFFFF ) )
+ {
+ aStatus.GetStatusWord() |= EE_STAT_WRONGWORDCHANGED;
+ CallStatusHdl();
+
+ if ( aEditViews.Count() )
+ {
+ // Bei SimpleRepaint wuerde ein uebermalen ohne VDev reichen,
+ // aber dann muesste ich ueber alle Views, Intersecten,
+ // Clippen, ...
+ // Lohnt wahrscheinlich nicht.
+ EditPaM aStartPaM( pNode, nPaintFrom );
+ EditPaM aEndPaM( pNode, nPaintTo );
+ Rectangle aStartCursor( PaMtoEditCursor( aStartPaM ) );
+ Rectangle aEndCursor( PaMtoEditCursor( aEndPaM ) );
+ DBG_ASSERT( aInvalidRec.IsEmpty(), "InvalidRect gesetzt!" );
+ aInvalidRec.Left() = 0;
+ aInvalidRec.Right() = GetPaperSize().Width();
+ aInvalidRec.Top() = aStartCursor.Top();
+ aInvalidRec.Bottom() = aEndCursor.Bottom();
+ if ( pActiveView && pActiveView->HasSelection() )
+ {
+ // Dann darf nicht ueber VDev ausgegeben werden
+ UpdateViews( NULL );
+ }
+ else if ( bSimpleRepaint )
+ {
+ for ( sal_uInt16 nView = 0; nView < aEditViews.Count(); nView++ )
+ {
+ EditView* pView = aEditViews[nView];
+ Rectangle aClipRec( aInvalidRec );
+ aClipRec.Intersection( pView->GetVisArea() );
+ if ( !aClipRec.IsEmpty() )
+ {
+ // in Fensterkoordinaten umwandeln....
+ aClipRec.SetPos( pView->pImpEditView->GetWindowPos( aClipRec.TopLeft() ) );
+ // Wenn Selektion, dann VDev...
+ Paint( pView->pImpEditView, aClipRec, pView->HasSelection() );
+ }
+ }
+ }
+ else
+ {
+ UpdateViews( pActiveView );
+ }
+ aInvalidRec = Rectangle();
+ }
+ }
+ // Nach zwei korrigierten Nodes die Kontrolle abgeben...
+ nInvalids++;
+ if ( bInteruptable && ( nInvalids >= 2 ) )
+ {
+ bRestartTimer = sal_True;
+ break;
+ }
+ }
+
+ if ( pThisNodeOnly )
+ break;
+ }
+ if ( bRestartTimer )
+ aOnlineSpellTimer.Start();
+#endif // !SVX_LIGHT
+}
+
+
+EESpellState ImpEditEngine::HasSpellErrors()
+{
+ DBG_ASSERT( xSpeller.is(), "Kein Speller gesetzt!" );
+
+#ifndef SVX_LIGHT
+ ContentNode* pLastNode = aEditDoc.SaveGetObject( aEditDoc.Count() - 1 );
+ EditSelection aCurSel( aEditDoc.GetStartPaM() );
+
+ String aWord;
+ Reference< XSpellAlternatives > xSpellAlt;
+ Sequence< PropertyValue > aEmptySeq;
+ while ( !xSpellAlt.is() )
+ {
+ if ( ( aCurSel.Max().GetNode() == pLastNode ) &&
+ ( aCurSel.Max().GetIndex() >= pLastNode->Len() ) )
+ {
+ return EE_SPELL_OK;
+ }
+
+ aCurSel = SelectWord( aCurSel, ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
+ aWord = GetSelected( aCurSel );
+ if ( aWord.Len() > 0 )
+ {
+ LanguageType eLang = GetLanguage( aCurSel.Max() );
+ SvxSpellWrapper::CheckSpellLang( xSpeller, eLang );
+ xSpellAlt = xSpeller->spell( aWord, eLang, aEmptySeq );
+ }
+ aCurSel = WordRight( aCurSel.Max(), ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
+ }
+#endif
+
+ return EE_SPELL_ERRORFOUND;
+}
+
+EESpellState ImpEditEngine::StartThesaurus( EditView* pEditView )
+{
+#ifndef SVX_LIGHT
+ EditSelection aCurSel( pEditView->pImpEditView->GetEditSelection() );
+ if ( !aCurSel.HasRange() )
+ aCurSel = SelectWord( aCurSel, ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
+ String aWord( GetSelected( aCurSel ) );
+
+ Reference< XThesaurus > xThes( SvxGetThesaurus() );
+ if (!xThes.is())
+ return EE_SPELL_ERRORFOUND;
+
+ EditAbstractDialogFactory* pFact = EditAbstractDialogFactory::Create();
+ AbstractThesaurusDialog* pDlg = pFact->CreateThesaurusDialog( pEditView->GetWindow(), xThes, aWord, GetLanguage( aCurSel.Max() ) );
+ if ( pDlg->Execute() == RET_OK )
+ {
+ // Wort ersetzen...
+ pEditView->pImpEditView->DrawSelection();
+ pEditView->pImpEditView->SetEditSelection( aCurSel );
+ pEditView->pImpEditView->DrawSelection();
+ pEditView->InsertText( pDlg->GetWord() );
+ pEditView->ShowCursor( sal_True, sal_False );
+ }
+
+ delete pDlg;
+ return EE_SPELL_OK;
+#else
+ return EE_SPELL_NOSPELLER;
+#endif
+}
+
+sal_uInt16 ImpEditEngine::StartSearchAndReplace( EditView* pEditView, const SvxSearchItem& rSearchItem )
+{
+ sal_uInt16 nFound = 0;
+
+#ifndef SVX_LIGHT
+ EditSelection aCurSel( pEditView->pImpEditView->GetEditSelection() );
+
+ // FIND_ALL ohne Mehrfachselektion nicht moeglich.
+ if ( ( rSearchItem.GetCommand() == SVX_SEARCHCMD_FIND ) ||
+ ( rSearchItem.GetCommand() == SVX_SEARCHCMD_FIND_ALL ) )
+ {
+ if ( Search( rSearchItem, pEditView ) )
+ nFound++;
+ }
+ else if ( rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE )
+ {
+ // Das Wort ist selektiert, wenn der Anwender die Selektion
+ // nicht zwischendurch manipuliert:
+ if ( aCurSel.HasRange() )
+ {
+ pEditView->InsertText( rSearchItem.GetReplaceString() );
+ nFound = 1;
+ }
+ else
+ if( Search( rSearchItem, pEditView ) )
+ nFound = 1;
+ }
+ else if ( rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL )
+ {
+ // Der Writer ersetzt alle, vorn Anfang bis Ende...
+ SvxSearchItem aTmpItem( rSearchItem );
+ aTmpItem.SetBackward( sal_False );
+
+ pEditView->pImpEditView->DrawSelection();
+
+ aCurSel.Adjust( aEditDoc );
+ EditPaM aStartPaM = aTmpItem.GetSelection() ? aCurSel.Min() : aEditDoc.GetStartPaM();
+ EditSelection aFoundSel( aCurSel.Max() );
+ sal_Bool bFound = ImpSearch( aTmpItem, aCurSel, aStartPaM, aFoundSel );
+ if ( bFound )
+ UndoActionStart( EDITUNDO_REPLACEALL );
+ while ( bFound )
+ {
+ nFound++;
+ aStartPaM = ImpInsertText( aFoundSel, rSearchItem.GetReplaceString() );
+ bFound = ImpSearch( aTmpItem, aCurSel, aStartPaM, aFoundSel );
+ }
+ if ( nFound )
+ {
+ EditPaM aNewPaM( aFoundSel.Max() );
+ if ( aNewPaM.GetIndex() > aNewPaM.GetNode()->Len() )
+ aNewPaM.GetIndex() = aNewPaM.GetNode()->Len();
+ pEditView->pImpEditView->SetEditSelection( aNewPaM );
+ FormatAndUpdate( pEditView );
+ UndoActionEnd( EDITUNDO_REPLACEALL );
+ }
+ else
+ {
+ pEditView->pImpEditView->DrawSelection();
+ pEditView->ShowCursor( sal_True, sal_False );
+ }
+ }
+#endif // !SVX_LIGHT
+ return nFound;
+}
+
+BOOL ImpEditEngine::Search( const SvxSearchItem& rSearchItem, EditView* pEditView )
+{
+ EditSelection aSel( pEditView->pImpEditView->GetEditSelection() );
+ aSel.Adjust( aEditDoc );
+ EditPaM aStartPaM( aSel.Max() );
+ if ( rSearchItem.GetSelection() && !rSearchItem.GetBackward() )
+ aStartPaM = aSel.Min();
+
+ EditSelection aFoundSel;
+ BOOL bFound = ImpSearch( rSearchItem, aSel, aStartPaM, aFoundSel );
+ if ( bFound && ( aFoundSel == aSel ) ) // Bei Rueckwaetssuche
+ {
+ aStartPaM = aSel.Min();
+ bFound = ImpSearch( rSearchItem, aSel, aStartPaM, aFoundSel );
+ }
+
+ pEditView->pImpEditView->DrawSelection();
+ if ( bFound )
+ {
+ // Erstmal das Min einstellen, damit das ganze Wort in den sichtbaren Bereich kommt.
+ pEditView->pImpEditView->SetEditSelection( aFoundSel.Min() );
+ pEditView->ShowCursor( TRUE, FALSE );
+ pEditView->pImpEditView->SetEditSelection( aFoundSel );
+ }
+ else
+ pEditView->pImpEditView->SetEditSelection( aSel.Max() );
+
+ pEditView->pImpEditView->DrawSelection();
+ pEditView->ShowCursor( TRUE, FALSE );
+ return bFound;
+}
+
+sal_Bool ImpEditEngine::ImpSearch( const SvxSearchItem& rSearchItem,
+ const EditSelection& rSearchSelection, const EditPaM& rStartPos, EditSelection& rFoundSel )
+{
+#ifndef SVX_LIGHT
+ util::SearchOptions aSearchOptions( rSearchItem.GetSearchOptions() );
+ aSearchOptions.Locale = GetLocale( rStartPos );
+
+ sal_Bool bBack = rSearchItem.GetBackward();
+ sal_Bool bSearchInSelection = rSearchItem.GetSelection();
+ sal_uInt16 nStartNode = aEditDoc.GetPos( rStartPos.GetNode() );
+ sal_uInt16 nEndNode;
+ if ( bSearchInSelection )
+ {
+ nEndNode = aEditDoc.GetPos( bBack ? rSearchSelection.Min().GetNode() : rSearchSelection.Max().GetNode() );
+ }
+ else
+ {
+ nEndNode = bBack ? 0 : aEditDoc.Count()-1;
+ }
+
+ utl::TextSearch aSearcher( aSearchOptions );
+
+ // ueber die Absaetze iterieren...
+ for ( sal_uInt16 nNode = nStartNode;
+ bBack ? ( nNode >= nEndNode ) : ( nNode <= nEndNode) ;
+ bBack ? nNode-- : nNode++ )
+ {
+ // Bei rueckwaertsuche, wenn nEndNode = 0:
+ if ( nNode >= 0xFFFF )
+ return sal_False;
+
+ ContentNode* pNode = aEditDoc.GetObject( nNode );
+
+ sal_uInt16 nStartPos = 0;
+ sal_uInt16 nEndPos = pNode->Len();
+ if ( nNode == nStartNode )
+ {
+ if ( bBack )
+ nEndPos = rStartPos.GetIndex();
+ else
+ nStartPos = rStartPos.GetIndex();
+ }
+ if ( ( nNode == nEndNode ) && bSearchInSelection )
+ {
+ if ( bBack )
+ nStartPos = rSearchSelection.Min().GetIndex();
+ else
+ nEndPos = rSearchSelection.Max().GetIndex();
+ }
+
+ // Suchen...
+ XubString aParaStr( GetEditDoc().GetParaAsString( pNode ) );
+ bool bFound = false;
+ if ( bBack )
+ {
+ SwapUSHORTs( nStartPos, nEndPos );
+ bFound = aSearcher.SearchBkwrd( aParaStr, &nStartPos, &nEndPos);
+ }
+ else
+ bFound = aSearcher.SearchFrwrd( aParaStr, &nStartPos, &nEndPos);
+
+ if ( bFound )
+ {
+ rFoundSel.Min().SetNode( pNode );
+ rFoundSel.Min().SetIndex( nStartPos );
+ rFoundSel.Max().SetNode( pNode );
+ rFoundSel.Max().SetIndex( nEndPos );
+ return sal_True;
+ }
+ }
+#endif // !SVX_LIGHT
+ return sal_False;
+}
+
+sal_Bool ImpEditEngine::HasText( const SvxSearchItem& rSearchItem )
+{
+#ifndef SVX_LIGHT
+ SvxSearchItem aTmpItem( rSearchItem );
+ aTmpItem.SetBackward( sal_False );
+ aTmpItem.SetSelection( sal_False );
+
+ EditPaM aStartPaM( aEditDoc.GetStartPaM() );
+ EditSelection aDummySel( aStartPaM );
+ EditSelection aFoundSel;
+ return ImpSearch( aTmpItem, aDummySel, aStartPaM, aFoundSel );
+#else
+ return sal_False;
+#endif
+}
+
+void ImpEditEngine::SetAutoCompleteText( const String& rStr, sal_Bool bClearTipWindow )
+{
+#ifndef SVX_LIGHT
+ aAutoCompleteText = rStr;
+ if ( bClearTipWindow && pActiveView )
+ Help::ShowQuickHelp( pActiveView->GetWindow(), Rectangle(), String(), 0 );
+#endif // !SVX_LIGHT
+}
+
+EditSelection ImpEditEngine::TransliterateText( const EditSelection& rSelection, sal_Int32 nTransliterationMode )
+{
+ EditSelection aSel( rSelection );
+ aSel.Adjust( aEditDoc );
+
+ if ( !aSel.HasRange() )
+ aSel = SelectWord( aSel );
+
+ EditSelection aNewSel( aSel );
+
+ USHORT nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
+ USHORT nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
+
+ BOOL bChanges = FALSE;
+ BOOL bLenChanged = FALSE;
+ EditUndoTransliteration* pUndo = NULL;
+
+ utl::TransliterationWrapper aTranslitarationWrapper( ::comphelper::getProcessServiceFactory(), nTransliterationMode );
+ BOOL bConsiderLanguage = aTranslitarationWrapper.needLanguageForTheMode();
+
+ for ( USHORT nNode = nStartNode; nNode <= nEndNode; nNode++ )
+ {
+ ContentNode* pNode = aEditDoc.GetObject( nNode );
+ xub_StrLen nStartPos = 0;
+ xub_StrLen nEndPos = pNode->Len();
+ if ( nNode == nStartNode )
+ nStartPos = aSel.Min().GetIndex();
+ if ( nNode == nEndNode ) // kann auch == nStart sein!
+ nEndPos = aSel.Max().GetIndex();
+
+ USHORT nCurrentStart = nStartPos;
+ USHORT nCurrentEnd = nEndPos;
+ sal_uInt16 nLanguage = LANGUAGE_SYSTEM;
+
+ do
+ {
+ if ( bConsiderLanguage )
+ {
+ nLanguage = GetLanguage( EditPaM( pNode, nCurrentStart+1 ), &nCurrentEnd );
+ if ( nCurrentEnd > nEndPos )
+ nCurrentEnd = nEndPos;
+ }
+
+ xub_StrLen nLen = nCurrentEnd - nCurrentStart;
+
+ Sequence <sal_Int32> aOffsets;
+ String aNewText( aTranslitarationWrapper.transliterate( *pNode, nLanguage, nCurrentStart, nLen, &aOffsets ) );
+
+ if( ( nLen != aNewText.Len() ) || !pNode->Equals( aNewText, nCurrentStart, nLen ) )
+ {
+ bChanges = TRUE;
+ if ( nLen != aNewText.Len() )
+ bLenChanged = TRUE;
+
+#ifndef SVX_LIGHT
+ // Create UndoAction on Demand....
+ if ( !pUndo && IsUndoEnabled() && !IsInUndo() )
+ {
+ ESelection aESel( CreateESel( aSel ) );
+ pUndo = new EditUndoTransliteration( this, aESel, nTransliterationMode );
+
+ if ( ( nStartNode == nEndNode ) && !aSel.Min().GetNode()->GetCharAttribs().HasAttrib( aSel.Min().GetIndex(), aSel.Max().GetIndex() ) )
+ pUndo->SetText( aSel.Min().GetNode()->Copy( aSel.Min().GetIndex(), aSel.Max().GetIndex()-aSel.Min().GetIndex() ) );
+ else
+ pUndo->SetText( CreateBinTextObject( aSel, NULL ) );
+ }
+#endif
+
+ // Change text without loosing the attributes
+ USHORT nCharsAfterTransliteration =
+ sal::static_int_cast< USHORT >(aOffsets.getLength());
+ const sal_Int32* pOffsets = aOffsets.getConstArray();
+ short nDiffs = 0;
+ for ( USHORT n = 0; n < nCharsAfterTransliteration; n++ )
+ {
+ USHORT nCurrentPos = nCurrentStart+n;
+ sal_Int32 nDiff = (nCurrentPos-nDiffs) - pOffsets[n];
+
+ if ( !nDiff )
+ {
+ DBG_ASSERT( nCurrentPos < pNode->Len(), "TransliterateText - String smaller than expected!" );
+ pNode->SetChar( nCurrentPos, aNewText.GetChar(n) );
+ }
+ else if ( nDiff < 0 )
+ {
+ // Replace first char, delete the rest...
+ DBG_ASSERT( nCurrentPos < pNode->Len(), "TransliterateText - String smaller than expected!" );
+ pNode->SetChar( nCurrentPos, aNewText.GetChar(n) );
+
+ DBG_ASSERT( (nCurrentPos+1) < pNode->Len(), "TransliterateText - String smaller than expected!" );
+ GetEditDoc().RemoveChars( EditPaM( pNode, nCurrentPos+1 ), sal::static_int_cast< USHORT >(-nDiff) );
+ }
+ else
+ {
+ DBG_ASSERT( nDiff == 1, "TransliterateText - Diff other than expected! But should work..." );
+ GetEditDoc().InsertText( EditPaM( pNode, nCurrentPos ), aNewText.GetChar(n) );
+
+ }
+ nDiffs = sal::static_int_cast< short >(nDiffs + nDiff);
+ }
+
+ if ( nNode == nEndNode )
+ aNewSel.Max().GetIndex() =
+ aNewSel.Max().GetIndex() + nDiffs;
+
+ ParaPortion* pParaPortion = GetParaPortions()[nNode];
+ pParaPortion->MarkSelectionInvalid( nCurrentStart, std::max< USHORT >( nCurrentStart+nLen, nCurrentStart+aNewText.Len() ) );
+
+ }
+ nCurrentStart = nCurrentEnd;
+ } while( nCurrentEnd < nEndPos );
+ }
+
+#ifndef SVX_LIGHT
+ if ( pUndo )
+ {
+ ESelection aESel( CreateESel( aNewSel ) );
+ pUndo->SetNewSelection( aESel );
+ InsertUndo( pUndo );
+ }
+#endif
+
+ if ( bChanges )
+ {
+ TextModified();
+ SetModifyFlag( sal_True );
+ if ( bLenChanged )
+ UpdateSelections();
+ FormatAndUpdate();
+ }
+
+ return aNewSel;
+}
+
+void ImpEditEngine::SetAsianCompressionMode( USHORT n )
+{
+ if ( n != nAsianCompressionMode )
+ {
+ nAsianCompressionMode = n;
+ if ( ImplHasText() )
+ {
+ FormatFullDoc();
+ UpdateViews();
+ }
+ }
+}
+
+void ImpEditEngine::SetKernAsianPunctuation( BOOL b )
+{
+ if ( b != bKernAsianPunctuation )
+ {
+ bKernAsianPunctuation = b;
+ if ( ImplHasText() )
+ {
+ FormatFullDoc();
+ UpdateViews();
+ }
+ }
+}
+
+void ImpEditEngine::SetAddExtLeading( BOOL bExtLeading )
+{
+ if ( IsAddExtLeading() != bExtLeading )
+ {
+ bAddExtLeading = bExtLeading;
+ if ( ImplHasText() )
+ {
+ FormatFullDoc();
+ UpdateViews();
+ }
+ }
+};
+
+
+
+BOOL ImpEditEngine::ImplHasText() const
+{
+ return ( ( GetEditDoc().Count() > 1 ) || GetEditDoc().GetObject(0)->Len() );
+}
+
+long ImpEditEngine::LogicToTwips( long n )
+{
+ Size aSz( n, 0 );
+ MapMode aTwipsMode( MAP_TWIP );
+ aSz = pRefDev->LogicToLogic( aSz, NULL, &aTwipsMode );
+ return aSz.Width();
+}
+
+
diff --git a/editeng/source/editeng/impedit5.cxx b/editeng/source/editeng/impedit5.cxx
new file mode 100644
index 0000000000..9f9700d891
--- /dev/null
+++ b/editeng/source/editeng/impedit5.cxx
@@ -0,0 +1,914 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: impedit5.cxx,v $
+ * $Revision: 1.34 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <eeng_pch.hxx>
+
+#include <impedit.hxx>
+#include <editeng/editeng.hxx>
+#include <editdbg.hxx>
+
+#include <svl/smplhint.hxx>
+
+
+#include <editeng/lrspitem.hxx>
+
+void ImpEditEngine::SetStyleSheetPool( SfxStyleSheetPool* pSPool )
+{
+ if ( pStylePool != pSPool )
+ {
+// if ( pStylePool )
+// EndListening( *pStylePool, TRUE );
+
+ pStylePool = pSPool;
+
+// if ( pStylePool )
+// StartListening( *pStylePool, TRUE );
+ }
+}
+
+SfxStyleSheet* ImpEditEngine::GetStyleSheet( USHORT nPara ) const
+{
+ ContentNode* pNode = aEditDoc.SaveGetObject( nPara );
+ return pNode ? pNode->GetContentAttribs().GetStyleSheet() : NULL;
+}
+
+void ImpEditEngine::SetStyleSheet( EditSelection aSel, SfxStyleSheet* pStyle )
+{
+ aSel.Adjust( aEditDoc );
+
+ USHORT nStartPara = aEditDoc.GetPos( aSel.Min().GetNode() );
+ USHORT nEndPara = aEditDoc.GetPos( aSel.Max().GetNode() );
+
+ BOOL _bUpdate = GetUpdateMode();
+ SetUpdateMode( FALSE );
+
+ for ( USHORT n = nStartPara; n <= nEndPara; n++ )
+ SetStyleSheet( n, pStyle );
+
+ SetUpdateMode( _bUpdate, 0 );
+}
+
+void ImpEditEngine::SetStyleSheet( USHORT nPara, SfxStyleSheet* pStyle )
+{
+ DBG_ASSERT( GetStyleSheetPool() || !pStyle, "SetStyleSheet: No StyleSheetPool registered!" );
+ ContentNode* pNode = aEditDoc.SaveGetObject( nPara );
+ SfxStyleSheet* pCurStyle = pNode->GetStyleSheet();
+ if ( pStyle != pCurStyle )
+ {
+ if ( IsUndoEnabled() && !IsInUndo() && aStatus.DoUndoAttribs() )
+ {
+ XubString aPrevStyleName;
+ if ( pCurStyle )
+ aPrevStyleName = pCurStyle->GetName();
+
+ XubString aNewStyleName;
+ if ( pStyle )
+ aNewStyleName = pStyle->GetName();
+
+ InsertUndo(
+ new EditUndoSetStyleSheet( this, aEditDoc.GetPos( pNode ),
+ aPrevStyleName, pCurStyle ? pCurStyle->GetFamily() : SFX_STYLE_FAMILY_PARA,
+ aNewStyleName, pStyle ? pStyle->GetFamily() : SFX_STYLE_FAMILY_PARA,
+ pNode->GetContentAttribs().GetItems() ) );
+ }
+ if ( pCurStyle )
+ EndListening( *pCurStyle, FALSE );
+ pNode->SetStyleSheet( pStyle, aStatus.UseCharAttribs() );
+ if ( pStyle )
+ StartListening( *pStyle, FALSE );
+ ParaAttribsChanged( pNode );
+ }
+ FormatAndUpdate();
+}
+
+void ImpEditEngine::UpdateParagraphsWithStyleSheet( SfxStyleSheet* pStyle )
+{
+ SvxFont aFontFromStyle;
+ CreateFont( aFontFromStyle, pStyle->GetItemSet() );
+
+ BOOL bUsed = FALSE;
+ for ( USHORT nNode = 0; nNode < aEditDoc.Count(); nNode++ )
+ {
+ ContentNode* pNode = aEditDoc.GetObject( nNode );
+ if ( pNode->GetStyleSheet() == pStyle )
+ {
+ bUsed = TRUE;
+ if ( aStatus.UseCharAttribs() )
+ pNode->SetStyleSheet( pStyle, aFontFromStyle );
+ else
+ pNode->SetStyleSheet( pStyle, FALSE );
+
+ ParaAttribsChanged( pNode );
+ }
+ }
+ if ( bUsed )
+ {
+ GetEditEnginePtr()->StyleSheetChanged( pStyle );
+ FormatAndUpdate();
+ }
+}
+
+void ImpEditEngine::RemoveStyleFromParagraphs( SfxStyleSheet* pStyle )
+{
+ for ( USHORT nNode = 0; nNode < aEditDoc.Count(); nNode++ )
+ {
+ ContentNode* pNode = aEditDoc.GetObject(nNode);
+ if ( pNode->GetStyleSheet() == pStyle )
+ {
+ pNode->SetStyleSheet( NULL );
+ ParaAttribsChanged( pNode );
+ }
+ }
+ FormatAndUpdate();
+}
+
+void ImpEditEngine::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ // Damit nicht beim Destruieren unnoetig formatiert wird:
+ if ( !bDowning )
+ {
+ DBG_CHKOBJ( GetEditEnginePtr(), EditEngine, 0 );
+
+ SfxStyleSheet* pStyle = NULL;
+ ULONG nId = 0;
+
+ if ( rHint.ISA( SfxStyleSheetHint ) )
+ {
+ const SfxStyleSheetHint& rH = (const SfxStyleSheetHint&) rHint;
+ DBG_ASSERT( rH.GetStyleSheet()->ISA( SfxStyleSheet ), "Kein SfxStyleSheet!" );
+ pStyle = (SfxStyleSheet*) rH.GetStyleSheet();
+ nId = rH.GetHint();
+ }
+ else if ( ( rHint.Type() == TYPE(SfxSimpleHint ) ) && ( rBC.ISA( SfxStyleSheet ) ) )
+ {
+ pStyle = (SfxStyleSheet*)&rBC;
+ nId = ((SfxSimpleHint&)rHint).GetId();
+ }
+
+ if ( pStyle )
+ {
+ if ( ( nId == SFX_HINT_DYING ) ||
+ ( nId == SFX_STYLESHEET_INDESTRUCTION ) ||
+ ( nId == SFX_STYLESHEET_ERASED ) )
+ {
+ RemoveStyleFromParagraphs( pStyle );
+ }
+ else if ( ( nId == SFX_HINT_DATACHANGED ) ||
+ ( nId == SFX_STYLESHEET_MODIFIED ) )
+ {
+ UpdateParagraphsWithStyleSheet( pStyle );
+
+ // Alle Absaetze mit EditStyles, die das geaenderte Style
+ // irgendwie als Parent haben, muessen formatiert werden.
+ // ULONG nStyles = pMyStylePool->GetStyles().Count();
+ // for ( ULONG nStyle = 0; nStyle < nStyles; nStyle++ )
+ // {
+ // EditStyleSheet* pES = (EditStyleSheet*)pMyStylePool->GetStyles().GetObject( nStyle );
+ // DBG_ASSERT( pES, "NULL-Pointer im StyleSheetPool!" );
+ // if ( pES->IsUsed() && pES->HasStyleAsAnyParent( *pStyle ) )
+ // UpdateParagraphsWithStyleSheet( pES );
+ // }
+ }
+ }
+ }
+}
+
+EditUndoSetAttribs* ImpEditEngine::CreateAttribUndo( EditSelection aSel, const SfxItemSet& rSet )
+{
+ DBG_ASSERT( !aSel.DbgIsBuggy( aEditDoc ), "CreateAttribUndo: Fehlerhafte Selektion" );
+ aSel.Adjust( aEditDoc );
+
+ ESelection aESel( CreateESel( aSel ) );
+
+ USHORT nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
+ USHORT nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
+
+ DBG_ASSERT( nStartNode <= nEndNode, "CreateAttribUndo: Start > End ?!" );
+
+ EditUndoSetAttribs* pUndo = NULL;
+ if ( rSet.GetPool() != &aEditDoc.GetItemPool() )
+ {
+ SfxItemSet aTmpSet( GetEmptyItemSet() );
+ aTmpSet.Put( rSet );
+ pUndo = new EditUndoSetAttribs( this, aESel, aTmpSet );
+ }
+ else
+ {
+ pUndo = new EditUndoSetAttribs( this, aESel, rSet );
+ }
+
+ SfxItemPool* pPool = pUndo->GetNewAttribs().GetPool();
+
+ for ( USHORT nPara = nStartNode; nPara <= nEndNode; nPara++ )
+ {
+ ContentNode* pNode = aEditDoc.GetObject( nPara );
+ DBG_ASSERT( aEditDoc.SaveGetObject( nPara ), "Node nicht gefunden: CreateAttribUndo" );
+ ContentAttribsInfo* pInf = new ContentAttribsInfo( pNode->GetContentAttribs().GetItems() );
+ pUndo->GetContentInfos().Insert( pInf, pUndo->GetContentInfos().Count() );
+
+ for ( USHORT nAttr = 0; nAttr < pNode->GetCharAttribs().Count(); nAttr++ )
+ {
+ EditCharAttribPtr pAttr = pNode->GetCharAttribs().GetAttribs()[ nAttr ];
+ if ( pAttr->GetLen() )
+ {
+ EditCharAttribPtr pNew = MakeCharAttrib( *pPool, *pAttr->GetItem(), pAttr->GetStart(), pAttr->GetEnd() );
+ pInf->GetPrevCharAttribs().Insert( pNew, pInf->GetPrevCharAttribs().Count() );
+ }
+ }
+ }
+ return pUndo;
+}
+
+void ImpEditEngine::UndoActionStart( USHORT nId, const ESelection& aSel )
+{
+ if ( IsUndoEnabled() && !IsInUndo() )
+ {
+ GetUndoManager().EnterListAction( GetEditEnginePtr()->GetUndoComment( nId ), XubString(), nId );
+ DBG_ASSERT( !pUndoMarkSelection, "UndoAction SelectionMarker?" );
+ pUndoMarkSelection = new ESelection( aSel );
+ }
+}
+
+void ImpEditEngine::UndoActionStart( USHORT nId )
+{
+ if ( IsUndoEnabled() && !IsInUndo() )
+ {
+ GetUndoManager().EnterListAction( GetEditEnginePtr()->GetUndoComment( nId ), XubString(), nId );
+ DBG_ASSERT( !pUndoMarkSelection, "UndoAction SelectionMarker?" );
+ }
+}
+
+void ImpEditEngine::UndoActionEnd( USHORT )
+{
+ if ( IsUndoEnabled() && !IsInUndo() )
+ {
+ GetUndoManager().LeaveListAction();
+ delete pUndoMarkSelection;
+ pUndoMarkSelection = NULL;
+ }
+}
+
+void ImpEditEngine::InsertUndo( EditUndo* pUndo, BOOL bTryMerge )
+{
+ DBG_ASSERT( !IsInUndo(), "InsertUndo im Undomodus!" );
+ if ( pUndoMarkSelection )
+ {
+ EditUndoMarkSelection* pU = new EditUndoMarkSelection( this, *pUndoMarkSelection );
+ GetUndoManager().AddUndoAction( pU, FALSE );
+ delete pUndoMarkSelection;
+ pUndoMarkSelection = NULL;
+ }
+ GetUndoManager().AddUndoAction( pUndo, bTryMerge );
+
+ mbLastTryMerge = bTryMerge;
+}
+
+void ImpEditEngine::ResetUndoManager()
+{
+ if ( HasUndoManager() )
+ GetUndoManager().Clear();
+}
+
+void ImpEditEngine::EnableUndo( BOOL bEnable )
+{
+ // Beim Umschalten des Modus Liste loeschen:
+ if ( bEnable != IsUndoEnabled() )
+ ResetUndoManager();
+
+ bUndoEnabled = bEnable;
+}
+
+BOOL ImpEditEngine::Undo( EditView* pView )
+{
+ if ( HasUndoManager() && GetUndoManager().GetUndoActionCount() )
+ {
+ SetActiveView( pView );
+ GetUndoManager().Undo( 1 );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL ImpEditEngine::Redo( EditView* pView )
+{
+ if ( HasUndoManager() && GetUndoManager().GetRedoActionCount() )
+ {
+ SetActiveView( pView );
+ GetUndoManager().Redo( 0 );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL ImpEditEngine::Repeat( EditView* /* pView */ )
+{
+ if ( HasUndoManager() && GetUndoManager().GetRepeatActionCount() )
+ {
+ DBG_WARNING( "Repeat nicht implementiert!" );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+SfxItemSet ImpEditEngine::GetAttribs( EditSelection aSel, BOOL bOnlyHardAttrib )
+{
+ DBG_CHKOBJ( GetEditEnginePtr(), EditEngine, 0 );
+
+ aSel.Adjust( aEditDoc );
+
+#if OSL_DEBUG_LEVEL > 1
+// if ( ( aSel.Min().GetNode() == aSel.Max().GetNode() ) && ( bOnlyHardAttrib == EditEngineAttribs_All ) )
+// return GetAttribs( aEditDoc.GetPos( aSel.Min().GetNode() ), aSel.Min().GetIndex(), aSel.Max().GetIndex(), GETATTRIBS_ALL );
+#endif
+
+
+ SfxItemSet aCurSet( GetEmptyItemSet() );
+
+ USHORT nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
+ USHORT nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
+
+ // ueber die Absaetze iterieren...
+ for ( USHORT nNode = nStartNode; nNode <= nEndNode; nNode++ )
+ {
+ ContentNode* pNode = aEditDoc.GetObject( nNode );
+ DBG_ASSERT( aEditDoc.SaveGetObject( nNode ), "Node nicht gefunden: GetAttrib" );
+
+ xub_StrLen nStartPos = 0;
+ xub_StrLen nEndPos = pNode->Len();
+ if ( nNode == nStartNode )
+ nStartPos = aSel.Min().GetIndex();
+ if ( nNode == nEndNode ) // kann auch == nStart sein!
+ nEndPos = aSel.Max().GetIndex();
+
+ // Problem: Vorlagen....
+ // => Andersrum:
+ // 1) Harte Zeichenattribute, wie gehabt...
+ // 2) Nur wenn OFF, Style and Absatzattr. pruefen...
+
+ // Erst die ganz harte Formatierung...
+ aEditDoc.FindAttribs( pNode, nStartPos, nEndPos, aCurSet );
+
+ if( bOnlyHardAttrib != EditEngineAttribs_OnlyHard )
+ {
+ // Und dann Absatzformatierung und Vorlage...
+ // SfxStyleSheet* pStyle = pNode->GetStyleSheet();
+ for ( USHORT nWhich = EE_ITEMS_START; nWhich <= EE_CHAR_END; nWhich++)
+ {
+ if ( aCurSet.GetItemState( nWhich ) == SFX_ITEM_OFF )
+ {
+ if ( bOnlyHardAttrib == EditEngineAttribs_All )
+ {
+ const SfxPoolItem& rItem = pNode->GetContentAttribs().GetItem( nWhich );
+ aCurSet.Put( rItem );
+ }
+ else if ( pNode->GetContentAttribs().GetItems().GetItemState( nWhich ) == SFX_ITEM_ON )
+ {
+ const SfxPoolItem& rItem = pNode->GetContentAttribs().GetItems().Get( nWhich );
+ aCurSet.Put( rItem );
+ }
+ }
+ else if ( aCurSet.GetItemState( nWhich ) == SFX_ITEM_ON )
+ {
+ const SfxPoolItem* pItem = NULL;
+ if ( bOnlyHardAttrib == EditEngineAttribs_All )
+ {
+ pItem = &pNode->GetContentAttribs().GetItem( nWhich );
+ }
+ else if ( pNode->GetContentAttribs().GetItems().GetItemState( nWhich ) == SFX_ITEM_ON )
+ {
+ pItem = &pNode->GetContentAttribs().GetItems().Get( nWhich );
+ }
+ // pItem can only be NULL when bOnlyHardAttrib...
+ if ( !pItem || ( *pItem != aCurSet.Get( nWhich ) ) )
+ {
+ // Problem: Wenn Absatzvorlage mit z.B. Font,
+ // aber Font hart und anders und komplett in Selektion
+ // Falsch, wenn invalidiert....
+ // => Lieber nicht invalidieren, UMSTELLEN!
+ // Besser waere, Absatzweise ein ItemSet zu fuellen
+ // und dieses mit dem gesmten vergleichen.
+ // aCurSet.InvalidateItem( nWhich );
+ if ( nWhich <= EE_PARA_END )
+ aCurSet.InvalidateItem( nWhich );
+ }
+ }
+ }
+ }
+ }
+
+ // Leere Slots mit Defaults fuellen...
+ if ( bOnlyHardAttrib == EditEngineAttribs_All )
+ {
+ for ( USHORT nWhich = EE_ITEMS_START; nWhich <= EE_CHAR_END; nWhich++ )
+ {
+ if ( aCurSet.GetItemState( nWhich ) == SFX_ITEM_OFF )
+ {
+ aCurSet.Put( aEditDoc.GetItemPool().GetDefaultItem( nWhich ) );
+ }
+ }
+ }
+ return aCurSet;
+}
+
+
+SfxItemSet ImpEditEngine::GetAttribs( USHORT nPara, USHORT nStart, USHORT nEnd, sal_uInt8 nFlags ) const
+{
+ // MT: #94002# Optimized function with less Puts(), which cause unnecessary cloning from default items.
+ // If this works, change GetAttribs( EditSelection ) to use this for each paragraph and merge the results!
+
+ DBG_CHKOBJ( GetEditEnginePtr(), EditEngine, 0 );
+
+ ContentNode* pNode = aEditDoc.SaveGetObject( nPara );
+ DBG_ASSERT( pNode, "GetAttribs - unknown paragraph!" );
+ DBG_ASSERT( nStart <= nEnd, "getAttribs: Start > End not supported!" );
+
+ SfxItemSet aAttribs( ((ImpEditEngine*)this)->GetEmptyItemSet() );
+
+ if ( pNode )
+ {
+ if ( nEnd > pNode->Len() )
+ nEnd = pNode->Len();
+
+ if ( nStart > nEnd )
+ nStart = nEnd;
+
+ // StyleSheet / Parattribs...
+
+ if ( pNode->GetStyleSheet() && ( nFlags & GETATTRIBS_STYLESHEET ) )
+ aAttribs.Set( pNode->GetStyleSheet()->GetItemSet(), TRUE );
+
+ if ( nFlags & GETATTRIBS_PARAATTRIBS )
+ aAttribs.Put( pNode->GetContentAttribs().GetItems() );
+
+ // CharAttribs...
+
+ if ( nFlags & GETATTRIBS_CHARATTRIBS )
+ {
+ // Make testing easier...
+ pNode->GetCharAttribs().OptimizeRanges( ((ImpEditEngine*)this)->GetEditDoc().GetItemPool() );
+
+ const CharAttribArray& rAttrs = pNode->GetCharAttribs().GetAttribs();
+ for ( USHORT nAttr = 0; nAttr < rAttrs.Count(); nAttr++ )
+ {
+ EditCharAttrib* pAttr = rAttrs.GetObject( nAttr );
+
+ if ( nStart == nEnd )
+ {
+ USHORT nCursorPos = nStart;
+ if ( ( pAttr->GetStart() <= nCursorPos ) && ( pAttr->GetEnd() >= nCursorPos ) )
+ {
+ // To be used the attribute has to start BEFORE the position, or it must be a
+ // new empty attr AT the position, or we are on position 0.
+ if ( ( pAttr->GetStart() < nCursorPos ) || pAttr->IsEmpty() || !nCursorPos )
+ {
+ // maybe this attrib ends here and a new attrib with 0 Len may follow and be valid here,
+ // but that s no problem, the empty item will come later and win.
+ aAttribs.Put( *pAttr->GetItem() );
+ }
+ }
+ }
+ else
+ {
+ // Check every attribute covering the area, partial or full.
+ if ( ( pAttr->GetStart() < nEnd ) && ( pAttr->GetEnd() > nStart ) )
+ {
+ if ( ( pAttr->GetStart() <= nStart ) && ( pAttr->GetEnd() >= nEnd ) )
+ {
+ // full coverage
+ aAttribs.Put( *pAttr->GetItem() );
+ }
+ else
+ {
+ // OptimizeRagnge() assures that not the same attr can follow for full coverage
+ // only partial, check with current, when using para/styhe, otherwise invalid.
+ if ( !( nFlags & (GETATTRIBS_PARAATTRIBS|GETATTRIBS_STYLESHEET) ) ||
+ ( *pAttr->GetItem() != aAttribs.Get( pAttr->Which() ) ) )
+ {
+ aAttribs.InvalidateItem( pAttr->Which() );
+ }
+ }
+ }
+ }
+
+ if ( pAttr->GetStart() > nEnd )
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ return aAttribs;
+}
+
+
+void ImpEditEngine::SetAttribs( EditSelection aSel, const SfxItemSet& rSet, BYTE nSpecial )
+{
+ aSel.Adjust( aEditDoc );
+
+ // Wenn keine Selektion => die Attribute aufs Wort anwenden.
+ // ( Der RTF-Perser sollte die Methode eigentlich nie ohne Range rufen )
+ if ( ( nSpecial == ATTRSPECIAL_WHOLEWORD ) && !aSel.HasRange() )
+ aSel = SelectWord( aSel, ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES, FALSE );
+
+ USHORT nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
+ USHORT nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
+
+ if ( IsUndoEnabled() && !IsInUndo() && aStatus.DoUndoAttribs() )
+ {
+ EditUndoSetAttribs* pUndo = CreateAttribUndo( aSel, rSet );
+ pUndo->SetSpecial( nSpecial );
+ InsertUndo( pUndo );
+ }
+
+ BOOL bCheckLanguage = FALSE;
+ if ( GetStatus().DoOnlineSpelling() )
+ {
+ bCheckLanguage = ( rSet.GetItemState( EE_CHAR_LANGUAGE ) == SFX_ITEM_ON ) ||
+ ( rSet.GetItemState( EE_CHAR_LANGUAGE_CJK ) == SFX_ITEM_ON ) ||
+ ( rSet.GetItemState( EE_CHAR_LANGUAGE_CTL ) == SFX_ITEM_ON );
+ }
+
+ // ueber die Absaetze iterieren...
+ for ( USHORT nNode = nStartNode; nNode <= nEndNode; nNode++ )
+ {
+ BOOL bParaAttribFound = FALSE;
+ BOOL bCharAttribFound = FALSE;
+
+ ContentNode* pNode = aEditDoc.GetObject( nNode );
+ ParaPortion* pPortion = GetParaPortions().GetObject( nNode );
+
+ DBG_ASSERT( aEditDoc.SaveGetObject( nNode ), "Node nicht gefunden: SetAttribs" );
+ DBG_ASSERT( GetParaPortions().GetObject( nNode ), "Portion nicht gefunden: SetAttribs" );
+
+ xub_StrLen nStartPos = 0;
+ xub_StrLen nEndPos = pNode->Len();
+ if ( nNode == nStartNode )
+ nStartPos = aSel.Min().GetIndex();
+ if ( nNode == nEndNode ) // kann auch == nStart sein!
+ nEndPos = aSel.Max().GetIndex();
+
+ // ueber die Items iterieren...
+#ifdef EDITDEBUG
+// FILE* fp = fopen( "d:\\debug.log", "a" );
+// if ( fp )
+// {
+// fprintf( fp, "\n \n=> Zeichen-Attribute: Absatz %i, %i-%i\n", nNode, nStartPos, nEndPos );
+// DbgOutItemSet( fp, rSet, TRUE, FALSE );
+// fclose( fp );
+// }
+#endif
+
+ for ( USHORT nWhich = EE_ITEMS_START; nWhich <= EE_CHAR_END; nWhich++)
+ {
+ if ( rSet.GetItemState( nWhich ) == SFX_ITEM_ON )
+ {
+ const SfxPoolItem& rItem = rSet.Get( nWhich );
+ if ( nWhich <= EE_PARA_END )
+ {
+ pNode->GetContentAttribs().GetItems().Put( rItem );
+ bParaAttribFound = TRUE;
+ }
+ else
+ {
+ aEditDoc.InsertAttrib( pNode, nStartPos, nEndPos, rItem );
+ bCharAttribFound = TRUE;
+ if ( nSpecial == ATTRSPECIAL_EDGE )
+ {
+ CharAttribArray& rAttribs = pNode->GetCharAttribs().GetAttribs();
+ USHORT nAttrs = rAttribs.Count();
+ for ( USHORT n = 0; n < nAttrs; n++ )
+ {
+ EditCharAttrib* pAttr = rAttribs.GetObject( n );
+ if ( pAttr->GetStart() > nEndPos )
+ break;
+
+ if ( ( pAttr->GetEnd() == nEndPos ) && ( pAttr->Which() == nWhich ) )
+ {
+ pAttr->SetEdge( TRUE );
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if ( bParaAttribFound )
+ {
+ ParaAttribsChanged( pPortion->GetNode() );
+ }
+ else if ( bCharAttribFound )
+ {
+ bFormatted = FALSE;
+ if ( !pNode->Len() || ( nStartPos != nEndPos ) )
+ {
+ pPortion->MarkSelectionInvalid( nStartPos, nEndPos-nStartPos );
+ if ( bCheckLanguage )
+ pNode->GetWrongList()->MarkInvalid( nStartPos, nEndPos );
+ }
+ }
+ }
+}
+
+void ImpEditEngine::RemoveCharAttribs( EditSelection aSel, BOOL bRemoveParaAttribs, USHORT nWhich )
+{
+ aSel.Adjust( aEditDoc );
+
+ USHORT nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
+ USHORT nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
+
+ const SfxItemSet* _pEmptyItemSet = bRemoveParaAttribs ? &GetEmptyItemSet() : 0;
+
+ if ( IsUndoEnabled() && !IsInUndo() && aStatus.DoUndoAttribs() )
+ {
+ // Eventuel spezielles Undo, oder ItemSet*
+ EditUndoSetAttribs* pUndo = CreateAttribUndo( aSel, GetEmptyItemSet() );
+ pUndo->SetRemoveAttribs( TRUE );
+ pUndo->SetRemoveParaAttribs( bRemoveParaAttribs );
+ pUndo->SetRemoveWhich( nWhich );
+ InsertUndo( pUndo );
+ }
+
+ // ueber die Absaetze iterieren...
+ for ( USHORT nNode = nStartNode; nNode <= nEndNode; nNode++ )
+ {
+ ContentNode* pNode = aEditDoc.GetObject( nNode );
+ ParaPortion* pPortion = GetParaPortions().GetObject( nNode );
+
+ DBG_ASSERT( aEditDoc.SaveGetObject( nNode ), "Node nicht gefunden: SetAttribs" );
+ DBG_ASSERT( GetParaPortions().SaveGetObject( nNode ), "Portion nicht gefunden: SetAttribs" );
+
+ xub_StrLen nStartPos = 0;
+ xub_StrLen nEndPos = pNode->Len();
+ if ( nNode == nStartNode )
+ nStartPos = aSel.Min().GetIndex();
+ if ( nNode == nEndNode ) // kann auch == nStart sein!
+ nEndPos = aSel.Max().GetIndex();
+
+ // Optimieren: Wenn ganzer Absatz, dann RemoveCharAttribs( nPara )?!
+ BOOL bChanged = aEditDoc.RemoveAttribs( pNode, nStartPos, nEndPos, nWhich );
+ if ( bRemoveParaAttribs )
+ {
+ SetParaAttribs( nNode, *_pEmptyItemSet ); // Invalidiert
+ }
+ else
+ {
+ // Bei 'Format-Standard' sollen auch die Zeichenattribute verschwinden,
+ // die von der DrawingEngine als Absatzattribute eingestellt wurden.
+ // Diese koennen sowieso nicht vom Anwender eingestellt worden sein.
+
+ // #106871# Not when nWhich
+ // Would have been better to offer a separate method for format/standard...
+ if ( !nWhich )
+ {
+ SfxItemSet aAttribs( GetParaAttribs( nNode ) );
+ for ( USHORT nW = EE_CHAR_START; nW <= EE_CHAR_END; nW++ )
+ aAttribs.ClearItem( nW );
+ SetParaAttribs( nNode, aAttribs );
+ }
+ }
+
+ if ( bChanged && !bRemoveParaAttribs )
+ {
+ bFormatted = FALSE;
+ pPortion->MarkSelectionInvalid( nStartPos, nEndPos-nStartPos );
+ }
+ }
+}
+
+typedef EditCharAttrib* EditCharAttribPtr;
+
+void ImpEditEngine::RemoveCharAttribs( USHORT nPara, USHORT nWhich, BOOL bRemoveFeatures )
+{
+ ContentNode* pNode = aEditDoc.SaveGetObject( nPara );
+ ParaPortion* pPortion = GetParaPortions().SaveGetObject( nPara );
+
+ DBG_ASSERT( pNode, "Node nicht gefunden: RemoveCharAttribs" );
+ DBG_ASSERT( pPortion, "Portion nicht gefunden: RemoveCharAttribs" );
+
+ if ( !pNode )
+ return;
+
+ USHORT nAttr = 0;
+ EditCharAttribPtr pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
+ while ( pAttr )
+ {
+ if ( ( !pAttr->IsFeature() || bRemoveFeatures ) &&
+ ( !nWhich || ( pAttr->GetItem()->Which() == nWhich ) ) )
+ {
+ pNode->GetCharAttribs().GetAttribs().Remove( nAttr );
+ delete pAttr;
+ nAttr--;
+ }
+ nAttr++;
+ pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
+ }
+
+ pPortion->MarkSelectionInvalid( 0, pNode->Len() );
+}
+
+void ImpEditEngine::SetParaAttribs( USHORT nPara, const SfxItemSet& rSet )
+{
+ ContentNode* pNode = aEditDoc.SaveGetObject( nPara );
+
+ if ( !pNode )
+ return;
+
+#ifdef EDITDEBUG
+// FILE* fp = fopen( "d:\\debug.log", "a" );
+// if ( fp )
+// {
+// fprintf( fp, "\n \n=> Absatz-Attribute: Absatz %i\n", nPara );
+// DbgOutItemSet( fp, rSet, TRUE, FALSE );
+// fclose( fp );
+// }
+#endif
+
+ if ( !( pNode->GetContentAttribs().GetItems() == rSet ) )
+ {
+ if ( IsUndoEnabled() && !IsInUndo() && aStatus.DoUndoAttribs() )
+ {
+ if ( rSet.GetPool() != &aEditDoc.GetItemPool() )
+ {
+ SfxItemSet aTmpSet( GetEmptyItemSet() );
+ aTmpSet.Put( rSet );
+ InsertUndo( new EditUndoSetParaAttribs( this, nPara, pNode->GetContentAttribs().GetItems(), aTmpSet ) );
+ }
+ else
+ {
+ InsertUndo( new EditUndoSetParaAttribs( this, nPara, pNode->GetContentAttribs().GetItems(), rSet ) );
+ }
+ }
+ pNode->GetContentAttribs().GetItems().Set( rSet );
+ if ( aStatus.UseCharAttribs() )
+ pNode->CreateDefFont();
+
+ ParaAttribsChanged( pNode );
+ }
+}
+
+const SfxItemSet& ImpEditEngine::GetParaAttribs( USHORT nPara ) const
+{
+ ContentNode* pNode = aEditDoc.GetObject( nPara );
+ DBG_ASSERT( pNode, "Node nicht gefunden: GetParaAttribs" );
+ return pNode->GetContentAttribs().GetItems();
+}
+
+BOOL ImpEditEngine::HasParaAttrib( USHORT nPara, USHORT nWhich ) const
+{
+ ContentNode* pNode = aEditDoc.GetObject( nPara );
+ DBG_ASSERT( pNode, "Node nicht gefunden: HasParaAttrib" );
+
+ return pNode->GetContentAttribs().HasItem( nWhich );
+}
+
+const SfxPoolItem& ImpEditEngine::GetParaAttrib( USHORT nPara, USHORT nWhich ) const
+{
+ ContentNode* pNode = aEditDoc.GetObject( nPara );
+ DBG_ASSERT( pNode, "Node nicht gefunden: GetParaAttrib" );
+
+ return pNode->GetContentAttribs().GetItem( nWhich );
+}
+
+void ImpEditEngine::GetCharAttribs( USHORT nPara, EECharAttribArray& rLst ) const
+{
+ rLst.Remove( 0, rLst.Count() );
+ ContentNode* pNode = aEditDoc.GetObject( nPara );
+ if ( pNode )
+ {
+ for ( USHORT nAttr = 0; nAttr < pNode->GetCharAttribs().Count(); nAttr++ )
+ {
+ EditCharAttribPtr pAttr = pNode->GetCharAttribs().GetAttribs()[ nAttr ];
+ EECharAttrib aEEAttr;
+ aEEAttr.pAttr = pAttr->GetItem();
+ aEEAttr.nPara = nPara;
+ aEEAttr.nStart = pAttr->GetStart();
+ aEEAttr.nEnd = pAttr->GetEnd();
+ rLst.Insert( aEEAttr, rLst.Count() );
+ }
+ }
+}
+
+void ImpEditEngine::ParaAttribsToCharAttribs( ContentNode* pNode )
+{
+ pNode->GetCharAttribs().DeleteEmptyAttribs( GetEditDoc().GetItemPool() );
+ xub_StrLen nEndPos = pNode->Len();
+ for ( USHORT nWhich = EE_CHAR_START; nWhich <= EE_CHAR_END; nWhich++ )
+ {
+ if ( pNode->GetContentAttribs().HasItem( nWhich ) )
+ {
+ const SfxPoolItem& rItem = pNode->GetContentAttribs().GetItem( nWhich );
+ // Die Luecken auffuellen:
+ USHORT nLastEnd = 0;
+ EditCharAttrib* pAttr = pNode->GetCharAttribs().FindNextAttrib( nWhich, nLastEnd );
+ while ( pAttr )
+ {
+ nLastEnd = pAttr->GetEnd();
+ if ( pAttr->GetStart() > nLastEnd )
+ aEditDoc.InsertAttrib( pNode, nLastEnd, pAttr->GetStart(), rItem );
+ // #112831# Last Attr might go from 0xffff to 0x0000
+ pAttr = nLastEnd ? pNode->GetCharAttribs().FindNextAttrib( nWhich, nLastEnd ) : NULL;
+ }
+
+ // Und den Rest:
+ if ( nLastEnd < nEndPos )
+ aEditDoc.InsertAttrib( pNode, nLastEnd, nEndPos, rItem );
+ }
+ }
+ bFormatted = FALSE;
+ // Portion braucht hier nicht invalidiert werden, geschieht woanders.
+}
+
+IdleFormattter::IdleFormattter()
+{
+ pView = 0;
+ nRestarts = 0;
+}
+
+IdleFormattter::~IdleFormattter()
+{
+ pView = 0;
+}
+
+void IdleFormattter::DoIdleFormat( EditView* pV )
+{
+ pView = pV;
+
+ if ( IsActive() )
+ nRestarts++;
+
+ if ( nRestarts > 4 )
+ ForceTimeout();
+ else
+ Start();
+}
+
+void IdleFormattter::ForceTimeout()
+{
+ if ( IsActive() )
+ {
+ Stop();
+ ((Link&)GetTimeoutHdl()).Call( this );
+ }
+}
+
+ImplIMEInfos::ImplIMEInfos( const EditPaM& rPos, const String& rOldTextAfterStartPos )
+ : aOldTextAfterStartPos( rOldTextAfterStartPos )
+{
+ aPos = rPos;
+ nLen = 0;
+ bCursor = TRUE;
+ pAttribs = NULL;
+ bWasCursorOverwrite = FALSE;
+}
+
+ImplIMEInfos::~ImplIMEInfos()
+{
+ delete[] pAttribs;
+}
+
+void ImplIMEInfos::CopyAttribs( const USHORT* pA, USHORT nL )
+{
+ nLen = nL;
+ delete pAttribs;
+ pAttribs = new USHORT[ nL ];
+ memcpy( pAttribs, pA, nL*sizeof(USHORT) );
+}
+
+void ImplIMEInfos::DestroyAttribs()
+{
+ delete[] pAttribs;
+ pAttribs = NULL;
+ nLen = 0;
+}
diff --git a/editeng/source/editeng/makefile.mk b/editeng/source/editeng/makefile.mk
new file mode 100644
index 0000000000..2a4fce319d
--- /dev/null
+++ b/editeng/source/editeng/makefile.mk
@@ -0,0 +1,84 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.18 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME=svx
+TARGET=editeng
+AUTOSEG=true
+
+#PROJECTPCH4DLL=TRUE
+#PROJECTPCH=eeng_pch
+#PROJECTPCHSOURCE=eeng_pch
+
+ENABLE_EXCEPTIONS=TRUE
+
+
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Allgemein ----------------------------------------------------------
+
+.IF "$(editdebug)" != "" || "$(EDITDEBUG)" != ""
+CDEFS+=-DEDITDEBUG
+.ENDIF
+
+SLOFILES = \
+ $(SLO)$/textconv.obj \
+ $(SLO)$/editattr.obj \
+ $(SLO)$/editdbg.obj \
+ $(SLO)$/editdoc.obj \
+ $(SLO)$/editdoc2.obj \
+ $(SLO)$/editeng.obj \
+ $(SLO)$/editobj.obj \
+ $(SLO)$/editsel.obj \
+ $(SLO)$/editundo.obj \
+ $(SLO)$/editview.obj \
+ $(SLO)$/edtspell.obj \
+ $(SLO)$/eehtml.obj \
+ $(SLO)$/eerdll.obj \
+ $(SLO)$/eeobj.obj \
+ $(SLO)$/eertfpar.obj \
+ $(SLO)$/impedit.obj \
+ $(SLO)$/impedit2.obj \
+ $(SLO)$/impedit3.obj \
+ $(SLO)$/impedit4.obj \
+ $(SLO)$/impedit5.obj
+
+SRS1NAME=$(TARGET)
+SRC1FILES= editeng.src
+
+EXCEPTIONSFILES= \
+ $(SLO)$/unolingu.obj
+
+.INCLUDE : target.mk
+
diff --git a/editeng/source/editeng/textconv.cxx b/editeng/source/editeng/textconv.cxx
new file mode 100644
index 0000000000..b02e5681ff
--- /dev/null
+++ b/editeng/source/editeng/textconv.cxx
@@ -0,0 +1,632 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textconv.cxx,v $
+ * $Revision: 1.14 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <vcl/wrkwin.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+
+#include <impedit.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/unolingu.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <editeng/langitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <textconv.hxx>
+
+
+using ::rtl::OUString;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::linguistic2;
+
+#define C2U(cChar) OUString::createFromAscii(cChar)
+
+//////////////////////////////////////////////////////////////////////
+
+TextConvWrapper::TextConvWrapper( Window* pWindow,
+ const Reference< XMultiServiceFactory >& rxMSF,
+ const Locale& rSourceLocale,
+ const Locale& rTargetLocale,
+ const Font* pTargetFont,
+ sal_Int32 nOptions,
+ sal_Bool bIsInteractive,
+ BOOL bIsStart,
+ EditView* pView ) :
+ HangulHanjaConversion( pWindow, rxMSF, rSourceLocale, rTargetLocale, pTargetFont, nOptions, bIsInteractive )
+{
+ DBG_ASSERT( pWindow, "TextConvWrapper: window missing" );
+
+ nConvTextLang = LANGUAGE_NONE;
+ nUnitOffset = 0;
+
+ bStartChk = sal_False;
+ bStartDone = bIsStart;
+ bEndDone = sal_False;
+ pWin = pWindow;
+ pEditView = pView;
+
+ aConvSel = pEditView->GetSelection();
+ aConvSel.Adjust(); // make Start <= End
+
+ bAllowChange = sal_False;
+}
+
+
+TextConvWrapper::~TextConvWrapper()
+{
+}
+
+
+sal_Bool TextConvWrapper::ConvNext_impl()
+{
+ // modified version of SvxSpellWrapper::SpellNext
+
+ if( bStartChk )
+ bStartDone = sal_True;
+ else
+ bEndDone = sal_True;
+
+ if ( bStartDone && bEndDone )
+ {
+ if ( ConvMore_impl() ) // ein weiteres Dokument pruefen?
+ {
+ bStartDone = sal_True;
+ bEndDone = sal_False;
+ ConvStart_impl( SVX_SPELL_BODY );
+ return sal_True;
+ }
+ return sal_False;
+
+ }
+
+ //ResMgr* pMgr = DIALOG_MGR();
+ sal_Bool bGoOn = sal_False;
+
+ if ( bStartDone && bEndDone )
+ {
+ if ( ConvMore_impl() ) // ein weiteres Dokument pruefen?
+ {
+ bStartDone = sal_True;
+ bEndDone = sal_False;
+ ConvStart_impl( SVX_SPELL_BODY );
+ return sal_True;
+ }
+ }
+ else
+ {
+ // Ein BODY_Bereich erledigt, Frage nach dem anderen BODY_Bereich
+/*
+ pWin->LeaveWait();
+
+ sal_uInt16 nResId = bReverse ? RID_SVXQB_BW_CONTINUE : RID_SVXQB_CONTINUE;
+ QueryBox aBox( pWin, ResId( nResId, pMgr ) );
+ if ( aBox.Execute() != RET_YES )
+ {
+ // Verzicht auf den anderen Bereich, ggf. Frage nach Sonderbereich
+ pWin->EnterWait();
+ bStartDone = bEndDone = sal_True;
+ return ConvNext_impl();
+ }
+ else
+ {
+*/
+ if (!aConvSel.HasRange())
+ {
+ bStartChk = !bStartDone;
+ ConvStart_impl( bStartChk ? SVX_SPELL_BODY_START : SVX_SPELL_BODY_END );
+ bGoOn = sal_True;
+ }
+/*
+ }
+ pWin->EnterWait();
+*/
+ }
+ return bGoOn;
+}
+
+
+sal_Bool TextConvWrapper::FindConvText_impl()
+{
+ // modified version of SvxSpellWrapper::FindSpellError
+
+ //ShowLanguageErrors();
+
+ sal_Bool bFound = sal_False;
+
+ pWin->EnterWait();
+ sal_Bool bConvert = sal_True;
+
+ while ( bConvert )
+ {
+ bFound = ConvContinue_impl();
+ if (bFound)
+ {
+ bConvert = sal_False;
+ }
+ else
+ {
+ ConvEnd_impl();
+ bConvert = ConvNext_impl();
+ }
+ }
+ pWin->LeaveWait();
+ return bFound;
+}
+
+
+sal_Bool TextConvWrapper::ConvMore_impl()
+{
+ // modified version of SvxSpellWrapper::SpellMore
+
+ sal_Bool bMore = sal_False;
+ ImpEditEngine* pImpEE = pEditView->GetImpEditEngine();
+ ConvInfo* pConvInfo = pImpEE->GetConvInfo();
+ if ( pConvInfo->bMultipleDoc )
+ {
+ bMore = pImpEE->GetEditEnginePtr()->ConvertNextDocument();
+ if ( bMore )
+ {
+ // Der Text wurde in diese Engine getreten...
+ pEditView->GetImpEditView()->SetEditSelection(
+ pImpEE->GetEditDoc().GetStartPaM() );
+ }
+ }
+ return bMore;
+}
+
+
+void TextConvWrapper::ConvStart_impl( SvxSpellArea eArea )
+{
+ // modified version of EditSpellWrapper::SpellStart
+
+ ImpEditEngine* pImpEE = pEditView->GetImpEditEngine();
+ ConvInfo* pConvInfo = pImpEE->GetConvInfo();
+
+ if ( eArea == SVX_SPELL_BODY_START )
+ {
+ // Wird gerufen, wenn Spell-Forwad am Ende angekomment ist
+ // und soll von vorne beginnen
+ if ( bEndDone )
+ {
+ pConvInfo->bConvToEnd = sal_False;
+ pConvInfo->aConvTo = pConvInfo->aConvStart;
+ pConvInfo->aConvContinue = EPaM( 0, 0 );
+ pEditView->GetImpEditView()->SetEditSelection(
+ pImpEE->GetEditDoc().GetStartPaM() );
+ }
+ else
+ {
+ pConvInfo->bConvToEnd = sal_True;
+ pConvInfo->aConvTo = pImpEE->CreateEPaM(
+ pImpEE->GetEditDoc().GetStartPaM() );
+ }
+ }
+ else if ( eArea == SVX_SPELL_BODY_END )
+ {
+ // Wird gerufen, wenn Spell-Forwad gestartet wird
+ pConvInfo->bConvToEnd = sal_True;
+ if (aConvSel.HasRange())
+ {
+ // user selection: convert to end of selection
+ pConvInfo->aConvTo.nPara = aConvSel.nEndPara;
+ pConvInfo->aConvTo.nIndex = aConvSel.nEndPos;
+ pConvInfo->bConvToEnd = sal_False;
+ }
+ else
+ {
+ // nothing selected: convert to end of document
+ pConvInfo->aConvTo = pImpEE->CreateEPaM(
+ pImpEE->GetEditDoc().GetEndPaM() );
+ }
+ }
+ else if ( eArea == SVX_SPELL_BODY )
+ {
+ // called by ConvNext_impl...
+ pConvInfo->aConvContinue = pConvInfo->aConvStart;
+ pConvInfo->aConvTo = pImpEE->CreateEPaM(
+ pImpEE->GetEditDoc().GetEndPaM() );
+ // pSpellInfo->bSpellToEnd = sal_True;
+ }
+ else
+ {
+ DBG_ERROR( "ConvStart_impl: Unknown Area!" );
+ }
+}
+
+
+void TextConvWrapper::ConvEnd_impl()
+{
+}
+
+
+sal_Bool TextConvWrapper::ConvContinue_impl()
+{
+ // modified version of EditSpellWrapper::SpellContinue
+
+ // get next convertible text portion and its language
+ aConvText = rtl::OUString();
+ nConvTextLang = LANGUAGE_NONE;
+ pEditView->GetImpEditEngine()->ImpConvert( aConvText, nConvTextLang,
+ pEditView, GetSourceLanguage(), aConvSel,
+ bAllowChange, GetTargetLanguage(), GetTargetFont() );
+ return aConvText.getLength() != 0;
+}
+
+
+void TextConvWrapper::SetLanguageAndFont( const ESelection &rESel,
+ LanguageType nLang, USHORT nLangWhichId,
+ const Font *pFont, USHORT nFontWhichId )
+{
+ ESelection aOldSel = pEditView->GetSelection();
+ pEditView->SetSelection( rESel );
+
+ // set new language attribute
+ SfxItemSet aNewSet( pEditView->GetEmptyItemSet() );
+ aNewSet.Put( SvxLanguageItem( nLang, nLangWhichId ) );
+
+ // new font to be set?
+ DBG_ASSERT( pFont, "target font missing?" );
+ if (pFont)
+ {
+ // set new font attribute
+ SvxFontItem aFontItem = (SvxFontItem&) aNewSet.Get( nFontWhichId );
+ aFontItem.GetFamilyName() = pFont->GetName();
+ aFontItem.GetFamily() = pFont->GetFamily();
+ aFontItem.GetStyleName() = pFont->GetStyleName();
+ aFontItem.GetPitch() = pFont->GetPitch();
+ aFontItem.GetCharSet() = pFont->GetCharSet();
+ aNewSet.Put( aFontItem );
+ }
+
+ // apply new attributes
+ pEditView->SetAttribs( aNewSet );
+
+ pEditView->SetSelection( aOldSel );
+}
+
+
+void TextConvWrapper::SelectNewUnit_impl(
+ const sal_Int32 nUnitStart,
+ const sal_Int32 nUnitEnd )
+{
+ BOOL bOK = 0 <= nUnitStart && 0 <= nUnitEnd && nUnitStart <= nUnitEnd;
+ DBG_ASSERT( bOK, "invalid arguments" );
+ if (!bOK)
+ return;
+
+ ESelection aSelection = pEditView->GetSelection();
+ DBG_ASSERT( aSelection.nStartPara == aSelection.nEndPara,
+ "paragraph mismatch in selection" );
+ aSelection.nStartPos = (USHORT) (nLastPos + nUnitOffset + nUnitStart);
+ aSelection.nEndPos = (USHORT) (nLastPos + nUnitOffset + nUnitEnd);
+ pEditView->SetSelection( aSelection );
+}
+
+
+void TextConvWrapper::GetNextPortion(
+ ::rtl::OUString& /* [out] */ rNextPortion,
+ LanguageType& /* [out] */ rLangOfPortion,
+ sal_Bool /* [in] */ _bAllowImplicitChangesForNotConvertibleText )
+{
+ bAllowChange = _bAllowImplicitChangesForNotConvertibleText;
+
+ FindConvText_impl();
+ rNextPortion = aConvText;
+ rLangOfPortion = nConvTextLang;
+ nUnitOffset = 0;
+
+ ESelection aSelection = pEditView->GetSelection();
+ DBG_ASSERT( aSelection.nStartPara == aSelection.nEndPara,
+ "paragraph mismatch in selection" );
+ DBG_ASSERT( aSelection.nStartPos <= aSelection.nEndPos,
+ "start pos > end pos" );
+ nLastPos = aSelection.nStartPos;
+}
+
+
+void TextConvWrapper::HandleNewUnit(
+ const sal_Int32 nUnitStart,
+ const sal_Int32 nUnitEnd )
+{
+ SelectNewUnit_impl( nUnitStart, nUnitEnd );
+}
+
+
+void TextConvWrapper::ReplaceUnit(
+ const sal_Int32 nUnitStart, const sal_Int32 nUnitEnd,
+ const ::rtl::OUString& rOrigText,
+ const ::rtl::OUString& rReplaceWith,
+ const ::com::sun::star::uno::Sequence< sal_Int32 > &rOffsets,
+ ReplacementAction eAction,
+ LanguageType *pNewUnitLanguage )
+{
+ BOOL bOK = 0 <= nUnitStart && 0 <= nUnitEnd && nUnitStart <= nUnitEnd;
+ DBG_ASSERT( bOK, "invalid arguments" );
+ if (!bOK)
+ return;
+
+ static OUString aBracketedStart( C2U( "(" ) );
+ static OUString aBracketedEnd( C2U( ")" ) );
+
+ // select current unit
+ SelectNewUnit_impl( nUnitStart, nUnitEnd );
+
+ OUString aOrigTxt( pEditView->GetSelected() );
+ OUString aNewTxt( rReplaceWith );
+ String aNewOrigText;
+ switch (eAction)
+ {
+ case eExchange :
+ break;
+ case eReplacementBracketed :
+ (((aNewTxt = aOrigTxt) += aBracketedStart) += rReplaceWith) += aBracketedEnd;
+ break;
+ case eOriginalBracketed :
+ (((aNewTxt = rReplaceWith) += aBracketedStart) += aOrigTxt) += aBracketedEnd;
+ break;
+ case eReplacementAbove :
+ case eOriginalAbove :
+ case eReplacementBelow :
+ case eOriginalBelow :
+ DBG_ERROR( "Rubies not supported" );
+ break;
+ default:
+ DBG_ERROR( "unexpected case" );
+ }
+ nUnitOffset = sal::static_int_cast< USHORT >(
+ nUnitOffset + nUnitStart + aNewTxt.getLength());
+
+ // remember current original language for kater use
+ ImpEditEngine *pImpEditEng = pEditView->GetImpEditEngine();
+ ESelection _aOldSel = pEditView->GetSelection();
+ //EditSelection aOldEditSel = pEditView->GetImpEditView()->GetEditSelection();
+
+#ifdef DBG_UTIL
+ LanguageType nOldLang = pImpEditEng->GetLanguage( pImpEditEng->CreateSel( _aOldSel ).Min() );
+#endif
+
+ pImpEditEng->UndoActionStart( EDITUNDO_INSERT );
+
+ // according to FT we should currently not bother about keeping
+ // attributes in Hangul/Hanja conversion and leave that untouched.
+ // Thus we do this only for Chinese translation...
+ sal_Bool bIsChineseConversion = IsChinese( GetSourceLanguage() );
+ if (bIsChineseConversion)
+ ChangeText( aNewTxt, rOrigText, &rOffsets, &_aOldSel );
+ else
+ ChangeText( aNewTxt, rOrigText, NULL, NULL );
+
+ // change language and font if necessary
+ if (bIsChineseConversion)
+ {
+ DBG_ASSERT( GetTargetLanguage() == LANGUAGE_CHINESE_SIMPLIFIED || GetTargetLanguage() == LANGUAGE_CHINESE_TRADITIONAL,
+ "TextConvWrapper::ReplaceUnit : unexpected target language" );
+
+ ESelection aOldSel = pEditView->GetSelection();
+ ESelection aNewSel( aOldSel );
+ aNewSel.nStartPos = sal::static_int_cast< xub_StrLen >(
+ aNewSel.nStartPos - aNewTxt.getLength());
+// DBG_ASSERT( aOldSel.nEndPos >= 0, "error while building selection" );
+
+ if (pNewUnitLanguage)
+ {
+ DBG_ASSERT(!IsSimilarChinese( *pNewUnitLanguage, nOldLang ),
+ "similar language should not be changed!");
+ SetLanguageAndFont( aNewSel, *pNewUnitLanguage, EE_CHAR_LANGUAGE_CJK,
+ GetTargetFont(), EE_CHAR_FONTINFO_CJK );
+ }
+ }
+
+ pImpEditEng->UndoActionEnd( EDITUNDO_INSERT );
+
+ // adjust ConvContinue / ConvTo if necessary
+ ImpEditEngine* pImpEE = pEditView->GetImpEditEngine();
+ ConvInfo* pConvInfo = pImpEE->GetConvInfo();
+ sal_Int32 nDelta = aNewTxt.getLength() - aOrigTxt.getLength();
+ if (nDelta != 0)
+ {
+ // Note: replacement is always done in the current paragraph
+ // which is the one ConvContinue points to
+ pConvInfo->aConvContinue.nIndex = sal::static_int_cast< USHORT >(
+ pConvInfo->aConvContinue.nIndex + nDelta);
+
+ // if that is the same as the one where the conversions ends
+ // the end needs to be updated also
+ if (pConvInfo->aConvTo.nPara == pConvInfo->aConvContinue.nPara)
+ pConvInfo->aConvTo.nIndex = sal::static_int_cast< USHORT >(
+ pConvInfo->aConvTo.nIndex + nDelta);
+ }
+}
+
+
+void TextConvWrapper::ChangeText( const String &rNewText,
+ const OUString& rOrigText,
+ const uno::Sequence< sal_Int32 > *pOffsets,
+ ESelection *pESelection )
+{
+ //!! code is a modifed copy of SwHHCWrapper::ChangeText from sw !!
+
+ DBG_ASSERT( rNewText.Len() != 0, "unexpected empty string" );
+ if (rNewText.Len() == 0)
+ return;
+
+ if (pOffsets && pESelection) // try to keep as much attributation as possible ?
+ {
+ pESelection->Adjust();
+
+ // remember cursor start position for later setting of the cursor
+ const xub_StrLen nStartIndex = pESelection->nStartPos;
+
+ const sal_Int32 nIndices = pOffsets->getLength();
+ const sal_Int32 *pIndices = pOffsets->getConstArray();
+ xub_StrLen nConvTextLen = rNewText.Len();
+ xub_StrLen nPos = 0;
+ xub_StrLen nChgPos = STRING_NOTFOUND;
+ xub_StrLen nChgLen = 0;
+ xub_StrLen nConvChgPos = STRING_NOTFOUND;
+ xub_StrLen nConvChgLen = 0;
+
+ // offset to calculate the position in the text taking into
+ // account that text may have been replaced with new text of
+ // different length. Negative values allowed!
+ long nCorrectionOffset = 0;
+
+ DBG_ASSERT(nIndices == 0 || nIndices == nConvTextLen,
+ "mismatch between string length and sequence length!" );
+
+ // find all substrings that need to be replaced (and only those)
+ while (sal_True)
+ {
+ // get index in original text that matches nPos in new text
+ xub_StrLen nIndex;
+ if (nPos < nConvTextLen)
+ nIndex = (sal_Int32) nPos < nIndices ? (xub_StrLen) pIndices[nPos] : nPos;
+ else
+ {
+ nPos = nConvTextLen;
+ nIndex = static_cast< xub_StrLen >( rOrigText.getLength() );
+ }
+
+ if (rOrigText.getStr()[nIndex] == rNewText.GetChar(nPos) ||
+ nPos == nConvTextLen /* end of string also terminates non-matching char sequence */)
+ {
+ // substring that needs to be replaced found?
+ if (nChgPos != STRING_NOTFOUND && nConvChgPos != STRING_NOTFOUND)
+ {
+ nChgLen = nIndex - nChgPos;
+ nConvChgLen = nPos - nConvChgPos;
+#ifdef DEBUG
+ String aInOrig( rOrigText.copy( nChgPos, nChgLen ) );
+#endif
+ String aInNew( rNewText.Copy( nConvChgPos, nConvChgLen ) );
+
+ // set selection to sub string to be replaced in original text
+ ESelection aSel( *pESelection );
+ xub_StrLen nChgInNodeStartIndex = static_cast< xub_StrLen >( nStartIndex + nCorrectionOffset + nChgPos );
+ aSel.nStartPos = nChgInNodeStartIndex;
+ aSel.nEndPos = nChgInNodeStartIndex + nChgLen;
+ pEditView->SetSelection( aSel );
+#ifdef DEBUG
+ String aSelTxt1( pEditView->GetSelected() );
+#endif
+
+ // replace selected sub string with the corresponding
+ // sub string from the new text while keeping as
+ // much from the attributes as possible
+ ChangeText_impl( aInNew, sal_True );
+
+ nCorrectionOffset += nConvChgLen - nChgLen;
+
+ nChgPos = STRING_NOTFOUND;
+ nConvChgPos = STRING_NOTFOUND;
+ }
+ }
+ else
+ {
+ // begin of non-matching char sequence found ?
+ if (nChgPos == STRING_NOTFOUND && nConvChgPos == STRING_NOTFOUND)
+ {
+ nChgPos = nIndex;
+ nConvChgPos = nPos;
+ }
+ }
+ if (nPos >= nConvTextLen)
+ break;
+ ++nPos;
+ }
+
+ // set cursor to the end of the inserted text
+ // (as it would happen after ChangeText_impl (Delete and Insert)
+ // of the whole text in the 'else' branch below)
+ pESelection->nStartPos = pESelection->nEndPos = nStartIndex + nConvTextLen;
+ }
+ else
+ {
+ ChangeText_impl( rNewText, sal_False );
+ }
+}
+
+
+void TextConvWrapper::ChangeText_impl( const String &rNewText, sal_Bool bKeepAttributes )
+{
+ if (bKeepAttributes)
+ {
+ // save attributes to be restored
+ SfxItemSet aSet( pEditView->GetAttribs() );
+
+#ifdef DEBUG
+ String aSelTxt1( pEditView->GetSelected() );
+#endif
+ // replace old text and select new text
+ pEditView->InsertText( rNewText, sal_True );
+#ifdef DEBUG
+ String aSelTxt2( pEditView->GetSelected() );
+#endif
+
+ // since 'SetAttribs' below function like merging with the attributes
+ // from the itemset with any existing ones we have to get rid of all
+ // all attributes now. (Those attributes that may take effect left
+ // to the position where the new text gets inserted after the old text
+ // was deleted)
+ pEditView->RemoveAttribs();
+ // apply saved attributes to new inserted text
+ pEditView->SetAttribs( aSet );
+ }
+ else
+ {
+ pEditView->InsertText( rNewText );
+ }
+}
+
+
+void TextConvWrapper::Convert()
+{
+ bStartChk = sal_False;
+ ConvStart_impl( SVX_SPELL_BODY_END );
+ ConvertDocument();
+ ConvEnd_impl();
+}
+
+
+sal_Bool TextConvWrapper::HasRubySupport() const
+{
+ return sal_False;
+}
+
+//////////////////////////////////////////////////////////////////////
+
diff --git a/editeng/source/editeng/textconv.hxx b/editeng/source/editeng/textconv.hxx
new file mode 100644
index 0000000000..080f575399
--- /dev/null
+++ b/editeng/source/editeng/textconv.hxx
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textconv.hxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _TEXTCONV_HXX
+#define _TEXTCONV_HXX
+
+#include <editeng/splwrap.hxx>
+#include <editeng/svxacorr.hxx>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <editeng/hangulhanja.hxx>
+
+class EditView;
+class ImpEditEngine;
+class ContentNode;
+
+class TextConvWrapper : public editeng::HangulHanjaConversion
+{
+ rtl::OUString aConvText; // convertible text part found last time
+ LanguageType nConvTextLang; // language of aConvText
+ USHORT nLastPos; // starting position of the last found text portion (word)
+ USHORT nUnitOffset; // offset of current unit in the current text portion (word)
+
+ ESelection aConvSel; // selection to be converted if
+ // 'HasRange' is true, other conversion
+ // starts from the cursor position
+
+ EditView * pEditView;
+ Window * pWin;
+
+ sal_Bool bStartChk;
+ sal_Bool bStartDone;
+ sal_Bool bEndDone;
+ sal_Bool bAllowChange; // storage for _bAllowImplicitChangesForNotConvertibleText
+ // paramters value of function GetNextPortion.
+ // used to transport the value to where it is needed.
+
+
+ // from SvxSpellWrapper copied and modified
+ sal_Bool ConvNext_impl(); // former SpellNext
+ sal_Bool FindConvText_impl(); // former FindSpellError
+ sal_Bool ConvMore_impl(); // former SpellMore
+
+ // from EditSpellWrapper copied and modified
+ void ConvStart_impl( SvxSpellArea eSpell ); // former SpellStart
+ void ConvEnd_impl(); // former SpellEnd
+ sal_Bool ConvContinue_impl(); // former SpellContinue
+
+ void SelectNewUnit_impl( const sal_Int32 nUnitStart,
+ const sal_Int32 nUnitEnd );
+
+ void ChangeText( const String &rNewText,
+ const ::rtl::OUString& rOrigText,
+ const ::com::sun::star::uno::Sequence< sal_Int32 > *pOffsets,
+ ESelection *pESelection );
+ void ChangeText_impl( const String &rNewText, sal_Bool bKeepAttributes );
+
+ // Forbidden and not implemented.
+ TextConvWrapper (const TextConvWrapper &);
+ TextConvWrapper & operator= (const TextConvWrapper &);
+
+protected:
+ virtual void GetNextPortion( ::rtl::OUString& /* [out] */ rNextPortion,
+ LanguageType& /* [out] */ rLangOfPortion,
+ sal_Bool /* [in] */ _bAllowImplicitChangesForNotConvertibleText );
+ virtual void HandleNewUnit( const sal_Int32 nUnitStart,
+ const sal_Int32 nUnitEnd );
+ virtual void ReplaceUnit(
+ const sal_Int32 nUnitStart, const sal_Int32 nUnitEnd,
+ const ::rtl::OUString& rOrigText,
+ const ::rtl::OUString& rReplaceWith,
+ const ::com::sun::star::uno::Sequence< sal_Int32 > &rOffsets,
+ ReplacementAction eAction,
+ LanguageType *pNewUnitLanguage );
+
+ virtual sal_Bool HasRubySupport() const;
+
+ void SetLanguageAndFont( const ESelection &rESel,
+ LanguageType nLang, USHORT nLangWhichId,
+ const Font *pFont, USHORT nFontWhichId );
+
+
+public:
+ TextConvWrapper( Window* pWindow,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxMSF,
+ const ::com::sun::star::lang::Locale& rSourceLocale,
+ const ::com::sun::star::lang::Locale& rTargetLocale,
+ const Font* pTargetFont,
+ INT32 nOptions,
+ sal_Bool bIsInteractive,
+ BOOL bIsStart, EditView* pView );
+
+ virtual ~TextConvWrapper();
+
+ void Convert();
+};
+
+#endif
+
diff --git a/editeng/source/items/bulitem.cxx b/editeng/source/items/bulitem.cxx
new file mode 100644
index 0000000000..e0fed4238b
--- /dev/null
+++ b/editeng/source/items/bulitem.cxx
@@ -0,0 +1,537 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: bulitem.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+// include ---------------------------------------------------------------
+#include <tools/stream.hxx>
+#include <vcl/outdev.hxx>
+
+#define _SVX_BULITEM_CXX
+
+#include <editeng/bulitem.hxx>
+#include <editeng/editrids.hrc>
+
+// #90477#
+#include <tools/tenccvt.hxx>
+
+#define BULITEM_VERSION ((USHORT)2)
+
+// -----------------------------------------------------------------------
+
+TYPEINIT1(SvxBulletItem,SfxPoolItem);
+
+// -----------------------------------------------------------------------
+
+void SvxBulletItem::StoreFont( SvStream& rStream, const Font& rFont )
+{
+ USHORT nTemp;
+
+ rStream << rFont.GetColor();
+ nTemp = (USHORT)rFont.GetFamily(); rStream << nTemp;
+
+ // #90477# nTemp = (USHORT)GetStoreCharSet( rFont.GetCharSet(), rStream.GetVersion() );
+ nTemp = (USHORT)GetSOStoreTextEncoding((rtl_TextEncoding)rFont.GetCharSet(), (sal_uInt16)rStream.GetVersion());
+ rStream << nTemp;
+
+ nTemp = (USHORT)rFont.GetPitch(); rStream << nTemp;
+ nTemp = (USHORT)rFont.GetAlign(); rStream << nTemp;
+ nTemp = (USHORT)rFont.GetWeight(); rStream << nTemp;
+ nTemp = (USHORT)rFont.GetUnderline(); rStream << nTemp;
+ nTemp = (USHORT)rFont.GetStrikeout(); rStream << nTemp;
+ nTemp = (USHORT)rFont.GetItalic(); rStream << nTemp;
+
+ // UNICODE: rStream << rFont.GetName();
+ rStream.WriteByteString(rFont.GetName());
+
+ rStream << rFont.IsOutline();
+ rStream << rFont.IsShadow();
+ rStream << rFont.IsTransparent();
+}
+
+// -----------------------------------------------------------------------
+
+Font SvxBulletItem::CreateFont( SvStream& rStream, USHORT nVer )
+{
+ Font aFont;
+ Color aColor;
+ rStream >> aColor; aFont.SetColor( aColor );
+ USHORT nTemp;
+ rStream >> nTemp; aFont.SetFamily((FontFamily)nTemp);
+
+ // #90477#
+ rStream >> nTemp;
+ nTemp = (sal_uInt16)GetSOLoadTextEncoding((rtl_TextEncoding)nTemp, (sal_uInt16)rStream.GetVersion());
+ aFont.SetCharSet((rtl_TextEncoding)nTemp);
+
+ rStream >> nTemp; aFont.SetPitch((FontPitch)nTemp);
+ rStream >> nTemp; aFont.SetAlign((FontAlign)nTemp);
+ rStream >> nTemp; aFont.SetWeight((FontWeight)nTemp);
+ rStream >> nTemp; aFont.SetUnderline((FontUnderline)nTemp);
+ rStream >> nTemp; aFont.SetStrikeout((FontStrikeout)nTemp);
+ rStream >> nTemp; aFont.SetItalic((FontItalic)nTemp);
+
+ // UNICODE: rStream >> aName; aFont.SetName( aName );
+ String aName;
+ rStream.ReadByteString(aName);
+ aFont.SetName( aName );
+
+ if( nVer == 1 )
+ {
+ long nHeight, nWidth;
+ rStream >> nHeight; rStream >> nWidth; Size aSize( nWidth, nHeight );
+ aFont.SetSize( aSize );
+ }
+
+ BOOL bTemp;
+ rStream >> bTemp; aFont.SetOutline( bTemp );
+ rStream >> bTemp; aFont.SetShadow( bTemp );
+ rStream >> bTemp; aFont.SetTransparent( bTemp );
+ return aFont;
+}
+
+
+// -----------------------------------------------------------------------
+
+SvxBulletItem::SvxBulletItem( USHORT _nWhich ) : SfxPoolItem( _nWhich )
+{
+ SetDefaultFont_Impl();
+ SetDefaults_Impl();
+ nValidMask = 0xFFFF;
+}
+
+// -----------------------------------------------------------------------
+
+SvxBulletItem::SvxBulletItem( BYTE nNewStyle, const Font& rFont, USHORT /*nStart*/, USHORT _nWhich ) : SfxPoolItem( _nWhich )
+{
+ SetDefaults_Impl();
+ nStyle = nNewStyle;
+ aFont = rFont;
+ nValidMask = 0xFFFF;
+}
+
+// -----------------------------------------------------------------------
+
+SvxBulletItem::SvxBulletItem( const Font& rFont, xub_Unicode cSymb, USHORT _nWhich ) : SfxPoolItem( _nWhich )
+{
+ SetDefaults_Impl();
+ aFont = rFont;
+ cSymbol = cSymb;
+ nStyle = BS_BULLET;
+ nValidMask = 0xFFFF;
+}
+
+// -----------------------------------------------------------------------
+
+SvxBulletItem::SvxBulletItem( const Bitmap& rBmp, USHORT _nWhich ) : SfxPoolItem( _nWhich )
+{
+ SetDefaults_Impl();
+
+ if( !rBmp.IsEmpty() )
+ {
+ pGraphicObject = new GraphicObject( rBmp );
+ nStyle = BS_BMP;
+ }
+
+ nValidMask = 0xFFFF;
+}
+
+// -----------------------------------------------------------------------
+
+SvxBulletItem::SvxBulletItem( const GraphicObject& rGraphicObject, USHORT _nWhich ) : SfxPoolItem( _nWhich )
+{
+ SetDefaults_Impl();
+
+ if( ( GRAPHIC_NONE != pGraphicObject->GetType() ) && ( GRAPHIC_DEFAULT != pGraphicObject->GetType() ) )
+ {
+ pGraphicObject = new GraphicObject( rGraphicObject );
+ nStyle = BS_BMP;
+ }
+
+ nValidMask = 0xFFFF;
+}
+
+// -----------------------------------------------------------------------
+
+SvxBulletItem::SvxBulletItem( SvStream& rStrm, USHORT _nWhich ) :
+ SfxPoolItem( _nWhich ),
+ pGraphicObject( NULL )
+{
+ rStrm >> nStyle;
+
+ if( nStyle != BS_BMP )
+ aFont = CreateFont( rStrm, BULITEM_VERSION );
+ else
+ {
+ // Sicheres Laden mit Test auf leere Bitmap
+ Bitmap aBmp;
+ const UINT32 nOldPos = rStrm.Tell();
+ // #69345# Errorcode beim Bitmap lesen ignorieren,
+ // siehe Kommentar #67581# in SvxBulletItem::Store()
+ BOOL bOldError = rStrm.GetError() ? TRUE : FALSE;
+ rStrm >> aBmp;
+ if ( !bOldError && rStrm.GetError() )
+ {
+ rStrm.ResetError();
+ // #71493# Keine Warnung: Das BulletItem interessiert seit 5.0 im Dateiformat nicht mehr.
+ // rStrm.SetError(ERRCODE_CLASS_READ | ERRCODE_SVX_BULLETITEM_NOBULLET | ERRCODE_WARNING_MASK);
+ }
+
+ if( aBmp.IsEmpty() )
+ {
+ rStrm.Seek( nOldPos );
+ nStyle = BS_NONE;
+ }
+ else
+ pGraphicObject = new GraphicObject( aBmp );
+ }
+
+ rStrm >> nWidth;
+ rStrm >> nStart;
+ rStrm >> nJustify;
+
+ char cTmpSymbol;
+ rStrm >> cTmpSymbol;
+ cSymbol = ByteString::ConvertToUnicode( cTmpSymbol, aFont.GetCharSet() );
+
+ rStrm >> nScale;
+
+ // UNICODE: rStrm >> aPrevText;
+ rStrm.ReadByteString(aPrevText);
+
+ // UNICODE: rStrm >> aFollowText;
+ rStrm.ReadByteString(aFollowText);
+
+ nValidMask = 0xFFFF;
+}
+
+// -----------------------------------------------------------------------
+
+SvxBulletItem::SvxBulletItem( const SvxBulletItem& rItem) : SfxPoolItem( rItem )
+{
+ aFont = rItem.aFont;
+ pGraphicObject = ( rItem.pGraphicObject ? new GraphicObject( *rItem.pGraphicObject ) : NULL );
+ aPrevText = rItem.aPrevText;
+ aFollowText = rItem.aFollowText;
+ nStart = rItem.nStart;
+ nStyle = rItem.nStyle;
+ nWidth = rItem.nWidth;
+ nScale = rItem.nScale;
+ cSymbol = rItem.cSymbol;
+ nJustify = rItem.nJustify;
+ nValidMask = rItem.nValidMask;
+}
+
+// -----------------------------------------------------------------------
+
+SvxBulletItem::~SvxBulletItem()
+{
+ if( pGraphicObject )
+ delete pGraphicObject;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxBulletItem::Clone( SfxItemPool * /*pPool*/ ) const
+{
+ return new SvxBulletItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxBulletItem::Create( SvStream& rStrm, USHORT /*nVersion*/ ) const
+{
+ return new SvxBulletItem( rStrm, Which() );
+}
+
+// -----------------------------------------------------------------------
+
+void SvxBulletItem::SetDefaultFont_Impl()
+{
+ aFont = OutputDevice::GetDefaultFont( DEFAULTFONT_FIXED, LANGUAGE_SYSTEM, 0 );
+ aFont.SetAlign( ALIGN_BOTTOM);
+ aFont.SetTransparent( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void SvxBulletItem::SetDefaults_Impl()
+{
+ pGraphicObject = NULL;
+ nWidth = 1200; // 1.2cm
+ nStart = 1;
+ nStyle = BS_123;
+ nJustify = BJ_HLEFT | BJ_VCENTER;
+ cSymbol = sal_Unicode(' ');
+ nScale = 75;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SvxBulletItem::GetVersion( USHORT /*nVersion*/ ) const
+{
+ return BULITEM_VERSION;
+}
+
+// -----------------------------------------------------------------------
+
+void SvxBulletItem::CopyValidProperties( const SvxBulletItem& rCopyFrom )
+{
+ Font _aFont = GetFont();
+ Font aNewFont = rCopyFrom.GetFont();
+ if ( rCopyFrom.IsValid( VALID_FONTNAME ) )
+ {
+ _aFont.SetName( aNewFont.GetName() );
+ _aFont.SetFamily( aNewFont.GetFamily() );
+ _aFont.SetStyleName( aNewFont.GetStyleName() );
+ }
+ if ( rCopyFrom.IsValid( VALID_FONTCOLOR ) )
+ _aFont.SetColor( aNewFont.GetColor() );
+ if ( rCopyFrom.IsValid( VALID_SYMBOL ) )
+ SetSymbol( rCopyFrom.GetSymbol() );
+ if ( rCopyFrom.IsValid( VALID_BITMAP ) )
+ SetGraphicObject( rCopyFrom.GetGraphicObject() );
+ if ( rCopyFrom.IsValid( VALID_SCALE ) )
+ SetScale( rCopyFrom.GetScale() );
+ if ( rCopyFrom.IsValid( VALID_START ) )
+ SetStart( rCopyFrom.GetStart() );
+ if ( rCopyFrom.IsValid( VALID_STYLE ) )
+ SetStyle( rCopyFrom.GetStyle() );
+ if ( rCopyFrom.IsValid( VALID_PREVTEXT ) )
+ SetPrevText( rCopyFrom.GetPrevText() );
+ if ( rCopyFrom.IsValid( VALID_FOLLOWTEXT ) )
+ SetFollowText( rCopyFrom.GetFollowText() );
+
+ SetFont( _aFont );
+}
+
+
+// -----------------------------------------------------------------------
+
+int SvxBulletItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT(rItem.ISA(SvxBulletItem),"operator==Types not matching");
+ const SvxBulletItem& rBullet = (const SvxBulletItem&)rItem;
+ // ValidMask mitvergleichen, da sonst kein Putten in ein AttrSet moeglich,
+ // wenn sich das Item nur in der ValidMask von einem existierenden unterscheidet.
+ if( nValidMask != rBullet.nValidMask ||
+ nStyle != rBullet.nStyle ||
+ nScale != rBullet.nScale ||
+ nJustify != rBullet.nJustify ||
+ nWidth != rBullet.nWidth ||
+ nStart != rBullet.nStart ||
+ cSymbol != rBullet.cSymbol ||
+ aPrevText != rBullet.aPrevText ||
+ aFollowText != rBullet.aFollowText )
+ return 0;
+
+ if( ( nStyle != BS_BMP ) && ( aFont != rBullet.aFont ) )
+ return 0;
+
+ if( nStyle == BS_BMP )
+ {
+ if( ( pGraphicObject && !rBullet.pGraphicObject ) || ( !pGraphicObject && rBullet.pGraphicObject ) )
+ return 0;
+
+ if( ( pGraphicObject && rBullet.pGraphicObject ) &&
+ ( ( *pGraphicObject != *rBullet.pGraphicObject ) ||
+ ( pGraphicObject->GetPrefSize() != rBullet.pGraphicObject->GetPrefSize() ) ) )
+ {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxBulletItem::Store( SvStream& rStrm, USHORT /*nItemVersion*/ ) const
+{
+ // Korrektur bei leerer Bitmap
+ if( ( nStyle == BS_BMP ) &&
+ ( !pGraphicObject || ( GRAPHIC_NONE == pGraphicObject->GetType() ) || ( GRAPHIC_DEFAULT == pGraphicObject->GetType() ) ) )
+ {
+ if( pGraphicObject )
+ {
+ delete( const_cast< SvxBulletItem* >( this )->pGraphicObject );
+ const_cast< SvxBulletItem* >( this )->pGraphicObject = NULL;
+ }
+
+ const_cast< SvxBulletItem* >( this )->nStyle = BS_NONE;
+ }
+
+ rStrm << nStyle;
+
+ if( nStyle != BS_BMP )
+ StoreFont( rStrm, aFont );
+ else
+ {
+ ULONG _nStart = rStrm.Tell();
+
+ // Kleine Vorab-Schaetzung der Groesse...
+ USHORT nFac = ( rStrm.GetCompressMode() != COMPRESSMODE_NONE ) ? 3 : 1;
+ const Bitmap aBmp( pGraphicObject->GetGraphic().GetBitmap() );
+ ULONG nBytes = aBmp.GetSizeBytes();
+ if ( nBytes < ULONG(0xFF00*nFac) )
+ rStrm << aBmp;
+
+ ULONG nEnd = rStrm.Tell();
+ // #67581# Item darf mit Overhead nicht mehr als 64K schreiben,
+ // sonst platzt der SfxMultiRecord
+ // Dann lieber auf die Bitmap verzichten, ist nur fuer Outliner
+ // und auch nur fuer <= 5.0 wichtig.
+ // Beim Einlesen merkt der Stream-Operator der Bitmap, dass dort keine steht.
+ // Hiermit funktioniert jetzt der Fall das die grosse Bitmap aus einem anderen
+ // Fileformat entstanden ist, welches keine 64K belegt, aber wenn eine
+ // Bitmap > 64K verwendet wird, hat das SvxNumBulletItem beim Laden ein Problem,
+ // stuerzt aber nicht ab.
+
+ if ( (nEnd-_nStart) > 0xFF00 )
+ rStrm.Seek( _nStart );
+ }
+ rStrm << nWidth;
+ rStrm << nStart;
+ rStrm << nJustify;
+ rStrm << (char)ByteString::ConvertFromUnicode( cSymbol, aFont.GetCharSet() );
+ rStrm << nScale;
+
+ // UNICODE: rStrm << aPrevText;
+ rStrm.WriteByteString(aPrevText);
+
+ // UNICODE: rStrm << aFollowText;
+ rStrm.WriteByteString(aFollowText);
+
+ return rStrm;
+}
+
+//------------------------------------------------------------------------
+
+XubString SvxBulletItem::GetFullText() const
+{
+ XubString aStr( aPrevText );
+ aStr += cSymbol;
+ aStr += aFollowText;
+ return aStr;
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxBulletItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *
+) const
+{
+ SfxItemPresentation eRet = SFX_ITEM_PRESENTATION_NONE;
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ eRet = SFX_ITEM_PRESENTATION_NONE;
+ break;
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = GetFullText();
+ eRet = SFX_ITEM_PRESENTATION_COMPLETE;
+ break;
+ default: ; //prevent warning
+ }
+ return eRet;
+}
+
+//------------------------------------------------------------------------
+
+Bitmap SvxBulletItem::GetBitmap() const
+{
+ if( pGraphicObject )
+ return pGraphicObject->GetGraphic().GetBitmap();
+ else
+ {
+ const Bitmap aDefaultBitmap;
+ return aDefaultBitmap;
+ }
+}
+
+//------------------------------------------------------------------------
+
+void SvxBulletItem::SetBitmap( const Bitmap& rBmp )
+{
+ if( rBmp.IsEmpty() )
+ {
+ if( pGraphicObject )
+ {
+ delete pGraphicObject;
+ pGraphicObject = NULL;
+ }
+ }
+ else
+ {
+ delete pGraphicObject;
+ pGraphicObject = new GraphicObject( rBmp );
+
+ }
+}
+
+//------------------------------------------------------------------------
+
+const GraphicObject& SvxBulletItem::GetGraphicObject() const
+{
+ if( pGraphicObject )
+ return *pGraphicObject;
+ else
+ {
+ static const GraphicObject aDefaultObject;
+ return aDefaultObject;
+ }
+}
+
+//------------------------------------------------------------------------
+
+void SvxBulletItem::SetGraphicObject( const GraphicObject& rGraphicObject )
+{
+ if( ( GRAPHIC_NONE == rGraphicObject.GetType() ) || ( GRAPHIC_DEFAULT == rGraphicObject.GetType() ) )
+ {
+ if( pGraphicObject )
+ {
+ delete pGraphicObject;
+ pGraphicObject = NULL;
+ }
+ }
+ else
+ {
+ delete pGraphicObject;
+ pGraphicObject = new GraphicObject( rGraphicObject );
+ }
+}
diff --git a/editeng/source/items/charhiddenitem.cxx b/editeng/source/items/charhiddenitem.cxx
new file mode 100644
index 0000000000..b40f55b262
--- /dev/null
+++ b/editeng/source/items/charhiddenitem.cxx
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: charhiddenitem.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+
+#include <editeng/charhiddenitem.hxx>
+#include <editeng/editrids.hrc>
+#include <editeng/eerdll.hxx>
+
+TYPEINIT1_FACTORY(SvxCharHiddenItem, SfxBoolItem, new SvxCharHiddenItem(sal_False, 0));
+
+/*-- 16.12.2003 15:24:25---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+SvxCharHiddenItem::SvxCharHiddenItem( const sal_Bool bHidden, const USHORT nId ) :
+ SfxBoolItem( nId, bHidden )
+{
+}
+/*-- 16.12.2003 15:24:25---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+SfxPoolItem* SvxCharHiddenItem::Clone( SfxItemPool * ) const
+{
+ return new SvxCharHiddenItem( *this );
+}
+/*-- 16.12.2003 15:24:25---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+SfxItemPresentation SvxCharHiddenItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ USHORT nId = RID_SVXITEMS_CHARHIDDEN_FALSE;
+
+ if ( GetValue() )
+ nId = RID_SVXITEMS_CHARHIDDEN_TRUE;
+ rText = EE_RESSTR(nId);
+ return ePres;
+ }
+ default: ; //prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
diff --git a/editeng/source/items/flditem.cxx b/editeng/source/items/flditem.cxx
new file mode 100644
index 0000000000..af356a50a0
--- /dev/null
+++ b/editeng/source/items/flditem.cxx
@@ -0,0 +1,1101 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: flditem.cxx,v $
+ * $Revision: 1.29 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <vcl/metaact.hxx>
+#include <svl/zforlist.hxx>
+#include <tools/urlobj.hxx>
+
+#define _SVX_FLDITEM_CXX
+#include <unotools/localfilehelper.hxx>
+
+#include <editeng/flditem.hxx>
+
+#include <editeng/svdfield.hxx>
+
+// #90477#
+#include <tools/tenccvt.hxx>
+
+#define FRAME_MARKER (sal_uInt32)0x21981357
+#define CHARSET_MARKER (FRAME_MARKER+1)
+
+// -----------------------------------------------------------------------
+
+TYPEINIT1( SvxFieldItem, SfxPoolItem );
+
+SV_IMPL_PERSIST1( SvxFieldData, SvPersistBase );
+
+// -----------------------------------------------------------------------
+
+SvxFieldData::SvxFieldData()
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvxFieldData::~SvxFieldData()
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvxFieldData* SvxFieldData::Clone() const
+{
+ return new SvxFieldData;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxFieldData::operator==( const SvxFieldData& rFld ) const
+{
+ DBG_ASSERT( Type() == rFld.Type(), "==: Verschiedene Typen" );
+ (void)rFld;
+ return TRUE; // Basicklasse immer gleich.
+}
+
+// -----------------------------------------------------------------------
+
+void SvxFieldData::Load( SvPersistStream & /*rStm*/ )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SvxFieldData::Save( SvPersistStream & /*rStm*/ )
+{
+}
+
+
+MetaAction* SvxFieldData::createBeginComment() const
+{
+ return new MetaCommentAction( "FIELD_SEQ_BEGIN" );
+}
+
+MetaAction* SvxFieldData::createEndComment() const
+{
+ return new MetaCommentAction( "FIELD_SEQ_END" );
+}
+
+// -----------------------------------------------------------------------
+
+SvxFieldItem::SvxFieldItem( SvxFieldData* pFld, const USHORT nId ) :
+ SfxPoolItem( nId )
+{
+ pField = pFld; // gehoert direkt dem Item
+}
+
+// -----------------------------------------------------------------------
+
+SvxFieldItem::SvxFieldItem( const SvxFieldData& rField, const USHORT nId ) :
+ SfxPoolItem( nId )
+{
+ pField = rField.Clone();
+}
+
+// -----------------------------------------------------------------------
+
+SvxFieldItem::SvxFieldItem( const SvxFieldItem& rItem ) :
+ SfxPoolItem ( rItem )
+{
+ pField = rItem.GetField() ? rItem.GetField()->Clone() : 0;
+}
+
+// -----------------------------------------------------------------------
+
+SvxFieldItem::~SvxFieldItem()
+{
+ delete pField;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxFieldItem::Clone( SfxItemPool* ) const
+{
+ return new SvxFieldItem(*this);
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxFieldItem::Create( SvStream& rStrm, USHORT ) const
+{
+ SvxFieldData* pData = 0;
+ SvPersistStream aPStrm( GetClassManager(), &rStrm );
+ aPStrm >> pData;
+
+ if( aPStrm.IsEof() )
+ aPStrm.SetError( SVSTREAM_GENERALERROR );
+
+ if ( aPStrm.GetError() == ERRCODE_IO_NOFACTORY )
+ aPStrm.ResetError(); // Eigentlich einen Code, dass nicht alle Attr gelesen wurden...
+
+ return new SvxFieldItem( pData, Which() );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxFieldItem::Store( SvStream& rStrm, USHORT /*nItemVersion*/ ) const
+{
+ DBG_ASSERT( pField, "SvxFieldItem::Store: Feld?!" );
+ SvPersistStream aPStrm( GetClassManager(), &rStrm );
+ // Das ResetError in der obigen Create-Methode gab es in 3.1 noch nicht,
+ // deshalb duerfen beim 3.x-Export neuere Items nicht gespeichert werden!
+ if ( ( rStrm.GetVersion() <= SOFFICE_FILEFORMAT_31 ) && pField &&
+ pField->GetClassId() == 50 /* SdrMeasureField */ )
+ {
+ // SvxFieldData reicht nicht, weil auch nicht am ClassMgr angemeldet
+ SvxURLField aDummyData;
+ aPStrm << &aDummyData;
+ }
+ else
+ aPStrm << pField;
+
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxFieldItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal which or type" );
+
+ const SvxFieldData* pOtherFld = ((const SvxFieldItem&)rItem).GetField();
+ if ( !pField && !pOtherFld )
+ return TRUE;
+
+ if ( ( !pField && pOtherFld ) || ( pField && !pOtherFld ) )
+ return FALSE;
+
+ return ( ( pField->Type() == pOtherFld->Type() )
+ && ( *pField == *pOtherFld ) );
+}
+
+// =================================================================
+// Es folgen die Ableitungen von SvxFieldData...
+// =================================================================
+
+SV_IMPL_PERSIST1( SvxDateField, SvxFieldData );
+
+// -----------------------------------------------------------------------
+
+SvxDateField::SvxDateField()
+{
+ nFixDate = Date().GetDate();
+ eType = SVXDATETYPE_VAR;
+ eFormat = SVXDATEFORMAT_STDSMALL;
+}
+
+// -----------------------------------------------------------------------
+
+SvxDateField::SvxDateField( const Date& rDate, SvxDateType eT, SvxDateFormat eF )
+{
+ nFixDate = rDate.GetDate();
+ eType = eT;
+ eFormat = eF;
+}
+
+// -----------------------------------------------------------------------
+
+SvxFieldData* SvxDateField::Clone() const
+{
+ return new SvxDateField( *this );
+}
+
+// -----------------------------------------------------------------------
+
+int SvxDateField::operator==( const SvxFieldData& rOther ) const
+{
+ if ( rOther.Type() != Type() )
+ return FALSE;
+
+ const SvxDateField& rOtherFld = (const SvxDateField&) rOther;
+ return ( ( nFixDate == rOtherFld.nFixDate ) &&
+ ( eType == rOtherFld.eType ) &&
+ ( eFormat == rOtherFld.eFormat ) );
+}
+
+// -----------------------------------------------------------------------
+
+void SvxDateField::Load( SvPersistStream & rStm )
+{
+ USHORT nType, nFormat;
+
+ rStm >> nFixDate;
+ rStm >> nType;
+ rStm >> nFormat;
+
+ eType = (SvxDateType)nType;
+ eFormat= (SvxDateFormat)nFormat;
+}
+
+// -----------------------------------------------------------------------
+
+void SvxDateField::Save( SvPersistStream & rStm )
+{
+ rStm << nFixDate;
+ rStm << (USHORT)eType;
+ rStm << (USHORT)eFormat;
+}
+
+// -----------------------------------------------------------------------
+
+String SvxDateField::GetFormatted( SvNumberFormatter& rFormatter, LanguageType eLang ) const
+{
+ Date aDate; // current date
+ if ( eType == SVXDATETYPE_FIX )
+ aDate.SetDate( nFixDate );
+
+ return GetFormatted( aDate, eFormat, rFormatter, eLang );
+}
+
+String SvxDateField::GetFormatted( Date& aDate, SvxDateFormat eFormat, SvNumberFormatter& rFormatter, LanguageType eLang )
+{
+ if ( eFormat == SVXDATEFORMAT_SYSTEM )
+ {
+ DBG_ERROR( "SVXDATEFORMAT_SYSTEM nicht implementiert!" );
+ eFormat = SVXDATEFORMAT_STDSMALL;
+ }
+ else if ( eFormat == SVXDATEFORMAT_APPDEFAULT )
+ {
+ DBG_ERROR( "SVXDATEFORMAT_APPDEFAULT: Woher nehmen?" );
+ eFormat = SVXDATEFORMAT_STDSMALL;
+ }
+
+ ULONG nFormatKey;
+
+ switch( eFormat )
+ {
+ case SVXDATEFORMAT_STDSMALL:
+ // short
+ nFormatKey = rFormatter.GetFormatIndex( NF_DATE_SYSTEM_SHORT, eLang );
+ break;
+ case SVXDATEFORMAT_STDBIG:
+ // long
+ nFormatKey = rFormatter.GetFormatIndex( NF_DATE_SYSTEM_LONG, eLang );
+ break;
+ case SVXDATEFORMAT_A:
+ // 13.02.96
+ nFormatKey = rFormatter.GetFormatIndex( NF_DATE_SYS_DDMMYY, eLang );
+ break;
+ case SVXDATEFORMAT_B:
+ // 13.02.1996
+ nFormatKey = rFormatter.GetFormatIndex( NF_DATE_SYS_DDMMYYYY, eLang );
+ break;
+ case SVXDATEFORMAT_C:
+ // 13. Feb 1996
+ nFormatKey = rFormatter.GetFormatIndex( NF_DATE_SYS_DMMMYYYY, eLang );
+ break;
+ case SVXDATEFORMAT_D:
+ // 13. Februar 1996
+ nFormatKey = rFormatter.GetFormatIndex( NF_DATE_SYS_DMMMMYYYY, eLang );
+ break;
+ case SVXDATEFORMAT_E:
+ // Die, 13. Februar 1996
+ nFormatKey = rFormatter.GetFormatIndex( NF_DATE_SYS_NNDMMMMYYYY, eLang );
+ break;
+ case SVXDATEFORMAT_F:
+ // Dienstag, 13. Februar 1996
+ nFormatKey = rFormatter.GetFormatIndex( NF_DATE_SYS_NNNNDMMMMYYYY, eLang );
+ break;
+ default:
+ nFormatKey = rFormatter.GetStandardFormat( NUMBERFORMAT_DATE, eLang );
+ }
+
+ double fDiffDate = aDate - *(rFormatter.GetNullDate());
+ String aStr;
+ Color* pColor = NULL;
+ rFormatter.GetOutputString( fDiffDate, nFormatKey, aStr, &pColor );
+ return aStr;
+}
+
+MetaAction* SvxDateField::createBeginComment() const
+{
+ return new MetaCommentAction( "FIELD_SEQ_BEGIN" );
+}
+
+SV_IMPL_PERSIST1( SvxURLField, SvxFieldData );
+
+// -----------------------------------------------------------------------
+
+SvxURLField::SvxURLField()
+{
+ eFormat = SVXURLFORMAT_URL;
+}
+
+// -----------------------------------------------------------------------
+
+SvxURLField::SvxURLField( const XubString& rURL, const XubString& rRepres, SvxURLFormat eFmt )
+ : aURL( rURL ), aRepresentation( rRepres )
+{
+ eFormat = eFmt;
+}
+
+// -----------------------------------------------------------------------
+
+SvxFieldData* SvxURLField::Clone() const
+{
+ return new SvxURLField( *this );
+}
+
+// -----------------------------------------------------------------------
+
+int SvxURLField::operator==( const SvxFieldData& rOther ) const
+{
+ if ( rOther.Type() != Type() )
+ return FALSE;
+
+ const SvxURLField& rOtherFld = (const SvxURLField&) rOther;
+ return ( ( eFormat == rOtherFld.eFormat ) &&
+ ( aURL == rOtherFld.aURL ) &&
+ ( aRepresentation == rOtherFld.aRepresentation ) &&
+ ( aTargetFrame == rOtherFld.aTargetFrame ) );
+}
+
+// -----------------------------------------------------------------------
+
+void SvxURLField::Load( SvPersistStream & rStm )
+{
+ USHORT nFormat;
+ sal_uInt32 nFrameMarker, nCharSetMarker;
+ long nUlongSize = (long)sizeof(sal_uInt32);
+ String aTmpURL;
+
+ rStm >> nFormat;
+
+ // UNICODE: rStm >> aTmpURL;
+ rStm.ReadByteString(aTmpURL);
+
+ // UNICODE: rStm >> aRepresentation;
+ // read to a temp string first, read text encoding and
+ // convert later to stay compatible to fileformat
+ ByteString aTempString;
+ rtl_TextEncoding aTempEncoding = RTL_TEXTENCODING_MS_1252; // #101493# Init for old documents
+ rStm.ReadByteString(aTempString);
+
+ rStm >> nFrameMarker;
+ if ( nFrameMarker == FRAME_MARKER )
+ {
+ // UNICODE: rStm >> aTargetFrame;
+ rStm.ReadByteString(aTargetFrame);
+
+ rStm >> nCharSetMarker;
+ if ( nCharSetMarker == CHARSET_MARKER )
+ {
+ USHORT nCharSet;
+ rStm >> nCharSet;
+
+ // remember encoding
+ aTempEncoding = (rtl_TextEncoding)nCharSet;
+ }
+ else
+ rStm.SeekRel( -nUlongSize );
+ }
+ else
+ rStm.SeekRel( -nUlongSize );
+
+ // now build representation string due to known encoding
+ aRepresentation = String(aTempString, aTempEncoding);
+
+ eFormat= (SvxURLFormat)nFormat;
+
+ // Relatives Speichern => Beim laden absolut machen.
+ DBG_ERROR("No BaseURL!");
+ // TODO/MBA: no BaseURL
+ aURL = INetURLObject::GetAbsURL( String(), aTmpURL );
+}
+
+// -----------------------------------------------------------------------
+
+void SvxURLField::Save( SvPersistStream & rStm )
+{
+ // Relatives Speichern der URL
+ DBG_ERROR("No BaseURL!");
+ // TODO/MBA: no BaseURL
+ String aTmpURL = INetURLObject::GetRelURL( String(), aURL );
+
+ rStm << (USHORT)eFormat;
+
+ // UNICODE: rStm << aTmpURL;
+ rStm.WriteByteString(aTmpURL);
+
+ // UNICODE: rStm << aRepresentation;
+ rStm.WriteByteString(aRepresentation);
+
+ rStm << FRAME_MARKER;
+
+ // UNICODE: rStm << aTargetFrame;
+ rStm.WriteByteString(aTargetFrame);
+
+ rStm << CHARSET_MARKER;
+
+ // #90477# rStm << (USHORT)GetStoreCharSet(gsl_getSystemTextEncoding(), rStm.GetVersion());
+ rStm << (USHORT)GetSOStoreTextEncoding(gsl_getSystemTextEncoding(), (sal_uInt16)rStm.GetVersion());
+}
+
+MetaAction* SvxURLField::createBeginComment() const
+{
+ // #i46618# Adding target URL to metafile comment
+ return new MetaCommentAction( "FIELD_SEQ_BEGIN",
+ 0,
+ reinterpret_cast<const BYTE*>(aURL.GetBuffer()),
+ 2*aURL.Len() );
+}
+
+// =================================================================
+// Die Felder, die aus Calc ausgebaut wurden:
+// =================================================================
+
+SV_IMPL_PERSIST1( SvxPageField, SvxFieldData );
+
+SvxFieldData* __EXPORT SvxPageField::Clone() const
+{
+ return new SvxPageField; // leer
+}
+
+int __EXPORT SvxPageField::operator==( const SvxFieldData& rCmp ) const
+{
+ return ( rCmp.Type() == TYPE(SvxPageField) );
+}
+
+void __EXPORT SvxPageField::Load( SvPersistStream & /*rStm*/ )
+{
+}
+
+void __EXPORT SvxPageField::Save( SvPersistStream & /*rStm*/ )
+{
+}
+
+MetaAction* SvxPageField::createBeginComment() const
+{
+ return new MetaCommentAction( "FIELD_SEQ_BEGIN;PageField" );
+}
+
+
+SV_IMPL_PERSIST1( SvxPagesField, SvxFieldData );
+
+SvxFieldData* __EXPORT SvxPagesField::Clone() const
+{
+ return new SvxPagesField; // leer
+}
+
+int __EXPORT SvxPagesField::operator==( const SvxFieldData& rCmp ) const
+{
+ return ( rCmp.Type() == TYPE(SvxPagesField) );
+}
+
+void __EXPORT SvxPagesField::Load( SvPersistStream & /*rStm*/ )
+{
+}
+
+void __EXPORT SvxPagesField::Save( SvPersistStream & /*rStm*/ )
+{
+}
+
+SV_IMPL_PERSIST1( SvxTimeField, SvxFieldData );
+
+SvxFieldData* __EXPORT SvxTimeField::Clone() const
+{
+ return new SvxTimeField; // leer
+}
+
+int __EXPORT SvxTimeField::operator==( const SvxFieldData& rCmp ) const
+{
+ return ( rCmp.Type() == TYPE(SvxTimeField) );
+}
+
+void __EXPORT SvxTimeField::Load( SvPersistStream & /*rStm*/ )
+{
+}
+
+void __EXPORT SvxTimeField::Save( SvPersistStream & /*rStm*/ )
+{
+}
+
+MetaAction* SvxTimeField::createBeginComment() const
+{
+ return new MetaCommentAction( "FIELD_SEQ_BEGIN" );
+}
+
+SV_IMPL_PERSIST1( SvxFileField, SvxFieldData );
+
+SvxFieldData* __EXPORT SvxFileField::Clone() const
+{
+ return new SvxFileField; // leer
+}
+
+int __EXPORT SvxFileField::operator==( const SvxFieldData& rCmp ) const
+{
+ return ( rCmp.Type() == TYPE(SvxFileField) );
+}
+
+void __EXPORT SvxFileField::Load( SvPersistStream & /*rStm*/ )
+{
+}
+
+void __EXPORT SvxFileField::Save( SvPersistStream & /*rStm*/ )
+{
+}
+
+SV_IMPL_PERSIST1( SvxTableField, SvxFieldData );
+
+SvxFieldData* __EXPORT SvxTableField::Clone() const
+{
+ return new SvxTableField; // leer
+}
+
+int __EXPORT SvxTableField::operator==( const SvxFieldData& rCmp ) const
+{
+ return ( rCmp.Type() == TYPE(SvxTableField) );
+}
+
+void __EXPORT SvxTableField::Load( SvPersistStream & /*rStm*/ )
+{
+}
+
+void __EXPORT SvxTableField::Save( SvPersistStream & /*rStm*/ )
+{
+}
+
+//----------------------------------------------------------------------------
+// SvxExtTimeField
+//----------------------------------------------------------------------------
+
+SV_IMPL_PERSIST1( SvxExtTimeField, SvxFieldData );
+
+//----------------------------------------------------------------------------
+
+SvxExtTimeField::SvxExtTimeField()
+{
+ nFixTime = Time().GetTime();
+ eType = SVXTIMETYPE_VAR;
+ eFormat = SVXTIMEFORMAT_STANDARD;
+}
+
+//----------------------------------------------------------------------------
+
+SvxExtTimeField::SvxExtTimeField( const Time& rTime, SvxTimeType eT, SvxTimeFormat eF )
+{
+ nFixTime = rTime.GetTime();
+ eType = eT;
+ eFormat = eF;
+}
+
+//----------------------------------------------------------------------------
+
+SvxFieldData* SvxExtTimeField::Clone() const
+{
+ return new SvxExtTimeField( *this );
+}
+
+//----------------------------------------------------------------------------
+
+int SvxExtTimeField::operator==( const SvxFieldData& rOther ) const
+{
+ if ( rOther.Type() != Type() )
+ return FALSE;
+
+ const SvxExtTimeField& rOtherFld = (const SvxExtTimeField&) rOther;
+ return ( ( nFixTime == rOtherFld.nFixTime ) &&
+ ( eType == rOtherFld.eType ) &&
+ ( eFormat == rOtherFld.eFormat ) );
+}
+
+//----------------------------------------------------------------------------
+
+void SvxExtTimeField::Load( SvPersistStream & rStm )
+{
+ USHORT nType, nFormat;
+
+ rStm >> nFixTime;
+ rStm >> nType;
+ rStm >> nFormat;
+
+ eType = (SvxTimeType) nType;
+ eFormat= (SvxTimeFormat) nFormat;
+}
+
+//----------------------------------------------------------------------------
+
+void SvxExtTimeField::Save( SvPersistStream & rStm )
+{
+ rStm << nFixTime;
+ rStm << (USHORT) eType;
+ rStm << (USHORT) eFormat;
+}
+
+//----------------------------------------------------------------------------
+
+String SvxExtTimeField::GetFormatted( SvNumberFormatter& rFormatter, LanguageType eLang ) const
+{
+ Time aTime; // current time
+ if ( eType == SVXTIMETYPE_FIX )
+ aTime.SetTime( nFixTime );
+ return GetFormatted( aTime, eFormat, rFormatter, eLang );
+}
+
+String SvxExtTimeField::GetFormatted( Time& aTime, SvxTimeFormat eFormat, SvNumberFormatter& rFormatter, LanguageType eLang )
+{
+ switch( eFormat )
+ {
+ case SVXTIMEFORMAT_SYSTEM :
+ DBG_ERROR( "SVXTIMEFORMAT_SYSTEM: not implemented" );
+ eFormat = SVXTIMEFORMAT_STANDARD;
+ break;
+ case SVXTIMEFORMAT_APPDEFAULT :
+ DBG_ERROR( "SVXTIMEFORMAT_APPDEFAULT: not implemented" );
+ eFormat = SVXTIMEFORMAT_STANDARD;
+ break;
+ default: ;//prevent warning
+ }
+
+ sal_uInt32 nFormatKey;
+
+ switch( eFormat )
+ {
+ case SVXTIMEFORMAT_12_HM:
+ nFormatKey = rFormatter.GetFormatIndex( NF_TIME_HHMMAMPM, eLang );
+ break;
+ case SVXTIMEFORMAT_12_HMSH:
+ { // no builtin format available, try to insert or reuse
+ String aFormatCode( RTL_CONSTASCII_USTRINGPARAM( "HH:MM:SS.00 AM/PM" ) );
+ xub_StrLen nCheckPos;
+ short nType;
+ /*BOOL bInserted = */rFormatter.PutandConvertEntry( aFormatCode,
+ nCheckPos, nType, nFormatKey, LANGUAGE_ENGLISH_US, eLang );
+ DBG_ASSERT( nCheckPos == 0, "SVXTIMEFORMAT_12_HMSH: could not insert format code" );
+ if ( nCheckPos )
+ nFormatKey = rFormatter.GetFormatIndex( NF_TIME_HH_MMSS00, eLang );
+ }
+ break;
+ case SVXTIMEFORMAT_24_HM:
+ nFormatKey = rFormatter.GetFormatIndex( NF_TIME_HHMM, eLang );
+ break;
+ case SVXTIMEFORMAT_24_HMSH:
+ nFormatKey = rFormatter.GetFormatIndex( NF_TIME_HH_MMSS00, eLang );
+ break;
+ case SVXTIMEFORMAT_12_HMS:
+ nFormatKey = rFormatter.GetFormatIndex( NF_TIME_HHMMSSAMPM, eLang );
+ break;
+ case SVXTIMEFORMAT_24_HMS:
+ nFormatKey = rFormatter.GetFormatIndex( NF_TIME_HHMMSS, eLang );
+ break;
+ case SVXTIMEFORMAT_STANDARD:
+ default:
+ nFormatKey = rFormatter.GetStandardFormat( NUMBERFORMAT_TIME, eLang );
+ }
+
+ double fFracTime = aTime.GetTimeInDays();
+ String aStr;
+ Color* pColor = NULL;
+ rFormatter.GetOutputString( fFracTime, nFormatKey, aStr, &pColor );
+ return aStr;
+}
+
+MetaAction* SvxExtTimeField::createBeginComment() const
+{
+ return new MetaCommentAction( "FIELD_SEQ_BEGIN" );
+}
+
+//----------------------------------------------------------------------------
+// SvxExtFileField
+//----------------------------------------------------------------------------
+
+SV_IMPL_PERSIST1( SvxExtFileField, SvxFieldData );
+
+//----------------------------------------------------------------------------
+
+SvxExtFileField::SvxExtFileField()
+{
+ eType = SVXFILETYPE_VAR;
+ eFormat = SVXFILEFORMAT_FULLPATH;
+}
+
+//----------------------------------------------------------------------------
+
+SvxExtFileField::SvxExtFileField( const XubString& rStr, SvxFileType eT, SvxFileFormat eF )
+{
+ aFile = rStr;
+ eType = eT;
+ eFormat = eF;
+}
+
+//----------------------------------------------------------------------------
+
+SvxFieldData* SvxExtFileField::Clone() const
+{
+ return new SvxExtFileField( *this );
+}
+
+//----------------------------------------------------------------------------
+
+int SvxExtFileField::operator==( const SvxFieldData& rOther ) const
+{
+ if ( rOther.Type() != Type() )
+ return FALSE;
+
+ const SvxExtFileField& rOtherFld = (const SvxExtFileField&) rOther;
+ return ( ( aFile == rOtherFld.aFile ) &&
+ ( eType == rOtherFld.eType ) &&
+ ( eFormat == rOtherFld.eFormat ) );
+}
+
+//----------------------------------------------------------------------------
+
+void SvxExtFileField::Load( SvPersistStream & rStm )
+{
+ USHORT nType, nFormat;
+
+ // UNICODE: rStm >> aFile;
+ rStm.ReadByteString(aFile);
+
+ rStm >> nType;
+ rStm >> nFormat;
+
+ eType = (SvxFileType) nType;
+ eFormat= (SvxFileFormat) nFormat;
+}
+
+//----------------------------------------------------------------------------
+
+void SvxExtFileField::Save( SvPersistStream & rStm )
+{
+ // UNICODE: rStm << aFile;
+ rStm.WriteByteString(aFile);
+
+ rStm << (USHORT) eType;
+ rStm << (USHORT) eFormat;
+}
+
+//----------------------------------------------------------------------------
+
+XubString SvxExtFileField::GetFormatted() const
+{
+ XubString aString;
+
+ INetURLObject aURLObj( aFile );
+
+ if( INET_PROT_NOT_VALID == aURLObj.GetProtocol() )
+ {
+ // invalid? try to interpret string as system file name
+ String aURLStr;
+
+ ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aFile, aURLStr );
+
+ aURLObj.SetURL( aURLStr );
+ }
+
+ // #92009# Be somewhat liberate when trying to
+ // get formatted content out of the FileField
+ if( INET_PROT_NOT_VALID == aURLObj.GetProtocol() )
+ {
+ // still not valid? Then output as is
+ aString = aFile;
+ }
+ else if( INET_PROT_FILE == aURLObj.GetProtocol() )
+ {
+ switch( eFormat )
+ {
+ case SVXFILEFORMAT_FULLPATH:
+ aString = aURLObj.getFSysPath(INetURLObject::FSYS_DETECT);
+ break;
+
+ case SVXFILEFORMAT_PATH:
+ aURLObj.removeSegment(INetURLObject::LAST_SEGMENT, false);
+ // #101742# Leave trailing slash at the pathname
+ aURLObj.setFinalSlash();
+ aString = aURLObj.getFSysPath(INetURLObject::FSYS_DETECT);
+ break;
+
+ case SVXFILEFORMAT_NAME:
+ aString = aURLObj.getBase(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_UNAMBIGUOUS);
+ break;
+
+ case SVXFILEFORMAT_NAME_EXT:
+ aString = aURLObj.getName(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_UNAMBIGUOUS);
+ break;
+ }
+ }
+ else
+ {
+ switch( eFormat )
+ {
+ case SVXFILEFORMAT_FULLPATH:
+ aString = aURLObj.GetMainURL( INetURLObject::DECODE_TO_IURI );
+ break;
+
+ case SVXFILEFORMAT_PATH:
+ aURLObj.removeSegment(INetURLObject::LAST_SEGMENT, false);
+ // #101742# Leave trailing slash at the pathname
+ aURLObj.setFinalSlash();
+ aString = aURLObj.GetMainURL( INetURLObject::DECODE_TO_IURI );
+ break;
+
+ case SVXFILEFORMAT_NAME:
+ aString = aURLObj.getBase();
+ break;
+
+ case SVXFILEFORMAT_NAME_EXT:
+ aString = aURLObj.getName();
+ break;
+ }
+ }
+
+ return( aString );
+}
+
+//----------------------------------------------------------------------------
+// SvxAuthorField
+//----------------------------------------------------------------------------
+
+SV_IMPL_PERSIST1( SvxAuthorField, SvxFieldData );
+
+//----------------------------------------------------------------------------
+
+SvxAuthorField::SvxAuthorField()
+{
+ eType = SVXAUTHORTYPE_VAR;
+ eFormat = SVXAUTHORFORMAT_FULLNAME;
+}
+
+//----------------------------------------------------------------------------
+
+SvxAuthorField::SvxAuthorField( const XubString& rFirstName,
+ const XubString& rLastName,
+ const XubString& rShortName,
+ SvxAuthorType eT, SvxAuthorFormat eF )
+{
+ aName = rLastName;
+ aFirstName = rFirstName;
+ aShortName = rShortName;
+ eType = eT;
+ eFormat = eF;
+}
+
+//----------------------------------------------------------------------------
+
+SvxFieldData* SvxAuthorField::Clone() const
+{
+ return new SvxAuthorField( *this );
+}
+
+//----------------------------------------------------------------------------
+
+int SvxAuthorField::operator==( const SvxFieldData& rOther ) const
+{
+ if ( rOther.Type() != Type() )
+ return FALSE;
+
+ const SvxAuthorField& rOtherFld = (const SvxAuthorField&) rOther;
+ return ( ( aName == rOtherFld.aName ) &&
+ ( aFirstName == rOtherFld.aFirstName ) &&
+ ( aShortName == rOtherFld.aShortName ) &&
+ ( eType == rOtherFld.eType ) &&
+ ( eFormat == rOtherFld.eFormat ) );
+}
+
+//----------------------------------------------------------------------------
+
+void SvxAuthorField::Load( SvPersistStream & rStm )
+{
+ USHORT nType, nFormat;
+
+ // UNICODE: rStm >> aName;
+ rStm.ReadByteString(aName);
+
+ // UNICODE: rStm >> aFirstName;
+ rStm.ReadByteString(aFirstName);
+
+ // UNICODE: rStm >> aShortName;
+ rStm.ReadByteString(aShortName);
+
+ rStm >> nType;
+ rStm >> nFormat;
+
+ eType = (SvxAuthorType) nType;
+ eFormat= (SvxAuthorFormat) nFormat;
+}
+
+//----------------------------------------------------------------------------
+
+void SvxAuthorField::Save( SvPersistStream & rStm )
+{
+ // UNICODE: rStm << aName;
+ rStm.WriteByteString(aName);
+
+ // UNICODE: rStm << aFirstName;
+ rStm.WriteByteString(aFirstName);
+
+ // UNICODE: rStm << aShortName;
+ rStm.WriteByteString(aShortName);
+
+ rStm << (USHORT) eType;
+ rStm << (USHORT) eFormat;
+}
+
+//----------------------------------------------------------------------------
+
+XubString SvxAuthorField::GetFormatted() const
+{
+ XubString aString;
+
+ switch( eFormat )
+ {
+ case SVXAUTHORFORMAT_FULLNAME:
+ aString = aFirstName;
+ aString += sal_Unicode(' ');
+ aString += aName;
+ break;
+
+ case SVXAUTHORFORMAT_NAME:
+ aString = aName;
+ break;
+
+ case SVXAUTHORFORMAT_FIRSTNAME:
+ aString = aFirstName;
+ break;
+
+ case SVXAUTHORFORMAT_SHORTNAME:
+ aString = aShortName;
+ break;
+ }
+
+ return( aString );
+}
+
+static SvClassManager* pClassMgr=0;
+
+SvClassManager& SvxFieldItem::GetClassManager()
+{
+ if ( !pClassMgr )
+ {
+ pClassMgr = new SvClassManager;
+ pClassMgr->SV_CLASS_REGISTER( SvxFieldData );
+ pClassMgr->SV_CLASS_REGISTER( SvxURLField );
+ pClassMgr->SV_CLASS_REGISTER( SvxDateField );
+ pClassMgr->SV_CLASS_REGISTER( SvxPageField );
+ pClassMgr->SV_CLASS_REGISTER( SvxTimeField );
+ pClassMgr->SV_CLASS_REGISTER( SvxExtTimeField );
+ pClassMgr->SV_CLASS_REGISTER( SvxExtFileField );
+ pClassMgr->SV_CLASS_REGISTER( SvxAuthorField );
+ }
+
+ return *pClassMgr;
+}
+
+///////////////////////////////////////////////////////////////////////
+
+SV_IMPL_PERSIST1( SvxHeaderField, SvxFieldData );
+
+SvxFieldData* __EXPORT SvxHeaderField::Clone() const
+{
+ return new SvxHeaderField; // leer
+}
+
+int __EXPORT SvxHeaderField::operator==( const SvxFieldData& rCmp ) const
+{
+ return ( rCmp.Type() == TYPE(SvxHeaderField) );
+}
+
+void __EXPORT SvxHeaderField::Load( SvPersistStream & /*rStm*/ )
+{
+}
+
+void __EXPORT SvxHeaderField::Save( SvPersistStream & /*rStm*/ )
+{
+}
+
+///////////////////////////////////////////////////////////////////////
+
+SV_IMPL_PERSIST1( SvxFooterField, SvxFieldData );
+
+SvxFieldData* __EXPORT SvxFooterField::Clone() const
+{
+ return new SvxFooterField; // leer
+}
+
+int __EXPORT SvxFooterField::operator==( const SvxFieldData& rCmp ) const
+{
+ return ( rCmp.Type() == TYPE(SvxFooterField) );
+}
+
+void __EXPORT SvxFooterField::Load( SvPersistStream & /*rStm*/ )
+{
+}
+
+void __EXPORT SvxFooterField::Save( SvPersistStream & /*rStm*/ )
+{
+}
+
+///////////////////////////////////////////////////////////////////////
+
+SV_IMPL_PERSIST1( SvxDateTimeField, SvxFieldData );
+
+SvxFieldData* __EXPORT SvxDateTimeField::Clone() const
+{
+ return new SvxDateTimeField; // leer
+}
+
+int __EXPORT SvxDateTimeField::operator==( const SvxFieldData& rCmp ) const
+{
+ return ( rCmp.Type() == TYPE(SvxDateTimeField) );
+}
+
+void __EXPORT SvxDateTimeField::Load( SvPersistStream & /*rStm*/ )
+{
+}
+
+void __EXPORT SvxDateTimeField::Save( SvPersistStream & /*rStm*/ )
+{
+}
+
+String SvxDateTimeField::GetFormatted( Date& rDate, Time& rTime, int eFormat, SvNumberFormatter& rFormatter, LanguageType eLanguage )
+{
+ String aRet;
+
+ SvxDateFormat eDateFormat = (SvxDateFormat)(eFormat & 0x0f);
+
+ if(eDateFormat)
+ {
+ aRet = SvxDateField::GetFormatted( rDate, eDateFormat, rFormatter, eLanguage );
+ }
+
+ SvxTimeFormat eTimeFormat = (SvxTimeFormat)((eFormat >> 4) & 0x0f);
+
+ if(eTimeFormat)
+ {
+ if(aRet.Len())
+ aRet += sal_Unicode(' ');
+
+ aRet += SvxExtTimeField::GetFormatted( rTime, eTimeFormat, rFormatter, eLanguage );
+ }
+
+ return aRet;
+}
+
diff --git a/editeng/source/items/frmitems.cxx b/editeng/source/items/frmitems.cxx
new file mode 100644
index 0000000000..7ccb6860ab
--- /dev/null
+++ b/editeng/source/items/frmitems.cxx
@@ -0,0 +1,4470 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: frmitems.cxx,v $
+ * $Revision: 1.53 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+// include ---------------------------------------------------------------
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/table/BorderLine.hpp>
+#include <com/sun/star/table/CellVertJustify.hpp>
+#include <com/sun/star/table/ShadowLocation.hpp>
+#include <com/sun/star/table/TableBorder.hpp>
+#include <com/sun/star/table/ShadowFormat.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/CellContentType.hpp>
+#include <com/sun/star/table/TableOrientation.hpp>
+#include <com/sun/star/table/CellHoriJustify.hpp>
+#include <com/sun/star/util/SortField.hpp>
+#include <com/sun/star/util/SortFieldType.hpp>
+#include <com/sun/star/table/CellOrientation.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/style/PageStyleLayout.hpp>
+#include <com/sun/star/style/BreakType.hpp>
+#include <com/sun/star/style/GraphicLocation.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/awt/Selection.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/text/WritingMode2.hpp>
+#include <com/sun/star/frame/status/UpperLowerMarginScale.hpp>
+
+#include <unotools/ucbstreamhelper.hxx>
+#include <limits.h>
+#include <comphelper/processfactory.hxx>
+#include <svtools/grfmgr.hxx>
+#include <tools/urlobj.hxx>
+#include <comphelper/types.hxx>
+#include <svl/memberid.hrc>
+#include <svtools/wallitem.hxx>
+#include <svl/cntwall.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <svtools/filter.hxx>
+
+#define GLOBALOVERFLOW3
+
+#define _SVX_FRMITEMS_CXX
+
+#include <editeng/editids.hrc>
+#include <editeng/editrids.hrc>
+#include <editeng/pbinitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/prntitem.hxx>
+#include <editeng/opaqitem.hxx>
+#include <editeng/protitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brkitem.hxx>
+#include <editeng/keepitem.hxx>
+#include <editeng/bolnitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/itemtype.hxx>
+#include <editeng/eerdll.hxx>
+#include <editeng/unoprnms.hxx>
+#include <editeng/memberids.hrc>
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+
+
+// Konvertierung fuer UNO
+#define TWIP_TO_MM100(TWIP) ((TWIP) >= 0 ? (((TWIP)*127L+36L)/72L) : (((TWIP)*127L-36L)/72L))
+#define MM100_TO_TWIP(MM100) ((MM100) >= 0 ? (((MM100)*72L+63L)/127L) : (((MM100)*72L-63L)/127L))
+#define TWIP_TO_MM100_UNSIGNED(TWIP) ((((TWIP)*127L+36L)/72L))
+#define MM100_TO_TWIP_UNSIGNED(MM100) ((((MM100)*72L+63L)/127L))
+
+// STATIC DATA -----------------------------------------------------------
+
+
+inline void SetValueProp( XubString& rStr, const sal_uInt16 nValue,
+ const sal_uInt16 nProp )
+{
+ if( 100 == nProp )
+ rStr += String::CreateFromInt32( nValue );
+ else
+ ( rStr += String::CreateFromInt32( nProp )) += sal_Unicode('%');
+}
+
+inline void SetValueProp( XubString& rStr, const short nValue,
+ const sal_uInt16 nProp )
+{
+ if( 100 == nProp )
+ rStr += String::CreateFromInt32( nValue );
+ else
+ ( rStr += String::CreateFromInt32( nProp )) += sal_Unicode('%');
+}
+
+// -----------------------------------------------------------------------
+
+TYPEINIT1_FACTORY(SvxPaperBinItem, SfxByteItem, new SvxPaperBinItem(0));
+TYPEINIT1_FACTORY(SvxSizeItem, SfxPoolItem, new SvxSizeItem(0));
+TYPEINIT1_FACTORY(SvxLRSpaceItem, SfxPoolItem, new SvxLRSpaceItem(0));
+TYPEINIT1_FACTORY(SvxULSpaceItem, SfxPoolItem, new SvxULSpaceItem(0));
+TYPEINIT1_FACTORY(SvxPrintItem, SfxBoolItem, new SvxPrintItem(0));
+TYPEINIT1_FACTORY(SvxOpaqueItem, SfxBoolItem, new SvxOpaqueItem(0));
+TYPEINIT1_FACTORY(SvxProtectItem, SfxPoolItem, new SvxProtectItem(0));
+TYPEINIT1_FACTORY(SvxBrushItem, SfxPoolItem, new SvxBrushItem(0));
+TYPEINIT1_FACTORY(SvxShadowItem, SfxPoolItem, new SvxShadowItem(0));
+TYPEINIT1_FACTORY(SvxBoxItem, SfxPoolItem, new SvxBoxItem(0));
+TYPEINIT1_FACTORY(SvxBoxInfoItem, SfxPoolItem, new SvxBoxInfoItem(0));
+TYPEINIT1_FACTORY(SvxFmtBreakItem, SfxEnumItem, new SvxFmtBreakItem(SVX_BREAK_NONE, 0));
+TYPEINIT1_FACTORY(SvxFmtKeepItem, SfxBoolItem, new SvxFmtKeepItem(sal_False, 0));
+TYPEINIT1_FACTORY(SvxLineItem, SfxPoolItem, new SvxLineItem(0));
+TYPEINIT1_FACTORY(SvxFrameDirectionItem, SfxUInt16Item, new SvxFrameDirectionItem(FRMDIR_HORI_LEFT_TOP, 0));
+
+
+// class SvxPaperBinItem ------------------------------------------------
+
+SfxPoolItem* SvxPaperBinItem::Clone( SfxItemPool* ) const
+{
+ return new SvxPaperBinItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxPaperBinItem::Store( SvStream& rStrm , sal_uInt16 /*nItemVersion*/ ) const
+{
+ rStrm << GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxPaperBinItem::Create( SvStream& rStrm, sal_uInt16 ) const
+{
+ sal_Int8 nBin;
+ rStrm >> nBin;
+ return new SvxPaperBinItem( Which(), nBin );
+}
+
+// -----------------------------------------------------------------------
+
+SfxItemPresentation SvxPaperBinItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return SFX_ITEM_PRESENTATION_NONE;
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ rText = String::CreateFromInt32( GetValue() );
+ return SFX_ITEM_PRESENTATION_NAMELESS;
+
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ BYTE nValue = GetValue();
+
+ if ( PAPERBIN_PRINTER_SETTINGS == nValue )
+ rText = EE_RESSTR(RID_SVXSTR_PAPERBIN_SETTINGS);
+ else
+ {
+ rText = EE_RESSTR(RID_SVXSTR_PAPERBIN);
+ rText += sal_Unicode(' ');
+ rText += String::CreateFromInt32( nValue );
+ }
+ return SFX_ITEM_PRESENTATION_COMPLETE;
+ }
+ //no break necessary
+ default: ;//prevent warning
+ }
+
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// class SvxSizeItem -----------------------------------------------------
+
+SvxSizeItem::SvxSizeItem( const sal_uInt16 nId, const Size& rSize ) :
+
+ SfxPoolItem( nId ),
+
+ aSize( rSize )
+{
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SvxSizeItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+ sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+
+ awt::Size aTmp(aSize.Width(), aSize.Height());
+ if( bConvert )
+ {
+ aTmp.Height = TWIP_TO_MM100(aTmp.Height);
+ aTmp.Width = TWIP_TO_MM100(aTmp.Width);
+ }
+
+ switch( nMemberId )
+ {
+ case MID_SIZE_SIZE: rVal <<= aTmp; break;
+ case MID_SIZE_WIDTH: rVal <<= aTmp.Width; break;
+ case MID_SIZE_HEIGHT: rVal <<= aTmp.Height; break;
+ default: DBG_ERROR("Wrong MemberId!"); return sal_False;
+ }
+
+ return sal_True;
+}
+// -----------------------------------------------------------------------
+sal_Bool SvxSizeItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+ sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+
+ switch( nMemberId )
+ {
+ case MID_SIZE_SIZE:
+ {
+ awt::Size aTmp;
+ if( rVal >>= aTmp )
+ {
+ if(bConvert)
+ {
+ aTmp.Height = MM100_TO_TWIP(aTmp.Height);
+ aTmp.Width = MM100_TO_TWIP(aTmp.Width);
+ }
+ aSize = Size( aTmp.Width, aTmp.Height );
+ }
+ else
+ {
+ return sal_False;
+ }
+ }
+ break;
+ case MID_SIZE_WIDTH:
+ {
+ sal_Int32 nVal = 0;
+ if(!(rVal >>= nVal ))
+ return sal_False;
+
+ aSize.Width() = bConvert ? MM100_TO_TWIP(nVal) : nVal;
+ }
+ break;
+ case MID_SIZE_HEIGHT:
+ {
+ sal_Int32 nVal = 0;
+ if(!(rVal >>= nVal))
+ return sal_True;
+
+ aSize.Height() = bConvert ? MM100_TO_TWIP(nVal) : nVal;
+ }
+ break;
+ default: DBG_ERROR("Wrong MemberId!");
+ return sal_False;
+ }
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+SvxSizeItem::SvxSizeItem( const sal_uInt16 nId ) :
+
+ SfxPoolItem( nId )
+{
+}
+
+// -----------------------------------------------------------------------
+
+int SvxSizeItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ return ( aSize == ( (SvxSizeItem&)rAttr ).GetSize() );
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxSizeItem::Clone( SfxItemPool* ) const
+{
+ return new SvxSizeItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxSizeItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit eCoreUnit,
+ SfxMapUnit ePresUnit,
+ XubString& rText, const IntlWrapper *pIntl
+) const
+{
+#ifndef SVX_LIGHT
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return SFX_ITEM_PRESENTATION_NONE;
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ rText = GetMetricText( aSize.Width(), eCoreUnit, ePresUnit, pIntl );
+ rText += cpDelim;
+ rText += GetMetricText( aSize.Height(), eCoreUnit, ePresUnit, pIntl );
+ return SFX_ITEM_PRESENTATION_NAMELESS;
+
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = EE_RESSTR(RID_SVXITEMS_SIZE_WIDTH);
+ rText += GetMetricText( aSize.Width(), eCoreUnit, ePresUnit, pIntl );
+ rText += EE_RESSTR(GetMetricId(ePresUnit));
+ rText += cpDelim;
+ rText += EE_RESSTR(RID_SVXITEMS_SIZE_HEIGHT);
+ rText += GetMetricText( aSize.Height(), eCoreUnit, ePresUnit, pIntl );
+ rText += EE_RESSTR(GetMetricId(ePresUnit));
+ return SFX_ITEM_PRESENTATION_COMPLETE;
+ //no break necessary
+ default: ;//prevent warning
+
+ }
+#endif // !SVX_LIGHT
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxSizeItem::Store( SvStream& rStrm , sal_uInt16 /*nItemVersion*/ ) const
+{
+ rStrm << aSize.Width();
+ rStrm << aSize.Height();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxSizeItem::ScaleMetrics( long nMult, long nDiv )
+{
+ aSize.Width() = Scale( aSize.Width(), nMult, nDiv );
+ aSize.Height() = Scale( aSize.Height(), nMult, nDiv );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxSizeItem::HasMetrics() const
+{
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+
+SfxPoolItem* SvxSizeItem::Create( SvStream& rStrm, sal_uInt16 ) const
+{
+ long nWidth, nHeight;
+ rStrm >> nWidth >> nHeight;
+
+ SvxSizeItem* pAttr = new SvxSizeItem( Which() );
+ pAttr->SetSize(Size(nWidth, nHeight));
+
+ return pAttr;
+}
+
+// class SvxLRSpaceItem --------------------------------------------------
+
+SvxLRSpaceItem::SvxLRSpaceItem( const sal_uInt16 nId ) :
+
+ SfxPoolItem( nId ),
+
+ nFirstLineOfst ( 0 ),
+ nTxtLeft ( 0 ),
+ nLeftMargin ( 0 ),
+ nRightMargin ( 0 ),
+ nPropFirstLineOfst( 100 ),
+ nPropLeftMargin( 100 ),
+ nPropRightMargin( 100 ),
+ bAutoFirst ( 0 )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvxLRSpaceItem::SvxLRSpaceItem( const long nLeft, const long nRight,
+ const long nTLeft, const short nOfset,
+ const sal_uInt16 nId ) :
+
+ SfxPoolItem( nId ),
+
+ nFirstLineOfst ( nOfset ),
+ nTxtLeft ( nTLeft ),
+ nLeftMargin ( nLeft ),
+ nRightMargin ( nRight ),
+ nPropFirstLineOfst( 100 ),
+ nPropLeftMargin( 100 ),
+ nPropRightMargin( 100 ),
+ bAutoFirst ( 0 )
+{
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SvxLRSpaceItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+ sal_Bool bRet = sal_True;
+ sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch( nMemberId )
+ {
+ // jetzt alles signed
+ case MID_L_MARGIN:
+ rVal <<= (sal_Int32)(bConvert ? TWIP_TO_MM100(nLeftMargin) : nLeftMargin);
+ break;
+
+ case MID_TXT_LMARGIN :
+ rVal <<= (sal_Int32)(bConvert ? TWIP_TO_MM100(nTxtLeft) : nTxtLeft);
+ break;
+ case MID_R_MARGIN:
+ rVal <<= (sal_Int32)(bConvert ? TWIP_TO_MM100(nRightMargin) : nRightMargin);
+ break;
+ case MID_L_REL_MARGIN:
+ rVal <<= (sal_Int16)nPropLeftMargin;
+ break;
+ case MID_R_REL_MARGIN:
+ rVal <<= (sal_Int16)nPropRightMargin;
+ break;
+
+ case MID_FIRST_LINE_INDENT:
+ rVal <<= (sal_Int32)(bConvert ? TWIP_TO_MM100(nFirstLineOfst) : nFirstLineOfst);
+ break;
+
+ case MID_FIRST_LINE_REL_INDENT:
+ rVal <<= (sal_Int16)(nPropFirstLineOfst);
+ break;
+
+ case MID_FIRST_AUTO:
+ rVal = Bool2Any(IsAutoFirst());
+ break;
+
+ default:
+ bRet = sal_False;
+ DBG_ERROR("unknown MemberId");
+ }
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SvxLRSpaceItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+ sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ sal_Int32 nVal = 0;
+ if( nMemberId != MID_FIRST_AUTO &&
+ nMemberId != MID_L_REL_MARGIN && nMemberId != MID_R_REL_MARGIN)
+ if(!(rVal >>= nVal))
+ return sal_False;
+
+ switch( nMemberId )
+ {
+ case MID_L_MARGIN:
+ SetLeft((sal_Int32)bConvert ? MM100_TO_TWIP(nVal) : nVal);
+ break;
+
+ case MID_TXT_LMARGIN :
+ SetTxtLeft((sal_Int32)bConvert ? MM100_TO_TWIP(nVal) : nVal);
+ break;
+
+ case MID_R_MARGIN:
+ SetRight((sal_Int32) bConvert ? MM100_TO_TWIP(nVal) : nVal);
+ break;
+ case MID_L_REL_MARGIN:
+ case MID_R_REL_MARGIN:
+ {
+ sal_Int32 nRel = 0;
+ if((rVal >>= nRel) && nRel >= 0 && nRel < USHRT_MAX)
+ {
+ if(MID_L_REL_MARGIN== nMemberId)
+ nPropLeftMargin = (USHORT)nRel;
+ else
+ nPropRightMargin = (USHORT)nRel;
+ }
+ else
+ return FALSE;
+ }
+ break;
+ case MID_FIRST_LINE_INDENT :
+ SetTxtFirstLineOfst((short)(bConvert ? MM100_TO_TWIP(nVal) : nVal));
+ break;
+
+ case MID_FIRST_LINE_REL_INDENT:
+ SetPropTxtFirstLineOfst ( (USHORT)nVal );
+ break;
+
+ case MID_FIRST_AUTO:
+ SetAutoFirst( Any2Bool(rVal) );
+ break;
+
+ default:
+ DBG_ERROR("unknown MemberId");
+ return sal_False;
+ }
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+// nLeftMargin und nTxtLeft anpassen.
+
+void SvxLRSpaceItem::AdjustLeft()
+{
+ if ( 0 > nFirstLineOfst )
+ nLeftMargin = nTxtLeft + nFirstLineOfst;
+ else
+ nLeftMargin = nTxtLeft;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxLRSpaceItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ return (
+ nLeftMargin == ((SvxLRSpaceItem&)rAttr).GetLeft() &&
+ nRightMargin == ((SvxLRSpaceItem&)rAttr).GetRight() &&
+ nFirstLineOfst == ((SvxLRSpaceItem&)rAttr).GetTxtFirstLineOfst() &&
+ nPropLeftMargin == ((SvxLRSpaceItem&)rAttr).GetPropLeft() &&
+ nPropRightMargin == ((SvxLRSpaceItem&)rAttr).GetPropRight() &&
+ nPropFirstLineOfst == ((SvxLRSpaceItem&)rAttr).GetPropTxtFirstLineOfst() &&
+ bAutoFirst == ((SvxLRSpaceItem&)rAttr).IsAutoFirst() );
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxLRSpaceItem::Clone( SfxItemPool* ) const
+{
+ return new SvxLRSpaceItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxLRSpaceItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit eCoreUnit,
+ SfxMapUnit ePresUnit,
+ XubString& rText, const IntlWrapper* pIntl
+) const
+{
+#ifndef SVX_LIGHT
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return SFX_ITEM_PRESENTATION_NONE;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ {
+ if ( 100 != nPropLeftMargin )
+ ( rText = String::CreateFromInt32( nPropLeftMargin )) += sal_Unicode('%');
+ else
+ rText = GetMetricText( (long)nLeftMargin,
+ eCoreUnit, ePresUnit, pIntl );
+ rText += cpDelim;
+ if ( 100 != nPropFirstLineOfst )
+ ( rText += String::CreateFromInt32( nPropFirstLineOfst )) += sal_Unicode('%');
+ else
+ rText += GetMetricText( (long)nFirstLineOfst,
+ eCoreUnit, ePresUnit, pIntl );
+ rText += cpDelim;
+ if ( 100 != nRightMargin )
+ ( rText += String::CreateFromInt32( nRightMargin )) += sal_Unicode('%');
+ else
+ rText += GetMetricText( (long)nRightMargin,
+ eCoreUnit, ePresUnit, pIntl );
+ return SFX_ITEM_PRESENTATION_NAMELESS;
+ }
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ rText = EE_RESSTR(RID_SVXITEMS_LRSPACE_LEFT);
+ if ( 100 != nPropLeftMargin )
+ ( rText += String::CreateFromInt32( nPropLeftMargin )) += sal_Unicode('%');
+ else
+ {
+ rText += GetMetricText( (long)nLeftMargin,
+ eCoreUnit, ePresUnit, pIntl );
+ rText += EE_RESSTR(GetMetricId(ePresUnit));
+ }
+ rText += cpDelim;
+ if ( 100 != nPropFirstLineOfst || nFirstLineOfst )
+ {
+ rText += EE_RESSTR(RID_SVXITEMS_LRSPACE_FLINE);
+ if ( 100 != nPropFirstLineOfst )
+ ( rText += String::CreateFromInt32( nPropFirstLineOfst ))
+ += sal_Unicode('%');
+ else
+ {
+ rText += GetMetricText( (long)nFirstLineOfst,
+ eCoreUnit, ePresUnit, pIntl );
+ rText += EE_RESSTR(GetMetricId(ePresUnit));
+ }
+ rText += cpDelim;
+ }
+ rText += EE_RESSTR(RID_SVXITEMS_LRSPACE_RIGHT);
+ if ( 100 != nPropRightMargin )
+ ( rText += String::CreateFromInt32( nPropRightMargin )) += sal_Unicode('%');
+ else
+ {
+ rText += GetMetricText( (long)nRightMargin,
+ eCoreUnit, ePresUnit, pIntl );
+ rText += EE_RESSTR(GetMetricId(ePresUnit));
+ }
+ return SFX_ITEM_PRESENTATION_COMPLETE;
+ }
+ default: ;//prevent warning
+ }
+#endif // !SVX_LIGHT
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+// MT: BulletFI: Vor 501 wurde im Outliner das Bullet nicht auf der Position des
+// FI positioniert, deshalb muss in aelteren Dokumenten der FI auf 0 stehen.
+
+#define BULLETLR_MARKER 0x599401FE
+
+SvStream& SvxLRSpaceItem::Store( SvStream& rStrm , sal_uInt16 nItemVersion ) const
+{
+ short nSaveFI = nFirstLineOfst;
+ ((SvxLRSpaceItem*)this)->SetTxtFirstLineOfst( 0 ); // nLeftMargin wird mitmanipuliert, siehe Create()
+
+ sal_uInt16 nMargin = 0;
+ if( nLeftMargin > 0 )
+ nMargin = sal_uInt16( nLeftMargin );
+ rStrm << nMargin;
+ rStrm << nPropLeftMargin;
+ if( nRightMargin > 0 )
+ nMargin = sal_uInt16( nRightMargin );
+ else
+ nMargin = 0;
+ rStrm << nMargin;
+ rStrm << nPropRightMargin;
+ rStrm << nFirstLineOfst;
+ rStrm << nPropFirstLineOfst;
+ if( nTxtLeft > 0 )
+ nMargin = sal_uInt16( nTxtLeft );
+ else
+ nMargin = 0;
+ rStrm << nMargin;
+ if( nItemVersion >= LRSPACE_AUTOFIRST_VERSION )
+ {
+ sal_Int8 nAutoFirst = bAutoFirst ? 1 : 0;
+ if( nItemVersion >= LRSPACE_NEGATIVE_VERSION &&
+ ( nLeftMargin < 0 || nRightMargin < 0 || nTxtLeft < 0 ) )
+ nAutoFirst |= 0x80;
+ rStrm << nAutoFirst;
+
+ // Ab 6.0 keine Magicnumber schreiben...
+ DBG_ASSERT( rStrm.GetVersion() <= SOFFICE_FILEFORMAT_50, "MT: Fileformat SvxLRSpaceItem aendern!" );
+ rStrm << (sal_uInt32) BULLETLR_MARKER;
+ rStrm << nSaveFI;
+
+ if( 0x80 & nAutoFirst )
+ {
+ rStrm << nLeftMargin;
+ rStrm << nRightMargin;
+ }
+ }
+
+ ((SvxLRSpaceItem*)this)->SetTxtFirstLineOfst( nSaveFI );
+
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxLRSpaceItem::Create( SvStream& rStrm, sal_uInt16 nVersion ) const
+{
+ sal_uInt16 left, prpleft, right, prpright, prpfirstline, txtleft;
+ short firstline;
+ sal_Int8 autofirst = 0;
+
+ if ( nVersion >= LRSPACE_AUTOFIRST_VERSION )
+ {
+ rStrm >> left >> prpleft >> right >> prpright >> firstline >>
+ prpfirstline >> txtleft >> autofirst;
+
+ sal_uInt32 nPos = rStrm.Tell();
+ sal_uInt32 nMarker;
+ rStrm >> nMarker;
+ if ( nMarker == BULLETLR_MARKER )
+ {
+ rStrm >> firstline;
+ if ( firstline < 0 )
+ left = left + static_cast<sal_uInt16>(firstline); // s.u.: txtleft = ...
+ }
+ else
+ rStrm.Seek( nPos );
+ }
+ else if ( nVersion == LRSPACE_TXTLEFT_VERSION )
+ {
+ rStrm >> left >> prpleft >> right >> prpright >> firstline >>
+ prpfirstline >> txtleft;
+ }
+ else if ( nVersion == LRSPACE_16_VERSION )
+ {
+ rStrm >> left >> prpleft >> right >> prpright >> firstline >>
+ prpfirstline;
+ }
+ else
+ {
+ sal_Int8 nL, nR, nFL;
+ rStrm >> left >> nL >> right >> nR >> firstline >> nFL;
+ prpleft = (sal_uInt16)nL;
+ prpright = (sal_uInt16)nR;
+ prpfirstline = (sal_uInt16)nFL;
+ }
+
+ txtleft = firstline >= 0 ? left : left - firstline;
+ SvxLRSpaceItem* pAttr = new SvxLRSpaceItem( Which() );
+
+ pAttr->nLeftMargin = left;
+ pAttr->nPropLeftMargin = prpleft;
+ pAttr->nRightMargin = right;
+ pAttr->nPropRightMargin = prpright;
+ pAttr->nFirstLineOfst = firstline;
+ pAttr->nPropFirstLineOfst = prpfirstline;
+ pAttr->nTxtLeft = txtleft;
+ pAttr->bAutoFirst = autofirst & 0x01;
+ if( nVersion >= LRSPACE_NEGATIVE_VERSION && ( autofirst & 0x80 ) )
+ {
+ sal_Int32 nMargin;
+ rStrm >> nMargin;
+ pAttr->nLeftMargin = nMargin;
+ pAttr->nTxtLeft = firstline >= 0 ? nMargin : nMargin - firstline;
+ rStrm >> nMargin;
+ pAttr->nRightMargin = nMargin;
+ }
+ return pAttr;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxLRSpaceItem::GetVersion( sal_uInt16 nFileVersion ) const
+{
+ return (nFileVersion == SOFFICE_FILEFORMAT_31)
+ ? LRSPACE_TXTLEFT_VERSION
+ : LRSPACE_NEGATIVE_VERSION;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxLRSpaceItem::ScaleMetrics( long nMult, long nDiv )
+{
+ nFirstLineOfst = (short)Scale( nFirstLineOfst, nMult, nDiv );
+ nTxtLeft = Scale( nTxtLeft, nMult, nDiv );
+ nLeftMargin = Scale( nLeftMargin, nMult, nDiv );
+ nRightMargin = Scale( nRightMargin, nMult, nDiv );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxLRSpaceItem::HasMetrics() const
+{
+ return 1;
+}
+
+// class SvxULSpaceItem --------------------------------------------------
+
+SvxULSpaceItem::SvxULSpaceItem( const sal_uInt16 nId ) :
+
+ SfxPoolItem( nId ),
+
+ nUpper( 0 ),
+ nLower( 0 ),
+ nPropUpper( 100 ),
+ nPropLower( 100 )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvxULSpaceItem::SvxULSpaceItem( const sal_uInt16 nUp, const sal_uInt16 nLow,
+ const sal_uInt16 nId ) :
+
+ SfxPoolItem( nId ),
+
+ nUpper( nUp ),
+ nLower( nLow ),
+ nPropUpper( 100 ),
+ nPropLower( 100 )
+{
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SvxULSpaceItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+ sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch( nMemberId )
+ {
+ // jetzt alles signed
+ case 0:
+ {
+ ::com::sun::star::frame::status::UpperLowerMarginScale aUpperLowerMarginScale;
+ aUpperLowerMarginScale.Upper = (sal_Int32)(bConvert ? TWIP_TO_MM100_UNSIGNED(nUpper) : nUpper);
+ aUpperLowerMarginScale.Lower = (sal_Int32)(bConvert ? TWIP_TO_MM100_UNSIGNED(nLower) : nPropUpper);
+ aUpperLowerMarginScale.ScaleUpper = (sal_Int16)nPropUpper;
+ aUpperLowerMarginScale.ScaleLower = (sal_Int16)nPropLower;
+ rVal <<= aUpperLowerMarginScale;
+ break;
+ }
+ case MID_UP_MARGIN: rVal <<= (sal_Int32)(bConvert ? TWIP_TO_MM100_UNSIGNED(nUpper) : nUpper); break;
+ case MID_LO_MARGIN: rVal <<= (sal_Int32)(bConvert ? TWIP_TO_MM100_UNSIGNED(nLower) : nLower); break;
+ case MID_UP_REL_MARGIN: rVal <<= (sal_Int16) nPropUpper; break;
+ case MID_LO_REL_MARGIN: rVal <<= (sal_Int16) nPropLower; break;
+ }
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SvxULSpaceItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+ sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ sal_Int32 nVal = 0;
+ switch( nMemberId )
+ {
+ case 0:
+ {
+ ::com::sun::star::frame::status::UpperLowerMarginScale aUpperLowerMarginScale;
+ if ( !(rVal >>= aUpperLowerMarginScale ))
+ return sal_False;
+ {
+ SetUpper((sal_uInt16)(bConvert ? MM100_TO_TWIP( aUpperLowerMarginScale.Upper ) : aUpperLowerMarginScale.Upper));
+ SetLower((sal_uInt16)(bConvert ? MM100_TO_TWIP( aUpperLowerMarginScale.Lower ) : aUpperLowerMarginScale.Lower));
+ if( aUpperLowerMarginScale.ScaleUpper > 1 )
+ nPropUpper = aUpperLowerMarginScale.ScaleUpper;
+ if( aUpperLowerMarginScale.ScaleLower > 1 )
+ nPropUpper = aUpperLowerMarginScale.ScaleLower;
+ }
+ }
+
+ case MID_UP_MARGIN :
+ if(!(rVal >>= nVal) || nVal < 0)
+ return sal_False;
+ SetUpper((USHORT)(bConvert ? MM100_TO_TWIP(nVal) : nVal));
+ break;
+ case MID_LO_MARGIN :
+ if(!(rVal >>= nVal) || nVal < 0)
+ return sal_False;
+ SetLower((USHORT)(bConvert ? MM100_TO_TWIP(nVal) : nVal));
+ break;
+ case MID_UP_REL_MARGIN:
+ case MID_LO_REL_MARGIN:
+ {
+ sal_Int32 nRel = 0;
+ if((rVal >>= nRel) && nRel > 1 )
+ {
+ if(MID_UP_REL_MARGIN == nMemberId)
+ nPropUpper = (USHORT)nRel;
+ else
+ nPropLower = (USHORT)nRel;
+ }
+ else
+ return FALSE;
+ }
+ break;
+
+
+ default:
+ DBG_ERROR("unknown MemberId");
+ return sal_False;
+ }
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxULSpaceItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ return ( nUpper == ( (SvxULSpaceItem&)rAttr ).nUpper &&
+ nLower == ( (SvxULSpaceItem&)rAttr ).nLower &&
+ nPropUpper == ( (SvxULSpaceItem&)rAttr ).nPropUpper &&
+ nPropLower == ( (SvxULSpaceItem&)rAttr ).nPropLower );
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxULSpaceItem::Clone( SfxItemPool* ) const
+{
+ return new SvxULSpaceItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxULSpaceItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit eCoreUnit,
+ SfxMapUnit ePresUnit,
+ XubString& rText, const IntlWrapper *pIntl
+) const
+{
+#ifndef SVX_LIGHT
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return SFX_ITEM_PRESENTATION_NONE;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ {
+ if ( 100 != nPropUpper )
+ ( rText = String::CreateFromInt32( nPropUpper )) += sal_Unicode('%');
+ else
+ rText = GetMetricText( (long)nUpper, eCoreUnit, ePresUnit, pIntl );
+ rText += cpDelim;
+ if ( 100 != nPropLower )
+ ( rText += String::CreateFromInt32( nPropLower )) += sal_Unicode('%');
+ else
+ rText += GetMetricText( (long)nLower, eCoreUnit, ePresUnit, pIntl );
+ return SFX_ITEM_PRESENTATION_NAMELESS;
+ }
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ rText = EE_RESSTR(RID_SVXITEMS_ULSPACE_UPPER);
+ if ( 100 != nPropUpper )
+ ( rText += String::CreateFromInt32( nPropUpper )) += sal_Unicode('%');
+ else
+ {
+ rText += GetMetricText( (long)nUpper, eCoreUnit, ePresUnit, pIntl );
+ rText += EE_RESSTR(GetMetricId(ePresUnit));
+ }
+ rText += cpDelim;
+ rText += EE_RESSTR(RID_SVXITEMS_ULSPACE_LOWER);
+ if ( 100 != nPropLower )
+ ( rText += String::CreateFromInt32( nPropLower )) += sal_Unicode('%');
+ else
+ {
+ rText += GetMetricText( (long)nLower, eCoreUnit, ePresUnit, pIntl );
+ rText += EE_RESSTR(GetMetricId(ePresUnit));
+ }
+ return SFX_ITEM_PRESENTATION_COMPLETE;
+ }
+ default: ;//prevent warning
+ }
+#endif
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxULSpaceItem::Store( SvStream& rStrm , sal_uInt16 /*nItemVersion*/ ) const
+{
+ rStrm << GetUpper()
+ << GetPropUpper()
+ << GetLower()
+ << GetPropLower();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxULSpaceItem::Create( SvStream& rStrm, sal_uInt16 nVersion ) const
+{
+ sal_uInt16 upper, lower, nPL = 0, nPU = 0;
+
+ if ( nVersion == ULSPACE_16_VERSION )
+ rStrm >> upper >> nPU >> lower >> nPL;
+ else
+ {
+ sal_Int8 nU, nL;
+ rStrm >> upper >> nU >> lower >> nL;
+ nPL = (sal_uInt16)nL;
+ nPU = (sal_uInt16)nU;
+ }
+
+ SvxULSpaceItem* pAttr = new SvxULSpaceItem( Which() );
+ pAttr->SetUpperValue( upper );
+ pAttr->SetLowerValue( lower );
+ pAttr->SetPropUpper( nPU );
+ pAttr->SetPropLower( nPL );
+ return pAttr;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxULSpaceItem::GetVersion( sal_uInt16 /*nFileVersion*/ ) const
+{
+ return ULSPACE_16_VERSION;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxULSpaceItem::ScaleMetrics( long nMult, long nDiv )
+{
+ nUpper = (sal_uInt16)Scale( nUpper, nMult, nDiv );
+ nLower = (sal_uInt16)Scale( nLower, nMult, nDiv );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxULSpaceItem::HasMetrics() const
+{
+ return 1;
+}
+
+
+// class SvxPrintItem ----------------------------------------------------
+
+SfxPoolItem* SvxPrintItem::Clone( SfxItemPool* ) const
+{
+ return new SvxPrintItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxPrintItem::Store( SvStream& rStrm , sal_uInt16 /*nItemVersion*/ ) const
+{
+ rStrm << (sal_Int8)GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxPrintItem::Create( SvStream& rStrm, sal_uInt16 ) const
+{
+ sal_Int8 bIsPrint;
+ rStrm >> bIsPrint;
+ return new SvxPrintItem( Which(), sal_Bool( bIsPrint != 0 ) );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxPrintItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *
+) const
+{
+#ifndef SVX_LIGHT
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ sal_uInt16 nId = RID_SVXITEMS_PRINT_FALSE;
+
+ if ( GetValue() )
+ nId = RID_SVXITEMS_PRINT_TRUE;
+ rText = EE_RESSTR(nId);
+ return ePres;
+ }
+ default: ;//prevent warning
+ }
+#endif // !SVX_LIGHT
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// class SvxOpaqueItem ---------------------------------------------------
+
+SfxPoolItem* SvxOpaqueItem::Clone( SfxItemPool* ) const
+{
+ return new SvxOpaqueItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxOpaqueItem::Store( SvStream& rStrm , sal_uInt16 /*nItemVersion*/ ) const
+{
+ rStrm << (sal_Int8)GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxOpaqueItem::Create( SvStream& rStrm, sal_uInt16 ) const
+{
+ sal_Int8 bIsOpaque;
+ rStrm >> bIsOpaque;
+ return new SvxOpaqueItem( Which(), sal_Bool( bIsOpaque != 0 ) );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxOpaqueItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *
+) const
+{
+#ifndef SVX_LIGHT
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ sal_uInt16 nId = RID_SVXITEMS_OPAQUE_FALSE;
+
+ if ( GetValue() )
+ nId = RID_SVXITEMS_OPAQUE_TRUE;
+ rText = EE_RESSTR(nId);
+ return ePres;
+ }
+ default: ;//prevent warning
+ }
+#endif // !SVX_LIGHT
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// class SvxProtectItem --------------------------------------------------
+
+int SvxProtectItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ return ( bCntnt == ( (SvxProtectItem&)rAttr ).bCntnt &&
+ bSize == ( (SvxProtectItem&)rAttr ).bSize &&
+ bPos == ( (SvxProtectItem&)rAttr ).bPos );
+}
+
+/*-----------------16.03.98 12:42-------------------
+--------------------------------------------------*/
+sal_Bool SvxProtectItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ sal_Bool bValue;
+ switch(nMemberId)
+ {
+ case MID_PROTECT_CONTENT : bValue = bCntnt; break;
+ case MID_PROTECT_SIZE : bValue = bSize; break;
+ case MID_PROTECT_POSITION: bValue = bPos; break;
+ default:
+ DBG_ERROR("falsche MemberId");
+ return sal_False;
+ }
+
+ rVal = Bool2Any( bValue );
+ return sal_True;
+}
+/*-----------------16.03.98 12:42-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxProtectItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ sal_Bool bVal( Any2Bool(rVal) );
+ switch(nMemberId)
+ {
+ case MID_PROTECT_CONTENT : bCntnt = bVal; break;
+ case MID_PROTECT_SIZE : bSize = bVal; break;
+ case MID_PROTECT_POSITION: bPos = bVal; break;
+ default:
+ DBG_ERROR("falsche MemberId");
+ return sal_False;
+ }
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxProtectItem::Clone( SfxItemPool* ) const
+{
+ return new SvxProtectItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxProtectItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *
+) const
+{
+#ifndef SVX_LIGHT
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ sal_uInt16 nId = RID_SVXITEMS_PROT_CONTENT_FALSE;
+
+ if ( bCntnt )
+ nId = RID_SVXITEMS_PROT_CONTENT_TRUE;
+ rText = EE_RESSTR(nId);
+ rText += cpDelim;
+ nId = RID_SVXITEMS_PROT_SIZE_FALSE;
+
+ if ( bSize )
+ nId = RID_SVXITEMS_PROT_SIZE_TRUE;
+ rText += EE_RESSTR(nId);
+ rText += cpDelim;
+ nId = RID_SVXITEMS_PROT_POS_FALSE;
+
+ if ( bPos )
+ nId = RID_SVXITEMS_PROT_POS_TRUE;
+ rText += EE_RESSTR(nId);
+ return ePres;
+ }
+ default: ;//prevent warning
+ }
+#endif // !SVX_LIGHT
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxProtectItem::Store( SvStream& rStrm , sal_uInt16 /*nItemVersion*/ ) const
+{
+ sal_Int8 cProt = 0;
+ if( IsPosProtected() ) cProt |= 0x01;
+ if( IsSizeProtected() ) cProt |= 0x02;
+ if( IsCntntProtected() ) cProt |= 0x04;
+ rStrm << (sal_Int8) cProt;
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxProtectItem::Create( SvStream& rStrm, sal_uInt16 ) const
+{
+ sal_Int8 cFlags;
+ rStrm >> cFlags;
+ SvxProtectItem* pAttr = new SvxProtectItem( Which() );
+ pAttr->SetPosProtect( sal_Bool( ( cFlags & 0x01 ) != 0 ) );
+ pAttr->SetSizeProtect( sal_Bool( ( cFlags & 0x02 ) != 0 ) );
+ pAttr->SetCntntProtect( sal_Bool( ( cFlags & 0x04 ) != 0 ) );
+ return pAttr;
+}
+
+// class SvxShadowItem ---------------------------------------------------
+
+SvxShadowItem::SvxShadowItem( const USHORT nId,
+ const Color *pColor, const USHORT nW,
+ const SvxShadowLocation eLoc ) :
+ SfxEnumItemInterface( nId ),
+ aShadowColor(COL_GRAY),
+ nWidth ( nW ),
+ eLocation ( eLoc )
+{
+ if ( pColor )
+ aShadowColor = *pColor;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SvxShadowItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+ sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+
+ table::ShadowFormat aShadow;
+ table::ShadowLocation eSet = table::ShadowLocation_NONE;
+ switch( eLocation )
+ {
+ case SVX_SHADOW_TOPLEFT : eSet = table::ShadowLocation_TOP_LEFT ; break;
+ case SVX_SHADOW_TOPRIGHT : eSet = table::ShadowLocation_TOP_RIGHT ; break;
+ case SVX_SHADOW_BOTTOMLEFT : eSet = table::ShadowLocation_BOTTOM_LEFT ; break;
+ case SVX_SHADOW_BOTTOMRIGHT: eSet = table::ShadowLocation_BOTTOM_RIGHT; break;
+ default: ;//prevent warning
+ }
+ aShadow.Location = eSet;
+ aShadow.ShadowWidth = bConvert ? TWIP_TO_MM100_UNSIGNED(nWidth) : nWidth;
+ aShadow.IsTransparent = aShadowColor.GetTransparency() > 0;
+ aShadow.Color = aShadowColor.GetRGBColor();
+
+ switch ( nMemberId )
+ {
+ case MID_LOCATION: rVal <<= aShadow.Location; break;
+ case MID_WIDTH: rVal <<= aShadow.ShadowWidth; break;
+ case MID_TRANSPARENT: rVal <<= aShadow.IsTransparent; break;
+ case MID_BG_COLOR: rVal <<= aShadow.Color; break;
+ case 0: rVal <<= aShadow; break;
+ default: DBG_ERROR("Wrong MemberId!"); return sal_False;
+ }
+
+ return sal_True;
+}
+// -----------------------------------------------------------------------
+sal_Bool SvxShadowItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+ sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+
+ table::ShadowFormat aShadow;
+ uno::Any aAny;
+ sal_Bool bRet = QueryValue( aAny, bConvert ? CONVERT_TWIPS : 0 ) && ( aAny >>= aShadow );
+ switch ( nMemberId )
+ {
+ case MID_LOCATION:
+ {
+ bRet = (rVal >>= aShadow.Location);
+ if ( !bRet )
+ {
+ sal_Int16 nVal = 0;
+ bRet = (rVal >>= nVal);
+ aShadow.Location = (table::ShadowLocation) nVal;
+ }
+
+ break;
+ }
+
+ case MID_WIDTH: rVal >>= aShadow.ShadowWidth; break;
+ case MID_TRANSPARENT: rVal >>= aShadow.IsTransparent; break;
+ case MID_BG_COLOR: rVal >>= aShadow.Color; break;
+ case 0: rVal >>= aShadow; break;
+ default: DBG_ERROR("Wrong MemberId!"); return sal_False;
+ }
+
+ if ( bRet )
+ {
+// SvxShadowLocation eSet = SVX_SHADOW_NONE;
+ switch( aShadow.Location )
+ {
+ case table::ShadowLocation_TOP_LEFT : eLocation = SVX_SHADOW_TOPLEFT; break;
+ case table::ShadowLocation_TOP_RIGHT : eLocation = SVX_SHADOW_TOPRIGHT; break;
+ case table::ShadowLocation_BOTTOM_LEFT : eLocation = SVX_SHADOW_BOTTOMLEFT ; break;
+ case table::ShadowLocation_BOTTOM_RIGHT: eLocation = SVX_SHADOW_BOTTOMRIGHT; break;
+ default: ;//prevent warning
+ }
+
+ nWidth = bConvert ? MM100_TO_TWIP(aShadow.ShadowWidth) : aShadow.ShadowWidth;
+ Color aSet(aShadow.Color);
+ aSet.SetTransparency(aShadow.IsTransparent ? 0xff : 0);
+ aShadowColor = aSet;
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxShadowItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ return ( ( aShadowColor == ( (SvxShadowItem&)rAttr ).aShadowColor ) &&
+ ( nWidth == ( (SvxShadowItem&)rAttr ).GetWidth() ) &&
+ ( eLocation == ( (SvxShadowItem&)rAttr ).GetLocation() ) );
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxShadowItem::Clone( SfxItemPool* ) const
+{
+ return new SvxShadowItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxShadowItem::CalcShadowSpace( sal_uInt16 nShadow ) const
+{
+ sal_uInt16 nSpace = 0;
+
+ switch ( nShadow )
+ {
+ case SHADOW_TOP:
+ if ( eLocation == SVX_SHADOW_TOPLEFT ||
+ eLocation == SVX_SHADOW_TOPRIGHT )
+ nSpace = nWidth;
+ break;
+
+ case SHADOW_BOTTOM:
+ if ( eLocation == SVX_SHADOW_BOTTOMLEFT ||
+ eLocation == SVX_SHADOW_BOTTOMRIGHT )
+ nSpace = nWidth;
+ break;
+
+ case SHADOW_LEFT:
+ if ( eLocation == SVX_SHADOW_TOPLEFT ||
+ eLocation == SVX_SHADOW_BOTTOMLEFT )
+ nSpace = nWidth;
+ break;
+
+ case SHADOW_RIGHT:
+ if ( eLocation == SVX_SHADOW_TOPRIGHT ||
+ eLocation == SVX_SHADOW_BOTTOMRIGHT )
+ nSpace = nWidth;
+ break;
+
+ default:
+ DBG_ERROR( "wrong shadow" );
+ }
+ return nSpace;
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxShadowItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit eCoreUnit,
+ SfxMapUnit ePresUnit,
+ XubString& rText, const IntlWrapper *pIntl
+) const
+{
+#ifndef SVX_LIGHT
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ {
+ rText = ::GetColorString( aShadowColor );
+ rText += cpDelim;
+ sal_uInt16 nId = RID_SVXITEMS_TRANSPARENT_FALSE;
+
+ if ( aShadowColor.GetTransparency() )
+ nId = RID_SVXITEMS_TRANSPARENT_TRUE;
+ rText += EE_RESSTR(nId);
+ rText += cpDelim;
+ rText += GetMetricText( (long)nWidth, eCoreUnit, ePresUnit, pIntl );
+ rText += cpDelim;
+ rText += EE_RESSTR(RID_SVXITEMS_SHADOW_BEGIN + eLocation);
+ return ePres;
+ }
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ rText = EE_RESSTR(RID_SVXITEMS_SHADOW_COMPLETE);
+ rText += ::GetColorString( aShadowColor );
+ rText += cpDelim;
+
+ sal_uInt16 nId = RID_SVXITEMS_TRANSPARENT_FALSE;
+ if ( aShadowColor.GetTransparency() )
+ nId = RID_SVXITEMS_TRANSPARENT_TRUE;
+ rText += EE_RESSTR(nId);
+ rText += cpDelim;
+ rText += GetMetricText( (long)nWidth, eCoreUnit, ePresUnit, pIntl );
+ rText += EE_RESSTR(GetMetricId(ePresUnit));
+ rText += cpDelim;
+ rText += EE_RESSTR(RID_SVXITEMS_SHADOW_BEGIN + eLocation);
+ return ePres;
+ }
+ default: ;//prevent warning
+ }
+#endif
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxShadowItem::Store( SvStream& rStrm , sal_uInt16 /*nItemVersion*/ ) const
+{
+ rStrm << (sal_Int8) GetLocation()
+ << (sal_uInt16) GetWidth()
+ << (sal_Bool)(aShadowColor.GetTransparency() > 0)
+ << GetColor()
+ << GetColor()
+ << (sal_Int8)(aShadowColor.GetTransparency() > 0 ? 0 : 1); //BRUSH_NULL : BRUSH_SOLID
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxShadowItem::ScaleMetrics( long nMult, long nDiv )
+{
+ nWidth = (sal_uInt16)Scale( nWidth, nMult, nDiv );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxShadowItem::HasMetrics() const
+{
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxShadowItem::Create( SvStream& rStrm, sal_uInt16 ) const
+{
+ sal_Int8 cLoc;
+ sal_uInt16 _nWidth;
+ sal_Bool bTrans;
+ Color aColor;
+ Color aFillColor;
+ sal_Int8 nStyle;
+ rStrm >> cLoc >> _nWidth
+ >> bTrans >> aColor >> aFillColor >> nStyle;
+ aColor.SetTransparency(bTrans ? 0xff : 0);
+ return new SvxShadowItem( Which(), &aColor, _nWidth, (SvxShadowLocation)cLoc );
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxShadowItem::GetValueCount() const
+{
+ return SVX_SHADOW_END; // SVX_SHADOW_BOTTOMRIGHT + 1
+}
+
+// -----------------------------------------------------------------------
+
+XubString SvxShadowItem::GetValueTextByPos( sal_uInt16 nPos ) const
+{
+ DBG_ASSERT( nPos < SVX_SHADOW_END, "enum overflow!" );
+ return XubString( EditResId( RID_SVXITEMS_SHADOW_BEGIN + nPos ) );
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxShadowItem::GetEnumValue() const
+{
+ return (sal_uInt16)GetLocation();
+}
+
+// -----------------------------------------------------------------------
+
+void SvxShadowItem::SetEnumValue( sal_uInt16 nVal )
+{
+ SetLocation( (const SvxShadowLocation)nVal );
+}
+
+// class SvxBorderLine --------------------------------------------------
+
+SvxBorderLine::SvxBorderLine( const Color *pCol, sal_uInt16 nOut, sal_uInt16 nIn, sal_uInt16 nDist )
+: nOutWidth( nOut )
+, nInWidth ( nIn )
+, nDistance( nDist )
+{
+ if ( pCol )
+ aColor = *pCol;
+}
+
+// -----------------------------------------------------------------------
+
+SvxBorderLine::SvxBorderLine( const SvxBorderLine& r )
+{
+ *this = r;
+}
+
+// -----------------------------------------------------------------------
+
+SvxBorderLine& SvxBorderLine::operator=( const SvxBorderLine& r )
+{
+ aColor = r.aColor;
+ nOutWidth = r.nOutWidth;
+ nInWidth = r.nInWidth;
+ nDistance = r.nDistance;
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+void SvxBorderLine::ScaleMetrics( long nMult, long nDiv )
+{
+ nOutWidth = (sal_uInt16)Scale( nOutWidth, nMult, nDiv );
+ nInWidth = (sal_uInt16)Scale( nInWidth, nMult, nDiv );
+ nDistance = (sal_uInt16)Scale( nDistance, nMult, nDiv );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvxBorderLine::operator==( const SvxBorderLine& rCmp ) const
+{
+ return ( ( aColor == rCmp.GetColor() ) &&
+ ( nInWidth == rCmp.GetInWidth() ) &&
+ ( nOutWidth == rCmp.GetOutWidth() ) &&
+ ( nDistance == rCmp.GetDistance() ) );
+}
+
+// -----------------------------------------------------------------------
+
+XubString SvxBorderLine::GetValueString( SfxMapUnit eSrcUnit,
+ SfxMapUnit eDestUnit,
+ const IntlWrapper* pIntl,
+ sal_Bool bMetricStr) const
+{
+#ifndef SVX_LIGHT
+ sal_uInt16 nResId = 0;
+
+ if ( 0 == nDistance )
+ {
+ // einfach Linie
+ if ( DEF_LINE_WIDTH_0 == nOutWidth )
+ nResId = RID_SINGLE_LINE0;
+ else if ( DEF_LINE_WIDTH_1 == nOutWidth )
+ nResId = RID_SINGLE_LINE1;
+ else if ( DEF_LINE_WIDTH_2 == nOutWidth )
+ nResId = RID_SINGLE_LINE2;
+ else if ( DEF_LINE_WIDTH_3 == nOutWidth )
+ nResId = RID_SINGLE_LINE3;
+ else if ( DEF_LINE_WIDTH_4 == nOutWidth )
+ nResId = RID_SINGLE_LINE4;
+ }
+ else if ( DEF_LINE_WIDTH_1 == nDistance )
+ {
+ // doppelte Linie, kleiner Abstand
+ if ( DEF_LINE_WIDTH_0 == nOutWidth && DEF_LINE_WIDTH_0 == nInWidth )
+ nResId = RID_DOUBLE_LINE0;
+ else if ( DEF_LINE_WIDTH_1 == nOutWidth &&
+ DEF_LINE_WIDTH_1 == nInWidth )
+ nResId = RID_DOUBLE_LINE2;
+ else if ( DEF_LINE_WIDTH_1 == nOutWidth &&
+ DEF_LINE_WIDTH_2 == nInWidth )
+ nResId = RID_DOUBLE_LINE8;
+ }
+ else if ( DEF_LINE_WIDTH_2 == nDistance )
+ {
+ // doppelte Linie, gro\ser Abstand
+ if ( DEF_LINE_WIDTH_0 == nOutWidth && DEF_LINE_WIDTH_0 == nInWidth )
+ nResId = RID_DOUBLE_LINE1;
+ else if ( DEF_LINE_WIDTH_2 == nOutWidth &&
+ DEF_LINE_WIDTH_2 == nInWidth )
+ nResId = RID_DOUBLE_LINE3;
+ else if ( DEF_LINE_WIDTH_1 == nOutWidth &&
+ DEF_LINE_WIDTH_0 == nInWidth )
+ nResId = RID_DOUBLE_LINE4;
+ else if ( DEF_LINE_WIDTH_2 == nOutWidth &&
+ DEF_LINE_WIDTH_0 == nInWidth )
+ nResId = RID_DOUBLE_LINE5;
+ else if ( DEF_LINE_WIDTH_3 == nOutWidth &&
+ DEF_LINE_WIDTH_0 == nInWidth )
+ nResId = RID_DOUBLE_LINE6;
+ else if ( DEF_LINE_WIDTH_2 == nOutWidth &&
+ DEF_LINE_WIDTH_1 == nInWidth )
+ nResId = RID_DOUBLE_LINE7;
+ else if ( DEF_LINE_WIDTH_3 == nOutWidth &&
+ DEF_LINE_WIDTH_2 == nInWidth )
+ nResId = RID_DOUBLE_LINE9;
+ else if ( DEF_LINE_WIDTH_2 == nOutWidth &&
+ DEF_LINE_WIDTH_3 == nInWidth )
+ nResId = RID_DOUBLE_LINE10;
+ }
+ String aStr;
+ aStr += sal_Unicode('(');
+ aStr += ::GetColorString( aColor );
+ aStr += cpDelim;
+
+ if ( nResId )
+ aStr += EE_RESSTR(nResId);
+ else
+ {
+ String sMetric = EE_RESSTR(GetMetricId( eDestUnit ));
+ aStr += GetMetricText( (long)nInWidth, eSrcUnit, eDestUnit, pIntl );
+ if ( bMetricStr )
+ aStr += sMetric;
+ aStr += cpDelim;
+ aStr += GetMetricText( (long)nOutWidth, eSrcUnit, eDestUnit, pIntl );
+ if ( bMetricStr )
+ aStr += sMetric;
+ aStr += cpDelim;
+ aStr += GetMetricText( (long)nDistance, eSrcUnit, eDestUnit, pIntl );
+ if ( bMetricStr )
+ aStr += sMetric;
+ }
+ aStr += sal_Unicode(')');
+ return aStr;
+#else
+ return UniString();
+#endif
+}
+
+bool SvxBorderLine::HasPriority( const SvxBorderLine& rOtherLine ) const
+{
+ const USHORT nThisSize = GetOutWidth() + GetDistance() + GetInWidth();
+ const USHORT nOtherSize = rOtherLine.GetOutWidth() + rOtherLine.GetDistance() + rOtherLine.GetInWidth();
+
+ if (nThisSize > nOtherSize)
+ {
+ return true;
+ }
+ else if (nThisSize < nOtherSize)
+ {
+ return false;
+ }
+ else
+ {
+ if ( rOtherLine.GetInWidth() && !GetInWidth() )
+ {
+ return true;
+ }
+ else if ( GetInWidth() && !rOtherLine.GetInWidth() )
+ {
+ return false;
+ }
+ else
+ {
+ return false;
+ }
+ }
+}
+
+// class SvxBoxItem ------------------------------------------------------
+
+SvxBoxItem::SvxBoxItem( const SvxBoxItem& rCpy ) :
+
+ SfxPoolItem ( rCpy ),
+ nTopDist ( rCpy.nTopDist ),
+ nBottomDist ( rCpy.nBottomDist ),
+ nLeftDist ( rCpy.nLeftDist ),
+ nRightDist ( rCpy.nRightDist )
+
+{
+ pTop = rCpy.GetTop() ? new SvxBorderLine( *rCpy.GetTop() ) : 0;
+ pBottom = rCpy.GetBottom() ? new SvxBorderLine( *rCpy.GetBottom() ) : 0;
+ pLeft = rCpy.GetLeft() ? new SvxBorderLine( *rCpy.GetLeft() ) : 0;
+ pRight = rCpy.GetRight() ? new SvxBorderLine( *rCpy.GetRight() ) : 0;
+}
+
+// -----------------------------------------------------------------------
+
+SvxBoxItem::SvxBoxItem( const sal_uInt16 nId ) :
+ SfxPoolItem( nId ),
+
+ pTop ( 0 ),
+ pBottom ( 0 ),
+ pLeft ( 0 ),
+ pRight ( 0 ),
+ nTopDist ( 0 ),
+ nBottomDist ( 0 ),
+ nLeftDist ( 0 ),
+ nRightDist ( 0 )
+
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvxBoxItem::~SvxBoxItem()
+{
+ delete pTop;
+ delete pBottom;
+ delete pLeft;
+ delete pRight;
+}
+
+// -----------------------------------------------------------------------
+
+SvxBoxItem& SvxBoxItem::operator=( const SvxBoxItem& rBox )
+{
+ nTopDist = rBox.nTopDist;
+ nBottomDist = rBox.nBottomDist;
+ nLeftDist = rBox.nLeftDist;
+ nRightDist = rBox.nRightDist;
+ SetLine( rBox.GetTop(), BOX_LINE_TOP );
+ SetLine( rBox.GetBottom(), BOX_LINE_BOTTOM );
+ SetLine( rBox.GetLeft(), BOX_LINE_LEFT );
+ SetLine( rBox.GetRight(), BOX_LINE_RIGHT );
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+inline sal_Bool CmpBrdLn( const SvxBorderLine* pBrd1, const SvxBorderLine* pBrd2 )
+{
+ sal_Bool bRet;
+ if( 0 != pBrd1 ? 0 == pBrd2 : 0 != pBrd2 )
+ bRet = sal_False;
+ else
+ if( !pBrd1 )
+ bRet = sal_True;
+ else
+ bRet = (*pBrd1 == *pBrd2);
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxBoxItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ return (
+ ( nTopDist == ( (SvxBoxItem&)rAttr ).nTopDist ) &&
+ ( nBottomDist == ( (SvxBoxItem&)rAttr ).nBottomDist ) &&
+ ( nLeftDist == ( (SvxBoxItem&)rAttr ).nLeftDist ) &&
+ ( nRightDist == ( (SvxBoxItem&)rAttr ).nRightDist ) &&
+ CmpBrdLn( pTop, ( (SvxBoxItem&)rAttr ).GetTop() ) &&
+ CmpBrdLn( pBottom, ( (SvxBoxItem&)rAttr ).GetBottom() ) &&
+ CmpBrdLn( pLeft, ( (SvxBoxItem&)rAttr ).GetLeft() ) &&
+ CmpBrdLn( pRight, ( (SvxBoxItem&)rAttr ).GetRight() ) );
+}
+
+// -----------------------------------------------------------------------
+table::BorderLine lcl_SvxLineToLine(const SvxBorderLine* pLine, sal_Bool bConvert)
+{
+ table::BorderLine aLine;
+ if(pLine)
+ {
+ aLine.Color = pLine->GetColor().GetColor() ;
+ aLine.InnerLineWidth = sal_uInt16( bConvert ? TWIP_TO_MM100_UNSIGNED(pLine->GetInWidth() ): pLine->GetInWidth() );
+ aLine.OuterLineWidth = sal_uInt16( bConvert ? TWIP_TO_MM100_UNSIGNED(pLine->GetOutWidth()): pLine->GetOutWidth() );
+ aLine.LineDistance = sal_uInt16( bConvert ? TWIP_TO_MM100_UNSIGNED(pLine->GetDistance()): pLine->GetDistance() );
+ }
+ else
+ aLine.Color = aLine.InnerLineWidth = aLine.OuterLineWidth = aLine.LineDistance = 0;
+ return aLine;
+}
+// -----------------------------------------------------------------------
+sal_Bool SvxBoxItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+ sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ table::BorderLine aRetLine;
+ sal_uInt16 nDist = 0;
+ sal_Bool bDistMember = sal_False;
+ nMemberId &= ~CONVERT_TWIPS;
+ sal_Bool bSerialize = sal_False;
+ switch(nMemberId)
+ {
+ case 0:
+ {
+ // 4 Borders and 5 distances
+ uno::Sequence< uno::Any > aSeq( 9 );
+ aSeq[0] = uno::makeAny( lcl_SvxLineToLine(GetLeft(), bConvert) );
+ aSeq[1] = uno::makeAny( lcl_SvxLineToLine(GetRight(), bConvert) );
+ aSeq[2] = uno::makeAny( lcl_SvxLineToLine(GetBottom(), bConvert) );
+ aSeq[3] = uno::makeAny( lcl_SvxLineToLine(GetTop(), bConvert) );
+ aSeq[4] <<= uno::makeAny( (sal_Int32)(bConvert ? TWIP_TO_MM100_UNSIGNED( GetDistance()) : GetDistance()));
+ aSeq[5] <<= uno::makeAny( (sal_Int32)(bConvert ? TWIP_TO_MM100_UNSIGNED( nTopDist ) : nTopDist ));
+ aSeq[6] <<= uno::makeAny( (sal_Int32)(bConvert ? TWIP_TO_MM100_UNSIGNED( nBottomDist ) : nBottomDist ));
+ aSeq[7] <<= uno::makeAny( (sal_Int32)(bConvert ? TWIP_TO_MM100_UNSIGNED( nLeftDist ) : nLeftDist ));
+ aSeq[8] <<= uno::makeAny( (sal_Int32)(bConvert ? TWIP_TO_MM100_UNSIGNED( nRightDist ) : nRightDist ));
+ rVal = uno::makeAny( aSeq );
+ return sal_True;
+ }
+ case MID_LEFT_BORDER:
+ bSerialize = sal_True; // intentionally no break!
+ case LEFT_BORDER:
+ aRetLine = lcl_SvxLineToLine(GetLeft(), bConvert);
+ break;
+ case MID_RIGHT_BORDER:
+ bSerialize = sal_True; // intentionally no break!
+ case RIGHT_BORDER:
+ aRetLine = lcl_SvxLineToLine(GetRight(), bConvert);
+ break;
+ case MID_BOTTOM_BORDER:
+ bSerialize = sal_True; // intentionally no break!
+ case BOTTOM_BORDER:
+ aRetLine = lcl_SvxLineToLine(GetBottom(), bConvert);
+ break;
+ case MID_TOP_BORDER:
+ bSerialize = sal_True; // intentionally no break!
+ case TOP_BORDER:
+ aRetLine = lcl_SvxLineToLine(GetTop(), bConvert);
+ break;
+ case BORDER_DISTANCE:
+ nDist = GetDistance();
+ bDistMember = sal_True;
+ break;
+ case TOP_BORDER_DISTANCE:
+ nDist = nTopDist;
+ bDistMember = sal_True;
+ break;
+ case BOTTOM_BORDER_DISTANCE:
+ nDist = nBottomDist;
+ bDistMember = sal_True;
+ break;
+ case LEFT_BORDER_DISTANCE:
+ nDist = nLeftDist;
+ bDistMember = sal_True;
+ break;
+ case RIGHT_BORDER_DISTANCE:
+ nDist = nRightDist;
+ bDistMember = sal_True;
+ break;
+ }
+
+ if( bDistMember )
+ rVal <<= (sal_Int32)(bConvert ? TWIP_TO_MM100_UNSIGNED(nDist) : nDist);
+ else
+ {
+/*
+ if ( bSerialize )
+ {
+ ::com::sun::star::uno::Sequence < ::com::sun::star::uno::Any > aSeq(4);
+ aSeq[0] <<= aRetLine.Color;
+ aSeq[1] <<= aRetLine.InnerLineWidth;
+ aSeq[2] <<= aRetLine.OuterLineWidth;
+ aSeq[3] <<= aRetLine.LineDistance;
+ rVal <<= aSeq;
+ }
+ else
+*/
+ rVal <<= aRetLine;
+ }
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool lcl_LineToSvxLine(const ::com::sun::star::table::BorderLine& rLine, SvxBorderLine& rSvxLine, sal_Bool bConvert)
+{
+ rSvxLine.SetColor( Color(rLine.Color));
+ rSvxLine.SetInWidth( sal_uInt16( bConvert ? MM100_TO_TWIP(rLine.InnerLineWidth) : rLine.InnerLineWidth ));
+ rSvxLine.SetOutWidth( sal_uInt16( bConvert ? MM100_TO_TWIP(rLine.OuterLineWidth) : rLine.OuterLineWidth ));
+ rSvxLine.SetDistance( sal_uInt16( bConvert ? MM100_TO_TWIP(rLine.LineDistance ) : rLine.LineDistance ));
+ sal_Bool bRet = rLine.InnerLineWidth > 0 || rLine.OuterLineWidth > 0;
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvxBoxItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+ sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ sal_uInt16 nLine = BOX_LINE_TOP;
+ sal_Bool bDistMember = sal_False;
+ nMemberId &= ~CONVERT_TWIPS;
+ switch(nMemberId)
+ {
+ case 0:
+ {
+ uno::Sequence< uno::Any > aSeq;
+ if (( rVal >>= aSeq ) && ( aSeq.getLength() == 9 ))
+ {
+ // 4 Borders and 5 distances
+ sal_Int32 nDist = 0;
+ SvxBorderLine aLine;
+ table::BorderLine aBorderLine;
+ if ( aSeq[0] >>= aBorderLine )
+ {
+ sal_Bool bSet = lcl_LineToSvxLine(aBorderLine, aLine, bConvert);
+ SetLine(bSet ? &aLine : 0, BOX_LINE_LEFT );
+ }
+ else
+ return sal_False;
+
+ if ( aSeq[1] >>= aBorderLine )
+ {
+ sal_Bool bSet = lcl_LineToSvxLine(aBorderLine, aLine, bConvert);
+ SetLine(bSet ? &aLine : 0, BOX_LINE_RIGHT );
+ }
+ else
+ return sal_False;
+
+ if ( aSeq[2] >>= aBorderLine )
+ {
+ sal_Bool bSet = lcl_LineToSvxLine(aBorderLine, aLine, bConvert);
+ SetLine(bSet ? &aLine : 0, BOX_LINE_BOTTOM );
+ }
+ else
+ return sal_False;
+
+ if ( aSeq[3] >>= aBorderLine )
+ {
+ sal_Bool bSet = lcl_LineToSvxLine(aBorderLine, aLine, bConvert);
+ SetLine(bSet ? &aLine : 0, BOX_LINE_TOP );
+ }
+ else
+ return sal_False;
+
+ sal_uInt16 nLines[4] = { BOX_LINE_TOP, BOX_LINE_BOTTOM, BOX_LINE_LEFT, BOX_LINE_RIGHT };
+ for ( sal_Int32 n = 4; n < 9; n++ )
+ {
+ if ( aSeq[n] >>= nDist )
+ {
+ if( bConvert )
+ nDist = MM100_TO_TWIP(nDist);
+ if ( n == 4 )
+ SetDistance( sal_uInt16( nDist ));
+ else
+ SetDistance( sal_uInt16( nDist ), nLines[n-5] );
+ }
+ else
+ return sal_False;
+ }
+
+ return sal_True;
+ }
+ else
+ return sal_False;
+ }
+ case LEFT_BORDER_DISTANCE:
+ bDistMember = sal_True;
+ case LEFT_BORDER:
+ case MID_LEFT_BORDER:
+ nLine = BOX_LINE_LEFT;
+ break;
+ case RIGHT_BORDER_DISTANCE:
+ bDistMember = sal_True;
+ case RIGHT_BORDER:
+ case MID_RIGHT_BORDER:
+ nLine = BOX_LINE_RIGHT;
+ break;
+ case BOTTOM_BORDER_DISTANCE:
+ bDistMember = sal_True;
+ case BOTTOM_BORDER:
+ case MID_BOTTOM_BORDER:
+ nLine = BOX_LINE_BOTTOM;
+ break;
+ case TOP_BORDER_DISTANCE:
+ bDistMember = sal_True;
+ case TOP_BORDER:
+ case MID_TOP_BORDER:
+ nLine = BOX_LINE_TOP;
+ break;
+ }
+
+ if( bDistMember || nMemberId == BORDER_DISTANCE )
+ {
+ sal_Int32 nDist = 0;
+ if(!(rVal >>= nDist))
+ return sal_False;
+
+ if(nDist >= 0)
+ {
+ if( bConvert )
+ nDist = MM100_TO_TWIP(nDist);
+ if( nMemberId == BORDER_DISTANCE )
+ SetDistance( sal_uInt16( nDist ));
+ else
+ SetDistance( sal_uInt16( nDist ), nLine );
+ }
+ }
+ else
+ {
+ SvxBorderLine aLine;
+ if( !rVal.hasValue() )
+ return sal_False;
+
+ table::BorderLine aBorderLine;
+ if( rVal >>= aBorderLine )
+ {
+ // usual struct
+ }
+ else if (rVal.getValueTypeClass() == uno::TypeClass_SEQUENCE )
+ {
+ // serialization for basic macro recording
+ uno::Reference < script::XTypeConverter > xConverter
+ ( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.script.Converter")),
+ uno::UNO_QUERY );
+ uno::Sequence < uno::Any > aSeq;
+ uno::Any aNew;
+ try { aNew = xConverter->convertTo( rVal, ::getCppuType((const uno::Sequence < uno::Any >*)0) ); }
+ catch (uno::Exception&) {}
+
+ aNew >>= aSeq;
+ if ( aSeq.getLength() == 4 )
+ {
+ sal_Int32 nVal = 0;
+ if ( aSeq[0] >>= nVal )
+ aBorderLine.Color = nVal;
+ if ( aSeq[1] >>= nVal )
+ aBorderLine.InnerLineWidth = (sal_Int16) nVal;
+ if ( aSeq[2] >>= nVal )
+ aBorderLine.OuterLineWidth = (sal_Int16) nVal;
+ if ( aSeq[3] >>= nVal )
+ aBorderLine.LineDistance = (sal_Int16) nVal;
+ }
+ else
+ return sal_False;
+ }
+ else
+ return sal_False;
+
+ sal_Bool bSet = lcl_LineToSvxLine(aBorderLine, aLine, bConvert);
+ SetLine(bSet ? &aLine : 0, nLine);
+ }
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxBoxItem::Clone( SfxItemPool* ) const
+{
+ return new SvxBoxItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxBoxItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit eCoreUnit,
+ SfxMapUnit ePresUnit,
+ XubString& rText, const IntlWrapper *pIntl
+) const
+{
+#ifndef SVX_LIGHT
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return SFX_ITEM_PRESENTATION_NONE;
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ {
+ rText.Erase();
+
+ if ( pTop )
+ {
+ rText = pTop->GetValueString( eCoreUnit, ePresUnit, pIntl );
+ rText += cpDelim;
+ }
+ if( !(pTop && pBottom && pLeft && pRight &&
+ *pTop == *pBottom && *pTop == *pLeft && *pTop == *pRight) )
+ {
+ if ( pBottom )
+ {
+ rText += pBottom->GetValueString( eCoreUnit, ePresUnit, pIntl );
+ rText += cpDelim;
+ }
+ if ( pLeft )
+ {
+ rText += pLeft->GetValueString( eCoreUnit, ePresUnit, pIntl );
+ rText += cpDelim;
+ }
+ if ( pRight )
+ {
+ rText += pRight->GetValueString( eCoreUnit, ePresUnit, pIntl );
+ rText += cpDelim;
+ }
+ }
+ rText += GetMetricText( (long)nTopDist, eCoreUnit, ePresUnit, pIntl );
+ if( nTopDist != nBottomDist || nTopDist != nLeftDist ||
+ nTopDist != nRightDist )
+ {
+ (((((rText += cpDelim)
+ += GetMetricText( (long)nBottomDist, eCoreUnit,
+ ePresUnit, pIntl ))
+ += cpDelim)
+ += GetMetricText( (long)nLeftDist, eCoreUnit, ePresUnit, pIntl ))
+ += cpDelim)
+ += GetMetricText( (long)nRightDist, eCoreUnit,
+ ePresUnit, pIntl );
+ }
+ return SFX_ITEM_PRESENTATION_NAMELESS;
+ }
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ if( !(pTop || pBottom || pLeft || pRight) )
+ {
+ rText = EE_RESSTR(RID_SVXITEMS_BORDER_NONE);
+ rText += cpDelim;
+ }
+ else
+ {
+ rText = EE_RESSTR(RID_SVXITEMS_BORDER_COMPLETE);
+ if( pTop && pBottom && pLeft && pRight &&
+ *pTop == *pBottom && *pTop == *pLeft && *pTop == *pRight )
+ {
+ rText += pTop->GetValueString( eCoreUnit, ePresUnit, pIntl, sal_True );
+ rText += cpDelim;
+ }
+ else
+ {
+ if ( pTop )
+ {
+ rText += EE_RESSTR(RID_SVXITEMS_BORDER_TOP);
+ rText += pTop->GetValueString( eCoreUnit, ePresUnit, pIntl, sal_True );
+ rText += cpDelim;
+ }
+ if ( pBottom )
+ {
+ rText += EE_RESSTR(RID_SVXITEMS_BORDER_BOTTOM);
+ rText += pBottom->GetValueString( eCoreUnit, ePresUnit, pIntl, sal_True );
+ rText += cpDelim;
+ }
+ if ( pLeft )
+ {
+ rText += EE_RESSTR(RID_SVXITEMS_BORDER_LEFT);
+ rText += pLeft->GetValueString( eCoreUnit, ePresUnit, pIntl, sal_True );
+ rText += cpDelim;
+ }
+ if ( pRight )
+ {
+ rText += EE_RESSTR(RID_SVXITEMS_BORDER_RIGHT);
+ rText += pRight->GetValueString( eCoreUnit, ePresUnit, pIntl, sal_True );
+ rText += cpDelim;
+ }
+ }
+ }
+
+ rText += EE_RESSTR(RID_SVXITEMS_BORDER_DISTANCE);
+ if( nTopDist == nBottomDist && nTopDist == nLeftDist &&
+ nTopDist == nRightDist )
+ {
+ rText += GetMetricText( (long)nTopDist, eCoreUnit,
+ ePresUnit, pIntl );
+ rText += EE_RESSTR(GetMetricId(ePresUnit));
+ }
+ else
+ {
+ (((rText += EE_RESSTR(RID_SVXITEMS_BORDER_TOP))
+ += GetMetricText( (long)nTopDist, eCoreUnit,
+ ePresUnit, pIntl ))
+ += EE_RESSTR(GetMetricId(ePresUnit)))
+ += cpDelim;
+ (((rText += EE_RESSTR(RID_SVXITEMS_BORDER_BOTTOM))
+ += GetMetricText( (long)nBottomDist, eCoreUnit,
+ ePresUnit, pIntl ))
+ += EE_RESSTR(GetMetricId(ePresUnit)))
+ += cpDelim;
+ (((rText += EE_RESSTR(RID_SVXITEMS_BORDER_LEFT))
+ += GetMetricText( (long)nLeftDist, eCoreUnit,
+ ePresUnit, pIntl ))
+ += EE_RESSTR(GetMetricId(ePresUnit)))
+ += cpDelim;
+ ((rText += EE_RESSTR(RID_SVXITEMS_BORDER_RIGHT))
+ += GetMetricText( (long)nRightDist, eCoreUnit,
+ ePresUnit, pIntl ))
+ += EE_RESSTR(GetMetricId(ePresUnit));
+ }
+ return SFX_ITEM_PRESENTATION_COMPLETE;
+ }
+ default: ;//prevent warning
+ }
+#endif // !SVX_LIGHT
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxBoxItem::Store( SvStream& rStrm , sal_uInt16 nItemVersion ) const
+{
+ rStrm << (sal_uInt16) GetDistance();
+ const SvxBorderLine* pLine[ 4 ]; // top, left, right, bottom
+ pLine[ 0 ] = GetTop();
+ pLine[ 1 ] = GetLeft();
+ pLine[ 2 ] = GetRight();
+ pLine[ 3 ] = GetBottom();
+
+ for( int i = 0; i < 4; i++ )
+ {
+ const SvxBorderLine* l = pLine[ i ];
+ if( l )
+ {
+ rStrm << (sal_Int8) i
+ << l->GetColor()
+ << (sal_uInt16) l->GetOutWidth()
+ << (sal_uInt16) l->GetInWidth()
+ << (sal_uInt16) l->GetDistance();
+ }
+ }
+ sal_Int8 cLine = 4;
+ if( nItemVersion >= BOX_4DISTS_VERSION &&
+ !(nTopDist == nLeftDist &&
+ nTopDist == nRightDist &&
+ nTopDist == nBottomDist) )
+ {
+ cLine |= 0x10;
+ }
+
+ rStrm << cLine;
+
+ if( nItemVersion >= BOX_4DISTS_VERSION && (cLine & 0x10) != 0 )
+ {
+ rStrm << (sal_uInt16)nTopDist
+ << (sal_uInt16)nLeftDist
+ << (sal_uInt16)nRightDist
+ << (sal_uInt16)nBottomDist;
+ }
+
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxBoxItem::GetVersion( sal_uInt16 nFFVer ) const
+{
+ DBG_ASSERT( SOFFICE_FILEFORMAT_31==nFFVer ||
+ SOFFICE_FILEFORMAT_40==nFFVer ||
+ SOFFICE_FILEFORMAT_50==nFFVer,
+ "SvxBoxItem: Gibt es ein neues Fileformat?" );
+ return SOFFICE_FILEFORMAT_31==nFFVer ||
+ SOFFICE_FILEFORMAT_40==nFFVer ? 0 : BOX_4DISTS_VERSION;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxBoxItem::ScaleMetrics( long nMult, long nDiv )
+{
+ if ( pTop ) pTop->ScaleMetrics( nMult, nDiv );
+ if ( pBottom ) pBottom->ScaleMetrics( nMult, nDiv );
+ if ( pLeft ) pLeft->ScaleMetrics( nMult, nDiv );
+ if ( pRight ) pBottom->ScaleMetrics( nMult, nDiv );
+ nTopDist = (sal_uInt16)Scale( nTopDist, nMult, nDiv );
+ nBottomDist = (sal_uInt16)Scale( nBottomDist, nMult, nDiv );
+ nLeftDist = (sal_uInt16)Scale( nLeftDist, nMult, nDiv );
+ nRightDist = (sal_uInt16)Scale( nRightDist, nMult, nDiv );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxBoxItem::HasMetrics() const
+{
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxBoxItem::Create( SvStream& rStrm, sal_uInt16 nIVersion ) const
+{
+ sal_uInt16 nDistance;
+ rStrm >> nDistance;
+ SvxBoxItem* pAttr = new SvxBoxItem( Which() );
+
+ sal_uInt16 aLineMap[4] = { BOX_LINE_TOP, BOX_LINE_LEFT,
+ BOX_LINE_RIGHT, BOX_LINE_BOTTOM };
+
+ sal_Int8 cLine;
+ while( sal_True )
+ {
+ rStrm >> cLine;
+
+ if( cLine > 3 )
+ break;
+ sal_uInt16 nOutline, nInline, _nDistance;
+ Color aColor;
+ rStrm >> aColor >> nOutline >> nInline >> _nDistance;
+ SvxBorderLine aBorder( &aColor, nOutline, nInline, _nDistance );
+
+ pAttr->SetLine( &aBorder, aLineMap[cLine] );
+ }
+
+ if( nIVersion >= BOX_4DISTS_VERSION && (cLine&0x10) != 0 )
+ {
+ for( sal_uInt16 i=0; i < 4; i++ )
+ {
+ sal_uInt16 nDist;
+ rStrm >> nDist;
+ pAttr->SetDistance( nDist, aLineMap[i] );
+ }
+ }
+ else
+ {
+ pAttr->SetDistance( nDistance );
+ }
+
+ return pAttr;
+}
+
+// -----------------------------------------------------------------------
+
+const SvxBorderLine *SvxBoxItem::GetLine( sal_uInt16 nLine ) const
+{
+ const SvxBorderLine *pRet = 0;
+
+ switch ( nLine )
+ {
+ case BOX_LINE_TOP:
+ pRet = pTop;
+ break;
+ case BOX_LINE_BOTTOM:
+ pRet = pBottom;
+ break;
+ case BOX_LINE_LEFT:
+ pRet = pLeft;
+ break;
+ case BOX_LINE_RIGHT:
+ pRet = pRight;
+ break;
+ default:
+ DBG_ERROR( "wrong line" );
+ break;
+ }
+
+ return pRet;
+}
+
+// -----------------------------------------------------------------------
+
+void SvxBoxItem::SetLine( const SvxBorderLine* pNew, sal_uInt16 nLine )
+{
+ SvxBorderLine* pTmp = pNew ? new SvxBorderLine( *pNew ) : 0;
+
+ switch ( nLine )
+ {
+ case BOX_LINE_TOP:
+ delete pTop;
+ pTop = pTmp;
+ break;
+ case BOX_LINE_BOTTOM:
+ delete pBottom;
+ pBottom = pTmp;
+ break;
+ case BOX_LINE_LEFT:
+ delete pLeft;
+ pLeft = pTmp;
+ break;
+ case BOX_LINE_RIGHT:
+ delete pRight;
+ pRight = pTmp;
+ break;
+ default:
+ DBG_ERROR( "wrong line" );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxBoxItem::GetDistance() const
+{
+ // The smallest distance that is not 0 will be returned.
+ sal_uInt16 nDist = nTopDist;
+ if( nBottomDist && (!nDist || nBottomDist < nDist) )
+ nDist = nBottomDist;
+ if( nLeftDist && (!nDist || nLeftDist < nDist) )
+ nDist = nLeftDist;
+ if( nRightDist && (!nDist || nRightDist < nDist) )
+ nDist = nRightDist;
+
+ return nDist;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxBoxItem::GetDistance( sal_uInt16 nLine ) const
+{
+ sal_uInt16 nDist = 0;
+ switch ( nLine )
+ {
+ case BOX_LINE_TOP:
+ nDist = nTopDist;
+ break;
+ case BOX_LINE_BOTTOM:
+ nDist = nBottomDist;
+ break;
+ case BOX_LINE_LEFT:
+ nDist = nLeftDist;
+ break;
+ case BOX_LINE_RIGHT:
+ nDist = nRightDist;
+ break;
+ default:
+ DBG_ERROR( "wrong line" );
+ }
+
+ return nDist;
+}
+
+// -----------------------------------------------------------------------
+
+void SvxBoxItem::SetDistance( sal_uInt16 nNew, sal_uInt16 nLine )
+{
+ switch ( nLine )
+ {
+ case BOX_LINE_TOP:
+ nTopDist = nNew;
+ break;
+ case BOX_LINE_BOTTOM:
+ nBottomDist = nNew;
+ break;
+ case BOX_LINE_LEFT:
+ nLeftDist = nNew;
+ break;
+ case BOX_LINE_RIGHT:
+ nRightDist = nNew;
+ break;
+ default:
+ DBG_ERROR( "wrong line" );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxBoxItem::CalcLineSpace( sal_uInt16 nLine, sal_Bool bIgnoreLine ) const
+{
+ SvxBorderLine* pTmp = 0;
+ sal_uInt16 nDist = 0;
+ switch ( nLine )
+ {
+ case BOX_LINE_TOP:
+ pTmp = pTop;
+ nDist = nTopDist;
+ break;
+ case BOX_LINE_BOTTOM:
+ pTmp = pBottom;
+ nDist = nBottomDist;
+ break;
+ case BOX_LINE_LEFT:
+ pTmp = pLeft;
+ nDist = nLeftDist;
+ break;
+ case BOX_LINE_RIGHT:
+ pTmp = pRight;
+ nDist = nRightDist;
+ break;
+ default:
+ DBG_ERROR( "wrong line" );
+ }
+
+ if( pTmp )
+ {
+ nDist = nDist + (sal_uInt16)(pTmp->GetOutWidth()) + (sal_uInt16)(pTmp->GetInWidth()) + (sal_uInt16)(pTmp->GetDistance());
+ }
+ else if( !bIgnoreLine )
+ nDist = 0;
+ return nDist;
+}
+
+// class SvxBoxInfoItem --------------------------------------------------
+
+SvxBoxInfoItem::SvxBoxInfoItem( const sal_uInt16 nId ) :
+ SfxPoolItem( nId ),
+ pHori ( 0 ),
+ pVert ( 0 ),
+ mbEnableHor( false ),
+ mbEnableVer( false ),
+ nDefDist( 0 )
+{
+ bDist = bMinDist = sal_False;
+ ResetFlags();
+}
+
+// -----------------------------------------------------------------------
+
+SvxBoxInfoItem::SvxBoxInfoItem( const SvxBoxInfoItem& rCpy ) :
+ SfxPoolItem( rCpy ),
+ mbEnableHor( rCpy.mbEnableHor ),
+ mbEnableVer( rCpy.mbEnableVer )
+{
+ pHori = rCpy.GetHori() ? new SvxBorderLine( *rCpy.GetHori() ) : 0;
+ pVert = rCpy.GetVert() ? new SvxBorderLine( *rCpy.GetVert() ) : 0;
+ bDist = rCpy.IsDist();
+ bMinDist = rCpy.IsMinDist();
+ nValidFlags = rCpy.nValidFlags;
+ nDefDist = rCpy.GetDefDist();
+}
+
+// -----------------------------------------------------------------------
+
+SvxBoxInfoItem::~SvxBoxInfoItem()
+{
+ delete pHori;
+ delete pVert;
+}
+
+// -----------------------------------------------------------------------
+
+SvxBoxInfoItem &SvxBoxInfoItem::operator=( const SvxBoxInfoItem& rCpy )
+{
+ delete pHori;
+ delete pVert;
+ pHori = rCpy.GetHori() ? new SvxBorderLine( *rCpy.GetHori() ) : 0;
+ pVert = rCpy.GetVert() ? new SvxBorderLine( *rCpy.GetVert() ) : 0;
+ mbEnableHor = rCpy.mbEnableHor;
+ mbEnableVer = rCpy.mbEnableVer;
+ bDist = rCpy.IsDist();
+ bMinDist = rCpy.IsMinDist();
+ nValidFlags = rCpy.nValidFlags;
+ nDefDist = rCpy.GetDefDist();
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxBoxInfoItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ SvxBoxInfoItem& rBoxInfo = (SvxBoxInfoItem&)rAttr;
+
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ return ( mbEnableHor == rBoxInfo.mbEnableHor
+ && mbEnableVer == rBoxInfo.mbEnableVer
+ && bDist == rBoxInfo.IsDist()
+ && bMinDist == rBoxInfo.IsMinDist()
+ && nValidFlags == rBoxInfo.nValidFlags
+ && nDefDist == rBoxInfo.GetDefDist()
+ && CmpBrdLn( pHori, rBoxInfo.GetHori() )
+ && CmpBrdLn( pVert, rBoxInfo.GetVert() )
+ );
+}
+
+// -----------------------------------------------------------------------
+
+void SvxBoxInfoItem::SetLine( const SvxBorderLine* pNew, sal_uInt16 nLine )
+{
+ SvxBorderLine* pTmp = pNew ? new SvxBorderLine( *pNew ) : 0;
+
+ if ( BOXINFO_LINE_HORI == nLine )
+ {
+ delete pHori;
+ pHori = pTmp;
+ }
+ else if ( BOXINFO_LINE_VERT == nLine )
+ {
+ delete pVert;
+ pVert = pTmp;
+ }
+ else
+ {
+ DBG_ERROR( "wrong line" );
+ }
+}
+
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxBoxInfoItem::Clone( SfxItemPool* ) const
+{
+ return new SvxBoxInfoItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxBoxInfoItem::GetPresentation
+(
+ SfxItemPresentation /*ePres*/,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *
+) const
+{
+#ifndef SVX_LIGHT
+/*!!!
+ ResMgr* pMgr = DIALOG_MGR();
+ if ( pHori )
+ {
+ rText += pHori->GetValueString();
+ rText += cpDelim;
+ }
+ if ( pVert )
+ {
+ rText += pVert->GetValueString();
+ rText += cpDelim;
+ }
+ if ( bTable )
+ rText += String( ResId( RID_SVXITEMS_BOXINF_TABLE_TRUE, pMgr ) );
+ else
+ rText += String( ResId( RID_SVXITEMS_BOXINF_TABLE_FALSE, pMgr ) );
+ rText += cpDelim;
+ if ( bDist )
+ rText += String( ResId( RID_SVXITEMS_BOXINF_DIST_TRUE, pMgr ) );
+ else
+ rText += String( ResId( RID_SVXITEMS_BOXINF_DIST_FALSE, pMgr ) );
+ rText += cpDelim;
+ if ( bMinDist )
+ rText += String( ResId( RID_SVXITEMS_BOXINF_MDIST_TRUE, pMgr ) );
+ else
+ rText += String( ResId( RID_SVXITEMS_BOXINF_MDIST_FALSE, pMgr ) );
+ rText += cpDelim;
+ rText += nDefDist;
+ return SFX_ITEM_PRESENTATION_NAMELESS;
+*/
+ rText.Erase();
+#endif // !SVX_LIGHT
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxBoxInfoItem::Store( SvStream& rStrm , sal_uInt16 /*nItemVersion*/ ) const
+{
+ sal_Int8 cFlags = 0;
+
+ if ( IsTable() )
+ cFlags |= 0x01;
+ if ( IsDist() )
+ cFlags |= 0x02;
+ if ( IsMinDist() )
+ cFlags |= 0x04;
+ rStrm << (sal_Int8) cFlags
+ << (sal_uInt16) GetDefDist();
+ const SvxBorderLine* pLine[ 2 ];
+ pLine[ 0 ] = GetHori();
+ pLine[ 1 ] = GetVert();
+
+ for( int i = 0; i < 2; i++ )
+ {
+ const SvxBorderLine* l = pLine[ i ];
+ if( l )
+ {
+ rStrm << (char) i
+ << l->GetColor()
+ << (short) l->GetOutWidth()
+ << (short) l->GetInWidth()
+ << (short) l->GetDistance();
+ }
+ }
+ rStrm << (char) 2;
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxBoxInfoItem::ScaleMetrics( long nMult, long nDiv )
+{
+ if ( pHori ) pHori->ScaleMetrics( nMult, nDiv );
+ if ( pVert ) pVert->ScaleMetrics( nMult, nDiv );
+ nDefDist = (sal_uInt16)Scale( nDefDist, nMult, nDiv );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxBoxInfoItem::HasMetrics() const
+{
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxBoxInfoItem::Create( SvStream& rStrm, sal_uInt16 ) const
+{
+ sal_Int8 cFlags;
+ sal_uInt16 _nDefDist;
+ rStrm >> cFlags >> _nDefDist;
+
+ SvxBoxInfoItem* pAttr = new SvxBoxInfoItem( Which() );
+
+ pAttr->SetTable ( ( cFlags & 0x01 ) != 0 );
+ pAttr->SetDist ( ( cFlags & 0x02 ) != 0 );
+ pAttr->SetMinDist( ( cFlags & 0x04 ) != 0 );
+ pAttr->SetDefDist( _nDefDist );
+
+ while( sal_True )
+ {
+ sal_Int8 cLine;
+ rStrm >> cLine;
+
+ if( cLine > 1 )
+ break;
+ short nOutline, nInline, nDistance;
+ Color aColor;
+ rStrm >> aColor >> nOutline >> nInline >> nDistance;
+ SvxBorderLine aBorder( &aColor, nOutline, nInline, nDistance );
+
+ switch( cLine )
+ {
+ case 0: pAttr->SetLine( &aBorder, BOXINFO_LINE_HORI ); break;
+ case 1: pAttr->SetLine( &aBorder, BOXINFO_LINE_VERT ); break;
+ }
+ }
+ return pAttr;
+}
+
+// -----------------------------------------------------------------------
+
+void SvxBoxInfoItem::ResetFlags()
+{
+ nValidFlags = 0x7F; // alles g"ultig au/ser Disable
+}
+
+sal_Bool SvxBoxInfoItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+ sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ table::BorderLine aRetLine;
+ sal_Int16 nVal=0;
+ sal_Bool bIntMember = sal_False;
+ nMemberId &= ~CONVERT_TWIPS;
+ sal_Bool bSerialize = sal_False;
+ switch(nMemberId)
+ {
+ case 0:
+ {
+ // 2 BorderLines, flags, valid flags and distance
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > aSeq( 5 );
+ aSeq[0] = ::com::sun::star::uno::makeAny( lcl_SvxLineToLine( pHori, bConvert) );
+ aSeq[1] = ::com::sun::star::uno::makeAny( lcl_SvxLineToLine( pVert, bConvert) );
+ if ( IsTable() )
+ nVal |= 0x01;
+ if ( IsDist() )
+ nVal |= 0x02;
+ if ( IsMinDist() )
+ nVal |= 0x04;
+ aSeq[2] = ::com::sun::star::uno::makeAny( nVal );
+ nVal = nValidFlags;
+ aSeq[3] = ::com::sun::star::uno::makeAny( nVal );
+ aSeq[4] = ::com::sun::star::uno::makeAny( (sal_Int32)(bConvert ? TWIP_TO_MM100_UNSIGNED(GetDefDist()) : GetDefDist()) );
+ rVal = ::com::sun::star::uno::makeAny( aSeq );
+ return sal_True;
+ }
+
+ case MID_HORIZONTAL:
+ bSerialize = sal_True;
+ aRetLine = lcl_SvxLineToLine( pHori, bConvert);
+ break;
+ case MID_VERTICAL:
+ bSerialize = sal_True;
+ aRetLine = lcl_SvxLineToLine( pVert, bConvert);
+ break;
+ case MID_FLAGS:
+ bIntMember = sal_True;
+ if ( IsTable() )
+ nVal |= 0x01;
+ if ( IsDist() )
+ nVal |= 0x02;
+ if ( IsMinDist() )
+ nVal |= 0x04;
+ rVal <<= nVal;
+ break;
+ case MID_VALIDFLAGS:
+ bIntMember = sal_True;
+ nVal = nValidFlags;
+ rVal <<= nVal;
+ break;
+ case MID_DISTANCE:
+ bIntMember = sal_True;
+ rVal <<= (sal_Int32)(bConvert ? TWIP_TO_MM100_UNSIGNED(GetDefDist()) : GetDefDist());
+ break;
+ default: DBG_ERROR("Wrong MemberId!"); return sal_False;
+ }
+
+ if( !bIntMember )
+ {
+/*
+ if ( bSerialize )
+ {
+ ::com::sun::star::uno::Sequence < ::com::sun::star::uno::Any > aSeq(4);
+ aSeq[0] <<= aRetLine.Color;
+ aSeq[1] <<= aRetLine.InnerLineWidth;
+ aSeq[2] <<= aRetLine.OuterLineWidth;
+ aSeq[3] <<= aRetLine.LineDistance;
+ rVal <<= aSeq;
+ }
+ else
+ */
+ rVal <<= aRetLine;
+ }
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvxBoxInfoItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+ sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+// sal_uInt16 nLine = BOX_LINE_TOP;
+// sal_Bool bDistMember = sal_False;
+ nMemberId &= ~CONVERT_TWIPS;
+ sal_Bool bRet;
+ switch(nMemberId)
+ {
+ case 0:
+ {
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > aSeq;
+ if (( rVal >>= aSeq ) && ( aSeq.getLength() == 5 ))
+ {
+ // 2 BorderLines, flags, valid flags and distance
+ table::BorderLine aBorderLine;
+ SvxBorderLine aLine;
+ sal_Int16 nFlags( 0 );
+ sal_Int32 nVal( 0 );
+ if ( aSeq[0] >>= aBorderLine )
+ {
+ sal_Bool bSet = lcl_LineToSvxLine(aBorderLine, aLine, bConvert);
+ if ( bSet )
+ SetLine( &aLine, BOXINFO_LINE_HORI );
+ }
+ else
+ return sal_False;
+ if ( aSeq[1] >>= aBorderLine )
+ {
+ sal_Bool bSet = lcl_LineToSvxLine(aBorderLine, aLine, bConvert);
+ if ( bSet )
+ SetLine( &aLine, BOXINFO_LINE_VERT );
+ }
+ else
+ return sal_False;
+ if ( aSeq[2] >>= nFlags )
+ {
+ SetTable ( ( nFlags & 0x01 ) != 0 );
+ SetDist ( ( nFlags & 0x02 ) != 0 );
+ SetMinDist( ( nFlags & 0x04 ) != 0 );
+ }
+ else
+ return sal_False;
+ if ( aSeq[3] >>= nFlags )
+ nValidFlags = (BYTE)nFlags;
+ else
+ return sal_False;
+ if (( aSeq[4] >>= nVal ) && ( nVal >= 0 ))
+ {
+ if( bConvert )
+ nVal = MM100_TO_TWIP(nVal);
+ SetDefDist( (USHORT)nVal );
+ }
+ }
+ return sal_True;
+ }
+
+ case MID_HORIZONTAL:
+ case MID_VERTICAL:
+ {
+ if( !rVal.hasValue() )
+ return sal_False;
+
+ table::BorderLine aBorderLine;
+ if( rVal >>= aBorderLine )
+ {
+ // usual struct
+ }
+ else if (rVal.getValueTypeClass() == uno::TypeClass_SEQUENCE )
+ {
+ // serialization for basic macro recording
+ uno::Reference < script::XTypeConverter > xConverter
+ ( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.script.Converter")),
+ uno::UNO_QUERY );
+ uno::Any aNew;
+ uno::Sequence < uno::Any > aSeq;
+ try { aNew = xConverter->convertTo( rVal, ::getCppuType((const uno::Sequence < uno::Any >*)0) ); }
+ catch (uno::Exception&) {}
+
+ if( (aNew >>= aSeq) && aSeq.getLength() == 4 )
+ {
+ sal_Int32 nVal = 0;
+ if ( aSeq[0] >>= nVal )
+ aBorderLine.Color = nVal;
+ if ( aSeq[1] >>= nVal )
+ aBorderLine.InnerLineWidth = (sal_Int16) nVal;
+ if ( aSeq[2] >>= nVal )
+ aBorderLine.OuterLineWidth = (sal_Int16) nVal;
+ if ( aSeq[3] >>= nVal )
+ aBorderLine.LineDistance = (sal_Int16) nVal;
+ }
+ else
+ return sal_False;
+ }
+ else if (rVal.getValueType() == ::getCppuType((const ::com::sun::star::uno::Sequence < sal_Int16 >*)0) )
+ {
+ // serialization for basic macro recording
+ ::com::sun::star::uno::Sequence < sal_Int16 > aSeq;
+ rVal >>= aSeq;
+ if ( aSeq.getLength() == 4 )
+ {
+ aBorderLine.Color = aSeq[0];
+ aBorderLine.InnerLineWidth = aSeq[1];
+ aBorderLine.OuterLineWidth = aSeq[2];
+ aBorderLine.LineDistance = aSeq[3];
+ }
+ else
+ return sal_False;
+ }
+ else
+ return sal_False;
+
+ SvxBorderLine aLine;
+ sal_Bool bSet = lcl_LineToSvxLine(aBorderLine, aLine, bConvert);
+ if ( bSet )
+ SetLine( &aLine, nMemberId == MID_HORIZONTAL ? BOXINFO_LINE_HORI : BOXINFO_LINE_VERT );
+ break;
+ }
+ case MID_FLAGS:
+ {
+ sal_Int16 nFlags = sal_Int16();
+ bRet = (rVal >>= nFlags);
+ if ( bRet )
+ {
+ SetTable ( ( nFlags & 0x01 ) != 0 );
+ SetDist ( ( nFlags & 0x02 ) != 0 );
+ SetMinDist( ( nFlags & 0x04 ) != 0 );
+ }
+
+ break;
+ }
+ case MID_VALIDFLAGS:
+ {
+ sal_Int16 nFlags = sal_Int16();
+ bRet = (rVal >>= nFlags);
+ if ( bRet )
+ nValidFlags = (BYTE)nFlags;
+ break;
+ }
+ case MID_DISTANCE:
+ {
+ sal_Int32 nVal = 0;
+ bRet = (rVal >>= nVal);
+ if ( bRet && nVal>=0 )
+ {
+ if( bConvert )
+ nVal = MM100_TO_TWIP(nVal);
+ SetDefDist( (USHORT)nVal );
+ }
+ break;
+ }
+ default: DBG_ERROR("Wrong MemberId!"); return sal_False;
+ }
+
+ return sal_True;
+}
+
+// class SvxFmtBreakItem -------------------------------------------------
+
+int SvxFmtBreakItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rAttr ), "unequal types" );
+
+ return GetValue() == ( (SvxFmtBreakItem&)rAttr ).GetValue();
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxFmtBreakItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *
+) const
+{
+#ifndef SVX_LIGHT
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return SFX_ITEM_PRESENTATION_NONE;
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = GetValueTextByPos( GetValue() );
+ return ePres;
+ default: ;//prevent warning
+ }
+#endif // !SVX_LIGHT
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SvxFmtBreakItem::GetValueTextByPos( sal_uInt16 nPos ) const
+{
+ DBG_ASSERT( nPos < SVX_BREAK_END, "enum overflow!" );
+ XubString aStr( EditResId( RID_SVXITEMS_BREAK_BEGIN + nPos ) );
+ return aStr;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SvxFmtBreakItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/ ) const
+{
+ style::BreakType eBreak = style::BreakType_NONE;
+ switch ( (SvxBreak)GetValue() )
+ {
+ case SVX_BREAK_COLUMN_BEFORE: eBreak = style::BreakType_COLUMN_BEFORE; break;
+ case SVX_BREAK_COLUMN_AFTER: eBreak = style::BreakType_COLUMN_AFTER ; break;
+ case SVX_BREAK_COLUMN_BOTH: eBreak = style::BreakType_COLUMN_BOTH ; break;
+ case SVX_BREAK_PAGE_BEFORE: eBreak = style::BreakType_PAGE_BEFORE ; break;
+ case SVX_BREAK_PAGE_AFTER: eBreak = style::BreakType_PAGE_AFTER ; break;
+ case SVX_BREAK_PAGE_BOTH: eBreak = style::BreakType_PAGE_BOTH ; break;
+ default: ;//prevent warning
+ }
+ rVal <<= eBreak;
+ return sal_True;
+}
+// -----------------------------------------------------------------------
+sal_Bool SvxFmtBreakItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/ )
+{
+ style::BreakType nBreak;
+
+ if(!(rVal >>= nBreak))
+ {
+ sal_Int32 nValue = 0;
+ if(!(rVal >>= nValue))
+ return sal_False;
+
+ nBreak = (style::BreakType) nValue;
+ }
+
+ SvxBreak eBreak = SVX_BREAK_NONE;
+ switch( nBreak )
+ {
+ case style::BreakType_COLUMN_BEFORE: eBreak = SVX_BREAK_COLUMN_BEFORE; break;
+ case style::BreakType_COLUMN_AFTER: eBreak = SVX_BREAK_COLUMN_AFTER; break;
+ case style::BreakType_COLUMN_BOTH: eBreak = SVX_BREAK_COLUMN_BOTH; break;
+ case style::BreakType_PAGE_BEFORE: eBreak = SVX_BREAK_PAGE_BEFORE; break;
+ case style::BreakType_PAGE_AFTER: eBreak = SVX_BREAK_PAGE_AFTER; break;
+ case style::BreakType_PAGE_BOTH: eBreak = SVX_BREAK_PAGE_BOTH; break;
+ default: ;//prevent warning
+ }
+ SetValue((sal_uInt16) eBreak);
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxFmtBreakItem::Clone( SfxItemPool* ) const
+{
+ return new SvxFmtBreakItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxFmtBreakItem::Store( SvStream& rStrm , sal_uInt16 nItemVersion ) const
+{
+ rStrm << (sal_Int8)GetValue();
+ if( FMTBREAK_NOAUTO > nItemVersion )
+ rStrm << (sal_Int8)0x01;
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxFmtBreakItem::GetVersion( sal_uInt16 nFFVer ) const
+{
+ DBG_ASSERT( SOFFICE_FILEFORMAT_31==nFFVer ||
+ SOFFICE_FILEFORMAT_40==nFFVer ||
+ SOFFICE_FILEFORMAT_50==nFFVer,
+ "SvxFmtBreakItem: Gibt es ein neues Fileformat?" );
+ return SOFFICE_FILEFORMAT_31==nFFVer ||
+ SOFFICE_FILEFORMAT_40==nFFVer ? 0 : FMTBREAK_NOAUTO;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxFmtBreakItem::Create( SvStream& rStrm, sal_uInt16 nVersion ) const
+{
+ sal_Int8 eBreak, bDummy;
+ rStrm >> eBreak;
+ if( FMTBREAK_NOAUTO > nVersion )
+ rStrm >> bDummy;
+ return new SvxFmtBreakItem( (const SvxBreak)eBreak, Which() );
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxFmtBreakItem::GetValueCount() const
+{
+ return SVX_BREAK_END; // SVX_BREAK_PAGE_BOTH + 1
+}
+
+// class SvxFmtKeepItem -------------------------------------------------
+
+SfxPoolItem* SvxFmtKeepItem::Clone( SfxItemPool* ) const
+{
+ return new SvxFmtKeepItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxFmtKeepItem::Store( SvStream& rStrm , sal_uInt16 /*nItemVersion*/ ) const
+{
+ rStrm << (sal_Int8)GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxFmtKeepItem::Create( SvStream& rStrm, sal_uInt16 ) const
+{
+ sal_Int8 bIsKeep;
+ rStrm >> bIsKeep;
+ return new SvxFmtKeepItem( sal_Bool( bIsKeep != 0 ), Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxFmtKeepItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *
+ ) const
+{
+#ifndef SVX_LIGHT
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ sal_uInt16 nId = RID_SVXITEMS_FMTKEEP_FALSE;
+
+ if ( GetValue() )
+ nId = RID_SVXITEMS_FMTKEEP_TRUE;
+ rText = EE_RESSTR(nId);
+ return ePres;
+ }
+ default: ;//prevent warning
+ }
+#endif
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// class SvxLineItem ------------------------------------------------------
+
+SvxLineItem::SvxLineItem( const sal_uInt16 nId ) :
+
+ SfxPoolItem ( nId ),
+
+ pLine( NULL )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvxLineItem::SvxLineItem( const SvxLineItem& rCpy ) :
+
+ SfxPoolItem ( rCpy )
+{
+ pLine = rCpy.GetLine() ? new SvxBorderLine( *rCpy.GetLine() ) : 0;
+}
+
+
+// -----------------------------------------------------------------------
+
+SvxLineItem::~SvxLineItem()
+{
+ delete pLine;
+}
+
+// -----------------------------------------------------------------------
+
+SvxLineItem& SvxLineItem::operator=( const SvxLineItem& rLine )
+{
+ SetLine( rLine.GetLine() );
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxLineItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ return CmpBrdLn( pLine, ((SvxLineItem&)rAttr).GetLine() );
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxLineItem::Clone( SfxItemPool* ) const
+{
+ return new SvxLineItem( *this );
+}
+
+sal_Bool SvxLineItem::QueryValue( uno::Any& rVal, BYTE nMemId ) const
+{
+ sal_Bool bConvert = 0!=(nMemId&CONVERT_TWIPS);
+ nMemId &= ~CONVERT_TWIPS;
+ if ( nMemId == 0 )
+ {
+ rVal <<= uno::makeAny( lcl_SvxLineToLine(pLine, bConvert) );
+ return sal_True;
+ }
+ else if ( pLine )
+ {
+ switch ( nMemId )
+ {
+ case MID_FG_COLOR: rVal <<= sal_Int32(pLine->GetColor().GetColor()); break;
+ case MID_OUTER_WIDTH: rVal <<= sal_Int32(pLine->GetOutWidth()); break;
+ case MID_INNER_WIDTH: rVal <<= sal_Int32(pLine->GetInWidth( )); break;
+ case MID_DISTANCE: rVal <<= sal_Int32(pLine->GetDistance()); break;
+ default:
+ DBG_ERROR( "Wrong MemberId" );
+ return sal_False;
+ }
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvxLineItem::PutValue( const uno::Any& rVal, BYTE nMemId )
+{
+ sal_Bool bConvert = 0!=(nMemId&CONVERT_TWIPS);
+ nMemId &= ~CONVERT_TWIPS;
+ sal_Int32 nVal = 0;
+ if ( nMemId == 0 )
+ {
+ table::BorderLine aLine;
+ if ( rVal >>= aLine )
+ {
+ if ( !pLine )
+ pLine = new SvxBorderLine;
+ if( !lcl_LineToSvxLine(aLine, *pLine, bConvert) )
+ DELETEZ( pLine );
+ return sal_True;
+ }
+ return sal_False;
+ }
+ else if ( rVal >>= nVal )
+ {
+ if ( !pLine )
+ pLine = new SvxBorderLine;
+
+ switch ( nMemId )
+ {
+ case MID_FG_COLOR: pLine->SetColor( Color(nVal) ); break;
+ case MID_OUTER_WIDTH: pLine->SetOutWidth((USHORT)nVal); break;
+ case MID_INNER_WIDTH: pLine->SetInWidth((USHORT)nVal); break;
+ case MID_DISTANCE: pLine->SetDistance((USHORT)nVal); break;
+ default:
+ DBG_ERROR( "Wrong MemberId" );
+ return sal_False;
+ }
+
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxLineItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit eCoreUnit,
+ SfxMapUnit ePresUnit,
+ XubString& rText, const IntlWrapper *pIntl
+) const
+{
+#ifndef SVX_LIGHT
+ rText.Erase();
+
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ return SFX_ITEM_PRESENTATION_NONE;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ if ( pLine )
+ rText = pLine->GetValueString( eCoreUnit, ePresUnit, pIntl,
+ (SFX_ITEM_PRESENTATION_COMPLETE == ePres) );
+ return ePres;
+ }
+ default: ;//prevent warning
+ }
+#endif
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxLineItem::Store( SvStream& rStrm , sal_uInt16 /*nItemVersion*/ ) const
+{
+ if( pLine )
+ {
+ rStrm << pLine->GetColor()
+ << (short)pLine->GetOutWidth()
+ << (short)pLine->GetInWidth()
+ << (short)pLine->GetDistance();
+ }
+ else
+ rStrm << Color() << (short)0 << (short)0 << (short)0;
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxLineItem::ScaleMetrics( long nMult, long nDiv )
+{
+ if ( pLine ) pLine->ScaleMetrics( nMult, nDiv );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxLineItem::HasMetrics() const
+{
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxLineItem::Create( SvStream& rStrm, sal_uInt16 ) const
+{
+ SvxLineItem* _pLine = new SvxLineItem( Which() );
+ short nOutline, nInline, nDistance;
+ Color aColor;
+
+ rStrm >> aColor >> nOutline >> nInline >> nDistance;
+ if( nOutline )
+ {
+ SvxBorderLine aLine( &aColor, nOutline, nInline, nDistance );
+ _pLine->SetLine( &aLine );
+ }
+ return _pLine;
+}
+
+// -----------------------------------------------------------------------
+
+void SvxLineItem::SetLine( const SvxBorderLine* pNew )
+{
+ delete pLine;
+ pLine = pNew ? new SvxBorderLine( *pNew ) : 0;
+}
+
+#ifdef _MSC_VER
+#pragma optimize ( "", off )
+#endif
+
+// class SvxBrushItem ----------------------------------------------------
+
+#define LOAD_GRAPHIC ((sal_uInt16)0x0001)
+#define LOAD_LINK ((sal_uInt16)0x0002)
+#define LOAD_FILTER ((sal_uInt16)0x0004)
+
+// class SvxBrushItem_Impl -----------------------------------------------
+
+class SvxBrushItem_Impl
+{
+public:
+ GraphicObject* pGraphicObject;
+ sal_Int8 nGraphicTransparency; //contains a percentage value which is
+ //copied to the GraphicObject when necessary
+ Link aDoneLink;
+ SvStream* pStream;
+
+ SvxBrushItem_Impl( GraphicObject* p ) : pGraphicObject( p ), nGraphicTransparency(0), pStream(0) {}
+};
+
+// -----------------------------------------------------------------------
+
+void SvxBrushItem::SetDoneLink( const Link& rLink )
+{
+ pImpl->aDoneLink = rLink;
+}
+
+// -----------------------------------------------------------------------
+
+SvxBrushItem::SvxBrushItem( sal_uInt16 _nWhich ) :
+
+ SfxPoolItem( _nWhich ),
+
+ aColor ( COL_TRANSPARENT ),
+ pImpl ( new SvxBrushItem_Impl( 0 ) ),
+ pStrLink ( NULL ),
+ pStrFilter ( NULL ),
+ eGraphicPos ( GPOS_NONE ),
+ bLoadAgain ( sal_True )
+
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvxBrushItem::SvxBrushItem( const Color& rColor, sal_uInt16 _nWhich) :
+
+ SfxPoolItem( _nWhich ),
+
+ aColor ( rColor ),
+ pImpl ( new SvxBrushItem_Impl( 0 ) ),
+ pStrLink ( NULL ),
+ pStrFilter ( NULL ),
+ eGraphicPos ( GPOS_NONE ),
+ bLoadAgain ( sal_True )
+
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvxBrushItem::SvxBrushItem( const Graphic& rGraphic, SvxGraphicPosition ePos,
+ sal_uInt16 _nWhich ) :
+
+ SfxPoolItem( _nWhich ),
+
+ aColor ( COL_TRANSPARENT ),
+ pImpl ( new SvxBrushItem_Impl( new GraphicObject( rGraphic ) ) ),
+ pStrLink ( NULL ),
+ pStrFilter ( NULL ),
+ eGraphicPos ( ( GPOS_NONE != ePos ) ? ePos : GPOS_MM ),
+ bLoadAgain ( sal_True )
+
+{
+ DBG_ASSERT( GPOS_NONE != ePos, "SvxBrushItem-Ctor with GPOS_NONE == ePos" );
+}
+
+// -----------------------------------------------------------------------
+
+SvxBrushItem::SvxBrushItem( const GraphicObject& rGraphicObj,
+ SvxGraphicPosition ePos, sal_uInt16 _nWhich ) :
+
+ SfxPoolItem( _nWhich ),
+
+ aColor ( COL_TRANSPARENT ),
+ pImpl ( new SvxBrushItem_Impl( new GraphicObject( rGraphicObj ) ) ),
+ pStrLink ( NULL ),
+ pStrFilter ( NULL ),
+ eGraphicPos ( ( GPOS_NONE != ePos ) ? ePos : GPOS_MM ),
+ bLoadAgain ( sal_True )
+
+{
+ DBG_ASSERT( GPOS_NONE != ePos, "SvxBrushItem-Ctor with GPOS_NONE == ePos" );
+}
+
+// -----------------------------------------------------------------------
+
+SvxBrushItem::SvxBrushItem(
+ const String& rLink, const String& rFilter,
+ SvxGraphicPosition ePos, sal_uInt16 _nWhich ) :
+
+ SfxPoolItem( _nWhich ),
+
+ aColor ( COL_TRANSPARENT ),
+ pImpl ( new SvxBrushItem_Impl( NULL ) ),
+ pStrLink ( new String( rLink ) ),
+ pStrFilter ( new String( rFilter ) ),
+ eGraphicPos ( ( GPOS_NONE != ePos ) ? ePos : GPOS_MM ),
+ bLoadAgain ( sal_True )
+
+{
+ DBG_ASSERT( GPOS_NONE != ePos, "SvxBrushItem-Ctor with GPOS_NONE == ePos" );
+}
+
+// -----------------------------------------------------------------------
+
+SvxBrushItem::SvxBrushItem( SvStream& rStream, sal_uInt16 nVersion,
+ sal_uInt16 _nWhich ) :
+
+ SfxPoolItem( _nWhich ),
+
+ aColor ( COL_TRANSPARENT ),
+ pImpl ( new SvxBrushItem_Impl( NULL ) ),
+ pStrLink ( NULL ),
+ pStrFilter ( NULL ),
+ eGraphicPos ( GPOS_NONE )
+
+{
+ sal_Bool bTrans;
+ Color aTempColor;
+ Color aTempFillColor;
+ sal_Int8 nStyle;
+
+ rStream >> bTrans;
+ rStream >> aTempColor;
+ rStream >> aTempFillColor;
+ rStream >> nStyle;
+
+ switch ( nStyle )
+ {
+ case 8://BRUSH_25:
+ {
+ sal_uInt32 nRed = aTempColor.GetRed();
+ sal_uInt32 nGreen = aTempColor.GetGreen();
+ sal_uInt32 nBlue = aTempColor.GetBlue();
+ nRed += (sal_uInt32)(aTempFillColor.GetRed())*2;
+ nGreen += (sal_uInt32)(aTempFillColor.GetGreen())*2;
+ nBlue += (sal_uInt32)(aTempFillColor.GetBlue())*2;
+ aColor = Color( (sal_Int8)(nRed/3), (sal_Int8)(nGreen/3), (sal_Int8)(nBlue/3) );
+ }
+ break;
+
+ case 9://BRUSH_50:
+ {
+ sal_uInt32 nRed = aTempColor.GetRed();
+ sal_uInt32 nGreen = aTempColor.GetGreen();
+ sal_uInt32 nBlue = aTempColor.GetBlue();
+ nRed += (sal_uInt32)(aTempFillColor.GetRed());
+ nGreen += (sal_uInt32)(aTempFillColor.GetGreen());
+ nBlue += (sal_uInt32)(aTempFillColor.GetBlue());
+ aColor = Color( (sal_Int8)(nRed/2), (sal_Int8)(nGreen/2), (sal_Int8)(nBlue/2) );
+ }
+ break;
+
+ case 10://BRUSH_75:
+ {
+ sal_uInt32 nRed = aTempColor.GetRed()*2;
+ sal_uInt32 nGreen = aTempColor.GetGreen()*2;
+ sal_uInt32 nBlue = aTempColor.GetBlue()*2;
+ nRed += (sal_uInt32)(aTempFillColor.GetRed());
+ nGreen += (sal_uInt32)(aTempFillColor.GetGreen());
+ nBlue += (sal_uInt32)(aTempFillColor.GetBlue());
+ aColor = Color( (sal_Int8)(nRed/3), (sal_Int8)(nGreen/3), (sal_Int8)(nBlue/3) );
+ }
+ break;
+
+ case 0://BRUSH_NULL:
+ aColor = Color( COL_TRANSPARENT );
+ break;
+
+ default:
+ aColor = aTempColor;
+ }
+
+ if ( nVersion >= BRUSH_GRAPHIC_VERSION )
+ {
+ sal_uInt16 nDoLoad = 0;
+ sal_Int8 nPos;
+
+ rStream >> nDoLoad;
+
+ if ( nDoLoad & LOAD_GRAPHIC )
+ {
+ Graphic aGraphic;
+
+ rStream >> aGraphic;
+ pImpl->pGraphicObject = new GraphicObject( aGraphic );
+
+ if( SVSTREAM_FILEFORMAT_ERROR == rStream.GetError() )
+ {
+ rStream.ResetError();
+ rStream.SetError( ERRCODE_SVX_GRAPHIC_WRONG_FILEFORMAT|
+ ERRCODE_WARNING_MASK );
+ }
+ }
+
+ if ( nDoLoad & LOAD_LINK )
+ {
+ String aRel;
+ // UNICODE: rStream >> aRel;
+ rStream.ReadByteString(aRel);
+
+ // TODO/MBA: how can we get a BaseURL here?!
+ DBG_ERROR("No BaseURL!");
+ String aAbs = INetURLObject::GetAbsURL( String(), aRel );
+ DBG_ASSERT( aAbs.Len(), "Invalid URL!" );
+ pStrLink = new String( aAbs );
+ }
+
+ if ( nDoLoad & LOAD_FILTER )
+ {
+ pStrFilter = new String;
+ // UNICODE: rStream >> *pStrFilter;
+ rStream.ReadByteString(*pStrFilter);
+ }
+
+ rStream >> nPos;
+
+ eGraphicPos = (SvxGraphicPosition)nPos;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SvxBrushItem::SvxBrushItem( const SvxBrushItem& rItem ) :
+
+ SfxPoolItem( rItem.Which() ),
+
+ pImpl ( new SvxBrushItem_Impl( NULL ) ),
+ pStrLink ( NULL ),
+ pStrFilter ( NULL ),
+ eGraphicPos ( GPOS_NONE ),
+ bLoadAgain ( sal_True )
+
+{
+ *this = rItem;
+}
+
+// -----------------------------------------------------------------------
+
+SvxBrushItem::~SvxBrushItem()
+{
+ delete pImpl->pGraphicObject;
+ delete pImpl;
+ delete pStrLink;
+ delete pStrFilter;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxBrushItem::GetVersion( sal_uInt16 /*nFileVersion*/ ) const
+{
+ return BRUSH_GRAPHIC_VERSION;
+}
+
+// -----------------------------------------------------------------------
+inline sal_Int8 lcl_PercentToTransparency(long nPercent)
+{
+ //0xff must not be returned!
+ return sal_Int8(nPercent ? (50 + 0xfe * nPercent) / 100 : 0);
+}
+inline sal_Int8 lcl_TransparencyToPercent(sal_Int32 nTrans)
+{
+ return (sal_Int8)((nTrans * 100 + 127) / 254);
+}
+
+sal_Bool SvxBrushItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch( nMemberId)
+ {
+ case MID_BACK_COLOR:
+ rVal <<= (sal_Int32)( aColor.GetColor() );
+ break;
+ case MID_BACK_COLOR_R_G_B:
+ rVal <<= (sal_Int32)( aColor.GetRGBColor() );
+ break;
+ case MID_BACK_COLOR_TRANSPARENCY:
+ rVal <<= lcl_TransparencyToPercent(aColor.GetTransparency());
+ break;
+ case MID_GRAPHIC_POSITION:
+ rVal <<= (style::GraphicLocation)(sal_Int16)eGraphicPos;
+ break;
+
+ case MID_GRAPHIC:
+ DBG_ERRORFILE( "not implemented" );
+ break;
+
+ case MID_GRAPHIC_TRANSPARENT:
+ rVal = Bool2Any( aColor.GetTransparency() == 0xff );
+ break;
+
+ case MID_GRAPHIC_URL:
+ {
+ OUString sLink;
+ if ( pStrLink )
+ sLink = *pStrLink;
+ else if( pImpl->pGraphicObject )
+ {
+ OUString sPrefix(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_GRAPHOBJ_URLPREFIX));
+ String sId( pImpl->pGraphicObject->GetUniqueID(),
+ RTL_TEXTENCODING_ASCII_US );
+ sLink = sPrefix;
+ sLink += OUString(sId);
+ }
+ rVal <<= sLink;
+ }
+ break;
+
+ case MID_GRAPHIC_FILTER:
+ {
+ OUString sFilter;
+ if ( pStrFilter )
+ sFilter = *pStrFilter;
+ rVal <<= sFilter;
+ }
+ break;
+ case MID_GRAPHIC_TRANSPARENCY :
+ rVal <<= pImpl->nGraphicTransparency;
+ break;
+ }
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvxBrushItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch( nMemberId)
+ {
+ case MID_BACK_COLOR:
+ case MID_BACK_COLOR_R_G_B:
+ {
+ sal_Int32 nCol = 0;
+ if ( !( rVal >>= nCol ) )
+ return sal_False;
+ if(MID_BACK_COLOR_R_G_B == nMemberId)
+ {
+ nCol = COLORDATA_RGB( nCol );
+ nCol += aColor.GetColor() & 0xff000000;
+ }
+ aColor = Color( nCol );
+ }
+ break;
+ case MID_BACK_COLOR_TRANSPARENCY:
+ {
+ sal_Int32 nTrans = 0;
+ if ( !( rVal >>= nTrans ) || nTrans < 0 || nTrans > 100 )
+ return sal_False;
+ aColor.SetTransparency(lcl_PercentToTransparency(nTrans));
+ }
+ break;
+
+ case MID_GRAPHIC_POSITION:
+ {
+ style::GraphicLocation eLocation;
+ if ( !( rVal>>=eLocation ) )
+ {
+ sal_Int32 nValue = 0;
+ if ( !( rVal >>= nValue ) )
+ return sal_False;
+ eLocation = (style::GraphicLocation)nValue;
+ }
+ SetGraphicPos( (SvxGraphicPosition)(sal_uInt16)eLocation );
+ }
+ break;
+
+ case MID_GRAPHIC:
+ DBG_ERRORFILE( "not implemented" );
+ break;
+
+ case MID_GRAPHIC_TRANSPARENT:
+ aColor.SetTransparency( Any2Bool( rVal ) ? 0xff : 0 );
+ break;
+
+ case MID_GRAPHIC_URL:
+ {
+ if ( rVal.getValueType() == ::getCppuType( (OUString*)0 ) )
+ {
+ OUString sLink;
+ rVal >>= sLink;
+ if( 0 == sLink.compareToAscii( UNO_NAME_GRAPHOBJ_URLPKGPREFIX,
+ sizeof(UNO_NAME_GRAPHOBJ_URLPKGPREFIX)-1 ) )
+ {
+ DBG_ERROR( "package urls aren't implemented" );
+ }
+ else if( 0 == sLink.compareToAscii( UNO_NAME_GRAPHOBJ_URLPREFIX,
+ sizeof(UNO_NAME_GRAPHOBJ_URLPREFIX)-1 ) )
+ {
+ DELETEZ( pStrLink );
+ String sTmp( sLink );
+ ByteString sId( sTmp.Copy(
+ sizeof(UNO_NAME_GRAPHOBJ_URLPREFIX)-1),
+ RTL_TEXTENCODING_ASCII_US );
+ GraphicObject *pOldGrfObj = pImpl->pGraphicObject;
+ pImpl->pGraphicObject = new GraphicObject( sId );
+ ApplyGraphicTransparency_Impl();
+ delete pOldGrfObj;
+ }
+ else
+ {
+ SetGraphicLink(sLink);
+ }
+ if ( sLink.getLength() && eGraphicPos == GPOS_NONE )
+ eGraphicPos = GPOS_MM;
+ else if( !sLink.getLength() )
+ eGraphicPos = GPOS_NONE;
+ }
+ }
+ break;
+
+ case MID_GRAPHIC_FILTER:
+ {
+ if( rVal.getValueType() == ::getCppuType( (OUString*)0 ) )
+ {
+ OUString sLink;
+ rVal >>= sLink;
+ SetGraphicFilter( sLink );
+ }
+ }
+ break;
+ case MID_GRAPHIC_TRANSPARENCY :
+ {
+ sal_Int32 nTmp = 0;
+ rVal >>= nTmp;
+ if(nTmp >= 0 && nTmp <= 100)
+ {
+ pImpl->nGraphicTransparency = sal_Int8(nTmp);
+ if(pImpl->pGraphicObject)
+ ApplyGraphicTransparency_Impl();
+ }
+ }
+ break;
+ }
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+SfxItemPresentation SvxBrushItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *
+ ) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ if ( GPOS_NONE == eGraphicPos )
+ {
+ rText = ::GetColorString( aColor );
+ rText += cpDelim;
+ sal_uInt16 nId = RID_SVXITEMS_TRANSPARENT_FALSE;
+
+ if ( aColor.GetTransparency() )
+ nId = RID_SVXITEMS_TRANSPARENT_TRUE;
+ rText += EE_RESSTR(nId);
+ }
+ else
+ {
+ rText = EE_RESSTR(RID_SVXITEMS_GRAPHIC);
+ }
+
+ return ePres;
+ }
+ default: ;//prevent warning
+ }
+
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+SvxBrushItem& SvxBrushItem::operator=( const SvxBrushItem& rItem )
+{
+ aColor = rItem.aColor;
+ eGraphicPos = rItem.eGraphicPos;
+
+ DELETEZ( pImpl->pGraphicObject );
+ DELETEZ( pStrLink );
+ DELETEZ( pStrFilter );
+
+ if ( GPOS_NONE != eGraphicPos )
+ {
+ if ( rItem.pStrLink )
+ pStrLink = new String( *rItem.pStrLink );
+ if ( rItem.pStrFilter )
+ pStrFilter = new String( *rItem.pStrFilter );
+ if ( rItem.pImpl->pGraphicObject )
+ {
+ pImpl->pGraphicObject = new GraphicObject( *rItem.pImpl->pGraphicObject );
+ }
+ }
+ pImpl->nGraphicTransparency = rItem.pImpl->nGraphicTransparency;
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxBrushItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ SvxBrushItem& rCmp = (SvxBrushItem&)rAttr;
+ sal_Bool bEqual = ( aColor == rCmp.aColor && eGraphicPos == rCmp.eGraphicPos &&
+ pImpl->nGraphicTransparency == rCmp.pImpl->nGraphicTransparency);
+
+ if ( bEqual )
+ {
+ if ( GPOS_NONE != eGraphicPos )
+ {
+ if ( !rCmp.pStrLink )
+ bEqual = !pStrLink;
+ else
+ bEqual = pStrLink && ( *pStrLink == *rCmp.pStrLink );
+
+ if ( bEqual )
+ {
+ if ( !rCmp.pStrFilter )
+ bEqual = !pStrFilter;
+ else
+ bEqual = pStrFilter && ( *pStrFilter == *rCmp.pStrFilter );
+ }
+
+ if ( bEqual && !rCmp.pStrLink )
+ {
+ if ( !rCmp.pImpl->pGraphicObject )
+ bEqual = !pImpl->pGraphicObject;
+ else
+ bEqual = pImpl->pGraphicObject &&
+ ( *pImpl->pGraphicObject == *rCmp.pImpl->pGraphicObject );
+ }
+ }
+ }
+
+ return bEqual;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxBrushItem::Clone( SfxItemPool* ) const
+{
+ return new SvxBrushItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxBrushItem::Create( SvStream& rStream, sal_uInt16 nVersion ) const
+{
+ return new SvxBrushItem( rStream, nVersion, Which() );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxBrushItem::Store( SvStream& rStream , sal_uInt16 /*nItemVersion*/ ) const
+{
+ rStream << (sal_Bool)sal_False;
+ rStream << aColor;
+ rStream << aColor;
+ rStream << (sal_Int8)(aColor.GetTransparency() > 0 ? 0 : 1); //BRUSH_NULL : BRUSH_SOLID
+
+ sal_uInt16 nDoLoad = 0;
+
+ if ( pImpl->pGraphicObject && !pStrLink )
+ nDoLoad |= LOAD_GRAPHIC;
+ if ( pStrLink )
+ nDoLoad |= LOAD_LINK;
+ if ( pStrFilter )
+ nDoLoad |= LOAD_FILTER;
+ rStream << nDoLoad;
+
+ if ( pImpl->pGraphicObject && !pStrLink )
+ rStream << pImpl->pGraphicObject->GetGraphic();
+ if ( pStrLink )
+ {
+ DBG_ERROR("No BaseURL!");
+ // TODO/MBA: how to get a BaseURL?!
+ String aRel = INetURLObject::GetRelURL( String(), *pStrLink );
+ // UNICODE: rStream << aRel;
+ rStream.WriteByteString(aRel);
+ }
+ if ( pStrFilter )
+ {
+ // UNICODE: rStream << *pStrFilter;
+ rStream.WriteByteString(*pStrFilter);
+ }
+ rStream << (sal_Int8)eGraphicPos;
+ return rStream;
+}
+
+// -----------------------------------------------------------------------
+// const wegcasten, da const als logisches const zu verstehen ist
+// wenn GetGraphic() gerufen wird, soll sich das Item darum kuemmern,
+// eine gelinkte Grafik zu holen.
+// -----------------------------------------------------------------------
+
+void SvxBrushItem::PurgeGraphic() const
+{
+ PurgeMedium();
+ DELETEZ( pImpl->pGraphicObject );
+ ((SvxBrushItem*)this)->bLoadAgain = sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+void SvxBrushItem::PurgeMedium() const
+{
+ DELETEZ( pImpl->pStream );
+}
+
+// -----------------------------------------------------------------------
+const GraphicObject* SvxBrushItem::GetGraphicObject() const
+{
+ if ( bLoadAgain && pStrLink && !pImpl->pGraphicObject )
+ // wenn Grafik schon geladen, als Cache benutzen
+ {
+ //JP 29.6.2001: only with "valid" names - empty names now allowed
+ if( pStrLink->Len() )
+ {
+ // currently we don't have asynchronous processing
+/* if( pImpl->aDoneLink.IsSet() )
+ {
+ // Auf besonderen Wunsch des Writers wird der synchrone und der
+ // asynchrone Fall was die Benachrichtigung angeht unterschiedlich
+ // behandelt. Der Callback erfolgt nur bei asynchronem Eintreffen
+ // der Daten
+
+ Link aTmp = pImpl->aDoneLink;
+ pImpl->aDoneLink = Link();
+ pImpl->xMedium->DownLoad(
+ STATIC_LINK( this, SvxBrushItem, DoneHdl_Impl ) );
+ pImpl->aDoneLink = aTmp;
+ } */
+
+ pImpl->pStream = utl::UcbStreamHelper::CreateStream( *pStrLink, STREAM_STD_READ );
+ if( pImpl->pStream && !pImpl->pStream->GetError() )
+ {
+ Graphic aGraphic;
+ int nRes;
+ pImpl->pStream->Seek( STREAM_SEEK_TO_BEGIN );
+ nRes = GraphicFilter::GetGraphicFilter()->
+ ImportGraphic( aGraphic, *pStrLink, *pImpl->pStream,
+ GRFILTER_FORMAT_DONTKNOW, NULL, GRFILTER_I_FLAGS_DONT_SET_LOGSIZE_FOR_JPEG );
+
+ if( nRes != GRFILTER_OK )
+ {
+ const_cast < SvxBrushItem*> (this)->bLoadAgain = sal_False;
+ }
+ else
+ {
+ pImpl->pGraphicObject = new GraphicObject;
+ pImpl->pGraphicObject->SetGraphic( aGraphic );
+ const_cast < SvxBrushItem*> (this)->ApplyGraphicTransparency_Impl();
+ }
+ }
+ else
+ {
+ const_cast < SvxBrushItem*> (this)->bLoadAgain = sal_False;
+ }
+
+ // currently we don't have asynchronous processing
+// pThis->pImpl->aDoneLink.Call( pThis );
+ }
+ }
+
+ return pImpl->pGraphicObject;
+}
+
+// -----------------------------------------------------------------------
+
+const Graphic* SvxBrushItem::GetGraphic() const
+{
+ const GraphicObject* pGrafObj = GetGraphicObject();
+ return( pGrafObj ? &( pGrafObj->GetGraphic() ) : NULL );
+}
+
+// -----------------------------------------------------------------------
+
+void SvxBrushItem::SetGraphicPos( SvxGraphicPosition eNew )
+{
+ eGraphicPos = eNew;
+
+ if ( GPOS_NONE == eGraphicPos )
+ {
+ DELETEZ( pImpl->pGraphicObject );
+ DELETEZ( pStrLink );
+ DELETEZ( pStrFilter );
+ }
+ else
+ {
+ if ( !pImpl->pGraphicObject && !pStrLink )
+ {
+ pImpl->pGraphicObject = new GraphicObject; // dummy anlegen
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SvxBrushItem::SetGraphic( const Graphic& rNew )
+{
+ if ( !pStrLink )
+ {
+ if ( pImpl->pGraphicObject )
+ pImpl->pGraphicObject->SetGraphic( rNew );
+ else
+ pImpl->pGraphicObject = new GraphicObject( rNew );
+
+ ApplyGraphicTransparency_Impl();
+
+ if ( GPOS_NONE == eGraphicPos )
+ eGraphicPos = GPOS_MM; // None waere Brush, also Default: Mitte
+ }
+ else
+ {
+ DBG_ERROR( "SetGraphic() on linked graphic! :-/" );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SvxBrushItem::SetGraphicObject( const GraphicObject& rNewObj )
+{
+ if ( !pStrLink )
+ {
+ if ( pImpl->pGraphicObject )
+ *pImpl->pGraphicObject = rNewObj;
+ else
+ pImpl->pGraphicObject = new GraphicObject( rNewObj );
+
+ ApplyGraphicTransparency_Impl();
+
+ if ( GPOS_NONE == eGraphicPos )
+ eGraphicPos = GPOS_MM; // None waere Brush, also Default: Mitte
+ }
+ else
+ {
+ DBG_ERROR( "SetGraphic() on linked graphic! :-/" );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SvxBrushItem::SetGraphicLink( const String& rNew )
+{
+ if ( !rNew.Len() )
+ DELETEZ( pStrLink );
+ else
+ {
+ if ( pStrLink )
+ *pStrLink = rNew;
+ else
+ pStrLink = new String( rNew );
+
+ DELETEZ( pImpl->pGraphicObject );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SvxBrushItem::SetGraphicFilter( const String& rNew )
+{
+ if ( !rNew.Len() )
+ DELETEZ( pStrFilter );
+ else
+ {
+ if ( pStrFilter )
+ *pStrFilter = rNew;
+ else
+ pStrFilter = new String( rNew );
+ }
+}
+
+//static
+SvxGraphicPosition SvxBrushItem::WallpaperStyle2GraphicPos( WallpaperStyle eStyle )
+{
+ SvxGraphicPosition eResult;
+ // der Switch ist nicht der schnellste, dafuer aber am sichersten
+ switch( eStyle )
+ {
+ case WALLPAPER_NULL: eResult = GPOS_NONE; break;
+ case WALLPAPER_TILE: eResult = GPOS_TILED; break;
+ case WALLPAPER_CENTER: eResult = GPOS_MM; break;
+ case WALLPAPER_SCALE: eResult = GPOS_AREA; break;
+ case WALLPAPER_TOPLEFT: eResult = GPOS_LT; break;
+ case WALLPAPER_TOP: eResult = GPOS_MT; break;
+ case WALLPAPER_TOPRIGHT: eResult = GPOS_RT; break;
+ case WALLPAPER_LEFT: eResult = GPOS_LM; break;
+ case WALLPAPER_RIGHT: eResult = GPOS_RM; break;
+ case WALLPAPER_BOTTOMLEFT: eResult = GPOS_LB; break;
+ case WALLPAPER_BOTTOM: eResult = GPOS_MB; break;
+ case WALLPAPER_BOTTOMRIGHT: eResult = GPOS_RB; break;
+ default: eResult = GPOS_NONE;
+ }
+ return eResult;
+};
+
+//static
+WallpaperStyle SvxBrushItem::GraphicPos2WallpaperStyle( SvxGraphicPosition ePos )
+{
+ WallpaperStyle eResult;
+ switch( ePos )
+ {
+ case GPOS_NONE: eResult = WALLPAPER_NULL; break;
+ case GPOS_TILED: eResult = WALLPAPER_TILE; break;
+ case GPOS_MM: eResult = WALLPAPER_CENTER; break;
+ case GPOS_AREA: eResult = WALLPAPER_SCALE; break;
+ case GPOS_LT: eResult = WALLPAPER_TOPLEFT; break;
+ case GPOS_MT: eResult = WALLPAPER_TOP; break;
+ case GPOS_RT: eResult = WALLPAPER_TOPRIGHT; break;
+ case GPOS_LM: eResult = WALLPAPER_LEFT; break;
+ case GPOS_RM: eResult = WALLPAPER_RIGHT; break;
+ case GPOS_LB: eResult = WALLPAPER_BOTTOMLEFT; break;
+ case GPOS_MB: eResult = WALLPAPER_BOTTOM; break;
+ case GPOS_RB: eResult = WALLPAPER_BOTTOMRIGHT; break;
+ default: eResult = WALLPAPER_NULL;
+ }
+ return eResult;
+}
+
+
+SvxBrushItem::SvxBrushItem( const CntWallpaperItem& rItem, sal_uInt16 _nWhich ) :
+ SfxPoolItem( _nWhich ),
+ pImpl( new SvxBrushItem_Impl( 0 ) ),
+ pStrLink(0),
+ pStrFilter(0),
+ bLoadAgain( sal_True )
+{
+ aColor = rItem.GetColor();
+
+ if( rItem.GetBitmapURL().Len() )
+ {
+ pStrLink = new String( rItem.GetBitmapURL() );
+ SetGraphicPos( WallpaperStyle2GraphicPos((WallpaperStyle)rItem.GetStyle() ) );
+ }
+}
+
+CntWallpaperItem* SvxBrushItem::CreateCntWallpaperItem() const
+{
+ CntWallpaperItem* pItem = new CntWallpaperItem( 0 );
+ pItem->SetColor( aColor.GetColor() );
+ pItem->SetStyle( (USHORT)GraphicPos2WallpaperStyle( GetGraphicPos() ) );
+ sal_Bool bLink = (pStrLink != 0);
+ if( bLink )
+ {
+ String aURL = *pStrLink;
+ pItem->SetBitmapURL( aURL );
+ }
+ if( pImpl->pGraphicObject )
+ {
+ DBG_ERRORFILE( "Don't know what to do with a graphic" );
+ }
+// pItem->SetGraphic( *pImpl->pGraphic, bLink );
+
+ return pItem;
+}
+
+#ifdef _MSC_VER
+#pragma optimize ( "", on )
+#endif
+/* -----------------------------16.08.2002 09:18------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SvxBrushItem::ApplyGraphicTransparency_Impl()
+{
+ DBG_ASSERT(pImpl->pGraphicObject, "no GraphicObject available" );
+ if(pImpl->pGraphicObject)
+ {
+ GraphicAttr aAttr(pImpl->pGraphicObject->GetAttr());
+ aAttr.SetTransparency(lcl_PercentToTransparency(
+ pImpl->nGraphicTransparency));
+ pImpl->pGraphicObject->SetAttr(aAttr);
+ }
+}
+// class SvxFrameDirectionItem ----------------------------------------------
+
+SvxFrameDirectionItem::SvxFrameDirectionItem( USHORT _nWhich )
+ : SfxUInt16Item( _nWhich, (UINT16)FRMDIR_HORI_LEFT_TOP )
+{
+}
+
+SvxFrameDirectionItem::SvxFrameDirectionItem( SvxFrameDirection nValue ,
+ USHORT _nWhich )
+ : SfxUInt16Item( _nWhich, (UINT16)nValue )
+{
+}
+
+SvxFrameDirectionItem::~SvxFrameDirectionItem()
+{
+}
+
+int SvxFrameDirectionItem::operator==( const SfxPoolItem& rCmp ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rCmp), "unequal types" );
+
+ return GetValue() == ((SvxFrameDirectionItem&)rCmp).GetValue();
+}
+
+SfxPoolItem* SvxFrameDirectionItem::Clone( SfxItemPool * ) const
+{
+ return new SvxFrameDirectionItem( *this );
+}
+
+SfxPoolItem* SvxFrameDirectionItem::Create( SvStream & rStrm, USHORT /*nVer*/ ) const
+{
+ sal_uInt16 nValue;
+ rStrm >> nValue;
+ return new SvxFrameDirectionItem( (SvxFrameDirection)nValue, Which() );
+}
+
+SvStream& SvxFrameDirectionItem::Store( SvStream & rStrm, USHORT /*nIVer*/ ) const
+{
+ sal_uInt16 nValue = GetValue();
+ rStrm << nValue;
+ return rStrm;
+}
+
+USHORT SvxFrameDirectionItem::GetVersion( USHORT nFVer ) const
+{
+ return SOFFICE_FILEFORMAT_50 > nFVer ? USHRT_MAX : 0;
+}
+
+SfxItemPresentation SvxFrameDirectionItem::GetPresentation(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *) const
+{
+ SfxItemPresentation eRet = ePres;
+ switch( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ break;
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = EE_RESSTR( RID_SVXITEMS_FRMDIR_BEGIN + GetValue() );
+ break;
+
+ default:
+ eRet = SFX_ITEM_PRESENTATION_NONE;
+ }
+ return eRet;
+}
+
+sal_Bool SvxFrameDirectionItem::PutValue( const com::sun::star::uno::Any& rVal,
+ BYTE )
+{
+ sal_Int16 nVal = sal_Int16();
+ sal_Bool bRet = ( rVal >>= nVal );
+ if( bRet )
+ {
+ // translate WritingDirection2 constants into SvxFrameDirection
+ switch( nVal )
+ {
+ case text::WritingMode2::LR_TB:
+ SetValue( FRMDIR_HORI_LEFT_TOP );
+ break;
+ case text::WritingMode2::RL_TB:
+ SetValue( FRMDIR_HORI_RIGHT_TOP );
+ break;
+ case text::WritingMode2::TB_RL:
+ SetValue( FRMDIR_VERT_TOP_RIGHT );
+ break;
+ case text::WritingMode2::TB_LR:
+ SetValue( FRMDIR_VERT_TOP_LEFT );
+ break;
+ case text::WritingMode2::PAGE:
+ SetValue( FRMDIR_ENVIRONMENT );
+ break;
+ default:
+ bRet = sal_False;
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+sal_Bool SvxFrameDirectionItem::QueryValue( com::sun::star::uno::Any& rVal,
+ BYTE ) const
+{
+ // translate SvxFrameDirection into WritingDirection2
+ sal_Int16 nVal;
+ sal_Bool bRet = sal_True;
+ switch( GetValue() )
+ {
+ case FRMDIR_HORI_LEFT_TOP:
+ nVal = text::WritingMode2::LR_TB;
+ break;
+ case FRMDIR_HORI_RIGHT_TOP:
+ nVal = text::WritingMode2::RL_TB;
+ break;
+ case FRMDIR_VERT_TOP_RIGHT:
+ nVal = text::WritingMode2::TB_RL;
+ break;
+ case FRMDIR_VERT_TOP_LEFT:
+ nVal = text::WritingMode2::TB_LR;
+ break;
+ case FRMDIR_ENVIRONMENT:
+ nVal = text::WritingMode2::PAGE;
+ break;
+ default:
+ DBG_ERROR("Unknown SvxFrameDirection value!");
+ bRet = sal_False;
+ break;
+ }
+
+ // return value + error state
+ if( bRet )
+ {
+ rVal <<= nVal;
+ }
+ return bRet;
+}
+
diff --git a/editeng/source/items/itemtype.cxx b/editeng/source/items/itemtype.cxx
new file mode 100644
index 0000000000..321961f402
--- /dev/null
+++ b/editeng/source/items/itemtype.cxx
@@ -0,0 +1,242 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: itemtype.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+// include ---------------------------------------------------------------
+#include <tools/list.hxx>
+#include <vcl/outdev.hxx>
+#include <editeng/editrids.hrc>
+#include <unotools/intlwrapper.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <editeng/itemtype.hxx>
+#include <editeng/eerdll.hxx>
+
+// -----------------------------------------------------------------------
+
+XubString GetMetricText( long nVal, SfxMapUnit eSrcUnit, SfxMapUnit eDestUnit, const IntlWrapper* pIntl )
+{
+ sal_Bool bNeg = sal_False;
+ long nRet = 0;
+ XubString sRet;
+
+ if ( nVal < 0 )
+ {
+ bNeg = sal_True;
+ nVal *= -1;
+ }
+
+ switch ( eDestUnit )
+ {
+ case SFX_MAPUNIT_100TH_MM:
+ case SFX_MAPUNIT_10TH_MM:
+ case SFX_MAPUNIT_MM:
+ case SFX_MAPUNIT_CM:
+ {
+ nRet = (long)OutputDevice::LogicToLogic(
+ nVal, (MapUnit)eSrcUnit, (MapUnit)SFX_MAPUNIT_100TH_MM );
+
+ switch ( eDestUnit )
+ {
+ case SFX_MAPUNIT_100TH_MM: nRet *= 1000; break;
+ case SFX_MAPUNIT_10TH_MM: nRet *= 100; break;
+ case SFX_MAPUNIT_MM: nRet *= 10; break;
+ default: ;//prevent warning
+ }
+ break;
+ }
+
+ case SFX_MAPUNIT_1000TH_INCH:
+ case SFX_MAPUNIT_100TH_INCH:
+ case SFX_MAPUNIT_10TH_INCH:
+ case SFX_MAPUNIT_INCH:
+ {
+ nRet = (long)OutputDevice::LogicToLogic(
+ nVal, (MapUnit)eSrcUnit, (MapUnit)SFX_MAPUNIT_1000TH_INCH );
+
+ switch ( eDestUnit )
+ {
+ case SFX_MAPUNIT_1000TH_INCH: nRet *= 1000; break;
+ case SFX_MAPUNIT_100TH_INCH: nRet *= 100; break;
+ case SFX_MAPUNIT_10TH_INCH: nRet *= 10; break;
+ default: ;//prevent warning
+ }
+ break;
+ }
+
+ case SFX_MAPUNIT_POINT:
+ case SFX_MAPUNIT_TWIP:
+ case SFX_MAPUNIT_PIXEL:
+ return String::CreateFromInt32( (long)OutputDevice::LogicToLogic(
+ nVal, (MapUnit)eSrcUnit, (MapUnit)eDestUnit ));
+
+ default:
+ DBG_ERROR( "not supported mapunit" );
+ return sRet;
+ }
+
+ if ( SFX_MAPUNIT_CM == eDestUnit || SFX_MAPUNIT_INCH == eDestUnit )
+ {
+ long nMod = nRet % 10;
+
+ if ( nMod > 4 )
+ nRet += 10 - nMod;
+ else if ( nMod > 0 )
+ nRet -= nMod;
+ }
+
+ if ( bNeg )
+ sRet += sal_Unicode('-');
+
+ long nDiff = 1000;
+ for( int nDigits = 4; nDigits; --nDigits, nDiff /= 10 )
+ {
+ if ( nRet < nDiff )
+ sRet += sal_Unicode('0');
+ else
+ sRet += String::CreateFromInt32( nRet / nDiff );
+ nRet %= nDiff;
+ if( 4 == nDigits )
+ {
+// DBG_ASSERT(pIntl, "no IntlWrapper* set")
+ if(pIntl)
+ sRet += pIntl->getLocaleData()->getNumDecimalSep();
+ else
+ sRet += ',';
+ if( !nRet )
+ {
+ sRet += sal_Unicode('0');
+ break;
+ }
+ }
+ else if( !nRet )
+ break;
+ }
+ return sRet;
+}
+
+// -----------------------------------------------------------------------
+
+XubString GetSvxString( sal_uInt16 nId )
+{
+ return EE_RESSTR( nId );
+}
+
+#ifndef SVX_LIGHT
+
+// -----------------------------------------------------------------------
+
+XubString GetColorString( const Color& rCol )
+{
+ XubString sStr;
+
+ FASTBOOL bFound = sal_False;
+ ColorData nColData =
+ RGB_COLORDATA( rCol.GetRed(), rCol.GetGreen(), rCol.GetBlue() );
+ sal_uInt16 nColor = 0, nColCount = 16;
+
+ static ColorData aColAry[] = {
+ COL_BLACK, COL_BLUE, COL_GREEN, COL_CYAN,
+ COL_RED, COL_MAGENTA, COL_BROWN, COL_GRAY,
+ COL_LIGHTGRAY, COL_LIGHTBLUE, COL_LIGHTGREEN, COL_LIGHTCYAN,
+ COL_LIGHTRED, COL_LIGHTMAGENTA, COL_YELLOW, COL_WHITE };
+
+ while ( !bFound && nColor < nColCount )
+ {
+ if ( aColAry[nColor] == nColData )
+ bFound = sal_True;
+ else
+ nColor++;
+ }
+
+ if ( nColor < nColCount )
+ sStr = EE_RESSTR( RID_SVXITEMS_COLOR_BEGIN + nColor + 1 );
+
+ if ( !sStr.Len() )
+ {
+ sStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "RGB" ));
+ sStr += sal_Unicode('(');
+ sStr += String::CreateFromInt32( rCol.GetRed() );
+ sStr += cpDelim;
+ sStr += String::CreateFromInt32( rCol.GetGreen() );
+ sStr += cpDelim;
+ sStr += String::CreateFromInt32( rCol.GetBlue() );
+ sStr += sal_Unicode(')');
+ }
+ return sStr;
+}
+
+#endif
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 GetMetricId( SfxMapUnit eUnit )
+{
+ sal_uInt16 nId = RID_SVXITEMS_METRIC_MM;
+
+ switch ( eUnit )
+ {
+ case SFX_MAPUNIT_100TH_MM:
+ case SFX_MAPUNIT_10TH_MM:
+ case SFX_MAPUNIT_MM:
+ nId = RID_SVXITEMS_METRIC_MM;
+ break;
+
+ case SFX_MAPUNIT_CM:
+ nId = RID_SVXITEMS_METRIC_CM;
+ break;
+
+ case SFX_MAPUNIT_1000TH_INCH:
+ case SFX_MAPUNIT_100TH_INCH:
+ case SFX_MAPUNIT_10TH_INCH:
+ case SFX_MAPUNIT_INCH:
+ nId = RID_SVXITEMS_METRIC_INCH;
+ break;
+
+ case SFX_MAPUNIT_POINT:
+ nId = RID_SVXITEMS_METRIC_POINT;
+ break;
+
+ case SFX_MAPUNIT_TWIP:
+ nId = RID_SVXITEMS_METRIC_TWIP;
+ break;
+
+ case SFX_MAPUNIT_PIXEL:
+ nId = RID_SVXITEMS_METRIC_PIXEL;
+ break;
+
+ default:
+ DBG_ERROR( "not supported mapunit" );
+ }
+ return nId;
+}
+
+
diff --git a/editeng/source/items/makefile.mk b/editeng/source/items/makefile.mk
new file mode 100644
index 0000000000..3b7412f213
--- /dev/null
+++ b/editeng/source/items/makefile.mk
@@ -0,0 +1,78 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.19 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+#PROJECTPCH4DLL=TRUE
+#PROJECTPCH=svxpch
+#PROJECTPCHSOURCE=$(PRJ)$/util$/svxpch
+#ENABLE_EXCEPTIONS=TRUE
+
+PRJNAME=editeng
+TARGET=items
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SRS1NAME=items
+SRC1FILES = \
+ page.src \
+ svxitems.src
+
+SLOFILES= \
+ $(SLO)$/svdfield.obj \
+ $(SLO)$/writingmodeitem.obj \
+ $(SLO)$/frmitems.obj \
+ $(SLO)$/paraitem.obj \
+ $(SLO)$/textitem.obj \
+ $(SLO)$/flditem.obj \
+ $(SLO)$/svxfont.obj \
+ $(SLO)$/paperinf.obj \
+ $(SLO)$/itemtype.obj \
+ $(SLO)$/bulitem.obj \
+ $(SLO)$/numitem.obj \
+ $(SLO)$/xmlcnitm.obj \
+ $(SLO)$/charhiddenitem.obj
+
+EXCEPTIONSFILES= \
+ $(SLO)$/svdfield.obj \
+ $(SLO)$/paraitem.obj \
+ $(SLO)$/frmitems.obj \
+ $(SLO)$/numitem.obj\
+ $(SLO)$/xmlcnitm.obj\
+ $(SLO)$/flditem.obj
+
+.INCLUDE : target.mk
+
diff --git a/editeng/source/items/numitem.cxx b/editeng/source/items/numitem.cxx
new file mode 100644
index 0000000000..0a35e0d6d8
--- /dev/null
+++ b/editeng/source/items/numitem.cxx
@@ -0,0 +1,1276 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: numitem.cxx,v $
+ * $Revision: 1.30 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <editeng/numitem.hxx>
+
+#include <com/sun/star/text/HoriOrientation.hpp>
+#include <com/sun/star/text/VertOrientation.hpp>
+#include <com/sun/star/text/RelOrientation.hpp>
+#include <editeng/brshitem.hxx>
+#include <vcl/font.hxx>
+#include <editeng/editids.hrc>
+#include <editeng/editrids.hrc>
+#include <editeng/numdef.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/window.hxx>
+#include <vcl/svapp.hxx>
+#include <editeng/unolingu.hxx>
+#include <com/sun/star/text/XNumberingFormatter.hpp>
+#include <com/sun/star/text/XDefaultNumberingProvider.hpp>
+#include <com/sun/star/style/NumberingType.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <comphelper/processfactory.hxx>
+
+#include <editeng/unonrule.hxx>
+
+#define MM100_TO_TWIP(MM100) ((MM100*72L+63L)/127L)
+
+#define DEF_WRITER_LSPACE 500 //Standardeinrueckung
+#define DEF_DRAW_LSPACE 800 //Standardeinrueckung
+
+#define NUMITEM_VERSION_01 0x01
+#define NUMITEM_VERSION_02 0x02
+#define NUMITEM_VERSION_03 0x03
+#define NUMITEM_VERSION_04 0x04
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::style;
+
+sal_Int32 SvxNumberType::nRefCount = 0;
+com::sun::star::uno::Reference<com::sun::star::text::XNumberingFormatter> SvxNumberType::xFormatter = 0;
+void lcl_getFormatter(com::sun::star::uno::Reference<com::sun::star::text::XNumberingFormatter>& _xFormatter)
+{
+ if(!_xFormatter.is())
+ {
+ try
+ {
+ Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
+ Reference < XInterface > xI = xMSF->createInstance(
+ ::rtl::OUString::createFromAscii( "com.sun.star.text.DefaultNumberingProvider" ) );
+ Reference<XDefaultNumberingProvider> xRet(xI, UNO_QUERY);
+ DBG_ASSERT(xRet.is(), "service missing: \"com.sun.star.text.DefaultNumberingProvider\"");
+ _xFormatter = Reference<XNumberingFormatter> (xRet, UNO_QUERY);
+ }
+ catch(Exception& )
+ {
+ }
+ }
+}
+/* -----------------------------22.02.01 14:24--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SvxNumberType::SvxNumberType(sal_Int16 nType) :
+ nNumType(nType),
+ bShowSymbol(sal_True)
+{
+ nRefCount++;
+}
+/* -----------------------------22.02.01 14:31--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SvxNumberType::SvxNumberType(const SvxNumberType& rType) :
+ nNumType(rType.nNumType),
+ bShowSymbol(rType.bShowSymbol)
+{
+ nRefCount++;
+}
+/* -----------------------------22.02.01 14:24--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SvxNumberType::~SvxNumberType()
+{
+ if(!--nRefCount)
+ xFormatter = 0;
+}
+/* -----------------------------22.02.01 11:09--------------------------------
+
+ ---------------------------------------------------------------------------*/
+String SvxNumberType::GetNumStr( ULONG nNo ) const
+{
+ LanguageType eLang = Application::GetSettings().GetLanguage();
+ Locale aLocale = SvxCreateLocale(eLang);
+ return GetNumStr( nNo, aLocale );
+}
+/* -----------------28.10.98 15:56-------------------
+ *
+ * --------------------------------------------------*/
+String SvxNumberType::GetNumStr( ULONG nNo, const Locale& rLocale ) const
+{
+ lcl_getFormatter(xFormatter);
+ String aTmpStr;
+ if(!xFormatter.is())
+ return aTmpStr;
+
+ if(bShowSymbol)
+ {
+ switch(nNumType)
+ {
+ case NumberingType::CHAR_SPECIAL:
+ case NumberingType::BITMAP:
+ break;
+ default:
+ {
+ //#95525# '0' allowed for ARABIC numberings
+ if(NumberingType::ARABIC == nNumType && 0 == nNo )
+ aTmpStr = '0';
+ else
+ {
+ Sequence< PropertyValue > aProperties(2);
+ PropertyValue* pValues = aProperties.getArray();
+ pValues[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NumberingType"));
+ pValues[0].Value <<= nNumType;
+ pValues[1].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Value"));
+ pValues[1].Value <<= (sal_Int32)nNo;
+
+ try
+ {
+ aTmpStr = xFormatter->makeNumberingString( aProperties, rLocale );
+ }
+ catch(Exception&)
+ {
+ }
+ }
+ }
+ }
+ }
+ return aTmpStr;
+}
+/* -----------------27.10.98 10:33-------------------
+ *
+ * --------------------------------------------------*/
+// --> OD 2008-01-09 #newlistlevelattrs#
+SvxNumberFormat::SvxNumberFormat( sal_Int16 eType,
+ SvxNumPositionAndSpaceMode ePositionAndSpaceMode )
+// <--
+ : SvxNumberType(eType),
+ eNumAdjust(SVX_ADJUST_LEFT),
+ nInclUpperLevels(0),
+ nStart(1),
+ cBullet(SVX_DEF_BULLET),
+ nBulletRelSize(100),
+ nBulletColor(COL_BLACK),
+ // --> OD 2008-01-09 #newlistlevelattrs#
+ mePositionAndSpaceMode( ePositionAndSpaceMode ),
+ // <--
+ nFirstLineOffset(0),
+ nAbsLSpace(0),
+ nLSpace(0),
+ nCharTextDistance(0),
+ // --> OD 2008-01-09 #newlistlevelattrs#
+ meLabelFollowedBy( LISTTAB ),
+ mnListtabPos( 0 ),
+ mnFirstLineIndent( 0 ),
+ mnIndentAt( 0 ),
+ // <--
+ pGraphicBrush(0),
+ eVertOrient(text::VertOrientation::NONE),
+ pBulletFont(0)
+{
+}
+/* -----------------27.10.98 10:56-------------------
+ *
+ * --------------------------------------------------*/
+SvxNumberFormat::SvxNumberFormat(const SvxNumberFormat& rFormat) :
+ SvxNumberType(rFormat),
+ // --> OD 2008-01-09 #newlistlevelattrs#
+ mePositionAndSpaceMode( rFormat.mePositionAndSpaceMode ),
+ // <--
+ pGraphicBrush(0),
+ pBulletFont(0)
+{
+ *this = rFormat;
+}
+/* -----------------27.10.98 10:56-------------------
+ *
+ * --------------------------------------------------*/
+SvxNumberFormat::~SvxNumberFormat()
+{
+ delete pGraphicBrush;
+ delete pBulletFont;
+}
+/* -----------------08.12.98 11:14-------------------
+ *
+ * --------------------------------------------------*/
+SvxNumberFormat::SvxNumberFormat(SvStream &rStream)
+: mePositionAndSpaceMode( LABEL_WIDTH_AND_POSITION ),
+ meLabelFollowedBy( LISTTAB ),
+ mnListtabPos( 0 ),
+ mnFirstLineIndent( 0 ),
+ mnIndentAt( 0 )
+{
+
+ USHORT nVersion;
+ rStream >> nVersion;
+
+ USHORT nUSHORT;
+ rStream >> nUSHORT;
+ SetNumberingType((sal_Int16)nUSHORT);
+ rStream >> nUSHORT;
+ eNumAdjust = (SvxAdjust)nUSHORT;
+ rStream >> nUSHORT;
+ nInclUpperLevels = (BYTE)nUSHORT;
+ rStream >> nUSHORT;
+ nStart = nUSHORT;
+ rStream >> nUSHORT;
+ cBullet = nUSHORT;
+
+ short nShort;
+ rStream >> nShort;
+ nFirstLineOffset = nShort;
+ rStream >> nShort;
+ nAbsLSpace = nShort;
+ rStream >> nShort;
+ nLSpace = nShort;
+
+ rStream >> nShort;
+ nCharTextDistance = nShort;
+ rtl_TextEncoding eEnc = gsl_getSystemTextEncoding();
+ rStream.ReadByteString(sPrefix, eEnc);
+ rStream.ReadByteString(sSuffix, eEnc);
+ rStream.ReadByteString(sCharStyleName, eEnc);
+ rStream >> nUSHORT;
+ if(nUSHORT)
+ {
+ SvxBrushItem aHelper(0);
+ pGraphicBrush = (SvxBrushItem*) aHelper.Create( rStream, BRUSH_GRAPHIC_VERSION );
+ }
+ else
+ pGraphicBrush = 0;
+
+ rStream >> nUSHORT;
+ eVertOrient = (sal_Int16)nUSHORT;
+
+ rStream >> nUSHORT;
+ if(nUSHORT)
+ {
+ pBulletFont = new Font;
+ rStream >> *pBulletFont;
+ if(!pBulletFont->GetCharSet())
+ pBulletFont->SetCharSet(rStream.GetStreamCharSet());
+ }
+ else
+ pBulletFont = 0;
+ rStream >> aGraphicSize;
+
+ rStream >> nBulletColor;
+ rStream >> nUSHORT;
+ nBulletRelSize = nUSHORT;
+ rStream >> nUSHORT;
+ SetShowSymbol((BOOL)nUSHORT);
+
+ if( nVersion < NUMITEM_VERSION_03 )
+ cBullet = ByteString::ConvertToUnicode( (sal_Char)cBullet,
+ (pBulletFont&&pBulletFont->GetCharSet()) ? pBulletFont->GetCharSet()
+ : RTL_TEXTENCODING_SYMBOL );
+ if(pBulletFont)
+ {
+ BOOL bConvertBulletFont = rStream.GetVersion() <= SOFFICE_FILEFORMAT_50;
+ if(bConvertBulletFont)
+ {
+
+ FontToSubsFontConverter pConverter =
+ CreateFontToSubsFontConverter(pBulletFont->GetName(),
+ FONTTOSUBSFONT_IMPORT|FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS);
+ if(pConverter)
+ {
+ cBullet = ConvertFontToSubsFontChar(pConverter, cBullet);
+ String sFontName = GetFontToSubsFontName(pConverter);
+ pBulletFont->SetName(sFontName);
+ DestroyFontToSubsFontConverter(pConverter);
+ }
+ }
+ }
+
+ if( NUMITEM_VERSION_04 <= nVersion )
+ {
+ rStream >> nUSHORT;
+ mePositionAndSpaceMode = (SvxNumPositionAndSpaceMode) nUSHORT;
+ rStream >> nUSHORT;
+ meLabelFollowedBy = ( SvxNumLabelFollowedBy ) nUSHORT;
+ long nLong;
+ rStream >> nLong;
+ mnListtabPos = nLong;
+ rStream >> nLong;
+ mnFirstLineIndent = nLong;
+ rStream >> nLong;
+ mnIndentAt = nLong;
+ }
+}
+/* -----------------08.12.98 11:14-------------------
+ *
+ * --------------------------------------------------*/
+SvStream& SvxNumberFormat::Store(SvStream &rStream, FontToSubsFontConverter pConverter)
+{
+ if(pConverter && pBulletFont)
+ {
+ cBullet = ConvertFontToSubsFontChar(pConverter, cBullet);
+ String sFontName = GetFontToSubsFontName(pConverter);
+ pBulletFont->SetName(sFontName);
+ }
+
+ rStream << (USHORT)NUMITEM_VERSION_04;
+
+ rStream << (USHORT)GetNumberingType();
+ rStream << (USHORT)eNumAdjust;
+ rStream << (USHORT)nInclUpperLevels;
+ rStream << nStart;
+ rStream << (USHORT)cBullet;
+
+ rStream << nFirstLineOffset;
+ rStream << nAbsLSpace;
+ rStream << nLSpace;
+
+ rStream << nCharTextDistance;
+ rtl_TextEncoding eEnc = gsl_getSystemTextEncoding();
+ rStream.WriteByteString(sPrefix, eEnc);
+ rStream.WriteByteString(sSuffix, eEnc);
+ rStream.WriteByteString(sCharStyleName, eEnc);
+ if(pGraphicBrush)
+ {
+ rStream << (USHORT)1;
+
+ // #75113# in SD or SI force bullet itself to be stored,
+ // for that purpose throw away link when link and graphic
+ // are present, so Brush save is forced
+ if(pGraphicBrush->GetGraphicLink() && pGraphicBrush->GetGraphic())
+ {
+ String aEmpty;
+ pGraphicBrush->SetGraphicLink(aEmpty);
+ }
+
+ pGraphicBrush->Store(rStream, BRUSH_GRAPHIC_VERSION);
+ }
+ else
+ rStream << (USHORT)0;
+
+ rStream << (USHORT)eVertOrient;
+ if(pBulletFont)
+ {
+ rStream << (USHORT)1;
+ rStream << *pBulletFont;
+ }
+ else
+ rStream << (USHORT)0;
+ rStream << aGraphicSize;
+
+ Color nTempColor = nBulletColor;
+ if(COL_AUTO == nBulletColor.GetColor())
+ nTempColor = COL_BLACK;
+ rStream << nTempColor;
+ rStream << nBulletRelSize;
+ rStream << (USHORT)IsShowSymbol();
+
+ rStream << ( USHORT ) mePositionAndSpaceMode;
+ rStream << ( USHORT ) meLabelFollowedBy;
+ rStream << ( long ) mnListtabPos;
+ rStream << ( long ) mnFirstLineIndent;
+ rStream << ( long ) mnIndentAt;
+
+ return rStream;
+}
+
+/* -----------------------------23.02.01 11:10--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SvxNumberFormat& SvxNumberFormat::operator=( const SvxNumberFormat& rFormat )
+{
+ SetNumberingType(rFormat.GetNumberingType());
+ eNumAdjust = rFormat.eNumAdjust ;
+ nInclUpperLevels = rFormat.nInclUpperLevels ;
+ nStart = rFormat.nStart ;
+ cBullet = rFormat.cBullet ;
+ // --> OD 2008-01-09 #newlistlevelattrs#
+ mePositionAndSpaceMode = rFormat.mePositionAndSpaceMode;
+ // <--
+ nFirstLineOffset = rFormat.nFirstLineOffset;
+ nAbsLSpace = rFormat.nAbsLSpace ;
+ nLSpace = rFormat.nLSpace ;
+ nCharTextDistance = rFormat.nCharTextDistance ;
+ // --> OD 2008-01-09 #newlistlevelattrs#
+ meLabelFollowedBy = rFormat.meLabelFollowedBy;
+ mnListtabPos = rFormat.mnListtabPos;
+ mnFirstLineIndent = rFormat.mnFirstLineIndent;
+ mnIndentAt = rFormat.mnIndentAt;
+ // <--
+ eVertOrient = rFormat.eVertOrient ;
+ sPrefix = rFormat.sPrefix ;
+ sSuffix = rFormat.sSuffix ;
+ aGraphicSize = rFormat.aGraphicSize ;
+ nBulletColor = rFormat.nBulletColor ;
+ nBulletRelSize = rFormat.nBulletRelSize;
+ SetShowSymbol(rFormat.IsShowSymbol());
+ sCharStyleName = rFormat.sCharStyleName;
+ DELETEZ(pGraphicBrush);
+ if(rFormat.pGraphicBrush)
+ {
+ pGraphicBrush = new SvxBrushItem(*rFormat.pGraphicBrush);
+ pGraphicBrush->SetDoneLink( STATIC_LINK( this, SvxNumberFormat, GraphicArrived) );
+ }
+ DELETEZ(pBulletFont);
+ if(rFormat.pBulletFont)
+ pBulletFont = new Font(*rFormat.pBulletFont);
+ return *this;
+}
+/* -----------------27.10.98 10:56-------------------
+ *
+ * --------------------------------------------------*/
+BOOL SvxNumberFormat::operator==( const SvxNumberFormat& rFormat) const
+{
+ if( GetNumberingType() != rFormat.GetNumberingType() ||
+ eNumAdjust != rFormat.eNumAdjust ||
+ nInclUpperLevels != rFormat.nInclUpperLevels ||
+ nStart != rFormat.nStart ||
+ cBullet != rFormat.cBullet ||
+ // --> OD 2008-01-09 #newlistlevelattrs#
+ mePositionAndSpaceMode != rFormat.mePositionAndSpaceMode ||
+ // <--
+ nFirstLineOffset != rFormat.nFirstLineOffset ||
+ nAbsLSpace != rFormat.nAbsLSpace ||
+ nLSpace != rFormat.nLSpace ||
+ nCharTextDistance != rFormat.nCharTextDistance ||
+ // --> OD 2008-01-09 #newlistlevelattrs#
+ meLabelFollowedBy != rFormat.meLabelFollowedBy ||
+ mnListtabPos != rFormat.mnListtabPos ||
+ mnFirstLineIndent != rFormat.mnFirstLineIndent ||
+ mnIndentAt != rFormat.mnIndentAt ||
+ // <--
+ eVertOrient != rFormat.eVertOrient ||
+ sPrefix != rFormat.sPrefix ||
+ sSuffix != rFormat.sSuffix ||
+ aGraphicSize != rFormat.aGraphicSize ||
+ nBulletColor != rFormat.nBulletColor ||
+ nBulletRelSize != rFormat.nBulletRelSize ||
+ IsShowSymbol() != rFormat.IsShowSymbol() ||
+ sCharStyleName != rFormat.sCharStyleName
+ )
+ return FALSE;
+ if (
+ (pGraphicBrush && !rFormat.pGraphicBrush) ||
+ (!pGraphicBrush && rFormat.pGraphicBrush) ||
+ (pGraphicBrush && *pGraphicBrush != *rFormat.pGraphicBrush)
+ )
+ {
+ return FALSE;
+ }
+ if (
+ (pBulletFont && !rFormat.pBulletFont) ||
+ (!pBulletFont && rFormat.pBulletFont) ||
+ (pBulletFont && *pBulletFont != *rFormat.pBulletFont)
+ )
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+/* -----------------28.10.98 09:53-------------------
+ *
+ * --------------------------------------------------*/
+void SvxNumberFormat::SetGraphicBrush( const SvxBrushItem* pBrushItem,
+ const Size* pSize, const sal_Int16* pOrient)
+{
+ if(!pBrushItem)
+ {
+ delete pGraphicBrush;
+ pGraphicBrush = 0;
+ }
+ else if ( !pGraphicBrush || (pGraphicBrush && !(*pBrushItem == *pGraphicBrush)) )
+ {
+ delete pGraphicBrush;
+ pGraphicBrush = (SvxBrushItem*)pBrushItem->Clone();
+ pGraphicBrush->SetDoneLink( STATIC_LINK( this, SvxNumberFormat, GraphicArrived) );
+ }
+
+ if(pOrient)
+ eVertOrient = *pOrient;
+ else
+ eVertOrient = text::VertOrientation::NONE;
+ if(pSize)
+ aGraphicSize = *pSize;
+ else
+ aGraphicSize.Width() = aGraphicSize.Height() = 0;
+}
+/* -----------------28.10.98 09:59-------------------
+ *
+ * --------------------------------------------------*/
+void SvxNumberFormat::SetGraphic( const String& rName )
+{
+ const String* pName;
+ if( pGraphicBrush &&
+ 0 != (pName = pGraphicBrush->GetGraphicLink())
+ && *pName == rName )
+ return ;
+
+ delete pGraphicBrush;
+ String sTmp;
+ pGraphicBrush = new SvxBrushItem( rName, sTmp, GPOS_AREA, 0 );
+ pGraphicBrush->SetDoneLink( STATIC_LINK( this, SvxNumberFormat, GraphicArrived) );
+ if( eVertOrient == text::VertOrientation::NONE )
+ eVertOrient = text::VertOrientation::TOP;
+
+ aGraphicSize.Width() = aGraphicSize.Height() = 0;
+}
+/* -----------------------------22.02.01 15:55--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SvxNumberFormat::SetVertOrient(sal_Int16 eSet)
+{
+ eVertOrient = eSet;
+}
+/* -----------------------------22.02.01 15:55--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int16 SvxNumberFormat::GetVertOrient() const
+{
+ return eVertOrient;
+}
+/* -----------------28.10.98 09:59-------------------
+ *
+ * --------------------------------------------------*/
+void SvxNumberFormat::SetBulletFont(const Font* pFont)
+{
+ delete pBulletFont;
+ pBulletFont = pFont ? new Font(*pFont): 0;
+}
+
+// --> OD 2008-01-09 #newlistlevelattrs#
+SvxNumberFormat::SvxNumPositionAndSpaceMode SvxNumberFormat::GetPositionAndSpaceMode() const
+{
+ return mePositionAndSpaceMode;
+}
+void SvxNumberFormat::SetPositionAndSpaceMode( SvxNumPositionAndSpaceMode ePositionAndSpaceMode )
+{
+ mePositionAndSpaceMode = ePositionAndSpaceMode;
+}
+
+short SvxNumberFormat::GetLSpace() const
+{
+//#if OSL_DEBUG_LEVEL > 1
+// DBG_ASSERT( mePositionAndSpaceMode == LABEL_WIDTH_AND_POSITION,
+// "<SvxNumberFormat::GetLSpace()> - misusage: position-and-space-mode does not equal LABEL_WIDTH_AND_POSITION");
+//#endif
+ return mePositionAndSpaceMode == LABEL_WIDTH_AND_POSITION ? nLSpace : 0;
+}
+short SvxNumberFormat::GetAbsLSpace() const
+{
+//#if OSL_DEBUG_LEVEL > 1
+// DBG_ASSERT( mePositionAndSpaceMode == LABEL_WIDTH_AND_POSITION,
+// "<SvxNumberFormat::GetAbsLSpace()> - misusage: position-and-space-mode does not equal LABEL_WIDTH_AND_POSITION");
+//#endif
+ return mePositionAndSpaceMode == LABEL_WIDTH_AND_POSITION
+ ? nAbsLSpace
+ : static_cast<short>( GetFirstLineIndent() + GetIndentAt() );
+}
+short SvxNumberFormat::GetFirstLineOffset() const
+{
+//#if OSL_DEBUG_LEVEL > 1
+// DBG_ASSERT( mePositionAndSpaceMode == LABEL_WIDTH_AND_POSITION,
+// "<SvxNumberFormat::GetFirstLineOffset()> - misusage: position-and-space-mode does not equal LABEL_WIDTH_AND_POSITION");
+//#endif
+ return mePositionAndSpaceMode == LABEL_WIDTH_AND_POSITION
+ ? nFirstLineOffset
+ : static_cast<short>( GetFirstLineIndent() );
+}
+short SvxNumberFormat::GetCharTextDistance() const
+{
+//#if OSL_DEBUG_LEVEL > 1
+// DBG_ASSERT( mePositionAndSpaceMode == LABEL_WIDTH_AND_POSITION,
+// "<SvxNumberFormat::GetCharTextDistance()> - misusage: position-and-space-mode does not equal LABEL_WIDTH_AND_POSITION");
+//#endif
+ return mePositionAndSpaceMode == LABEL_WIDTH_AND_POSITION ? nCharTextDistance : 0;
+}
+
+void SvxNumberFormat::SetLabelFollowedBy( const SvxNumLabelFollowedBy eLabelFollowedBy )
+{
+ meLabelFollowedBy = eLabelFollowedBy;
+}
+SvxNumberFormat::SvxNumLabelFollowedBy SvxNumberFormat::GetLabelFollowedBy() const
+{
+ return meLabelFollowedBy;
+}
+void SvxNumberFormat::SetListtabPos( const long nListtabPos )
+{
+ mnListtabPos = nListtabPos;
+}
+long SvxNumberFormat::GetListtabPos() const
+{
+ return mnListtabPos;
+}
+void SvxNumberFormat::SetFirstLineIndent( const long nFirstLineIndent )
+{
+ mnFirstLineIndent = nFirstLineIndent;
+}
+long SvxNumberFormat::GetFirstLineIndent() const
+{
+ return mnFirstLineIndent;
+}
+void SvxNumberFormat::SetIndentAt( const long nIndentAt )
+{
+ mnIndentAt = nIndentAt;
+}
+long SvxNumberFormat::GetIndentAt() const
+{
+ return mnIndentAt;
+}
+// <--
+
+/* -----------------28.10.98 10:03-------------------
+ *
+ * --------------------------------------------------*/
+IMPL_STATIC_LINK( SvxNumberFormat, GraphicArrived, void *, EMPTYARG )
+{
+ // ggfs. die GrfSize setzen:
+ if( !pThis->aGraphicSize.Width() || !pThis->aGraphicSize.Height() )
+ {
+ const Graphic* pGrf = pThis->pGraphicBrush->GetGraphic();
+ if( pGrf )
+ pThis->aGraphicSize = SvxNumberFormat::GetGraphicSizeMM100( pGrf );
+ }
+ pThis->NotifyGraphicArrived();
+ return 0;
+}
+/* -----------------------------02.07.01 15:36--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SvxNumberFormat::NotifyGraphicArrived()
+{
+}
+
+/* -----------------28.10.98 10:38-------------------
+ *
+ * --------------------------------------------------*/
+Size SvxNumberFormat::GetGraphicSizeMM100(const Graphic* pGraphic)
+{
+ const MapMode aMapMM100( MAP_100TH_MM );
+ const Size& rSize = pGraphic->GetPrefSize();
+ Size aRetSize;
+ if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
+ {
+ OutputDevice* pOutDev = Application::GetDefaultDevice();
+ MapMode aOldMap( pOutDev->GetMapMode() );
+ pOutDev->SetMapMode( aMapMM100 );
+ aRetSize = pOutDev->PixelToLogic( rSize );
+ pOutDev->SetMapMode( aOldMap );
+ }
+ else
+ aRetSize = OutputDevice::LogicToLogic( rSize, pGraphic->GetPrefMapMode(), aMapMM100 );
+ return aRetSize;
+}
+/* -----------------28.10.98 15:57-------------------
+ *
+ * --------------------------------------------------*/
+String SvxNumberFormat::CreateRomanString( ULONG nNo, BOOL bUpper )
+{
+ nNo %= 4000; // mehr kann nicht dargestellt werden
+// i, ii, iii, iv, v, vi, vii, vii, viii, ix
+// (Dummy),1000,500,100,50,10,5,1
+ const char *cRomanArr = bUpper
+ ? "MDCLXVI--" // +2 Dummy-Eintraege !!
+ : "mdclxvi--"; // +2 Dummy-Eintraege !!
+
+ String sRet;
+ USHORT nMask = 1000;
+ while( nMask )
+ {
+ BYTE nZahl = BYTE(nNo / nMask);
+ BYTE nDiff = 1;
+ nNo %= nMask;
+
+ if( 5 < nZahl )
+ {
+ if( nZahl < 9 )
+ sRet += sal_Unicode(*(cRomanArr-1));
+ ++nDiff;
+ nZahl -= 5;
+ }
+ switch( nZahl )
+ {
+ case 3: { sRet += sal_Unicode(*cRomanArr); }
+ case 2: { sRet += sal_Unicode(*cRomanArr); }
+ case 1: { sRet += sal_Unicode(*cRomanArr); }
+ break;
+
+ case 4: {
+ sRet += sal_Unicode(*cRomanArr);
+ sRet += sal_Unicode(*(cRomanArr-nDiff));
+ }
+ break;
+ case 5: { sRet += sal_Unicode(*(cRomanArr-nDiff)); }
+ break;
+ }
+
+ nMask /= 10; // zur naechsten Dekade
+ cRomanArr += 2;
+ }
+ return sRet;
+}
+#ifdef OLD_NUMBER_FORMATTING
+void SvxNumberFormat::GetCharStr( ULONG nNo, String& rStr ) const
+{
+ DBG_ASSERT( nNo, "0 ist eine ungueltige Nummer !!" );
+
+ const ULONG coDiff = 'Z' - 'A' +1;
+ char cAdd = (SVX_NUM_CHARS_UPPER_LETTER == eNumType ? 'A' : 'a') - 1;
+ ULONG nCalc;
+
+ do {
+ nCalc = nNo % coDiff;
+ if( !nCalc )
+ nCalc = coDiff;
+ rStr.Insert( sal_Unicode(cAdd + nCalc ), 0 );
+ nNo -= nCalc;
+ if( nNo )
+ nNo /= coDiff;
+ } while( nNo );
+}
+
+void SvxNumberFormat::GetCharStrN( ULONG nNo, String& rStr ) const
+{
+ DBG_ASSERT( nNo, "0 ist eine ungueltige Nummer !!" );
+
+ const ULONG coDiff = 'Z' - 'A' +1;
+ char cChar = (char)(--nNo % coDiff);
+ if( SVX_NUM_CHARS_UPPER_LETTER_N == eNumType )
+ cChar += 'A';
+ else
+ cChar += 'a';
+
+ rStr.Fill( (USHORT)(nNo / coDiff) + 1, sal_Unicode(cChar) );
+}
+#endif //OLD_NUMBER_FORMATTING
+/* -----------------------------22.02.01 13:31--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const String& SvxNumberFormat::GetCharFmtName()const
+{
+ return sCharStyleName;
+}
+/* -----------------27.10.98 10:38-------------------
+ *
+ * --------------------------------------------------*/
+sal_Int32 SvxNumRule::nRefCount = 0;
+static SvxNumberFormat* pStdNumFmt = 0;
+static SvxNumberFormat* pStdOutlineNumFmt = 0;
+// --> OD 2008-02-11 #newlistlevelattrs#
+SvxNumRule::SvxNumRule( ULONG nFeatures,
+ USHORT nLevels,
+ BOOL bCont,
+ SvxNumRuleType eType,
+ SvxNumberFormat::SvxNumPositionAndSpaceMode
+ eDefaultNumberFormatPositionAndSpaceMode )
+ : nLevelCount(nLevels),
+ nFeatureFlags(nFeatures),
+ eNumberingType(eType),
+ bContinuousNumbering(bCont)
+{
+ ++nRefCount;
+ LanguageType eLang = Application::GetSettings().GetLanguage();
+ aLocale = SvxCreateLocale(eLang);
+ for(USHORT i = 0; i < SVX_MAX_NUM; i++)
+ {
+ if(i < nLevels)
+ {
+ aFmts[i] = new SvxNumberFormat(SVX_NUM_CHARS_UPPER_LETTER);
+ //daran wird zwischen writer und draw unterschieden
+ if(nFeatures & NUM_CONTINUOUS)
+ {
+ // --> OD 2008-02-11 #newlistlevelattrs#
+ if ( eDefaultNumberFormatPositionAndSpaceMode ==
+ SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
+ {
+ aFmts[i]->SetLSpace( MM100_TO_TWIP(DEF_WRITER_LSPACE) );
+ aFmts[i]->SetAbsLSpace( MM100_TO_TWIP(DEF_WRITER_LSPACE * (i+1)) );
+ aFmts[i]->SetFirstLineOffset(MM100_TO_TWIP(-DEF_WRITER_LSPACE));
+ }
+ else if ( eDefaultNumberFormatPositionAndSpaceMode ==
+ SvxNumberFormat::LABEL_ALIGNMENT )
+ {
+ // first line indent of general numbering in inch: -0,25 inch
+ const long cFirstLineIndent = -1440/4;
+ // indent values of general numbering in inch:
+ // 0,5 0,75 1,0 1,25 1,5
+ // 1,75 2,0 2,25 2,5 2,75
+ const long cIndentAt = 1440/4;
+ aFmts[i]->SetPositionAndSpaceMode( SvxNumberFormat::LABEL_ALIGNMENT );
+ aFmts[i]->SetLabelFollowedBy( SvxNumberFormat::LISTTAB );
+ aFmts[i]->SetListtabPos( cIndentAt * (i+2) );
+ aFmts[i]->SetFirstLineIndent( cFirstLineIndent );
+ aFmts[i]->SetIndentAt( cIndentAt * (i+2) );
+ }
+ // <--
+ }
+ else
+ {
+ aFmts[i]->SetLSpace( DEF_DRAW_LSPACE );
+ aFmts[i]->SetAbsLSpace( DEF_DRAW_LSPACE * (i) );
+ }
+ }
+ else
+ aFmts[i] = 0;
+ aFmtsSet[i] = FALSE;
+ }
+}
+/* -----------------27.10.98 10:41-------------------
+ *
+ * --------------------------------------------------*/
+SvxNumRule::SvxNumRule(const SvxNumRule& rCopy)
+{
+ ++nRefCount;
+ aLocale = rCopy.aLocale;
+ nLevelCount = rCopy.nLevelCount ;
+ nFeatureFlags = rCopy.nFeatureFlags ;
+ bContinuousNumbering = rCopy.bContinuousNumbering;
+ eNumberingType = rCopy.eNumberingType;
+ memset( aFmts, 0, sizeof( aFmts ));
+ for(USHORT i = 0; i < SVX_MAX_NUM; i++)
+ {
+ if(rCopy.aFmts[i])
+ aFmts[i] = new SvxNumberFormat(*rCopy.aFmts[i]);
+ else
+ aFmts[i] = 0;
+ aFmtsSet[i] = rCopy.aFmtsSet[i];
+ }
+}
+/* -----------------08.12.98 11:07-------------------
+ *
+ * --------------------------------------------------*/
+SvxNumRule::SvxNumRule(SvStream &rStream)
+{
+ ++nRefCount;
+ LanguageType eLang = Application::GetSettings().GetLanguage();
+ aLocale = SvxCreateLocale(eLang);
+ USHORT nVersion;
+ USHORT nTemp;
+ rStream >> nVersion;
+ rStream >> nLevelCount;
+ rStream >> nTemp;
+ nFeatureFlags = nTemp;
+ rStream >> nTemp;
+ bContinuousNumbering = (BOOL)nTemp;
+ rStream >> nTemp;
+ eNumberingType = (SvxNumRuleType)nTemp;
+ memset( aFmts, 0, sizeof( aFmts ));
+
+ for(USHORT i = 0; i < SVX_MAX_NUM; i++)
+ {
+ USHORT nSet;
+ rStream >> nSet;
+ if(nSet)
+ aFmts[i] = new SvxNumberFormat(rStream);
+ else
+ aFmts[i] = 0;
+ aFmtsSet[i] = aFmts[i] ? TRUE : FALSE;
+ }
+ if(NUMITEM_VERSION_02 <= nVersion)
+ {
+ USHORT nShort;
+ rStream >> nShort;
+ nFeatureFlags = nShort;
+ }
+}
+
+/* -----------------08.12.98 11:07-------------------
+ *
+ * --------------------------------------------------*/
+SvStream& SvxNumRule::Store(SvStream &rStream)
+{
+ rStream<<(USHORT)NUMITEM_VERSION_03;
+ rStream<<nLevelCount;
+ //first save of nFeatureFlags for old versions
+ rStream<<(USHORT)nFeatureFlags;
+ rStream<<(USHORT)bContinuousNumbering;
+ rStream<<(USHORT)eNumberingType;
+
+ FontToSubsFontConverter pConverter = 0;
+ BOOL bConvertBulletFont = rStream.GetVersion() <= SOFFICE_FILEFORMAT_50;
+ for(USHORT i = 0; i < SVX_MAX_NUM; i++)
+ {
+ if(aFmts[i])
+ {
+ rStream << USHORT(1);
+ if(bConvertBulletFont && aFmts[i]->GetBulletFont())
+ {
+ if(!pConverter)
+ pConverter =
+ CreateFontToSubsFontConverter(aFmts[i]->GetBulletFont()->GetName(),
+ FONTTOSUBSFONT_EXPORT|FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS);
+ }
+ aFmts[i]->Store(rStream, pConverter);
+ }
+ else
+ rStream << USHORT(0);
+ }
+ //second save of nFeatureFlags for new versions
+ rStream<<(USHORT)nFeatureFlags;
+ if(pConverter)
+ DestroyFontToSubsFontConverter(pConverter);
+
+ return rStream;
+}
+
+/* -----------------27.10.98 10:41-------------------
+ *
+ * --------------------------------------------------*/
+SvxNumRule::~SvxNumRule()
+{
+ for(USHORT i = 0; i < SVX_MAX_NUM; i++)
+ delete aFmts[i];
+ if(!--nRefCount)
+ {
+ DELETEZ(pStdNumFmt);
+ DELETEZ(pStdOutlineNumFmt);
+ }
+}
+/* -----------------29.10.98 16:07-------------------
+ *
+ * --------------------------------------------------*/
+SvxNumRule& SvxNumRule::operator=( const SvxNumRule& rCopy )
+{
+ nLevelCount = rCopy.nLevelCount;
+ nFeatureFlags = rCopy.nFeatureFlags;
+ bContinuousNumbering = rCopy.bContinuousNumbering;
+ eNumberingType = rCopy.eNumberingType;
+ for(USHORT i = 0; i < SVX_MAX_NUM; i++)
+ {
+ delete aFmts[i];
+ if(rCopy.aFmts[i])
+ aFmts[i] = new SvxNumberFormat(*rCopy.aFmts[i]);
+ else
+ aFmts[i] = 0;
+ aFmtsSet[i] = rCopy.aFmtsSet[i];
+ }
+ return *this;
+}
+/* -----------------27.10.98 10:41-------------------
+ *
+ * --------------------------------------------------*/
+int SvxNumRule::operator==( const SvxNumRule& rCopy) const
+{
+ if(nLevelCount != rCopy.nLevelCount ||
+ nFeatureFlags != rCopy.nFeatureFlags ||
+ bContinuousNumbering != rCopy.bContinuousNumbering ||
+ eNumberingType != rCopy.eNumberingType)
+ return FALSE;
+ for(USHORT i = 0; i < nLevelCount; i++)
+ {
+ if (
+ (aFmtsSet[i] != rCopy.aFmtsSet[i]) ||
+ (!aFmts[i] && rCopy.aFmts[i]) ||
+ (aFmts[i] && !rCopy.aFmts[i]) ||
+ (aFmts[i] && *aFmts[i] != *rCopy.aFmts[i])
+ )
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+/* -----------------27.10.98 10:41-------------------
+ *
+ * --------------------------------------------------*/
+const SvxNumberFormat* SvxNumRule::Get(USHORT nLevel)const
+{
+ DBG_ASSERT(nLevel < SVX_MAX_NUM, "falsches Level" );
+ if( nLevel < SVX_MAX_NUM )
+ return aFmtsSet[nLevel] ? aFmts[nLevel] : 0;
+ else
+ return 0;
+}
+/* -----------------02.11.98 09:10-------------------
+ *
+ * --------------------------------------------------*/
+const SvxNumberFormat& SvxNumRule::GetLevel(USHORT nLevel)const
+{
+ if(!pStdNumFmt)
+ {
+ pStdNumFmt = new SvxNumberFormat(SVX_NUM_ARABIC);
+ pStdOutlineNumFmt = new SvxNumberFormat(SVX_NUM_NUMBER_NONE);
+ }
+
+ DBG_ASSERT(nLevel < SVX_MAX_NUM, "falsches Level" );
+
+ return ( ( nLevel < SVX_MAX_NUM ) && aFmts[nLevel] ) ?
+ *aFmts[nLevel] : eNumberingType == SVX_RULETYPE_NUMBERING ?
+ *pStdNumFmt : *pStdOutlineNumFmt;
+}
+
+/* -----------------29.10.98 09:08-------------------
+ *
+ * --------------------------------------------------*/
+void SvxNumRule::SetLevel( USHORT i, const SvxNumberFormat& rNumFmt, BOOL bIsValid )
+{
+ DBG_ASSERT(i < SVX_MAX_NUM, "falsches Level" );
+
+ if( (i < SVX_MAX_NUM) && (!aFmtsSet[i] || !(rNumFmt == *Get( i ))) )
+ {
+ delete aFmts[ i ];
+ aFmts[ i ] = new SvxNumberFormat( rNumFmt );
+ aFmtsSet[i] = bIsValid;
+// bInvalidRuleFlag = TRUE;
+ }
+}
+/* -----------------30.10.98 12:44-------------------
+ *
+ * --------------------------------------------------*/
+void SvxNumRule::SetLevel(USHORT nLevel, const SvxNumberFormat* pFmt)
+{
+ DBG_ASSERT(nLevel < SVX_MAX_NUM, "falsches Level" );
+
+ if( nLevel < SVX_MAX_NUM )
+ {
+ aFmtsSet[nLevel] = 0 != pFmt;
+ if(pFmt)
+ SetLevel(nLevel, *pFmt);
+ else
+ {
+ delete aFmts[nLevel];
+ aFmts[nLevel] = 0;
+ }
+ }
+}
+/* -----------------28.10.98 15:38-------------------
+ *
+ * --------------------------------------------------*/
+String SvxNumRule::MakeNumString( const SvxNodeNum& rNum, BOOL bInclStrings ) const
+{
+ String aStr;
+ if( SVX_NO_NUM > rNum.GetLevel() && !( SVX_NO_NUMLEVEL & rNum.GetLevel() ) )
+ {
+ const SvxNumberFormat& rMyNFmt = GetLevel( rNum.GetLevel() );
+ if( SVX_NUM_NUMBER_NONE != rMyNFmt.GetNumberingType() )
+ {
+ BYTE i = rNum.GetLevel();
+
+ if( !IsContinuousNumbering() &&
+ 1 < rMyNFmt.GetIncludeUpperLevels() ) // nur der eigene Level ?
+ {
+ BYTE n = rMyNFmt.GetIncludeUpperLevels();
+ if( 1 < n )
+ {
+ if( i+1 >= n )
+ i -= n - 1;
+ else
+ i = 0;
+ }
+ }
+
+ for( ; i <= rNum.GetLevel(); ++i )
+ {
+ const SvxNumberFormat& rNFmt = GetLevel( i );
+ if( SVX_NUM_NUMBER_NONE == rNFmt.GetNumberingType() )
+ {
+ // Soll aus 1.1.1 --> 2. NoNum --> 1..1 oder 1.1 ??
+ // if( i != rNum.nMyLevel )
+ // aStr += aDotStr;
+ continue;
+ }
+
+ sal_Bool bDot = sal_True;
+ if( rNum.GetLevelVal()[ i ] )
+ {
+ if(SVX_NUM_BITMAP != rNFmt.GetNumberingType())
+ aStr += rNFmt.GetNumStr( rNum.GetLevelVal()[ i ], aLocale );
+ else
+ bDot = sal_False;
+ }
+ else
+ aStr += sal_Unicode('0'); // alle 0-Level sind eine 0
+ if( i != rNum.GetLevel() && bDot)
+ aStr += sal_Unicode('.');
+ }
+ }
+
+ if( bInclStrings )
+ {
+ aStr.Insert( rMyNFmt.GetPrefix(), 0 );
+ aStr += rMyNFmt.GetSuffix();
+ }
+ }
+ return aStr;
+}
+/* -----------------18.08.99 10:18-------------------
+ Description: changes linked to embedded bitmaps
+ --------------------------------------------------*/
+BOOL SvxNumRule::UnLinkGraphics()
+{
+ BOOL bRet = FALSE;
+ for(USHORT i = 0; i < GetLevelCount(); i++)
+ {
+ SvxNumberFormat aFmt(GetLevel(i));
+ const SvxBrushItem* pBrush = aFmt.GetBrush();
+ const String* pLinkStr;
+ const Graphic* pGraphic;
+ if(SVX_NUM_BITMAP == aFmt.GetNumberingType())
+ {
+ if(pBrush &&
+ 0 != (pLinkStr = pBrush->GetGraphicLink()) &&
+ pLinkStr->Len() &&
+ 0 !=(pGraphic = pBrush->GetGraphic()))
+ {
+ SvxBrushItem aTempItem(*pBrush);
+ aTempItem.SetGraphicLink( String());
+ aTempItem.SetGraphic(*pGraphic);
+ sal_Int16 eOrient = aFmt.GetVertOrient();
+ aFmt.SetGraphicBrush( &aTempItem, &aFmt.GetGraphicSize(), &eOrient );
+ bRet = TRUE;
+ }
+ }
+ else if((SVX_NUM_BITMAP|LINK_TOKEN) == aFmt.GetNumberingType())
+ aFmt.SetNumberingType(SVX_NUM_BITMAP);
+ SetLevel(i, aFmt);
+ }
+ return bRet;
+}
+
+/* -----------------27.10.98 10:41-------------------
+ *
+ * --------------------------------------------------*/
+SvxNumBulletItem::SvxNumBulletItem(SvxNumRule& rRule) :
+ SfxPoolItem(SID_ATTR_NUMBERING_RULE),
+ pNumRule(new SvxNumRule(rRule))
+{
+}
+
+/*-----------------23.11.98 10:36-------------------
+ MT: Das sind ja sehr sinnige Kommentare...
+--------------------------------------------------*/
+SvxNumBulletItem::SvxNumBulletItem(SvxNumRule& rRule, USHORT _nWhich ) :
+ SfxPoolItem(_nWhich),
+ pNumRule(new SvxNumRule(rRule))
+{
+}
+
+/* -----------------27.10.98 10:41-------------------
+ *
+ * --------------------------------------------------*/
+SvxNumBulletItem::SvxNumBulletItem(const SvxNumBulletItem& rCopy) :
+ SfxPoolItem(rCopy.Which())
+{
+ pNumRule = new SvxNumRule(*rCopy.pNumRule);
+}
+/* -----------------27.10.98 10:41-------------------
+ *
+ * --------------------------------------------------*/
+SvxNumBulletItem::~SvxNumBulletItem()
+{
+ delete pNumRule;
+}
+
+/* -----------------27.10.98 10:41-------------------
+ *
+ * --------------------------------------------------*/
+int SvxNumBulletItem::operator==( const SfxPoolItem& rCopy) const
+{
+ return *pNumRule == *((SvxNumBulletItem&)rCopy).pNumRule;
+}
+/* -----------------27.10.98 10:41-------------------
+ *
+ * --------------------------------------------------*/
+SfxPoolItem* SvxNumBulletItem::Clone( SfxItemPool * ) const
+{
+ return new SvxNumBulletItem(*this);
+}
+/* -----------------08.12.98 10:43-------------------
+ *
+ * --------------------------------------------------*/
+SfxPoolItem* SvxNumBulletItem::Create(SvStream &rStream, USHORT) const
+{
+ SvxNumRule aRule(rStream);
+ return new SvxNumBulletItem(aRule, Which() );
+}
+USHORT SvxNumBulletItem::GetVersion( USHORT /*nFileVersion*/ ) const
+{
+ return NUMITEM_VERSION_03;
+}
+/* -----------------08.12.98 10:43-------------------
+ *
+ * --------------------------------------------------*/
+SvStream& SvxNumBulletItem::Store(SvStream &rStream, USHORT /*nItemVersion*/ )const
+{
+ pNumRule->Store(rStream);
+ return rStream;
+}
+
+/* -----------------08.12.98 10:43-------------------
+ *
+ * --------------------------------------------------*/
+
+sal_Bool SvxNumBulletItem::QueryValue( com::sun::star::uno::Any& rVal, BYTE /*nMemberId*/ ) const
+{
+ rVal <<= SvxCreateNumRule( pNumRule );
+ return sal_True;
+}
+
+sal_Bool SvxNumBulletItem::PutValue( const com::sun::star::uno::Any& rVal, BYTE /*nMemberId*/ )
+{
+ uno::Reference< container::XIndexReplace > xRule;
+ if( rVal >>= xRule )
+ {
+ try
+ {
+ SvxNumRule* pNewRule = new SvxNumRule( SvxGetNumRule( xRule ) );
+ if( pNewRule->GetLevelCount() != pNumRule->GetLevelCount() ||
+ pNewRule->GetNumRuleType() != pNumRule->GetNumRuleType() )
+ {
+ SvxNumRule* pConverted = SvxConvertNumRule( pNewRule, pNumRule->GetLevelCount(), pNumRule->GetNumRuleType() );
+ delete pNewRule;
+ pNewRule = pConverted;
+ }
+ delete pNumRule;
+ pNumRule = pNewRule;
+ return sal_True;
+ }
+ catch(lang::IllegalArgumentException&)
+ {
+ }
+ }
+ return sal_False;
+}
+
+/* -----------------08.12.98 10:43-------------------
+ *
+ * --------------------------------------------------*/
+SvxNumRule* SvxConvertNumRule( const SvxNumRule* pRule, USHORT nLevels, SvxNumRuleType eType )
+{
+ const USHORT nSrcLevels = pRule->GetLevelCount();
+ SvxNumRule* pNewRule = new SvxNumRule( pRule->GetFeatureFlags(), nLevels, pRule->IsContinuousNumbering(), eType );
+
+ for( USHORT nLevel = 0; (nLevel < nLevels) && (nLevel < nSrcLevels); nLevel++ )
+ pNewRule->SetLevel( nLevel, pRule->GetLevel( nLevel ) );
+
+ return pNewRule;
+}
diff --git a/editeng/source/items/page.src b/editeng/source/items/page.src
new file mode 100644
index 0000000000..2e0b86f5d8
--- /dev/null
+++ b/editeng/source/items/page.src
@@ -0,0 +1,258 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: page.src,v $
+ * $Revision: 1.71 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+ // include ---------------------------------------------------------------
+
+#include <editeng/editrids.hrc>
+
+String RID_SVXSTR_PAPER_A0
+{
+ Text = "A0" ;
+};
+String RID_SVXSTR_PAPER_A1
+{
+ Text = "A1" ;
+};
+String RID_SVXSTR_PAPER_A2
+{
+ Text = "A2" ;
+};
+String RID_SVXSTR_PAPER_A3
+{
+ Text = "A3" ;
+};
+String RID_SVXSTR_PAPER_A4
+{
+ Text = "A4" ;
+};
+String RID_SVXSTR_PAPER_A5
+{
+ Text = "A5" ;
+};
+String RID_SVXSTR_PAPER_B4_ISO
+{
+ Text = "B4 (ISO)" ;
+};
+String RID_SVXSTR_PAPER_B5_ISO
+{
+ Text = "B5 (ISO)" ;
+};
+String RID_SVXSTR_PAPER_LETTER
+{
+ Text = "Letter" ;
+};
+String RID_SVXSTR_PAPER_LEGAL
+{
+ Text = "Legal" ;
+};
+String RID_SVXSTR_PAPER_TABLOID
+{
+ Text = "Tabloid" ;
+};
+String RID_SVXSTR_PAPER_USER
+{
+ Text [ en-US ] = "User Defined" ;
+};
+String RID_SVXSTR_PAPER_B6_ISO
+{
+ Text = "B6 (ISO)" ;
+};
+String RID_SVXSTR_PAPER_C4
+{
+ Text = "C4 Envelope" ;
+};
+String RID_SVXSTR_PAPER_C5
+{
+ Text = "C5 Envelope" ;
+};
+String RID_SVXSTR_PAPER_C6
+{
+ Text = "C6 Envelope" ;
+};
+String RID_SVXSTR_PAPER_C65
+{
+ Text = "C6/5 Envelope" ;
+};
+String RID_SVXSTR_PAPER_DL
+{
+ Text = "DL Envelope" ;
+};
+String RID_SVXSTR_PAPER_DIA
+{
+ Text = "Dia Slide" ;
+};
+String RID_SVXSTR_PAPER_SCREEN
+{
+ Text [ en-US ] = "Screen" ;
+};
+String RID_SVXSTR_PAPER_C
+{
+ Text = "C" ;
+};
+String RID_SVXSTR_PAPER_D
+{
+ Text = "D" ;
+};
+String RID_SVXSTR_PAPER_E
+{
+ Text = "E" ;
+};
+String RID_SVXSTR_PAPER_EXECUTIVE
+{
+ Text = "Executive" ;
+};
+String RID_SVXSTR_PAPER_LEGAL2
+{
+ Text = "Long Bond" ;
+};
+String RID_SVXSTR_PAPER_MONARCH
+{
+ Text = "#8 (Monarch) Envelope" ;
+};
+String RID_SVXSTR_PAPER_COM675
+{
+ Text = "#6 3/4 (Personal) Envelope" ;
+};
+String RID_SVXSTR_PAPER_COM9
+{
+ Text = "#9 Envelope" ;
+};
+String RID_SVXSTR_PAPER_COM10
+{
+ Text = "#10 Envelope" ;
+};
+String RID_SVXSTR_PAPER_COM11
+{
+ Text = "#11 Envelope" ;
+};
+String RID_SVXSTR_PAPER_COM12
+{
+ Text = "#12 Envelope" ;
+};
+String RID_SVXSTR_PAPER_KAI16
+{
+ Text = "16 Kai" ;
+};
+String RID_SVXSTR_PAPER_KAI32
+{
+ Text = "32 Kai" ;
+};
+String RID_SVXSTR_PAPER_KAI32BIG
+{
+ Text = "Big 32 Kai" ;
+};
+String RID_SVXSTR_PAPER_B4_JIS
+{
+ Text = "B4 (JIS)" ;
+};
+String RID_SVXSTR_PAPER_B5_JIS
+{
+ Text = "B5 (JIS)" ;
+};
+String RID_SVXSTR_PAPER_B6_JIS
+{
+ Text = "B6 (JIS)" ;
+};
+String RID_SVXSTR_PAPERBIN
+{
+ Text [ en-US ] = "Paper tray" ;
+};
+String RID_SVXSTR_PAPERBIN_SETTINGS
+{
+ Text [ en-US ] = "[From printer settings]" ;
+};
+ // ********************************************************************** EOF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/editeng/source/items/paperinf.cxx b/editeng/source/items/paperinf.cxx
new file mode 100644
index 0000000000..4992a25a9b
--- /dev/null
+++ b/editeng/source/items/paperinf.cxx
@@ -0,0 +1,188 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: paperinf.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+// include ---------------------------------------------------------------
+
+#include <limits.h>
+#include <tools/shl.hxx>
+#include <tools/debug.hxx>
+#include <vcl/svapp.hxx>
+#include <editeng/editrids.hrc>
+#include <editeng/paperinf.hxx>
+#include <editeng/eerdll.hxx>
+
+/*--------------------------------------------------------------------
+ Beschreibung: Ist der Printer gueltig
+ --------------------------------------------------------------------*/
+
+inline BOOL IsValidPrinter( const Printer* pPtr )
+{
+ return pPtr->GetName().Len() ? TRUE : FALSE;
+}
+
+//------------------------------------------------------------------------
+
+Size SvxPaperInfo::GetPaperSize( Paper ePaper, MapUnit eUnit )
+{
+ PaperInfo aInfo(ePaper);
+ Size aRet(aInfo.getWidth(), aInfo.getHeight()); // in 100thMM
+ return eUnit == MAP_100TH_MM ? aRet : OutputDevice::LogicToLogic(aRet, MAP_100TH_MM, eUnit);
+}
+
+/*------------------------------------------------------------------------
+ Beschreibung: Papiergroesse der Druckers liefern, aligned auf
+ die eigenen Groessen.
+ Falls kein Printer im System eingestellt ist,
+ wird DIN A4 Portrait als Defaultpapiergroesse geliefert.
+------------------------------------------------------------------------*/
+
+//Is this method may be confused about the units it returns ?
+//Always returns TWIPS for known paper sizes or on failure.
+//But in the case of PAPER_USER paper and with a Printer with a mapmode set
+//will return in those printer units ?
+Size SvxPaperInfo::GetPaperSize( const Printer* pPrinter )
+{
+ if ( !IsValidPrinter(pPrinter) )
+ return GetPaperSize( PAPER_A4 );
+ const Paper ePaper = pPrinter->GetPaper();
+
+ if ( ePaper == PAPER_USER )
+ {
+ // Orientation nicht beruecksichtigen, da durch SV bereits
+ // die richtigen Masze eingestellt worden sind.
+ Size aPaperSize = pPrinter->GetPaperSize();
+ const Size aInvalidSize;
+
+ if ( aPaperSize == aInvalidSize )
+ return GetPaperSize(PAPER_A4);
+ MapMode aMap1 = pPrinter->GetMapMode();
+ MapMode aMap2;
+
+ if ( aMap1 == aMap2 )
+ aPaperSize =
+ pPrinter->PixelToLogic( aPaperSize, MapMode( MAP_TWIP ) );
+ return aPaperSize;
+ }
+
+ const Orientation eOrient = pPrinter->GetOrientation();
+ Size aSize( GetPaperSize( ePaper ) );
+ // bei Landscape die Seiten tauschen, ist bei SV schon geschehen
+ if ( eOrient == ORIENTATION_LANDSCAPE )
+ Swap( aSize );
+ return aSize;
+}
+
+// -----------------------------------------------------------------------
+
+Paper SvxPaperInfo::GetSvxPaper( const Size &rSize, MapUnit eUnit, bool bSloppy )
+{
+ Size aSize(eUnit == MAP_100TH_MM ? rSize : OutputDevice::LogicToLogic(rSize, eUnit, MAP_100TH_MM));
+ PaperInfo aInfo(aSize.Width(), aSize.Height());
+ if (bSloppy)
+ aInfo.doSloppyFit();
+ return aInfo.getPaper();
+}
+
+// -----------------------------------------------------------------------
+
+long SvxPaperInfo::GetSloppyPaperDimension( long nSize, MapUnit eUnit )
+{
+ nSize = eUnit == MAP_100TH_MM ? nSize : OutputDevice::LogicToLogic(nSize, eUnit, MAP_100TH_MM);
+ nSize = PaperInfo::sloppyFitPageDimension(nSize);
+ return eUnit == MAP_100TH_MM ? nSize : OutputDevice::LogicToLogic(nSize, MAP_100TH_MM, eUnit);
+}
+
+// -----------------------------------------------------------------------
+
+Size SvxPaperInfo::GetDefaultPaperSize( MapUnit eUnit )
+{
+ PaperInfo aInfo(PaperInfo::getSystemDefaultPaper());
+ Size aRet(aInfo.getWidth(), aInfo.getHeight());
+ return eUnit == MAP_100TH_MM ? aRet : OutputDevice::LogicToLogic(aRet, MAP_100TH_MM, eUnit);
+}
+
+/*------------------------------------------------------------------------
+ Beschreibung: String Repr"asentation f"ur die SV-Defines f"ur
+ Papiergroessen.
+------------------------------------------------------------------------*/
+
+String SvxPaperInfo::GetName( Paper ePaper )
+{
+ USHORT nResId = 0;
+
+ switch ( ePaper )
+ {
+ case PAPER_A0: nResId = RID_SVXSTR_PAPER_A0; break;
+ case PAPER_A1: nResId = RID_SVXSTR_PAPER_A1; break;
+ case PAPER_A2: nResId = RID_SVXSTR_PAPER_A2; break;
+ case PAPER_A3: nResId = RID_SVXSTR_PAPER_A3; break;
+ case PAPER_A4: nResId = RID_SVXSTR_PAPER_A4; break;
+ case PAPER_A5: nResId = RID_SVXSTR_PAPER_A5; break;
+ case PAPER_B4_ISO: nResId = RID_SVXSTR_PAPER_B4_ISO; break;
+ case PAPER_B5_ISO: nResId = RID_SVXSTR_PAPER_B5_ISO; break;
+ case PAPER_LETTER: nResId = RID_SVXSTR_PAPER_LETTER; break;
+ case PAPER_LEGAL: nResId = RID_SVXSTR_PAPER_LEGAL; break;
+ case PAPER_TABLOID: nResId = RID_SVXSTR_PAPER_TABLOID; break;
+ case PAPER_USER: nResId = RID_SVXSTR_PAPER_USER; break;
+ case PAPER_B6_ISO: nResId = RID_SVXSTR_PAPER_B6_ISO; break;
+ case PAPER_ENV_C4: nResId = RID_SVXSTR_PAPER_C4; break;
+ case PAPER_ENV_C5: nResId = RID_SVXSTR_PAPER_C5; break;
+ case PAPER_ENV_C6: nResId = RID_SVXSTR_PAPER_C6; break;
+ case PAPER_ENV_C65: nResId = RID_SVXSTR_PAPER_C65; break;
+ case PAPER_ENV_DL: nResId = RID_SVXSTR_PAPER_DL; break;
+ case PAPER_SLIDE_DIA: nResId = RID_SVXSTR_PAPER_DIA; break;
+ case PAPER_SCREEN: nResId = RID_SVXSTR_PAPER_SCREEN; break;
+ case PAPER_C: nResId = RID_SVXSTR_PAPER_C; break;
+ case PAPER_D: nResId = RID_SVXSTR_PAPER_D; break;
+ case PAPER_E: nResId = RID_SVXSTR_PAPER_E; break;
+ case PAPER_EXECUTIVE: nResId = RID_SVXSTR_PAPER_EXECUTIVE;break;
+ case PAPER_FANFOLD_LEGAL_DE: nResId = RID_SVXSTR_PAPER_LEGAL2; break;
+ case PAPER_ENV_MONARCH: nResId = RID_SVXSTR_PAPER_MONARCH; break;
+ case PAPER_ENV_PERSONAL: nResId = RID_SVXSTR_PAPER_COM675; break;
+ case PAPER_ENV_9: nResId = RID_SVXSTR_PAPER_COM9; break;
+ case PAPER_ENV_10: nResId = RID_SVXSTR_PAPER_COM10; break;
+ case PAPER_ENV_11: nResId = RID_SVXSTR_PAPER_COM11; break;
+ case PAPER_ENV_12: nResId = RID_SVXSTR_PAPER_COM12; break;
+ case PAPER_KAI16: nResId = RID_SVXSTR_PAPER_KAI16; break;
+ case PAPER_KAI32: nResId = RID_SVXSTR_PAPER_KAI32; break;
+ case PAPER_KAI32BIG: nResId = RID_SVXSTR_PAPER_KAI32BIG; break;
+ case PAPER_B4_JIS: nResId = RID_SVXSTR_PAPER_B4_JIS; break;
+ case PAPER_B5_JIS: nResId = RID_SVXSTR_PAPER_B5_JIS; break;
+ case PAPER_B6_JIS: nResId = RID_SVXSTR_PAPER_B6_JIS; break;
+ default: DBG_ERRORFILE( "unknown papersize" );
+ }
+
+ return ( nResId > 0 ) ? String( EditResId( nResId ) ) : String();
+}
+
+
diff --git a/editeng/source/items/paraitem.cxx b/editeng/source/items/paraitem.cxx
new file mode 100644
index 0000000000..1f62a43fae
--- /dev/null
+++ b/editeng/source/items/paraitem.cxx
@@ -0,0 +1,1761 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: paraitem.cxx,v $
+ * $Revision: 1.40 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+// include ---------------------------------------------------------------
+#include <com/sun/star/style/TabStop.hpp>
+#include <com/sun/star/style/LineSpacing.hpp>
+#include <com/sun/star/style/LineSpacingMode.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/syslocale.hxx>
+#include <comphelper/types.hxx>
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+
+#include <tools/rtti.hxx>
+#include <basic/sbx.hxx>
+#define GLOBALOVERFLOW3
+
+#define _SVX_PARAITEM_CXX
+#include <svl/itempool.hxx>
+
+#include <svl/memberid.hrc>
+#include <editeng/editrids.hrc>
+
+#include <editeng/lspcitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/orphitem.hxx>
+#include <editeng/widwitem.hxx>
+#include <editeng/tstpitem.hxx>
+#include <editeng/pmdlitem.hxx>
+#include <editeng/spltitem.hxx>
+#include <editeng/hyznitem.hxx>
+#include <editeng/scriptspaceitem.hxx>
+#include <editeng/hngpnctitem.hxx>
+#include <editeng/forbiddenruleitem.hxx>
+#include <editeng/paravertalignitem.hxx>
+#include <editeng/pgrditem.hxx>
+#include <rtl/ustring.hxx>
+#include <editeng/memberids.hrc>
+#include <editeng/editids.hrc>
+#include <editeng/itemtype.hxx>
+#include <editeng/eerdll.hxx>
+#include <editeng/paperinf.hxx>
+#include <vcl/svapp.hxx>
+#include <algorithm>
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+
+// Konvertierung fuer UNO
+#define TWIP_TO_MM100(TWIP) ((TWIP) >= 0 ? (((TWIP)*127L+36L)/72L) : (((TWIP)*127L-36L)/72L))
+#define TWIP_TO_MM100_UNSIGNED(TWIP) ((((TWIP)*127L+36L)/72L))
+#define MM100_TO_TWIP(MM100) ((MM100) >= 0 ? (((MM100)*72L+63L)/127L) : (((MM100)*72L-63L)/127L))
+#define MM100_TO_TWIP_UNSIGNED(MM100) ((((MM100)*72L+63L)/127L))
+
+
+// STATIC DATA -----------------------------------------------------------
+
+
+// -----------------------------------------------------------------------
+
+
+TYPEINIT1_FACTORY(SvxLineSpacingItem, SfxPoolItem , new SvxLineSpacingItem(LINE_SPACE_DEFAULT_HEIGHT, 0));
+TYPEINIT1_FACTORY(SvxAdjustItem, SfxPoolItem, new SvxAdjustItem(SVX_ADJUST_LEFT, 0));
+TYPEINIT1_FACTORY(SvxWidowsItem, SfxByteItem, new SvxWidowsItem(0, 0));
+TYPEINIT1_FACTORY(SvxOrphansItem, SfxByteItem, new SvxOrphansItem(0, 0));
+TYPEINIT1_FACTORY(SvxHyphenZoneItem, SfxPoolItem, new SvxHyphenZoneItem(sal_False, 0));
+TYPEINIT1_FACTORY(SvxTabStopItem, SfxPoolItem, new SvxTabStopItem(0));
+TYPEINIT1_FACTORY(SvxFmtSplitItem, SfxBoolItem, new SvxFmtSplitItem(sal_False, 0));
+TYPEINIT1_FACTORY(SvxPageModelItem, SfxStringItem, new SvxPageModelItem(0));
+TYPEINIT1_FACTORY(SvxScriptSpaceItem, SfxBoolItem, new SvxScriptSpaceItem(sal_False, 0));
+TYPEINIT1_FACTORY(SvxHangingPunctuationItem, SfxBoolItem, new SvxHangingPunctuationItem(sal_False, 0));
+TYPEINIT1_FACTORY(SvxForbiddenRuleItem, SfxBoolItem, new SvxForbiddenRuleItem(sal_False, 0));
+TYPEINIT1_FACTORY(SvxParaVertAlignItem, SfxUInt16Item, new SvxParaVertAlignItem(0, 0));
+TYPEINIT1_FACTORY(SvxParaGridItem, SfxBoolItem, new SvxParaGridItem(sal_True, 0));
+
+SV_IMPL_VARARR_SORT( SvxTabStopArr, SvxTabStop )
+
+// -----------------------------------------------------------------------
+
+SvxLineSpacingItem::SvxLineSpacingItem( sal_uInt16 nHeight, const sal_uInt16 nId )
+ : SfxEnumItemInterface( nId )
+{
+ nPropLineSpace = 100;
+ nInterLineSpace = 0;
+ nLineHeight = nHeight;
+ eLineSpace = SVX_LINE_SPACE_AUTO;
+ eInterLineSpace = SVX_INTER_LINE_SPACE_OFF;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxLineSpacingItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ const SvxLineSpacingItem& rLineSpace = (const SvxLineSpacingItem&)rAttr;
+ return (
+ // Gleiche Linespacing Rule?
+ (eLineSpace == rLineSpace.eLineSpace)
+ // Bei maximalem und minimalem Linespacing muss das Mass
+ // uebereinstimmen.
+ && (eLineSpace == SVX_LINE_SPACE_AUTO ||
+ nLineHeight == rLineSpace.nLineHeight)
+ // Gleiche Interlinespacing Rule?
+ && ( eInterLineSpace == rLineSpace.eInterLineSpace )
+ // Entweder proportional oder draufaddieren eingestellt.
+ && (( eInterLineSpace == SVX_INTER_LINE_SPACE_OFF)
+ || (eInterLineSpace == SVX_INTER_LINE_SPACE_PROP
+ && nPropLineSpace == rLineSpace.nPropLineSpace)
+ || (eInterLineSpace == SVX_INTER_LINE_SPACE_FIX
+ && (nInterLineSpace == rLineSpace.nInterLineSpace)))) ?
+ 1 : 0;
+}
+
+/*-----------------18.03.98 16:32-------------------
+ os: wer weiss noch, wieso das LineSpacingItem so
+ kompliziert ist? Fuer UNO koennen wir das nicht
+ gebrauchen. Da gibt es nur zwei Werte:
+ - ein sal_uInt16 fuer den Modus
+ - ein sal_uInt32 fuer alle Werte (Abstand, Hoehe, rel. Angaben)
+
+--------------------------------------------------*/
+sal_Bool SvxLineSpacingItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+ sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+
+ style::LineSpacing aLSp;
+ switch( eLineSpace )
+ {
+ case SVX_LINE_SPACE_AUTO:
+ if(eInterLineSpace == SVX_INTER_LINE_SPACE_FIX)
+ {
+ aLSp.Mode = style::LineSpacingMode::LEADING;
+ aLSp.Height = ( bConvert ? (short)TWIP_TO_MM100(nInterLineSpace) : nInterLineSpace);
+ }
+ else if(eInterLineSpace == SVX_INTER_LINE_SPACE_OFF)
+ {
+ aLSp.Mode = style::LineSpacingMode::PROP;
+ aLSp.Height = 100;
+ }
+ else
+ {
+ aLSp.Mode = style::LineSpacingMode::PROP;
+ aLSp.Height = nPropLineSpace;
+ }
+ break;
+ case SVX_LINE_SPACE_FIX :
+ case SVX_LINE_SPACE_MIN :
+ aLSp.Mode = eLineSpace == SVX_LINE_SPACE_FIX ? style::LineSpacingMode::FIX : style::LineSpacingMode::MINIMUM;
+ aLSp.Height = ( bConvert ? (short)TWIP_TO_MM100_UNSIGNED(nLineHeight) : nLineHeight );
+ break;
+ default:
+ ;//prevent warning about SVX_LINE_SPACE_END
+ }
+
+ switch ( nMemberId )
+ {
+ case 0 : rVal <<= aLSp; break;
+ case MID_LINESPACE : rVal <<= aLSp.Mode; break;
+ case MID_HEIGHT : rVal <<= aLSp.Height; break;
+ default: DBG_ERROR("Wrong MemberId!"); break;
+ }
+
+ return sal_True;
+}
+/*-----------------18.03.98 16:32-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxLineSpacingItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+ sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+
+ // fill with current data
+ style::LineSpacing aLSp;
+ uno::Any aAny;
+ sal_Bool bRet = QueryValue( aAny, bConvert ? CONVERT_TWIPS : 0 ) && ( aAny >>= aLSp );
+
+ // get new data
+ switch ( nMemberId )
+ {
+ case 0 : bRet = (rVal >>= aLSp); break;
+ case MID_LINESPACE : bRet = (rVal >>= aLSp.Mode); break;
+ case MID_HEIGHT : bRet = (rVal >>= aLSp.Height); break;
+ default: DBG_ERROR("Wrong MemberId!"); break;
+ }
+
+ if( bRet )
+ {
+ nLineHeight = aLSp.Height;
+ switch( aLSp.Mode )
+ {
+ case style::LineSpacingMode::LEADING:
+ {
+ eInterLineSpace = SVX_INTER_LINE_SPACE_FIX;
+ eLineSpace = SVX_LINE_SPACE_AUTO;
+ nInterLineSpace = aLSp.Height;
+ if(bConvert)
+ nInterLineSpace = (short)MM100_TO_TWIP(nInterLineSpace);
+
+ }
+ break;
+ case style::LineSpacingMode::PROP:
+ {
+ eLineSpace = SVX_LINE_SPACE_AUTO;
+ nPropLineSpace = (sal_Int8)std::min(aLSp.Height, (short)0xFF);
+ if(100 == aLSp.Height)
+ eInterLineSpace = SVX_INTER_LINE_SPACE_OFF;
+ else
+ eInterLineSpace = SVX_INTER_LINE_SPACE_PROP;
+ }
+ break;
+ case style::LineSpacingMode::FIX:
+ case style::LineSpacingMode::MINIMUM:
+ {
+ eInterLineSpace = SVX_INTER_LINE_SPACE_OFF;
+ eLineSpace = aLSp.Mode == style::LineSpacingMode::FIX ? SVX_LINE_SPACE_FIX : SVX_LINE_SPACE_MIN;
+ nLineHeight = aLSp.Height;
+ if(bConvert)
+ nLineHeight = (USHORT)MM100_TO_TWIP_UNSIGNED(nLineHeight);
+ }
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxLineSpacingItem::Clone( SfxItemPool * ) const
+{
+ return new SvxLineSpacingItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxLineSpacingItem::GetPresentation
+(
+ SfxItemPresentation /*ePres*/,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *
+) const
+{
+#ifdef DBG_UTIL
+ rText.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "SvxLineSpacingItem" ));
+#else
+ rText.Erase();
+#endif
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxLineSpacingItem::Create(SvStream& rStrm, sal_uInt16) const
+{
+ sal_Int8 nPropSpace;
+ short nInterSpace;
+ sal_uInt16 nHeight;
+ sal_Int8 nRule, nInterRule;
+
+ rStrm >> nPropSpace
+ >> nInterSpace
+ >> nHeight
+ >> nRule
+ >> nInterRule;
+
+ SvxLineSpacingItem* pAttr = new SvxLineSpacingItem( nHeight, Which() );
+ pAttr->SetInterLineSpace( nInterSpace );
+ pAttr->SetPropLineSpace( nPropSpace );
+ pAttr->GetLineSpaceRule() = (SvxLineSpace)nRule;
+ pAttr->GetInterLineSpaceRule() = (SvxInterLineSpace)nInterRule;
+ return pAttr;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxLineSpacingItem::Store( SvStream& rStrm, sal_uInt16 /*nItemVersion*/ ) const
+{
+ rStrm << (sal_Int8) GetPropLineSpace()
+ << (short) GetInterLineSpace()
+ << (sal_uInt16) GetLineHeight()
+ << (sal_Int8) GetLineSpaceRule()
+ << (sal_Int8) GetInterLineSpaceRule();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxLineSpacingItem::GetValueCount() const
+{
+ return SVX_LINESPACE_END; // SVX_LINESPACE_TWO_LINES + 1
+}
+
+// -----------------------------------------------------------------------
+
+XubString SvxLineSpacingItem::GetValueTextByPos( sal_uInt16 nPos ) const
+{
+ //! Strings demnaechst aus Resource laden
+ XubString aText;
+ switch ( nPos )
+ {
+ case SVX_LINESPACE_USER : aText.AppendAscii( "Benutzer" ); break;
+ case SVX_LINESPACE_ONE_LINE : aText.AppendAscii( "Einzeilig" ); break;
+ case SVX_LINESPACE_ONE_POINT_FIVE_LINES : aText.AppendAscii( "1,5zeilig" ); break;
+ case SVX_LINESPACE_TWO_LINES : aText.AppendAscii( "Zweizeilig" ); break;
+ }
+ return aText;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxLineSpacingItem::GetEnumValue() const
+{
+ sal_uInt16 nVal;
+ switch ( nPropLineSpace )
+ {
+ case 100: nVal = SVX_LINESPACE_ONE_LINE; break;
+ case 150: nVal = SVX_LINESPACE_ONE_POINT_FIVE_LINES; break;
+ case 200: nVal = SVX_LINESPACE_TWO_LINES; break;
+ default: nVal = SVX_LINESPACE_USER; break;
+ }
+ return nVal;
+}
+
+// -----------------------------------------------------------------------
+
+void SvxLineSpacingItem::SetEnumValue( sal_uInt16 nVal )
+{
+ switch ( nVal )
+ {
+ case SVX_LINESPACE_ONE_LINE: nPropLineSpace = 100; break;
+ case SVX_LINESPACE_ONE_POINT_FIVE_LINES: nPropLineSpace = 150; break;
+ case SVX_LINESPACE_TWO_LINES: nPropLineSpace = 200; break;
+ }
+}
+
+// class SvxAdjustItem ---------------------------------------------------
+
+SvxAdjustItem::SvxAdjustItem(const SvxAdjust eAdjst, const sal_uInt16 nId )
+ : SfxEnumItemInterface( nId ),
+ bOneBlock( sal_False ), bLastCenter( sal_False ), bLastBlock( sal_False )
+{
+ SetAdjust( eAdjst );
+}
+
+// -----------------------------------------------------------------------
+
+int SvxAdjustItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ return( ( GetAdjust() == ((SvxAdjustItem&)rAttr).GetAdjust() &&
+ bOneBlock == ((SvxAdjustItem&)rAttr).bOneBlock &&
+ bLastCenter == ((SvxAdjustItem&)rAttr).bLastCenter &&
+ bLastBlock == ((SvxAdjustItem&)rAttr).bLastBlock )
+ ? 1 : 0 );
+}
+
+/*-----------------18.03.98 16:15-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxAdjustItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch( nMemberId )
+ {
+ case MID_PARA_ADJUST : rVal <<= (sal_Int16)GetAdjust(); break;
+ case MID_LAST_LINE_ADJUST : rVal <<= (sal_Int16)GetLastBlock(); break;
+ case MID_EXPAND_SINGLE :
+ {
+ sal_Bool bValue = bOneBlock;
+ rVal.setValue( &bValue, ::getCppuBooleanType() );
+ break;
+ }
+ default: ;//prevent warning
+ }
+ return sal_True;
+}
+/*-----------------18.03.98 16:15-------------------
+
+--------------------------------------------------*/
+
+sal_Bool SvxAdjustItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch( nMemberId )
+ {
+ case MID_PARA_ADJUST :
+ case MID_LAST_LINE_ADJUST :
+ {
+ sal_Int32 eVal = - 1;
+ try
+ {
+ eVal = ::comphelper::getEnumAsINT32(rVal);
+ }
+ catch(...) {}
+ if(eVal >= 0 && eVal <= 4)
+ {
+ if(MID_LAST_LINE_ADJUST == nMemberId &&
+ eVal != SVX_ADJUST_LEFT &&
+ eVal != SVX_ADJUST_BLOCK &&
+ eVal != SVX_ADJUST_CENTER)
+ return FALSE;
+ if(eVal < (sal_uInt16)SVX_ADJUST_END)
+ nMemberId == MID_PARA_ADJUST ?
+ SetAdjust((SvxAdjust)eVal) :
+ SetLastBlock((SvxAdjust)eVal);
+ }
+ }
+ break;
+ case MID_EXPAND_SINGLE :
+ bOneBlock = Any2Bool(rVal);
+ break;
+ }
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxAdjustItem::Clone( SfxItemPool * ) const
+{
+ return new SvxAdjustItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxAdjustItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return SFX_ITEM_PRESENTATION_NONE;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = GetValueTextByPos( (sal_uInt16)GetAdjust() );
+ return ePres;
+ default: ;//prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxAdjustItem::GetValueCount() const
+{
+ return SVX_ADJUST_END; // SVX_ADJUST_BLOCKLINE + 1
+}
+
+// -----------------------------------------------------------------------
+
+XubString SvxAdjustItem::GetValueTextByPos( sal_uInt16 nPos ) const
+{
+ DBG_ASSERT( nPos <= (sal_uInt16)SVX_ADJUST_BLOCKLINE, "enum overflow!" );
+ return EE_RESSTR(RID_SVXITEMS_ADJUST_BEGIN + nPos);
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxAdjustItem::GetEnumValue() const
+{
+ return (sal_uInt16)GetAdjust();
+}
+
+// -----------------------------------------------------------------------
+
+void SvxAdjustItem::SetEnumValue( sal_uInt16 nVal )
+{
+ SetAdjust( (const SvxAdjust)nVal );
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxAdjustItem::GetVersion( sal_uInt16 nFileVersion ) const
+{
+ return (nFileVersion == SOFFICE_FILEFORMAT_31)
+ ? 0 : ADJUST_LASTBLOCK_VERSION;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxAdjustItem::Create(SvStream& rStrm, sal_uInt16 nVersion) const
+{
+ char eAdjustment;
+ rStrm >> eAdjustment;
+ SvxAdjustItem *pRet = new SvxAdjustItem( (SvxAdjust)eAdjustment, Which() );
+ if( nVersion >= ADJUST_LASTBLOCK_VERSION )
+ {
+ sal_Int8 nFlags;
+ rStrm >> nFlags;
+ pRet->bOneBlock = 0 != (nFlags & 0x0001);
+ pRet->bLastCenter = 0 != (nFlags & 0x0002);
+ pRet->bLastBlock = 0 != (nFlags & 0x0004);
+ }
+ return pRet;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxAdjustItem::Store( SvStream& rStrm, sal_uInt16 nItemVersion ) const
+{
+ rStrm << (char)GetAdjust();
+ if ( nItemVersion >= ADJUST_LASTBLOCK_VERSION )
+ {
+ sal_Int8 nFlags = 0;
+ if ( bOneBlock )
+ nFlags |= 0x0001;
+ if ( bLastCenter )
+ nFlags |= 0x0002;
+ if ( bLastBlock )
+ nFlags |= 0x0004;
+ rStrm << (sal_Int8) nFlags;
+ }
+ return rStrm;
+}
+
+// class SvxWidowsItem ---------------------------------------------------
+
+SvxWidowsItem::SvxWidowsItem(const BYTE nL, const USHORT nId ) :
+ SfxByteItem( nId, nL )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxWidowsItem::Clone( SfxItemPool * ) const
+{
+ return new SvxWidowsItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxWidowsItem::Create(SvStream& rStrm, sal_uInt16) const
+{
+ sal_Int8 nLines;
+ rStrm >> nLines;
+ return new SvxWidowsItem( nLines, Which() );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxWidowsItem::Store( SvStream& rStrm, sal_uInt16 /*nItemVersion*/ ) const
+{
+ rStrm << (sal_Int8)GetValue();
+ return rStrm;
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxWidowsItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ {
+ rText.Erase();
+ break;
+ }
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ {
+ rText = EE_RESSTR(RID_SVXITEMS_LINES);
+ break;
+ }
+
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ rText = EE_RESSTR(RID_SVXITEMS_WIDOWS_COMPLETE);
+ rText += ' ';
+ rText += EE_RESSTR(RID_SVXITEMS_LINES);
+ }
+
+ default:
+ {
+ DBG_ERRORFILE( "SvxWidowsItem::GetPresentation(): unknown SfxItemPresentation" );
+ }
+ }
+
+ rText.SearchAndReplace( String::CreateFromAscii( "%1" ), String::CreateFromInt32( GetValue() ) );
+ return ePres;
+}
+
+// class SvxOrphansItem --------------------------------------------------
+
+SvxOrphansItem::SvxOrphansItem(const BYTE nL, const USHORT nId ) :
+ SfxByteItem( nId, nL )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxOrphansItem::Clone( SfxItemPool * ) const
+{
+ return new SvxOrphansItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxOrphansItem::Create(SvStream& rStrm, sal_uInt16) const
+{
+ sal_Int8 nLines;
+ rStrm >> nLines;
+ return new SvxOrphansItem( nLines, Which() );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxOrphansItem::Store( SvStream& rStrm, sal_uInt16 /*nItemVersion*/ ) const
+{
+ rStrm << (sal_Int8) GetValue();
+ return rStrm;
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxOrphansItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ {
+ rText.Erase();
+ break;
+ }
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ {
+ rText = EE_RESSTR(RID_SVXITEMS_LINES);
+ break;
+ }
+
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ rText = EE_RESSTR(RID_SVXITEMS_ORPHANS_COMPLETE);
+ rText += ' ';
+ rText += EE_RESSTR(RID_SVXITEMS_LINES);
+ }
+
+ default:
+ {
+ DBG_ERRORFILE( "SvxOrphansItem::GetPresentation(): unknown SfxItemPresentation" );
+ }
+ }
+
+ rText.SearchAndReplace( String::CreateFromAscii( "%1" ), String::CreateFromInt32( GetValue() ) );
+ return ePres;
+}
+
+// class SvxHyphenZoneItem -----------------------------------------------
+
+SvxHyphenZoneItem::SvxHyphenZoneItem( const sal_Bool bHyph, const sal_uInt16 nId ) :
+ SfxPoolItem( nId )
+{
+ bHyphen = bHyph;
+ bPageEnd = sal_True;
+ nMinLead = nMinTrail = 0;
+ nMaxHyphens = 255;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SvxHyphenZoneItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch(nMemberId)
+ {
+ case MID_IS_HYPHEN:
+ rVal = Bool2Any(bHyphen);
+ break;
+ case MID_HYPHEN_MIN_LEAD:
+ rVal <<= (sal_Int16)nMinLead;
+ break;
+ case MID_HYPHEN_MIN_TRAIL:
+ rVal <<= (sal_Int16)nMinTrail;
+ break;
+ case MID_HYPHEN_MAX_HYPHENS:
+ rVal <<= (sal_Int16)nMaxHyphens;
+ break;
+ }
+ return sal_True;
+}
+// -----------------------------------------------------------------------
+sal_Bool SvxHyphenZoneItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ sal_Int16 nNewVal = 0;
+
+ if( nMemberId != MID_IS_HYPHEN )
+ if(!(rVal >>= nNewVal))
+ return sal_False;
+
+ switch(nMemberId)
+ {
+ case MID_IS_HYPHEN:
+ bHyphen = Any2Bool(rVal);
+ break;
+ case MID_HYPHEN_MIN_LEAD:
+ nMinLead = (BYTE)nNewVal;
+ break;
+ case MID_HYPHEN_MIN_TRAIL:
+ nMinTrail = (BYTE)nNewVal;
+ break;
+ case MID_HYPHEN_MAX_HYPHENS:
+ nMaxHyphens = (BYTE)nNewVal;
+ break;
+ }
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxHyphenZoneItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ return ( (((SvxHyphenZoneItem&)rAttr).bHyphen == bHyphen)
+ && (((SvxHyphenZoneItem&)rAttr).bPageEnd == bPageEnd)
+ && (((SvxHyphenZoneItem&)rAttr).nMinLead == nMinLead)
+ && (((SvxHyphenZoneItem&)rAttr).nMinTrail == nMinTrail)
+ && (((SvxHyphenZoneItem&)rAttr).nMaxHyphens == nMaxHyphens) );
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxHyphenZoneItem::Clone( SfxItemPool * ) const
+{
+ return new SvxHyphenZoneItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxHyphenZoneItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return SFX_ITEM_PRESENTATION_NONE;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ {
+ sal_uInt16 nId = RID_SVXITEMS_HYPHEN_FALSE;
+
+ if ( bHyphen )
+ nId = RID_SVXITEMS_HYPHEN_TRUE;
+ rText = EE_RESSTR(nId);
+ rText += cpDelim;
+ nId = RID_SVXITEMS_PAGE_END_FALSE;
+
+ if ( bPageEnd )
+ nId = RID_SVXITEMS_PAGE_END_TRUE;
+ rText += EE_RESSTR(nId);
+ rText += cpDelim;
+ rText += String::CreateFromInt32( nMinLead );
+ rText += cpDelim;
+ rText += String::CreateFromInt32( nMinTrail );
+ rText += cpDelim;
+ rText += String::CreateFromInt32( nMaxHyphens );
+ return SFX_ITEM_PRESENTATION_COMPLETE;
+ }
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ sal_uInt16 nId = RID_SVXITEMS_HYPHEN_FALSE;
+
+ if ( bHyphen )
+ nId = RID_SVXITEMS_HYPHEN_TRUE;
+ rText = EE_RESSTR(nId);
+ rText += cpDelim;
+ nId = RID_SVXITEMS_PAGE_END_FALSE;
+
+ if ( bPageEnd )
+ nId = RID_SVXITEMS_PAGE_END_TRUE;
+ rText += EE_RESSTR(nId);
+ rText += cpDelim;
+ rText += String::CreateFromInt32(nMinLead);
+ rText += EE_RESSTR(RID_SVXITEMS_HYPHEN_MINLEAD);
+ rText += cpDelim;
+ rText += String::CreateFromInt32(nMinTrail);
+ rText += EE_RESSTR(RID_SVXITEMS_HYPHEN_MINTRAIL);
+ rText += cpDelim;
+ rText += String::CreateFromInt32(nMaxHyphens);
+ rText += EE_RESSTR(RID_SVXITEMS_HYPHEN_MAX);
+ return SFX_ITEM_PRESENTATION_COMPLETE;
+ }
+ default: ;//prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxHyphenZoneItem::Create(SvStream& rStrm, sal_uInt16) const
+{
+ sal_Int8 _bHyphen, _bHyphenPageEnd;
+ sal_Int8 _nMinLead, _nMinTrail, _nMaxHyphens;
+ rStrm >> _bHyphen >> _bHyphenPageEnd >> _nMinLead >> _nMinTrail >> _nMaxHyphens;
+ SvxHyphenZoneItem* pAttr = new SvxHyphenZoneItem( sal_False, Which() );
+ pAttr->SetHyphen( sal_Bool( _bHyphen != 0 ) );
+ pAttr->SetPageEnd( sal_Bool( _bHyphenPageEnd != 0 ) );
+ pAttr->GetMinLead() = _nMinLead;
+ pAttr->GetMinTrail() = _nMinTrail;
+ pAttr->GetMaxHyphens() = _nMaxHyphens;
+ return pAttr;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxHyphenZoneItem::Store( SvStream& rStrm, sal_uInt16 /*nItemVersion*/ ) const
+{
+ rStrm << (sal_Int8) IsHyphen()
+ << (sal_Int8) IsPageEnd()
+ << (sal_Int8) GetMinLead()
+ << (sal_Int8) GetMinTrail()
+ << (sal_Int8) GetMaxHyphens();
+ return rStrm;
+}
+
+// class SvxTabStop ------------------------------------------------------
+
+SvxTabStop::SvxTabStop()
+{
+ nTabPos = 0;
+ eAdjustment = SVX_TAB_ADJUST_LEFT;
+ m_cDecimal = cDfltDecimalChar;
+ cFill = cDfltFillChar;
+}
+
+// -----------------------------------------------------------------------
+
+SvxTabStop::SvxTabStop( const long nPos, const SvxTabAdjust eAdjst,
+ const sal_Unicode cDec, const sal_Unicode cFil )
+{
+ nTabPos = nPos;
+ eAdjustment = eAdjst;
+ m_cDecimal = cDec;
+ cFill = cFil;
+}
+// -----------------------------------------------------------------------------
+void SvxTabStop::fillDecimal() const
+{
+ if ( cDfltDecimalChar == m_cDecimal )
+ m_cDecimal = SvtSysLocale().GetLocaleData().getNumDecimalSep().GetChar(0);
+}
+// -----------------------------------------------------------------------
+
+XubString SvxTabStop::GetValueString() const
+{
+ XubString aStr;
+
+ aStr += sal_Unicode( '(' );
+ aStr += UniString::CreateFromInt32(nTabPos);
+ aStr += cpDelim;
+ aStr += XubString( EditResId( RID_SVXITEMS_TAB_ADJUST_BEGIN + (sal_uInt16)eAdjustment ) );
+
+ aStr += cpDelim;
+ aStr += sal_Unicode('[');
+ aStr += XubString( EditResId( RID_SVXITEMS_TAB_DECIMAL_CHAR ) );
+ aStr += GetDecimal();
+ aStr += sal_Unicode(']');
+ aStr += cpDelim;
+ aStr += cpDelim;
+ aStr += sal_Unicode('[');
+ aStr += XubString( EditResId( RID_SVXITEMS_TAB_FILL_CHAR ) );
+ aStr += cFill;
+ aStr += sal_Unicode(']');
+ aStr += sal_Unicode(')');
+
+ return aStr;
+}
+
+// class SvxTabStopItem --------------------------------------------------
+
+SvxTabStopItem::SvxTabStopItem( sal_uInt16 _nWhich ) :
+ SfxPoolItem( _nWhich ),
+ SvxTabStopArr( sal_Int8(SVX_TAB_DEFCOUNT) )
+{
+ const sal_uInt16 nTabs = SVX_TAB_DEFCOUNT, nDist = SVX_TAB_DEFDIST;
+ const SvxTabAdjust eAdjst= SVX_TAB_ADJUST_DEFAULT;
+
+ for (sal_uInt16 i = 0; i < nTabs; ++i)
+ {
+ SvxTabStop aTab( (i + 1) * nDist, eAdjst );
+ SvxTabStopArr::Insert( aTab );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SvxTabStopItem::SvxTabStopItem( const sal_uInt16 nTabs,
+ const sal_uInt16 nDist,
+ const SvxTabAdjust eAdjst,
+ sal_uInt16 _nWhich ) :
+ SfxPoolItem( _nWhich ),
+ SvxTabStopArr( sal_Int8(nTabs) )
+{
+ for ( sal_uInt16 i = 0; i < nTabs; ++i )
+ {
+ SvxTabStop aTab( (i + 1) * nDist, eAdjst );
+ SvxTabStopArr::Insert( aTab );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SvxTabStopItem::SvxTabStopItem( const SvxTabStopItem& rTSI ) :
+ SfxPoolItem( rTSI.Which() ),
+ SvxTabStopArr( (sal_Int8)rTSI.Count() )
+{
+ SvxTabStopArr::Insert( &rTSI );
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxTabStopItem::GetPos( const SvxTabStop& rTab ) const
+{
+ sal_uInt16 nFound;
+ return Seek_Entry( rTab, &nFound ) ? nFound : SVX_TAB_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 SvxTabStopItem::GetPos( const long nPos ) const
+{
+ sal_uInt16 nFound;
+ return Seek_Entry( SvxTabStop( nPos ), &nFound ) ? nFound : SVX_TAB_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+SvxTabStopItem& SvxTabStopItem::operator=( const SvxTabStopItem& rTSI )
+{
+ Remove( 0, Count() );
+ SvxTabStopArr::Insert( &rTSI );
+ return *this;
+}
+
+
+/*
+ enum ::com::sun::star::style::TabAlign
+{
+ TABALIGN_LEFT,
+ TABALIGN_CENTER,
+ TABALIGN_RIGHT,
+ TABALIGN_DECIMAL
+};
+
+struct ::com::sun::star::style::TabStop
+{
+ long Position;
+ ::com::sun::star::style::TabAlign ::com::sun::star::drawing::Alignment;
+ unsigned short DecimalChar;
+ unsigned short FillChar;
+};
+typedef sequence ::com::sun::star::style::TabStop> TabSTopSequence;
+
+ */
+/*-----------------19.03.98 08:50-------------------
+
+--------------------------------------------------*/
+
+sal_Bool SvxTabStopItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+ sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch ( nMemberId )
+ {
+ case MID_TABSTOPS:
+ {
+ sal_uInt16 nCount = Count();
+ uno::Sequence< style::TabStop> aSeq(nCount);
+ style::TabStop* pArr = aSeq.getArray();
+ for(sal_uInt16 i = 0; i < nCount; i++)
+ {
+ const SvxTabStop& rTab = *(GetStart() + i);
+ pArr[i].Position = bConvert ? TWIP_TO_MM100(rTab.GetTabPos()) : rTab.GetTabPos();
+ switch(rTab.GetAdjustment())
+ {
+ case SVX_TAB_ADJUST_LEFT : pArr[i].Alignment = style::TabAlign_LEFT; break;
+ case SVX_TAB_ADJUST_RIGHT : pArr[i].Alignment = style::TabAlign_RIGHT; break;
+ case SVX_TAB_ADJUST_DECIMAL: pArr[i].Alignment = style::TabAlign_DECIMAL; break;
+ case SVX_TAB_ADJUST_CENTER : pArr[i].Alignment = style::TabAlign_CENTER; break;
+ default: //SVX_TAB_ADJUST_DEFAULT
+ pArr[i].Alignment = style::TabAlign_DEFAULT;
+
+ }
+ pArr[i].DecimalChar = rTab.GetDecimal();
+ pArr[i].FillChar = rTab.GetFill();
+ }
+ rVal <<= aSeq;
+ break;
+ }
+ case MID_STD_TAB:
+ {
+ const SvxTabStop &rTab = *(GetStart());
+ rVal <<= static_cast<sal_Int32>(bConvert ? TWIP_TO_MM100(rTab.GetTabPos()) : rTab.GetTabPos());
+ break;
+ }
+ }
+ return sal_True;
+}
+/*-----------------19.03.98 08:50-------------------
+
+--------------------------------------------------*/
+
+sal_Bool SvxTabStopItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+ sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch ( nMemberId )
+ {
+ case MID_TABSTOPS:
+ {
+ uno::Sequence< style::TabStop> aSeq;
+ if(!(rVal >>= aSeq))
+ {
+ uno::Sequence < uno::Sequence < uno::Any > > aAnySeq;
+ if (!(rVal >>= aAnySeq))
+ return sal_False;
+ sal_Int32 nLength = aAnySeq.getLength();
+ aSeq.realloc( nLength );
+ for ( sal_Int32 n=0; n<nLength; n++ )
+ {
+ uno::Sequence < uno::Any >& rAnySeq = aAnySeq[n];
+ if ( rAnySeq.getLength() == 4 )
+ {
+ if (!(rAnySeq[0] >>= aSeq[n].Position)) return sal_False;
+ if (!(rAnySeq[1] >>= aSeq[n].Alignment))
+ {
+ sal_Int32 nVal = 0;
+ if (rAnySeq[1] >>= nVal)
+ aSeq[n].Alignment = (com::sun::star::style::TabAlign) nVal;
+ else
+ return sal_False;
+ }
+ if (!(rAnySeq[2] >>= aSeq[n].DecimalChar))
+ {
+ ::rtl::OUString aVal;
+ if ( (rAnySeq[2] >>= aVal) && aVal.getLength() == 1 )
+ aSeq[n].DecimalChar = aVal.toChar();
+ else
+ return sal_False;
+ }
+ if (!(rAnySeq[3] >>= aSeq[n].FillChar))
+ {
+ ::rtl::OUString aVal;
+ if ( (rAnySeq[3] >>= aVal) && aVal.getLength() == 1 )
+ aSeq[n].FillChar = aVal.toChar();
+ else
+ return sal_False;
+ }
+ }
+ else
+ return sal_False;
+ }
+ }
+
+ SvxTabStopArr::Remove( 0, Count() );
+ const style::TabStop* pArr = aSeq.getConstArray();
+ const sal_uInt16 nCount = (sal_uInt16)aSeq.getLength();
+ for(sal_uInt16 i = 0; i < nCount ; i++)
+ {
+ SvxTabAdjust eAdjust = SVX_TAB_ADJUST_DEFAULT;
+ switch(pArr[i].Alignment)
+ {
+ case style::TabAlign_LEFT : eAdjust = SVX_TAB_ADJUST_LEFT; break;
+ case style::TabAlign_CENTER : eAdjust = SVX_TAB_ADJUST_CENTER; break;
+ case style::TabAlign_RIGHT : eAdjust = SVX_TAB_ADJUST_RIGHT; break;
+ case style::TabAlign_DECIMAL: eAdjust = SVX_TAB_ADJUST_DECIMAL; break;
+ default: ;//prevent warning
+ }
+ sal_Unicode cFill = pArr[i].FillChar;
+ sal_Unicode cDecimal = pArr[i].DecimalChar;
+ SvxTabStop aTab( bConvert ? MM100_TO_TWIP(pArr[i].Position) : pArr[i].Position,
+ eAdjust,
+ cDecimal,
+ cFill );
+ Insert(aTab);
+ }
+ break;
+ }
+ case MID_STD_TAB:
+ {
+ sal_Int32 nNewPos = 0;
+ if (!(rVal >>= nNewPos) )
+ return sal_False;
+ const SvxTabStop& rTab = *(GetStart());
+ SvxTabStop aNewTab ( bConvert ? MM100_TO_TWIP ( nNewPos ) : nNewPos,
+ rTab.GetAdjustment(), rTab.GetDecimal(), rTab.GetFill() );
+ Remove ( 0 );
+ Insert( aNewTab );
+ break;
+ }
+ }
+ return sal_True;
+}
+// -----------------------------------------------------------------------
+
+int SvxTabStopItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ const SvxTabStopItem& rTSI = (SvxTabStopItem&)rAttr;
+
+ if ( Count() != rTSI.Count() )
+ return 0;
+
+ for ( sal_uInt16 i = 0; i < Count(); ++i )
+ if( !(*this)[i].IsEqual( rTSI[i] ) )
+ return 0;
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxTabStopItem::Clone( SfxItemPool * ) const
+{
+ return new SvxTabStopItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxTabStopItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit eCoreUnit,
+ SfxMapUnit ePresUnit,
+ XubString& rText, const IntlWrapper *pIntl
+) const
+{
+ rText.Erase();
+
+ if ( ePres > SFX_ITEM_PRESENTATION_NONE )
+ {
+#ifndef SVX_LIGHT
+ sal_Bool bComma = sal_False;
+
+ for ( sal_uInt16 i = 0; i < Count(); ++i )
+ {
+ if ( SVX_TAB_ADJUST_DEFAULT != ((*this)[i]).GetAdjustment() )
+ {
+ if ( bComma )
+ rText += sal_Unicode(',');
+ rText += GetMetricText(
+ (long)((*this)[i]).GetTabPos(), eCoreUnit, ePresUnit, pIntl );
+ if ( SFX_ITEM_PRESENTATION_COMPLETE == ePres )
+ rText += EE_RESSTR(GetMetricId(ePresUnit));
+ bComma = sal_True;
+ }
+ }
+#endif
+ }
+ return ePres;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxTabStopItem::Create( SvStream& rStrm, sal_uInt16 ) const
+{
+ sal_Int8 nTabs;
+ rStrm >> nTabs;
+ SvxTabStopItem* pAttr =
+ new SvxTabStopItem( 0, 0, SVX_TAB_ADJUST_DEFAULT, Which() );
+
+ for ( sal_Int8 i = 0; i < nTabs; i++ )
+ {
+ long nPos;
+ sal_Int8 eAdjust;
+ unsigned char cDecimal, cFill;
+ rStrm >> nPos >> eAdjust >> cDecimal >> cFill;
+ if( !i || SVX_TAB_ADJUST_DEFAULT != eAdjust )
+ pAttr->Insert( SvxTabStop
+ ( nPos, (SvxTabAdjust)eAdjust, sal_Unicode(cDecimal), sal_Unicode(cFill) ) );
+ }
+ return pAttr;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxTabStopItem::Store( SvStream& rStrm, sal_uInt16 /*nItemVersion*/ ) const
+{
+ //MA 05. Sep. 96: Default-Tabs werden nur noch fuer das default-Attr
+ //expandiert. Fuer vollstaendige Rueckwaertskompatibilitaet (<=304)
+ //muessten alle Tabs expandiert werden, dass blaeht aber das File u.U.
+ //enorm auf.
+ //Alles nur SWG!
+
+ const SfxItemPool *pPool = SfxItemPool::GetStoringPool();
+ const FASTBOOL bStoreDefTabs = pPool
+ && pPool->GetName().EqualsAscii("SWG")
+ && ::IsDefaultItem( this );
+
+ const short nTabs = Count();
+ sal_uInt16 nCount = 0, nDefDist = 0;
+ long nNew = 0;
+
+ if( bStoreDefTabs )
+ {
+ const SvxTabStopItem& rDefTab = (const SvxTabStopItem &)
+ pPool->GetDefaultItem( pPool->GetWhich( SID_ATTR_TABSTOP, sal_False ) );
+ nDefDist = sal_uInt16( rDefTab.GetStart()->GetTabPos() );
+ const long nPos = nTabs > 0 ? (*this)[nTabs-1].GetTabPos() : 0;
+ nCount = (sal_uInt16)(nPos / nDefDist);
+ nNew = (nCount + 1) * nDefDist;
+
+ if( nNew <= nPos + 50 )
+ nNew += nDefDist;
+
+ long lA3Width = SvxPaperInfo::GetPaperSize(PAPER_A3).Width();
+ nCount = (sal_uInt16)(nNew < lA3Width ? ( lA3Width - nNew ) / nDefDist + 1 : 0);
+ }
+
+ rStrm << (sal_Int8) ( nTabs + nCount );
+ for ( short i = 0; i < nTabs; i++ )
+ {
+ const SvxTabStop& rTab = (*this)[ i ];
+ rStrm << (long) rTab.GetTabPos()
+ << (sal_Int8) rTab.GetAdjustment()
+ << (unsigned char) rTab.GetDecimal()
+ << (unsigned char) rTab.GetFill();
+ }
+
+ if ( bStoreDefTabs )
+ for( ; nCount; --nCount )
+ {
+ SvxTabStop aSwTabStop(nNew, SVX_TAB_ADJUST_DEFAULT);
+ rStrm << (long) aSwTabStop.GetTabPos()
+ << (sal_Int8) aSwTabStop.GetAdjustment()
+ << (unsigned char) aSwTabStop.GetDecimal()
+ << (unsigned char) aSwTabStop.GetFill();
+ nNew += nDefDist;
+ }
+
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SvxTabStopItem::Insert( const SvxTabStop& rTab )
+{
+ sal_uInt16 nTabPos = GetPos(rTab);
+ if(SVX_TAB_NOTFOUND != nTabPos )
+ Remove(nTabPos);
+ return SvxTabStopArr::Insert( rTab );
+}
+// -----------------------------------------------------------------------
+void SvxTabStopItem::Insert( const SvxTabStopItem* pTabs, sal_uInt16 nStart,
+ sal_uInt16 nEnd )
+{
+ for( sal_uInt16 i = nStart; i < nEnd && i < pTabs->Count(); i++ )
+ {
+ const SvxTabStop& rTab = (*pTabs)[i];
+ sal_uInt16 nTabPos = GetPos(rTab);
+ if(SVX_TAB_NOTFOUND != nTabPos)
+ Remove(nTabPos);
+ }
+ SvxTabStopArr::Insert( pTabs, nStart, nEnd );
+}
+
+
+
+// class SvxFmtSplitItem -------------------------------------------------
+SvxFmtSplitItem::~SvxFmtSplitItem()
+{
+}
+// -----------------------------------------------------------------------
+SfxPoolItem* SvxFmtSplitItem::Clone( SfxItemPool * ) const
+{
+ return new SvxFmtSplitItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxFmtSplitItem::Store( SvStream& rStrm, sal_uInt16 /*nItemVersion*/ ) const
+{
+ rStrm << (sal_Int8)GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxFmtSplitItem::Create( SvStream& rStrm, sal_uInt16 ) const
+{
+ sal_Int8 bIsSplit;
+ rStrm >> bIsSplit;
+ return new SvxFmtSplitItem( sal_Bool( bIsSplit != 0 ), Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxFmtSplitItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return SFX_ITEM_PRESENTATION_NONE;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ sal_uInt16 nId = RID_SVXITEMS_FMTSPLIT_FALSE;
+
+ if ( GetValue() )
+ nId = RID_SVXITEMS_FMTSPLIT_TRUE;
+ rText = EE_RESSTR(nId);
+ return ePres;
+ }
+ default: ;//prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// --------------------------------------------------------------------
+
+SfxPoolItem* SvxPageModelItem::Clone( SfxItemPool* ) const
+{
+ return new SvxPageModelItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SvxPageModelItem::QueryValue( com::sun::star::uno::Any& rVal, BYTE nMemberId ) const
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+
+ switch ( nMemberId )
+ {
+ case MID_AUTO: rVal <<= (sal_Bool) bAuto; break;
+ case MID_NAME: rVal <<= ::rtl::OUString( GetValue() ); break;
+ default: DBG_ERROR("Wrong MemberId!"); return sal_False;
+ }
+
+ return sal_True;
+}
+
+sal_Bool SvxPageModelItem::PutValue( const com::sun::star::uno::Any& rVal, BYTE nMemberId )
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ sal_Bool bRet;
+ ::rtl::OUString aStr;
+ switch ( nMemberId )
+ {
+ case MID_AUTO: bRet = ( rVal >>= bAuto ); break;
+ case MID_NAME: bRet = ( rVal >>= aStr ); if ( bRet ) SetValue(aStr); break;
+ default: DBG_ERROR("Wrong MemberId!"); return sal_False;
+ }
+
+ return bRet;
+}
+
+SfxItemPresentation SvxPageModelItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *
+) const
+{
+ rText.Erase();
+ FASTBOOL bSet = ( GetValue().Len() > 0 );
+
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ return SFX_ITEM_PRESENTATION_NONE;
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ if ( bSet )
+ rText = GetValue();
+ return SFX_ITEM_PRESENTATION_NAMELESS;
+
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ if ( bSet )
+ {
+ rText = EE_RESSTR(RID_SVXITEMS_PAGEMODEL_COMPLETE);
+ rText += GetValue();
+ }
+ return SFX_ITEM_PRESENTATION_COMPLETE;
+ default: ;//prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+//------------------------------------------------------------------------
+
+SvxScriptSpaceItem::SvxScriptSpaceItem( sal_Bool bOn, const sal_uInt16 nId )
+ : SfxBoolItem( nId, bOn )
+{
+}
+
+SfxPoolItem* SvxScriptSpaceItem::Clone( SfxItemPool * ) const
+{
+ return new SvxScriptSpaceItem( GetValue(), Which() );
+}
+
+SfxPoolItem* SvxScriptSpaceItem::Create(SvStream & rStrm, USHORT) const
+{
+ sal_Bool bFlag;
+ rStrm >> bFlag;
+ return new SvxScriptSpaceItem( bFlag, Which() );
+}
+
+USHORT SvxScriptSpaceItem::GetVersion( USHORT nFFVer ) const
+{
+ DBG_ASSERT( SOFFICE_FILEFORMAT_31==nFFVer ||
+ SOFFICE_FILEFORMAT_40==nFFVer ||
+ SOFFICE_FILEFORMAT_50==nFFVer,
+ "SvxTwoLinesItem: Gibt es ein neues Fileformat?" );
+
+ return SOFFICE_FILEFORMAT_50 > nFFVer ? USHRT_MAX : 0;
+}
+
+SfxItemPresentation SvxScriptSpaceItem::GetPresentation(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/,
+ String &rText, const IntlWrapper* /*pIntl*/ ) const
+{
+ switch( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ break;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ rText = EE_RESSTR( !GetValue()
+ ? RID_SVXITEMS_SCRPTSPC_OFF
+ : RID_SVXITEMS_SCRPTSPC_ON );
+ return ePres;
+ }
+ default: ;//prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+//------------------------------------------------------------------------
+
+SvxHangingPunctuationItem::SvxHangingPunctuationItem(
+ sal_Bool bOn, const sal_uInt16 nId )
+ : SfxBoolItem( nId, bOn )
+{
+}
+
+SfxPoolItem* SvxHangingPunctuationItem::Clone( SfxItemPool * ) const
+{
+ return new SvxHangingPunctuationItem( GetValue(), Which() );
+}
+
+SfxPoolItem* SvxHangingPunctuationItem::Create(SvStream & rStrm, USHORT) const
+{
+ sal_Bool nValue;
+ rStrm >> nValue;
+ return new SvxHangingPunctuationItem( nValue, Which() );
+}
+
+USHORT SvxHangingPunctuationItem::GetVersion( USHORT nFFVer ) const
+{
+ DBG_ASSERT( SOFFICE_FILEFORMAT_31==nFFVer ||
+ SOFFICE_FILEFORMAT_40==nFFVer ||
+ SOFFICE_FILEFORMAT_50==nFFVer,
+ "SvxHangingPunctuationItem: Gibt es ein neues Fileformat?" );
+
+ return SOFFICE_FILEFORMAT_50 > nFFVer ? USHRT_MAX : 0;
+}
+
+SfxItemPresentation SvxHangingPunctuationItem::GetPresentation(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/,
+ String &rText, const IntlWrapper* /*pIntl*/ ) const
+{
+ switch( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ break;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ rText = EE_RESSTR( !GetValue()
+ ? RID_SVXITEMS_HNGPNCT_OFF
+ : RID_SVXITEMS_HNGPNCT_ON );
+ return ePres;
+ }
+ default: ;//prevent warning
+ break;
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+//------------------------------------------------------------------------
+
+SvxForbiddenRuleItem::SvxForbiddenRuleItem(
+ sal_Bool bOn, const sal_uInt16 nId )
+ : SfxBoolItem( nId, bOn )
+{
+}
+/* -----------------------------29.11.00 11:23--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SfxPoolItem* SvxForbiddenRuleItem::Clone( SfxItemPool * ) const
+{
+ return new SvxForbiddenRuleItem( GetValue(), Which() );
+}
+/* -----------------------------29.11.00 11:23--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SfxPoolItem* SvxForbiddenRuleItem::Create(SvStream & rStrm, USHORT) const
+{
+ sal_Bool nValue;
+ rStrm >> nValue;
+ return new SvxForbiddenRuleItem( nValue, Which() );
+}
+/* -----------------------------29.11.00 11:23--------------------------------
+
+ ---------------------------------------------------------------------------*/
+USHORT SvxForbiddenRuleItem::GetVersion( USHORT nFFVer ) const
+{
+ DBG_ASSERT( SOFFICE_FILEFORMAT_31==nFFVer ||
+ SOFFICE_FILEFORMAT_40==nFFVer ||
+ SOFFICE_FILEFORMAT_50==nFFVer,
+ "SvxForbiddenRuleItem: Gibt es ein neues Fileformat?" );
+
+ return SOFFICE_FILEFORMAT_50 > nFFVer ? USHRT_MAX : 0;
+}
+/* -----------------------------29.11.00 11:23--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SfxItemPresentation SvxForbiddenRuleItem::GetPresentation(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/,
+ String &rText, const IntlWrapper* /*pIntl*/ ) const
+{
+ switch( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ break;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ rText = EE_RESSTR( !GetValue()
+ ? RID_SVXITEMS_FORBIDDEN_RULE_OFF
+ : RID_SVXITEMS_FORBIDDEN_RULE_ON );
+ return ePres;
+ }
+ default: ;//prevent warning
+ break;
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+/*************************************************************************
+|* class SvxParaVertAlignItem
+*************************************************************************/
+
+SvxParaVertAlignItem::SvxParaVertAlignItem( sal_uInt16 nValue,
+ const sal_uInt16 nW )
+ : SfxUInt16Item( nW, nValue )
+{
+}
+
+SfxPoolItem* SvxParaVertAlignItem::Clone( SfxItemPool* ) const
+{
+ return new SvxParaVertAlignItem( GetValue(), Which() );
+}
+
+SfxPoolItem* SvxParaVertAlignItem::Create( SvStream& rStrm, USHORT ) const
+{
+ sal_uInt16 nVal;
+ rStrm >> nVal;
+ return new SvxParaVertAlignItem( nVal, Which() );
+}
+
+SvStream& SvxParaVertAlignItem::Store( SvStream & rStrm, USHORT ) const
+{
+ rStrm << GetValue();
+ return rStrm;
+}
+
+USHORT SvxParaVertAlignItem::GetVersion( USHORT nFFVer ) const
+{
+ return SOFFICE_FILEFORMAT_50 > nFFVer ? USHRT_MAX : 0;
+}
+
+SfxItemPresentation SvxParaVertAlignItem::GetPresentation(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/,
+ String &rText, const IntlWrapper* ) const
+{
+ switch( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ break;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ USHORT nTmp;
+ switch( GetValue() )
+ {
+ case AUTOMATIC: nTmp = RID_SVXITEMS_PARAVERTALIGN_AUTO; break;
+ case TOP: nTmp = RID_SVXITEMS_PARAVERTALIGN_TOP; break;
+ case CENTER: nTmp = RID_SVXITEMS_PARAVERTALIGN_CENTER; break;
+ case BOTTOM: nTmp = RID_SVXITEMS_PARAVERTALIGN_BOTTOM; break;
+ default: nTmp = RID_SVXITEMS_PARAVERTALIGN_BASELINE; break;
+ }
+ rText = EE_RESSTR( nTmp );
+ return ePres;
+ }
+ default: ;//prevent warning
+ break;
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+sal_Bool SvxParaVertAlignItem::QueryValue( com::sun::star::uno::Any& rVal,
+ BYTE /*nMemberId*/ ) const
+{
+ rVal <<= (sal_Int16)GetValue();
+ return sal_True;
+}
+
+sal_Bool SvxParaVertAlignItem::PutValue( const com::sun::star::uno::Any& rVal,
+ BYTE /*nMemberId*/ )
+{
+ sal_Int16 nVal = sal_Int16();
+ if((rVal >>= nVal) && nVal >=0 && nVal <= BOTTOM )
+ {
+ SetValue( (USHORT)nVal );
+ return sal_True;
+ }
+ else
+ return sal_False;
+}
+
+int SvxParaVertAlignItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" );
+ return SfxUInt16Item::operator==( rItem );
+}
+
+
+SvxParaGridItem::SvxParaGridItem( sal_Bool bOn, const sal_uInt16 nId )
+ : SfxBoolItem( nId, bOn )
+{
+}
+
+SfxPoolItem* SvxParaGridItem::Clone( SfxItemPool * ) const
+{
+ return new SvxParaGridItem( GetValue(), Which() );
+}
+
+SfxPoolItem* SvxParaGridItem::Create(SvStream & rStrm, USHORT) const
+{
+ sal_Bool bFlag;
+ rStrm >> bFlag;
+ return new SvxParaGridItem( bFlag, Which() );
+}
+
+USHORT SvxParaGridItem::GetVersion( USHORT nFFVer ) const
+{
+ DBG_ASSERT( SOFFICE_FILEFORMAT_31==nFFVer ||
+ SOFFICE_FILEFORMAT_40==nFFVer ||
+ SOFFICE_FILEFORMAT_50==nFFVer,
+ "SvxParaGridItem: Gibt es ein neues Fileformat?" );
+
+ return SOFFICE_FILEFORMAT_50 > nFFVer ? USHRT_MAX : 0;
+}
+
+SfxItemPresentation SvxParaGridItem::GetPresentation(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/,
+ String &rText, const IntlWrapper* /*pIntl*/ ) const
+{
+ switch( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ break;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ rText = GetValue() ?
+ EE_RESSTR( RID_SVXITEMS_PARASNAPTOGRID_ON ) :
+ EE_RESSTR( RID_SVXITEMS_PARASNAPTOGRID_OFF );
+
+ return ePres;
+ }
+ default: ;//prevent warning
+ break;
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+
diff --git a/editeng/source/items/svdfield.cxx b/editeng/source/items/svdfield.cxx
new file mode 100644
index 0000000000..1244e012d3
--- /dev/null
+++ b/editeng/source/items/svdfield.cxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: svdomeas.cxx,v $
+ * $Revision: 1.35.18.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <editeng/svdfield.hxx>
+
+SV_IMPL_PERSIST1(SdrMeasureField,SvxFieldData);
+
+__EXPORT SdrMeasureField::~SdrMeasureField()
+{
+}
+
+SvxFieldData* __EXPORT SdrMeasureField::Clone() const
+{
+ return new SdrMeasureField(*this);
+}
+
+int __EXPORT SdrMeasureField::operator==(const SvxFieldData& rSrc) const
+{
+ return eMeasureFieldKind==((SdrMeasureField&)rSrc).GetMeasureFieldKind();
+}
+
+void __EXPORT SdrMeasureField::Load(SvPersistStream& rIn)
+{
+ UINT16 nFieldKind;
+ rIn>>nFieldKind;
+ eMeasureFieldKind=(SdrMeasureFieldKind)nFieldKind;
+}
+
+void __EXPORT SdrMeasureField::Save(SvPersistStream& rOut)
+{
+ rOut<<(UINT16)eMeasureFieldKind;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/editeng/source/items/svxfont.cxx b/editeng/source/items/svxfont.cxx
new file mode 100644
index 0000000000..ea25be1c48
--- /dev/null
+++ b/editeng/source/items/svxfont.cxx
@@ -0,0 +1,860 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: svxfont.cxx,v $
+ * $Revision: 1.15.216.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+// include ----------------------------------------------------------------
+
+#include <vcl/outdev.hxx>
+#include <vcl/print.hxx>
+#include <tools/poly.hxx>
+#include <unotools/charclass.hxx>
+#include <editeng/unolingu.hxx>
+#include <com/sun/star/i18n/KCharacterType.hpp>
+
+#define _SVX_SVXFONT_CXX
+
+#include <editeng/svxfont.hxx>
+#include <editeng/escpitem.hxx>
+
+// Minimum: Prozentwert fuers kernen
+#define MINKERNPERCENT 5
+
+// prop. Groesse der Kleinbuchstaben bei Kapitaelchen
+#define KAPITAELCHENPROP 66
+
+#ifndef REDUCEDSVXFONT
+ const sal_Unicode CH_BLANK = sal_Unicode(' '); // ' ' Leerzeichen
+ static sal_Char __READONLY_DATA sDoubleSpace[] = " ";
+#endif
+
+/*************************************************************************
+ * class SvxFont
+ *************************************************************************/
+
+SvxFont::SvxFont()
+{
+ nKern = nEsc = 0;
+ nPropr = 100;
+ eCaseMap = SVX_CASEMAP_NOT_MAPPED;
+ eLang = LANGUAGE_SYSTEM;
+}
+
+SvxFont::SvxFont( const Font &rFont )
+ : Font( rFont )
+{
+ nKern = nEsc = 0;
+ nPropr = 100;
+ eCaseMap = SVX_CASEMAP_NOT_MAPPED;
+ eLang = LANGUAGE_SYSTEM;
+}
+
+/*************************************************************************
+ * class SvxFont: Copy-Ctor
+ *************************************************************************/
+
+SvxFont::SvxFont( const SvxFont &rFont )
+ : Font( rFont )
+{
+ nKern = rFont.GetFixKerning();
+ nEsc = rFont.GetEscapement();
+ nPropr = rFont.GetPropr();
+ eCaseMap = rFont.GetCaseMap();
+ eLang = rFont.GetLanguage();
+}
+
+/*************************************************************************
+ * static SvxFont::DrawArrow
+ *************************************************************************/
+
+void SvxFont::DrawArrow( OutputDevice &rOut, const Rectangle& rRect,
+ const Size& rSize, const Color& rCol, BOOL bLeft )
+{
+ long nLeft = ( rRect.Left() + rRect.Right() - rSize.Width() )/ 2;
+ long nRight = nLeft + rSize.Width();
+ long nMid = ( rRect.Top() + rRect.Bottom() ) / 2;
+ long nTop = nMid - rSize.Height() / 2;
+ long nBottom = nTop + rSize.Height();
+ if( nLeft < rRect.Left() )
+ {
+ nLeft = rRect.Left();
+ nRight = rRect.Right();
+ }
+ if( nTop < rRect.Top() )
+ {
+ nTop = rRect.Top();
+ nBottom = rRect.Bottom();
+ }
+ Polygon aPoly;
+ Point aTmp( bLeft ? nLeft : nRight, nMid );
+ Point aNxt( bLeft ? nRight : nLeft, nTop );
+ aPoly.Insert( 0, aTmp );
+ aPoly.Insert( 0, aNxt );
+ aNxt.Y() = nBottom;
+ aPoly.Insert( 0, aNxt );
+ aPoly.Insert( 0, aTmp );
+ Color aOldLineColor = rOut.GetLineColor();
+ Color aOldFillColor = rOut.GetFillColor();
+ rOut.SetFillColor( rCol );
+ rOut.SetLineColor( Color( COL_BLACK ) );
+ rOut.DrawPolygon( aPoly );
+ rOut.DrawLine( aTmp, aNxt );
+ rOut.SetLineColor( aOldLineColor );
+ rOut.SetFillColor( aOldFillColor );
+}
+
+/*************************************************************************
+ * SvxFont::CalcCaseMap
+ *************************************************************************/
+
+XubString SvxFont::CalcCaseMap( const XubString &rTxt ) const
+{
+ if( !IsCaseMap() || !rTxt.Len() ) return rTxt;
+ XubString aTxt( rTxt );
+ // Ich muss mir noch die Sprache besorgen
+ const LanguageType eLng = LANGUAGE_DONTKNOW == eLang
+ ? LANGUAGE_SYSTEM : eLang;
+
+ CharClass aCharClass( SvxCreateLocale( eLng ) );
+
+ switch( eCaseMap )
+ {
+ case SVX_CASEMAP_KAPITAELCHEN:
+ case SVX_CASEMAP_VERSALIEN:
+ {
+ aCharClass.toUpper( aTxt );
+ break;
+ }
+
+ case SVX_CASEMAP_GEMEINE:
+ {
+ aCharClass.toLower( aTxt );
+ break;
+ }
+ case SVX_CASEMAP_TITEL:
+ {
+ // Jeder Wortbeginn wird gross geschrieben,
+ // der Rest des Wortes wird unbesehen uebernommen.
+ // Bug: wenn das Attribut mitten im Wort beginnt.
+ BOOL bBlank = TRUE;
+
+ for( USHORT i = 0; i < aTxt.Len(); ++i )
+ {
+ if( sal_Unicode(' ') == aTxt.GetChar(i) || sal_Unicode('\t') == aTxt.GetChar(i) )
+ bBlank = TRUE;
+ else
+ {
+ if( bBlank )
+ {
+ String aTemp( aTxt.GetChar( i ) );
+ aCharClass.toUpper( aTemp );
+ aTxt.Replace( i, 1, aTemp );
+ }
+ bBlank = FALSE;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ DBG_ASSERT(!this, "SvxFont::CaseMapTxt: unknown casemap");
+ break;
+ }
+ }
+ return aTxt;
+}
+
+/*************************************************************************
+ * Hier beginnen die Methoden, die im Writer nicht benutzt werden koennen,
+ * deshalb kann man diesen Bereich durch setzen von REDUCEDSVXFONT ausklammern.
+ *************************************************************************/
+#ifndef REDUCEDSVXFONT
+
+/*************************************************************************
+ * class SvxDoCapitals
+ * die virtuelle Methode Do wird von SvxFont::DoOnCapitals abwechselnd mit
+ * den "Gross-" und "Kleinbuchstaben"-Teilen aufgerufen.
+ * Die Ableitungen von SvxDoCapitals erfuellen diese Methode mit Leben.
+ *************************************************************************/
+
+class SvxDoCapitals
+{
+protected:
+ OutputDevice *pOut;
+ const XubString &rTxt;
+ const xub_StrLen nIdx;
+ const xub_StrLen nLen;
+
+public:
+ SvxDoCapitals( OutputDevice *_pOut, const XubString &_rTxt,
+ const xub_StrLen _nIdx, const xub_StrLen _nLen )
+ : pOut(_pOut), rTxt(_rTxt), nIdx(_nIdx), nLen(_nLen)
+ { }
+
+ virtual void DoSpace( const BOOL bDraw );
+ virtual void SetSpace();
+ virtual void Do( const XubString &rTxt,
+ const xub_StrLen nIdx, const xub_StrLen nLen,
+ const BOOL bUpper ) = 0;
+
+ inline OutputDevice *GetOut() { return pOut; }
+ inline const XubString &GetTxt() const { return rTxt; }
+ xub_StrLen GetIdx() const { return nIdx; }
+ xub_StrLen GetLen() const { return nLen; }
+};
+
+void SvxDoCapitals::DoSpace( const BOOL /*bDraw*/ ) { }
+
+void SvxDoCapitals::SetSpace() { }
+
+void SvxDoCapitals::Do( const XubString &/*_rTxt*/, const xub_StrLen /*_nIdx*/,
+ const xub_StrLen /*_nLen*/, const BOOL /*bUpper*/ ) { }
+
+/*************************************************************************
+ * SvxFont::DoOnCapitals() const
+ * zerlegt den String in Gross- und Kleinbuchstaben und ruft jeweils die
+ * Methode SvxDoCapitals::Do( ) auf.
+ *************************************************************************/
+
+void SvxFont::DoOnCapitals(SvxDoCapitals &rDo, const xub_StrLen nPartLen) const
+{
+ const XubString &rTxt = rDo.GetTxt();
+ const xub_StrLen nIdx = rDo.GetIdx();
+ const xub_StrLen nLen = STRING_LEN == nPartLen ? rDo.GetLen() : nPartLen;
+
+ const XubString aTxt( CalcCaseMap( rTxt ) );
+ const USHORT nTxtLen = Min( rTxt.Len(), nLen );
+ USHORT nPos = 0;
+ USHORT nOldPos = nPos;
+
+ // #108210#
+ // Test if string length differ between original and CaseMapped
+ sal_Bool bCaseMapLengthDiffers(aTxt.Len() != rTxt.Len());
+
+ const LanguageType eLng = LANGUAGE_DONTKNOW == eLang
+ ? LANGUAGE_SYSTEM : eLang;
+
+ CharClass aCharClass( SvxCreateLocale( eLng ) );
+ String aCharString;
+
+ while( nPos < nTxtLen )
+ {
+ // Erst kommen die Upper-Chars dran
+
+ // 4251: Es gibt Zeichen, die Upper _und_ Lower sind (z.B. das Blank).
+ // Solche Zweideutigkeiten fuehren ins Chaos, deswegen werden diese
+ // Zeichen der Menge Lower zugeordnet !
+
+ while( nPos < nTxtLen )
+ {
+ aCharString = rTxt.GetChar( nPos + nIdx );
+ sal_Int32 nCharacterType = aCharClass.getCharacterType( aCharString, 0 );
+ if ( nCharacterType & ::com::sun::star::i18n::KCharacterType::LOWER )
+ break;
+ if ( ! ( nCharacterType & ::com::sun::star::i18n::KCharacterType::UPPER ) )
+ break;
+ ++nPos;
+ }
+ if( nOldPos != nPos )
+ {
+ if(bCaseMapLengthDiffers)
+ {
+ // #108210#
+ // If strings differ work preparing the necessary snippet to address that
+ // potential difference
+ const XubString aSnippet(rTxt, nIdx + nOldPos, nPos-nOldPos);
+ XubString aNewText = CalcCaseMap(aSnippet);
+
+ rDo.Do( aNewText, 0, aNewText.Len(), TRUE );
+ }
+ else
+ {
+ rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, TRUE );
+ }
+
+ nOldPos = nPos;
+ }
+ // Nun werden die Lower-Chars verarbeitet (ohne Blanks)
+ while( nPos < nTxtLen )
+ {
+ sal_uInt32 nCharacterType = aCharClass.getCharacterType( aCharString, 0 );
+ if ( ( nCharacterType & ::com::sun::star::i18n::KCharacterType::UPPER ) )
+ break;
+ if ( CH_BLANK == aCharString )
+ break;
+ if( ++nPos < nTxtLen )
+ aCharString = rTxt.GetChar( nPos + nIdx );
+ }
+ if( nOldPos != nPos )
+ {
+ if(bCaseMapLengthDiffers)
+ {
+ // #108210#
+ // If strings differ work preparing the necessary snippet to address that
+ // potential difference
+ const XubString aSnippet(rTxt, nIdx + nOldPos, nPos - nOldPos);
+ XubString aNewText = CalcCaseMap(aSnippet);
+
+ rDo.Do( aNewText, 0, aNewText.Len(), FALSE );
+ }
+ else
+ {
+ rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, FALSE );
+ }
+
+ nOldPos = nPos;
+ }
+ // Nun werden die Blanks verarbeitet
+ while( nPos < nTxtLen && CH_BLANK == aCharString && ++nPos < nTxtLen )
+ aCharString = rTxt.GetChar( nPos + nIdx );
+
+ if( nOldPos != nPos )
+ {
+ rDo.DoSpace( FALSE );
+
+ if(bCaseMapLengthDiffers)
+ {
+ // #108210#
+ // If strings differ work preparing the necessary snippet to address that
+ // potential difference
+ const XubString aSnippet(rTxt, nIdx + nOldPos, nPos - nOldPos);
+ XubString aNewText = CalcCaseMap(aSnippet);
+
+ rDo.Do( aNewText, 0, aNewText.Len(), FALSE );
+ }
+ else
+ {
+ rDo.Do( aTxt, nIdx + nOldPos, nPos - nOldPos, FALSE );
+ }
+
+ nOldPos = nPos;
+ rDo.SetSpace();
+ }
+ }
+ rDo.DoSpace( TRUE );
+}
+
+/**************************************************************************
+ * SvxFont::SetPhysFont()
+ *************************************************************************/
+
+void SvxFont::SetPhysFont( OutputDevice *pOut ) const
+{
+ const Font& rCurrentFont = pOut->GetFont();
+ if ( nPropr == 100 )
+ {
+ if ( !rCurrentFont.IsSameInstance( *this ) )
+ pOut->SetFont( *this );
+ }
+ else
+ {
+ Font aNewFont( *this );
+ Size aSize( aNewFont.GetSize() );
+ aNewFont.SetSize( Size( aSize.Width() * nPropr / 100L,
+ aSize.Height() * nPropr / 100L ) );
+ if ( !rCurrentFont.IsSameInstance( aNewFont ) )
+ pOut->SetFont( aNewFont );
+ }
+}
+
+/*************************************************************************
+ * SvxFont::ChgPhysFont()
+ *************************************************************************/
+
+Font SvxFont::ChgPhysFont( OutputDevice *pOut ) const
+{
+ Font aOldFont( pOut->GetFont() );
+ SetPhysFont( pOut );
+ return aOldFont;
+}
+
+/*************************************************************************
+ * SvxFont::GetPhysTxtSize()
+ *************************************************************************/
+
+Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const XubString &rTxt,
+ const xub_StrLen nIdx, const xub_StrLen nLen ) const
+{
+ if ( !IsCaseMap() && !IsKern() )
+ return Size( pOut->GetTextWidth( rTxt, nIdx, nLen ),
+ pOut->GetTextHeight() );
+
+ Size aTxtSize;
+ aTxtSize.setHeight( pOut->GetTextHeight() );
+ if ( !IsCaseMap() )
+ aTxtSize.setWidth( pOut->GetTextWidth( rTxt, nIdx, nLen ) );
+ else
+ {
+ // #108210#
+ const XubString aNewText = CalcCaseMap(rTxt);
+ sal_Bool bCaseMapLengthDiffers(aNewText.Len() != rTxt.Len());
+ sal_Int32 nWidth(0L);
+
+ if(bCaseMapLengthDiffers)
+ {
+ // If strings differ work preparing the necessary snippet to address that
+ // potential difference
+ const XubString aSnippet(rTxt, nIdx, nLen);
+ XubString _aNewText = CalcCaseMap(aSnippet);
+ nWidth = pOut->GetTextWidth( _aNewText, 0, _aNewText.Len() );
+ }
+ else
+ {
+ nWidth = pOut->GetTextWidth( aNewText, nIdx, nLen );
+ }
+
+ aTxtSize.setWidth(nWidth);
+ }
+
+ if( IsKern() && ( nLen > 1 ) )
+ aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) );
+
+ return aTxtSize;
+}
+
+Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const XubString &rTxt )
+{
+ if ( !IsCaseMap() && !IsKern() )
+ return Size( pOut->GetTextWidth( rTxt ), pOut->GetTextHeight() );
+
+ Size aTxtSize;
+ aTxtSize.setHeight( pOut->GetTextHeight() );
+ if ( !IsCaseMap() )
+ aTxtSize.setWidth( pOut->GetTextWidth( rTxt ) );
+ else
+ aTxtSize.setWidth( pOut->GetTextWidth( CalcCaseMap( rTxt ) ) );
+
+ if( IsKern() && ( rTxt.Len() > 1 ) )
+ aTxtSize.Width() += ( ( rTxt.Len()-1 ) * long( nKern ) );
+
+ return aTxtSize;
+}
+
+Size SvxFont::QuickGetTextSize( const OutputDevice *pOut, const XubString &rTxt,
+ const USHORT nIdx, const USHORT nLen, sal_Int32* pDXArray ) const
+{
+ if ( !IsCaseMap() && !IsKern() )
+ return Size( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ),
+ pOut->GetTextHeight() );
+
+ Size aTxtSize;
+ aTxtSize.setHeight( pOut->GetTextHeight() );
+ if ( !IsCaseMap() )
+ aTxtSize.setWidth( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ) );
+ else
+ aTxtSize.setWidth( pOut->GetTextArray( CalcCaseMap( rTxt ),
+ pDXArray, nIdx, nLen ) );
+
+ if( IsKern() && ( nLen > 1 ) )
+ {
+ aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) );
+
+ if ( pDXArray )
+ {
+ for ( xub_StrLen i = 0; i < nLen; i++ )
+ pDXArray[i] += ( (i+1) * long( nKern ) );
+ // Der letzte ist um ein nKern zu gross:
+ pDXArray[nLen-1] -= nKern;
+ }
+ }
+ return aTxtSize;
+}
+
+/*************************************************************************
+ * SvxFont::GetTxtSize()
+ *************************************************************************/
+
+Size SvxFont::GetTxtSize( const OutputDevice *pOut, const XubString &rTxt,
+ const xub_StrLen nIdx, const xub_StrLen nLen )
+{
+ xub_StrLen nTmp = nLen;
+ if ( nTmp == STRING_LEN ) // schon initialisiert?
+ nTmp = rTxt.Len();
+ Font aOldFont( ChgPhysFont((OutputDevice *)pOut) );
+ Size aTxtSize;
+ if( IsCapital() && rTxt.Len() )
+ {
+ aTxtSize = GetCapitalSize( pOut, rTxt, nIdx, nTmp );
+ }
+ else aTxtSize = GetPhysTxtSize(pOut,rTxt,nIdx,nTmp);
+ ((OutputDevice *)pOut)->SetFont( aOldFont );
+ return aTxtSize;
+}
+
+/*************************************************************************
+ * SvxFont::DrawText()
+ *************************************************************************/
+
+void SvxFont::DrawText( OutputDevice *pOut,
+ const Point &rPos, const XubString &rTxt,
+ const xub_StrLen nIdx, const xub_StrLen nLen ) const
+{
+ if( !nLen || !rTxt.Len() ) return;
+ xub_StrLen nTmp = nLen;
+ if ( nTmp == STRING_LEN ) // schon initialisiert?
+ nTmp = rTxt.Len();
+ Point aPos( rPos );
+ if ( nEsc )
+ {
+ Size aSize = (this->GetSize());
+ aPos.Y() -= ((nEsc*long(aSize.Height()))/ 100L);
+ }
+ Font aOldFont( ChgPhysFont( pOut ) );
+
+ if ( IsCapital() )
+ DrawCapital( pOut, aPos, rTxt, nIdx, nTmp );
+ else
+ {
+ Size aSize = GetPhysTxtSize( pOut, rTxt, nIdx, nTmp );
+
+ if ( !IsCaseMap() )
+ pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nTmp );
+ else
+ pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ),
+ nIdx, nTmp );
+ }
+ pOut->SetFont(aOldFont);
+}
+
+void SvxFont::QuickDrawText( OutputDevice *pOut,
+ const Point &rPos, const XubString &rTxt,
+ const xub_StrLen nIdx, const xub_StrLen nLen, const sal_Int32* pDXArray ) const
+{
+ // Font muss ins OutputDevice selektiert sein...
+ if ( !IsCaseMap() && !IsCapital() && !IsKern() && !IsEsc() )
+ {
+ pOut->DrawTextArray( rPos, rTxt, pDXArray, nIdx, nLen );
+ return;
+ }
+
+ Point aPos( rPos );
+
+ if ( nEsc )
+ {
+ long nDiff = GetSize().Height();
+ nDiff *= nEsc;
+ nDiff /= 100;
+
+ if ( !IsVertical() )
+ aPos.Y() -= nDiff;
+ else
+ aPos.X() += nDiff;
+ }
+
+ if( IsCapital() )
+ {
+ DBG_ASSERT( !pDXArray, "DrawCapital nicht fuer TextArray!" );
+ DrawCapital( pOut, aPos, rTxt, nIdx, nLen );
+ }
+ else
+ {
+ if ( IsKern() && !pDXArray )
+ {
+ Size aSize = GetPhysTxtSize( pOut, rTxt, nIdx, nLen );
+
+ if ( !IsCaseMap() )
+ pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nLen );
+ else
+ pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nLen );
+ }
+ else
+ {
+ if ( !IsCaseMap() )
+ pOut->DrawTextArray( aPos, rTxt, pDXArray, nIdx, nLen );
+ else
+ pOut->DrawTextArray( aPos, CalcCaseMap( rTxt ), pDXArray, nIdx, nLen );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SvxFont::DrawPrev( OutputDevice *pOut, Printer* pPrinter,
+ const Point &rPos, const XubString &rTxt,
+ const xub_StrLen nIdx, const xub_StrLen nLen ) const
+{
+ if ( !nLen || !rTxt.Len() )
+ return;
+ xub_StrLen nTmp = nLen;
+
+ if ( nTmp == STRING_LEN ) // schon initialisiert?
+ nTmp = rTxt.Len();
+ Point aPos( rPos );
+
+ if ( nEsc )
+ {
+ short nTmpEsc;
+ if( DFLT_ESC_AUTO_SUPER == nEsc )
+ nTmpEsc = 33;
+ else if( DFLT_ESC_AUTO_SUB == nEsc )
+ nTmpEsc = -20;
+ else
+ nTmpEsc = nEsc;
+ Size aSize = ( this->GetSize() );
+ aPos.Y() -= ( ( nTmpEsc * long( aSize.Height() ) ) / 100L );
+ }
+ Font aOldFont( ChgPhysFont( pOut ) );
+ Font aOldPrnFont( ChgPhysFont( pPrinter ) );
+
+ if ( IsCapital() )
+ DrawCapital( pOut, aPos, rTxt, nIdx, nTmp );
+ else
+ {
+ Size aSize = GetPhysTxtSize( pPrinter, rTxt, nIdx, nTmp );
+
+ if ( !IsCaseMap() )
+ pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nTmp );
+ else
+ {
+ // #108210#
+ const XubString aNewText = CalcCaseMap(rTxt);
+ sal_Bool bCaseMapLengthDiffers(aNewText.Len() != rTxt.Len());
+
+ if(bCaseMapLengthDiffers)
+ {
+ // If strings differ work preparing the necessary snippet to address that
+ // potential difference
+ const XubString aSnippet(rTxt, nIdx, nTmp);
+ XubString _aNewText = CalcCaseMap(aSnippet);
+
+ pOut->DrawStretchText( aPos, aSize.Width(), _aNewText, 0, _aNewText.Len() );
+ }
+ else
+ {
+ pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nTmp );
+ }
+ }
+ }
+ pOut->SetFont(aOldFont);
+ pPrinter->SetFont( aOldPrnFont );
+}
+
+// -----------------------------------------------------------------------
+
+SvxFont& SvxFont::operator=( const Font& rFont )
+{
+ Font::operator=( rFont );
+ return *this;
+}
+
+SvxFont& SvxFont::operator=( const SvxFont& rFont )
+{
+ Font::operator=( rFont );
+ eLang = rFont.eLang;
+ eCaseMap = rFont.eCaseMap;
+ nEsc = rFont.nEsc;
+ nPropr = rFont.nPropr;
+ nKern = rFont.nKern;
+ return *this;
+}
+
+
+/*************************************************************************
+ * class SvxDoGetCapitalSize
+ * wird von SvxFont::GetCapitalSize() zur Berechnung der TxtSize bei
+ * eingestellten Kapitaelchen benutzt.
+ *************************************************************************/
+
+class SvxDoGetCapitalSize : public SvxDoCapitals
+{
+protected:
+ SvxFont* pFont;
+ Size aTxtSize;
+ short nKern;
+public:
+ SvxDoGetCapitalSize( SvxFont *_pFnt, const OutputDevice *_pOut,
+ const XubString &_rTxt, const xub_StrLen _nIdx,
+ const xub_StrLen _nLen, const short _nKrn )
+ : SvxDoCapitals( (OutputDevice*)_pOut, _rTxt, _nIdx, _nLen ),
+ pFont( _pFnt ),
+ nKern( _nKrn )
+ { }
+
+ virtual void Do( const XubString &rTxt, const xub_StrLen nIdx,
+ const xub_StrLen nLen, const BOOL bUpper );
+
+ inline const Size &GetSize() const { return aTxtSize; };
+};
+
+void SvxDoGetCapitalSize::Do( const XubString &_rTxt, const xub_StrLen _nIdx,
+ const xub_StrLen _nLen, const BOOL bUpper )
+{
+ Size aPartSize;
+ if ( !bUpper )
+ {
+ BYTE nProp = pFont->GetPropr();
+ pFont->SetProprRel( KAPITAELCHENPROP );
+ pFont->SetPhysFont( pOut );
+ aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
+ aPartSize.setHeight( pOut->GetTextHeight() );
+ aTxtSize.Height() = aPartSize.Height();
+ pFont->SetPropr( nProp );
+ pFont->SetPhysFont( pOut );
+ }
+ else
+ {
+ aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
+ aPartSize.setHeight( pOut->GetTextHeight() );
+ }
+ aTxtSize.Width() += aPartSize.Width();
+ aTxtSize.Width() += ( _nLen * long( nKern ) );
+}
+
+/*************************************************************************
+ * SvxFont::GetCapitalSize()
+ * berechnet TxtSize, wenn Kapitaelchen eingestellt sind.
+ *************************************************************************/
+
+Size SvxFont::GetCapitalSize( const OutputDevice *pOut, const XubString &rTxt,
+ const xub_StrLen nIdx, const xub_StrLen nLen) const
+{
+ // Start:
+ SvxDoGetCapitalSize aDo( (SvxFont *)this, pOut, rTxt, nIdx, nLen, nKern );
+ DoOnCapitals( aDo );
+ Size aTxtSize( aDo.GetSize() );
+
+ // End:
+ if( !aTxtSize.Height() )
+ {
+ aTxtSize.setWidth( 0 );
+ aTxtSize.setHeight( pOut->GetTextHeight() );
+ }
+ return aTxtSize;
+}
+
+/*************************************************************************
+ * class SvxDoDrawCapital
+ * wird von SvxFont::DrawCapital zur Ausgabe von Kapitaelchen benutzt.
+ *************************************************************************/
+
+class SvxDoDrawCapital : public SvxDoCapitals
+{
+protected:
+ SvxFont *pFont;
+ Point aPos;
+ Point aSpacePos;
+ short nKern;
+public:
+ SvxDoDrawCapital( SvxFont *pFnt, OutputDevice *_pOut, const XubString &_rTxt,
+ const xub_StrLen _nIdx, const xub_StrLen _nLen,
+ const Point &rPos, const short nKrn )
+ : SvxDoCapitals( _pOut, _rTxt, _nIdx, _nLen ),
+ pFont( pFnt ),
+ aPos( rPos ),
+ aSpacePos( rPos ),
+ nKern( nKrn )
+ { }
+ virtual void DoSpace( const BOOL bDraw );
+ virtual void SetSpace();
+ virtual void Do( const XubString &rTxt, const xub_StrLen nIdx,
+ const xub_StrLen nLen, const BOOL bUpper );
+};
+
+void SvxDoDrawCapital::DoSpace( const BOOL bDraw )
+{
+ if ( bDraw || pFont->IsWordLineMode() )
+ {
+ USHORT nDiff = (USHORT)(aPos.X() - aSpacePos.X());
+ if ( nDiff )
+ {
+ BOOL bWordWise = pFont->IsWordLineMode();
+ BOOL bTrans = pFont->IsTransparent();
+ pFont->SetWordLineMode( FALSE );
+ pFont->SetTransparent( TRUE );
+ pFont->SetPhysFont( pOut );
+ pOut->DrawStretchText( aSpacePos, nDiff, XubString( sDoubleSpace,
+ RTL_TEXTENCODING_MS_1252 ), 0, 2 );
+ pFont->SetWordLineMode( bWordWise );
+ pFont->SetTransparent( bTrans );
+ pFont->SetPhysFont( pOut );
+ }
+ }
+}
+
+void SvxDoDrawCapital::SetSpace()
+{
+ if ( pFont->IsWordLineMode() )
+ aSpacePos.X() = aPos.X();
+}
+
+void SvxDoDrawCapital::Do( const XubString &_rTxt, const xub_StrLen _nIdx,
+ const xub_StrLen _nLen, const BOOL bUpper)
+{
+ BYTE nProp = 0;
+ Size aPartSize;
+
+ // Einstellen der gewuenschten Fonts
+ FontUnderline eUnder = pFont->GetUnderline();
+ FontStrikeout eStrike = pFont->GetStrikeout();
+ pFont->SetUnderline( UNDERLINE_NONE );
+ pFont->SetStrikeout( STRIKEOUT_NONE );
+ if ( !bUpper )
+ {
+ nProp = pFont->GetPropr();
+ pFont->SetProprRel( KAPITAELCHENPROP );
+ }
+ pFont->SetPhysFont( pOut );
+
+ aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
+ aPartSize.setHeight( pOut->GetTextHeight() );
+ long nWidth = aPartSize.Width();
+ if ( nKern )
+ {
+ aPos.X() += (nKern/2);
+ if ( _nLen ) nWidth += (_nLen*long(nKern));
+ }
+ pOut->DrawStretchText(aPos,nWidth-nKern,_rTxt,_nIdx,_nLen);
+
+ // Font restaurieren
+ pFont->SetUnderline( eUnder );
+ pFont->SetStrikeout( eStrike );
+ if ( !bUpper )
+ pFont->SetPropr( nProp );
+ pFont->SetPhysFont( pOut );
+
+ aPos.X() += nWidth-(nKern/2);
+}
+
+/*************************************************************************
+ * SvxFont::DrawCapital() gibt Kapitaelchen aus.
+ *************************************************************************/
+
+void SvxFont::DrawCapital( OutputDevice *pOut,
+ const Point &rPos, const XubString &rTxt,
+ const xub_StrLen nIdx, const xub_StrLen nLen ) const
+{
+ SvxDoDrawCapital aDo( (SvxFont *)this,pOut,rTxt,nIdx,nLen,rPos,nKern );
+ DoOnCapitals( aDo );
+}
+
+#endif // !REDUCEDSVXFONT
+
+
diff --git a/editeng/source/items/svxitems.src b/editeng/source/items/svxitems.src
new file mode 100644
index 0000000000..3b50d35d5d
--- /dev/null
+++ b/editeng/source/items/svxitems.src
@@ -0,0 +1,1027 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: svxitems.src,v $
+ * $Revision: 1.83.212.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+ // include ------------------------------------------------------------------
+#include <editeng/editrids.hrc>
+ // pragma -------------------------------------------------------------------
+
+ // Value-Strings ------------------------------------------------------------
+String RID_SVXITEMS_TRUE
+{
+ Text [ en-US ] = "True" ;
+};
+String RID_SVXITEMS_FALSE
+{
+ Text [ en-US ] = "False" ;
+};
+ // enum SvxBreak ------------------------------------------------------------
+String RID_SVXITEMS_BREAK_NONE
+{
+ Text [ en-US ] = "No break" ;
+};
+String RID_SVXITEMS_BREAK_COLUMN_BEFORE
+{
+ Text [ en-US ] = "Break before new column" ;
+};
+String RID_SVXITEMS_BREAK_COLUMN_AFTER
+{
+ Text [ en-US ] = "Break after new column" ;
+};
+String RID_SVXITEMS_BREAK_COLUMN_BOTH
+{
+ Text [ en-US ] = "Break before and after new column" ;
+};
+String RID_SVXITEMS_BREAK_PAGE_BEFORE
+{
+ Text [ en-US ] = "Break before new page" ;
+};
+String RID_SVXITEMS_BREAK_PAGE_AFTER
+{
+ Text [ en-US ] = "Break after new page" ;
+};
+String RID_SVXITEMS_BREAK_PAGE_BOTH
+{
+ Text [ en-US ] = "Break before and after new page" ;
+};
+ // enum SvxShadowLocation ---------------------------------------------------
+String RID_SVXITEMS_SHADOW_NONE
+{
+ Text [ en-US ] = "No Shadow" ;
+};
+String RID_SVXITEMS_SHADOW_TOPLEFT
+{
+ Text [ en-US ] = "Shadow top left" ;
+};
+String RID_SVXITEMS_SHADOW_TOPRIGHT
+{
+ Text [ en-US ] = "Shadow top right" ;
+};
+String RID_SVXITEMS_SHADOW_BOTTOMLEFT
+{
+ Text [ en-US ] = "Shadow bottom left" ;
+};
+String RID_SVXITEMS_SHADOW_BOTTOMRIGHT
+{
+ Text [ en-US ] = "Shadow bottom right" ;
+};
+ // enum ColorName -----------------------------------------------------------
+String RID_SVXITEMS_COLOR
+{
+ Text [ en-US ] = "Color " ;
+};
+String RID_SVXITEMS_COLOR_BLACK
+{
+ Text [ en-US ] = "Black" ;
+};
+String RID_SVXITEMS_COLOR_BLUE
+{
+ Text [ en-US ] = "Blue" ;
+};
+String RID_SVXITEMS_COLOR_GREEN
+{
+ Text [ en-US ] = "Green" ;
+};
+String RID_SVXITEMS_COLOR_CYAN
+{
+ Text [ en-US ] = "Cyan" ;
+};
+String RID_SVXITEMS_COLOR_RED
+{
+ Text [ en-US ] = "Red" ;
+};
+String RID_SVXITEMS_COLOR_MAGENTA
+{
+ Text [ en-US ] = "Magenta" ;
+};
+String RID_SVXITEMS_COLOR_BROWN
+{
+ Text [ en-US ] = "Brown" ;
+};
+String RID_SVXITEMS_COLOR_GRAY
+{
+ Text [ en-US ] = "Gray" ;
+};
+String RID_SVXITEMS_COLOR_LIGHTGRAY
+{
+ Text [ en-US ] = "Light Gray" ;
+};
+String RID_SVXITEMS_COLOR_LIGHTBLUE
+{
+ Text [ en-US ] = "Light Blue" ;
+};
+String RID_SVXITEMS_COLOR_LIGHTGREEN
+{
+ Text [ en-US ] = "Light Green" ;
+};
+String RID_SVXITEMS_COLOR_LIGHTCYAN
+{
+ Text [ en-US ] = "Light Cyan" ;
+};
+String RID_SVXITEMS_COLOR_LIGHTRED
+{
+ Text [ en-US ] = "Light Red" ;
+};
+String RID_SVXITEMS_COLOR_LIGHTMAGENTA
+{
+ Text [ en-US ] = "Light Magenta" ;
+};
+String RID_SVXITEMS_COLOR_YELLOW
+{
+ Text [ en-US ] = "Yellow" ;
+};
+String RID_SVXITEMS_COLOR_WHITE
+{
+ Text [ en-US ] = "White" ;
+};
+String RID_SVXITEMS_COLOR_MENUBAR
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_COLOR_MENUBARTEXT
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_COLOR_POPUPMENU
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_COLOR_POPUPMENUTEXT
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_COLOR_WINDOWTEXT
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_COLOR_WINDOWWORKSPACE
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_COLOR_HIGHLIGHT
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_COLOR_HIGHLIGHTTEXT
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_COLOR_3DTEXT
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_COLOR_3DFACE
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_COLOR_3DLIGHT
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_COLOR_3DSHADOW
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_COLOR_SCROLLBAR
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_COLOR_FIELD
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_COLOR_FIELDTEXT
+{
+ Text = "?" ;
+};
+ // enum FontItalic -------------------------------------------------------
+String RID_SVXITEMS_ITALIC_NONE
+{
+ Text [ en-US ] = "Not Italic" ;
+};
+String RID_SVXITEMS_ITALIC_OBLIQUE
+{
+ Text [ en-US ] = "Oblique italic" ;
+};
+String RID_SVXITEMS_ITALIC_NORMAL
+{
+ Text [ en-US ] = "Italic" ;
+};
+ // enum FontWeight -------------------------------------------------------
+String RID_SVXITEMS_WEIGHT_DONTKNOW
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_WEIGHT_THIN
+{
+ Text [ en-US ] = "thin" ;
+};
+String RID_SVXITEMS_WEIGHT_ULTRALIGHT
+{
+ Text [ en-US ] = "ultra thin" ;
+};
+String RID_SVXITEMS_WEIGHT_LIGHT
+{
+ Text [ en-US ] = "light" ;
+};
+String RID_SVXITEMS_WEIGHT_SEMILIGHT
+{
+ Text [ en-US ] = "semi light" ;
+};
+String RID_SVXITEMS_WEIGHT_NORMAL
+{
+ Text [ en-US ] = "normal" ;
+};
+String RID_SVXITEMS_WEIGHT_MEDIUM
+{
+ Text [ en-US ] = "medium" ;
+};
+String RID_SVXITEMS_WEIGHT_SEMIBOLD
+{
+ Text [ en-US ] = "semi bold" ;
+};
+String RID_SVXITEMS_WEIGHT_BOLD
+{
+ Text [ en-US ] = "bold" ;
+};
+String RID_SVXITEMS_WEIGHT_ULTRABOLD
+{
+ Text [ en-US ] = "ultra bold" ;
+};
+String RID_SVXITEMS_WEIGHT_BLACK
+{
+ Text [ en-US ] = "black" ;
+};
+ // enum FontUnderline - used for underline ------------------------------
+String RID_SVXITEMS_UL_NONE
+{
+ Text [ en-US ] = "No underline" ;
+};
+String RID_SVXITEMS_UL_SINGLE
+{
+ Text [ en-US ] = "Single underline" ;
+};
+String RID_SVXITEMS_UL_DOUBLE
+{
+ Text [ en-US ] = "Double underline" ;
+};
+String RID_SVXITEMS_UL_DOTTED
+{
+ Text [ en-US ] = "Dotted underline" ;
+};
+String RID_SVXITEMS_UL_DONTKNOW
+{
+ Text [ en-US ] = "Underline";
+};
+String RID_SVXITEMS_UL_DASH
+{
+ Text [ en-US ] = "Underline (dashes)";
+};
+String RID_SVXITEMS_UL_LONGDASH
+{
+ Text [ en-US ] = "Underline (long dashes)";
+};
+String RID_SVXITEMS_UL_DASHDOT
+{
+ Text [ en-US ] = "Underline (dot dash)";
+};
+String RID_SVXITEMS_UL_DASHDOTDOT
+{
+ Text [ en-US ] = "Underline (dot dot dash)";
+};
+String RID_SVXITEMS_UL_SMALLWAVE
+{
+ Text [ en-US ] = "Underline (small wave)";
+};
+String RID_SVXITEMS_UL_WAVE
+{
+ Text [ en-US ] = "Underline (Wave)";
+};
+String RID_SVXITEMS_UL_DOUBLEWAVE
+{
+ Text [ en-US ] = "Underline (Double wave)";
+};
+String RID_SVXITEMS_UL_BOLD
+{
+ Text [ en-US ] = "Underlined (Bold)";
+};
+String RID_SVXITEMS_UL_BOLDDOTTED
+{
+ Text [ en-US ] = "Dotted underline (Bold)";
+};
+String RID_SVXITEMS_UL_BOLDDASH
+{
+ Text [ en-US ] = "Underline (Dash bold)";
+};
+String RID_SVXITEMS_UL_BOLDLONGDASH
+{
+ Text [ en-US ] = "Underline (long dash, bold)";
+};
+String RID_SVXITEMS_UL_BOLDDASHDOT
+{
+ Text [ en-US ] = "Underline (dot dash, bold)";
+};
+String RID_SVXITEMS_UL_BOLDDASHDOTDOT
+{
+ Text [ en-US ] = "Underline (dot dot dash, bold)";
+};
+String RID_SVXITEMS_UL_BOLDWAVE
+{
+ Text [ en-US ] = "Underline (wave, bold)";
+};
+ // enum FontUnderline - used for overline -------------------------------
+String RID_SVXITEMS_OL_NONE
+{
+ Text [ en-US ] = "No overline" ;
+};
+String RID_SVXITEMS_OL_SINGLE
+{
+ Text [ en-US ] = "Single overline" ;
+};
+String RID_SVXITEMS_OL_DOUBLE
+{
+ Text [ en-US ] = "Double overline" ;
+};
+String RID_SVXITEMS_OL_DOTTED
+{
+ Text [ en-US ] = "Dotted overline" ;
+};
+String RID_SVXITEMS_OL_DONTKNOW
+{
+ Text [ en-US ] = "Overline";
+};
+String RID_SVXITEMS_OL_DASH
+{
+ Text [ en-US ] = "Overline (dashes)";
+};
+String RID_SVXITEMS_OL_LONGDASH
+{
+ Text [ en-US ] = "Overline (long dashes)";
+};
+String RID_SVXITEMS_OL_DASHDOT
+{
+ Text [ en-US ] = "Overline (dot dash)";
+};
+String RID_SVXITEMS_OL_DASHDOTDOT
+{
+ Text [ en-US ] = "Overline (dot dot dash)";
+};
+String RID_SVXITEMS_OL_SMALLWAVE
+{
+ Text [ en-US ] = "Overline (small wave)";
+};
+String RID_SVXITEMS_OL_WAVE
+{
+ Text [ en-US ] = "Overline (Wave)";
+};
+String RID_SVXITEMS_OL_DOUBLEWAVE
+{
+ Text [ en-US ] = "Overline (Double wave)";
+};
+String RID_SVXITEMS_OL_BOLD
+{
+ Text [ en-US ] = "Overlined (Bold)";
+};
+String RID_SVXITEMS_OL_BOLDDOTTED
+{
+ Text [ en-US ] = "Dotted overline (Bold)";
+};
+String RID_SVXITEMS_OL_BOLDDASH
+{
+ Text [ en-US ] = "Overline (Dash bold)";
+};
+String RID_SVXITEMS_OL_BOLDLONGDASH
+{
+ Text [ en-US ] = "Overline (long dash, bold)";
+};
+String RID_SVXITEMS_OL_BOLDDASHDOT
+{
+ Text [ en-US ] = "Overline (dot dash, bold)";
+};
+String RID_SVXITEMS_OL_BOLDDASHDOTDOT
+{
+ Text [ en-US ] = "Overline (dot dot dash, bold)";
+};
+String RID_SVXITEMS_OL_BOLDWAVE
+{
+ Text [ en-US ] = "Overline (wave, bold)";
+};
+ // enum FontStrikeout ----------------------------------------------------
+String RID_SVXITEMS_STRIKEOUT_NONE
+{
+ Text [ en-US ] = "No strikethrough" ;
+};
+String RID_SVXITEMS_STRIKEOUT_SINGLE
+{
+ Text [ en-US ] = "Single strikethrough" ;
+};
+String RID_SVXITEMS_STRIKEOUT_DOUBLE
+{
+ Text [ en-US ] = "Double strikethrough" ;
+};
+String RID_SVXITEMS_STRIKEOUT_BOLD
+{
+ Text [ en-US ] = "Bold strikethrough";
+};
+String RID_SVXITEMS_STRIKEOUT_SLASH
+{
+ Text [ en-US ] = "Strike through with slash";
+};
+String RID_SVXITEMS_STRIKEOUT_X
+{
+ Text [ en-US ] = "Strike through with Xes";
+};
+ // enum CASEMAP ----------------------------------------------------------
+String RID_SVXITEMS_CASEMAP_NONE
+{
+ Text [ en-US ] = "None" ;
+};
+String RID_SVXITEMS_CASEMAP_VERSALIEN
+{
+ Text [ en-US ] = "Caps" ;
+};
+String RID_SVXITEMS_CASEMAP_GEMEINE
+{
+ Text [ en-US ] = "Lowercase" ;
+};
+String RID_SVXITEMS_CASEMAP_TITEL
+{
+ Text [ en-US ] = "Title" ;
+};
+String RID_SVXITEMS_CASEMAP_KAPITAELCHEN
+{
+ Text [ en-US ] = "Small caps" ;
+};
+ // enum ESCAPEMENT -------------------------------------------------------
+String RID_SVXITEMS_ESCAPEMENT_OFF
+{
+ Text [ en-US ] = "Normal position" ;
+};
+String RID_SVXITEMS_ESCAPEMENT_SUPER
+{
+ Text [ en-US ] = "Superscript " ;
+};
+String RID_SVXITEMS_ESCAPEMENT_SUB
+{
+ Text [ en-US ] = "Subscript " ;
+};
+String RID_SVXITEMS_ESCAPEMENT_AUTO
+{
+ Text [ en-US ] = "automatic" ;
+};
+ // enum SvxAdjust -----------------------------------------------------------
+String RID_SVXITEMS_ADJUST_LEFT
+{
+ Text [ en-US ] = "Align left" ;
+};
+String RID_SVXITEMS_ADJUST_RIGHT
+{
+ Text [ en-US ] = "Align right" ;
+};
+String RID_SVXITEMS_ADJUST_BLOCK
+{
+ Text [ en-US ] = "Justify" ;
+};
+String RID_SVXITEMS_ADJUST_CENTER
+{
+ Text [ en-US ] = "Centered" ;
+};
+String RID_SVXITEMS_ADJUST_BLOCKLINE
+{
+ Text [ en-US ] = "Justify" ;
+};
+ // enum SvxTabAdjust --------------------------------------------------------
+String RID_SVXITEMS_TAB_DECIMAL_CHAR
+{
+ Text [ en-US ] = "Decimal Symbol:" ;
+};
+String RID_SVXITEMS_TAB_FILL_CHAR
+{
+ Text [ en-US ] = "Fill character:" ;
+};
+String RID_SVXITEMS_TAB_ADJUST_LEFT
+{
+ Text [ en-US ] = "Left" ;
+};
+String RID_SVXITEMS_TAB_ADJUST_RIGHT
+{
+ Text [ en-US ] = "Right" ;
+};
+String RID_SVXITEMS_TAB_ADJUST_DECIMAL
+{
+ Text [ en-US ] = "Decimal" ;
+};
+String RID_SVXITEMS_TAB_ADJUST_CENTER
+{
+ Text [ en-US ] = "Centered" ;
+};
+String RID_SVXITEMS_TAB_ADJUST_DEFAULT
+{
+ Text [ en-US ] = "Default" ;
+};
+String RID_SINGLE_LINE0
+{
+ Text [ en-US ] = "Single, fine lines" ;
+};
+String RID_SINGLE_LINE1
+{
+ Text [ en-US ] = "Single, thin" ;
+};
+String RID_SINGLE_LINE2
+{
+ Text [ en-US ] = "Single, thick" ;
+};
+String RID_SINGLE_LINE3
+{
+ Text [ en-US ] = "Single, very thick" ;
+};
+String RID_SINGLE_LINE4
+{
+ Text [ en-US ] = "Single, bold" ;
+};
+String RID_DOUBLE_LINE0
+{
+ Text [ en-US ] = "Double, fine lines, spacing: small" ;
+};
+String RID_DOUBLE_LINE1
+{
+ Text [ en-US ] = "Double, fine line, spacing: large" ;
+};
+String RID_DOUBLE_LINE2
+{
+ Text [ en-US ] = "Double, thin, spacing: small" ;
+};
+String RID_DOUBLE_LINE3
+{
+ Text [ en-US ] = "Double, thick, spacing: large" ;
+};
+String RID_DOUBLE_LINE4
+{
+ Text [ en-US ] = "Double, inside: fine lines, outside: thin, spacing: large" ;
+};
+String RID_DOUBLE_LINE5
+{
+ Text [ en-US ] = "Double, inside: fine lines, outside: thick, spacing: large" ;
+};
+String RID_DOUBLE_LINE6
+{
+ Text [ en-US ] = "Double, inside: fine lines, outside: very thick, spacing: large" ;
+};
+String RID_DOUBLE_LINE7
+{
+ Text [ en-US ] = "Double, inside: thin, outside: thick, spacing: large" ;
+};
+String RID_DOUBLE_LINE8
+{
+ Text [ en-US ] = "Double, inside: thick, outside: thin, spacing: small" ;
+};
+String RID_DOUBLE_LINE9
+{
+ Text [ en-US ] = "Double, inside: thick, outside: very thick, spacing: large" ;
+};
+String RID_DOUBLE_LINE10
+{
+ Text [ en-US ] = "Double, inside: very thick, outside: thick, Spacing: large" ;
+};
+String RID_SVXITEMS_METRIC_MM
+{
+ Text = "mm" ;
+};
+String RID_SVXITEMS_METRIC_CM
+{
+ Text = "cm" ;
+};
+String RID_SVXITEMS_METRIC_INCH
+{
+ Text = "inch" ;
+};
+String RID_SVXITEMS_METRIC_POINT
+{
+ Text = "pt" ;
+};
+String RID_SVXITEMS_METRIC_TWIP
+{
+ Text = "twip" ;
+};
+String RID_SVXITEMS_METRIC_PIXEL
+{
+ Text = "pixel" ;
+};
+ // GetValueText von BoolItems
+String RID_SVXITEMS_SHADOWED_TRUE
+{
+ Text [ en-US ] = "Shadowed" ;
+};
+String RID_SVXITEMS_SHADOWED_FALSE
+{
+ Text [ en-US ] = "Not Shadowed" ;
+};
+String RID_SVXITEMS_BLINK_TRUE
+{
+ Text [ en-US ] = "Blinking" ;
+};
+String RID_SVXITEMS_BLINK_FALSE
+{
+ Text [ en-US ] = "Not Blinking" ;
+};
+String RID_SVXITEMS_AUTOKERN_TRUE
+{
+ Text [ en-US ] = "Pair Kerning" ;
+};
+String RID_SVXITEMS_AUTOKERN_FALSE
+{
+ Text [ en-US ] = "No pair kerning" ;
+};
+String RID_SVXITEMS_WORDLINE_TRUE
+{
+ Text [ en-US ] = "Individual words" ;
+};
+String RID_SVXITEMS_WORDLINE_FALSE
+{
+ Text [ en-US ] = "Not Words Only" ;
+};
+String RID_SVXITEMS_CONTOUR_TRUE
+{
+ Text [ en-US ] = "Outline" ;
+};
+String RID_SVXITEMS_CONTOUR_FALSE
+{
+ Text [ en-US ] = "No Outline" ;
+};
+String RID_SVXITEMS_NOLINEBREAK_TRUE
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_NOLINEBREAK_FALSE
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_NOHYPHEN_TRUE
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_NOHYPHEN_FALSE
+{
+ Text = "?" ;
+};
+String RID_SVXITEMS_PRINT_TRUE
+{
+ Text [ en-US ] = "Print" ;
+};
+String RID_SVXITEMS_PRINT_FALSE
+{
+ Text [ en-US ] = "Don't print" ;
+};
+String RID_SVXITEMS_OPAQUE_TRUE
+{
+ Text [ en-US ] = "Opaque" ;
+};
+String RID_SVXITEMS_OPAQUE_FALSE
+{
+ Text [ en-US ] = "Not Opaque" ;
+};
+String RID_SVXITEMS_FMTKEEP_TRUE
+{
+ Text [ en-US ] = "Keep with next paragraph" ;
+};
+String RID_SVXITEMS_FMTKEEP_FALSE
+{
+ Text [ en-US ] = "Don't Keep Paragraphs Together" ;
+};
+String RID_SVXITEMS_FMTSPLIT_TRUE
+{
+ Text [ en-US ] = "Split paragraph" ;
+};
+String RID_SVXITEMS_FMTSPLIT_FALSE
+{
+ Text [ en-US ] = "Don't split paragraph" ;
+};
+String RID_SVXITEMS_PROT_CONTENT_TRUE
+{
+ Text [ en-US ] = "Contents protected" ;
+};
+String RID_SVXITEMS_PROT_CONTENT_FALSE
+{
+ Text [ en-US ] = "Contents not protected" ;
+};
+String RID_SVXITEMS_PROT_SIZE_TRUE
+{
+ Text [ en-US ] = "Size protected" ;
+};
+String RID_SVXITEMS_PROT_SIZE_FALSE
+{
+ Text [ en-US ] = "Size not protected" ;
+};
+String RID_SVXITEMS_PROT_POS_TRUE
+{
+ Text [ en-US ] = "Position protected" ;
+};
+String RID_SVXITEMS_PROT_POS_FALSE
+{
+ Text [ en-US ] = "Position not protected" ;
+};
+String RID_SVXITEMS_TRANSPARENT_TRUE
+{
+ Text [ en-US ] = "Transparent" ;
+};
+String RID_SVXITEMS_TRANSPARENT_FALSE
+{
+ Text [ en-US ] = "Not Transparent" ;
+};
+String RID_SVXITEMS_HYPHEN_TRUE
+{
+ Text [ en-US ] = "Hyphenation" ;
+};
+String RID_SVXITEMS_HYPHEN_FALSE
+{
+ Text [ en-US ] = "No hyphenation" ;
+};
+String RID_SVXITEMS_PAGE_END_TRUE
+{
+ Text [ en-US ] = "Page End" ;
+};
+String RID_SVXITEMS_PAGE_END_FALSE
+{
+ Text [ en-US ] = "No Page End" ;
+};
+String RID_SVXITEMS_SIZE_WIDTH
+{
+ Text [ en-US ] = "Width: " ;
+};
+String RID_SVXITEMS_SIZE_HEIGHT
+{
+ Text [ en-US ] = "Height: " ;
+};
+String RID_SVXITEMS_LRSPACE_LEFT
+{
+ Text [ en-US ] = "Indent left " ;
+};
+String RID_SVXITEMS_LRSPACE_FLINE
+{
+ Text [ en-US ] = "First Line " ;
+};
+String RID_SVXITEMS_LRSPACE_RIGHT
+{
+ Text [ en-US ] = "Indent right " ;
+};
+String RID_SVXITEMS_SHADOW_COMPLETE
+{
+ Text [ en-US ] = "Shadow: " ;
+};
+String RID_SVXITEMS_BORDER_COMPLETE
+{
+ Text [ en-US ] = "Borders " ;
+};
+String RID_SVXITEMS_BORDER_NONE
+{
+ Text [ en-US ] = "No border";
+};
+String RID_SVXITEMS_BORDER_TOP
+{
+ Text [ en-US ] = "top " ;
+};
+String RID_SVXITEMS_BORDER_BOTTOM
+{
+ Text [ en-US ] = "bottom " ;
+};
+String RID_SVXITEMS_BORDER_LEFT
+{
+ Text [ en-US ] = "left " ;
+};
+String RID_SVXITEMS_BORDER_RIGHT
+{
+ Text [ en-US ] = "right " ;
+};
+String RID_SVXITEMS_BORDER_DISTANCE
+{
+ Text [ en-US ] = "Spacing " ;
+};
+String RID_SVXITEMS_ULSPACE_UPPER
+{
+ Text [ en-US ] = "From top " ;
+};
+String RID_SVXITEMS_ULSPACE_LOWER
+{
+ Text [ en-US ] = "From bottom " ;
+};
+String RID_SVXITEMS_LINES
+{
+ Text [ en-US ] = "%1 Lines" ;
+ Text [ x-comment ] = "pb: %1 == will be replaced by the number of lines";
+};
+String RID_SVXITEMS_WIDOWS_COMPLETE
+{
+ Text [ en-US ] = "Widow control" ;
+};
+String RID_SVXITEMS_ORPHANS_COMPLETE
+{
+ Text [ en-US ] = "Orphan control" ;
+};
+String RID_SVXITEMS_HYPHEN_MINLEAD
+{
+ Text [ en-US ] = "Characters at end of line" ;
+};
+String RID_SVXITEMS_HYPHEN_MINTRAIL
+{
+ Text [ en-US ] = "Characters at beginning of line" ;
+};
+String RID_SVXITEMS_HYPHEN_MAX
+{
+ Text [ en-US ] = "Hyphens" ;
+};
+String RID_SVXITEMS_PAGEMODEL_COMPLETE
+{
+ Text [ en-US ] = "Page Style: " ;
+};
+String RID_SVXITEMS_KERNING_COMPLETE
+{
+ Text [ en-US ] = "Kerning " ;
+};
+String RID_SVXITEMS_KERNING_EXPANDED
+{
+ Text [ en-US ] = "locked " ;
+};
+String RID_SVXITEMS_KERNING_CONDENSED
+{
+ Text [ en-US ] = "Condensed " ;
+};
+String RID_SVXITEMS_GRAPHIC
+{
+ Text [ en-US ] = "Graphic" ;
+};
+String RID_SVXITEMS_EMPHASIS_NONE_STYLE
+{
+ Text [ en-US ] = "none";
+};
+String RID_SVXITEMS_EMPHASIS_DOT_STYLE
+{
+ Text [ en-US ] = "Dots ";
+};
+String RID_SVXITEMS_EMPHASIS_CIRCLE_STYLE
+{
+ Text [ en-US ] = "Circle ";
+};
+String RID_SVXITEMS_EMPHASIS_DISC_STYLE
+{
+// ??? disc == filled ring
+ Text [ en-US ] = "Filled circle ";
+};
+String RID_SVXITEMS_EMPHASIS_ACCENT_STYLE
+{
+ Text [ en-US ] = "Accent ";
+};
+String RID_SVXITEMS_EMPHASIS_ABOVE_POS
+{
+ Text [ en-US ] = "Above";
+};
+String RID_SVXITEMS_EMPHASIS_BELOW_POS
+{
+ Text [ en-US ] = "Below";
+};
+String RID_SVXITEMS_TWOLINES_OFF
+{
+ Text [ en-US ] = "Double-lined off";
+};
+String RID_SVXITEMS_TWOLINES
+{
+ Text [ en-US ] = "Double-lined";
+};
+String RID_SVXITEMS_SCRPTSPC_OFF
+{
+ Text [ en-US ] = "No automatic character spacing";
+};
+String RID_SVXITEMS_SCRPTSPC_ON
+{
+ Text [ en-US ] = "No automatic character spacing";
+};
+String RID_SVXITEMS_HNGPNCT_OFF
+{
+ Text [ en-US ] = "No hanging punctuation at line end";
+};
+String RID_SVXITEMS_HNGPNCT_ON
+{
+ Text [ en-US ] = "Hanging punctuation at line end";
+};
+String RID_SVXITEMS_FORBIDDEN_RULE_OFF
+{
+ Text [ en-US ] = "Apply list of forbidden characters to beginning and end of lines";
+};
+String RID_SVXITEMS_FORBIDDEN_RULE_ON
+{
+ Text [ en-US ] = "Don't apply list of forbidden characters to beginning and end of lines";
+};
+String RID_SVXITEMS_CHARROTATE_OFF
+{
+ Text [ en-US ] = "No rotated characters";
+};
+String RID_SVXITEMS_CHARROTATE
+{
+ Text [ en-US ] = "Character rotated by $(ARG1)°";
+};
+String RID_SVXITEMS_CHARROTATE_FITLINE
+{
+ Text [ en-US ] = "Fit to line";
+};
+String RID_SVXITEMS_CHARSCALE
+{
+ Text [ en-US ] = "Characters scaled $(ARG1)%";
+};
+String RID_SVXITEMS_CHARSCALE_OFF
+{
+ Text [ en-US ] = "No scaled characters";
+};
+String RID_SVXITEMS_RELIEF_NONE
+{
+ Text [ en-US ] = "No relief";
+};
+String RID_SVXITEMS_RELIEF_EMBOSSED
+{
+ Text [ en-US ] = "Relief";
+};
+String RID_SVXITEMS_RELIEF_ENGRAVED
+{
+ Text [ en-US ] = "Engraved";
+};
+String RID_SVXITEMS_PARAVERTALIGN_AUTO
+{
+ Text [ en-US ] = "Automatic text alignment";
+};
+String RID_SVXITEMS_PARAVERTALIGN_BASELINE
+{
+ Text [ en-US ] = "Text aligned to base line";
+};
+String RID_SVXITEMS_PARAVERTALIGN_TOP
+{
+ Text [ en-US ] = "Text aligned top";
+};
+String RID_SVXITEMS_PARAVERTALIGN_CENTER
+{
+ Text [ en-US ] = "Text aligned middle";
+};
+String RID_SVXITEMS_PARAVERTALIGN_BOTTOM
+{
+ Text [ en-US ] = "Text aligned bottom";
+};
+String RID_SVXITEMS_FRMDIR_HORI_LEFT_TOP
+{
+ Text [ en-US ] = "Text direction left-to-right (horizontal)";
+};
+String RID_SVXITEMS_FRMDIR_HORI_RIGHT_TOP
+{
+ Text [ en-US ] = "Text direction right-to-left (horizontal)";
+};
+String RID_SVXITEMS_FRMDIR_VERT_TOP_RIGHT
+{
+ Text [ en-US ] = "Text direction right-to-left (vertical)";
+};
+String RID_SVXITEMS_FRMDIR_VERT_TOP_LEFT
+{
+ Text [ en-US ] = "Text direction left-to-right (vertical)";
+};
+String RID_SVXITEMS_FRMDIR_ENVIRONMENT
+{
+ Text [ en-US ] = "Use superordinate object text direction setting";
+};
+String RID_SVXITEMS_PARASNAPTOGRID_ON
+{
+ Text[ en-US ] = "Paragraph snaps to text grid (if active)";
+};
+String RID_SVXITEMS_PARASNAPTOGRID_OFF
+{
+ Text[ en-US ] = "Paragraph does not snap to text grid";
+};
+String RID_SVXITEMS_CHARHIDDEN_FALSE
+{
+ Text [ en-US ] = "Not hidden";
+};
+String RID_SVXITEMS_CHARHIDDEN_TRUE
+{
+ Text [ en-US ] = "Hidden";
+};
+// ********************************************************************** EOF
+
diff --git a/editeng/source/items/textitem.cxx b/editeng/source/items/textitem.cxx
new file mode 100644
index 0000000000..9ba0b722cf
--- /dev/null
+++ b/editeng/source/items/textitem.cxx
@@ -0,0 +1,3846 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textitem.cxx,v $
+ * $Revision: 1.74.86.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+// include ---------------------------------------------------------------
+#include <com/sun/star/style/CaseMap.hpp>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/frame/status/FontHeight.hpp>
+#include <vcl/bitmapex.hxx>
+#include <tools/stream.hxx>
+#include <toolkit/unohlp.hxx>
+#include <math.h>
+#include <rtl/math.hxx>
+#include <unotools/fontdefs.hxx>
+#include <vcl/outdev.hxx>
+#include <editeng/eeitem.hxx>
+#include <svtools/unitconv.hxx>
+
+#define GLOBALOVERFLOW3
+
+#include <svl/memberid.hrc>
+#include <editeng/editids.hrc>
+#include <editeng/editrids.hrc>
+#include <vcl/vclenum.hxx>
+#include <tools/bigint.hxx>
+#include <tools/tenccvt.hxx>
+
+#include <rtl/ustring.hxx>
+#include <i18npool/mslangid.hxx>
+#include <svl/itemset.hxx>
+
+#include <svtools/langtab.hxx>
+#include <svl/itempool.hxx>
+#include <svtools/ctrltool.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <com/sun/star/style/CaseMap.hpp>
+#include <com/sun/star/awt/SimpleFontMetric.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/CharSet.hpp>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/awt/FontWidth.hpp>
+#include <com/sun/star/awt/XFont.hpp>
+#include <com/sun/star/awt/FontType.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/FontStrikeout.hpp>
+#include <com/sun/star/awt/FontFamily.hpp>
+#include <com/sun/star/awt/FontPitch.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/text/FontEmphasis.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <editeng/memberids.hrc>
+#include <editeng/flstitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fwdtitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/akrnitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/prszitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/cscoitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/cmapitem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/nlbkitem.hxx>
+#include <editeng/nhypitem.hxx>
+#include <editeng/lcolitem.hxx>
+#include <editeng/blnkitem.hxx>
+#include <editeng/emphitem.hxx>
+#include <editeng/twolinesitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <editeng/charrotateitem.hxx>
+#include <editeng/charscaleitem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <editeng/itemtype.hxx>
+#include <editeng/eerdll.hxx>
+
+// #90477#
+#include <tools/tenccvt.hxx>
+
+#define STORE_UNICODE_MAGIC_MARKER 0xFE331188
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::text;
+
+// Konvertierung fuer UNO
+#define TWIP_TO_MM100(TWIP) ((TWIP) >= 0 ? (((TWIP)*127L+36L)/72L) : (((TWIP)*127L-36L)/72L))
+#define MM100_TO_TWIP(MM100) ((MM100) >= 0 ? (((MM100)*72L+63L)/127L) : (((MM100)*72L-63L)/127L))
+#define TWIP_TO_MM100_UNSIGNED(TWIP) ((((TWIP)*127L+36L)/72L))
+#define MM100_TO_TWIP_UNSIGNED(MM100) ((((MM100)*72L+63L)/127L))
+
+BOOL SvxFontItem::bEnableStoreUnicodeNames = FALSE;
+
+// STATIC DATA -----------------------------------------------------------
+
+// -----------------------------------------------------------------------
+
+TYPEINIT1(SvxFontListItem, SfxPoolItem);
+TYPEINIT1_FACTORY(SvxFontItem, SfxPoolItem, new SvxFontItem(0));
+TYPEINIT1_FACTORY(SvxPostureItem, SfxEnumItem, new SvxPostureItem(ITALIC_NONE, 0));
+TYPEINIT1_FACTORY(SvxWeightItem, SfxEnumItem, new SvxWeightItem(WEIGHT_NORMAL, 0));
+TYPEINIT1_FACTORY(SvxFontHeightItem, SfxPoolItem, new SvxFontHeightItem(240, 100, 0));
+TYPEINIT1_FACTORY(SvxFontWidthItem, SfxPoolItem, new SvxFontWidthItem(0, 100, 0));
+TYPEINIT1_FACTORY(SvxTextLineItem, SfxEnumItem, new SvxTextLineItem(UNDERLINE_NONE, 0));
+TYPEINIT1_FACTORY(SvxUnderlineItem, SfxEnumItem, new SvxUnderlineItem(UNDERLINE_NONE, 0));
+TYPEINIT1_FACTORY(SvxOverlineItem, SfxEnumItem, new SvxOverlineItem(UNDERLINE_NONE, 0));
+TYPEINIT1_FACTORY(SvxCrossedOutItem, SfxEnumItem, new SvxCrossedOutItem(STRIKEOUT_NONE, 0));
+TYPEINIT1_FACTORY(SvxShadowedItem, SfxBoolItem, new SvxShadowedItem(sal_False, 0));
+TYPEINIT1_FACTORY(SvxAutoKernItem, SfxBoolItem, new SvxAutoKernItem(sal_False, 0));
+TYPEINIT1_FACTORY(SvxWordLineModeItem, SfxBoolItem, new SvxWordLineModeItem(sal_False, 0));
+TYPEINIT1_FACTORY(SvxContourItem, SfxBoolItem, new SvxContourItem(sal_False, 0));
+TYPEINIT1_FACTORY(SvxPropSizeItem, SfxUInt16Item, new SvxPropSizeItem(100, 0));
+TYPEINIT1_FACTORY(SvxColorItem, SfxPoolItem, new SvxColorItem(0));
+TYPEINIT1_FACTORY(SvxCharSetColorItem, SvxColorItem, new SvxCharSetColorItem(0));
+TYPEINIT1_FACTORY(SvxKerningItem, SfxInt16Item, new SvxKerningItem(0, 0));
+TYPEINIT1_FACTORY(SvxCaseMapItem, SfxEnumItem, new SvxCaseMapItem(SVX_CASEMAP_NOT_MAPPED, 0));
+TYPEINIT1_FACTORY(SvxEscapementItem, SfxPoolItem, new SvxEscapementItem(0));
+TYPEINIT1_FACTORY(SvxLanguageItem, SfxEnumItem, new SvxLanguageItem(LANGUAGE_GERMAN, 0));
+TYPEINIT1_FACTORY(SvxNoLinebreakItem, SfxBoolItem, new SvxNoLinebreakItem(sal_True, 0));
+TYPEINIT1_FACTORY(SvxNoHyphenItem, SfxBoolItem, new SvxNoHyphenItem(sal_True, 0));
+TYPEINIT1_FACTORY(SvxLineColorItem, SvxColorItem, new SvxLineColorItem(0));
+TYPEINIT1_FACTORY(SvxBlinkItem, SfxBoolItem, new SvxBlinkItem(sal_False, 0));
+TYPEINIT1_FACTORY(SvxEmphasisMarkItem, SfxUInt16Item, new SvxEmphasisMarkItem(EMPHASISMARK_NONE, 0));
+TYPEINIT1_FACTORY(SvxTwoLinesItem, SfxPoolItem, new SvxTwoLinesItem(sal_True, 0, 0, 0));
+TYPEINIT1_FACTORY(SvxScriptTypeItem, SfxUInt16Item, new SvxScriptTypeItem);
+TYPEINIT1_FACTORY(SvxCharRotateItem, SfxUInt16Item, new SvxCharRotateItem(0, sal_False, 0));
+TYPEINIT1_FACTORY(SvxCharScaleWidthItem, SfxUInt16Item, new SvxCharScaleWidthItem(100, 0));
+TYPEINIT1_FACTORY(SvxCharReliefItem, SfxEnumItem, new SvxCharReliefItem(RELIEF_NONE, 0));
+
+
+TYPEINIT1(SvxScriptSetItem, SfxSetItem );
+
+
+// class SvxFontListItem -------------------------------------------------
+
+SvxFontListItem::SvxFontListItem( const FontList* pFontLst,
+ const USHORT nId ) :
+ SfxPoolItem( nId ),
+ pFontList( pFontLst )
+{
+ if ( pFontList )
+ {
+ sal_Int32 nCount = pFontList->GetFontNameCount();
+ aFontNameSeq.realloc( nCount );
+
+ for ( USHORT i = 0; i < nCount; i++ )
+ aFontNameSeq[i] = pFontList->GetFontName(i).GetName();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SvxFontListItem::SvxFontListItem( const SvxFontListItem& rItem ) :
+
+ SfxPoolItem( rItem ),
+ pFontList( rItem.GetFontList() ),
+ aFontNameSeq( rItem.aFontNameSeq )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxFontListItem::Clone( SfxItemPool* ) const
+{
+ return new SvxFontListItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+int SvxFontListItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ return( pFontList == ((SvxFontListItem&)rAttr).pFontList );
+}
+
+sal_Bool SvxFontListItem::QueryValue( com::sun::star::uno::Any& rVal, BYTE /*nMemberId*/ ) const
+{
+ rVal <<= aFontNameSeq;
+ return sal_True;
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxFontListItem::GetPresentation
+(
+ SfxItemPresentation /*ePres*/,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+ rText.Erase();
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// class SvxFontItem -----------------------------------------------------
+
+SvxFontItem::SvxFontItem( const USHORT nId ) :
+ SfxPoolItem( nId )
+{
+ eFamily = FAMILY_SWISS;
+ ePitch = PITCH_VARIABLE;
+ eTextEncoding = RTL_TEXTENCODING_DONTKNOW;
+}
+
+// -----------------------------------------------------------------------
+
+SvxFontItem::SvxFontItem( const FontFamily eFam, const XubString& aName,
+ const XubString& aStName, const FontPitch eFontPitch,
+ const rtl_TextEncoding eFontTextEncoding, const USHORT nId ) :
+
+ SfxPoolItem( nId ),
+
+ aFamilyName(aName),
+ aStyleName(aStName)
+{
+ eFamily = eFam;
+ ePitch = eFontPitch;
+ eTextEncoding = eFontTextEncoding;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvxFontItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch(nMemberId)
+ {
+ case 0:
+ {
+ com::sun::star::awt::FontDescriptor aFontDescriptor;
+ aFontDescriptor.Name = aFamilyName.GetBuffer();
+ aFontDescriptor.StyleName = aStyleName.GetBuffer();
+ aFontDescriptor.Family = (sal_Int16)(eFamily);
+ aFontDescriptor.CharSet = (sal_Int16)(eTextEncoding);
+ aFontDescriptor.Pitch = (sal_Int16)(ePitch);
+ rVal <<= aFontDescriptor;
+ }
+ break;
+ case MID_FONT_FAMILY_NAME :
+ rVal <<= OUString(aFamilyName.GetBuffer());
+ break;
+ case MID_FONT_STYLE_NAME:
+ rVal <<= OUString(aStyleName.GetBuffer());
+ break;
+ case MID_FONT_FAMILY : rVal <<= (sal_Int16)(eFamily); break;
+ case MID_FONT_CHAR_SET : rVal <<= (sal_Int16)(eTextEncoding); break;
+ case MID_FONT_PITCH : rVal <<= (sal_Int16)(ePitch); break;
+ }
+ return sal_True;
+}
+// -----------------------------------------------------------------------
+sal_Bool SvxFontItem::PutValue( const uno::Any& rVal, BYTE nMemberId)
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch(nMemberId)
+ {
+ case 0:
+ {
+ com::sun::star::awt::FontDescriptor aFontDescriptor;
+ if ( !( rVal >>= aFontDescriptor ))
+ return sal_False;
+
+ aFamilyName = aFontDescriptor.Name;
+ aStyleName = aFontDescriptor.StyleName;
+ eFamily = (FontFamily)aFontDescriptor.Family;
+ eTextEncoding = (rtl_TextEncoding)aFontDescriptor.CharSet;
+ ePitch = (FontPitch)aFontDescriptor.Pitch;
+ }
+ break;
+ case MID_FONT_FAMILY_NAME :
+ {
+ OUString aStr;
+ if(!(rVal >>= aStr))
+ return sal_False;
+ aFamilyName = aStr.getStr();
+ }
+ break;
+ case MID_FONT_STYLE_NAME:
+ {
+ OUString aStr;
+ if(!(rVal >>= aStr))
+ return sal_False;
+ aStyleName = aStr.getStr();
+ }
+ break;
+ case MID_FONT_FAMILY :
+ {
+ sal_Int16 nFamily = sal_Int16();
+ if(!(rVal >>= nFamily))
+ return sal_False;
+ eFamily = (FontFamily)nFamily;
+ }
+ break;
+ case MID_FONT_CHAR_SET :
+ {
+ sal_Int16 nSet = sal_Int16();
+ if(!(rVal >>= nSet))
+ return sal_False;
+ eTextEncoding = (rtl_TextEncoding)nSet;
+ }
+ break;
+ case MID_FONT_PITCH :
+ {
+ sal_Int16 nPitch = sal_Int16();
+ if(!(rVal >>= nPitch))
+ return sal_False;
+ ePitch = (FontPitch)nPitch;
+ }
+ break;
+ }
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxFontItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ const SvxFontItem& rItem = (const SvxFontItem&)rAttr;
+
+ int bRet = ( eFamily == rItem.eFamily &&
+ aFamilyName == rItem.aFamilyName &&
+ aStyleName == rItem.aStyleName );
+
+ if ( bRet )
+ {
+ if ( ePitch != rItem.ePitch || eTextEncoding != rItem.eTextEncoding )
+ {
+ bRet = sal_False;
+ DBG_WARNING( "FontItem::operator==(): nur Pitch oder rtl_TextEncoding unterschiedlich" );
+ }
+ }
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxFontItem::Clone( SfxItemPool * ) const
+{
+ return new SvxFontItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxFontItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ BOOL bToBats =
+ GetFamilyName().EqualsAscii( "StarSymbol", 0, sizeof("StarSymbol")-1 ) ||
+ GetFamilyName().EqualsAscii( "OpenSymbol", 0, sizeof("OpenSymbol")-1 );
+
+ // #90477# rStrm << (BYTE) GetFamily()
+ // << (BYTE) GetPitch()
+ // << (BYTE)(bToBats ? RTL_TEXTENCODING_SYMBOL : GetStoreCharSet( GetCharSet(), (USHORT)rStrm.GetVersion() ) );
+ rStrm << (BYTE) GetFamily() << (BYTE) GetPitch()
+ << (BYTE)(bToBats ? RTL_TEXTENCODING_SYMBOL : GetSOStoreTextEncoding(GetCharSet(), (sal_uInt16)rStrm.GetVersion()));
+
+ String aStoreFamilyName( GetFamilyName() );
+ if( bToBats )
+ aStoreFamilyName = String( "StarBats", sizeof("StarBats")-1, RTL_TEXTENCODING_ASCII_US );
+ rStrm.WriteByteString(aStoreFamilyName);
+ rStrm.WriteByteString(GetStyleName());
+
+ // #96441# Kach for EditEngine, only set while creating clipboard stream.
+ if ( bEnableStoreUnicodeNames )
+ {
+ sal_uInt32 nMagic = STORE_UNICODE_MAGIC_MARKER;
+ rStrm << nMagic;
+ rStrm.WriteByteString( aStoreFamilyName, RTL_TEXTENCODING_UNICODE );
+ rStrm.WriteByteString( GetStyleName(), RTL_TEXTENCODING_UNICODE );
+ }
+
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxFontItem::Create(SvStream& rStrm, USHORT) const
+{
+ BYTE _eFamily, eFontPitch, eFontTextEncoding;
+ String aName, aStyle;
+ rStrm >> _eFamily;
+ rStrm >> eFontPitch;
+ rStrm >> eFontTextEncoding;
+
+ // UNICODE: rStrm >> aName;
+ rStrm.ReadByteString(aName);
+
+ // UNICODE: rStrm >> aStyle;
+ rStrm.ReadByteString(aStyle);
+
+ // Task 91008/90471: set the "correct" textencoding
+ eFontTextEncoding = (BYTE)GetSOLoadTextEncoding( eFontTextEncoding, (USHORT)rStrm.GetVersion() );
+
+ // irgendwann wandelte sich der StarBats vom ANSI- zum SYMBOL-Font
+ if ( RTL_TEXTENCODING_SYMBOL != eFontTextEncoding && aName.EqualsAscii("StarBats") )
+ eFontTextEncoding = RTL_TEXTENCODING_SYMBOL;
+
+ // Check if we have stored unicode
+ sal_Size nStreamPos = rStrm.Tell();
+ sal_uInt32 nMagic = STORE_UNICODE_MAGIC_MARKER;
+ rStrm >> nMagic;
+ if ( nMagic == STORE_UNICODE_MAGIC_MARKER )
+ {
+ rStrm.ReadByteString( aName, RTL_TEXTENCODING_UNICODE );
+ rStrm.ReadByteString( aStyle, RTL_TEXTENCODING_UNICODE );
+ }
+ else
+ {
+ rStrm.Seek( nStreamPos );
+ }
+
+
+
+ return new SvxFontItem( (FontFamily)_eFamily, aName, aStyle,
+ (FontPitch)eFontPitch, (rtl_TextEncoding)eFontTextEncoding, Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxFontItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = aFamilyName;
+ return ePres;
+ default: ; //prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+//------------------------------------------------------------------------
+
+void SvxFontItem::EnableStoreUnicodeNames( BOOL bEnable )
+{
+ bEnableStoreUnicodeNames = bEnable;
+}
+
+// class SvxPostureItem --------------------------------------------------
+
+SvxPostureItem::SvxPostureItem( const FontItalic ePosture, const USHORT nId ) :
+ SfxEnumItem( nId, (USHORT)ePosture )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxPostureItem::Clone( SfxItemPool * ) const
+{
+ return new SvxPostureItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SvxPostureItem::GetValueCount() const
+{
+ return ITALIC_NORMAL + 1; // auch ITALIC_NONE geh"ort dazu
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxPostureItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ rStrm << (BYTE)GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxPostureItem::Create(SvStream& rStrm, USHORT) const
+{
+ BYTE nPosture;
+ rStrm >> nPosture;
+ return new SvxPostureItem( (const FontItalic)nPosture, Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxPostureItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = GetValueTextByPos( GetValue() );
+ return ePres;
+ default: ;//prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SvxPostureItem::GetValueTextByPos( USHORT nPos ) const
+{
+ DBG_ASSERT( nPos <= (USHORT)ITALIC_NORMAL, "enum overflow!" );
+
+ XubString sTxt;
+ FontItalic eItalic = (FontItalic)nPos;
+ USHORT nId = 0;
+
+ switch ( eItalic )
+ {
+ case ITALIC_NONE: nId = RID_SVXITEMS_ITALIC_NONE; break;
+ case ITALIC_OBLIQUE: nId = RID_SVXITEMS_ITALIC_OBLIQUE; break;
+ case ITALIC_NORMAL: nId = RID_SVXITEMS_ITALIC_NORMAL; break;
+ default: ;//prevent warning
+ }
+
+ if ( nId )
+ sTxt = EditResId( nId );
+ return sTxt;
+}
+
+
+/*-----------------13.03.98 14:28-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxPostureItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch( nMemberId )
+ {
+ case MID_ITALIC:
+ rVal = Bool2Any(GetBoolValue());
+ break;
+ case MID_POSTURE:
+ rVal <<= (awt::FontSlant)GetValue(); // Werte von awt::FontSlant und FontItalic sind gleich
+ break;
+ }
+ return sal_True;
+}
+/*-----------------13.03.98 14:28-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxPostureItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch( nMemberId )
+ {
+ case MID_ITALIC:
+ SetBoolValue(Any2Bool(rVal));
+ break;
+ case MID_POSTURE:
+ {
+ awt::FontSlant eSlant;
+ if(!(rVal >>= eSlant))
+ {
+ sal_Int32 nValue = 0;
+ if(!(rVal >>= nValue))
+ return sal_False;
+
+ eSlant = (awt::FontSlant)nValue;
+ }
+ SetValue((USHORT)eSlant);
+ }
+ }
+ return sal_True;
+}
+// -----------------------------------------------------------------------
+
+int SvxPostureItem::HasBoolValue() const
+{
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvxPostureItem::GetBoolValue() const
+{
+ return ( (FontItalic)GetValue() >= ITALIC_OBLIQUE );
+}
+
+// -----------------------------------------------------------------------
+
+void SvxPostureItem::SetBoolValue( sal_Bool bVal )
+{
+ SetValue( (USHORT)(bVal ? ITALIC_NORMAL : ITALIC_NONE) );
+}
+
+// class SvxWeightItem ---------------------------------------------------
+
+SvxWeightItem::SvxWeightItem( const FontWeight eWght, const USHORT nId ) :
+ SfxEnumItem( nId, (USHORT)eWght )
+{
+}
+
+
+
+// -----------------------------------------------------------------------
+
+int SvxWeightItem::HasBoolValue() const
+{
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvxWeightItem::GetBoolValue() const
+{
+ return (FontWeight)GetValue() >= WEIGHT_BOLD;
+}
+
+// -----------------------------------------------------------------------
+
+void SvxWeightItem::SetBoolValue( sal_Bool bVal )
+{
+ SetValue( (USHORT)(bVal ? WEIGHT_BOLD : WEIGHT_NORMAL) );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SvxWeightItem::GetValueCount() const
+{
+ return WEIGHT_BLACK; // WEIGHT_DONTKNOW geh"ort nicht dazu
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxWeightItem::Clone( SfxItemPool * ) const
+{
+ return new SvxWeightItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxWeightItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ rStrm << (BYTE)GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxWeightItem::Create(SvStream& rStrm, USHORT) const
+{
+ BYTE nWeight;
+ rStrm >> nWeight;
+ return new SvxWeightItem( (FontWeight)nWeight, Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxWeightItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = GetValueTextByPos( GetValue() );
+ return ePres;
+ default: ;//prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SvxWeightItem::GetValueTextByPos( USHORT nPos ) const
+{
+ DBG_ASSERT( nPos <= (USHORT)WEIGHT_BLACK, "enum overflow!" );
+ return EE_RESSTR( RID_SVXITEMS_WEIGHT_BEGIN + nPos );
+}
+
+/*-----------------13.03.98 14:18-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxWeightItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch( nMemberId )
+ {
+ case MID_BOLD :
+ rVal = Bool2Any(GetBoolValue());
+ break;
+ case MID_WEIGHT:
+ {
+ rVal <<= (float)( VCLUnoHelper::ConvertFontWeight( (FontWeight)GetValue() ) );
+ }
+ break;
+ }
+ return sal_True;
+}
+/*-----------------13.03.98 14:18-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxWeightItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch( nMemberId )
+ {
+ case MID_BOLD :
+ SetBoolValue(Any2Bool(rVal));
+ break;
+ case MID_WEIGHT:
+ {
+ double fValue = 0;
+ if(!(rVal >>= fValue))
+ {
+ sal_Int32 nValue = 0;
+ if(!(rVal >>= nValue))
+ return sal_False;
+ fValue = (float)nValue;
+ }
+ SetValue( (USHORT)VCLUnoHelper::ConvertFontWeight((float)fValue) );
+ }
+ break;
+ }
+ return sal_True;
+}
+
+// class SvxFontHeightItem -----------------------------------------------
+
+SvxFontHeightItem::SvxFontHeightItem( const ULONG nSz,
+ const USHORT nPrp,
+ const USHORT nId ) :
+ SfxPoolItem( nId )
+{
+ SetHeight( nSz,nPrp ); // mit den Prozenten rechnen
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxFontHeightItem::Clone( SfxItemPool * ) const
+{
+ return new SvxFontHeightItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxFontHeightItem::Store( SvStream& rStrm , USHORT nItemVersion ) const
+{
+ rStrm << (USHORT)GetHeight();
+
+ if( FONTHEIGHT_UNIT_VERSION <= nItemVersion )
+ rStrm << GetProp() << (USHORT)GetPropUnit();
+ else
+ {
+ // JP 30.06.98: beim Export in alte Versionen geht die relative
+ // Angabe verloren, wenn es keine Prozentuale ist
+ USHORT _nProp = GetProp();
+ if( SFX_MAPUNIT_RELATIVE != GetPropUnit() )
+ _nProp = 100;
+ rStrm << _nProp;
+ }
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxFontHeightItem::Create( SvStream& rStrm,
+ USHORT nVersion ) const
+{
+ USHORT nsize, nprop = 0, nPropUnit = SFX_MAPUNIT_RELATIVE;
+
+ rStrm >> nsize;
+
+ if( FONTHEIGHT_16_VERSION <= nVersion )
+ rStrm >> nprop;
+ else
+ {
+ BYTE nP;
+ rStrm >> nP;
+ nprop = (USHORT)nP;
+ }
+
+ if( FONTHEIGHT_UNIT_VERSION <= nVersion )
+ rStrm >> nPropUnit;
+
+ SvxFontHeightItem* pItem = new SvxFontHeightItem( nsize, 100, Which() );
+ pItem->SetProp( nprop, (SfxMapUnit)nPropUnit );
+ return pItem;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxFontHeightItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" );
+ return GetHeight() == ((SvxFontHeightItem&)rItem).GetHeight() &&
+ GetProp() == ((SvxFontHeightItem&)rItem).GetProp() &&
+ GetPropUnit() == ((SvxFontHeightItem&)rItem).GetPropUnit();
+}
+
+/*-----------------13.03.98 14:53-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxFontHeightItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+ // In StarOne sind im uno::Any immer 1/100mm. Ueber die MemberId wird
+ // gesteuert, ob der Wert im Item 1/100mm oder Twips sind.
+
+ sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch( nMemberId )
+ {
+ case 0:
+ {
+ ::com::sun::star::frame::status::FontHeight aFontHeight;
+
+ // Point (also Twips) sind gefragt,
+ // also umrechnen, wenn CONVERT_TWIPS nicht gesetzt ist
+ if( bConvert )
+ {
+ long nTwips = bConvert ? nHeight : MM100_TO_TWIP_UNSIGNED(nHeight);
+ aFontHeight.Height = (float)( nTwips / 20.0 );
+ }
+ else
+ {
+ double fPoints = MM100_TO_TWIP_UNSIGNED(nHeight) / 20.0;
+ float fRoundPoints =
+ static_cast<float>(::rtl::math::round(fPoints, 1));
+ aFontHeight.Height = fRoundPoints;
+ }
+
+ aFontHeight.Prop = (sal_Int16)(SFX_MAPUNIT_RELATIVE == ePropUnit ? nProp : 100);
+
+ float fRet = (float)(short)nProp;
+ switch( ePropUnit )
+ {
+ case SFX_MAPUNIT_RELATIVE:
+ fRet = 0.;
+ break;
+ case SFX_MAPUNIT_100TH_MM:
+ fRet = MM100_TO_TWIP(fRet);
+ fRet /= 20.;
+ break;
+ case SFX_MAPUNIT_POINT:
+
+ break;
+ case SFX_MAPUNIT_TWIP:
+ fRet /= 20.;
+ break;
+ default: ;//prevent warning
+ }
+ aFontHeight.Diff = fRet;
+ rVal <<= aFontHeight;
+ }
+ break;
+ case MID_FONTHEIGHT:
+ {
+ // Point (also Twips) sind gefragt,
+ // also umrechnen, wenn CONVERT_TWIPS nicht gesetzt ist
+ if( bConvert )
+ {
+ long nTwips = bConvert ? nHeight : MM100_TO_TWIP_UNSIGNED(nHeight);
+ rVal <<= (float)( nTwips / 20.0 );
+ }
+ else
+ {
+ double fPoints = MM100_TO_TWIP_UNSIGNED(nHeight) / 20.0;
+ float fRoundPoints =
+ static_cast<float>(::rtl::math::round(fPoints, 1));
+ rVal <<= fRoundPoints;
+ }
+ }
+ break;
+ case MID_FONTHEIGHT_PROP:
+ rVal <<= (sal_Int16)(SFX_MAPUNIT_RELATIVE == ePropUnit ? nProp : 100);
+ break;
+ case MID_FONTHEIGHT_DIFF:
+ {
+ float fRet = (float)(short)nProp;
+ switch( ePropUnit )
+ {
+ case SFX_MAPUNIT_RELATIVE:
+ fRet = 0.;
+ break;
+ case SFX_MAPUNIT_100TH_MM:
+ fRet = MM100_TO_TWIP(fRet);
+ fRet /= 20.;
+ break;
+ case SFX_MAPUNIT_POINT:
+
+ break;
+ case SFX_MAPUNIT_TWIP:
+ fRet /= 20.;
+ break;
+ default: ;//prevent warning
+ }
+ rVal <<= fRet;
+ }
+ break;
+ }
+ return sal_True;
+}
+/* -----------------01.07.98 13:43-------------------
+ * Relative Abweichung aus der Hoehe herausrechnen
+ * --------------------------------------------------*/
+sal_uInt32 lcl_GetRealHeight_Impl(sal_uInt32 nHeight, sal_uInt16 nProp, SfxMapUnit eProp, sal_Bool bCoreInTwip)
+{
+ sal_uInt32 nRet = nHeight;
+ short nDiff = 0;
+ switch( eProp )
+ {
+ case SFX_MAPUNIT_RELATIVE:
+ nRet *= 100;
+ nRet /= nProp;
+ break;
+ case SFX_MAPUNIT_POINT:
+ {
+ short nTemp = (short)nProp;
+ nDiff = nTemp * 20;
+ if(!bCoreInTwip)
+ nDiff = (short)TWIP_TO_MM100((long)(nDiff));
+ }
+ break;
+ case SFX_MAPUNIT_100TH_MM:
+ //dann ist die Core doch wohl auch in 1/100 mm
+ nDiff = (short)nProp;
+ break;
+ case SFX_MAPUNIT_TWIP:
+ // hier doch sicher TWIP
+ nDiff = ((short)nProp);
+ break;
+ default: ;//prevent warning
+ }
+ nRet -= nDiff;
+
+ return nRet;
+}
+
+/*-----------------13.03.98 14:53-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxFontHeightItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+ sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch( nMemberId )
+ {
+ case 0:
+ {
+ ::com::sun::star::frame::status::FontHeight aFontHeight;
+ if ( rVal >>= aFontHeight )
+ {
+ // Height
+ ePropUnit = SFX_MAPUNIT_RELATIVE;
+ nProp = 100;
+ double fPoint = aFontHeight.Height;
+ if( fPoint < 0. || fPoint > 10000. )
+ return sal_False;
+
+ nHeight = (long)( fPoint * 20.0 + 0.5 ); // Twips
+ if (!bConvert)
+ nHeight = TWIP_TO_MM100_UNSIGNED(nHeight); // umrechnen, wenn das Item 1/100mm enthaelt
+
+ nProp = aFontHeight.Prop;
+ }
+ else
+ return sal_False;
+ }
+ break;
+ case MID_FONTHEIGHT:
+ {
+ ePropUnit = SFX_MAPUNIT_RELATIVE;
+ nProp = 100;
+ double fPoint = 0;
+ if(!(rVal >>= fPoint))
+ {
+ sal_Int32 nValue = 0;
+ if(!(rVal >>= nValue))
+ return sal_False;
+ fPoint = (float)nValue;
+ }
+ if(fPoint < 0. || fPoint > 10000.)
+ return sal_False;
+
+ nHeight = (long)( fPoint * 20.0 + 0.5 ); // Twips
+ if (!bConvert)
+ nHeight = TWIP_TO_MM100_UNSIGNED(nHeight); // umrechnen, wenn das Item 1/100mm enthaelt
+ }
+ break;
+ case MID_FONTHEIGHT_PROP:
+ {
+ sal_Int16 nNew = sal_Int16();
+ if(!(rVal >>= nNew))
+ return sal_True;
+
+ nHeight = lcl_GetRealHeight_Impl(nHeight, nProp, ePropUnit, bConvert);
+
+ nHeight *= nNew;
+ nHeight /= 100;
+ nProp = nNew;
+ ePropUnit = SFX_MAPUNIT_RELATIVE;
+ }
+ break;
+ case MID_FONTHEIGHT_DIFF:
+ {
+ nHeight = lcl_GetRealHeight_Impl(nHeight, nProp, ePropUnit, bConvert);
+ float fValue = 0;
+ if(!(rVal >>= fValue))
+ {
+ sal_Int32 nValue = 0;
+ if(!(rVal >>= nValue))
+ return sal_False;
+ fValue = (float)nValue;
+ }
+ sal_Int16 nCoreDiffValue = (sal_Int16)(fValue * 20.);
+ nHeight += bConvert ? nCoreDiffValue : TWIP_TO_MM100(nCoreDiffValue);
+ nProp = (sal_uInt16)((sal_Int16)fValue);
+ ePropUnit = SFX_MAPUNIT_POINT;
+ }
+ break;
+ }
+ return sal_True;
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxFontHeightItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit eCoreUnit,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *pIntl
+) const
+{
+#ifndef SVX_LIGHT
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ if( SFX_MAPUNIT_RELATIVE != ePropUnit )
+ {
+ ( rText = String::CreateFromInt32( (short)nProp ) ) +=
+ EE_RESSTR( GetMetricId( ePropUnit ) );
+ if( 0 <= (short)nProp )
+ rText.Insert( sal_Unicode('+'), 0 );
+ }
+ else if( 100 == nProp )
+ {
+ rText = GetMetricText( (long)nHeight,
+ eCoreUnit, SFX_MAPUNIT_POINT, pIntl );
+ rText += EE_RESSTR(GetMetricId(SFX_MAPUNIT_POINT));
+ }
+ else
+ ( rText = String::CreateFromInt32( nProp )) += sal_Unicode('%');
+ return ePres;
+ }
+ default: ; //prevent warning
+ }
+#endif
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SvxFontHeightItem::GetVersion(USHORT nFileVersion) const
+{
+ return (nFileVersion <= SOFFICE_FILEFORMAT_40)
+ ? FONTHEIGHT_16_VERSION
+ : FONTHEIGHT_UNIT_VERSION;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxFontHeightItem::ScaleMetrics( long nMult, long nDiv )
+{
+ nHeight = (sal_uInt32)Scale( nHeight, nMult, nDiv );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxFontHeightItem::HasMetrics() const
+{
+ return 1;
+}
+
+void SvxFontHeightItem::SetHeight( sal_uInt32 nNewHeight, const USHORT nNewProp,
+ SfxMapUnit eUnit )
+{
+ DBG_ASSERT( GetRefCount() == 0, "SetValue() with pooled item" );
+
+#ifndef SVX_LIGHT
+ if( SFX_MAPUNIT_RELATIVE != eUnit )
+ nHeight = nNewHeight + ::ItemToControl( (short)nNewProp, eUnit,
+ SFX_FUNIT_TWIP );
+ else
+#endif // !SVX_LIGHT
+ if( 100 != nNewProp )
+ nHeight = sal_uInt32(( nNewHeight * nNewProp ) / 100 );
+ else
+ nHeight = nNewHeight;
+
+ nProp = nNewProp;
+ ePropUnit = eUnit;
+}
+
+void SvxFontHeightItem::SetHeight( sal_uInt32 nNewHeight, USHORT nNewProp,
+ SfxMapUnit eMetric, SfxMapUnit eCoreMetric )
+{
+ DBG_ASSERT( GetRefCount() == 0, "SetValue() with pooled item" );
+
+#ifndef SVX_LIGHT
+ if( SFX_MAPUNIT_RELATIVE != eMetric )
+ nHeight = nNewHeight +
+ ::ControlToItem( ::ItemToControl((short)nNewProp, eMetric,
+ SFX_FUNIT_TWIP ), SFX_FUNIT_TWIP,
+ eCoreMetric );
+ else
+#endif // !SVX_LIGHT
+ if( 100 != nNewProp )
+ nHeight = sal_uInt32(( nNewHeight * nNewProp ) / 100 );
+ else
+ nHeight = nNewHeight;
+
+ nProp = nNewProp;
+ ePropUnit = eMetric;
+}
+
+// class SvxFontWidthItem -----------------------------------------------
+
+SvxFontWidthItem::SvxFontWidthItem( const USHORT nSz, const USHORT nPrp, const USHORT nId ) :
+ SfxPoolItem( nId )
+{
+ nWidth = nSz;
+ nProp = nPrp;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxFontWidthItem::Clone( SfxItemPool * ) const
+{
+ return new SvxFontWidthItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxFontWidthItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ rStrm << GetWidth() << GetProp();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxFontWidthItem::ScaleMetrics( long nMult, long nDiv )
+{
+ nWidth = (USHORT)Scale( nWidth, nMult, nDiv );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxFontWidthItem::HasMetrics() const
+{
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxFontWidthItem::Create( SvStream& rStrm,
+ USHORT /*nVersion*/ ) const
+{
+ USHORT nS;
+ USHORT nP;
+
+ rStrm >> nS;
+ rStrm >> nP;
+ SvxFontWidthItem* pItem = new SvxFontWidthItem( 0, nP, Which() );
+ pItem->SetWidthValue( nS );
+ return pItem;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxFontWidthItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" );
+ return GetWidth() == ((SvxFontWidthItem&)rItem).GetWidth() &&
+ GetProp() == ((SvxFontWidthItem&)rItem).GetProp();
+}
+
+/*-----------------13.03.98 16:03-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxFontWidthItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch(nMemberId)
+ {
+ case MID_FONTWIDTH:
+ rVal <<= (sal_Int16)(nWidth);
+ break;
+ case MID_FONTWIDTH_PROP:
+ rVal <<= (sal_Int16)(nProp);
+ break;
+ }
+ return sal_True;
+}
+/*-----------------13.03.98 16:03-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxFontWidthItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ sal_Int16 nVal = sal_Int16();
+ if(!(rVal >>= nVal))
+ return sal_False;
+
+ switch(nMemberId)
+ {
+ case MID_FONTWIDTH:
+ nProp = nVal;
+ break;
+ case MID_FONTWIDTH_PROP:
+ nWidth = nVal;
+ break;
+ }
+ return sal_True;
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxFontWidthItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit eCoreUnit,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *pIntl
+) const
+{
+#ifndef SVX_LIGHT
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ if ( 100 == nProp )
+ {
+ rText = GetMetricText( (long)nWidth,
+ eCoreUnit, SFX_MAPUNIT_POINT, pIntl );
+ rText += EE_RESSTR(GetMetricId(SFX_MAPUNIT_POINT));
+ }
+ else
+ ( rText = String::CreateFromInt32( nProp )) += sal_Unicode('%');
+ return ePres;
+ }
+ default: ; //prevent warning
+ }
+#endif
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// class SvxTextLineItem ------------------------------------------------
+
+SvxTextLineItem::SvxTextLineItem( const FontUnderline eSt, const USHORT nId )
+ : SfxEnumItem( nId, (USHORT)eSt ), mColor( COL_TRANSPARENT )
+{
+}
+
+// -----------------------------------------------------------------------
+
+int SvxTextLineItem::HasBoolValue() const
+{
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvxTextLineItem::GetBoolValue() const
+{
+ return (FontUnderline)GetValue() != UNDERLINE_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+void SvxTextLineItem::SetBoolValue( sal_Bool bVal )
+{
+ SetValue( (USHORT)(bVal ? UNDERLINE_SINGLE : UNDERLINE_NONE) );
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxTextLineItem::Clone( SfxItemPool * ) const
+{
+ SvxTextLineItem* pNew = new SvxTextLineItem( *this );
+ pNew->SetColor( GetColor() );
+ return pNew;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SvxTextLineItem::GetValueCount() const
+{
+ return UNDERLINE_DOTTED + 1; // auch UNDERLINE_NONE geh"ort dazu
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxTextLineItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ rStrm << (BYTE)GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxTextLineItem::Create(SvStream& rStrm, USHORT) const
+{
+ BYTE nState;
+ rStrm >> nState;
+ return new SvxTextLineItem( (FontUnderline)nState, Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxTextLineItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+#ifndef SVX_LIGHT
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = GetValueTextByPos( GetValue() );
+ if( !mColor.GetTransparency() )
+ ( rText += cpDelim ) += ::GetColorString( mColor );
+ return ePres;
+ default: ; //prevent warning
+ }
+#endif
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SvxTextLineItem::GetValueTextByPos( USHORT /*nPos*/ ) const
+{
+ DBG_ERROR("SvxTextLineItem::GetValueTextByPos: Pure virtual method");
+ return XubString();
+}
+
+/*-----------------13.03.98 16:25-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxTextLineItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch(nMemberId)
+ {
+ case MID_TEXTLINED:
+ rVal = Bool2Any(GetBoolValue());
+ break;
+ case MID_TL_STYLE:
+ rVal <<= (sal_Int16)(GetValue());
+ break;
+ case MID_TL_COLOR:
+ rVal <<= (sal_Int32)( mColor.GetColor() );
+ break;
+ case MID_TL_HASCOLOR:
+ rVal = Bool2Any( !mColor.GetTransparency() );
+ break;
+ }
+ return sal_True;
+
+}
+/*-----------------13.03.98 16:28-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxTextLineItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ sal_Bool bRet = sal_True;
+ switch(nMemberId)
+ {
+ case MID_TEXTLINED:
+ SetBoolValue(Any2Bool(rVal));
+ break;
+ case MID_TL_STYLE:
+ {
+ sal_Int32 nValue = 0;
+ if(!(rVal >>= nValue))
+ bRet = sal_False;
+ else
+ SetValue((sal_Int16)nValue);
+ }
+ break;
+ case MID_TL_COLOR:
+ {
+ sal_Int32 nCol = 0;
+ if( !( rVal >>= nCol ) )
+ bRet = sal_False;
+ else
+ {
+ // Keep transparence, because it contains the information
+ // whether the font color or the stored color should be used
+ sal_uInt8 nTrans = mColor.GetTransparency();
+ mColor = Color( nCol );
+ mColor.SetTransparency( nTrans );
+ }
+ }
+ break;
+ case MID_TL_HASCOLOR:
+ mColor.SetTransparency( Any2Bool( rVal ) ? 0 : 0xff );
+ break;
+ }
+ return bRet;
+}
+
+int SvxTextLineItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" );
+ return SfxEnumItem::operator==( rItem ) &&
+ GetColor() == ((SvxTextLineItem&)rItem).GetColor();
+}
+
+// class SvxUnderlineItem ------------------------------------------------
+
+SvxUnderlineItem::SvxUnderlineItem( const FontUnderline eSt, const USHORT nId )
+ : SvxTextLineItem( eSt, nId )
+{
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* SvxUnderlineItem::Clone( SfxItemPool * ) const
+{
+ SvxUnderlineItem* pNew = new SvxUnderlineItem( *this );
+ pNew->SetColor( GetColor() );
+ return pNew;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxUnderlineItem::Create(SvStream& rStrm, USHORT) const
+{
+ BYTE nState;
+ rStrm >> nState;
+ return new SvxUnderlineItem( (FontUnderline)nState, Which() );
+}
+
+// -----------------------------------------------------------------------
+
+XubString SvxUnderlineItem::GetValueTextByPos( USHORT nPos ) const
+{
+ DBG_ASSERT( nPos <= (USHORT)UNDERLINE_BOLDWAVE, "enum overflow!" );
+ return EE_RESSTR( RID_SVXITEMS_UL_BEGIN + nPos );
+}
+
+// class SvxOverlineItem ------------------------------------------------
+
+SvxOverlineItem::SvxOverlineItem( const FontUnderline eSt, const USHORT nId )
+ : SvxTextLineItem( eSt, nId )
+{
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* SvxOverlineItem::Clone( SfxItemPool * ) const
+{
+ SvxOverlineItem* pNew = new SvxOverlineItem( *this );
+ pNew->SetColor( GetColor() );
+ return pNew;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxOverlineItem::Create(SvStream& rStrm, USHORT) const
+{
+ BYTE nState;
+ rStrm >> nState;
+ return new SvxOverlineItem( (FontUnderline)nState, Which() );
+}
+
+// -----------------------------------------------------------------------
+
+XubString SvxOverlineItem::GetValueTextByPos( USHORT nPos ) const
+{
+ DBG_ASSERT( nPos <= (USHORT)UNDERLINE_BOLDWAVE, "enum overflow!" );
+ return EE_RESSTR( RID_SVXITEMS_OL_BEGIN + nPos );
+}
+
+// class SvxCrossedOutItem -----------------------------------------------
+
+SvxCrossedOutItem::SvxCrossedOutItem( const FontStrikeout eSt, const USHORT nId )
+ : SfxEnumItem( nId, (USHORT)eSt )
+{
+}
+
+// -----------------------------------------------------------------------
+
+int SvxCrossedOutItem::HasBoolValue() const
+{
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvxCrossedOutItem::GetBoolValue() const
+{
+ return (FontStrikeout)GetValue() != STRIKEOUT_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+void SvxCrossedOutItem::SetBoolValue( sal_Bool bVal )
+{
+ SetValue( (USHORT)(bVal ? STRIKEOUT_SINGLE : STRIKEOUT_NONE) );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SvxCrossedOutItem::GetValueCount() const
+{
+ return STRIKEOUT_DOUBLE + 1; // auch STRIKEOUT_NONE geh"ort dazu
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxCrossedOutItem::Clone( SfxItemPool * ) const
+{
+ return new SvxCrossedOutItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxCrossedOutItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ rStrm << (BYTE)GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxCrossedOutItem::Create(SvStream& rStrm, USHORT) const
+{
+ BYTE eCross;
+ rStrm >> eCross;
+ return new SvxCrossedOutItem( (FontStrikeout)eCross, Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxCrossedOutItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = GetValueTextByPos( GetValue() );
+ return ePres;
+ default: ;//prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SvxCrossedOutItem::GetValueTextByPos( USHORT nPos ) const
+{
+ DBG_ASSERT( nPos <= (USHORT)STRIKEOUT_X, "enum overflow!" );
+ return EE_RESSTR( RID_SVXITEMS_STRIKEOUT_BEGIN + nPos );
+}
+
+/*-----------------13.03.98 16:28-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxCrossedOutItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch(nMemberId)
+ {
+ case MID_CROSSED_OUT:
+ rVal = Bool2Any(GetBoolValue());
+ break;
+ case MID_CROSS_OUT:
+ rVal <<= (sal_Int16)(GetValue());
+ break;
+ }
+ return sal_True;
+}
+/*-----------------13.03.98 16:29-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxCrossedOutItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch(nMemberId)
+ {
+ case MID_CROSSED_OUT:
+ SetBoolValue(Any2Bool(rVal));
+ break;
+ case MID_CROSS_OUT:
+ {
+ sal_Int32 nValue = 0;
+ if(!(rVal >>= nValue))
+ return sal_False;
+ SetValue((sal_Int16)nValue);
+ }
+ break;
+ }
+ return sal_True;
+}
+// class SvxShadowedItem -------------------------------------------------
+
+SvxShadowedItem::SvxShadowedItem( const sal_Bool bShadowed, const USHORT nId ) :
+ SfxBoolItem( nId, bShadowed )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxShadowedItem::Clone( SfxItemPool * ) const
+{
+ return new SvxShadowedItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxShadowedItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ rStrm << (BYTE) GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxShadowedItem::Create(SvStream& rStrm, USHORT) const
+{
+ BYTE nState;
+ rStrm >> nState;
+ return new SvxShadowedItem( nState, Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxShadowedItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ USHORT nId = RID_SVXITEMS_SHADOWED_FALSE;
+
+ if ( GetValue() )
+ nId = RID_SVXITEMS_SHADOWED_TRUE;
+ rText = EE_RESSTR(nId);
+ return ePres;
+ }
+ default: ; //prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// class SvxAutoKernItem -------------------------------------------------
+
+SvxAutoKernItem::SvxAutoKernItem( const sal_Bool bAutoKern, const USHORT nId ) :
+ SfxBoolItem( nId, bAutoKern )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxAutoKernItem::Clone( SfxItemPool * ) const
+{
+ return new SvxAutoKernItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxAutoKernItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ rStrm << (BYTE) GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxAutoKernItem::Create(SvStream& rStrm, USHORT) const
+{
+ BYTE nState;
+ rStrm >> nState;
+ return new SvxAutoKernItem( nState, Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxAutoKernItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ USHORT nId = RID_SVXITEMS_AUTOKERN_FALSE;
+
+ if ( GetValue() )
+ nId = RID_SVXITEMS_AUTOKERN_TRUE;
+ rText = EE_RESSTR(nId);
+ return ePres;
+ }
+ default: ; //prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// class SvxWordLineModeItem ---------------------------------------------
+
+SvxWordLineModeItem::SvxWordLineModeItem( const sal_Bool bWordLineMode,
+ const USHORT nId ) :
+ SfxBoolItem( nId, bWordLineMode )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxWordLineModeItem::Clone( SfxItemPool * ) const
+{
+ return new SvxWordLineModeItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxWordLineModeItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ rStrm << (sal_Bool) GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxWordLineModeItem::Create(SvStream& rStrm, USHORT) const
+{
+ sal_Bool bValue;
+ rStrm >> bValue;
+ return new SvxWordLineModeItem( bValue, Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxWordLineModeItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ USHORT nId = RID_SVXITEMS_WORDLINE_FALSE;
+
+ if ( GetValue() )
+ nId = RID_SVXITEMS_WORDLINE_TRUE;
+ rText = EE_RESSTR(nId);
+ return ePres;
+ }
+ default: ; //prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// class SvxContourItem --------------------------------------------------
+
+SvxContourItem::SvxContourItem( const sal_Bool bContoured, const USHORT nId ) :
+ SfxBoolItem( nId, bContoured )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxContourItem::Clone( SfxItemPool * ) const
+{
+ return new SvxContourItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxContourItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ rStrm << (sal_Bool) GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxContourItem::Create(SvStream& rStrm, USHORT) const
+{
+ sal_Bool bValue;
+ rStrm >> bValue;
+ return new SvxContourItem( bValue, Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxContourItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ USHORT nId = RID_SVXITEMS_CONTOUR_FALSE;
+
+ if ( GetValue() )
+ nId = RID_SVXITEMS_CONTOUR_TRUE;
+ rText = EE_RESSTR(nId);
+ return ePres;
+ }
+ default: ; //prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// class SvxPropSizeItem -------------------------------------------------
+
+SvxPropSizeItem::SvxPropSizeItem( const USHORT nPercent, const USHORT nId ) :
+ SfxUInt16Item( nId, nPercent )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxPropSizeItem::Clone( SfxItemPool * ) const
+{
+ return new SvxPropSizeItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxPropSizeItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ rStrm << (USHORT) GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxPropSizeItem::Create(SvStream& rStrm, USHORT) const
+{
+ USHORT nSize;
+ rStrm >> nSize;
+ return new SvxPropSizeItem( nSize, Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxPropSizeItem::GetPresentation
+(
+ SfxItemPresentation /*ePres*/,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+ rText.Erase();
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// class SvxColorItem ----------------------------------------------------
+
+SvxColorItem::SvxColorItem( const USHORT nId ) :
+ SfxPoolItem( nId ),
+ mColor( COL_BLACK )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvxColorItem::SvxColorItem( const Color& rCol, const USHORT nId ) :
+ SfxPoolItem( nId ),
+ mColor( rCol )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvxColorItem::SvxColorItem( SvStream &rStrm, const USHORT nId ) :
+ SfxPoolItem( nId )
+{
+ Color aColor;
+ rStrm >> aColor;
+ mColor = aColor;
+}
+
+// -----------------------------------------------------------------------
+
+SvxColorItem::SvxColorItem( const SvxColorItem &rCopy ) :
+ SfxPoolItem( rCopy ),
+ mColor( rCopy.mColor )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvxColorItem::~SvxColorItem()
+{
+}
+
+// -----------------------------------------------------------------------
+USHORT SvxColorItem::GetVersion( USHORT nFFVer ) const
+{
+ DBG_ASSERT( SOFFICE_FILEFORMAT_31==nFFVer ||
+ SOFFICE_FILEFORMAT_40==nFFVer ||
+ SOFFICE_FILEFORMAT_50==nFFVer,
+ "SvxColorItem: Gibt es ein neues Fileformat?" );
+ return SOFFICE_FILEFORMAT_50 >= nFFVer ? VERSION_USEAUTOCOLOR : 0;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxColorItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ return mColor == ( (const SvxColorItem&)rAttr ).mColor;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvxColorItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/ ) const
+{
+ rVal <<= (sal_Int32)(mColor.GetColor());
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvxColorItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/ )
+{
+ sal_Int32 nColor = 0;
+ if(!(rVal >>= nColor))
+ return sal_False;
+
+ mColor.SetColor( nColor );
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxColorItem::Clone( SfxItemPool * ) const
+{
+ return new SvxColorItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxColorItem::Store( SvStream& rStrm , USHORT nItemVersion ) const
+{
+ if( VERSION_USEAUTOCOLOR == nItemVersion &&
+ COL_AUTO == mColor.GetColor() )
+ rStrm << Color( COL_BLACK );
+ else
+ rStrm << mColor;
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxColorItem::Create(SvStream& rStrm, USHORT /*nVer*/ ) const
+{
+ return new SvxColorItem( rStrm, Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxColorItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+#ifndef SVX_LIGHT
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = ::GetColorString( mColor );
+ return ePres;
+ default: ; //prevent warning
+ }
+#endif
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+void SvxColorItem::SetValue( const Color& rNewCol )
+{
+ mColor = rNewCol;
+}
+
+// class SvxCharSetColorItem ---------------------------------------------
+
+SvxCharSetColorItem::SvxCharSetColorItem( const USHORT nId ) :
+ SvxColorItem( nId ),
+
+ eFrom( RTL_TEXTENCODING_DONTKNOW )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvxCharSetColorItem::SvxCharSetColorItem( const Color& rCol,
+ const rtl_TextEncoding _eFrom,
+ const USHORT nId ) :
+ SvxColorItem( rCol, nId ),
+
+ eFrom( _eFrom )
+{
+}
+
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxCharSetColorItem::Clone( SfxItemPool * ) const
+{
+ return new SvxCharSetColorItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxCharSetColorItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ // #90477# rStrm << (BYTE) GetStoreCharSet( GetCharSet(), (USHORT)rStrm.GetVersion() )
+ // << GetValue();
+ rStrm << (BYTE)GetSOStoreTextEncoding(GetCharSet(), (sal_uInt16)rStrm.GetVersion())
+ << GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxCharSetColorItem::Create(SvStream& rStrm, USHORT) const
+{
+ BYTE cSet;
+ Color aColor;
+ rStrm >> cSet >> aColor;
+ return new SvxCharSetColorItem( aColor, (rtl_TextEncoding)cSet, Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxCharSetColorItem::GetPresentation
+(
+ SfxItemPresentation /*ePres*/,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+ rText.Erase();
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// class SvxKerningItem --------------------------------------------------
+
+SvxKerningItem::SvxKerningItem( const short nKern, const USHORT nId ) :
+ SfxInt16Item( nId, nKern )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxKerningItem::Clone( SfxItemPool * ) const
+{
+ return new SvxKerningItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxKerningItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ rStrm << (short) GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxKerningItem::ScaleMetrics( long nMult, long nDiv )
+{
+ SetValue( (sal_Int16)Scale( GetValue(), nMult, nDiv ) );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+int SvxKerningItem::HasMetrics() const
+{
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxKerningItem::Create(SvStream& rStrm, USHORT) const
+{
+ short nValue;
+ rStrm >> nValue;
+ return new SvxKerningItem( nValue, Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxKerningItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit eCoreUnit,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper *pIntl
+) const
+{
+#ifndef SVX_LIGHT
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ rText = GetMetricText( (long)GetValue(), eCoreUnit, SFX_MAPUNIT_POINT, pIntl );
+ rText += EE_RESSTR(GetMetricId(SFX_MAPUNIT_POINT));
+ return ePres;
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ rText = EE_RESSTR(RID_SVXITEMS_KERNING_COMPLETE);
+ USHORT nId = 0;
+
+ if ( GetValue() > 0 )
+ nId = RID_SVXITEMS_KERNING_EXPANDED;
+ else if ( GetValue() < 0 )
+ nId = RID_SVXITEMS_KERNING_CONDENSED;
+
+ if ( nId )
+ rText += EE_RESSTR(nId);
+ rText += GetMetricText( (long)GetValue(), eCoreUnit, SFX_MAPUNIT_POINT, pIntl );
+ rText += EE_RESSTR(GetMetricId(SFX_MAPUNIT_POINT));
+ return ePres;
+ }
+ default: ; //prevent warning
+ }
+#endif
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+/* -----------------------------19.02.01 12:21--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool SvxKerningItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+ sal_Int16 nVal = GetValue();
+ if(nMemberId & CONVERT_TWIPS)
+ nVal = (sal_Int16)TWIP_TO_MM100(nVal);
+ rVal <<= nVal;
+ return sal_True;
+}
+// -----------------------------------------------------------------------
+sal_Bool SvxKerningItem::PutValue( const uno::Any& rVal, BYTE nMemberId)
+{
+ sal_Int16 nVal = sal_Int16();
+ if(!(rVal >>= nVal))
+ return sal_False;
+ if(nMemberId & CONVERT_TWIPS)
+ nVal = (sal_Int16)MM100_TO_TWIP(nVal);
+ SetValue(nVal);
+ return sal_True;
+}
+
+// class SvxCaseMapItem --------------------------------------------------
+
+SvxCaseMapItem::SvxCaseMapItem( const SvxCaseMap eMap, const USHORT nId ) :
+ SfxEnumItem( nId, (USHORT)eMap )
+{
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SvxCaseMapItem::GetValueCount() const
+{
+ return SVX_CASEMAP_END; // SVX_CASEMAP_KAPITAELCHEN + 1
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxCaseMapItem::Clone( SfxItemPool * ) const
+{
+ return new SvxCaseMapItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxCaseMapItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ rStrm << (BYTE) GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxCaseMapItem::Create(SvStream& rStrm, USHORT) const
+{
+ BYTE cMap;
+ rStrm >> cMap;
+ return new SvxCaseMapItem( (const SvxCaseMap)cMap, Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxCaseMapItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = GetValueTextByPos( GetValue() );
+ return ePres;
+ default: ; //prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SvxCaseMapItem::GetValueTextByPos( USHORT nPos ) const
+{
+ DBG_ASSERT( nPos < (USHORT)SVX_CASEMAP_END, "enum overflow!" );
+ return EE_RESSTR( RID_SVXITEMS_CASEMAP_BEGIN + nPos );
+}
+
+/*-----------------13.03.98 16:29-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxCaseMapItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/ ) const
+{
+ sal_Int16 nRet = style::CaseMap::NONE;
+ switch( GetValue() )
+ {
+// case SVX_CASEMAP_NOT_MAPPED : nRet = style::CaseMap::NONE ; break;
+ case SVX_CASEMAP_VERSALIEN : nRet = style::CaseMap::UPPERCASE; break;
+ case SVX_CASEMAP_GEMEINE : nRet = style::CaseMap::LOWERCASE; break;
+ case SVX_CASEMAP_TITEL : nRet = style::CaseMap::TITLE ; break;
+ case SVX_CASEMAP_KAPITAELCHEN: nRet = style::CaseMap::SMALLCAPS; break;
+ }
+ rVal <<= (sal_Int16)(nRet);
+ return sal_True;
+}
+/*-----------------13.03.98 16:29-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxCaseMapItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/ )
+{
+ sal_uInt16 nVal = sal_uInt16();
+ if(!(rVal >>= nVal))
+ return sal_False;
+
+ switch( nVal )
+ {
+ case style::CaseMap::NONE : nVal = SVX_CASEMAP_NOT_MAPPED ; break;
+ case style::CaseMap::UPPERCASE: nVal = SVX_CASEMAP_VERSALIEN ; break;
+ case style::CaseMap::LOWERCASE: nVal = SVX_CASEMAP_GEMEINE ; break;
+ case style::CaseMap::TITLE : nVal = SVX_CASEMAP_TITEL ; break;
+ case style::CaseMap::SMALLCAPS: nVal = SVX_CASEMAP_KAPITAELCHEN; break;
+ }
+ SetValue(nVal);
+ return sal_True;
+}
+
+// class SvxEscapementItem -----------------------------------------------
+
+SvxEscapementItem::SvxEscapementItem( const USHORT nId ) :
+ SfxEnumItemInterface( nId ),
+
+ nEsc ( 0 ),
+ nProp ( 100 )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvxEscapementItem::SvxEscapementItem( const SvxEscapement eEscape,
+ const USHORT nId ) :
+ SfxEnumItemInterface( nId ),
+ nProp( 100 )
+{
+ SetEscapement( eEscape );
+ if( nEsc )
+ nProp = 58;
+}
+
+// -----------------------------------------------------------------------
+
+SvxEscapementItem::SvxEscapementItem( const short _nEsc,
+ const BYTE _nProp,
+ const USHORT nId ) :
+ SfxEnumItemInterface( nId ),
+ nEsc ( _nEsc ),
+ nProp ( _nProp )
+{
+}
+
+// -----------------------------------------------------------------------
+
+int SvxEscapementItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ return( nEsc == ((SvxEscapementItem&)rAttr).nEsc &&
+ nProp == ((SvxEscapementItem&)rAttr).nProp );
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxEscapementItem::Clone( SfxItemPool * ) const
+{
+ return new SvxEscapementItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxEscapementItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ short _nEsc = GetEsc();
+ if( SOFFICE_FILEFORMAT_31 == rStrm.GetVersion() )
+ {
+ if( DFLT_ESC_AUTO_SUPER == _nEsc )
+ _nEsc = DFLT_ESC_SUPER;
+ else if( DFLT_ESC_AUTO_SUB == _nEsc )
+ _nEsc = DFLT_ESC_SUB;
+ }
+ rStrm << (BYTE) GetProp()
+ << (short) _nEsc;
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxEscapementItem::Create(SvStream& rStrm, USHORT) const
+{
+ BYTE _nProp;
+ short _nEsc;
+ rStrm >> _nProp >> _nEsc;
+ return new SvxEscapementItem( _nEsc, _nProp, Which() );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SvxEscapementItem::GetValueCount() const
+{
+ return SVX_ESCAPEMENT_END; // SVX_ESCAPEMENT_SUBSCRIPT + 1
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxEscapementItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ rText = GetValueTextByPos( GetEnumValue() );
+
+ if ( nEsc != 0 )
+ {
+ if( DFLT_ESC_AUTO_SUPER == nEsc || DFLT_ESC_AUTO_SUB == nEsc )
+ rText += String( EE_RESSTR(RID_SVXITEMS_ESCAPEMENT_AUTO) );
+ else
+ ( rText += String::CreateFromInt32( nEsc )) += sal_Unicode('%');
+ }
+ return ePres;
+ }
+ default: ; //prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SvxEscapementItem::GetValueTextByPos( USHORT nPos ) const
+{
+ DBG_ASSERT( nPos < (USHORT)SVX_ESCAPEMENT_END, "enum overflow!" );
+ return EE_RESSTR(RID_SVXITEMS_ESCAPEMENT_BEGIN + nPos);
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SvxEscapementItem::GetEnumValue() const
+{
+ if ( nEsc < 0 )
+ return SVX_ESCAPEMENT_SUBSCRIPT;
+ else if ( nEsc > 0 )
+ return SVX_ESCAPEMENT_SUPERSCRIPT;
+ return SVX_ESCAPEMENT_OFF;
+}
+
+// -----------------------------------------------------------------------
+
+void SvxEscapementItem::SetEnumValue( USHORT nVal )
+{
+ SetEscapement( (const SvxEscapement)nVal );
+}
+
+/*-----------------13.03.98 17:05-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxEscapementItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch(nMemberId)
+ {
+ case MID_ESC:
+ rVal <<= (sal_Int16)(nEsc);
+ break;
+ case MID_ESC_HEIGHT:
+ rVal <<= (sal_Int8)(nProp);
+ break;
+ case MID_AUTO_ESC:
+ rVal = Bool2Any(DFLT_ESC_AUTO_SUB == nEsc || DFLT_ESC_AUTO_SUPER == nEsc);
+ break;
+ }
+ return sal_True;
+}
+/*-----------------13.03.98 17:05-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxEscapementItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch(nMemberId)
+ {
+ case MID_ESC:
+ {
+ sal_Int16 nVal = sal_Int16();
+ if( (rVal >>= nVal) && (Abs(nVal) <= 101))
+ nEsc = nVal;
+ else
+ return sal_False;
+ }
+ break;
+ case MID_ESC_HEIGHT:
+ {
+ sal_Int8 nVal = sal_Int8();
+ if( (rVal >>= nVal) && (nVal <= 100))
+ nProp = nVal;
+ else
+ return sal_False;
+ }
+ break;
+ case MID_AUTO_ESC:
+ {
+ BOOL bVal = Any2Bool(rVal);
+ if(bVal)
+ {
+ if(nEsc < 0)
+ nEsc = DFLT_ESC_AUTO_SUB;
+ else
+ nEsc = DFLT_ESC_AUTO_SUPER;
+ }
+ else
+ if(DFLT_ESC_AUTO_SUPER == nEsc )
+ --nEsc;
+ else if(DFLT_ESC_AUTO_SUB == nEsc)
+ ++nEsc;
+ }
+ break;
+ }
+ return sal_True;
+}
+
+// class SvxLanguageItem -------------------------------------------------
+
+SvxLanguageItem::SvxLanguageItem( const LanguageType eLang, const USHORT nId )
+ : SfxEnumItem( nId , eLang )
+{
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SvxLanguageItem::GetValueCount() const
+{
+ // #i50205# got rid of class International
+ DBG_ERRORFILE("SvxLanguageItem::GetValueCount: supposed to return a count of what?");
+ // FIXME: previously returned LANGUAGE_COUNT from tools/intn.hxx which was wrong anyway.
+ // Could be SvtLanguageTable::GetEntryCount() (all locales with resource string)?
+ // Could be LocaleDataWrapper::getInstalledLanguageTypes() (all locales with locale data)?
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxLanguageItem::Clone( SfxItemPool * ) const
+{
+ return new SvxLanguageItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxLanguageItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ rStrm << (USHORT) GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxLanguageItem::Create(SvStream& rStrm, USHORT) const
+{
+ USHORT nValue;
+ rStrm >> nValue;
+ return new SvxLanguageItem( (LanguageType)nValue, Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxLanguageItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+#ifndef SVX_LIGHT
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ SvtLanguageTable aLangTable;
+ rText = aLangTable.GetString( (LanguageType)GetValue() );
+ return ePres;
+ }
+ default: ; //prevent warning
+ }
+#endif // !SVX_LIGHT
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+/*-----------------14.03.98 14:13-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxLanguageItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch(nMemberId)
+ {
+ case MID_LANG_INT: // for basic conversions!
+ rVal <<= (sal_Int16)(GetValue());
+ break;
+ case MID_LANG_LOCALE:
+ lang::Locale aRet( MsLangId::convertLanguageToLocale( GetValue(), false));
+ rVal <<= aRet;
+ break;
+ }
+ return sal_True;
+}
+/*-----------------14.03.98 14:13-------------------
+
+--------------------------------------------------*/
+sal_Bool SvxLanguageItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch(nMemberId)
+ {
+ case MID_LANG_INT: // for basic conversions!
+ {
+ sal_Int32 nValue = 0;
+ if(!(rVal >>= nValue))
+ return sal_False;
+
+ SetValue((sal_Int16)nValue);
+ }
+ break;
+ case MID_LANG_LOCALE:
+ {
+ lang::Locale aLocale;
+ if(!(rVal >>= aLocale))
+ return sal_False;
+
+ if (aLocale.Language.getLength() || aLocale.Country.getLength())
+ SetValue(MsLangId::convertLocaleToLanguage( aLocale ));
+ else
+ SetValue(LANGUAGE_NONE);
+ }
+ break;
+ }
+ return sal_True;
+}
+
+// class SvxNoLinebreakItem ----------------------------------------------
+SvxNoLinebreakItem::SvxNoLinebreakItem( const sal_Bool bBreak, const USHORT nId ) :
+ SfxBoolItem( nId, bBreak )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxNoLinebreakItem::Clone( SfxItemPool* ) const
+{
+ return new SvxNoLinebreakItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxNoLinebreakItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ rStrm << (sal_Bool)GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxNoLinebreakItem::Create(SvStream& rStrm, USHORT) const
+{
+ sal_Bool bValue;
+ rStrm >> bValue;
+ return new SvxNoLinebreakItem( bValue, Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxNoLinebreakItem::GetPresentation
+(
+ SfxItemPresentation /*ePres*/,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+ rText.Erase();
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// class SvxNoHyphenItem -------------------------------------------------
+
+SvxNoHyphenItem::SvxNoHyphenItem( const sal_Bool bHyphen, const USHORT nId ) :
+ SfxBoolItem( nId , bHyphen )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxNoHyphenItem::Clone( SfxItemPool* ) const
+{
+ return new SvxNoHyphenItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxNoHyphenItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ rStrm << (sal_Bool) GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxNoHyphenItem::Create( SvStream& rStrm, USHORT ) const
+{
+ sal_Bool bValue;
+ rStrm >> bValue;
+ return new SvxNoHyphenItem( bValue, Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxNoHyphenItem::GetPresentation
+(
+ SfxItemPresentation /*ePres*/,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+ rText.Erase();
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+/*
+ * Dummy-Item fuer ToolBox-Controls:
+ *
+ */
+
+// -----------------------------------------------------------------------
+// class SvxLineColorItem (== SvxColorItem)
+// -----------------------------------------------------------------------
+
+SvxLineColorItem::SvxLineColorItem( const USHORT nId ) :
+ SvxColorItem( nId )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvxLineColorItem::SvxLineColorItem( const Color& rCol, const USHORT nId ) :
+ SvxColorItem( rCol, nId )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvxLineColorItem::SvxLineColorItem( SvStream &rStrm, const USHORT nId ) :
+ SvxColorItem( rStrm, nId )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvxLineColorItem::SvxLineColorItem( const SvxLineColorItem &rCopy ) :
+ SvxColorItem( rCopy )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SvxLineColorItem::~SvxLineColorItem()
+{
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxLineColorItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit eCoreUnit,
+ SfxMapUnit ePresUnit,
+ XubString& rText,
+ const IntlWrapper * pIntlWrapper
+) const
+{
+ return SvxColorItem::GetPresentation( ePres, eCoreUnit, ePresUnit,
+ rText, pIntlWrapper );
+}
+
+// class SvxBlinkItem -------------------------------------------------
+
+
+SvxBlinkItem::SvxBlinkItem( const sal_Bool bBlink, const USHORT nId ) :
+ SfxBoolItem( nId, bBlink )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxBlinkItem::Clone( SfxItemPool * ) const
+{
+ return new SvxBlinkItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxBlinkItem::Store( SvStream& rStrm , USHORT /*nItemVersion*/ ) const
+{
+ rStrm << (BYTE) GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxBlinkItem::Create(SvStream& rStrm, USHORT) const
+{
+ BYTE nState;
+ rStrm >> nState;
+ return new SvxBlinkItem( nState, Which() );
+}
+
+// -----------------------------------------------------------------------
+
+SfxItemPresentation SvxBlinkItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ USHORT nId = RID_SVXITEMS_BLINK_FALSE;
+
+ if ( GetValue() )
+ nId = RID_SVXITEMS_BLINK_TRUE;
+ rText = EE_RESSTR(nId);
+ return ePres;
+ }
+ default: ; //prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// class SvxEmphaisMarkItem ---------------------------------------------------
+
+SvxEmphasisMarkItem::SvxEmphasisMarkItem( const FontEmphasisMark nValue,
+ const USHORT nId )
+ : SfxUInt16Item( nId, nValue )
+{
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxEmphasisMarkItem::Clone( SfxItemPool * ) const
+{
+ return new SvxEmphasisMarkItem( *this );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvxEmphasisMarkItem::Store( SvStream& rStrm,
+ USHORT /*nItemVersion*/ ) const
+{
+ rStrm << (sal_uInt16)GetValue();
+ return rStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SvxEmphasisMarkItem::Create( SvStream& rStrm, USHORT ) const
+{
+ sal_uInt16 nValue;
+ rStrm >> nValue;
+ return new SvxEmphasisMarkItem( (FontEmphasisMark)nValue, Which() );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SvxEmphasisMarkItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText,
+ const IntlWrapper * /*pIntl*/
+) const
+{
+ switch ( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ return ePres;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ sal_uInt16 nVal = GetValue();
+ rText = EE_RESSTR( RID_SVXITEMS_EMPHASIS_BEGIN_STYLE +
+ ( EMPHASISMARK_STYLE & nVal ));
+ USHORT nId = ( EMPHASISMARK_POS_ABOVE & nVal )
+ ? RID_SVXITEMS_EMPHASIS_ABOVE_POS
+ : ( EMPHASISMARK_POS_BELOW & nVal )
+ ? RID_SVXITEMS_EMPHASIS_BELOW_POS
+ : 0;
+ if( nId )
+ rText += EE_RESSTR( nId );
+ return ePres;
+ }
+ default: ; //prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvxEmphasisMarkItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ switch( nMemberId )
+ {
+ case MID_EMPHASIS:
+ {
+ sal_Int16 nValue = GetValue();
+ sal_Int16 nRet = 0;
+ switch(nValue & EMPHASISMARK_STYLE)
+ {
+ case EMPHASISMARK_NONE : nRet = FontEmphasis::NONE; break;
+ case EMPHASISMARK_DOT : nRet = FontEmphasis::DOT_ABOVE; break;
+ case EMPHASISMARK_CIRCLE : nRet = FontEmphasis::CIRCLE_ABOVE; break;
+ case EMPHASISMARK_DISC : nRet = FontEmphasis::DISK_ABOVE; break;
+ case EMPHASISMARK_ACCENT : nRet = FontEmphasis::ACCENT_ABOVE; break;
+ }
+ if(nRet && nValue & EMPHASISMARK_POS_BELOW)
+ nRet += 10;
+ rVal <<= nRet;
+ }
+ break;
+ }
+ return sal_True;
+}
+
+sal_Bool SvxEmphasisMarkItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ sal_Bool bRet = sal_True;
+ switch( nMemberId )
+ {
+ case MID_EMPHASIS:
+ {
+ sal_Int32 nValue = -1;
+ rVal >>= nValue;
+ switch(nValue)
+ {
+ case FontEmphasis::NONE : nValue = EMPHASISMARK_NONE; break;
+ case FontEmphasis::DOT_ABOVE : nValue = EMPHASISMARK_DOT|EMPHASISMARK_POS_ABOVE; break;
+ case FontEmphasis::CIRCLE_ABOVE: nValue = EMPHASISMARK_CIRCLE|EMPHASISMARK_POS_ABOVE; break;
+ case FontEmphasis::DISK_ABOVE : nValue = EMPHASISMARK_DISC|EMPHASISMARK_POS_ABOVE; break;
+ case FontEmphasis::ACCENT_ABOVE: nValue = EMPHASISMARK_ACCENT|EMPHASISMARK_POS_ABOVE; break;
+ case FontEmphasis::DOT_BELOW : nValue = EMPHASISMARK_DOT|EMPHASISMARK_POS_BELOW; break;
+ case FontEmphasis::CIRCLE_BELOW: nValue = EMPHASISMARK_CIRCLE|EMPHASISMARK_POS_BELOW; break;
+ case FontEmphasis::DISK_BELOW : nValue = EMPHASISMARK_DISC|EMPHASISMARK_POS_BELOW; break;
+ case FontEmphasis::ACCENT_BELOW: nValue = EMPHASISMARK_ACCENT|EMPHASISMARK_POS_BELOW; break;
+ default: return sal_False;
+ }
+ SetValue( (sal_Int16)nValue );
+ }
+ break;
+ }
+ return bRet;
+}
+
+USHORT SvxEmphasisMarkItem::GetVersion( USHORT nFFVer ) const
+{
+ DBG_ASSERT( SOFFICE_FILEFORMAT_31==nFFVer ||
+ SOFFICE_FILEFORMAT_40==nFFVer ||
+ SOFFICE_FILEFORMAT_50==nFFVer,
+ "SvxEmphasisMarkItem: Gibt es ein neues Fileformat?" );
+
+ return SOFFICE_FILEFORMAT_50 > nFFVer ? USHRT_MAX : 0;
+}
+
+
+/*************************************************************************
+|* class SvxTwoLinesItem
+*************************************************************************/
+
+SvxTwoLinesItem::SvxTwoLinesItem( sal_Bool bFlag, sal_Unicode nStartBracket,
+ sal_Unicode nEndBracket, sal_uInt16 nW )
+ : SfxPoolItem( nW ),
+ cStartBracket( nStartBracket ), cEndBracket( nEndBracket ), bOn( bFlag )
+{
+}
+
+SvxTwoLinesItem::SvxTwoLinesItem( const SvxTwoLinesItem& rAttr )
+ : SfxPoolItem( rAttr.Which() ),
+ cStartBracket( rAttr.cStartBracket ),
+ cEndBracket( rAttr.cEndBracket ),
+ bOn( rAttr.bOn )
+{
+}
+
+SvxTwoLinesItem::~SvxTwoLinesItem()
+{
+}
+
+int SvxTwoLinesItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rAttr ), "not equal attribute types" );
+ return bOn == ((SvxTwoLinesItem&)rAttr).bOn &&
+ cStartBracket == ((SvxTwoLinesItem&)rAttr).cStartBracket &&
+ cEndBracket == ((SvxTwoLinesItem&)rAttr).cEndBracket;
+}
+
+SfxPoolItem* SvxTwoLinesItem::Clone( SfxItemPool* ) const
+{
+ return new SvxTwoLinesItem( *this );
+}
+
+sal_Bool SvxTwoLinesItem::QueryValue( com::sun::star::uno::Any& rVal,
+ BYTE nMemberId ) const
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ sal_Bool bRet = sal_True;
+ switch( nMemberId )
+ {
+ case MID_TWOLINES:
+ rVal = Bool2Any( bOn );
+ break;
+ case MID_START_BRACKET:
+ {
+ OUString s;
+ if( cStartBracket )
+ s = OUString( cStartBracket );
+ rVal <<= s;
+ }
+ break;
+ case MID_END_BRACKET:
+ {
+ OUString s;
+ if( cEndBracket )
+ s = OUString( cEndBracket );
+ rVal <<= s;
+ }
+ break;
+ default:
+ bRet = sal_False;
+ break;
+ }
+ return bRet;
+}
+
+sal_Bool SvxTwoLinesItem::PutValue( const com::sun::star::uno::Any& rVal,
+ BYTE nMemberId )
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ sal_Bool bRet = sal_False;
+ OUString s;
+ switch( nMemberId )
+ {
+ case MID_TWOLINES:
+ bOn = Any2Bool( rVal );
+ bRet = sal_True;
+ break;
+ case MID_START_BRACKET:
+ if( rVal >>= s )
+ {
+ cStartBracket = s.getLength() ? s[ 0 ] : 0;
+ bRet = sal_True;
+ }
+ break;
+ case MID_END_BRACKET:
+ if( rVal >>= s )
+ {
+ cEndBracket = s.getLength() ? s[ 0 ] : 0;
+ bRet = sal_True;
+ }
+ break;
+ }
+ return bRet;
+}
+
+SfxItemPresentation SvxTwoLinesItem::GetPresentation( SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/,
+ String &rText, const IntlWrapper* /*pIntl*/ ) const
+{
+ switch( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ break;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ if( !GetValue() )
+ rText = EE_RESSTR( RID_SVXITEMS_TWOLINES_OFF );
+ else
+ {
+ rText = EE_RESSTR( RID_SVXITEMS_TWOLINES );
+ if( GetStartBracket() )
+ rText.Insert( GetStartBracket(), 0 );
+ if( GetEndBracket() )
+ rText += GetEndBracket();
+ }
+ return ePres;
+ }
+ default: ; //prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+
+SfxPoolItem* SvxTwoLinesItem::Create( SvStream & rStrm, USHORT /*nVer*/) const
+{
+ sal_Bool _bOn;
+ sal_Unicode cStart, cEnd;
+ rStrm >> _bOn >> cStart >> cEnd;
+ return new SvxTwoLinesItem( _bOn, cStart, cEnd, Which() );
+}
+
+SvStream& SvxTwoLinesItem::Store(SvStream & rStrm, USHORT /*nIVer*/) const
+{
+ rStrm << GetValue() << GetStartBracket() << GetEndBracket();
+ return rStrm;
+}
+
+USHORT SvxTwoLinesItem::GetVersion( USHORT nFFVer ) const
+{
+ DBG_ASSERT( SOFFICE_FILEFORMAT_31==nFFVer ||
+ SOFFICE_FILEFORMAT_40==nFFVer ||
+ SOFFICE_FILEFORMAT_50==nFFVer,
+ "SvxTwoLinesItem: Gibt es ein neues Fileformat?" );
+
+ return SOFFICE_FILEFORMAT_50 > nFFVer ? USHRT_MAX : 0;
+}
+
+
+/*************************************************************************
+|* class SvxCharRotateItem
+*************************************************************************/
+
+SvxCharRotateItem::SvxCharRotateItem( sal_uInt16 nValue,
+ sal_Bool bFitIntoLine,
+ const sal_uInt16 nW )
+ : SfxUInt16Item( nW, nValue ), bFitToLine( bFitIntoLine )
+{
+}
+
+SfxPoolItem* SvxCharRotateItem::Clone( SfxItemPool* ) const
+{
+ return new SvxCharRotateItem( GetValue(), IsFitToLine(), Which() );
+}
+
+SfxPoolItem* SvxCharRotateItem::Create( SvStream& rStrm, USHORT ) const
+{
+ sal_uInt16 nVal;
+ sal_Bool b;
+ rStrm >> nVal >> b;
+ return new SvxCharRotateItem( nVal, b, Which() );
+}
+
+SvStream& SvxCharRotateItem::Store( SvStream & rStrm, USHORT ) const
+{
+ sal_Bool bFlag = IsFitToLine();
+ rStrm << GetValue() << bFlag;
+ return rStrm;
+}
+
+USHORT SvxCharRotateItem::GetVersion( USHORT nFFVer ) const
+{
+ return SOFFICE_FILEFORMAT_50 > nFFVer ? USHRT_MAX : 0;
+}
+
+SfxItemPresentation SvxCharRotateItem::GetPresentation(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/,
+ String &rText, const IntlWrapper* ) const
+{
+ switch( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ break;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ if( !GetValue() )
+ rText = EE_RESSTR( RID_SVXITEMS_CHARROTATE_OFF );
+ else
+ {
+ rText = EE_RESSTR( RID_SVXITEMS_CHARROTATE );
+ rText.SearchAndReplaceAscii( "$(ARG1)",
+ String::CreateFromInt32( GetValue() / 10 ));
+ if( IsFitToLine() )
+ rText += EE_RESSTR( RID_SVXITEMS_CHARROTATE_FITLINE );
+ }
+ return ePres;
+ }
+ default: ; //prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+sal_Bool SvxCharRotateItem::QueryValue( com::sun::star::uno::Any& rVal,
+ BYTE nMemberId ) const
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ sal_Bool bRet = sal_True;
+ switch( nMemberId )
+ {
+ case MID_ROTATE:
+ rVal <<= (sal_Int16)GetValue();
+ break;
+ case MID_FITTOLINE:
+ rVal = Bool2Any( IsFitToLine() );
+ break;
+ default:
+ bRet = sal_False;
+ break;
+ }
+ return bRet;
+}
+
+sal_Bool SvxCharRotateItem::PutValue( const com::sun::star::uno::Any& rVal,
+ BYTE nMemberId )
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ sal_Bool bRet = sal_True;
+ switch( nMemberId )
+ {
+ case MID_ROTATE:
+ {
+ sal_Int16 nVal = 0;
+ if((rVal >>= nVal) && (0 == nVal || 900 == nVal || 2700 == nVal))
+ SetValue( (USHORT)nVal );
+ else
+ bRet = sal_False;
+ break;
+ }
+
+ case MID_FITTOLINE:
+ SetFitToLine( Any2Bool( rVal ) );
+ break;
+ default:
+ bRet = sal_False;
+ }
+ return bRet;
+}
+
+int SvxCharRotateItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" );
+ return SfxUInt16Item::operator==( rItem ) &&
+ IsFitToLine() == ((const SvxCharRotateItem&)rItem).IsFitToLine();
+}
+
+
+/*************************************************************************
+|* class SvxCharScaleItem
+*************************************************************************/
+
+SvxCharScaleWidthItem::SvxCharScaleWidthItem( sal_uInt16 nValue,
+ const sal_uInt16 nW )
+ : SfxUInt16Item( nW, nValue )
+{
+}
+
+SfxPoolItem* SvxCharScaleWidthItem::Clone( SfxItemPool* ) const
+{
+ return new SvxCharScaleWidthItem( GetValue(), Which() );
+}
+
+SfxPoolItem* SvxCharScaleWidthItem::Create( SvStream& rStrm, USHORT ) const
+{
+ sal_uInt16 nVal;
+ rStrm >> nVal;
+ SvxCharScaleWidthItem* pItem = new SvxCharScaleWidthItem( nVal, Which() );
+
+ if ( Which() == EE_CHAR_FONTWIDTH )
+ {
+ // #87271#: Was a SvxFontWidthItem in 5.2
+ // USHORT nFixWidth, USHORT nPropWidth.
+ // nFixWidth has never been used...
+ rStrm >> nVal;
+ USHORT nTest;
+ rStrm >> nTest;
+ if ( nTest == 0x1234 )
+ pItem->SetValue( nVal );
+ else
+ rStrm.SeekRel( -2*(long)sizeof(sal_uInt16) );
+ }
+
+ return pItem;
+}
+
+SvStream& SvxCharScaleWidthItem::Store( SvStream& rStream, USHORT nVer ) const
+{
+ SvStream& rRet = SfxUInt16Item::Store( rStream, nVer );
+ if ( Which() == EE_CHAR_FONTWIDTH )
+ {
+ // see comment in Create()....
+ rRet.SeekRel( -1*(long)sizeof(USHORT) );
+ rRet << (USHORT)0;
+ rRet << GetValue();
+ // Really ugly, but not a problem for reading the doc in 5.2
+ rRet << (USHORT)0x1234;
+ }
+ return rRet;
+}
+
+
+USHORT SvxCharScaleWidthItem::GetVersion( USHORT nFFVer ) const
+{
+ return SOFFICE_FILEFORMAT_50 > nFFVer ? USHRT_MAX : 0;
+}
+
+SfxItemPresentation SvxCharScaleWidthItem::GetPresentation(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/,
+ String &rText, const IntlWrapper* ) const
+{
+ switch( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ break;
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ {
+ if( !GetValue() )
+ rText = EE_RESSTR( RID_SVXITEMS_CHARSCALE_OFF );
+ else
+ {
+ rText = EE_RESSTR( RID_SVXITEMS_CHARSCALE );
+ rText.SearchAndReplaceAscii( "$(ARG1)",
+ String::CreateFromInt32( GetValue() ));
+ }
+ return ePres;
+ }
+ default: ; //prevent warning
+ }
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+sal_Bool SvxCharScaleWidthItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/ )
+{
+ // SfxUInt16Item::QueryValue returns sal_Int32 in Any now... (srx642w)
+ // where we still want this to be a sal_Int16
+ sal_Int16 nValue = sal_Int16();
+ if (rVal >>= nValue)
+ {
+ SetValue( (UINT16) nValue );
+ return TRUE;
+ }
+
+ DBG_ERROR( "SvxCharScaleWidthItem::PutValue - Wrong type!" );
+ return FALSE;
+}
+
+sal_Bool SvxCharScaleWidthItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/ ) const
+{
+ // SfxUInt16Item::QueryValue returns sal_Int32 in Any now... (srx642w)
+ // where we still want this to be a sal_Int16
+ rVal <<= (sal_Int16)GetValue();
+ return TRUE;
+}
+
+/*************************************************************************
+|* class SvxCharReliefItem
+*************************************************************************/
+
+SvxCharReliefItem::SvxCharReliefItem( FontRelief eValue,
+ const sal_uInt16 nId )
+ : SfxEnumItem( nId, (USHORT)eValue )
+{
+}
+
+SfxPoolItem* SvxCharReliefItem::Clone( SfxItemPool * ) const
+{
+ return new SvxCharReliefItem( *this );
+}
+
+SfxPoolItem* SvxCharReliefItem::Create(SvStream & rStrm, USHORT) const
+{
+ sal_uInt16 nVal;
+ rStrm >> nVal;
+ return new SvxCharReliefItem( (FontRelief)nVal, Which() );
+}
+
+SvStream& SvxCharReliefItem::Store(SvStream & rStrm, USHORT /*nIVer*/) const
+{
+ sal_uInt16 nVal = GetValue();
+ rStrm << nVal;
+ return rStrm;
+}
+
+USHORT SvxCharReliefItem::GetVersion( USHORT nFFVer ) const
+{
+ return SOFFICE_FILEFORMAT_50 > nFFVer ? USHRT_MAX : 0;
+}
+
+String SvxCharReliefItem::GetValueTextByPos( USHORT nPos ) const
+{
+ DBG_ASSERT( RID_SVXITEMS_RELIEF_ENGRAVED - RID_SVXITEMS_RELIEF_NONE,
+ "enum overflow" );
+ return String( EditResId( RID_SVXITEMS_RELIEF_BEGIN + nPos ));
+}
+
+USHORT SvxCharReliefItem::GetValueCount() const
+{
+ return RID_SVXITEMS_RELIEF_ENGRAVED - RID_SVXITEMS_RELIEF_NONE;
+}
+
+SfxItemPresentation SvxCharReliefItem::GetPresentation
+(
+ SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText, const IntlWrapper * /*pIntl*/
+) const
+{
+ SfxItemPresentation eRet = ePres;
+ switch( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ break;
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = GetValueTextByPos( GetValue() );
+ break;
+
+ default:
+ eRet = SFX_ITEM_PRESENTATION_NONE;
+ }
+ return eRet;
+}
+
+sal_Bool SvxCharReliefItem::PutValue( const com::sun::star::uno::Any& rVal,
+ BYTE nMemberId )
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ sal_Bool bRet = sal_True;
+ switch( nMemberId )
+ {
+ case MID_RELIEF:
+ {
+ sal_Int16 nVal = -1;
+ rVal >>= nVal;
+ if(nVal >= 0 && nVal <= RELIEF_ENGRAVED)
+ SetValue( (USHORT)nVal );
+ else
+ bRet = sal_False;
+ }
+ break;
+ default:
+ bRet = sal_False;
+ break;
+ }
+ return bRet;
+}
+
+sal_Bool SvxCharReliefItem::QueryValue( com::sun::star::uno::Any& rVal,
+ BYTE nMemberId ) const
+{
+// sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ sal_Bool bRet = sal_True;
+ switch( nMemberId )
+ {
+ case MID_RELIEF:
+ rVal <<= (sal_Int16)GetValue();
+ break;
+ default:
+ bRet = sal_False;
+ break;
+ }
+ return bRet;
+}
+
+/*************************************************************************
+|* class SvxScriptTypeItemItem
+*************************************************************************/
+
+SvxScriptTypeItem::SvxScriptTypeItem( sal_uInt16 nType )
+ : SfxUInt16Item( SID_ATTR_CHAR_SCRIPTTYPE, nType )
+{
+}
+SfxPoolItem* SvxScriptTypeItem::Clone( SfxItemPool * ) const
+{
+ return new SvxScriptTypeItem( GetValue() );
+}
+
+/*************************************************************************
+|* class SvxScriptSetItem
+*************************************************************************/
+
+SvxScriptSetItem::SvxScriptSetItem( USHORT nSlotId, SfxItemPool& rPool )
+ : SfxSetItem( nSlotId, new SfxItemSet( rPool,
+ SID_ATTR_CHAR_FONT, SID_ATTR_CHAR_FONT ))
+{
+ USHORT nLatin, nAsian, nComplex;
+ GetWhichIds( nLatin, nAsian, nComplex );
+
+ USHORT aIds[ 9 ] = { 0 };
+ aIds[ 0 ] = aIds[ 1 ] = nLatin;
+ aIds[ 2 ] = aIds[ 3 ] = nAsian;
+ aIds[ 4 ] = aIds[ 5 ] = nComplex;
+ aIds[ 6 ] = aIds[ 7 ] = SID_ATTR_CHAR_SCRIPTTYPE;
+ aIds[ 8 ] = 0;
+
+ GetItemSet().SetRanges( aIds );
+}
+
+SfxPoolItem* SvxScriptSetItem::Clone( SfxItemPool * ) const
+{
+ SvxScriptSetItem* p = new SvxScriptSetItem( Which(), *GetItemSet().GetPool() );
+ p->GetItemSet().Put( GetItemSet(), FALSE );
+ return p;
+}
+
+SfxPoolItem* SvxScriptSetItem::Create( SvStream &, USHORT ) const
+{
+ return 0;
+}
+
+const SfxPoolItem* SvxScriptSetItem::GetItemOfScriptSet(
+ const SfxItemSet& rSet, USHORT nId )
+{
+ const SfxPoolItem* pI;
+ SfxItemState eSt = rSet.GetItemState( nId, FALSE, &pI );
+ if( SFX_ITEM_SET != eSt )
+ pI = SFX_ITEM_DEFAULT == eSt ? &rSet.Get( nId ) : 0;
+ return pI;
+}
+
+const SfxPoolItem* SvxScriptSetItem::GetItemOfScript( USHORT nSlotId, const SfxItemSet& rSet, USHORT nScript )
+{
+ USHORT nLatin, nAsian, nComplex;
+ GetWhichIds( nSlotId, rSet, nLatin, nAsian, nComplex );
+
+ const SfxPoolItem *pRet, *pAsn, *pCmplx;
+ switch( nScript )
+ {
+ default: //no one valid -> match to latin
+ // case SCRIPTTYPE_LATIN:
+ pRet = GetItemOfScriptSet( rSet, nLatin );
+ break;
+ case SCRIPTTYPE_ASIAN:
+ pRet = GetItemOfScriptSet( rSet, nAsian );
+ break;
+ case SCRIPTTYPE_COMPLEX:
+ pRet = GetItemOfScriptSet( rSet, nComplex );
+ break;
+
+ case SCRIPTTYPE_LATIN|SCRIPTTYPE_ASIAN:
+ if( 0 == (pRet = GetItemOfScriptSet( rSet, nLatin )) ||
+ 0 == (pAsn = GetItemOfScriptSet( rSet, nAsian )) ||
+ *pRet != *pAsn )
+ pRet = 0;
+ break;
+
+ case SCRIPTTYPE_LATIN|SCRIPTTYPE_COMPLEX:
+ if( 0 == (pRet = GetItemOfScriptSet( rSet, nLatin )) ||
+ 0 == (pCmplx = GetItemOfScriptSet( rSet, nComplex )) ||
+ *pRet != *pCmplx )
+ pRet = 0;
+ break;
+
+ case SCRIPTTYPE_ASIAN|SCRIPTTYPE_COMPLEX:
+ if( 0 == (pRet = GetItemOfScriptSet( rSet, nAsian )) ||
+ 0 == (pCmplx = GetItemOfScriptSet( rSet, nComplex )) ||
+ *pRet != *pCmplx )
+ pRet = 0;
+ break;
+
+ case SCRIPTTYPE_LATIN|SCRIPTTYPE_ASIAN|SCRIPTTYPE_COMPLEX:
+ if( 0 == (pRet = GetItemOfScriptSet( rSet, nLatin )) ||
+ 0 == (pAsn = GetItemOfScriptSet( rSet, nAsian )) ||
+ 0 == (pCmplx = GetItemOfScriptSet( rSet, nComplex )) ||
+ *pRet != *pAsn || *pRet != *pCmplx )
+ pRet = 0;
+ break;
+ }
+ return pRet;
+}
+
+const SfxPoolItem* SvxScriptSetItem::GetItemOfScript( USHORT nScript ) const
+{
+ return GetItemOfScript( Which(), GetItemSet(), nScript );
+}
+
+void SvxScriptSetItem::PutItemForScriptType( USHORT nScriptType,
+ const SfxPoolItem& rItem )
+{
+ USHORT nLatin, nAsian, nComplex;
+ GetWhichIds( nLatin, nAsian, nComplex );
+
+ SfxPoolItem* pCpy = rItem.Clone();
+ if( SCRIPTTYPE_LATIN & nScriptType )
+ {
+ pCpy->SetWhich( nLatin );
+ GetItemSet().Put( *pCpy );
+ }
+ if( SCRIPTTYPE_ASIAN & nScriptType )
+ {
+ pCpy->SetWhich( nAsian );
+ GetItemSet().Put( *pCpy );
+ }
+ if( SCRIPTTYPE_COMPLEX & nScriptType )
+ {
+ pCpy->SetWhich( nComplex );
+ GetItemSet().Put( *pCpy );
+ }
+ delete pCpy;
+}
+
+void SvxScriptSetItem::GetWhichIds( USHORT nSlotId, const SfxItemSet& rSet, USHORT& rLatin, USHORT& rAsian, USHORT& rComplex )
+{
+ const SfxItemPool& rPool = *rSet.GetPool();
+ GetSlotIds( nSlotId, rLatin, rAsian, rComplex );
+ rLatin = rPool.GetWhich( rLatin );
+ rAsian = rPool.GetWhich( rAsian );
+ rComplex = rPool.GetWhich( rComplex );
+}
+
+void SvxScriptSetItem::GetWhichIds( USHORT& rLatin, USHORT& rAsian,
+ USHORT& rComplex ) const
+{
+ GetWhichIds( Which(), GetItemSet(), rLatin, rAsian, rComplex );
+}
+
+void SvxScriptSetItem::GetSlotIds( USHORT nSlotId, USHORT& rLatin,
+ USHORT& rAsian, USHORT& rComplex )
+{
+ switch( nSlotId )
+ {
+ default:
+ DBG_ASSERT( FALSE, "wrong SlotId for class SvxScriptSetItem" );
+ // no break - default to font - Id Range !!
+
+ case SID_ATTR_CHAR_FONT:
+ rLatin = SID_ATTR_CHAR_FONT;
+ rAsian = SID_ATTR_CHAR_CJK_FONT;
+ rComplex = SID_ATTR_CHAR_CTL_FONT;
+ break;
+ case SID_ATTR_CHAR_FONTHEIGHT:
+ rLatin = SID_ATTR_CHAR_FONTHEIGHT;
+ rAsian = SID_ATTR_CHAR_CJK_FONTHEIGHT;
+ rComplex = SID_ATTR_CHAR_CTL_FONTHEIGHT;
+ break;
+ case SID_ATTR_CHAR_WEIGHT:
+ rLatin = SID_ATTR_CHAR_WEIGHT;
+ rAsian = SID_ATTR_CHAR_CJK_WEIGHT;
+ rComplex = SID_ATTR_CHAR_CTL_WEIGHT;
+ break;
+ case SID_ATTR_CHAR_POSTURE:
+ rLatin = SID_ATTR_CHAR_POSTURE;
+ rAsian = SID_ATTR_CHAR_CJK_POSTURE;
+ rComplex = SID_ATTR_CHAR_CTL_POSTURE;
+ break;
+ case SID_ATTR_CHAR_LANGUAGE:
+ rLatin = SID_ATTR_CHAR_LANGUAGE;
+ rAsian = SID_ATTR_CHAR_CJK_LANGUAGE;
+ rComplex = SID_ATTR_CHAR_CTL_LANGUAGE;
+ break;
+ }
+}
+
+void GetDefaultFonts( SvxFontItem& rLatin, SvxFontItem& rAsian, SvxFontItem& rComplex )
+{
+ const USHORT nItemCnt = 3;
+
+ static struct
+ {
+ USHORT nFontType;
+ USHORT nLanguage;
+ }
+ aOutTypeArr[ nItemCnt ] =
+ {
+ { DEFAULTFONT_LATIN_TEXT, LANGUAGE_ENGLISH_US },
+ { DEFAULTFONT_CJK_TEXT, LANGUAGE_ENGLISH_US },
+ { DEFAULTFONT_CTL_TEXT, LANGUAGE_ARABIC_SAUDI_ARABIA }
+ };
+
+ SvxFontItem* aItemArr[ nItemCnt ] = { &rLatin, &rAsian, &rComplex };
+
+ for ( USHORT n = 0; n < nItemCnt; ++n )
+ {
+ Font aFont( OutputDevice::GetDefaultFont( aOutTypeArr[ n ].nFontType,
+ aOutTypeArr[ n ].nLanguage,
+ DEFAULTFONT_FLAGS_ONLYONE, 0 ) );
+ SvxFontItem* pItem = aItemArr[ n ];
+ pItem->GetFamily() = aFont.GetFamily();
+ pItem->GetFamilyName() = aFont.GetName();
+ pItem->GetStyleName().Erase();
+ pItem->GetPitch() = aFont.GetPitch();
+ pItem->GetCharSet() = aFont.GetCharSet();
+ }
+}
+
+
+USHORT GetI18NScriptTypeOfLanguage( USHORT nLang )
+{
+ return GetI18NScriptType( SvtLanguageOptions::GetScriptTypeOfLanguage( nLang ) );
+}
+
+USHORT GetItemScriptType( short nI18NType )
+{
+ switch ( nI18NType )
+ {
+ case i18n::ScriptType::LATIN: return SCRIPTTYPE_LATIN;
+ case i18n::ScriptType::ASIAN: return SCRIPTTYPE_ASIAN;
+ case i18n::ScriptType::COMPLEX: return SCRIPTTYPE_COMPLEX;
+ }
+ return 0;
+}
+
+short GetI18NScriptType( USHORT nItemType )
+{
+ switch ( nItemType )
+ {
+ case SCRIPTTYPE_LATIN: return i18n::ScriptType::LATIN;
+ case SCRIPTTYPE_ASIAN: return i18n::ScriptType::ASIAN;
+ case SCRIPTTYPE_COMPLEX: return i18n::ScriptType::COMPLEX;
+ }
+ return 0;
+}
diff --git a/editeng/source/items/writingmodeitem.cxx b/editeng/source/items/writingmodeitem.cxx
new file mode 100644
index 0000000000..2abf14d8d8
--- /dev/null
+++ b/editeng/source/items/writingmodeitem.cxx
@@ -0,0 +1,156 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: writingmodeitem.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+// include ---------------------------------------------------------------
+
+
+#include <editeng/writingmodeitem.hxx>
+#include <editeng/eerdll.hxx>
+#include <editeng/editrids.hrc>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+
+// class SvxWritingModeItem -------------------------------------------------
+
+TYPEINIT1_FACTORY(SvxWritingModeItem, SfxUInt16Item, new SvxWritingModeItem(com::sun::star::text::WritingMode_LR_TB, 0));
+
+SvxWritingModeItem::SvxWritingModeItem( WritingMode eValue, USHORT _nWhich )
+ : SfxUInt16Item( _nWhich, (sal_uInt16)eValue )
+{
+}
+
+SvxWritingModeItem::~SvxWritingModeItem()
+{
+}
+
+int SvxWritingModeItem::operator==( const SfxPoolItem& rCmp ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rCmp), "unequal types" );
+
+ return GetValue() == ((SvxWritingModeItem&)rCmp).GetValue();
+}
+
+SfxPoolItem* SvxWritingModeItem::Clone( SfxItemPool * ) const
+{
+ return new SvxWritingModeItem( *this );
+}
+
+SfxPoolItem* SvxWritingModeItem::Create( SvStream & , USHORT ) const
+{
+ DBG_ERROR("SvxWritingModeItem should not be streamed!");
+ return NULL;
+}
+
+SvStream& SvxWritingModeItem::Store( SvStream & rStrm, USHORT ) const
+{
+ DBG_ERROR("SvxWritingModeItem should not be streamed!");
+ return rStrm;
+}
+
+USHORT SvxWritingModeItem::GetVersion( USHORT /*nFVer*/ ) const
+{
+ return USHRT_MAX;
+}
+
+SfxItemPresentation SvxWritingModeItem::GetPresentation( SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/,
+ SfxMapUnit /*ePresMetric*/,
+ String &rText,
+ const IntlWrapper * ) const
+{
+ SfxItemPresentation eRet = ePres;
+ switch( ePres )
+ {
+ case SFX_ITEM_PRESENTATION_NONE:
+ rText.Erase();
+ break;
+
+ case SFX_ITEM_PRESENTATION_NAMELESS:
+ case SFX_ITEM_PRESENTATION_COMPLETE:
+ rText = String( EditResId( RID_SVXITEMS_FRMDIR_BEGIN + GetValue() ) );
+ break;
+
+ default:
+ eRet = SFX_ITEM_PRESENTATION_NONE;
+ }
+ return eRet;
+}
+
+sal_Bool SvxWritingModeItem::PutValue( const com::sun::star::uno::Any& rVal, BYTE )
+{
+ sal_Int32 nVal = 0;
+ sal_Bool bRet = ( rVal >>= nVal );
+
+ if( !bRet )
+ {
+ WritingMode eMode;
+ bRet = rVal >>= eMode;
+
+ if( bRet )
+ {
+ nVal = (sal_Int32)eMode;
+ }
+ }
+
+ if( bRet )
+ {
+ switch( nVal )
+ {
+ case WritingMode_LR_TB:
+ case WritingMode_RL_TB:
+ case WritingMode_TB_RL:
+ SetValue( (sal_uInt16)nVal );
+ bRet = true;
+ break;
+ default:
+ bRet = false;
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+sal_Bool SvxWritingModeItem::QueryValue( com::sun::star::uno::Any& rVal,
+ BYTE ) const
+{
+ rVal <<= (WritingMode)GetValue();
+ return true;
+}
+
+SvxWritingModeItem& SvxWritingModeItem::operator=( const SvxWritingModeItem& rItem )
+{
+ SetValue( rItem.GetValue() );
+ return *this;
+}
diff --git a/editeng/source/items/xmlcnitm.cxx b/editeng/source/items/xmlcnitm.cxx
new file mode 100644
index 0000000000..0de29159c7
--- /dev/null
+++ b/editeng/source/items/xmlcnitm.cxx
@@ -0,0 +1,251 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: xmlcnitm.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <com/sun/star/xml/AttributeData.hpp>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <xmloff/xmlcnimp.hxx>
+#include <xmloff/unoatrcn.hxx>
+#include <editeng/xmlcnitm.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::xml;
+
+// ------------------------------------------------------------------------
+
+TYPEINIT1(SvXMLAttrContainerItem, SfxPoolItem);
+
+SvXMLAttrContainerItem::SvXMLAttrContainerItem( USHORT _nWhich ) :
+ SfxPoolItem( _nWhich )
+{
+ pImpl = new SvXMLAttrContainerData;
+}
+
+SvXMLAttrContainerItem::SvXMLAttrContainerItem(
+ const SvXMLAttrContainerItem& rItem ) :
+ SfxPoolItem( rItem )
+{
+ pImpl = new SvXMLAttrContainerData( *rItem.pImpl );
+}
+
+SvXMLAttrContainerItem::~SvXMLAttrContainerItem()
+{
+ delete pImpl;
+}
+
+int SvXMLAttrContainerItem::operator==( const SfxPoolItem& rItem ) const
+{
+ DBG_ASSERT( rItem.ISA(SvXMLAttrContainerItem),
+ "SvXMLAttrContainerItem::operator ==(): Bad type");
+ return *pImpl == *((const SvXMLAttrContainerItem&)rItem).pImpl;
+}
+
+int SvXMLAttrContainerItem::Compare( const SfxPoolItem &/*rWith*/ ) const
+{
+ DBG_ASSERT( !this, "not yet implemented" );
+
+ return 0;
+}
+
+SfxItemPresentation SvXMLAttrContainerItem::GetPresentation(
+ SfxItemPresentation /*ePresentation*/,
+ SfxMapUnit /*eCoreMetric*/,
+ SfxMapUnit /*ePresentationMetric*/,
+ XubString &/*rText*/,
+ const IntlWrapper * /*pIntlWrapper*/ ) const
+{
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+USHORT SvXMLAttrContainerItem::GetVersion( USHORT /*nFileFormatVersion*/ ) const
+{
+ // This item should never be stored
+ return USHRT_MAX;
+}
+
+BOOL SvXMLAttrContainerItem::QueryValue( com::sun::star::uno::Any& rVal, BYTE /*nMemberId*/ ) const
+{
+ Reference<XNameContainer> xContainer =
+ new SvUnoAttributeContainer( new SvXMLAttrContainerData( *pImpl ) );
+
+ rVal.setValue( &xContainer, ::getCppuType((Reference<XNameContainer>*)0) );
+ return TRUE;
+}
+BOOL SvXMLAttrContainerItem::PutValue( const com::sun::star::uno::Any& rVal, BYTE /*nMemberId*/ )
+{
+ Reference<XInterface> xRef;
+ SvUnoAttributeContainer* pContainer = NULL;
+
+ if( rVal.getValue() != NULL && rVal.getValueType().getTypeClass() == TypeClass_INTERFACE )
+ {
+ xRef = *(Reference<XInterface>*)rVal.getValue();
+ Reference<XUnoTunnel> xTunnel(xRef, UNO_QUERY);
+ if( xTunnel.is() )
+ pContainer = (SvUnoAttributeContainer*)(ULONG)xTunnel->getSomething(SvUnoAttributeContainer::getUnoTunnelId());
+ }
+
+ if( pContainer )
+ {
+ delete pImpl;
+ pImpl = new SvXMLAttrContainerData( * pContainer->GetContainerImpl() );
+ }
+ else
+ {
+ SvXMLAttrContainerData* pNewImpl = new SvXMLAttrContainerData;
+
+ try
+ {
+ Reference<XNameContainer> xContainer( xRef, UNO_QUERY );
+ if( !xContainer.is() )
+ return FALSE;
+
+ const Sequence< ::rtl::OUString > aNameSequence( xContainer->getElementNames() );
+ const ::rtl::OUString* pNames = aNameSequence.getConstArray();
+ const INT32 nCount = aNameSequence.getLength();
+ Any aAny;
+ AttributeData* pData;
+ INT32 nAttr;
+
+ for( nAttr = 0; nAttr < nCount; nAttr++ )
+ {
+ const ::rtl::OUString aName( *pNames++ );
+
+ aAny = xContainer->getByName( aName );
+ if( aAny.getValue() == NULL || aAny.getValueType() != ::getCppuType((AttributeData*)0) )
+ return FALSE;
+
+ pData = (AttributeData*)aAny.getValue();
+ sal_Int32 pos = aName.indexOf( sal_Unicode(':') );
+ if( pos != -1 )
+ {
+ const ::rtl::OUString aPrefix( aName.copy( 0, pos ));
+ const ::rtl::OUString aLName( aName.copy( pos+1 ));
+
+ if( pData->Namespace.getLength() == 0 )
+ {
+ if( !pNewImpl->AddAttr( aPrefix, aLName, pData->Value ) )
+ break;
+ }
+ else
+ {
+ if( !pNewImpl->AddAttr( aPrefix, pData->Namespace, aLName, pData->Value ) )
+ break;
+ }
+ }
+ else
+ {
+ if( !pNewImpl->AddAttr( aName, pData->Value ) )
+ break;
+ }
+ }
+
+ if( nAttr == nCount )
+ {
+ delete pImpl;
+ pImpl = pNewImpl;
+ }
+ else
+ {
+ delete pNewImpl;
+ return FALSE;
+ }
+ }
+ catch(...)
+ {
+ delete pNewImpl;
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+
+BOOL SvXMLAttrContainerItem::AddAttr( const ::rtl::OUString& rLName,
+ const ::rtl::OUString& rValue )
+{
+ return pImpl->AddAttr( rLName, rValue );
+}
+
+BOOL SvXMLAttrContainerItem::AddAttr( const ::rtl::OUString& rPrefix,
+ const ::rtl::OUString& rNamespace, const ::rtl::OUString& rLName,
+ const ::rtl::OUString& rValue )
+{
+ return pImpl->AddAttr( rPrefix, rNamespace, rLName, rValue );
+}
+
+USHORT SvXMLAttrContainerItem::GetAttrCount() const
+{
+ return (USHORT)pImpl->GetAttrCount();
+}
+
+::rtl::OUString SvXMLAttrContainerItem::GetAttrNamespace( USHORT i ) const
+{
+ return pImpl->GetAttrNamespace( i );
+}
+
+::rtl::OUString SvXMLAttrContainerItem::GetAttrPrefix( USHORT i ) const
+{
+ return pImpl->GetAttrPrefix( i );
+}
+
+const ::rtl::OUString& SvXMLAttrContainerItem::GetAttrLName( USHORT i ) const
+{
+ return pImpl->GetAttrLName( i );
+}
+
+const ::rtl::OUString& SvXMLAttrContainerItem::GetAttrValue( USHORT i ) const
+{
+ return pImpl->GetAttrValue( i );
+}
+
+
+USHORT SvXMLAttrContainerItem::GetFirstNamespaceIndex() const
+{
+ return pImpl->GetFirstNamespaceIndex();
+}
+
+USHORT SvXMLAttrContainerItem::GetNextNamespaceIndex( USHORT nIdx ) const
+{
+ return pImpl->GetNextNamespaceIndex( nIdx );
+}
+
+const ::rtl::OUString& SvXMLAttrContainerItem::GetNamespace( USHORT i ) const
+{
+ return pImpl->GetNamespace( i );
+}
+
+const ::rtl::OUString& SvXMLAttrContainerItem::GetPrefix( USHORT i ) const
+{
+ return pImpl->GetPrefix( i );
+}
+
diff --git a/editeng/source/misc/SvXMLAutoCorrectExport.cxx b/editeng/source/misc/SvXMLAutoCorrectExport.cxx
new file mode 100644
index 0000000000..05d11181b9
--- /dev/null
+++ b/editeng/source/misc/SvXMLAutoCorrectExport.cxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: SvXMLAutoCorrectExport.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <SvXMLAutoCorrectExport.hxx>
+#define _SVSTDARR_STRINGSISORTDTOR
+#define _SVSTDARR_STRINGSDTOR
+#include <svl/svstdarr.hxx>
+#include <xmloff/xmltoken.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star;
+using namespace ::xmloff::token;
+using namespace ::rtl;
+
+// #110680#
+SvXMLAutoCorrectExport::SvXMLAutoCorrectExport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ const SvxAutocorrWordList * pNewAutocorr_List,
+ const rtl::OUString &rFileName,
+ com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler> &rHandler)
+: SvXMLExport( xServiceFactory, rFileName, rHandler ),
+ pAutocorr_List( pNewAutocorr_List )
+{
+ _GetNamespaceMap().Add( GetXMLToken ( XML_NP_BLOCK_LIST),
+ GetXMLToken ( XML_N_BLOCK_LIST ),
+ XML_NAMESPACE_BLOCKLIST );
+}
+
+sal_uInt32 SvXMLAutoCorrectExport::exportDoc(enum XMLTokenEnum /*eClass*/)
+{
+ GetDocHandler()->startDocument();
+
+ AddAttribute ( XML_NAMESPACE_NONE,
+ _GetNamespaceMap().GetAttrNameByKey ( XML_NAMESPACE_BLOCKLIST ),
+ _GetNamespaceMap().GetNameByKey ( XML_NAMESPACE_BLOCKLIST ) );
+ {
+ SvXMLElementExport aRoot (*this, XML_NAMESPACE_BLOCKLIST, XML_BLOCK_LIST, sal_True, sal_True);
+ sal_uInt16 nBlocks= pAutocorr_List->Count();
+ for ( sal_uInt16 i = 0; i < nBlocks; i++)
+ {
+ SvxAutocorrWord* p = pAutocorr_List->GetObject(i);
+
+ AddAttribute( XML_NAMESPACE_BLOCKLIST,
+ XML_ABBREVIATED_NAME,
+ OUString(p->GetShort()));
+ AddAttribute( XML_NAMESPACE_BLOCKLIST,
+ XML_NAME,
+ OUString(p->IsTextOnly() ? p->GetLong() : p->GetShort()));
+
+ SvXMLElementExport aBlock( *this, XML_NAMESPACE_BLOCKLIST, XML_BLOCK, sal_True, sal_True);
+ }
+ }
+ GetDocHandler()->endDocument();
+ return 0;
+}
+
+// #110680#
+SvXMLExceptionListExport::SvXMLExceptionListExport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ const SvStringsISortDtor &rNewList,
+ const rtl::OUString &rFileName,
+ com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler> &rHandler)
+: SvXMLExport( xServiceFactory, rFileName, rHandler ),
+ rList( rNewList )
+{
+ _GetNamespaceMap().Add( GetXMLToken ( XML_NP_BLOCK_LIST ),
+ GetXMLToken ( XML_N_BLOCK_LIST ),
+ XML_NAMESPACE_BLOCKLIST );
+}
+
+sal_uInt32 SvXMLExceptionListExport::exportDoc(enum XMLTokenEnum /*eClass*/)
+{
+ GetDocHandler()->startDocument();
+
+ AddAttribute ( XML_NAMESPACE_NONE,
+ _GetNamespaceMap().GetAttrNameByKey ( XML_NAMESPACE_BLOCKLIST ),
+ _GetNamespaceMap().GetNameByKey ( XML_NAMESPACE_BLOCKLIST ) );
+ {
+ SvXMLElementExport aRoot (*this, XML_NAMESPACE_BLOCKLIST, XML_BLOCK_LIST, sal_True, sal_True);
+ sal_uInt16 nBlocks= rList.Count();
+ for ( sal_uInt16 i = 0; i < nBlocks; i++)
+ {
+ AddAttribute( XML_NAMESPACE_BLOCKLIST,
+ XML_ABBREVIATED_NAME,
+ OUString( *rList[i] ) );
+ SvXMLElementExport aBlock( *this, XML_NAMESPACE_BLOCKLIST, XML_BLOCK, sal_True, sal_True);
+ }
+ }
+ GetDocHandler()->endDocument();
+ return 0;
+}
diff --git a/editeng/source/misc/SvXMLAutoCorrectExport.hxx b/editeng/source/misc/SvXMLAutoCorrectExport.hxx
new file mode 100644
index 0000000000..b88fbc7287
--- /dev/null
+++ b/editeng/source/misc/SvXMLAutoCorrectExport.hxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: SvXMLAutoCorrectExport.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _SV_XMLAUTOCORRECTEXPORT_HXX
+#define _SV_XMLAUTOCORRECTEXPORT_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlexp.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <editeng/svxacorr.hxx>
+
+class SvXMLAutoCorrectExport : public SvXMLExport
+{
+private:
+ const SvxAutocorrWordList *pAutocorr_List;
+public:
+ // #110680#
+ SvXMLAutoCorrectExport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ const SvxAutocorrWordList * pNewAutocorr_List,
+ const rtl::OUString &rFileName,
+ com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler> &rHandler);
+
+ virtual ~SvXMLAutoCorrectExport ( void ) {}
+ sal_uInt32 exportDoc(enum ::xmloff::token::XMLTokenEnum eClass);
+ void _ExportAutoStyles() {}
+ void _ExportMasterStyles () {}
+ void _ExportContent() {}
+};
+
+class SvStringsISortDtor;
+
+class SvXMLExceptionListExport : public SvXMLExport
+{
+private:
+ const SvStringsISortDtor & rList;
+public:
+ // #110680#
+ SvXMLExceptionListExport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ const SvStringsISortDtor &rNewList,
+ const rtl::OUString &rFileName,
+ com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler> &rHandler);
+
+ virtual ~SvXMLExceptionListExport ( void ) {}
+ sal_uInt32 exportDoc(enum ::xmloff::token::XMLTokenEnum eClass);
+ void _ExportAutoStyles() {}
+ void _ExportMasterStyles () {}
+ void _ExportContent() {}
+};
+#endif
diff --git a/editeng/source/misc/SvXMLAutoCorrectImport.cxx b/editeng/source/misc/SvXMLAutoCorrectImport.cxx
new file mode 100644
index 0000000000..0230e849b8
--- /dev/null
+++ b/editeng/source/misc/SvXMLAutoCorrectImport.cxx
@@ -0,0 +1,269 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: SvXMLAutoCorrectImport.cxx,v $
+ * $Revision: 1.14 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <SvXMLAutoCorrectImport.hxx>
+#ifndef _APP_HXX //autogen
+#include <vcl/svapp.hxx>
+#endif
+
+#define _SVSTDARR_STRINGSISORTDTOR
+#define _SVSTDARR_STRINGSDTOR
+#include <svl/svstdarr.hxx>
+#include <xmloff/xmltoken.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::xmloff::token;
+using namespace ::rtl;
+
+
+static OUString sBlockList ( RTL_CONSTASCII_USTRINGPARAM ( "_block-list" ) );
+
+// #110680#
+SvXMLAutoCorrectImport::SvXMLAutoCorrectImport(
+ const uno::Reference< lang::XMultiServiceFactory > xServiceFactory,
+ SvxAutocorrWordList *pNewAutocorr_List,
+ SvxAutoCorrect &rNewAutoCorrect,
+ const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& rNewStorage)
+: SvXMLImport( xServiceFactory ),
+ pAutocorr_List (pNewAutocorr_List),
+ rAutoCorrect ( rNewAutoCorrect ),
+ xStorage ( rNewStorage )
+{
+ GetNamespaceMap().Add(
+ sBlockList,
+ GetXMLToken ( XML_N_BLOCK_LIST),
+ XML_NAMESPACE_BLOCKLIST );
+}
+
+SvXMLAutoCorrectImport::~SvXMLAutoCorrectImport ( void ) throw ()
+{
+}
+
+SvXMLImportContext *SvXMLAutoCorrectImport::CreateContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( XML_NAMESPACE_BLOCKLIST == nPrefix &&
+ IsXMLToken ( rLocalName, XML_BLOCK_LIST ) )
+ pContext = new SvXMLWordListContext( *this, nPrefix, rLocalName, xAttrList );
+ else
+ pContext = SvXMLImport::CreateContext( nPrefix, rLocalName, xAttrList );
+ return pContext;
+}
+
+SvXMLWordListContext::SvXMLWordListContext(
+ SvXMLAutoCorrectImport& rImport,
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::xml::sax::XAttributeList > & /*xAttrList*/ ) :
+ SvXMLImportContext ( rImport, nPrefix, rLocalName ),
+ rLocalRef(rImport)
+{
+}
+
+SvXMLImportContext *SvXMLWordListContext::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if (nPrefix == XML_NAMESPACE_BLOCKLIST &&
+ IsXMLToken ( rLocalName, XML_BLOCK ) )
+ pContext = new SvXMLWordContext (rLocalRef, nPrefix, rLocalName, xAttrList);
+ else
+ pContext = new SvXMLImportContext( rLocalRef, nPrefix, rLocalName);
+ return pContext;
+}
+SvXMLWordListContext::~SvXMLWordListContext ( void )
+{
+}
+
+SvXMLWordContext::SvXMLWordContext(
+ SvXMLAutoCorrectImport& rImport,
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::xml::sax::XAttributeList > & xAttrList ) :
+ SvXMLImportContext ( rImport, nPrefix, rLocalName ),
+ rLocalRef(rImport)
+{
+ String sRight, sWrong;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+
+ for (sal_Int16 i=0; i < nAttrCount; i++)
+ {
+ const OUString& rAttrName = xAttrList->getNameByIndex( i );
+ OUString aLocalName;
+ sal_uInt16 nAttrPrefix = rImport.GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName);
+ const OUString& rAttrValue = xAttrList->getValueByIndex( i );
+ if (XML_NAMESPACE_BLOCKLIST == nAttrPrefix)
+ {
+ if ( IsXMLToken ( aLocalName, XML_ABBREVIATED_NAME ) )
+ {
+ sWrong = rAttrValue;
+ }
+ else if ( IsXMLToken ( aLocalName, XML_NAME ) )
+ {
+ sRight = rAttrValue;
+ }
+ }
+ }
+ if (!sWrong.Len() || !sRight.Len() )
+ return;
+
+// const International& rInter = Application::GetAppInternational();
+// BOOL bOnlyTxt = COMPARE_EQUAL != rInter.Compare( sRight, sWrong, INTN_COMPARE_IGNORECASE );
+ BOOL bOnlyTxt = sRight != sWrong;
+ if( !bOnlyTxt )
+ {
+ String sLongSave( sRight );
+ if( !rLocalRef.rAutoCorrect.GetLongText( rLocalRef.xStorage, String(), sWrong, sRight ) &&
+ sLongSave.Len() )
+ {
+ sRight = sLongSave;
+ bOnlyTxt = TRUE;
+ }
+ }
+ SvxAutocorrWordPtr pNew = new SvxAutocorrWord( sWrong, sRight, bOnlyTxt );
+
+ if( !rLocalRef.pAutocorr_List->Insert( pNew ) )
+ delete pNew;
+}
+
+SvXMLWordContext::~SvXMLWordContext ( void )
+{
+}
+
+// #110680#
+SvXMLExceptionListImport::SvXMLExceptionListImport(
+ const uno::Reference< lang::XMultiServiceFactory > xServiceFactory,
+ SvStringsISortDtor & rNewList )
+: SvXMLImport( xServiceFactory ),
+ rList (rNewList)
+{
+ GetNamespaceMap().Add(
+ sBlockList,
+ GetXMLToken ( XML_N_BLOCK_LIST),
+ XML_NAMESPACE_BLOCKLIST );
+}
+
+SvXMLExceptionListImport::~SvXMLExceptionListImport ( void ) throw ()
+{
+}
+
+SvXMLImportContext *SvXMLExceptionListImport::CreateContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( XML_NAMESPACE_BLOCKLIST==nPrefix &&
+ IsXMLToken ( rLocalName, XML_BLOCK_LIST ) )
+ pContext = new SvXMLExceptionListContext( *this, nPrefix, rLocalName, xAttrList );
+ else
+ pContext = SvXMLImport::CreateContext( nPrefix, rLocalName, xAttrList );
+ return pContext;
+}
+
+SvXMLExceptionListContext::SvXMLExceptionListContext(
+ SvXMLExceptionListImport& rImport,
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::xml::sax::XAttributeList > & /* xAttrList */ ) :
+ SvXMLImportContext ( rImport, nPrefix, rLocalName ),
+ rLocalRef(rImport)
+{
+}
+
+SvXMLImportContext *SvXMLExceptionListContext::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if (nPrefix == XML_NAMESPACE_BLOCKLIST &&
+ IsXMLToken ( rLocalName, XML_BLOCK ) )
+ pContext = new SvXMLExceptionContext (rLocalRef, nPrefix, rLocalName, xAttrList);
+ else
+ pContext = new SvXMLImportContext( rLocalRef, nPrefix, rLocalName);
+ return pContext;
+}
+SvXMLExceptionListContext::~SvXMLExceptionListContext ( void )
+{
+}
+
+SvXMLExceptionContext::SvXMLExceptionContext(
+ SvXMLExceptionListImport& rImport,
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::xml::sax::XAttributeList > & xAttrList ) :
+ SvXMLImportContext ( rImport, nPrefix, rLocalName ),
+ rLocalRef(rImport)
+{
+ String sWord;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+
+ for (sal_Int16 i=0; i < nAttrCount; i++)
+ {
+ const OUString& rAttrName = xAttrList->getNameByIndex( i );
+ OUString aLocalName;
+ sal_uInt16 nAttrPrefix = rImport.GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName);
+ const OUString& rAttrValue = xAttrList->getValueByIndex( i );
+ if (XML_NAMESPACE_BLOCKLIST == nAttrPrefix)
+ {
+ if ( IsXMLToken ( aLocalName, XML_ABBREVIATED_NAME ) )
+ {
+ sWord = rAttrValue;
+ }
+ }
+ }
+ if (!sWord.Len() )
+ return;
+
+ String * pNew = new String( sWord );
+
+ if( !rLocalRef.rList.Insert( pNew ) )
+ delete pNew;
+}
+
+SvXMLExceptionContext::~SvXMLExceptionContext ( void )
+{
+}
diff --git a/editeng/source/misc/SvXMLAutoCorrectImport.hxx b/editeng/source/misc/SvXMLAutoCorrectImport.hxx
new file mode 100644
index 0000000000..8118782961
--- /dev/null
+++ b/editeng/source/misc/SvXMLAutoCorrectImport.hxx
@@ -0,0 +1,151 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: SvXMLAutoCorrectImport.hxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _SV_XMLAUTOCORRECTIMPORT_HXX
+#define _SV_XMLAUTOCORRECTIMPORT_HXX
+
+#ifndef _SVSTOR_HXX
+#include <sot/storage.hxx>
+#endif
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <editeng/svxacorr.hxx>
+
+class SvXMLAutoCorrectImport : public SvXMLImport
+{
+protected:
+
+ // This method is called after the namespace map has been updated, but
+ // before a context for the current element has been pushed.
+ virtual SvXMLImportContext *CreateContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+public:
+ SvxAutocorrWordList *pAutocorr_List;
+ SvxAutoCorrect &rAutoCorrect;
+ com::sun::star::uno::Reference < com::sun::star::embed::XStorage > xStorage;
+ //SvStorageRef &rStorage;
+
+ // #110680#
+ SvXMLAutoCorrectImport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ SvxAutocorrWordList *pNewAutocorr_List,
+ SvxAutoCorrect &rNewAutoCorrect,
+ const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& rNewStorage);
+
+ ~SvXMLAutoCorrectImport ( void ) throw ();
+};
+
+class SvXMLWordListContext : public SvXMLImportContext
+{
+private:
+ SvXMLAutoCorrectImport & rLocalRef;
+public:
+ SvXMLWordListContext ( SvXMLAutoCorrectImport& rImport,
+ sal_uInt16 nPrefix,
+ const rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+ ~SvXMLWordListContext ( void );
+};
+
+class SvXMLWordContext : public SvXMLImportContext
+{
+private:
+ SvXMLAutoCorrectImport & rLocalRef;
+public:
+ SvXMLWordContext ( SvXMLAutoCorrectImport& rImport,
+ sal_uInt16 nPrefix,
+ const rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+ ~SvXMLWordContext ( void );
+};
+
+
+class SvXMLExceptionListImport : public SvXMLImport
+{
+protected:
+
+ // This method is called after the namespace map has been updated, but
+ // before a context for the current element has been pushed.
+ virtual SvXMLImportContext *CreateContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+public:
+ SvStringsISortDtor &rList;
+
+ // #110680#
+ SvXMLExceptionListImport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ SvStringsISortDtor & rNewList );
+
+ ~SvXMLExceptionListImport ( void ) throw ();
+};
+
+class SvXMLExceptionListContext : public SvXMLImportContext
+{
+private:
+ SvXMLExceptionListImport & rLocalRef;
+public:
+ SvXMLExceptionListContext ( SvXMLExceptionListImport& rImport,
+ sal_uInt16 nPrefix,
+ const rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+ ~SvXMLExceptionListContext ( void );
+};
+
+class SvXMLExceptionContext : public SvXMLImportContext
+{
+private:
+ SvXMLExceptionListImport & rLocalRef;
+public:
+ SvXMLExceptionContext ( SvXMLExceptionListImport& rImport,
+ sal_uInt16 nPrefix,
+ const rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+ ~SvXMLExceptionContext ( void );
+};
+
+
+#endif
diff --git a/editeng/source/misc/acorrcfg.cxx b/editeng/source/misc/acorrcfg.cxx
new file mode 100644
index 0000000000..9c90f9e9e9
--- /dev/null
+++ b/editeng/source/misc/acorrcfg.cxx
@@ -0,0 +1,681 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: acorrcfg.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <editeng/acorrcfg.hxx>
+#include <tools/debug.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svl/urihelper.hxx>
+
+#include <editeng/svxacorr.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+using namespace utl;
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+#define C2U(cChar) OUString::createFromAscii(cChar)
+
+static SvxAutoCorrCfg* pAutoCorrCfg = 0;
+
+/*--------------------------------------------------------------------
+ Beschreibung: Ctor Dtor
+ --------------------------------------------------------------------*/
+
+SvxAutoCorrCfg::SvxAutoCorrCfg() :
+ aBaseConfig(*this),
+ aSwConfig(*this),
+ bFileRel(TRUE),
+ bNetRel(TRUE),
+ bAutoTextTip(TRUE),
+ bAutoTextPreview(FALSE),
+ bAutoFmtByInput(TRUE),
+ bSearchInAllCategories(FALSE)
+{
+ SvtPathOptions aPathOpt;
+ String sSharePath, sUserPath, sAutoPath( aPathOpt.GetAutoCorrectPath() );
+
+ String* pS = &sSharePath;
+ for( USHORT n = 0; n < 2; ++n, pS = &sUserPath )
+ {
+ *pS = sAutoPath.GetToken( n, ';' );
+ INetURLObject aPath( *pS );
+ aPath.insertName( String::CreateFromAscii("acor") );
+ *pS = aPath.GetMainURL(INetURLObject::DECODE_TO_IURI);
+ }
+ pAutoCorrect = new SvxAutoCorrect( sSharePath, sUserPath );
+
+ aBaseConfig.Load(sal_True);
+ aSwConfig.Load(sal_True);
+}
+
+SvxAutoCorrCfg::~SvxAutoCorrCfg()
+{
+ delete pAutoCorrect;
+}
+
+void SvxAutoCorrCfg::SetAutoCorrect( SvxAutoCorrect* pNew )
+{
+ if( pNew && pNew != pAutoCorrect )
+ {
+ if( pAutoCorrect->GetFlags() != pNew->GetFlags() )
+ {
+ aBaseConfig.SetModified();
+ aSwConfig.SetModified();
+ }
+ delete pAutoCorrect;
+ pAutoCorrect = pNew;
+ }
+}
+/*-- 12.10.00 11:44:17---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+Sequence<OUString> SvxBaseAutoCorrCfg::GetPropertyNames()
+{
+ static const char* aPropNames[] =
+ {
+ "Exceptions/TwoCapitalsAtStart", // 0
+ "Exceptions/CapitalAtStartSentence", // 1
+ "UseReplacementTable", // 2
+ "TwoCapitalsAtStart", // 3
+ "CapitalAtStartSentence", // 4
+ "ChangeUnderlineWeight", // 5
+ "SetInetAttribute", // 6
+ "ChangeOrdinalNumber", // 7
+ "ChangeFraction", // 8
+ "ChangeDash", // 9
+ "RemoveDoubleSpaces", // 10
+ "ReplaceSingleQuote", // 11
+ "SingleQuoteAtStart", // 12
+ "SingleQuoteAtEnd", // 13
+ "ReplaceDoubleQuote", // 14
+ "DoubleQuoteAtStart", // 15
+ "DoubleQuoteAtEnd" // 16
+ };
+ const int nCount = 17;
+ Sequence<OUString> aNames(nCount);
+ OUString* pNames = aNames.getArray();
+ for(int i = 0; i < nCount; i++)
+ pNames[i] = OUString::createFromAscii(aPropNames[i]);
+ return aNames;
+}
+/*-- 12.10.00 11:44:18---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SvxBaseAutoCorrCfg::Load(sal_Bool bInit)
+{
+ Sequence<OUString> aNames = GetPropertyNames();
+ Sequence<Any> aValues = GetProperties(aNames);
+ if(bInit)
+ EnableNotification(aNames);
+ const Any* pValues = aValues.getConstArray();
+ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed");
+ if(aValues.getLength() == aNames.getLength())
+ {
+ long nFlags = 0; // default alles aus
+ sal_Int32 nTemp = 0;
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ if(pValues[nProp].hasValue())
+ {
+ switch(nProp)
+ {
+ case 0:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ nFlags |= SaveWordCplSttLst;
+ break;//"Exceptions/TwoCapitalsAtStart",
+ case 1:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ nFlags |= SaveWordWrdSttLst;
+ break;//"Exceptions/CapitalAtStartSentence",
+ case 2:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ nFlags |= Autocorrect;
+ break;//"UseReplacementTable",
+ case 3:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ nFlags |= CptlSttWrd;
+ break;//"TwoCapitalsAtStart",
+ case 4:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ nFlags |= CptlSttSntnc;
+ break;//"CapitalAtStartSentence",
+ case 5:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ nFlags |= ChgWeightUnderl;
+ break;//"ChangeUnderlineWeight",
+ case 6:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ nFlags |= SetINetAttr;
+ break;//"SetInetAttribute",
+ case 7:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ nFlags |= ChgOrdinalNumber;
+ break;//"ChangeOrdinalNumber",
+ case 8:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ nFlags |= ChgFractionSymbol;
+ break;//"ChangeFraction",
+ case 9:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ nFlags |= ChgToEnEmDash;
+ break;//"ChangeDash",
+ case 10:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ nFlags |= IngnoreDoubleSpace;
+ break;//"RemoveDoubleSpaces",
+ case 11:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ nFlags |= ChgSglQuotes;
+ break;//"ReplaceSingleQuote",
+ case 12:
+ pValues[nProp] >>= nTemp;
+ rParent.pAutoCorrect->SetStartSingleQuote(
+ sal::static_int_cast< sal_Unicode >( nTemp ) );
+ break;//"SingleQuoteAtStart",
+ case 13:
+ pValues[nProp] >>= nTemp;
+ rParent.pAutoCorrect->SetEndSingleQuote(
+ sal::static_int_cast< sal_Unicode >( nTemp ) );
+ break;//"SingleQuoteAtEnd",
+ case 14:
+ if(*(sal_Bool*)pValues[nProp].getValue())
+ nFlags |= ChgQuotes;
+ break;//"ReplaceDoubleQuote",
+ case 15:
+ pValues[nProp] >>= nTemp;
+ rParent.pAutoCorrect->SetStartDoubleQuote(
+ sal::static_int_cast< sal_Unicode >( nTemp ) );
+ break;//"DoubleQuoteAtStart",
+ case 16:
+ pValues[nProp] >>= nTemp;
+ rParent.pAutoCorrect->SetEndDoubleQuote(
+ sal::static_int_cast< sal_Unicode >( nTemp ) );
+ break;//"DoubleQuoteAtEnd"
+ }
+ }
+ }
+ if( nFlags )
+ rParent.pAutoCorrect->SetAutoCorrFlag( nFlags, TRUE );
+ rParent.pAutoCorrect->SetAutoCorrFlag( ( 0xffff & ~nFlags ), FALSE );
+
+ }
+}
+/*-- 12.10.00 11:44:19---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+SvxBaseAutoCorrCfg::SvxBaseAutoCorrCfg(SvxAutoCorrCfg& rPar) :
+ utl::ConfigItem(C2U("Office.Common/AutoCorrect")),
+ rParent(rPar)
+{
+}
+/*-- 12.10.00 11:44:19---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+SvxBaseAutoCorrCfg::~SvxBaseAutoCorrCfg()
+{
+}
+/*-- 12.10.00 11:44:20---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SvxBaseAutoCorrCfg::Commit()
+{
+ Sequence<OUString> aNames( GetPropertyNames() );
+
+ Sequence<Any> aValues(aNames.getLength());
+ Any* pValues = aValues.getArray();
+
+ const Type& rType = ::getBooleanCppuType();
+ BOOL bVal;
+ const long nFlags = rParent.pAutoCorrect->GetFlags();
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ switch(nProp)
+ {
+ case 0:
+ bVal = 0 != (nFlags & SaveWordCplSttLst);
+ pValues[nProp].setValue(&bVal, rType);
+ break;//"Exceptions/TwoCapitalsAtStart",
+ case 1:
+ bVal = 0 != (nFlags & SaveWordWrdSttLst);
+ pValues[nProp].setValue(&bVal, rType);
+ break;//"Exceptions/CapitalAtStartSentence",
+ case 2:
+ bVal = 0 != (nFlags & Autocorrect);
+ pValues[nProp].setValue(&bVal, rType);
+ break;//"UseReplacementTable",
+ case 3:
+ bVal = 0 != (nFlags & CptlSttWrd);
+ pValues[nProp].setValue(&bVal, rType);
+ break;//"TwoCapitalsAtStart",
+ case 4:
+ bVal = 0 != (nFlags & CptlSttSntnc);
+ pValues[nProp].setValue(&bVal, rType);
+ break;//"CapitalAtStartSentence",
+ case 5:
+ bVal = 0 != (nFlags & ChgWeightUnderl);
+ pValues[nProp].setValue(&bVal, rType);
+ break;//"ChangeUnderlineWeight",
+ case 6:
+ bVal = 0 != (nFlags & SetINetAttr);
+ pValues[nProp].setValue(&bVal, rType);
+ break;//"SetInetAttribute",
+ case 7:
+ bVal = 0 != (nFlags & ChgOrdinalNumber);
+ pValues[nProp].setValue(&bVal, rType);
+ break;//"ChangeOrdinalNumber",
+ case 8:
+ bVal = 0 != (nFlags & ChgFractionSymbol);
+ pValues[nProp].setValue(&bVal, rType);
+ break;//"ChangeFraction",
+ case 9:
+ bVal = 0 != (nFlags & ChgToEnEmDash);
+ pValues[nProp].setValue(&bVal, rType);
+ break;//"ChangeDash",
+ case 10:
+ bVal = 0 != (nFlags & IngnoreDoubleSpace);
+ pValues[nProp].setValue(&bVal, rType);
+ break;//"RemoveDoubleSpaces",
+ case 11:
+ bVal = 0 != (nFlags & ChgSglQuotes);
+ pValues[nProp].setValue(&bVal, rType);
+ break;//"ReplaceSingleQuote",
+ case 12:
+ pValues[nProp] <<= (sal_Int32)rParent.pAutoCorrect->GetStartSingleQuote();
+ break;//"SingleQuoteAtStart",
+ case 13:
+ pValues[nProp] <<= (sal_Int32) rParent.pAutoCorrect->GetEndSingleQuote();
+ break;//"SingleQuoteAtEnd",
+ case 14:
+ bVal = 0 != (nFlags & ChgQuotes);
+ pValues[nProp].setValue(&bVal, rType);
+ break;//"ReplaceDoubleQuote",
+ case 15:
+ pValues[nProp] <<= (sal_Int32) rParent.pAutoCorrect->GetStartDoubleQuote();
+ break;//"DoubleQuoteAtStart",
+ case 16:
+ pValues[nProp] <<= (sal_Int32) rParent.pAutoCorrect->GetEndDoubleQuote();
+ break;//"DoubleQuoteAtEnd"
+ }
+ }
+ PutProperties(aNames, aValues);
+}
+/*-- 12.10.00 11:44:21---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SvxBaseAutoCorrCfg::Notify( const Sequence<OUString>& /* aPropertyNames */)
+{
+ Load(sal_False);
+}
+/*-- 12.10.00 11:51:48---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+Sequence<OUString> SvxSwAutoCorrCfg::GetPropertyNames()
+{
+ static const char* aPropNames[] =
+ {
+ "Text/FileLinks", // 0
+ "Text/InternetLinks", // 1
+ "Text/ShowPreview", // 2
+ "Text/ShowToolTip", // 3
+ "Text/SearchInAllCategories", // 4
+ "Format/Option/UseReplacementTable", // 5
+ "Format/Option/TwoCapitalsAtStart", // 6
+ "Format/Option/CapitalAtStartSentence", // 7
+ "Format/Option/ChangeUnderlineWeight", // 8
+ "Format/Option/SetInetAttribute", // 9
+ "Format/Option/ChangeOrdinalNumber", //10
+ "Format/Option/ChangeFraction", //11
+ "Format/Option/ChangeDash", //12
+ "Format/Option/DelEmptyParagraphs", //13
+ "Format/Option/ReplaceUserStyle", //14
+ "Format/Option/ChangeToBullets/Enable", //15
+ "Format/Option/ChangeToBullets/SpecialCharacter/Char", //16
+ "Format/Option/ChangeToBullets/SpecialCharacter/Font", //17
+ "Format/Option/ChangeToBullets/SpecialCharacter/FontFamily", //18
+ "Format/Option/ChangeToBullets/SpecialCharacter/FontCharset", //19
+ "Format/Option/ChangeToBullets/SpecialCharacter/FontPitch", //20
+ "Format/Option/ReplaceQuote", //21
+ "Format/Option/CombineParagraphs", //22
+ "Format/Option/CombineValue", //23
+ "Format/Option/DelSpacesAtStartEnd", //24
+ "Format/Option/DelSpacesBetween", //25
+ "Format/ByInput/Enable", //26
+ "Format/ByInput/ChangeDash", //27
+ "Format/ByInput/ApplyNumbering/Enable", //28
+ "Format/ByInput/ChangeToBorders", //29
+ "Format/ByInput/ChangeToTable", //30
+ "Format/ByInput/ReplaceStyle", //31
+ "Format/ByInput/DelSpacesAtStartEnd", //32
+ "Format/ByInput/DelSpacesBetween", //33
+ "Completion/Enable", //34
+ "Completion/MinWordLen", //35
+ "Completion/MaxListLen", //36
+ "Completion/CollectWords", //37
+ "Completion/EndlessList", //38
+ "Completion/AppendBlank", //39
+ "Completion/ShowAsTip", //40
+ "Completion/AcceptKey", //41
+ "Completion/KeepList", //42
+ "Format/ByInput/ApplyNumbering/SpecialCharacter/Char", //43
+ "Format/ByInput/ApplyNumbering/SpecialCharacter/Font", //44
+ "Format/ByInput/ApplyNumbering/SpecialCharacter/FontFamily", //45
+ "Format/ByInput/ApplyNumbering/SpecialCharacter/FontCharset", //46
+ "Format/ByInput/ApplyNumbering/SpecialCharacter/FontPitch", //47
+ };
+ const int nCount = 48;
+ Sequence<OUString> aNames(nCount);
+ OUString* pNames = aNames.getArray();
+ for(int i = 0; i < nCount; i++)
+ pNames[i] = OUString::createFromAscii(aPropNames[i]);
+ return aNames;
+}
+/*-- 12.10.00 11:51:48---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SvxSwAutoCorrCfg::Load(sal_Bool bInit)
+{
+ Sequence<OUString> aNames = GetPropertyNames();
+ Sequence<Any> aValues = GetProperties(aNames);
+ if(bInit)
+ EnableNotification(aNames);
+ const Any* pValues = aValues.getConstArray();
+ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed");
+ if(aValues.getLength() == aNames.getLength())
+ {
+ SvxSwAutoFmtFlags& rSwFlags = rParent.pAutoCorrect->GetSwFlags();
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ if(pValues[nProp].hasValue())
+ {
+ switch(nProp)
+ {
+ case 0: rParent.bFileRel = *(sal_Bool*)pValues[nProp].getValue(); break; // "Text/FileLinks",
+ case 1: rParent.bNetRel = *(sal_Bool*)pValues[nProp].getValue(); break; // "Text/InternetLinks",
+ case 2: rParent.bAutoTextPreview = *(sal_Bool*)pValues[nProp].getValue(); break; // "Text/ShowPreview",
+ case 3: rParent.bAutoTextTip = *(sal_Bool*)pValues[nProp].getValue(); break; // "Text/ShowToolTip",
+ case 4: rParent.bSearchInAllCategories = *(sal_Bool*)pValues[nProp].getValue(); break; //"Text/SearchInAllCategories"
+ case 5: rSwFlags.bAutoCorrect = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/Option/UseReplacementTable",
+ case 6: rSwFlags.bCptlSttSntnc = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/Option/TwoCapitalsAtStart",
+ case 7: rSwFlags.bCptlSttWrd = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/Option/CapitalAtStartSentence",
+ case 8: rSwFlags.bChgWeightUnderl = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/Option/ChangeUnderlineWeight",
+ case 9: rSwFlags.bSetINetAttr = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/Option/SetInetAttribute",
+ case 10: rSwFlags.bChgOrdinalNumber = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/Option/ChangeOrdinalNumber",
+ case 11: rSwFlags.bChgFracionSymbol = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/Option/ChangeFraction",
+// it doesn't exist here - the common flags are used for that -> LM
+// case 12: rSwFlags.bChgToEnEmDash = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/Option/ChangeDash",
+ case 13: rSwFlags.bDelEmptyNode = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/Option/DelEmptyParagraphs",
+ case 14: rSwFlags.bChgUserColl = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/Option/ReplaceUserStyle",
+ case 15: rSwFlags.bChgEnumNum = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/Option/ChangeToBullets/Enable",
+ case 16:
+ {
+ sal_Int32 nVal = 0; pValues[nProp] >>= nVal;
+ rSwFlags.cBullet =
+ sal::static_int_cast< sal_Unicode >(nVal);
+ }
+ break; // "Format/Option/ChangeToBullets/SpecialCharacter/Char",
+ case 17:
+ {
+ OUString sTemp; pValues[nProp] >>= sTemp;
+ rSwFlags.aBulletFont.SetName(sTemp);
+ }
+ break; // "Format/Option/ChangeToBullets/SpecialCharacter/Font",
+ case 18:
+ {
+ sal_Int32 nVal = 0; pValues[nProp] >>= nVal;
+ rSwFlags.aBulletFont.SetFamily(FontFamily(nVal));
+ }
+ break; // "Format/Option/ChangeToBullets/SpecialCharacter/FontFamily",
+ case 19:
+ {
+ sal_Int32 nVal = 0; pValues[nProp] >>= nVal;
+ rSwFlags.aBulletFont.SetCharSet(CharSet(nVal));
+ }
+ break; // "Format/Option/ChangeToBullets/SpecialCharacter/FontCharset",
+ case 20:
+ {
+ sal_Int32 nVal = 0; pValues[nProp] >>= nVal;
+ rSwFlags.aBulletFont.SetPitch(FontPitch(nVal));
+ }
+ break; // "Format/Option/ChangeToBullets/SpecialCharacter/FontPitch",
+ case 21: rSwFlags.bReplaceQuote = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/Option/ReplaceQuote",
+ case 22: rSwFlags.bRightMargin = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/Option/CombineParagraphs",
+ case 23:
+ {
+ sal_Int32 nVal = 0; pValues[nProp] >>= nVal;
+ rSwFlags.nRightMargin =
+ sal::static_int_cast< BYTE >(nVal);
+ }
+ break; // "Format/Option/CombineValue",
+ case 24: rSwFlags.bAFmtDelSpacesAtSttEnd = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/Option/DelSpacesAtStartEnd",
+ case 25: rSwFlags.bAFmtDelSpacesBetweenLines = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/Option/DelSpacesBetween",
+ case 26: rParent.bAutoFmtByInput = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/ByInput/Enable",
+ case 27: rSwFlags.bChgToEnEmDash = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/ByInput/ChangeDash",
+ case 28: rSwFlags.bSetNumRule = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/ByInput/ApplyNumbering/Enable",
+ case 29: rSwFlags.bSetBorder = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/ByInput/ChangeToBorders",
+ case 30: rSwFlags.bCreateTable = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/ByInput/ChangeToTable",
+ case 31: rSwFlags.bReplaceStyles = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/ByInput/ReplaceStyle",
+ case 32: rSwFlags.bAFmtByInpDelSpacesAtSttEnd = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/ByInput/DelSpacesAtStartEnd",
+ case 33: rSwFlags.bAFmtByInpDelSpacesBetweenLines = *(sal_Bool*)pValues[nProp].getValue(); break; // "Format/ByInput/DelSpacesBetween",
+ case 34: rSwFlags.bAutoCompleteWords = *(sal_Bool*)pValues[nProp].getValue(); break; // "Completion/Enable",
+ case 35:
+ {
+ sal_Int32 nVal = 0; pValues[nProp] >>= nVal;
+ rSwFlags.nAutoCmpltWordLen =
+ sal::static_int_cast< USHORT >(nVal);
+ }
+ break; // "Completion/MinWordLen",
+ case 36:
+ {
+ sal_Int32 nVal = 0; pValues[nProp] >>= nVal;
+ rSwFlags.nAutoCmpltListLen =
+ sal::static_int_cast< USHORT >(nVal);
+ }
+ break; // "Completion/MaxListLen",
+ case 37: rSwFlags.bAutoCmpltCollectWords = *(sal_Bool*)pValues[nProp].getValue(); break; // "Completion/CollectWords",
+ case 38: rSwFlags.bAutoCmpltEndless = *(sal_Bool*)pValues[nProp].getValue(); break; // "Completion/EndlessList",
+ case 39: rSwFlags.bAutoCmpltAppendBlanc = *(sal_Bool*)pValues[nProp].getValue(); break; // "Completion/AppendBlank",
+ case 40: rSwFlags.bAutoCmpltShowAsTip = *(sal_Bool*)pValues[nProp].getValue(); break; // "Completion/ShowAsTip",
+ case 41:
+ {
+ sal_Int32 nVal = 0; pValues[nProp] >>= nVal;
+ rSwFlags.nAutoCmpltExpandKey =
+ sal::static_int_cast< USHORT >(nVal);
+ }
+ break; // "Completion/AcceptKey"
+ case 42 :rSwFlags.bAutoCmpltKeepList = *(sal_Bool*)pValues[nProp].getValue(); break;//"Completion/KeepList"
+ case 43 :
+ {
+ sal_Int32 nVal = 0; pValues[nProp] >>= nVal;
+ rSwFlags.cByInputBullet =
+ sal::static_int_cast< sal_Unicode >(nVal);
+ }
+ break;// "Format/ByInput/ApplyNumbering/SpecialCharacter/Char",
+ case 44 :
+ {
+ OUString sTemp; pValues[nProp] >>= sTemp;
+ rSwFlags.aByInputBulletFont.SetName(sTemp);
+ }
+ break;// "Format/ByInput/ApplyNumbering/SpecialCharacter/Font",
+ case 45 :
+ {
+ sal_Int32 nVal = 0; pValues[nProp] >>= nVal;
+ rSwFlags.aByInputBulletFont.SetFamily(FontFamily(nVal));
+ }
+ break;// "Format/ByInput/ApplyNumbering/SpecialCharacter/FontFamily",
+ case 46 :
+ {
+ sal_Int32 nVal = 0; pValues[nProp] >>= nVal;
+ rSwFlags.aByInputBulletFont.SetCharSet(CharSet(nVal));
+ }
+ break;// "Format/ByInput/ApplyNumbering/SpecialCharacter/FontCharset",
+ case 47 :
+ {
+ sal_Int32 nVal = 0; pValues[nProp] >>= nVal;
+ rSwFlags.aByInputBulletFont.SetPitch(FontPitch(nVal));
+ }
+ break;// "Format/ByInput/ApplyNumbering/SpecialCharacter/FontPitch",
+ }
+ }
+ }
+ }
+}
+/*-- 12.10.00 11:51:48---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+SvxSwAutoCorrCfg::SvxSwAutoCorrCfg(SvxAutoCorrCfg& rPar) :
+ utl::ConfigItem(C2U("Office.Writer/AutoFunction")),
+ rParent(rPar)
+{
+}
+/*-- 12.10.00 11:51:48---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+SvxSwAutoCorrCfg::~SvxSwAutoCorrCfg()
+{
+}
+/*-- 12.10.00 11:51:48---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SvxSwAutoCorrCfg::Commit()
+{
+ Sequence<OUString> aNames = GetPropertyNames();
+
+ Sequence<Any> aValues(aNames.getLength());
+ Any* pValues = aValues.getArray();
+
+ const Type& rType = ::getBooleanCppuType();
+ BOOL bVal;
+ SvxSwAutoFmtFlags& rSwFlags = rParent.pAutoCorrect->GetSwFlags();
+ for(int nProp = 0; nProp < aNames.getLength(); nProp++)
+ {
+ switch(nProp)
+ {
+ case 0: pValues[nProp].setValue(&rParent.bFileRel, rType); break; // "Text/FileLinks",
+ case 1: pValues[nProp].setValue(&rParent.bNetRel, rType); break; // "Text/InternetLinks",
+ case 2: pValues[nProp].setValue(&rParent.bAutoTextPreview, rType); break; // "Text/ShowPreview",
+ case 3: pValues[nProp].setValue(&rParent.bAutoTextTip, rType); break; // "Text/ShowToolTip",
+ case 4: pValues[nProp].setValue(&rParent.bSearchInAllCategories, rType );break; //"Text/SearchInAllCategories"
+ case 5: bVal = rSwFlags.bAutoCorrect; pValues[nProp].setValue(&bVal, rType); break; // "Format/Option/UseReplacementTable",
+ case 6: bVal = rSwFlags.bCptlSttSntnc; pValues[nProp].setValue(&bVal, rType); break; // "Format/Option/TwoCapitalsAtStart",
+ case 7: bVal = rSwFlags.bCptlSttWrd; pValues[nProp].setValue(&bVal, rType); break; // "Format/Option/CapitalAtStartSentence",
+ case 8: bVal = rSwFlags.bChgWeightUnderl; pValues[nProp].setValue(&bVal, rType); break; // "Format/Option/ChangeUnderlineWeight",
+ case 9: bVal = rSwFlags.bSetINetAttr; pValues[nProp].setValue(&bVal, rType); break; // "Format/Option/SetInetAttribute",
+ case 10: bVal = rSwFlags.bChgOrdinalNumber; pValues[nProp].setValue(&bVal, rType); break; // "Format/Option/ChangeOrdinalNumber",
+ case 11: bVal = rSwFlags.bChgFracionSymbol; pValues[nProp].setValue(&bVal, rType); break; // "Format/Option/ChangeFraction",
+// it doesn't exist here - the common flags are used for that -> LM
+ case 12:
+ bVal = sal_True; pValues[nProp].setValue(&bVal, rType);
+ break; // "Format/Option/ChangeDash",
+ case 13: bVal = rSwFlags.bDelEmptyNode; pValues[nProp].setValue(&bVal, rType); break; // "Format/Option/DelEmptyParagraphs",
+ case 14: bVal = rSwFlags.bChgUserColl; pValues[nProp].setValue(&bVal, rType); break; // "Format/Option/ReplaceUserStyle",
+ case 15: bVal = rSwFlags.bChgEnumNum; pValues[nProp].setValue(&bVal, rType); break; // "Format/Option/ChangeToBullets/Enable",
+ case 16:
+ pValues[nProp] <<= (sal_Int32)rSwFlags.cBullet;
+ break; // "Format/Option/ChangeToBullets/SpecialCharacter/Char",
+ case 17:
+ pValues[nProp] <<= OUString(rSwFlags.aBulletFont.GetName());
+ break; // "Format/Option/ChangeToBullets/SpecialCharacter/Font",
+ case 18:
+ pValues[nProp] <<= (sal_Int32)rSwFlags.aBulletFont.GetFamily();
+ break; // "Format/Option/ChangeToBullets/SpecialCharacter/FontFamily",
+ case 19:
+ pValues[nProp] <<= (sal_Int32)rSwFlags.aBulletFont.GetCharSet();
+ break; // "Format/Option/ChangeToBullets/SpecialCharacter/FontCharset",
+ case 20:
+ pValues[nProp] <<= (sal_Int32)rSwFlags.aBulletFont.GetPitch();
+ break; // "Format/Option/ChangeToBullets/SpecialCharacter/FontPitch",
+ case 21: bVal = rSwFlags.bReplaceQuote; pValues[nProp].setValue(&bVal, rType); break; // "Format/Option/ReplaceQuote",
+ case 22: bVal = rSwFlags.bRightMargin; pValues[nProp].setValue(&bVal, rType); break; // "Format/Option/CombineParagraphs",
+ case 23:
+ pValues[nProp] <<= (sal_Int32)rSwFlags.nRightMargin;
+ break; // "Format/Option/CombineValue",
+ case 24: bVal = rSwFlags.bAFmtDelSpacesAtSttEnd; pValues[nProp].setValue(&bVal, rType); break; // "Format/Option/DelSpacesAtStartEnd",
+ case 25: bVal = rSwFlags.bAFmtDelSpacesBetweenLines; pValues[nProp].setValue(&bVal, rType); break; // "Format/Option/DelSpacesBetween",
+ case 26: bVal = rParent.bAutoFmtByInput; pValues[nProp].setValue(&bVal, rType); break; // "Format/ByInput/Enable",
+ case 27: bVal = rSwFlags.bChgToEnEmDash; pValues[nProp].setValue(&bVal, rType); break; // "Format/ByInput/ChangeDash",
+ case 28: bVal = rSwFlags.bSetNumRule; pValues[nProp].setValue(&bVal, rType); break; // "Format/ByInput/ApplyNumbering/Enable",
+ case 29: bVal = rSwFlags.bSetBorder; pValues[nProp].setValue(&bVal, rType); break; // "Format/ByInput/ChangeToBorders",
+ case 30: bVal = rSwFlags.bCreateTable; pValues[nProp].setValue(&bVal, rType); break; // "Format/ByInput/ChangeToTable",
+ case 31: bVal = rSwFlags.bReplaceStyles; pValues[nProp].setValue(&bVal, rType); break; // "Format/ByInput/ReplaceStyle",
+ case 32: bVal = rSwFlags.bAFmtByInpDelSpacesAtSttEnd; pValues[nProp].setValue(&bVal, rType); break; // "Format/ByInput/DelSpacesAtStartEnd",
+ case 33: bVal = rSwFlags.bAFmtByInpDelSpacesBetweenLines; pValues[nProp].setValue(&bVal, rType); break; // "Format/ByInput/DelSpacesBetween",
+ case 34: bVal = rSwFlags.bAutoCompleteWords; pValues[nProp].setValue(&bVal, rType); break; // "Completion/Enable",
+ case 35:
+ pValues[nProp] <<= (sal_Int32)rSwFlags.nAutoCmpltWordLen;
+ break; // "Completion/MinWordLen",
+ case 36:
+ pValues[nProp] <<= (sal_Int32)rSwFlags.nAutoCmpltListLen;
+ break; // "Completion/MaxListLen",
+ case 37: bVal = rSwFlags.bAutoCmpltCollectWords; pValues[nProp].setValue(&bVal, rType); break; // "Completion/CollectWords",
+ case 38: bVal = rSwFlags.bAutoCmpltEndless; pValues[nProp].setValue(&bVal, rType); break; // "Completion/EndlessList",
+ case 39: bVal = rSwFlags.bAutoCmpltAppendBlanc; pValues[nProp].setValue(&bVal, rType); break; // "Completion/AppendBlank",
+ case 40: bVal = rSwFlags.bAutoCmpltShowAsTip; pValues[nProp].setValue(&bVal, rType); break; // "Completion/ShowAsTip",
+ case 41:
+ pValues[nProp] <<= (sal_Int32)rSwFlags.nAutoCmpltExpandKey;
+ break; // "Completion/AcceptKey"
+ case 42 :bVal = rSwFlags.bAutoCmpltKeepList; pValues[nProp].setValue(&bVal, rType); break;// "Completion/KeepList"
+ case 43 :
+ pValues[nProp] <<= (sal_Int32)rSwFlags.cByInputBullet;
+ break;// "Format/ByInput/ApplyNumbering/SpecialCharacter/Char",
+ case 44 :
+ pValues[nProp] <<= OUString(rSwFlags.aByInputBulletFont.GetName());
+ break;// "Format/ByInput/ApplyNumbering/SpecialCharacter/Font",
+ case 45 :
+ pValues[nProp] <<= (sal_Int32)rSwFlags.aByInputBulletFont.GetFamily();
+ break;// "Format/ByInput/ApplyNumbering/SpecialCharacter/FontFamily",
+ case 46 :
+ pValues[nProp] <<= (sal_Int32)rSwFlags.aByInputBulletFont.GetCharSet();
+ break;// "Format/ByInput/ApplyNumbering/SpecialCharacter/FontCharset",
+ case 47 :
+ pValues[nProp] <<= (sal_Int32)rSwFlags.aByInputBulletFont.GetPitch();
+ break;// "Format/ByInput/ApplyNumbering/SpecialCharacter/FontPitch",
+ }
+ }
+ PutProperties(aNames, aValues);
+}
+/*-- 12.10.00 11:51:49---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SvxSwAutoCorrCfg::Notify( const Sequence<OUString>& /* aPropertyNames */ )
+{
+ Load(sal_False);
+}
+
+SvxAutoCorrCfg* SvxAutoCorrCfg::Get()
+{
+ if( !pAutoCorrCfg )
+ pAutoCorrCfg = new SvxAutoCorrCfg;
+ return pAutoCorrCfg;
+}
diff --git a/editeng/source/misc/edtdlg.cxx b/editeng/source/misc/edtdlg.cxx
new file mode 100644
index 0000000000..4f589eee7d
--- /dev/null
+++ b/editeng/source/misc/edtdlg.cxx
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: sfxdlg.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <editeng/edtdlg.hxx>
+
+EditAbstractDialogFactory* EditAbstractDialogFactory::Create()
+{
+ return (EditAbstractDialogFactory*) VclAbstractDialogFactory::Create();
+}
diff --git a/editeng/source/misc/forbiddencharacterstable.cxx b/editeng/source/misc/forbiddencharacterstable.cxx
new file mode 100644
index 0000000000..c4d3e158e0
--- /dev/null
+++ b/editeng/source/misc/forbiddencharacterstable.cxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: forbiddencharacterstable.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <editeng/forbiddencharacterstable.hxx>
+
+#include <unotools/localedatawrapper.hxx>
+#include <editeng/unolingu.hxx>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+SvxForbiddenCharactersTable::SvxForbiddenCharactersTable( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMSF, USHORT nISize, USHORT nGrow )
+ : SvxForbiddenCharactersTableImpl( nISize, nGrow )
+{
+ mxMSF = xMSF;
+}
+
+
+SvxForbiddenCharactersTable::~SvxForbiddenCharactersTable()
+{
+ for ( ULONG n = Count(); n; )
+ delete GetObject( --n );
+}
+
+
+
+const com::sun::star::i18n::ForbiddenCharacters* SvxForbiddenCharactersTable::GetForbiddenCharacters( USHORT nLanguage, BOOL bGetDefault ) const
+{
+ ForbiddenCharactersInfo* pInf = Get( nLanguage );
+ if ( !pInf && bGetDefault && mxMSF.is() )
+ {
+ const SvxForbiddenCharactersTableImpl *pConstImpl = dynamic_cast<const SvxForbiddenCharactersTableImpl*>(this);
+ SvxForbiddenCharactersTableImpl* pImpl = const_cast<SvxForbiddenCharactersTableImpl*>(pConstImpl);
+ pInf = new ForbiddenCharactersInfo;
+ pImpl->Insert( nLanguage, pInf );
+
+ pInf->bTemporary = TRUE;
+ LocaleDataWrapper aWrapper( mxMSF, SvxCreateLocale( nLanguage ) );
+ pInf->aForbiddenChars = aWrapper.getForbiddenCharacters();
+ }
+ return pInf ? &pInf->aForbiddenChars : NULL;
+}
+
+
+
+void SvxForbiddenCharactersTable::SetForbiddenCharacters( USHORT nLanguage, const com::sun::star::i18n::ForbiddenCharacters& rForbiddenChars )
+{
+ ForbiddenCharactersInfo* pInf = Get( nLanguage );
+ if ( !pInf )
+ {
+ pInf = new ForbiddenCharactersInfo;
+ Insert( nLanguage, pInf );
+ }
+ pInf->bTemporary = FALSE;
+ pInf->aForbiddenChars = rForbiddenChars;
+}
+
+void SvxForbiddenCharactersTable::ClearForbiddenCharacters( USHORT nLanguage )
+{
+ ForbiddenCharactersInfo* pInf = Get( nLanguage );
+ if ( pInf )
+ {
+ Remove( nLanguage );
+ delete pInf;
+ }
+}
diff --git a/editeng/source/misc/hangulhanja.cxx b/editeng/source/misc/hangulhanja.cxx
new file mode 100644
index 0000000000..7fe2919621
--- /dev/null
+++ b/editeng/source/misc/hangulhanja.cxx
@@ -0,0 +1,1174 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: hangulhanja.cxx,v $
+ * $Revision: 1.20.102.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <editeng/hangulhanja.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/button.hxx>
+#include <unotools/lingucfg.hxx>
+#include <unotools/linguprops.hxx>
+
+#include <set>
+#include <map>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <com/sun/star/i18n/UnicodeScript.hpp>
+#include <com/sun/star/i18n/XTextConversion.hpp>
+#include <com/sun/star/i18n/XExtendedTextConversion.hpp>
+#include <com/sun/star/i18n/TextConversionType.hpp>
+#include <com/sun/star/i18n/TextConversionOption.hpp>
+#include <com/sun/star/i18n/WordType.hpp>
+#include <vcl/stdtext.hxx>
+#include <unotools/charclass.hxx>
+
+#include <editeng/edtdlg.hxx>
+#include <editeng/editrids.hrc>
+#include <editeng/unolingu.hxx>
+
+#define HHC HangulHanjaConversion
+
+//.............................................................................
+namespace editeng
+{
+//.............................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::i18n;
+ using namespace ::com::sun::star::i18n::TextConversionOption;
+ using namespace ::com::sun::star::i18n::TextConversionType;
+ using namespace ::com::sun::star::lang;
+/*
+ using HangulHanjaConversion::ReplacementAction;
+ using HangulHanjaConversion::eExchange;
+ using HangulHanjaConversion::eReplacementBracketed;
+ using HangulHanjaConversion::eOriginalBracketed;
+ using HangulHanjaConversion::eReplacementAbove;
+ using HangulHanjaConversion::eOriginalAbove;
+ using HangulHanjaConversion::eReplacementBelow;
+ using HangulHanjaConversion::eOriginalBelow;
+
+ using HangulHanjaConversion::eHangulToHanja;
+ using HangulHanjaConversion::eHanjaToHangul;
+
+ using HangulHanjaConversion::eSimpleConversion;
+ using HangulHanjaConversion::eHangulBracketed;
+ using HangulHanjaConversion::eHanjaBracketed;
+ using HangulHanjaConversion::eRubyHanjaAbove;
+ using HangulHanjaConversion::eRubyHanjaBelow;
+ using HangulHanjaConversion::eRubyHangulAbove;
+ using HangulHanjaConversion::eRubyHangulBelow;
+
+ using ::com::sun::star::i18n::TextConversionType::TO_HANJA;
+ using ::com::sun::star::i18n::TextConversionType::TO_HANGUL;
+ using ::com::sun::star::i18n::TextConversionOption::CHARACTER_BY_CHARACTER;
+ using ::com::sun::star::i18n::TextConversionOption::NONE;
+*/
+ //=========================================================================
+ //= HangulHanjaConversion_Impl
+ //=========================================================================
+ //using HangulHanjaConversion::ConversionFormat;
+
+ class HangulHanjaConversion_Impl
+ {
+ private:
+ typedef ::std::set< ::rtl::OUString, ::std::less< ::rtl::OUString > > StringBag;
+ typedef ::std::map< ::rtl::OUString, ::rtl::OUString, ::std::less< ::rtl::OUString > > StringMap;
+
+ private:
+ StringBag m_sIgnoreList;
+ StringMap m_aChangeList;
+ static StringMap m_aRecentlyUsedList;
+
+ // general
+ AbstractHangulHanjaConversionDialog* //CHINA001 HangulHanjaConversionDialog*
+ m_pConversionDialog; // the dialog to display for user interaction
+ Window* m_pUIParent; // the parent window for any UI we raise
+ Reference< XMultiServiceFactory >
+ m_xORB; // the service factory to use
+ Reference< XTextConversion >
+ m_xConverter; // the text conversion service
+ Locale m_aSourceLocale; // the locale we're working with
+
+ // additions for Chinese simplified / traditional conversion
+ HHC::ConversionType m_eConvType; // conversion type (Hangul/Hanja, simplified/traditional Chinese,...)
+ LanguageType m_nSourceLang; // just a 'copy' of m_aSourceLocale in order in order to
+ // save the applications from always converting to this
+ // type in their implementations
+ LanguageType m_nTargetLang; // target language of new replacement text
+ const Font* m_pTargetFont; // target font of new replacement text
+ sal_Int32 m_nConvOptions; // text conversion options (as used by 'getConversions')
+ sal_Bool m_bIsInteractive; // specifies if the conversion requires user interaction
+ // (and likeley a specialised dialog) or if it is to run
+ // automatically without any user interaction.
+ // True for Hangul / Hanja conversion
+ // False for Chinese simlified / traditional conversion
+
+ HangulHanjaConversion* m_pAntiImpl; // our "anti-impl" instance
+
+ // options
+ sal_Bool m_bByCharacter; // are we in "by character" mode currently?
+ HHC::ConversionFormat m_eConversionFormat; // the current format for the conversion
+ HHC::ConversionDirection m_ePrimaryConversionDirection; // the primary conversion direction
+ HHC::ConversionDirection m_eCurrentConversionDirection; // the primary conversion direction
+
+ //options from Hangul/Hanja Options dialog (also saved to configuration)
+ bool m_bIgnorePostPositionalWord;
+ bool m_bShowRecentlyUsedFirst;
+ bool m_bAutoReplaceUnique;
+
+ // state
+ ::rtl::OUString m_sCurrentPortion; // the text which we are currently working on
+ LanguageType m_nCurrentPortionLang; // language of m_sCurrentPortion found
+ sal_Int32 m_nCurrentStartIndex; // the start index within m_sCurrentPortion of the current convertible portion
+ sal_Int32 m_nCurrentEndIndex; // the end index (excluding) within m_sCurrentPortion of the current convertible portion
+ sal_Int32 m_nReplacementBaseIndex;// index which ReplaceUnit-calls need to be relative to
+ sal_Int32 m_nCurrentConversionOption;
+ sal_Int16 m_nCurrentConversionType;
+ Sequence< ::rtl::OUString >
+ m_aCurrentSuggestions; // the suggestions for the current unit
+ // (means for the text [m_nCurrentStartIndex, m_nCurrentEndIndex) in m_sCurrentPortion)
+ sal_Bool m_bTryBothDirections; // specifies if other conversion directions should be tried when looking for convertible characters
+
+
+ public:
+ HangulHanjaConversion_Impl(
+ Window* _pUIParent,
+ const Reference< XMultiServiceFactory >& _rxORB,
+ const Locale& _rSourceLocale,
+ const Locale& _rTargetLocale,
+ const Font* _pTargetFont,
+ sal_Int32 _nConvOptions,
+ sal_Bool _bIsInteractive,
+ HangulHanjaConversion* _pAntiImpl );
+
+ public:
+
+ static void SetUseSavedConversionDirectionState( sal_Bool bVal );
+
+ void DoDocumentConversion( );
+
+ inline sal_Bool IsByCharacter( ) const { return m_bByCharacter; }
+
+ inline sal_Bool IsValid() const { return m_xConverter.is(); }
+
+ inline LanguageType GetSourceLang() const { return m_nSourceLang; }
+ inline LanguageType GetTargetLang() const { return m_nTargetLang; }
+ inline const Font * GetTargetFont() const { return m_pTargetFont; }
+ inline sal_Int32 GetConvOptions() const { return m_nConvOptions; }
+ inline sal_Bool IsInteractive() const { return m_bIsInteractive; }
+
+ protected:
+ void createDialog();
+
+ /** continue with the conversion, return <TRUE/> if and only if the complete conversion is done
+ @param _bRepeatCurrentUnit
+ if <TRUE/>, an implNextConvertible will be called initially to advance to the next convertible.
+ if <FALSE/>, the method will initially work with the current convertible unit
+ */
+ sal_Bool ContinueConversion( bool _bRepeatCurrentUnit );
+
+ private:
+ DECL_LINK( OnOptionsChanged, void* );
+ DECL_LINK( OnIgnore, void* );
+ DECL_LINK( OnIgnoreAll, void* );
+ DECL_LINK( OnChange, void* );
+ DECL_LINK( OnChangeAll, void* );
+ DECL_LINK( OnByCharClicked, CheckBox* );
+ DECL_LINK( OnConversionTypeChanged, void* );
+ DECL_LINK( OnFind, void* );
+
+ /** proceed, after the current convertible has been handled
+
+ <p><b>Attention:</b>
+ When returning from this method, the dialog may have been deleted!</p>
+
+ @param _bRepeatCurrentUnit
+ will be passed to the <member>ContinueConversion</member> call
+ */
+ void implProceed( bool _bRepeatCurrentUnit );
+
+ // change the current convertible, and do _not_ proceed
+ void implChange( const ::rtl::OUString& _rChangeInto );
+
+ /** find the next convertible piece of text, with possibly advancing to the next portion
+
+ @see HangulHanjaConversion::GetNextPortion
+ */
+ sal_Bool implNextConvertible( bool _bRepeatUnit );
+
+ /** find the next convertible unit within the current portion
+ @param _bRepeatUnit
+ if <TRUE/>, the search will start at the beginning of the current unit,
+ if <FALSE/>, it will start at the end of the current unit
+ */
+ bool implNextConvertibleUnit( const sal_Int32 _nStartAt );
+
+ /** retrieves the next portion, with setting the index members properly
+ @return
+ <TRUE/> if and only if there is a next portion
+ */
+ bool implRetrieveNextPortion( );
+
+ /** determine the ConversionDirection for m_sCurrentPortion
+ @return
+ <FALSE/> if and only if something went wrong
+ */
+ bool implGetConversionDirectionForCurrentPortion( HHC::ConversionDirection& rDirection );
+
+ /** member m_aCurrentSuggestions and m_nCurrentEndIndex are updated according to the other settings and current dictionaries
+
+ if _bAllowSearchNextConvertibleText is true _nStartAt is used as starting point to search the next
+ convertible text portion. This may result in changing of the member m_nCurrentStartIndex additionally.
+
+ @return
+ <TRUE/> if Suggestions were found
+ */
+ bool implUpdateSuggestions( const bool _bAllowSearchNextConvertibleText=false, const sal_Int32 _nStartAt=-1 );
+
+ /** reads the options from Hangul/Hanja Options dialog that are saved to configuration
+ */
+ void implReadOptionsFromConfiguration();
+
+ /** get the string currently considered to be replaced or ignored
+ */
+ ::rtl::OUString GetCurrentUnit() const;
+
+ /** read options from configuration, update suggestion list and dialog content
+ */
+ void implUpdateData();
+
+ /** get the conversion direction dependent from m_eConvType and m_eCurrentConversionDirection
+ in case of switching the direction is allowed this can be triggered with parameter bSwitchDirection
+ */
+ sal_Int16 implGetConversionType( bool bSwitchDirection=false ) const;
+ };
+
+ //=========================================================================
+ //= HangulHanjaConversion_Impl
+ //=========================================================================
+ //-------------------------------------------------------------------------
+ // static member initialization
+ HangulHanjaConversion_Impl::StringMap HangulHanjaConversion_Impl::m_aRecentlyUsedList = HangulHanjaConversion_Impl::StringMap();
+
+ //-------------------------------------------------------------------------
+ HangulHanjaConversion_Impl::HangulHanjaConversion_Impl( Window* _pUIParent,
+ const Reference< XMultiServiceFactory >& _rxORB,
+ const Locale& _rSourceLocale,
+ const Locale& _rTargetLocale,
+ const Font* _pTargetFont,
+ sal_Int32 _nOptions,
+ sal_Bool _bIsInteractive,
+ HangulHanjaConversion* _pAntiImpl )
+: m_pConversionDialog( NULL )
+, m_pUIParent( _pUIParent )
+, m_xORB( _rxORB )
+, m_aSourceLocale( _rSourceLocale )
+, m_nSourceLang( SvxLocaleToLanguage( _rSourceLocale ) )
+, m_nTargetLang( SvxLocaleToLanguage( _rTargetLocale ) )
+, m_pTargetFont( _pTargetFont )
+, m_bIsInteractive( _bIsInteractive )
+, m_pAntiImpl( _pAntiImpl )
+, m_nCurrentPortionLang( LANGUAGE_NONE )
+, m_nCurrentStartIndex( 0 )
+, m_nCurrentEndIndex( 0 )
+, m_nReplacementBaseIndex( 0 )
+, m_nCurrentConversionOption( TextConversionOption::NONE )
+, m_nCurrentConversionType( -1 ) // not yet known
+, m_bTryBothDirections( sal_True )
+ {
+ implReadOptionsFromConfiguration();
+
+ DBG_ASSERT( m_xORB.is(), "HangulHanjaConversion_Impl::HangulHanjaConversion_Impl: no ORB!" );
+
+ // determine conversion type
+ if (m_nSourceLang == LANGUAGE_KOREAN && m_nTargetLang == LANGUAGE_KOREAN)
+ m_eConvType = HHC::eConvHangulHanja;
+ else if ( (m_nSourceLang == LANGUAGE_CHINESE_TRADITIONAL && m_nTargetLang == LANGUAGE_CHINESE_SIMPLIFIED) ||
+ (m_nSourceLang == LANGUAGE_CHINESE_SIMPLIFIED && m_nTargetLang == LANGUAGE_CHINESE_TRADITIONAL) )
+ m_eConvType = HHC::eConvSimplifiedTraditional;
+ else
+ {
+ DBG_ERROR( "failed to determine conversion type from languages" );
+ }
+
+ // set remaining conversion parameters to their default values
+ m_nConvOptions = _nOptions;
+ m_bByCharacter = 0 != (_nOptions & CHARACTER_BY_CHARACTER);
+ m_eConversionFormat = HHC::eSimpleConversion;
+ m_ePrimaryConversionDirection = HHC::eHangulToHanja; // used for eConvHangulHanja
+ m_eCurrentConversionDirection = HHC::eHangulToHanja; // used for eConvHangulHanja
+
+ if ( m_xORB.is() )
+ {
+ ::rtl::OUString sTextConversionService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.TextConversion" ) );
+ m_xConverter = m_xConverter.query( m_xORB->createInstance( sTextConversionService ) );
+ if ( !m_xConverter.is() )
+ ShowServiceNotAvailableError( m_pUIParent, sTextConversionService, sal_True );
+ }
+
+ }
+
+ //-------------------------------------------------------------------------
+ void HangulHanjaConversion_Impl::createDialog()
+ {
+ DBG_ASSERT( m_bIsInteractive, "createDialog when the conversion should not be interactive?" );
+ if ( m_bIsInteractive && !m_pConversionDialog )
+ {
+ EditAbstractDialogFactory* pFact = EditAbstractDialogFactory::Create();
+ if(pFact)
+ {
+ m_pConversionDialog = pFact->CreateHangulHanjaConversionDialog(m_pUIParent, m_ePrimaryConversionDirection );
+ DBG_ASSERT(m_pConversionDialog, "Dialogdiet fail!");//CHINA001
+
+ m_pConversionDialog->EnableRubySupport( m_pAntiImpl->HasRubySupport() );
+
+ m_pConversionDialog->SetByCharacter( m_bByCharacter );
+ m_pConversionDialog->SetConversionFormat( m_eConversionFormat );
+ m_pConversionDialog->SetConversionDirectionState( m_bTryBothDirections, m_ePrimaryConversionDirection );
+
+ // the handlers
+ m_pConversionDialog->SetOptionsChangedHdl( LINK( this, HangulHanjaConversion_Impl, OnOptionsChanged ) );
+ m_pConversionDialog->SetIgnoreHdl( LINK( this, HangulHanjaConversion_Impl, OnIgnore ) );
+ m_pConversionDialog->SetIgnoreAllHdl( LINK( this, HangulHanjaConversion_Impl, OnIgnoreAll ) );
+ m_pConversionDialog->SetChangeHdl( LINK( this, HangulHanjaConversion_Impl, OnChange ) );
+ m_pConversionDialog->SetChangeAllHdl( LINK( this, HangulHanjaConversion_Impl, OnChangeAll ) );
+ m_pConversionDialog->SetClickByCharacterHdl( LINK( this, HangulHanjaConversion_Impl, OnByCharClicked ) );
+ m_pConversionDialog->SetConversionFormatChangedHdl( LINK( this, HangulHanjaConversion_Impl, OnConversionTypeChanged ) );
+ m_pConversionDialog->SetFindHdl( LINK( this, HangulHanjaConversion_Impl, OnFind ) );
+ }
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ sal_Int16 HangulHanjaConversion_Impl::implGetConversionType( bool bSwitchDirection ) const
+ {
+ sal_Int16 nConversionType = -1;
+ if (m_eConvType == HHC::eConvHangulHanja)
+ nConversionType = HHC::eHangulToHanja == ( m_eCurrentConversionDirection && !bSwitchDirection ) ? TO_HANJA : TO_HANGUL;
+ else if (m_eConvType == HHC::eConvSimplifiedTraditional)
+ nConversionType = LANGUAGE_CHINESE_SIMPLIFIED == m_nTargetLang ? TO_SCHINESE : TO_TCHINESE;
+ DBG_ASSERT( nConversionType != -1, "unexpected conversion type" );
+ return nConversionType;
+ }
+
+ //-------------------------------------------------------------------------
+ bool HangulHanjaConversion_Impl::implUpdateSuggestions( bool _bAllowSearchNextConvertibleText, const sal_Int32 _nStartAt )
+ {
+ // parameters for the converter
+ sal_Int32 nStartSearch = m_nCurrentStartIndex;
+ if( _bAllowSearchNextConvertibleText )
+ nStartSearch = _nStartAt;
+
+ sal_Int32 nLength = m_sCurrentPortion.getLength() - nStartSearch;
+ m_nCurrentConversionType = implGetConversionType();
+ m_nCurrentConversionOption = IsByCharacter() ? CHARACTER_BY_CHARACTER : NONE;
+ if( m_bIgnorePostPositionalWord )
+ m_nCurrentConversionOption = m_nCurrentConversionOption | IGNORE_POST_POSITIONAL_WORD;
+
+ // no need to check both directions for chinese conversion (saves time)
+ if (m_eConvType == HHC::eConvSimplifiedTraditional)
+ m_bTryBothDirections = sal_False;
+
+ sal_Bool bFoundAny = sal_True;
+ try
+ {
+ TextConversionResult aResult = m_xConverter->getConversions(
+ m_sCurrentPortion,
+ nStartSearch,
+ nLength,
+ m_aSourceLocale,
+ m_nCurrentConversionType,
+ m_nCurrentConversionOption
+ );
+ sal_Bool bFoundPrimary = aResult.Boundary.startPos < aResult.Boundary.endPos;
+ bFoundAny = bFoundPrimary;
+
+ if ( m_bTryBothDirections )
+ { // see if we find another convertible when assuming the other direction
+ TextConversionResult aSecondResult = m_xConverter->getConversions(
+ m_sCurrentPortion,
+ nStartSearch,
+ nLength,
+ m_aSourceLocale,
+ implGetConversionType( true ), // switched!
+ m_nCurrentConversionOption
+ );
+ if ( aSecondResult.Boundary.startPos < aSecondResult.Boundary.endPos )
+ { // we indeed found such a convertible
+
+ // in case the first attempt (with the original conversion direction)
+ // didn't find anything
+ if ( !bFoundPrimary
+ // or if the second location is _before_ the first one
+ || ( aSecondResult.Boundary.startPos < aResult.Boundary.startPos )
+ )
+ {
+ // then use the second finding
+ aResult = aSecondResult;
+
+ // our current conversion direction changed now
+ m_eCurrentConversionDirection = ( HHC::eHangulToHanja == m_eCurrentConversionDirection )
+ ? HHC::eHanjaToHangul : HHC::eHangulToHanja;
+ bFoundAny = sal_True;
+ }
+ }
+ }
+
+ if( _bAllowSearchNextConvertibleText )
+ {
+ //this might change the current position
+ m_aCurrentSuggestions = aResult.Candidates;
+ m_nCurrentStartIndex = aResult.Boundary.startPos;
+ m_nCurrentEndIndex = aResult.Boundary.endPos;
+ }
+ else
+ {
+ //the change of starting position is not allowed
+ if( m_nCurrentStartIndex == aResult.Boundary.startPos
+ && aResult.Boundary.endPos != aResult.Boundary.startPos )
+ {
+ m_aCurrentSuggestions = aResult.Candidates;
+ m_nCurrentEndIndex = aResult.Boundary.endPos;
+ }
+ else
+ {
+ m_aCurrentSuggestions.realloc( 0 );
+ if( m_sCurrentPortion.getLength() >= m_nCurrentStartIndex+1 )
+ m_nCurrentEndIndex = m_nCurrentStartIndex+1;
+ }
+ }
+
+ //put recently used string to front:
+ if( m_bShowRecentlyUsedFirst && m_aCurrentSuggestions.getLength()>1 )
+ {
+ ::rtl::OUString sCurrentUnit( GetCurrentUnit() );
+ StringMap::const_iterator aRecentlyUsed = m_aRecentlyUsedList.find( sCurrentUnit );
+ bool bUsedBefore = aRecentlyUsed != m_aRecentlyUsedList.end();
+ if( bUsedBefore && m_aCurrentSuggestions[0] != aRecentlyUsed->second )
+ {
+ sal_Int32 nCount = m_aCurrentSuggestions.getLength();
+ Sequence< ::rtl::OUString > aTmp(nCount);
+ aTmp[0]=aRecentlyUsed->second;
+ sal_Int32 nDiff = 1;
+ for( sal_Int32 n=1; n<nCount; n++)//we had 0 already
+ {
+ if( nDiff && m_aCurrentSuggestions[n-nDiff]==aRecentlyUsed->second )
+ nDiff=0;
+ aTmp[n]=m_aCurrentSuggestions[n-nDiff];
+ }
+ m_aCurrentSuggestions = aTmp;
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_ERROR( "HangulHanjaConversion_Impl::implNextConvertibleUnit: caught an exception!" );
+
+ //!!! at least we want to move on in the text in order
+ //!!! to avoid an endless loop...
+ return false;
+ }
+ return bFoundAny;
+ }
+
+ //-------------------------------------------------------------------------
+ bool HangulHanjaConversion_Impl::implNextConvertibleUnit( const sal_Int32 _nStartAt )
+ {
+ m_aCurrentSuggestions.realloc( 0 );
+
+ // ask the TextConversion service for the next convertible piece of text
+
+ // get current values from dialog
+ if( m_eConvType == HHC::eConvHangulHanja && m_pConversionDialog )
+ {
+ m_bTryBothDirections = m_pConversionDialog->GetUseBothDirections();
+ HHC::ConversionDirection eDialogDirection = HHC::eHangulToHanja;
+ eDialogDirection = m_pConversionDialog->GetDirection( eDialogDirection );
+
+ if( !m_bTryBothDirections && eDialogDirection != m_eCurrentConversionDirection )
+ {
+ m_eCurrentConversionDirection = eDialogDirection;
+ }
+
+ // save curently used value for possible later use
+ m_pAntiImpl->m_bTryBothDirectionsSave = m_bTryBothDirections;
+ m_pAntiImpl->m_ePrimaryConversionDirectionSave = m_eCurrentConversionDirection;
+ }
+
+ bool bFoundAny = implUpdateSuggestions( true, _nStartAt );
+
+ return bFoundAny &&
+ (m_nCurrentStartIndex < m_sCurrentPortion.getLength());
+ }
+
+ //-------------------------------------------------------------------------
+ bool HangulHanjaConversion_Impl::implRetrieveNextPortion( )
+ {
+ sal_Bool bAllowImplicitChanges = m_eConvType == HHC::eConvSimplifiedTraditional;
+
+ m_sCurrentPortion = ::rtl::OUString();
+ m_nCurrentPortionLang = LANGUAGE_NONE;
+ m_pAntiImpl->GetNextPortion( m_sCurrentPortion, m_nCurrentPortionLang, bAllowImplicitChanges );
+ m_nReplacementBaseIndex = 0;
+ m_nCurrentStartIndex = m_nCurrentEndIndex = 0;
+
+ bool bRet = 0 != m_sCurrentPortion.getLength();
+
+ if (m_eConvType == HHC::eConvHangulHanja && m_bTryBothDirections)
+ implGetConversionDirectionForCurrentPortion( m_eCurrentConversionDirection );
+
+ return bRet;
+ }
+
+ //-------------------------------------------------------------------------
+ sal_Bool HangulHanjaConversion_Impl::implNextConvertible( bool _bRepeatUnit )
+ {
+ if ( _bRepeatUnit || ( m_nCurrentEndIndex < m_sCurrentPortion.getLength() ) )
+ {
+ if ( implNextConvertibleUnit(
+ _bRepeatUnit
+ ? ( IsByCharacter() ? m_nCurrentStartIndex : m_nCurrentStartIndex )
+ : m_nCurrentEndIndex
+ ) )
+ return sal_True;
+ }
+
+ // no convertible text in the current portion anymore
+ // -> advance to the next portion
+ do
+ {
+ // next portion
+ if ( implRetrieveNextPortion( ) )
+ { // there is a next portion
+ // -> find the next convertible unit in the current portion
+ if ( implNextConvertibleUnit( 0 ) )
+ return sal_True;
+ }
+ }
+ while ( m_sCurrentPortion.getLength() );
+
+ // no more portions
+ return sal_False;
+ }
+
+ //-------------------------------------------------------------------------
+ ::rtl::OUString HangulHanjaConversion_Impl::GetCurrentUnit() const
+ {
+ DBG_ASSERT( m_nCurrentStartIndex < m_sCurrentPortion.getLength(),
+ "HangulHanjaConversion_Impl::GetCurrentUnit: invalid index into current portion!" );
+ DBG_ASSERT( m_nCurrentEndIndex <= m_sCurrentPortion.getLength(),
+ "HangulHanjaConversion_Impl::GetCurrentUnit: invalid index into current portion!" );
+ DBG_ASSERT( m_nCurrentStartIndex <= m_nCurrentEndIndex,
+ "HangulHanjaConversion_Impl::GetCurrentUnit: invalid interval!" );
+
+ ::rtl::OUString sCurrentUnit = m_sCurrentPortion.copy( m_nCurrentStartIndex, m_nCurrentEndIndex - m_nCurrentStartIndex );
+ return sCurrentUnit;
+ }
+
+ //-------------------------------------------------------------------------
+ sal_Bool HangulHanjaConversion_Impl::ContinueConversion( bool _bRepeatCurrentUnit )
+ {
+ sal_Bool bNeedUserInteraction = sal_False; // when we leave here, do we need user interaction?
+ sal_Bool bDocumentDone = sal_False; // did we already check the whole document?
+
+ while ( !bDocumentDone && !bNeedUserInteraction && implNextConvertible( _bRepeatCurrentUnit ) )
+ {
+ ::rtl::OUString sCurrentUnit( GetCurrentUnit() );
+
+ // do we need to ignore it?
+ sal_Bool bAlwaysIgnoreThis = m_sIgnoreList.end() != m_sIgnoreList.find( sCurrentUnit );
+
+ // do we need to change it?
+ StringMap::const_iterator aChangeListPos = m_aChangeList.find( sCurrentUnit );
+ sal_Bool bAlwaysChangeThis = m_aChangeList.end() != aChangeListPos;
+
+ // do we automatically change this?
+ sal_Bool bAutoChange = m_bAutoReplaceUnique && m_aCurrentSuggestions.getLength() == 1;
+
+ if (!m_bIsInteractive)
+ {
+ // silent conversion (e.g. for simplified/traditional Chinese)...
+ if(m_aCurrentSuggestions.getLength()>0)
+ implChange( m_aCurrentSuggestions.getConstArray()[0] );
+ }
+ else if (bAutoChange)
+ {
+ implChange( m_aCurrentSuggestions.getConstArray()[0] );
+ }
+ else if ( bAlwaysChangeThis )
+ {
+ implChange( aChangeListPos->second );
+ }
+ else if ( !bAlwaysIgnoreThis )
+ {
+ // here we need to ask the user for what to do with the text
+ // for this, allow derivees to highlight the current text unit in a possible document view
+ m_pAntiImpl->HandleNewUnit( m_nCurrentStartIndex - m_nReplacementBaseIndex, m_nCurrentEndIndex - m_nReplacementBaseIndex );
+
+ DBG_ASSERT( m_pConversionDialog, "we should always have a dialog here!" );
+ if( m_pConversionDialog )
+ m_pConversionDialog->SetCurrentString( sCurrentUnit, m_aCurrentSuggestions );
+
+ // do not look for the next convertible: We have to wait for the user to interactivly
+ // decide what happens with the current convertible
+ bNeedUserInteraction = sal_True;
+ }
+ }
+
+ /*
+ if ( bDocumentDone )
+ return sal_True; // we explicitly know that the complete document is done
+ else if ( bNeedUserInteraction )
+ return sal_False; // the doc is not done, we found a convertible, but need the user to decide
+ else
+ return sal_True; // we did not find a next convertible, so the document is implicitly done
+ */
+
+ return bDocumentDone || !bNeedUserInteraction;
+ }
+
+ //-------------------------------------------------------------------------
+ bool HangulHanjaConversion_Impl::implGetConversionDirectionForCurrentPortion( HHC::ConversionDirection& rDirection )
+ {
+ // - For eConvHangulHanja the direction is determined by
+ // the first encountered Korean character.
+ // - For eConvSimplifiedTraditional the conversion direction
+ // is already specified by the source language.
+
+ bool bSuccess = true;
+
+ if (m_eConvType == HHC::eConvHangulHanja)
+ {
+ bSuccess = false;
+ try
+ {
+ // get the break iterator service
+ ::rtl::OUString sBreakIteratorService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.BreakIterator" ) );
+ Reference< XInterface > xBI( m_xORB->createInstance( ::rtl::OUString( sBreakIteratorService ) ) );
+ Reference< XBreakIterator > xBreakIter( xBI, UNO_QUERY );
+ if ( !xBreakIter.is() )
+ {
+ ShowServiceNotAvailableError( m_pUIParent, sBreakIteratorService, sal_True );
+ }
+ else
+ {
+ sal_Int32 nNextAsianScript = xBreakIter->beginOfScript( m_sCurrentPortion, m_nCurrentStartIndex, com::sun::star::i18n::ScriptType::ASIAN );
+ if ( -1 == nNextAsianScript )
+ nNextAsianScript = xBreakIter->nextScript( m_sCurrentPortion, m_nCurrentStartIndex, com::sun::star::i18n::ScriptType::ASIAN );
+ if ( ( nNextAsianScript >= m_nCurrentStartIndex ) && ( nNextAsianScript < m_sCurrentPortion.getLength() ) )
+ { // found asian text
+
+ // determine if it's Hangul
+ CharClass aCharClassificaton( m_xORB, m_aSourceLocale );
+ sal_Int16 nScript = aCharClassificaton.getScript( m_sCurrentPortion, sal::static_int_cast< USHORT >(nNextAsianScript) );
+ if ( ( UnicodeScript_kHangulJamo == nScript )
+ || ( UnicodeScript_kHangulCompatibilityJamo == nScript )
+ || ( UnicodeScript_kHangulSyllable == nScript )
+ )
+ {
+ rDirection = HHC::eHangulToHanja;
+ }
+ else
+ {
+ rDirection = HHC::eHanjaToHangul;
+ }
+
+ bSuccess = true;
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_ERROR( "HangulHanjaConversion_Impl::implGetConversionDirectionForCurrentPortion: caught an exception!" );
+ }
+ }
+
+ return bSuccess;
+ }
+
+ //-------------------------------------------------------------------------
+ void HangulHanjaConversion_Impl::DoDocumentConversion( )
+ {
+ // clear the change-all list - it's to be re-initialized for every single document
+ {
+ StringMap aEmpty;
+ m_aChangeList.swap( aEmpty );
+ }
+
+ // first of all, we need to guess the direction of our conversion - it is determined by the first
+ // hangul or hanja character in the first text
+ if ( !implRetrieveNextPortion() )
+ {
+ DBG_WARNING( "HangulHanjaConversion_Impl::DoDocumentConversion: why did you call me if you do have nothing to convert?" );
+ // nothing to do
+ return;
+ }
+ if( m_eConvType == HHC::eConvHangulHanja )
+ {
+ //init conversion direction from saved value
+ HHC::ConversionDirection eDirection = HHC::eHangulToHanja;
+ if(!implGetConversionDirectionForCurrentPortion( eDirection ))
+ // something went wrong, has already been asserted
+ return;
+
+ if (m_pAntiImpl->IsUseSavedConversionDirectionState())
+ {
+ m_ePrimaryConversionDirection = m_pAntiImpl->m_ePrimaryConversionDirectionSave;
+ m_bTryBothDirections = m_pAntiImpl->m_bTryBothDirectionsSave;
+ if( m_bTryBothDirections )
+ m_eCurrentConversionDirection = eDirection;
+ else
+ m_eCurrentConversionDirection = m_ePrimaryConversionDirection;
+ }
+ else
+ {
+ m_ePrimaryConversionDirection = eDirection;
+ m_eCurrentConversionDirection = eDirection;
+ }
+ }
+
+ if (m_bIsInteractive && m_eConvType == HHC::eConvHangulHanja)
+ {
+ //always open dialog if at least having a hangul or hanja text portion
+ createDialog();
+ if(m_pAntiImpl->IsUseSavedConversionDirectionState())
+ ContinueConversion( sal_False );
+ else
+ implUpdateData();
+ m_pConversionDialog->Execute();
+ DELETEZ( m_pConversionDialog );
+ }
+ else
+ {
+#ifdef DBG_UTIL
+ sal_Bool bCompletelyDone =
+#endif
+ ContinueConversion( sal_False );
+ DBG_ASSERT( bCompletelyDone, "HangulHanjaConversion_Impl::DoDocumentConversion: ContinueConversion should have returned true here!" );
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ void HangulHanjaConversion_Impl::implProceed( bool _bRepeatCurrentUnit )
+ {
+ if ( ContinueConversion( _bRepeatCurrentUnit ) )
+ { // we're done with the whole document
+ DBG_ASSERT( !m_bIsInteractive || m_pConversionDialog, "HangulHanjaConversion_Impl::implProceed: we should not reach this here without dialog!" );
+ if ( m_pConversionDialog )
+ m_pConversionDialog->EndDialog( RET_OK );
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ void HangulHanjaConversion_Impl::implChange( const ::rtl::OUString& _rChangeInto )
+ {
+ if( !_rChangeInto.getLength() )
+ return;
+
+ // translate the conversion format into a replacement action
+ // this translation depends on whether we have a Hangul original, or a Hanja original
+
+ HHC::ReplacementAction eAction( HHC::eExchange );
+
+ if (m_eConvType == HHC::eConvHangulHanja)
+ {
+ // is the original we're about to change in Hangul?
+ sal_Bool bOriginalIsHangul = HHC::eHangulToHanja == m_eCurrentConversionDirection;
+
+ switch ( m_eConversionFormat )
+ {
+ case HHC::eSimpleConversion: eAction = HHC::eExchange; break;
+ case HHC::eHangulBracketed: eAction = bOriginalIsHangul ? HHC::eOriginalBracketed : HHC::eReplacementBracketed; break;
+ case HHC::eHanjaBracketed: eAction = bOriginalIsHangul ? HHC::eReplacementBracketed : HHC::eOriginalBracketed; break;
+ case HHC::eRubyHanjaAbove: eAction = bOriginalIsHangul ? HHC::eReplacementAbove : HHC::eOriginalAbove; break;
+ case HHC::eRubyHanjaBelow: eAction = bOriginalIsHangul ? HHC::eReplacementBelow : HHC::eOriginalBelow; break;
+ case HHC::eRubyHangulAbove: eAction = bOriginalIsHangul ? HHC::eOriginalAbove : HHC::eReplacementAbove; break;
+ case HHC::eRubyHangulBelow: eAction = bOriginalIsHangul ? HHC::eOriginalBelow : HHC::eReplacementBelow; break;
+ default:
+ DBG_ERROR( "HangulHanjaConversion_Impl::implChange: invalid/unexpected conversion format!" );
+ }
+ }
+
+ // the proper indicies (the wrapper implementation needs indicies relative to the
+ // previous replacement)
+ DBG_ASSERT( ( m_nReplacementBaseIndex <= m_nCurrentStartIndex ) && ( m_nReplacementBaseIndex <= m_nCurrentEndIndex ),
+ "HangulHanjaConversion_Impl::implChange: invalid replacement base!" );
+
+ sal_Int32 nStartIndex = m_nCurrentStartIndex - m_nReplacementBaseIndex;
+ sal_Int32 nEndIndex = m_nCurrentEndIndex - m_nReplacementBaseIndex;
+
+ //remind this decision
+ m_aRecentlyUsedList[ GetCurrentUnit() ] = _rChangeInto;
+
+ LanguageType *pNewUnitLang = 0;
+ LanguageType nNewUnitLang = LANGUAGE_NONE;
+ if (m_eConvType == HHC::eConvSimplifiedTraditional)
+ {
+ // check if language needs to be changed
+ if ( m_pAntiImpl->GetTargetLanguage() == LANGUAGE_CHINESE_TRADITIONAL &&
+ !m_pAntiImpl->IsTraditional( m_nCurrentPortionLang ))
+ nNewUnitLang = LANGUAGE_CHINESE_TRADITIONAL;
+ else if ( m_pAntiImpl->GetTargetLanguage() == LANGUAGE_CHINESE_SIMPLIFIED &&
+ !m_pAntiImpl->IsSimplified( m_nCurrentPortionLang ))
+ nNewUnitLang = LANGUAGE_CHINESE_SIMPLIFIED;
+ if (nNewUnitLang != LANGUAGE_NONE)
+ pNewUnitLang = &nNewUnitLang;
+ }
+
+ // according to FT we should not (yet) bother about Hangul/Hanja conversion here
+ //
+ // aOffsets is needed in ReplaceUnit below in order to to find out
+ // exactly which characters are really changed in order to keep as much
+ // from attributation for the text as possible.
+ Sequence< sal_Int32 > aOffsets;
+ Reference< XExtendedTextConversion > xExtConverter( m_xConverter, UNO_QUERY );
+ if (m_eConvType == HHC::eConvSimplifiedTraditional && xExtConverter.is())
+ {
+ try
+ {
+ ::rtl::OUString aConvText = xExtConverter->getConversionWithOffset(
+ m_sCurrentPortion,
+ m_nCurrentStartIndex,
+ m_nCurrentEndIndex - m_nCurrentStartIndex,
+ m_aSourceLocale,
+ m_nCurrentConversionType,
+ m_nCurrentConversionOption,
+ aOffsets
+ );
+ }
+ catch( const Exception& )
+ {
+ DBG_ERROR( "HangulHanjaConversion_Impl::implChange: caught unexpected exception!" );
+ aOffsets.realloc(0);
+ }
+ }
+
+ // do the replacement
+ m_pAntiImpl->ReplaceUnit( nStartIndex, nEndIndex, m_sCurrentPortion,
+ _rChangeInto, aOffsets, eAction, pNewUnitLang );
+
+
+ // adjust the replacement base
+ m_nReplacementBaseIndex = m_nCurrentEndIndex;
+ }
+
+ //-------------------------------------------------------------------------
+ void HangulHanjaConversion_Impl::implReadOptionsFromConfiguration()
+ {
+ SvtLinguConfig aLngCfg;
+ aLngCfg.GetProperty( UPH_IS_IGNORE_POST_POSITIONAL_WORD ) >>= m_bIgnorePostPositionalWord;
+ aLngCfg.GetProperty( UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST ) >>= m_bShowRecentlyUsedFirst;
+ aLngCfg.GetProperty( UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES ) >>= m_bAutoReplaceUnique;
+ }
+
+ //-------------------------------------------------------------------------
+ void HangulHanjaConversion_Impl::implUpdateData()
+ {
+ implReadOptionsFromConfiguration();
+ implUpdateSuggestions();
+
+ if(m_pConversionDialog)
+ {
+ ::rtl::OUString sCurrentUnit( GetCurrentUnit() );
+
+ m_pConversionDialog->SetCurrentString( sCurrentUnit, m_aCurrentSuggestions );
+ m_pConversionDialog->FocusSuggestion();
+ }
+
+ m_pAntiImpl->HandleNewUnit( m_nCurrentStartIndex - m_nReplacementBaseIndex, m_nCurrentEndIndex - m_nReplacementBaseIndex );
+ }
+
+ //-------------------------------------------------------------------------
+ IMPL_LINK( HangulHanjaConversion_Impl, OnOptionsChanged, void*, EMPTYARG )
+ {
+ //options and dictionaries might have been changed
+ //-> update our internal settings and the dialog
+ implUpdateData();
+
+ return 0L;
+ }
+
+ //-------------------------------------------------------------------------
+ IMPL_LINK( HangulHanjaConversion_Impl, OnIgnore, void*, EMPTYARG )
+ {
+ // simply ignore, and proceed
+ implProceed( sal_False );
+ return 0L;
+ }
+
+ //-------------------------------------------------------------------------
+ IMPL_LINK( HangulHanjaConversion_Impl, OnIgnoreAll, void*, EMPTYARG )
+ {
+ DBG_ASSERT( m_pConversionDialog, "HangulHanjaConversion_Impl::OnIgnoreAll: no dialog! How this?" );
+
+ if ( m_pConversionDialog )
+ {
+ String sCurrentUnit = m_pConversionDialog->GetCurrentString();
+ DBG_ASSERT( m_sIgnoreList.end() == m_sIgnoreList.find( sCurrentUnit ),
+ "HangulHanjaConversion_Impl, OnIgnoreAll: shouldn't this have been ignored before" );
+
+ // put into the "ignore all" list
+ m_sIgnoreList.insert( sCurrentUnit );
+
+ // and proceed
+ implProceed( sal_False );
+ }
+
+ return 0L;
+ }
+
+ //-------------------------------------------------------------------------
+ IMPL_LINK( HangulHanjaConversion_Impl, OnChange, void*, EMPTYARG )
+ {
+ // change
+ DBG_ASSERT( m_pConversionDialog, "we should always have a dialog here!" );
+ if( m_pConversionDialog )
+ implChange( m_pConversionDialog->GetCurrentSuggestion( ) );
+ // and proceed
+ implProceed( sal_False );
+
+ return 0L;
+ }
+
+ //-------------------------------------------------------------------------
+ IMPL_LINK( HangulHanjaConversion_Impl, OnChangeAll, void*, EMPTYARG )
+ {
+ DBG_ASSERT( m_pConversionDialog, "HangulHanjaConversion_Impl::OnChangeAll: no dialog! How this?" );
+ if ( m_pConversionDialog )
+ {
+ ::rtl::OUString sCurrentUnit( m_pConversionDialog->GetCurrentString() );
+ ::rtl::OUString sChangeInto( m_pConversionDialog->GetCurrentSuggestion( ) );
+
+ if( sChangeInto.getLength() )
+ {
+ // change the current occurence
+ implChange( sChangeInto );
+
+ // put into the "change all" list
+ m_aChangeList.insert( StringMap::value_type( sCurrentUnit, sChangeInto ) );
+ }
+
+ // and proceed
+ implProceed( sal_False );
+ }
+
+ return 0L;
+ }
+
+ //-------------------------------------------------------------------------
+ IMPL_LINK( HangulHanjaConversion_Impl, OnByCharClicked, CheckBox*, _pBox )
+ {
+ m_bByCharacter = _pBox->IsChecked();
+
+ // continue conversion, without advancing to the next unit, but instead continuing with the current unit
+ implProceed( sal_True );
+ return 0L;
+ }
+
+ //-------------------------------------------------------------------------
+ IMPL_LINK( HangulHanjaConversion_Impl, OnConversionTypeChanged, void*, EMPTYARG )
+ {
+ DBG_ASSERT( m_pConversionDialog, "we should always have a dialog here!" );
+ if( m_pConversionDialog )
+ m_eConversionFormat = m_pConversionDialog->GetConversionFormat( );
+ return 0L;
+ }
+
+ //-------------------------------------------------------------------------
+ IMPL_LINK( HangulHanjaConversion_Impl, OnFind, void*, EMPTYARG )
+ {
+ DBG_ASSERT( m_pConversionDialog, "HangulHanjaConversion_Impl::OnFind: where did this come from?" );
+ if ( m_pConversionDialog )
+ {
+ try
+ {
+ ::rtl::OUString sNewOriginal( m_pConversionDialog->GetCurrentSuggestion( ) );
+ Sequence< ::rtl::OUString > aSuggestions;
+
+ DBG_ASSERT( m_xConverter.is(), "HangulHanjaConversion_Impl::OnFind: no converter!" );
+ TextConversionResult aToHanja = m_xConverter->getConversions(
+ sNewOriginal,
+ 0, sNewOriginal.getLength(),
+ m_aSourceLocale,
+ TextConversionType::TO_HANJA,
+ TextConversionOption::NONE
+ );
+ TextConversionResult aToHangul = m_xConverter->getConversions(
+ sNewOriginal,
+ 0, sNewOriginal.getLength(),
+ m_aSourceLocale,
+ TextConversionType::TO_HANGUL,
+ TextConversionOption::NONE
+ );
+
+ bool bHaveToHanja = ( aToHanja.Boundary.startPos < aToHanja.Boundary.endPos );
+ bool bHaveToHangul = ( aToHangul.Boundary.startPos < aToHangul.Boundary.endPos );
+
+ TextConversionResult* pResult = NULL;
+ if ( bHaveToHanja && bHaveToHangul )
+ { // it found convertibles in both directions -> use the first
+ if ( aToHangul.Boundary.startPos < aToHanja.Boundary.startPos )
+ pResult = &aToHangul;
+ else
+ pResult = &aToHanja;
+ }
+ else if ( bHaveToHanja )
+ { // only found toHanja
+ pResult = &aToHanja;
+ }
+ else
+ { // only found toHangul
+ pResult = &aToHangul;
+ }
+ if ( pResult )
+ aSuggestions = pResult->Candidates;
+
+ m_pConversionDialog->SetCurrentString( sNewOriginal, aSuggestions, false );
+ m_pConversionDialog->FocusSuggestion();
+ }
+ catch( const Exception& )
+ {
+ DBG_ERROR( "HangulHanjaConversion_Impl::OnFind: caught an exception!" );
+ }
+ }
+ return 0L;
+ }
+
+ //=========================================================================
+ //= HangulHanjaConversion
+ //=========================================================================
+ //-------------------------------------------------------------------------
+
+ // static member initialization
+ sal_Bool HangulHanjaConversion::m_bUseSavedValues = sal_False;
+ sal_Bool HangulHanjaConversion::m_bTryBothDirectionsSave = sal_False;
+ HHC::ConversionDirection HangulHanjaConversion::m_ePrimaryConversionDirectionSave = HHC::eHangulToHanja;
+
+ //-------------------------------------------------------------------------
+ HangulHanjaConversion::HangulHanjaConversion( Window* _pUIParent,
+ const Reference< XMultiServiceFactory >& _rxORB,
+ const Locale& _rSourceLocale, const Locale& _rTargetLocale,
+ const Font* _pTargetFont,
+ sal_Int32 _nOptions, sal_Bool _bIsInteractive)
+ :m_pImpl( new HangulHanjaConversion_Impl( _pUIParent, _rxORB, _rSourceLocale, _rTargetLocale, _pTargetFont, _nOptions, _bIsInteractive, this ) )
+ {
+ }
+
+ //-------------------------------------------------------------------------
+ HangulHanjaConversion::~HangulHanjaConversion( )
+ {
+ }
+
+ //-------------------------------------------------------------------------
+ void HangulHanjaConversion::SetUseSavedConversionDirectionState( sal_Bool bVal )
+ {
+ m_bUseSavedValues = bVal;
+ }
+
+ //-------------------------------------------------------------------------
+ sal_Bool HangulHanjaConversion::IsUseSavedConversionDirectionState()
+ {
+ return m_bUseSavedValues;
+ }
+
+ //-------------------------------------------------------------------------
+ LanguageType HangulHanjaConversion::GetSourceLanguage( ) const
+ {
+ return m_pImpl->GetSourceLang();
+ }
+
+ //-------------------------------------------------------------------------
+ LanguageType HangulHanjaConversion::GetTargetLanguage( ) const
+ {
+ return m_pImpl->GetTargetLang();
+ }
+
+ //-------------------------------------------------------------------------
+ const Font * HangulHanjaConversion::GetTargetFont( ) const
+ {
+ return m_pImpl->GetTargetFont();
+ }
+
+ //-------------------------------------------------------------------------
+ sal_Int32 HangulHanjaConversion::GetConversionOptions( ) const
+ {
+ return m_pImpl->GetConvOptions();
+ }
+
+ //-------------------------------------------------------------------------
+ sal_Bool HangulHanjaConversion::IsInteractive( ) const
+ {
+ return m_pImpl->IsInteractive();
+ }
+
+ //-------------------------------------------------------------------------
+ void HangulHanjaConversion::HandleNewUnit( const sal_Int32, const sal_Int32 )
+ {
+ // nothing to do, only derived classes need this.
+ }
+
+ //-------------------------------------------------------------------------
+ void HangulHanjaConversion::GetNextPortion( ::rtl::OUString&, LanguageType&, sal_Bool )
+ {
+ DBG_ERROR( "HangulHanjaConversion::GetNextPortion: to be overridden!" );
+ }
+
+ //-------------------------------------------------------------------------
+ void HangulHanjaConversion::ReplaceUnit(
+ const sal_Int32, const sal_Int32,
+ const ::rtl::OUString&,
+ const ::rtl::OUString&,
+ const ::com::sun::star::uno::Sequence< sal_Int32 > &,
+ ReplacementAction,
+ LanguageType * )
+ {
+ DBG_ERROR( "HangulHanjaConversion::ReplaceUnit: to be overridden!" );
+ }
+
+ //-------------------------------------------------------------------------
+ sal_Bool HangulHanjaConversion::HasRubySupport() const
+ {
+ DBG_ERROR( "HangulHanjaConversion::HasRubySupport: to be overridden!" );
+ return sal_False;
+ }
+
+ //-------------------------------------------------------------------------
+ void HangulHanjaConversion::ConvertDocument()
+ {
+ if ( m_pImpl->IsValid() )
+ m_pImpl->DoDocumentConversion( );
+ }
+
+//.............................................................................
+} // namespace svx
+//.............................................................................
+
diff --git a/editeng/source/misc/lingu.src b/editeng/source/misc/lingu.src
new file mode 100644
index 0000000000..a3325aedc0
--- /dev/null
+++ b/editeng/source/misc/lingu.src
@@ -0,0 +1,107 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: lingu.src,v $
+ * $Revision: 1.33 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+ // include ---------------------------------------------------------------
+#include <editeng/editrids.hrc>
+ // pragma ----------------------------------------------------------------
+
+ // QueryBoxen ---------------------------------------------------------------
+QueryBox RID_SVXQB_CONTINUE
+{
+ BUTTONS = WB_YES_NO ;
+ DEFBUTTON = WB_DEF_YES ;
+ /* ### ACHTUNG: Neuer Text in Resource? Überprüfung am Anfang des Dokumentes fortsetzen? : šberpr³fung am Anfang des Dokumentes fortsetzen? */
+ /* ### ACHTUNG: Neuer Text in Resource? Überprüfung am Anfang des Dokumentes fortsetzen? : šberpr³fung am Anfang des Dokumentes fortsetzen? */
+ Message [ en-US ] = "Continue checking at beginning of document?" ;
+};
+QueryBox RID_SVXQB_BW_CONTINUE
+{
+ BUTTONS = WB_YES_NO ;
+ DEFBUTTON = WB_DEF_YES ;
+ /* ### ACHTUNG: Neuer Text in Resource? Überprüfung am Ende des Dokumentes fortsetzen? : šberpr³fung am Ende des Dokumentes fortsetzen? */
+ /* ### ACHTUNG: Neuer Text in Resource? Überprüfung am Ende des Dokumentes fortsetzen? : šberpr³fung am Ende des Dokumentes fortsetzen? */
+ Message [ en-US ] = "Continue checking at end of document?" ;
+};
+String RID_SVXSTR_HMERR_THESAURUS
+{
+ /* ### ACHTUNG: Neuer Text in Resource? Ein Thesaurus für die eingestellte Sprache ist nicht verfügbar. \nÜberprüfen Sie bitte Ihre Installation und installieren Sie \ngegebenenfalls die gewünschte Sprache : Ein Thesaurus f³r die eingestellte Sprache ist nicht verf³gbar. \nšberpr³fen Sie bitte Ihre Installation und installieren Sie \ngegebenenfalls die gew³nschte Sprache */
+ /* ### ACHTUNG: Neuer Text in Resource? Ein Thesaurus für die eingestellte Sprache ist nicht verfügbar. \nÜberprüfen Sie bitte Ihre Installation und installieren Sie \ngegebenenfalls die gewünschte Sprache : Ein Thesaurus f³r die eingestellte Sprache ist nicht verf³gbar. \nšberpr³fen Sie bitte Ihre Installation und installieren Sie \ngegebenenfalls die gew³nschte Sprache */
+ Text [ en-US ] = "No thesaurus is available for the selected language. \nPlease check your installation and install the desired language\n" ;
+};
+String RID_SVXSTR_DIC_ERR_UNKNOWN
+{
+ Text [ en-US ] = "Word cannot be added to dictionary\ndue to unknown reason.";
+};
+String RID_SVXSTR_DIC_ERR_FULL
+{
+ Text [ en-US ] = "The dictionary is already full.";
+};
+String RID_SVXSTR_DIC_ERR_READONLY
+{
+ Text [ en-US ] = "The dictionary is read-only.";
+};
+
+ // ********************************************************************** EOF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/editeng/source/misc/makefile.mk b/editeng/source/misc/makefile.mk
new file mode 100644
index 0000000000..7eb2d80447
--- /dev/null
+++ b/editeng/source/misc/makefile.mk
@@ -0,0 +1,71 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.18 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME=editeng
+TARGET=misc
+
+#PROJECTPCH4DLL=TRUE
+#PROJECTPCH=eeng_pch
+#PROJECTPCHSOURCE=eeng_pch
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Allgemein ----------------------------------------------------------
+
+.IF "$(editdebug)" != "" || "$(EDITDEBUG)" != ""
+CDEFS+=-DEDITDEBUG
+.ENDIF
+
+SLOFILES = \
+ $(SLO)$/edtdlg.obj \
+ $(SLO)$/unolingu.obj \
+ $(SLO)$/acorrcfg.obj \
+ $(SLO)$/forbiddencharacterstable.obj \
+ $(SLO)$/hangulhanja.obj \
+ $(SLO)$/splwrap.obj \
+ $(SLO)$/svxacorr.obj \
+ $(SLO)$/SvXMLAutoCorrectExport.obj \
+ $(SLO)$/SvXMLAutoCorrectImport.obj \
+ $(SLO)$/swafopt.obj \
+ $(SLO)$/txtrange.obj
+
+SRS1NAME=misc
+SRC1FILES = \
+ lingu.src
+
+.INCLUDE : target.mk
+
diff --git a/editeng/source/misc/splwrap.cxx b/editeng/source/misc/splwrap.cxx
new file mode 100644
index 0000000000..bf3ae7d092
--- /dev/null
+++ b/editeng/source/misc/splwrap.cxx
@@ -0,0 +1,637 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: splwrap.cxx,v $
+ * $Revision: 1.19 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include<rtl/ustring.hxx>
+#include <tools/shl.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/msgbox.hxx>
+#include <tools/debug.hxx>
+#include <svtools/langtab.hxx>
+
+#ifndef __RSC
+#include <tools/errinf.hxx>
+#endif
+//#include <svxerr.hxx>
+//#include <dlgutil.hxx>
+#include <editeng/unolingu.hxx>
+#include <sfx2/sfxuno.hxx>
+#include <linguistic/lngprops.hxx>
+#include <com/sun/star/frame/XStorable.hpp>
+
+#include <map>
+
+#include <editeng/svxenum.hxx>
+#include <editeng/splwrap.hxx> // Der Wrapper
+#include <editeng/edtdlg.hxx>
+#include <editeng/eerdll.hxx>
+#include <editeng/editrids.hrc>
+#include <editeng/editids.hrc>
+
+#define WAIT_ON() if(pWin != NULL) { pWin->EnterWait(); }
+
+#define WAIT_OFF() if(pWin != NULL) { pWin->LeaveWait(); }
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::linguistic2;
+
+
+// misc functions ---------------------------------------------
+
+void SvxPrepareAutoCorrect( String &rOldText, String &rNewText )
+{
+ // This function should be used to strip (or add) trailing '.' from
+ // the strings before passing them on to the autocorrect function in
+ // order that the autocorrect function will hopefully
+ // works properly with normal words and abbreviations (with trailing '.')
+ // independ of if they are at the end of the sentence or not.
+ //
+ // rOldText: text to be replaced
+ // rNewText: replacement text
+
+ xub_StrLen nOldLen = rOldText.Len(),
+ nNewLen = rNewText.Len();
+ if (nOldLen && nNewLen)
+ {
+ sal_Bool bOldHasDot = sal_Unicode( '.' ) == rOldText.GetChar( nOldLen - 1 ),
+ bNewHasDot = sal_Unicode( '.' ) == rNewText.GetChar( nNewLen - 1 );
+ if (bOldHasDot && !bNewHasDot
+ /*this is: !(bOldHasDot && bNewHasDot) && bOldHasDot*/)
+ rOldText.Erase( nOldLen - 1 );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+#define SVX_LANG_NEED_CHECK 0
+#define SVX_LANG_OK 1
+#define SVX_LANG_MISSING 2
+#define SVX_LANG_MISSING_DO_WARN 3
+
+#define SVX_FLAGS_NEW
+
+
+struct lt_LanguageType
+{
+ bool operator()( LanguageType n1, LanguageType n2 ) const
+ {
+ return n1 < n2;
+ }
+};
+
+typedef std::map< LanguageType, USHORT, lt_LanguageType > LangCheckState_map_t;
+
+static LangCheckState_map_t & GetLangCheckState()
+{
+ static LangCheckState_map_t aLangCheckState;
+ return aLangCheckState;
+}
+
+void SvxSpellWrapper::ShowLanguageErrors()
+{
+ // display message boxes for languages not available for
+ // spellchecking or hyphenation
+ LangCheckState_map_t &rLCS = GetLangCheckState();
+ LangCheckState_map_t::iterator aIt( rLCS.begin() );
+ while (aIt != rLCS.end())
+ {
+ LanguageType nLang = aIt->first;
+ sal_uInt16 nVal = aIt->second;
+ sal_uInt16 nTmpSpell = nVal & 0x00FF;
+ sal_uInt16 nTmpHyph = (nVal >> 8) & 0x00FF;
+
+ if (SVX_LANG_MISSING_DO_WARN == nTmpSpell)
+ {
+ String aErr( SvtLanguageTable::GetLanguageString( nLang ) );
+ ErrorHandler::HandleError(
+ *new StringErrorInfo( ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aErr ) );
+ nTmpSpell = SVX_LANG_MISSING;
+ }
+ if (SVX_LANG_MISSING_DO_WARN == nTmpHyph)
+ {
+ String aErr( SvtLanguageTable::GetLanguageString( nLang ) );
+ ErrorHandler::HandleError(
+ *new StringErrorInfo( ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aErr ) );
+ nTmpHyph = SVX_LANG_MISSING;
+ }
+
+ rLCS[ nLang ] = (nTmpHyph << 8) | nTmpSpell;
+ ++aIt;
+ }
+
+}
+
+SvxSpellWrapper::~SvxSpellWrapper()
+{
+}
+
+/*--------------------------------------------------------------------
+ * Beschreibung: Ctor, die Pruefreihenfolge wird festgelegt
+ *
+ * !bStart && !bOtherCntnt: BODY_END, BODY_START, OTHER
+ * !bStart && bOtherCntnt: OTHER, BODY
+ * bStart && !bOtherCntnt: BODY_END, OTHER
+ * bStart && bOtherCntnt: OTHER
+ *
+ --------------------------------------------------------------------*/
+
+SvxSpellWrapper::SvxSpellWrapper( Window* pWn,
+ Reference< XSpellChecker1 > &xSpellChecker,
+ const sal_Bool bStart, const sal_Bool bIsAllRight,
+ const sal_Bool bOther, const sal_Bool bRevAllow ) :
+
+ pWin ( pWn ),
+ xSpell ( xSpellChecker ),
+ bOtherCntnt ( bOther ),
+ bDialog ( sal_False ),
+ bHyphen ( sal_False ),
+ bAuto ( sal_False ),
+ bStartChk ( bOther ),
+ bRevAllowed ( bRevAllow ),
+ bAllRight ( bIsAllRight )
+{
+ Reference< beans::XPropertySet > xProp( SvxGetLinguPropertySet() );
+ sal_Bool bWrapReverse = xProp.is() ?
+ *(sal_Bool*)xProp->getPropertyValue(
+ ::rtl::OUString::createFromAscii(UPN_IS_WRAP_REVERSE) ).getValue()
+ : sal_False;
+ bReverse = bRevAllow && bWrapReverse;
+ bStartDone = bOther || ( !bReverse && bStart );
+ bEndDone = bReverse && bStart && !bOther;
+}
+
+// -----------------------------------------------------------------------
+
+SvxSpellWrapper::SvxSpellWrapper( Window* pWn,
+ Reference< XHyphenator > &xHyphenator,
+ const sal_Bool bStart, const sal_Bool bOther ) :
+ pWin ( pWn ),
+ xHyph ( xHyphenator ),
+ bOtherCntnt ( bOther ),
+ bDialog ( sal_False ),
+ bHyphen ( sal_False ),
+ bAuto ( sal_False ),
+ bReverse ( sal_False ),
+ bStartDone ( bOther || ( !bReverse && bStart ) ),
+ bEndDone ( bReverse && bStart && !bOther ),
+ bStartChk ( bOther ),
+ bRevAllowed ( sal_False ),
+ bAllRight ( sal_True )
+{
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int16 SvxSpellWrapper::CheckSpellLang(
+ Reference< XSpellChecker1 > xSpell, sal_Int16 nLang)
+{
+ LangCheckState_map_t &rLCS = GetLangCheckState();
+
+ LangCheckState_map_t::iterator aIt( rLCS.find( nLang ) );
+ sal_uInt16 nVal = aIt == rLCS.end() ? SVX_LANG_NEED_CHECK : aIt->second;
+
+ if (aIt == rLCS.end())
+ rLCS[ nLang ] = nVal;
+
+ if (SVX_LANG_NEED_CHECK == (nVal & 0x00FF))
+ {
+ sal_uInt16 nTmpVal = SVX_LANG_MISSING_DO_WARN;
+ if (xSpell.is() && xSpell->hasLanguage( nLang ))
+ nTmpVal = SVX_LANG_OK;
+ nVal &= 0xFF00;
+ nVal |= nTmpVal;
+
+ rLCS[ nLang ] = nVal;
+ }
+
+ return (sal_Int16) nVal;
+}
+
+sal_Int16 SvxSpellWrapper::CheckHyphLang(
+ Reference< XHyphenator > xHyph, sal_Int16 nLang)
+{
+ LangCheckState_map_t &rLCS = GetLangCheckState();
+
+ LangCheckState_map_t::iterator aIt( rLCS.find( nLang ) );
+ sal_uInt16 nVal = aIt == rLCS.end() ? 0 : aIt->second;
+
+ if (aIt == rLCS.end())
+ rLCS[ nLang ] = nVal;
+
+ if (SVX_LANG_NEED_CHECK == ((nVal >> 8) & 0x00FF))
+ {
+ sal_uInt16 nTmpVal = SVX_LANG_MISSING_DO_WARN;
+ if (xHyph.is() && xHyph->hasLocale( SvxCreateLocale( nLang ) ))
+ nTmpVal = SVX_LANG_OK;
+ nVal &= 0x00FF;
+ nVal |= nTmpVal << 8;
+
+ rLCS[ nLang ] = nVal;
+ }
+
+ return (sal_Int16) nVal;
+}
+
+// -----------------------------------------------------------------------
+
+
+void SvxSpellWrapper::SpellStart( SvxSpellArea /*eSpell*/ )
+{ // Hier muessen die notwendigen Vorbereitungen fuer SpellContinue
+} // im uebergebenen Bereich getroffen werden.
+
+// -----------------------------------------------------------------------
+
+
+sal_Bool SvxSpellWrapper::HasOtherCnt()
+{
+ return sal_False; // Gibt es ueberhaupt einen Sonderbereich?
+}
+
+// -----------------------------------------------------------------------
+
+
+sal_Bool SvxSpellWrapper::SpellMore()
+{
+ return sal_False; // Sollen weitere Dokumente geprueft werden?
+}
+
+// -----------------------------------------------------------------------
+
+
+void SvxSpellWrapper::SpellEnd()
+{ // Bereich ist abgeschlossen, ggf. Aufraeumen
+
+ // display error for last language not found
+ ShowLanguageErrors();
+}
+
+// -----------------------------------------------------------------------
+
+
+sal_Bool SvxSpellWrapper::SpellContinue()
+{
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------
+
+void SvxSpellWrapper::AutoCorrect( const String&, const String& )
+{
+}
+
+// -----------------------------------------------------------------------
+
+
+void SvxSpellWrapper::ScrollArea()
+{ // Scrollarea einstellen
+}
+
+// -----------------------------------------------------------------------
+
+
+void SvxSpellWrapper::ChangeWord( const String&, const sal_uInt16 )
+{ // Wort ersetzen
+}
+
+// -----------------------------------------------------------------------
+
+
+String SvxSpellWrapper::GetThesWord()
+{
+ // Welches Wort soll nachgeschlagen werden?
+ return String();
+}
+
+// -----------------------------------------------------------------------
+
+
+void SvxSpellWrapper::ChangeThesWord( const String& )
+{
+ // Wort wg. Thesaurus ersetzen
+}
+
+// -----------------------------------------------------------------------
+
+void SvxSpellWrapper::StartThesaurus( const String &rWord, sal_uInt16 nLanguage )
+{
+ Reference< XThesaurus > xThes( SvxGetThesaurus() );
+ if (!xThes.is())
+ {
+ InfoBox( pWin, EE_RESSTR( RID_SVXSTR_HMERR_THESAURUS ) ).Execute();
+ return;
+ }
+
+ WAIT_ON(); // while looking up for initial word
+ EditAbstractDialogFactory* pFact = EditAbstractDialogFactory::Create();
+ AbstractThesaurusDialog* pDlg = pFact->CreateThesaurusDialog( pWin, xThes, rWord, nLanguage );
+ WAIT_OFF();
+ if ( pDlg->Execute()== RET_OK )
+ {
+ ChangeThesWord( pDlg->GetWord() );
+ }
+ delete pDlg;
+}
+
+// -----------------------------------------------------------------------
+
+void SvxSpellWrapper::ReplaceAll( const String &, sal_Int16 )
+{ // Wort aus der Replace-Liste ersetzen
+}
+
+// -----------------------------------------------------------------------
+
+
+void SvxSpellWrapper::SetLanguage( const sal_uInt16 )
+{ // Sprache aendern
+}
+
+// -----------------------------------------------------------------------
+
+
+void SvxSpellWrapper::InsertHyphen( const sal_uInt16 )
+{ // Hyphen einfuegen bzw. loeschen
+}
+
+// -----------------------------------------------------------------------
+// Pruefung der Dokumentbereiche in der durch die Flags angegebenen Reihenfolge
+
+
+void SvxSpellWrapper::SpellDocument( )
+{
+ if ( bOtherCntnt )
+ {
+ bReverse = sal_False;
+ SpellStart( SVX_SPELL_OTHER );
+ }
+ else
+ {
+ bStartChk = bReverse;
+ SpellStart( bReverse ? SVX_SPELL_BODY_START : SVX_SPELL_BODY_END );
+ }
+
+ if ( FindSpellError() )
+ {
+ Reference< XSpellAlternatives > xAlt( GetLast(), UNO_QUERY );
+ Reference< XHyphenatedWord > xHyphWord( GetLast(), UNO_QUERY );
+
+ Window *pOld = pWin;
+ bDialog = sal_True;
+ if (xHyphWord.is())
+ {
+ EditAbstractDialogFactory* pFact = EditAbstractDialogFactory::Create();
+ AbstractHyphenWordDialog* pDlg = pFact->CreateHyphenWordDialog( pWin,
+ xHyphWord->getWord(),
+ SvxLocaleToLanguage( xHyphWord->getLocale() ),
+ xHyph, this );
+ pWin = pDlg->GetWindow();
+ pDlg->Execute();
+ delete pDlg;
+ }
+ bDialog = sal_False;
+ pWin = pOld;
+ };
+}
+
+// -----------------------------------------------------------------------
+// Naechsten Bereich auswaehlen
+
+
+sal_Bool SvxSpellWrapper::SpellNext( )
+{
+ Reference< beans::XPropertySet > xProp( SvxGetLinguPropertySet() );
+ sal_Bool bWrapReverse = xProp.is() ?
+ *(sal_Bool*)xProp->getPropertyValue(
+ ::rtl::OUString::createFromAscii(UPN_IS_WRAP_REVERSE) ).getValue()
+ : sal_False;
+ sal_Bool bActRev = bRevAllowed && bWrapReverse;
+
+ // bActRev ist die Richtung nach dem Spellen, bReverse die am Anfang.
+ if( bActRev == bReverse )
+ { // Keine Richtungsaenderung, also ist
+ if( bStartChk ) // der gewuenschte Bereich ( bStartChk )
+ bStartDone = sal_True; // vollstaendig abgearbeitet.
+ else
+ bEndDone = sal_True;
+ }
+ else if( bReverse == bStartChk ) // Bei einer Richtungsaenderung kann
+ { // u.U. auch ein Bereich abgearbeitet sein.
+ if( bStartChk ) // Sollte der vordere Teil rueckwaerts gespellt
+ bEndDone = sal_True; // werden und wir kehren unterwegs um, so ist
+ else // der hintere Teil abgearbeitet (und umgekehrt).
+ bStartDone = sal_True;
+ }
+
+ bReverse = bActRev;
+ if( bOtherCntnt && bStartDone && bEndDone ) // Dokument komplett geprueft?
+ {
+ if ( SpellMore() ) // ein weiteres Dokument pruefen?
+ {
+ bOtherCntnt = sal_False;
+ bStartDone = !bReverse;
+ bEndDone = bReverse;
+ SpellStart( SVX_SPELL_BODY );
+ return sal_True;
+ }
+ return sal_False;
+ }
+
+ sal_Bool bGoOn = sal_False;
+
+ if ( bOtherCntnt )
+ {
+ bStartChk = sal_False;
+ SpellStart( SVX_SPELL_BODY );
+ bGoOn = sal_True;
+ }
+ else if ( bStartDone && bEndDone )
+ {
+ sal_Bool bIsSpellSpecial = xProp.is() ?
+ *(sal_Bool*)xProp->getPropertyValue(
+ ::rtl::OUString::createFromAscii(UPN_IS_SPELL_SPECIAL) ).getValue()
+ : sal_False;
+ // Bodybereich erledigt, Frage nach Sonderbereich
+ if( !IsHyphen() && bIsSpellSpecial && HasOtherCnt() )
+ {
+ SpellStart( SVX_SPELL_OTHER );
+ bOtherCntnt = bGoOn = sal_True;
+ }
+ else if ( SpellMore() ) // ein weiteres Dokument pruefen?
+ {
+ bOtherCntnt = sal_False;
+ bStartDone = !bReverse;
+ bEndDone = bReverse;
+ SpellStart( SVX_SPELL_BODY );
+ return sal_True;
+ }
+ }
+ else
+ {
+ // Ein BODY_Bereich erledigt, Frage nach dem anderen BODY_Bereich
+ WAIT_OFF();
+
+// Sobald im Dialog das DontWrapAround gesetzt werden kann, kann der
+// folgende #ifdef-Zweig aktiviert werden ...
+#ifdef USED
+ sal_Bool bDontWrapAround = IsHyphen() ?
+ pSpell->GetOptions() & DONT_WRAPAROUND :
+ pSpell->GetHyphOptions() & HYPH_DONT_WRAPAROUND;
+ if( bDontWrapAround )
+#else
+ sal_uInt16 nResId = bReverse ? RID_SVXQB_BW_CONTINUE : RID_SVXQB_CONTINUE;
+ QueryBox aBox( pWin, EditResId( nResId ) );
+ if ( aBox.Execute() != RET_YES )
+#endif
+
+ {
+ // Verzicht auf den anderen Bereich, ggf. Frage nach Sonderbereich
+ WAIT_ON();
+ bStartDone = bEndDone = sal_True;
+ return SpellNext();
+ }
+ else
+ {
+ bStartChk = !bStartDone;
+ SpellStart( bStartChk ? SVX_SPELL_BODY_START : SVX_SPELL_BODY_END );
+ bGoOn = sal_True;
+ }
+ WAIT_ON();
+ }
+ return bGoOn;
+}
+
+// -----------------------------------------------------------------------
+
+Reference< XDictionary > SvxSpellWrapper::GetAllRightDic() const
+{
+ Reference< XDictionary > xDic;
+
+ Reference< XDictionaryList > xDicList( SvxGetDictionaryList() );
+ if (xDicList.is())
+ {
+ Sequence< Reference< XDictionary > > aDics( xDicList->getDictionaries() );
+ const Reference< XDictionary > *pDic = aDics.getConstArray();
+ sal_Int32 nCount = aDics.getLength();
+
+ sal_Int32 i = 0;
+ while (!xDic.is() && i < nCount)
+ {
+ Reference< XDictionary > xTmp( pDic[i], UNO_QUERY );
+ if (xTmp.is())
+ {
+ if ( xTmp->isActive() &&
+ xTmp->getDictionaryType() != DictionaryType_NEGATIVE &&
+ SvxLocaleToLanguage( xTmp->getLocale() ) == LANGUAGE_NONE )
+ {
+ Reference< frame::XStorable > xStor( xTmp, UNO_QUERY );
+ if (xStor.is() && xStor->hasLocation() && !xStor->isReadonly())
+ {
+ xDic = xTmp;
+ }
+ }
+ }
+ ++i;
+ }
+
+ if (!xDic.is())
+ {
+ xDic = SvxGetOrCreatePosDic( xDicList );
+ if (xDic.is())
+ xDic->setActive( sal_True );
+ }
+ }
+
+ return xDic;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SvxSpellWrapper::FindSpellError()
+{
+ ShowLanguageErrors();
+
+ Reference< XInterface > xRef;
+
+ WAIT_ON();
+ sal_Bool bSpell = sal_True;
+
+ Reference< XDictionary > xAllRightDic;
+ if (IsAllRight())
+ xAllRightDic = GetAllRightDic();
+
+ while ( bSpell )
+ {
+ SpellContinue();
+
+ Reference< XSpellAlternatives > xAlt( GetLast(), UNO_QUERY );
+ Reference< XHyphenatedWord > xHyphWord( GetLast(), UNO_QUERY );
+
+ if (xAlt.is())
+ {
+ if (IsAllRight() && xAllRightDic.is())
+ {
+ xAllRightDic->add( xAlt->getWord(), sal_False, ::rtl::OUString() );
+ }
+ else
+ {
+ // look up in ChangeAllList for misspelled word
+ Reference< XDictionary > xChangeAllList(
+ SvxGetChangeAllList(), UNO_QUERY );
+ Reference< XDictionaryEntry > xEntry;
+ if (xChangeAllList.is())
+ xEntry = xChangeAllList->getEntry( xAlt->getWord() );
+
+ if (xEntry.is())
+ {
+ // replace word without asking
+ ReplaceAll( xEntry->getReplacementText(),
+ SvxLocaleToLanguage( xAlt->getLocale() ) );
+ }
+ else
+ bSpell = sal_False;
+ }
+ }
+ else if (xHyphWord.is())
+ bSpell = sal_False;
+ else
+ {
+ SpellEnd();
+ bSpell = SpellNext();
+ }
+ }
+ WAIT_OFF();
+ return GetLast().is();
+}
+
+
+
diff --git a/editeng/source/misc/svxacorr.cxx b/editeng/source/misc/svxacorr.cxx
new file mode 100644
index 0000000000..3a3751b2c3
--- /dev/null
+++ b/editeng/source/misc/svxacorr.cxx
@@ -0,0 +1,2706 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: svxacorr.cxx,v $
+ * $Revision: 1.62 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+
+#include <com/sun/star/io/XStream.hpp>
+#include <tools/urlobj.hxx>
+#include <tools/table.hxx>
+#include <i18npool/mslangid.hxx>
+#include <vcl/svapp.hxx>
+#include <sot/storinfo.hxx>
+// fuer die Sort-String-Arrays aus dem SVMEM.HXX
+#define _SVSTDARR_STRINGSISORTDTOR
+#define _SVSTDARR_STRINGSDTOR
+#include <svl/svstdarr.hxx>
+#include <svl/fstathelper.hxx>
+#include <svtools/helpopt.hxx>
+#include <svl/urihelper.hxx>
+#include <unotools/charclass.hxx>
+#include <com/sun/star/i18n/UnicodeType.hdl>
+#include <unotools/collatorwrapper.hxx>
+#include <com/sun/star/i18n/CollatorOptions.hpp>
+#include <unotools/localedatawrapper.hxx>
+#include <unotools/transliterationwrapper.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <editeng/editids.hrc>
+#include <sot/storage.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/svxacorr.hxx>
+#include <editeng/unolingu.hxx>
+#include <helpid.hrc>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <unotools/streamwrap.hxx>
+#include <SvXMLAutoCorrectImport.hxx>
+#include <SvXMLAutoCorrectExport.hxx>
+#include <ucbhelper/content.hxx>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <xmloff/xmltoken.hxx>
+#include <vcl/help.hxx>
+
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star;
+using namespace ::xmloff::token;
+using namespace ::rtl;
+using namespace ::utl;
+
+const int C_NONE = 0x00;
+const int C_FULL_STOP = 0x01;
+const int C_EXCLAMATION_MARK = 0x02;
+const int C_QUESTION_MARK = 0x04;
+
+static const sal_Char pImplWrdStt_ExcptLstStr[] = "WordExceptList";
+static const sal_Char pImplCplStt_ExcptLstStr[] = "SentenceExceptList";
+static const sal_Char pImplAutocorr_ListStr[] = "DocumentList";
+static const sal_Char pXMLImplWrdStt_ExcptLstStr[] = "WordExceptList.xml";
+static const sal_Char pXMLImplCplStt_ExcptLstStr[] = "SentenceExceptList.xml";
+static const sal_Char pXMLImplAutocorr_ListStr[] = "DocumentList.xml";
+
+static const sal_Char
+ /* auch bei diesen Anfaengen - Klammern auf und alle Arten von Anf.Zei. */
+ sImplSttSkipChars[] = "\"\'([{\x83\x84\x89\x91\x92\x93\x94",
+ /* auch bei diesen Ende - Klammern auf und alle Arten von Anf.Zei. */
+ sImplEndSkipChars[] = "\"\')]}\x83\x84\x89\x91\x92\x93\x94";
+
+// diese Zeichen sind in Worten erlaubt: (fuer FnCptlSttSntnc)
+static const sal_Char sImplWordChars[] = "-'";
+
+void EncryptBlockName_Imp( String& rName );
+void DecryptBlockName_Imp( String& rName );
+
+
+// FileVersions Nummern fuer die Ersetzungs-/Ausnahmelisten getrennt
+#define WORDLIST_VERSION_358 1
+#define EXEPTLIST_VERSION_358 0
+
+
+_SV_IMPL_SORTAR_ALG( SvxAutocorrWordList, SvxAutocorrWordPtr )
+TYPEINIT0(SvxAutoCorrect)
+
+typedef SvxAutoCorrectLanguageLists* SvxAutoCorrectLanguageListsPtr;
+DECLARE_TABLE( SvxAutoCorrLanguageTable_Impl, SvxAutoCorrectLanguageListsPtr)
+
+DECLARE_TABLE( SvxAutoCorrLastFileAskTable_Impl, long )
+
+
+inline int IsWordDelim( const sal_Unicode c )
+{
+ return ' ' == c || '\t' == c || 0x0a == c ||
+ 0xA0 == c || 0x2011 == c || 0x1 == c;
+}
+
+inline int IsLowerLetter( sal_Int32 nCharType )
+{
+ return CharClass::isLetterType( nCharType ) &&
+ 0 == ( ::com::sun::star::i18n::KCharacterType::UPPER & nCharType);
+}
+inline int IsUpperLetter( sal_Int32 nCharType )
+{
+ return CharClass::isLetterType( nCharType ) &&
+ 0 == ( ::com::sun::star::i18n::KCharacterType::LOWER & nCharType);
+}
+
+BOOL lcl_IsSymbolChar( CharClass& rCC, const String& rTxt,
+ xub_StrLen nStt, xub_StrLen nEnd )
+{
+ for( ; nStt < nEnd; ++nStt )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ sal_Int32 nCharType;
+ sal_Int32 nChType;
+ nCharType = rCC.getCharacterType( rTxt, nStt );
+ nChType = rCC.getType( rTxt, nStt );
+#endif
+ if( ::com::sun::star::i18n::UnicodeType::PRIVATE_USE ==
+ rCC.getType( rTxt, nStt ))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static BOOL lcl_IsInAsciiArr( const sal_Char* pArr, const sal_Unicode c )
+{
+ BOOL bRet = FALSE;
+ for( ; *pArr; ++pArr )
+ if( *pArr == c )
+ {
+ bRet = TRUE;
+ break;
+ }
+ return bRet;
+}
+
+SvxAutoCorrDoc::~SvxAutoCorrDoc()
+{
+}
+
+
+ // wird nach dem austauschen der Zeichen von den Funktionen
+ // - FnCptlSttWrd
+ // - FnCptlSttSntnc
+ // gerufen. Dann koennen die Worte ggfs. in die Ausnahmelisten
+ // aufgenommen werden.
+void SvxAutoCorrDoc::SaveCpltSttWord( ULONG, xub_StrLen, const String&,
+ sal_Unicode )
+{
+}
+
+LanguageType SvxAutoCorrDoc::GetLanguage( xub_StrLen , BOOL ) const
+{
+ return LANGUAGE_SYSTEM;
+}
+
+static ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& GetProcessFact()
+{
+ static ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory > xMSF =
+ ::comphelper::getProcessServiceFactory();
+ return xMSF;
+}
+
+static USHORT GetAppLang()
+{
+ return Application::GetSettings().GetLanguage();
+}
+static LocaleDataWrapper& GetLocaleDataWrapper( USHORT nLang )
+{
+ static LocaleDataWrapper aLclDtWrp( GetProcessFact(),
+ SvxCreateLocale( GetAppLang() ) );
+ ::com::sun::star::lang::Locale aLcl( SvxCreateLocale( nLang ));
+ const ::com::sun::star::lang::Locale& rLcl = aLclDtWrp.getLoadedLocale();
+ if( aLcl.Language != rLcl.Language ||
+ aLcl.Country != rLcl.Country ||
+ aLcl.Variant != rLcl.Variant )
+ aLclDtWrp.setLocale( aLcl );
+ return aLclDtWrp;
+}
+static TransliterationWrapper& GetIgnoreTranslWrapper()
+{
+ static int bIsInit = 0;
+ static TransliterationWrapper aWrp( GetProcessFact(),
+ ::com::sun::star::i18n::TransliterationModules_IGNORE_CASE |
+ ::com::sun::star::i18n::TransliterationModules_IGNORE_KANA |
+ ::com::sun::star::i18n::TransliterationModules_IGNORE_WIDTH );
+ if( !bIsInit )
+ {
+ aWrp.loadModuleIfNeeded( GetAppLang() );
+ bIsInit = 1;
+ }
+ return aWrp;
+}
+static CollatorWrapper& GetCollatorWrapper()
+{
+ static int bIsInit = 0;
+ static CollatorWrapper aCollWrp( GetProcessFact() );
+ if( !bIsInit )
+ {
+ aCollWrp.loadDefaultCollator( SvxCreateLocale( GetAppLang() ), 0 );
+ bIsInit = 1;
+ }
+ return aCollWrp;
+}
+
+
+void SvxAutocorrWordList::DeleteAndDestroy( USHORT nP, USHORT nL )
+{
+ if( nL )
+ {
+ DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );
+ for( USHORT n=nP; n < nP + nL; n++ )
+ delete *((SvxAutocorrWordPtr*)pData+n);
+ SvPtrarr::Remove( nP, nL );
+ }
+}
+
+
+BOOL SvxAutocorrWordList::Seek_Entry( const SvxAutocorrWordPtr aE, USHORT* pP ) const
+{
+ register USHORT nO = SvxAutocorrWordList_SAR::Count(),
+ nM,
+ nU = 0;
+ if( nO > 0 )
+ {
+ CollatorWrapper& rCmp = ::GetCollatorWrapper();
+ nO--;
+ while( nU <= nO )
+ {
+ nM = nU + ( nO - nU ) / 2;
+ long nCmp = rCmp.compareString( aE->GetShort(),
+ (*((SvxAutocorrWordPtr*)pData + nM))->GetShort() );
+ if( 0 == nCmp )
+ {
+ if( pP ) *pP = nM;
+ return TRUE;
+ }
+ else if( 0 < nCmp )
+ nU = nM + 1;
+ else if( nM == 0 )
+ {
+ if( pP ) *pP = nU;
+ return FALSE;
+ }
+ else
+ nO = nM - 1;
+ }
+ }
+ if( pP ) *pP = nU;
+ return FALSE;
+}
+
+/* -----------------18.11.98 15:28-------------------
+ *
+ * --------------------------------------------------*/
+void lcl_ClearTable(SvxAutoCorrLanguageTable_Impl& rLangTable)
+{
+ SvxAutoCorrectLanguageListsPtr pLists = rLangTable.Last();
+ while(pLists)
+ {
+ delete pLists;
+ pLists = rLangTable.Prev();
+ }
+ rLangTable.Clear();
+}
+
+/* -----------------03.11.06 10:15-------------------
+ *
+ * --------------------------------------------------*/
+
+sal_Bool SvxAutoCorrect::IsAutoCorrectChar( sal_Unicode cChar )
+{
+ return cChar == '\0' || cChar == '\t' || cChar == 0x0a ||
+ cChar == ' ' || cChar == '\'' || cChar == '\"' ||
+ cChar == '*' || cChar == '_' ||
+ cChar == '.' || cChar == ',' || cChar == ';' ||
+ cChar == ':' || cChar == '?' || cChar == '!';
+}
+
+/* -----------------19.11.98 10:15-------------------
+ *
+ * --------------------------------------------------*/
+long SvxAutoCorrect::GetDefaultFlags()
+{
+ long nRet = Autocorrect
+ | CptlSttSntnc
+ | CptlSttWrd
+ | ChgFractionSymbol
+ | ChgOrdinalNumber
+ | ChgToEnEmDash
+ | ChgWeightUnderl
+ | SetINetAttr
+ | ChgQuotes
+ | SaveWordCplSttLst
+ | SaveWordWrdSttLst;
+ LanguageType eLang = GetAppLang();
+ switch( eLang )
+ {
+ case LANGUAGE_ENGLISH:
+ case LANGUAGE_ENGLISH_US:
+ case LANGUAGE_ENGLISH_UK:
+ case LANGUAGE_ENGLISH_AUS:
+ case LANGUAGE_ENGLISH_CAN:
+ case LANGUAGE_ENGLISH_NZ:
+ case LANGUAGE_ENGLISH_EIRE:
+ case LANGUAGE_ENGLISH_SAFRICA:
+ case LANGUAGE_ENGLISH_JAMAICA:
+ case LANGUAGE_ENGLISH_CARRIBEAN:
+ nRet &= ~(ChgQuotes|ChgSglQuotes);
+ break;
+ }
+ return nRet;
+}
+
+
+SvxAutoCorrect::SvxAutoCorrect( const String& rShareAutocorrFile,
+ const String& rUserAutocorrFile )
+ : sShareAutoCorrFile( rShareAutocorrFile ),
+ sUserAutoCorrFile( rUserAutocorrFile ),
+ pLangTable( new SvxAutoCorrLanguageTable_Impl ),
+ pLastFileTable( new SvxAutoCorrLastFileAskTable_Impl ),
+ pCharClass( 0 ),
+ cStartDQuote( 0 ), cEndDQuote( 0 ), cStartSQuote( 0 ), cEndSQuote( 0 )
+{
+ nFlags = SvxAutoCorrect::GetDefaultFlags();
+
+ c1Div2 = ByteString::ConvertToUnicode( '\xBD', RTL_TEXTENCODING_MS_1252 );
+ c1Div4 = ByteString::ConvertToUnicode( '\xBC', RTL_TEXTENCODING_MS_1252 );
+ c3Div4 = ByteString::ConvertToUnicode( '\xBE', RTL_TEXTENCODING_MS_1252 );
+ cEmDash = ByteString::ConvertToUnicode( '\x97', RTL_TEXTENCODING_MS_1252 );
+ cEnDash = ByteString::ConvertToUnicode( '\x96', RTL_TEXTENCODING_MS_1252 );
+}
+
+SvxAutoCorrect::SvxAutoCorrect( const SvxAutoCorrect& rCpy )
+: sShareAutoCorrFile( rCpy.sShareAutoCorrFile ),
+ sUserAutoCorrFile( rCpy.sUserAutoCorrFile ),
+
+ aSwFlags( rCpy.aSwFlags ),
+
+ pLangTable( new SvxAutoCorrLanguageTable_Impl ),
+ pLastFileTable( new SvxAutoCorrLastFileAskTable_Impl ),
+ pCharClass( 0 ),
+
+ nFlags( rCpy.nFlags & ~(ChgWordLstLoad|CplSttLstLoad|WrdSttLstLoad)),
+ cStartDQuote( rCpy.cStartDQuote ), cEndDQuote( rCpy.cEndDQuote ),
+ cStartSQuote( rCpy.cStartSQuote ), cEndSQuote( rCpy.cEndSQuote ),
+ c1Div2( rCpy.c1Div2 ), c1Div4( rCpy.c1Div4 ), c3Div4( rCpy.c3Div4 ),
+ cEmDash( rCpy.cEmDash ), cEnDash( rCpy.cEnDash )
+{
+}
+
+
+SvxAutoCorrect::~SvxAutoCorrect()
+{
+ lcl_ClearTable(*pLangTable);
+ delete pLangTable;
+ delete pLastFileTable;
+ delete pCharClass;
+}
+
+void SvxAutoCorrect::_GetCharClass( LanguageType eLang )
+{
+ delete pCharClass;
+ pCharClass = new CharClass( SvxCreateLocale( eLang ));
+ eCharClassLang = eLang;
+}
+
+void SvxAutoCorrect::SetAutoCorrFlag( long nFlag, BOOL bOn )
+{
+ long nOld = nFlags;
+ nFlags = bOn ? nFlags | nFlag
+ : nFlags & ~nFlag;
+
+ if( !bOn )
+ {
+ if( (nOld & CptlSttSntnc) != (nFlags & CptlSttSntnc) )
+ nFlags &= ~CplSttLstLoad;
+ if( (nOld & CptlSttWrd) != (nFlags & CptlSttWrd) )
+ nFlags &= ~WrdSttLstLoad;
+ if( (nOld & Autocorrect) != (nFlags & Autocorrect) )
+ nFlags &= ~ChgWordLstLoad;
+ }
+}
+
+
+ // Zwei Grossbuchstaben am Wort-Anfang ??
+BOOL SvxAutoCorrect::FnCptlSttWrd( SvxAutoCorrDoc& rDoc, const String& rTxt,
+ xub_StrLen nSttPos, xub_StrLen nEndPos,
+ LanguageType eLang )
+{
+ BOOL bRet = FALSE;
+ CharClass& rCC = GetCharClass( eLang );
+
+ // loesche alle nicht alpanum. Zeichen am Wortanfang/-ende und
+ // teste dann ( erkennt: "(min.", "/min.", usw.)
+ for( ; nSttPos < nEndPos; ++nSttPos )
+ if( rCC.isLetterNumeric( rTxt, nSttPos ))
+ break;
+ for( ; nSttPos < nEndPos; --nEndPos )
+ if( rCC.isLetterNumeric( rTxt, nEndPos - 1 ))
+ break;
+
+ // Zwei Grossbuchstaben am Wort-Anfang ??
+ if( nSttPos+2 < nEndPos &&
+ IsUpperLetter( rCC.getCharacterType( rTxt, nSttPos )) &&
+ IsUpperLetter( rCC.getCharacterType( rTxt, ++nSttPos )) &&
+ // ist das 3. Zeichen ein klein geschiebenes Alpha-Zeichen
+ IsLowerLetter( rCC.getCharacterType( rTxt, nSttPos +1 )) &&
+ // keine Sonder-Attribute ersetzen
+ 0x1 != rTxt.GetChar( nSttPos ) && 0x2 != rTxt.GetChar( nSttPos ))
+ {
+ // teste ob das Wort in einer Ausnahmeliste steht
+ String sWord( rTxt.Copy( nSttPos - 1, nEndPos - nSttPos + 1 ));
+ if( !FindInWrdSttExceptList(eLang, sWord) )
+ {
+ sal_Unicode cSave = rTxt.GetChar( nSttPos );
+ String sChar( cSave );
+ rCC.toLower( sChar );
+ if( sChar.GetChar(0) != cSave && rDoc.Replace( nSttPos, sChar ))
+ {
+ if( SaveWordWrdSttLst & nFlags )
+ rDoc.SaveCpltSttWord( CptlSttWrd, nSttPos, sWord, cSave );
+ bRet = TRUE;
+ }
+ }
+ }
+ return bRet;
+}
+
+
+BOOL SvxAutoCorrect::FnChgFractionSymbol(
+ SvxAutoCorrDoc& rDoc, const String& rTxt,
+ xub_StrLen nSttPos, xub_StrLen nEndPos )
+{
+ sal_Unicode cChar = 0;
+
+ for( ; nSttPos < nEndPos; ++nSttPos )
+ if( !lcl_IsInAsciiArr( sImplSttSkipChars, rTxt.GetChar( nSttPos ) ))
+ break;
+ for( ; nSttPos < nEndPos; --nEndPos )
+ if( !lcl_IsInAsciiArr( sImplEndSkipChars, rTxt.GetChar( nEndPos - 1 ) ))
+ break;
+
+ // 1/2, 1/4, ... ersetzen durch das entsprechende Zeichen vom Font
+ if( 3 == nEndPos - nSttPos && '/' == rTxt.GetChar( nSttPos+1 ))
+ {
+ switch( ( rTxt.GetChar( nSttPos )) * 256 + rTxt.GetChar( nEndPos-1 ))
+ {
+ case '1' * 256 + '2': cChar = c1Div2; break;
+ case '1' * 256 + '4': cChar = c1Div4; break;
+ case '3' * 256 + '4': cChar = c3Div4; break;
+ }
+
+ if( cChar )
+ {
+ // also austauschen:
+ rDoc.Delete( nSttPos+1, nEndPos );
+ rDoc.Replace( nSttPos, cChar );
+ }
+ }
+ return 0 != cChar;
+}
+
+
+BOOL SvxAutoCorrect::FnChgOrdinalNumber(
+ SvxAutoCorrDoc& rDoc, const String& rTxt,
+ xub_StrLen nSttPos, xub_StrLen nEndPos,
+ LanguageType eLang )
+{
+// 1st, 2nd, 3rd, 4 - 0th
+// 201th oder 201st
+// 12th oder 12nd
+ CharClass& rCC = GetCharClass( eLang );
+ BOOL bChg = FALSE;
+
+ for( ; nSttPos < nEndPos; ++nSttPos )
+ if( !lcl_IsInAsciiArr( sImplSttSkipChars, rTxt.GetChar( nSttPos ) ))
+ break;
+ for( ; nSttPos < nEndPos; --nEndPos )
+ if( !lcl_IsInAsciiArr( sImplEndSkipChars, rTxt.GetChar( nEndPos - 1 ) ))
+ break;
+
+ if( 2 < nEndPos - nSttPos &&
+ rCC.isDigit( rTxt, nEndPos - 3 ) )
+ {
+ static sal_Char __READONLY_DATA
+ sAll[] = "th", /* rest */
+ sFirst[] = "st", /* 1 */
+ sSecond[] = "nd", /* 2 */
+ sThird[] = "rd"; /* 3 */
+ static const sal_Char* __READONLY_DATA aNumberTab[ 4 ] =
+ {
+ sAll, sFirst, sSecond, sThird
+ };
+
+ sal_Unicode c = rTxt.GetChar( nEndPos - 3 );
+ if( ( c -= '0' ) > 3 )
+ c = 0;
+
+ bChg = ( ((sal_Unicode)*((aNumberTab[ c ])+0)) ==
+ rTxt.GetChar( nEndPos - 2 ) &&
+ ((sal_Unicode)*((aNumberTab[ c ])+1)) ==
+ rTxt.GetChar( nEndPos - 1 )) ||
+ ( 3 < nEndPos - nSttPos &&
+ ( ((sal_Unicode)*(sAll+0)) == rTxt.GetChar( nEndPos - 2 ) &&
+ ((sal_Unicode)*(sAll+1)) == rTxt.GetChar( nEndPos - 1 )));
+
+ if( bChg )
+ {
+ // dann pruefe mal, ob alle bis zum Start alle Zahlen sind
+ for( xub_StrLen n = nEndPos - 3; nSttPos < n; )
+ if( !rCC.isDigit( rTxt, --n ) )
+ {
+ bChg = !rCC.isLetter( rTxt, n );
+ break;
+ }
+
+ if( bChg ) // dann setze mal das Escapement Attribut
+ {
+ SvxEscapementItem aSvxEscapementItem( DFLT_ESC_AUTO_SUPER,
+ DFLT_ESC_PROP, SID_ATTR_CHAR_ESCAPEMENT );
+ rDoc.SetAttr( nEndPos - 2, nEndPos,
+ SID_ATTR_CHAR_ESCAPEMENT,
+ aSvxEscapementItem);
+ }
+ }
+
+ }
+ return bChg;
+}
+
+
+BOOL SvxAutoCorrect::FnChgToEnEmDash(
+ SvxAutoCorrDoc& rDoc, const String& rTxt,
+ xub_StrLen nSttPos, xub_StrLen nEndPos,
+ LanguageType eLang )
+{
+ BOOL bRet = FALSE;
+ CharClass& rCC = GetCharClass( eLang );
+ if (eLang == LANGUAGE_SYSTEM)
+ eLang = GetAppLang();
+ bool bAlwaysUseEmDash = (cEmDash && (eLang == LANGUAGE_RUSSIAN || eLang == LANGUAGE_UKRAINIAN));
+
+ // ersetze " - " oder " --" durch "enDash"
+ if( cEnDash && 1 < nSttPos && 1 <= nEndPos - nSttPos )
+ {
+ sal_Unicode cCh = rTxt.GetChar( nSttPos );
+ if( '-' == cCh )
+ {
+ if( ' ' == rTxt.GetChar( nSttPos-1 ) &&
+ '-' == rTxt.GetChar( nSttPos+1 ))
+ {
+ xub_StrLen n;
+ for( n = nSttPos+2; n < nEndPos && lcl_IsInAsciiArr(
+ sImplSttSkipChars,(cCh = rTxt.GetChar( n )));
+ ++n )
+ ;
+
+ // found: " --[<AnySttChars>][A-z0-9]
+ if( rCC.isLetterNumeric( cCh ) )
+ {
+ for( n = nSttPos-1; n && lcl_IsInAsciiArr(
+ sImplEndSkipChars,(cCh = rTxt.GetChar( --n ))); )
+ ;
+
+ // found: "[A-z0-9][<AnyEndChars>] --[<AnySttChars>][A-z0-9]
+ if( rCC.isLetterNumeric( cCh ))
+ {
+ rDoc.Delete( nSttPos, nSttPos + 2 );
+ rDoc.Insert( nSttPos, bAlwaysUseEmDash ? cEmDash : cEnDash );
+ bRet = TRUE;
+ }
+ }
+ }
+ }
+ else if( 3 < nSttPos &&
+ ' ' == rTxt.GetChar( nSttPos-1 ) &&
+ '-' == rTxt.GetChar( nSttPos-2 ))
+ {
+ xub_StrLen n, nLen = 1, nTmpPos = nSttPos - 2;
+ if( '-' == ( cCh = rTxt.GetChar( nTmpPos-1 )) )
+ {
+ --nTmpPos;
+ ++nLen;
+ cCh = rTxt.GetChar( nTmpPos-1 );
+ }
+ if( ' ' == cCh )
+ {
+ for( n = nSttPos; n < nEndPos && lcl_IsInAsciiArr(
+ sImplSttSkipChars,(cCh = rTxt.GetChar( n )));
+ ++n )
+ ;
+
+ // found: " - [<AnySttChars>][A-z0-9]
+ if( rCC.isLetterNumeric( cCh ) )
+ {
+ cCh = ' ';
+ for( n = nTmpPos-1; n && lcl_IsInAsciiArr(
+ sImplEndSkipChars,(cCh = rTxt.GetChar( --n ))); )
+ ;
+ // found: "[A-z0-9][<AnyEndChars>] - [<AnySttChars>][A-z0-9]
+ if( rCC.isLetterNumeric( cCh ))
+ {
+ rDoc.Delete( nTmpPos, nTmpPos + nLen );
+ rDoc.Insert( nTmpPos, bAlwaysUseEmDash ? cEmDash : cEnDash );
+ bRet = TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ // Replace [A-z0-9]--[A-z0-9] double dash with "emDash" or "enDash".
+ // Finnish and Hungarian use enDash instead of emDash.
+ bool bEnDash = (eLang == LANGUAGE_HUNGARIAN || eLang == LANGUAGE_FINNISH);
+ if( ((cEmDash && !bEnDash) || (cEnDash && bEnDash)) && 4 <= nEndPos - nSttPos )
+ {
+ String sTmp( rTxt.Copy( nSttPos, nEndPos - nSttPos ) );
+ xub_StrLen nFndPos = sTmp.SearchAscii( "--" );
+ if( STRING_NOTFOUND != nFndPos && nFndPos &&
+ nFndPos + 2 < sTmp.Len() &&
+ ( rCC.isLetterNumeric( sTmp, nFndPos - 1 ) ||
+ lcl_IsInAsciiArr( sImplEndSkipChars, rTxt.GetChar( nFndPos - 1 ) )) &&
+ ( rCC.isLetterNumeric( sTmp, nFndPos + 2 ) ||
+ lcl_IsInAsciiArr( sImplSttSkipChars, rTxt.GetChar( nFndPos + 2 ) )))
+ {
+ nSttPos = nSttPos + nFndPos;
+ rDoc.Delete( nSttPos, nSttPos + 2 );
+ rDoc.Insert( nSttPos, (bEnDash ? cEnDash : cEmDash) );
+ bRet = TRUE;
+ }
+ }
+ return bRet;
+}
+
+
+BOOL SvxAutoCorrect::FnSetINetAttr( SvxAutoCorrDoc& rDoc, const String& rTxt,
+ xub_StrLen nSttPos, xub_StrLen nEndPos,
+ LanguageType eLang )
+{
+ String sURL( URIHelper::FindFirstURLInText( rTxt, nSttPos, nEndPos,
+ GetCharClass( eLang ) ));
+ BOOL bRet = 0 != sURL.Len();
+ if( bRet ) // also Attribut setzen:
+ rDoc.SetINetAttr( nSttPos, nEndPos, sURL );
+ return bRet;
+}
+
+
+BOOL SvxAutoCorrect::FnChgWeightUnderl( SvxAutoCorrDoc& rDoc, const String& rTxt,
+ xub_StrLen, xub_StrLen nEndPos,
+ LanguageType eLang )
+{
+ // Bedingung:
+ // Am Anfang: _ oder * hinter Space mit nachfolgenden !Space
+ // Am Ende: _ oder * vor Space (Worttrenner?)
+
+ sal_Unicode c, cInsChar = rTxt.GetChar( nEndPos ); // unterstreichen oder fett
+ if( ++nEndPos != rTxt.Len() &&
+ !IsWordDelim( rTxt.GetChar( nEndPos ) ) )
+ return FALSE;
+
+ --nEndPos;
+
+ BOOL bAlphaNum = FALSE;
+ xub_StrLen nPos = nEndPos, nFndPos = STRING_NOTFOUND;
+ CharClass& rCC = GetCharClass( eLang );
+
+ while( nPos )
+ {
+ switch( c = rTxt.GetChar( --nPos ) )
+ {
+ case '_':
+ case '*':
+ if( c == cInsChar )
+ {
+ if( bAlphaNum && nPos+1 < nEndPos && ( !nPos ||
+ IsWordDelim( rTxt.GetChar( nPos-1 ))) &&
+ !IsWordDelim( rTxt.GetChar( nPos+1 )))
+ nFndPos = nPos;
+ else
+ // Bedingung ist nicht erfuellt, also abbrechen
+ nFndPos = STRING_NOTFOUND;
+ nPos = 0;
+ }
+ break;
+ default:
+ if( !bAlphaNum )
+ bAlphaNum = rCC.isLetterNumeric( rTxt, nPos );
+ }
+ }
+
+ if( STRING_NOTFOUND != nFndPos )
+ {
+ // ueber den gefundenen Bereich das Attribut aufspannen und
+ // das gefunde und am Ende stehende Zeichen loeschen
+ if( '*' == cInsChar ) // Fett
+ {
+ SvxWeightItem aSvxWeightItem( WEIGHT_BOLD, SID_ATTR_CHAR_WEIGHT );
+ rDoc.SetAttr( nFndPos + 1, nEndPos,
+ SID_ATTR_CHAR_WEIGHT,
+ aSvxWeightItem);
+ }
+ else // unterstrichen
+ {
+ SvxUnderlineItem aSvxUnderlineItem( UNDERLINE_SINGLE, SID_ATTR_CHAR_UNDERLINE );
+ rDoc.SetAttr( nFndPos + 1, nEndPos,
+ SID_ATTR_CHAR_UNDERLINE,
+ aSvxUnderlineItem);
+ }
+ rDoc.Delete( nEndPos, nEndPos + 1 );
+ rDoc.Delete( nFndPos, nFndPos + 1 );
+ }
+
+ return STRING_NOTFOUND != nFndPos;
+}
+
+
+BOOL SvxAutoCorrect::FnCptlSttSntnc( SvxAutoCorrDoc& rDoc,
+ const String& rTxt, BOOL bNormalPos,
+ xub_StrLen nSttPos, xub_StrLen nEndPos,
+ LanguageType eLang )
+{
+ // Grossbuchstabe am Satz-Anfang ??
+ if( !rTxt.Len() || nEndPos <= nSttPos )
+ return FALSE;
+
+ CharClass& rCC = GetCharClass( eLang );
+ String aText( rTxt );
+ const sal_Unicode *pStart = aText.GetBuffer(),
+ *pStr = pStart + nEndPos,
+ *pWordStt = 0,
+ *pDelim = 0;
+
+ BOOL bAtStart = FALSE, bPrevPara = FALSE;
+ do {
+ --pStr;
+ if( rCC.isLetter(
+ aText, sal::static_int_cast< xub_StrLen >( pStr - pStart ) ) )
+ {
+ if( !pWordStt )
+ pDelim = pStr+1;
+ pWordStt = pStr;
+ }
+ else if( pWordStt &&
+ !rCC.isDigit(
+ aText,
+ sal::static_int_cast< xub_StrLen >( pStr - pStart ) ) )
+ {
+ if( lcl_IsInAsciiArr( sImplWordChars, *pStr ) &&
+ pWordStt - 1 == pStr &&
+ // --> FME 2005-02-14 #i38971#
+ // l'intallazione at beginning of paragraph. Replaced < by <=
+ (long)(pStart + 1) <= (long)pStr &&
+ // <--
+ rCC.isLetter(
+ aText,
+ sal::static_int_cast< xub_StrLen >( pStr-1 - pStart ) ) )
+ pWordStt = --pStr;
+ else
+ break;
+ }
+ } while( 0 == ( bAtStart = (pStart == pStr)) );
+
+
+ if( !pWordStt ||
+ rCC.isDigit(
+ aText, sal::static_int_cast< xub_StrLen >( pStr - pStart ) ) ||
+ IsUpperLetter(
+ rCC.getCharacterType(
+ aText,
+ sal::static_int_cast< xub_StrLen >( pWordStt - pStart ) ) ) ||
+ 0x1 == *pWordStt || 0x2 == *pWordStt )
+ return FALSE; // kein zu ersetzendes Zeichen, oder schon ok
+
+ // JP 27.10.97: wenn das Wort weniger als 3 Zeichen hat und der Trenner
+ // ein "Num"-Trenner ist, dann nicht ersetzen!
+ // Damit wird ein "a.", "a)", "a-a" nicht ersetzt!
+ if( *pDelim && 2 >= pDelim - pWordStt &&
+ lcl_IsInAsciiArr( ".-)>", *pDelim ) )
+ return FALSE;
+
+ if( !bAtStart ) // noch kein Absatz Anfang ?
+ {
+ if ( IsWordDelim( *pStr ) )
+ {
+ while( 0 == ( bAtStart = (pStart == pStr--) ) && IsWordDelim( *pStr ))
+ ;
+ }
+ // Asian full stop, full width full stop, full width exclamation mark
+ // and full width question marks are treated as word delimiters
+ else if ( 0x3002 != *pStr && 0xFF0E != *pStr && 0xFF01 != *pStr &&
+ 0xFF1F != *pStr )
+ return FALSE; // kein gueltiger Trenner -> keine Ersetzung
+ }
+
+ if( bAtStart ) // am Absatz Anfang ?
+ {
+ // Ueberpruefe den vorherigen Absatz, wenn es diesen gibt.
+ // Wenn ja, dann pruefe auf SatzTrenner am Ende.
+ const String* pPrevPara = rDoc.GetPrevPara( bNormalPos );
+ if( !pPrevPara )
+ {
+ // gueltiger Trenner -> Ersetze
+ String sChar( *pWordStt );
+ rCC.toUpper( sChar );
+ return sChar != *pWordStt &&
+ rDoc.Replace( xub_StrLen( pWordStt - pStart ), sChar );
+ }
+
+ aText = *pPrevPara;
+ bPrevPara = TRUE;
+ bAtStart = FALSE;
+ pStart = aText.GetBuffer();
+ pStr = pStart + aText.Len();
+
+ do { // alle Blanks ueberlesen
+ --pStr;
+ if( !IsWordDelim( *pStr ))
+ break;
+ } while( 0 == ( bAtStart = (pStart == pStr)) );
+
+ if( bAtStart )
+ return FALSE; // kein gueltiger Trenner -> keine Ersetzung
+ }
+
+ // bis hierhier wurde [ \t]+[A-Z0-9]+ gefunden. Test jetzt auf den
+ // Satztrenner. Es koennen alle 3 vorkommen, aber nicht mehrfach !!
+ const sal_Unicode* pExceptStt = 0;
+ if( !bAtStart )
+ {
+ BOOL bWeiter = TRUE;
+ int nFlag = C_NONE;
+ do {
+ switch( *pStr )
+ {
+ // Western and Asian full stop
+ case '.':
+ case 0x3002 :
+ case 0xFF0E :
+ {
+ if( nFlag & C_FULL_STOP )
+ return FALSE; // kein gueltiger Trenner -> keine Ersetzung
+ nFlag |= C_FULL_STOP;
+ pExceptStt = pStr;
+ }
+ break;
+ case '!':
+ case 0xFF01 :
+ {
+ if( nFlag & C_EXCLAMATION_MARK )
+ return FALSE; // kein gueltiger Trenner -> keine Ersetzung
+ nFlag |= C_EXCLAMATION_MARK;
+ }
+ break;
+ case '?':
+ case 0xFF1F :
+ {
+ if( nFlag & C_QUESTION_MARK)
+ return FALSE; // kein gueltiger Trenner -> keine Ersetzung
+ nFlag |= C_QUESTION_MARK;
+ }
+ break;
+ default:
+ if( !nFlag )
+ return FALSE; // kein gueltiger Trenner -> keine Ersetzung
+ else
+ bWeiter = FALSE;
+ break;
+ }
+
+ if( bWeiter && pStr-- == pStart )
+ {
+// !!! wenn am Anfang, dann nie ersetzen.
+// if( !nFlag )
+ return FALSE; // kein gueltiger Trenner -> keine Ersetzung
+// ++pStr;
+// break; // Schleife beenden
+ }
+ } while( bWeiter );
+ if( C_FULL_STOP != nFlag )
+ pExceptStt = 0;
+ }
+
+ if( 2 > ( pStr - pStart ) )
+ return FALSE;
+
+ if( !rCC.isLetterNumeric(
+ aText, sal::static_int_cast< xub_StrLen >( pStr-- - pStart ) ) )
+ {
+ BOOL bValid = FALSE, bAlphaFnd = FALSE;
+ const sal_Unicode* pTmpStr = pStr;
+ while( !bValid )
+ {
+ if( rCC.isDigit(
+ aText,
+ sal::static_int_cast< xub_StrLen >( pTmpStr - pStart ) ) )
+ {
+ bValid = TRUE;
+ pStr = pTmpStr - 1;
+ }
+ else if( rCC.isLetter(
+ aText,
+ sal::static_int_cast< xub_StrLen >(
+ pTmpStr - pStart ) ) )
+ {
+ if( bAlphaFnd )
+ {
+ bValid = TRUE;
+ pStr = pTmpStr;
+ }
+ else
+ bAlphaFnd = TRUE;
+ }
+ else if( bAlphaFnd || IsWordDelim( *pTmpStr ) )
+ break;
+
+ if( pTmpStr == pStart )
+ break;
+
+ --pTmpStr;
+ }
+
+ if( !bValid )
+ return FALSE; // kein gueltiger Trenner -> keine Ersetzung
+ }
+
+ BOOL bNumericOnly = '0' <= *(pStr+1) && *(pStr+1) <= '9';
+
+ // suche den Anfang vom Wort
+ while( !IsWordDelim( *pStr ))
+ {
+ if( bNumericOnly &&
+ rCC.isLetter(
+ aText, sal::static_int_cast< xub_StrLen >( pStr - pStart ) ) )
+ bNumericOnly = FALSE;
+
+ if( pStart == pStr )
+ break;
+
+ --pStr;
+ }
+
+ if( bNumericOnly ) // besteht nur aus Zahlen, dann nicht
+ return FALSE;
+
+ if( IsWordDelim( *pStr ))
+ ++pStr;
+
+ String sWord;
+
+ // ueberpruefe anhand der Exceptionliste
+ if( pExceptStt )
+ {
+ sWord = String(
+ pStr, sal::static_int_cast< xub_StrLen >( pExceptStt - pStr + 1 ) );
+ if( FindInCplSttExceptList(eLang, sWord) )
+ return FALSE;
+
+ // loesche alle nicht alpanum. Zeichen am Wortanfang/-ende und
+ // teste dann noch mal ( erkennt: "(min.", "/min.", usw.)
+ String sTmp( sWord );
+ while( sTmp.Len() &&
+ !rCC.isLetterNumeric( sTmp, 0 ) )
+ sTmp.Erase( 0, 1 );
+
+ // alle hinteren nicht alphanumerische Zeichen bis auf das
+ // Letzte entfernen
+ xub_StrLen nLen = sTmp.Len();
+ while( nLen && !rCC.isLetterNumeric( sTmp, nLen-1 ) )
+ --nLen;
+ if( nLen + 1 < sTmp.Len() )
+ sTmp.Erase( nLen + 1 );
+
+ if( sTmp.Len() && sTmp.Len() != sWord.Len() &&
+ FindInCplSttExceptList(eLang, sTmp))
+ return FALSE;
+
+ if(FindInCplSttExceptList(eLang, sWord, TRUE))
+ return FALSE;
+ }
+
+ // Ok, dann ersetze mal
+ sal_Unicode cSave = *pWordStt;
+ nSttPos = sal::static_int_cast< xub_StrLen >( pWordStt - rTxt.GetBuffer() );
+ String sChar( cSave );
+ rCC.toUpper( sChar );
+ BOOL bRet = sChar.GetChar(0) != cSave && rDoc.Replace( nSttPos, sChar );
+
+ // das Wort will vielleicht jemand haben
+ if( bRet && SaveWordCplSttLst & nFlags )
+ rDoc.SaveCpltSttWord( CptlSttSntnc, nSttPos, sWord, cSave );
+
+ return bRet;
+}
+//The method below is renamed from _GetQuote to GetQuote by BerryJia for Bug95846 Time:2002-8-13 15:50
+sal_Unicode SvxAutoCorrect::GetQuote( sal_Unicode cInsChar, BOOL bSttQuote,
+ LanguageType eLang ) const
+{
+ sal_Unicode cRet = bSttQuote ? ( '\"' == cInsChar
+ ? GetStartDoubleQuote()
+ : GetStartSingleQuote() )
+ : ( '\"' == cInsChar
+ ? GetEndDoubleQuote()
+ : GetEndSingleQuote() );
+ if( !cRet )
+ {
+ // dann ueber die Language das richtige Zeichen heraussuchen
+ if( LANGUAGE_NONE == eLang )
+ cRet = cInsChar;
+ else
+ {
+ LocaleDataWrapper& rLcl = GetLocaleDataWrapper( eLang );
+ String sRet( bSttQuote
+ ? ( '\"' == cInsChar
+ ? rLcl.getDoubleQuotationMarkStart()
+ : rLcl.getQuotationMarkStart() )
+ : ( '\"' == cInsChar
+ ? rLcl.getDoubleQuotationMarkEnd()
+ : rLcl.getQuotationMarkEnd() ));
+ cRet = sRet.Len() ? sRet.GetChar( 0 ) : cInsChar;
+ }
+ }
+ return cRet;
+}
+
+void SvxAutoCorrect::InsertQuote( SvxAutoCorrDoc& rDoc, xub_StrLen nInsPos,
+ sal_Unicode cInsChar, BOOL bSttQuote,
+ BOOL bIns )
+{
+ LanguageType eLang = rDoc.GetLanguage( nInsPos, FALSE );
+ sal_Unicode cRet = GetQuote( cInsChar, bSttQuote, eLang );
+
+ //JP 13.02.99: damit beim Undo das "einfuegte" Zeichen wieder erscheint,
+ // wird es erstmal eingefuegt und dann ueberschrieben
+ String sChg( cInsChar );
+ if( bIns )
+ rDoc.Insert( nInsPos, sChg );
+ else
+ rDoc.Replace( nInsPos, sChg );
+
+ //JP 13.08.97: Bug 42477 - bei doppelten Anfuehrungszeichen muss bei
+ // franzoesischer Sprache an Anfang ein Leerzeichen dahinter
+ // und am Ende ein Leerzeichen dahinter eingefuegt werden.
+ sChg = cRet;
+
+ if( '\"' == cInsChar )
+ {
+ if( LANGUAGE_SYSTEM == eLang )
+ eLang = GetAppLang();
+ switch( eLang )
+ {
+ case LANGUAGE_FRENCH:
+ case LANGUAGE_FRENCH_BELGIAN:
+ case LANGUAGE_FRENCH_CANADIAN:
+ case LANGUAGE_FRENCH_SWISS:
+ case LANGUAGE_FRENCH_LUXEMBOURG:
+ // JP 09.02.99: das zusaetzliche Zeichen immer per Insert einfuegen.
+ // Es ueberschreibt nichts!
+ {
+ String s( static_cast< sal_Unicode >(0xA0) );
+ // UNICODE code for no break space
+ if( rDoc.Insert( bSttQuote ? nInsPos+1 : nInsPos, s ))
+ {
+ if( !bSttQuote )
+ ++nInsPos;
+ }
+ }
+ break;
+ }
+ }
+
+ rDoc.Replace( nInsPos, sChg );
+}
+
+String SvxAutoCorrect::GetQuote( SvxAutoCorrDoc& rDoc, xub_StrLen nInsPos,
+ sal_Unicode cInsChar, BOOL bSttQuote )
+{
+ LanguageType eLang = rDoc.GetLanguage( nInsPos, FALSE );
+ sal_Unicode cRet = GetQuote( cInsChar, bSttQuote, eLang );
+
+ String sRet( cRet );
+ //JP 13.08.97: Bug 42477 - bei doppelten Anfuehrungszeichen muss bei
+ // franzoesischer Sprache an Anfang ein Leerzeichen dahinter
+ // und am Ende ein Leerzeichen dahinter eingefuegt werden.
+ if( '\"' == cInsChar )
+ {
+ if( LANGUAGE_SYSTEM == eLang )
+ eLang = GetAppLang();
+ switch( eLang )
+ {
+ case LANGUAGE_FRENCH:
+ case LANGUAGE_FRENCH_BELGIAN:
+ case LANGUAGE_FRENCH_CANADIAN:
+ case LANGUAGE_FRENCH_SWISS:
+ case LANGUAGE_FRENCH_LUXEMBOURG:
+ if( bSttQuote )
+ sRet += ' ';
+ else
+ sRet.Insert( ' ', 0 );
+ break;
+ }
+ }
+ return sRet;
+}
+
+ULONG SvxAutoCorrect::AutoCorrect( SvxAutoCorrDoc& rDoc, const String& rTxt,
+ xub_StrLen nInsPos, sal_Unicode cChar,
+ BOOL bInsert )
+{
+ ULONG nRet = 0;
+ do{ // only for middle check loop !!
+ if( cChar )
+ {
+ //JP 10.02.97: doppelte Spaces verhindern
+ if( nInsPos && ' ' == cChar &&
+ IsAutoCorrFlag( IngnoreDoubleSpace ) &&
+ ' ' == rTxt.GetChar( nInsPos - 1 ) )
+ {
+ nRet = IngnoreDoubleSpace;
+ break;
+ }
+
+ BOOL bSingle = '\'' == cChar;
+ BOOL bIsReplaceQuote =
+ (IsAutoCorrFlag( ChgQuotes ) && ('\"' == cChar )) ||
+ (IsAutoCorrFlag( ChgSglQuotes ) && bSingle );
+ if( bIsReplaceQuote )
+ {
+ sal_Unicode cPrev;
+ BOOL bSttQuote = !nInsPos ||
+ IsWordDelim( ( cPrev = rTxt.GetChar( nInsPos-1 ))) ||
+// os: #56034# - Warum kein schliessendes Anfuehrungszeichen nach dem Bindestrich?
+// strchr( "-([{", cPrev ) ||
+ lcl_IsInAsciiArr( "([{", cPrev ) ||
+ ( cEmDash && cEmDash == cPrev ) ||
+ ( cEnDash && cEnDash == cPrev );
+
+ InsertQuote( rDoc, nInsPos, cChar, bSttQuote, bInsert );
+ nRet = bSingle ? ChgSglQuotes : ChgQuotes;
+ break;
+ }
+
+ if( bInsert )
+ rDoc.Insert( nInsPos, cChar );
+ else
+ rDoc.Replace( nInsPos, cChar );
+ }
+
+ if( !nInsPos )
+ break;
+
+ xub_StrLen nPos = nInsPos - 1;
+
+ // Bug 19286: nur direkt hinter dem "Wort" aufsetzen
+ if( IsWordDelim( rTxt.GetChar( nPos )))
+ break;
+
+ // automatisches Fett oder Unterstreichen setzen?
+ if( '*' == cChar || '_' == cChar )
+ {
+ if( IsAutoCorrFlag( ChgWeightUnderl ) &&
+ FnChgWeightUnderl( rDoc, rTxt, 0, nPos+1 ) )
+ nRet = ChgWeightUnderl;
+ break;
+ }
+
+ while( nPos && !IsWordDelim( rTxt.GetChar( --nPos )))
+ ;
+
+ // Absatz-Anfang oder ein Blank gefunden, suche nach dem Wort
+ // Kuerzel im Auto
+ xub_StrLen nCapLttrPos = nPos+1; // auf das 1. Zeichen
+ if( !nPos && !IsWordDelim( rTxt.GetChar( 0 )))
+ --nCapLttrPos; // Absatz Anfang und kein Blank !
+
+ LanguageType eLang = rDoc.GetLanguage( nCapLttrPos, FALSE );
+ if( LANGUAGE_SYSTEM == eLang )
+ eLang = MsLangId::getSystemLanguage();
+ CharClass& rCC = GetCharClass( eLang );
+
+ // Bug 19285: Symbolzeichen nicht anfassen
+ if( lcl_IsSymbolChar( rCC, rTxt, nCapLttrPos, nInsPos ))
+ break;
+
+ if( IsAutoCorrFlag( Autocorrect ) )
+ {
+ const String* pPara = 0;
+ const String** ppPara = IsAutoCorrFlag(CptlSttSntnc) ? &pPara : 0;
+
+ BOOL bChgWord = rDoc.ChgAutoCorrWord( nCapLttrPos, nInsPos,
+ *this, ppPara );
+ if( !bChgWord )
+ {
+ // JP 16.06.98: dann versuche mal alle !AlphaNum. Zeichen los zu
+ // werden und teste dann nochmals
+ //JP 22.04.99: Bug 63883 - entferne nur die "Klammern Start/-Anfaenge",
+ // alle anderen Zeichen muessen drin bleiben.
+ xub_StrLen nCapLttrPos1 = nCapLttrPos, nInsPos1 = nInsPos;
+ while( nCapLttrPos1 < nInsPos &&
+ lcl_IsInAsciiArr( sImplSttSkipChars, rTxt.GetChar( nCapLttrPos1 ) )
+ )
+ ++nCapLttrPos1;
+ while( nCapLttrPos1 < nInsPos1 && nInsPos1 &&
+ lcl_IsInAsciiArr( sImplEndSkipChars, rTxt.GetChar( nInsPos1-1 ) )
+ )
+ --nInsPos1;
+
+ if( (nCapLttrPos1 != nCapLttrPos || nInsPos1 != nInsPos ) &&
+ nCapLttrPos1 < nInsPos1 &&
+ rDoc.ChgAutoCorrWord( nCapLttrPos1, nInsPos1, *this, ppPara ))
+ {
+ bChgWord = TRUE;
+ nCapLttrPos = nCapLttrPos1;
+ }
+ }
+
+ if( bChgWord )
+ {
+ nRet = Autocorrect;
+ if( pPara )
+ {
+ xub_StrLen nEnd = nCapLttrPos;
+ while( nEnd < pPara->Len() &&
+ !IsWordDelim( pPara->GetChar( nEnd )))
+ ++nEnd;
+
+ // Grossbuchstabe am Satz-Anfang ??
+ if( IsAutoCorrFlag( CptlSttSntnc ) &&
+ FnCptlSttSntnc( rDoc, *pPara, FALSE,
+ nCapLttrPos, nEnd, eLang ) )
+ nRet |= CptlSttSntnc;
+
+ if( IsAutoCorrFlag( ChgToEnEmDash ) &&
+ FnChgToEnEmDash( rDoc, rTxt, nCapLttrPos, nEnd, eLang ) )
+ nRet |= ChgToEnEmDash;
+ }
+ break;
+ }
+ }
+
+ if( ( IsAutoCorrFlag( nRet = ChgFractionSymbol ) &&
+ FnChgFractionSymbol( rDoc, rTxt, nCapLttrPos, nInsPos ) ) ||
+ ( IsAutoCorrFlag( nRet = ChgOrdinalNumber ) &&
+ FnChgOrdinalNumber( rDoc, rTxt, nCapLttrPos, nInsPos, eLang ) ) ||
+ ( IsAutoCorrFlag( nRet = SetINetAttr ) &&
+ ( ' ' == cChar || '\t' == cChar || 0x0a == cChar || !cChar ) &&
+ FnSetINetAttr( rDoc, rTxt, nCapLttrPos, nInsPos, eLang ) ) )
+ ;
+ else
+ {
+ nRet = 0;
+ // Grossbuchstabe am Satz-Anfang ??
+ if( IsAutoCorrFlag( CptlSttSntnc ) &&
+ FnCptlSttSntnc( rDoc, rTxt, TRUE, nCapLttrPos, nInsPos, eLang ) )
+ nRet |= CptlSttSntnc;
+
+ // Zwei Grossbuchstaben am Wort-Anfang ??
+ if( IsAutoCorrFlag( CptlSttWrd ) &&
+ FnCptlSttWrd( rDoc, rTxt, nCapLttrPos, nInsPos, eLang ) )
+ nRet |= CptlSttWrd;
+
+ if( IsAutoCorrFlag( ChgToEnEmDash ) &&
+ FnChgToEnEmDash( rDoc, rTxt, nCapLttrPos, nInsPos, eLang ) )
+ nRet |= ChgToEnEmDash;
+ }
+
+ } while( FALSE );
+
+ if( nRet )
+ {
+ ULONG nHelpId = 0;
+ if( nRet & ( Autocorrect|CptlSttSntnc|CptlSttWrd|ChgToEnEmDash ) )
+ {
+ // von 0 - 15
+ if( nRet & ChgToEnEmDash )
+ nHelpId += 8;
+ if( nRet & Autocorrect )
+ nHelpId += 4;
+ if( nRet & CptlSttSntnc )
+ nHelpId += 2;
+ if( nRet & CptlSttWrd )
+ nHelpId += 1;
+ }
+ else
+ {
+ if( nRet & ChgQuotes) nHelpId = 16;
+ else if( nRet & ChgSglQuotes) nHelpId = 17;
+ else if( nRet & SetINetAttr) nHelpId = 18;
+ else if( nRet & IngnoreDoubleSpace) nHelpId = 19;
+ else if( nRet & ChgWeightUnderl) nHelpId = 20;
+ else if( nRet & ChgFractionSymbol ) nHelpId = 21;
+ else if( nRet & ChgOrdinalNumber) nHelpId = 22;
+ }
+
+ if( nHelpId )
+ {
+ nHelpId += HID_AUTOCORR_HELP_START - 1;
+ Application::GetHelp()->OpenHelpAgent( nHelpId );
+ }
+ }
+
+
+ return nRet;
+}
+
+SvxAutoCorrectLanguageLists& SvxAutoCorrect::_GetLanguageList(
+ LanguageType eLang )
+{
+ if( !pLangTable->IsKeyValid( ULONG( eLang )))
+ CreateLanguageFile( eLang, TRUE);
+ return *pLangTable->Seek( ULONG( eLang ) );
+}
+
+void SvxAutoCorrect::SaveCplSttExceptList( LanguageType eLang )
+{
+ if( pLangTable->IsKeyValid( ULONG( eLang )))
+ {
+ SvxAutoCorrectLanguageListsPtr pLists = pLangTable->Seek(ULONG(eLang));
+ if( pLists )
+ pLists->SaveCplSttExceptList();
+ }
+#ifdef DBG_UTIL
+ else
+ {
+ DBG_ERROR("speichern einer leeren Liste?");
+ }
+#endif
+}
+
+void SvxAutoCorrect::SaveWrdSttExceptList(LanguageType eLang)
+{
+ if(pLangTable->IsKeyValid(ULONG(eLang)))
+ {
+ SvxAutoCorrectLanguageListsPtr pLists = pLangTable->Seek(ULONG(eLang));
+ if(pLists)
+ pLists->SaveWrdSttExceptList();
+ }
+#ifdef DBG_UTIL
+ else
+ {
+ DBG_ERROR("speichern einer leeren Liste?");
+ }
+#endif
+}
+
+
+ // fuegt ein einzelnes Wort hinzu. Die Liste wird sofort
+ // in die Datei geschrieben!
+BOOL SvxAutoCorrect::AddCplSttException( const String& rNew,
+ LanguageType eLang )
+{
+ SvxAutoCorrectLanguageListsPtr pLists = 0;
+ //entweder die richtige Sprache ist vorhanden oder es kommt in die allg. Liste
+ if( pLangTable->IsKeyValid(ULONG(eLang)))
+ pLists = pLangTable->Seek(ULONG(eLang));
+ else if(pLangTable->IsKeyValid(ULONG(LANGUAGE_DONTKNOW))||
+ CreateLanguageFile(LANGUAGE_DONTKNOW, TRUE))
+ {
+ pLists = pLangTable->Seek(ULONG(LANGUAGE_DONTKNOW));
+ }
+ DBG_ASSERT(pLists, "keine Autokorrekturdatei");
+ return pLists->AddToCplSttExceptList(rNew);
+}
+
+
+ // fuegt ein einzelnes Wort hinzu. Die Liste wird sofort
+ // in die Datei geschrieben!
+BOOL SvxAutoCorrect::AddWrtSttException( const String& rNew,
+ LanguageType eLang )
+{
+ SvxAutoCorrectLanguageListsPtr pLists = 0;
+ //entweder die richtige Sprache ist vorhanden oder es kommt in die allg. Liste
+ if(pLangTable->IsKeyValid(ULONG(eLang)))
+ pLists = pLangTable->Seek(ULONG(eLang));
+ else if(pLangTable->IsKeyValid(ULONG(LANGUAGE_DONTKNOW))||
+ CreateLanguageFile(LANGUAGE_DONTKNOW, TRUE))
+ pLists = pLangTable->Seek(ULONG(LANGUAGE_DONTKNOW));
+ DBG_ASSERT(pLists, "keine Autokorrekturdatei");
+ return pLists->AddToWrdSttExceptList(rNew);
+}
+
+
+
+
+void SvxAutoCorrect::SetUserAutoCorrFileName( const String& rNew )
+{
+ if( sUserAutoCorrFile != rNew )
+ {
+ sUserAutoCorrFile = rNew;
+
+ // sind die Listen gesetzt sind, so muessen sie jetzt geloescht
+ // werden
+ lcl_ClearTable(*pLangTable);
+ nFlags &= ~(CplSttLstLoad | WrdSttLstLoad | ChgWordLstLoad );
+ }
+}
+
+void SvxAutoCorrect::SetShareAutoCorrFileName( const String& rNew )
+{
+ if( sShareAutoCorrFile != rNew )
+ {
+ sShareAutoCorrFile = rNew;
+
+ // sind die Listen gesetzt sind, so muessen sie jetzt geloescht
+ // werden
+ lcl_ClearTable(*pLangTable);
+ nFlags &= ~(CplSttLstLoad | WrdSttLstLoad | ChgWordLstLoad );
+ }
+}
+
+
+BOOL SvxAutoCorrect::GetPrevAutoCorrWord( SvxAutoCorrDoc& rDoc,
+ const String& rTxt, xub_StrLen nPos,
+ String& rWord ) const
+{
+ if( !nPos )
+ return FALSE;
+
+ xub_StrLen nEnde = nPos;
+
+ // dahinter muss ein Blank oder Tab folgen!
+ if( ( nPos < rTxt.Len() &&
+ !IsWordDelim( rTxt.GetChar( nPos ))) ||
+ IsWordDelim( rTxt.GetChar( --nPos )))
+ return FALSE;
+
+ while( nPos && !IsWordDelim( rTxt.GetChar( --nPos )))
+ ;
+
+ // Absatz-Anfang oder ein Blank gefunden, suche nach dem Wort
+ // Kuerzel im Auto
+ xub_StrLen nCapLttrPos = nPos+1; // auf das 1. Zeichen
+ if( !nPos && !IsWordDelim( rTxt.GetChar( 0 )))
+ --nCapLttrPos; // Absatz Anfang und kein Blank !
+
+ while( lcl_IsInAsciiArr( sImplSttSkipChars, rTxt.GetChar( nCapLttrPos )) )
+ if( ++nCapLttrPos >= nEnde )
+ return FALSE;
+
+ // Bug 19285: Symbolzeichen nicht anfassen
+ // Interresant erst ab 3 Zeichen
+ if( 3 > nEnde - nCapLttrPos )
+ return FALSE;
+
+ LanguageType eLang = rDoc.GetLanguage( nCapLttrPos, FALSE );
+ if( LANGUAGE_SYSTEM == eLang )
+ eLang = MsLangId::getSystemLanguage();
+
+ SvxAutoCorrect* pThis = (SvxAutoCorrect*)this;
+ CharClass& rCC = pThis->GetCharClass( eLang );
+
+ if( lcl_IsSymbolChar( rCC, rTxt, nCapLttrPos, nEnde ))
+ return FALSE;
+
+ rWord = rTxt.Copy( nCapLttrPos, nEnde - nCapLttrPos );
+ return TRUE;
+}
+
+BOOL SvxAutoCorrect::CreateLanguageFile( LanguageType eLang, BOOL bNewFile )
+{
+ DBG_ASSERT(!pLangTable->IsKeyValid(ULONG(eLang)), "Sprache ist bereits vorhanden");
+
+ String sUserDirFile( GetAutoCorrFileName( eLang, TRUE, FALSE )),
+ sShareDirFile( sUserDirFile );
+ SvxAutoCorrectLanguageListsPtr pLists = 0;
+
+ Time nMinTime( 0, 2 ), nAktTime, nLastCheckTime;
+ ULONG nFndPos;
+ if( TABLE_ENTRY_NOTFOUND !=
+ pLastFileTable->SearchKey( ULONG( eLang ), &nFndPos ) &&
+ ( nLastCheckTime.SetTime( pLastFileTable->GetObject( nFndPos )),
+ nLastCheckTime < nAktTime ) &&
+ ( nAktTime - nLastCheckTime ) < nMinTime )
+ {
+ // no need to test the file, because the last check is not older then
+ // 2 minutes.
+ if( bNewFile )
+ {
+ sShareDirFile = sUserDirFile;
+ pLists = new SvxAutoCorrectLanguageLists( *this, sShareDirFile,
+ sUserDirFile, eLang );
+ pLangTable->Insert( ULONG(eLang), pLists );
+ pLastFileTable->Remove( ULONG( eLang ) );
+ }
+ }
+ else if( ( FStatHelper::IsDocument( sUserDirFile ) ||
+ FStatHelper::IsDocument( sShareDirFile =
+ GetAutoCorrFileName( eLang, FALSE, FALSE ) ) ) ||
+ ( sShareDirFile = sUserDirFile, bNewFile ))
+ {
+ pLists = new SvxAutoCorrectLanguageLists( *this, sShareDirFile,
+ sUserDirFile, eLang );
+ pLangTable->Insert( ULONG(eLang), pLists );
+ pLastFileTable->Remove( ULONG( eLang ) );
+ }
+ else if( !bNewFile )
+ {
+ if( !pLastFileTable->Insert( ULONG( eLang ), nAktTime.GetTime() ))
+ pLastFileTable->Replace( ULONG( eLang ), nAktTime.GetTime() );
+ }
+ return pLists != 0;
+}
+
+BOOL SvxAutoCorrect::PutText( const String& rShort, const String& rLong,
+ LanguageType eLang )
+{
+ BOOL bRet = FALSE;
+ if( pLangTable->IsKeyValid( ULONG(eLang)) || CreateLanguageFile(eLang) )
+ bRet = pLangTable->Seek( ULONG(eLang) )->PutText(rShort, rLong);
+ return bRet;
+}
+
+
+ // - loesche einen Eintrag
+BOOL SvxAutoCorrect::DeleteText( const String& rShort, LanguageType eLang )
+{
+ BOOL bRet = FALSE;
+ if( pLangTable->IsKeyValid( ULONG( eLang )) )
+ bRet = pLangTable->Seek( ULONG( eLang ))->DeleteText( rShort );
+ return bRet;
+}
+
+
+ // - return den Ersetzungstext (nur fuer SWG-Format, alle anderen
+ // koennen aus der Wortliste herausgeholt werden!)
+BOOL SvxAutoCorrect::GetLongText( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >&, const String&, const String& , String& )
+{
+ return FALSE;
+}
+
+ // - Text mit Attributierung (kann nur der SWG - SWG-Format!)
+BOOL SvxAutoCorrect::PutText( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >&, const String&, const String&, SfxObjectShell&,
+ String& )
+{
+ return FALSE;
+}
+
+void EncryptBlockName_Imp( String& rName )
+{
+ xub_StrLen nLen, nPos = 1;
+ rName.Insert( '#', 0 );
+ sal_Unicode* pName = rName.GetBufferAccess();
+ for ( nLen = rName.Len(), ++pName; nPos < nLen; ++nPos, ++pName )
+ {
+ if( lcl_IsInAsciiArr( "!/:.\\", *pName ))
+ *pName &= 0x0f;
+ }
+}
+
+/* This code is copied from SwXMLTextBlocks::GeneratePackageName */
+void GeneratePackageName ( const String& rShort, String& rPackageName )
+{
+ rPackageName = rShort;
+ xub_StrLen nPos = 0;
+ sal_Unicode pDelims[] = { '!', '/', ':', '.', '\\', 0 };
+ ByteString sByte ( rPackageName, RTL_TEXTENCODING_UTF7);
+ rPackageName = String (sByte, RTL_TEXTENCODING_ASCII_US);
+ while( STRING_NOTFOUND != ( nPos = rPackageName.SearchChar( pDelims, nPos )))
+ {
+ rPackageName.SetChar( nPos, '_' );
+ ++nPos;
+ }
+}
+
+void DecryptBlockName_Imp( String& rName )
+{
+ if( '#' == rName.GetChar( 0 ) )
+ {
+ rName.Erase( 0, 1 );
+ sal_Unicode* pName = rName.GetBufferAccess();
+ xub_StrLen nLen, nPos;
+ for ( nLen = rName.Len(), nPos = 0; nPos < nLen; ++nPos, ++pName )
+ switch( *pName )
+ {
+ case 0x01: *pName = '!'; break;
+ case 0x0A: *pName = ':'; break;
+ case 0x0C: *pName = '\\'; break;
+ case 0x0E: *pName = '.'; break;
+ case 0x0F: *pName = '/'; break;
+ }
+ }
+}
+
+
+/* -----------------18.11.98 16:00-------------------
+ *
+ * --------------------------------------------------*/
+const SvxAutocorrWord* lcl_SearchWordsInList(
+ SvxAutoCorrectLanguageListsPtr pList, const String& rTxt,
+ xub_StrLen& rStt, xub_StrLen nEndPos, SvxAutoCorrDoc& )
+{
+ const SvxAutocorrWordList* pAutoCorrWordList = pList->GetAutocorrWordList();
+ TransliterationWrapper& rCmp = GetIgnoreTranslWrapper();
+ for( xub_StrLen nPos = 0; nPos < pAutoCorrWordList->Count(); ++nPos )
+ {
+ const SvxAutocorrWord* pFnd = (*pAutoCorrWordList)[ nPos ];
+ const String& rChk = pFnd->GetShort();
+ if( nEndPos >= rChk.Len() )
+ {
+ xub_StrLen nCalcStt = nEndPos - rChk.Len();
+ if( ( !nCalcStt || nCalcStt == rStt ||
+ ( nCalcStt < rStt &&
+ IsWordDelim( rTxt.GetChar(nCalcStt - 1 ) ))) )
+ {
+ String sWord( rTxt.GetBuffer() + nCalcStt, rChk.Len() );
+ if( rCmp.isEqual( rChk, sWord ))
+ {
+ rStt = nCalcStt;
+ return pFnd;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+
+// suche das oder die Worte in der ErsetzungsTabelle
+const SvxAutocorrWord* SvxAutoCorrect::SearchWordsInList(
+ const String& rTxt, xub_StrLen& rStt, xub_StrLen nEndPos,
+ SvxAutoCorrDoc& rDoc, LanguageType& rLang )
+{
+ LanguageType eLang = rLang;
+ const SvxAutocorrWord* pRet = 0;
+ if( LANGUAGE_SYSTEM == eLang )
+ eLang = MsLangId::getSystemLanguage();
+
+ // zuerst nach eLang suchen, dann nach der Obersprache
+ // US-Englisch -> Englisch und zuletzt in LANGUAGE_DONTKNOW
+
+ if( pLangTable->IsKeyValid( ULONG( eLang ) ) ||
+ CreateLanguageFile( eLang, FALSE ))
+ {
+ //die Sprache ist vorhanden - also her damit
+ SvxAutoCorrectLanguageListsPtr pList = pLangTable->Seek(ULONG(eLang));
+ pRet = lcl_SearchWordsInList( pList, rTxt, rStt, nEndPos, rDoc );
+ if( pRet )
+ {
+ rLang = eLang;
+ return pRet;
+ }
+ }
+
+ // wenn es hier noch nicht gefunden werden konnte, dann weitersuchen
+ ULONG nTmpKey1 = eLang & 0x7ff, // die Hauptsprache in vielen Faellen u.B. DE
+ nTmpKey2 = eLang & 0x3ff, // sonst z.B. EN
+ nTmp;
+
+ if( ((nTmp = nTmpKey1) != (ULONG)eLang &&
+ ( pLangTable->IsKeyValid( nTmpKey1 ) ||
+ CreateLanguageFile( LanguageType( nTmpKey1 ), FALSE ) )) ||
+ (( nTmp = nTmpKey2) != (ULONG)eLang &&
+ ( pLangTable->IsKeyValid( nTmpKey2 ) ||
+ CreateLanguageFile( LanguageType( nTmpKey2 ), FALSE ) )) )
+ {
+ //die Sprache ist vorhanden - also her damit
+ SvxAutoCorrectLanguageListsPtr pList = pLangTable->Seek( nTmp );
+ pRet = lcl_SearchWordsInList( pList, rTxt, rStt, nEndPos, rDoc);
+ if( pRet )
+ {
+ rLang = LanguageType( nTmp );
+ return pRet;
+ }
+ }
+ if( pLangTable->IsKeyValid( ULONG( LANGUAGE_DONTKNOW ) ) ||
+ CreateLanguageFile( LANGUAGE_DONTKNOW, FALSE ) )
+ {
+ //die Sprache ist vorhanden - also her damit
+ SvxAutoCorrectLanguageListsPtr pList = pLangTable->Seek(ULONG(LANGUAGE_DONTKNOW));
+ pRet = lcl_SearchWordsInList( pList, rTxt, rStt, nEndPos, rDoc);
+ if( pRet )
+ {
+ rLang = LANGUAGE_DONTKNOW;
+ return pRet;
+ }
+ }
+ return 0;
+}
+/* -----------------18.11.98 13:46-------------------
+ *
+ * --------------------------------------------------*/
+BOOL SvxAutoCorrect::FindInWrdSttExceptList( LanguageType eLang,
+ const String& sWord )
+{
+ //zuerst nach eLang suchen, dann nach der Obersprace US-Englisch -> Englisch
+ //und zuletzt in LANGUAGE_DONTKNOW
+ ULONG nTmpKey1 = eLang & 0x7ff; // die Hauptsprache in vielen Faellen u.B. DE
+ ULONG nTmpKey2 = eLang & 0x3ff; // sonst z.B. EN
+ String sTemp(sWord);
+ if( pLangTable->IsKeyValid( ULONG( eLang )) ||
+ CreateLanguageFile( eLang, FALSE ) )
+ {
+ //die Sprache ist vorhanden - also her damit
+ SvxAutoCorrectLanguageListsPtr pList = pLangTable->Seek(ULONG(eLang));
+ String _sTemp(sWord);
+ if(pList->GetWrdSttExceptList()->Seek_Entry(&_sTemp))
+ return TRUE;
+
+ }
+ // wenn es hier noch nicht gefunden werden konnte, dann weitersuchen
+ ULONG nTmp;
+ if( ((nTmp = nTmpKey1) != (ULONG)eLang &&
+ ( pLangTable->IsKeyValid( nTmpKey1 ) ||
+ CreateLanguageFile( LanguageType( nTmpKey1 ), FALSE ) )) ||
+ (( nTmp = nTmpKey2) != (ULONG)eLang &&
+ ( pLangTable->IsKeyValid( nTmpKey2 ) ||
+ CreateLanguageFile( LanguageType( nTmpKey2 ), FALSE ) )) )
+ {
+ //die Sprache ist vorhanden - also her damit
+ SvxAutoCorrectLanguageListsPtr pList = pLangTable->Seek(nTmp);
+ if(pList->GetWrdSttExceptList()->Seek_Entry(&sTemp))
+ return TRUE;
+ }
+ if(pLangTable->IsKeyValid(ULONG(LANGUAGE_DONTKNOW))|| CreateLanguageFile(LANGUAGE_DONTKNOW, FALSE))
+ {
+ //die Sprache ist vorhanden - also her damit
+ SvxAutoCorrectLanguageListsPtr pList = pLangTable->Seek(ULONG(LANGUAGE_DONTKNOW));
+ if(pList->GetWrdSttExceptList()->Seek_Entry(&sTemp))
+ return TRUE;
+ }
+ return FALSE;
+}
+/* -----------------18.11.98 14:28-------------------
+ *
+ * --------------------------------------------------*/
+BOOL lcl_FindAbbreviation( const SvStringsISortDtor* pList, const String& sWord)
+{
+ String sAbk( '~' );
+ USHORT nPos;
+ pList->Seek_Entry( &sAbk, &nPos );
+ if( nPos < pList->Count() )
+ {
+ String sLowerWord( sWord ); sLowerWord.ToLowerAscii();
+ const String* pAbk;
+ for( USHORT n = nPos;
+ n < pList->Count() &&
+ '~' == ( pAbk = (*pList)[ n ])->GetChar( 0 );
+ ++n )
+ {
+ // ~ und ~. sind nicht erlaubt!
+ if( 2 < pAbk->Len() && pAbk->Len() - 1 <= sWord.Len() )
+ {
+ String sLowerAbk( *pAbk ); sLowerAbk.ToLowerAscii();
+ for( xub_StrLen i = sLowerAbk.Len(), ii = sLowerWord.Len(); i; )
+ {
+ if( !--i ) // stimmt ueberein
+ return TRUE;
+
+ if( sLowerAbk.GetChar( i ) != sLowerWord.GetChar( --ii ))
+ break;
+ }
+ }
+ }
+ }
+ DBG_ASSERT( !(nPos && '~' == (*pList)[ --nPos ]->GetChar( 0 ) ),
+ "falsch sortierte ExeptionListe?" );
+ return FALSE;
+}
+/* -----------------18.11.98 14:49-------------------
+ *
+ * --------------------------------------------------*/
+BOOL SvxAutoCorrect::FindInCplSttExceptList(LanguageType eLang,
+ const String& sWord, BOOL bAbbreviation)
+{
+ //zuerst nach eLang suchen, dann nach der Obersprace US-Englisch -> Englisch
+ //und zuletzt in LANGUAGE_DONTKNOW
+ ULONG nTmpKey1 = eLang & 0x7ff; // die Hauptsprache in vielen Faellen u.B. DE
+ ULONG nTmpKey2 = eLang & 0x3ff; // sonst z.B. EN
+ String sTemp( sWord );
+ if( pLangTable->IsKeyValid( ULONG( eLang )) ||
+ CreateLanguageFile( eLang, FALSE ))
+ {
+ //die Sprache ist vorhanden - also her damit
+ SvxAutoCorrectLanguageListsPtr pLists = pLangTable->Seek(ULONG(eLang));
+ const SvStringsISortDtor* pList = pLists->GetCplSttExceptList();
+ if(bAbbreviation ? lcl_FindAbbreviation( pList, sWord)
+ : pList->Seek_Entry( &sTemp ) )
+ return TRUE;
+ }
+ // wenn es hier noch nicht gefunden werden konnte, dann weitersuchen
+ ULONG nTmp;
+
+ if( ((nTmp = nTmpKey1) != (ULONG)eLang &&
+ ( pLangTable->IsKeyValid( nTmpKey1 ) ||
+ CreateLanguageFile( LanguageType( nTmpKey1 ), FALSE ) )) ||
+ (( nTmp = nTmpKey2) != (ULONG)eLang &&
+ ( pLangTable->IsKeyValid( nTmpKey2 ) ||
+ CreateLanguageFile( LanguageType( nTmpKey2 ), FALSE ) )) )
+ {
+ //die Sprache ist vorhanden - also her damit
+ SvxAutoCorrectLanguageListsPtr pLists = pLangTable->Seek(nTmp);
+ const SvStringsISortDtor* pList = pLists->GetCplSttExceptList();
+ if(bAbbreviation ? lcl_FindAbbreviation( pList, sWord)
+ : pList->Seek_Entry( &sTemp ) )
+ return TRUE;
+ }
+ if(pLangTable->IsKeyValid(ULONG(LANGUAGE_DONTKNOW))|| CreateLanguageFile(LANGUAGE_DONTKNOW, FALSE))
+ {
+ //die Sprache ist vorhanden - also her damit
+ SvxAutoCorrectLanguageListsPtr pLists = pLangTable->Seek(LANGUAGE_DONTKNOW);
+ const SvStringsISortDtor* pList = pLists->GetCplSttExceptList();
+ if(bAbbreviation ? lcl_FindAbbreviation( pList, sWord)
+ : pList->Seek_Entry( &sTemp ) )
+ return TRUE;
+ }
+ return FALSE;
+
+}
+
+/* -----------------20.11.98 11:53-------------------
+ *
+ * --------------------------------------------------*/
+String SvxAutoCorrect::GetAutoCorrFileName( LanguageType eLang,
+ BOOL bNewFile, BOOL bTst ) const
+{
+ String sRet, sExt( MsLangId::convertLanguageToIsoString( eLang ) );
+ sExt.Insert('_', 0);
+ sExt.AppendAscii( ".dat" );
+ if( bNewFile )
+ ( sRet = sUserAutoCorrFile ) += sExt;
+ else if( !bTst )
+ ( sRet = sShareAutoCorrFile ) += sExt;
+ else
+ {
+ // test first in the user directory - if not exist, then
+ ( sRet = sUserAutoCorrFile ) += sExt;
+ if( !FStatHelper::IsDocument( sRet ))
+ ( sRet = sShareAutoCorrFile ) += sExt;
+ }
+ return sRet;
+}
+
+/* -----------------18.11.98 11:16-------------------
+ *
+ * --------------------------------------------------*/
+SvxAutoCorrectLanguageLists::SvxAutoCorrectLanguageLists(
+ SvxAutoCorrect& rParent,
+ const String& rShareAutoCorrectFile,
+ const String& rUserAutoCorrectFile,
+ LanguageType eLang)
+: sShareAutoCorrFile( rShareAutoCorrectFile ),
+ sUserAutoCorrFile( rUserAutoCorrectFile ),
+ eLanguage(eLang),
+ pCplStt_ExcptLst( 0 ),
+ pWrdStt_ExcptLst( 0 ),
+ pAutocorr_List( 0 ),
+ rAutoCorrect(rParent),
+ nFlags(0)
+{
+}
+
+/* -----------------18.11.98 11:16-------------------
+ *
+ * --------------------------------------------------*/
+SvxAutoCorrectLanguageLists::~SvxAutoCorrectLanguageLists()
+{
+ delete pCplStt_ExcptLst;
+ delete pWrdStt_ExcptLst;
+ delete pAutocorr_List;
+}
+
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+BOOL SvxAutoCorrectLanguageLists::IsFileChanged_Imp()
+{
+ // nur alle 2 Minuten aufs FileSystem zugreifen um den
+ // Dateistempel zu ueberpruefen
+ BOOL bRet = FALSE;
+
+ Time nMinTime( 0, 2 );
+ Time nAktTime;
+ if( aLastCheckTime > nAktTime || // ueberlauf ?
+ ( nAktTime -= aLastCheckTime ) > nMinTime ) // min Zeit vergangen
+ {
+ Date aTstDate; Time aTstTime;
+ if( FStatHelper::GetModifiedDateTimeOfFile( sShareAutoCorrFile,
+ &aTstDate, &aTstTime ) &&
+ ( aModifiedDate != aTstDate || aModifiedTime != aTstTime ))
+ {
+ bRet = TRUE;
+ // dann mal schnell alle Listen entfernen!
+ if( CplSttLstLoad & nFlags && pCplStt_ExcptLst )
+ delete pCplStt_ExcptLst, pCplStt_ExcptLst = 0;
+ if( WrdSttLstLoad & nFlags && pWrdStt_ExcptLst )
+ delete pWrdStt_ExcptLst, pWrdStt_ExcptLst = 0;
+ if( ChgWordLstLoad & nFlags && pAutocorr_List )
+ delete pAutocorr_List, pAutocorr_List = 0;
+ nFlags &= ~(CplSttLstLoad | WrdSttLstLoad | ChgWordLstLoad );
+ }
+ aLastCheckTime = Time();
+ }
+ return bRet;
+}
+
+void SvxAutoCorrectLanguageLists::LoadXMLExceptList_Imp(
+ SvStringsISortDtor*& rpLst,
+ const sal_Char* pStrmName,
+ SotStorageRef& rStg)
+{
+ if( rpLst )
+ rpLst->DeleteAndDestroy( 0, rpLst->Count() );
+ else
+ rpLst = new SvStringsISortDtor( 16, 16 );
+
+ {
+ String sStrmName( pStrmName, RTL_TEXTENCODING_MS_1252 );
+ String sTmp( sStrmName );
+
+ if( rStg.Is() && rStg->IsStream( sStrmName ) )
+ {
+ SvStorageStreamRef xStrm = rStg->OpenSotStream( sTmp,
+ ( STREAM_READ | STREAM_SHARE_DENYWRITE | STREAM_NOCREATE ) );
+ if( SVSTREAM_OK != xStrm->GetError())
+ {
+ xStrm.Clear();
+ rStg.Clear();
+ RemoveStream_Imp( sStrmName );
+ }
+ else
+ {
+ uno::Reference< lang::XMultiServiceFactory > xServiceFactory =
+ comphelper::getProcessServiceFactory();
+ DBG_ASSERT( xServiceFactory.is(),
+ "XMLReader::Read: got no service manager" );
+ if( !xServiceFactory.is() )
+ {
+ // Throw an exception ?
+ }
+
+ xml::sax::InputSource aParserInput;
+ aParserInput.sSystemId = sStrmName;
+
+ xStrm->Seek( 0L );
+ xStrm->SetBufferSize( 8 * 1024 );
+ aParserInput.aInputStream = new utl::OInputStreamWrapper( *xStrm );
+
+ // get parser
+ uno::Reference< XInterface > xXMLParser = xServiceFactory->createInstance(
+ OUString::createFromAscii("com.sun.star.xml.sax.Parser") );
+ DBG_ASSERT( xXMLParser.is(),
+ "XMLReader::Read: com.sun.star.xml.sax.Parser service missing" );
+ if( !xXMLParser.is() )
+ {
+ // Maybe throw an exception?
+ }
+
+ // get filter
+ // #110680#
+ // uno::Reference< xml::sax::XDocumentHandler > xFilter = new SvXMLExceptionListImport ( *rpLst );
+ uno::Reference< xml::sax::XDocumentHandler > xFilter = new SvXMLExceptionListImport ( xServiceFactory, *rpLst );
+
+ // connect parser and filter
+ uno::Reference< xml::sax::XParser > xParser( xXMLParser, UNO_QUERY );
+ xParser->setDocumentHandler( xFilter );
+
+ // parse
+ try
+ {
+ xParser->parseStream( aParserInput );
+ }
+ catch( xml::sax::SAXParseException& )
+ {
+ // re throw ?
+ }
+ catch( xml::sax::SAXException& )
+ {
+ // re throw ?
+ }
+ catch( io::IOException& )
+ {
+ // re throw ?
+ }
+ }
+ }
+
+ // Zeitstempel noch setzen
+ FStatHelper::GetModifiedDateTimeOfFile( sShareAutoCorrFile,
+ &aModifiedDate, &aModifiedTime );
+ aLastCheckTime = Time();
+ }
+
+}
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+void SvxAutoCorrectLanguageLists::SaveExceptList_Imp(
+ const SvStringsISortDtor& rLst,
+ const sal_Char* pStrmName,
+ SotStorageRef &rStg,
+ BOOL bConvert )
+{
+ if( rStg.Is() )
+ {
+ String sStrmName( pStrmName, RTL_TEXTENCODING_MS_1252 );
+ if( !rLst.Count() )
+ {
+ rStg->Remove( sStrmName );
+ rStg->Commit();
+ }
+ else
+ {
+ SotStorageStreamRef xStrm = rStg->OpenSotStream( sStrmName,
+ ( STREAM_READ | STREAM_WRITE | STREAM_SHARE_DENYWRITE ) );
+ if( xStrm.Is() )
+ {
+ xStrm->SetSize( 0 );
+ xStrm->SetBufferSize( 8192 );
+ String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
+ OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
+ uno::Any aAny;
+ aAny <<= aMime;
+ xStrm->SetProperty( aPropName, aAny );
+
+
+ uno::Reference< lang::XMultiServiceFactory > xServiceFactory =
+ comphelper::getProcessServiceFactory();
+ DBG_ASSERT( xServiceFactory.is(),
+ "XMLReader::Read: got no service manager" );
+ if( !xServiceFactory.is() )
+ {
+ // Throw an exception ?
+ }
+
+ uno::Reference < XInterface > xWriter (xServiceFactory->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer"))));
+ DBG_ASSERT(xWriter.is(),"com.sun.star.xml.sax.Writer service missing");
+ uno::Reference < io::XOutputStream> xOut = new utl::OOutputStreamWrapper( *xStrm );
+ uno::Reference<io::XActiveDataSource> xSrc(xWriter, uno::UNO_QUERY);
+ xSrc->setOutputStream(xOut);
+
+ uno::Reference<xml::sax::XDocumentHandler> xHandler(xWriter, uno::UNO_QUERY);
+
+ // #110680#
+ // SvXMLExceptionListExport aExp(rLst, sStrmName, xHandler);
+ SvXMLExceptionListExport aExp( xServiceFactory, rLst, sStrmName, xHandler );
+
+ aExp.exportDoc( XML_BLOCK_LIST );
+
+ xStrm->Commit();
+ if( xStrm->GetError() == SVSTREAM_OK )
+ {
+ xStrm.Clear();
+ if (!bConvert)
+ {
+ rStg->Commit();
+ if( SVSTREAM_OK != rStg->GetError() )
+ {
+ rStg->Remove( sStrmName );
+ rStg->Commit();
+ }
+ }
+ }
+ }
+ }
+ }
+}
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+SvxAutocorrWordList* SvxAutoCorrectLanguageLists::LoadAutocorrWordList()
+{
+ if( pAutocorr_List )
+ pAutocorr_List->DeleteAndDestroy( 0, pAutocorr_List->Count() );
+ else
+ pAutocorr_List = new SvxAutocorrWordList( 16, 16 );
+
+ SvStringsDtor aRemoveArr;
+ try
+ {
+ uno::Reference < embed::XStorage > xStg = comphelper::OStorageHelper::GetStorageFromURL( sShareAutoCorrFile, embed::ElementModes::READ );
+ String aXMLWordListName( pXMLImplAutocorr_ListStr, RTL_TEXTENCODING_MS_1252 );
+ uno::Reference < io::XStream > xStrm = xStg->openStreamElement( aXMLWordListName, embed::ElementModes::READ );
+ uno::Reference< lang::XMultiServiceFactory > xServiceFactory = comphelper::getProcessServiceFactory();
+
+ xml::sax::InputSource aParserInput;
+ aParserInput.sSystemId = aXMLWordListName;
+ aParserInput.aInputStream = xStrm->getInputStream();
+
+ // get parser
+ uno::Reference< XInterface > xXMLParser = xServiceFactory->createInstance( OUString::createFromAscii("com.sun.star.xml.sax.Parser") );
+ DBG_ASSERT( xXMLParser.is(), "XMLReader::Read: com.sun.star.xml.sax.Parser service missing" );
+ if( xXMLParser.is() )
+ {
+ uno::Reference< xml::sax::XDocumentHandler > xFilter = new SvXMLAutoCorrectImport( xServiceFactory, pAutocorr_List, rAutoCorrect, xStg );
+
+ // connect parser and filter
+ uno::Reference< xml::sax::XParser > xParser( xXMLParser, UNO_QUERY );
+ xParser->setDocumentHandler( xFilter );
+
+ // parse
+ xParser->parseStream( aParserInput );
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ }
+
+ // Zeitstempel noch setzen
+ FStatHelper::GetModifiedDateTimeOfFile( sShareAutoCorrFile,
+ &aModifiedDate, &aModifiedTime );
+ aLastCheckTime = Time();
+
+ return pAutocorr_List;
+}
+
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+
+void SvxAutoCorrectLanguageLists::SetAutocorrWordList( SvxAutocorrWordList* pList )
+{
+ if( pAutocorr_List && pList != pAutocorr_List )
+ delete pAutocorr_List;
+ pAutocorr_List = pList;
+ if( !pAutocorr_List )
+ {
+ DBG_ASSERT( !this, "keine gueltige Liste" );
+ pAutocorr_List = new SvxAutocorrWordList( 16, 16 );
+ }
+ nFlags |= ChgWordLstLoad;
+}
+
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+const SvxAutocorrWordList* SvxAutoCorrectLanguageLists::GetAutocorrWordList()
+{
+ if( !( ChgWordLstLoad & nFlags ) || IsFileChanged_Imp() )
+ SetAutocorrWordList( LoadAutocorrWordList() );
+ return pAutocorr_List;
+}
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+SvStringsISortDtor* SvxAutoCorrectLanguageLists::GetCplSttExceptList()
+{
+ if( !( CplSttLstLoad & nFlags ) || IsFileChanged_Imp() )
+ SetCplSttExceptList( LoadCplSttExceptList() );
+ return pCplStt_ExcptLst;
+}
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+BOOL SvxAutoCorrectLanguageLists::AddToCplSttExceptList(const String& rNew)
+{
+ String* pNew = new String( rNew );
+ if( rNew.Len() && GetCplSttExceptList()->Insert( pNew ) )
+ {
+ MakeUserStorage_Impl();
+ SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, TRUE );
+
+ SaveExceptList_Imp( *pCplStt_ExcptLst, pXMLImplCplStt_ExcptLstStr, xStg );
+
+ xStg = 0;
+ // Zeitstempel noch setzen
+ FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile,
+ &aModifiedDate, &aModifiedTime );
+ aLastCheckTime = Time();
+ }
+ else
+ delete pNew, pNew = 0;
+ return 0 != pNew;
+}
+/* -----------------18.11.98 15:20-------------------
+ *
+ * --------------------------------------------------*/
+BOOL SvxAutoCorrectLanguageLists::AddToWrdSttExceptList(const String& rNew)
+{
+ String* pNew = new String( rNew );
+ SvStringsISortDtor* pExceptList = LoadWrdSttExceptList();
+ if( rNew.Len() && pExceptList && pExceptList->Insert( pNew ) )
+ {
+ MakeUserStorage_Impl();
+ SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, TRUE );
+
+ SaveExceptList_Imp( *pWrdStt_ExcptLst, pXMLImplWrdStt_ExcptLstStr, xStg );
+
+ xStg = 0;
+ // Zeitstempel noch setzen
+ FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile,
+ &aModifiedDate, &aModifiedTime );
+ aLastCheckTime = Time();
+ }
+ else
+ delete pNew, pNew = 0;
+ return 0 != pNew;
+}
+
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+SvStringsISortDtor* SvxAutoCorrectLanguageLists::LoadCplSttExceptList()
+{
+ SotStorageRef xStg = new SotStorage( sShareAutoCorrFile, STREAM_READ | STREAM_SHARE_DENYNONE, TRUE );
+ String sTemp ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplCplStt_ExcptLstStr ) );
+ if( xStg.Is() && xStg->IsContained( sTemp ) )
+ LoadXMLExceptList_Imp( pCplStt_ExcptLst, pXMLImplCplStt_ExcptLstStr, xStg );
+
+ return pCplStt_ExcptLst;
+}
+
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+void SvxAutoCorrectLanguageLists::SaveCplSttExceptList()
+{
+ MakeUserStorage_Impl();
+ SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, TRUE );
+
+ SaveExceptList_Imp( *pCplStt_ExcptLst, pXMLImplCplStt_ExcptLstStr, xStg );
+
+ xStg = 0;
+
+ // Zeitstempel noch setzen
+ FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile,
+ &aModifiedDate, &aModifiedTime );
+ aLastCheckTime = Time();
+}
+
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+void SvxAutoCorrectLanguageLists::SetCplSttExceptList( SvStringsISortDtor* pList )
+{
+ if( pCplStt_ExcptLst && pList != pCplStt_ExcptLst )
+ delete pCplStt_ExcptLst;
+
+ pCplStt_ExcptLst = pList;
+ if( !pCplStt_ExcptLst )
+ {
+ DBG_ASSERT( !this, "keine gueltige Liste" );
+ pCplStt_ExcptLst = new SvStringsISortDtor( 16, 16 );
+ }
+ nFlags |= CplSttLstLoad;
+}
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+SvStringsISortDtor* SvxAutoCorrectLanguageLists::LoadWrdSttExceptList()
+{
+ SotStorageRef xStg = new SotStorage( sShareAutoCorrFile, STREAM_READ | STREAM_SHARE_DENYNONE, TRUE );
+ String sTemp ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplWrdStt_ExcptLstStr ) );
+ if( xStg.Is() && xStg->IsContained( sTemp ) )
+ LoadXMLExceptList_Imp( pWrdStt_ExcptLst, pXMLImplWrdStt_ExcptLstStr, xStg );
+ return pWrdStt_ExcptLst;
+}
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+void SvxAutoCorrectLanguageLists::SaveWrdSttExceptList()
+{
+ MakeUserStorage_Impl();
+ SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, TRUE );
+
+ SaveExceptList_Imp( *pWrdStt_ExcptLst, pXMLImplWrdStt_ExcptLstStr, xStg );
+
+ xStg = 0;
+ // Zeitstempel noch setzen
+ FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile,
+ &aModifiedDate, &aModifiedTime );
+ aLastCheckTime = Time();
+}
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+void SvxAutoCorrectLanguageLists::SetWrdSttExceptList( SvStringsISortDtor* pList )
+{
+ if( pWrdStt_ExcptLst && pList != pWrdStt_ExcptLst )
+ delete pWrdStt_ExcptLst;
+ pWrdStt_ExcptLst = pList;
+ if( !pWrdStt_ExcptLst )
+ {
+ DBG_ASSERT( !this, "keine gueltige Liste" );
+ pWrdStt_ExcptLst = new SvStringsISortDtor( 16, 16 );
+ }
+ nFlags |= WrdSttLstLoad;
+}
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+SvStringsISortDtor* SvxAutoCorrectLanguageLists::GetWrdSttExceptList()
+{
+ if( !( WrdSttLstLoad & nFlags ) || IsFileChanged_Imp() )
+ SetWrdSttExceptList( LoadWrdSttExceptList() );
+ return pWrdStt_ExcptLst;
+}
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+void SvxAutoCorrectLanguageLists::RemoveStream_Imp( const String& rName )
+{
+ if( sShareAutoCorrFile != sUserAutoCorrFile )
+ {
+ SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, TRUE );
+ if( xStg.Is() && SVSTREAM_OK == xStg->GetError() &&
+ xStg->IsStream( rName ) )
+ {
+ xStg->Remove( rName );
+ xStg->Commit();
+
+ xStg = 0;
+ }
+ }
+}
+
+void SvxAutoCorrectLanguageLists::MakeUserStorage_Impl()
+{
+ // The conversion needs to happen if the file is already in the user
+ // directory and is in the old format. Additionally it needs to
+ // happen when the file is being copied from share to user.
+
+ sal_Bool bError = sal_False, bConvert = sal_False, bCopy = sal_False;
+ INetURLObject aDest;
+ INetURLObject aSource;
+
+// String sDestPath = sUserAutoCorrFile.Copy ( 0, sUserAutoCorrFile.Len()-3);
+// sDestPath.AppendAscii ("bak");
+
+
+ if (sUserAutoCorrFile != sShareAutoCorrFile )
+ {
+ aSource = INetURLObject ( sShareAutoCorrFile ); //aSource.setFSysPath ( sShareAutoCorrFile, INetURLObject::FSYS_DETECT );
+ aDest = INetURLObject ( sUserAutoCorrFile );
+ if ( SotStorage::IsOLEStorage ( sShareAutoCorrFile ) )
+ {
+ aDest.SetExtension ( String::CreateFromAscii ( "bak" ) );
+ bConvert = sal_True;
+ }
+ bCopy = sal_True;
+ }
+ else if ( SotStorage::IsOLEStorage ( sUserAutoCorrFile ) )
+ {
+ aSource = INetURLObject ( sUserAutoCorrFile );
+ aDest = INetURLObject ( sUserAutoCorrFile );
+ aDest.SetExtension ( String::CreateFromAscii ( "bak" ) );
+ bCopy = bConvert = sal_True;
+ }
+ if (bCopy)
+ {
+ try
+ {
+ String sMain(aDest.GetMainURL( INetURLObject::DECODE_TO_IURI ));
+ sal_Unicode cSlash = '/';
+ xub_StrLen nSlashPos = sMain.SearchBackward(cSlash);
+ sMain.Erase(nSlashPos);
+ ::ucbhelper::Content aNewContent( sMain, uno::Reference< XCommandEnvironment > ());
+ Any aAny;
+ TransferInfo aInfo;
+ aInfo.NameClash = NameClash::OVERWRITE;
+ aInfo.NewTitle = aDest.GetName();
+ aInfo.SourceURL = aSource.GetMainURL( INetURLObject::DECODE_TO_IURI );
+ aInfo.MoveData = FALSE;
+ aAny <<= aInfo;
+ aNewContent.executeCommand( OUString ( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ), aAny);
+ }
+ catch (...)
+ {
+ bError = sal_True;
+ }
+ }
+ if (bConvert && !bError)
+ {
+ SotStorageRef xSrcStg = new SotStorage( aDest.GetMainURL( INetURLObject::DECODE_TO_IURI ), STREAM_READ, TRUE );
+ SotStorageRef xDstStg = new SotStorage( sUserAutoCorrFile, STREAM_WRITE, TRUE );
+
+ if( xSrcStg.Is() && xDstStg.Is() )
+ {
+ String sWord ( RTL_CONSTASCII_USTRINGPARAM ( pImplWrdStt_ExcptLstStr ) );
+ String sSentence ( RTL_CONSTASCII_USTRINGPARAM ( pImplCplStt_ExcptLstStr ) );
+ String sXMLWord ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplWrdStt_ExcptLstStr ) );
+ String sXMLSentence ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplCplStt_ExcptLstStr ) );
+ SvStringsISortDtor *pTmpWordList = NULL;
+
+ if (xSrcStg->IsContained( sXMLWord ) )
+ LoadXMLExceptList_Imp( pTmpWordList, pXMLImplWrdStt_ExcptLstStr, xSrcStg );
+
+ if (pTmpWordList)
+ {
+ SaveExceptList_Imp( *pTmpWordList, pXMLImplWrdStt_ExcptLstStr, xDstStg, TRUE );
+ pTmpWordList->DeleteAndDestroy( 0, pTmpWordList->Count() );
+ pTmpWordList = NULL;
+ }
+
+
+ if (xSrcStg->IsContained( sXMLSentence ) )
+ LoadXMLExceptList_Imp( pTmpWordList, pXMLImplCplStt_ExcptLstStr, xSrcStg );
+
+ if (pTmpWordList)
+ {
+ SaveExceptList_Imp( *pTmpWordList, pXMLImplCplStt_ExcptLstStr, xDstStg, TRUE );
+ pTmpWordList->DeleteAndDestroy( 0, pTmpWordList->Count() );
+ }
+
+ GetAutocorrWordList();
+ MakeBlocklist_Imp( *xDstStg );
+ // xDstStg is committed in MakeBlocklist_Imp
+ /*xSrcStg->CopyTo( &xDstStg );*/
+ sShareAutoCorrFile = sUserAutoCorrFile;
+ xDstStg = 0;
+ try
+ {
+ ::ucbhelper::Content aContent ( aDest.GetMainURL( INetURLObject::DECODE_TO_IURI ), uno::Reference < XCommandEnvironment > ());
+ aContent.executeCommand ( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "delete" ) ), makeAny ( sal_Bool (sal_True ) ) );
+ }
+ catch (...)
+ {
+ }
+ }
+ }
+ else if( bCopy && !bError )
+ sShareAutoCorrFile = sUserAutoCorrFile;
+}
+
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+BOOL SvxAutoCorrectLanguageLists::MakeBlocklist_Imp( SvStorage& rStg )
+{
+ String sStrmName( pXMLImplAutocorr_ListStr, RTL_TEXTENCODING_MS_1252 );
+ BOOL bRet = TRUE, bRemove = !pAutocorr_List || !pAutocorr_List->Count();
+ if( !bRemove )
+ {
+ /*
+ if ( rStg.IsContained( sStrmName) )
+ {
+ rStg.Remove ( sStrmName );
+ rStg.Commit();
+ }
+ */
+ SvStorageStreamRef refList = rStg.OpenSotStream( sStrmName,
+ ( STREAM_READ | STREAM_WRITE | STREAM_SHARE_DENYWRITE ) );
+ if( refList.Is() )
+ {
+ refList->SetSize( 0 );
+ refList->SetBufferSize( 8192 );
+ String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
+ OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
+ uno::Any aAny;
+ aAny <<= aMime;
+ refList->SetProperty( aPropName, aAny );
+
+ uno::Reference< lang::XMultiServiceFactory > xServiceFactory =
+ comphelper::getProcessServiceFactory();
+ DBG_ASSERT( xServiceFactory.is(),
+ "XMLReader::Read: got no service manager" );
+ if( !xServiceFactory.is() )
+ {
+ // Throw an exception ?
+ }
+
+ uno::Reference < XInterface > xWriter (xServiceFactory->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer"))));
+ DBG_ASSERT(xWriter.is(),"com.sun.star.xml.sax.Writer service missing");
+ uno::Reference < io::XOutputStream> xOut = new utl::OOutputStreamWrapper( *refList );
+ uno::Reference<io::XActiveDataSource> xSrc(xWriter, uno::UNO_QUERY);
+ xSrc->setOutputStream(xOut);
+
+ uno::Reference<xml::sax::XDocumentHandler> xHandler(xWriter, uno::UNO_QUERY);
+
+ // #110680#
+ // SvXMLAutoCorrectExport aExp(pAutocorr_List, sStrmName, xHandler);
+ SvXMLAutoCorrectExport aExp( xServiceFactory, pAutocorr_List, sStrmName, xHandler );
+
+ aExp.exportDoc( XML_BLOCK_LIST );
+
+ refList->Commit();
+ bRet = SVSTREAM_OK == refList->GetError();
+ if( bRet )
+ {
+ refList.Clear();
+ rStg.Commit();
+ if( SVSTREAM_OK != rStg.GetError() )
+ {
+ bRemove = TRUE;
+ bRet = FALSE;
+ }
+ }
+
+ /*
+ refList->SetSize( 0 );
+ refList->SetBufferSize( 8192 );
+ rtl_TextEncoding eEncoding = gsl_getSystemTextEncoding();
+
+ String aDummy; // Erkennungszeichen fuer neue Streams
+ refList->WriteByteString( aDummy, RTL_TEXTENCODING_MS_1252 )
+ << (BYTE) 4 // Laenge des Headers (ohne den Leerstring)
+ << (USHORT)WORDLIST_VERSION_358 // Version des Streams
+ << (BYTE)eEncoding; // der Zeichensatz
+
+ for( USHORT i = 0; i < pAutocorr_List->Count() &&
+ SVSTREAM_OK == refList->GetError(); ++i )
+ {
+ SvxAutocorrWord* p = pAutocorr_List->GetObject( i );
+ refList->WriteByteString( p->GetShort(), eEncoding ).
+ WriteByteString( p->IsTextOnly()
+ ? p->GetLong()
+ : p->GetShort(), eEncoding );
+ }
+ refList->Commit();
+ bRet = SVSTREAM_OK == refList->GetError();
+ if( bRet )
+ {
+ refList.Clear();
+ rStg.Commit();
+ if( SVSTREAM_OK != rStg.GetError() )
+ {
+ bRemove = TRUE;
+ bRet = FALSE;
+ }
+ }
+ */
+ }
+ else
+ bRet = FALSE;
+ }
+
+ if( bRemove )
+ {
+ rStg.Remove( sStrmName );
+ rStg.Commit();
+ }
+
+ return bRet;
+}
+
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+BOOL SvxAutoCorrectLanguageLists::PutText( const String& rShort,
+ const String& rLong )
+{
+ // erstmal akt. Liste besorgen!
+ GetAutocorrWordList();
+
+ MakeUserStorage_Impl();
+ SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, TRUE );
+
+ BOOL bRet = xStg.Is() && SVSTREAM_OK == xStg->GetError();
+
+/* if( bRet )
+ {
+ // PutText( *xStg, rShort );
+ }
+*/
+ // die Wortliste aktualisieren
+ if( bRet )
+ {
+ USHORT nPos;
+ SvxAutocorrWord* pNew = new SvxAutocorrWord( rShort, rLong, TRUE );
+ if( pAutocorr_List->Seek_Entry( pNew, &nPos ) )
+ {
+ if( !(*pAutocorr_List)[ nPos ]->IsTextOnly() )
+ {
+ // dann ist der Storage noch zu entfernen
+ String sStgNm( rShort );
+ if (xStg->IsOLEStorage())
+ EncryptBlockName_Imp( sStgNm );
+ else
+ GeneratePackageName ( rShort, sStgNm);
+
+ if( xStg->IsContained( sStgNm ) )
+ xStg->Remove( sStgNm );
+ }
+ pAutocorr_List->DeleteAndDestroy( nPos );
+ }
+
+ if( pAutocorr_List->Insert( pNew ) )
+ {
+ bRet = MakeBlocklist_Imp( *xStg );
+ xStg = 0;
+ }
+ else
+ {
+ delete pNew;
+ bRet = FALSE;
+ }
+ }
+ return bRet;
+}
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+ // - Text mit Attributierung (kann nur der SWG - SWG-Format!)
+BOOL SvxAutoCorrectLanguageLists::PutText( const String& rShort,
+ SfxObjectShell& rShell )
+{
+ // erstmal akt. Liste besorgen!
+ GetAutocorrWordList();
+
+ MakeUserStorage_Impl();
+
+ BOOL bRet = FALSE;
+ String sLong;
+ try
+ {
+ uno::Reference < embed::XStorage > xStg = comphelper::OStorageHelper::GetStorageFromURL( sUserAutoCorrFile, embed::ElementModes::READWRITE );
+// String aName( rShort );
+// EncryptBlockName_Imp( aName );
+// bRet = PutText( *xStg, aName, rShell, sLong );
+ bRet = rAutoCorrect.PutText( xStg, sUserAutoCorrFile, rShort, rShell, sLong );
+ xStg = 0;
+
+ // die Wortliste aktualisieren
+ if( bRet )
+ {
+ SvxAutocorrWord* pNew = new SvxAutocorrWord( rShort, sLong, FALSE );
+ if( pAutocorr_List->Insert( pNew ) )
+ {
+ SotStorageRef xStor = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, TRUE );
+ MakeBlocklist_Imp( *xStor );
+ }
+ else
+ delete pNew;
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ }
+
+ return bRet;
+}
+
+/* -----------------18.11.98 11:26-------------------
+ *
+ * --------------------------------------------------*/
+ // - loesche einen Eintrag
+BOOL SvxAutoCorrectLanguageLists::DeleteText( const String& rShort )
+{
+ // erstmal akt. Liste besorgen!
+ GetAutocorrWordList();
+
+ MakeUserStorage_Impl();
+
+ SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, TRUE );
+ BOOL bRet = xStg.Is() && SVSTREAM_OK == xStg->GetError();
+ if( bRet )
+ {
+ USHORT nPos;
+ SvxAutocorrWord aTmp( rShort, rShort );
+ if( pAutocorr_List->Seek_Entry( &aTmp, &nPos ) )
+ {
+ SvxAutocorrWord* pFnd = (*pAutocorr_List)[ nPos ];
+ if( !pFnd->IsTextOnly() )
+ {
+ String aName( rShort );
+ if (xStg->IsOLEStorage())
+ EncryptBlockName_Imp( aName );
+ else
+ GeneratePackageName ( rShort, aName );
+ if( xStg->IsContained( aName ) )
+ {
+ xStg->Remove( aName );
+ bRet = xStg->Commit();
+ }
+
+ }
+ // die Wortliste aktualisieren
+ pAutocorr_List->DeleteAndDestroy( nPos );
+ MakeBlocklist_Imp( *xStg );
+ xStg = 0;
+ }
+ else
+ bRet = FALSE;
+ }
+ return bRet;
+}
diff --git a/editeng/source/misc/swafopt.cxx b/editeng/source/misc/swafopt.cxx
new file mode 100644
index 0000000000..e6dcd15972
--- /dev/null
+++ b/editeng/source/misc/swafopt.cxx
@@ -0,0 +1,163 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: swafopt.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <vcl/keycodes.hxx>
+#include <tools/string.hxx>
+
+#include <editeng/swafopt.hxx>
+
+/*------------------------------------------------------------------------
+ Beschreibung:
+------------------------------------------------------------------------*/
+
+SvxSwAutoFmtFlags::SvxSwAutoFmtFlags()
+ : aBulletFont( String::CreateFromAscii(
+ RTL_CONSTASCII_STRINGPARAM( "StarSymbol" )),
+ Size( 0, 14 ) )
+{
+ bReplaceQuote =
+ bAutoCorrect =
+ bCptlSttSntnc =
+ bCptlSttWrd =
+ bChkFontAttr =
+ bChgUserColl =
+ bChgEnumNum =
+ bChgFracionSymbol =
+ bChgOrdinalNumber =
+ bChgToEnEmDash =
+ bChgWeightUnderl =
+ bSetINetAttr =
+ bAFmtDelSpacesAtSttEnd =
+ bAFmtDelSpacesBetweenLines =
+ bAFmtByInpDelSpacesAtSttEnd =
+ bAFmtByInpDelSpacesBetweenLines =
+ bDummy = TRUE;
+
+ bReplaceStyles =
+ bDelEmptyNode =
+ bWithRedlining =
+ bAutoCmpltEndless =
+ bAutoCmpltAppendBlanc =
+ bAutoCmpltShowAsTip = FALSE;
+
+ bSetBorder =
+ bCreateTable =
+ bSetNumRule =
+ bAFmtByInput =
+ bRightMargin =
+ bAutoCompleteWords =
+ bAutoCmpltCollectWords =
+ bAutoCmpltKeepList = TRUE;
+
+ bDummy6 = bDummy7 = bDummy8 =
+ FALSE;
+
+ nRightMargin = 50; // dflt. 50 %
+ nAutoCmpltExpandKey = KEY_RETURN;
+
+ aBulletFont.SetCharSet( RTL_TEXTENCODING_SYMBOL );
+ aBulletFont.SetFamily( FAMILY_DONTKNOW );
+ aBulletFont.SetPitch( PITCH_DONTKNOW );
+ aBulletFont.SetWeight( WEIGHT_DONTKNOW );
+ aBulletFont.SetTransparent( TRUE );
+
+ cBullet = 0x2022;
+ cByInputBullet = cBullet;
+ aByInputBulletFont = aBulletFont;
+
+ nAutoCmpltWordLen = 10;
+ nAutoCmpltListLen = 500;
+ pAutoCmpltList = 0;
+ pSmartTagMgr = 0;
+}
+
+
+SvxSwAutoFmtFlags& SvxSwAutoFmtFlags::operator=( const SvxSwAutoFmtFlags& rAFFlags )
+{
+ bAutoCorrect = rAFFlags.bAutoCorrect;
+ bReplaceQuote = rAFFlags.bReplaceQuote;
+ bCptlSttSntnc = rAFFlags.bCptlSttSntnc;
+ bCptlSttWrd = rAFFlags.bCptlSttWrd;
+ bChkFontAttr = rAFFlags.bChkFontAttr;
+
+ bChgUserColl = rAFFlags.bChgUserColl;
+ bChgEnumNum = rAFFlags.bChgEnumNum;
+ bDelEmptyNode = rAFFlags.bDelEmptyNode;
+ bSetNumRule = rAFFlags.bSetNumRule;
+ bAFmtByInput = rAFFlags.bAFmtByInput;
+
+ bChgFracionSymbol = rAFFlags.bChgFracionSymbol;
+ bChgOrdinalNumber = rAFFlags.bChgOrdinalNumber;
+ bChgToEnEmDash = rAFFlags.bChgToEnEmDash;
+ bChgWeightUnderl = rAFFlags.bChgWeightUnderl;
+ bSetINetAttr = rAFFlags.bSetINetAttr;
+ bSetBorder = rAFFlags.bSetBorder;
+ bCreateTable = rAFFlags.bCreateTable;
+ bReplaceStyles = rAFFlags.bReplaceStyles;
+ bAFmtDelSpacesAtSttEnd = rAFFlags.bAFmtDelSpacesAtSttEnd;
+ bAFmtDelSpacesBetweenLines = rAFFlags.bAFmtDelSpacesBetweenLines;
+ bAFmtByInpDelSpacesAtSttEnd = rAFFlags.bAFmtByInpDelSpacesAtSttEnd;
+ bAFmtByInpDelSpacesBetweenLines = rAFFlags.bAFmtByInpDelSpacesBetweenLines;
+
+ bDummy = rAFFlags.bDummy;
+
+ bDummy6 = rAFFlags.bDummy6;
+ bDummy7 = rAFFlags.bDummy7;
+ bDummy8 = rAFFlags.bDummy8;
+
+ bWithRedlining = rAFFlags.bWithRedlining;
+
+ bRightMargin = rAFFlags.bRightMargin;
+ nRightMargin = rAFFlags.nRightMargin;
+
+ cBullet = rAFFlags.cBullet;
+ aBulletFont = rAFFlags.aBulletFont;
+
+ cByInputBullet = rAFFlags.cByInputBullet;
+ aByInputBulletFont = rAFFlags.aByInputBulletFont;
+
+ bAutoCompleteWords = rAFFlags.bAutoCompleteWords;
+ bAutoCmpltCollectWords = rAFFlags.bAutoCmpltCollectWords;
+ bAutoCmpltKeepList = rAFFlags.bAutoCmpltKeepList;
+ bAutoCmpltEndless = rAFFlags.bAutoCmpltEndless;
+ bAutoCmpltAppendBlanc = rAFFlags.bAutoCmpltAppendBlanc;
+ bAutoCmpltShowAsTip = rAFFlags.bAutoCmpltShowAsTip;
+ pAutoCmpltList = rAFFlags.pAutoCmpltList;
+ pSmartTagMgr = rAFFlags.pSmartTagMgr;
+ nAutoCmpltExpandKey = rAFFlags.nAutoCmpltExpandKey;
+
+ nAutoCmpltWordLen = rAFFlags.nAutoCmpltWordLen;
+ nAutoCmpltListLen = rAFFlags.nAutoCmpltListLen;
+
+ return *this;
+}
+
diff --git a/editeng/source/misc/txtrange.cxx b/editeng/source/misc/txtrange.cxx
new file mode 100644
index 0000000000..0c7f9dc7aa
--- /dev/null
+++ b/editeng/source/misc/txtrange.cxx
@@ -0,0 +1,722 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: txtrange.cxx,v $
+ * $Revision: 1.15 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <editeng/txtrange.hxx>
+#include <math.h>
+#include <tools/poly.hxx>
+#include <tools/debug.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+
+/*************************************************************************
+|*
+|* TextRanger::TextRanger()
+|*
+|* Beschreibung
+|* Ersterstellung 20.01.97
+|* Letzte Aenderung 20.01.97 AMA
+|*
+*************************************************************************/
+
+#ifdef WIN
+#pragma optimize ( "", off )
+#endif
+
+TextRanger::TextRanger( const basegfx::B2DPolyPolygon& rPolyPolygon, const basegfx::B2DPolyPolygon* pLinePolyPolygon,
+ USHORT nCacheSz, USHORT nLft, USHORT nRght, BOOL bSimpl, BOOL bInnr,
+ BOOL bVert ) :
+ pBound( NULL ),
+ nCacheSize( nCacheSz ),
+ nCacheIdx( 0 ),
+ nRight( nRght ),
+ nLeft( nLft ),
+ nUpper( 0 ),
+ nLower( 0 ),
+ nPointCount( 0 ),
+ bSimple( bSimpl ),
+ bInner( bInnr ),
+ bVertical( bVert )
+{
+#ifdef DBG_UTIL
+ bFlag3 = bFlag4 = bFlag5 = bFlag6 = bFlag7 = FALSE;
+#endif
+ pRangeArr = new Range[ nCacheSize ];
+ pCache = new SvLongsPtr[ nCacheSize ];
+ memset( pRangeArr, 0, nCacheSize * sizeof( Range ) );
+ memset( pCache, 0, nCacheSize * sizeof( SvLongsPtr ) );
+ sal_uInt32 nCount(rPolyPolygon.count());
+ mpPolyPolygon = new PolyPolygon( (sal_uInt16)nCount );
+
+ for(sal_uInt32 i(0L); i < nCount; i++)
+ {
+ const basegfx::B2DPolygon aCandidate(rPolyPolygon.getB2DPolygon(i).getDefaultAdaptiveSubdivision());
+ nPointCount += aCandidate.count();
+ mpPolyPolygon->Insert( Polygon(aCandidate), (sal_uInt16)i );
+ }
+
+ if( pLinePolyPolygon )
+ {
+ nCount = pLinePolyPolygon->count();
+ mpLinePolyPolygon = new PolyPolygon();
+
+ for(sal_uInt32 i(0L); i < nCount; i++)
+ {
+ const basegfx::B2DPolygon aCandidate(pLinePolyPolygon->getB2DPolygon(i).getDefaultAdaptiveSubdivision());
+ nPointCount += aCandidate.count();
+ mpLinePolyPolygon->Insert( Polygon(aCandidate), (sal_uInt16)i );
+ }
+ }
+ else
+ mpLinePolyPolygon = NULL;
+}
+
+#ifdef WIN
+#pragma optimize ( "", on )
+#endif
+
+/*************************************************************************
+|*
+|* TextRanger::~TextRanger()
+|*
+|* Beschreibung
+|* Ersterstellung 20.01.97
+|* Letzte Aenderung 20.01.97 AMA
+|*
+*************************************************************************/
+
+TextRanger::~TextRanger()
+{
+ for( USHORT i = 0; i < nCacheSize; ++i )
+ delete pCache[i];
+ delete[] pCache;
+ delete[] pRangeArr;
+ delete mpPolyPolygon;
+ delete mpLinePolyPolygon;
+}
+
+/*-----------------17.11.00 09:49-------------------
+ * TextRanger::SetVertical(..)
+ * If there's is a change in the writing direction,
+ * the cache has to be cleared.
+ * --------------------------------------------------*/
+
+void TextRanger::SetVertical( BOOL bNew )
+{
+ if( IsVertical() != bNew )
+ {
+ bVertical = bNew;
+ for( USHORT i = 0; i < nCacheSize; ++i )
+ delete pCache[i];
+ memset( pRangeArr, 0, nCacheSize * sizeof( Range ) );
+ memset( pCache, 0, nCacheSize * sizeof( SvLongsPtr ) );
+ }
+}
+
+/*************************************************************************
+|*
+|* SvxBoundArgs
+|*
+|* Beschreibung
+|* Ersterstellung 20.01.97
+|* Letzte Aenderung 20.01.97 AMA
+|*
+*************************************************************************/
+
+class SvxBoundArgs
+{
+ SvBools aBoolArr;
+ SvLongs *pLongArr;
+ TextRanger *pTextRanger;
+ long nMin;
+ long nMax;
+ long nTop;
+ long nBottom;
+ long nUpDiff;
+ long nLowDiff;
+ long nUpper;
+ long nLower;
+ long nStart;
+ long nEnd;
+ USHORT nCut;
+ USHORT nLast;
+ USHORT nNext;
+ BYTE nAct;
+ BYTE nFirst;
+ BOOL bClosed : 1;
+ BOOL bInner : 1;
+ BOOL bMultiple : 1;
+ BOOL bConcat : 1;
+ BOOL bRotate : 1;
+ void NoteRange( BOOL bToggle );
+ long Cut( long nY, const Point& rPt1, const Point& rPt2 );
+ void Add();
+ void _NoteFarPoint( long nPx, long nPyDiff, long nDiff );
+ void NoteFarPoint( long nPx, long nPyDiff, long nDiff )
+ { if( nDiff ) _NoteFarPoint( nPx, nPyDiff, nDiff ); }
+ long CalcMax( const Point& rPt1, const Point& rPt2, long nRange, long nFar );
+ void CheckCut( const Point& rLst, const Point& rNxt );
+ inline long A( const Point& rP ) const { return bRotate ? rP.Y() : rP.X(); }
+ inline long B( const Point& rP ) const { return bRotate ? rP.X() : rP.Y(); }
+public:
+ SvxBoundArgs( TextRanger* pRanger, SvLongs *pLong, const Range& rRange );
+ void NotePoint( const long nA ) { NoteMargin( nA - nStart, nA + nEnd ); }
+ void NoteMargin( const long nL, const long nR )
+ { if( nMin > nL ) nMin = nL; if( nMax < nR ) nMax = nR; }
+ USHORT Area( const Point& rPt );
+ void NoteUpLow( long nA, const BYTE nArea );
+ void Calc( const PolyPolygon& rPoly );
+ void Concat( const PolyPolygon* pPoly );
+ // inlines
+ void NoteLast() { if( bMultiple ) NoteRange( nAct == nFirst ); }
+ void SetClosed( const BOOL bNew ){ bClosed = bNew; }
+ BOOL IsClosed() const { return bClosed; }
+ void SetConcat( const BOOL bNew ){ bConcat = bNew; }
+ BOOL IsConcat() const { return bConcat; }
+ BYTE GetAct() const { return nAct; }
+};
+
+SvxBoundArgs::SvxBoundArgs( TextRanger* pRanger, SvLongs *pLong,
+ const Range& rRange )
+ : aBoolArr( 4, 4 ), pLongArr( pLong ), pTextRanger( pRanger ),
+ nTop( rRange.Min() ), nBottom( rRange.Max() ),
+ bInner( pRanger->IsInner() ), bMultiple( bInner || !pRanger->IsSimple() ),
+ bConcat( FALSE ), bRotate( pRanger->IsVertical() )
+{
+ if( bRotate )
+ {
+ nStart = pRanger->GetUpper();
+ nEnd = pRanger->GetLower();
+ nLowDiff = pRanger->GetLeft();
+ nUpDiff = pRanger->GetRight();
+ }
+ else
+ {
+ nStart = pRanger->GetLeft();
+ nEnd = pRanger->GetRight();
+ nLowDiff = pRanger->GetUpper();
+ nUpDiff = pRanger->GetLower();
+ }
+ nUpper = nTop - nUpDiff;
+ nLower = nBottom + nLowDiff;
+ pLongArr->Remove( 0, pLongArr->Count() );
+}
+
+long SvxBoundArgs::CalcMax( const Point& rPt1, const Point& rPt2,
+ long nRange, long nFarRange )
+{
+ double nDa = Cut( nRange, rPt1, rPt2 ) - Cut( nFarRange, rPt1, rPt2 );
+ double nB;
+ if( nDa < 0 )
+ {
+ nDa = -nDa;
+ nB = nEnd;
+ }
+ else
+ nB = nStart;
+ nB *= nB;
+ nB += nDa * nDa;
+ nB = nRange + nDa * ( nFarRange - nRange ) / sqrt( nB );
+
+ BOOL bNote;
+ if( nB < B(rPt2) )
+ bNote = nB > B(rPt1);
+ else
+ bNote = nB < B(rPt1);
+ if( bNote )
+ return( long( nB ) );
+ return 0;
+}
+
+void SvxBoundArgs::CheckCut( const Point& rLst, const Point& rNxt )
+{
+ if( nCut & 1 )
+ NotePoint( Cut( nBottom, rLst, rNxt ) );
+ if( nCut & 2 )
+ NotePoint( Cut( nTop, rLst, rNxt ) );
+ if( rLst.X() != rNxt.X() && rLst.Y() != rNxt.Y() )
+ {
+ long nYps;
+ if( nLowDiff && ( ( nCut & 1 ) || nLast == 1 || nNext == 1 ) )
+ {
+ nYps = CalcMax( rLst, rNxt, nBottom, nLower );
+ if( nYps )
+ _NoteFarPoint( Cut( nYps, rLst, rNxt ), nLower-nYps, nLowDiff );
+ }
+ if( nUpDiff && ( ( nCut & 2 ) || nLast == 2 || nNext == 2 ) )
+ {
+ nYps = CalcMax( rLst, rNxt, nTop, nUpper );
+ if( nYps )
+ _NoteFarPoint( Cut( nYps, rLst, rNxt ), nYps-nUpper, nUpDiff );
+ }
+ }
+}
+
+void SvxBoundArgs::_NoteFarPoint( long nPa, long nPbDiff, long nDiff )
+{
+ long nTmpA;
+ double nQuot = 2 * nDiff - nPbDiff;
+ nQuot *= nPbDiff;
+ nQuot = sqrt( nQuot );
+ nQuot /= nDiff;
+ nTmpA = nPa - long( nStart * nQuot );
+ nPbDiff = nPa + long( nEnd * nQuot );
+ NoteMargin( nTmpA, nPbDiff );
+}
+
+void SvxBoundArgs::NoteRange( BOOL bToggle )
+{
+ DBG_ASSERT( nMax >= nMin || bInner, "NoteRange: Min > Max?");
+ if( nMax < nMin )
+ return;
+ if( !bClosed )
+ bToggle = FALSE;
+ USHORT nIdx = 0;
+ USHORT nCount = pLongArr->Count();
+ DBG_ASSERT( nCount == 2 * aBoolArr.Count(), "NoteRange: Incompatible Sizes" );
+ while( nIdx < nCount && (*pLongArr)[ nIdx ] < nMin )
+ ++nIdx;
+ BOOL bOdd = nIdx % 2 ? TRUE : FALSE;
+ // Kein Ueberlappung mit vorhandenen Intervallen?
+ if( nIdx == nCount || ( !bOdd && nMax < (*pLongArr)[ nIdx ] ) )
+ { // Dann wird ein neues eingefuegt ...
+ pLongArr->Insert( nMin, nIdx );
+ pLongArr->Insert( nMax, nIdx + 1 );
+ aBoolArr.Insert( bToggle, nIdx / 2 );
+ }
+ else
+ { // ein vorhandes Intervall erweitern ...
+ USHORT nMaxIdx = nIdx;
+ // Wenn wir auf einer linken Intervallgrenze gelandet sind, muss diese
+ // auf nMin gesenkt werden.
+ if( bOdd )
+ --nIdx;
+ else
+ (*pLongArr)[ nIdx ] = nMin;
+ while( nMaxIdx < nCount && (*pLongArr)[ nMaxIdx ] < nMax )
+ ++nMaxIdx;
+ DBG_ASSERT( nMaxIdx > nIdx || nMin == nMax, "NoteRange: Funny Situation." );
+ if( nMaxIdx )
+ --nMaxIdx;
+ if( nMaxIdx < nIdx )
+ nMaxIdx = nIdx;
+ // Wenn wir auf einer rechten Intervallgrenze landen, muss diese
+ // auf nMax angehoben werden.
+ if( nMaxIdx % 2 )
+ (*pLongArr)[ nMaxIdx-- ] = nMax;
+ // Jetzt werden eventuell noch Intervalle verschmolzen
+ USHORT nDiff = nMaxIdx - nIdx;
+ nMaxIdx = nIdx / 2; // Ab hier ist nMaxIdx der Index im BoolArray.
+ if( nDiff )
+ {
+ (*pLongArr).Remove( nIdx + 1, nDiff );
+ nDiff /= 2;
+ USHORT nStop = nMaxIdx + nDiff;
+ for( USHORT i = nMaxIdx; i < nStop; ++i )
+ bToggle ^= aBoolArr[ i ];
+ aBoolArr.Remove( nMaxIdx, nDiff );
+ }
+ DBG_ASSERT( nMaxIdx < aBoolArr.Count(), "NoteRange: Too much deleted" );
+ aBoolArr[ nMaxIdx ] ^= bToggle;
+ }
+}
+
+void SvxBoundArgs::Calc( const PolyPolygon& rPoly )
+{
+ USHORT nCount;
+ nAct = 0;
+ for( USHORT i = 0; i < rPoly.Count(); ++i )
+ {
+ const Polygon& rPol = rPoly[ i ];
+ nCount = rPol.GetSize();
+ if( nCount )
+ {
+ const Point& rNull = rPol[ 0 ];
+ SetClosed( IsConcat() || ( rNull == rPol[ nCount - 1 ] ) );
+ nLast = Area( rNull );
+ if( nLast & 12 )
+ {
+ nFirst = 3;
+ if( bMultiple )
+ nAct = 0;
+ }
+ else
+ {
+ // Der erste Punkt des Polygons liegt innerhalb der Zeile.
+ if( nLast )
+ {
+ if( bMultiple || !nAct )
+ {
+ nMin = USHRT_MAX;
+ nMax = 0;
+ }
+ if( nLast & 1 )
+ NoteFarPoint( A(rNull), nLower - B(rNull), nLowDiff );
+ else
+ NoteFarPoint( A(rNull), B(rNull) - nUpper, nUpDiff );
+ }
+ else
+ {
+ if( bMultiple || !nAct )
+ {
+ nMin = A(rNull);
+ nMax = nMin + nEnd;
+ nMin -= nStart;
+ }
+ else
+ NotePoint( A(rNull) );
+ }
+ nFirst = 0; // In welcher Richtung wird die Zeile verlassen?
+ nAct = 3; // Wir sind z.Z. innerhalb der Zeile.
+ }
+ if( nCount > 1 )
+ {
+ USHORT nIdx = 1;
+ while( TRUE )
+ {
+ const Point& rLast = rPol[ nIdx - 1 ];
+ if( nIdx == nCount )
+ nIdx = 0;
+ const Point& rNext = rPol[ nIdx ];
+ nNext = Area( rNext );
+ nCut = nNext ^ nLast;
+ USHORT nOldAct = nAct;
+ if( nAct )
+ CheckCut( rLast, rNext );
+ if( nCut & 4 )
+ {
+ NoteUpLow( Cut( nLower, rLast, rNext ), 2 );
+ if( nAct && nAct != nOldAct )
+ {
+ nOldAct = nAct;
+ CheckCut( rLast, rNext );
+ }
+ }
+ if( nCut & 8 )
+ {
+ NoteUpLow( Cut( nUpper, rLast, rNext ), 1 );
+ if( nAct && nAct != nOldAct )
+ CheckCut( rLast, rNext );
+ }
+ if( !nIdx )
+ {
+ if( !( nNext & 12 ) )
+ NoteLast();
+ break;
+ }
+ if( !( nNext & 12 ) )
+ {
+ if( !nNext )
+ NotePoint( A(rNext) );
+ else if( nNext & 1 )
+ NoteFarPoint( A(rNext), nLower-B(rNext), nLowDiff );
+ else
+ NoteFarPoint( A(rNext), B(rNext)-nUpper, nUpDiff );
+ }
+ nLast = nNext;
+ if( ++nIdx == nCount && !IsClosed() )
+ {
+ if( !( nNext & 12 ) )
+ NoteLast();
+ break;
+ }
+ }
+ }
+ if( bMultiple && IsConcat() )
+ {
+ Add();
+ nAct = 0;
+ }
+ }
+ }
+ if( !bMultiple )
+ {
+ DBG_ASSERT( pLongArr->Count() == 0, "I said: Simple!" );
+ if( nAct )
+ {
+ if( bInner )
+ {
+ long nTmpMin, nTmpMax;
+ {
+ nTmpMin = nMin + 2 * nStart;
+ nTmpMax = nMax - 2 * nEnd;
+ if( nTmpMin <= nTmpMax )
+ {
+ pLongArr->Insert( nTmpMin, 0 );
+ pLongArr->Insert( nTmpMax, 1 );
+ }
+ }
+ }
+ else
+ {
+ pLongArr->Insert( nMin, 0 );
+ pLongArr->Insert( nMax, 1 );
+ }
+ }
+ }
+ else if( !IsConcat() )
+ Add();
+}
+
+void SvxBoundArgs::Add()
+{
+ USHORT nLongIdx = 1;
+ USHORT nCount = aBoolArr.Count();
+ if( nCount && ( !bInner || !pTextRanger->IsSimple() ) )
+ {
+ BOOL bDelete = aBoolArr[ 0 ];
+ if( bInner )
+ bDelete = !bDelete;
+ for( USHORT nBoolIdx = 1; nBoolIdx < nCount; ++nBoolIdx )
+ {
+ if( bDelete )
+ {
+ USHORT next = 2;
+ while( nBoolIdx < nCount && !aBoolArr[ nBoolIdx++ ] &&
+ (!bInner || nBoolIdx < nCount ) )
+ next += 2;
+ pLongArr->Remove( nLongIdx, next );
+ next /= 2;
+ nBoolIdx = nBoolIdx - next;
+ nCount = nCount - next;
+ aBoolArr.Remove( nBoolIdx, next );
+ if( nBoolIdx )
+ aBoolArr[ nBoolIdx - 1 ] = FALSE;
+#if OSL_DEBUG_LEVEL > 1
+ else
+ ++next;
+#endif
+ }
+ bDelete = nBoolIdx < nCount && aBoolArr[ nBoolIdx ];
+ nLongIdx += 2;
+ DBG_ASSERT( nLongIdx == 2*nBoolIdx+1, "BoundArgs: Array-Idx Confusion" );
+ DBG_ASSERT( aBoolArr.Count()*2 == pLongArr->Count(),
+ "BoundArgs: Array-Count: Confusion" );
+ }
+ }
+ if( 0 != ( nCount = pLongArr->Count() ) )
+ {
+ if( bInner )
+ {
+ pLongArr->Remove( 0, 1 );
+ pLongArr->Remove( pLongArr->Count() - 1, 1 );
+
+ // Hier wird die Zeile beim "einfachen" Konturumfluss im Innern
+ // in ein grosses Rechteck zusammengefasst.
+ // Zur Zeit (April 1999) wertet die EditEngine nur das erste Rechteck
+ // aus, falls sie eines Tages in der Lage ist, eine Zeile in mehreren
+ // Teilen auszugeben, kann es sinnvoll sein, die folgenden Zeilen
+ // zu loeschen.
+ if( pTextRanger->IsSimple() && pLongArr->Count() > 2 )
+ pLongArr->Remove( 1, pLongArr->Count() - 2 );
+
+ }
+ }
+}
+
+void SvxBoundArgs::Concat( const PolyPolygon* pPoly )
+{
+ SetConcat( TRUE );
+ DBG_ASSERT( pPoly, "Nothing to do?" );
+ SvLongs *pOld = pLongArr;
+ pLongArr = new SvLongs( 2, 8 );
+ aBoolArr.Remove( 0, aBoolArr.Count() );
+ bInner = FALSE;
+ Calc( *pPoly );
+ USHORT nCount = pLongArr->Count();
+ USHORT nIdx = 0;
+ USHORT i = 0;
+ BOOL bSubtract = pTextRanger->IsInner();
+ while( i < nCount )
+ {
+ USHORT nOldCount = pOld->Count();
+ if( nIdx == nOldCount )
+ { // Am Ende des alten Arrays angelangt...
+ if( !bSubtract )
+ pOld->Insert( pLongArr, nIdx, i, USHRT_MAX );
+ break;
+ }
+ long nLeft = (*pLongArr)[ i++ ];
+ long nRight = (*pLongArr)[ i++ ];
+ USHORT nLeftPos = nIdx + 1;
+ while( nLeftPos < nOldCount && nLeft > (*pOld)[ nLeftPos ] )
+ nLeftPos += 2;
+ if( nLeftPos >= nOldCount )
+ { // Das aktuelle Intervall gehoert ans Ende des alten Arrays...
+ if( !bSubtract )
+ pOld->Insert( pLongArr, nOldCount, i - 2, USHRT_MAX );
+ break;
+ }
+ USHORT nRightPos = nLeftPos - 1;
+ while( nRightPos < nOldCount && nRight >= (*pOld)[ nRightPos ] )
+ nRightPos += 2;
+ if( nRightPos < nLeftPos )
+ { // Das aktuelle Intervall gehoert zwischen zwei alte Intervalle
+ if( !bSubtract )
+ pOld->Insert( pLongArr, nRightPos, i - 2, i );
+ nIdx = nRightPos + 2;
+ }
+ else if( bSubtract ) // Subtrahieren ggf. Trennen
+ {
+ long nOld;
+ if( nLeft > ( nOld = (*pOld)[ nLeftPos - 1 ] ) )
+ { // Jetzt spalten wir den linken Teil ab...
+ if( nLeft - 1 > nOld )
+ {
+ pOld->Insert( nOld, nLeftPos - 1 );
+ pOld->Insert( nLeft - 1, nLeftPos );
+ nLeftPos += 2;
+ nRightPos += 2;
+ }
+ }
+ if( nRightPos - nLeftPos > 1 )
+ pOld->Remove( nLeftPos, nRightPos - nLeftPos - 1 );
+ if( ++nRight >= ( nOld = (*pOld)[ nLeftPos ] ) )
+ pOld->Remove( nLeftPos - 1, 2 );
+ else
+ (*pOld)[ nLeftPos - 1 ] = nRight;
+ }
+ else // Verschmelzen
+ {
+ if( nLeft < (*pOld)[ nLeftPos - 1 ] )
+ (*pOld)[ nLeftPos - 1 ] = nLeft;
+ if( nRight > (*pOld)[ nRightPos - 1 ] )
+ (*pOld)[ nRightPos - 1 ] = nRight;
+ if( nRightPos - nLeftPos > 1 )
+ pOld->Remove( nLeftPos, nRightPos - nLeftPos - 1 );
+
+ }
+ nIdx = nLeftPos - 1;
+ }
+ delete pLongArr;
+}
+
+/*************************************************************************
+ * SvxBoundArgs::Area ermittelt den Bereich, in dem sich der Punkt befindet
+ * 0 = innerhalb der Zeile
+ * 1 = unterhalb, aber innerhalb der oberen Randes
+ * 2 = oberhalb, aber innerhalb der unteren Randes
+ * 5 = unterhalb des oberen Randes
+ *10 = oberhalb des unteren Randes
+ *************************************************************************/
+
+USHORT SvxBoundArgs::Area( const Point& rPt )
+{
+ long nB = B( rPt );
+ if( nB >= nBottom )
+ {
+ if( nB >= nLower )
+ return 5;
+ return 1;
+ }
+ if( nB <= nTop )
+ {
+ if( nB <= nUpper )
+ return 10;
+ return 2;
+ }
+ return 0;
+}
+
+/*************************************************************************
+ * lcl_Cut berechnet die X-Koordinate der Strecke (Pt1-Pt2) auf der
+ * Y-Koordinate nY.
+ * Vorausgesetzt wird, dass einer der Punkte oberhalb und der andere
+ * unterhalb der Y-Koordinate liegt.
+ *************************************************************************/
+
+long SvxBoundArgs::Cut( long nB, const Point& rPt1, const Point& rPt2 )
+{
+ if( pTextRanger->IsVertical() )
+ {
+ double nQuot = nB - rPt1.X();
+ nQuot /= ( rPt2.X() - rPt1.X() );
+ nQuot *= ( rPt2.Y() - rPt1.Y() );
+ return long( rPt1.Y() + nQuot );
+ }
+ double nQuot = nB - rPt1.Y();
+ nQuot /= ( rPt2.Y() - rPt1.Y() );
+ nQuot *= ( rPt2.X() - rPt1.X() );
+ return long( rPt1.X() + nQuot );
+}
+
+void SvxBoundArgs::NoteUpLow( long nA, const BYTE nArea )
+{
+ if( nAct )
+ {
+ NoteMargin( nA, nA );
+ if( bMultiple )
+ {
+ NoteRange( nArea != nAct );
+ nAct = 0;
+ }
+ if( !nFirst )
+ nFirst = nArea;
+ }
+ else
+ {
+ nAct = nArea;
+ nMin = nA;
+ nMax = nA;
+ }
+}
+
+SvLongsPtr TextRanger::GetTextRanges( const Range& rRange )
+{
+ DBG_ASSERT( rRange.Min() || rRange.Max(), "Zero-Range not allowed, Bye Bye" );
+ USHORT nIndex = 0;
+ while( nIndex < nCacheSize && rRange != pRangeArr[ nIndex ] )
+ ++nIndex;
+ if( nIndex >= nCacheSize )
+ {
+ ++nCacheIdx;
+ nCacheIdx %= nCacheSize;
+ pRangeArr[ nCacheIdx ] = rRange;
+ if( !pCache[ nCacheIdx ] )
+ pCache[ nCacheIdx ] = new SvLongs( 2, 8 );
+ nIndex = nCacheIdx;
+ SvxBoundArgs aArg( this, pCache[ nCacheIdx ], rRange );
+ aArg.Calc( *mpPolyPolygon );
+ if( mpLinePolyPolygon )
+ aArg.Concat( mpLinePolyPolygon );
+ }
+ return pCache[ nIndex ];
+}
+
+const Rectangle& TextRanger::_GetBoundRect()
+{
+ DBG_ASSERT( 0 == pBound, "Don't call twice." );
+ pBound = new Rectangle( mpPolyPolygon->GetBoundRect() );
+ return *pBound;
+}
+
+
diff --git a/editeng/source/misc/unolingu.cxx b/editeng/source/misc/unolingu.cxx
new file mode 100644
index 0000000000..f356c4be73
--- /dev/null
+++ b/editeng/source/misc/unolingu.cxx
@@ -0,0 +1,1377 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unolingu.cxx,v $
+ * $Revision: 1.39 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <map>
+#include <set>
+#include <vector>
+#include <slist>
+#include <memory>
+#include <editeng/unolingu.hxx>
+#include <tools/debug.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/logfile.hxx>
+#include <unotools/pathoptions.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/linguistic2/XAvailableLocales.hpp>
+#include <com/sun/star/ucb/XAnyCompareFactory.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp>
+#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <cppuhelper/implbase1.hxx> // helper for implementations
+#include <i18npool/mslangid.hxx>
+#include <unotools/lingucfg.hxx>
+#include <unotools/ucbhelper.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <ucbhelper/commandenvironment.hxx>
+#include <ucbhelper/content.hxx>
+#include <comphelper/processfactory.hxx>
+#include <vcl/msgbox.hxx>
+#include <tools/shl.hxx>
+#include <linguistic/misc.hxx>
+#include <editeng/eerdll.hxx>
+#include <editeng/editrids.hrc>
+
+using namespace ::rtl;
+using namespace ::comphelper;
+using namespace ::linguistic;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::linguistic2;
+
+#define CSS com::sun::star
+
+///////////////////////////////////////////////////////////////////////////
+
+
+static uno::Reference< XLinguServiceManager > GetLngSvcMgr_Impl()
+{
+ uno::Reference< XLinguServiceManager > xRes;
+ uno::Reference< XMultiServiceFactory > xMgr = getProcessServiceFactory();
+ if (xMgr.is())
+ {
+ xRes = uno::Reference< XLinguServiceManager > ( xMgr->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.linguistic2.LinguServiceManager" ) ) ), UNO_QUERY ) ;
+ }
+ return xRes;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+BOOL lcl_FindEntry( const OUString &rEntry, const Sequence< OUString > &rCfgSvcs )
+{
+ INT32 nRes = -1;
+ INT32 nEntries = rCfgSvcs.getLength();
+ const OUString *pEntry = rCfgSvcs.getConstArray();
+ for (INT32 i = 0; i < nEntries && nRes == -1; ++i)
+ {
+ if (rEntry == pEntry[i])
+ nRes = i;
+ }
+ return nRes != -1;
+}
+
+
+Sequence< OUString > lcl_RemoveMissingEntries(
+ const Sequence< OUString > &rCfgSvcs,
+ const Sequence< OUString > &rAvailSvcs )
+{
+ Sequence< OUString > aRes( rCfgSvcs.getLength() );
+ OUString *pRes = aRes.getArray();
+ INT32 nCnt = 0;
+
+ INT32 nEntries = rCfgSvcs.getLength();
+ const OUString *pEntry = rCfgSvcs.getConstArray();
+ for (INT32 i = 0; i < nEntries; ++i)
+ {
+ if (pEntry[i].getLength() && lcl_FindEntry( pEntry[i], rAvailSvcs ))
+ pRes[ nCnt++ ] = pEntry[i];
+ }
+
+ aRes.realloc( nCnt );
+ return aRes;
+}
+
+
+Sequence< OUString > lcl_GetLastFoundSvcs(
+ SvtLinguConfig &rCfg,
+ const OUString &rLastFoundList ,
+ const Locale &rAvailLocale )
+{
+ Sequence< OUString > aRes;
+
+ OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
+ SvxLocaleToLanguage( rAvailLocale ) ) );
+
+ Sequence< OUString > aNodeNames( rCfg.GetNodeNames(rLastFoundList) );
+ BOOL bFound = lcl_FindEntry( aCfgLocaleStr, aNodeNames);
+
+ if (bFound)
+ {
+ Sequence< OUString > aNames(1);
+ OUString &rNodeName = aNames.getArray()[0];
+ rNodeName = rLastFoundList;
+ rNodeName += OUString::valueOf( (sal_Unicode)'/' );
+ rNodeName += aCfgLocaleStr;
+ Sequence< Any > aValues( rCfg.GetProperties( aNames ) );
+#if OSL_DEBUG_LEVEL > 1
+ const Any *pValue;
+ pValue = aValues.getConstArray();
+#endif
+ if (aValues.getLength())
+ {
+ DBG_ASSERT( aValues.getLength() == 1, "unexpected length of sequence" );
+ Sequence< OUString > aSvcImplNames;
+ if (aValues.getConstArray()[0] >>= aSvcImplNames)
+ aRes = aSvcImplNames;
+ else
+ {
+ DBG_ERROR( "type mismatch" );
+ }
+ }
+ }
+
+ return aRes;
+}
+
+
+Sequence< OUString > lcl_GetNewEntries(
+ const Sequence< OUString > &rLastFoundSvcs,
+ const Sequence< OUString > &rAvailSvcs )
+{
+ INT32 nLen = rAvailSvcs.getLength();
+ Sequence< OUString > aRes( nLen );
+ OUString *pRes = aRes.getArray();
+ INT32 nCnt = 0;
+
+ const OUString *pEntry = rAvailSvcs.getConstArray();
+ for (INT32 i = 0; i < nLen; ++i)
+ {
+ if (pEntry[i].getLength() && !lcl_FindEntry( pEntry[i], rLastFoundSvcs ))
+ pRes[ nCnt++ ] = pEntry[i];
+ }
+
+ aRes.realloc( nCnt );
+ return aRes;
+}
+
+
+Sequence< OUString > lcl_MergeSeq(
+ const Sequence< OUString > &rCfgSvcs,
+ const Sequence< OUString > &rNewSvcs )
+{
+ Sequence< OUString > aRes( rCfgSvcs.getLength() + rNewSvcs.getLength() );
+ OUString *pRes = aRes.getArray();
+ INT32 nCnt = 0;
+
+ for (INT32 k = 0; k < 2; ++k)
+ {
+ // add previously configuerd service first and append
+ // new found services at the end
+ const Sequence< OUString > &rSeq = k == 0 ? rCfgSvcs : rNewSvcs;
+
+ INT32 nLen = rSeq.getLength();
+ const OUString *pEntry = rSeq.getConstArray();
+ for (INT32 i = 0; i < nLen; ++i)
+ {
+ if (pEntry[i].getLength() && !lcl_FindEntry( pEntry[i], aRes ))
+ pRes[ nCnt++ ] = pEntry[i];
+ }
+ }
+
+ aRes.realloc( nCnt );
+ return aRes;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+// static member initialization
+INT16 SvxLinguConfigUpdate::nNeedUpdating = -1;
+INT32 SvxLinguConfigUpdate::nCurrentDataFilesChangedCheckValue = -1;
+
+void SvxLinguConfigUpdate::UpdateAll( sal_Bool bForceCheck )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll" );
+
+ if (IsNeedUpdateAll( bForceCheck ))
+ {
+ typedef OUString OUstring_t;
+ typedef Sequence< OUString > Sequence_OUString_t;
+ typedef std::vector< OUstring_t > OUString_vector_t;
+ typedef std::set< OUstring_t > OUString_set_t;
+ std::vector< OUString_vector_t > aVector;
+ typedef std::map< OUstring_t, Sequence_OUString_t > list_entry_map_t;
+
+ RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll - updating..." );
+
+ DBG_ASSERT( nNeedUpdating == 1, "SvxLinguConfigUpdate::UpdateAll already updated!" );
+
+ uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
+ DBG_ASSERT( xLngSvcMgr.is(), "service manager missing");
+ if (!xLngSvcMgr.is())
+ return;
+
+ SvtLinguConfig aCfg;
+
+ const int nNumServices = 4;
+ const sal_Char * apServices[nNumServices] = { SN_SPELLCHECKER, SN_GRAMMARCHECKER, SN_HYPHENATOR, SN_THESAURUS };
+ const sal_Char * apCurLists[nNumServices] = { "ServiceManager/SpellCheckerList", "ServiceManager/GrammarCheckerList", "ServiceManager/HyphenatorList", "ServiceManager/ThesaurusList" };
+ const sal_Char * apLastFoundLists[nNumServices] = { "ServiceManager/LastFoundSpellCheckers", "ServiceManager/LastFoundGrammarCheckers", "ServiceManager/LastFoundHyphenators", "ServiceManager/LastFoundThesauri" };
+
+ // usage of indices as above: 0 = spell checker, 1 = grammar checker, 2 = hyphenator, 3 = thesaurus
+ std::vector< list_entry_map_t > aLastFoundSvcs(nNumServices);
+ std::vector< list_entry_map_t > aCurSvcs(nNumServices);
+
+ for (int k = 0; k < nNumServices; ++k)
+ {
+ OUString aService( A2OU( apServices[k] ) );
+ OUString aActiveList( A2OU( apCurLists[k] ) );
+ OUString aLastFoundList( A2OU( apLastFoundLists[k] ) );
+ INT32 i;
+
+ //
+ // remove configured but not available language/services entries
+ //
+ Sequence< OUString > aNodeNames( aCfg.GetNodeNames( aActiveList ) ); // list of configured locales
+ INT32 nNodeNames = aNodeNames.getLength();
+ const OUString *pNodeName = aNodeNames.getConstArray();
+ for (i = 0; i < nNodeNames; ++i)
+ {
+ Locale aLocale( SvxCreateLocale( MsLangId::convertIsoStringToLanguage(pNodeName[i]) ) );
+ Sequence< OUString > aCfgSvcs(
+ xLngSvcMgr->getConfiguredServices( aService, aLocale ));
+ Sequence< OUString > aAvailSvcs(
+ xLngSvcMgr->getAvailableServices( aService, aLocale ));
+#if OSL_DEBUG_LEVEL > 1
+ const OUString * pCfgSvcs = aCfgSvcs.getConstArray();;
+ const OUString * pAvailSvcs = aAvailSvcs.getConstArray();;
+ (void) pCfgSvcs;
+ (void) pAvailSvcs;
+#endif
+ aCfgSvcs = lcl_RemoveMissingEntries( aCfgSvcs, aAvailSvcs );
+
+ aCurSvcs[k][ pNodeName[i] ] = aCfgSvcs;
+ }
+
+ //
+ // add new available language/servcice entries
+ //
+ uno::Reference< XAvailableLocales > xAvail( xLngSvcMgr, UNO_QUERY );
+ Sequence< Locale > aAvailLocales( xAvail->getAvailableLocales(aService) );
+ INT32 nAvailLocales = aAvailLocales.getLength();
+ const Locale *pAvailLocale = aAvailLocales.getConstArray();
+ for (i = 0; i < nAvailLocales; ++i)
+ {
+ Sequence< OUString > aAvailSvcs(
+ xLngSvcMgr->getAvailableServices( aService, pAvailLocale[i] ));
+ Sequence< OUString > aLastSvcs(
+ lcl_GetLastFoundSvcs( aCfg, aLastFoundList , pAvailLocale[i] ));
+ Sequence< OUString > aNewSvcs =
+ lcl_GetNewEntries( aLastSvcs, aAvailSvcs );
+#if OSL_DEBUG_LEVEL > 1
+ const OUString * pAvailSvcs = aAvailSvcs.getConstArray();
+ const OUString * pLastSvcs = aLastSvcs.getConstArray();
+ const OUString * pNewSvcs = aNewSvcs.getConstArray();
+ (void) pAvailSvcs;
+ (void) pLastSvcs;
+ (void) pNewSvcs;
+#endif
+
+ OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
+ SvxLocaleToLanguage( pAvailLocale[i] ) ) );
+ Sequence< OUString > aCfgSvcs( aCurSvcs[k][ aCfgLocaleStr ] );
+
+ // merge services list (previously configured to be listed first).
+ aCfgSvcs = lcl_MergeSeq( aCfgSvcs, aNewSvcs );
+
+/*
+ // there is at most one Hyphenator per language allowed
+ // to be configured, thus we only use the first one found.
+ if (k == 2 && aCfgSvcs.getLength() > 1)
+ aCfgSvcs.realloc(1);
+*/
+ aCurSvcs[k][ aCfgLocaleStr ] = aCfgSvcs;
+ }
+
+ //
+ // set last found services to currently available ones
+ //
+ for (i = 0; i < nAvailLocales; ++i)
+ {
+ Sequence< OUString > aSvcImplNames(
+ xLngSvcMgr->getAvailableServices( aService, pAvailLocale[i] ) );
+
+#if OSL_DEBUG_LEVEL > 1
+ INT32 nSvcs = aSvcImplNames.getLength();
+ const OUString *pSvcImplName = aSvcImplNames.getConstArray();
+ for (INT32 j = 0; j < nSvcs; ++j)
+ {
+ OUString aImplName( pSvcImplName[j] );
+ }
+#endif
+
+ OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
+ SvxLocaleToLanguage( pAvailLocale[i] ) ) );
+ aLastFoundSvcs[k][ aCfgLocaleStr ] = aSvcImplNames;
+ }
+ }
+
+ //
+ // write new data back to configuration
+ //
+ for (int k = 0; k < nNumServices; ++k)
+ {
+ for (int i = 0; i < 2; ++i)
+ {
+ const sal_Char *pSubNodeName = (i == 0) ? apCurLists[k] : apLastFoundLists[k];
+ OUString aSubNodeName( A2OU(pSubNodeName) );
+
+ list_entry_map_t &rCurMap = (i == 0) ? aCurSvcs[k] : aLastFoundSvcs[k];
+ list_entry_map_t::const_iterator aIt( rCurMap.begin() );
+ sal_Int32 nVals = static_cast< sal_Int32 >( rCurMap.size() );
+ Sequence< PropertyValue > aNewValues( nVals );
+ PropertyValue *pNewValue = aNewValues.getArray();
+ while (aIt != rCurMap.end())
+ {
+ OUString aCfgEntryName( aSubNodeName );
+ aCfgEntryName += OUString::valueOf( (sal_Unicode) '/' );
+ aCfgEntryName += (*aIt).first;
+
+#if OSL_DEBUG_LEVEL > 1
+ Sequence< OUString > aSvcImplNames( (*aIt).second );
+ INT32 nSvcs = aSvcImplNames.getLength();
+ const OUString *pSvcImplName = aSvcImplNames.getConstArray();
+ for (INT32 j = 0; j < nSvcs; ++j)
+ {
+ OUString aImplName( pSvcImplName[j] );
+ }
+#endif
+ pNewValue->Name = aCfgEntryName;
+ pNewValue->Value <<= (*aIt).second;
+ ++pNewValue;
+ ++aIt;
+ }
+ DBG_ASSERT( pNewValue - aNewValues.getArray() == nVals,
+ "possible mismatch of sequence size and property number" );
+
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll - ReplaceSetProperties" );
+ // add new or replace existing entries.
+ BOOL bRes = aCfg.ReplaceSetProperties( aSubNodeName, aNewValues );
+ if (!bRes)
+ {
+#if OSL_DEBUG_LEVEL > 1
+ DBG_ERROR( "failed to set new configuration values" );
+#endif
+ }
+ }
+ }
+ }
+ DBG_ASSERT( nCurrentDataFilesChangedCheckValue != -1, "SvxLinguConfigUpdate::UpdateAll DataFilesChangedCheckValue not yet calculated!" );
+ Any aAny;
+
+ // for the time being (developer builds until OOo 3.0)
+ // we should always check for everything available
+ // otherwise we may miss a new installed extension dicitonary
+ // just because e.g. the spellchecker is not asked what
+ // languages it does support currently...
+ // Since the check is on-demand occuring and executed once it should
+ // not be too troublesome.
+ // In OOo 3.0 we will not need the respective code anymore at all.
+// aAny <<= nCurrentDataFilesChangedCheckValue;
+ aAny <<= (INT32) -1; // keep the value set to 'need to check'
+
+ aCfg.SetProperty( A2OU( "DataFilesChangedCheckValue" ), aAny );
+
+ //! Note 1: the new values are commited when the 'aCfg' object
+ //! gets destroyed.
+ //! Note 2: the new settings in the configuration get applied
+ //! because the 'LngSvcMgr' (in linguistic/source/lngsvcmgr.hxx)
+ //! listens to the configuration for changes of the relevant
+ //! properties and then applies the new settings.
+
+ // nothing needs to be done anymore
+ nNeedUpdating = 0;
+ }
+}
+
+
+INT32 SvxLinguConfigUpdate::CalcDataFilesChangedCheckValue()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::CalcDataFilesChangedCheckValue" );
+
+ INT32 nHashVal = 0;
+ // nothing to be checked anymore since those old directory paths are gone by now
+ return nHashVal;
+}
+
+
+BOOL SvxLinguConfigUpdate::IsNeedUpdateAll( sal_Bool bForceCheck )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::IsNeedUpdateAll" );
+ if (nNeedUpdating == -1 || bForceCheck ) // need to check if updating is necessary
+ {
+ // calculate hash value for current data files
+ nCurrentDataFilesChangedCheckValue = CalcDataFilesChangedCheckValue();
+
+ // compare hash value and check value to see if anything has changed
+ // and thus the configuration needs to be updated
+ SvtLinguOptions aLinguOpt;
+ SvtLinguConfig aCfg;
+ aCfg.GetOptions( aLinguOpt );
+ nNeedUpdating = (nCurrentDataFilesChangedCheckValue == aLinguOpt.nDataFilesChangedCheckValue) ? 0 : 1;
+ }
+ DBG_ASSERT( nNeedUpdating != -1,
+ "need for linguistic configuration update should have been already checked." );
+
+ return nNeedUpdating == 1;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+
+//! Dummy implementation in order to avoid loading of lingu DLL
+//! when only the XSupportedLocales interface is used.
+//! The dummy accesses the real implementation (and thus loading the DLL)
+//! when "real" work needs to be done only.
+class ThesDummy_Impl :
+ public cppu::WeakImplHelper1< XThesaurus >
+{
+ uno::Reference< XThesaurus > xThes; // the real one...
+ Sequence< Locale > *pLocaleSeq;
+
+ void GetCfgLocales();
+
+ void GetThes_Impl();
+
+public:
+ ThesDummy_Impl() : pLocaleSeq(0) {}
+ ~ThesDummy_Impl();
+
+ // XSupportedLocales
+ virtual ::com::sun::star::uno::Sequence<
+ ::com::sun::star::lang::Locale > SAL_CALL
+ getLocales()
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL
+ hasLocale( const ::com::sun::star::lang::Locale& rLocale )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XThesaurus
+ virtual ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::linguistic2::XMeaning > > SAL_CALL
+ queryMeanings( const ::rtl::OUString& rTerm,
+ const ::com::sun::star::lang::Locale& rLocale,
+ const ::com::sun::star::beans::PropertyValues& rProperties )
+ throw(::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException);
+};
+
+
+ThesDummy_Impl::~ThesDummy_Impl()
+{
+ delete pLocaleSeq;
+}
+
+
+void ThesDummy_Impl::GetCfgLocales()
+{
+ if (!pLocaleSeq)
+ {
+ SvtLinguConfig aCfg;
+ String aNode( A2OU( "ServiceManager/ThesaurusList" ) );
+ Sequence < OUString > aNodeNames( aCfg.GetNodeNames( aNode ) );
+ const OUString *pNodeNames = aNodeNames.getConstArray();
+ INT32 nLen = aNodeNames.getLength();
+ pLocaleSeq = new Sequence< Locale >( nLen );
+ Locale *pLocale = pLocaleSeq->getArray();
+ for (INT32 i = 0; i < nLen; ++i)
+ {
+ pLocale[i] = SvxCreateLocale(
+ MsLangId::convertIsoStringToLanguage( pNodeNames[i] ) );
+ }
+ }
+}
+
+
+void ThesDummy_Impl::GetThes_Impl()
+{
+ // update configuration before accessing the service
+ if (SvxLinguConfigUpdate::IsNeedUpdateAll())
+ SvxLinguConfigUpdate::UpdateAll();
+
+ if (!xThes.is())
+ {
+ uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
+ if (xLngSvcMgr.is())
+ xThes = xLngSvcMgr->getThesaurus();
+
+ if (xThes.is())
+ {
+ // no longer needed...
+ delete pLocaleSeq; pLocaleSeq = 0;
+ }
+ }
+}
+
+
+uno::Sequence< lang::Locale > SAL_CALL
+ ThesDummy_Impl::getLocales()
+ throw(uno::RuntimeException)
+{
+ if (!SvxLinguConfigUpdate::IsNeedUpdateAll()) // configuration already update and thus lingu DLL's already loaded ?
+ GetThes_Impl();
+ if (xThes.is())
+ return xThes->getLocales();
+ else if (!pLocaleSeq) // if not already loaded save startup time by avoiding loading them now
+ GetCfgLocales();
+ return *pLocaleSeq;
+}
+
+
+sal_Bool SAL_CALL
+ ThesDummy_Impl::hasLocale( const lang::Locale& rLocale )
+ throw(uno::RuntimeException)
+{
+ if (!SvxLinguConfigUpdate::IsNeedUpdateAll()) // configuration already update and thus lingu DLL's already loaded ?
+ GetThes_Impl();
+ if (xThes.is())
+ return xThes->hasLocale( rLocale );
+ else if (!pLocaleSeq) // if not already loaded save startup time by avoiding loading them now
+ GetCfgLocales();
+ GetCfgLocales();
+ BOOL bFound = FALSE;
+ INT32 nLen = pLocaleSeq->getLength();
+ const Locale *pLocale = pLocaleSeq->getConstArray();
+ const Locale *pEnd = pLocale + nLen;
+ for ( ; pLocale < pEnd && !bFound; ++pLocale)
+ {
+ bFound = pLocale->Language == rLocale.Language &&
+ pLocale->Country == rLocale.Country &&
+ pLocale->Variant == rLocale.Variant;
+ }
+ return bFound;
+}
+
+
+uno::Sequence< uno::Reference< linguistic2::XMeaning > > SAL_CALL
+ ThesDummy_Impl::queryMeanings(
+ const rtl::OUString& rTerm,
+ const lang::Locale& rLocale,
+ const beans::PropertyValues& rProperties )
+ throw(lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ GetThes_Impl();
+ uno::Sequence< uno::Reference< linguistic2::XMeaning > > aRes;
+ DBG_ASSERT( xThes.is(), "Thesaurus missing" );
+ if (xThes.is())
+ aRes = xThes->queryMeanings( rTerm, rLocale, rProperties );
+ return aRes;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+
+
+//! Dummy implementation in order to avoid loading of lingu DLL.
+//! The dummy accesses the real implementation (and thus loading the DLL)
+//! when it needs to be done only.
+class SpellDummy_Impl :
+ public cppu::WeakImplHelper1< XSpellChecker1 >
+{
+ uno::Reference< XSpellChecker1 > xSpell; // the real one...
+
+ void GetSpell_Impl();
+
+public:
+
+ // XSupportedLanguages (for XSpellChecker1)
+ virtual ::com::sun::star::uno::Sequence< sal_Int16 > SAL_CALL
+ getLanguages()
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL
+ hasLanguage( sal_Int16 nLanguage )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XSpellChecker1 (same as XSpellChecker but sal_Int16 for language)
+ virtual sal_Bool SAL_CALL
+ isValid( const ::rtl::OUString& rWord, sal_Int16 nLanguage,
+ const ::com::sun::star::beans::PropertyValues& rProperties )
+ throw(::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::linguistic2::XSpellAlternatives > SAL_CALL
+ spell( const ::rtl::OUString& rWord, sal_Int16 nLanguage,
+ const ::com::sun::star::beans::PropertyValues& rProperties )
+ throw(::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException);
+};
+
+
+void SpellDummy_Impl::GetSpell_Impl()
+{
+ // update configuration before accessing the service
+ if (SvxLinguConfigUpdate::IsNeedUpdateAll())
+ SvxLinguConfigUpdate::UpdateAll();
+
+ if (!xSpell.is())
+ {
+ uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
+ if (xLngSvcMgr.is())
+ xSpell = uno::Reference< XSpellChecker1 >( xLngSvcMgr->getSpellChecker(), UNO_QUERY );
+ }
+}
+
+
+uno::Sequence< sal_Int16 > SAL_CALL
+ SpellDummy_Impl::getLanguages()
+ throw(uno::RuntimeException)
+{
+ GetSpell_Impl();
+ if (xSpell.is())
+ return xSpell->getLanguages();
+ else
+ return uno::Sequence< sal_Int16 >();
+}
+
+
+sal_Bool SAL_CALL
+ SpellDummy_Impl::hasLanguage( sal_Int16 nLanguage )
+ throw(uno::RuntimeException)
+{
+ GetSpell_Impl();
+ BOOL bRes = FALSE;
+ if (xSpell.is())
+ bRes = xSpell->hasLanguage( nLanguage );
+ return bRes;
+}
+
+
+sal_Bool SAL_CALL
+ SpellDummy_Impl::isValid( const rtl::OUString& rWord, sal_Int16 nLanguage,
+ const beans::PropertyValues& rProperties )
+ throw(lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ GetSpell_Impl();
+ BOOL bRes = TRUE;
+ if (xSpell.is())
+ bRes = xSpell->isValid( rWord, nLanguage, rProperties );
+ return bRes;
+}
+
+
+uno::Reference< linguistic2::XSpellAlternatives > SAL_CALL
+ SpellDummy_Impl::spell( const rtl::OUString& rWord, sal_Int16 nLanguage,
+ const beans::PropertyValues& rProperties )
+ throw(lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ GetSpell_Impl();
+ uno::Reference< linguistic2::XSpellAlternatives > xRes;
+ if (xSpell.is())
+ xRes = xSpell->spell( rWord, nLanguage, rProperties );
+ return xRes;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+
+
+//! Dummy implementation in order to avoid loading of lingu DLL.
+//! The dummy accesses the real implementation (and thus loading the DLL)
+//! when it needs to be done only.
+class HyphDummy_Impl :
+ public cppu::WeakImplHelper1< XHyphenator >
+{
+ uno::Reference< XHyphenator > xHyph; // the real one...
+
+ void GetHyph_Impl();
+
+public:
+
+ // XSupportedLocales
+ virtual ::com::sun::star::uno::Sequence<
+ ::com::sun::star::lang::Locale > SAL_CALL
+ getLocales()
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL
+ hasLocale( const ::com::sun::star::lang::Locale& rLocale )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XHyphenator
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::linguistic2::XHyphenatedWord > SAL_CALL
+ hyphenate( const ::rtl::OUString& rWord,
+ const ::com::sun::star::lang::Locale& rLocale,
+ sal_Int16 nMaxLeading,
+ const ::com::sun::star::beans::PropertyValues& rProperties )
+ throw(::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::linguistic2::XHyphenatedWord > SAL_CALL
+ queryAlternativeSpelling( const ::rtl::OUString& rWord,
+ const ::com::sun::star::lang::Locale& rLocale,
+ sal_Int16 nIndex,
+ const ::com::sun::star::beans::PropertyValues& rProperties )
+ throw(::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::linguistic2::XPossibleHyphens > SAL_CALL
+ createPossibleHyphens(
+ const ::rtl::OUString& rWord,
+ const ::com::sun::star::lang::Locale& rLocale,
+ const ::com::sun::star::beans::PropertyValues& rProperties )
+ throw(::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException);
+};
+
+
+void HyphDummy_Impl::GetHyph_Impl()
+{
+ // update configuration before accessing the service
+ if (SvxLinguConfigUpdate::IsNeedUpdateAll())
+ SvxLinguConfigUpdate::UpdateAll();
+
+ if (!xHyph.is())
+ {
+ uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
+ if (xLngSvcMgr.is())
+ xHyph = xLngSvcMgr->getHyphenator();
+ }
+}
+
+
+uno::Sequence< lang::Locale > SAL_CALL
+ HyphDummy_Impl::getLocales()
+ throw(uno::RuntimeException)
+{
+ GetHyph_Impl();
+ if (xHyph.is())
+ return xHyph->getLocales();
+ else
+ return uno::Sequence< lang::Locale >();
+}
+
+
+sal_Bool SAL_CALL
+ HyphDummy_Impl::hasLocale( const lang::Locale& rLocale )
+ throw(uno::RuntimeException)
+{
+ GetHyph_Impl();
+ BOOL bRes = FALSE;
+ if (xHyph.is())
+ bRes = xHyph->hasLocale( rLocale );
+ return bRes;
+}
+
+
+uno::Reference< linguistic2::XHyphenatedWord > SAL_CALL
+ HyphDummy_Impl::hyphenate(
+ const rtl::OUString& rWord,
+ const lang::Locale& rLocale,
+ sal_Int16 nMaxLeading,
+ const beans::PropertyValues& rProperties )
+ throw(lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ GetHyph_Impl();
+ uno::Reference< linguistic2::XHyphenatedWord > xRes;
+ if (xHyph.is())
+ xRes = xHyph->hyphenate( rWord, rLocale, nMaxLeading, rProperties );
+ return xRes;
+}
+
+
+uno::Reference< linguistic2::XHyphenatedWord > SAL_CALL
+ HyphDummy_Impl::queryAlternativeSpelling(
+ const rtl::OUString& rWord,
+ const lang::Locale& rLocale,
+ sal_Int16 nIndex,
+ const PropertyValues& rProperties )
+ throw(lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ GetHyph_Impl();
+ uno::Reference< linguistic2::XHyphenatedWord > xRes;
+ if (xHyph.is())
+ xRes = xHyph->queryAlternativeSpelling( rWord, rLocale, nIndex, rProperties );
+ return xRes;
+}
+
+
+uno::Reference< linguistic2::XPossibleHyphens > SAL_CALL
+ HyphDummy_Impl::createPossibleHyphens(
+ const rtl::OUString& rWord,
+ const lang::Locale& rLocale,
+ const beans::PropertyValues& rProperties )
+ throw(lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ GetHyph_Impl();
+ uno::Reference< linguistic2::XPossibleHyphens > xRes;
+ if (xHyph.is())
+ xRes = xHyph->createPossibleHyphens( rWord, rLocale, rProperties );
+ return xRes;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+
+
+typedef cppu::WeakImplHelper1 < XEventListener > LinguMgrAppExitLstnrBaseClass;
+
+class LinguMgrAppExitLstnr : public LinguMgrAppExitLstnrBaseClass
+{
+ uno::Reference< XComponent > xDesktop;
+
+public:
+ LinguMgrAppExitLstnr();
+ virtual ~LinguMgrAppExitLstnr();
+
+ virtual void AtExit() = 0;
+
+
+ // lang::XEventListener
+ virtual void SAL_CALL disposing(const EventObject& rSource)
+ throw( RuntimeException );
+};
+
+LinguMgrAppExitLstnr::LinguMgrAppExitLstnr()
+{
+ // add object to frame::Desktop EventListeners in order to properly call
+ // the AtExit function at appliction exit.
+
+ uno::Reference< XMultiServiceFactory > xMgr = getProcessServiceFactory();
+ if ( xMgr.is() )
+ {
+ xDesktop = uno::Reference< XComponent > ( xMgr->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) ) ), UNO_QUERY ) ;
+ if (xDesktop.is())
+ xDesktop->addEventListener( this );
+ }
+}
+
+LinguMgrAppExitLstnr::~LinguMgrAppExitLstnr()
+{
+ if (xDesktop.is())
+ {
+ xDesktop->removeEventListener( this );
+ xDesktop = NULL; //! release reference to desktop
+ }
+ DBG_ASSERT(!xDesktop.is(), "reference to desktop should be realeased");
+}
+
+void LinguMgrAppExitLstnr::disposing(const EventObject& rSource)
+ throw( RuntimeException )
+{
+ if (xDesktop.is() && rSource.Source == xDesktop)
+ {
+ xDesktop->removeEventListener( this );
+ xDesktop = NULL; //! release reference to desktop
+
+ AtExit();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+class LinguMgrExitLstnr : public LinguMgrAppExitLstnr
+{
+public:
+ virtual void AtExit();
+};
+
+void LinguMgrExitLstnr::AtExit()
+{
+ // release references
+ LinguMgr::xLngSvcMgr = 0;
+ LinguMgr::xSpell = 0;
+ LinguMgr::xHyph = 0;
+ LinguMgr::xThes = 0;
+ LinguMgr::xDicList = 0;
+ LinguMgr::xProp = 0;
+ LinguMgr::xIgnoreAll = 0;
+ LinguMgr::xChangeAll = 0;
+
+ LinguMgr::bExiting = sal_True;
+
+ //TL:TODO: MBA fragen wie ich ohne Absturz hier meinen Speicher
+ // wieder freibekomme...
+ //delete LinguMgr::pExitLstnr;
+ LinguMgr::pExitLstnr = 0;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+
+// static member initialization
+LinguMgrExitLstnr * LinguMgr::pExitLstnr = 0;
+sal_Bool LinguMgr::bExiting = sal_False;
+uno::Reference< XLinguServiceManager > LinguMgr::xLngSvcMgr = 0;
+uno::Reference< XSpellChecker1 > LinguMgr::xSpell = 0;
+uno::Reference< XHyphenator > LinguMgr::xHyph = 0;
+uno::Reference< XThesaurus > LinguMgr::xThes = 0;
+uno::Reference< XDictionaryList > LinguMgr::xDicList = 0;
+uno::Reference< XPropertySet > LinguMgr::xProp = 0;
+uno::Reference< XDictionary > LinguMgr::xIgnoreAll = 0;
+uno::Reference< XDictionary > LinguMgr::xChangeAll = 0;
+
+
+uno::Reference< XLinguServiceManager > LinguMgr::GetLngSvcMgr()
+{
+ if (bExiting)
+ return 0;
+
+ if (!pExitLstnr)
+ pExitLstnr = new LinguMgrExitLstnr;
+
+ if (!xLngSvcMgr.is())
+ xLngSvcMgr = GetLngSvcMgr_Impl();
+
+ return xLngSvcMgr;
+}
+
+
+uno::Reference< XSpellChecker1 > LinguMgr::GetSpellChecker()
+{
+ return xSpell.is() ? xSpell : GetSpell();
+}
+
+uno::Reference< XHyphenator > LinguMgr::GetHyphenator()
+{
+ return xHyph.is() ? xHyph : GetHyph();
+}
+
+uno::Reference< XThesaurus > LinguMgr::GetThesaurus()
+{
+ return xThes.is() ? xThes : GetThes();
+}
+
+uno::Reference< XDictionaryList > LinguMgr::GetDictionaryList()
+{
+ return xDicList.is() ? xDicList : GetDicList();
+}
+
+uno::Reference< XPropertySet > LinguMgr::GetLinguPropertySet()
+{
+ return xProp.is() ? xProp : GetProp();
+}
+
+uno::Reference< XDictionary > LinguMgr::GetStandardDic()
+{
+ //! don't hold reference to this
+ //! (it may be removed from dictionary list and needs to be
+ //! created empty if accessed again)
+ return GetStandard();
+}
+
+uno::Reference< XDictionary > LinguMgr::GetIgnoreAllList()
+{
+ return xIgnoreAll.is() ? xIgnoreAll : GetIgnoreAll();
+}
+
+uno::Reference< XDictionary > LinguMgr::GetChangeAllList()
+{
+ return xChangeAll.is() ? xChangeAll : GetChangeAll();
+}
+
+uno::Reference< XSpellChecker1 > LinguMgr::GetSpell()
+{
+ if (bExiting)
+ return 0;
+
+ if (!pExitLstnr)
+ pExitLstnr = new LinguMgrExitLstnr;
+
+ //! use dummy implementation in order to avoid loading of lingu DLL
+ xSpell = new SpellDummy_Impl;
+
+/* if (!xLngSvcMgr.is())
+ xLngSvcMgr = GetLngSvcMgr_Impl();
+
+ if (xLngSvcMgr.is())
+ {
+ xSpell = uno::Reference< XSpellChecker1 > (
+ xLngSvcMgr->getSpellChecker(), UNO_QUERY );
+ }
+*/
+ return xSpell;
+}
+
+uno::Reference< XHyphenator > LinguMgr::GetHyph()
+{
+ if (bExiting)
+ return 0;
+
+ if (!pExitLstnr)
+ pExitLstnr = new LinguMgrExitLstnr;
+
+ //! use dummy implementation in order to avoid loading of lingu DLL
+ xHyph = new HyphDummy_Impl;
+
+/*
+ if (!xLngSvcMgr.is())
+ xLngSvcMgr = GetLngSvcMgr_Impl();
+
+ if (xLngSvcMgr.is())
+ {
+ xHyph = xLngSvcMgr->getHyphenator();
+ }
+*/
+ return xHyph;
+}
+
+uno::Reference< XThesaurus > LinguMgr::GetThes()
+{
+ if (bExiting)
+ return 0;
+
+ if (!pExitLstnr)
+ pExitLstnr = new LinguMgrExitLstnr;
+
+ //! use dummy implementation in order to avoid loading of lingu DLL
+ //! when only the XSupportedLocales interface is used.
+ //! The dummy accesses the real implementation (and thus loading the DLL)
+ //! when "real" work needs to be done only.
+ xThes = new ThesDummy_Impl;
+/*
+ if (!xLngSvcMgr.is())
+ xLngSvcMgr = GetLngSvcMgr_Impl();
+
+ if (xLngSvcMgr.is())
+ {
+ xThes = xLngSvcMgr->getThesaurus();
+ }
+*/
+ return xThes;
+}
+
+
+void LinguMgr::UpdateAll()
+{
+}
+
+
+uno::Reference< XDictionaryList > LinguMgr::GetDicList()
+{
+ if (bExiting)
+ return 0;
+
+ if (!pExitLstnr)
+ pExitLstnr = new LinguMgrExitLstnr;
+
+ uno::Reference< XMultiServiceFactory > xMgr( getProcessServiceFactory() );
+ if (xMgr.is())
+ {
+ xDicList = uno::Reference< XDictionaryList > ( xMgr->createInstance(
+ A2OU("com.sun.star.linguistic2.DictionaryList") ), UNO_QUERY );
+ }
+ return xDicList;
+}
+
+uno::Reference< XPropertySet > LinguMgr::GetProp()
+{
+ if (bExiting)
+ return 0;
+
+ if (!pExitLstnr)
+ pExitLstnr = new LinguMgrExitLstnr;
+
+ uno::Reference< XMultiServiceFactory > xMgr( getProcessServiceFactory() );
+ if (xMgr.is())
+ {
+ xProp = uno::Reference< XPropertySet > ( xMgr->createInstance(
+ A2OU("com.sun.star.linguistic2.LinguProperties") ), UNO_QUERY );
+ }
+ return xProp;
+}
+
+uno::Reference< XDictionary > LinguMgr::GetIgnoreAll()
+{
+ if (bExiting)
+ return 0;
+
+ if (!pExitLstnr)
+ pExitLstnr = new LinguMgrExitLstnr;
+
+ uno::Reference< XDictionaryList > xTmpDicList( GetDictionaryList() );
+ if (xTmpDicList.is())
+ {
+ xIgnoreAll = uno::Reference< XDictionary > ( xTmpDicList->getDictionaryByName(
+ A2OU("IgnoreAllList") ), UNO_QUERY );
+ }
+ return xIgnoreAll;
+}
+
+uno::Reference< XDictionary > LinguMgr::GetChangeAll()
+{
+ if (bExiting)
+ return 0;
+
+ if (!pExitLstnr)
+ pExitLstnr = new LinguMgrExitLstnr;
+
+ uno::Reference< XDictionaryList > _xDicList( GetDictionaryList() , UNO_QUERY );
+ if (_xDicList.is())
+ {
+ xChangeAll = uno::Reference< XDictionary > (
+ _xDicList->createDictionary(
+ A2OU("ChangeAllList"),
+ SvxCreateLocale( LANGUAGE_NONE ),
+ DictionaryType_NEGATIVE, String() ), UNO_QUERY );
+ }
+ return xChangeAll;
+}
+
+uno::Reference< XDictionary > LinguMgr::GetStandard()
+{
+ // Tries to return a dictionary which may hold positive entries is
+ // persistent and not read-only.
+
+ if (bExiting)
+ return 0;
+
+ uno::Reference< XDictionaryList > xTmpDicList( GetDictionaryList() );
+ if (!xTmpDicList.is())
+ return NULL;
+
+ const OUString aDicName( RTL_CONSTASCII_USTRINGPARAM( "standard.dic" ) );
+ uno::Reference< XDictionary > xDic( xTmpDicList->getDictionaryByName( aDicName ),
+ UNO_QUERY );
+ if (!xDic.is())
+ {
+ // try to create standard dictionary
+ uno::Reference< XDictionary > xTmp;
+ try
+ {
+ xTmp = xTmpDicList->createDictionary( aDicName,
+ SvxCreateLocale( LANGUAGE_NONE ),
+ DictionaryType_POSITIVE,
+ linguistic::GetWritableDictionaryURL( aDicName ) );
+ }
+ catch(com::sun::star::uno::Exception &)
+ {
+ }
+
+ // add new dictionary to list
+ if (xTmp.is())
+ xTmpDicList->addDictionary( xTmp );
+ xDic = uno::Reference< XDictionary > ( xTmp, UNO_QUERY );
+ }
+#if OSL_DEBUG_LEVEL > 1
+ uno::Reference< XStorable > xStor( xDic, UNO_QUERY );
+ DBG_ASSERT( xDic.is() && xDic->getDictionaryType() == DictionaryType_POSITIVE,
+ "wrong dictionary type");
+ DBG_ASSERT( xDic.is() && SvxLocaleToLanguage( xDic->getLocale() ) == LANGUAGE_NONE,
+ "wrong dictionary language");
+ DBG_ASSERT( !xStor.is() || (xStor->hasLocation() && !xStor->isReadonly()),
+ "dictionary not editable" );
+#endif
+
+ return xDic;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+uno::Reference< XSpellChecker1 > SvxGetSpellChecker()
+{
+ return LinguMgr::GetSpellChecker();
+}
+
+uno::Reference< XHyphenator > SvxGetHyphenator()
+{
+ return LinguMgr::GetHyphenator();
+}
+
+uno::Reference< XThesaurus > SvxGetThesaurus()
+{
+ return LinguMgr::GetThesaurus();
+}
+
+uno::Reference< XDictionaryList > SvxGetDictionaryList()
+{
+ return LinguMgr::GetDictionaryList();
+}
+
+uno::Reference< XPropertySet > SvxGetLinguPropertySet()
+{
+ return LinguMgr::GetLinguPropertySet();
+}
+
+//TL:TODO: remove argument or provide SvxGetIgnoreAllList with the same one
+uno::Reference< XDictionary > SvxGetOrCreatePosDic(
+ uno::Reference< XDictionaryList > /* xDicList */ )
+{
+ return LinguMgr::GetStandardDic();
+}
+
+uno::Reference< XDictionary > SvxGetIgnoreAllList()
+{
+ return LinguMgr::GetIgnoreAllList();
+}
+
+uno::Reference< XDictionary > SvxGetChangeAllList()
+{
+ return LinguMgr::GetChangeAllList();
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+
+#include <com/sun/star/linguistic2/XHyphenatedWord.hpp>
+
+SvxAlternativeSpelling SvxGetAltSpelling(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::linguistic2::XHyphenatedWord > & rHyphWord )
+{
+ SvxAlternativeSpelling aRes;
+ if (rHyphWord.is() && rHyphWord->isAlternativeSpelling())
+ {
+ OUString aWord( rHyphWord->getWord() ),
+ aAltWord( rHyphWord->getHyphenatedWord() );
+ INT16 nHyphenationPos = rHyphWord->getHyphenationPos(),
+ nHyphenPos = rHyphWord->getHyphenPos();
+ INT16 nLen = (INT16)aWord.getLength();
+ INT16 nAltLen = (INT16)aAltWord.getLength();
+ const sal_Unicode *pWord = aWord.getStr(),
+ *pAltWord = aAltWord.getStr();
+
+ // count number of chars from the left to the
+ // hyphenation pos / hyphen pos that are equal
+ INT16 nL = 0;
+ while (nL <= nHyphenationPos && nL <= nHyphenPos
+ && pWord[ nL ] == pAltWord[ nL ])
+ ++nL;
+ // count number of chars from the right to the
+ // hyphenation pos / hyphen pos that are equal
+ INT16 nR = 0;
+ INT32 nIdx = nLen - 1;
+ INT32 nAltIdx = nAltLen - 1;
+ while (nIdx > nHyphenationPos && nAltIdx > nHyphenPos
+ && pWord[ nIdx-- ] == pAltWord[ nAltIdx-- ])
+ ++nR;
+
+ aRes.aReplacement = OUString( aAltWord.copy( nL, nAltLen - nL - nR ) );
+ aRes.nChangedPos = (INT16) nL;
+ aRes.nChangedLength = nLen - nL - nR;
+ aRes.bIsAltSpelling = TRUE;
+ aRes.xHyphWord = rHyphWord;
+ }
+ return aRes;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+
+SvxDicListChgClamp::SvxDicListChgClamp( uno::Reference< XDictionaryList > &rxDicList ) :
+ xDicList ( rxDicList )
+{
+ if (xDicList.is())
+ {
+ xDicList->beginCollectEvents();
+ }
+}
+
+SvxDicListChgClamp::~SvxDicListChgClamp()
+{
+ if (xDicList.is())
+ {
+ xDicList->endCollectEvents();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+short SvxDicError( Window *pParent, sal_Int16 nError )
+{
+ short nRes = 0;
+ if (DIC_ERR_NONE != nError)
+ {
+ int nRid;
+ switch (nError)
+ {
+ case DIC_ERR_FULL : nRid = RID_SVXSTR_DIC_ERR_FULL; break;
+ case DIC_ERR_READONLY : nRid = RID_SVXSTR_DIC_ERR_READONLY; break;
+ default:
+ nRid = RID_SVXSTR_DIC_ERR_UNKNOWN;
+ DBG_ASSERT(0, "unexpected case");
+ }
+ nRes = InfoBox( pParent, EE_RESSTR( nRid ) ).Execute();
+ }
+ return nRes;
+}
+
+LanguageType SvxLocaleToLanguage( const Locale& rLocale )
+{
+ // empty Locale -> LANGUAGE_NONE
+ if ( rLocale.Language.getLength() == 0 )
+ return LANGUAGE_NONE;
+
+ return MsLangId::convertLocaleToLanguage( rLocale );
+}
+
+Locale& SvxLanguageToLocale( Locale& rLocale, LanguageType eLang )
+{
+ if ( eLang != LANGUAGE_NONE /* && eLang != LANGUAGE_SYSTEM */)
+ MsLangId::convertLanguageToLocale( eLang, rLocale );
+ else
+ rLocale = Locale();
+
+ return rLocale;
+}
+
+Locale SvxCreateLocale( LanguageType eLang )
+{
+ Locale aLocale;
+ if ( eLang != LANGUAGE_NONE /* && eLang != LANGUAGE_SYSTEM */)
+ MsLangId::convertLanguageToLocale( eLang, aLocale );
+
+ return aLocale;
+}
+
+
diff --git a/editeng/source/outliner/makefile.mk b/editeng/source/outliner/makefile.mk
new file mode 100644
index 0000000000..deef353049
--- /dev/null
+++ b/editeng/source/outliner/makefile.mk
@@ -0,0 +1,64 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.6 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=svx
+TARGET=outliner
+AUTOSEG=true
+ENABLE_EXCEPTIONS=TRUE
+
+PROJECTPCH4DLL=TRUE
+PROJECTPCH=outl_pch
+PROJECTPCHSOURCE=outl_pch
+
+
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Allgemein ----------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/outlundo.obj \
+ $(SLO)$/outliner.obj \
+ $(SLO)$/outlin2.obj \
+ $(SLO)$/paralist.obj \
+ $(SLO)$/outlvw.obj \
+ $(SLO)$/outleeng.obj \
+ $(SLO)$/outlobj.obj
+
+SRS1NAME=$(TARGET)
+SRC1FILES= outliner.src
+
+.INCLUDE : target.mk
+
diff --git a/editeng/source/outliner/outl_pch.cxx b/editeng/source/outliner/outl_pch.cxx
new file mode 100644
index 0000000000..58e7511910
--- /dev/null
+++ b/editeng/source/outliner/outl_pch.cxx
@@ -0,0 +1,34 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: outl_pch.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <outl_pch.hxx>
+
diff --git a/editeng/source/outliner/outl_pch.hxx b/editeng/source/outliner/outl_pch.hxx
new file mode 100644
index 0000000000..e8a8a5045b
--- /dev/null
+++ b/editeng/source/outliner/outl_pch.hxx
@@ -0,0 +1,36 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: outl_pch.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <svl/intitem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/eerdll.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/fhgtitem.hxx>
diff --git a/editeng/source/outliner/outleeng.cxx b/editeng/source/outliner/outleeng.cxx
new file mode 100644
index 0000000000..831cdc02be
--- /dev/null
+++ b/editeng/source/outliner/outleeng.cxx
@@ -0,0 +1,247 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: outleeng.cxx,v $
+ * $Revision: 1.19 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <svl/intitem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/eerdll.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/fhgtitem.hxx>
+
+#define _OUTLINER_CXX
+#include <editeng/outliner.hxx>
+#include <outleeng.hxx>
+#include <paralist.hxx>
+#include <editeng/editrids.hrc>
+#include <svl/itemset.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/editstat.hxx>
+#include "outlundo.hxx"
+
+OutlinerEditEng::OutlinerEditEng( Outliner* pEngOwner, SfxItemPool* pPool )
+ : EditEngine( pPool )
+{
+ pOwner = pEngOwner;
+}
+
+OutlinerEditEng::~OutlinerEditEng()
+{
+}
+
+void OutlinerEditEng::PaintingFirstLine( USHORT nPara, const Point& rStartPos, long nBaseLineY, const Point& rOrigin, short nOrientation, OutputDevice* pOutDev )
+{
+ if( GetControlWord() && EE_CNTRL_OUTLINER )
+ {
+ PaintFirstLineInfo aInfo( nPara, rStartPos, nBaseLineY, rOrigin, nOrientation, pOutDev );
+ pOwner->maPaintFirstLineHdl.Call( &aInfo );
+ }
+
+ pOwner->PaintBullet( nPara, rStartPos, rOrigin, nOrientation, pOutDev );
+}
+
+const SvxNumberFormat* OutlinerEditEng::GetNumberFormat( USHORT nPara ) const
+{
+ const SvxNumberFormat* pFmt = NULL;
+ if (pOwner)
+ pFmt = pOwner->GetNumberFormat( nPara );
+ return pFmt;
+}
+
+
+Rectangle OutlinerEditEng::GetBulletArea( USHORT nPara )
+{
+ Rectangle aBulletArea = Rectangle( Point(), Point() );
+ if ( nPara < pOwner->pParaList->GetParagraphCount() )
+ {
+ if ( pOwner->ImplHasBullet( nPara ) )
+ aBulletArea = pOwner->ImpCalcBulletArea( nPara, FALSE, FALSE );
+ }
+ return aBulletArea;
+}
+
+void OutlinerEditEng::ParagraphInserted( USHORT nNewParagraph )
+{
+ pOwner->ParagraphInserted( nNewParagraph );
+
+ EditEngine::ParagraphInserted( nNewParagraph );
+}
+
+void OutlinerEditEng::ParagraphDeleted( USHORT nDeletedParagraph )
+{
+ pOwner->ParagraphDeleted( nDeletedParagraph );
+
+ EditEngine::ParagraphDeleted( nDeletedParagraph );
+}
+
+void OutlinerEditEng::ParagraphConnected( USHORT /*nLeftParagraph*/, USHORT nRightParagraph )
+{
+ if( pOwner && pOwner->IsUndoEnabled() && !const_cast<EditEngine&>(pOwner->GetEditEngine()).IsInUndo() )
+ {
+ Paragraph* pPara = pOwner->GetParagraph( nRightParagraph );
+ if( pPara && pOwner->HasParaFlag( pPara, PARAFLAG_ISPAGE ) )
+ {
+ pOwner->InsertUndo( new OutlinerUndoChangeParaFlags( pOwner, nRightParagraph, PARAFLAG_ISPAGE, 0 ) );
+ }
+ }
+}
+
+
+void OutlinerEditEng::StyleSheetChanged( SfxStyleSheet* pStyle )
+{
+ pOwner->StyleSheetChanged( pStyle );
+}
+
+void OutlinerEditEng::ParaAttribsChanged( USHORT nPara )
+{
+ pOwner->ParaAttribsChanged( nPara );
+}
+
+BOOL OutlinerEditEng::SpellNextDocument()
+{
+ return pOwner->SpellNextDocument();
+}
+
+BOOL OutlinerEditEng::ConvertNextDocument()
+{
+ return pOwner->ConvertNextDocument();
+}
+
+XubString OutlinerEditEng::GetUndoComment( USHORT nUndoId ) const
+{
+ switch( nUndoId )
+ {
+ case OLUNDO_DEPTH:
+ return XubString( EditResId( RID_OUTLUNDO_DEPTH ));
+
+ case OLUNDO_EXPAND:
+ return XubString( EditResId( RID_OUTLUNDO_EXPAND ));
+
+ case OLUNDO_COLLAPSE:
+ return XubString( EditResId( RID_OUTLUNDO_COLLAPSE ));
+
+ case OLUNDO_ATTR:
+ return XubString( EditResId( RID_OUTLUNDO_ATTR ));
+
+ case OLUNDO_INSERT:
+ return XubString( EditResId( RID_OUTLUNDO_INSERT ));
+
+ default:
+ return EditEngine::GetUndoComment( nUndoId );
+ }
+}
+
+// #101498#
+void OutlinerEditEng::DrawingText( const Point& rStartPos, const XubString& rText, USHORT nTextStart, USHORT nTextLen,
+ const sal_Int32* pDXArray, const SvxFont& rFont, USHORT nPara, USHORT nIndex, BYTE nRightToLeft,
+ const EEngineData::WrongSpellVector* pWrongSpellVector,
+ const SvxFieldData* pFieldData,
+ bool bEndOfLine,
+ bool bEndOfParagraph,
+ bool bEndOfBullet,
+ const ::com::sun::star::lang::Locale* pLocale,
+ const Color& rOverlineColor,
+ const Color& rTextLineColor)
+{
+ // why do bullet here at all? Just use GetEditEnginePtr()->PaintingFirstLine
+ // inside of ImpEditEngine::Paint which calls pOwner->PaintBullet with the correct
+ // values for hor and ver. No change for not-layouting (painting).
+ // changed, bullet rendering now using PaintBullet via
+/* if ( nIndex == 0 )
+ {
+ // Dann das Bullet 'malen', dort wird bStrippingPortions ausgewertet
+ // und Outliner::DrawingText gerufen
+
+ // DrawingText liefert die BaseLine, DrawBullet braucht Top().
+
+ if(true)
+ {
+ // ##
+ // another error: This call happens when only stripping, but the position
+ // is already aligned to text output. For bullet rendering, it needs to be reset
+ // to the correct value in x and y. PaintBullet takes care of X-start offset itself
+ const Point aDocPosTopLeft(GetDocPosTopLeft( nPara ));
+ const Point aCorrectedPos(rStartPos.X() - aDocPosTopLeft.X(), aDocPosTopLeft.Y() + GetFirstLineOffset( nPara ));
+ pOwner->PaintBullet( nPara, aCorrectedPos, Point(), 0, GetRefDevice() );
+ }
+ else
+ {
+ Point aCorrectedPos( rStartPos );
+ aCorrectedPos.Y() = GetDocPosTopLeft( nPara ).Y();
+ aCorrectedPos.Y() += GetFirstLineOffset( nPara );
+ pOwner->PaintBullet( nPara, aCorrectedPos, Point(), 0, GetRefDevice() );
+ }
+ } */
+
+ // #101498#
+ pOwner->DrawingText(rStartPos,rText,nTextStart,nTextLen,pDXArray,rFont,nPara,nIndex,nRightToLeft,
+ pWrongSpellVector, pFieldData, bEndOfLine, bEndOfParagraph, bEndOfBullet, pLocale, rOverlineColor, rTextLineColor);
+}
+
+void OutlinerEditEng::FieldClicked( const SvxFieldItem& rField, USHORT nPara, USHORT nPos )
+{
+ EditEngine::FieldClicked( rField, nPara, nPos ); // Falls URL
+ pOwner->FieldClicked( rField, nPara, nPos );
+}
+
+void OutlinerEditEng::FieldSelected( const SvxFieldItem& rField, USHORT nPara, USHORT nPos )
+{
+ pOwner->FieldSelected( rField, nPara, nPos );
+}
+
+XubString OutlinerEditEng::CalcFieldValue( const SvxFieldItem& rField, USHORT nPara, USHORT nPos, Color*& rpTxtColor, Color*& rpFldColor )
+{
+ return pOwner->CalcFieldValue( rField, nPara, nPos, rpTxtColor, rpFldColor );
+}
+
+void OutlinerEditEng::SetParaAttribs( USHORT nPara, const SfxItemSet& rSet )
+{
+ Paragraph* pPara = pOwner->pParaList->GetParagraph( nPara );
+ if( pPara )
+ {
+ if ( !IsInUndo() && IsUndoEnabled() )
+ pOwner->UndoActionStart( OLUNDO_ATTR );
+
+ EditEngine::SetParaAttribs( (USHORT)nPara, rSet );
+
+ pOwner->ImplCheckNumBulletItem( (USHORT)nPara );
+ // --> OD 2009-03-10 #i100014#
+ // It is not a good idea to substract 1 from a count and cast the result
+ // to USHORT without check, if the count is 0.
+ pOwner->ImplCheckParagraphs( (USHORT)nPara, (USHORT) (pOwner->pParaList->GetParagraphCount()) );
+ // <--
+
+ if ( !IsInUndo() && IsUndoEnabled() )
+ pOwner->UndoActionEnd( OLUNDO_ATTR );
+ }
+}
+
diff --git a/editeng/source/outliner/outleeng.hxx b/editeng/source/outliner/outleeng.hxx
new file mode 100644
index 0000000000..99c2567a0f
--- /dev/null
+++ b/editeng/source/outliner/outleeng.hxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: outleeng.hxx,v $
+ * $Revision: 1.15 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _OUTLEENG_HXX
+#define _OUTLEENG_HXX
+
+#include <editeng/outliner.hxx>
+#ifndef _EDITENG_HXX
+#include <editeng/editeng.hxx>
+#endif
+
+typedef EENotify* EENotifyPtr;
+SV_DECL_PTRARR_DEL( NotifyList, EENotifyPtr, 1, 1 )
+
+class OutlinerEditEng : public EditEngine
+{
+ Outliner* pOwner;
+
+protected:
+
+ // derived from EditEngine. Allows Outliner objetcs to provide
+ // bullet access to the EditEngine.
+ virtual const SvxNumberFormat* GetNumberFormat( USHORT nPara ) const;
+
+public:
+ OutlinerEditEng( Outliner* pOwner, SfxItemPool* pPool );
+ ~OutlinerEditEng();
+
+ virtual void PaintingFirstLine( USHORT nPara, const Point& rStartPos, long nBaseLineY, const Point& rOrigin, short nOrientation, OutputDevice* pOutDev );
+
+ virtual void ParagraphInserted( USHORT nNewParagraph );
+ virtual void ParagraphDeleted( USHORT nDeletedParagraph );
+ virtual void ParagraphConnected( USHORT nLeftParagraph, USHORT nRightParagraph );
+
+ // #101498#
+ virtual void DrawingText(
+ const Point& rStartPos, const XubString& rText, USHORT nTextStart, USHORT nTextLen, const sal_Int32* pDXArray, const SvxFont& rFont,
+ USHORT nPara, USHORT nIndex, BYTE nRightToLeft,
+ const EEngineData::WrongSpellVector* pWrongSpellVector,
+ const SvxFieldData* pFieldData,
+ bool bEndOfLine,
+ bool bEndOfParagraph,
+ bool bEndOfBullet,
+ const ::com::sun::star::lang::Locale* pLocale,
+ const Color& rOverlineColor,
+ const Color& rTextLineColor);
+
+ virtual void StyleSheetChanged( SfxStyleSheet* pStyle );
+ virtual void ParaAttribsChanged( USHORT nPara );
+ virtual BOOL SpellNextDocument();
+ virtual XubString GetUndoComment( USHORT nUndoId ) const;
+
+ // for text conversion
+ virtual BOOL ConvertNextDocument();
+
+ virtual void FieldClicked( const SvxFieldItem& rField, USHORT nPara, USHORT nPos );
+ virtual void FieldSelected( const SvxFieldItem& rField, USHORT nPara, USHORT nPos );
+ virtual XubString CalcFieldValue( const SvxFieldItem& rField, USHORT nPara, USHORT nPos, Color*& rTxtColor, Color*& rFldColor );
+
+ virtual Rectangle GetBulletArea( USHORT nPara );
+
+ virtual void SetParaAttribs( USHORT nPara, const SfxItemSet& rSet );
+
+ // belongs into class Outliner, move there before incompatible update!
+ Link aOutlinerNotifyHdl;
+ NotifyList aNotifyCache;
+};
+
+#endif
+
diff --git a/editeng/source/outliner/outlin2.cxx b/editeng/source/outliner/outlin2.cxx
new file mode 100644
index 0000000000..b3f99e8dae
--- /dev/null
+++ b/editeng/source/outliner/outlin2.cxx
@@ -0,0 +1,816 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: outlin2.cxx,v $
+ * $Revision: 1.37 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <svl/intitem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/eerdll.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <tools/list.hxx>
+#include <svl/style.hxx>
+#include <vcl/mapmod.hxx>
+
+#include <editeng/forbiddencharacterstable.hxx>
+
+#define _OUTLINER_CXX
+
+#include <editeng/outliner.hxx>
+#include <paralist.hxx>
+#include <editeng/outlobj.hxx>
+#include <outleeng.hxx>
+#include <outlundo.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/editstat.hxx>
+
+DBG_NAMEEX(Outliner)
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::linguistic2;
+
+// =====================================================================
+// ====================== Einfache Durchreicher =======================
+// ======================================================================
+
+void Outliner::SetUpdateMode( BOOL bUpdate )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetUpdateMode( bUpdate );
+}
+
+
+BOOL Outliner::GetUpdateMode() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetUpdateMode();
+}
+
+const SfxItemSet& Outliner::GetEmptyItemSet() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetEmptyItemSet();
+}
+
+void Outliner::EnableUndo( BOOL bEnable )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->EnableUndo( bEnable );
+}
+
+BOOL Outliner::IsUndoEnabled() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->IsUndoEnabled();
+}
+
+MapMode Outliner::GetRefMapMode() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetRefMapMode();
+}
+
+void Outliner::SetRefMapMode( const MapMode& rMMode )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetRefMapMode( rMMode );
+}
+
+void Outliner::SetBackgroundColor( const Color& rColor )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetBackgroundColor( rColor );
+}
+
+Color Outliner::GetBackgroundColor() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetBackgroundColor();
+}
+
+
+void Outliner::ClearModifyFlag()
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->ClearModifyFlag();
+}
+
+BOOL Outliner::IsModified() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->IsModified();
+}
+
+ULONG Outliner::GetTextHeight() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetTextHeight();
+}
+
+void Outliner::SetModifyHdl( const Link& rLink )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetModifyHdl( rLink );
+}
+
+Link Outliner::GetModifyHdl() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetModifyHdl();
+}
+
+void Outliner::SetNotifyHdl( const Link& rLink )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->aOutlinerNotifyHdl = rLink;
+
+ if ( rLink.IsSet() )
+ pEditEngine->SetNotifyHdl( LINK( this, Outliner, EditEngineNotifyHdl ) );
+ else
+ pEditEngine->SetNotifyHdl( Link() );
+
+}
+
+Link Outliner::GetNotifyHdl() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->aOutlinerNotifyHdl;
+}
+
+void Outliner::SetStatusEventHdl( const Link& rLink )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetStatusEventHdl( rLink );
+}
+
+Link Outliner::GetStatusEventHdl() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetStatusEventHdl();
+}
+
+void Outliner::SetDefTab( USHORT nTab )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetDefTab( nTab );
+}
+
+USHORT Outliner::GetDefTab() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetDefTab();
+}
+
+BOOL Outliner::IsFlatMode() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->IsFlatMode();
+}
+
+BOOL Outliner::UpdateFields()
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->UpdateFields();
+}
+
+void Outliner::RemoveFields( BOOL bKeepFieldText, TypeId aType )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->RemoveFields( bKeepFieldText, aType );
+}
+
+void Outliner::SetWordDelimiters( const String& rDelimiters )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetWordDelimiters( rDelimiters );
+}
+
+String Outliner::GetWordDelimiters() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetWordDelimiters();
+}
+
+String Outliner::GetWord( USHORT nPara, USHORT nIndex )
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetWord( nPara, nIndex );
+}
+
+void Outliner::Draw( OutputDevice* pOutDev, const Rectangle& rOutRect )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->Draw( pOutDev, rOutRect );
+}
+
+void Outliner::Draw( OutputDevice* pOutDev, const Rectangle& rOutRect, const Point& rStartDocPos )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->Draw( pOutDev, rOutRect, rStartDocPos );
+}
+
+
+void Outliner::Draw( OutputDevice* pOutDev, const Point& rStartPos, short nOrientation )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->Draw( pOutDev, rStartPos, nOrientation );
+}
+
+void Outliner::SetPaperSize( const Size& rSize )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetPaperSize( rSize );
+}
+
+const Size& Outliner::GetPaperSize() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetPaperSize();
+}
+
+void Outliner::SetPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon )
+{
+ DBG_CHKTHIS( Outliner, 0 );
+ pEditEngine->SetPolygon( rPolyPolygon );
+}
+
+void Outliner::SetPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon, const basegfx::B2DPolyPolygon* pLinePolyPolygon)
+{
+ DBG_CHKTHIS( Outliner, 0 );
+ pEditEngine->SetPolygon( rPolyPolygon, pLinePolyPolygon);
+}
+
+void Outliner::ClearPolygon()
+{
+ DBG_CHKTHIS( Outliner, 0 );
+ pEditEngine->ClearPolygon();
+}
+
+const PolyPolygon* Outliner::GetPolygon()
+{
+ DBG_CHKTHIS( Outliner, 0 );
+ return pEditEngine->GetPolygon();
+}
+
+const Size& Outliner::GetMinAutoPaperSize() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetMinAutoPaperSize();
+}
+
+void Outliner::SetMinAutoPaperSize( const Size& rSz )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetMinAutoPaperSize( rSz );
+}
+
+const Size& Outliner::GetMaxAutoPaperSize() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetMaxAutoPaperSize();
+}
+
+void Outliner::SetMaxAutoPaperSize( const Size& rSz )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetMaxAutoPaperSize( rSz );
+}
+
+BOOL Outliner::IsExpanded( Paragraph* pPara ) const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pParaList->HasVisibleChilds( pPara );
+}
+
+Paragraph* Outliner::GetParent( Paragraph* pParagraph ) const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pParaList->GetParent( pParagraph );
+}
+
+ULONG Outliner::GetChildCount( Paragraph* pParent ) const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pParaList->GetChildCount( pParent );
+}
+
+Size Outliner::CalcTextSize()
+{
+ DBG_CHKTHIS(Outliner,0);
+ return Size(pEditEngine->CalcTextWidth(),pEditEngine->GetTextHeight());
+}
+
+Point Outliner::GetDocPos( Paragraph* pPara )
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetDocPosTopLeft( (USHORT)pParaList->GetAbsPos( pPara ) );
+}
+
+void Outliner::SetStyleSheetPool( SfxStyleSheetPool* pSPool )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetStyleSheetPool( pSPool );
+}
+
+SfxStyleSheetPool* Outliner::GetStyleSheetPool()
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetStyleSheetPool();
+}
+
+SfxStyleSheet* Outliner::GetStyleSheet( ULONG nPara )
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetStyleSheet( (USHORT)nPara );
+}
+
+BOOL Outliner::IsInSelectionMode() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->IsInSelectionMode();
+}
+
+void Outliner::SetControlWord( ULONG nWord )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetControlWord( nWord );
+}
+
+ULONG Outliner::GetControlWord() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetControlWord();
+}
+
+void Outliner::SetAsianCompressionMode( USHORT n )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetAsianCompressionMode( n );
+}
+
+USHORT Outliner::GetAsianCompressionMode() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetAsianCompressionMode();
+}
+
+void Outliner::SetKernAsianPunctuation( BOOL b )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetKernAsianPunctuation( b );
+}
+
+BOOL Outliner::IsKernAsianPunctuation() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->IsKernAsianPunctuation();
+}
+
+void Outliner::SetAddExtLeading( BOOL bExtLeading )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetAddExtLeading( bExtLeading );
+}
+
+BOOL Outliner::IsAddExtLeading() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->IsAddExtLeading();
+}
+
+void Outliner::UndoActionStart( USHORT nId )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->UndoActionStart( nId );
+}
+
+void Outliner::UndoActionEnd( USHORT nId )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->UndoActionEnd( nId );
+}
+
+void Outliner::InsertUndo( EditUndo* pUndo )
+{
+#ifndef SVX_LIGHT
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->GetUndoManager().AddUndoAction( pUndo, FALSE );
+#endif
+}
+
+BOOL Outliner::IsInUndo()
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->IsInUndo();
+}
+
+ULONG Outliner::GetLineCount( ULONG nParagraph ) const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetLineCount( (USHORT)nParagraph );
+}
+
+USHORT Outliner::GetLineLen( ULONG nParagraph, USHORT nLine ) const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetLineLen( (USHORT)nParagraph, nLine );
+}
+
+ULONG Outliner::GetLineHeight( ULONG nParagraph, ULONG nLine )
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetLineHeight( (USHORT)nParagraph, (USHORT)nLine );
+}
+
+void Outliner::QuickRemoveCharAttribs( USHORT nPara, USHORT nWhich )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->QuickRemoveCharAttribs( nPara, nWhich );
+}
+
+EESpellState Outliner::HasSpellErrors()
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->HasSpellErrors();
+}
+
+sal_Bool Outliner::HasConvertibleTextPortion( LanguageType nLang )
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->HasConvertibleTextPortion( nLang );
+}
+
+BOOL Outliner::ConvertNextDocument()
+{
+ DBG_CHKTHIS(Outliner,0);
+ return FALSE;
+}
+
+void Outliner::SetDefaultLanguage( LanguageType eLang )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetDefaultLanguage( eLang );
+}
+
+LanguageType Outliner::GetDefaultLanguage() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetDefaultLanguage();
+}
+
+BOOL Outliner::HasOnlineSpellErrors() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->HasOnlineSpellErrors();
+}
+
+void Outliner::CompleteOnlineSpelling()
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->CompleteOnlineSpelling();
+}
+
+BOOL Outliner::HasText( const SvxSearchItem& rSearchItem )
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->HasText( rSearchItem );
+}
+
+void Outliner::SetEditTextObjectPool( SfxItemPool* pPool )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetEditTextObjectPool( pPool );
+}
+
+SfxItemPool* Outliner::GetEditTextObjectPool() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetEditTextObjectPool();
+}
+
+BOOL Outliner::SpellNextDocument()
+{
+ DBG_CHKTHIS(Outliner,0);
+ return FALSE;
+}
+
+
+void Outliner::SetSpeller( Reference< XSpellChecker1 > &xSpeller )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetSpeller( xSpeller );
+}
+Reference< XSpellChecker1 > Outliner::GetSpeller()
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetSpeller();
+}
+
+void Outliner::SetForbiddenCharsTable( vos::ORef<SvxForbiddenCharactersTable> xForbiddenChars )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetForbiddenCharsTable( xForbiddenChars );
+}
+
+vos::ORef<SvxForbiddenCharactersTable> Outliner::GetForbiddenCharsTable() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetForbiddenCharsTable();
+}
+
+
+Reference< XHyphenator > Outliner::GetHyphenator() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetHyphenator();
+}
+
+void Outliner::SetHyphenator( Reference< XHyphenator >& xHyph )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetHyphenator( xHyph );
+}
+
+OutputDevice* Outliner::GetRefDevice() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetRefDevice();
+}
+
+USHORT Outliner::GetFirstLineOffset( ULONG nParagraph )
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetFirstLineOffset( (USHORT)nParagraph );
+}
+
+ULONG Outliner::GetTextHeight( ULONG nParagraph ) const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetTextHeight((USHORT)nParagraph );
+}
+
+Point Outliner::GetDocPos( const Point& rPaperPos ) const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetDocPos( rPaperPos );
+}
+
+Point Outliner::GetDocPosTopLeft( ULONG nParagraph )
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetDocPosTopLeft( (USHORT)nParagraph );
+}
+
+BOOL Outliner::IsTextPos( const Point& rPaperPos, USHORT nBorder )
+{
+ return IsTextPos( rPaperPos, nBorder, NULL );
+}
+
+BOOL Outliner::IsTextPos( const Point& rPaperPos, USHORT nBorder, BOOL* pbBullet )
+{
+ DBG_CHKTHIS(Outliner,0);
+ if ( pbBullet)
+ *pbBullet = FALSE;
+ BOOL bTextPos = pEditEngine->IsTextPos( rPaperPos, nBorder );
+ if ( !bTextPos )
+ {
+ Point aDocPos = GetDocPos( rPaperPos );
+ USHORT nPara = pEditEngine->FindParagraph( aDocPos.Y() );
+ if ( ( nPara != EE_PARA_NOT_FOUND ) && ImplHasBullet( nPara ) )
+ {
+ Rectangle aBulArea = ImpCalcBulletArea( nPara, TRUE, TRUE );
+ if ( aBulArea.IsInside( rPaperPos ) )
+ {
+ bTextPos = TRUE;
+ if ( pbBullet)
+ *pbBullet = TRUE;
+ }
+ }
+ }
+
+ return bTextPos;
+}
+
+void Outliner::QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->QuickSetAttribs( rSet, rSel );
+}
+
+void Outliner::QuickInsertText( const XubString& rText, const ESelection& rSel )
+{
+ bFirstParaIsEmpty = FALSE;
+ pEditEngine->QuickInsertText( rText, rSel );
+}
+
+void Outliner::QuickDelete( const ESelection& rSel )
+{
+ bFirstParaIsEmpty = FALSE;
+ pEditEngine->QuickDelete( rSel );
+}
+
+void Outliner::QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel )
+{
+ DBG_CHKTHIS(Outliner,0);
+ bFirstParaIsEmpty = FALSE;
+ pEditEngine->QuickInsertField( rFld, rSel );
+}
+
+void Outliner::QuickInsertLineBreak( const ESelection& rSel )
+{
+ DBG_CHKTHIS(Outliner,0);
+ bFirstParaIsEmpty = FALSE;
+ pEditEngine->QuickInsertLineBreak( rSel );
+}
+
+void Outliner::QuickFormatDoc( BOOL bFull )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->QuickFormatDoc( bFull );
+}
+
+void Outliner::SetGlobalCharStretching( USHORT nX, USHORT nY )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetGlobalCharStretching( nX, nY );
+}
+
+void Outliner::GetGlobalCharStretching( USHORT& rX, USHORT& rY )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->GetGlobalCharStretching( rX, rY );
+}
+
+
+void Outliner::DoStretchChars( USHORT nX, USHORT nY )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->DoStretchChars( nX, nY );
+}
+
+void Outliner::EraseVirtualDevice()
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->EraseVirtualDevice();
+}
+
+void Outliner::SetBigTextObjectStart( USHORT nStartAtPortionCount )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetBigTextObjectStart( nStartAtPortionCount );
+}
+
+USHORT Outliner::GetBigTextObjectStart() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetBigTextObjectStart();
+}
+
+BOOL Outliner::ShouldCreateBigTextObject() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->ShouldCreateBigTextObject();
+}
+
+void Outliner::SetVertical( BOOL b )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetVertical( b );
+}
+
+BOOL Outliner::IsVertical() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->IsVertical();
+}
+
+void Outliner::SetFixedCellHeight( BOOL bUseFixedCellHeight )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetFixedCellHeight( bUseFixedCellHeight );
+}
+
+BOOL Outliner::IsFixedCellHeight() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->IsFixedCellHeight();
+}
+
+
+void Outliner::SetDefaultHorizontalTextDirection( EEHorizontalTextDirection eHTextDir )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetDefaultHorizontalTextDirection( eHTextDir );
+}
+
+EEHorizontalTextDirection Outliner::GetDefaultHorizontalTextDirection() const
+{
+ return pEditEngine->GetDefaultHorizontalTextDirection();
+}
+
+USHORT Outliner::GetScriptType( const ESelection& rSelection ) const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetScriptType( rSelection );
+}
+
+LanguageType Outliner::GetLanguage( USHORT nPara, USHORT nPos ) const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetLanguage( nPara, nPos );
+}
+
+void Outliner::RemoveAttribs( const ESelection& rSelection, sal_Bool bRemoveParaAttribs, sal_uInt16 nWhich )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->RemoveAttribs( rSelection, bRemoveParaAttribs, nWhich );
+}
+
+void Outliner::EnableAutoColor( BOOL b )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->EnableAutoColor( b );
+}
+
+BOOL Outliner::IsAutoColorEnabled() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->IsAutoColorEnabled();
+}
+
+void Outliner::ForceAutoColor( BOOL b )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->ForceAutoColor( b );
+}
+
+BOOL Outliner::IsForceAutoColor() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->IsForceAutoColor();
+}
+/*-- 13.10.2003 16:56:23---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void Outliner::StartSpelling(EditView& rEditView, sal_Bool bMultipleDoc)
+{
+ pEditEngine->StartSpelling(rEditView, bMultipleDoc);
+}
+/*-- 13.10.2003 16:56:23---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void Outliner::EndSpelling()
+{
+ pEditEngine->EndSpelling();
+}
+/*-- 13.10.2003 16:56:23---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+bool Outliner::SpellSentence(EditView& rEditView, ::svx::SpellPortions& rToFill, bool bIsGrammarChecking )
+{
+ return pEditEngine->SpellSentence(rEditView, rToFill, bIsGrammarChecking );
+}
+/*-- 08.09.2008 11:39:05---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void Outliner::PutSpellingToSentenceStart( EditView& rEditView )
+{
+ pEditEngine->PutSpellingToSentenceStart( rEditView );
+}
+/*-- 13.10.2003 16:56:25---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void Outliner::ApplyChangedSentence(EditView& rEditView, const ::svx::SpellPortions& rNewPortions, bool bIsGrammarChecking )
+{
+ pEditEngine->ApplyChangedSentence( rEditView, rNewPortions, bIsGrammarChecking );
+}
diff --git a/editeng/source/outliner/outliner.cxx b/editeng/source/outliner/outliner.cxx
new file mode 100644
index 0000000000..f464e6cb81
--- /dev/null
+++ b/editeng/source/outliner/outliner.cxx
@@ -0,0 +1,2184 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: outliner.cxx,v $
+ * $Revision: 1.75.20.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <svl/intitem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/eerdll.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/fhgtitem.hxx>
+
+#include <math.h>
+#include <svl/style.hxx>
+#include <vcl/wrkwin.hxx>
+#define _OUTLINER_CXX
+#include <editeng/outliner.hxx>
+#include <paralist.hxx>
+#include <editeng/outlobj.hxx>
+#include <outleeng.hxx>
+#include <outlundo.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <editeng/editobj.hxx>
+#include <svl/itemset.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/metric.hxx>
+#include <editeng/numitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/gdimtf.hxx>
+#include <vcl/metaact.hxx>
+#include <svtools/grfmgr.hxx>
+#include <editeng/svxfont.hxx>
+#include <editeng/brshitem.hxx>
+#include <svl/itempool.hxx>
+
+// #101498# calculate if it's RTL or not
+#include <unicode/ubidi.h>
+
+#define DEFAULT_SCALE 75
+
+static const USHORT nDefStyles = 3; // Sonderbehandlung fuer die ersten 3 Ebenen
+static const USHORT nDefBulletIndent = 800;
+static const USHORT nDefBulletWidth = 700;
+static const USHORT pDefBulletIndents[nDefStyles]= { 1400, 800, 800 };
+static const USHORT pDefBulletWidths[nDefStyles] = { 1000, 850, 700 };
+
+USHORT lcl_ImplGetDefBulletWidth( sal_Int16 nDepth )
+{
+ return ( nDepth < nDefStyles ) ? pDefBulletWidths[nDepth] : nDefBulletWidth;
+}
+
+USHORT lcl_ImplGetDefBulletIndent( sal_Int16 nDepth )
+{
+ USHORT nI = 0;
+
+ if( nDepth >= 0 )
+ {
+ for ( sal_Int16 n = 0; n <= nDepth; n++ )
+ nI = nI +
+ ( ( n < nDefStyles ) ? pDefBulletIndents[n] : nDefBulletIndent );
+ }
+ return nI;
+}
+
+
+// ----------------------------------------------------------------------
+// Outliner
+// ----------------------------------------------------------------------
+DBG_NAME(Outliner);
+
+void Outliner::ImplCheckDepth( sal_Int16& rnDepth ) const
+{
+ if( rnDepth < nMinDepth )
+ rnDepth = nMinDepth;
+ else if( rnDepth > nMaxDepth )
+ rnDepth = nMaxDepth;
+}
+
+Paragraph* Outliner::Insert(const XubString& rText, ULONG nAbsPos, sal_Int16 nDepth)
+{
+ DBG_CHKTHIS(Outliner,0);
+ DBG_ASSERT(pParaList->GetParagraphCount(),"Insert:No Paras");
+
+ Paragraph* pPara;
+
+ ImplCheckDepth( nDepth );
+
+ ULONG nParagraphCount = pParaList->GetParagraphCount();
+ if( nAbsPos > nParagraphCount )
+ nAbsPos = nParagraphCount;
+
+ if( bFirstParaIsEmpty )
+ {
+ pPara = pParaList->GetParagraph( 0 );
+ if( pPara->GetDepth() != nDepth )
+ {
+ nDepthChangedHdlPrevDepth = pPara->GetDepth();
+ mnDepthChangeHdlPrevFlags = pPara->nFlags;
+ pPara->SetDepth( nDepth );
+ pHdlParagraph = pPara;
+ DepthChangedHdl();
+ }
+ pPara->nFlags |= PARAFLAG_HOLDDEPTH;
+ SetText( rText, pPara );
+ }
+ else
+ {
+ BOOL bUpdate = pEditEngine->GetUpdateMode();
+ pEditEngine->SetUpdateMode( FALSE );
+ ImplBlockInsertionCallbacks( TRUE );
+ pPara = new Paragraph( nDepth );
+ pParaList->Insert( pPara, nAbsPos );
+ pEditEngine->InsertParagraph( (USHORT)nAbsPos, String() );
+ DBG_ASSERT(pPara==pParaList->GetParagraph(nAbsPos),"Insert:Failed");
+ ImplInitDepth( (USHORT)nAbsPos, nDepth, FALSE );
+ pHdlParagraph = pPara;
+ ParagraphInsertedHdl();
+ pPara->nFlags |= PARAFLAG_HOLDDEPTH;
+ SetText( rText, pPara );
+ ImplBlockInsertionCallbacks( FALSE );
+ pEditEngine->SetUpdateMode( bUpdate );
+ }
+ bFirstParaIsEmpty = FALSE;
+ DBG_ASSERT(pEditEngine->GetParagraphCount()==pParaList->GetParagraphCount(),"SetText failed");
+ return pPara;
+}
+
+
+void Outliner::ParagraphInserted( USHORT nPara )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ if ( bBlockInsCallback )
+ return;
+
+ if( bPasting || pEditEngine->IsInUndo() )
+ {
+ Paragraph* pPara = new Paragraph( -1 );
+ pParaList->Insert( pPara, nPara );
+ if( pEditEngine->IsInUndo() )
+ {
+ pPara->nFlags = PARAFLAG_SETBULLETTEXT;
+ pPara->bVisible = TRUE;
+ const SfxInt16Item& rLevel = (const SfxInt16Item&) pEditEngine->GetParaAttrib( nPara, EE_PARA_OUTLLEVEL );
+ pPara->SetDepth( rLevel.GetValue() );
+ }
+ }
+ else
+ {
+ sal_Int16 nDepth = -1;
+ Paragraph* pParaBefore = pParaList->GetParagraph( nPara-1 );
+ if ( pParaBefore )
+ nDepth = pParaBefore->GetDepth();
+
+ Paragraph* pPara = new Paragraph( nDepth );
+ pParaList->Insert( pPara, nPara );
+
+ if( !pEditEngine->IsInUndo() )
+ {
+ ImplCalcBulletText( nPara, TRUE, FALSE );
+ pHdlParagraph = pPara;
+ ParagraphInsertedHdl();
+ }
+ }
+}
+
+void Outliner::ParagraphDeleted( USHORT nPara )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ if ( bBlockInsCallback || ( nPara == EE_PARA_ALL ) )
+ return;
+
+ Paragraph* pPara = pParaList->GetParagraph( nPara );
+ if (!pPara)
+ return;
+
+ sal_Int16 nDepth = pPara->GetDepth();
+
+ if( !pEditEngine->IsInUndo() )
+ {
+ pHdlParagraph = pPara;
+ ParagraphRemovingHdl();
+ }
+
+ pParaList->Remove( nPara );
+ delete pPara;
+
+ if( !pEditEngine->IsInUndo() && !bPasting )
+ {
+ pPara = pParaList->GetParagraph( nPara );
+ if ( pPara && ( pPara->GetDepth() > nDepth ) )
+ {
+ ImplCalcBulletText( nPara, TRUE, FALSE );
+ // naechsten auf gleicher Ebene suchen...
+ while ( pPara && pPara->GetDepth() > nDepth )
+ pPara = pParaList->GetParagraph( ++nPara );
+ }
+
+ if ( pPara && ( pPara->GetDepth() == nDepth ) )
+ ImplCalcBulletText( nPara, TRUE, FALSE );
+ }
+}
+
+void Outliner::Init( USHORT nMode )
+{
+ nOutlinerMode = nMode;
+
+ Clear();
+
+ ULONG nCtrl = pEditEngine->GetControlWord();
+ nCtrl &= ~(EE_CNTRL_OUTLINER|EE_CNTRL_OUTLINER2);
+
+ SetMaxDepth( 9 );
+
+ switch ( ImplGetOutlinerMode() )
+ {
+ case OUTLINERMODE_TEXTOBJECT:
+ case OUTLINERMODE_TITLEOBJECT:
+ break;
+
+ case OUTLINERMODE_OUTLINEOBJECT:
+ nCtrl |= EE_CNTRL_OUTLINER2;
+ break;
+ case OUTLINERMODE_OUTLINEVIEW:
+ nCtrl |= EE_CNTRL_OUTLINER;
+ break;
+
+ default: DBG_ERROR( "Outliner::Init - Invalid Mode!" );
+ }
+
+ pEditEngine->SetControlWord( nCtrl );
+
+ ImplInitDepth( 0, GetMinDepth(), FALSE );
+
+ GetUndoManager().Clear();
+}
+
+void Outliner::SetMaxDepth( sal_Int16 nDepth, BOOL bCheckParagraphs )
+{
+ if( nMaxDepth != nDepth )
+ {
+ nMaxDepth = Min( nDepth, (sal_Int16)(SVX_MAX_NUM-1) );
+
+ if( bCheckParagraphs )
+ {
+ USHORT nParagraphs = (USHORT)pParaList->GetParagraphCount();
+ for ( USHORT nPara = 0; nPara < nParagraphs; nPara++ )
+ {
+ Paragraph* pPara = pParaList->GetParagraph( nPara );
+ if( pPara && pPara->GetDepth() > nMaxDepth )
+ {
+ SetDepth( pPara, nMaxDepth );
+ }
+ }
+ }
+ }
+}
+
+sal_Int16 Outliner::GetDepth( ULONG nPara ) const
+{
+ Paragraph* pPara = pParaList->GetParagraph( nPara );
+ DBG_ASSERT( pPara, "Outliner::GetDepth - Paragraph not found!" );
+ return pPara ? pPara->GetDepth() : -1;
+}
+
+void Outliner::SetDepth( Paragraph* pPara, sal_Int16 nNewDepth )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ ImplCheckDepth( nNewDepth );
+
+ if ( nNewDepth != pPara->GetDepth() )
+ {
+ nDepthChangedHdlPrevDepth = pPara->GetDepth();
+ mnDepthChangeHdlPrevFlags = pPara->nFlags;
+ pHdlParagraph = pPara;
+
+ USHORT nPara = (USHORT)GetAbsPos( pPara );
+ ImplInitDepth( nPara, nNewDepth, TRUE );
+ ImplCalcBulletText( nPara, FALSE, FALSE );
+
+ if ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT )
+ ImplSetLevelDependendStyleSheet( nPara );
+
+ DepthChangedHdl();
+ }
+}
+
+sal_Int16 Outliner::GetNumberingStartValue( sal_uInt16 nPara )
+{
+ Paragraph* pPara = pParaList->GetParagraph( nPara );
+ DBG_ASSERT( pPara, "Outliner::GetNumberingStartValue - Paragraph not found!" );
+ return pPara ? pPara->GetNumberingStartValue() : -1;
+}
+
+void Outliner::SetNumberingStartValue( sal_uInt16 nPara, sal_Int16 nNumberingStartValue )
+{
+ Paragraph* pPara = pParaList->GetParagraph( nPara );
+ DBG_ASSERT( pPara, "Outliner::GetNumberingStartValue - Paragraph not found!" );
+ if( pPara && pPara->GetNumberingStartValue() != nNumberingStartValue )
+ {
+ if( IsUndoEnabled() && !IsInUndo() )
+ InsertUndo( new OutlinerUndoChangeParaNumberingRestart( this, nPara,
+ pPara->GetNumberingStartValue(), nNumberingStartValue,
+ pPara->IsParaIsNumberingRestart(), pPara->IsParaIsNumberingRestart() ) );
+
+ pPara->SetNumberingStartValue( nNumberingStartValue );
+ // --> OD 2009-03-10 #i100014#
+ // It is not a good idea to substract 1 from a count and cast the result
+ // to USHORT without check, if the count is 0.
+ ImplCheckParagraphs( nPara, (USHORT) (pParaList->GetParagraphCount()) );
+ // <--
+ pEditEngine->SetModified();
+ }
+}
+
+sal_Bool Outliner::IsParaIsNumberingRestart( sal_uInt16 nPara )
+{
+ Paragraph* pPara = pParaList->GetParagraph( nPara );
+ DBG_ASSERT( pPara, "Outliner::IsParaIsNumberingRestart - Paragraph not found!" );
+ return pPara ? pPara->IsParaIsNumberingRestart() : sal_False;
+}
+
+void Outliner::SetParaIsNumberingRestart( sal_uInt16 nPara, sal_Bool bParaIsNumberingRestart )
+{
+ Paragraph* pPara = pParaList->GetParagraph( nPara );
+ DBG_ASSERT( pPara, "Outliner::SetParaIsNumberingRestart - Paragraph not found!" );
+ if( pPara && (pPara->IsParaIsNumberingRestart() != bParaIsNumberingRestart) )
+ {
+ if( IsUndoEnabled() && !IsInUndo() )
+ InsertUndo( new OutlinerUndoChangeParaNumberingRestart( this, nPara,
+ pPara->GetNumberingStartValue(), pPara->GetNumberingStartValue(),
+ pPara->IsParaIsNumberingRestart(), bParaIsNumberingRestart ) );
+
+ pPara->SetParaIsNumberingRestart( bParaIsNumberingRestart );
+ // --> OD 2009-03-10 #i100014#
+ // It is not a good idea to substract 1 from a count and cast the result
+ // to USHORT without check, if the count is 0.
+ ImplCheckParagraphs( nPara, (USHORT) (pParaList->GetParagraphCount()) );
+ // <--
+ pEditEngine->SetModified();
+ }
+}
+
+OutlinerParaObject* Outliner::CreateParaObject( USHORT nStartPara, USHORT nCount ) const
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ if ( sal::static_int_cast< ULONG >( nStartPara + nCount ) >
+ pParaList->GetParagraphCount() )
+ nCount = sal::static_int_cast< USHORT >(
+ pParaList->GetParagraphCount() - nStartPara );
+
+ // When a new OutlinerParaObject is created because a paragraph is just beeing deleted,
+ // it can happen that the ParaList is not updated yet...
+ if ( ( nStartPara + nCount ) > pEditEngine->GetParagraphCount() )
+ nCount = pEditEngine->GetParagraphCount() - nStartPara;
+
+ if( !nCount )
+ return NULL;
+
+ EditTextObject* pText = pEditEngine->CreateTextObject( nStartPara, nCount );
+ const bool bIsEditDoc(OUTLINERMODE_TEXTOBJECT == ImplGetOutlinerMode());
+ ParagraphDataVector aParagraphDataVector(nCount);
+ const sal_uInt16 nLastPara(nStartPara + nCount - 1);
+
+ for(sal_uInt16 nPara(nStartPara); nPara <= nLastPara; nPara++)
+ {
+ aParagraphDataVector[nPara-nStartPara] = *GetParagraph(nPara);
+ }
+
+ OutlinerParaObject* pPObj = new OutlinerParaObject(*pText, aParagraphDataVector, bIsEditDoc);
+ pPObj->SetOutlinerMode(GetMode());
+ delete pText;
+
+ return pPObj;
+}
+
+void Outliner::SetText( const XubString& rText, Paragraph* pPara )
+{
+ DBG_CHKTHIS(Outliner,0);
+ DBG_ASSERT(pPara,"SetText:No Para");
+
+ BOOL bUpdate = pEditEngine->GetUpdateMode();
+ pEditEngine->SetUpdateMode( FALSE );
+ ImplBlockInsertionCallbacks( TRUE );
+
+ USHORT nPara = (USHORT)pParaList->GetAbsPos( pPara );
+
+ if( !rText.Len() )
+ {
+ pEditEngine->SetText( nPara, rText );
+ ImplInitDepth( nPara, pPara->GetDepth(), FALSE );
+ }
+ else
+ {
+ XubString aText( rText );
+ aText.ConvertLineEnd( LINEEND_LF );
+
+ if( aText.GetChar( aText.Len()-1 ) == '\x0A' )
+ aText.Erase( aText.Len()-1, 1 ); // letzten Umbruch loeschen
+
+ USHORT nCount = aText.GetTokenCount( '\x0A' );
+ USHORT nPos = 0;
+ USHORT nInsPos = nPara+1;
+ while( nCount > nPos )
+ {
+ XubString aStr = aText.GetToken( nPos, '\x0A' );
+
+ sal_Int16 nCurDepth;
+ if( nPos )
+ {
+ pPara = new Paragraph( -1 );
+ nCurDepth = -1;
+ }
+ else
+ nCurDepth = pPara->GetDepth();
+
+ // Im Outliner-Modus die Tabulatoren filtern und die
+ // Einrueckung ueber ein LRSpaceItem einstellen
+ // Im EditEngine-Modus ueber Maltes Tabulatoren einruecken
+ if( ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT ) ||
+ ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEVIEW ) )
+ {
+ // Tabs raus
+ USHORT nTabs = 0;
+ while ( ( nTabs < aStr.Len() ) && ( aStr.GetChar( nTabs ) == '\t' ) )
+ nTabs++;
+ if ( nTabs )
+ aStr.Erase( 0, nTabs );
+
+ // Tiefe beibehalten ? (siehe Outliner::Insert)
+ if( !(pPara->nFlags & PARAFLAG_HOLDDEPTH) )
+ {
+ nCurDepth = nTabs-1;
+ ImplCheckDepth( nCurDepth );
+ pPara->SetDepth( nCurDepth );
+ pPara->nFlags &= (~PARAFLAG_HOLDDEPTH);
+ }
+ }
+ if( nPos ) // nicht mit dem ersten Absatz
+ {
+ pParaList->Insert( pPara, nInsPos );
+ pEditEngine->InsertParagraph( nInsPos, aStr );
+ pHdlParagraph = pPara;
+ ParagraphInsertedHdl();
+ }
+ else
+ {
+ nInsPos--;
+ pEditEngine->SetText( nInsPos, aStr );
+ }
+ ImplInitDepth( nInsPos, nCurDepth, FALSE );
+ nInsPos++;
+ nPos++;
+ }
+ }
+
+ DBG_ASSERT(pParaList->GetParagraphCount()==pEditEngine->GetParagraphCount(),"SetText failed!");
+ bFirstParaIsEmpty = FALSE;
+ ImplBlockInsertionCallbacks( FALSE );
+ pEditEngine->SetUpdateMode( bUpdate );
+}
+
+// pView == 0 -> Tabulatoren nicht beachten
+
+bool Outliner::ImpConvertEdtToOut( sal_uInt32 nPara,EditView* pView)
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ bool bConverted = false;
+ USHORT nTabs = 0;
+ ESelection aDelSel;
+
+// const SfxItemSet& rAttrs = pEditEngine->GetParaAttribs( (sal_uInt16)nPara );
+// bool bAlreadyOutliner = rAttrs.GetItemState( EE_PARA_OUTLLRSPACE ) == SFX_ITEM_ON ? true : false;
+
+ XubString aName;
+ XubString aHeading_US( RTL_CONSTASCII_USTRINGPARAM( "heading" ) );
+ XubString aNumber_US( RTL_CONSTASCII_USTRINGPARAM( "Numbering" ) );
+
+ XubString aStr( pEditEngine->GetText( (USHORT)nPara ) );
+ xub_Unicode* pPtr = (xub_Unicode*)aStr.GetBuffer();
+
+ USHORT nHeadingNumberStart = 0;
+ USHORT nNumberingNumberStart = 0;
+ SfxStyleSheet* pStyle= pEditEngine->GetStyleSheet( (USHORT)nPara );
+ if( pStyle )
+ {
+ aName = pStyle->GetName();
+ USHORT nSearch;
+ if ( ( nSearch = aName.Search( aHeading_US ) ) != STRING_NOTFOUND )
+ nHeadingNumberStart = nSearch + aHeading_US.Len();
+ else if ( ( nSearch = aName.Search( aNumber_US ) ) != STRING_NOTFOUND )
+ nNumberingNumberStart = nSearch + aNumber_US.Len();
+ }
+
+ if ( nHeadingNumberStart || nNumberingNumberStart )
+ {
+ // PowerPoint-Import ?
+ if( nHeadingNumberStart && ( aStr.Len() >= 2 ) &&
+ ( pPtr[0] != '\t' ) && ( pPtr[1] == '\t' ) )
+ {
+ // Bullet & Tab raus
+ aDelSel = ESelection( (USHORT)nPara, 0, (USHORT)nPara, 2 );
+ }
+
+ USHORT nPos = nHeadingNumberStart ? nHeadingNumberStart : nNumberingNumberStart;
+ String aLevel = aName.Copy( nPos );
+ aLevel.EraseLeadingChars( ' ' );
+ nTabs = sal::static_int_cast< USHORT >(aLevel.ToInt32());
+ if( nTabs )
+ nTabs--; // ebene 0 = "heading 1"
+ bConverted = TRUE;
+ }
+ else
+ {
+ // Fuehrende Tabulatoren filtern
+ while( *pPtr == '\t' )
+ {
+ pPtr++;
+ nTabs++;
+ }
+ // Tabulatoren aus dem Text entfernen
+ if( nTabs )
+ aDelSel = ESelection( (USHORT)nPara, 0, (USHORT)nPara, nTabs );
+ }
+
+ if ( aDelSel.HasRange() )
+ {
+ if ( pView )
+ {
+ pView->SetSelection( aDelSel );
+ pView->DeleteSelected();
+ }
+ else
+ pEditEngine->QuickDelete( aDelSel );
+ }
+
+ const SfxInt16Item& rLevel = (const SfxInt16Item&) pEditEngine->GetParaAttrib( sal::static_int_cast< sal_uInt16 >(nPara), EE_PARA_OUTLLEVEL );
+ sal_Int16 nOutlLevel = rLevel.GetValue();
+
+ ImplCheckDepth( nOutlLevel );
+ ImplInitDepth( sal::static_int_cast< sal_uInt16 >(nPara), nOutlLevel, FALSE );
+
+ return bConverted;
+}
+
+void Outliner::SetText( const OutlinerParaObject& rPObj )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ BOOL bUpdate = pEditEngine->GetUpdateMode();
+ pEditEngine->SetUpdateMode( FALSE );
+
+ BOOL bUndo = pEditEngine->IsUndoEnabled();
+ EnableUndo( FALSE );
+
+ Init( rPObj.GetOutlinerMode() );
+
+ ImplBlockInsertionCallbacks( TRUE );
+ pEditEngine->SetText(rPObj.GetTextObject());
+ if( rPObj.Count() != pEditEngine->GetParagraphCount() )
+ {
+ int nop=0;nop++;
+ }
+
+ bFirstParaIsEmpty = FALSE;
+
+ pParaList->Clear( TRUE );
+ for( USHORT nCurPara = 0; nCurPara < rPObj.Count(); nCurPara++ )
+ {
+ Paragraph* pPara = new Paragraph( rPObj.GetParagraphData(nCurPara));
+ ImplCheckDepth( pPara->nDepth );
+
+ pParaList->Insert( pPara, LIST_APPEND );
+ ImplCheckNumBulletItem( nCurPara );
+ }
+
+ // --> OD 2009-03-10 #i100014#
+ // It is not a good idea to substract 1 from a count and cast the result
+ // to USHORT without check, if the count is 0.
+ ImplCheckParagraphs( 0, (USHORT) (pParaList->GetParagraphCount()) );
+ // <--
+
+ EnableUndo( bUndo );
+ ImplBlockInsertionCallbacks( FALSE );
+ pEditEngine->SetUpdateMode( bUpdate );
+
+ DBG_ASSERT( pParaList->GetParagraphCount()==rPObj.Count(),"SetText failed");
+ DBG_ASSERT( pEditEngine->GetParagraphCount()==rPObj.Count(),"SetText failed");
+}
+
+void Outliner::AddText( const OutlinerParaObject& rPObj )
+{
+ DBG_CHKTHIS(Outliner,0);
+ Paragraph* pPara;
+
+ BOOL bUpdate = pEditEngine->GetUpdateMode();
+ pEditEngine->SetUpdateMode( FALSE );
+
+ ImplBlockInsertionCallbacks( TRUE );
+ ULONG nPara;
+ if( bFirstParaIsEmpty )
+ {
+ pParaList->Clear( TRUE );
+ pEditEngine->SetText(rPObj.GetTextObject());
+ nPara = 0;
+ }
+ else
+ {
+ nPara = pParaList->GetParagraphCount();
+ pEditEngine->InsertParagraph( EE_PARA_APPEND, rPObj.GetTextObject() );
+ }
+ bFirstParaIsEmpty = FALSE;
+
+ for( USHORT n = 0; n < rPObj.Count(); n++ )
+ {
+ pPara = new Paragraph( rPObj.GetParagraphData(n) );
+ pParaList->Insert( pPara, LIST_APPEND );
+ USHORT nP = sal::static_int_cast< USHORT >(nPara+n);
+ DBG_ASSERT(pParaList->GetAbsPos(pPara)==nP,"AddText:Out of sync");
+ ImplInitDepth( nP, pPara->GetDepth(), FALSE );
+ }
+ DBG_ASSERT( pEditEngine->GetParagraphCount()==pParaList->GetParagraphCount(), "SetText: OutOfSync" );
+
+ // --> OD 2009-03-10 #i100014#
+ // It is not a good idea to substract 1 from a count and cast the result
+ // to USHORT without check, if the count is 0.
+ ImplCheckParagraphs( (USHORT)nPara, (USHORT) (pParaList->GetParagraphCount()) );
+ // <--
+
+ ImplBlockInsertionCallbacks( FALSE );
+ pEditEngine->SetUpdateMode( bUpdate );
+}
+
+void __EXPORT Outliner::FieldClicked( const SvxFieldItem& rField, USHORT nPara, USHORT nPos )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ if ( aFieldClickedHdl.IsSet() )
+ {
+ EditFieldInfo aFldInfo( this, rField, nPara, nPos );
+ aFldInfo.SetSimpleClick( TRUE );
+ aFieldClickedHdl.Call( &aFldInfo );
+ }
+}
+
+
+void __EXPORT Outliner::FieldSelected( const SvxFieldItem& rField, USHORT nPara, USHORT nPos )
+{
+ DBG_CHKTHIS(Outliner,0);
+ if ( !aFieldClickedHdl.IsSet() )
+ return;
+
+ EditFieldInfo aFldInfo( this, rField, nPara, nPos );
+ aFldInfo.SetSimpleClick( FALSE );
+ aFieldClickedHdl.Call( &aFldInfo );
+}
+
+
+XubString __EXPORT Outliner::CalcFieldValue( const SvxFieldItem& rField, USHORT nPara, USHORT nPos, Color*& rpTxtColor, Color*& rpFldColor )
+{
+ DBG_CHKTHIS(Outliner,0);
+ if ( !aCalcFieldValueHdl.IsSet() )
+ return String( ' ' );
+
+ EditFieldInfo aFldInfo( this, rField, nPara, nPos );
+ // Die FldColor ist mit COL_LIGHTGRAY voreingestellt.
+ if ( rpFldColor )
+ aFldInfo.SetFldColor( *rpFldColor );
+
+ aCalcFieldValueHdl.Call( &aFldInfo );
+ if ( aFldInfo.GetTxtColor() )
+ {
+ delete rpTxtColor;
+ rpTxtColor = new Color( *aFldInfo.GetTxtColor() );
+ }
+
+ delete rpFldColor;
+ rpFldColor = aFldInfo.GetFldColor() ? new Color( *aFldInfo.GetFldColor() ) : 0;
+
+ return aFldInfo.GetRepresentation();
+}
+
+void Outliner::SetStyleSheet( ULONG nPara, SfxStyleSheet* pStyle )
+{
+ DBG_CHKTHIS(Outliner,0);
+ Paragraph* pPara = pParaList->GetParagraph( nPara );
+ if (pPara)
+ {
+ pEditEngine->SetStyleSheet( (USHORT)nPara, pStyle );
+ pPara->nFlags |= PARAFLAG_SETBULLETTEXT;
+ ImplCheckNumBulletItem( (USHORT) nPara );
+ }
+}
+
+void Outliner::SetVisible( Paragraph* pPara, BOOL bVisible )
+{
+ DBG_CHKTHIS(Outliner,0);
+ DBG_ASSERT( pPara, "SetVisible: pPara = NULL" );
+
+ if (pPara)
+ {
+ pPara->bVisible = bVisible;
+ ULONG nPara = pParaList->GetAbsPos( pPara );
+ pEditEngine->ShowParagraph( (USHORT)nPara, bVisible );
+ }
+}
+
+void Outliner::ImplCheckNumBulletItem( USHORT nPara )
+{
+ Paragraph* pPara = pParaList->GetParagraph( nPara );
+ if (pPara)
+ pPara->aBulSize.Width() = -1;
+}
+
+void Outliner::ImplSetLevelDependendStyleSheet( USHORT nPara, SfxStyleSheet* pLevelStyle )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ DBG_ASSERT( ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT ) || ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEVIEW ), "SetLevelDependendStyleSheet: Wrong Mode!" );
+
+ SfxStyleSheet* pStyle = pLevelStyle;
+ if ( !pStyle )
+ pStyle = GetStyleSheet( nPara );
+
+ if ( pStyle )
+ {
+ sal_Int16 nDepth = GetDepth( nPara );
+ if( nDepth < 0 )
+ nDepth = 0;
+
+ String aNewStyleSheetName( pStyle->GetName() );
+ aNewStyleSheetName.Erase( aNewStyleSheetName.Len()-1, 1 );
+ aNewStyleSheetName += String::CreateFromInt32( nDepth+1 );
+ SfxStyleSheet* pNewStyle = (SfxStyleSheet*)GetStyleSheetPool()->Find( aNewStyleSheetName, pStyle->GetFamily() );
+ DBG_ASSERT( pNewStyle, "AutoStyleSheetName - Style not found!" );
+ if ( pNewStyle && ( pNewStyle != GetStyleSheet( nPara ) ) )
+ {
+ SfxItemSet aOldAttrs( GetParaAttribs( nPara ) );
+ SetStyleSheet( nPara, pNewStyle );
+ if ( aOldAttrs.GetItemState( EE_PARA_NUMBULLET ) == SFX_ITEM_ON )
+ {
+ SfxItemSet aAttrs( GetParaAttribs( nPara ) );
+ aAttrs.Put( aOldAttrs.Get( EE_PARA_NUMBULLET ) );
+ SetParaAttribs( nPara, aAttrs );
+ }
+ }
+ }
+}
+
+void Outliner::ImplInitDepth( USHORT nPara, sal_Int16 nDepth, BOOL bCreateUndo, BOOL bUndoAction )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ DBG_ASSERT( ( nDepth >= nMinDepth ) && ( nDepth <= nMaxDepth ), "ImplInitDepth - Depth is invalid!" );
+
+ Paragraph* pPara = pParaList->GetParagraph( nPara );
+ if (!pPara)
+ return;
+ sal_Int16 nOldDepth = pPara->GetDepth();
+ pPara->SetDepth( nDepth );
+
+ // Bei IsInUndo brauchen Attribute und Style nicht eingestellt werden,
+ // dort werden die alten Werte durch die EditEngine restauriert.
+
+ if( !IsInUndo() )
+ {
+ BOOL bUpdate = pEditEngine->GetUpdateMode();
+ pEditEngine->SetUpdateMode( FALSE );
+
+ BOOL bUndo = bCreateUndo && IsUndoEnabled();
+ if ( bUndo && bUndoAction )
+ UndoActionStart( OLUNDO_DEPTH );
+
+ SfxItemSet aAttrs( pEditEngine->GetParaAttribs( nPara ) );
+ aAttrs.Put( SfxInt16Item( EE_PARA_OUTLLEVEL, nDepth ) );
+ pEditEngine->SetParaAttribs( nPara, aAttrs );
+ ImplCheckNumBulletItem( nPara );
+ ImplCalcBulletText( nPara, FALSE, FALSE );
+
+ if ( bUndo )
+ {
+ InsertUndo( new OutlinerUndoChangeDepth( this, nPara, nOldDepth, nDepth ) );
+ if ( bUndoAction )
+ UndoActionEnd( OLUNDO_DEPTH );
+ }
+
+ pEditEngine->SetUpdateMode( bUpdate );
+ }
+}
+
+void Outliner::SetParaAttribs( USHORT nPara, const SfxItemSet& rSet )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ pEditEngine->SetParaAttribs( nPara, rSet );
+}
+
+BOOL Outliner::Expand( Paragraph* pPara )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ if ( pParaList->HasHiddenChilds( pPara ) )
+ {
+ OLUndoExpand* pUndo = 0;
+ BOOL bUndo = IsUndoEnabled() && !IsInUndo();
+ if( bUndo )
+ {
+ UndoActionStart( OLUNDO_EXPAND );
+ pUndo = new OLUndoExpand( this, OLUNDO_EXPAND );
+ pUndo->pParas = 0;
+ pUndo->nCount = (USHORT)pParaList->GetAbsPos( pPara );
+ }
+ pHdlParagraph = pPara;
+ bIsExpanding = TRUE;
+ pParaList->Expand( pPara );
+ ExpandHdl();
+ InvalidateBullet( pPara, pParaList->GetAbsPos(pPara) );
+ if( bUndo )
+ {
+ InsertUndo( pUndo );
+ UndoActionEnd( OLUNDO_EXPAND );
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+BOOL Outliner::Collapse( Paragraph* pPara )
+{
+ DBG_CHKTHIS(Outliner,0);
+ if ( pParaList->HasVisibleChilds( pPara ) ) // expandiert
+ {
+ OLUndoExpand* pUndo = 0;
+ BOOL bUndo = FALSE;
+
+ if( !IsInUndo() && IsUndoEnabled() )
+ bUndo = TRUE;
+ if( bUndo )
+ {
+ UndoActionStart( OLUNDO_COLLAPSE );
+ pUndo = new OLUndoExpand( this, OLUNDO_COLLAPSE );
+ pUndo->pParas = 0;
+ pUndo->nCount = (USHORT)pParaList->GetAbsPos( pPara );
+ }
+
+ pHdlParagraph = pPara;
+ bIsExpanding = FALSE;
+ pParaList->Collapse( pPara );
+ ExpandHdl();
+ InvalidateBullet( pPara, pParaList->GetAbsPos(pPara) );
+ if( bUndo )
+ {
+ InsertUndo( pUndo );
+ UndoActionEnd( OLUNDO_COLLAPSE );
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+Font Outliner::ImpCalcBulletFont( USHORT nPara ) const
+{
+ const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
+ DBG_ASSERT( pFmt && ( pFmt->GetNumberingType() != SVX_NUM_BITMAP ) && ( pFmt->GetNumberingType() != SVX_NUM_NUMBER_NONE ), "ImpCalcBulletFont: Missing or BitmapBullet!" );
+
+ Font aStdFont; //#107508#
+ if ( !pEditEngine->IsFlatMode() )
+ {
+ ESelection aSel( nPara, 0, nPara, 0 );
+ aStdFont = EditEngine::CreateFontFromItemSet( pEditEngine->GetAttribs( aSel ), GetScriptType( aSel ) );
+ }
+ else
+ {
+ aStdFont = pEditEngine->GetStandardFont( nPara );
+ }
+
+ Font aBulletFont;
+ if ( pFmt->GetNumberingType() == SVX_NUM_CHAR_SPECIAL )
+ {
+ aBulletFont = *pFmt->GetBulletFont();
+ }
+ else
+ {
+ aBulletFont = aStdFont;
+ aBulletFont.SetUnderline( UNDERLINE_NONE );
+ aBulletFont.SetOverline( UNDERLINE_NONE );
+ aBulletFont.SetStrikeout( STRIKEOUT_NONE );
+ aBulletFont.SetEmphasisMark( EMPHASISMARK_NONE );
+ aBulletFont.SetRelief( RELIEF_NONE );
+ }
+
+ // #107508# Use original scale...
+ USHORT nScale = /* pEditEngine->IsFlatMode() ? DEFAULT_SCALE : */ pFmt->GetBulletRelSize();
+ ULONG nScaledLineHeight = aStdFont.GetSize().Height();
+ nScaledLineHeight *= nScale*10;
+ nScaledLineHeight /= 1000;
+
+ aBulletFont.SetAlign( ALIGN_BOTTOM );
+ aBulletFont.SetSize( Size( 0, nScaledLineHeight ) );
+ BOOL bVertical = IsVertical();
+ aBulletFont.SetVertical( bVertical );
+ aBulletFont.SetOrientation( bVertical ? 2700 : 0 );
+
+ Color aColor( COL_AUTO );
+ if( !pEditEngine->IsFlatMode() && !( pEditEngine->GetControlWord() & EE_CNTRL_NOCOLORS ) )
+ {
+ aColor = pFmt->GetBulletColor();
+ }
+
+ if ( ( aColor == COL_AUTO ) || ( IsForceAutoColor() ) )
+ aColor = pEditEngine->GetAutoColor();
+
+ aBulletFont.SetColor( aColor );
+ return aBulletFont;
+}
+
+void Outliner::PaintBullet( USHORT nPara, const Point& rStartPos,
+ const Point& rOrigin, short nOrientation, OutputDevice* pOutDev )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ bool bDrawBullet = false;
+ if (pEditEngine)
+ {
+ const SfxBoolItem& rBulletState = (const SfxBoolItem&) pEditEngine->GetParaAttrib( nPara, EE_PARA_BULLETSTATE );
+ bDrawBullet = rBulletState.GetValue() ? true : false;
+ }
+
+ if ( ImplHasBullet( nPara ) && bDrawBullet)
+ {
+ BOOL bVertical = IsVertical();
+
+ BOOL bRightToLeftPara = pEditEngine->IsRightToLeft( nPara );
+
+ Rectangle aBulletArea( ImpCalcBulletArea( nPara, TRUE, FALSE ) );
+
+ Paragraph* pPara = pParaList->GetParagraph( nPara );
+ const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
+ if ( pFmt && ( pFmt->GetNumberingType() != SVX_NUM_NUMBER_NONE ) )
+ {
+ if( pFmt->GetNumberingType() != SVX_NUM_BITMAP )
+ {
+ Font aBulletFont( ImpCalcBulletFont( nPara ) );
+ // #2338# Use base line
+ BOOL bSymbol = pFmt->GetNumberingType() == SVX_NUM_CHAR_SPECIAL;
+ aBulletFont.SetAlign( bSymbol ? ALIGN_BOTTOM : ALIGN_BASELINE );
+ Font aOldFont = pOutDev->GetFont();
+ pOutDev->SetFont( aBulletFont );
+
+ ParagraphInfos aParaInfos = pEditEngine->GetParagraphInfos( nPara );
+ Point aTextPos;
+ if ( !bVertical )
+ {
+// aTextPos.Y() = rStartPos.Y() + aBulletArea.Bottom();
+ aTextPos.Y() = rStartPos.Y() + ( bSymbol ? aBulletArea.Bottom() : aParaInfos.nFirstLineMaxAscent );
+ if ( !bRightToLeftPara )
+ aTextPos.X() = rStartPos.X() + aBulletArea.Left();
+ else
+ aTextPos.X() = rStartPos.X() + GetPaperSize().Width() - aBulletArea.Left();
+ }
+ else
+ {
+// aTextPos.X() = rStartPos.X() - aBulletArea.Bottom();
+ aTextPos.X() = rStartPos.X() - ( bSymbol ? aBulletArea.Bottom() : aParaInfos.nFirstLineMaxAscent );
+ aTextPos.Y() = rStartPos.Y() + aBulletArea.Left();
+ }
+
+ if ( nOrientation )
+ {
+ // Sowohl TopLeft als auch BottomLeft nicht ganz richtig, da
+ // in EditEngine BaseLine...
+ double nRealOrientation = nOrientation*F_PI1800;
+ double nCos = cos( nRealOrientation );
+ double nSin = sin( nRealOrientation );
+ Point aRotatedPos;
+ // Translation...
+ aTextPos -= rOrigin;
+ // Rotation...
+ aRotatedPos.X()=(long) (nCos*aTextPos.X() + nSin*aTextPos.Y());
+ aRotatedPos.Y()=(long) - (nSin*aTextPos.X() - nCos*aTextPos.Y());
+ aTextPos = aRotatedPos;
+ // Translation...
+ aTextPos += rOrigin;
+ Font aRotatedFont( aBulletFont );
+ aRotatedFont.SetOrientation( nOrientation );
+ pOutDev->SetFont( aRotatedFont );
+ }
+
+ // #105803# VCL will care for brackets and so on...
+ ULONG nLayoutMode = pOutDev->GetLayoutMode();
+ nLayoutMode &= ~(TEXT_LAYOUT_BIDI_RTL|TEXT_LAYOUT_COMPLEX_DISABLED|TEXT_LAYOUT_BIDI_STRONG);
+ if ( bRightToLeftPara )
+ nLayoutMode |= TEXT_LAYOUT_BIDI_RTL;
+ pOutDev->SetLayoutMode( nLayoutMode );
+
+ if(bStrippingPortions)
+ {
+ const Font aSvxFont(pOutDev->GetFont());
+ sal_Int32* pBuf = new sal_Int32[ pPara->GetText().Len() ];
+ pOutDev->GetTextArray( pPara->GetText(), pBuf );
+
+ if(bSymbol)
+ {
+ // aTextPos is Bottom, go to Baseline
+ FontMetric aMetric(pOutDev->GetFontMetric());
+ aTextPos.Y() -= aMetric.GetDescent();
+ }
+
+ DrawingText(aTextPos, pPara->GetText(), 0, pPara->GetText().Len(), pBuf,
+ aSvxFont, nPara, 0xFFFF, 0xFF, 0, 0, false, false, true, 0, Color(), Color());
+
+ delete[] pBuf;
+ }
+ else
+ {
+ pOutDev->DrawText( aTextPos, pPara->GetText() );
+ }
+
+ pOutDev->SetFont( aOldFont );
+ }
+ else
+ {
+ if ( pFmt->GetBrush()->GetGraphicObject() )
+ {
+ Point aBulletPos;
+ if ( !bVertical )
+ {
+ aBulletPos.Y() = rStartPos.Y() + aBulletArea.Top();
+ if ( !bRightToLeftPara )
+ aBulletPos.X() = rStartPos.X() + aBulletArea.Left();
+ else
+ aBulletPos.X() = rStartPos.X() + GetPaperSize().Width() - aBulletArea.Right();
+ }
+ else
+ {
+ aBulletPos.X() = rStartPos.X() - aBulletArea.Bottom();
+ aBulletPos.Y() = rStartPos.Y() + aBulletArea.Left();
+ }
+
+ if(bStrippingPortions)
+ {
+ if(aDrawBulletHdl.IsSet())
+ {
+ // call something analog to aDrawPortionHdl (if set) and feed it something
+ // analog to DrawPortionInfo...
+ // created aDrawBulletHdl, Set/GetDrawBulletHdl.
+ // created DrawBulletInfo and added handling to sdrtextdecomposition.cxx
+ DrawBulletInfo aDrawBulletInfo(
+ *pFmt->GetBrush()->GetGraphicObject(),
+ aBulletPos,
+ pPara->aBulSize);
+
+ aDrawBulletHdl.Call(&aDrawBulletInfo);
+ }
+ }
+ else
+ {
+ // MT: Remove CAST when KA made the Draw-Method const
+ ((GraphicObject*)pFmt->GetBrush()->GetGraphicObject())->Draw( pOutDev, aBulletPos, pPara->aBulSize );
+ }
+ }
+ }
+ }
+
+ // Bei zusammengeklappten Absaetzen einen Strich vor den Text malen.
+ if( pParaList->HasChilds(pPara) && !pParaList->HasVisibleChilds(pPara) &&
+ !bStrippingPortions && !nOrientation )
+ {
+ long nWidth = pOutDev->PixelToLogic( Size( 10, 0 ) ).Width();
+
+ Point aStartPos, aEndPos;
+ if ( !bVertical )
+ {
+ aStartPos.Y() = rStartPos.Y() + aBulletArea.Bottom();
+ if ( !bRightToLeftPara )
+ aStartPos.X() = rStartPos.X() + aBulletArea.Right();
+ else
+ aStartPos.X() = rStartPos.X() + GetPaperSize().Width() - aBulletArea.Left();
+ aEndPos = aStartPos;
+ aEndPos.X() += nWidth;
+ }
+ else
+ {
+ aStartPos.X() = rStartPos.X() - aBulletArea.Bottom();
+ aStartPos.Y() = rStartPos.Y() + aBulletArea.Right();
+ aEndPos = aStartPos;
+ aEndPos.Y() += nWidth;
+ }
+
+ const Color& rOldLineColor = pOutDev->GetLineColor();
+ pOutDev->SetLineColor( Color( COL_BLACK ) );
+ pOutDev->DrawLine( aStartPos, aEndPos );
+ pOutDev->SetLineColor( rOldLineColor );
+ }
+ }
+}
+
+void Outliner::InvalidateBullet( Paragraph* /*pPara*/, ULONG nPara )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ long nLineHeight = (long)pEditEngine->GetLineHeight((USHORT)nPara );
+ OutlinerView* pView = aViewList.First();
+ while( pView )
+ {
+ Point aPos( pView->pEditView->GetWindowPosTopLeft((USHORT)nPara ) );
+ Rectangle aRect( pView->GetOutputArea() );
+ aRect.Right() = aPos.X();
+ aRect.Top() = aPos.Y();
+ aRect.Bottom() = aPos.Y();
+ aRect.Bottom() += nLineHeight;
+
+ pView->GetWindow()->Invalidate( aRect );
+ pView = aViewList.Next();
+ }
+}
+
+ULONG Outliner::Read( SvStream& rInput, const String& rBaseURL, USHORT eFormat, SvKeyValueIterator* pHTTPHeaderAttrs )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ BOOL bOldUndo = pEditEngine->IsUndoEnabled();
+ EnableUndo( FALSE );
+
+ BOOL bUpdate = pEditEngine->GetUpdateMode();
+ pEditEngine->SetUpdateMode( FALSE );
+
+ Clear();
+
+ ImplBlockInsertionCallbacks( TRUE );
+ ULONG nRet = pEditEngine->Read( rInput, rBaseURL, (EETextFormat)eFormat, pHTTPHeaderAttrs );
+
+ bFirstParaIsEmpty = FALSE;
+
+ USHORT nParas = pEditEngine->GetParagraphCount();
+ pParaList->Clear( TRUE );
+ USHORT n;
+ for ( n = 0; n < nParas; n++ )
+ {
+ Paragraph* pPara = new Paragraph( 0 );
+ pParaList->Insert( pPara, LIST_APPEND );
+
+ if ( eFormat == EE_FORMAT_BIN )
+ {
+ const SfxItemSet& rAttrs = pEditEngine->GetParaAttribs( n );
+ const SfxInt16Item& rLevel = (const SfxInt16Item&) rAttrs.Get( EE_PARA_OUTLLEVEL );
+ sal_Int16 nDepth = rLevel.GetValue();
+ ImplInitDepth( n, nDepth, FALSE );
+ }
+ }
+
+ if ( eFormat != EE_FORMAT_BIN )
+ {
+ ImpFilterIndents( 0, nParas-1 );
+ }
+
+ ImplBlockInsertionCallbacks( FALSE );
+ pEditEngine->SetUpdateMode( bUpdate );
+ EnableUndo( bOldUndo );
+
+ return nRet;
+}
+
+
+void Outliner::ImpFilterIndents( ULONG nFirstPara, ULONG nLastPara )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ BOOL bUpdate = pEditEngine->GetUpdateMode();
+ pEditEngine->SetUpdateMode( FALSE );
+
+ Paragraph* pLastConverted = NULL;
+ for( ULONG nPara = nFirstPara; nPara <= nLastPara; nPara++ )
+ {
+ Paragraph* pPara = pParaList->GetParagraph( nPara );
+ if (pPara)
+ {
+ if( ImpConvertEdtToOut( nPara ) )
+ {
+ pLastConverted = pPara;
+ }
+ else if ( pLastConverted )
+ {
+ // Normale Absaetze unter der Ueberschrift anordnen...
+ pPara->SetDepth( pLastConverted->GetDepth() );
+ }
+
+ ImplInitDepth( (USHORT)nPara, pPara->GetDepth(), FALSE );
+ }
+ }
+
+ pEditEngine->SetUpdateMode( bUpdate );
+}
+
+SfxUndoManager& Outliner::GetUndoManager()
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetUndoManager();
+}
+
+void Outliner::ImpTextPasted( ULONG nStartPara, USHORT nCount )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ BOOL bUpdate = pEditEngine->GetUpdateMode();
+ pEditEngine->SetUpdateMode( FALSE );
+
+ const ULONG nStart = nStartPara;
+
+ Paragraph* pPara = pParaList->GetParagraph( nStartPara );
+// Paragraph* pLastConverted = NULL;
+// bool bFirst = true;
+
+ while( nCount && pPara )
+ {
+ if( ImplGetOutlinerMode() != OUTLINERMODE_TEXTOBJECT )
+ {
+ nDepthChangedHdlPrevDepth = pPara->GetDepth();
+ mnDepthChangeHdlPrevFlags = pPara->nFlags;
+
+ ImpConvertEdtToOut( nStartPara );
+
+ pHdlParagraph = pPara;
+
+ if( nStartPara == nStart )
+ {
+ // the existing paragraph has changed depth or flags
+ if( (pPara->GetDepth() != nDepthChangedHdlPrevDepth) || (pPara->nFlags != mnDepthChangeHdlPrevFlags) )
+ DepthChangedHdl();
+ }
+ }
+ else // EditEngine-Modus
+ {
+ sal_Int16 nDepth = -1;
+ const SfxItemSet& rAttrs = pEditEngine->GetParaAttribs( (USHORT)nStartPara );
+ if ( rAttrs.GetItemState( EE_PARA_OUTLLEVEL ) == SFX_ITEM_ON )
+ {
+ const SfxInt16Item& rLevel = (const SfxInt16Item&) rAttrs.Get( EE_PARA_OUTLLEVEL );
+ nDepth = rLevel.GetValue();
+ }
+ if ( nDepth != GetDepth( nStartPara ) )
+ ImplInitDepth( (USHORT)nStartPara, nDepth, FALSE );
+ }
+
+ nCount--;
+ nStartPara++;
+ pPara = pParaList->GetParagraph( nStartPara );
+ }
+
+ pEditEngine->SetUpdateMode( bUpdate );
+
+ DBG_ASSERT(pParaList->GetParagraphCount()==pEditEngine->GetParagraphCount(),"ImpTextPasted failed");
+}
+
+long Outliner::IndentingPagesHdl( OutlinerView* pView )
+{
+ DBG_CHKTHIS(Outliner,0);
+ if( !aIndentingPagesHdl.IsSet() )
+ return 1;
+ return aIndentingPagesHdl.Call( pView );
+}
+
+BOOL Outliner::ImpCanIndentSelectedPages( OutlinerView* pCurView )
+{
+ DBG_CHKTHIS(Outliner,0);
+ // Die selektierten Seiten muessen vorher durch ImpCalcSelectedPages
+ // schon eingestellt sein
+
+ // Wenn der erste Absatz auf Ebene 0 liegt darf er auf keinen Fall
+ // eingerueckt werden, evtl folgen aber weitere auf Ebene 0.
+ if ( ( mnFirstSelPage == 0 ) && ( ImplGetOutlinerMode() != OUTLINERMODE_TEXTOBJECT ) )
+ {
+ if ( nDepthChangedHdlPrevDepth == 1 ) // ist die einzige Seite
+ return FALSE;
+ else
+ pCurView->ImpCalcSelectedPages( FALSE ); // ohne die erste
+ }
+ return (BOOL)IndentingPagesHdl( pCurView );
+}
+
+
+BOOL Outliner::ImpCanDeleteSelectedPages( OutlinerView* pCurView )
+{
+ DBG_CHKTHIS(Outliner,0);
+ // Die selektierten Seiten muessen vorher durch ImpCalcSelectedPages
+ // schon eingestellt sein
+ return (BOOL)RemovingPagesHdl( pCurView );
+}
+
+Outliner::Outliner( SfxItemPool* pPool, USHORT nMode )
+: nMinDepth( -1 )
+{
+ DBG_CTOR( Outliner, 0 );
+
+ bStrippingPortions = FALSE;
+ bPasting = FALSE;
+
+ nFirstPage = 1;
+ bBlockInsCallback = FALSE;
+
+ nMaxDepth = 9;
+
+ pParaList = new ParagraphList;
+ pParaList->SetVisibleStateChangedHdl( LINK( this, Outliner, ParaVisibleStateChangedHdl ) );
+ Paragraph* pPara = new Paragraph( 0 );
+ pParaList->Insert( pPara, LIST_APPEND );
+ bFirstParaIsEmpty = TRUE;
+
+ pEditEngine = new OutlinerEditEng( this, pPool );
+ pEditEngine->SetBeginMovingParagraphsHdl( LINK( this, Outliner, BeginMovingParagraphsHdl ) );
+ pEditEngine->SetEndMovingParagraphsHdl( LINK( this, Outliner, EndMovingParagraphsHdl ) );
+ pEditEngine->SetBeginPasteOrDropHdl( LINK( this, Outliner, BeginPasteOrDropHdl ) );
+ pEditEngine->SetEndPasteOrDropHdl( LINK( this, Outliner, EndPasteOrDropHdl ) );
+
+ Init( nMode );
+}
+
+Outliner::~Outliner()
+{
+ DBG_DTOR(Outliner,0);
+
+ pParaList->Clear( TRUE );
+ delete pParaList;
+ delete pEditEngine;
+}
+
+ULONG Outliner::InsertView( OutlinerView* pView, ULONG nIndex )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ aViewList.Insert( pView, nIndex );
+ pEditEngine->InsertView( pView->pEditView, (USHORT)nIndex );
+ return aViewList.GetPos( pView );
+}
+
+OutlinerView* Outliner::RemoveView( OutlinerView* pView )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ ULONG nPos = aViewList.GetPos( pView );
+ if ( nPos != LIST_ENTRY_NOTFOUND )
+ {
+ pView->pEditView->HideCursor(); // HACK wg. BugId 10006
+ pEditEngine->RemoveView( pView->pEditView );
+ aViewList.Remove( nPos );
+ }
+ return NULL; // MT: return ueberfluessig
+}
+
+OutlinerView* Outliner::RemoveView( ULONG nIndex )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ EditView* pEditView = pEditEngine->GetView( (USHORT)nIndex );
+ pEditView->HideCursor(); // HACK wg. BugId 10006
+
+ pEditEngine->RemoveView( (USHORT)nIndex );
+ aViewList.Remove( nIndex );
+ return NULL; // MT: return ueberfluessig
+}
+
+
+OutlinerView* Outliner::GetView( ULONG nIndex ) const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return aViewList.GetObject( nIndex );
+}
+
+ULONG Outliner::GetViewCount() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return aViewList.Count();
+}
+
+void Outliner::ParagraphInsertedHdl()
+{
+ DBG_CHKTHIS(Outliner,0);
+ if( !IsInUndo() )
+ aParaInsertedHdl.Call( this );
+}
+
+
+void Outliner::ParagraphRemovingHdl()
+{
+ DBG_CHKTHIS(Outliner,0);
+ if( !IsInUndo() )
+ aParaRemovingHdl.Call( this );
+}
+
+
+void Outliner::DepthChangedHdl()
+{
+ DBG_CHKTHIS(Outliner,0);
+ if( !IsInUndo() )
+ aDepthChangedHdl.Call( this );
+}
+
+
+ULONG Outliner::GetAbsPos( Paragraph* pPara )
+{
+ DBG_CHKTHIS(Outliner,0);
+ DBG_ASSERT(pPara,"GetAbsPos:No Para");
+ return pParaList->GetAbsPos( pPara );
+}
+
+ULONG Outliner::GetParagraphCount() const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pParaList->GetParagraphCount();
+}
+
+Paragraph* Outliner::GetParagraph( ULONG nAbsPos ) const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pParaList->GetParagraph( nAbsPos );
+}
+
+BOOL Outliner::HasChilds( Paragraph* pParagraph ) const
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pParaList->HasChilds( pParagraph );
+}
+
+BOOL Outliner::ImplHasBullet( USHORT nPara ) const
+{
+ return GetNumberFormat(nPara) != 0;
+}
+
+const SvxNumberFormat* Outliner::GetNumberFormat( USHORT nPara ) const
+{
+ const SvxNumberFormat* pFmt = NULL;
+
+ Paragraph* pPara = pParaList->GetParagraph( nPara );
+ if (pPara == NULL)
+ return NULL;
+
+ sal_Int16 nDepth = pPara? pPara->GetDepth() : -1;
+
+ if( nDepth >= 0 )
+ {
+ const SvxNumBulletItem& rNumBullet = (const SvxNumBulletItem&) pEditEngine->GetParaAttrib( nPara, EE_PARA_NUMBULLET );
+ if ( rNumBullet.GetNumRule()->GetLevelCount() > nDepth )
+ pFmt = rNumBullet.GetNumRule()->Get( nDepth );
+ }
+
+ return pFmt;
+}
+
+Size Outliner::ImplGetBulletSize( USHORT nPara )
+{
+ Paragraph* pPara = pParaList->GetParagraph( nPara );
+ if (!pPara)
+ return Size();
+
+ if( pPara->aBulSize.Width() == -1 )
+ {
+ const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
+ DBG_ASSERT( pFmt, "ImplGetBulletSize - no Bullet!" );
+
+ if ( pFmt->GetNumberingType() == SVX_NUM_NUMBER_NONE )
+ {
+ pPara->aBulSize = Size( 0, 0 );
+ }
+ else if( pFmt->GetNumberingType() != SVX_NUM_BITMAP )
+ {
+ String aBulletText = ImplGetBulletText( nPara );
+ OutputDevice* pRefDev = pEditEngine->GetRefDevice();
+ Font aBulletFont( ImpCalcBulletFont( nPara ) );
+ Font aRefFont( pRefDev->GetFont());
+ pRefDev->SetFont( aBulletFont );
+ pPara->aBulSize.Width() = pRefDev->GetTextWidth( aBulletText );
+ pPara->aBulSize.Height() = pRefDev->GetTextHeight();
+ pRefDev->SetFont( aRefFont );
+ }
+ else
+ {
+ pPara->aBulSize = OutputDevice::LogicToLogic( pFmt->GetGraphicSize(), MAP_100TH_MM, pEditEngine->GetRefDevice()->GetMapMode() );
+ }
+ }
+
+ return pPara->aBulSize;
+}
+
+void Outliner::ImplCheckParagraphs( USHORT nStart, USHORT nEnd )
+{
+ DBG_CHKTHIS( Outliner, 0 );
+
+ // --> OD 2009-03-10 #i100014#
+ // assure that the following for-loop does not loop forever
+ for ( USHORT n = nStart; n < nEnd; n++ )
+ // <--
+ {
+ Paragraph* pPara = pParaList->GetParagraph( n );
+ if (pPara)
+ {
+ pPara->Invalidate();
+ ImplCalcBulletText( n, FALSE, FALSE );
+ }
+ }
+}
+
+void Outliner::SetRefDevice( OutputDevice* pRefDev )
+{
+ DBG_CHKTHIS(Outliner,0);
+ pEditEngine->SetRefDevice( pRefDev );
+ for ( USHORT n = (USHORT) pParaList->GetParagraphCount(); n; )
+ {
+ Paragraph* pPara = pParaList->GetParagraph( --n );
+ pPara->Invalidate();
+ }
+}
+
+void Outliner::ParaAttribsChanged( USHORT nPara )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ // Der Outliner hat kein eigenes Undo, wenn Absaetz getrennt/verschmolzen werden.
+ // Beim ParagraphInserted ist das Attribut EE_PARA_OUTLLEVEL
+ // ggf. noch nicht eingestellt, dies wird aber benoetigt um die Tiefe
+ // des Absatzes zu bestimmen.
+
+ if( pEditEngine->IsInUndo() )
+ {
+ if ( pParaList->GetParagraphCount() == pEditEngine->GetParagraphCount() )
+ {
+ Paragraph* pPara = pParaList->GetParagraph( nPara );
+ const SfxInt16Item& rLevel = (const SfxInt16Item&) pEditEngine->GetParaAttrib( nPara, EE_PARA_OUTLLEVEL );
+ if ( pPara && pPara->GetDepth() != rLevel.GetValue() )
+ {
+ pPara->SetDepth( rLevel.GetValue() );
+ ImplCalcBulletText( nPara, TRUE, TRUE );
+ }
+ }
+ }
+}
+
+void Outliner::StyleSheetChanged( SfxStyleSheet* pStyle )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ // Die EditEngine ruft StyleSheetChanged auch fuer abgeleitete Styles.
+ // MT: Hier wurde frueher alle Absaetze durch ein ImpRecalcParaAttribs
+ // gejagt, die die besagte Vorlage haben, warum?
+ // => Eigentlich kann sich nur die Bullet-Repraesentation aendern...
+
+ USHORT nParas = (USHORT)pParaList->GetParagraphCount();
+ for( USHORT nPara = 0; nPara < nParas; nPara++ )
+ {
+ if ( pEditEngine->GetStyleSheet( nPara ) == pStyle )
+ {
+ ImplCheckNumBulletItem( nPara );
+ ImplCalcBulletText( nPara, FALSE, FALSE );
+ // #97333# EditEngine formats changed paragraphs before calling this method,
+ // so they are not reformatted now and use wrong bullet indent
+ pEditEngine->QuickMarkInvalid( ESelection( nPara, 0, nPara, 0 ) );
+ }
+ }
+}
+
+Rectangle Outliner::ImpCalcBulletArea( USHORT nPara, BOOL bAdjust, BOOL bReturnPaperPos )
+{
+ // Bullet-Bereich innerhalb des Absatzes...
+ Rectangle aBulletArea;
+
+ const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
+ if ( pFmt )
+ {
+ Point aTopLeft;
+ Size aBulletSize( ImplGetBulletSize( nPara ) );
+
+ BOOL bOutlineMode = ( pEditEngine->GetControlWord() & EE_CNTRL_OUTLINER ) != 0;
+
+ // the ODF attribut text:space-before which holds the spacing to add to the left of the label
+ const short nSpaceBefore = pFmt->GetAbsLSpace() + pFmt->GetFirstLineOffset();
+
+ const SvxLRSpaceItem& rLR = (const SvxLRSpaceItem&) pEditEngine->GetParaAttrib( nPara, bOutlineMode ? EE_PARA_OUTLLRSPACE : EE_PARA_LRSPACE );
+ aTopLeft.X() = rLR.GetTxtLeft() + rLR.GetTxtFirstLineOfst() + nSpaceBefore;
+
+ long nBulletWidth = Max( (long) -rLR.GetTxtFirstLineOfst(), (long) ((-pFmt->GetFirstLineOffset()) + pFmt->GetCharTextDistance()) );
+ if ( nBulletWidth < aBulletSize.Width() ) // Bullet macht sich Platz
+ nBulletWidth = aBulletSize.Width();
+
+ if ( bAdjust && !bOutlineMode )
+ {
+ // Bei zentriert/rechtsbuendig anpassen
+ const SvxAdjustItem& rItem = (const SvxAdjustItem&)pEditEngine->GetParaAttrib( nPara, EE_PARA_JUST );
+ if ( ( !pEditEngine->IsRightToLeft( nPara ) && ( rItem.GetAdjust() != SVX_ADJUST_LEFT ) ) ||
+ ( pEditEngine->IsRightToLeft( nPara ) && ( rItem.GetAdjust() != SVX_ADJUST_RIGHT ) ) )
+ {
+ aTopLeft.X() = pEditEngine->GetFirstLineStartX( nPara ) - nBulletWidth;
+ }
+ }
+
+ // Vertikal:
+ ParagraphInfos aInfos = pEditEngine->GetParagraphInfos( nPara );
+ if ( aInfos.bValid )
+ {
+ aTopLeft.Y() = /* aInfos.nFirstLineOffset + */ // #91076# nFirstLineOffset is already added to the StartPos (PaintBullet) from the EditEngine
+ aInfos.nFirstLineHeight - aInfos.nFirstLineTextHeight
+ + aInfos.nFirstLineTextHeight / 2
+ - aBulletSize.Height() / 2;
+ // ggf. lieber auf der Baseline ausgeben...
+ if( ( pFmt->GetNumberingType() != SVX_NUM_NUMBER_NONE ) && ( pFmt->GetNumberingType() != SVX_NUM_BITMAP ) && ( pFmt->GetNumberingType() != SVX_NUM_CHAR_SPECIAL ) )
+ {
+ Font aBulletFont( ImpCalcBulletFont( nPara ) );
+ if ( aBulletFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL )
+ {
+ OutputDevice* pRefDev = pEditEngine->GetRefDevice();
+ Font aOldFont = pRefDev->GetFont();
+ pRefDev->SetFont( aBulletFont );
+ FontMetric aMetric( pRefDev->GetFontMetric() );
+ // Leading der ersten Zeile...
+ aTopLeft.Y() = /* aInfos.nFirstLineOffset + */ aInfos.nFirstLineMaxAscent;
+ aTopLeft.Y() -= aMetric.GetAscent();
+ pRefDev->SetFont( aOldFont );
+ }
+ }
+ }
+
+ // Horizontal:
+ if( pFmt->GetNumAdjust() == SVX_ADJUST_RIGHT )
+ {
+ aTopLeft.X() += nBulletWidth - aBulletSize.Width();
+ }
+ else if( pFmt->GetNumAdjust() == SVX_ADJUST_CENTER )
+ {
+ aTopLeft.X() += ( nBulletWidth - aBulletSize.Width() ) / 2;
+ }
+
+ if ( aTopLeft.X() < 0 ) // dann draengeln
+ aTopLeft.X() = 0;
+
+ aBulletArea = Rectangle( aTopLeft, aBulletSize );
+ }
+ if ( bReturnPaperPos )
+ {
+ Size aBulletSize( aBulletArea.GetSize() );
+ Point aBulletDocPos( aBulletArea.TopLeft() );
+ aBulletDocPos.Y() += pEditEngine->GetDocPosTopLeft( nPara ).Y();
+ Point aBulletPos( aBulletDocPos );
+
+ if ( IsVertical() )
+ {
+ aBulletPos.Y() = aBulletDocPos.X();
+ aBulletPos.X() = GetPaperSize().Width() - aBulletDocPos.Y();
+ // Rotate:
+ aBulletPos.X() -= aBulletSize.Height();
+ Size aSz( aBulletSize );
+ aBulletSize.Width() = aSz.Height();
+ aBulletSize.Height() = aSz.Width();
+ }
+ else if ( pEditEngine->IsRightToLeft( nPara ) )
+ {
+ aBulletPos.X() = GetPaperSize().Width() - aBulletDocPos.X() - aBulletSize.Width();
+ }
+
+ aBulletArea = Rectangle( aBulletPos, aBulletSize );
+ }
+ return aBulletArea;
+}
+
+void Outliner::ExpandHdl()
+{
+ DBG_CHKTHIS(Outliner,0);
+ aExpandHdl.Call( this );
+}
+
+EBulletInfo Outliner::GetBulletInfo( USHORT nPara )
+{
+ EBulletInfo aInfo;
+
+ aInfo.nParagraph = nPara;
+ aInfo.bVisible = ImplHasBullet( nPara );
+
+ const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
+ aInfo.nType = pFmt ? pFmt->GetNumberingType() : 0;
+
+ if( pFmt )
+ {
+ if( pFmt->GetNumberingType() != SVX_NUM_BITMAP )
+ {
+ aInfo.aText = ImplGetBulletText( nPara );
+
+ if( pFmt->GetBulletFont() )
+ aInfo.aFont = *pFmt->GetBulletFont();
+ }
+ else if ( pFmt->GetBrush()->GetGraphicObject() )
+ {
+ aInfo.aGraphic = pFmt->GetBrush()->GetGraphicObject()->GetGraphic();
+ }
+ }
+
+ if ( aInfo.bVisible )
+ {
+ aInfo.aBounds = ImpCalcBulletArea( nPara, TRUE, TRUE );
+ }
+
+ return aInfo;
+}
+
+XubString Outliner::GetText( Paragraph* pParagraph, ULONG nCount ) const
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ XubString aText;
+ USHORT nStartPara = (USHORT) pParaList->GetAbsPos( pParagraph );
+ for ( USHORT n = 0; n < nCount; n++ )
+ {
+ aText += pEditEngine->GetText( nStartPara + n );
+ if ( (n+1) < (USHORT)nCount )
+ aText += '\n';
+ }
+ return aText;
+}
+
+void Outliner::Remove( Paragraph* pPara, ULONG nParaCount )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ ULONG nPos = pParaList->GetAbsPos( pPara );
+ if( !nPos && ( nParaCount >= pParaList->GetParagraphCount() ) )
+ {
+ Clear();
+ }
+ else
+ {
+ for( USHORT n = 0; n < (USHORT)nParaCount; n++ )
+ pEditEngine->RemoveParagraph( (USHORT) nPos );
+ }
+}
+
+void Outliner::StripPortions()
+{
+ DBG_CHKTHIS(Outliner,0);
+ bStrippingPortions = TRUE;
+ pEditEngine->StripPortions();
+ bStrippingPortions = FALSE;
+}
+
+// #101498#
+void Outliner::DrawingText( const Point& rStartPos, const XubString& rText, USHORT nTextStart, USHORT nTextLen, const sal_Int32* pDXArray,const SvxFont& rFont,
+ USHORT nPara, USHORT nIndex, BYTE nRightToLeft,
+ const EEngineData::WrongSpellVector* pWrongSpellVector,
+ const SvxFieldData* pFieldData,
+ bool bEndOfLine,
+ bool bEndOfParagraph,
+ bool bEndOfBullet,
+ const ::com::sun::star::lang::Locale* pLocale,
+ const Color& rOverlineColor,
+ const Color& rTextLineColor)
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ if(aDrawPortionHdl.IsSet())
+ {
+ // #101498#
+ DrawPortionInfo aInfo( rStartPos, rText, nTextStart, nTextLen, rFont, nPara, nIndex, pDXArray, pWrongSpellVector,
+ pFieldData, pLocale, rOverlineColor, rTextLineColor, nRightToLeft, bEndOfLine, bEndOfParagraph, bEndOfBullet);
+
+ aDrawPortionHdl.Call( &aInfo );
+ }
+}
+
+long Outliner::RemovingPagesHdl( OutlinerView* pView )
+{
+ DBG_CHKTHIS(Outliner,0);
+ return aRemovingPagesHdl.IsSet() ? aRemovingPagesHdl.Call( pView ) : TRUE;
+}
+
+BOOL Outliner::ImpCanDeleteSelectedPages( OutlinerView* pCurView, USHORT _nFirstPage, USHORT nPages )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ nDepthChangedHdlPrevDepth = nPages;
+ mnFirstSelPage = _nFirstPage;
+ pHdlParagraph = 0;
+ return (BOOL)RemovingPagesHdl( pCurView );
+}
+
+SfxItemSet Outliner::GetParaAttribs( USHORT nPara )
+{
+ DBG_CHKTHIS(Outliner,0);
+ return pEditEngine->GetParaAttribs( nPara );
+}
+
+IMPL_LINK( Outliner, ParaVisibleStateChangedHdl, Paragraph*, pPara )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ ULONG nPara = pParaList->GetAbsPos( pPara );
+ pEditEngine->ShowParagraph( (USHORT)nPara, pPara->IsVisible() );
+
+ return 0;
+}
+
+IMPL_LINK( Outliner, BeginMovingParagraphsHdl, MoveParagraphsInfo*, EMPTYARG )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ if( !IsInUndo() )
+ GetBeginMovingHdl().Call( this );
+
+ return 0;
+}
+
+IMPL_LINK( Outliner, BeginPasteOrDropHdl, PasteOrDropInfos*, pInfos )
+{
+ UndoActionStart( EDITUNDO_DRAGANDDROP );
+ maBeginPasteOrDropHdl.Call(pInfos);
+ return 0;
+}
+
+IMPL_LINK( Outliner, EndPasteOrDropHdl, PasteOrDropInfos*, pInfos )
+{
+ bPasting = FALSE;
+ ImpTextPasted( pInfos->nStartPara, pInfos->nEndPara - pInfos->nStartPara + 1 );
+ maEndPasteOrDropHdl.Call( pInfos );
+ UndoActionEnd( EDITUNDO_DRAGANDDROP );
+ return 0;
+}
+
+IMPL_LINK( Outliner, EndMovingParagraphsHdl, MoveParagraphsInfo*, pInfos )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ pParaList->MoveParagraphs( pInfos->nStartPara, pInfos->nDestPara, pInfos->nEndPara - pInfos->nStartPara + 1 );
+ USHORT nChangesStart = Min( pInfos->nStartPara, pInfos->nDestPara );
+ USHORT nParas = (USHORT)pParaList->GetParagraphCount();
+ for ( USHORT n = nChangesStart; n < nParas; n++ )
+ ImplCalcBulletText( n, FALSE, FALSE );
+
+ if( !IsInUndo() )
+ aEndMovingHdl.Call( this );
+
+ return 0;
+}
+
+static bool isSameNumbering( const SvxNumberFormat& rN1, const SvxNumberFormat& rN2 )
+{
+ if( rN1.GetNumberingType() != rN2.GetNumberingType() )
+ return false;
+
+ if( rN1.GetNumStr(1) != rN2.GetNumStr(1) )
+ return false;
+
+ if( (rN1.GetPrefix() != rN2.GetPrefix()) || (rN1.GetSuffix() != rN2.GetSuffix()) )
+ return false;
+
+ return true;
+}
+
+sal_uInt16 Outliner::ImplGetNumbering( USHORT nPara, const SvxNumberFormat* pParaFmt )
+{
+ sal_uInt16 nNumber = pParaFmt->GetStart() - 1;
+
+ Paragraph* pPara = pParaList->GetParagraph( nPara );
+ const sal_Int16 nParaDepth = pPara->GetDepth();
+
+ do
+ {
+ pPara = pParaList->GetParagraph( nPara );
+ const sal_Int16 nDepth = pPara->GetDepth();
+
+ // ignore paragraphs that are below our paragraph or have no numbering
+ if( (nDepth > nParaDepth) || (nDepth == -1) )
+ continue;
+
+ // stop on paragraphs that are above our paragraph
+ if( nDepth < nParaDepth )
+ break;
+
+ const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
+
+ if( pFmt == 0 )
+ continue; // ignore paragraphs without bullets
+
+ // check if numbering is the same
+ if( !isSameNumbering( *pFmt, *pParaFmt ) )
+ break;
+
+ const SfxBoolItem& rBulletState = (const SfxBoolItem&) pEditEngine->GetParaAttrib( nPara, EE_PARA_BULLETSTATE );
+
+ if( rBulletState.GetValue() )
+ nNumber += 1;
+
+ // same depth, same number format, check for restart
+ const sal_Int16 nNumberingStartValue = pPara->GetNumberingStartValue();
+ if( (nNumberingStartValue != -1) || pPara->IsParaIsNumberingRestart() )
+ {
+ if( nNumberingStartValue != -1 )
+ nNumber += nNumberingStartValue - 1;
+ break;
+ }
+ }
+ while( nPara-- );
+
+ return nNumber;
+}
+
+void Outliner::ImplCalcBulletText( USHORT nPara, BOOL bRecalcLevel, BOOL bRecalcChilds )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ Paragraph* pPara = pParaList->GetParagraph( nPara );
+ USHORT nRelPos = 0xFFFF;
+
+ while ( pPara )
+ {
+ XubString aBulletText;
+ const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
+ if( pFmt && ( pFmt->GetNumberingType() != SVX_NUM_BITMAP ) )
+ {
+ aBulletText += pFmt->GetPrefix();
+ if( pFmt->GetNumberingType() == SVX_NUM_CHAR_SPECIAL )
+ {
+ aBulletText += pFmt->GetBulletChar();
+ }
+ else if( pFmt->GetNumberingType() != SVX_NUM_NUMBER_NONE )
+ {
+ aBulletText += pFmt->GetNumStr( ImplGetNumbering( nPara, pFmt ) );
+ }
+ aBulletText += pFmt->GetSuffix();
+ }
+
+ if( aBulletText != pPara->GetText() )
+ pPara->SetText( aBulletText );
+
+ pPara->nFlags &= (~PARAFLAG_SETBULLETTEXT);
+
+ if ( bRecalcLevel )
+ {
+ if ( nRelPos != 0xFFFF )
+ nRelPos++;
+
+ sal_Int16 nDepth = pPara->GetDepth();
+ pPara = pParaList->GetParagraph( ++nPara );
+ if ( !bRecalcChilds )
+ {
+ while ( pPara && ( pPara->GetDepth() > nDepth ) )
+ pPara = pParaList->GetParagraph( ++nPara );
+ }
+
+ if ( pPara && ( pPara->GetDepth() < nDepth ) )
+ pPara = NULL;
+ }
+ else
+ {
+ pPara = NULL;
+ }
+ }
+}
+
+void Outliner::Clear()
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ if( !bFirstParaIsEmpty )
+ {
+ ImplBlockInsertionCallbacks( TRUE );
+ pEditEngine->Clear();
+ pParaList->Clear( TRUE );
+ pParaList->Insert( new Paragraph( nMinDepth ), LIST_APPEND );
+ bFirstParaIsEmpty = TRUE;
+ ImplBlockInsertionCallbacks( FALSE );
+ }
+ else
+ {
+ Paragraph* pPara = pParaList->GetParagraph( 0 );
+ if(pPara)
+ pPara->SetDepth( nMinDepth );
+ }
+}
+
+void Outliner::SetFlatMode( BOOL bFlat )
+{
+ DBG_CHKTHIS(Outliner,0);
+
+ if( bFlat != pEditEngine->IsFlatMode() )
+ {
+ for ( USHORT nPara = (USHORT)pParaList->GetParagraphCount(); nPara; )
+ pParaList->GetParagraph( --nPara )->aBulSize.Width() = -1;
+
+ pEditEngine->SetFlatMode( bFlat );
+ }
+}
+
+String Outliner::ImplGetBulletText( USHORT nPara )
+{
+ String aRes;
+ Paragraph* pPara = pParaList->GetParagraph( nPara );
+ if (pPara)
+ {
+ // MT: Optimierung mal wieder aktivieren...
+// if( pPara->nFlags & PARAFLAG_SETBULLETTEXT )
+ ImplCalcBulletText( nPara, FALSE, FALSE );
+ aRes = pPara->GetText();
+ }
+ return aRes;
+}
+
+// this is needed for StarOffice Api
+void Outliner::SetLevelDependendStyleSheet( USHORT nPara )
+{
+ SfxItemSet aOldAttrs( pEditEngine->GetParaAttribs( nPara ) );
+ ImplSetLevelDependendStyleSheet( nPara );
+ pEditEngine->SetParaAttribs( nPara, aOldAttrs );
+}
+
+SV_IMPL_PTRARR( NotifyList, EENotifyPtr );
+
+void Outliner::ImplBlockInsertionCallbacks( BOOL b )
+{
+ if ( b )
+ {
+ bBlockInsCallback++;
+ }
+ else
+ {
+ DBG_ASSERT( bBlockInsCallback, "ImplBlockInsertionCallbacks ?!" );
+ bBlockInsCallback--;
+ if ( !bBlockInsCallback )
+ {
+ // Call blocked notify events...
+ while ( pEditEngine->aNotifyCache.Count() )
+ {
+ EENotify* pNotify = pEditEngine->aNotifyCache[0];
+ // Remove from list before calling, maybe we enter LeaveBlockNotifications while calling the handler...
+ pEditEngine->aNotifyCache.Remove( 0 );
+ pEditEngine->aOutlinerNotifyHdl.Call( pNotify );
+ delete pNotify;
+ }
+ }
+ }
+}
+
+IMPL_LINK( Outliner, EditEngineNotifyHdl, EENotify*, pNotify )
+{
+ if ( !bBlockInsCallback )
+ {
+ pEditEngine->aOutlinerNotifyHdl.Call( pNotify );
+ }
+ else
+ {
+ EENotify* pNewNotify = new EENotify( *pNotify );
+ pEditEngine->aNotifyCache.Insert( pNewNotify, pEditEngine->aNotifyCache.Count() );
+ }
+
+ return 0;
+}
+
+/** sets a link that is called at the beginning of a drag operation at an edit view */
+void Outliner::SetBeginDropHdl( const Link& rLink )
+{
+ pEditEngine->SetBeginDropHdl( rLink );
+}
+
+Link Outliner::GetBeginDropHdl() const
+{
+ return pEditEngine->GetBeginDropHdl();
+}
+
+/** sets a link that is called at the end of a drag operation at an edit view */
+void Outliner::SetEndDropHdl( const Link& rLink )
+{
+ pEditEngine->SetEndDropHdl( rLink );
+}
+
+Link Outliner::GetEndDropHdl() const
+{
+ return pEditEngine->GetEndDropHdl();
+}
+
+/** sets a link that is called before a drop or paste operation. */
+void Outliner::SetBeginPasteOrDropHdl( const Link& rLink )
+{
+ maBeginPasteOrDropHdl = rLink;
+}
+
+/** sets a link that is called after a drop or paste operation. */
+void Outliner::SetEndPasteOrDropHdl( const Link& rLink )
+{
+ maEndPasteOrDropHdl = rLink;
+}
+
+void Outliner::SetParaFlag( Paragraph* pPara, sal_uInt16 nFlag )
+{
+ if( pPara && !pPara->HasFlag( nFlag ) )
+ {
+ if( IsUndoEnabled() && !IsInUndo() )
+ InsertUndo( new OutlinerUndoChangeParaFlags( this, (sal_uInt16)GetAbsPos( pPara ), pPara->nFlags, pPara->nFlags|nFlag ) );
+
+ pPara->SetFlag( nFlag );
+ }
+}
+
+void Outliner::RemoveParaFlag( Paragraph* pPara, sal_uInt16 nFlag )
+{
+ if( pPara && pPara->HasFlag( nFlag ) )
+ {
+ if( IsUndoEnabled() && !IsInUndo() )
+ InsertUndo( new OutlinerUndoChangeParaFlags( this, (sal_uInt16)GetAbsPos( pPara ), pPara->nFlags, pPara->nFlags & ~nFlag ) );
+
+ pPara->RemoveFlag( nFlag );
+ }
+}
+
+bool Outliner::HasParaFlag( const Paragraph* pPara, sal_uInt16 nFlag ) const
+{
+ return pPara && pPara->HasFlag( nFlag );
+}
+
+
+sal_Bool DrawPortionInfo::IsRTL() const
+{
+ if(0xFF == mnBiDiLevel)
+ {
+ // Use Bidi functions from icu 2.0 to calculate if this portion
+ // is RTL or not.
+ UErrorCode nError(U_ZERO_ERROR);
+ UBiDi* pBidi = ubidi_openSized(mrText.Len(), 0, &nError);
+ nError = U_ZERO_ERROR;
+
+ // I do not have this info here. Is it necessary? I'll have to ask MT.
+ const BYTE nDefaultDir = UBIDI_LTR; //IsRightToLeft( nPara ) ? UBIDI_RTL : UBIDI_LTR;
+
+ ubidi_setPara(pBidi, reinterpret_cast<const UChar *>(mrText.GetBuffer()), mrText.Len(), nDefaultDir, NULL, &nError); // UChar != sal_Unicode in MinGW
+ nError = U_ZERO_ERROR;
+
+// sal_Int32 nCount(ubidi_countRuns(pBidi, &nError));
+
+ int32_t nStart(0);
+ int32_t nEnd;
+ UBiDiLevel nCurrDir;
+
+ ubidi_getLogicalRun(pBidi, nStart, &nEnd, &nCurrDir);
+
+ ubidi_close(pBidi);
+
+ // remember on-demand calculated state
+ ((DrawPortionInfo*)this)->mnBiDiLevel = nCurrDir;
+ }
+
+ return (1 == (mnBiDiLevel % 2));
+}
+
+// eof
diff --git a/editeng/source/outliner/outliner.src b/editeng/source/outliner/outliner.src
new file mode 100644
index 0000000000..6cbd46d3ce
--- /dev/null
+++ b/editeng/source/outliner/outliner.src
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: outliner.src,v $
+ * $Revision: 1.20 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <editeng/editrids.hrc>
+
+String RID_OUTLUNDO_HEIGHT
+{
+ Text [ en-US ] = "Move" ;
+};
+String RID_OUTLUNDO_DEPTH
+{
+ Text [ en-US ] = "Indent" ;
+};
+String RID_OUTLUNDO_EXPAND
+{
+ Text [ en-US ] = "Show subpoints" ;
+};
+String RID_OUTLUNDO_COLLAPSE
+{
+ Text [ en-US ] = "Collapse" ;
+};
+String RID_OUTLUNDO_ATTR
+{
+ Text [ en-US ] = "Apply attributes" ;
+};
+String RID_OUTLUNDO_INSERT
+{
+ Text [ en-US ] = "Insert" ;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/editeng/source/outliner/outlobj.cxx b/editeng/source/outliner/outlobj.cxx
new file mode 100644
index 0000000000..00b70f8899
--- /dev/null
+++ b/editeng/source/outliner/outlobj.cxx
@@ -0,0 +1,274 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: outlobj.cxx,v $
+ * $Revision: 1.12.78.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <outl_pch.hxx>
+
+#define _OUTLINER_CXX
+#include <editeng/outliner.hxx>
+#include <editeng/outlobj.hxx>
+#include <outleeng.hxx>
+#include <editeng/editobj.hxx>
+#include <vcl/bitmap.hxx>
+#include <tools/stream.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+class ImplOutlinerParaObject
+{
+public:
+ // data members
+ EditTextObject* mpEditTextObject;
+ ParagraphDataVector maParagraphDataVector;
+ bool mbIsEditDoc;
+
+ // refcounter
+ sal_uInt32 mnRefCount;
+
+ // constuctor
+ ImplOutlinerParaObject(EditTextObject* pEditTextObject, const ParagraphDataVector& rParagraphDataVector, bool bIsEditDoc)
+ : mpEditTextObject(pEditTextObject),
+ maParagraphDataVector(rParagraphDataVector),
+ mbIsEditDoc(bIsEditDoc),
+ mnRefCount(0)
+ {
+ if( (maParagraphDataVector.size() == 0) && (pEditTextObject->GetParagraphCount() != 0) )
+ maParagraphDataVector.resize(pEditTextObject->GetParagraphCount());
+ }
+
+ // destructor
+ ~ImplOutlinerParaObject()
+ {
+ delete mpEditTextObject;
+ }
+
+ bool operator==(const ImplOutlinerParaObject& rCandidate) const
+ {
+ return (*mpEditTextObject == *rCandidate.mpEditTextObject
+ && maParagraphDataVector == rCandidate.maParagraphDataVector
+ && mbIsEditDoc == rCandidate.mbIsEditDoc);
+ }
+
+ // #i102062#
+ bool isWrongListEqual(const ImplOutlinerParaObject& rCompare) const
+ {
+ return mpEditTextObject->isWrongListEqual(*rCompare.mpEditTextObject);
+ }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+void OutlinerParaObject::ImplMakeUnique()
+{
+ if(mpImplOutlinerParaObject->mnRefCount)
+ {
+ ImplOutlinerParaObject* pNew = new ImplOutlinerParaObject(
+ mpImplOutlinerParaObject->mpEditTextObject->Clone(),
+ mpImplOutlinerParaObject->maParagraphDataVector,
+ mpImplOutlinerParaObject->mbIsEditDoc);
+ mpImplOutlinerParaObject->mnRefCount--;
+ mpImplOutlinerParaObject = pNew;
+ }
+}
+
+OutlinerParaObject::OutlinerParaObject(const EditTextObject& rEditTextObject, const ParagraphDataVector& rParagraphDataVector, bool bIsEditDoc)
+: mpImplOutlinerParaObject(new ImplOutlinerParaObject(rEditTextObject.Clone(), rParagraphDataVector, bIsEditDoc))
+{
+}
+
+OutlinerParaObject::OutlinerParaObject(const OutlinerParaObject& rCandidate)
+: mpImplOutlinerParaObject(rCandidate.mpImplOutlinerParaObject)
+{
+ mpImplOutlinerParaObject->mnRefCount++;
+}
+
+OutlinerParaObject::~OutlinerParaObject()
+{
+ if(mpImplOutlinerParaObject->mnRefCount)
+ {
+ mpImplOutlinerParaObject->mnRefCount--;
+ }
+ else
+ {
+ delete mpImplOutlinerParaObject;
+ }
+}
+
+OutlinerParaObject& OutlinerParaObject::operator=(const OutlinerParaObject& rCandidate)
+{
+ if(rCandidate.mpImplOutlinerParaObject != mpImplOutlinerParaObject)
+ {
+ if(mpImplOutlinerParaObject->mnRefCount)
+ {
+ mpImplOutlinerParaObject->mnRefCount--;
+ }
+ else
+ {
+ delete mpImplOutlinerParaObject;
+ }
+
+ mpImplOutlinerParaObject = rCandidate.mpImplOutlinerParaObject;
+ mpImplOutlinerParaObject->mnRefCount++;
+ }
+
+ return *this;
+}
+
+bool OutlinerParaObject::operator==(const OutlinerParaObject& rCandidate) const
+{
+ if(rCandidate.mpImplOutlinerParaObject == mpImplOutlinerParaObject)
+ {
+ return true;
+ }
+
+ return (*rCandidate.mpImplOutlinerParaObject == *mpImplOutlinerParaObject);
+}
+
+// #i102062#
+bool OutlinerParaObject::isWrongListEqual(const OutlinerParaObject& rCompare) const
+{
+ if(rCompare.mpImplOutlinerParaObject == mpImplOutlinerParaObject)
+ {
+ return true;
+ }
+
+ return mpImplOutlinerParaObject->isWrongListEqual(*rCompare.mpImplOutlinerParaObject);
+}
+
+sal_uInt16 OutlinerParaObject::GetOutlinerMode() const
+{
+ return mpImplOutlinerParaObject->mpEditTextObject->GetUserType();
+}
+
+void OutlinerParaObject::SetOutlinerMode(sal_uInt16 nNew)
+{
+ if(mpImplOutlinerParaObject->mpEditTextObject->GetUserType() != nNew)
+ {
+ ImplMakeUnique();
+ mpImplOutlinerParaObject->mpEditTextObject->SetUserType(nNew);
+ }
+}
+
+bool OutlinerParaObject::IsVertical() const
+{
+ return mpImplOutlinerParaObject->mpEditTextObject->IsVertical();
+}
+
+void OutlinerParaObject::SetVertical(bool bNew)
+{
+ if((bool)mpImplOutlinerParaObject->mpEditTextObject->IsVertical() != bNew)
+ {
+ ImplMakeUnique();
+ mpImplOutlinerParaObject->mpEditTextObject->SetVertical(bNew);
+ }
+}
+
+sal_uInt32 OutlinerParaObject::Count() const
+{
+ return mpImplOutlinerParaObject->maParagraphDataVector.size();
+}
+
+sal_Int16 OutlinerParaObject::GetDepth(sal_uInt16 nPara) const
+{
+ if(nPara < mpImplOutlinerParaObject->maParagraphDataVector.size())
+ {
+ return mpImplOutlinerParaObject->maParagraphDataVector[nPara].getDepth();
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+const EditTextObject& OutlinerParaObject::GetTextObject() const
+{
+ return *mpImplOutlinerParaObject->mpEditTextObject;
+}
+
+bool OutlinerParaObject::IsEditDoc() const
+{
+ return mpImplOutlinerParaObject->mbIsEditDoc;
+}
+
+const ParagraphData& OutlinerParaObject::GetParagraphData(sal_uInt32 nIndex) const
+{
+ if(nIndex < mpImplOutlinerParaObject->maParagraphDataVector.size())
+ {
+ return mpImplOutlinerParaObject->maParagraphDataVector[nIndex];
+ }
+ else
+ {
+ OSL_ENSURE(false, "OutlinerParaObject::GetParagraphData: Access out of range (!)");
+ static ParagraphData aEmptyParagraphData;
+ return aEmptyParagraphData;
+ }
+}
+
+void OutlinerParaObject::ClearPortionInfo()
+{
+ ImplMakeUnique();
+ mpImplOutlinerParaObject->mpEditTextObject->ClearPortionInfo();
+}
+
+bool OutlinerParaObject::ChangeStyleSheets(const XubString& rOldName, SfxStyleFamily eOldFamily, const XubString& rNewName, SfxStyleFamily eNewFamily)
+{
+ ImplMakeUnique();
+ return mpImplOutlinerParaObject->mpEditTextObject->ChangeStyleSheets(rOldName, eOldFamily, rNewName, eNewFamily);
+}
+
+void OutlinerParaObject::ChangeStyleSheetName(SfxStyleFamily eFamily, const XubString& rOldName, const XubString& rNewName)
+{
+ ImplMakeUnique();
+ mpImplOutlinerParaObject->mpEditTextObject->ChangeStyleSheetName(eFamily, rOldName, rNewName);
+}
+
+void OutlinerParaObject::SetStyleSheets(sal_uInt16 nLevel, const XubString rNewName, const SfxStyleFamily& rNewFamily)
+{
+ const sal_uInt32 nCount(mpImplOutlinerParaObject->maParagraphDataVector.size());
+
+ if(nCount)
+ {
+ ImplMakeUnique();
+ sal_uInt16 nDecrementer(sal::static_int_cast< sal_uInt16 >(nCount));
+
+ for(;nDecrementer;)
+ {
+ if(GetDepth(--nDecrementer) == nLevel)
+ {
+ mpImplOutlinerParaObject->mpEditTextObject->SetStyleSheet(nDecrementer, rNewName, rNewFamily);
+ }
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/editeng/source/outliner/outlundo.cxx b/editeng/source/outliner/outlundo.cxx
new file mode 100644
index 0000000000..f5e8116bb7
--- /dev/null
+++ b/editeng/source/outliner/outlundo.cxx
@@ -0,0 +1,237 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: outlundo.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <svl/intitem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/eerdll.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/fhgtitem.hxx>
+
+#define _OUTLINER_CXX
+#include <editeng/outliner.hxx>
+#include <outlundo.hxx>
+
+
+OutlinerUndoBase::OutlinerUndoBase( USHORT _nId, Outliner* pOutliner )
+ : EditUndo( _nId, NULL )
+{
+ DBG_ASSERT( pOutliner, "Undo: Outliner?!" );
+ mpOutliner = pOutliner;
+}
+
+OutlinerUndoChangeParaFlags::OutlinerUndoChangeParaFlags( Outliner* pOutliner, sal_uInt16 nPara, sal_uInt16 nOldFlags, sal_uInt16 nNewFlags )
+: OutlinerUndoBase( OLUNDO_DEPTH, pOutliner )
+{
+ mnPara = nPara;
+ mnOldFlags = nOldFlags;
+ mnNewFlags = nNewFlags;
+}
+
+void OutlinerUndoChangeParaFlags::Undo()
+{
+ ImplChangeFlags( mnOldFlags );
+}
+
+void OutlinerUndoChangeParaFlags::Redo()
+{
+ ImplChangeFlags( mnNewFlags );
+}
+
+void OutlinerUndoChangeParaFlags::ImplChangeFlags( sal_uInt16 nFlags )
+{
+ Outliner* pOutliner = GetOutliner();
+ Paragraph* pPara = pOutliner->GetParagraph( mnPara );
+ if( pPara )
+ {
+ pOutliner->nDepthChangedHdlPrevDepth = pPara->GetDepth();
+ pOutliner->mnDepthChangeHdlPrevFlags = pPara->nFlags;
+ pOutliner->pHdlParagraph = pPara;
+
+ pPara->nFlags = nFlags;
+ pOutliner->DepthChangedHdl();
+ }
+}
+
+OutlinerUndoChangeParaNumberingRestart::OutlinerUndoChangeParaNumberingRestart( Outliner* pOutliner, sal_uInt16 nPara,
+ sal_Int16 nOldNumberingStartValue, sal_Int16 nNewNumberingStartValue,
+ sal_Bool bOldParaIsNumberingRestart, sal_Bool bNewParaIsNumberingRestart )
+: OutlinerUndoBase( OLUNDO_DEPTH, pOutliner )
+{
+ mnPara = nPara;
+
+ maUndoData.mnNumberingStartValue = nOldNumberingStartValue;
+ maUndoData.mbParaIsNumberingRestart = bOldParaIsNumberingRestart;
+ maRedoData.mnNumberingStartValue = nNewNumberingStartValue;
+ maRedoData.mbParaIsNumberingRestart = bNewParaIsNumberingRestart;
+}
+
+void OutlinerUndoChangeParaNumberingRestart::Undo()
+{
+ ImplApplyData( maUndoData );
+}
+
+void OutlinerUndoChangeParaNumberingRestart::Redo()
+{
+ ImplApplyData( maRedoData );
+}
+
+void OutlinerUndoChangeParaNumberingRestart::ImplApplyData( const ParaRestartData& rData )
+{
+ Outliner* pOutliner = GetOutliner();
+ pOutliner->SetNumberingStartValue( mnPara, rData.mnNumberingStartValue );
+ pOutliner->SetParaIsNumberingRestart( mnPara, rData.mbParaIsNumberingRestart );
+}
+
+OutlinerUndoChangeDepth::OutlinerUndoChangeDepth( Outliner* pOutliner, USHORT nPara, sal_Int16 nOldDepth, sal_Int16 nNewDepth )
+ : OutlinerUndoBase( OLUNDO_DEPTH, pOutliner )
+{
+ mnPara = nPara;
+ mnOldDepth = nOldDepth;
+ mnNewDepth = nNewDepth;
+}
+
+void OutlinerUndoChangeDepth::Undo()
+{
+ GetOutliner()->ImplInitDepth( mnPara, mnOldDepth, FALSE );
+}
+
+void OutlinerUndoChangeDepth::Redo()
+{
+ GetOutliner()->ImplInitDepth( mnPara, mnNewDepth, FALSE );
+}
+
+void OutlinerUndoChangeDepth::Repeat()
+{
+ DBG_ERROR( "Repeat not implemented!" );
+}
+
+
+OutlinerUndoCheckPara::OutlinerUndoCheckPara( Outliner* pOutliner, USHORT nPara )
+ : OutlinerUndoBase( OLUNDO_DEPTH, pOutliner )
+{
+ mnPara = nPara;
+}
+
+void OutlinerUndoCheckPara::Undo()
+{
+ Paragraph* pPara = GetOutliner()->GetParagraph( mnPara );
+ pPara->Invalidate();
+ GetOutliner()->ImplCalcBulletText( mnPara, FALSE, FALSE );
+}
+
+void OutlinerUndoCheckPara::Redo()
+{
+ Paragraph* pPara = GetOutliner()->GetParagraph( mnPara );
+ pPara->Invalidate();
+ GetOutliner()->ImplCalcBulletText( mnPara, FALSE, FALSE );
+}
+
+void OutlinerUndoCheckPara::Repeat()
+{
+ DBG_ERROR( "Repeat not implemented!" );
+}
+
+DBG_NAME(OLUndoExpand);
+
+OLUndoExpand::OLUndoExpand(Outliner* pOut, USHORT _nId )
+ : EditUndo( _nId, 0 )
+{
+ DBG_CTOR(OLUndoExpand,0);
+ DBG_ASSERT(pOut,"Undo:No Outliner");
+ pOutliner = pOut;
+ nCount = 0;
+ pParas = 0;
+}
+
+
+OLUndoExpand::~OLUndoExpand()
+{
+ DBG_DTOR(OLUndoExpand,0);
+ delete pParas;
+}
+
+
+void OLUndoExpand::Restore( BOOL bUndo )
+{
+ DBG_CHKTHIS(OLUndoExpand,0);
+ DBG_ASSERT(pOutliner,"Undo:No Outliner");
+ DBG_ASSERT(pOutliner->pEditEngine,"Outliner already deleted");
+ Paragraph* pPara;
+
+ BOOL bExpand = FALSE;
+ USHORT _nId = GetId();
+ if((_nId == OLUNDO_EXPAND && !bUndo) || (_nId == OLUNDO_COLLAPSE && bUndo))
+ bExpand = TRUE;
+ if( !pParas )
+ {
+ pPara = pOutliner->GetParagraph( (ULONG)nCount );
+ if( bExpand )
+ pOutliner->Expand( pPara );
+ else
+ pOutliner->Collapse( pPara );
+ }
+ else
+ {
+ for( USHORT nIdx = 0; nIdx < nCount; nIdx++ )
+ {
+ pPara = pOutliner->GetParagraph( (ULONG)(pParas[nIdx]) );
+ if( bExpand )
+ pOutliner->Expand( pPara );
+ else
+ pOutliner->Collapse( pPara );
+ }
+ }
+}
+
+
+void OLUndoExpand::Undo()
+{
+ DBG_CHKTHIS(OLUndoExpand,0);
+ Restore( TRUE );
+}
+
+
+void OLUndoExpand::Redo()
+{
+ DBG_CHKTHIS(OLUndoExpand,0);
+ Restore( FALSE );
+}
+
+
+void OLUndoExpand::Repeat()
+{
+ DBG_CHKTHIS(OLUndoExpand,0);
+ DBG_ERROR("Not implemented");
+}
diff --git a/editeng/source/outliner/outlundo.hxx b/editeng/source/outliner/outlundo.hxx
new file mode 100644
index 0000000000..c79aee8ec1
--- /dev/null
+++ b/editeng/source/outliner/outlundo.hxx
@@ -0,0 +1,143 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: outlundo.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _OUTLUNDO_HXX
+#define _OUTLUNDO_HXX
+
+#include <editeng/outliner.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/editund2.hxx>
+
+class OutlinerUndoBase : public EditUndo
+{
+private:
+ Outliner* mpOutliner;
+
+public:
+ OutlinerUndoBase( USHORT nId, Outliner* pOutliner );
+
+ Outliner* GetOutliner() const { return mpOutliner; }
+};
+
+class OutlinerUndoChangeParaFlags : public OutlinerUndoBase
+{
+private:
+ sal_uInt16 mnPara;
+ sal_uInt16 mnOldFlags;
+ sal_uInt16 mnNewFlags;
+
+ void ImplChangeFlags( sal_uInt16 nFlags );
+
+public:
+ OutlinerUndoChangeParaFlags( Outliner* pOutliner, sal_uInt16 nPara, sal_uInt16 nOldDepth, sal_uInt16 nNewDepth );
+
+ virtual void Undo();
+ virtual void Redo();
+};
+
+class OutlinerUndoChangeParaNumberingRestart : public OutlinerUndoBase
+{
+private:
+ sal_uInt16 mnPara;
+
+ struct ParaRestartData
+ {
+ sal_Int16 mnNumberingStartValue;
+ sal_Bool mbParaIsNumberingRestart;
+ };
+
+ ParaRestartData maUndoData;
+ ParaRestartData maRedoData;
+
+ void ImplApplyData( const ParaRestartData& rData );
+public:
+ OutlinerUndoChangeParaNumberingRestart( Outliner* pOutliner, sal_uInt16 nPara,
+ sal_Int16 nOldNumberingStartValue, sal_Int16 mnNewNumberingStartValue,
+ sal_Bool nOldbParaIsNumberingRestart, sal_Bool nbNewParaIsNumberingRestart );
+
+ virtual void Undo();
+ virtual void Redo();
+};
+
+class OutlinerUndoChangeDepth : public OutlinerUndoBase
+{
+ using SfxUndoAction::Repeat;
+private:
+ USHORT mnPara;
+ sal_Int16 mnOldDepth;
+ sal_Int16 mnNewDepth;
+
+public:
+ OutlinerUndoChangeDepth( Outliner* pOutliner, USHORT nPara, sal_Int16 nOldDepth, sal_Int16 nNewDepth );
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat();
+};
+
+// Hilfs-Undo: Wenn es fuer eine Aktion keine OutlinerUndoAction gibst, weil
+// die EditEngine das handelt, aber z.B. noch das Bullet neu berechnet werden muss.
+
+class OutlinerUndoCheckPara : public OutlinerUndoBase
+{
+ using SfxUndoAction::Repeat;
+private:
+ USHORT mnPara;
+
+public:
+ OutlinerUndoCheckPara( Outliner* pOutliner, USHORT nPara );
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat();
+};
+
+
+
+// -------------------------------------
+
+
+class OLUndoExpand : public EditUndo
+{
+ using SfxUndoAction::Repeat;
+ void Restore( BOOL bUndo );
+public:
+ OLUndoExpand( Outliner* pOut, USHORT nId );
+ ~OLUndoExpand();
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat();
+
+ USHORT* pParas; // 0 == nCount enthaelt Absatznummer
+ Outliner* pOutliner;
+ USHORT nCount;
+};
+
+#endif
diff --git a/editeng/source/outliner/outlvw.cxx b/editeng/source/outliner/outlvw.cxx
new file mode 100644
index 0000000000..64cedbf970
--- /dev/null
+++ b/editeng/source/outliner/outlvw.cxx
@@ -0,0 +1,1663 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: outlvw.cxx,v $
+ * $Revision: 1.34.150.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <svl/intitem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/eerdll.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <svl/style.hxx>
+
+#define _OUTLINER_CXX
+#include <editeng/outliner.hxx>
+#include <outleeng.hxx>
+#include <paralist.hxx>
+#include <outlundo.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/numitem.hxx>
+#include <vcl/window.hxx>
+#include <svl/itemset.hxx>
+#include <editeng/editstat.hxx>
+
+
+// Breite der Randzonen innerhalb derer beim D&D gescrollt wird
+#define OL_SCROLL_LRBORDERWIDTHPIX 10
+#define OL_SCROLL_TBBORDERWIDTHPIX 10
+
+// Wert, um den Fensterinhalt beim D&D gescrollt wird
+#define OL_SCROLL_HOROFFSET 20 /* in % von VisibleSize.Width */
+#define OL_SCROLL_VEROFFSET 20 /* in % von VisibleSize.Height */
+
+DBG_NAME(OutlinerView)
+
+
+OutlinerView::OutlinerView( Outliner* pOut, Window* pWin )
+{
+ DBG_CTOR( OutlinerView, 0 );
+
+ pOwner = pOut;
+ bDDCursorVisible = FALSE;
+ bInDragMode = FALSE;
+ nDDScrollLRBorderWidthWin = 0;
+ nDDScrollTBBorderWidthWin = 0;
+ pHorTabArrDoc = 0;
+
+ pEditView = new EditView( pOut->pEditEngine, pWin );
+ pEditView->SetSelectionMode( EE_SELMODE_TXTONLY );
+}
+
+OutlinerView::~OutlinerView()
+{
+ DBG_DTOR(OutlinerView,0);
+ delete pEditView;
+}
+
+void OutlinerView::Paint( const Rectangle& rRect )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+
+ // beim ersten Paint/KeyInput/Drop wird aus einem leeren Outliner ein
+ // Outliner mit genau einem Absatz
+ if( pOwner->bFirstParaIsEmpty )
+ pOwner->Insert( String() );
+
+ pEditView->Paint( rRect );
+}
+
+BOOL OutlinerView::PostKeyEvent( const KeyEvent& rKEvt )
+{
+ DBG_CHKTHIS( OutlinerView, 0 );
+
+ // beim ersten Paint/KeyInput/Drop wird aus einem leeren Outliner ein
+ // Outliner mit genau einem Absatz
+ if( pOwner->bFirstParaIsEmpty )
+ pOwner->Insert( String() );
+
+
+ BOOL bKeyProcessed = FALSE;
+ ESelection aSel( pEditView->GetSelection() );
+ BOOL bSelection = aSel.HasRange();
+ KeyCode aKeyCode = rKEvt.GetKeyCode();
+ KeyFuncType eFunc = aKeyCode.GetFunction();
+ USHORT nCode = aKeyCode.GetCode();
+ BOOL bReadOnly = IsReadOnly();
+
+ if( bSelection && ( nCode != KEY_TAB ) && EditEngine::DoesKeyChangeText( rKEvt ) )
+ {
+ if ( ImpCalcSelectedPages( FALSE ) && !pOwner->ImpCanDeleteSelectedPages( this ) )
+ return TRUE;
+ }
+
+ if ( eFunc != KEYFUNC_DONTKNOW )
+ {
+ switch ( eFunc )
+ {
+ case KEYFUNC_CUT:
+ {
+ if ( !bReadOnly )
+ {
+ Cut();
+ bKeyProcessed = TRUE;
+ }
+ }
+ break;
+ case KEYFUNC_COPY:
+ {
+ Copy();
+ bKeyProcessed = TRUE;
+ }
+ break;
+ case KEYFUNC_PASTE:
+ {
+ if ( !bReadOnly )
+ {
+ PasteSpecial();
+ bKeyProcessed = TRUE;
+ }
+ }
+ break;
+ case KEYFUNC_DELETE:
+ {
+ if( !bReadOnly && !bSelection && ( pOwner->ImplGetOutlinerMode() != OUTLINERMODE_TEXTOBJECT ) )
+ {
+ if( aSel.nEndPos == pOwner->pEditEngine->GetTextLen( aSel.nEndPara ) )
+ {
+ Paragraph* pNext = pOwner->pParaList->GetParagraph( aSel.nEndPara+1 );
+ if( pNext && pNext->HasFlag(PARAFLAG_ISPAGE) )
+ {
+ if( !pOwner->ImpCanDeleteSelectedPages( this, aSel.nEndPara, 1 ) )
+ return FALSE;
+ }
+ }
+ }
+ }
+ break;
+ default: // wird dann evtl. unten bearbeitet.
+ eFunc = KEYFUNC_DONTKNOW;
+ }
+ }
+ if ( eFunc == KEYFUNC_DONTKNOW )
+ {
+ switch ( nCode )
+ {
+ case KEY_TAB:
+ {
+ if ( !bReadOnly && !aKeyCode.IsMod1() && !aKeyCode.IsMod2() )
+ {
+ if ( ( pOwner->ImplGetOutlinerMode() != OUTLINERMODE_TEXTOBJECT ) &&
+ ( pOwner->ImplGetOutlinerMode() != OUTLINERMODE_TITLEOBJECT ) &&
+ ( bSelection || !aSel.nStartPos ) )
+ {
+ Indent( aKeyCode.IsShift() ? (-1) : (+1) );
+ bKeyProcessed = TRUE;
+ }
+ else if ( ( pOwner->ImplGetOutlinerMode() == OUTLINERMODE_TEXTOBJECT ) &&
+ !bSelection && !aSel.nEndPos && pOwner->ImplHasBullet( aSel.nEndPara ) )
+ {
+ Indent( aKeyCode.IsShift() ? (-1) : (+1) );
+ bKeyProcessed = TRUE;
+ }
+ }
+ }
+ break;
+ case KEY_BACKSPACE:
+ {
+ if( !bReadOnly && !bSelection && aSel.nEndPara && !aSel.nEndPos )
+ {
+ Paragraph* pPara = pOwner->pParaList->GetParagraph( aSel.nEndPara );
+ Paragraph* pPrev = pOwner->pParaList->GetParagraph( aSel.nEndPara-1 );
+ if( !pPrev->IsVisible() )
+ return TRUE;
+ if( !pPara->GetDepth() )
+ {
+ if(!pOwner->ImpCanDeleteSelectedPages(this, aSel.nEndPara , 1 ) )
+ return TRUE;
+ }
+ }
+ }
+ break;
+ case KEY_RETURN:
+ {
+ if ( !bReadOnly )
+ {
+ // Sonderbehandlung: Hartes Return am Ende eines Absatzes,
+ // der eingeklappte Unterabsaetze besitzt
+ Paragraph* pPara = pOwner->pParaList->GetParagraph( aSel.nEndPara );
+
+ if( !aKeyCode.IsShift() )
+ {
+ // Nochmal ImpGetCursor ???
+ if( !bSelection &&
+ aSel.nEndPos == pOwner->pEditEngine->GetTextLen( aSel.nEndPara ) )
+ {
+ ULONG nChilds = pOwner->pParaList->GetChildCount(pPara);
+ if( nChilds && !pOwner->pParaList->HasVisibleChilds(pPara))
+ {
+ pOwner->UndoActionStart( OLUNDO_INSERT );
+ ULONG nTemp = aSel.nEndPara;
+ nTemp += nChilds;
+ nTemp++; // einfuegen ueber naechstem Non-Child
+ pOwner->Insert( String(),nTemp,pPara->GetDepth());
+ // Cursor positionieren
+ ESelection aTmpSel((USHORT)nTemp,0,(USHORT)nTemp,0);
+ pEditView->SetSelection( aTmpSel );
+ pEditView->ShowCursor( TRUE, TRUE );
+ pOwner->UndoActionEnd( OLUNDO_INSERT );
+ bKeyProcessed = TRUE;
+ }
+ }
+ }
+ if( !bKeyProcessed && !bSelection &&
+ !aKeyCode.IsShift() && aKeyCode.IsMod1() &&
+ ( aSel.nEndPos == pOwner->pEditEngine->GetTextLen(aSel.nEndPara) ) )
+ {
+ pOwner->UndoActionStart( OLUNDO_INSERT );
+ ULONG nTemp = aSel.nEndPara;
+ nTemp++;
+ pOwner->Insert( String(), nTemp, pPara->GetDepth()+1 );
+
+ // Cursor positionieren
+ ESelection aTmpSel((USHORT)nTemp,0,(USHORT)nTemp,0);
+ pEditView->SetSelection( aTmpSel );
+ pEditView->ShowCursor( TRUE, TRUE );
+ pOwner->UndoActionEnd( OLUNDO_INSERT );
+ bKeyProcessed = TRUE;
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ return bKeyProcessed ? TRUE : pEditView->PostKeyEvent( rKEvt );
+}
+
+
+ULONG OutlinerView::ImpCheckMousePos(const Point& rPosPix, MouseTarget& reTarget)
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ ULONG nPara = EE_PARA_NOT_FOUND;
+
+ Point aMousePosWin = pEditView->GetWindow()->PixelToLogic( rPosPix );
+ if( !pEditView->GetOutputArea().IsInside( aMousePosWin ) )
+ {
+ reTarget = MouseOutside;
+ }
+ else
+ {
+ reTarget = MouseText;
+
+ Point aPaperPos( aMousePosWin );
+ Rectangle aOutArea = pEditView->GetOutputArea();
+ Rectangle aVisArea = pEditView->GetVisArea();
+ aPaperPos.X() -= aOutArea.Left();
+ aPaperPos.X() += aVisArea.Left();
+ aPaperPos.Y() -= aOutArea.Top();
+ aPaperPos.Y() += aVisArea.Top();
+
+ BOOL bBullet;
+ if ( pOwner->IsTextPos( aPaperPos, 0, &bBullet ) )
+ {
+ Point aDocPos = pOwner->GetDocPos( aPaperPos );
+ nPara = pOwner->pEditEngine->FindParagraph( aDocPos.Y() );
+
+ if ( bBullet )
+ {
+ reTarget = MouseBullet;
+ }
+ else
+ {
+ // Check for hyperlink
+ const SvxFieldItem* pFieldItem = pEditView->GetField( aMousePosWin );
+ if ( pFieldItem && pFieldItem->GetField() && pFieldItem->GetField()->ISA( SvxURLField ) )
+ reTarget = MouseHypertext;
+ }
+ }
+ }
+ return nPara;
+}
+
+BOOL __EXPORT OutlinerView::MouseMove( const MouseEvent& rMEvt )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+
+ if( ( pOwner->ImplGetOutlinerMode() == OUTLINERMODE_TEXTOBJECT ) || pEditView->GetEditEngine()->IsInSelectionMode())
+ return pEditView->MouseMove( rMEvt );
+
+ Point aMousePosWin( pEditView->GetWindow()->PixelToLogic( rMEvt.GetPosPixel() ) );
+ if( !pEditView->GetOutputArea().IsInside( aMousePosWin ) )
+ return FALSE;
+
+ Pointer aPointer = GetPointer( rMEvt.GetPosPixel() );
+ pEditView->GetWindow()->SetPointer( aPointer );
+ return pEditView->MouseMove( rMEvt );
+}
+
+
+BOOL __EXPORT OutlinerView::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ if ( ( pOwner->ImplGetOutlinerMode() == OUTLINERMODE_TEXTOBJECT ) || pEditView->GetEditEngine()->IsInSelectionMode() )
+ return pEditView->MouseButtonDown( rMEvt );
+
+ Point aMousePosWin( pEditView->GetWindow()->PixelToLogic( rMEvt.GetPosPixel() ) );
+ if( !pEditView->GetOutputArea().IsInside( aMousePosWin ) )
+ return FALSE;
+
+ Pointer aPointer = GetPointer( rMEvt.GetPosPixel() );
+ pEditView->GetWindow()->SetPointer( aPointer );
+
+ MouseTarget eTarget;
+ ULONG nPara = ImpCheckMousePos( rMEvt.GetPosPixel(), eTarget );
+ if ( eTarget == MouseBullet )
+ {
+ Paragraph* pPara = pOwner->pParaList->GetParagraph( nPara );
+ BOOL bHasChilds = (pPara && pOwner->pParaList->HasChilds(pPara));
+ if( rMEvt.GetClicks() == 1 )
+ {
+ ULONG nEndPara = nPara;
+ if ( bHasChilds && pOwner->pParaList->HasVisibleChilds(pPara) )
+ nEndPara += pOwner->pParaList->GetChildCount( pPara );
+ // umgekehrt rum selektieren, damit EditEngine nicht scrollt
+ ESelection aSel((USHORT)nEndPara, 0xffff,(USHORT)nPara, 0 );
+ pEditView->SetSelection( aSel );
+ }
+ else if( rMEvt.GetClicks() == 2 && bHasChilds )
+ ImpToggleExpand( pPara );
+
+ aDDStartPosPix = rMEvt.GetPosPixel();
+ aDDStartPosRef=pEditView->GetWindow()->PixelToLogic( aDDStartPosPix,pOwner->GetRefMapMode());
+ return TRUE;
+ }
+ return pEditView->MouseButtonDown( rMEvt );
+}
+
+
+BOOL __EXPORT OutlinerView::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ if ( ( pOwner->ImplGetOutlinerMode() == OUTLINERMODE_TEXTOBJECT ) || pEditView->GetEditEngine()->IsInSelectionMode() )
+ return pEditView->MouseButtonUp( rMEvt );
+
+ Point aMousePosWin( pEditView->GetWindow()->PixelToLogic( rMEvt.GetPosPixel() ) );
+ if( !pEditView->GetOutputArea().IsInside( aMousePosWin ) )
+ return FALSE;
+
+ Pointer aPointer = GetPointer( rMEvt.GetPosPixel() );
+ pEditView->GetWindow()->SetPointer( aPointer );
+
+ return pEditView->MouseButtonUp( rMEvt );
+}
+
+void OutlinerView::ImpHideDDCursor()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ if ( bDDCursorVisible )
+ {
+ bDDCursorVisible = FALSE;
+ ImpPaintDDCursor();
+ }
+}
+
+void OutlinerView::ImpShowDDCursor()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ if ( !bDDCursorVisible )
+ {
+ bDDCursorVisible = TRUE;
+ ImpPaintDDCursor();
+ }
+}
+
+void OutlinerView::ImpPaintDDCursor()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+
+ Window* pWindow = pEditView->GetWindow();
+ RasterOp eOldOp = pWindow->GetRasterOp();
+ pWindow->SetRasterOp( ROP_INVERT );
+
+ const Color& rOldLineColor = pWindow->GetLineColor();
+ pWindow->SetLineColor( Color( COL_BLACK ) );
+
+ Point aStartPointWin, aEndPointWin;
+ Rectangle aOutputArWin = pEditView->GetOutputArea();
+ Rectangle aVisAreaRef = pEditView->GetVisArea();
+
+ if( bDDChangingDepth )
+ {
+ aStartPointWin.X() = pHorTabArrDoc[ nDDCurDepth ];
+ aStartPointWin.X() += aOutputArWin.Left();
+ aStartPointWin.Y() = aOutputArWin.Top();
+ aEndPointWin.X() = aStartPointWin.X();
+ aEndPointWin.Y() = aOutputArWin.Bottom();
+ }
+ else
+ {
+ ULONG nPara = nDDCurPara;
+ if ( nDDCurPara == LIST_APPEND )
+ {
+ Paragraph* pTemp = pOwner->pParaList->LastVisible();
+ nPara = pOwner->pParaList->GetAbsPos( pTemp );
+ }
+ aStartPointWin = pEditView->GetWindowPosTopLeft((USHORT) nPara );
+ if ( nDDCurPara == LIST_APPEND )
+ {
+ long nHeight = pOwner->pEditEngine->GetTextHeight((USHORT)nPara );
+ aStartPointWin.Y() += nHeight;
+ }
+ aStartPointWin.X() = aOutputArWin.Left();
+ aEndPointWin.Y() = aStartPointWin.Y();
+ aEndPointWin.X() = aOutputArWin.Right();
+ }
+
+ pWindow->DrawLine( aStartPointWin, aEndPointWin );
+ pWindow->SetLineColor( rOldLineColor );
+ pWindow->SetRasterOp( eOldOp );
+}
+
+// Berechnet, ueber welchem Absatz eingefuegt werden muss
+
+ULONG OutlinerView::ImpGetInsertionPara( const Point& rPosPixel )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ ULONG nCurPara = pEditView->GetParagraph( rPosPixel );
+ ParagraphList* pParaList = pOwner->pParaList;
+
+ if ( nCurPara == EE_PARA_NOT_FOUND )
+ nCurPara = LIST_APPEND;
+ else
+ {
+ Point aPosWin = pEditView->GetWindow()->PixelToLogic( rPosPixel );
+ Point aParaPosWin = pEditView->GetWindowPosTopLeft((USHORT)nCurPara);
+ long nHeightRef = pOwner->pEditEngine->GetTextHeight((USHORT)nCurPara);
+ long nParaYOffs = aPosWin.Y() - aParaPosWin.Y();
+
+ if ( nParaYOffs > nHeightRef / 2 )
+ {
+ Paragraph* p = pParaList->GetParagraph( nCurPara );
+ p = pParaList->NextVisible( p );
+ nCurPara = p ? pParaList->GetAbsPos( p ) : LIST_APPEND;
+ }
+ }
+ return nCurPara;
+}
+
+
+void OutlinerView::ImpToggleExpand( Paragraph* pPara )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+
+ USHORT nPara = (USHORT) pOwner->pParaList->GetAbsPos( pPara );
+ pEditView->SetSelection( ESelection( nPara, 0, nPara, 0 ) );
+ ImplExpandOrCollaps( nPara, nPara, !pOwner->pParaList->HasVisibleChilds( pPara ) );
+ pEditView->ShowCursor();
+}
+
+
+void OutlinerView::SetOutliner( Outliner* pOutliner )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pOwner = pOutliner;
+ pEditView->SetEditEngine( pOutliner->pEditEngine );
+}
+
+
+
+ULONG OutlinerView::Select( Paragraph* pParagraph, BOOL bSelect,
+ BOOL bWithChilds )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+
+ ULONG nPara = pOwner->pParaList->GetAbsPos( pParagraph );
+ USHORT nEnd = 0;
+ if ( bSelect )
+ nEnd = 0xffff;
+
+ ULONG nChildCount = 0;
+ if ( bWithChilds )
+ nChildCount = pOwner->pParaList->GetChildCount( pParagraph );
+
+ ESelection aSel( (USHORT)nPara, 0,(USHORT)(nPara+nChildCount), nEnd );
+ pEditView->SetSelection( aSel );
+ return nChildCount+1;
+}
+
+
+void OutlinerView::SetAttribs( const SfxItemSet& rAttrs )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+
+ BOOL bUpdate = pOwner->pEditEngine->GetUpdateMode();
+ pOwner->pEditEngine->SetUpdateMode( FALSE );
+
+ if( !pOwner->IsInUndo() && pOwner->IsUndoEnabled() )
+ pOwner->UndoActionStart( OLUNDO_ATTR );
+
+ ParaRange aSel = ImpGetSelectedParagraphs( FALSE );
+
+ pEditView->SetAttribs( rAttrs );
+
+ // Bullet-Texte aktualisieren
+ for( USHORT nPara= aSel.nStartPara; nPara <= aSel.nEndPara; nPara++ )
+ {
+ pOwner->ImplCheckNumBulletItem( nPara );
+ pOwner->ImplCalcBulletText( nPara, FALSE, FALSE );
+
+ if( !pOwner->IsInUndo() && pOwner->IsUndoEnabled() )
+ pOwner->InsertUndo( new OutlinerUndoCheckPara( pOwner, nPara ) );
+ }
+
+ if( !pOwner->IsInUndo() && pOwner->IsUndoEnabled() )
+ pOwner->UndoActionEnd( OLUNDO_ATTR );
+
+ pEditView->SetEditEngineUpdateMode( bUpdate );
+}
+
+ParaRange OutlinerView::ImpGetSelectedParagraphs( BOOL bIncludeHiddenChilds )
+{
+ DBG_CHKTHIS( OutlinerView, 0 );
+
+ ESelection aSel = pEditView->GetSelection();
+ ParaRange aParas( aSel.nStartPara, aSel.nEndPara );
+ aParas.Adjust();
+
+ // unsichtbare Childs des letzten Parents in Selektion mit aufnehmen
+ if ( bIncludeHiddenChilds )
+ {
+ Paragraph* pLast = pOwner->pParaList->GetParagraph( aParas.nEndPara );
+ if ( pOwner->pParaList->HasHiddenChilds( pLast ) )
+ aParas.nEndPara =
+ sal::static_int_cast< USHORT >(
+ aParas.nEndPara +
+ pOwner->pParaList->GetChildCount( pLast ) );
+ }
+ return aParas;
+}
+
+// MT: Name sollte mal geaendert werden!
+void OutlinerView::AdjustDepth( short nDX )
+{
+ Indent( nDX );
+}
+
+void OutlinerView::Indent( short nDiff )
+{
+ DBG_CHKTHIS( OutlinerView, 0 );
+
+ if( !nDiff || ( ( nDiff > 0 ) && ImpCalcSelectedPages( TRUE ) && !pOwner->ImpCanIndentSelectedPages( this ) ) )
+ return;
+
+ const bool bOutlinerView = pOwner->pEditEngine->GetControlWord() & EE_CNTRL_OUTLINER;
+ BOOL bUpdate = pOwner->pEditEngine->GetUpdateMode();
+ pOwner->pEditEngine->SetUpdateMode( FALSE );
+
+ BOOL bUndo = !pOwner->IsInUndo() && pOwner->IsUndoEnabled();
+
+ if( bUndo )
+ pOwner->UndoActionStart( OLUNDO_DEPTH );
+
+ sal_Int16 nMinDepth = -1; // Optimierung: Nicht unnoetig viele Absatze neu berechnen
+
+ ParaRange aSel = ImpGetSelectedParagraphs( TRUE );
+ for ( USHORT nPara = aSel.nStartPara; nPara <= aSel.nEndPara; nPara++ )
+ {
+ Paragraph* pPara = pOwner->pParaList->GetParagraph( nPara );
+
+ sal_Int16 nOldDepth = pPara->GetDepth();
+ sal_Int16 nNewDepth = nOldDepth + nDiff;
+
+ if( bOutlinerView && nPara )
+ {
+ const bool bPage = pPara->HasFlag(PARAFLAG_ISPAGE);
+ if( (bPage && (nDiff == +1)) || (!bPage && (nDiff == -1) && (nOldDepth <= 0)) )
+ {
+ // App benachrichtigen
+ pOwner->nDepthChangedHdlPrevDepth = (sal_Int16)nOldDepth;
+ pOwner->mnDepthChangeHdlPrevFlags = pPara->nFlags;
+ pOwner->pHdlParagraph = pPara;
+
+ if( bPage )
+ pPara->RemoveFlag( PARAFLAG_ISPAGE );
+ else
+ pPara->SetFlag( PARAFLAG_ISPAGE );
+
+ pOwner->DepthChangedHdl();
+ pOwner->pEditEngine->QuickMarkInvalid( ESelection( nPara, 0, nPara, 0 ) );
+
+ if( bUndo )
+ pOwner->InsertUndo( new OutlinerUndoChangeParaFlags( pOwner, nPara, pOwner->mnDepthChangeHdlPrevFlags, pPara->nFlags ) );
+
+ continue;
+ }
+ }
+
+ // do not switch off numeration with tab
+ if( (nOldDepth == 0) && (nNewDepth == -1) )
+ continue;
+
+ // do not indent if there is no numeration enabled
+ if( nOldDepth == -1 )
+ continue;
+
+ if ( nNewDepth < pOwner->nMinDepth )
+ nNewDepth = pOwner->nMinDepth;
+ if ( nNewDepth > pOwner->nMaxDepth )
+ nNewDepth = pOwner->nMaxDepth;
+
+ if( nOldDepth < nMinDepth )
+ nMinDepth = nOldDepth;
+ if( nNewDepth < nMinDepth )
+ nMinDepth = nNewDepth;
+
+ if( nOldDepth != nNewDepth )
+ {
+ if ( ( nPara == aSel.nStartPara ) && aSel.nStartPara && ( pOwner->ImplGetOutlinerMode() != OUTLINERMODE_TEXTOBJECT ))
+ {
+ // Sonderfall: Der Vorgaenger eines eingerueckten Absatzes ist
+ // unsichtbar und steht jetzt auf der gleichen Ebene wie der
+ // sichtbare Absatz. In diesem Fall wird der naechste sichtbare
+ // Absatz gesucht und aufgeplustert.
+#ifdef DBG_UTIL
+ Paragraph* _pPara = pOwner->pParaList->GetParagraph( aSel.nStartPara );
+ DBG_ASSERT(_pPara->IsVisible(),"Selected Paragraph invisible ?!");
+#endif
+ Paragraph* pPrev= pOwner->pParaList->GetParagraph( aSel.nStartPara-1 );
+
+ if( !pPrev->IsVisible() && ( pPrev->GetDepth() == nNewDepth ) )
+ {
+ // Vorgaenger ist eingeklappt und steht auf gleicher Ebene
+ // => naechsten sichtbaren Absatz suchen und expandieren
+ pPrev = pOwner->pParaList->GetParent( pPrev );
+ while( !pPrev->IsVisible() )
+ pPrev = pOwner->pParaList->GetParent( pPrev );
+
+ pOwner->Expand( pPrev );
+ pOwner->InvalidateBullet( pPrev, pOwner->pParaList->GetAbsPos( pPrev ) );
+ }
+ }
+
+ pOwner->nDepthChangedHdlPrevDepth = (sal_Int16)nOldDepth;
+ pOwner->mnDepthChangeHdlPrevFlags = pPara->nFlags;
+ pOwner->pHdlParagraph = pPara;
+
+ pOwner->ImplInitDepth( nPara, nNewDepth, TRUE, FALSE );
+ pOwner->ImplCalcBulletText( nPara, FALSE, FALSE );
+
+ if ( pOwner->ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT )
+ pOwner->ImplSetLevelDependendStyleSheet( nPara );
+
+ // App benachrichtigen
+ pOwner->DepthChangedHdl();
+ }
+ else
+ {
+ // Needs at least a repaint...
+ pOwner->pEditEngine->QuickMarkInvalid( ESelection( nPara, 0, nPara, 0 ) );
+ }
+ }
+
+ // MT 19.08.99: War mal fuer Optimierung (outliner.cxx#1.193),
+ // hat aber zu zuviel Wartungsaufwand / doppelten Funktionen gefuehrt
+ // und zu wenig gebracht:
+ // pOwner->ImpSetBulletTextsFrom( aSel.nStartPara+1, nMinDepth );
+ // Wird jetzt direkt in Schleife mit ImplCalcBulletText() erledigt.
+ // Jetzt fehlen nur noch die folgenden Ansaetze, die davon betroffen sind.
+ USHORT nParas = (USHORT)pOwner->pParaList->GetParagraphCount();
+ for ( USHORT n = aSel.nEndPara+1; n < nParas; n++ )
+ {
+ Paragraph* pPara = pOwner->pParaList->GetParagraph( n );
+ if ( pPara->GetDepth() < nMinDepth )
+ break;
+ pOwner->ImplCalcBulletText( n, FALSE, FALSE );
+ }
+
+ if ( bUpdate )
+ {
+ pEditView->SetEditEngineUpdateMode( TRUE );
+ pEditView->ShowCursor();
+ }
+
+ if( bUndo )
+ pOwner->UndoActionEnd( OLUNDO_DEPTH );
+}
+
+BOOL OutlinerView::AdjustHeight( long nDY )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->MoveParagraphs( nDY );
+ return TRUE; // remove return value...
+}
+
+void OutlinerView::AdjustDepth( Paragraph* pPara, short nDX, BOOL bWithChilds)
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ ULONG nStartPara = pOwner->pParaList->GetAbsPos( pPara );
+ ULONG nEndPara = nStartPara;
+ if ( bWithChilds )
+ nEndPara += pOwner->pParaList->GetChildCount( pPara );
+ ESelection aSel((USHORT)nStartPara, 0,(USHORT)nEndPara, 0xffff );
+ pEditView->SetSelection( aSel );
+ AdjustDepth( nDX );
+}
+
+void OutlinerView::AdjustHeight( Paragraph* pPara, long nDY, BOOL bWithChilds )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ ULONG nStartPara = pOwner->pParaList->GetAbsPos( pPara );
+ ULONG nEndPara = nStartPara;
+ if ( bWithChilds )
+ nEndPara += pOwner->pParaList->GetChildCount( pPara );
+ ESelection aSel( (USHORT)nStartPara, 0, (USHORT)nEndPara, 0xffff );
+ pEditView->SetSelection( aSel );
+ AdjustHeight( nDY );
+}
+
+
+Rectangle OutlinerView::GetVisArea() const
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetVisArea();
+}
+
+
+Point OutlinerView::ImpGetDocPos( const Point& rPosPixel )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ Rectangle aOutArWin = GetOutputArea();
+ // Position in der OutputArea berechnen
+ Point aCurPosDoc( rPosPixel );
+ aCurPosDoc = pEditView->GetWindow()->PixelToLogic( aCurPosDoc );
+ aCurPosDoc -= aOutArWin.TopLeft();
+ aCurPosDoc += pEditView->GetVisArea().TopLeft();
+ return aCurPosDoc;
+}
+
+// MT 05/00: Wofuer dies ImpXXXScroll, sollte das nicht die EditEngine machen???
+
+void OutlinerView::ImpDragScroll( const Point& rPosPix )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ Point aPosWin = pEditView->GetWindow()->PixelToLogic( rPosPix );
+ Rectangle aOutputArWin = pEditView->GetOutputArea();
+ if ( aPosWin.X() <= aOutputArWin.Left() + nDDScrollLRBorderWidthWin)
+ ImpScrollLeft();
+ else if( aPosWin.X() >= aOutputArWin.Right()- nDDScrollLRBorderWidthWin)
+ ImpScrollRight();
+ else if( aPosWin.Y() <= aOutputArWin.Top() + nDDScrollTBBorderWidthWin)
+ ImpScrollUp();
+ else if(aPosWin.Y() >= aOutputArWin.Bottom() - nDDScrollTBBorderWidthWin)
+ ImpScrollDown();
+}
+
+
+void OutlinerView::ImpScrollLeft()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ Rectangle aVisArea( pEditView->GetVisArea() );
+ long nMaxScrollOffs = aVisArea.Left();
+ if ( !nMaxScrollOffs )
+ return;
+ long nScrollOffsRef = (aVisArea.GetWidth() * OL_SCROLL_HOROFFSET) / 100;
+ if ( !nScrollOffsRef )
+ nScrollOffsRef = 1;
+ if ( nScrollOffsRef > nMaxScrollOffs )
+ nScrollOffsRef = nMaxScrollOffs;
+
+ ImpHideDDCursor();
+ Scroll( -nScrollOffsRef, 0 );
+
+ EditStatus aScrollStat;
+ aScrollStat.GetStatusWord() = EE_STAT_HSCROLL;
+ pOwner->pEditEngine->GetStatusEventHdl().Call( &aScrollStat );
+}
+
+
+void OutlinerView::ImpScrollRight()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ Rectangle aVisArea( pEditView->GetVisArea() );
+ long nMaxScrollOffs = pOwner->pEditEngine->GetPaperSize().Width() -
+ aVisArea.Right();
+ if ( !nMaxScrollOffs )
+ return;
+ long nScrollOffsRef = (aVisArea.GetWidth() * OL_SCROLL_HOROFFSET) / 100;
+ if ( !nScrollOffsRef )
+ nScrollOffsRef = 1;
+ if ( nScrollOffsRef > nMaxScrollOffs )
+ nScrollOffsRef = nMaxScrollOffs;
+
+ ImpHideDDCursor();
+ Scroll( nScrollOffsRef, 0 );
+
+ EditStatus aScrollStat;
+ aScrollStat.GetStatusWord() = EE_STAT_HSCROLL;
+ pOwner->pEditEngine->GetStatusEventHdl().Call( &aScrollStat );
+}
+
+
+void OutlinerView::ImpScrollDown()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ Rectangle aVisArea( pEditView->GetVisArea() );
+ Size aDocSize( 0, (long)pOwner->pEditEngine->GetTextHeight() );
+
+ long nMaxScrollOffs = aDocSize.Height();
+ nMaxScrollOffs -= aVisArea.Top();
+ nMaxScrollOffs -= aVisArea.GetHeight();
+ if ( !nMaxScrollOffs )
+ return;
+
+ long nScrollOffsRef = (aVisArea.GetHeight() * OL_SCROLL_VEROFFSET) / 100;
+
+ if ( nScrollOffsRef > nMaxScrollOffs )
+ nScrollOffsRef = nMaxScrollOffs;
+ if ( !nScrollOffsRef )
+ nScrollOffsRef = 1;
+
+ ImpHideDDCursor();
+ Scroll( 0, -nScrollOffsRef );
+
+ EditStatus aScrollStat;
+ aScrollStat.GetStatusWord() = EE_STAT_VSCROLL;
+ pOwner->pEditEngine->GetStatusEventHdl().Call( &aScrollStat );
+}
+
+
+void OutlinerView::ImpScrollUp()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ Rectangle aVisArea( pEditView->GetVisArea() );
+ long nMaxScrollOffs = aVisArea.Top();
+ if ( !nMaxScrollOffs )
+ return;
+ long nScrollOffsRef = (aVisArea.GetHeight() * OL_SCROLL_VEROFFSET) / 100;
+
+
+ if ( nScrollOffsRef > nMaxScrollOffs )
+ nScrollOffsRef = nMaxScrollOffs;
+ if ( !nScrollOffsRef )
+ nScrollOffsRef = 1;
+
+ ImpHideDDCursor();
+ Scroll( 0, nScrollOffsRef );
+
+ EditStatus aScrollStat;
+ aScrollStat.GetStatusWord() = EE_STAT_VSCROLL;
+ pOwner->pEditEngine->GetStatusEventHdl().Call( &aScrollStat );
+}
+
+
+void OutlinerView::Expand()
+{
+ DBG_CHKTHIS( OutlinerView, 0 );
+ ParaRange aParas = ImpGetSelectedParagraphs( FALSE );
+ ImplExpandOrCollaps( aParas.nStartPara, aParas.nEndPara, TRUE );
+}
+
+
+void OutlinerView::Collapse()
+{
+ DBG_CHKTHIS( OutlinerView, 0 );
+ ParaRange aParas = ImpGetSelectedParagraphs( FALSE );
+ ImplExpandOrCollaps( aParas.nStartPara, aParas.nEndPara, FALSE );
+}
+
+
+void OutlinerView::ExpandAll()
+{
+ DBG_CHKTHIS( OutlinerView, 0 );
+ ImplExpandOrCollaps( 0, (USHORT)(pOwner->pParaList->GetParagraphCount()-1), TRUE );
+}
+
+
+void OutlinerView::CollapseAll()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ ImplExpandOrCollaps( 0, (USHORT)(pOwner->pParaList->GetParagraphCount()-1), FALSE );
+}
+
+void OutlinerView::ImplExpandOrCollaps( USHORT nStartPara, USHORT nEndPara, BOOL bExpand )
+{
+ DBG_CHKTHIS( OutlinerView, 0 );
+
+ BOOL bUpdate = pOwner->GetUpdateMode();
+ pOwner->SetUpdateMode( FALSE );
+
+ BOOL bUndo = !pOwner->IsInUndo() && pOwner->IsUndoEnabled();
+ if( bUndo )
+ pOwner->UndoActionStart( bExpand ? OLUNDO_EXPAND : OLUNDO_COLLAPSE );
+
+ for ( USHORT nPara = nStartPara; nPara <= nEndPara; nPara++ )
+ {
+ Paragraph* pPara = pOwner->pParaList->GetParagraph( nPara );
+ BOOL bDone = bExpand ? pOwner->Expand( pPara ) : pOwner->Collapse( pPara );
+ if( bDone )
+ {
+ // Der Strich unter dem Absatz muss verschwinden...
+ pOwner->pEditEngine->QuickMarkToBeRepainted( nPara );
+ }
+ }
+
+ if( bUndo )
+ pOwner->UndoActionEnd( bExpand ? OLUNDO_EXPAND : OLUNDO_COLLAPSE );
+
+ if ( bUpdate )
+ {
+ pOwner->SetUpdateMode( TRUE );
+ pEditView->ShowCursor();
+ }
+}
+
+
+void OutlinerView::Expand( Paragraph* pPara)
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pOwner->Expand( pPara );
+}
+
+
+void OutlinerView::Collapse( Paragraph* pPara)
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pOwner->Collapse( pPara );
+}
+
+void OutlinerView::InsertText( const OutlinerParaObject& rParaObj )
+{
+ // MT: Wie Paste, nur EditView::Insert, statt EditView::Paste.
+ // Eigentlich nicht ganz richtig, das evtl. Einrueckungen
+ // korrigiert werden muessen, aber das kommt spaeter durch ein
+ // allgemeingueltiges Import.
+ // Dann wird im Inserted gleich ermittelt, was fr eine Einrueckebene
+ // Moegliche Struktur:
+ // pImportInfo mit DestPara, DestPos, nFormat, pParaObj...
+ // Evtl. Problematisch:
+ // EditEngine, RTF => Absplittung des Bereichs, spaeter
+ // zusammenfuehrung
+
+ DBG_CHKTHIS(OutlinerView,0);
+
+ if ( ImpCalcSelectedPages( FALSE ) && !pOwner->ImpCanDeleteSelectedPages( this ) )
+ return;
+
+ pOwner->UndoActionStart( OLUNDO_INSERT );
+
+ pOwner->pEditEngine->SetUpdateMode( FALSE );
+ ULONG nStart, nParaCount;
+ nParaCount = pOwner->pEditEngine->GetParagraphCount();
+ USHORT nSize = ImpInitPaste( nStart );
+ pEditView->InsertText( rParaObj.GetTextObject() );
+ ImpPasted( nStart, nParaCount, nSize);
+ pEditView->SetEditEngineUpdateMode( TRUE );
+
+ pOwner->UndoActionEnd( OLUNDO_INSERT );
+
+ pEditView->ShowCursor( TRUE, TRUE );
+}
+
+
+
+void OutlinerView::Cut()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ if ( !ImpCalcSelectedPages( FALSE ) || pOwner->ImpCanDeleteSelectedPages( this ) )
+ pEditView->Cut();
+}
+
+void OutlinerView::Paste()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ PasteSpecial(); // HACK(SD ruft nicht PasteSpecial auf)
+}
+
+void OutlinerView::PasteSpecial()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ if ( !ImpCalcSelectedPages( FALSE ) || pOwner->ImpCanDeleteSelectedPages( this ) )
+ {
+ pOwner->UndoActionStart( OLUNDO_INSERT );
+
+ pOwner->pEditEngine->SetUpdateMode( FALSE );
+ pOwner->bPasting = TRUE;
+ pEditView->PasteSpecial();
+
+ if ( pOwner->ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT )
+ {
+ const USHORT nParaCount = pOwner->pEditEngine->GetParagraphCount();
+
+ for( USHORT nPara = 0; nPara < nParaCount; nPara++ )
+ pOwner->ImplSetLevelDependendStyleSheet( nPara );
+ }
+
+ pEditView->SetEditEngineUpdateMode( TRUE );
+ pOwner->UndoActionEnd( OLUNDO_INSERT );
+ pEditView->ShowCursor( TRUE, TRUE );
+ }
+}
+
+List* OutlinerView::CreateSelectionList()
+{
+ DBG_CHKTHIS( OutlinerView, 0 );
+
+ ParaRange aParas = ImpGetSelectedParagraphs( TRUE );
+ List* pSelList = new List;
+ for ( USHORT nPara = aParas.nStartPara; nPara <= aParas.nEndPara; nPara++ )
+ {
+ Paragraph* pPara = pOwner->pParaList->GetParagraph( nPara );
+ pSelList->Insert( pPara, LIST_APPEND );
+ }
+ return pSelList;
+}
+
+SfxStyleSheet* OutlinerView::GetStyleSheet() const
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetStyleSheet();
+}
+
+void OutlinerView::SetStyleSheet( SfxStyleSheet* pStyle )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->SetStyleSheet( pStyle );
+
+ ParaRange aSel = ImpGetSelectedParagraphs( TRUE );
+ for( USHORT nPara = aSel.nStartPara; nPara <= aSel.nEndPara; nPara++ )
+ {
+ pOwner->ImplCheckNumBulletItem( nPara );
+ pOwner->ImplCalcBulletText( nPara, FALSE, FALSE );
+ }
+}
+
+Pointer OutlinerView::GetPointer( const Point& rPosPixel )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+
+ MouseTarget eTarget;
+ ImpCheckMousePos( rPosPixel, eTarget );
+
+ PointerStyle ePointerStyle = POINTER_ARROW;
+ if ( eTarget == MouseText )
+ {
+ ePointerStyle = GetOutliner()->IsVertical() ? POINTER_TEXT_VERTICAL : POINTER_TEXT;
+ }
+ else if ( eTarget == MouseHypertext )
+ {
+ ePointerStyle = POINTER_REFHAND;
+ }
+ else if ( eTarget == MouseBullet )
+ {
+ ePointerStyle = POINTER_MOVE;
+ }
+
+ return Pointer( ePointerStyle );
+}
+
+
+USHORT OutlinerView::ImpInitPaste( ULONG& rStart )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pOwner->bPasting = TRUE;
+ ESelection aSelection( pEditView->GetSelection() );
+ aSelection.Adjust();
+ rStart = aSelection.nStartPara;
+ USHORT nSize = aSelection.nEndPara - aSelection.nStartPara + 1;
+ return nSize;
+}
+
+
+void OutlinerView::ImpPasted( ULONG nStart, ULONG nPrevParaCount, USHORT nSize)
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pOwner->bPasting = FALSE;
+ ULONG nCurParaCount = (ULONG)pOwner->pEditEngine->GetParagraphCount();
+ if( nCurParaCount < nPrevParaCount )
+ nSize = sal::static_int_cast< USHORT >(
+ nSize - ( nPrevParaCount - nCurParaCount ) );
+ else
+ nSize = sal::static_int_cast< USHORT >(
+ nSize + ( nCurParaCount - nPrevParaCount ) );
+ pOwner->ImpTextPasted( nStart, nSize );
+}
+
+
+void OutlinerView::Command( const CommandEvent& rCEvt )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->Command( rCEvt );
+}
+
+
+void OutlinerView::SelectRange( ULONG nFirst, USHORT nCount )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ ULONG nLast = nFirst+nCount;
+ nCount = (USHORT)pOwner->pParaList->GetParagraphCount();
+ if( nLast <= nCount )
+ nLast = nCount - 1;
+ ESelection aSel( (USHORT)nFirst, 0, (USHORT)nLast, 0xffff );
+ pEditView->SetSelection( aSel );
+}
+
+
+USHORT OutlinerView::ImpCalcSelectedPages( BOOL bIncludeFirstSelected )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+
+ ESelection aSel( pEditView->GetSelection() );
+ aSel.Adjust();
+
+ USHORT nPages = 0;
+ USHORT nFirstPage = 0xFFFF;
+ USHORT nStartPara = aSel.nStartPara;
+ if ( !bIncludeFirstSelected )
+ nStartPara++; // alle nach StartPara kommenden Absaetze werden geloescht
+ for ( USHORT nPara = nStartPara; nPara <= aSel.nEndPara; nPara++ )
+ {
+ Paragraph* pPara = pOwner->pParaList->GetParagraph( nPara );
+ DBG_ASSERT(pPara, "ImpCalcSelectedPages: ungueltige Selection? ");
+ if( pPara->HasFlag(PARAFLAG_ISPAGE) )
+ {
+ nPages++;
+ if( nFirstPage == 0xFFFF )
+ nFirstPage = nPara;
+ }
+ }
+
+ if( nPages )
+ {
+ pOwner->nDepthChangedHdlPrevDepth = nPages;
+ pOwner->pHdlParagraph = 0;
+ pOwner->mnFirstSelPage = nFirstPage;
+ }
+
+ return nPages;
+}
+
+
+void OutlinerView::ToggleBullets()
+{
+ pOwner->UndoActionStart( OLUNDO_DEPTH );
+
+ ESelection aSel( pEditView->GetSelection() );
+ aSel.Adjust();
+
+ const bool bUpdate = pOwner->pEditEngine->GetUpdateMode();
+ pOwner->pEditEngine->SetUpdateMode( FALSE );
+
+ sal_Int16 nDepth = -2;
+
+ for ( USHORT nPara = aSel.nStartPara; nPara <= aSel.nEndPara; nPara++ )
+ {
+ Paragraph* pPara = pOwner->pParaList->GetParagraph( nPara );
+ DBG_ASSERT(pPara, "OutlinerView::ToggleBullets(), illegal selection?");
+
+ if( pPara )
+ {
+ if( nDepth == -2 )
+ nDepth = (pOwner->GetDepth(nPara) == -1) ? 0 : -1;
+
+ pOwner->SetDepth( pPara, nDepth );
+
+ if( nDepth == -1 )
+ {
+ const SfxItemSet& rAttrs = pOwner->GetParaAttribs( nPara );
+ if(rAttrs.GetItemState( EE_PARA_BULLETSTATE ) == SFX_ITEM_SET)
+ {
+ SfxItemSet aAttrs(rAttrs);
+ aAttrs.ClearItem( EE_PARA_BULLETSTATE );
+ pOwner->SetParaAttribs( nPara, aAttrs );
+ }
+ }
+ }
+ }
+
+ // --> OD 2009-03-10 #i100014#
+ // It is not a good idea to substract 1 from a count and cast the result
+ // to USHORT without check, if the count is 0.
+ USHORT nParaCount = (USHORT) (pOwner->pParaList->GetParagraphCount());
+ // <--
+ pOwner->ImplCheckParagraphs( aSel.nStartPara, nParaCount );
+ pOwner->pEditEngine->QuickMarkInvalid( ESelection( aSel.nStartPara, 0, nParaCount, 0 ) );
+
+ pOwner->pEditEngine->SetUpdateMode( bUpdate );
+
+ pOwner->UndoActionEnd( OLUNDO_DEPTH );
+}
+
+void OutlinerView::EnableBullets()
+{
+ pOwner->UndoActionStart( OLUNDO_DEPTH );
+
+ ESelection aSel( pEditView->GetSelection() );
+ aSel.Adjust();
+
+ const bool bUpdate = pOwner->pEditEngine->GetUpdateMode();
+ pOwner->pEditEngine->SetUpdateMode( FALSE );
+
+ for ( USHORT nPara = aSel.nStartPara; nPara <= aSel.nEndPara; nPara++ )
+ {
+ Paragraph* pPara = pOwner->pParaList->GetParagraph( nPara );
+ DBG_ASSERT(pPara, "OutlinerView::ToggleBullets(), illegal selection?");
+
+ if( pPara && (pOwner->GetDepth(nPara) == -1) )
+ {
+ pOwner->SetDepth( pPara, 0 );
+ }
+ }
+
+ // --> OD 2009-03-10 #i100014#
+ // It is not a good idea to substract 1 from a count and cast the result
+ // to USHORT without check, if the count is 0.
+ USHORT nParaCount = (USHORT) (pOwner->pParaList->GetParagraphCount());
+ // <--
+ pOwner->ImplCheckParagraphs( aSel.nStartPara, nParaCount );
+ pOwner->pEditEngine->QuickMarkInvalid( ESelection( aSel.nStartPara, 0, nParaCount, 0 ) );
+
+ pOwner->pEditEngine->SetUpdateMode( bUpdate );
+
+ pOwner->UndoActionEnd( OLUNDO_DEPTH );
+}
+
+
+void OutlinerView::RemoveAttribsKeepLanguages( BOOL bRemoveParaAttribs )
+{
+ RemoveAttribs( bRemoveParaAttribs, 0, TRUE /*keep language attribs*/ );
+}
+
+void OutlinerView::RemoveAttribs( BOOL bRemoveParaAttribs, USHORT nWhich, BOOL bKeepLanguages )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ BOOL bUpdate = pOwner->GetUpdateMode();
+ pOwner->SetUpdateMode( FALSE );
+ pOwner->UndoActionStart( OLUNDO_ATTR );
+ if (bKeepLanguages)
+ pEditView->RemoveAttribsKeepLanguages( bRemoveParaAttribs );
+ else
+ pEditView->RemoveAttribs( bRemoveParaAttribs, nWhich );
+ if ( bRemoveParaAttribs )
+ {
+ // Ueber alle Absaetze, und Einrueckung und Level einstellen
+ ESelection aSel = pEditView->GetSelection();
+ aSel.Adjust();
+ for ( USHORT nPara = aSel.nStartPara; nPara <= aSel.nEndPara; nPara++ )
+ {
+ Paragraph* pPara = pOwner->pParaList->GetParagraph( nPara );
+ pOwner->ImplInitDepth( nPara, pPara->GetDepth(), FALSE, FALSE );
+ }
+ }
+ pOwner->UndoActionEnd( OLUNDO_ATTR );
+ pOwner->SetUpdateMode( bUpdate );
+}
+
+
+
+ // =====================================================================
+// ====================== Einfache Durchreicher =======================
+// ======================================================================
+
+
+void OutlinerView::InsertText( const XubString& rNew, BOOL bSelect )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ if( pOwner->bFirstParaIsEmpty )
+ pOwner->Insert( String() );
+ pEditView->InsertText( rNew, bSelect );
+}
+
+void OutlinerView::SetVisArea( const Rectangle& rRec )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->SetVisArea( rRec );
+}
+
+
+void OutlinerView::SetSelection( const ESelection& rSel )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->SetSelection( rSel );
+}
+
+void OutlinerView::SetReadOnly( BOOL bReadOnly )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->SetReadOnly( bReadOnly );
+}
+
+BOOL OutlinerView::IsReadOnly() const
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->IsReadOnly();
+}
+
+BOOL OutlinerView::HasSelection() const
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->HasSelection();
+}
+
+
+void OutlinerView::ShowCursor( BOOL bGotoCursor )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->ShowCursor( bGotoCursor );
+}
+
+
+void OutlinerView::HideCursor()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->HideCursor();
+}
+
+
+void OutlinerView::SetWindow( Window* pWin )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->SetWindow( pWin );
+}
+
+
+Window* OutlinerView::GetWindow() const
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetWindow();
+}
+
+
+void OutlinerView::SetOutputArea( const Rectangle& rRect )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->SetOutputArea( rRect );
+}
+
+
+Rectangle OutlinerView::GetOutputArea() const
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetOutputArea();
+}
+
+
+XubString OutlinerView::GetSelected() const
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetSelected();
+}
+
+
+void OutlinerView::RemoveCharAttribs( ULONG nPara, USHORT nWhich)
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->RemoveCharAttribs( (USHORT)nPara, nWhich);
+}
+
+
+void OutlinerView::CompleteAutoCorrect()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->CompleteAutoCorrect();
+}
+
+
+EESpellState OutlinerView::StartSpeller( BOOL bMultiDoc )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->StartSpeller( bMultiDoc );
+}
+
+
+EESpellState OutlinerView::StartThesaurus()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->StartThesaurus();
+}
+
+
+void OutlinerView::StartTextConversion(
+ LanguageType nSrcLang, LanguageType nDestLang, const Font *pDestFont,
+ INT32 nOptions, BOOL bIsInteractive, BOOL bMultipleDoc )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ if (
+ (LANGUAGE_KOREAN == nSrcLang && LANGUAGE_KOREAN == nDestLang) ||
+ (LANGUAGE_CHINESE_SIMPLIFIED == nSrcLang && LANGUAGE_CHINESE_TRADITIONAL == nDestLang) ||
+ (LANGUAGE_CHINESE_TRADITIONAL == nSrcLang && LANGUAGE_CHINESE_SIMPLIFIED == nDestLang)
+ )
+ {
+ pEditView->StartTextConversion( nSrcLang, nDestLang, pDestFont, nOptions, bIsInteractive, bMultipleDoc );
+ }
+ else
+ {
+ DBG_ERROR( "unexpected language" );
+ }
+}
+
+
+USHORT OutlinerView::StartSearchAndReplace( const SvxSearchItem& rSearchItem )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->StartSearchAndReplace( rSearchItem );
+}
+
+void OutlinerView::TransliterateText( sal_Int32 nTransliterationMode )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->TransliterateText( nTransliterationMode );
+}
+
+
+
+ESelection OutlinerView::GetSelection()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetSelection();
+}
+
+
+void OutlinerView::Scroll( long nHorzScroll, long nVertScroll )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->Scroll( nHorzScroll, nVertScroll );
+}
+
+
+void OutlinerView::SetControlWord( ULONG nWord )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->SetControlWord( nWord );
+}
+
+
+ULONG OutlinerView::GetControlWord() const
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetControlWord();
+}
+
+
+void OutlinerView::SetAnchorMode( EVAnchorMode eMode )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->SetAnchorMode( eMode );
+}
+
+
+EVAnchorMode OutlinerView::GetAnchorMode() const
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetAnchorMode();
+}
+
+
+void OutlinerView::Undo()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->Undo();
+}
+
+
+void OutlinerView::Redo()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->Redo();
+}
+
+
+void OutlinerView::EnablePaste( BOOL bEnable )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->EnablePaste( bEnable );
+}
+
+
+void OutlinerView::Copy()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->Copy();
+}
+
+
+void OutlinerView::InsertField( const SvxFieldItem& rFld )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->InsertField( rFld );
+}
+
+
+const SvxFieldItem* OutlinerView::GetFieldUnderMousePointer() const
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetFieldUnderMousePointer();
+}
+
+
+const SvxFieldItem* OutlinerView::GetFieldUnderMousePointer( USHORT& nPara, USHORT& nPos ) const
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetFieldUnderMousePointer( nPara, nPos );
+}
+
+
+const SvxFieldItem* OutlinerView::GetFieldAtSelection() const
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetFieldAtSelection();
+}
+
+void OutlinerView::SetInvalidateMore( USHORT nPixel )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->SetInvalidateMore( nPixel );
+}
+
+
+USHORT OutlinerView::GetInvalidateMore() const
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetInvalidateMore();
+}
+
+
+BOOL OutlinerView::IsCursorAtWrongSpelledWord( BOOL bMarkIfWrong )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->IsCursorAtWrongSpelledWord( bMarkIfWrong );
+}
+
+
+BOOL OutlinerView::IsWrongSpelledWordAtPos( const Point& rPosPixel, BOOL bMarkIfWrong )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->IsWrongSpelledWordAtPos( rPosPixel, bMarkIfWrong );
+}
+
+
+void OutlinerView::SpellIgnoreWord()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->SpellIgnoreWord();
+}
+
+
+void OutlinerView::ExecuteSpellPopup( const Point& rPosPixel, Link* pStartDlg )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->ExecuteSpellPopup( rPosPixel, pStartDlg );
+}
+
+ULONG OutlinerView::Read( SvStream& rInput, const String& rBaseURL, EETextFormat eFormat, BOOL bSelect, SvKeyValueIterator* pHTTPHeaderAttrs )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ USHORT nOldParaCount = pEditView->GetEditEngine()->GetParagraphCount();
+ ESelection aOldSel = pEditView->GetSelection();
+ aOldSel.Adjust();
+
+ ULONG nRet = pEditView->Read( rInput, rBaseURL, eFormat, bSelect, pHTTPHeaderAttrs );
+
+ // MT 08/00: Hier sollte eigentlich das gleiche wie in PasteSpecial passieren!
+ // Mal anpassen, wenn dieses ImplInitPaste und ImpPasted-Geraffel ueberarbeitet ist.
+
+ long nParaDiff = pEditView->GetEditEngine()->GetParagraphCount() - nOldParaCount;
+ USHORT nChangesStart = aOldSel.nStartPara;
+ USHORT nChangesEnd = sal::static_int_cast< USHORT >(nChangesStart + nParaDiff + (aOldSel.nEndPara-aOldSel.nStartPara));
+
+ for ( USHORT n = nChangesStart; n <= nChangesEnd; n++ )
+ {
+ if ( eFormat == EE_FORMAT_BIN )
+ {
+ USHORT nDepth = 0;
+ const SfxItemSet& rAttrs = pOwner->GetParaAttribs( n );
+ const SfxInt16Item& rLevel = (const SfxInt16Item&) rAttrs.Get( EE_PARA_OUTLLEVEL );
+ nDepth = rLevel.GetValue();
+ pOwner->ImplInitDepth( n, nDepth, FALSE );
+ }
+
+ if ( pOwner->ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT )
+ pOwner->ImplSetLevelDependendStyleSheet( n );
+ }
+
+ if ( eFormat != EE_FORMAT_BIN )
+ {
+ pOwner->ImpFilterIndents( nChangesStart, nChangesEnd );
+ }
+
+ return nRet;
+}
+
+ULONG OutlinerView::Write( SvStream& rOutput, EETextFormat eFormat )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->Write( rOutput, eFormat );
+}
+
+void OutlinerView::SetBackgroundColor( const Color& rColor )
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ pEditView->SetBackgroundColor( rColor );
+}
+
+
+Color OutlinerView::GetBackgroundColor()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetBackgroundColor();
+}
+
+SfxItemSet OutlinerView::GetAttribs()
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetAttribs();
+}
+
+USHORT OutlinerView::GetSelectedScriptType() const
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetSelectedScriptType();
+}
+
+String OutlinerView::GetSurroundingText() const
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetSurroundingText();
+}
+
+Selection OutlinerView::GetSurroundingTextSelection() const
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetSurroundingTextSelection();
+}
diff --git a/editeng/source/outliner/paralist.cxx b/editeng/source/outliner/paralist.cxx
new file mode 100644
index 0000000000..1cdc628140
--- /dev/null
+++ b/editeng/source/outliner/paralist.cxx
@@ -0,0 +1,290 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: paralist.cxx,v $
+ * $Revision: 1.11.6.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <paralist.hxx>
+#include <editeng/outliner.hxx> // nur wegen Paragraph, muss geaendert werden!
+#include <editeng/numdef.hxx>
+
+DBG_NAME(Paragraph)
+
+ParagraphData::ParagraphData()
+: nDepth( -1 )
+, mnNumberingStartValue( -1 )
+, mbParaIsNumberingRestart( sal_False )
+{
+}
+
+ParagraphData::ParagraphData( const ParagraphData& r )
+: nDepth( r.nDepth )
+, mnNumberingStartValue( r.mnNumberingStartValue )
+, mbParaIsNumberingRestart( r.mbParaIsNumberingRestart )
+{
+}
+
+ParagraphData& ParagraphData::operator=( const ParagraphData& r)
+{
+ nDepth = r.nDepth;
+ mnNumberingStartValue = r.mnNumberingStartValue;
+ mbParaIsNumberingRestart = r.mbParaIsNumberingRestart;
+ return *this;
+}
+
+bool ParagraphData::operator==(const ParagraphData& rCandidate) const
+{
+ return (nDepth == rCandidate.nDepth
+ && mnNumberingStartValue == rCandidate.mnNumberingStartValue
+ && mbParaIsNumberingRestart == rCandidate.mbParaIsNumberingRestart);
+}
+
+Paragraph::Paragraph( sal_Int16 nDDepth )
+: aBulSize( -1, -1)
+{
+ DBG_CTOR( Paragraph, 0 );
+
+ DBG_ASSERT( ( nDDepth >= -1 ) && ( nDDepth < SVX_MAX_NUM ), "Paragraph-CTOR: nDepth invalid!" );
+
+ nDepth = nDDepth;
+ nFlags = 0;
+ bVisible = TRUE;
+}
+
+Paragraph::Paragraph( const Paragraph& rPara )
+: ParagraphData( rPara )
+, aBulText( rPara.aBulText )
+, aBulSize( rPara.aBulSize )
+{
+ DBG_CTOR( Paragraph, 0 );
+
+ nDepth = rPara.nDepth;
+ nFlags = rPara.nFlags;
+ bVisible = rPara.bVisible;
+}
+
+Paragraph::Paragraph( const ParagraphData& rData )
+: nFlags( 0 )
+, aBulSize( -1, -1)
+, bVisible( TRUE )
+{
+ DBG_CTOR( Paragraph, 0 );
+
+ nDepth = rData.nDepth;
+ mnNumberingStartValue = rData.mnNumberingStartValue;
+ mbParaIsNumberingRestart = rData.mbParaIsNumberingRestart;
+}
+
+Paragraph::~Paragraph()
+{
+ DBG_DTOR( Paragraph, 0 );
+}
+
+void Paragraph::SetNumberingStartValue( sal_Int16 nNumberingStartValue )
+{
+ mnNumberingStartValue = nNumberingStartValue;
+ if( mnNumberingStartValue != -1 )
+ mbParaIsNumberingRestart = true;
+}
+
+void Paragraph::SetParaIsNumberingRestart( sal_Bool bParaIsNumberingRestart )
+{
+ mbParaIsNumberingRestart = bParaIsNumberingRestart;
+ if( !mbParaIsNumberingRestart )
+ mnNumberingStartValue = -1;
+}
+
+void ParagraphList::Clear( BOOL bDestroyParagraphs )
+{
+ if ( bDestroyParagraphs )
+ {
+ for ( ULONG n = GetParagraphCount(); n; )
+ {
+ Paragraph* pPara = GetParagraph( --n );
+ delete pPara;
+ }
+ }
+ List::Clear();
+}
+
+void ParagraphList::MoveParagraphs( ULONG nStart, ULONG nDest, ULONG _nCount )
+{
+ if ( ( nDest < nStart ) || ( nDest >= ( nStart + _nCount ) ) )
+ {
+ ULONG n;
+ ParagraphList aParas;
+ for ( n = 0; n < _nCount; n++ )
+ {
+ Paragraph* pPara = GetParagraph( nStart );
+ aParas.Insert( pPara, LIST_APPEND );
+ Remove( nStart );
+ }
+
+ if ( nDest > nStart )
+ nDest -= _nCount;
+
+ for ( n = 0; n < _nCount; n++ )
+ {
+ Paragraph* pPara = aParas.GetParagraph( n );
+ Insert( pPara, nDest++ );
+ }
+ }
+ else
+ {
+ DBG_ERROR( "MoveParagraphs: Invalid Parameters" );
+ }
+}
+
+Paragraph* ParagraphList::NextVisible( Paragraph* pPara ) const
+{
+ ULONG n = GetAbsPos( pPara );
+
+ Paragraph* p = GetParagraph( ++n );
+ while ( p && !p->IsVisible() )
+ p = GetParagraph( ++n );
+
+ return p;
+}
+
+Paragraph* ParagraphList::PrevVisible( Paragraph* pPara ) const
+{
+ ULONG n = GetAbsPos( pPara );
+
+ Paragraph* p = n ? GetParagraph( --n ) : NULL;
+ while ( p && !p->IsVisible() )
+ p = n ? GetParagraph( --n ) : NULL;
+
+ return p;
+}
+
+Paragraph* ParagraphList::LastVisible() const
+{
+ ULONG n = GetParagraphCount();
+
+ Paragraph* p = n ? GetParagraph( --n ) : NULL;
+ while ( p && !p->IsVisible() )
+ p = n ? GetParagraph( --n ) : NULL;
+
+ return p;
+}
+
+BOOL ParagraphList::HasChilds( Paragraph* pParagraph ) const
+{
+ ULONG n = GetAbsPos( pParagraph );
+ Paragraph* pNext = GetParagraph( ++n );
+ return ( pNext && ( pNext->GetDepth() > pParagraph->GetDepth() ) ) ? TRUE : FALSE;
+}
+
+BOOL ParagraphList::HasHiddenChilds( Paragraph* pParagraph ) const
+{
+ ULONG n = GetAbsPos( pParagraph );
+ Paragraph* pNext = GetParagraph( ++n );
+ return ( pNext && ( pNext->GetDepth() > pParagraph->GetDepth() ) && !pNext->IsVisible() ) ? TRUE : FALSE;
+}
+
+BOOL ParagraphList::HasVisibleChilds( Paragraph* pParagraph ) const
+{
+ ULONG n = GetAbsPos( pParagraph );
+ Paragraph* pNext = GetParagraph( ++n );
+ return ( pNext && ( pNext->GetDepth() > pParagraph->GetDepth() ) && pNext->IsVisible() ) ? TRUE : FALSE;
+}
+
+ULONG ParagraphList::GetChildCount( Paragraph* pParent ) const
+{
+ ULONG nChildCount = 0;
+ ULONG n = GetAbsPos( pParent );
+ Paragraph* pPara = GetParagraph( ++n );
+ while ( pPara && ( pPara->GetDepth() > pParent->GetDepth() ) )
+ {
+ nChildCount++;
+ pPara = GetParagraph( ++n );
+ }
+ return nChildCount;
+}
+
+Paragraph* ParagraphList::GetParent( Paragraph* pParagraph /*, USHORT& rRelPos */ ) const
+{
+ /* rRelPos = 0 */;
+ ULONG n = GetAbsPos( pParagraph );
+ Paragraph* pPrev = GetParagraph( --n );
+ while ( pPrev && ( pPrev->GetDepth() >= pParagraph->GetDepth() ) )
+ {
+// if ( pPrev->GetDepth() == pParagraph->GetDepth() )
+// rRelPos++;
+ pPrev = GetParagraph( --n );
+ }
+
+ return pPrev;
+}
+
+void ParagraphList::Expand( Paragraph* pParent )
+{
+ ULONG nChildCount = GetChildCount( pParent );
+ ULONG nPos = GetAbsPos( pParent );
+
+ for ( ULONG n = 1; n <= nChildCount; n++ )
+ {
+ Paragraph* pPara = GetParagraph( nPos+n );
+ if ( !( pPara->IsVisible() ) )
+ {
+ pPara->bVisible = TRUE;
+ aVisibleStateChangedHdl.Call( pPara );
+ }
+ }
+}
+
+void ParagraphList::Collapse( Paragraph* pParent )
+{
+ ULONG nChildCount = GetChildCount( pParent );
+ ULONG nPos = GetAbsPos( pParent );
+
+ for ( ULONG n = 1; n <= nChildCount; n++ )
+ {
+ Paragraph* pPara = GetParagraph( nPos+n );
+ if ( pPara->IsVisible() )
+ {
+ pPara->bVisible = FALSE;
+ aVisibleStateChangedHdl.Call( pPara );
+ }
+ }
+}
+
+ULONG ParagraphList::GetVisPos( Paragraph* pPara )
+{
+ ULONG nVisPos = 0;
+ ULONG nPos = GetAbsPos( pPara );
+ for ( ULONG n = 0; n < nPos; n++ )
+ {
+ Paragraph* _pPara = GetParagraph( n );
+ if ( _pPara->IsVisible() )
+ nVisPos++;
+ }
+ return nVisPos;
+}
diff --git a/editeng/source/outliner/paralist.hxx b/editeng/source/outliner/paralist.hxx
new file mode 100644
index 0000000000..c2205530a9
--- /dev/null
+++ b/editeng/source/outliner/paralist.hxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: paralist.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _PARALIST_HXX
+#define _PARALIST_HXX
+
+class Paragraph;
+
+#include <tools/list.hxx>
+#include <tools/link.hxx>
+
+class ParagraphList : private List
+{
+private:
+ Link aVisibleStateChangedHdl;
+
+public:
+ void Clear( BOOL bDestroyParagraphs );
+
+ ULONG GetParagraphCount() const { return List::Count(); }
+ Paragraph* GetParagraph( ULONG nPos ) const { return (Paragraph*)List::GetObject( nPos ); }
+
+ ULONG GetAbsPos( Paragraph* pParent ) const { return List::GetPos( pParent ); }
+ ULONG GetVisPos( Paragraph* pParagraph );
+
+ void Insert( Paragraph* pPara, ULONG nAbsPos = LIST_APPEND ) { List::Insert( pPara, nAbsPos ); }
+ void Remove( ULONG nPara ) { List::Remove( nPara ); }
+ void MoveParagraphs( ULONG nStart, ULONG nDest, ULONG nCount );
+
+ Paragraph* NextVisible( Paragraph* ) const;
+ Paragraph* PrevVisible( Paragraph* ) const;
+ Paragraph* LastVisible() const;
+
+ Paragraph* GetParent( Paragraph* pParagraph /*, USHORT& rRelPos */ ) const;
+ BOOL HasChilds( Paragraph* pParagraph ) const;
+ BOOL HasHiddenChilds( Paragraph* pParagraph ) const;
+ BOOL HasVisibleChilds( Paragraph* pParagraph ) const;
+ ULONG GetChildCount( Paragraph* pParagraph ) const;
+
+ void Expand( Paragraph* pParent );
+ void Collapse( Paragraph* pParent );
+
+ void SetVisibleStateChangedHdl( const Link& rLink ) { aVisibleStateChangedHdl = rLink; }
+ Link GetVisibleStateChangedHdl() const { return aVisibleStateChangedHdl; }
+};
+
+#endif
diff --git a/editeng/source/rtf/makefile.mk b/editeng/source/rtf/makefile.mk
new file mode 100644
index 0000000000..b633d5c088
--- /dev/null
+++ b/editeng/source/rtf/makefile.mk
@@ -0,0 +1,55 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.5 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=editeng
+TARGET=rtf
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+EXCEPTIONSFILES= \
+ $(SLO)$/svxrtf.obj
+
+SLOFILES= \
+ $(EXCEPTIONSFILES) \
+ $(SLO)$/rtfitem.obj \
+ $(SLO)$/rtfgrf.obj
+
+# ==========================================================================
+
+.INCLUDE : target.mk
+
diff --git a/editeng/source/rtf/rtfgrf.cxx b/editeng/source/rtf/rtfgrf.cxx
new file mode 100644
index 0000000000..c36bf6b29a
--- /dev/null
+++ b/editeng/source/rtf/rtfgrf.cxx
@@ -0,0 +1,561 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: rtfgrf.cxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
+#include <osl/endian.h>
+#include <tools/cachestr.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/svapp.hxx>
+#include <svtools/rtfkeywd.hxx>
+#include <svtools/rtftoken.h>
+#include <svtools/filter.hxx>
+
+#include <editeng/svxrtf.hxx>
+
+
+#ifndef DBG_UTIL
+#undef DEBUG_JP
+#endif
+
+#ifdef DEBUG_JP
+
+#include <tools/fsys.hxx>
+
+class GrfWindow : public WorkWindow
+{
+ Graphic aGrf;
+public:
+ GrfWindow( const Graphic& rGrf );
+ virtual void Paint( const Rectangle& rRect );
+};
+
+GrfWindow::GrfWindow( const Graphic& rGrf )
+ : WorkWindow( NULL ),
+ aGrf( rGrf )
+{
+ SetPosSizePixel( Point( 100, 0 ), Size( 300, 300 ));
+ Show();
+ Invalidate();
+ Update();
+}
+
+void GrfWindow::Paint( const Rectangle& )
+{
+ aGrf.Draw( this, Point(0,0), GetSizePixel() );
+}
+#endif
+
+static BYTE __FAR_DATA aPal1[ 2 * 4 ] = {
+ 0x00, 0x00, 0x00, 0x00, // Schwarz
+ 0xFF, 0xFF, 0xFF, 0x00 // Weiss
+};
+
+static BYTE __FAR_DATA aPal4[ 16 * 4 ] = {
+ 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x80, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00,
+ 0x80, 0x00, 0x80, 0x00,
+ 0x00, 0x80, 0x80, 0x00,
+ 0x80, 0x80, 0x80, 0x00,
+ 0xC0, 0xC0, 0xC0, 0x00,
+ 0xFF, 0x00, 0x00, 0x00,
+ 0x00, 0xFF, 0x00, 0x00,
+ 0xFF, 0xFF, 0x00, 0x00,
+ 0x00, 0x00, 0xFF, 0x00,
+ 0xFF, 0x00, 0xFF, 0x00,
+ 0x00, 0xFF, 0xFF, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x00
+};
+
+static BYTE __FAR_DATA aPal8[ 256 * 4 ] =
+{
+0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00,
+0x80, 0x92, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x80, 0x00, 0xAA, 0x00,
+0x00, 0x92, 0xAA, 0x00, 0xC1, 0xC1, 0xC1, 0x00, 0xC9, 0xC9, 0xC9, 0x00,
+0xAA, 0xDB, 0xFF, 0x00, 0x00, 0x49, 0xAA, 0x00, 0x00, 0x49, 0xFF, 0x00,
+0x00, 0x6D, 0x00, 0x00, 0x00, 0x6D, 0x55, 0x00, 0x00, 0x6D, 0xAA, 0x00,
+0x00, 0x6D, 0xFF, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x92, 0x55, 0x00,
+0x00, 0x24, 0xAA, 0x00, 0x00, 0x92, 0xFF, 0x00, 0x00, 0xB6, 0x00, 0x00,
+0x00, 0xB6, 0x55, 0x00, 0x00, 0xB6, 0xAA, 0x00, 0x00, 0xB6, 0xFF, 0x00,
+0x00, 0xDB, 0x00, 0x00, 0x00, 0xDB, 0x55, 0x00, 0x00, 0xDB, 0xAA, 0x00,
+0x00, 0xDB, 0xFF, 0x00, 0xFF, 0xDB, 0xAA, 0x00, 0x00, 0xFF, 0x55, 0x00,
+0x00, 0xFF, 0xAA, 0x00, 0xFF, 0xFF, 0xAA, 0x00, 0x2B, 0x00, 0x00, 0x00,
+0x2B, 0x00, 0x55, 0x00, 0x2B, 0x00, 0xAA, 0x00, 0x2B, 0x00, 0xFF, 0x00,
+0x2B, 0x24, 0x00, 0x00, 0x2B, 0x24, 0x55, 0x00, 0x2B, 0x24, 0xAA, 0x00,
+0x2B, 0x24, 0xFF, 0x00, 0x2B, 0x49, 0x00, 0x00, 0x2B, 0x49, 0x55, 0x00,
+0x2B, 0x49, 0xAA, 0x00, 0x2B, 0x49, 0xFF, 0x00, 0x2B, 0x6D, 0x00, 0x00,
+0x2B, 0x6D, 0x55, 0x00, 0x2B, 0x6D, 0xAA, 0x00, 0x2B, 0x6D, 0xFF, 0x00,
+0x2B, 0x92, 0x00, 0x00, 0x2B, 0x92, 0x55, 0x00, 0x2B, 0x92, 0xAA, 0x00,
+0x2B, 0x92, 0xFF, 0x00, 0x2B, 0xB6, 0x00, 0x00, 0x2B, 0xB6, 0x55, 0x00,
+0x2B, 0xB6, 0xAA, 0x00, 0x2B, 0xB6, 0xFF, 0x00, 0x2B, 0xDB, 0x00, 0x00,
+0x2B, 0xDB, 0x55, 0x00, 0x2B, 0xDB, 0xAA, 0x00, 0x2B, 0xDB, 0xFF, 0x00,
+0x2B, 0xFF, 0x00, 0x00, 0x2B, 0xFF, 0x55, 0x00, 0x2B, 0xFF, 0xAA, 0x00,
+0x2B, 0xFF, 0xFF, 0x00, 0x55, 0x00, 0x00, 0x00, 0x55, 0x00, 0x55, 0x00,
+0x55, 0x00, 0xAA, 0x00, 0x55, 0x00, 0xFF, 0x00, 0x55, 0x24, 0x00, 0x00,
+0x55, 0x24, 0x55, 0x00, 0x55, 0x24, 0xAA, 0x00, 0x55, 0x24, 0xFF, 0x00,
+0x55, 0x49, 0x00, 0x00, 0x55, 0x49, 0x55, 0x00, 0x55, 0x49, 0xAA, 0x00,
+0x55, 0x49, 0xFF, 0x00, 0x55, 0x6D, 0x00, 0x00, 0x55, 0x6D, 0x55, 0x00,
+0x55, 0x6D, 0xAA, 0x00, 0x55, 0x6D, 0xFF, 0x00, 0x55, 0x92, 0x00, 0x00,
+0x55, 0x92, 0x55, 0x00, 0x55, 0x92, 0xAA, 0x00, 0x55, 0x92, 0xFF, 0x00,
+0x55, 0xB6, 0x00, 0x00, 0x55, 0xB6, 0x55, 0x00, 0x55, 0xB6, 0xAA, 0x00,
+0x55, 0xB6, 0xFF, 0x00, 0x55, 0xDB, 0x00, 0x00, 0x55, 0xDB, 0x55, 0x00,
+0x55, 0xDB, 0xAA, 0x00, 0x55, 0xDB, 0xFF, 0x00, 0x55, 0xFF, 0x00, 0x00,
+0x55, 0xFF, 0x55, 0x00, 0x55, 0xFF, 0xAA, 0x00, 0x55, 0xFF, 0xFF, 0x00,
+0x00, 0x00, 0x55, 0x00, 0x80, 0x00, 0x55, 0x00, 0x00, 0x24, 0x55, 0x00,
+0x80, 0x00, 0xFF, 0x00, 0x80, 0x24, 0x00, 0x00, 0x80, 0x24, 0x55, 0x00,
+0x80, 0x24, 0xAA, 0x00, 0x80, 0x24, 0xFF, 0x00, 0x80, 0x49, 0x00, 0x00,
+0x80, 0x49, 0x55, 0x00, 0x80, 0x49, 0xAA, 0x00, 0x80, 0x49, 0xFF, 0x00,
+0x80, 0x6D, 0x00, 0x00, 0x80, 0x6D, 0x55, 0x00, 0x80, 0x6D, 0xAA, 0x00,
+0x80, 0x6D, 0xFF, 0x00, 0x08, 0x08, 0x08, 0x00, 0x0F, 0x0F, 0x0F, 0x00,
+0x17, 0x17, 0x17, 0x00, 0x1F, 0x1F, 0x1F, 0x00, 0x27, 0x27, 0x27, 0x00,
+0x2E, 0x2E, 0x2E, 0x00, 0x36, 0x36, 0x36, 0x00, 0x3E, 0x3E, 0x3E, 0x00,
+0x46, 0x46, 0x46, 0x00, 0x4D, 0x4D, 0x4D, 0x00, 0x55, 0x55, 0x55, 0x00,
+0x5D, 0x5D, 0x5D, 0x00, 0x64, 0x64, 0x64, 0x00, 0x6C, 0x6C, 0x6C, 0x00,
+0x74, 0x74, 0x74, 0x00, 0x7C, 0x7C, 0x7C, 0x00, 0xFF, 0xDB, 0x00, 0x00,
+0x8B, 0x8B, 0x8B, 0x00, 0x93, 0x93, 0x93, 0x00, 0x9B, 0x9B, 0x9B, 0x00,
+0xFF, 0xB6, 0xFF, 0x00, 0xAA, 0xAA, 0xAA, 0x00, 0xB2, 0xB2, 0xB2, 0x00,
+0xB9, 0xB9, 0xB9, 0x00, 0x00, 0x24, 0xFF, 0x00, 0x00, 0x49, 0x00, 0x00,
+0xD1, 0xD1, 0xD1, 0x00, 0xD8, 0xD8, 0xD8, 0x00, 0xE0, 0xE0, 0xE0, 0x00,
+0xE8, 0xE8, 0xE8, 0x00, 0xF0, 0xF0, 0xF0, 0x00, 0xFF, 0xB6, 0xAA, 0x00,
+0xFF, 0xDB, 0xFF, 0x00, 0x80, 0x92, 0x55, 0x00, 0x80, 0x92, 0xAA, 0x00,
+0x80, 0x92, 0xFF, 0x00, 0x80, 0xB6, 0x00, 0x00, 0x80, 0xB6, 0x55, 0x00,
+0x80, 0xB6, 0xAA, 0x00, 0x80, 0xB6, 0xFF, 0x00, 0x80, 0xDB, 0x00, 0x00,
+0x80, 0xDB, 0x55, 0x00, 0x80, 0xDB, 0xAA, 0x00, 0x80, 0xDB, 0xFF, 0x00,
+0x80, 0xFF, 0x00, 0x00, 0x80, 0xFF, 0x55, 0x00, 0x80, 0xFF, 0xAA, 0x00,
+0x80, 0xFF, 0xFF, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x55, 0x00,
+0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xFF, 0x00, 0xAA, 0x24, 0x00, 0x00,
+0xAA, 0x24, 0x55, 0x00, 0xAA, 0x24, 0xAA, 0x00, 0xAA, 0x24, 0xFF, 0x00,
+0xAA, 0x49, 0x00, 0x00, 0xAA, 0x49, 0x55, 0x00, 0xAA, 0x49, 0xAA, 0x00,
+0xAA, 0x49, 0xFF, 0x00, 0xAA, 0x6D, 0x00, 0x00, 0xAA, 0x6D, 0x55, 0x00,
+0xAA, 0x6D, 0xAA, 0x00, 0xAA, 0x6D, 0xFF, 0x00, 0xAA, 0x92, 0x00, 0x00,
+0xAA, 0x92, 0x55, 0x00, 0xAA, 0x92, 0xAA, 0x00, 0xAA, 0x92, 0xFF, 0x00,
+0xAA, 0xB6, 0x00, 0x00, 0xAA, 0xB6, 0x55, 0x00, 0xAA, 0xB6, 0xAA, 0x00,
+0xAA, 0xB6, 0xFF, 0x00, 0xAA, 0xDB, 0x00, 0x00, 0xAA, 0xDB, 0x55, 0x00,
+0xAA, 0xDB, 0xAA, 0x00, 0x00, 0x49, 0x55, 0x00, 0xAA, 0xFF, 0x00, 0x00,
+0xAA, 0xFF, 0x55, 0x00, 0xAA, 0xFF, 0xAA, 0x00, 0xAA, 0xFF, 0xFF, 0x00,
+0xD5, 0x00, 0x00, 0x00, 0xD5, 0x00, 0x55, 0x00, 0xD5, 0x00, 0xAA, 0x00,
+0xD5, 0x00, 0xFF, 0x00, 0xD5, 0x24, 0x00, 0x00, 0xD5, 0x24, 0x55, 0x00,
+0xD5, 0x24, 0xAA, 0x00, 0xD5, 0x24, 0xFF, 0x00, 0xD5, 0x49, 0x00, 0x00,
+0xD5, 0x49, 0x55, 0x00, 0xD5, 0x49, 0xAA, 0x00, 0xD5, 0x49, 0xFF, 0x00,
+0xD5, 0x6D, 0x00, 0x00, 0xD5, 0x6D, 0x55, 0x00, 0xD5, 0x6D, 0xAA, 0x00,
+0xD5, 0x6D, 0xFF, 0x00, 0xD5, 0x92, 0x00, 0x00, 0xD5, 0x92, 0x55, 0x00,
+0xD5, 0x92, 0xAA, 0x00, 0xD5, 0x92, 0xFF, 0x00, 0xD5, 0xB6, 0x00, 0x00,
+0xD5, 0xB6, 0x55, 0x00, 0xD5, 0xB6, 0xAA, 0x00, 0xD5, 0xB6, 0xFF, 0x00,
+0xD5, 0xDB, 0x00, 0x00, 0xD5, 0xDB, 0x55, 0x00, 0xD5, 0xDB, 0xAA, 0x00,
+0xD5, 0xDB, 0xFF, 0x00, 0xD5, 0xFF, 0x00, 0x00, 0xD5, 0xFF, 0x55, 0x00,
+0xD5, 0xFF, 0xAA, 0x00, 0xD5, 0xFF, 0xFF, 0x00, 0xFF, 0xDB, 0x55, 0x00,
+0xFF, 0x00, 0x55, 0x00, 0xFF, 0x00, 0xAA, 0x00, 0xFF, 0xFF, 0x55, 0x00,
+0xFF, 0x24, 0x00, 0x00, 0xFF, 0x24, 0x55, 0x00, 0xFF, 0x24, 0xAA, 0x00,
+0xFF, 0x24, 0xFF, 0x00, 0xFF, 0x49, 0x00, 0x00, 0xFF, 0x49, 0x55, 0x00,
+0xFF, 0x49, 0xAA, 0x00, 0xFF, 0x49, 0xFF, 0x00, 0xFF, 0x6D, 0x00, 0x00,
+0xFF, 0x6D, 0x55, 0x00, 0xFF, 0x6D, 0xAA, 0x00, 0xFF, 0x6D, 0xFF, 0x00,
+0xFF, 0x92, 0x00, 0x00, 0xFF, 0x92, 0x55, 0x00, 0xFF, 0x92, 0xAA, 0x00,
+0xFF, 0x92, 0xFF, 0x00, 0xFF, 0xB6, 0x00, 0x00, 0xFF, 0xB6, 0x55, 0x00,
+0xF7, 0xF7, 0xF7, 0x00, 0xA2, 0xA2, 0xA2, 0x00, 0x83, 0x83, 0x83, 0x00,
+0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
+0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00,
+0xFF, 0xFF, 0xFF, 0x00
+};
+
+
+/* */
+
+
+inline long SwapLong( long n )
+{
+#ifndef OSL_LITENDIAN
+ return SWAPLONG( n );
+#else
+ return n;
+#endif
+}
+
+inline short SwapShort( short n )
+{
+#ifndef OSL_LITENDIAN
+ return SWAPSHORT( n );
+#else
+ return n;
+#endif
+}
+
+
+static void WriteBMPHeader( SvStream& rStream,
+ const SvxRTFPictureType& rPicType )
+{
+ ULONG n4Width = rPicType.nWidth;
+ ULONG n4Height = rPicType.nHeight;
+ USHORT n4ColBits = rPicType.nBitsPerPixel;
+
+ USHORT nColors = (1 << n4ColBits); // Anzahl der Farben ( 1, 16, 256 )
+ USHORT nWdtOut = rPicType.nWidthBytes;
+ if( !nWdtOut )
+ nWdtOut = (USHORT)((( n4Width * n4ColBits + 31 ) / 32 ) * 4 );
+
+ long nOffset = 14 + 40; // BMP_FILE_HD_SIZ + sizeof(*pBmpInfo);
+ if( 256 >= nColors )
+ nOffset += nColors * 4;
+ long nSize = nOffset + nWdtOut * n4Height;
+ rStream << "BM" // = "BM"
+ << SwapLong(nSize) // Filesize in Bytes
+ << SwapShort(0) // Reserviert
+ << SwapShort(0) // Reserviert
+ << SwapLong(nOffset); // Offset?
+
+ rStream << SwapLong(40) // sizeof( BmpInfo )
+ << SwapLong(n4Width)
+ << SwapLong(n4Height)
+ << (USHORT)1
+ << n4ColBits
+ << SwapLong(0)
+ << SwapLong(0)
+ << SwapLong( rPicType.nGoalWidth
+ ? rPicType.nGoalWidth * 1000L / 254L
+ : 0 ) // DPI in Pixel per Meter
+ << SwapLong( rPicType.nGoalHeight
+ ? rPicType.nGoalHeight * 1000L / 254L // dito
+ : 0 )
+ << SwapLong(0)
+ << SwapLong(0);
+
+
+ switch( rPicType.nBitsPerPixel )
+ {
+ case 1: rStream.Write( aPal1, sizeof( aPal1 )); break;
+ case 4: rStream.Write( aPal4, sizeof( aPal4 )); break;
+ case 8: rStream.Write( aPal8, sizeof( aPal8 )); break;
+ }
+}
+
+/* */
+
+ // wandel die ASCII-HexCodes in binaere Zeichen um. Werden
+ // ungueltige Daten gefunden (Zeichen ausser 0-9|a-f|A-F, so
+ // wird USHRT_MAX returnt, ansonsten die Anzahl der umgewandelten Ze.
+xub_StrLen SvxRTFParser::HexToBin( String& rToken )
+{
+ // dann mache aus den Hex-Werten mal "Binare Daten"
+ // (missbrauche den String als temp Buffer)
+ if( rToken.Len() & 1 ) // ungerade Anzahl, mit 0 auffuellen
+ rToken += '0';
+
+ xub_StrLen n, nLen;
+ sal_Unicode nVal;
+ BOOL bValidData = TRUE;
+ const sal_Unicode* pStr = rToken.GetBufferAccess();
+ sal_Char* pData = (sal_Char*)pStr;
+ for( n = 0, nLen = rToken.Len(); n < nLen; ++n, ++pStr )
+ {
+ if( ((nVal = *pStr) >= '0') && ( nVal <= '9') )
+ nVal -= '0';
+ else if( (nVal >= 'A') && (nVal <= 'F') )
+ nVal -= 'A' - 10;
+ else if( (nVal >= 'a') && (nVal <= 'f') )
+ nVal -= 'a' - 10;
+ else
+ {
+ DBG_ASSERT( !this, "ungueltiger Hex-Wert" );
+ bValidData = FALSE;
+ break;
+ }
+
+ if( n & 1 )
+ *(pData++) |= nVal & 0x0f;
+ else
+ *(pData) = sal::static_int_cast< char >( ( nVal << 4 ) & 0xf0 );
+ }
+ // the len div 2, because 2 character are one byte
+ return bValidData ? nLen / 2 : STRING_NOTFOUND;
+}
+
+BOOL SvxRTFParser::ReadBmpData( Graphic& rGrf, SvxRTFPictureType& rPicType )
+{
+ // die alten Daten loeschen
+ rGrf.Clear();
+// ULONG nBmpSize = 0;
+
+ rtl_TextEncoding eOldEnc = GetSrcEncoding();
+ SetSrcEncoding( RTL_TEXTENCODING_MS_1252 );
+
+ const sal_Char* pFilterNm = 0;
+ SvCacheStream* pTmpFile = 0;
+
+ int nToken = 0;
+ bool bValidBmp = true, bFirstTextToken = true;
+ int _nOpenBrakets = 1, // die erste wurde schon vorher erkannt !!
+ nValidDataBraket = 1;
+
+ if( RTF_SHPPICT == GetStackPtr(0)->nTokenId )
+ ++nValidDataBraket;
+
+ while( _nOpenBrakets && IsParserWorking() && bValidBmp )
+ {
+ nToken = GetNextToken();
+ USHORT nVal = USHORT( nTokenValue );
+ switch( nToken )
+ {
+ case '}': --_nOpenBrakets; break;
+ case '{':
+ {
+ if( RTF_IGNOREFLAG != GetNextToken() )
+ nToken = SkipToken( -1 );
+ else if( RTF_UNKNOWNCONTROL != GetNextToken() )
+ nToken = SkipToken( -2 );
+ else
+ {
+ // gleich herausfiltern
+ ReadUnknownData();
+ nToken = GetNextToken();
+ if( '}' != nToken )
+ eState = SVPAR_ERROR;
+ break;
+ }
+ ++_nOpenBrakets;
+ }
+ break;
+
+ case RTF_MACPICT:
+ {
+ rPicType.eStyle = SvxRTFPictureType::MAC_QUICKDRAW;
+ // Mac-Pict bekommt einen leeren Header voran
+ pTmpFile = new SvCacheStream;
+ ByteString aStr;
+ aStr.Fill( 512, '\0' );
+ pTmpFile->Write( aStr.GetBuffer(), aStr.Len() );
+ pFilterNm = "PCT";
+ }
+ break;
+
+ case RTF_EMFBLIP:
+ case RTF_WMETAFILE:
+ case RTF_PNGBLIP:
+ case RTF_JPEGBLIP:
+ case RTF_WBITMAP:
+ case RTF_OSMETAFILE:
+ case RTF_DIBITMAP:
+ {
+ switch( nToken )
+ {
+ case RTF_EMFBLIP:
+ rPicType.eStyle = SvxRTFPictureType::ENHANCED_MF;
+ pFilterNm = "EMF";
+ break;
+ case RTF_WMETAFILE:
+ rPicType.eStyle = SvxRTFPictureType::WIN_METAFILE;
+ pFilterNm = "WMF";
+ break;
+ case RTF_PNGBLIP:
+ rPicType.eStyle = SvxRTFPictureType::RTF_PNG;
+ pFilterNm = "PNG";
+ break;
+ case RTF_JPEGBLIP:
+ rPicType.eStyle = SvxRTFPictureType::RTF_JPG;
+ pFilterNm = "JPG";
+ break;
+
+ case RTF_WBITMAP:
+ rPicType.eStyle = SvxRTFPictureType::RTF_BITMAP;
+ break;
+ case RTF_OSMETAFILE:
+ rPicType.eStyle = SvxRTFPictureType::OS2_METAFILE;
+ break;
+ case RTF_DIBITMAP:
+ rPicType.eStyle = SvxRTFPictureType::RTF_DI_BMP;
+ break;
+ }
+
+ rPicType.nType = nVal;
+ pTmpFile = new SvCacheStream;
+ }
+ break;
+
+ case RTF_PICW: rPicType.nWidth = nVal; break;
+ case RTF_PICH: rPicType.nHeight = nVal; break;
+ case RTF_WBMBITSPIXEL: rPicType.nBitsPerPixel = nVal; break;
+ case RTF_WBMPLANES: rPicType.nPlanes = nVal; break;
+ case RTF_WBMWIDTHBYTES: rPicType.nWidthBytes = nVal; break;
+ case RTF_PICWGOAL: rPicType.nGoalWidth = nVal; break;
+ case RTF_PICHGOAL: rPicType.nGoalHeight = nVal; break;
+ case RTF_BIN:
+ rPicType.nMode = SvxRTFPictureType::BINARY_MODE;
+ rPicType.uPicLen = nTokenValue;
+ if (rPicType.uPicLen)
+ {
+ ULONG nPos = rStrm.Tell();
+ nPos = nPos;
+ rStrm.SeekRel(-1);
+ sal_uInt8 aData[4096];
+ ULONG nSize = sizeof(aData);
+
+ while (rPicType.uPicLen > 0)
+ {
+ if (rPicType.uPicLen < nSize)
+ nSize = rPicType.uPicLen;
+
+ rStrm.Read(aData, nSize);
+ pTmpFile->Write(aData, nSize);
+ rPicType.uPicLen -= nSize;
+ }
+ nNextCh = GetNextChar();
+ bValidBmp = !pTmpFile->GetError();
+ nPos = rStrm.Tell();
+ nPos = nPos;
+ }
+ break;
+ case RTF_PICSCALEX: rPicType.nScalX = nVal; break;
+ case RTF_PICSCALEY: rPicType.nScalY = nVal; break;
+ case RTF_PICSCALED: break;
+
+ case RTF_PICCROPT: rPicType.nCropT = (short)nTokenValue; break;
+ case RTF_PICCROPB: rPicType.nCropB = (short)nTokenValue; break;
+ case RTF_PICCROPL: rPicType.nCropL = (short)nTokenValue; break;
+ case RTF_PICCROPR: rPicType.nCropR = (short)nTokenValue; break;
+
+ case RTF_TEXTTOKEN:
+ // JP 26.06.98: Bug #51719# - nur TextToken auf 1. Ebene
+ // auswerten. Alle anderen sind irgendwelche
+ // nicht auszuwertende Daten
+ if( nValidDataBraket != _nOpenBrakets )
+ break;
+
+ if( bFirstTextToken )
+ {
+ switch( rPicType.eStyle )
+ {
+ case SvxRTFPictureType::RTF_BITMAP:
+ // erstmal die Header und Info-Struktur schreiben
+ if( pTmpFile )
+ ::WriteBMPHeader( *pTmpFile, rPicType );
+ break;
+ default:
+ break;
+ }
+ bFirstTextToken = FALSE;
+ }
+
+ if( pTmpFile && SvxRTFPictureType::HEX_MODE == rPicType.nMode )
+ {
+ xub_StrLen nTokenLen = HexToBin( aToken );
+ if( STRING_NOTFOUND == nTokenLen )
+ bValidBmp = FALSE;
+ else
+ {
+ pTmpFile->Write( (sal_Char*)aToken.GetBuffer(),
+ nTokenLen );
+ bValidBmp = 0 == pTmpFile->GetError();
+ }
+ }
+ break;
+ }
+ }
+
+ if (pTmpFile)
+ {
+ //#i20775#
+ if (pTmpFile->Tell() == 0)
+ bValidBmp = false;
+
+ if( bValidBmp )
+ {
+ GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
+ USHORT nImportFilter = GRFILTER_FORMAT_DONTKNOW;
+
+ if( pFilterNm )
+ {
+ String sTmp;
+ for( USHORT n = pGF->GetImportFormatCount(); n; )
+ {
+ sTmp = pGF->GetImportFormatShortName( --n );
+ if( sTmp.EqualsAscii( pFilterNm ))
+ {
+ nImportFilter = n;
+ break;
+ }
+ }
+ }
+
+ String sTmpStr;
+ pTmpFile->Seek( STREAM_SEEK_TO_BEGIN );
+ bValidBmp = 0 == pGF->ImportGraphic( rGrf, sTmpStr, *pTmpFile,
+ nImportFilter );
+ }
+ delete pTmpFile;
+ }
+
+ if( !bValidBmp )
+ {
+ rGrf.Clear();
+ //TODO If nToken were not initialized to 0 above, it would potentially
+ // be used uninitialized here (if IsParserWorking() is false at the
+ // start of the while loop above):
+ if( '}' != nToken )
+ SkipGroup();
+ }
+ else
+ {
+ switch( rPicType.eStyle )
+ {
+//?? ENHANCED_MF, // in den Pict.Daten steht ein Enhanced-Metafile
+ case SvxRTFPictureType::RTF_PNG:
+ case SvxRTFPictureType::RTF_JPG:
+ {
+ const MapMode aMap( MAP_100TH_MM );
+ Size aSize( rGrf.GetPrefSize() );
+ if( MAP_PIXEL == rGrf.GetPrefMapMode().GetMapUnit() )
+ aSize = Application::GetDefaultDevice()->PixelToLogic(
+ aSize, aMap );
+ else
+ aSize = OutputDevice::LogicToLogic( aSize,
+ rGrf.GetPrefMapMode(), aMap );
+ rPicType.nWidth = sal::static_int_cast< USHORT >(aSize.Width());
+ rPicType.nHeight = sal::static_int_cast< USHORT >(
+ aSize.Height());
+ }
+ break;
+ default:
+ break;
+ }
+
+#ifdef DEBUG_JP
+ new GrfWindow( rGrf );
+#endif
+ }
+ SetSrcEncoding( eOldEnc );
+
+ SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
+ return bValidBmp;
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/editeng/source/rtf/rtfitem.cxx b/editeng/source/rtf/rtfitem.cxx
new file mode 100644
index 0000000000..8cafac9da2
--- /dev/null
+++ b/editeng/source/rtf/rtfitem.cxx
@@ -0,0 +1,2104 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: rtfitem.cxx,v $
+ * $Revision: 1.35.212.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
+
+#include <editeng/flstitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fwdtitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/akrnitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/prszitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/cscoitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/cmapitem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/nlbkitem.hxx>
+#include <editeng/nhypitem.hxx>
+#include <editeng/lcolitem.hxx>
+#include <editeng/blnkitem.hxx>
+#include <editeng/emphitem.hxx>
+#include <editeng/twolinesitem.hxx>
+#include <editeng/pbinitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/prntitem.hxx>
+#include <editeng/opaqitem.hxx>
+#include <editeng/protitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brkitem.hxx>
+#include <editeng/keepitem.hxx>
+#include <editeng/bolnitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/lspcitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/orphitem.hxx>
+#include <editeng/widwitem.hxx>
+#include <editeng/tstpitem.hxx>
+#include <editeng/pmdlitem.hxx>
+#include <editeng/spltitem.hxx>
+#include <editeng/hyznitem.hxx>
+#include <editeng/charscaleitem.hxx>
+#include <editeng/charrotateitem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <editeng/paravertalignitem.hxx>
+#include <editeng/forbiddenruleitem.hxx>
+#include <editeng/hngpnctitem.hxx>
+#include <editeng/scriptspaceitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/charhiddenitem.hxx>
+
+#include <svtools/rtftoken.h>
+#include <svl/itempool.hxx>
+#include <svl/itemiter.hxx>
+
+#include <editeng/svxrtf.hxx>
+#include <editeng/editids.hrc>
+
+#define BRACELEFT '{'
+#define BRACERIGHT '}'
+
+
+// einige Hilfs-Funktionen
+// char
+inline const SvxEscapementItem& GetEscapement(const SfxItemSet& rSet,USHORT nId,BOOL bInP=TRUE)
+ { return (const SvxEscapementItem&)rSet.Get( nId,bInP); }
+inline const SvxLineSpacingItem& GetLineSpacing(const SfxItemSet& rSet,USHORT nId,BOOL bInP=TRUE)
+ { return (const SvxLineSpacingItem&)rSet.Get( nId,bInP); }
+// frm
+inline const SvxLRSpaceItem& GetLRSpace(const SfxItemSet& rSet,USHORT nId,BOOL bInP=TRUE)
+ { return (const SvxLRSpaceItem&)rSet.Get( nId,bInP); }
+inline const SvxULSpaceItem& GetULSpace(const SfxItemSet& rSet,USHORT nId,BOOL bInP=TRUE)
+ { return (const SvxULSpaceItem&)rSet.Get( nId,bInP); }
+
+#define PARDID ((RTFPardAttrMapIds*)aPardMap.GetData())
+#define PLAINID ((RTFPlainAttrMapIds*)aPlainMap.GetData())
+
+void SvxRTFParser::SetScriptAttr( RTF_CharTypeDef eType, SfxItemSet& rSet,
+ SfxPoolItem& rItem )
+{
+ const USHORT *pNormal = 0, *pCJK = 0, *pCTL = 0;
+ const RTFPlainAttrMapIds* pIds = (RTFPlainAttrMapIds*)aPlainMap.GetData();
+ switch( rItem.Which() )
+ {
+ case SID_ATTR_CHAR_FONT:
+ pNormal = &pIds->nFont;
+ pCJK = &pIds->nCJKFont;
+ pCTL = &pIds->nCTLFont;
+ break;
+
+ case SID_ATTR_CHAR_FONTHEIGHT:
+ pNormal = &pIds->nFontHeight;
+ pCJK = &pIds->nCJKFontHeight;
+ pCTL = &pIds->nCTLFontHeight;
+ break;
+
+ case SID_ATTR_CHAR_POSTURE:
+ pNormal = &pIds->nPosture;
+ pCJK = &pIds->nCJKPosture;
+ pCTL = &pIds->nCTLPosture;
+ break;
+
+ case SID_ATTR_CHAR_WEIGHT:
+ pNormal = &pIds->nWeight;
+ pCJK = &pIds->nCJKWeight;
+ pCTL = &pIds->nCTLWeight;
+ break;
+
+ case SID_ATTR_CHAR_LANGUAGE:
+ pNormal = &pIds->nLanguage;
+ pCJK = &pIds->nCJKLanguage;
+ pCTL = &pIds->nCTLLanguage;
+ break;
+
+ case 0:
+ // it exist no WhichId - don't set this item
+ break;
+
+ default:
+ rSet.Put( rItem );
+ break;
+ }
+
+
+ if( DOUBLEBYTE_CHARTYPE == eType )
+ {
+ if( bIsLeftToRightDef && *pCJK )
+ {
+ rItem.SetWhich( *pCJK );
+ rSet.Put( rItem );
+ }
+ }
+ else if( !bIsLeftToRightDef )
+ {
+ if( *pCTL )
+ {
+ rItem.SetWhich( *pCTL );
+ rSet.Put( rItem );
+ }
+ }
+ else
+ {
+ if( LOW_CHARTYPE == eType )
+ {
+ if( *pNormal )
+ {
+ rItem.SetWhich( *pNormal );
+ rSet.Put( rItem );
+ }
+ }
+ else if( HIGH_CHARTYPE == eType )
+ {
+ if( *pCTL )
+ {
+ rItem.SetWhich( *pCTL );
+ rSet.Put( rItem );
+ }
+ }
+ else
+ {
+ if( *pCJK )
+ {
+ rItem.SetWhich( *pCJK );
+ rSet.Put( rItem );
+ }
+ if( *pCTL )
+ {
+ rItem.SetWhich( *pCTL );
+ rSet.Put( rItem );
+ }
+ if( *pNormal )
+ {
+ rItem.SetWhich( *pNormal );
+ rSet.Put( rItem );
+ }
+ }
+ }
+}
+
+// --------------------
+
+void SvxRTFParser::ReadAttr( int nToken, SfxItemSet* pSet )
+{
+ DBG_ASSERT( pSet, "Es muss ein SfxItemSet uebergeben werden!" );
+ int bFirstToken = TRUE, bWeiter = TRUE;
+ USHORT nStyleNo = 0; // default
+ FontUnderline eUnderline;
+ FontUnderline eOverline;
+ FontEmphasisMark eEmphasis;
+ bPardTokenRead = FALSE;
+ RTF_CharTypeDef eCharType = NOTDEF_CHARTYPE;
+ USHORT nFontAlign;
+
+ int bChkStkPos = !bNewGroup && aAttrStack.Top();
+
+ while( bWeiter && IsParserWorking() ) // solange bekannte Attribute erkannt werden
+ {
+ switch( nToken )
+ {
+ case RTF_PARD:
+ RTFPardPlain( TRUE, &pSet );
+ ResetPard();
+ nStyleNo = 0;
+ bPardTokenRead = TRUE;
+ break;
+
+ case RTF_PLAIN:
+ RTFPardPlain( FALSE, &pSet );
+ break;
+
+ default:
+ do { // middle checked loop
+ if( !bChkStkPos )
+ break;
+
+ SvxRTFItemStackType* pAkt = aAttrStack.Top();
+ if( !pAkt || (pAkt->pSttNd->GetIdx() == pInsPos->GetNodeIdx() &&
+ pAkt->nSttCnt == pInsPos->GetCntIdx() ))
+ break;
+
+ int nLastToken = GetStackPtr(-1)->nTokenId;
+ if( RTF_PARD == nLastToken || RTF_PLAIN == nLastToken )
+ break;
+
+ if( pAkt->aAttrSet.Count() || pAkt->pChildList ||
+ pAkt->nStyleNo )
+ {
+ // eine neue Gruppe aufmachen
+ SvxRTFItemStackType* pNew = new SvxRTFItemStackType(
+ *pAkt, *pInsPos, TRUE );
+ pNew->SetRTFDefaults( GetRTFDefaults() );
+
+ // alle bis hierher gueltigen Attribute "setzen"
+ AttrGroupEnd();
+ pAkt = aAttrStack.Top(); // can be changed after AttrGroupEnd!
+ pNew->aAttrSet.SetParent( pAkt ? &pAkt->aAttrSet : 0 );
+
+ aAttrStack.Push( pNew );
+ pAkt = pNew;
+ }
+ else
+ // diesen Eintrag als neuen weiterbenutzen
+ pAkt->SetStartPos( *pInsPos );
+
+ pSet = &pAkt->aAttrSet;
+ } while( FALSE );
+
+ switch( nToken )
+ {
+ case RTF_INTBL:
+ case RTF_PAGEBB:
+ case RTF_SBYS:
+ case RTF_CS:
+ case RTF_LS:
+ case RTF_ILVL:
+ UnknownAttrToken( nToken, pSet );
+ break;
+
+ case RTF_S:
+ if( bIsInReadStyleTab )
+ {
+ if( !bFirstToken )
+ SkipToken( -1 );
+ bWeiter = FALSE;
+ }
+ else
+ {
+ nStyleNo = -1 == nTokenValue ? 0 : USHORT(nTokenValue);
+ // setze am akt. auf dem AttrStack stehenden Style die
+ // StyleNummer
+ SvxRTFItemStackType* pAkt = aAttrStack.Top();
+ if( !pAkt )
+ break;
+
+ pAkt->nStyleNo = USHORT( nStyleNo );
+
+#if 0
+// JP 05.09.95: zuruecksetzen der Style-Attribute fuehrt nur zu Problemen.
+// Es muss reichen, wenn das ueber pard/plain erfolgt
+// ansonsten Bugdoc 15304.rtf - nach nur "\pard" falscher Font !!
+
+ SvxRTFStyleType* pStyle = aStyleTbl.Get( pAkt->nStyleNo );
+ if( pStyle && pStyle->aAttrSet.Count() )
+ {
+ //JP 07.07.95:
+ // alle Attribute, die in der Vorlage gesetzt werden
+ // auf defaults setzen. In RTF werden die Attribute
+ // der Vorlage danach ja wiederholt.
+ // WICHTIG: Attribute die in der Vorlage definiert
+ // sind, werden zurueckgesetzt !!!!
+ // pAkt->aAttrSet.Put( pStyle->aAttrSet );
+
+ SfxItemIter aIter( pStyle->aAttrSet );
+ SfxItemPool* pPool = pStyle->aAttrSet.GetPool();
+ USHORT nWh = aIter.GetCurItem()->Which();
+ while( TRUE )
+ {
+ pAkt->aAttrSet.Put( pPool->GetDefaultItem( nWh ));
+ if( aIter.IsAtEnd() )
+ break;
+ nWh = aIter.NextItem()->Which();
+ }
+ }
+#endif
+ }
+ break;
+
+ case RTF_KEEP:
+ if( PARDID->nSplit )
+ {
+ pSet->Put( SvxFmtSplitItem( FALSE, PARDID->nSplit ));
+ }
+ break;
+
+ case RTF_KEEPN:
+ if( PARDID->nKeep )
+ {
+ pSet->Put( SvxFmtKeepItem( TRUE, PARDID->nKeep ));
+ }
+ break;
+
+ case RTF_LEVEL:
+ if( PARDID->nOutlineLvl )
+ {
+ pSet->Put( SfxUInt16Item( PARDID->nOutlineLvl,
+ (UINT16)nTokenValue ));
+ }
+ break;
+
+ case RTF_QL:
+ if( PARDID->nAdjust )
+ {
+ pSet->Put( SvxAdjustItem( SVX_ADJUST_LEFT, PARDID->nAdjust ));
+ }
+ break;
+ case RTF_QR:
+ if( PARDID->nAdjust )
+ {
+ pSet->Put( SvxAdjustItem( SVX_ADJUST_RIGHT, PARDID->nAdjust ));
+ }
+ break;
+ case RTF_QJ:
+ if( PARDID->nAdjust )
+ {
+ pSet->Put( SvxAdjustItem( SVX_ADJUST_BLOCK, PARDID->nAdjust ));
+ }
+ break;
+ case RTF_QC:
+ if( PARDID->nAdjust )
+ {
+ pSet->Put( SvxAdjustItem( SVX_ADJUST_CENTER, PARDID->nAdjust ));
+ }
+ break;
+
+ case RTF_FI:
+ if( PARDID->nLRSpace )
+ {
+ SvxLRSpaceItem aLR( GetLRSpace(*pSet, PARDID->nLRSpace ));
+ USHORT nSz = 0;
+ if( -1 != nTokenValue )
+ {
+ if( IsCalcValue() )
+ CalcValue();
+ nSz = USHORT(nTokenValue);
+ }
+ aLR.SetTxtFirstLineOfst( nSz );
+ pSet->Put( aLR );
+ }
+ break;
+
+ case RTF_LI:
+ case RTF_LIN:
+ if( PARDID->nLRSpace )
+ {
+ SvxLRSpaceItem aLR( GetLRSpace(*pSet, PARDID->nLRSpace ));
+ USHORT nSz = 0;
+ if( 0 < nTokenValue )
+ {
+ if( IsCalcValue() )
+ CalcValue();
+ nSz = USHORT(nTokenValue);
+ }
+ aLR.SetTxtLeft( nSz );
+ pSet->Put( aLR );
+ }
+ break;
+
+ case RTF_RI:
+ case RTF_RIN:
+ if( PARDID->nLRSpace )
+ {
+ SvxLRSpaceItem aLR( GetLRSpace(*pSet, PARDID->nLRSpace ));
+ USHORT nSz = 0;
+ if( 0 < nTokenValue )
+ {
+ if( IsCalcValue() )
+ CalcValue();
+ nSz = USHORT(nTokenValue);
+ }
+ aLR.SetRight( nSz );
+ pSet->Put( aLR );
+ }
+ break;
+
+ case RTF_SB:
+ if( PARDID->nULSpace )
+ {
+ SvxULSpaceItem aUL( GetULSpace(*pSet, PARDID->nULSpace ));
+ USHORT nSz = 0;
+ if( 0 < nTokenValue )
+ {
+ if( IsCalcValue() )
+ CalcValue();
+ nSz = USHORT(nTokenValue);
+ }
+ aUL.SetUpper( nSz );
+ pSet->Put( aUL );
+ }
+ break;
+
+ case RTF_SA:
+ if( PARDID->nULSpace )
+ {
+ SvxULSpaceItem aUL( GetULSpace(*pSet, PARDID->nULSpace ));
+ USHORT nSz = 0;
+ if( 0 < nTokenValue )
+ {
+ if( IsCalcValue() )
+ CalcValue();
+ nSz = USHORT(nTokenValue);
+ }
+ aUL.SetLower( nSz );
+ pSet->Put( aUL );
+ }
+ break;
+
+ case RTF_SLMULT:
+ if( PARDID->nLinespacing && 1 == nTokenValue )
+ {
+ // dann wird auf mehrzeilig umgeschaltet!
+ SvxLineSpacingItem aLSpace( GetLineSpacing( *pSet,
+ PARDID->nLinespacing, FALSE ));
+
+ // wieviel bekommt man aus dem LineHeight Wert heraus
+
+ // Proportionale-Groesse:
+ // D.H. das Verhaeltnis ergibt sich aus ( n / 240 ) Twips
+
+ nTokenValue = 240;
+ if( IsCalcValue() )
+ CalcValue();
+
+ nTokenValue = short( 100L * aLSpace.GetLineHeight()
+ / long( nTokenValue ) );
+
+ if( nTokenValue > 200 ) // Datenwert fuer PropLnSp
+ nTokenValue = 200; // ist ein BYTE !!!
+
+ aLSpace.SetPropLineSpace( (const BYTE)nTokenValue );
+ aLSpace.GetLineSpaceRule() = SVX_LINE_SPACE_AUTO;
+
+ pSet->Put( aLSpace );
+ }
+ break;
+
+ case RTF_SL:
+ if( PARDID->nLinespacing )
+ {
+ // errechne das Verhaeltnis aus dem default Font zu der
+ // Size Angabe. Der Abstand besteht aus der Zeilenhoehe
+ // (100%) und dem Leerraum ueber der Zeile (20%).
+ SvxLineSpacingItem aLSpace(0, PARDID->nLinespacing);
+
+ nTokenValue = !bTokenHasValue ? 0 : nTokenValue;
+ if (1000 == nTokenValue )
+ nTokenValue = 240;
+
+ SvxLineSpace eLnSpc;
+ if (nTokenValue < 0)
+ {
+ eLnSpc = SVX_LINE_SPACE_FIX;
+ nTokenValue = -nTokenValue;
+ }
+ else if (nTokenValue == 0)
+ {
+ //if \sl0 is used, the line spacing is automatically
+ //determined
+ eLnSpc = SVX_LINE_SPACE_AUTO;
+ }
+ else
+ eLnSpc = SVX_LINE_SPACE_MIN;
+
+ if (IsCalcValue())
+ CalcValue();
+
+ if (eLnSpc != SVX_LINE_SPACE_AUTO)
+ aLSpace.SetLineHeight( (const USHORT)nTokenValue );
+
+ aLSpace.GetLineSpaceRule() = eLnSpc;
+ pSet->Put(aLSpace);
+ }
+ break;
+
+ case RTF_NOCWRAP:
+ if( PARDID->nForbRule )
+ {
+ pSet->Put( SvxForbiddenRuleItem( FALSE,
+ PARDID->nForbRule ));
+ }
+ break;
+ case RTF_NOOVERFLOW:
+ if( PARDID->nHangPunct )
+ {
+ pSet->Put( SvxHangingPunctuationItem( FALSE,
+ PARDID->nHangPunct ));
+ }
+ break;
+
+ case RTF_ASPALPHA:
+ if( PARDID->nScriptSpace )
+ {
+ pSet->Put( SvxScriptSpaceItem( TRUE,
+ PARDID->nScriptSpace ));
+ }
+ break;
+
+ case RTF_FAFIXED:
+ case RTF_FAAUTO: nFontAlign = SvxParaVertAlignItem::AUTOMATIC;
+ goto SET_FONTALIGNMENT;
+ case RTF_FAHANG: nFontAlign = SvxParaVertAlignItem::TOP;
+ goto SET_FONTALIGNMENT;
+ case RTF_FAVAR: nFontAlign = SvxParaVertAlignItem::BOTTOM;
+ goto SET_FONTALIGNMENT;
+ case RTF_FACENTER: nFontAlign = SvxParaVertAlignItem::CENTER;
+ goto SET_FONTALIGNMENT;
+ case RTF_FAROMAN: nFontAlign = SvxParaVertAlignItem::BASELINE;
+ goto SET_FONTALIGNMENT;
+SET_FONTALIGNMENT:
+ if( PARDID->nFontAlign )
+ {
+ pSet->Put( SvxParaVertAlignItem( nFontAlign,
+ PARDID->nFontAlign ));
+ }
+ break;
+
+/* */
+ case RTF_B:
+ case RTF_AB:
+ if( IsAttrSttPos() ) // nicht im Textfluss ?
+ {
+
+ SvxWeightItem aTmpItem(
+ nTokenValue ? WEIGHT_BOLD : WEIGHT_NORMAL,
+ SID_ATTR_CHAR_WEIGHT );
+ SetScriptAttr( eCharType, *pSet, aTmpItem);
+ }
+ break;
+
+ case RTF_CAPS:
+ case RTF_SCAPS:
+ if( PLAINID->nCaseMap &&
+ IsAttrSttPos() ) // nicht im Textfluss ?
+ {
+ SvxCaseMap eCaseMap;
+ if( !nTokenValue )
+ eCaseMap = SVX_CASEMAP_NOT_MAPPED;
+ else if( RTF_CAPS == nToken )
+ eCaseMap = SVX_CASEMAP_VERSALIEN;
+ else
+ eCaseMap = SVX_CASEMAP_KAPITAELCHEN;
+
+ pSet->Put( SvxCaseMapItem( eCaseMap, PLAINID->nCaseMap ));
+ }
+ break;
+
+ case RTF_DN:
+ case RTF_SUB:
+ if( PLAINID->nEscapement )
+ {
+ const USHORT nEsc = PLAINID->nEscapement;
+ if( -1 == nTokenValue || RTF_SUB == nToken )
+ nTokenValue = 6;
+ if( IsCalcValue() )
+ CalcValue();
+ const SvxEscapementItem& rOld = GetEscapement( *pSet, nEsc, FALSE );
+ short nEs;
+ BYTE nProp;
+ if( DFLT_ESC_AUTO_SUPER == rOld.GetEsc() )
+ {
+ nEs = DFLT_ESC_AUTO_SUB;
+ nProp = rOld.GetProp();
+ }
+ else
+ {
+ nEs = (short)-nTokenValue;
+ nProp = (nToken == RTF_SUB) ? DFLT_ESC_PROP : 100;
+ }
+ pSet->Put( SvxEscapementItem( nEs, nProp, nEsc ));
+ }
+ break;
+
+ case RTF_NOSUPERSUB:
+ if( PLAINID->nEscapement )
+ {
+ const USHORT nEsc = PLAINID->nEscapement;
+ pSet->Put( SvxEscapementItem( nEsc ));
+ }
+ break;
+
+ case RTF_EXPND:
+ if( PLAINID->nKering )
+ {
+ if( -1 == nTokenValue )
+ nTokenValue = 0;
+ else
+ nTokenValue *= 5;
+ if( IsCalcValue() )
+ CalcValue();
+ pSet->Put( SvxKerningItem( (short)nTokenValue, PLAINID->nKering ));
+ }
+ break;
+
+ case RTF_KERNING:
+ if( PLAINID->nAutoKerning )
+ {
+ if( -1 == nTokenValue )
+ nTokenValue = 0;
+ else
+ nTokenValue *= 10;
+ if( IsCalcValue() )
+ CalcValue();
+ pSet->Put( SvxAutoKernItem( 0 != nTokenValue,
+ PLAINID->nAutoKerning ));
+ }
+ break;
+
+ case RTF_EXPNDTW:
+ if( PLAINID->nKering )
+ {
+ if( -1 == nTokenValue )
+ nTokenValue = 0;
+ if( IsCalcValue() )
+ CalcValue();
+ pSet->Put( SvxKerningItem( (short)nTokenValue, PLAINID->nKering ));
+ }
+ break;
+
+ case RTF_F:
+ case RTF_AF:
+ {
+ const Font& rSVFont = GetFont( USHORT(nTokenValue) );
+ SvxFontItem aTmpItem( rSVFont.GetFamily(),
+ rSVFont.GetName(), rSVFont.GetStyleName(),
+ rSVFont.GetPitch(), rSVFont.GetCharSet(),
+ SID_ATTR_CHAR_FONT );
+ SetScriptAttr( eCharType, *pSet, aTmpItem );
+ if( RTF_F == nToken )
+ {
+ SetEncoding( rSVFont.GetCharSet() );
+ RereadLookahead();
+ }
+ }
+ break;
+
+ case RTF_FS:
+ case RTF_AFS:
+ {
+ if( -1 == nTokenValue )
+ nTokenValue = 240;
+ else
+ nTokenValue *= 10;
+// #i66167#
+// for the SwRTFParser 'IsCalcValue' will be false and for the EditRTFParser
+// the converiosn takes now place in EditRTFParser since for other reasons
+// the wrong MapUnit might still be use there
+// if( IsCalcValue() )
+// CalcValue();
+ SvxFontHeightItem aTmpItem(
+ (const USHORT)nTokenValue, 100,
+ SID_ATTR_CHAR_FONTHEIGHT );
+ SetScriptAttr( eCharType, *pSet, aTmpItem );
+ }
+ break;
+
+ case RTF_I:
+ case RTF_AI:
+ if( IsAttrSttPos() ) // nicht im Textfluss ?
+ {
+ SvxPostureItem aTmpItem(
+ nTokenValue ? ITALIC_NORMAL : ITALIC_NONE,
+ SID_ATTR_CHAR_POSTURE );
+ SetScriptAttr( eCharType, *pSet, aTmpItem );
+ }
+ break;
+
+ case RTF_OUTL:
+ if( PLAINID->nContour &&
+ IsAttrSttPos() ) // nicht im Textfluss ?
+ {
+ pSet->Put( SvxContourItem( nTokenValue ? TRUE : FALSE,
+ PLAINID->nContour ));
+ }
+ break;
+
+ case RTF_SHAD:
+ if( PLAINID->nShadowed &&
+ IsAttrSttPos() ) // nicht im Textfluss ?
+ {
+ pSet->Put( SvxShadowedItem( nTokenValue ? TRUE : FALSE,
+ PLAINID->nShadowed ));
+ }
+ break;
+
+ case RTF_STRIKE:
+ if( PLAINID->nCrossedOut &&
+ IsAttrSttPos() ) // nicht im Textfluss ?
+ {
+ pSet->Put( SvxCrossedOutItem(
+ nTokenValue ? STRIKEOUT_SINGLE : STRIKEOUT_NONE,
+ PLAINID->nCrossedOut ));
+ }
+ break;
+
+ case RTF_STRIKED:
+ if( PLAINID->nCrossedOut ) // nicht im Textfluss ?
+ {
+ pSet->Put( SvxCrossedOutItem(
+ nTokenValue ? STRIKEOUT_DOUBLE : STRIKEOUT_NONE,
+ PLAINID->nCrossedOut ));
+ }
+ break;
+
+ case RTF_UL:
+ if( !IsAttrSttPos() )
+ break;
+ eUnderline = nTokenValue ? UNDERLINE_SINGLE : UNDERLINE_NONE;
+ goto ATTR_SETUNDERLINE;
+
+ case RTF_ULD:
+ eUnderline = UNDERLINE_DOTTED;
+ goto ATTR_SETUNDERLINE;
+ case RTF_ULDASH:
+ eUnderline = UNDERLINE_DASH;
+ goto ATTR_SETUNDERLINE;
+ case RTF_ULDASHD:
+ eUnderline = UNDERLINE_DASHDOT;
+ goto ATTR_SETUNDERLINE;
+ case RTF_ULDASHDD:
+ eUnderline = UNDERLINE_DASHDOTDOT;
+ goto ATTR_SETUNDERLINE;
+ case RTF_ULDB:
+ eUnderline = UNDERLINE_DOUBLE;
+ goto ATTR_SETUNDERLINE;
+ case RTF_ULNONE:
+ eUnderline = UNDERLINE_NONE;
+ goto ATTR_SETUNDERLINE;
+ case RTF_ULTH:
+ eUnderline = UNDERLINE_BOLD;
+ goto ATTR_SETUNDERLINE;
+ case RTF_ULWAVE:
+ eUnderline = UNDERLINE_WAVE;
+ goto ATTR_SETUNDERLINE;
+ case RTF_ULTHD:
+ eUnderline = UNDERLINE_BOLDDOTTED;
+ goto ATTR_SETUNDERLINE;
+ case RTF_ULTHDASH:
+ eUnderline = UNDERLINE_BOLDDASH;
+ goto ATTR_SETUNDERLINE;
+ case RTF_ULLDASH:
+ eUnderline = UNDERLINE_LONGDASH;
+ goto ATTR_SETUNDERLINE;
+ case RTF_ULTHLDASH:
+ eUnderline = UNDERLINE_BOLDLONGDASH;
+ goto ATTR_SETUNDERLINE;
+ case RTF_ULTHDASHD:
+ eUnderline = UNDERLINE_BOLDDASHDOT;
+ goto ATTR_SETUNDERLINE;
+ case RTF_ULTHDASHDD:
+ eUnderline = UNDERLINE_BOLDDASHDOTDOT;
+ goto ATTR_SETUNDERLINE;
+ case RTF_ULHWAVE:
+ eUnderline = UNDERLINE_BOLDWAVE;
+ goto ATTR_SETUNDERLINE;
+ case RTF_ULULDBWAVE:
+ eUnderline = UNDERLINE_DOUBLEWAVE;
+ goto ATTR_SETUNDERLINE;
+
+ case RTF_ULW:
+ eUnderline = UNDERLINE_SINGLE;
+
+ if( PLAINID->nWordlineMode )
+ {
+ pSet->Put( SvxWordLineModeItem( TRUE, PLAINID->nWordlineMode ));
+ }
+ goto ATTR_SETUNDERLINE;
+
+ATTR_SETUNDERLINE:
+ if( PLAINID->nUnderline )
+ {
+ pSet->Put( SvxUnderlineItem( eUnderline, PLAINID->nUnderline ));
+ }
+ break;
+
+ case RTF_ULC:
+ if( PLAINID->nUnderline )
+ {
+ SvxUnderlineItem aUL( UNDERLINE_SINGLE, PLAINID->nUnderline );
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == pSet->GetItemState(
+ PLAINID->nUnderline, FALSE, &pItem ) )
+ {
+ // is switched off ?
+ if( UNDERLINE_NONE ==
+ ((SvxUnderlineItem*)pItem)->GetLineStyle() )
+ break;
+ aUL = *(SvxUnderlineItem*)pItem;
+ }
+ else
+ aUL = (const SvxUnderlineItem&)pSet->Get( PLAINID->nUnderline, FALSE );
+
+ if( UNDERLINE_NONE == aUL.GetLineStyle() )
+ aUL.SetLineStyle( UNDERLINE_SINGLE );
+ aUL.SetColor( GetColor( USHORT(nTokenValue) ));
+ pSet->Put( aUL );
+ }
+ break;
+
+ case RTF_OL:
+ if( !IsAttrSttPos() )
+ break;
+ eOverline = nTokenValue ? UNDERLINE_SINGLE : UNDERLINE_NONE;
+ goto ATTR_SETOVERLINE;
+
+ case RTF_OLD:
+ eOverline = UNDERLINE_DOTTED;
+ goto ATTR_SETOVERLINE;
+ case RTF_OLDASH:
+ eOverline = UNDERLINE_DASH;
+ goto ATTR_SETOVERLINE;
+ case RTF_OLDASHD:
+ eOverline = UNDERLINE_DASHDOT;
+ goto ATTR_SETOVERLINE;
+ case RTF_OLDASHDD:
+ eOverline = UNDERLINE_DASHDOTDOT;
+ goto ATTR_SETOVERLINE;
+ case RTF_OLDB:
+ eOverline = UNDERLINE_DOUBLE;
+ goto ATTR_SETOVERLINE;
+ case RTF_OLNONE:
+ eOverline = UNDERLINE_NONE;
+ goto ATTR_SETOVERLINE;
+ case RTF_OLTH:
+ eOverline = UNDERLINE_BOLD;
+ goto ATTR_SETOVERLINE;
+ case RTF_OLWAVE:
+ eOverline = UNDERLINE_WAVE;
+ goto ATTR_SETOVERLINE;
+ case RTF_OLTHD:
+ eOverline = UNDERLINE_BOLDDOTTED;
+ goto ATTR_SETOVERLINE;
+ case RTF_OLTHDASH:
+ eOverline = UNDERLINE_BOLDDASH;
+ goto ATTR_SETOVERLINE;
+ case RTF_OLLDASH:
+ eOverline = UNDERLINE_LONGDASH;
+ goto ATTR_SETOVERLINE;
+ case RTF_OLTHLDASH:
+ eOverline = UNDERLINE_BOLDLONGDASH;
+ goto ATTR_SETOVERLINE;
+ case RTF_OLTHDASHD:
+ eOverline = UNDERLINE_BOLDDASHDOT;
+ goto ATTR_SETOVERLINE;
+ case RTF_OLTHDASHDD:
+ eOverline = UNDERLINE_BOLDDASHDOTDOT;
+ goto ATTR_SETOVERLINE;
+ case RTF_OLHWAVE:
+ eOverline = UNDERLINE_BOLDWAVE;
+ goto ATTR_SETOVERLINE;
+ case RTF_OLOLDBWAVE:
+ eOverline = UNDERLINE_DOUBLEWAVE;
+ goto ATTR_SETOVERLINE;
+
+ case RTF_OLW:
+ eOverline = UNDERLINE_SINGLE;
+
+ if( PLAINID->nWordlineMode )
+ {
+ pSet->Put( SvxWordLineModeItem( TRUE, PLAINID->nWordlineMode ));
+ }
+ goto ATTR_SETOVERLINE;
+
+ATTR_SETOVERLINE:
+ if( PLAINID->nUnderline )
+ {
+ pSet->Put( SvxOverlineItem( eOverline, PLAINID->nOverline ));
+ }
+ break;
+
+ case RTF_OLC:
+ if( PLAINID->nOverline )
+ {
+ SvxOverlineItem aOL( UNDERLINE_SINGLE, PLAINID->nOverline );
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == pSet->GetItemState(
+ PLAINID->nOverline, FALSE, &pItem ) )
+ {
+ // is switched off ?
+ if( UNDERLINE_NONE ==
+ ((SvxOverlineItem*)pItem)->GetLineStyle() )
+ break;
+ aOL = *(SvxOverlineItem*)pItem;
+ }
+ else
+ aOL = (const SvxOverlineItem&)pSet->Get( PLAINID->nUnderline, FALSE );
+
+ if( UNDERLINE_NONE == aOL.GetLineStyle() )
+ aOL.SetLineStyle( UNDERLINE_SINGLE );
+ aOL.SetColor( GetColor( USHORT(nTokenValue) ));
+ pSet->Put( aOL );
+ }
+ break;
+
+ case RTF_UP:
+ case RTF_SUPER:
+ if( PLAINID->nEscapement )
+ {
+ const USHORT nEsc = PLAINID->nEscapement;
+ if( -1 == nTokenValue || RTF_SUPER == nToken )
+ nTokenValue = 6;
+ if( IsCalcValue() )
+ CalcValue();
+ const SvxEscapementItem& rOld = GetEscapement( *pSet, nEsc, FALSE );
+ short nEs;
+ BYTE nProp;
+ if( DFLT_ESC_AUTO_SUB == rOld.GetEsc() )
+ {
+ nEs = DFLT_ESC_AUTO_SUPER;
+ nProp = rOld.GetProp();
+ }
+ else
+ {
+ nEs = (short)nTokenValue;
+ nProp = (nToken == RTF_SUPER) ? DFLT_ESC_PROP : 100;
+ }
+ pSet->Put( SvxEscapementItem( nEs, nProp, nEsc ));
+ }
+ break;
+
+ case RTF_CF:
+ if( PLAINID->nColor )
+ {
+ pSet->Put( SvxColorItem( GetColor( USHORT(nTokenValue) ),
+ PLAINID->nColor ));
+ }
+ break;
+#if 0
+ //#i12501# While cb is clearly documented in the rtf spec, word
+ //doesn't accept it at all
+ case RTF_CB:
+ if( PLAINID->nBgColor )
+ {
+ pSet->Put( SvxBrushItem( GetColor( USHORT(nTokenValue) ),
+ PLAINID->nBgColor ));
+ }
+ break;
+#endif
+ case RTF_LANG:
+ if( PLAINID->nLanguage )
+ {
+ pSet->Put( SvxLanguageItem( (LanguageType)nTokenValue,
+ PLAINID->nLanguage ));
+ }
+ break;
+
+ case RTF_LANGFE:
+ if( PLAINID->nCJKLanguage )
+ {
+ pSet->Put( SvxLanguageItem( (LanguageType)nTokenValue,
+ PLAINID->nCJKLanguage ));
+ }
+ break;
+ case RTF_ALANG:
+ {
+ SvxLanguageItem aTmpItem( (LanguageType)nTokenValue,
+ SID_ATTR_CHAR_LANGUAGE );
+ SetScriptAttr( eCharType, *pSet, aTmpItem );
+ }
+ break;
+
+ case RTF_RTLCH:
+ bIsLeftToRightDef = FALSE;
+ break;
+ case RTF_LTRCH:
+ bIsLeftToRightDef = TRUE;
+ break;
+ case RTF_RTLPAR:
+ if (PARDID->nDirection)
+ {
+ pSet->Put(SvxFrameDirectionItem(FRMDIR_HORI_RIGHT_TOP,
+ PARDID->nDirection));
+ }
+ break;
+ case RTF_LTRPAR:
+ if (PARDID->nDirection)
+ {
+ pSet->Put(SvxFrameDirectionItem(FRMDIR_HORI_LEFT_TOP,
+ PARDID->nDirection));
+ }
+ break;
+ case RTF_LOCH: eCharType = LOW_CHARTYPE; break;
+ case RTF_HICH: eCharType = HIGH_CHARTYPE; break;
+ case RTF_DBCH: eCharType = DOUBLEBYTE_CHARTYPE; break;
+
+
+ case RTF_ACCNONE:
+ eEmphasis = EMPHASISMARK_NONE;
+ goto ATTR_SETEMPHASIS;
+ case RTF_ACCDOT:
+ eEmphasis = EMPHASISMARK_DOTS_ABOVE;
+ goto ATTR_SETEMPHASIS;
+
+ case RTF_ACCCOMMA:
+ eEmphasis = EMPHASISMARK_SIDE_DOTS;
+ATTR_SETEMPHASIS:
+ if( PLAINID->nEmphasis )
+ {
+ pSet->Put( SvxEmphasisMarkItem( eEmphasis,
+ PLAINID->nEmphasis ));
+ }
+ break;
+
+ case RTF_TWOINONE:
+ if( PLAINID->nTwoLines )
+ {
+ sal_Unicode cStt, cEnd;
+ switch ( nTokenValue )
+ {
+ case 1: cStt = '(', cEnd = ')'; break;
+ case 2: cStt = '[', cEnd = ']'; break;
+ case 3: cStt = '<', cEnd = '>'; break;
+ case 4: cStt = '{', cEnd = '}'; break;
+ default: cStt = 0, cEnd = 0; break;
+ }
+
+ pSet->Put( SvxTwoLinesItem( TRUE, cStt, cEnd,
+ PLAINID->nTwoLines ));
+ }
+ break;
+
+ case RTF_CHARSCALEX :
+ if (PLAINID->nCharScaleX)
+ {
+ //i21372
+ if (nTokenValue < 1 || nTokenValue > 600)
+ nTokenValue = 100;
+ pSet->Put( SvxCharScaleWidthItem( USHORT(nTokenValue),
+ PLAINID->nCharScaleX ));
+ }
+ break;
+
+ case RTF_HORZVERT:
+ if( PLAINID->nHorzVert )
+ {
+ // RTF knows only 90deg
+ pSet->Put( SvxCharRotateItem( 900, 1 == nTokenValue,
+ PLAINID->nHorzVert ));
+ }
+ break;
+
+ case RTF_EMBO:
+ if (PLAINID->nRelief)
+ {
+ pSet->Put(SvxCharReliefItem(RELIEF_EMBOSSED,
+ PLAINID->nRelief));
+ }
+ break;
+ case RTF_IMPR:
+ if (PLAINID->nRelief)
+ {
+ pSet->Put(SvxCharReliefItem(RELIEF_ENGRAVED,
+ PLAINID->nRelief));
+ }
+ break;
+ case RTF_V:
+ if (PLAINID->nHidden)
+ {
+ pSet->Put(SvxCharHiddenItem(nTokenValue != 0,
+ PLAINID->nHidden));
+ }
+ break;
+ case RTF_CHBGFDIAG:
+ case RTF_CHBGDKVERT:
+ case RTF_CHBGDKHORIZ:
+ case RTF_CHBGVERT:
+ case RTF_CHBGHORIZ:
+ case RTF_CHBGDKFDIAG:
+ case RTF_CHBGDCROSS:
+ case RTF_CHBGCROSS:
+ case RTF_CHBGBDIAG:
+ case RTF_CHBGDKDCROSS:
+ case RTF_CHBGDKCROSS:
+ case RTF_CHBGDKBDIAG:
+ case RTF_CHCBPAT:
+ case RTF_CHCFPAT:
+ case RTF_CHSHDNG:
+ if( PLAINID->nBgColor )
+ ReadBackgroundAttr( nToken, *pSet );
+ break;
+
+
+/* */
+
+ case BRACELEFT:
+ {
+ // teste auf Swg-Interne Tokens
+ bool bHandled = false;
+ short nSkip = 0;
+ if( RTF_IGNOREFLAG != GetNextToken())
+ nSkip = -1;
+ else if( (nToken = GetNextToken() ) & RTF_SWGDEFS )
+ {
+ bHandled = true;
+ switch( nToken )
+ {
+ case RTF_PGDSCNO:
+ case RTF_PGBRK:
+ case RTF_SOUTLVL:
+ UnknownAttrToken( nToken, pSet );
+ // ueberlese die schliessende Klammer
+ break;
+
+ case RTF_SWG_ESCPROP:
+ {
+ // prozentuale Veraenderung speichern !
+ BYTE nProp = BYTE( nTokenValue / 100 );
+ short nEsc = 0;
+ if( 1 == ( nTokenValue % 100 ))
+ // Erkennung unseres AutoFlags!
+ nEsc = DFLT_ESC_AUTO_SUPER;
+
+ if( PLAINID->nEscapement )
+ pSet->Put( SvxEscapementItem( nEsc, nProp,
+ PLAINID->nEscapement ));
+ }
+ break;
+
+ case RTF_HYPHEN:
+ {
+ SvxHyphenZoneItem aHypenZone(
+ (nTokenValue & 1) ? TRUE : FALSE,
+ PARDID->nHyphenzone );
+ aHypenZone.SetPageEnd(
+ (nTokenValue & 2) ? TRUE : FALSE );
+
+ if( PARDID->nHyphenzone &&
+ RTF_HYPHLEAD == GetNextToken() &&
+ RTF_HYPHTRAIL == GetNextToken() &&
+ RTF_HYPHMAX == GetNextToken() )
+ {
+ aHypenZone.GetMinLead() =
+ BYTE(GetStackPtr( -2 )->nTokenValue);
+ aHypenZone.GetMinTrail() =
+ BYTE(GetStackPtr( -1 )->nTokenValue);
+ aHypenZone.GetMaxHyphens() =
+ BYTE(nTokenValue);
+
+ pSet->Put( aHypenZone );
+ }
+ else
+ SkipGroup(); // ans Ende der Gruppe
+ }
+ break;
+
+ case RTF_SHADOW:
+ {
+ int bSkip = TRUE;
+ do { // middle check loop
+ SvxShadowLocation eSL = SvxShadowLocation( nTokenValue );
+ if( RTF_SHDW_DIST != GetNextToken() )
+ break;
+ USHORT nDist = USHORT( nTokenValue );
+
+ if( RTF_SHDW_STYLE != GetNextToken() )
+ break;
+ //! (pb) class Brush removed -> obsolete
+ //! BrushStyle eStyle = BrushStyle( nTokenValue );
+
+ if( RTF_SHDW_COL != GetNextToken() )
+ break;
+ USHORT nCol = USHORT( nTokenValue );
+
+ if( RTF_SHDW_FCOL != GetNextToken() )
+ break;
+// USHORT nFillCol = USHORT( nTokenValue );
+
+ Color aColor = GetColor( nCol );
+
+ if( PARDID->nShadow )
+ pSet->Put( SvxShadowItem( PARDID->nShadow,
+ &aColor, nDist, eSL ) );
+
+ bSkip = FALSE;
+ } while( FALSE );
+
+ if( bSkip )
+ SkipGroup(); // ans Ende der Gruppe
+ }
+ break;
+
+ default:
+ bHandled = false;
+ if( (nToken & ~(0xff | RTF_SWGDEFS)) == RTF_TABSTOPDEF )
+ {
+ nToken = SkipToken( -2 );
+ ReadTabAttr( nToken, *pSet );
+
+ /*
+ cmc: #i76140, he who consumed the { must consume the }
+ We rewound to a state of { being the current
+ token so it is our responsibility to consume the }
+ token if we consumed the {. We will not have consumed
+ the { if it belonged to our caller, i.e. if the { we
+ are handling is the "firsttoken" passed to us then
+ the *caller* must consume it, not us. Otherwise *we*
+ should consume it.
+ */
+ if (nToken == BRACELEFT && !bFirstToken)
+ {
+ nToken = GetNextToken();
+ DBG_ASSERT( nToken == BRACERIGHT,
+ "} did not follow { as expected\n");
+ }
+ }
+ else if( (nToken & ~(0xff| RTF_SWGDEFS)) == RTF_BRDRDEF)
+ {
+ nToken = SkipToken( -2 );
+ ReadBorderAttr( nToken, *pSet );
+ }
+ else // also kein Attribut mehr
+ nSkip = -2;
+ break;
+ }
+
+#if 1
+ /*
+ cmc: #i4727# / #i12713# Who owns this closing bracket?
+ If we read the opening one, we must read this one, if
+ other is counting the brackets so as to push/pop off
+ the correct environment then we will have pushed a new
+ environment for the start { of this, but will not see
+ the } and so is out of sync for the rest of the
+ document.
+ */
+ if (bHandled && !bFirstToken)
+ GetNextToken();
+#endif
+ }
+ else
+ nSkip = -2;
+
+ if( nSkip ) // alles voellig unbekannt
+ {
+ if (!bFirstToken)
+ --nSkip; // BRACELEFT: ist das naechste Token
+ SkipToken( nSkip );
+ bWeiter = FALSE;
+ }
+ }
+ break;
+ default:
+ if( (nToken & ~0xff ) == RTF_TABSTOPDEF )
+ ReadTabAttr( nToken, *pSet );
+ else if( (nToken & ~0xff ) == RTF_BRDRDEF )
+ ReadBorderAttr( nToken, *pSet );
+ else if( (nToken & ~0xff ) == RTF_SHADINGDEF )
+ ReadBackgroundAttr( nToken, *pSet );
+ else
+ {
+ // kenne das Token nicht also das Token "in den Parser zurueck"
+ if( !bFirstToken )
+ SkipToken( -1 );
+ bWeiter = FALSE;
+ }
+ }
+ }
+ if( bWeiter )
+ {
+ nToken = GetNextToken();
+ }
+ bFirstToken = FALSE;
+ }
+
+/*
+ // teste Attribute gegen ihre Styles
+ if( IsChkStyleAttr() && pSet->Count() && !pInsPos->GetCntIdx() )
+ {
+ SvxRTFStyleType* pStyle = aStyleTbl.Get( nStyleNo );
+ if( pStyle && pStyle->aAttrSet.Count() )
+ {
+ // alle Attribute, die schon vom Style definiert sind, aus dem
+ // akt. Set entfernen
+ const SfxPoolItem* pItem;
+ SfxItemIter aIter( *pSet );
+ USHORT nWhich = aIter.GetCurItem()->Which();
+ while( TRUE )
+ {
+ if( SFX_ITEM_SET == pStyle->aAttrSet.GetItemState(
+ nWhich, FALSE, &pItem ) && *pItem == *aIter.GetCurItem())
+ pSet->ClearItem( nWhich ); // loeschen
+
+ if( aIter.IsAtEnd() )
+ break;
+ nWhich = aIter.NextItem()->Which();
+ }
+ }
+ }
+*/
+}
+
+void SvxRTFParser::ReadTabAttr( int nToken, SfxItemSet& rSet )
+{
+ bool bMethodOwnsToken = false; // #i52542# patch from cmc.
+// dann lese doch mal alle TabStops ein
+ SvxTabStop aTabStop;
+ SvxTabStopItem aAttr( 0, 0, SVX_TAB_ADJUST_DEFAULT, PARDID->nTabStop );
+ int bWeiter = TRUE;
+ do {
+ switch( nToken )
+ {
+ case RTF_TB: // BarTab ???
+ case RTF_TX:
+ {
+ if( IsCalcValue() )
+ CalcValue();
+ aTabStop.GetTabPos() = nTokenValue;
+ aAttr.Insert( aTabStop );
+ aTabStop = SvxTabStop(); // alle Werte default
+ }
+ break;
+
+ case RTF_TQL:
+ aTabStop.GetAdjustment() = SVX_TAB_ADJUST_LEFT;
+ break;
+ case RTF_TQR:
+ aTabStop.GetAdjustment() = SVX_TAB_ADJUST_RIGHT;
+ break;
+ case RTF_TQC:
+ aTabStop.GetAdjustment() = SVX_TAB_ADJUST_CENTER;
+ break;
+ case RTF_TQDEC:
+ aTabStop.GetAdjustment() = SVX_TAB_ADJUST_DECIMAL;
+ break;
+
+ case RTF_TLDOT: aTabStop.GetFill() = '.'; break;
+ case RTF_TLHYPH: aTabStop.GetFill() = ' '; break;
+ case RTF_TLUL: aTabStop.GetFill() = '_'; break;
+ case RTF_TLTH: aTabStop.GetFill() = '-'; break;
+ case RTF_TLEQ: aTabStop.GetFill() = '='; break;
+
+ case BRACELEFT:
+ {
+ // Swg - Kontrol BRACELEFT RTF_IGNOREFLAG RTF_TLSWG BRACERIGHT
+ short nSkip = 0;
+ if( RTF_IGNOREFLAG != GetNextToken() )
+ nSkip = -1;
+ else if( RTF_TLSWG != ( nToken = GetNextToken() ))
+ nSkip = -2;
+ else
+ {
+ aTabStop.GetDecimal() = BYTE(nTokenValue & 0xff);
+ aTabStop.GetFill() = BYTE((nTokenValue >> 8) & 0xff);
+ // ueberlese noch die schliessende Klammer
+ if (bMethodOwnsToken)
+ GetNextToken();
+ }
+ if( nSkip )
+ {
+ SkipToken( nSkip ); // Ignore wieder zurueck
+ bWeiter = FALSE;
+ }
+ }
+ break;
+
+ default:
+ bWeiter = FALSE;
+ }
+ if( bWeiter )
+ {
+ nToken = GetNextToken();
+ bMethodOwnsToken = true;
+ }
+ } while( bWeiter );
+
+ // mit Defaults aufuellen fehlt noch !!!
+ rSet.Put( aAttr );
+ SkipToken( -1 );
+}
+
+static void SetBorderLine( int nBorderTyp, SvxBoxItem& rItem,
+ const SvxBorderLine& rBorder )
+{
+ switch( nBorderTyp )
+ {
+ case RTF_BOX: // alle Stufen durchlaufen
+
+ case RTF_BRDRT:
+ rItem.SetLine( &rBorder, BOX_LINE_TOP );
+ if( RTF_BOX != nBorderTyp )
+ return;
+
+ case RTF_BRDRB:
+ rItem.SetLine( &rBorder, BOX_LINE_BOTTOM );
+ if( RTF_BOX != nBorderTyp )
+ return;
+
+ case RTF_BRDRL:
+ rItem.SetLine( &rBorder, BOX_LINE_LEFT );
+ if( RTF_BOX != nBorderTyp )
+ return;
+
+ case RTF_BRDRR:
+ rItem.SetLine( &rBorder, BOX_LINE_RIGHT );
+ if( RTF_BOX != nBorderTyp )
+ return;
+ }
+}
+
+void SvxRTFParser::ReadBorderAttr( int nToken, SfxItemSet& rSet,
+ int bTableDef )
+{
+ // dann lese doch mal das BoderAttribut ein
+ SvxBoxItem aAttr( PARDID->nBox );
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == rSet.GetItemState( PARDID->nBox, FALSE, &pItem ) )
+ aAttr = *(SvxBoxItem*)pItem;
+
+ SvxBorderLine aBrd( 0, DEF_LINE_WIDTH_0, 0, 0 ); // einfache Linien
+ int bWeiter = TRUE, nBorderTyp = 0;
+
+ do {
+ switch( nToken )
+ {
+ case RTF_BOX:
+ case RTF_BRDRT:
+ case RTF_BRDRB:
+ case RTF_BRDRL:
+ case RTF_BRDRR:
+ nBorderTyp = nToken;
+ goto SETBORDER;
+
+ case RTF_CLBRDRT:
+ if( !bTableDef )
+ break;
+ nBorderTyp = RTF_BRDRT;
+ goto SETBORDER;
+ case RTF_CLBRDRB:
+ if( !bTableDef )
+ break;
+ nBorderTyp = RTF_BRDRB;
+ goto SETBORDER;
+ case RTF_CLBRDRL:
+ if( !bTableDef )
+ break;
+ nBorderTyp = RTF_BRDRL;
+ goto SETBORDER;
+ case RTF_CLBRDRR:
+ if( !bTableDef )
+ break;
+ nBorderTyp = RTF_BRDRR;
+ goto SETBORDER;
+
+SETBORDER:
+ {
+ // auf defaults setzen
+ aBrd.SetOutWidth( DEF_LINE_WIDTH_0 );
+ aBrd.SetInWidth( 0 );
+ aBrd.SetDistance( 0 );
+ aBrd.SetColor( Color( COL_BLACK ) );
+ }
+ break;
+
+
+// werden noch nicht ausgewertet
+ case RTF_BRSP:
+ {
+ switch( nBorderTyp )
+ {
+ case RTF_BRDRB:
+ aAttr.SetDistance( (USHORT)nTokenValue, BOX_LINE_BOTTOM );
+ break;
+
+ case RTF_BRDRT:
+ aAttr.SetDistance( (USHORT)nTokenValue, BOX_LINE_TOP );
+ break;
+
+ case RTF_BRDRL:
+ aAttr.SetDistance( (USHORT)nTokenValue, BOX_LINE_LEFT );
+ break;
+
+ case RTF_BRDRR:
+ aAttr.SetDistance( (USHORT)nTokenValue, BOX_LINE_RIGHT );
+ break;
+
+ case RTF_BOX:
+ aAttr.SetDistance( (USHORT)nTokenValue );
+ break;
+ }
+ }
+ break;
+
+case RTF_BRDRBTW:
+case RTF_BRDRBAR: break;
+
+
+ case RTF_BRDRCF:
+ {
+ aBrd.SetColor( GetColor( USHORT(nTokenValue) ) );
+ SetBorderLine( nBorderTyp, aAttr, aBrd );
+ }
+ break;
+
+ case RTF_BRDRTH:
+ aBrd.SetOutWidth( DEF_LINE_WIDTH_1 );
+ aBrd.SetInWidth( 0 );
+ aBrd.SetDistance( 0 );
+ goto SETBORDERLINE;
+
+ case RTF_BRDRDB:
+ aBrd.SetOutWidth( DEF_DOUBLE_LINE0_OUT );
+ aBrd.SetInWidth( DEF_DOUBLE_LINE0_IN );
+ aBrd.SetDistance( DEF_DOUBLE_LINE0_DIST );
+ goto SETBORDERLINE;
+
+ case RTF_BRDRSH:
+ // schattierte Box
+ {
+ rSet.Put( SvxShadowItem( PARDID->nShadow, (Color*) 0, 60 /*3pt*/,
+ SVX_SHADOW_BOTTOMRIGHT ) );
+ }
+ break;
+
+ case RTF_BRDRW:
+ if( -1 != nTokenValue )
+ {
+ // sollte es eine "dicke" Linie sein ?
+ if( DEF_LINE_WIDTH_0 != aBrd.GetOutWidth() )
+ nTokenValue *= 2;
+
+ // eine Doppelline?
+ if( aBrd.GetInWidth() )
+ {
+ // WinWord - Werte an StarOffice anpassen
+ if( nTokenValue < DEF_LINE_WIDTH_1 - (DEF_LINE_WIDTH_1/10))
+ {
+ aBrd.SetOutWidth( DEF_DOUBLE_LINE0_OUT );
+ aBrd.SetInWidth( DEF_DOUBLE_LINE0_IN );
+ aBrd.SetDistance( DEF_DOUBLE_LINE0_DIST );
+ }
+ else
+ if( nTokenValue < DEF_LINE_WIDTH_2 - (DEF_LINE_WIDTH_2/10))
+ {
+ aBrd.SetOutWidth( DEF_DOUBLE_LINE1_OUT );
+ aBrd.SetInWidth( DEF_DOUBLE_LINE1_IN );
+ aBrd.SetDistance( DEF_DOUBLE_LINE1_DIST );
+ }
+ else
+ {
+ aBrd.SetOutWidth( DEF_DOUBLE_LINE2_OUT );
+ aBrd.SetInWidth( DEF_DOUBLE_LINE2_IN );
+ aBrd.SetDistance( DEF_DOUBLE_LINE2_DIST );
+ }
+ }
+ else
+ {
+ // WinWord - Werte an StarOffice anpassen
+ if( nTokenValue < DEF_LINE_WIDTH_1 - (DEF_LINE_WIDTH_1/10))
+ aBrd.SetOutWidth( DEF_LINE_WIDTH_0 );
+ else
+ if( nTokenValue < DEF_LINE_WIDTH_2 - (DEF_LINE_WIDTH_2/10))
+ aBrd.SetOutWidth( DEF_LINE_WIDTH_1 );
+ else
+ if( nTokenValue < DEF_LINE_WIDTH_3 - (DEF_LINE_WIDTH_3/10))
+ aBrd.SetOutWidth( DEF_LINE_WIDTH_2 );
+ else
+ if( nTokenValue < DEF_LINE_WIDTH_4 )
+ aBrd.SetOutWidth( DEF_LINE_WIDTH_3 );
+ else
+ aBrd.SetOutWidth( DEF_LINE_WIDTH_4 );
+ }
+ }
+ goto SETBORDERLINE;
+
+ case RTF_BRDRS:
+ case RTF_BRDRDOT:
+ case RTF_BRDRHAIR:
+ case RTF_BRDRDASH:
+SETBORDERLINE:
+ SetBorderLine( nBorderTyp, aAttr, aBrd );
+ break;
+
+ case BRACELEFT:
+ {
+ short nSkip = 0;
+ if( RTF_IGNOREFLAG != GetNextToken() )
+ nSkip = -1;
+ else
+ {
+ int bSwgControl = TRUE, bFirstToken = TRUE;
+ nToken = GetNextToken();
+ do {
+ switch( nToken )
+ {
+ case RTF_BRDBOX:
+ aAttr.SetDistance( USHORT(nTokenValue) );
+ break;
+
+ case RTF_BRDRT:
+ case RTF_BRDRB:
+ case RTF_BRDRR:
+ case RTF_BRDRL:
+ nBorderTyp = nToken;
+ bFirstToken = FALSE;
+ if( RTF_BRDLINE_COL != GetNextToken() )
+ {
+ bSwgControl = FALSE;
+ break;
+ }
+ aBrd.SetColor( GetColor( USHORT(nTokenValue) ));
+
+ if( RTF_BRDLINE_IN != GetNextToken() )
+ {
+ bSwgControl = FALSE;
+ break;
+ }
+ aBrd.SetInWidth( USHORT(nTokenValue));
+
+ if( RTF_BRDLINE_OUT != GetNextToken() )
+ {
+ bSwgControl = FALSE;
+ break;
+ }
+ aBrd.SetOutWidth( USHORT(nTokenValue));
+
+ if( RTF_BRDLINE_DIST != GetNextToken() )
+ {
+ bSwgControl = FALSE;
+ break;
+ }
+ aBrd.SetDistance( USHORT(nTokenValue));
+ SetBorderLine( nBorderTyp, aAttr, aBrd );
+ break;
+
+ default:
+ bSwgControl = FALSE;
+ break;
+ }
+
+ if( bSwgControl )
+ {
+ nToken = GetNextToken();
+ bFirstToken = FALSE;
+ }
+ } while( bSwgControl );
+
+ // Ende der Swg-Gruppe
+ // -> lese noch die schliessende Klammer
+ if( BRACERIGHT == nToken )
+ ;
+ else if( !bFirstToken )
+ {
+ // es ist ein Parser-Fehler, springe zum
+ // Ende der Gruppe
+ SkipGroup();
+ // schliessende BRACERIGHT ueberspringen
+ GetNextToken();
+ }
+ else
+ nSkip = -2;
+ }
+
+ if( nSkip )
+ {
+ SkipToken( nSkip ); // Ignore wieder zurueck
+ bWeiter = FALSE;
+ }
+ }
+ break;
+
+ default:
+ bWeiter = (nToken & ~(0xff| RTF_SWGDEFS)) == RTF_BRDRDEF;
+ }
+ if( bWeiter )
+ nToken = GetNextToken();
+ } while( bWeiter );
+ rSet.Put( aAttr );
+ SkipToken( -1 );
+}
+
+inline ULONG CalcShading( ULONG nColor, ULONG nFillColor, BYTE nShading )
+{
+ nColor = (nColor * nShading) / 100;
+ nFillColor = (nFillColor * ( 100 - nShading )) / 100;
+ return nColor + nFillColor;
+}
+
+void SvxRTFParser::ReadBackgroundAttr( int nToken, SfxItemSet& rSet,
+ int bTableDef )
+{
+ // dann lese doch mal das BoderAttribut ein
+ int bWeiter = TRUE;
+ USHORT nColor = USHRT_MAX, nFillColor = USHRT_MAX;
+ BYTE nFillValue = 0;
+
+ USHORT nWh = ( nToken & ~0xff ) == RTF_CHRFMT
+ ? PLAINID->nBgColor
+ : PARDID->nBrush;
+
+ do {
+ switch( nToken )
+ {
+ case RTF_CLCBPAT:
+ case RTF_CHCBPAT:
+ case RTF_CBPAT:
+ nFillColor = USHORT( nTokenValue );
+ break;
+
+ case RTF_CLCFPAT:
+ case RTF_CHCFPAT:
+ case RTF_CFPAT:
+ nColor = USHORT( nTokenValue );
+ break;
+
+ case RTF_CLSHDNG:
+ case RTF_CHSHDNG:
+ case RTF_SHADING:
+ nFillValue = (BYTE)( nTokenValue / 100 );
+ break;
+
+ case RTF_CLBGDKHOR:
+ case RTF_CHBGDKHORIZ:
+ case RTF_BGDKHORIZ:
+ case RTF_CLBGDKVERT:
+ case RTF_CHBGDKVERT:
+ case RTF_BGDKVERT:
+ case RTF_CLBGDKBDIAG:
+ case RTF_CHBGDKBDIAG:
+ case RTF_BGDKBDIAG:
+ case RTF_CLBGDKFDIAG:
+ case RTF_CHBGDKFDIAG:
+ case RTF_BGDKFDIAG:
+ case RTF_CLBGDKCROSS:
+ case RTF_CHBGDKCROSS:
+ case RTF_BGDKCROSS:
+ case RTF_CLBGDKDCROSS:
+ case RTF_CHBGDKDCROSS:
+ case RTF_BGDKDCROSS:
+ // dark -> 60%
+ nFillValue = 60;
+ break;
+
+ case RTF_CLBGHORIZ:
+ case RTF_CHBGHORIZ:
+ case RTF_BGHORIZ:
+ case RTF_CLBGVERT:
+ case RTF_CHBGVERT:
+ case RTF_BGVERT:
+ case RTF_CLBGBDIAG:
+ case RTF_CHBGBDIAG:
+ case RTF_BGBDIAG:
+ case RTF_CLBGFDIAG:
+ case RTF_CHBGFDIAG:
+ case RTF_BGFDIAG:
+ case RTF_CLBGCROSS:
+ case RTF_CHBGCROSS:
+ case RTF_BGCROSS:
+ case RTF_CLBGDCROSS:
+ case RTF_CHBGDCROSS:
+ case RTF_BGDCROSS:
+ // light -> 20%
+ nFillValue = 20;
+ break;
+
+ default:
+ if( bTableDef )
+ bWeiter = (nToken & ~(0xff | RTF_TABLEDEF) ) == RTF_SHADINGDEF;
+ else
+ bWeiter = (nToken & ~0xff) == RTF_SHADINGDEF;
+ }
+ if( bWeiter )
+ nToken = GetNextToken();
+ } while( bWeiter );
+
+ Color aCol( COL_WHITE ), aFCol;
+ if( !nFillValue )
+ {
+ // es wurde nur eine von beiden Farben angegeben oder kein BrushTyp
+ if( USHRT_MAX != nFillColor )
+ {
+ nFillValue = 100;
+ aCol = GetColor( nFillColor );
+ }
+ else if( USHRT_MAX != nColor )
+ aFCol = GetColor( nColor );
+ }
+ else
+ {
+ if( USHRT_MAX != nColor )
+ aCol = GetColor( nColor );
+ else
+ aCol = Color( COL_BLACK );
+
+ if( USHRT_MAX != nFillColor )
+ aFCol = GetColor( nFillColor );
+ else
+ aFCol = Color( COL_WHITE );
+ }
+
+ Color aColor;
+ if( 0 == nFillValue || 100 == nFillValue )
+ aColor = aCol;
+ else
+ aColor = Color(
+ (BYTE)CalcShading( aCol.GetRed(), aFCol.GetRed(), nFillValue ),
+ (BYTE)CalcShading( aCol.GetGreen(), aFCol.GetGreen(), nFillValue ),
+ (BYTE)CalcShading( aCol.GetBlue(), aFCol.GetBlue(), nFillValue ) );
+
+ rSet.Put( SvxBrushItem( aColor, nWh ) );
+ SkipToken( -1 );
+}
+
+
+// pard / plain abarbeiten
+void SvxRTFParser::RTFPardPlain( int bPard, SfxItemSet** ppSet )
+{
+ if( !bNewGroup && aAttrStack.Top() ) // nicht am Anfang einer neuen Gruppe
+ {
+ SvxRTFItemStackType* pAkt = aAttrStack.Top();
+
+ int nLastToken = GetStackPtr(-1)->nTokenId;
+ int bNewStkEntry = TRUE;
+ if( RTF_PARD != nLastToken &&
+ RTF_PLAIN != nLastToken &&
+ BRACELEFT != nLastToken )
+ {
+ if( pAkt->aAttrSet.Count() || pAkt->pChildList || pAkt->nStyleNo )
+ {
+ // eine neue Gruppe aufmachen
+ SvxRTFItemStackType* pNew = new SvxRTFItemStackType( *pAkt, *pInsPos, TRUE );
+ pNew->SetRTFDefaults( GetRTFDefaults() );
+
+ // alle bis hierher gueltigen Attribute "setzen"
+ AttrGroupEnd();
+ pAkt = aAttrStack.Top(); // can be changed after AttrGroupEnd!
+ pNew->aAttrSet.SetParent( pAkt ? &pAkt->aAttrSet : 0 );
+ aAttrStack.Push( pNew );
+ pAkt = pNew;
+ }
+ else
+ {
+ // diesen Eintrag als neuen weiterbenutzen
+ pAkt->SetStartPos( *pInsPos );
+ bNewStkEntry = FALSE;
+ }
+ }
+
+ // jetzt noch alle auf default zuruecksetzen
+ if( bNewStkEntry &&
+ ( pAkt->aAttrSet.GetParent() || pAkt->aAttrSet.Count() ))
+ {
+ const SfxPoolItem *pItem, *pDef;
+ const USHORT* pPtr;
+ USHORT nCnt;
+ const SfxItemSet* pDfltSet = &GetRTFDefaults();
+ if( bPard )
+ {
+ pAkt->nStyleNo = 0;
+ pPtr = aPardMap.GetData();
+ nCnt = aPardMap.Count();
+ }
+ else
+ {
+ pPtr = aPlainMap.GetData();
+ nCnt = aPlainMap.Count();
+ }
+
+ for( USHORT n = 0; n < nCnt; ++n, ++pPtr )
+ {
+ // Item gesetzt und unterschiedlich -> das Pooldefault setzen
+ //JP 06.04.98: bei Items die nur SlotItems sind, darf nicht
+ // auf das Default zugefriffen werden. Diese
+ // werden gecleart
+ if( !*pPtr )
+ ;
+ else if( SFX_WHICH_MAX < *pPtr )
+ pAkt->aAttrSet.ClearItem( *pPtr );
+ else if( IsChkStyleAttr() )
+ pAkt->aAttrSet.Put( pDfltSet->Get( *pPtr ) );
+ else if( !pAkt->aAttrSet.GetParent() )
+ {
+ if( SFX_ITEM_SET ==
+ pDfltSet->GetItemState( *pPtr, FALSE, &pDef ))
+ pAkt->aAttrSet.Put( *pDef );
+ else
+ pAkt->aAttrSet.ClearItem( *pPtr );
+ }
+ else if( SFX_ITEM_SET == pAkt->aAttrSet.GetParent()->
+ GetItemState( *pPtr, TRUE, &pItem ) &&
+ *( pDef = &pDfltSet->Get( *pPtr )) != *pItem )
+ pAkt->aAttrSet.Put( *pDef );
+ else
+ {
+ if( SFX_ITEM_SET ==
+ pDfltSet->GetItemState( *pPtr, FALSE, &pDef ))
+ pAkt->aAttrSet.Put( *pDef );
+ else
+ pAkt->aAttrSet.ClearItem( *pPtr );
+ }
+ }
+ }
+ else if( bPard )
+ pAkt->nStyleNo = 0; // Style-Nummer zuruecksetzen
+
+ *ppSet = &pAkt->aAttrSet;
+
+ if (!bPard)
+ {
+ //Once we have a default font, then any text without a font specifier is
+ //in the default font, and thus has the default font charset, otherwise
+ //we can fall back to the ansicpg set codeset
+ if (nDfltFont != -1)
+ {
+ const Font& rSVFont = GetFont(USHORT(nDfltFont));
+ SetEncoding(rSVFont.GetCharSet());
+ }
+ else
+ SetEncoding(GetCodeSet());
+ }
+ }
+}
+
+void SvxRTFParser::SetDefault( int nToken, int nValue )
+{
+ if( !bNewDoc )
+ return;
+
+ SfxItemSet aTmp( *pAttrPool, aWhichMap.GetData() );
+ BOOL bOldFlag = bIsLeftToRightDef;
+ bIsLeftToRightDef = TRUE;
+ switch( nToken )
+ {
+ case RTF_ADEFF: bIsLeftToRightDef = FALSE; // no break!
+ case RTF_DEFF:
+ {
+ if( -1 == nValue )
+ nValue = 0;
+ const Font& rSVFont = GetFont( USHORT(nValue) );
+ SvxFontItem aTmpItem(
+ rSVFont.GetFamily(), rSVFont.GetName(),
+ rSVFont.GetStyleName(), rSVFont.GetPitch(),
+ rSVFont.GetCharSet(), SID_ATTR_CHAR_FONT );
+ SetScriptAttr( NOTDEF_CHARTYPE, aTmp, aTmpItem );
+ }
+ break;
+
+ case RTF_ADEFLANG: bIsLeftToRightDef = FALSE; // no break!
+ case RTF_DEFLANG:
+ // default Language merken
+ if( -1 != nValue )
+ {
+ SvxLanguageItem aTmpItem( (const LanguageType)nValue,
+ SID_ATTR_CHAR_LANGUAGE );
+ SetScriptAttr( NOTDEF_CHARTYPE, aTmp, aTmpItem );
+ }
+ break;
+
+ case RTF_DEFTAB:
+ if( PARDID->nTabStop )
+ {
+ // RTF definiert 720 twips als default
+ bIsSetDfltTab = TRUE;
+ if( -1 == nValue || !nValue )
+ nValue = 720;
+
+ // wer keine Twips haben moechte ...
+ if( IsCalcValue() )
+ {
+ nTokenValue = nValue;
+ CalcValue();
+ nValue = nTokenValue;
+ }
+#if 1
+ /*
+ cmc:
+ This stuff looks a little hairy indeed, this should be totally
+ unnecessary where default tabstops are understood. Just make one
+ tabstop and stick the value in there, the first one is all that
+ matters.
+
+ e.g.
+
+ SvxTabStopItem aNewTab(1, USHORT(nValue), SVX_TAB_ADJUST_DEFAULT,
+ PARDID->nTabStop);
+ ((SvxTabStop&)aNewTab[0]).GetAdjustment() = SVX_TAB_ADJUST_DEFAULT;
+
+
+ It must exist as a foul hack to support somebody that does not
+ have a true concept of default tabstops by making a tabsetting
+ result from the default tabstop, creating a lot of them all at
+ the default locations to give the effect of the first real
+ default tabstop being in use just in case the receiving
+ application doesn't do that for itself.
+ */
+#endif
+
+ // Verhaeltnis der def. TabWidth / Tabs errechnen und
+ // enstsprechend die neue Anzahl errechnen.
+/*-----------------14.12.94 19:32-------------------
+ ?? wie kommt man auf die 13 ??
+--------------------------------------------------*/
+ USHORT nAnzTabs = (SVX_TAB_DEFDIST * 13 ) / USHORT(nValue);
+ /*
+ cmc, make sure we have at least one, or all hell breaks loose in
+ everybodies exporters, #i8247#
+ */
+ if (nAnzTabs < 1)
+ nAnzTabs = 1;
+
+ // wir wollen Defaulttabs
+ SvxTabStopItem aNewTab( nAnzTabs, USHORT(nValue),
+ SVX_TAB_ADJUST_DEFAULT, PARDID->nTabStop );
+ while( nAnzTabs )
+ ((SvxTabStop&)aNewTab[ --nAnzTabs ]).GetAdjustment() = SVX_TAB_ADJUST_DEFAULT;
+
+ pAttrPool->SetPoolDefaultItem( aNewTab );
+ }
+ break;
+ }
+ bIsLeftToRightDef = bOldFlag;
+
+ if( aTmp.Count() )
+ {
+ SfxItemIter aIter( aTmp );
+ const SfxPoolItem* pItem = aIter.GetCurItem();
+ while( TRUE )
+ {
+ pAttrPool->SetPoolDefaultItem( *pItem );
+ if( aIter.IsAtEnd() )
+ break;
+ pItem = aIter.NextItem();
+ }
+ }
+}
+
+// default: keine Umrechnung, alles bei Twips lassen.
+void SvxRTFParser::CalcValue()
+{
+}
+
+ // fuer Tokens, die im ReadAttr nicht ausgewertet werden
+void SvxRTFParser::UnknownAttrToken( int, SfxItemSet* )
+{
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/editeng/source/rtf/segincr.asm b/editeng/source/rtf/segincr.asm
new file mode 100644
index 0000000000..d90d79dbd8
--- /dev/null
+++ b/editeng/source/rtf/segincr.asm
@@ -0,0 +1,43 @@
+;*************************************************************************
+;
+; DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+;
+; Copyright 2008 by Sun Microsystems, Inc.
+;
+; OpenOffice.org - a multi-platform office productivity suite
+;
+; $RCSfile: segincr.asm,v $
+;
+; $Revision: 1.6 $
+;
+; This file is part of OpenOffice.org.
+;
+; OpenOffice.org is free software: you can redistribute it and/or modify
+; it under the terms of the GNU Lesser General Public License version 3
+; only, as published by the Free Software Foundation.
+;
+; OpenOffice.org is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU Lesser General Public License version 3 for more details
+; (a copy is included in the LICENSE file that accompanied this code).
+;
+; You should have received a copy of the GNU Lesser General Public License
+; version 3 along with OpenOffice.org. If not, see
+; <http://www.openoffice.org/license.html>
+; for a copy of the LGPLv3 License.
+;
+;*************************************************************************
+
+EXTRN __AHINCR:abs
+ .MODEL LARGE
+STARTWS0_SEG SEGMENT WORD PUBLIC 'STARTWS_CODE'
+
+ PUBLIC _SegIncr
+_SegIncr PROC
+ MOV AX, __AHINCR
+ RET
+_SegIncr ENDP
+
+STARTWS0_SEG ENDS
+ END
diff --git a/editeng/source/rtf/svxrtf.cxx b/editeng/source/rtf/svxrtf.cxx
new file mode 100644
index 0000000000..30ed65fceb
--- /dev/null
+++ b/editeng/source/rtf/svxrtf.cxx
@@ -0,0 +1,1517 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: svxrtf.cxx,v $
+ * $Revision: 1.34.212.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
+
+
+#include <ctype.h>
+#include <tools/datetime.hxx>
+#include <rtl/tencinfo.h>
+#include <svl/itemiter.hxx>
+#include <svl/whiter.hxx>
+#include <svtools/rtftoken.h>
+#include <svl/itempool.hxx>
+
+#include <comphelper/string.hxx>
+
+#include <com/sun/star/lang/Locale.hpp>
+#include <editeng/scriptspaceitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/svxrtf.hxx>
+#include <editeng/editids.hrc>
+#include <vcl/svapp.hxx>
+
+#include <com/sun/star/document/XDocumentProperties.hpp>
+
+
+using namespace ::com::sun::star;
+
+
+SV_IMPL_PTRARR( SvxRTFColorTbl, ColorPtr )
+SV_IMPL_PTRARR( SvxRTFItemStackList, SvxRTFItemStackType* )
+
+CharSet lcl_GetDefaultTextEncodingForRTF()
+{
+
+ ::com::sun::star::lang::Locale aLocale;
+ ::rtl::OUString aLangString;
+
+ aLocale = Application::GetSettings().GetLocale();
+ aLangString = aLocale.Language;
+
+ if ( aLangString.equals( ::rtl::OUString::createFromAscii( "ru" ) )
+ || aLangString.equals( ::rtl::OUString::createFromAscii( "uk" ) ) )
+ return RTL_TEXTENCODING_MS_1251;
+ if ( aLangString.equals( ::rtl::OUString::createFromAscii( "tr" ) ) )
+ return RTL_TEXTENCODING_MS_1254;
+ else
+ return RTL_TEXTENCODING_MS_1252;
+}
+
+// -------------- Methoden --------------------
+
+SvxRTFParser::SvxRTFParser( SfxItemPool& rPool, SvStream& rIn,
+ uno::Reference<document::XDocumentProperties> i_xDocProps,
+ int bReadNewDoc )
+ : SvRTFParser( rIn, 5 ),
+ rStrm(rIn),
+ aColorTbl( 16, 4 ),
+ aFontTbl( 16, 4 ),
+ pInsPos( 0 ),
+ pAttrPool( &rPool ),
+ m_xDocProps( i_xDocProps ),
+ pRTFDefaults( 0 ),
+ nVersionNo( 0 )
+{
+ bNewDoc = bReadNewDoc;
+
+ bChkStyleAttr = bCalcValue = bReadDocInfo = bIsInReadStyleTab = FALSE;
+ bIsLeftToRightDef = TRUE;
+
+ {
+ RTFPlainAttrMapIds aTmp( rPool );
+ aPlainMap.Insert( (USHORT*)&aTmp,
+ sizeof( RTFPlainAttrMapIds ) / sizeof(USHORT), 0 );
+ }
+ {
+ RTFPardAttrMapIds aTmp( rPool );
+ aPardMap.Insert( (USHORT*)&aTmp,
+ sizeof( RTFPardAttrMapIds ) / sizeof(USHORT), 0 );
+ }
+ pDfltFont = new Font;
+ pDfltColor = new Color;
+}
+
+void SvxRTFParser::EnterEnvironment()
+{
+}
+
+void SvxRTFParser::LeaveEnvironment()
+{
+}
+
+void SvxRTFParser::ResetPard()
+{
+}
+
+SvxRTFParser::~SvxRTFParser()
+{
+ if( aColorTbl.Count() )
+ ClearColorTbl();
+ if( aFontTbl.Count() )
+ ClearFontTbl();
+ if( aStyleTbl.Count() )
+ ClearStyleTbl();
+ if( aAttrStack.Count() )
+ ClearAttrStack();
+
+ delete pRTFDefaults;
+
+ delete pInsPos;
+ delete pDfltFont;
+ delete pDfltColor;
+}
+
+void SvxRTFParser::SetInsPos( const SvxPosition& rNew )
+{
+ if( pInsPos )
+ delete pInsPos;
+ pInsPos = rNew.Clone();
+}
+
+SvParserState SvxRTFParser::CallParser()
+{
+ DBG_ASSERT( pInsPos, "keine Einfuegeposition" );
+
+ if( !pInsPos )
+ return SVPAR_ERROR;
+
+ if( aColorTbl.Count() )
+ ClearColorTbl();
+ if( aFontTbl.Count() )
+ ClearFontTbl();
+ if( aStyleTbl.Count() )
+ ClearStyleTbl();
+ if( aAttrStack.Count() )
+ ClearAttrStack();
+
+ bIsSetDfltTab = FALSE;
+ bNewGroup = FALSE;
+ nDfltFont = 0;
+
+ sBaseURL.Erase();
+
+ // erzeuge aus den gesetzten WhichIds die richtige WhichId-Tabelle.
+ BuildWhichTbl();
+
+ return SvRTFParser::CallParser();
+}
+
+void SvxRTFParser::Continue( int nToken )
+{
+ SvRTFParser::Continue( nToken );
+
+ if( SVPAR_PENDING != GetStatus() )
+ {
+ SetAllAttrOfStk();
+#if 0
+ //Regardless of what "color 0" is, word defaults to auto as the default colour.
+ //e.g. see #i7713#
+ if( bNewDoc && ((RTFPlainAttrMapIds*)aPlainMap.GetData())->nColor )
+ pAttrPool->SetPoolDefaultItem( SvxColorItem( GetColor( 0 ),
+ ((RTFPlainAttrMapIds*)aPlainMap.GetData())->nColor ));
+#endif
+ }
+}
+
+
+// wird fuer jedes Token gerufen, das in CallParser erkannt wird
+void SvxRTFParser::NextToken( int nToken )
+{
+ sal_Unicode cCh;
+ switch( nToken )
+ {
+ case RTF_COLORTBL: ReadColorTable(); break;
+ case RTF_FONTTBL: ReadFontTable(); break;
+ case RTF_STYLESHEET: ReadStyleTable(); break;
+
+ case RTF_DEFF:
+ if( bNewDoc )
+ {
+ if( aFontTbl.Count() )
+ // koennen wir sofort setzen
+ SetDefault( nToken, nTokenValue );
+ else
+ // wird nach einlesen der Fonttabelle gesetzt
+ nDfltFont = int(nTokenValue);
+ }
+ break;
+
+ case RTF_DEFTAB:
+ case RTF_DEFLANG:
+ if( bNewDoc )
+ SetDefault( nToken, nTokenValue );
+ break;
+
+
+ case RTF_PICT: ReadBitmapData(); break;
+
+ case RTF_LINE: cCh = '\n'; goto INSINGLECHAR;
+ case RTF_TAB: cCh = '\t'; goto INSINGLECHAR;
+ case RTF_SUBENTRYINDEX: cCh = ':'; goto INSINGLECHAR;
+
+ case RTF_EMDASH: cCh = 151; goto INSINGLECHAR;
+ case RTF_ENDASH: cCh = 150; goto INSINGLECHAR;
+ case RTF_BULLET: cCh = 149; goto INSINGLECHAR;
+ case RTF_LQUOTE: cCh = 145; goto INSINGLECHAR;
+ case RTF_RQUOTE: cCh = 146; goto INSINGLECHAR;
+ case RTF_LDBLQUOTE: cCh = 147; goto INSINGLECHAR;
+ case RTF_RDBLQUOTE: cCh = 148; goto INSINGLECHAR;
+INSINGLECHAR:
+ aToken = ByteString::ConvertToUnicode( (sal_Char)cCh,
+ RTL_TEXTENCODING_MS_1252 );
+
+ // kein Break, aToken wird als Text gesetzt
+ case RTF_TEXTTOKEN:
+ {
+ InsertText();
+ // alle angesammelten Attribute setzen
+ for( USHORT n = aAttrSetList.Count(); n; )
+ {
+ SvxRTFItemStackType* pStkSet = aAttrSetList[--n];
+ SetAttrSet( *pStkSet );
+ aAttrSetList.DeleteAndDestroy( n );
+ }
+ }
+ break;
+
+
+ case RTF_PAR:
+ InsertPara();
+ break;
+ case '{':
+ if (bNewGroup) // Verschachtelung !!
+ _GetAttrSet();
+ EnterEnvironment();
+ bNewGroup = true;
+ break;
+ case '}':
+ if( !bNewGroup ) // leere Gruppe ??
+ AttrGroupEnd();
+ LeaveEnvironment();
+ bNewGroup = false;
+ break;
+ case RTF_INFO:
+#ifndef SVX_LIGHT
+ if (bReadDocInfo && bNewDoc && m_xDocProps.is())
+ ReadInfo();
+ else
+#endif
+ SkipGroup();
+ break;
+
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ // erstmal gesamt ueberlesen (muessen alle in einer Gruppe stehen !!)
+ // Koennen auch ohne dem IGNORE-Flag im RTF-File auftreten; alle Gruppen
+ // mit IGNORE-Flag werden im default-Zweig ueberlesen.
+
+ case RTF_SWG_PRTDATA:
+ case RTF_FIELD:
+ case RTF_ATNID:
+ case RTF_ANNOTATION:
+
+ case RTF_BKMKSTART:
+ case RTF_BKMKEND:
+ case RTF_BKMK_KEY:
+ case RTF_XE:
+ case RTF_TC:
+ case RTF_NEXTFILE:
+ case RTF_TEMPLATE:
+#if 0
+ //disabled for #i19718#
+ case RTF_SHPRSLT: // RTF_SHP fehlt noch !!
+#endif
+ SkipGroup();
+ break;
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ case RTF_PGDSCNO:
+ case RTF_PGBRK:
+ case RTF_SHADOW:
+ if( RTF_IGNOREFLAG != GetStackPtr( -1 )->nTokenId )
+ break;
+ nToken = SkipToken( -1 );
+ if( '{' == GetStackPtr( -1 )->nTokenId )
+ nToken = SkipToken( -1 );
+
+ ReadAttr( nToken, &GetAttrSet() );
+ break;
+
+ default:
+ switch( nToken & ~(0xff | RTF_SWGDEFS) )
+ {
+ case RTF_PARFMT: // hier gibts keine Swg-Defines
+ ReadAttr( nToken, &GetAttrSet() );
+ break;
+
+ case RTF_CHRFMT:
+ case RTF_BRDRDEF:
+ case RTF_TABSTOPDEF:
+
+ if( RTF_SWGDEFS & nToken)
+ {
+ if( RTF_IGNOREFLAG != GetStackPtr( -1 )->nTokenId )
+ break;
+ nToken = SkipToken( -1 );
+ if( '{' == GetStackPtr( -1 )->nTokenId )
+ {
+ nToken = SkipToken( -1 );
+ }
+ }
+ ReadAttr( nToken, &GetAttrSet() );
+ break;
+ default:
+ {
+ if( /*( '{' == GetStackPtr( -1 )->nTokenId ) ||*/
+ ( RTF_IGNOREFLAG == GetStackPtr( -1 )->nTokenId &&
+ '{' == GetStackPtr( -2 )->nTokenId ) )
+ SkipGroup();
+ }
+ break;
+ }
+ break;
+ }
+}
+
+void SvxRTFParser::ReadStyleTable()
+{
+ int nToken, bSaveChkStyleAttr = bChkStyleAttr;
+ short nStyleNo = 0;
+ int _nOpenBrakets = 1; // die erste wurde schon vorher erkannt !!
+ SvxRTFStyleType* pStyle = new SvxRTFStyleType( *pAttrPool, aWhichMap.GetData() );
+ pStyle->aAttrSet.Put( GetRTFDefaults() );
+
+ bIsInReadStyleTab = TRUE;
+ bChkStyleAttr = FALSE; // Attribute nicht gegen die Styles checken
+
+ while( _nOpenBrakets && IsParserWorking() )
+ {
+ switch( nToken = GetNextToken() )
+ {
+ case '}': if( --_nOpenBrakets && IsParserWorking() )
+ // Style konnte vollstaendig gelesen werden,
+ // also ist das noch ein stabiler Status
+ SaveState( RTF_STYLESHEET );
+ break;
+ case '{':
+ {
+ if( RTF_IGNOREFLAG != GetNextToken() )
+ nToken = SkipToken( -1 );
+ else if( RTF_UNKNOWNCONTROL != ( nToken = GetNextToken() ) &&
+ RTF_PN != nToken )
+ nToken = SkipToken( -2 );
+ else
+ {
+ // gleich herausfiltern
+ ReadUnknownData();
+ nToken = GetNextToken();
+ if( '}' != nToken )
+ eState = SVPAR_ERROR;
+ break;
+ }
+ ++_nOpenBrakets;
+ }
+ break;
+
+ case RTF_SBASEDON: pStyle->nBasedOn = USHORT(nTokenValue); pStyle->bBasedOnIsSet=TRUE; break;
+ case RTF_SNEXT: pStyle->nNext = USHORT(nTokenValue); break;
+ case RTF_OUTLINELEVEL:
+ case RTF_SOUTLVL: pStyle->nOutlineNo = BYTE(nTokenValue); break;
+ case RTF_S: nStyleNo = (short)nTokenValue; break;
+ case RTF_CS: nStyleNo = (short)nTokenValue;
+ pStyle->bIsCharFmt = TRUE;
+ break;
+
+ case RTF_TEXTTOKEN:
+ {
+ pStyle->sName = DelCharAtEnd( aToken, ';' );
+
+/*
+??? soll man das umsetzen ???
+ if( !pStyle->sName.Len() )
+ pStyle->sName = "Standard";
+*/
+ // sollte die Nummer doppelt vergeben werden ?
+ if( aStyleTbl.Count() )
+ {
+ SvxRTFStyleType* pOldSt = aStyleTbl.Remove( nStyleNo );
+ if( pOldSt )
+ delete pOldSt;
+ }
+ // alle Daten vom Style vorhanden, also ab in die Tabelle
+ aStyleTbl.Insert( nStyleNo, pStyle );
+ pStyle = new SvxRTFStyleType( *pAttrPool, aWhichMap.GetData() );
+ pStyle->aAttrSet.Put( GetRTFDefaults() );
+ nStyleNo = 0;
+ }
+ break;
+ default:
+ switch( nToken & ~(0xff | RTF_SWGDEFS) )
+ {
+ case RTF_PARFMT: // hier gibts keine Swg-Defines
+ ReadAttr( nToken, &pStyle->aAttrSet );
+ break;
+
+ case RTF_CHRFMT:
+ case RTF_BRDRDEF:
+ case RTF_TABSTOPDEF:
+
+ if( RTF_SWGDEFS & nToken)
+ {
+ if( RTF_IGNOREFLAG != GetStackPtr( -1 )->nTokenId )
+ break;
+ nToken = SkipToken( -1 );
+ if( '{' == GetStackPtr( -1 )->nTokenId )
+ {
+ nToken = SkipToken( -1 );
+#if 0
+ --_nOpenBrakets; // korrigieren!!
+#endif
+ }
+ }
+ ReadAttr( nToken, &pStyle->aAttrSet );
+ break;
+ }
+ break;
+ }
+ }
+ delete pStyle; // loesche das letze Style
+ SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
+
+ // Flag wieder auf alten Zustand
+ bChkStyleAttr = bSaveChkStyleAttr;
+ bIsInReadStyleTab = FALSE;
+}
+
+void SvxRTFParser::ReadColorTable()
+{
+ int nToken;
+ BYTE nRed = 0xff, nGreen = 0xff, nBlue = 0xff;
+
+ while( '}' != ( nToken = GetNextToken() ) && IsParserWorking() )
+ {
+ switch( nToken )
+ {
+ case RTF_RED: nRed = BYTE(nTokenValue); break;
+ case RTF_GREEN: nGreen = BYTE(nTokenValue); break;
+ case RTF_BLUE: nBlue = BYTE(nTokenValue); break;
+
+ case RTF_TEXTTOKEN: // oder sollte irgendein Unsin darumstehen?
+ if( 1 == aToken.Len()
+ ? aToken.GetChar( 0 ) != ';'
+ : STRING_NOTFOUND == aToken.Search( ';' ) )
+ break; // es muss zumindestens das ';' gefunden werden
+
+ // else kein break !!
+
+ case ';':
+ if( IsParserWorking() )
+ {
+ // eine Farbe ist Fertig, in die Tabelle eintragen
+ // versuche die Werte auf SV interne Namen zu mappen
+ ColorPtr pColor = new Color( nRed, nGreen, nBlue );
+ if( !aColorTbl.Count() &&
+ BYTE(-1) == nRed && BYTE(-1) == nGreen && BYTE(-1) == nBlue )
+ pColor->SetColor( COL_AUTO );
+ aColorTbl.Insert( pColor, aColorTbl.Count() );
+ nRed = 0, nGreen = 0, nBlue = 0;
+
+ // Color konnte vollstaendig gelesen werden,
+ // also ist das noch ein stabiler Status
+ SaveState( RTF_COLORTBL );
+ }
+ break;
+ }
+ }
+ SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
+}
+
+void SvxRTFParser::ReadFontTable()
+{
+ int nToken;
+ int _nOpenBrakets = 1; // die erste wurde schon vorher erkannt !!
+ Font* pFont = new Font();
+ short nFontNo(0), nInsFontNo (0);
+ String sAltNm, sFntNm;
+ BOOL bIsAltFntNm = FALSE, bCheckNewFont;
+
+ CharSet nSystemChar = lcl_GetDefaultTextEncodingForRTF();
+ pFont->SetCharSet( nSystemChar );
+ SetEncoding( nSystemChar );
+
+ while( _nOpenBrakets && IsParserWorking() )
+ {
+ bCheckNewFont = FALSE;
+ switch( ( nToken = GetNextToken() ))
+ {
+ case '}':
+ bIsAltFntNm = FALSE;
+ // Style konnte vollstaendig gelesen werden,
+ // also ist das noch ein stabiler Status
+ if( --_nOpenBrakets <= 1 && IsParserWorking() )
+ SaveState( RTF_FONTTBL );
+ bCheckNewFont = TRUE;
+ nInsFontNo = nFontNo;
+ break;
+ case '{':
+ if( RTF_IGNOREFLAG != GetNextToken() )
+ nToken = SkipToken( -1 );
+ // Unknown und alle bekannten nicht ausgewerteten Gruppen
+ // sofort ueberspringen
+ else if( RTF_UNKNOWNCONTROL != ( nToken = GetNextToken() ) &&
+ RTF_PANOSE != nToken && RTF_FNAME != nToken &&
+ RTF_FONTEMB != nToken && RTF_FONTFILE != nToken )
+ nToken = SkipToken( -2 );
+ else
+ {
+ // gleich herausfiltern
+ ReadUnknownData();
+ nToken = GetNextToken();
+ if( '}' != nToken )
+ eState = SVPAR_ERROR;
+ break;
+ }
+ ++_nOpenBrakets;
+ break;
+ case RTF_FROMAN:
+ pFont->SetFamily( FAMILY_ROMAN );
+ break;
+ case RTF_FSWISS:
+ pFont->SetFamily( FAMILY_SWISS );
+ break;
+ case RTF_FMODERN:
+ pFont->SetFamily( FAMILY_MODERN );
+ break;
+ case RTF_FSCRIPT:
+ pFont->SetFamily( FAMILY_SCRIPT );
+ break;
+ case RTF_FDECOR:
+ pFont->SetFamily( FAMILY_DECORATIVE );
+ break;
+ // bei technischen/symbolischen Font wird der CharSet ungeschaltet!!
+ case RTF_FTECH:
+ pFont->SetCharSet( RTL_TEXTENCODING_SYMBOL );
+ // deliberate fall through
+ case RTF_FNIL:
+ pFont->SetFamily( FAMILY_DONTKNOW );
+ break;
+ case RTF_FCHARSET:
+ if (-1 != nTokenValue)
+ {
+ CharSet nCharSet = rtl_getTextEncodingFromWindowsCharset(
+ (BYTE)nTokenValue);
+ pFont->SetCharSet(nCharSet);
+ //When we're in a font, the fontname is in the font
+ //charset, except for symbol fonts I believe
+ if (nCharSet == RTL_TEXTENCODING_SYMBOL)
+ nCharSet = RTL_TEXTENCODING_DONTKNOW;
+ SetEncoding(nCharSet);
+ }
+ break;
+ case RTF_FPRQ:
+ switch( nTokenValue )
+ {
+ case 1:
+ pFont->SetPitch( PITCH_FIXED );
+ break;
+ case 2:
+ pFont->SetPitch( PITCH_VARIABLE );
+ break;
+ }
+ break;
+ case RTF_F:
+ bCheckNewFont = TRUE;
+ nInsFontNo = nFontNo;
+ nFontNo = (short)nTokenValue;
+ break;
+ case RTF_FALT:
+ bIsAltFntNm = TRUE;
+ break;
+ case RTF_TEXTTOKEN:
+ DelCharAtEnd( aToken, ';' );
+ if ( aToken.Len() )
+ {
+ if( bIsAltFntNm )
+ sAltNm = aToken;
+ else
+ sFntNm = aToken;
+ }
+ break;
+ }
+
+ if( bCheckNewFont && 1 >= _nOpenBrakets && sFntNm.Len() ) // one font is ready
+ {
+ // alle Daten vom Font vorhanden, also ab in die Tabelle
+ if (sAltNm.Len())
+ (sFntNm += ';' ) += sAltNm;
+
+ pFont->SetName( sFntNm );
+ aFontTbl.Insert( nInsFontNo, pFont );
+ pFont = new Font();
+ pFont->SetCharSet( nSystemChar );
+ sAltNm.Erase();
+ sFntNm.Erase();
+ }
+ }
+ // den letzen muessen wir selbst loeschen
+ delete pFont;
+ SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
+
+ // setze den default Font am Doc
+ if( bNewDoc && IsParserWorking() )
+ SetDefault( RTF_DEFF, nDfltFont );
+}
+
+void SvxRTFParser::ReadBitmapData()
+{
+ SvRTFParser::ReadBitmapData();
+}
+
+void SvxRTFParser::ReadOLEData()
+{
+ SvRTFParser::ReadOLEData();
+}
+
+String& SvxRTFParser::GetTextToEndGroup( String& rStr )
+{
+ rStr.Erase( 0 );
+ int _nOpenBrakets = 1, nToken; // die erste wurde schon vorher erkannt !!
+
+ while( _nOpenBrakets && IsParserWorking() )
+ {
+ switch( nToken = GetNextToken() )
+ {
+ case '}': --_nOpenBrakets; break;
+ case '{':
+ {
+ if( RTF_IGNOREFLAG != GetNextToken() )
+ nToken = SkipToken( -1 );
+ else if( RTF_UNKNOWNCONTROL != GetNextToken() )
+ nToken = SkipToken( -2 );
+ else
+ {
+ // gleich herausfiltern
+ ReadUnknownData();
+ nToken = GetNextToken();
+ if( '}' != nToken )
+ eState = SVPAR_ERROR;
+ break;
+ }
+ ++_nOpenBrakets;
+ }
+ break;
+
+ case RTF_TEXTTOKEN:
+ rStr += aToken;
+ break;
+ }
+ }
+ SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
+ return rStr;
+}
+
+util::DateTime SvxRTFParser::GetDateTimeStamp( )
+{
+ util::DateTime aDT;
+ BOOL bWeiter = TRUE;
+ int nToken;
+ while( bWeiter && IsParserWorking() )
+ {
+ switch( nToken = GetNextToken() )
+ {
+ case RTF_YR: aDT.Year = (USHORT)nTokenValue; break;
+ case RTF_MO: aDT.Month = (USHORT)nTokenValue; break;
+ case RTF_DY: aDT.Day = (USHORT)nTokenValue; break;
+ case RTF_HR: aDT.Hours = (USHORT)nTokenValue; break;
+ case RTF_MIN: aDT.Minutes = (USHORT)nTokenValue; break;
+ default:
+ bWeiter = FALSE;
+ }
+ }
+ SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
+ return aDT;
+}
+
+void SvxRTFParser::ReadInfo( const sal_Char* pChkForVerNo )
+{
+#ifndef SVX_LIGHT
+ int _nOpenBrakets = 1, nToken; // die erste wurde schon vorher erkannt !!
+ DBG_ASSERT(m_xDocProps.is(),
+ "SvxRTFParser::ReadInfo: no DocumentProperties");
+ String sStr, sComment;
+ long nVersNo = 0;
+
+ while( _nOpenBrakets && IsParserWorking() )
+ {
+ switch( nToken = GetNextToken() )
+ {
+ case '}': --_nOpenBrakets; break;
+ case '{':
+ {
+ if( RTF_IGNOREFLAG != GetNextToken() )
+ nToken = SkipToken( -1 );
+ else if( RTF_UNKNOWNCONTROL != GetNextToken() )
+ nToken = SkipToken( -2 );
+ else
+ {
+ // gleich herausfiltern
+ ReadUnknownData();
+ nToken = GetNextToken();
+ if( '}' != nToken )
+ eState = SVPAR_ERROR;
+ break;
+ }
+ ++_nOpenBrakets;
+ }
+ break;
+
+ case RTF_TITLE:
+ m_xDocProps->setTitle( GetTextToEndGroup( sStr ) );
+ break;
+ case RTF_SUBJECT:
+ m_xDocProps->setSubject( GetTextToEndGroup( sStr ) );
+ break;
+ case RTF_AUTHOR:
+ m_xDocProps->setAuthor( GetTextToEndGroup( sStr ) );
+ break;
+ case RTF_OPERATOR:
+ m_xDocProps->setModifiedBy( GetTextToEndGroup( sStr ) );
+ break;
+ case RTF_KEYWORDS:
+ {
+ ::rtl::OUString sTemp = GetTextToEndGroup( sStr );
+ m_xDocProps->setKeywords(
+ ::comphelper::string::convertCommaSeparated(sTemp) );
+ break;
+ }
+ case RTF_DOCCOMM:
+ m_xDocProps->setDescription( GetTextToEndGroup( sStr ) );
+ break;
+
+ case RTF_HLINKBASE:
+ sBaseURL = GetTextToEndGroup( sStr ) ;
+ break;
+
+ case RTF_CREATIM:
+ m_xDocProps->setCreationDate( GetDateTimeStamp() );
+ break;
+
+ case RTF_REVTIM:
+ m_xDocProps->setModificationDate( GetDateTimeStamp() );
+ break;
+
+ case RTF_PRINTIM:
+ m_xDocProps->setPrintDate( GetDateTimeStamp() );
+ break;
+
+ case RTF_COMMENT:
+ GetTextToEndGroup( sComment );
+ break;
+
+ case RTF_BUPTIM:
+ SkipGroup();
+ break;
+
+ case RTF_VERN:
+ nVersNo = nTokenValue;
+ break;
+
+ case RTF_EDMINS:
+ case RTF_ID:
+ case RTF_VERSION:
+ case RTF_NOFPAGES:
+ case RTF_NOFWORDS:
+ case RTF_NOFCHARS:
+ NextToken( nToken );
+ break;
+
+// default:
+ }
+ }
+
+ if( pChkForVerNo &&
+ COMPARE_EQUAL == sComment.CompareToAscii( pChkForVerNo ))
+ nVersionNo = nVersNo;
+
+ SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
+#endif
+}
+
+
+void SvxRTFParser::ClearColorTbl()
+{
+ aColorTbl.DeleteAndDestroy( 0, aColorTbl.Count() );
+}
+
+void SvxRTFParser::ClearFontTbl()
+{
+ for( ULONG nCnt = aFontTbl.Count(); nCnt; )
+ delete aFontTbl.GetObject( --nCnt );
+}
+
+void SvxRTFParser::ClearStyleTbl()
+{
+ for( ULONG nCnt = aStyleTbl.Count(); nCnt; )
+ delete aStyleTbl.GetObject( --nCnt );
+}
+
+void SvxRTFParser::ClearAttrStack()
+{
+ SvxRTFItemStackType* pTmp;
+ for( ULONG nCnt = aAttrStack.Count(); nCnt; --nCnt )
+ {
+ pTmp = aAttrStack.Pop();
+ delete pTmp;
+ }
+}
+
+String& SvxRTFParser::DelCharAtEnd( String& rStr, const sal_Unicode cDel )
+{
+ if( rStr.Len() && ' ' == rStr.GetChar( 0 ))
+ rStr.EraseLeadingChars();
+ if( rStr.Len() && ' ' == rStr.GetChar( rStr.Len()-1 ))
+ rStr.EraseTrailingChars();
+ if( rStr.Len() && cDel == rStr.GetChar( rStr.Len()-1 ))
+ rStr.Erase( rStr.Len()-1 );
+ return rStr;
+}
+
+
+const Font& SvxRTFParser::GetFont( USHORT nId )
+{
+ const Font* pFont = aFontTbl.Get( nId );
+ if( !pFont )
+ {
+ const SvxFontItem& rDfltFont = (const SvxFontItem&)
+ pAttrPool->GetDefaultItem(
+ ((RTFPlainAttrMapIds*)aPlainMap.GetData())->nFont );
+ pDfltFont->SetName( rDfltFont.GetStyleName() );
+ pDfltFont->SetFamily( rDfltFont.GetFamily() );
+ pFont = pDfltFont;
+ }
+ return *pFont;
+}
+
+SvxRTFItemStackType* SvxRTFParser::_GetAttrSet( int bCopyAttr )
+{
+ SvxRTFItemStackType* pAkt = aAttrStack.Top();
+ SvxRTFItemStackType* pNew;
+ if( pAkt )
+ pNew = new SvxRTFItemStackType( *pAkt, *pInsPos, bCopyAttr );
+ else
+ pNew = new SvxRTFItemStackType( *pAttrPool, aWhichMap.GetData(),
+ *pInsPos );
+ pNew->SetRTFDefaults( GetRTFDefaults() );
+
+ aAttrStack.Push( pNew );
+ bNewGroup = FALSE;
+ return pNew;
+}
+
+
+void SvxRTFParser::_ClearStyleAttr( SvxRTFItemStackType& rStkType )
+{
+ // check attributes to the attributes of the stylesheet or to
+ // the default attrs of the document
+ SfxItemSet &rSet = rStkType.GetAttrSet();
+ const SfxItemPool& rPool = *rSet.GetPool();
+ const SfxPoolItem* pItem;
+ SfxWhichIter aIter( rSet );
+
+ SvxRTFStyleType* pStyle;
+ if( !IsChkStyleAttr() ||
+ !rStkType.GetAttrSet().Count() ||
+ 0 == ( pStyle = aStyleTbl.Get( rStkType.nStyleNo ) ))
+ {
+ for( USHORT nWhich = aIter.GetCurWhich(); nWhich; nWhich = aIter.NextWhich() )
+ {
+ if( SFX_WHICH_MAX > nWhich &&
+ SFX_ITEM_SET == rSet.GetItemState( nWhich, FALSE, &pItem ) &&
+ rPool.GetDefaultItem( nWhich ) == *pItem )
+ rSet.ClearItem( nWhich ); // loeschen
+ }
+ }
+ else
+ {
+ // alle Attribute, die schon vom Style definiert sind, aus dem
+ // akt. AttrSet entfernen
+ SfxItemSet &rStyleSet = pStyle->aAttrSet;
+ const SfxPoolItem* pSItem;
+ for( USHORT nWhich = aIter.GetCurWhich(); nWhich; nWhich = aIter.NextWhich() )
+ {
+ if( SFX_ITEM_SET == rStyleSet.GetItemState( nWhich, TRUE, &pSItem ))
+ {
+ // JP 22.06.99: im Style und im Set gleich gesetzt -> loeschen
+ if( SFX_ITEM_SET == rSet.GetItemState( nWhich, FALSE, &pItem )
+ && *pItem == *pSItem )
+ rSet.ClearItem( nWhich ); // loeschen
+ }
+ // Bug 59571 - falls nicht im Style gesetzt und gleich mit
+ // dem PoolDefault -> auch dann loeschen
+ else if( SFX_WHICH_MAX > nWhich &&
+ SFX_ITEM_SET == rSet.GetItemState( nWhich, FALSE, &pItem ) &&
+ rPool.GetDefaultItem( nWhich ) == *pItem )
+ rSet.ClearItem( nWhich ); // loeschen
+ }
+ }
+}
+
+void SvxRTFParser::AttrGroupEnd() // den akt. Bearbeiten, vom Stack loeschen
+{
+ if( aAttrStack.Count() )
+ {
+ SvxRTFItemStackType *pOld = aAttrStack.Pop();
+ SvxRTFItemStackType *pAkt = aAttrStack.Top();
+
+ do { // middle check loop
+ ULONG nOldSttNdIdx = pOld->pSttNd->GetIdx();
+ if( !pOld->pChildList &&
+ ((!pOld->aAttrSet.Count() && !pOld->nStyleNo ) ||
+ (nOldSttNdIdx == pInsPos->GetNodeIdx() &&
+ pOld->nSttCnt == pInsPos->GetCntIdx() )))
+ break; // keine Attribute oder Bereich
+
+ // setze nur die Attribute, die unterschiedlich zum Parent sind
+ if( pAkt && pOld->aAttrSet.Count() )
+ {
+ SfxItemIter aIter( pOld->aAttrSet );
+ const SfxPoolItem* pItem = aIter.GetCurItem(), *pGet;
+ while( TRUE )
+ {
+ if( SFX_ITEM_SET == pAkt->aAttrSet.GetItemState(
+ pItem->Which(), FALSE, &pGet ) &&
+ *pItem == *pGet )
+ pOld->aAttrSet.ClearItem( pItem->Which() );
+
+ if( aIter.IsAtEnd() )
+ break;
+ pItem = aIter.NextItem();
+ }
+
+ if( !pOld->aAttrSet.Count() && !pOld->pChildList &&
+ !pOld->nStyleNo )
+ break;
+ }
+
+ // setze alle Attribute, die von Start bis hier
+ // definiert sind.
+ int bCrsrBack = !pInsPos->GetCntIdx();
+ if( bCrsrBack )
+ {
+ // am Absatzanfang ? eine Position zurueck
+ ULONG nNd = pInsPos->GetNodeIdx();
+ MovePos( FALSE );
+ // if can not move backward then later dont move forward !
+ bCrsrBack = nNd != pInsPos->GetNodeIdx();
+ }
+
+ //Bug #46608#: ungueltige Bereiche ignorieren!
+ if( ( pOld->pSttNd->GetIdx() < pInsPos->GetNodeIdx() ||
+ ( pOld->pSttNd->GetIdx() == pInsPos->GetNodeIdx() &&
+ pOld->nSttCnt <= pInsPos->GetCntIdx() ))
+#if 0
+//BUG 68555 - dont test for empty paragraph or any range
+ && ( nOldSttNdIdx != pInsPos->GetNodeIdx() ||
+ pOld->nSttCnt != pInsPos->GetCntIdx() ||
+ !pOld->nSttCnt )
+#endif
+ )
+ {
+ if( !bCrsrBack )
+ {
+ // alle pard-Attribute gelten nur bis zum vorherigen
+ // Absatz !!
+ if( nOldSttNdIdx == pInsPos->GetNodeIdx() )
+ {
+#if 0
+//BUG 68555 - dont reset pard attrs, if the group not begins not at start of
+// paragraph
+ // Bereich innerhalb eines Absatzes:
+ // alle Absatz-Attribute und StyleNo loeschen
+ // aber nur wenn mitten drin angefangen wurde
+ if( pOld->nSttCnt )
+ {
+ pOld->nStyleNo = 0;
+ for( USHORT n = 0; n < aPardMap.Count() &&
+ pOld->aAttrSet.Count(); ++n )
+ if( aPardMap[n] )
+ pOld->aAttrSet.ClearItem( aPardMap[n] );
+
+ if( !pOld->aAttrSet.Count() && !pOld->pChildList &&
+ !pOld->nStyleNo )
+ break; // auch dieser verlaesst uns jetzt
+ }
+#endif
+ }
+ else
+ {
+ // jetzt wirds kompliziert:
+ // - alle Zeichen-Attribute behalten den Bereich,
+ // - alle Absatz-Attribute bekommen den Bereich
+ // bis zum vorherigen Absatz
+ SvxRTFItemStackType* pNew = new SvxRTFItemStackType(
+ *pOld, *pInsPos, TRUE );
+ pNew->aAttrSet.SetParent( pOld->aAttrSet.GetParent() );
+
+ // loesche aus pNew alle Absatz Attribute
+ for( USHORT n = 0; n < aPardMap.Count() &&
+ pNew->aAttrSet.Count(); ++n )
+ if( aPardMap[n] )
+ pNew->aAttrSet.ClearItem( aPardMap[n] );
+ pNew->SetRTFDefaults( GetRTFDefaults() );
+
+ // gab es ueberhaupt welche ?
+ if( pNew->aAttrSet.Count() == pOld->aAttrSet.Count() )
+ delete pNew; // das wars dann
+ else
+ {
+ pNew->nStyleNo = 0;
+
+ // spanne jetzt den richtigen Bereich auf
+ // pNew von alter
+ SetEndPrevPara( pOld->pEndNd, pOld->nEndCnt );
+ pNew->nSttCnt = 0;
+
+ if( IsChkStyleAttr() )
+ {
+ _ClearStyleAttr( *pOld );
+ _ClearStyleAttr( *pNew ); //#i10381#, methinks.
+ }
+
+ if( pAkt )
+ {
+ pAkt->Add( pOld );
+ pAkt->Add( pNew );
+ }
+ else
+ {
+ // letzter vom Stack, also zwischenspeichern, bis der
+ // naechste Text eingelesen wurde. (keine Attribute
+ // aufspannen!!)
+ aAttrSetList.Insert( pOld, aAttrSetList.Count() );
+ aAttrSetList.Insert( pNew, aAttrSetList.Count() );
+ }
+ pOld = 0; // pOld nicht loeschen
+ break; // das wars !!
+ }
+ }
+ }
+
+ pOld->pEndNd = pInsPos->MakeNodeIdx();
+ pOld->nEndCnt = pInsPos->GetCntIdx();
+
+#if 0
+ if( IsChkStyleAttr() )
+ _ClearStyleAttr( *pOld );
+#else
+ /*
+ #i21422#
+ If the parent (pAkt) sets something e.g. , and the child (pOld)
+ unsets it and the style both are based on has it unset then
+ clearing the pOld by looking at the style is clearly a disaster
+ as the text ends up with pAkts bold and not pOlds no bold, this
+ should be rethought out. For the moment its safest to just do
+ the clean if we have no parent, all we suffer is too many
+ redundant properties.
+ */
+ if (IsChkStyleAttr() && !pAkt)
+ _ClearStyleAttr( *pOld );
+#endif
+
+ if( pAkt )
+ {
+ pAkt->Add( pOld );
+ // split up and create new entry, because it make no sense
+ // to create a "so long" depend list. Bug 95010
+ if( bCrsrBack && 50 < pAkt->pChildList->Count() )
+ {
+ // am Absatzanfang ? eine Position zurueck
+ MovePos( TRUE );
+ bCrsrBack = FALSE;
+
+ // eine neue Gruppe aufmachen
+ SvxRTFItemStackType* pNew = new SvxRTFItemStackType(
+ *pAkt, *pInsPos, TRUE );
+ pNew->SetRTFDefaults( GetRTFDefaults() );
+
+ // alle bis hierher gueltigen Attribute "setzen"
+ AttrGroupEnd();
+ pAkt = aAttrStack.Top(); // can be changed after AttrGroupEnd!
+ pNew->aAttrSet.SetParent( pAkt ? &pAkt->aAttrSet : 0 );
+ aAttrStack.Push( pNew );
+ pAkt = pNew;
+ }
+ }
+ else
+ // letzter vom Stack, also zwischenspeichern, bis der
+ // naechste Text eingelesen wurde. (keine Attribute
+ // aufspannen!!)
+ aAttrSetList.Insert( pOld, aAttrSetList.Count() );
+
+ pOld = 0;
+ }
+
+ if( bCrsrBack )
+ // am Absatzanfang ? eine Position zurueck
+ MovePos( TRUE );
+
+ } while( FALSE );
+
+ if( pOld )
+ delete pOld;
+
+ bNewGroup = FALSE;
+ }
+}
+
+void SvxRTFParser::SetAllAttrOfStk() // end all Attr. and set it into doc
+{
+ // noch alle Attrbute vom Stack holen !!
+ while( aAttrStack.Count() )
+ AttrGroupEnd();
+
+ for( USHORT n = aAttrSetList.Count(); n; )
+ {
+ SvxRTFItemStackType* pStkSet = aAttrSetList[--n];
+ SetAttrSet( *pStkSet );
+ aAttrSetList.DeleteAndDestroy( n );
+ }
+}
+
+// setzt alle Attribute, die unterschiedlich zum aktuellen sind
+void SvxRTFParser::SetAttrSet( SvxRTFItemStackType &rSet )
+{
+ // wurde DefTab nie eingelesen? dann setze auf default
+ if( !bIsSetDfltTab )
+ SetDefault( RTF_DEFTAB, 720 );
+
+ if( rSet.pChildList )
+ rSet.Compress( *this );
+ if( rSet.aAttrSet.Count() || rSet.nStyleNo )
+ SetAttrInDoc( rSet );
+
+ // dann mal alle Childs abarbeiten
+ if( rSet.pChildList )
+ for( USHORT n = 0; n < rSet.pChildList->Count(); ++n )
+ SetAttrSet( *(*rSet.pChildList)[ n ] );
+}
+
+ // wurde noch kein Text eingefuegt ? (SttPos vom obersten StackEintrag!)
+int SvxRTFParser::IsAttrSttPos()
+{
+ SvxRTFItemStackType* pAkt = aAttrStack.Top();
+ return !pAkt || (pAkt->pSttNd->GetIdx() == pInsPos->GetNodeIdx() &&
+ pAkt->nSttCnt == pInsPos->GetCntIdx());
+}
+
+
+void SvxRTFParser::SetAttrInDoc( SvxRTFItemStackType & )
+{
+}
+
+#ifdef USED
+void SvxRTFParser::SaveState( int nToken )
+{
+ SvRTFParser::SaveState( nToken );
+}
+
+void SvxRTFParser::RestoreState()
+{
+ SvRTFParser::RestoreState();
+}
+#endif
+
+void SvxRTFParser::BuildWhichTbl()
+{
+ if( aWhichMap.Count() )
+ aWhichMap.Remove( 0, aWhichMap.Count() );
+ aWhichMap.Insert( (USHORT)0, (USHORT)0 );
+
+ // Aufbau einer Which-Map 'rWhichMap' aus einem Array von
+ // 'pWhichIds' von Which-Ids. Es hat die Lange 'nWhichIds'.
+ // Die Which-Map wird nicht geloescht.
+ SvParser::BuildWhichTbl( aWhichMap, (USHORT*)aPardMap.GetData(), aPardMap.Count() );
+ SvParser::BuildWhichTbl( aWhichMap, (USHORT*)aPlainMap.GetData(), aPlainMap.Count() );
+}
+
+const SfxItemSet& SvxRTFParser::GetRTFDefaults()
+{
+ if( !pRTFDefaults )
+ {
+ pRTFDefaults = new SfxItemSet( *pAttrPool, aWhichMap.GetData() );
+ USHORT nId;
+ if( 0 != ( nId = ((RTFPardAttrMapIds*)aPardMap.GetData())->nScriptSpace ))
+ {
+ SvxScriptSpaceItem aItem( FALSE, nId );
+ if( bNewDoc )
+ pAttrPool->SetPoolDefaultItem( aItem );
+ else
+ pRTFDefaults->Put( aItem );
+ }
+ }
+ return *pRTFDefaults;
+}
+
+/* */
+
+SvxRTFStyleType::SvxRTFStyleType( SfxItemPool& rPool, const USHORT* pWhichRange )
+ : aAttrSet( rPool, pWhichRange )
+{
+ nOutlineNo = BYTE(-1); // nicht gesetzt
+ nBasedOn = 0;
+ bBasedOnIsSet = FALSE; //$flr #117411#
+ nNext = 0;
+ bIsCharFmt = FALSE;
+}
+
+
+SvxRTFItemStackType::SvxRTFItemStackType(
+ SfxItemPool& rPool, const USHORT* pWhichRange,
+ const SvxPosition& rPos )
+ : aAttrSet( rPool, pWhichRange ),
+ pChildList( 0 ),
+ nStyleNo( 0 )
+{
+ pSttNd = rPos.MakeNodeIdx();
+ nSttCnt = rPos.GetCntIdx();
+ pEndNd = pSttNd;
+ nEndCnt = nSttCnt;
+}
+
+SvxRTFItemStackType::SvxRTFItemStackType(
+ const SvxRTFItemStackType& rCpy,
+ const SvxPosition& rPos,
+ int bCopyAttr )
+ : aAttrSet( *rCpy.aAttrSet.GetPool(), rCpy.aAttrSet.GetRanges() ),
+ pChildList( 0 ),
+ nStyleNo( rCpy.nStyleNo )
+{
+ pSttNd = rPos.MakeNodeIdx();
+ nSttCnt = rPos.GetCntIdx();
+ pEndNd = pSttNd;
+ nEndCnt = nSttCnt;
+
+ aAttrSet.SetParent( &rCpy.aAttrSet );
+ if( bCopyAttr )
+ aAttrSet.Put( rCpy.aAttrSet );
+}
+
+SvxRTFItemStackType::~SvxRTFItemStackType()
+{
+ if( pChildList )
+ delete pChildList;
+ if( pSttNd != pEndNd )
+ delete pEndNd;
+ delete pSttNd;
+}
+
+void SvxRTFItemStackType::Add( SvxRTFItemStackType* pIns )
+{
+ if( !pChildList )
+ pChildList = new SvxRTFItemStackList( 4, 16 );
+ pChildList->Insert( pIns, pChildList->Count() );
+}
+
+#if 0
+//cmc: This is the original. nEndCnt is redundantly assigned to itself, and
+//pEndNd can leak if not equal to pSttNd.
+void SvxRTFItemStackType::SetStartPos( const SvxPosition& rPos )
+{
+ delete pSttNd;
+ pSttNd = rPos.MakeNodeIdx();
+ nSttCnt = rPos.GetCntIdx();
+ pEndNd = pSttNd;
+ nEndCnt = nEndCnt;
+}
+#else
+void SvxRTFItemStackType::SetStartPos( const SvxPosition& rPos )
+{
+ if (pSttNd != pEndNd)
+ delete pEndNd;
+ delete pSttNd;
+ pSttNd = rPos.MakeNodeIdx();
+ pEndNd = pSttNd;
+ nSttCnt = rPos.GetCntIdx();
+}
+#endif
+
+void SvxRTFItemStackType::MoveFullNode(const SvxNodeIdx &rOldNode,
+ const SvxNodeIdx &rNewNode)
+{
+ bool bSameEndAsStart = (pSttNd == pEndNd) ? true : false;
+
+ if (GetSttNodeIdx() == rOldNode.GetIdx())
+ {
+ delete pSttNd;
+ pSttNd = rNewNode.Clone();
+ if (bSameEndAsStart)
+ pEndNd = pSttNd;
+ }
+
+ if (!bSameEndAsStart && GetEndNodeIdx() == rOldNode.GetIdx())
+ {
+ delete pEndNd;
+ pEndNd = rNewNode.Clone();
+ }
+
+ //And the same for all the children
+ USHORT nCount = pChildList ? pChildList->Count() : 0;
+ for (USHORT i = 0; i < nCount; ++i)
+ {
+ SvxRTFItemStackType* pStk = (*pChildList)[i];
+ pStk->MoveFullNode(rOldNode, rNewNode);
+ }
+}
+
+bool SvxRTFParser::UncompressableStackEntry(const SvxRTFItemStackType &) const
+{
+ return false;
+}
+
+void SvxRTFItemStackType::Compress( const SvxRTFParser& rParser )
+{
+ DBG_ASSERT( pChildList, "es gibt keine ChildListe" );
+
+ USHORT n;
+ SvxRTFItemStackType* pTmp = (*pChildList)[0];
+
+ if( !pTmp->aAttrSet.Count() ||
+ pSttNd->GetIdx() != pTmp->pSttNd->GetIdx() ||
+ nSttCnt != pTmp->nSttCnt )
+ return;
+
+ SvxNodeIdx* pLastNd = pTmp->pEndNd;
+ xub_StrLen nLastCnt = pTmp->nEndCnt;
+
+ SfxItemSet aMrgSet( pTmp->aAttrSet );
+ for( n = 1; n < pChildList->Count(); ++n )
+ {
+ pTmp = (*pChildList)[n];
+ if( pTmp->pChildList )
+ pTmp->Compress( rParser );
+
+ if( !pTmp->nSttCnt
+ ? (pLastNd->GetIdx()+1 != pTmp->pSttNd->GetIdx() ||
+ !rParser.IsEndPara( pLastNd, nLastCnt ) )
+ : ( pTmp->nSttCnt != nLastCnt ||
+ pLastNd->GetIdx() != pTmp->pSttNd->GetIdx() ))
+ {
+ while( ++n < pChildList->Count() )
+ if( (pTmp = (*pChildList)[n])->pChildList )
+ pTmp->Compress( rParser );
+ return;
+ }
+
+ if (rParser.UncompressableStackEntry(*pTmp))
+ return;
+
+ if( n )
+ {
+ // suche alle, die ueber den gesamten Bereich gesetzt sind
+ SfxItemIter aIter( aMrgSet );
+ const SfxPoolItem* pItem;
+ do {
+ USHORT nWhich = aIter.GetCurItem()->Which();
+ if( SFX_ITEM_SET != pTmp->aAttrSet.GetItemState( nWhich,
+ FALSE, &pItem ) || *pItem != *aIter.GetCurItem() )
+ aMrgSet.ClearItem( nWhich );
+
+ if( aIter.IsAtEnd() )
+ break;
+ aIter.NextItem();
+ } while( TRUE );
+
+ if( !aMrgSet.Count() )
+ return;
+ }
+
+ pLastNd = pTmp->pEndNd;
+ nLastCnt = pTmp->nEndCnt;
+ }
+
+ if( pEndNd->GetIdx() != pLastNd->GetIdx() || nEndCnt != nLastCnt )
+ return;
+
+ // es kann zusammengefasst werden
+ aAttrSet.Put( aMrgSet );
+
+ for( n = 0; n < pChildList->Count(); ++n )
+ {
+ pTmp = (*pChildList)[n];
+ pTmp->aAttrSet.Differentiate( aMrgSet );
+
+ if( !pTmp->pChildList && !pTmp->aAttrSet.Count() && !pTmp->nStyleNo )
+ {
+ pChildList->Remove( n );
+ delete pTmp;
+ --n;
+ continue;
+ }
+ }
+ if( !pChildList->Count() )
+ {
+ delete pChildList;
+ pChildList = 0;
+ }
+}
+void SvxRTFItemStackType::SetRTFDefaults( const SfxItemSet& rDefaults )
+{
+ if( rDefaults.Count() )
+ {
+ SfxItemIter aIter( rDefaults );
+ do {
+ USHORT nWhich = aIter.GetCurItem()->Which();
+ if( SFX_ITEM_SET != aAttrSet.GetItemState( nWhich, FALSE ))
+ aAttrSet.Put( *aIter.GetCurItem() );
+
+ if( aIter.IsAtEnd() )
+ break;
+ aIter.NextItem();
+ } while( TRUE );
+ }
+}
+
+/* */
+
+RTFPlainAttrMapIds::RTFPlainAttrMapIds( const SfxItemPool& rPool )
+{
+ nCaseMap = rPool.GetTrueWhich( SID_ATTR_CHAR_CASEMAP, FALSE );
+ nBgColor = rPool.GetTrueWhich( SID_ATTR_BRUSH_CHAR, FALSE );
+ nColor = rPool.GetTrueWhich( SID_ATTR_CHAR_COLOR, FALSE );
+ nContour = rPool.GetTrueWhich( SID_ATTR_CHAR_CONTOUR, FALSE );
+ nCrossedOut = rPool.GetTrueWhich( SID_ATTR_CHAR_STRIKEOUT, FALSE );
+ nEscapement = rPool.GetTrueWhich( SID_ATTR_CHAR_ESCAPEMENT, FALSE );
+ nFont = rPool.GetTrueWhich( SID_ATTR_CHAR_FONT, FALSE );
+ nFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_FONTHEIGHT, FALSE );
+ nKering = rPool.GetTrueWhich( SID_ATTR_CHAR_KERNING, FALSE );
+ nLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_LANGUAGE, FALSE );
+ nPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_POSTURE, FALSE );
+ nShadowed = rPool.GetTrueWhich( SID_ATTR_CHAR_SHADOWED, FALSE );
+ nUnderline = rPool.GetTrueWhich( SID_ATTR_CHAR_UNDERLINE, FALSE );
+ nOverline = rPool.GetTrueWhich( SID_ATTR_CHAR_OVERLINE, FALSE );
+ nWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_WEIGHT, FALSE );
+ nWordlineMode = rPool.GetTrueWhich( SID_ATTR_CHAR_WORDLINEMODE, FALSE );
+ nAutoKerning = rPool.GetTrueWhich( SID_ATTR_CHAR_AUTOKERN, FALSE );
+
+ nCJKFont = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONT, FALSE );
+ nCJKFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT, FALSE );
+ nCJKLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_LANGUAGE, FALSE );
+ nCJKPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_POSTURE, FALSE );
+ nCJKWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_WEIGHT, FALSE );
+ nCTLFont = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONT, FALSE );
+ nCTLFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT, FALSE );
+ nCTLLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_LANGUAGE, FALSE );
+ nCTLPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_POSTURE, FALSE );
+ nCTLWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_WEIGHT, FALSE );
+ nEmphasis = rPool.GetTrueWhich( SID_ATTR_CHAR_EMPHASISMARK, FALSE );
+ nTwoLines = rPool.GetTrueWhich( SID_ATTR_CHAR_TWO_LINES, FALSE );
+ nRuby = 0; //rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_RUBY, FALSE );
+ nCharScaleX = rPool.GetTrueWhich( SID_ATTR_CHAR_SCALEWIDTH, FALSE );
+ nHorzVert = rPool.GetTrueWhich( SID_ATTR_CHAR_ROTATED, FALSE );
+ nRelief = rPool.GetTrueWhich( SID_ATTR_CHAR_RELIEF, FALSE );
+ nHidden = rPool.GetTrueWhich( SID_ATTR_CHAR_HIDDEN, FALSE );
+}
+
+RTFPardAttrMapIds ::RTFPardAttrMapIds ( const SfxItemPool& rPool )
+{
+ nLinespacing = rPool.GetTrueWhich( SID_ATTR_PARA_LINESPACE, FALSE );
+ nAdjust = rPool.GetTrueWhich( SID_ATTR_PARA_ADJUST, FALSE );
+ nTabStop = rPool.GetTrueWhich( SID_ATTR_TABSTOP, FALSE );
+ nHyphenzone = rPool.GetTrueWhich( SID_ATTR_PARA_HYPHENZONE, FALSE );
+ nLRSpace = rPool.GetTrueWhich( SID_ATTR_LRSPACE, FALSE );
+ nULSpace = rPool.GetTrueWhich( SID_ATTR_ULSPACE, FALSE );
+ nBrush = rPool.GetTrueWhich( SID_ATTR_BRUSH, FALSE );
+ nBox = rPool.GetTrueWhich( SID_ATTR_BORDER_OUTER, FALSE );
+ nShadow = rPool.GetTrueWhich( SID_ATTR_BORDER_SHADOW, FALSE );
+ nOutlineLvl = rPool.GetTrueWhich( SID_ATTR_PARA_OUTLLEVEL, FALSE );
+ nSplit = rPool.GetTrueWhich( SID_ATTR_PARA_SPLIT, FALSE );
+ nKeep = rPool.GetTrueWhich( SID_ATTR_PARA_KEEP, FALSE );
+ nFontAlign = rPool.GetTrueWhich( SID_PARA_VERTALIGN, FALSE );
+ nScriptSpace = rPool.GetTrueWhich( SID_ATTR_PARA_SCRIPTSPACE, FALSE );
+ nHangPunct = rPool.GetTrueWhich( SID_ATTR_PARA_HANGPUNCTUATION, FALSE );
+ nForbRule = rPool.GetTrueWhich( SID_ATTR_PARA_FORBIDDEN_RULES, FALSE );
+ nDirection = rPool.GetTrueWhich( SID_ATTR_FRAMEDIRECTION, FALSE );
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/editeng/source/uno/UnoForbiddenCharsTable.cxx b/editeng/source/uno/UnoForbiddenCharsTable.cxx
new file mode 100644
index 0000000000..c83120428d
--- /dev/null
+++ b/editeng/source/uno/UnoForbiddenCharsTable.cxx
@@ -0,0 +1,148 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: UnoForbiddenCharsTable.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <editeng/UnoForbiddenCharsTable.hxx>
+#include <editeng/forbiddencharacterstable.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <editeng/unolingu.hxx> // LocalToLanguage, LanguageToLocale
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::i18n;
+using namespace ::rtl;
+using namespace ::vos;
+using namespace ::cppu;
+
+SvxUnoForbiddenCharsTable::SvxUnoForbiddenCharsTable(ORef<SvxForbiddenCharactersTable> xForbiddenChars) :
+ mxForbiddenChars( xForbiddenChars )
+{
+}
+
+SvxUnoForbiddenCharsTable::~SvxUnoForbiddenCharsTable()
+{
+}
+
+void SvxUnoForbiddenCharsTable::onChange()
+{
+}
+
+ForbiddenCharacters SvxUnoForbiddenCharsTable::getForbiddenCharacters( const Locale& rLocale )
+ throw(NoSuchElementException, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if(!mxForbiddenChars.isValid())
+ throw RuntimeException();
+
+ const LanguageType eLang = SvxLocaleToLanguage( rLocale );
+ const ForbiddenCharacters* pForbidden = mxForbiddenChars->GetForbiddenCharacters( eLang, FALSE );
+ if(!pForbidden)
+ throw NoSuchElementException();
+
+ return *pForbidden;
+}
+
+sal_Bool SvxUnoForbiddenCharsTable::hasForbiddenCharacters( const Locale& rLocale )
+ throw(RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if(!mxForbiddenChars.isValid())
+ return sal_False;
+
+ const LanguageType eLang = SvxLocaleToLanguage( rLocale );
+ const ForbiddenCharacters* pForbidden = mxForbiddenChars->GetForbiddenCharacters( eLang, FALSE );
+
+ return NULL != pForbidden;
+}
+
+void SvxUnoForbiddenCharsTable::setForbiddenCharacters(const Locale& rLocale, const ForbiddenCharacters& rForbiddenCharacters )
+ throw(RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if(!mxForbiddenChars.isValid())
+ throw RuntimeException();
+
+ const LanguageType eLang = SvxLocaleToLanguage( rLocale );
+ mxForbiddenChars->SetForbiddenCharacters( eLang, rForbiddenCharacters );
+
+ onChange();
+}
+
+void SvxUnoForbiddenCharsTable::removeForbiddenCharacters( const Locale& rLocale )
+ throw(RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if(!mxForbiddenChars.isValid())
+ throw RuntimeException();
+
+ const LanguageType eLang = SvxLocaleToLanguage( rLocale );
+ mxForbiddenChars->ClearForbiddenCharacters( eLang );
+
+ onChange();
+}
+
+// XSupportedLocales
+Sequence< Locale > SAL_CALL SvxUnoForbiddenCharsTable::getLocales()
+ throw(RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ const sal_Int32 nCount = mxForbiddenChars.isValid() ? mxForbiddenChars->Count() : 0;
+
+ Sequence< Locale > aLocales( nCount );
+ if( nCount )
+ {
+ Locale* pLocales = aLocales.getArray();
+
+ for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ const ULONG nLanguage = mxForbiddenChars->GetObjectKey( nIndex );
+ SvxLanguageToLocale ( *pLocales++, static_cast < LanguageType > (nLanguage) );
+ }
+ }
+
+ return aLocales;
+}
+
+sal_Bool SAL_CALL SvxUnoForbiddenCharsTable::hasLocale( const Locale& aLocale )
+ throw(RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ return hasForbiddenCharacters( aLocale );
+}
diff --git a/editeng/source/uno/makefile.mk b/editeng/source/uno/makefile.mk
new file mode 100644
index 0000000000..c044e1e38d
--- /dev/null
+++ b/editeng/source/uno/makefile.mk
@@ -0,0 +1,65 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.11 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=svx
+TARGET=uno
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/unonrule.obj \
+ $(SLO)$/unoedsrc.obj \
+ $(SLO)$/unoedhlp.obj \
+ $(SLO)$/unofdesc.obj \
+ $(SLO)$/unoviwou.obj \
+ $(SLO)$/unofored.obj \
+ $(SLO)$/unoforou.obj \
+ $(SLO)$/unoipset.obj \
+ $(SLO)$/unotext.obj \
+ $(SLO)$/unotext2.obj \
+ $(SLO)$/unofield.obj \
+ $(SLO)$/UnoForbiddenCharsTable.obj \
+ $(SLO)$/unopracc.obj \
+ $(SLO)$/unoedprx.obj \
+ $(SLO)$/unoviwed.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/editeng/source/uno/unoedhlp.cxx b/editeng/source/uno/unoedhlp.cxx
new file mode 100644
index 0000000000..22c377c59d
--- /dev/null
+++ b/editeng/source/uno/unoedhlp.cxx
@@ -0,0 +1,200 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unoedhlp.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <tools/debug.hxx>
+
+#include <editeng/unoedhlp.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/editeng.hxx>
+
+//------------------------------------------------------------------------
+
+TYPEINIT1( SvxEditSourceHint, TextHint );
+
+SvxEditSourceHint::SvxEditSourceHint( ULONG _nId ) :
+ TextHint( _nId ),
+ mnStart( 0 ),
+ mnEnd( 0 )
+{
+}
+
+SvxEditSourceHint::SvxEditSourceHint( ULONG _nId, ULONG nValue, ULONG nStart, ULONG nEnd ) :
+ TextHint( _nId, nValue ),
+ mnStart( nStart),
+ mnEnd( nEnd )
+{
+}
+
+ULONG SvxEditSourceHint::GetValue() const
+{
+ return TextHint::GetValue();
+}
+
+ULONG SvxEditSourceHint::GetStartValue() const
+{
+ return mnStart;
+}
+
+ULONG SvxEditSourceHint::GetEndValue() const
+{
+ return mnEnd;
+}
+
+void SvxEditSourceHint::SetValue( ULONG n )
+{
+ TextHint::SetValue( n );
+}
+
+void SvxEditSourceHint::SetStartValue( ULONG n )
+{
+ mnStart = n;
+}
+
+void SvxEditSourceHint::SetEndValue( ULONG n )
+{
+ mnEnd = n;
+}
+
+//------------------------------------------------------------------------
+
+::std::auto_ptr<SfxHint> SvxEditSourceHelper::EENotification2Hint( EENotify* aNotify )
+{
+ if( aNotify )
+ {
+ switch( aNotify->eNotificationType )
+ {
+ case EE_NOTIFY_TEXTMODIFIED:
+ return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_MODIFIED, aNotify->nParagraph ) );
+
+ case EE_NOTIFY_PARAGRAPHINSERTED:
+ return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_PARAINSERTED, aNotify->nParagraph ) );
+
+ case EE_NOTIFY_PARAGRAPHREMOVED:
+ return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_PARAREMOVED, aNotify->nParagraph ) );
+
+ case EE_NOTIFY_PARAGRAPHSMOVED:
+ return ::std::auto_ptr<SfxHint>( new SvxEditSourceHint( EDITSOURCE_HINT_PARASMOVED, aNotify->nParagraph, aNotify->nParam1, aNotify->nParam2 ) );
+
+ case EE_NOTIFY_TEXTHEIGHTCHANGED:
+ return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_TEXTHEIGHTCHANGED, aNotify->nParagraph ) );
+
+ case EE_NOTIFY_TEXTVIEWSCROLLED:
+ return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_VIEWSCROLLED ) );
+
+ case EE_NOTIFY_TEXTVIEWSELECTIONCHANGED:
+ return ::std::auto_ptr<SfxHint>( new SvxEditSourceHint( EDITSOURCE_HINT_SELECTIONCHANGED ) );
+
+ case EE_NOTIFY_BLOCKNOTIFICATION_START:
+ return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_BLOCKNOTIFICATION_START, 0 ) );
+
+ case EE_NOTIFY_BLOCKNOTIFICATION_END:
+ return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_BLOCKNOTIFICATION_END, 0 ) );
+
+ case EE_NOTIFY_INPUT_START:
+ return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_INPUT_START, 0 ) );
+
+ case EE_NOTIFY_INPUT_END:
+ return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_INPUT_END, 0 ) );
+
+ default:
+ DBG_ERROR( "SvxEditSourceHelper::EENotification2Hint unknown notification" );
+ break;
+ }
+ }
+
+ return ::std::auto_ptr<SfxHint>( new SfxHint() );
+}
+
+sal_Bool SvxEditSourceHelper::GetAttributeRun( USHORT& nStartIndex, USHORT& nEndIndex, const EditEngine& rEE, USHORT nPara, USHORT nIndex )
+{
+ EECharAttribArray aCharAttribs;
+
+ rEE.GetCharAttribs( nPara, aCharAttribs );
+
+ // find closest index in front of nIndex
+ USHORT nAttr, nCurrIndex;
+ sal_Int32 nClosestStartIndex;
+ for( nAttr=0, nClosestStartIndex=0; nAttr<aCharAttribs.Count(); ++nAttr )
+ {
+ nCurrIndex = aCharAttribs[nAttr].nStart;
+
+ if( nCurrIndex > nIndex )
+ break; // aCharAttribs array is sorted in increasing order for nStart values
+
+ if( nCurrIndex > nClosestStartIndex )
+ {
+ nClosestStartIndex = nCurrIndex;
+ }
+ }
+
+ // find closest index behind of nIndex
+ sal_Int32 nClosestEndIndex;
+ for( nAttr=0, nClosestEndIndex=rEE.GetTextLen(nPara); nAttr<aCharAttribs.Count(); ++nAttr )
+ {
+ nCurrIndex = aCharAttribs[nAttr].nEnd;
+
+ if( nCurrIndex > nIndex &&
+ nCurrIndex < nClosestEndIndex )
+ {
+ nClosestEndIndex = nCurrIndex;
+ }
+ }
+
+ nStartIndex = static_cast<USHORT>( nClosestStartIndex );
+ nEndIndex = static_cast<USHORT>( nClosestEndIndex );
+
+ return sal_True;
+}
+
+Point SvxEditSourceHelper::EEToUserSpace( const Point& rPoint, const Size& rEESize, bool bIsVertical )
+{
+ return bIsVertical ? Point( -rPoint.Y() + rEESize.Height(), rPoint.X() ) : rPoint;
+}
+
+Point SvxEditSourceHelper::UserSpaceToEE( const Point& rPoint, const Size& rEESize, bool bIsVertical )
+{
+ return bIsVertical ? Point( rPoint.Y(), -rPoint.X() + rEESize.Height() ) : rPoint;
+}
+
+Rectangle SvxEditSourceHelper::EEToUserSpace( const Rectangle& rRect, const Size& rEESize, bool bIsVertical )
+{
+ // #106775# Don't touch rect if not vertical
+ return bIsVertical ? Rectangle( EEToUserSpace(rRect.BottomLeft(), rEESize, bIsVertical),
+ EEToUserSpace(rRect.TopRight(), rEESize, bIsVertical) ) : rRect;
+}
+
+Rectangle SvxEditSourceHelper::UserSpaceToEE( const Rectangle& rRect, const Size& rEESize, bool bIsVertical )
+{
+ // #106775# Don't touch rect if not vertical
+ return bIsVertical ? Rectangle( UserSpaceToEE(rRect.TopRight(), rEESize, bIsVertical),
+ UserSpaceToEE(rRect.BottomLeft(), rEESize, bIsVertical) ) : rRect;
+}
diff --git a/editeng/source/uno/unoedprx.cxx b/editeng/source/uno/unoedprx.cxx
new file mode 100644
index 0000000000..e2de161139
--- /dev/null
+++ b/editeng/source/uno/unoedprx.cxx
@@ -0,0 +1,1292 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unoedprx.cxx,v $
+ * $Revision: 1.22 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+//------------------------------------------------------------------------
+//
+// Global header
+//
+//------------------------------------------------------------------------
+
+#include <limits.h>
+#include <vector>
+#include <algorithm>
+#include <vos/mutex.hxx>
+#include <vcl/window.hxx>
+#include <vcl/svapp.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+//------------------------------------------------------------------------
+//
+// Project-local header
+//
+//------------------------------------------------------------------------
+#include "unoedprx.hxx"
+#include <editeng/unotext.hxx>
+#include <editeng/unoedhlp.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/AccessibleStringWrap.hxx>
+#include <editeng/outliner.hxx>
+
+using namespace ::com::sun::star;
+
+
+class SvxAccessibleTextIndex
+{
+public:
+ SvxAccessibleTextIndex() :
+ mnPara(0),
+ mnIndex(0),
+ mnEEIndex(0),
+ mnFieldOffset(0),
+ mnFieldLen(0),
+ mbInField(sal_False),
+ mnBulletOffset(0),
+ mnBulletLen(0),
+ mbInBullet(sal_False) {};
+ ~SvxAccessibleTextIndex() {};
+
+ // Get/Set current paragraph
+ void SetParagraph( USHORT nPara )
+ {
+ mnPara = nPara;
+ }
+ USHORT GetParagraph() const { return mnPara; }
+
+ /** Set the index in the UAA semantic
+
+ @param nIndex
+ The index from the UA API (fields and bullets are expanded)
+
+ @param rTF
+ The text forwarder to use in the calculations
+ */
+ void SetIndex( sal_Int32 nIndex, const SvxTextForwarder& rTF );
+ void SetIndex( USHORT nPara, sal_Int32 nIndex, const SvxTextForwarder& rTF ) { SetParagraph(nPara); SetIndex(nIndex, rTF); }
+ sal_Int32 GetIndex() const { return mnIndex; }
+
+ /** Set the index in the edit engine semantic
+
+ Update the object state to reflect the given index position in
+ EditEngine/Outliner index values
+
+ @param nEEIndex
+ The index from the edit engine (fields span exactly one index increment)
+
+ @param rTF
+ The text forwarder to use in the calculations
+ */
+ void SetEEIndex( USHORT nEEIndex, const SvxTextForwarder& rTF );
+ void SetEEIndex( USHORT nPara, USHORT nEEIndex, const SvxTextForwarder& rTF ) { SetParagraph(nPara); SetEEIndex(nEEIndex, rTF); }
+ USHORT GetEEIndex() const;
+
+ void SetFieldOffset( sal_Int32 nOffset, sal_Int32 nLen ) { mnFieldOffset = nOffset; mnFieldLen = nLen; }
+ sal_Int32 GetFieldOffset() const { return mnFieldOffset; }
+ sal_Int32 GetFieldLen() const { return mnFieldLen; }
+ void AreInField( sal_Bool bInField = sal_True ) { mbInField = bInField; }
+ sal_Bool InField() const { return mbInField; }
+
+ void SetBulletOffset( sal_Int32 nOffset, sal_Int32 nLen ) { mnBulletOffset = nOffset; mnBulletLen = nLen; }
+ sal_Int32 GetBulletOffset() const { return mnBulletOffset; }
+ sal_Int32 GetBulletLen() const { return mnBulletLen; }
+ void AreInBullet( sal_Bool bInBullet = sal_True ) { mbInBullet = bInBullet; }
+ sal_Bool InBullet() const { return mbInBullet; }
+
+ /// returns false if the current index contains non-editable text (e.g. bullets)
+ sal_Bool IsEditable() const;
+
+ /// returns false if the given range is non-editable (e.g. contains bullets or _parts_ of fields)
+ sal_Bool IsEditableRange( const SvxAccessibleTextIndex& rEnd ) const;
+
+private:
+ USHORT mnPara;
+ sal_Int32 mnIndex;
+ sal_Int32 mnEEIndex;
+ sal_Int32 mnFieldOffset;
+ sal_Int32 mnFieldLen;
+ sal_Bool mbInField;
+ sal_Int32 mnBulletOffset;
+ sal_Int32 mnBulletLen;
+ sal_Bool mbInBullet;
+};
+
+ESelection MakeEESelection( const SvxAccessibleTextIndex& rStart, const SvxAccessibleTextIndex& rEnd )
+{
+ // deal with field special case: to really get a field contained
+ // within a selection, the start index must be before or on the
+ // field, the end index after it.
+
+ // The SvxAccessibleTextIndex.GetEEIndex method gives the index on
+ // the field, as long the input index is on the field. Thus,
+ // correction necessary for the end index
+
+ // Therefore, for _ranges_, if part of the field is touched, all
+ // of the field must be selected
+ if( rStart.GetParagraph() <= rEnd.GetParagraph() ||
+ (rStart.GetParagraph() == rEnd.GetParagraph() &&
+ rStart.GetEEIndex() <= rEnd.GetEEIndex()) )
+ {
+ if( rEnd.InField() && rEnd.GetFieldOffset() )
+ return ESelection( rStart.GetParagraph(), rStart.GetEEIndex(),
+ rEnd.GetParagraph(), rEnd.GetEEIndex()+1 );
+ }
+ else if( rStart.GetParagraph() > rEnd.GetParagraph() ||
+ (rStart.GetParagraph() == rEnd.GetParagraph() &&
+ rStart.GetEEIndex() > rEnd.GetEEIndex()) )
+ {
+ if( rStart.InField() && rStart.GetFieldOffset() )
+ return ESelection( rStart.GetParagraph(), rStart.GetEEIndex()+1,
+ rEnd.GetParagraph(), rEnd.GetEEIndex() );
+ }
+
+ return ESelection( rStart.GetParagraph(), rStart.GetEEIndex(),
+ rEnd.GetParagraph(), rEnd.GetEEIndex() );
+}
+
+ESelection MakeEESelection( const SvxAccessibleTextIndex& rIndex )
+{
+ return ESelection( rIndex.GetParagraph(), rIndex.GetEEIndex(),
+ rIndex.GetParagraph(), rIndex.GetEEIndex() + 1 );
+}
+
+USHORT SvxAccessibleTextIndex::GetEEIndex() const
+{
+ DBG_ASSERT(mnEEIndex >= 0 && mnEEIndex <= USHRT_MAX,
+ "SvxAccessibleTextIndex::GetEEIndex: index value overflow");
+
+ return static_cast< USHORT > (mnEEIndex);
+}
+
+void SvxAccessibleTextIndex::SetEEIndex( USHORT nEEIndex, const SvxTextForwarder& rTF )
+{
+ // reset
+ mnFieldOffset = 0;
+ mbInField = sal_False;
+ mnFieldLen = 0;
+ mnBulletOffset = 0;
+ mbInBullet = sal_False;
+ mnBulletLen = 0;
+
+ // set known values
+ mnEEIndex = nEEIndex;
+
+ // calculate unknowns
+ USHORT nCurrField, nFieldCount = rTF.GetFieldCount( GetParagraph() );
+
+ mnIndex = nEEIndex;
+
+ EBulletInfo aBulletInfo = rTF.GetBulletInfo( GetParagraph() );
+
+ // any text bullets?
+ if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
+ aBulletInfo.bVisible &&
+ aBulletInfo.nType != SVX_NUM_BITMAP )
+ {
+ mnIndex += aBulletInfo.aText.Len();
+ }
+
+ for( nCurrField=0; nCurrField < nFieldCount; ++nCurrField )
+ {
+ EFieldInfo aFieldInfo( rTF.GetFieldInfo( GetParagraph(), nCurrField ) );
+
+ if( aFieldInfo.aPosition.nIndex > nEEIndex )
+ break;
+
+ if( aFieldInfo.aPosition.nIndex == nEEIndex )
+ {
+ AreInField();
+ break;
+ }
+
+ // #106010#
+ mnIndex += ::std::max(aFieldInfo.aCurrentText.Len()-1, 0);
+ }
+}
+
+void SvxAccessibleTextIndex::SetIndex( sal_Int32 nIndex, const SvxTextForwarder& rTF )
+{
+ // reset
+ mnFieldOffset = 0;
+ mbInField = sal_False;
+ mnFieldLen = 0;
+ mnBulletOffset = 0;
+ mbInBullet = sal_False;
+ mnBulletLen = 0;
+
+ // set known values
+ mnIndex = nIndex;
+
+ // calculate unknowns
+ USHORT nCurrField, nFieldCount = rTF.GetFieldCount( GetParagraph() );
+
+ DBG_ASSERT(nIndex >= 0 && nIndex <= USHRT_MAX,
+ "SvxAccessibleTextIndex::SetIndex: index value overflow");
+
+ mnEEIndex = nIndex;
+
+ EBulletInfo aBulletInfo = rTF.GetBulletInfo( GetParagraph() );
+
+ // any text bullets?
+ if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
+ aBulletInfo.bVisible &&
+ aBulletInfo.nType != SVX_NUM_BITMAP )
+ {
+ sal_Int32 nBulletLen = aBulletInfo.aText.Len();
+
+ if( nIndex < nBulletLen )
+ {
+ AreInBullet();
+ SetBulletOffset( nIndex, nBulletLen );
+ mnEEIndex = 0;
+ return;
+ }
+
+ mnEEIndex = mnEEIndex - nBulletLen;
+ }
+
+ for( nCurrField=0; nCurrField < nFieldCount; ++nCurrField )
+ {
+ EFieldInfo aFieldInfo( rTF.GetFieldInfo( GetParagraph(), nCurrField ) );
+
+ // we're before a field
+ if( aFieldInfo.aPosition.nIndex > mnEEIndex )
+ break;
+
+ // #106010#
+ mnEEIndex -= ::std::max(aFieldInfo.aCurrentText.Len()-1, 0);
+
+ // we're within a field
+ if( aFieldInfo.aPosition.nIndex >= mnEEIndex )
+ {
+ AreInField();
+ SetFieldOffset( ::std::max(aFieldInfo.aCurrentText.Len()-1, 0) - (aFieldInfo.aPosition.nIndex - mnEEIndex),
+ aFieldInfo.aCurrentText.Len() );
+ mnEEIndex = aFieldInfo.aPosition.nIndex ;
+ break;
+ }
+ }
+}
+
+sal_Bool SvxAccessibleTextIndex::IsEditable() const
+{
+ if( InBullet() || InField() )
+ return sal_False;
+
+ return sal_True;
+}
+
+sal_Bool SvxAccessibleTextIndex::IsEditableRange( const SvxAccessibleTextIndex& rEnd ) const
+{
+ if( GetIndex() > rEnd.GetIndex() )
+ return rEnd.IsEditableRange( *this );
+
+ if( InBullet() || rEnd.InBullet() )
+ return sal_False;
+
+ if( InField() && GetFieldOffset() )
+ return sal_False; // within field
+
+ if( rEnd.InField() && rEnd.GetFieldOffset() >= rEnd.GetFieldLen() - 1 )
+ return sal_False; // within field
+
+ return sal_True;
+}
+
+//---------------------------------------------------------------------------------
+
+SvxEditSourceAdapter::SvxEditSourceAdapter() : mbEditSourceValid( sal_False )
+{
+}
+
+SvxEditSourceAdapter::~SvxEditSourceAdapter()
+{
+}
+
+SvxEditSource* SvxEditSourceAdapter::Clone() const
+{
+ if( mbEditSourceValid && mpAdaptee.get() )
+ {
+ ::std::auto_ptr< SvxEditSource > pClonedAdaptee( mpAdaptee->Clone() );
+
+ if( pClonedAdaptee.get() )
+ {
+ SvxEditSourceAdapter* pClone = new SvxEditSourceAdapter();
+
+ if( pClone )
+ {
+ pClone->SetEditSource( pClonedAdaptee );
+ return pClone;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+SvxAccessibleTextAdapter* SvxEditSourceAdapter::GetTextForwarderAdapter()
+{
+ if( mbEditSourceValid && mpAdaptee.get() )
+ {
+ SvxTextForwarder* pTextForwarder = mpAdaptee->GetTextForwarder();
+
+ if( pTextForwarder )
+ {
+ maTextAdapter.SetForwarder(*pTextForwarder);
+
+ return &maTextAdapter;
+ }
+ }
+
+ return NULL;
+}
+
+SvxTextForwarder* SvxEditSourceAdapter::GetTextForwarder()
+{
+ return GetTextForwarderAdapter();
+}
+
+SvxViewForwarder* SvxEditSourceAdapter::GetViewForwarder()
+{
+ if( mbEditSourceValid && mpAdaptee.get() )
+ return mpAdaptee->GetViewForwarder();
+
+ return NULL;
+}
+
+SvxAccessibleTextEditViewAdapter* SvxEditSourceAdapter::GetEditViewForwarderAdapter( sal_Bool bCreate )
+{
+ if( mbEditSourceValid && mpAdaptee.get() )
+ {
+ SvxEditViewForwarder* pEditViewForwarder = mpAdaptee->GetEditViewForwarder(bCreate);
+
+ if( pEditViewForwarder )
+ {
+ SvxAccessibleTextAdapter* pTextAdapter = GetTextForwarderAdapter();
+
+ if( pTextAdapter )
+ {
+ maEditViewAdapter.SetForwarder(*pEditViewForwarder, *pTextAdapter);
+
+ return &maEditViewAdapter;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+SvxEditViewForwarder* SvxEditSourceAdapter::GetEditViewForwarder( sal_Bool bCreate )
+{
+ return GetEditViewForwarderAdapter( bCreate );
+}
+
+void SvxEditSourceAdapter::UpdateData()
+{
+ if( mbEditSourceValid && mpAdaptee.get() )
+ mpAdaptee->UpdateData();
+}
+
+SfxBroadcaster& SvxEditSourceAdapter::GetBroadcaster() const
+{
+ if( mbEditSourceValid && mpAdaptee.get() )
+ return mpAdaptee->GetBroadcaster();
+
+ return maDummyBroadcaster;
+}
+
+void SvxEditSourceAdapter::SetEditSource( ::std::auto_ptr< SvxEditSource > pAdaptee )
+{
+ if( pAdaptee.get() )
+ {
+ mpAdaptee = pAdaptee;
+ mbEditSourceValid = sal_True;
+ }
+ else
+ {
+ // do a lazy delete (prevents us from deleting the broadcaster
+ // from within a broadcast in
+ // AccessibleTextHelper_Impl::Notify)
+ mbEditSourceValid = sal_False;
+ }
+}
+
+sal_Bool SvxEditSourceAdapter::IsValid() const
+{
+ return mbEditSourceValid;
+}
+
+
+//--------------------------------------------------------------------------------------
+
+SvxAccessibleTextAdapter::SvxAccessibleTextAdapter() : mrTextForwarder( NULL )
+{
+}
+
+SvxAccessibleTextAdapter::~SvxAccessibleTextAdapter()
+{
+}
+
+USHORT SvxAccessibleTextAdapter::GetParagraphCount() const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ return mrTextForwarder->GetParagraphCount();
+}
+
+USHORT SvxAccessibleTextAdapter::GetTextLen( USHORT nParagraph ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ SvxAccessibleTextIndex aIndex;
+ aIndex.SetEEIndex( nParagraph, mrTextForwarder->GetTextLen( nParagraph ), *this );
+
+ return static_cast< USHORT >(aIndex.GetIndex());
+}
+
+String SvxAccessibleTextAdapter::GetText( const ESelection& rSel ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ SvxAccessibleTextIndex aStartIndex;
+ SvxAccessibleTextIndex aEndIndex;
+
+ aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
+ aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
+
+ // normalize selection
+ if( rSel.nStartPara > rSel.nEndPara ||
+ (rSel.nStartPara == rSel.nEndPara && rSel.nStartPos > rSel.nEndPos) )
+ {
+ ::std::swap( aStartIndex, aEndIndex );
+ }
+
+ String sStr = mrTextForwarder->GetText( MakeEESelection(aStartIndex, aEndIndex) );
+
+ // trim field text, if necessary
+ if( aStartIndex.InField() )
+ {
+ DBG_ASSERT(aStartIndex.GetFieldOffset() >= 0 &&
+ aStartIndex.GetFieldOffset() <= USHRT_MAX,
+ "SvxAccessibleTextIndex::GetText: index value overflow");
+
+ sStr.Erase(0, static_cast< USHORT > (aStartIndex.GetFieldOffset()) );
+ }
+ if( aEndIndex.InField() && aEndIndex.GetFieldOffset() )
+ {
+ DBG_ASSERT(sStr.Len() - (aEndIndex.GetFieldLen() - aEndIndex.GetFieldOffset()) >= 0 &&
+ sStr.Len() - (aEndIndex.GetFieldLen() - aEndIndex.GetFieldOffset()) <= USHRT_MAX,
+ "SvxAccessibleTextIndex::GetText: index value overflow");
+
+ sStr = sStr.Copy(0, static_cast< USHORT > (sStr.Len() - (aEndIndex.GetFieldLen() - aEndIndex.GetFieldOffset())) );
+ }
+
+ EBulletInfo aBulletInfo1 = GetBulletInfo( static_cast< USHORT >(aStartIndex.GetParagraph()) );
+ EBulletInfo aBulletInfo2 = GetBulletInfo( static_cast< USHORT >(aEndIndex.GetParagraph()) );
+
+ if( aStartIndex.InBullet() )
+ {
+ // prepend leading bullet
+ String sBullet = aBulletInfo1.aText;
+
+ DBG_ASSERT(aStartIndex.GetBulletOffset() >= 0 &&
+ aStartIndex.GetBulletOffset() <= USHRT_MAX,
+ "SvxAccessibleTextIndex::GetText: index value overflow");
+
+ sBullet.Erase(0, static_cast< USHORT > (aStartIndex.GetBulletOffset()) );
+
+ sBullet += sStr;
+ sStr = sBullet;
+ }
+
+ if( aEndIndex.InBullet() )
+ {
+ // append trailing bullet
+ sStr += aBulletInfo2.aText;;
+
+ DBG_ASSERT(sStr.Len() - (aEndIndex.GetBulletLen() - aEndIndex.GetBulletOffset()) >= 0 &&
+ sStr.Len() - (aEndIndex.GetBulletLen() - aEndIndex.GetBulletOffset()) <= USHRT_MAX,
+ "SvxAccessibleTextIndex::GetText: index value overflow");
+
+ sStr = sStr.Copy(0, static_cast< USHORT > (sStr.Len() - (aEndIndex.GetBulletLen() - aEndIndex.GetBulletOffset())) );
+ }
+ else if( aStartIndex.GetParagraph() != aEndIndex.GetParagraph() &&
+ HaveTextBullet( aEndIndex.GetParagraph() ) )
+ {
+ String sBullet = aBulletInfo2.aText;
+
+ DBG_ASSERT(sBullet.Len() - (aEndIndex.GetBulletLen() - aEndIndex.GetBulletOffset()) >= 0 &&
+ sBullet.Len() - (aEndIndex.GetBulletLen() - aEndIndex.GetBulletOffset()) <= USHRT_MAX,
+ "SvxAccessibleTextIndex::GetText: index value overflow");
+
+ sBullet = sBullet.Copy(0, static_cast< USHORT > (sBullet.Len() - (aEndIndex.GetBulletLen() - aEndIndex.GetBulletOffset())) );
+
+ // insert bullet
+ sStr.Insert( sBullet,
+ static_cast< USHORT > (GetTextLen(aStartIndex.GetParagraph()) - aStartIndex.GetIndex()) );
+ }
+
+ return sStr;
+}
+
+SfxItemSet SvxAccessibleTextAdapter::GetAttribs( const ESelection& rSel, BOOL bOnlyHardAttrib ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ SvxAccessibleTextIndex aStartIndex;
+ SvxAccessibleTextIndex aEndIndex;
+
+ aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
+ aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
+
+ return mrTextForwarder->GetAttribs( MakeEESelection(aStartIndex, aEndIndex),
+ bOnlyHardAttrib );
+}
+
+SfxItemSet SvxAccessibleTextAdapter::GetParaAttribs( USHORT nPara ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ return mrTextForwarder->GetParaAttribs( nPara );
+}
+
+void SvxAccessibleTextAdapter::SetParaAttribs( USHORT nPara, const SfxItemSet& rSet )
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ mrTextForwarder->SetParaAttribs( nPara, rSet );
+}
+
+void SvxAccessibleTextAdapter::RemoveAttribs( const ESelection& , sal_Bool , sal_uInt16 )
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+}
+
+void SvxAccessibleTextAdapter::GetPortions( USHORT nPara, SvUShorts& rList ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ mrTextForwarder->GetPortions( nPara, rList );
+}
+
+USHORT SvxAccessibleTextAdapter::GetItemState( const ESelection& rSel, USHORT nWhich ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ SvxAccessibleTextIndex aStartIndex;
+ SvxAccessibleTextIndex aEndIndex;
+
+ aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
+ aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
+
+ return mrTextForwarder->GetItemState( MakeEESelection(aStartIndex, aEndIndex),
+ nWhich );
+}
+
+USHORT SvxAccessibleTextAdapter::GetItemState( USHORT nPara, USHORT nWhich ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ return mrTextForwarder->GetItemState( nPara, nWhich );
+}
+
+void SvxAccessibleTextAdapter::QuickInsertText( const String& rText, const ESelection& rSel )
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ SvxAccessibleTextIndex aStartIndex;
+ SvxAccessibleTextIndex aEndIndex;
+
+ aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
+ aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
+
+ mrTextForwarder->QuickInsertText( rText,
+ MakeEESelection(aStartIndex, aEndIndex) );
+}
+
+void SvxAccessibleTextAdapter::QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel )
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ SvxAccessibleTextIndex aStartIndex;
+ SvxAccessibleTextIndex aEndIndex;
+
+ aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
+ aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
+
+ mrTextForwarder->QuickInsertField( rFld,
+ MakeEESelection(aStartIndex, aEndIndex) );
+}
+
+void SvxAccessibleTextAdapter::QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel )
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ SvxAccessibleTextIndex aStartIndex;
+ SvxAccessibleTextIndex aEndIndex;
+
+ aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
+ aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
+
+ mrTextForwarder->QuickSetAttribs( rSet,
+ MakeEESelection(aStartIndex, aEndIndex) );
+}
+
+void SvxAccessibleTextAdapter::QuickInsertLineBreak( const ESelection& rSel )
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ SvxAccessibleTextIndex aStartIndex;
+ SvxAccessibleTextIndex aEndIndex;
+
+ aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
+ aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
+
+ mrTextForwarder->QuickInsertLineBreak( MakeEESelection(aStartIndex, aEndIndex) );
+}
+
+SfxItemPool* SvxAccessibleTextAdapter::GetPool() const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ return mrTextForwarder->GetPool();
+}
+
+XubString SvxAccessibleTextAdapter::CalcFieldValue( const SvxFieldItem& rField, USHORT nPara, USHORT nPos, Color*& rpTxtColor, Color*& rpFldColor )
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ return mrTextForwarder->CalcFieldValue( rField, nPara, nPos, rpTxtColor, rpFldColor );
+}
+
+BOOL SvxAccessibleTextAdapter::IsValid() const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ if( mrTextForwarder )
+ return mrTextForwarder->IsValid();
+ else
+ return sal_False;
+}
+
+LanguageType SvxAccessibleTextAdapter::GetLanguage( USHORT nPara, USHORT nPos ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ SvxAccessibleTextIndex aIndex;
+
+ aIndex.SetIndex( nPara, nPos, *this );
+
+ return mrTextForwarder->GetLanguage( nPara, aIndex.GetEEIndex() );
+}
+
+USHORT SvxAccessibleTextAdapter::GetFieldCount( USHORT nPara ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ return mrTextForwarder->GetFieldCount( nPara );
+}
+
+EFieldInfo SvxAccessibleTextAdapter::GetFieldInfo( USHORT nPara, USHORT nField ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ return mrTextForwarder->GetFieldInfo( nPara, nField );
+}
+
+EBulletInfo SvxAccessibleTextAdapter::GetBulletInfo( USHORT nPara ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ return mrTextForwarder->GetBulletInfo( nPara );
+}
+
+Rectangle SvxAccessibleTextAdapter::GetCharBounds( USHORT nPara, USHORT nIndex ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ SvxAccessibleTextIndex aIndex;
+ aIndex.SetIndex( nPara, nIndex, *this );
+
+ // preset if anything goes wrong below
+ // n-th char in GetParagraphIndex's paragraph
+ Rectangle aRect = mrTextForwarder->GetCharBounds( nPara, static_cast< USHORT >( aIndex.GetEEIndex() ) );
+
+ if( aIndex.InBullet() )
+ {
+ EBulletInfo aBulletInfo = GetBulletInfo( nPara );
+
+ OutputDevice* pOutDev = GetRefDevice();
+
+ DBG_ASSERT(pOutDev!=NULL, "SvxAccessibleTextAdapter::GetCharBounds: No ref device");
+
+ // preset if anything goes wrong below
+ aRect = aBulletInfo.aBounds; // better than nothing
+ if( pOutDev )
+ {
+ AccessibleStringWrap aStringWrap( *pOutDev, aBulletInfo.aFont, aBulletInfo.aText );
+
+ if( aStringWrap.GetCharacterBounds( aIndex.GetBulletOffset(), aRect ) )
+ aRect.Move( aBulletInfo.aBounds.Left(), aBulletInfo.aBounds.Top() );
+ }
+ }
+ else
+ {
+ // handle field content manually
+ if( aIndex.InField() )
+ {
+ OutputDevice* pOutDev = GetRefDevice();
+
+ DBG_ASSERT(pOutDev!=NULL, "SvxAccessibleTextAdapter::GetCharBounds: No ref device");
+
+ if( pOutDev )
+ {
+ ESelection aSel = MakeEESelection( aIndex );
+
+ SvxFont aFont = EditEngine::CreateSvxFontFromItemSet( mrTextForwarder->GetAttribs( aSel ) );
+ AccessibleStringWrap aStringWrap( *pOutDev,
+ aFont,
+ mrTextForwarder->GetText( aSel ) );
+
+ Rectangle aStartRect = mrTextForwarder->GetCharBounds( nPara, static_cast< USHORT >( aIndex.GetEEIndex() ) );
+
+ if( !aStringWrap.GetCharacterBounds( aIndex.GetFieldOffset(), aRect ) )
+ aRect = aStartRect;
+ else
+ aRect.Move( aStartRect.Left(), aStartRect.Top() );
+ }
+ }
+ }
+
+ return aRect;
+}
+
+Rectangle SvxAccessibleTextAdapter::GetParaBounds( USHORT nPara ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ EBulletInfo aBulletInfo = GetBulletInfo( nPara );
+
+ if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
+ aBulletInfo.bVisible &&
+ aBulletInfo.nType != SVX_NUM_BITMAP )
+ {
+ // include bullet in para bounding box
+ Rectangle aRect( mrTextForwarder->GetParaBounds( nPara ) );
+
+ aRect.Union( aBulletInfo.aBounds );
+
+ return aRect;
+ }
+
+ return mrTextForwarder->GetParaBounds( nPara );
+}
+
+MapMode SvxAccessibleTextAdapter::GetMapMode() const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ return mrTextForwarder->GetMapMode();
+}
+
+OutputDevice* SvxAccessibleTextAdapter::GetRefDevice() const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ return mrTextForwarder->GetRefDevice();
+}
+
+sal_Bool SvxAccessibleTextAdapter::GetIndexAtPoint( const Point& rPoint, USHORT& nPara, USHORT& nIndex ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ if( !mrTextForwarder->GetIndexAtPoint( rPoint, nPara, nIndex ) )
+ return sal_False;
+
+ SvxAccessibleTextIndex aIndex;
+ aIndex.SetEEIndex(nPara, nIndex, *this);
+
+ DBG_ASSERT(aIndex.GetIndex() >= 0 && aIndex.GetIndex() <= USHRT_MAX,
+ "SvxAccessibleTextIndex::SetIndex: index value overflow");
+
+ nIndex = static_cast< USHORT > (aIndex.GetIndex());
+
+ EBulletInfo aBulletInfo = GetBulletInfo( nPara );
+
+ // any text bullets?
+ if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
+ aBulletInfo.bVisible &&
+ aBulletInfo.nType != SVX_NUM_BITMAP )
+ {
+ if( aBulletInfo.aBounds.IsInside( rPoint) )
+ {
+ OutputDevice* pOutDev = GetRefDevice();
+
+ DBG_ASSERT(pOutDev!=NULL, "SvxAccessibleTextAdapter::GetIndexAtPoint: No ref device");
+
+ if( !pOutDev )
+ return sal_False;
+
+ AccessibleStringWrap aStringWrap( *pOutDev, aBulletInfo.aFont, aBulletInfo.aText );
+
+ Point aPoint = rPoint;
+ aPoint.Move( -aBulletInfo.aBounds.Left(), -aBulletInfo.aBounds.Top() );
+
+ DBG_ASSERT(aStringWrap.GetIndexAtPoint( aPoint ) >= 0 &&
+ aStringWrap.GetIndexAtPoint( aPoint ) <= USHRT_MAX,
+ "SvxAccessibleTextIndex::SetIndex: index value overflow");
+
+ nIndex = static_cast< USHORT > (aStringWrap.GetIndexAtPoint( aPoint ));
+ return sal_True;
+ }
+ }
+
+ if( aIndex.InField() )
+ {
+ OutputDevice* pOutDev = GetRefDevice();
+
+ DBG_ASSERT(pOutDev!=NULL, "SvxAccessibleTextAdapter::GetIndexAtPoint: No ref device");
+
+ if( !pOutDev )
+ return sal_False;
+
+ ESelection aSelection = MakeEESelection( aIndex );
+ SvxFont aFont = EditEngine::CreateSvxFontFromItemSet( mrTextForwarder->GetAttribs( aSelection ) );
+ AccessibleStringWrap aStringWrap( *pOutDev,
+ aFont,
+ mrTextForwarder->GetText( aSelection ) );
+
+ Rectangle aRect = mrTextForwarder->GetCharBounds( nPara, aIndex.GetEEIndex() );
+ Point aPoint = rPoint;
+ aPoint.Move( -aRect.Left(), -aRect.Top() );
+
+ DBG_ASSERT(aIndex.GetIndex() + aStringWrap.GetIndexAtPoint( rPoint ) >= 0 &&
+ aIndex.GetIndex() + aStringWrap.GetIndexAtPoint( rPoint ) <= USHRT_MAX,
+ "SvxAccessibleTextIndex::SetIndex: index value overflow");
+
+ nIndex = static_cast< USHORT >(aIndex.GetIndex() + aStringWrap.GetIndexAtPoint( aPoint ));
+ return sal_True;
+ }
+
+ return sal_True;
+}
+
+sal_Bool SvxAccessibleTextAdapter::GetWordIndices( USHORT nPara, USHORT nIndex, USHORT& nStart, USHORT& nEnd ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ SvxAccessibleTextIndex aIndex;
+ aIndex.SetIndex(nPara, nIndex, *this);
+ nIndex = aIndex.GetEEIndex();
+
+ if( aIndex.InBullet() )
+ {
+ DBG_ASSERT(aIndex.GetBulletLen() >= 0 &&
+ aIndex.GetBulletLen() <= USHRT_MAX,
+ "SvxAccessibleTextIndex::SetIndex: index value overflow");
+
+ // always treat bullet as separate word
+ nStart = 0;
+ nEnd = static_cast< USHORT > (aIndex.GetBulletLen());
+
+ return sal_True;
+ }
+
+ if( aIndex.InField() )
+ {
+ DBG_ASSERT(aIndex.GetIndex() - aIndex.GetFieldOffset() >= 0 &&
+ aIndex.GetIndex() - aIndex.GetFieldOffset() <= USHRT_MAX &&
+ nStart + aIndex.GetFieldLen() >= 0 &&
+ nStart + aIndex.GetFieldLen() <= USHRT_MAX,
+ "SvxAccessibleTextIndex::SetIndex: index value overflow");
+
+ // always treat field as separate word
+ // TODO: to circumvent this, _we_ would have to do the break iterator stuff!
+ nStart = static_cast< USHORT > (aIndex.GetIndex() - aIndex.GetFieldOffset());
+ nEnd = static_cast< USHORT > (nStart + aIndex.GetFieldLen());
+
+ return sal_True;
+ }
+
+ if( !mrTextForwarder->GetWordIndices( nPara, nIndex, nStart, nEnd ) )
+ return sal_False;
+
+ aIndex.SetEEIndex( nPara, nStart, *this );
+ DBG_ASSERT(aIndex.GetIndex() >= 0 &&
+ aIndex.GetIndex() <= USHRT_MAX,
+ "SvxAccessibleTextIndex::SetIndex: index value overflow");
+ nStart = static_cast< USHORT > (aIndex.GetIndex());
+
+ aIndex.SetEEIndex( nPara, nEnd, *this );
+ DBG_ASSERT(aIndex.GetIndex() >= 0 &&
+ aIndex.GetIndex() <= USHRT_MAX,
+ "SvxAccessibleTextIndex::SetIndex: index value overflow");
+ nEnd = static_cast< USHORT > (aIndex.GetIndex());
+
+ return sal_True;
+}
+
+sal_Bool SvxAccessibleTextAdapter::GetAttributeRun( USHORT& nStartIndex, USHORT& nEndIndex, USHORT nPara, USHORT nIndex ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ SvxAccessibleTextIndex aIndex;
+ aIndex.SetIndex(nPara, nIndex, *this);
+ nIndex = aIndex.GetEEIndex();
+
+ if( aIndex.InBullet() )
+ {
+ DBG_ASSERT(aIndex.GetBulletLen() >= 0 &&
+ aIndex.GetBulletLen() <= USHRT_MAX,
+ "SvxAccessibleTextIndex::SetIndex: index value overflow");
+
+ // always treat bullet as distinct attribute
+ nStartIndex = 0;
+ nEndIndex = static_cast< USHORT > (aIndex.GetBulletLen());
+
+ return sal_True;
+ }
+
+ if( aIndex.InField() )
+ {
+ DBG_ASSERT(aIndex.GetIndex() - aIndex.GetFieldOffset() >= 0 &&
+ aIndex.GetIndex() - aIndex.GetFieldOffset() <= USHRT_MAX,
+ "SvxAccessibleTextIndex::SetIndex: index value overflow");
+
+ // always treat field as distinct attribute
+ nStartIndex = static_cast< USHORT > (aIndex.GetIndex() - aIndex.GetFieldOffset());
+ nEndIndex = static_cast< USHORT > (nStartIndex + aIndex.GetFieldLen());
+
+ return sal_True;
+ }
+
+ if( !mrTextForwarder->GetAttributeRun( nStartIndex, nEndIndex, nPara, nIndex ) )
+ return sal_False;
+
+ aIndex.SetEEIndex( nPara, nStartIndex, *this );
+ DBG_ASSERT(aIndex.GetIndex() >= 0 &&
+ aIndex.GetIndex() <= USHRT_MAX,
+ "SvxAccessibleTextIndex::SetIndex: index value overflow");
+ nStartIndex = static_cast< USHORT > (aIndex.GetIndex());
+
+ aIndex.SetEEIndex( nPara, nEndIndex, *this );
+ DBG_ASSERT(aIndex.GetIndex() >= 0 &&
+ aIndex.GetIndex() <= USHRT_MAX,
+ "SvxAccessibleTextIndex::SetIndex: index value overflow");
+ nEndIndex = static_cast< USHORT > (aIndex.GetIndex());
+
+ return sal_True;
+}
+
+USHORT SvxAccessibleTextAdapter::GetLineCount( USHORT nPara ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ return mrTextForwarder->GetLineCount( nPara );
+}
+
+USHORT SvxAccessibleTextAdapter::GetLineLen( USHORT nPara, USHORT nLine ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ SvxAccessibleTextIndex aStartIndex;
+ SvxAccessibleTextIndex aEndIndex;
+ USHORT nCurrLine;
+ USHORT nCurrIndex, nLastIndex;
+ for( nCurrLine=0, nCurrIndex=0, nLastIndex=0; nCurrLine<=nLine; ++nCurrLine )
+ {
+ nLastIndex = nCurrIndex;
+ nCurrIndex =
+ nCurrIndex + mrTextForwarder->GetLineLen( nPara, nCurrLine );
+ }
+
+ aEndIndex.SetEEIndex( nPara, nCurrIndex, *this );
+ if( nLine > 0 )
+ {
+ aStartIndex.SetEEIndex( nPara, nLastIndex, *this );
+
+ return static_cast< USHORT >(aEndIndex.GetIndex() - aStartIndex.GetIndex());
+ }
+ else
+ return static_cast< USHORT >(aEndIndex.GetIndex());
+}
+
+void SvxAccessibleTextAdapter::GetLineBoundaries( /*out*/USHORT &rStart, /*out*/USHORT &rEnd, USHORT nParagraph, USHORT nLine ) const
+{
+ mrTextForwarder->GetLineBoundaries( rStart, rEnd, nParagraph, nLine );
+}
+
+USHORT SvxAccessibleTextAdapter::GetLineNumberAtIndex( USHORT nPara, USHORT nIndex ) const
+{
+ return mrTextForwarder->GetLineNumberAtIndex( nPara, nIndex );
+}
+
+sal_Bool SvxAccessibleTextAdapter::Delete( const ESelection& rSel )
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ SvxAccessibleTextIndex aStartIndex;
+ SvxAccessibleTextIndex aEndIndex;
+
+ aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
+ aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
+
+ return mrTextForwarder->Delete( MakeEESelection(aStartIndex, aEndIndex ) );
+}
+
+sal_Bool SvxAccessibleTextAdapter::InsertText( const String& rStr, const ESelection& rSel )
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ SvxAccessibleTextIndex aStartIndex;
+ SvxAccessibleTextIndex aEndIndex;
+
+ aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
+ aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
+
+ return mrTextForwarder->InsertText( rStr, MakeEESelection(aStartIndex, aEndIndex) );
+}
+
+sal_Bool SvxAccessibleTextAdapter::QuickFormatDoc( BOOL bFull )
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ return mrTextForwarder->QuickFormatDoc( bFull );
+}
+
+sal_Int16 SvxAccessibleTextAdapter::GetDepth( USHORT nPara ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ return mrTextForwarder->GetDepth( nPara );
+}
+
+sal_Bool SvxAccessibleTextAdapter::SetDepth( USHORT nPara, sal_Int16 nNewDepth )
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ return mrTextForwarder->SetDepth( nPara, nNewDepth );
+}
+
+void SvxAccessibleTextAdapter::SetForwarder( SvxTextForwarder& rForwarder )
+{
+ mrTextForwarder = &rForwarder;
+}
+
+sal_Bool SvxAccessibleTextAdapter::HaveImageBullet( USHORT nPara ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ EBulletInfo aBulletInfo = GetBulletInfo( nPara );
+
+ if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
+ aBulletInfo.bVisible &&
+ aBulletInfo.nType == SVX_NUM_BITMAP )
+ {
+ return sal_True;
+ }
+ else
+ {
+ return sal_False;
+ }
+}
+
+sal_Bool SvxAccessibleTextAdapter::HaveTextBullet( USHORT nPara ) const
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ EBulletInfo aBulletInfo = GetBulletInfo( nPara );
+
+ if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
+ aBulletInfo.bVisible &&
+ aBulletInfo.nType != SVX_NUM_BITMAP )
+ {
+ return sal_True;
+ }
+ else
+ {
+ return sal_False;
+ }
+}
+
+sal_Bool SvxAccessibleTextAdapter::IsEditable( const ESelection& rSel )
+{
+ DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder");
+
+ SvxAccessibleTextIndex aStartIndex;
+ SvxAccessibleTextIndex aEndIndex;
+
+ aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
+ aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
+
+ // normalize selection
+ if( rSel.nStartPara > rSel.nEndPara ||
+ (rSel.nStartPara == rSel.nEndPara && rSel.nStartPos > rSel.nEndPos) )
+ {
+ ::std::swap( aStartIndex, aEndIndex );
+ }
+
+ return aStartIndex.IsEditableRange( aEndIndex );
+}
+
+const SfxItemSet * SvxAccessibleTextAdapter::GetEmptyItemSetPtr()
+{
+ DBG_ERROR( "not implemented" );
+ return 0;
+}
+
+void SvxAccessibleTextAdapter::AppendParagraph()
+{
+ DBG_ERROR( "not implemented" );
+}
+
+xub_StrLen SvxAccessibleTextAdapter::AppendTextPortion( USHORT, const String &, const SfxItemSet & )
+{
+ DBG_ERROR( "not implemented" );
+ return 0;
+}
+void SvxAccessibleTextAdapter::CopyText(const SvxTextForwarder&)
+{
+ DBG_ERROR( "not implemented" );
+}
+
+
+
+//---------------------------------------------------------------------------------------
+
+SvxAccessibleTextEditViewAdapter::SvxAccessibleTextEditViewAdapter()
+{
+}
+
+SvxAccessibleTextEditViewAdapter::~SvxAccessibleTextEditViewAdapter()
+{
+}
+
+BOOL SvxAccessibleTextEditViewAdapter::IsValid() const
+{
+ DBG_ASSERT(mrViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
+
+ if( mrViewForwarder )
+ return mrViewForwarder->IsValid();
+ else
+ return sal_False;
+}
+
+Rectangle SvxAccessibleTextEditViewAdapter::GetVisArea() const
+{
+ DBG_ASSERT(mrViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
+
+ return mrViewForwarder->GetVisArea();
+}
+
+Point SvxAccessibleTextEditViewAdapter::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ DBG_ASSERT(mrViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
+
+ return mrViewForwarder->LogicToPixel(rPoint, rMapMode);
+}
+
+Point SvxAccessibleTextEditViewAdapter::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ DBG_ASSERT(mrViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
+
+ return mrViewForwarder->PixelToLogic(rPoint, rMapMode);
+}
+
+sal_Bool SvxAccessibleTextEditViewAdapter::GetSelection( ESelection& rSel ) const
+{
+ DBG_ASSERT(mrViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
+
+ ESelection aSelection;
+
+ if( !mrViewForwarder->GetSelection( aSelection ) )
+ return sal_False;
+
+ SvxAccessibleTextIndex aStartIndex;
+ SvxAccessibleTextIndex aEndIndex;
+
+ aStartIndex.SetEEIndex( aSelection.nStartPara, aSelection.nStartPos, *mrTextForwarder );
+ aEndIndex.SetEEIndex( aSelection.nEndPara, aSelection.nEndPos, *mrTextForwarder );
+
+ DBG_ASSERT(aStartIndex.GetIndex() >= 0 && aStartIndex.GetIndex() <= USHRT_MAX &&
+ aEndIndex.GetIndex() >= 0 && aEndIndex.GetIndex() <= USHRT_MAX,
+ "SvxAccessibleTextEditViewAdapter::GetSelection: index value overflow");
+
+ rSel = ESelection( aStartIndex.GetParagraph(), static_cast< USHORT > (aStartIndex.GetIndex()),
+ aEndIndex.GetParagraph(), static_cast< USHORT > (aEndIndex.GetIndex()) );
+
+ return sal_True;
+}
+
+sal_Bool SvxAccessibleTextEditViewAdapter::SetSelection( const ESelection& rSel )
+{
+ DBG_ASSERT(mrViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
+
+ SvxAccessibleTextIndex aStartIndex;
+ SvxAccessibleTextIndex aEndIndex;
+
+ aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *mrTextForwarder );
+ aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *mrTextForwarder );
+
+ return mrViewForwarder->SetSelection( MakeEESelection(aStartIndex, aEndIndex) );
+}
+
+sal_Bool SvxAccessibleTextEditViewAdapter::Copy()
+{
+ DBG_ASSERT(mrViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
+
+ return mrViewForwarder->Copy();
+}
+
+sal_Bool SvxAccessibleTextEditViewAdapter::Cut()
+{
+ DBG_ASSERT(mrViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
+
+ return mrViewForwarder->Cut();
+}
+
+sal_Bool SvxAccessibleTextEditViewAdapter::Paste()
+{
+ DBG_ASSERT(mrViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
+
+ return mrViewForwarder->Paste();
+}
+
+void SvxAccessibleTextEditViewAdapter::SetForwarder( SvxEditViewForwarder& rForwarder,
+ SvxAccessibleTextAdapter& rTextForwarder )
+{
+ mrViewForwarder = &rForwarder;
+ mrTextForwarder = &rTextForwarder;
+}
+
diff --git a/editeng/source/uno/unoedsrc.cxx b/editeng/source/uno/unoedsrc.cxx
new file mode 100644
index 0000000000..df10f1faac
--- /dev/null
+++ b/editeng/source/uno/unoedsrc.cxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unoedsrc.cxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <svl/brdcst.hxx>
+
+#include <editeng/unoedsrc.hxx>
+
+
+//------------------------------------------------------------------------
+
+void SvxEditSource::addRange( SvxUnoTextRangeBase* )
+{
+}
+
+//------------------------------------------------------------------------
+
+void SvxEditSource::removeRange( SvxUnoTextRangeBase* )
+{
+}
+
+//------------------------------------------------------------------------
+
+const SvxUnoTextRangeBaseList& SvxEditSource::getRanges() const
+{
+ static SvxUnoTextRangeBaseList gList;
+ return gList;
+}
+
+//------------------------------------------------------------------------
+
+SvxTextForwarder::~SvxTextForwarder()
+{
+}
+
+//------------------------------------------------------------------------
+
+SvxViewForwarder::~SvxViewForwarder()
+{
+}
+
+//------------------------------------------------------------------------
+
+SvxEditSource::~SvxEditSource()
+{
+}
+
+SvxViewForwarder* SvxEditSource::GetViewForwarder()
+{
+ return NULL;
+}
+
+SvxEditViewForwarder* SvxEditSource::GetEditViewForwarder( sal_Bool )
+{
+ return NULL;
+}
+
+SfxBroadcaster& SvxEditSource::GetBroadcaster() const
+{
+ DBG_ERROR("SvxEditSource::GetBroadcaster called for implementation missing this feature!");
+
+ static SfxBroadcaster aBroadcaster;
+
+ return aBroadcaster;
+}
diff --git a/editeng/source/uno/unofdesc.cxx b/editeng/source/uno/unofdesc.cxx
new file mode 100644
index 0000000000..d5cb98a19b
--- /dev/null
+++ b/editeng/source/uno/unofdesc.cxx
@@ -0,0 +1,269 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unofdesc.cxx,v $
+ * $Revision: 1.7.212.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <editeng/eeitem.hxx>
+#include <com/sun/star/uno/Any.hxx>
+
+#ifndef _TOOLKIT_HELPRE_VCLUNOHELPER_HXX_
+#include <toolkit/helper/vclunohelper.hxx>
+#endif
+#include <editeng/fontitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/memberids.hrc>
+#include <svl/itempool.hxx>
+
+#include <editeng/unofdesc.hxx>
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+
+
+void SvxUnoFontDescriptor::ConvertToFont( const awt::FontDescriptor& rDesc, Font& rFont )
+{
+ rFont.SetName( rDesc.Name );
+ rFont.SetStyleName( rDesc.StyleName );
+ rFont.SetSize( Size( rDesc.Width, rDesc.Height ) );
+ rFont.SetFamily( (FontFamily)rDesc.Family );
+ rFont.SetCharSet( (CharSet)rDesc.CharSet );
+ rFont.SetPitch( (FontPitch)rDesc.Pitch );
+ rFont.SetOrientation( (short)(rDesc.Orientation*10) );
+ rFont.SetKerning( rDesc.Kerning );
+ rFont.SetWeight( VCLUnoHelper::ConvertFontWeight(rDesc.Weight) );
+ rFont.SetItalic( (FontItalic)rDesc.Slant );
+ rFont.SetUnderline( (FontUnderline)rDesc.Underline );
+ rFont.SetStrikeout( (FontStrikeout)rDesc.Strikeout );
+ rFont.SetWordLineMode( rDesc.WordLineMode );
+}
+
+void SvxUnoFontDescriptor::ConvertFromFont( const Font& rFont, awt::FontDescriptor& rDesc )
+{
+ rDesc.Name = rFont.GetName();
+ rDesc.StyleName = rFont.GetStyleName();
+ rDesc.Width = sal::static_int_cast< sal_Int16 >(rFont.GetSize().Width());
+ rDesc.Height = sal::static_int_cast< sal_Int16 >(rFont.GetSize().Height());
+ rDesc.Family = sal::static_int_cast< sal_Int16 >(rFont.GetFamily());
+ rDesc.CharSet = rFont.GetCharSet();
+ rDesc.Pitch = sal::static_int_cast< sal_Int16 >(rFont.GetPitch());
+ rDesc.Orientation = static_cast< float >(rFont.GetOrientation() / 10);
+ rDesc.Kerning = rFont.IsKerning();
+ rDesc.Weight = VCLUnoHelper::ConvertFontWeight( rFont.GetWeight() );
+ rDesc.Slant = (awt::FontSlant)rFont.GetItalic();
+ rDesc.Underline = sal::static_int_cast< sal_Int16 >(rFont.GetUnderline());
+ rDesc.Strikeout = sal::static_int_cast< sal_Int16 >(rFont.GetStrikeout());
+ rDesc.WordLineMode = rFont.IsWordLineMode();
+}
+
+void SvxUnoFontDescriptor::FillItemSet( const awt::FontDescriptor& rDesc, SfxItemSet& rSet )
+{
+ uno::Any aTemp;
+
+ {
+ SvxFontItem aFontItem( EE_CHAR_FONTINFO );
+ aFontItem.GetFamilyName()= rDesc.Name;
+ aFontItem.GetStyleName() = rDesc.StyleName;
+ aFontItem.GetFamily() = (FontFamily)rDesc.Family;
+ aFontItem.GetCharSet() = rDesc.CharSet;
+ aFontItem.GetPitch() = (FontPitch)rDesc.Pitch;
+ rSet.Put(aFontItem);
+ }
+
+ {
+ SvxFontHeightItem aFontHeightItem( 0, 100, EE_CHAR_FONTHEIGHT );
+ aTemp <<= (float)rDesc.Height;
+ ((SfxPoolItem*)&aFontHeightItem)->PutValue( aTemp, MID_FONTHEIGHT|CONVERT_TWIPS );
+ rSet.Put(aFontHeightItem);
+ }
+
+ {
+ SvxPostureItem aPostureItem( (FontItalic)0, EE_CHAR_ITALIC );
+ aTemp <<= rDesc.Slant;
+ ((SfxPoolItem*)&aPostureItem)->PutValue( aTemp, MID_POSTURE );
+ rSet.Put(aPostureItem);
+ }
+
+ {
+ SvxUnderlineItem aUnderlineItem( (FontUnderline)0, EE_CHAR_UNDERLINE );
+ aTemp <<= (sal_Int16)rDesc.Underline;
+ ((SfxPoolItem*)&aUnderlineItem)->PutValue( aTemp, MID_TL_STYLE );
+ rSet.Put( aUnderlineItem );
+ }
+
+ {
+ SvxWeightItem aWeightItem( (FontWeight)0, EE_CHAR_WEIGHT );
+ aTemp <<= rDesc.Weight;
+ ((SfxPoolItem*)&aWeightItem)->PutValue( aTemp, MID_WEIGHT );
+ rSet.Put( aWeightItem );
+ }
+
+ {
+ SvxCrossedOutItem aCrossedOutItem( (FontStrikeout)0, EE_CHAR_STRIKEOUT );
+ aTemp <<= rDesc.Strikeout;
+ ((SfxPoolItem*)&aCrossedOutItem)->PutValue( aTemp, MID_CROSS_OUT );
+ rSet.Put( aCrossedOutItem );
+ }
+
+ {
+ SvxWordLineModeItem aWLMItem( rDesc.WordLineMode, EE_CHAR_WLM );
+ rSet.Put( aWLMItem );
+ }
+}
+
+void SvxUnoFontDescriptor::FillFromItemSet( const SfxItemSet& rSet, awt::FontDescriptor& rDesc )
+{
+ const SfxPoolItem* pItem = NULL;
+ {
+ SvxFontItem* pFontItem = (SvxFontItem*)&rSet.Get( EE_CHAR_FONTINFO, TRUE );
+ rDesc.Name = pFontItem->GetFamilyName();
+ rDesc.StyleName = pFontItem->GetStyleName();
+ rDesc.Family = sal::static_int_cast< sal_Int16 >(
+ pFontItem->GetFamily());
+ rDesc.CharSet = pFontItem->GetCharSet();
+ rDesc.Pitch = sal::static_int_cast< sal_Int16 >(
+ pFontItem->GetPitch());
+ }
+ {
+ pItem = &rSet.Get( EE_CHAR_FONTHEIGHT, TRUE );
+ uno::Any aHeight;
+ if( pItem->QueryValue( aHeight, MID_FONTHEIGHT ) )
+ aHeight >>= rDesc.Height;
+ }
+ {
+ pItem = &rSet.Get( EE_CHAR_ITALIC, TRUE );
+ uno::Any aFontSlant;
+ if(pItem->QueryValue( aFontSlant, MID_POSTURE ))
+ aFontSlant >>= rDesc.Slant;
+ }
+ {
+ pItem = &rSet.Get( EE_CHAR_UNDERLINE, TRUE );
+ uno::Any aUnderline;
+ if(pItem->QueryValue( aUnderline, MID_TL_STYLE ))
+ aUnderline >>= rDesc.Underline;
+ }
+ {
+ pItem = &rSet.Get( EE_CHAR_WEIGHT, TRUE );
+ uno::Any aWeight;
+ if(pItem->QueryValue( aWeight, MID_WEIGHT ))
+ aWeight >>= rDesc.Weight;
+ }
+ {
+ pItem = &rSet.Get( EE_CHAR_STRIKEOUT, TRUE );
+ uno::Any aStrikeOut;
+ if(pItem->QueryValue( aStrikeOut, MID_CROSS_OUT ))
+ aStrikeOut >>= rDesc.Strikeout;
+ }
+ {
+ SvxWordLineModeItem* pWLMItem = (SvxWordLineModeItem*)&rSet.Get( EE_CHAR_WLM, TRUE );
+ rDesc.WordLineMode = pWLMItem->GetValue();
+ }
+}
+
+#define CheckState( state ) \
+ switch( state ) \
+ { \
+ case SFX_ITEM_DONTCARE: \
+ case SFX_ITEM_DISABLED: \
+ return beans::PropertyState_AMBIGUOUS_VALUE; \
+ case SFX_ITEM_READONLY: \
+ case SFX_ITEM_SET: \
+ return beans::PropertyState_DIRECT_VALUE; \
+ }
+
+beans::PropertyState SvxUnoFontDescriptor::getPropertyState( const SfxItemSet& rSet )
+{
+ CheckState(rSet.GetItemState( EE_CHAR_FONTINFO, FALSE ));
+ CheckState(rSet.GetItemState( EE_CHAR_FONTHEIGHT, FALSE ));
+ CheckState(rSet.GetItemState( EE_CHAR_ITALIC, FALSE ));
+ CheckState(rSet.GetItemState( EE_CHAR_UNDERLINE, FALSE ));
+ CheckState(rSet.GetItemState( EE_CHAR_WEIGHT, FALSE ));
+ CheckState(rSet.GetItemState( EE_CHAR_STRIKEOUT, FALSE ));
+ CheckState(rSet.GetItemState( EE_CHAR_WLM, FALSE ));
+
+ return beans::PropertyState_DEFAULT_VALUE;
+}
+
+void SvxUnoFontDescriptor::setPropertyToDefault( SfxItemSet& rSet )
+{
+ rSet.InvalidateItem( EE_CHAR_FONTINFO );
+ rSet.InvalidateItem( EE_CHAR_FONTHEIGHT );
+ rSet.InvalidateItem( EE_CHAR_ITALIC );
+ rSet.InvalidateItem( EE_CHAR_UNDERLINE );
+ rSet.InvalidateItem( EE_CHAR_WEIGHT );
+ rSet.InvalidateItem( EE_CHAR_STRIKEOUT );
+ rSet.InvalidateItem( EE_CHAR_WLM );
+}
+
+uno::Any SvxUnoFontDescriptor::getPropertyDefault( SfxItemPool* pPool )
+{
+ SfxItemSet aSet( *pPool, EE_CHAR_FONTINFO, EE_CHAR_FONTINFO,
+ EE_CHAR_FONTHEIGHT, EE_CHAR_FONTHEIGHT,
+ EE_CHAR_ITALIC, EE_CHAR_ITALIC,
+ EE_CHAR_UNDERLINE, EE_CHAR_UNDERLINE,
+ EE_CHAR_WEIGHT, EE_CHAR_WEIGHT,
+ EE_CHAR_STRIKEOUT, EE_CHAR_STRIKEOUT,
+ EE_CHAR_WLM, EE_CHAR_WLM, 0 );
+
+ uno::Any aAny;
+
+ if(!pPool->IsWhich(EE_CHAR_FONTINFO)||
+ !pPool->IsWhich(EE_CHAR_FONTHEIGHT)||
+ !pPool->IsWhich(EE_CHAR_ITALIC)||
+ !pPool->IsWhich(EE_CHAR_UNDERLINE)||
+ !pPool->IsWhich(EE_CHAR_WEIGHT)||
+ !pPool->IsWhich(EE_CHAR_STRIKEOUT)||
+ !pPool->IsWhich(EE_CHAR_WLM))
+ return aAny;
+
+ aSet.Put(pPool->GetDefaultItem(EE_CHAR_FONTINFO));
+ aSet.Put(pPool->GetDefaultItem(EE_CHAR_FONTHEIGHT));
+ aSet.Put(pPool->GetDefaultItem(EE_CHAR_ITALIC));
+ aSet.Put(pPool->GetDefaultItem(EE_CHAR_UNDERLINE));
+ aSet.Put(pPool->GetDefaultItem(EE_CHAR_WEIGHT));
+ aSet.Put(pPool->GetDefaultItem(EE_CHAR_STRIKEOUT));
+ aSet.Put(pPool->GetDefaultItem(EE_CHAR_WLM));
+
+ awt::FontDescriptor aDesc;
+
+ FillFromItemSet( aSet, aDesc );
+
+ aAny <<= aDesc;
+
+ return aAny;
+}
+
+
+
diff --git a/editeng/source/uno/unofield.cxx b/editeng/source/uno/unofield.cxx
new file mode 100644
index 0000000000..7f5e1387b1
--- /dev/null
+++ b/editeng/source/uno/unofield.cxx
@@ -0,0 +1,1183 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unofield.cxx,v $
+ * $Revision: 1.31 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/text/FilenameDisplayFormat.hpp>
+#include <com/sun/star/lang/NoSupportException.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <vcl/svapp.hxx>
+#include <vos/mutex.hxx>
+
+#include <rtl/uuid.h>
+#include <rtl/memory.h>
+
+#include <editeng/eeitem.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/svdfield.hxx>
+#include <editeng/unofield.hxx>
+#include <editeng/unotext.hxx>
+#include <comphelper/serviceinfohelper.hxx>
+
+using namespace ::rtl;
+using namespace ::vos;
+using namespace ::cppu;
+using namespace ::com::sun::star;
+
+#define QUERYINT( xint ) \
+ if( rType == ::getCppuType((const uno::Reference< xint >*)0) ) \
+ aAny <<= uno::Reference< xint >(this)
+
+
+#define WID_DATE 0
+#define WID_BOOL1 1
+#define WID_BOOL2 2
+#define WID_INT32 3
+#define WID_INT16 4
+#define WID_STRING1 5
+#define WID_STRING2 6
+#define WID_STRING3 7
+
+class SvxUnoFieldData_Impl
+{
+public:
+ sal_Bool mbBoolean1;
+ sal_Bool mbBoolean2;
+ sal_Int32 mnInt32;
+ sal_Int16 mnInt16;
+ OUString msString1;
+ OUString msString2;
+ OUString msString3;
+ util::DateTime maDateTime;
+
+ OUString msPresentation;
+};
+
+const SfxItemPropertySet* ImplGetFieldItemPropertySet( sal_Int32 mnId )
+{
+ static SfxItemPropertyMapEntry aExDateTimeFieldPropertyMap_Impl[] =
+ {
+ { MAP_CHAR_LEN("DateTime"), WID_DATE, &::getCppuType((const util::DateTime*)0), 0, 0 },
+ { MAP_CHAR_LEN("IsFixed"), WID_BOOL1, &::getBooleanCppuType(), 0, 0 },
+ { MAP_CHAR_LEN("IsDate"), WID_BOOL2, &::getBooleanCppuType(), 0, 0 },
+ { MAP_CHAR_LEN("NumberFormat"), WID_INT32, &::getCppuType((const sal_Int16*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertySet aExDateTimeFieldPropertySet_Impl(aExDateTimeFieldPropertyMap_Impl);
+
+ static SfxItemPropertyMapEntry aDateTimeFieldPropertyMap_Impl[] =
+ {
+ { MAP_CHAR_LEN("IsDate"), WID_BOOL2, &::getBooleanCppuType(), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertySet aDateTimeFieldPropertySet_Impl(aDateTimeFieldPropertyMap_Impl);
+
+ static SfxItemPropertyMapEntry aUrlFieldPropertyMap_Impl[] =
+ {
+
+ { MAP_CHAR_LEN("Format"), WID_INT16, &::getCppuType((const sal_Int16*)0), 0, 0 },
+ { MAP_CHAR_LEN("Representation"), WID_STRING1, &::getCppuType((const OUString*)0), 0, 0 },
+ { MAP_CHAR_LEN("TargetFrame"), WID_STRING2, &::getCppuType((const OUString*)0), 0, 0 },
+ { MAP_CHAR_LEN("URL"), WID_STRING3, &::getCppuType((const OUString*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertySet aUrlFieldPropertySet_Impl(aUrlFieldPropertyMap_Impl);
+
+ static SfxItemPropertyMapEntry aEmptyPropertyMap_Impl[] =
+ {
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertySet aEmptyPropertySet_Impl(aEmptyPropertyMap_Impl);
+
+ static SfxItemPropertyMapEntry aExtFileFieldPropertyMap_Impl[] =
+ {
+ { MAP_CHAR_LEN("IsFixed"), WID_BOOL1, &::getBooleanCppuType(), 0, 0 },
+ { MAP_CHAR_LEN("FileFormat"), WID_INT16, &::getCppuType((const sal_Int16*)0), 0, 0 },
+ { MAP_CHAR_LEN("CurrentPresentation"), WID_STRING1,&::getCppuType((const OUString*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertySet aExtFileFieldPropertySet_Impl(aExtFileFieldPropertyMap_Impl);
+
+ static SfxItemPropertyMapEntry aAuthorFieldPropertyMap_Impl[] =
+ {
+ { MAP_CHAR_LEN("IsFixed"), WID_BOOL1, &::getBooleanCppuType(), 0, 0 },
+ { MAP_CHAR_LEN("CurrentPresentation"), WID_STRING1,&::getCppuType((const OUString*)0), 0, 0 },
+ { MAP_CHAR_LEN("Content"), WID_STRING2,&::getCppuType((const OUString*)0), 0, 0 },
+ { MAP_CHAR_LEN("AuthorFormat"), WID_INT16, &::getCppuType((const sal_Int16*)0), 0, 0 },
+ { MAP_CHAR_LEN("FullName"), WID_BOOL2, &::getBooleanCppuType(), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertySet aAuthorFieldPropertySet_Impl(aAuthorFieldPropertyMap_Impl);
+
+ static SfxItemPropertyMapEntry aMeasureFieldPropertyMap_Impl[] =
+ {
+ { MAP_CHAR_LEN("Kind"), WID_INT16, &::getCppuType((const sal_Int16*)0), 0, 0 },
+ {0,0,0,0,0,0}
+ };
+ static SfxItemPropertySet aMeasureFieldPropertySet_Impl(aMeasureFieldPropertyMap_Impl);
+
+ switch( mnId )
+ {
+ case ID_EXT_DATEFIELD:
+ case ID_EXT_TIMEFIELD:
+ return &aExDateTimeFieldPropertySet_Impl;
+ case ID_URLFIELD:
+ return &aUrlFieldPropertySet_Impl;
+ case ID_DATEFIELD:
+ case ID_TIMEFIELD:
+ return &aDateTimeFieldPropertySet_Impl;
+ case ID_EXT_FILEFIELD:
+ return &aExtFileFieldPropertySet_Impl;
+ case ID_AUTHORFIELD:
+ return &aAuthorFieldPropertySet_Impl;
+ case ID_MEASUREFIELD:
+ return &aMeasureFieldPropertySet_Impl;
+// case ID_PAGEFIELD:
+// case ID_PAGESFIELD:
+// case ID_FILEFIELD:
+// case ID_TABLEFIELD:
+// case ID_HEADERFIELD:
+// case ID_FOOTERFIELD:
+// case ID_DATETIMEFIELD::
+ default:
+ return &aEmptyPropertySet_Impl;
+ }
+}
+
+static sal_Char const* aFieldItemNameMap_Impl[] =
+{
+ "Date",
+ "URL",
+ "Page",
+ "Pages",
+ "Time",
+ "File",
+ "Table",
+ "ExtTime",
+ "ExtFile",
+ "Author",
+ "Measure",
+ "ExtDate",
+ "Header",
+ "Footer",
+ "DateTime",
+ "Unknown"
+};
+
+/* conversion routines */
+
+static sal_Int16 getFileNameDisplayFormat( SvxFileFormat nFormat )
+{
+ switch( nFormat )
+ {
+ case SVXFILEFORMAT_NAME_EXT: return text::FilenameDisplayFormat::NAME_AND_EXT;
+ case SVXFILEFORMAT_FULLPATH: return text::FilenameDisplayFormat::FULL;
+ case SVXFILEFORMAT_PATH: return text::FilenameDisplayFormat::PATH;
+// case SVXFILEFORMAT_NAME:
+ default: return text::FilenameDisplayFormat::NAME;
+ }
+}
+
+static SvxFileFormat setFileNameDisplayFormat( sal_Int16 nFormat )
+{
+ switch( nFormat )
+ {
+ case text::FilenameDisplayFormat::FULL: return SVXFILEFORMAT_FULLPATH;
+ case text::FilenameDisplayFormat::PATH: return SVXFILEFORMAT_PATH;
+ case text::FilenameDisplayFormat::NAME: return SVXFILEFORMAT_NAME;
+// case text::FilenameDisplayFormat::NAME_AND_EXT:
+ default:
+ return SVXFILEFORMAT_NAME_EXT;
+ }
+}
+
+static util::DateTime getDate( ULONG nDate )
+{
+ util::DateTime aDate;
+ memset( &aDate, 0, sizeof( util::DateTime ) );
+
+ Date aTempDate( nDate );
+
+ aDate.Day = aTempDate.GetDay();
+ aDate.Month = aTempDate.GetMonth();
+ aDate.Year = aTempDate.GetYear();
+
+ return aDate;
+}
+
+inline Date setDate( util::DateTime& rDate )
+{
+ return Date( rDate.Day, rDate.Month, rDate.Year );
+}
+
+static util::DateTime getTime( long nTime )
+{
+ util::DateTime aTime;
+ memset( &aTime, 0, sizeof( util::DateTime ) );
+
+ Time aTempTime( nTime );
+
+ aTime.HundredthSeconds = aTempTime.Get100Sec();
+ aTime.Seconds = aTempTime.GetSec();
+ aTime.Minutes = aTempTime.GetMin();
+ aTime.Hours = aTempTime.GetHour();
+
+ return aTime;
+}
+
+inline Time setTime( util::DateTime& rDate )
+{
+ return Time( rDate.Hours, rDate.Minutes, rDate.Seconds, rDate.HundredthSeconds );
+}
+
+// ====================================================================
+// class SvxUnoTextField
+// ====================================================================
+UNO3_GETIMPLEMENTATION_IMPL( SvxUnoTextField );
+
+SvxUnoTextField::SvxUnoTextField( sal_Int32 nServiceId ) throw()
+: OComponentHelper( getMutex() )
+, mpPropSet(NULL)
+, mnServiceId(nServiceId)
+, mpImpl( new SvxUnoFieldData_Impl )
+{
+ mpPropSet = ImplGetFieldItemPropertySet(mnServiceId);
+
+ memset( &(mpImpl->maDateTime), 0, sizeof( util::DateTime ) );
+
+ switch( nServiceId )
+ {
+ case ID_EXT_DATEFIELD:
+ case ID_DATEFIELD:
+ mpImpl->mbBoolean2 = sal_True;
+ mpImpl->mnInt32 = SVXDATEFORMAT_STDSMALL;
+ mpImpl->mbBoolean1 = sal_False;
+ break;
+
+ case ID_EXT_TIMEFIELD:
+ case ID_TIMEFIELD:
+ mpImpl->mbBoolean2 = sal_False;
+ mpImpl->mbBoolean1 = sal_False;
+ mpImpl->mnInt32 = SVXTIMEFORMAT_STANDARD;
+ break;
+
+ case ID_URLFIELD:
+ mpImpl->mnInt16 = SVXURLFORMAT_REPR;
+ break;
+
+ case ID_EXT_FILEFIELD:
+ mpImpl->mbBoolean1 = sal_False;
+ mpImpl->mnInt16 = text::FilenameDisplayFormat::FULL;
+ break;
+
+ case ID_AUTHORFIELD:
+ mpImpl->mnInt16 = SVXAUTHORFORMAT_FULLNAME;
+ mpImpl->mbBoolean1 = sal_False;
+ mpImpl->mbBoolean2 = sal_True;
+ break;
+
+ case ID_MEASUREFIELD:
+ mpImpl->mnInt16 = SDRMEASUREFIELD_VALUE;
+ break;
+
+ default:
+ mpImpl->mbBoolean1 = sal_False;
+ mpImpl->mbBoolean2 = sal_False;
+ mpImpl->mnInt32 = 0;
+ mpImpl->mnInt16 = 0;
+
+ }
+}
+
+SvxUnoTextField::SvxUnoTextField( uno::Reference< text::XTextRange > xAnchor, const OUString& rPresentation, const SvxFieldData* pData ) throw()
+: OComponentHelper( getMutex() )
+, mxAnchor( xAnchor )
+, mpPropSet(NULL)
+, mnServiceId(ID_UNKNOWN)
+, mpImpl( new SvxUnoFieldData_Impl )
+{
+ DBG_ASSERT(pData, "pFieldData == NULL! [CL]" );
+
+ mpImpl->msPresentation = rPresentation;
+
+ if(pData)
+ {
+ mnServiceId = GetFieldId(pData);
+ DBG_ASSERT(mnServiceId != ID_UNKNOWN, "unknown SvxFieldData! [CL]");
+ if(mnServiceId != ID_UNKNOWN)
+ {
+ // extract field properties from data class
+ switch( mnServiceId )
+ {
+ case ID_DATEFIELD:
+ case ID_EXT_DATEFIELD:
+ {
+ mpImpl->mbBoolean2 = sal_True;
+ // #i35416# for variable date field, don't use invalid "0000-00-00" date,
+ // use current date instead
+ sal_Bool bFixed = ((SvxDateField*)pData)->GetType() == SVXDATETYPE_FIX;
+ mpImpl->maDateTime = getDate( bFixed ?
+ ((SvxDateField*)pData)->GetFixDate() :
+ Date().GetDate() );
+ mpImpl->mnInt32 = ((SvxDateField*)pData)->GetFormat();
+ mpImpl->mbBoolean1 = bFixed;
+ }
+ break;
+
+ case ID_TIMEFIELD:
+ mpImpl->mbBoolean2 = sal_False;
+ mpImpl->mbBoolean1 = sal_False;
+ mpImpl->mnInt32 = SVXTIMEFORMAT_STANDARD;
+ break;
+
+ case ID_EXT_TIMEFIELD:
+ mpImpl->mbBoolean2 = sal_False;
+ mpImpl->maDateTime = getTime( ((SvxExtTimeField*)pData)->GetFixTime() );
+ mpImpl->mbBoolean1 = ((SvxExtTimeField*)pData)->GetType() == SVXTIMETYPE_FIX;
+ mpImpl->mnInt32 = ((SvxExtTimeField*)pData)->GetFormat();
+ break;
+
+ case ID_URLFIELD:
+ mpImpl->msString1 = ((SvxURLField*)pData)->GetRepresentation();
+ mpImpl->msString2 = ((SvxURLField*)pData)->GetTargetFrame();
+ mpImpl->msString3 = ((SvxURLField*)pData)->GetURL();
+ mpImpl->mnInt16 = sal::static_int_cast< sal_Int16 >(
+ ((SvxURLField*)pData)->GetFormat());
+ break;
+
+ case ID_EXT_FILEFIELD:
+ mpImpl->msString1 = ((SvxExtFileField*)pData)->GetFile();
+ mpImpl->mbBoolean1 = ((SvxExtFileField*)pData)->GetType() == SVXFILETYPE_FIX;
+ mpImpl->mnInt16 = getFileNameDisplayFormat(((SvxExtFileField*)pData)->GetFormat());
+ break;
+
+ case ID_AUTHORFIELD:
+ mpImpl->msString1 = ((SvxAuthorField*)pData)->GetFormatted();
+ mpImpl->msString2 = ((SvxAuthorField*)pData)->GetFormatted();
+ mpImpl->mnInt16 = sal::static_int_cast< sal_Int16 >(
+ ((SvxAuthorField*)pData)->GetFormat());
+ mpImpl->mbBoolean1 = ((SvxAuthorField*)pData)->GetType() == SVXAUTHORTYPE_FIX;
+ mpImpl->mbBoolean2 = ((SvxAuthorField*)pData)->GetFormat() != SVXAUTHORFORMAT_SHORTNAME;
+ break;
+
+ case ID_MEASUREFIELD:
+ mpImpl->mnInt16 = sal::static_int_cast< sal_Int16 >(((SdrMeasureField*)pData)->GetMeasureFieldKind());
+ break;
+ }
+ }
+ }
+
+ mpPropSet = ImplGetFieldItemPropertySet(mnServiceId);
+}
+
+SvxUnoTextField::~SvxUnoTextField() throw()
+{
+ delete mpImpl;
+}
+
+SvxFieldData* SvxUnoTextField::CreateFieldData() const throw()
+{
+ SvxFieldData* pData = NULL;
+
+ switch( mnServiceId )
+ {
+ case ID_TIMEFIELD:
+ case ID_EXT_TIMEFIELD:
+ case ID_DATEFIELD:
+ case ID_EXT_DATEFIELD:
+ {
+ if( mpImpl->mbBoolean2 ) // IsDate?
+ {
+ Date aDate( setDate( mpImpl->maDateTime ) );
+ pData = new SvxDateField( aDate, mpImpl->mbBoolean1?SVXDATETYPE_FIX:SVXDATETYPE_VAR );
+ if( mpImpl->mnInt32 >= SVXDATEFORMAT_APPDEFAULT && mpImpl->mnInt32 <= SVXDATEFORMAT_F )
+ ((SvxDateField*)pData)->SetFormat( (SvxDateFormat)mpImpl->mnInt32 );
+ }
+ else
+ {
+ if( mnServiceId != ID_TIMEFIELD && mnServiceId != ID_DATEFIELD )
+ {
+ Time aTime( setTime( mpImpl->maDateTime ) );
+ pData = new SvxExtTimeField( aTime, mpImpl->mbBoolean1?SVXTIMETYPE_FIX:SVXTIMETYPE_VAR );
+
+ if( mpImpl->mnInt32 >= SVXTIMEFORMAT_APPDEFAULT && mpImpl->mnInt32 <= SVXTIMEFORMAT_AM_HMSH )
+ ((SvxExtTimeField*)pData)->SetFormat( (SvxTimeFormat)mpImpl->mnInt32 );
+ }
+ else
+ {
+ pData = new SvxTimeField();
+ }
+ }
+
+ }
+ break;
+
+ case ID_URLFIELD:
+ pData = new SvxURLField( mpImpl->msString3, mpImpl->msString1, mpImpl->msString1.getLength() ? SVXURLFORMAT_REPR : SVXURLFORMAT_URL );
+ ((SvxURLField*)pData)->SetTargetFrame( mpImpl->msString2 );
+ if( mpImpl->mnInt16 >= SVXURLFORMAT_APPDEFAULT && mpImpl->mnInt16 <= SVXURLFORMAT_REPR )
+ ((SvxURLField*)pData)->SetFormat( (SvxURLFormat)mpImpl->mnInt16 );
+ break;
+
+ case ID_PAGEFIELD:
+ pData = new SvxPageField();
+ break;
+
+ case ID_PAGESFIELD:
+ pData = new SvxPagesField();
+ break;
+
+ case ID_FILEFIELD:
+ pData = new SvxFileField();
+ break;
+
+ case ID_TABLEFIELD:
+ pData = new SvxTableField();
+ break;
+
+ case ID_EXT_FILEFIELD:
+ {
+ // #92009# pass fixed attribute to constructor
+ pData = new SvxExtFileField( mpImpl->msString1,
+ mpImpl->mbBoolean1 ? SVXFILETYPE_FIX : SVXFILETYPE_VAR,
+ setFileNameDisplayFormat(mpImpl->mnInt16 ) );
+ break;
+ }
+
+ case ID_AUTHORFIELD:
+ {
+ ::rtl::OUString aContent;
+ String aFirstName;
+ String aLastName;
+ String aEmpty;
+
+ // do we have CurrentPresentation given?
+ // mimic behaviour of writer, which means:
+ // prefer CurrentPresentation over Content
+ // if both are given.
+ if( mpImpl->msString1.getLength() )
+ aContent = mpImpl->msString1;
+ else
+ aContent = mpImpl->msString2;
+
+ sal_Int32 nPos = aContent.lastIndexOf( sal_Char(' '), 0 );
+ if( nPos > 0 )
+ {
+ aFirstName = aContent.copy( 0, nPos );
+ aLastName = aContent.copy( nPos + 1 );
+ }
+ else
+ {
+ aLastName = aContent;
+ }
+
+ // #92009# pass fixed attribute to constructor
+ pData = new SvxAuthorField( aFirstName, aLastName, aEmpty,
+ mpImpl->mbBoolean1 ? SVXAUTHORTYPE_FIX : SVXAUTHORTYPE_VAR );
+
+ if( !mpImpl->mbBoolean2 )
+ {
+ ((SvxAuthorField*)pData)->SetFormat( SVXAUTHORFORMAT_SHORTNAME );
+ }
+ else if( mpImpl->mnInt16 >= SVXAUTHORFORMAT_FULLNAME || mpImpl->mnInt16 <= SVXAUTHORFORMAT_SHORTNAME )
+ {
+ ((SvxAuthorField*)pData)->SetFormat( (SvxAuthorFormat) mpImpl->mnInt16 );
+ }
+
+ break;
+ }
+
+ case ID_MEASUREFIELD:
+ {
+ SdrMeasureFieldKind eKind = SDRMEASUREFIELD_VALUE;
+ if( mpImpl->mnInt16 == (sal_Int16)SDRMEASUREFIELD_UNIT || mpImpl->mnInt16 == (sal_Int16)SDRMEASUREFIELD_ROTA90BLANCS )
+ eKind = (SdrMeasureFieldKind) mpImpl->mnInt16;
+ pData = new SdrMeasureField( eKind);
+ break;
+ }
+ case ID_HEADERFIELD:
+ pData = new SvxHeaderField();
+ break;
+ case ID_FOOTERFIELD:
+ pData = new SvxFooterField();
+ break;
+ case ID_DATETIMEFIELD:
+ pData = new SvxDateTimeField();
+ break;
+ };
+
+ return pData;
+}
+
+// uno::XInterface
+uno::Any SAL_CALL SvxUnoTextField::queryAggregation( const uno::Type & rType )
+ throw(uno::RuntimeException)
+{
+ uno::Any aAny;
+
+ QUERYINT( beans::XPropertySet );
+ else QUERYINT( text::XTextContent );
+ else QUERYINT( text::XTextField );
+ else QUERYINT( lang::XServiceInfo );
+ else QUERYINT( lang::XUnoTunnel );
+ else
+ return OComponentHelper::queryAggregation( rType );
+
+ return aAny;
+}
+
+// XTypeProvider
+
+uno::Sequence< uno::Type > SAL_CALL SvxUnoTextField::getTypes()
+ throw (uno::RuntimeException)
+{
+ if( maTypeSequence.getLength() == 0 )
+ {
+ maTypeSequence = OComponentHelper::getTypes();
+ sal_Int32 nOldCount = maTypeSequence.getLength();
+
+ maTypeSequence.realloc( nOldCount + 4 ); // !DANGER! keep this updated
+ uno::Type* pTypes = &maTypeSequence.getArray()[nOldCount];
+
+ *pTypes++ = ::getCppuType(( const uno::Reference< text::XTextField >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< beans::XPropertySet >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< lang::XServiceInfo >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< lang::XUnoTunnel >*)0);
+ }
+ return maTypeSequence;
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL SvxUnoTextField::getImplementationId()
+ throw (uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+uno::Any SAL_CALL SvxUnoTextField::queryInterface( const uno::Type & rType )
+ throw(uno::RuntimeException)
+{
+ return OComponentHelper::queryInterface(rType);
+}
+
+void SAL_CALL SvxUnoTextField::acquire() throw( )
+{
+ OComponentHelper::acquire();
+}
+
+void SAL_CALL SvxUnoTextField::release() throw( )
+{
+ OComponentHelper::release();
+}
+
+// Interface text::XTextField
+OUString SAL_CALL SvxUnoTextField::getPresentation( sal_Bool bShowCommand )
+ throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if(bShowCommand)
+ {
+ DBG_ASSERT( ((sal_uInt32)mnServiceId) < ID_UNKNOWN, "Unknown field type" );
+ return OUString::createFromAscii( aFieldItemNameMap_Impl[(((sal_uInt32)mnServiceId) > ID_UNKNOWN)? ID_UNKNOWN : mnServiceId ] );
+ }
+ else
+ {
+ return mpImpl->msPresentation;
+ }
+}
+
+// Interface text::XTextContent
+void SAL_CALL SvxUnoTextField::attach( const uno::Reference< text::XTextRange >& xTextRange )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ SvxUnoTextRangeBase* pRange = SvxUnoTextRange::getImplementation( xTextRange );
+ if(pRange == NULL)
+ throw lang::IllegalArgumentException();
+
+ SvxFieldData* pData = CreateFieldData();
+ if( pData )
+ pRange->attachField( pData );
+
+ delete pData;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextField::getAnchor()
+ throw(uno::RuntimeException)
+{
+ return mxAnchor;
+}
+
+// lang::XComponent
+void SAL_CALL SvxUnoTextField::dispose()
+ throw(uno::RuntimeException)
+{
+ OComponentHelper::dispose();
+}
+
+void SAL_CALL SvxUnoTextField::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ OComponentHelper::addEventListener(xListener);
+}
+
+void SAL_CALL SvxUnoTextField::removeEventListener( const uno::Reference< lang::XEventListener >& aListener )
+ throw(uno::RuntimeException)
+{
+ OComponentHelper::removeEventListener(aListener);
+}
+
+
+// Interface beans::XPropertySet
+uno::Reference< beans::XPropertySetInfo > SAL_CALL SvxUnoTextField::getPropertySetInfo( )
+ throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ return mpPropSet->getPropertySetInfo();
+}
+
+void SAL_CALL SvxUnoTextField::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if( mpImpl == NULL )
+ throw uno::RuntimeException();
+
+ const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMap()->getByName( aPropertyName );
+ if ( !pMap )
+ throw beans::UnknownPropertyException();
+
+ switch( pMap->nWID )
+ {
+ case WID_DATE:
+ if(aValue >>= mpImpl->maDateTime)
+ return;
+ break;
+ case WID_BOOL1:
+ if(aValue >>= mpImpl->mbBoolean1)
+ return;
+ break;
+ case WID_BOOL2:
+ if(aValue >>= mpImpl->mbBoolean2)
+ return;
+ break;
+ case WID_INT16:
+ if(aValue >>= mpImpl->mnInt16)
+ return;
+ break;
+ case WID_INT32:
+ if(aValue >>= mpImpl->mnInt32)
+ return;
+ break;
+ case WID_STRING1:
+ if(aValue >>= mpImpl->msString1)
+ return;
+ break;
+ case WID_STRING2:
+ if(aValue >>= mpImpl->msString2)
+ return;
+ break;
+ case WID_STRING3:
+ if(aValue >>= mpImpl->msString3)
+ return;
+ break;
+ }
+
+ throw lang::IllegalArgumentException();
+
+/*
+ case WID_FORMAT:
+ {
+ sal_Int32 nFormat;
+
+ switch( mnId )
+ {
+ case ID_DATEFIELD:
+ {
+ SvxDateField* pDate = PTR_CAST( SvxDateField, aFieldItem.GetField() );
+ if(pDate)
+ pDate->SetFormat( (SvxDateFormat)nFormat );
+ break;
+ }
+ case ID_URLFIELD:
+ {
+ SvxURLField* pURL = PTR_CAST( SvxURLField, aFieldItem.GetField() );
+ if(pURL)
+ pURL->SetFormat( (SvxURLFormat)nFormat );
+ break;
+ }
+ case ID_EXT_TIMEFIELD:
+ {
+ SvxExtTimeField* pTime = PTR_CAST( SvxExtTimeField, aFieldItem.GetField() );
+ if(pTime)
+ pTime->SetFormat( (SvxTimeFormat)nFormat );
+ break;
+ }
+ case ID_EXT_FILEFIELD:
+ {
+ SvxExtFileField* pFile = PTR_CAST( SvxExtFileField, aFieldItem.GetField() );
+ if(pFile)
+ pFile->SetFormat( (SvxFileFormat)nFormat );
+ break;
+ }
+ case ID_AUTHORFIELD:
+ {
+ SvxAuthorField* pAuthor = PTR_CAST( SvxAuthorField, aFieldItem.GetField() );
+ if(pAuthor)
+ pAuthor->SetFormat( (SvxAuthorFormat)nFormat );
+ break;
+ }
+ default:
+ throw beans::UnknownPropertyException();
+ }
+ }
+ break;
+ case WID_FIX:
+ {
+ if( aValue.hasValue() || aValue.getValueType() != ::getCppuBooleanType() )
+ throw lang::IllegalArgumentException();
+ sal_Bool bFix( *(sal_Bool*)aValue.getValue() );
+ switch( mnId )
+ {
+ case ID_EXT_TIMEFIELD:
+ {
+ SvxExtTimeField* pTime = PTR_CAST( SvxExtTimeField, aFieldItem.GetField() );
+ if(pTime)
+ pTime->SetType( (SvxTimeType)bFix?SVXTIMETYPE_FIX:SVXTIMETYPE_VAR );
+ break;
+ }
+ case ID_DATEFIELD:
+ {
+ SvxDateField* pDate = PTR_CAST( SvxDateField, aFieldItem.GetField() );
+ if(pDate)
+ pDate->SetType( (SvxDateType)bFix?SVXDATETYPE_FIX:SVXDATETYPE_VAR );
+ break;
+ }
+ case ID_EXT_FILEFIELD:
+ {
+ SvxExtFileField* pFile = PTR_CAST( SvxExtFileField, aFieldItem.GetField() );
+ if(pFile)
+ pFile->SetType( (SvxFileType)bFix?SVXFILETYPE_FIX:SVXFILETYPE_VAR );
+ break;
+ }
+ case ID_AUTHORFIELD:
+ {
+ SvxAuthorField* pAuthor = PTR_CAST( SvxAuthorField, aFieldItem.GetField() );
+ if(pAuthor)
+ pAuthor->SetType( (SvxAuthorType)bFix?SVXAUTHORTYPE_FIX:SVXAUTHORTYPE_VAR );
+ break;
+ }
+ default:
+ throw beans::UnknownPropertyException();
+ }
+ }
+ break;
+ case WID_PRES:
+ case WID_URL:
+ case WID_TARGET:
+ {
+ SvxURLField* pURL = PTR_CAST( SvxURLField, aFieldItem.GetField() );
+ if(pURL)
+ {
+ OUString aUnoStr;
+ if(!(aValue >>= aUnoStr))
+ throw lang::IllegalArgumentException();
+
+ switch( pMap->nWID )
+ {
+ case WID_PRES:
+ pURL->SetRepresentation( aUnoStr );
+ break;
+ case WID_URL:
+ pURL->SetURL( aUnoStr );
+ break;
+ case WID_TARGET:
+ pURL->SetTargetFrame( aUnoStr );
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ SfxItemSet aSet = pForwarder->GetAttribs( GetSelection() );
+ aSet.Put( aFieldItem );
+*/
+}
+
+uno::Any SAL_CALL SvxUnoTextField::getPropertyValue( const OUString& PropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ uno::Any aValue;
+
+ const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMap()->getByName( PropertyName );
+ if ( !pMap )
+ throw beans::UnknownPropertyException();
+
+ switch( pMap->nWID )
+ {
+ case WID_DATE:
+ aValue <<= mpImpl->maDateTime;
+ break;
+ case WID_BOOL1:
+ aValue <<= mpImpl->mbBoolean1;
+ break;
+ case WID_BOOL2:
+ aValue <<= mpImpl->mbBoolean2;
+ break;
+ case WID_INT16:
+ aValue <<= mpImpl->mnInt16;
+ break;
+ case WID_INT32:
+ aValue <<= mpImpl->mnInt32;
+ break;
+ case WID_STRING1:
+ aValue <<= mpImpl->msString1;
+ break;
+ case WID_STRING2:
+ aValue <<= mpImpl->msString2;
+ break;
+ case WID_STRING3:
+ aValue <<= mpImpl->msString3;
+ break;
+ }
+
+ return aValue;
+
+/*
+ switch(pMap->nWID)
+ {
+ case WID_FORMAT:
+ switch( mnId )
+ {
+ case ID_DATEFIELD:
+ {
+ SvxDateField* pDate = PTR_CAST( SvxDateField, pFieldItem->GetField() );
+ if(pDate)
+ aValue <<= (sal_Int32)pDate->GetFormat();
+ break;
+ }
+ case ID_URLFIELD:
+ {
+ SvxURLField* pURL = PTR_CAST( SvxURLField, pFieldItem->GetField() );
+ if(pURL)
+ aValue <<= (sal_Int32)pURL->GetFormat();
+ break;
+ }
+ case ID_EXT_TIMEFIELD:
+ {
+ SvxExtTimeField* pTime = PTR_CAST( SvxExtTimeField, pFieldItem->GetField() );
+ if(pTime)
+ aValue <<= (sal_Int32)pTime->GetFormat();
+ break;
+ }
+ case ID_EXT_FILEFIELD:
+ {
+ SvxExtFileField* pFile = PTR_CAST( SvxExtFileField, pFieldItem->GetField() );
+ if(pFile)
+ aValue <<= (sal_Int32)pFile->GetFormat();
+ break;
+ }
+ case ID_AUTHORFIELD:
+ {
+ SvxAuthorField* pAuthor = PTR_CAST( SvxAuthorField, pFieldItem->GetField() );
+ if(pAuthor)
+ aValue <<= (sal_Int32)pAuthor->GetFormat();
+ break;
+ }
+ default:
+ throw beans::UnknownPropertyException();
+ }
+ break;
+ case WID_FIX:
+ {
+ sal_Bool bFix = sal_False;
+ switch( mnId )
+ {
+ case ID_EXT_TIMEFIELD:
+ {
+ SvxExtTimeField* pTime = PTR_CAST( SvxExtTimeField, pFieldItem->GetField() );
+ if(pTime)
+ bFix = pTime->GetType() == SVXTIMETYPE_FIX;
+ break;
+ }
+ case ID_DATEFIELD:
+ {
+ SvxDateField* pDate = PTR_CAST( SvxDateField, pFieldItem->GetField() );
+ if(pDate)
+ bFix = pDate->GetType() == SVXDATETYPE_FIX;
+ break;
+ }
+ case ID_EXT_FILEFIELD:
+ {
+ SvxExtFileField* pFile = PTR_CAST( SvxExtFileField, pFieldItem->GetField() );
+ if(pFile)
+ bFix = pFile->GetType() == SVXFILETYPE_FIX;
+ break;
+ }
+ case ID_AUTHORFIELD:
+ {
+ SvxAuthorField* pAuthor = PTR_CAST( SvxAuthorField, pFieldItem->GetField() );
+ if(pAuthor)
+ bFix = pAuthor->GetType() == SVXAUTHORTYPE_FIX;
+ break;
+ }
+ default:
+ throw beans::UnknownPropertyException();
+ }
+ aValue.setValue( &bFix, ::getCppuBooleanType() );
+ }
+ break;
+ case WID_PRES:
+ case WID_URL:
+ case WID_TARGET:
+ {
+ SvxURLField* pURL = PTR_CAST( SvxURLField, pFieldItem->GetField() );
+ if(pURL)
+ {
+ OUString aStr;
+ switch( pMap->nWID )
+ {
+ case WID_PRES:
+ aStr = pURL->GetRepresentation();
+ break;
+ case WID_URL:
+ aStr = pURL->GetURL();
+ break;
+ case WID_TARGET:
+ aStr = pURL->GetTargetFrame();
+ break;
+ }
+ aValue <<= aStr;
+ }
+ break;
+ }
+ case WID_FCOLOR:
+ case WID_TCOLOR:
+ {
+ Color* pFColor = NULL;
+ Color* pTColor = NULL;
+ const ESelection aSel = GetSelection();
+
+ pForwarder->CalcFieldValue( *pFieldItem, aSel.nStartPara, aSel.nStartPos, pTColor, pFColor );
+
+ if( pMap->nWID == WID_FCOLOR )
+ aValue <<= (sal_Int32)pFColor->GetColor();
+ else
+ aValue <<= (sal_Int32)pTColor->GetColor();
+ break;
+
+ delete pTColor;
+ delete pFColor;
+ }
+ }
+ return aValue;
+*/
+}
+
+void SAL_CALL SvxUnoTextField::addPropertyChangeListener( const OUString&, const uno::Reference< beans::XPropertyChangeListener >& ) throw(::com::sun::star::beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) {}
+void SAL_CALL SvxUnoTextField::removePropertyChangeListener( const OUString&, const uno::Reference< beans::XPropertyChangeListener >& ) throw(::com::sun::star::beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) {}
+void SAL_CALL SvxUnoTextField::addVetoableChangeListener( const OUString&, const uno::Reference< beans::XVetoableChangeListener >& ) throw(::com::sun::star::beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) {}
+void SAL_CALL SvxUnoTextField::removeVetoableChangeListener( const OUString&, const uno::Reference< beans::XVetoableChangeListener >& ) throw(::com::sun::star::beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) {}
+
+// OComponentHelper
+void SvxUnoTextField::disposing()
+{
+ // nothing to do
+}
+
+sal_Int32 SvxUnoTextField::GetFieldId( const SvxFieldData* pFieldData ) const throw()
+{
+ if( pFieldData->ISA( SvxURLField ) )
+ return ID_URLFIELD;
+ else if( pFieldData->ISA( SvxPageField ) )
+ return ID_PAGEFIELD;
+ else if( pFieldData->ISA( SvxPagesField ) )
+ return ID_PAGESFIELD;
+ else if( pFieldData->ISA( SvxTimeField ) )
+ return ID_TIMEFIELD;
+ else if( pFieldData->ISA( SvxFileField ) )
+ return ID_FILEFIELD;
+ else if( pFieldData->ISA( SvxTableField ) )
+ return ID_TABLEFIELD;
+ else if( pFieldData->ISA( SvxExtTimeField ) )
+ return ID_EXT_TIMEFIELD;
+ else if( pFieldData->ISA( SvxExtFileField ) )
+ return ID_EXT_FILEFIELD;
+ else if( pFieldData->ISA( SvxAuthorField ) )
+ return ID_AUTHORFIELD;
+ else if( pFieldData->ISA( SvxDateField ) )
+ return ID_EXT_DATEFIELD;
+ else if( pFieldData->ISA( SdrMeasureField ) )
+ return ID_MEASUREFIELD;
+ else if( pFieldData->ISA( SvxHeaderField ) )
+ return ID_HEADERFIELD;
+ else if( pFieldData->ISA( SvxFooterField ) )
+ return ID_FOOTERFIELD;
+ else if( pFieldData->ISA( SvxDateTimeField ) )
+ return ID_DATETIMEFIELD;
+
+ return ID_UNKNOWN;
+}
+
+// lang::XServiceInfo
+OUString SAL_CALL SvxUnoTextField::getImplementationName() throw(uno::RuntimeException)
+{
+ return OUString(RTL_CONSTASCII_USTRINGPARAM("SvxUnoTextField"));
+}
+
+static const sal_Char* pOldServiceNames[] =
+{
+ "com.sun.star.text.TextField.DateTime",
+ "com.sun.star.text.TextField.URL",
+ "com.sun.star.text.TextField.PageNumber",
+ "com.sun.star.text.TextField.PageCount",
+ "com.sun.star.text.TextField.DateTime",
+ "com.sun.star.text.TextField.DocInfo.Title", // SvxFileField is used for title
+ "com.sun.star.text.TextField.SheetName",
+ "com.sun.star.text.TextField.DateTime",
+ "com.sun.star.text.TextField.FileName",
+ "com.sun.star.text.TextField.Author",
+ "com.sun.star.text.TextField.Measure",
+ "com.sun.star.text.TextField.DateTime",
+ "com.sun.star.presentation.TextField.Header",
+ "com.sun.star.presentation.TextField.Footer",
+ "com.sun.star.presentation.TextField.DateTime"
+};
+
+static const sal_Char* pNewServiceNames[] =
+{
+ "com.sun.star.text.textfield.DateTime",
+ "com.sun.star.text.textfield.URL",
+ "com.sun.star.text.textfield.PageNumber",
+ "com.sun.star.text.textfield.PageCount",
+ "com.sun.star.text.textfield.DateTime",
+ "com.sun.star.text.textfield.docinfo.Title", // SvxFileField is used for title
+ "com.sun.star.text.textfield.SheetName",
+ "com.sun.star.text.textfield.DateTime",
+ "com.sun.star.text.textfield.FileName",
+ "com.sun.star.text.textfield.Author",
+ "com.sun.star.text.textfield.Measure",
+ "com.sun.star.text.textfield.DateTime",
+ "com.sun.star.presentation.textfield.Header",
+ "com.sun.star.presentation.textfield.Footer",
+ "com.sun.star.presentation.textfield.DateTime"
+};
+
+uno::Sequence< OUString > SAL_CALL SvxUnoTextField::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence< OUString > aSeq( 4 );
+ OUString* pServices = aSeq.getArray();
+ pServices[0] = OUString::createFromAscii( pNewServiceNames[mnServiceId] );
+ pServices[1] = OUString::createFromAscii( pOldServiceNames[mnServiceId] );
+ pServices[2] = OUString::createFromAscii( "com.sun.star.text.TextContent" ),
+ pServices[3] = OUString::createFromAscii( "com.sun.star.text.TextField" );
+
+ return aSeq;
+}
+
+sal_Bool SAL_CALL SvxUnoTextField::supportsService( const OUString& ServiceName ) throw( uno::RuntimeException )
+{
+ return comphelper::ServiceInfoHelper::supportsService( ServiceName, getSupportedServiceNames() );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL SvxUnoTextCreateTextField( const ::rtl::OUString& ServiceSpecifier ) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ uno::Reference< uno::XInterface > xRet;
+
+ const OUString aTextFieldPrexit( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.textfield.") );
+
+ // #i93308# up to OOo 3.2 we used this wrong namespace name with the capital T & F. This is
+ // fixed since OOo 3.2 but for compatibility we will still provide support for the wrong notation.
+ const OUString aTextFieldPrexit2( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextField.") );
+
+ if( (ServiceSpecifier.compareTo( aTextFieldPrexit, aTextFieldPrexit.getLength() ) == 0) ||
+ (ServiceSpecifier.compareTo( aTextFieldPrexit2, aTextFieldPrexit2.getLength() ) == 0) )
+ {
+ OUString aFieldType( ServiceSpecifier.copy( aTextFieldPrexit.getLength() ) );
+
+ sal_Int32 nId = ID_UNKNOWN;
+
+ if( aFieldType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DateTime") ) )
+ {
+ nId = ID_DATEFIELD;
+ }
+ else if( aFieldType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("URL") ) )
+ {
+ nId = ID_URLFIELD;
+ }
+ else if( aFieldType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("PageNumber") ) )
+ {
+ nId = ID_PAGEFIELD;
+ }
+ else if( aFieldType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("PageCount") ) )
+ {
+ nId = ID_PAGESFIELD;
+ }
+ else if( aFieldType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("SheetName") ) )
+ {
+ nId = ID_TABLEFIELD;
+ }
+ else if( aFieldType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("FileName") ) )
+ {
+ nId = ID_EXT_FILEFIELD;
+ }
+ else if (aFieldType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("docinfo.Title") ) ||
+ aFieldType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("DocInfo.Title") ) )
+ {
+ nId = ID_FILEFIELD;
+ }
+ else if( aFieldType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Author") ) )
+ {
+ nId = ID_AUTHORFIELD;
+ }
+ else if( aFieldType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Measure") ) )
+ {
+ nId = ID_MEASUREFIELD;
+ }
+
+ if( nId != ID_UNKNOWN )
+ xRet = (::cppu::OWeakObject * )new SvxUnoTextField( nId );
+ }
+
+ return xRet;
+}
diff --git a/editeng/source/uno/unofored.cxx b/editeng/source/uno/unofored.cxx
new file mode 100644
index 0000000000..a9056b923e
--- /dev/null
+++ b/editeng/source/uno/unofored.cxx
@@ -0,0 +1,555 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unofored.cxx,v $
+ * $Revision: 1.31 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <algorithm>
+#include <editeng/eeitem.hxx>
+#include <com/sun/star/i18n/WordType.hpp>
+
+#include <svl/itemset.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/unoedhlp.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/editobj.hxx> // nur fuer die GetText-Kruecke
+
+#include <editeng/unofored.hxx>
+
+using namespace ::com::sun::star;
+
+//------------------------------------------------------------------------
+
+SvxEditEngineForwarder::SvxEditEngineForwarder( EditEngine& rEngine ) :
+ rEditEngine( rEngine )
+{
+}
+
+SvxEditEngineForwarder::~SvxEditEngineForwarder()
+{
+ // die EditEngine muss ggf. von aussen geloescht werden
+}
+
+USHORT SvxEditEngineForwarder::GetParagraphCount() const
+{
+ return rEditEngine.GetParagraphCount();
+}
+
+USHORT SvxEditEngineForwarder::GetTextLen( USHORT nParagraph ) const
+{
+ return rEditEngine.GetTextLen( nParagraph );
+}
+
+String SvxEditEngineForwarder::GetText( const ESelection& rSel ) const
+{
+ String aRet = rEditEngine.GetText( rSel, LINEEND_LF );
+ aRet.ConvertLineEnd();
+ return aRet;
+}
+
+SfxItemSet SvxEditEngineForwarder::GetAttribs( const ESelection& rSel, BOOL bOnlyHardAttrib ) const
+{
+ if( rSel.nStartPara == rSel.nEndPara )
+ {
+ sal_uInt8 nFlags = 0;
+ switch( bOnlyHardAttrib )
+ {
+ case EditEngineAttribs_All:
+ nFlags = GETATTRIBS_ALL;
+ break;
+ case EditEngineAttribs_HardAndPara:
+ nFlags = GETATTRIBS_PARAATTRIBS|GETATTRIBS_CHARATTRIBS;
+ break;
+ case EditEngineAttribs_OnlyHard:
+ nFlags = GETATTRIBS_CHARATTRIBS;
+ break;
+ default:
+ DBG_ERROR("unknown flags for SvxOutlinerForwarder::GetAttribs");
+ }
+
+ return rEditEngine.GetAttribs( rSel.nStartPara, rSel.nStartPos, rSel.nEndPos, nFlags );
+ }
+ else
+ {
+ return rEditEngine.GetAttribs( rSel, bOnlyHardAttrib );
+ }
+}
+
+SfxItemSet SvxEditEngineForwarder::GetParaAttribs( USHORT nPara ) const
+{
+ SfxItemSet aSet( rEditEngine.GetParaAttribs( nPara ) );
+
+ USHORT nWhich = EE_PARA_START;
+ while( nWhich <= EE_PARA_END )
+ {
+ if( aSet.GetItemState( nWhich, TRUE ) != SFX_ITEM_ON )
+ {
+ if( rEditEngine.HasParaAttrib( nPara, nWhich ) )
+ aSet.Put( rEditEngine.GetParaAttrib( nPara, nWhich ) );
+ }
+ nWhich++;
+ }
+
+ return aSet;
+}
+
+void SvxEditEngineForwarder::SetParaAttribs( USHORT nPara, const SfxItemSet& rSet )
+{
+ rEditEngine.SetParaAttribs( nPara, rSet );
+}
+
+void SvxEditEngineForwarder::RemoveAttribs( const ESelection& rSelection, sal_Bool bRemoveParaAttribs, sal_uInt16 nWhich )
+{
+ rEditEngine.RemoveAttribs( rSelection, bRemoveParaAttribs, nWhich );
+}
+
+SfxItemPool* SvxEditEngineForwarder::GetPool() const
+{
+ return rEditEngine.GetEmptyItemSet().GetPool();
+}
+
+void SvxEditEngineForwarder::GetPortions( USHORT nPara, SvUShorts& rList ) const
+{
+ rEditEngine.GetPortions( nPara, rList );
+}
+
+void SvxEditEngineForwarder::QuickInsertText( const String& rText, const ESelection& rSel )
+{
+ rEditEngine.QuickInsertText( rText, rSel );
+}
+
+void SvxEditEngineForwarder::QuickInsertLineBreak( const ESelection& rSel )
+{
+ rEditEngine.QuickInsertLineBreak( rSel );
+}
+
+void SvxEditEngineForwarder::QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel )
+{
+ rEditEngine.QuickInsertField( rFld, rSel );
+}
+
+void SvxEditEngineForwarder::QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel )
+{
+ rEditEngine.QuickSetAttribs( rSet, rSel );
+}
+
+BOOL SvxEditEngineForwarder::IsValid() const
+{
+ // cannot reliably query EditEngine state
+ // while in the middle of an update
+ return rEditEngine.GetUpdateMode();
+}
+
+XubString SvxEditEngineForwarder::CalcFieldValue( const SvxFieldItem& rField, USHORT nPara, USHORT nPos, Color*& rpTxtColor, Color*& rpFldColor )
+{
+ return rEditEngine.CalcFieldValue( rField, nPara, nPos, rpTxtColor, rpFldColor );
+}
+
+USHORT GetSvxEditEngineItemState( EditEngine& rEditEngine, const ESelection& rSel, USHORT nWhich )
+{
+ EECharAttribArray aAttribs;
+
+ const SfxPoolItem* pLastItem = NULL;
+
+ SfxItemState eState = SFX_ITEM_DEFAULT;
+
+ // check all paragraphs inside the selection
+ for( USHORT nPara = rSel.nStartPara; nPara <= rSel.nEndPara; nPara++ )
+ {
+ SfxItemState eParaState = SFX_ITEM_DEFAULT;
+
+ // calculate start and endpos for this paragraph
+ USHORT nPos = 0;
+ if( rSel.nStartPara == nPara )
+ nPos = rSel.nStartPos;
+
+ USHORT nEndPos = rSel.nEndPos;
+ if( rSel.nEndPara != nPara )
+ nEndPos = rEditEngine.GetTextLen( nPara );
+
+
+ // get list of char attribs
+ rEditEngine.GetCharAttribs( nPara, aAttribs );
+
+ BOOL bEmpty = TRUE; // we found no item inside the selektion of this paragraph
+ BOOL bGaps = FALSE; // we found items but theire gaps between them
+ USHORT nLastEnd = nPos;
+
+ const SfxPoolItem* pParaItem = NULL;
+
+ for( USHORT nAttrib = 0; nAttrib < aAttribs.Count(); nAttrib++ )
+ {
+ struct EECharAttrib aAttrib = aAttribs.GetObject( nAttrib );
+ DBG_ASSERT( aAttrib.pAttr, "GetCharAttribs gives corrupt data" );
+
+ const sal_Bool bEmptyPortion = aAttrib.nStart == aAttrib.nEnd;
+ if( (!bEmptyPortion && (aAttrib.nStart >= nEndPos)) || (bEmptyPortion && (aAttrib.nStart > nEndPos)) )
+ break; // break if we are already behind our selektion
+
+ if( (!bEmptyPortion && (aAttrib.nEnd <= nPos)) || (bEmptyPortion && (aAttrib.nEnd < nPos)) )
+ continue; // or if the attribute ends before our selektion
+
+ if( aAttrib.pAttr->Which() != nWhich )
+ continue; // skip if is not the searched item
+
+ // if we already found an item
+ if( pParaItem )
+ {
+ // ... and its different to this one than the state is dont care
+ if( *pParaItem != *aAttrib.pAttr )
+ return SFX_ITEM_DONTCARE;
+ }
+ else
+ {
+ pParaItem = aAttrib.pAttr;
+ }
+
+ if( bEmpty )
+ bEmpty = FALSE;
+
+ if( !bGaps && aAttrib.nStart > nLastEnd )
+ bGaps = TRUE;
+
+ nLastEnd = aAttrib.nEnd;
+ }
+
+ if( !bEmpty && !bGaps && nLastEnd < ( nEndPos - 1 ) )
+ bGaps = TRUE;
+/*
+ // since we have no portion with our item or if there were gaps
+ if( bEmpty || bGaps )
+ {
+ // we need to check the paragraph item
+ const SfxItemSet& rParaSet = rEditEngine.GetParaAttribs( nPara );
+ if( rParaSet.GetItemState( nWhich ) == SFX_ITEM_SET )
+ {
+ eState = SFX_ITEM_SET;
+ // get item from the paragraph
+ const SfxPoolItem* pTempItem = rParaSet.GetItem( nWhich );
+ if( pParaItem )
+ {
+ if( *pParaItem != *pTempItem )
+ return SFX_ITEM_DONTCARE;
+ }
+ else
+ {
+ pParaItem = pTempItem;
+ }
+
+ // set if theres no last item or if its the same
+ eParaState = SFX_ITEM_SET;
+ }
+ else if( bEmpty )
+ {
+ eParaState = SFX_ITEM_DEFAULT;
+ }
+ else if( bGaps )
+ {
+ // gaps and item not set in paragraph, thats a dont care
+ return SFX_ITEM_DONTCARE;
+ }
+ }
+ else
+ {
+ eParaState = SFX_ITEM_SET;
+ }
+*/
+ if( bEmpty )
+ eParaState = SFX_ITEM_DEFAULT;
+ else if( bGaps )
+ eParaState = SFX_ITEM_DONTCARE;
+ else
+ eParaState = SFX_ITEM_SET;
+
+ // if we already found an item check if we found the same
+ if( pLastItem )
+ {
+ if( (pParaItem == NULL) || (*pLastItem != *pParaItem) )
+ return SFX_ITEM_DONTCARE;
+ }
+ else
+ {
+ pLastItem = pParaItem;
+ eState = eParaState;
+ }
+ }
+
+ return eState;
+}
+
+USHORT SvxEditEngineForwarder::GetItemState( const ESelection& rSel, USHORT nWhich ) const
+{
+ return GetSvxEditEngineItemState( rEditEngine, rSel, nWhich );
+}
+
+USHORT SvxEditEngineForwarder::GetItemState( USHORT nPara, USHORT nWhich ) const
+{
+ const SfxItemSet& rSet = rEditEngine.GetParaAttribs( nPara );
+ return rSet.GetItemState( nWhich );
+}
+
+LanguageType SvxEditEngineForwarder::GetLanguage( USHORT nPara, USHORT nIndex ) const
+{
+ return rEditEngine.GetLanguage(nPara, nIndex);
+}
+
+USHORT SvxEditEngineForwarder::GetFieldCount( USHORT nPara ) const
+{
+ return rEditEngine.GetFieldCount(nPara);
+}
+
+EFieldInfo SvxEditEngineForwarder::GetFieldInfo( USHORT nPara, USHORT nField ) const
+{
+ return rEditEngine.GetFieldInfo( nPara, nField );
+}
+
+EBulletInfo SvxEditEngineForwarder::GetBulletInfo( USHORT ) const
+{
+ return EBulletInfo();
+}
+
+Rectangle SvxEditEngineForwarder::GetCharBounds( USHORT nPara, USHORT nIndex ) const
+{
+ // #101701#
+ // EditEngine's 'internal' methods like GetCharacterBounds()
+ // don't rotate for vertical text.
+ Size aSize( rEditEngine.CalcTextWidth(), rEditEngine.GetTextHeight() );
+ ::std::swap( aSize.Width(), aSize.Height() );
+ bool bIsVertical( rEditEngine.IsVertical() == TRUE );
+
+ // #108900# Handle virtual position one-past-the end of the string
+ if( nIndex >= rEditEngine.GetTextLen(nPara) )
+ {
+ Rectangle aLast;
+
+ if( nIndex )
+ {
+ // use last character, if possible
+ aLast = rEditEngine.GetCharacterBounds( EPosition(nPara, nIndex-1) );
+
+ // move at end of this last character, make one pixel wide
+ aLast.Move( aLast.Right() - aLast.Left(), 0 );
+ aLast.SetSize( Size(1, aLast.GetHeight()) );
+
+ // take care for CTL
+ aLast = SvxEditSourceHelper::EEToUserSpace( aLast, aSize, bIsVertical );
+ }
+ else
+ {
+ // #109864# Bounds must lie within the paragraph
+ aLast = GetParaBounds( nPara );
+
+ // #109151# Don't use paragraph height, but line height
+ // instead. aLast is already CTL-correct
+ if( bIsVertical)
+ aLast.SetSize( Size( rEditEngine.GetLineHeight(nPara,0), 1 ) );
+ else
+ aLast.SetSize( Size( 1, rEditEngine.GetLineHeight(nPara,0) ) );
+ }
+
+ return aLast;
+ }
+ else
+ {
+ return SvxEditSourceHelper::EEToUserSpace( rEditEngine.GetCharacterBounds( EPosition(nPara, nIndex) ),
+ aSize, bIsVertical );
+ }
+}
+
+Rectangle SvxEditEngineForwarder::GetParaBounds( USHORT nPara ) const
+{
+ const Point aPnt = rEditEngine.GetDocPosTopLeft( nPara );
+ ULONG nWidth;
+ ULONG nHeight;
+ ULONG nTextWidth;
+
+ if( rEditEngine.IsVertical() )
+ {
+ // #101701#
+ // Hargl. EditEngine's 'external' methods return the rotated
+ // dimensions, 'internal' methods like GetTextHeight( n )
+ // don't rotate.
+ nWidth = rEditEngine.GetTextHeight( nPara );
+ nHeight = rEditEngine.GetTextHeight();
+ nTextWidth = rEditEngine.GetTextHeight();
+
+ return Rectangle( nTextWidth - aPnt.Y() - nWidth, 0, nTextWidth - aPnt.Y(), nHeight );
+ }
+ else
+ {
+ nWidth = rEditEngine.CalcTextWidth();
+ nHeight = rEditEngine.GetTextHeight( nPara );
+
+ return Rectangle( 0, aPnt.Y(), nWidth, aPnt.Y() + nHeight );
+ }
+}
+
+MapMode SvxEditEngineForwarder::GetMapMode() const
+{
+ return rEditEngine.GetRefMapMode();
+}
+
+OutputDevice* SvxEditEngineForwarder::GetRefDevice() const
+{
+ return rEditEngine.GetRefDevice();
+}
+
+sal_Bool SvxEditEngineForwarder::GetIndexAtPoint( const Point& rPos, USHORT& nPara, USHORT& nIndex ) const
+{
+ // #101701#
+ Size aSize( rEditEngine.CalcTextWidth(), rEditEngine.GetTextHeight() );
+ ::std::swap( aSize.Width(), aSize.Height() );
+ Point aEEPos( SvxEditSourceHelper::UserSpaceToEE( rPos,
+ aSize,
+ rEditEngine.IsVertical() == TRUE ));
+
+ EPosition aDocPos = rEditEngine.FindDocPosition( aEEPos );
+
+ nPara = aDocPos.nPara;
+ nIndex = aDocPos.nIndex;
+
+ return sal_True;
+}
+
+sal_Bool SvxEditEngineForwarder::GetWordIndices( USHORT nPara, USHORT nIndex, USHORT& nStart, USHORT& nEnd ) const
+{
+ ESelection aRes = rEditEngine.GetWord( ESelection(nPara, nIndex, nPara, nIndex), com::sun::star::i18n::WordType::DICTIONARY_WORD );
+
+ if( aRes.nStartPara == nPara &&
+ aRes.nStartPara == aRes.nEndPara )
+ {
+ nStart = aRes.nStartPos;
+ nEnd = aRes.nEndPos;
+
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+sal_Bool SvxEditEngineForwarder::GetAttributeRun( USHORT& nStartIndex, USHORT& nEndIndex, USHORT nPara, USHORT nIndex ) const
+{
+ return SvxEditSourceHelper::GetAttributeRun( nStartIndex, nEndIndex, rEditEngine, nPara, nIndex );
+}
+
+USHORT SvxEditEngineForwarder::GetLineCount( USHORT nPara ) const
+{
+ return rEditEngine.GetLineCount(nPara);
+}
+
+USHORT SvxEditEngineForwarder::GetLineLen( USHORT nPara, USHORT nLine ) const
+{
+ return rEditEngine.GetLineLen(nPara, nLine);
+}
+
+void SvxEditEngineForwarder::GetLineBoundaries( /*out*/USHORT &rStart, /*out*/USHORT &rEnd, USHORT nPara, USHORT nLine ) const
+{
+ rEditEngine.GetLineBoundaries(rStart, rEnd, nPara, nLine);
+}
+
+USHORT SvxEditEngineForwarder::GetLineNumberAtIndex( USHORT nPara, USHORT nIndex ) const
+{
+ return rEditEngine.GetLineNumberAtIndex(nPara, nIndex);
+}
+
+
+sal_Bool SvxEditEngineForwarder::QuickFormatDoc( BOOL )
+{
+ rEditEngine.QuickFormatDoc();
+
+ return sal_True;
+}
+
+sal_Bool SvxEditEngineForwarder::Delete( const ESelection& rSelection )
+{
+ rEditEngine.QuickDelete( rSelection );
+ rEditEngine.QuickFormatDoc();
+
+ return sal_True;
+}
+
+sal_Bool SvxEditEngineForwarder::InsertText( const String& rStr, const ESelection& rSelection )
+{
+ rEditEngine.QuickInsertText( rStr, rSelection );
+ rEditEngine.QuickFormatDoc();
+
+ return sal_True;
+}
+
+sal_Int16 SvxEditEngineForwarder::GetDepth( USHORT ) const
+{
+ // EditEngine does not support outline depth
+ return -1;
+}
+
+sal_Bool SvxEditEngineForwarder::SetDepth( USHORT, sal_Int16 nNewDepth )
+{
+ // EditEngine does not support outline depth
+ return nNewDepth == -1 ? sal_True : sal_False;
+}
+
+const SfxItemSet * SvxEditEngineForwarder::GetEmptyItemSetPtr()
+{
+ return &rEditEngine.GetEmptyItemSet();
+}
+
+void SvxEditEngineForwarder::AppendParagraph()
+{
+ rEditEngine.InsertParagraph( rEditEngine.GetParagraphCount(), String::EmptyString() );
+}
+
+xub_StrLen SvxEditEngineForwarder::AppendTextPortion( USHORT nPara, const String &rText, const SfxItemSet & /*rSet*/ )
+{
+ xub_StrLen nLen = 0;
+
+ USHORT nParaCount = rEditEngine.GetParagraphCount();
+ DBG_ASSERT( nPara < nParaCount, "paragraph index out of bounds" );
+ if (/*0 <= nPara && */nPara < nParaCount)
+ {
+ nLen = rEditEngine.GetTextLen( nPara );
+ rEditEngine.QuickInsertText( rText, ESelection( nPara, nLen, nPara, nLen ) );
+ }
+
+ return nLen;
+}
+
+void SvxEditEngineForwarder::CopyText(const SvxTextForwarder& rSource)
+{
+ const SvxEditEngineForwarder* pSourceForwarder = dynamic_cast< const SvxEditEngineForwarder* >( &rSource );
+ if( !pSourceForwarder )
+ return;
+ EditTextObject* pNewTextObject = pSourceForwarder->rEditEngine.CreateTextObject();
+ rEditEngine.SetText( *pNewTextObject );
+ delete pNewTextObject;
+}
+
+//------------------------------------------------------------------------
diff --git a/editeng/source/uno/unoforou.cxx b/editeng/source/uno/unoforou.cxx
new file mode 100644
index 0000000000..9638d77d8e
--- /dev/null
+++ b/editeng/source/uno/unoforou.cxx
@@ -0,0 +1,613 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unoforou.cxx,v $
+ * $Revision: 1.36 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#include <algorithm>
+#include <svl/style.hxx>
+#include <com/sun/star/i18n/WordType.hpp>
+
+#include <svl/itemset.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/unoedhlp.hxx>
+#include <svl/poolitem.hxx>
+#include <vcl/wrkwin.hxx>
+#include <editeng/eeitem.hxx>
+
+#include <editeng/unoforou.hxx>
+#include <editeng/unofored.hxx>
+#include <editeng/outlobj.hxx>
+
+using namespace ::com::sun::star;
+
+//------------------------------------------------------------------------
+
+SvxOutlinerForwarder::SvxOutlinerForwarder( Outliner& rOutl, BOOL bOutlText /* = FALSE */ ) :
+ rOutliner( rOutl ),
+ bOutlinerText( bOutlText ),
+ mpAttribsCache( NULL ),
+ mpParaAttribsCache( NULL ),
+ mnParaAttribsCache( 0 )
+{
+}
+
+SvxOutlinerForwarder::~SvxOutlinerForwarder()
+{
+ flushCache();
+}
+
+USHORT SvxOutlinerForwarder::GetParagraphCount() const
+{
+ return (USHORT)rOutliner.GetParagraphCount();
+}
+
+USHORT SvxOutlinerForwarder::GetTextLen( USHORT nParagraph ) const
+{
+ return rOutliner.GetEditEngine().GetTextLen( nParagraph );
+}
+
+String SvxOutlinerForwarder::GetText( const ESelection& rSel ) const
+{
+ //! GetText(ESelection) sollte es wohl auch mal am Outliner geben
+ // solange den Hack fuer die EditEngine uebernehmen:
+ EditEngine* pEditEngine = (EditEngine*)&rOutliner.GetEditEngine();
+ return pEditEngine->GetText( rSel, LINEEND_LF );
+}
+
+static SfxItemSet ImplOutlinerForwarderGetAttribs( const ESelection& rSel, BOOL bOnlyHardAttrib, EditEngine& rEditEngine )
+{
+ if( rSel.nStartPara == rSel.nEndPara )
+ {
+ sal_uInt8 nFlags = 0;
+
+ switch( bOnlyHardAttrib )
+ {
+ case EditEngineAttribs_All:
+ nFlags = GETATTRIBS_ALL;
+ break;
+ case EditEngineAttribs_HardAndPara:
+ nFlags = GETATTRIBS_PARAATTRIBS|GETATTRIBS_CHARATTRIBS;
+ break;
+ case EditEngineAttribs_OnlyHard:
+ nFlags = GETATTRIBS_CHARATTRIBS;
+ break;
+ default:
+ DBG_ERROR("unknown flags for SvxOutlinerForwarder::GetAttribs");
+ }
+ return rEditEngine.GetAttribs( rSel.nStartPara, rSel.nStartPos, rSel.nEndPos, nFlags );
+ }
+ else
+ {
+ return rEditEngine.GetAttribs( rSel, bOnlyHardAttrib );
+ }
+}
+
+SfxItemSet SvxOutlinerForwarder::GetAttribs( const ESelection& rSel, BOOL bOnlyHardAttrib ) const
+{
+ if( mpAttribsCache && ( 0 == bOnlyHardAttrib ) )
+ {
+ // have we the correct set in cache?
+ if( ((SvxOutlinerForwarder*)this)->maAttribCacheSelection.IsEqual(rSel) )
+ {
+ // yes! just return the cache
+ return *mpAttribsCache;
+ }
+ else
+ {
+ // no, we need delete the old cache
+ delete mpAttribsCache;
+ mpAttribsCache = NULL;
+ }
+ }
+
+ //! gibt's das nicht am Outliner ???
+ //! und warum ist GetAttribs an der EditEngine nicht const?
+ EditEngine& rEditEngine = (EditEngine&)rOutliner.GetEditEngine();
+
+ SfxItemSet aSet( ImplOutlinerForwarderGetAttribs( rSel, bOnlyHardAttrib, rEditEngine ) );
+
+ if( 0 == bOnlyHardAttrib )
+ {
+ mpAttribsCache = new SfxItemSet( aSet );
+ maAttribCacheSelection = rSel;
+ }
+
+ SfxStyleSheet* pStyle = rEditEngine.GetStyleSheet( rSel.nStartPara );
+ if( pStyle )
+ aSet.SetParent( &(pStyle->GetItemSet() ) );
+
+ return aSet;
+}
+
+SfxItemSet SvxOutlinerForwarder::GetParaAttribs( USHORT nPara ) const
+{
+ if( mpParaAttribsCache )
+ {
+ // have we the correct set in cache?
+ if( nPara == mnParaAttribsCache )
+ {
+ // yes! just return the cache
+ return *mpParaAttribsCache;
+ }
+ else
+ {
+ // no, we need delete the old cache
+ delete mpParaAttribsCache;
+ mpParaAttribsCache = NULL;
+ }
+ }
+
+ mpParaAttribsCache = new SfxItemSet( rOutliner.GetParaAttribs( nPara ) );
+ mnParaAttribsCache = nPara;
+
+ EditEngine& rEditEngine = (EditEngine&)rOutliner.GetEditEngine();
+
+ SfxStyleSheet* pStyle = rEditEngine.GetStyleSheet( nPara );
+ if( pStyle )
+ mpParaAttribsCache->SetParent( &(pStyle->GetItemSet() ) );
+
+ return *mpParaAttribsCache;
+}
+
+void SvxOutlinerForwarder::SetParaAttribs( USHORT nPara, const SfxItemSet& rSet )
+{
+ flushCache();
+
+ const SfxItemSet* pOldParent = rSet.GetParent();
+ if( pOldParent )
+ ((SfxItemSet*)&rSet)->SetParent( NULL );
+
+ rOutliner.SetParaAttribs( nPara, rSet );
+
+ if( pOldParent )
+ ((SfxItemSet*)&rSet)->SetParent( pOldParent );
+}
+
+void SvxOutlinerForwarder::RemoveAttribs( const ESelection& rSelection, sal_Bool bRemoveParaAttribs, sal_uInt16 nWhich )
+{
+ rOutliner.RemoveAttribs( rSelection, bRemoveParaAttribs, nWhich );
+}
+
+SfxItemPool* SvxOutlinerForwarder::GetPool() const
+{
+ return rOutliner.GetEmptyItemSet().GetPool();
+}
+
+void SvxOutlinerForwarder::GetPortions( USHORT nPara, SvUShorts& rList ) const
+{
+ ((EditEngine&)rOutliner.GetEditEngine()).GetPortions( nPara, rList );
+}
+
+void SvxOutlinerForwarder::QuickInsertText( const String& rText, const ESelection& rSel )
+{
+ flushCache();
+ if( rText.Len() == 0 )
+ {
+ rOutliner.QuickDelete( rSel );
+ }
+ else
+ {
+ rOutliner.QuickInsertText( rText, rSel );
+ }
+}
+
+void SvxOutlinerForwarder::QuickInsertLineBreak( const ESelection& rSel )
+{
+ flushCache();
+ rOutliner.QuickInsertLineBreak( rSel );
+}
+
+void SvxOutlinerForwarder::QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel )
+{
+ flushCache();
+ rOutliner.QuickInsertField( rFld, rSel );
+}
+
+void SvxOutlinerForwarder::QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel )
+{
+ flushCache();
+ rOutliner.QuickSetAttribs( rSet, rSel );
+}
+
+XubString SvxOutlinerForwarder::CalcFieldValue( const SvxFieldItem& rField, USHORT nPara, USHORT nPos, Color*& rpTxtColor, Color*& rpFldColor )
+{
+ return rOutliner.CalcFieldValue( rField, nPara, nPos, rpTxtColor, rpFldColor );
+}
+
+BOOL SvxOutlinerForwarder::IsValid() const
+{
+ // cannot reliably query outliner state
+ // while in the middle of an update
+ return rOutliner.GetUpdateMode();
+}
+
+extern USHORT GetSvxEditEngineItemState( EditEngine& rEditEngine, const ESelection& rSel, USHORT nWhich );
+
+USHORT SvxOutlinerForwarder::GetItemState( const ESelection& rSel, USHORT nWhich ) const
+{
+ return GetSvxEditEngineItemState( (EditEngine&)rOutliner.GetEditEngine(), rSel, nWhich );
+}
+
+USHORT SvxOutlinerForwarder::GetItemState( USHORT nPara, USHORT nWhich ) const
+{
+ const SfxItemSet& rSet = rOutliner.GetParaAttribs( nPara );
+ return rSet.GetItemState( nWhich );
+}
+
+
+void SvxOutlinerForwarder::flushCache()
+{
+ if( mpAttribsCache )
+ {
+ delete mpAttribsCache;
+ mpAttribsCache = NULL;
+ }
+
+ if( mpParaAttribsCache )
+ {
+ delete mpParaAttribsCache;
+ mpParaAttribsCache = NULL;
+ }
+}
+
+LanguageType SvxOutlinerForwarder::GetLanguage( USHORT nPara, USHORT nIndex ) const
+{
+ return rOutliner.GetLanguage(nPara, nIndex);
+}
+
+USHORT SvxOutlinerForwarder::GetFieldCount( USHORT nPara ) const
+{
+ return rOutliner.GetEditEngine().GetFieldCount(nPara);
+}
+
+EFieldInfo SvxOutlinerForwarder::GetFieldInfo( USHORT nPara, USHORT nField ) const
+{
+ return rOutliner.GetEditEngine().GetFieldInfo( nPara, nField );
+}
+
+EBulletInfo SvxOutlinerForwarder::GetBulletInfo( USHORT nPara ) const
+{
+ return rOutliner.GetBulletInfo( nPara );
+}
+
+Rectangle SvxOutlinerForwarder::GetCharBounds( USHORT nPara, USHORT nIndex ) const
+{
+ // #101701#
+ // EditEngine's 'internal' methods like GetCharacterBounds()
+ // don't rotate for vertical text.
+ Size aSize( rOutliner.CalcTextSize() );
+ ::std::swap( aSize.Width(), aSize.Height() );
+ bool bIsVertical( rOutliner.IsVertical() == TRUE );
+
+ // #108900# Handle virtual position one-past-the end of the string
+ if( nIndex >= GetTextLen(nPara) )
+ {
+ Rectangle aLast;
+
+ if( nIndex )
+ {
+ // use last character, if possible
+ aLast = rOutliner.GetEditEngine().GetCharacterBounds( EPosition(nPara, nIndex-1) );
+
+ // move at end of this last character, make one pixel wide
+ aLast.Move( aLast.Right() - aLast.Left(), 0 );
+ aLast.SetSize( Size(1, aLast.GetHeight()) );
+
+ // take care for CTL
+ aLast = SvxEditSourceHelper::EEToUserSpace( aLast, aSize, bIsVertical );
+ }
+ else
+ {
+ // #109864# Bounds must lie within the paragraph
+ aLast = GetParaBounds( nPara );
+
+ // #109151# Don't use paragraph height, but line height
+ // instead. aLast is already CTL-correct
+ if( bIsVertical)
+ aLast.SetSize( Size( rOutliner.GetLineHeight(nPara,0), 1 ) );
+ else
+ aLast.SetSize( Size( 1, rOutliner.GetLineHeight(nPara,0) ) );
+ }
+
+ return aLast;
+ }
+ else
+ {
+ return SvxEditSourceHelper::EEToUserSpace( rOutliner.GetEditEngine().GetCharacterBounds( EPosition(nPara, nIndex) ),
+ aSize, bIsVertical );
+ }
+}
+
+Rectangle SvxOutlinerForwarder::GetParaBounds( USHORT nPara ) const
+{
+ Point aPnt = rOutliner.GetDocPosTopLeft( nPara );
+ Size aSize = rOutliner.CalcTextSize();
+
+ if( rOutliner.IsVertical() )
+ {
+ // #101701#
+ // Hargl. Outliner's 'external' methods return the rotated
+ // dimensions, 'internal' methods like GetTextHeight( n )
+ // don't rotate.
+ ULONG nWidth = rOutliner.GetTextHeight( nPara );
+
+ return Rectangle( aSize.Width() - aPnt.Y() - nWidth, 0, aSize.Width() - aPnt.Y(), aSize.Height() );
+ }
+ else
+ {
+ ULONG nHeight = rOutliner.GetTextHeight( nPara );
+
+ return Rectangle( 0, aPnt.Y(), aSize.Width(), aPnt.Y() + nHeight );
+ }
+}
+
+MapMode SvxOutlinerForwarder::GetMapMode() const
+{
+ return rOutliner.GetRefMapMode();
+}
+
+OutputDevice* SvxOutlinerForwarder::GetRefDevice() const
+{
+ return rOutliner.GetRefDevice();
+}
+
+sal_Bool SvxOutlinerForwarder::GetIndexAtPoint( const Point& rPos, USHORT& nPara, USHORT& nIndex ) const
+{
+ // #101701#
+ Size aSize( rOutliner.CalcTextSize() );
+ ::std::swap( aSize.Width(), aSize.Height() );
+ Point aEEPos( SvxEditSourceHelper::UserSpaceToEE( rPos,
+ aSize,
+ rOutliner.IsVertical() == TRUE ));
+
+ EPosition aDocPos = rOutliner.GetEditEngine().FindDocPosition( aEEPos );
+
+ nPara = aDocPos.nPara;
+ nIndex = aDocPos.nIndex;
+
+ return sal_True;
+}
+
+sal_Bool SvxOutlinerForwarder::GetWordIndices( USHORT nPara, USHORT nIndex, USHORT& nStart, USHORT& nEnd ) const
+{
+ ESelection aRes = rOutliner.GetEditEngine().GetWord( ESelection(nPara, nIndex, nPara, nIndex), com::sun::star::i18n::WordType::DICTIONARY_WORD );
+
+ if( aRes.nStartPara == nPara &&
+ aRes.nStartPara == aRes.nEndPara )
+ {
+ nStart = aRes.nStartPos;
+ nEnd = aRes.nEndPos;
+
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+sal_Bool SvxOutlinerForwarder::GetAttributeRun( USHORT& nStartIndex, USHORT& nEndIndex, USHORT nPara, USHORT nIndex ) const
+{
+ return SvxEditSourceHelper::GetAttributeRun( nStartIndex, nEndIndex, rOutliner.GetEditEngine(), nPara, nIndex );
+}
+
+USHORT SvxOutlinerForwarder::GetLineCount( USHORT nPara ) const
+{
+ return static_cast < USHORT >( rOutliner.GetLineCount(nPara) );
+}
+
+USHORT SvxOutlinerForwarder::GetLineLen( USHORT nPara, USHORT nLine ) const
+{
+ return rOutliner.GetLineLen(nPara, nLine);
+}
+
+void SvxOutlinerForwarder::GetLineBoundaries( /*out*/USHORT &rStart, /*out*/USHORT &rEnd, USHORT nPara, USHORT nLine ) const
+{
+ return rOutliner.GetEditEngine().GetLineBoundaries( rStart, rEnd, nPara, nLine );
+}
+
+USHORT SvxOutlinerForwarder::GetLineNumberAtIndex( USHORT nPara, USHORT nIndex ) const
+{
+ return rOutliner.GetEditEngine().GetLineNumberAtIndex( nPara, nIndex );
+}
+
+sal_Bool SvxOutlinerForwarder::QuickFormatDoc( BOOL )
+{
+ rOutliner.QuickFormatDoc();
+
+ return sal_True;
+}
+
+sal_Bool SvxOutlinerForwarder::Delete( const ESelection& rSelection )
+{
+ flushCache();
+ rOutliner.QuickDelete( rSelection );
+ rOutliner.QuickFormatDoc();
+
+ return sal_True;
+}
+
+sal_Bool SvxOutlinerForwarder::InsertText( const String& rStr, const ESelection& rSelection )
+{
+ flushCache();
+ rOutliner.QuickInsertText( rStr, rSelection );
+ rOutliner.QuickFormatDoc();
+
+ return sal_True;
+}
+
+sal_Int16 SvxOutlinerForwarder::GetDepth( USHORT nPara ) const
+{
+ DBG_ASSERT( nPara < GetParagraphCount(), "SvxOutlinerForwarder::GetDepth: Invalid paragraph index");
+
+ Paragraph* pPara = rOutliner.GetParagraph( nPara );
+
+ sal_Int16 nLevel = -1;
+
+ if( pPara )
+ nLevel = rOutliner.GetDepth( nPara );
+
+ return nLevel;
+}
+
+sal_Bool SvxOutlinerForwarder::SetDepth( USHORT nPara, sal_Int16 nNewDepth )
+{
+ DBG_ASSERT( nPara < GetParagraphCount(), "SvxOutlinerForwarder::SetDepth: Invalid paragraph index");
+
+ if( (nNewDepth >= -1) && (nNewDepth <= 9) && (nPara < GetParagraphCount()) )
+ {
+ Paragraph* pPara = rOutliner.GetParagraph( nPara );
+ if( pPara )
+ {
+ rOutliner.SetDepth( pPara, nNewDepth );
+
+// const bool bOutlinerText = pSdrObject && (pSdrObject->GetObjInventor() == SdrInventor) && (pSdrObject->GetObjIdentifier() == OBJ_OUTLINETEXT);
+ if( bOutlinerText )
+ rOutliner.SetLevelDependendStyleSheet( nPara );
+
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+
+sal_Int16 SvxOutlinerForwarder::GetNumberingStartValue( sal_uInt16 nPara )
+{
+ if( nPara < GetParagraphCount() )
+ {
+ return rOutliner.GetNumberingStartValue( nPara );
+ }
+ else
+ {
+ DBG_ERROR( "SvxOutlinerForwarder::GetNumberingStartValue)(), Invalid paragraph index");
+ return -1;
+ }
+}
+
+void SvxOutlinerForwarder::SetNumberingStartValue( sal_uInt16 nPara, sal_Int16 nNumberingStartValue )
+{
+ if( nPara < GetParagraphCount() )
+ {
+ rOutliner.SetNumberingStartValue( nPara, nNumberingStartValue );
+ }
+ else
+ {
+ DBG_ERROR( "SvxOutlinerForwarder::SetNumberingStartValue)(), Invalid paragraph index");
+ }
+}
+
+sal_Bool SvxOutlinerForwarder::IsParaIsNumberingRestart( sal_uInt16 nPara )
+{
+ if( nPara < GetParagraphCount() )
+ {
+ return rOutliner.IsParaIsNumberingRestart( nPara );
+ }
+ else
+ {
+ DBG_ERROR( "SvxOutlinerForwarder::IsParaIsNumberingRestart)(), Invalid paragraph index");
+ return sal_False;
+ }
+}
+
+void SvxOutlinerForwarder::SetParaIsNumberingRestart( sal_uInt16 nPara, sal_Bool bParaIsNumberingRestart )
+{
+ if( nPara < GetParagraphCount() )
+ {
+ rOutliner.SetParaIsNumberingRestart( nPara, bParaIsNumberingRestart );
+ }
+ else
+ {
+ DBG_ERROR( "SvxOutlinerForwarder::SetParaIsNumberingRestart)(), Invalid paragraph index");
+ }
+}
+
+const SfxItemSet * SvxOutlinerForwarder::GetEmptyItemSetPtr()
+{
+ EditEngine& rEditEngine = const_cast< EditEngine& >( rOutliner.GetEditEngine() );
+ return &rEditEngine.GetEmptyItemSet();
+}
+
+void SvxOutlinerForwarder::AppendParagraph()
+{
+ EditEngine& rEditEngine = const_cast< EditEngine& >( rOutliner.GetEditEngine() );
+ rEditEngine.InsertParagraph( rEditEngine.GetParagraphCount(), String::EmptyString() );
+}
+
+xub_StrLen SvxOutlinerForwarder::AppendTextPortion( USHORT nPara, const String &rText, const SfxItemSet & /*rSet*/ )
+{
+ xub_StrLen nLen = 0;
+
+ EditEngine& rEditEngine = const_cast< EditEngine& >( rOutliner.GetEditEngine() );
+ USHORT nParaCount = rEditEngine.GetParagraphCount();
+ DBG_ASSERT( nPara < nParaCount, "paragraph index out of bounds" );
+ if (/*0 <= nPara && */nPara < nParaCount)
+ {
+ nLen = rEditEngine.GetTextLen( nPara );
+ rEditEngine.QuickInsertText( rText, ESelection( nPara, nLen, nPara, nLen ) );
+ }
+
+ return nLen;
+}
+
+void SvxOutlinerForwarder::CopyText(const SvxTextForwarder& rSource)
+{
+ const SvxOutlinerForwarder* pSourceForwarder = dynamic_cast< const SvxOutlinerForwarder* >( &rSource );
+ if( !pSourceForwarder )
+ return;
+ OutlinerParaObject* pNewOutlinerParaObject = pSourceForwarder->rOutliner.CreateParaObject();
+ rOutliner.SetText( *pNewOutlinerParaObject );
+ delete pNewOutlinerParaObject;
+}
+
+//------------------------------------------------------------------------
+
+
+sal_Int16 SvxTextForwarder::GetNumberingStartValue( sal_uInt16 )
+{
+ return -1;
+}
+
+void SvxTextForwarder::SetNumberingStartValue( sal_uInt16, sal_Int16 )
+{
+}
+
+sal_Bool SvxTextForwarder::IsParaIsNumberingRestart( sal_uInt16 )
+{
+ return sal_False;
+}
+
+void SvxTextForwarder::SetParaIsNumberingRestart( sal_uInt16, sal_Bool )
+{
+}
+
+//------------------------------------------------------------------------
+
diff --git a/editeng/source/uno/unoipset.cxx b/editeng/source/uno/unoipset.cxx
new file mode 100644
index 0000000000..f5f0322f93
--- /dev/null
+++ b/editeng/source/uno/unoipset.cxx
@@ -0,0 +1,425 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unoipset.cxx,v $
+ * $Revision: 1.28 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <svl/eitem.hxx>
+#include <tools/list.hxx>
+
+#include <hash_map>
+#include <vector>
+#include <svl/itemprop.hxx>
+
+#include <editeng/unoipset.hxx>
+#include <editeng/editids.hrc>
+#include <editeng/editeng.hxx>
+#include <svl/itempool.hxx>
+#include <algorithm>
+
+using namespace ::com::sun::star;
+using namespace ::rtl;
+
+//----------------------------------------------------------------------
+
+struct SfxItemPropertyMapEntryHash
+{
+ size_t operator()(const SfxItemPropertyMapEntry* pMap) const { return (size_t)pMap; }
+};
+
+//----------------------------------------------------------------------
+
+struct SvxIDPropertyCombine
+{
+ sal_uInt16 nWID;
+ uno::Any aAny;
+};
+
+DECLARE_LIST( SvxIDPropertyCombineList, SvxIDPropertyCombine * )
+
+SvxItemPropertySet::SvxItemPropertySet( const SfxItemPropertyMapEntry* pMap, SfxItemPool& rItemPool, sal_Bool bConvertTwips )
+: m_aPropertyMap( pMap ),
+ _pMap(pMap), mbConvertTwips(bConvertTwips), mrItemPool( rItemPool )
+{
+ pCombiList = NULL;
+}
+
+//----------------------------------------------------------------------
+SvxItemPropertySet::~SvxItemPropertySet()
+{
+/*
+ if(pItemPool)
+ delete pItemPool;
+ pItemPool = NULL;
+*/
+
+ if(pCombiList)
+ delete pCombiList;
+ pCombiList = NULL;
+}
+
+//----------------------------------------------------------------------
+uno::Any* SvxItemPropertySet::GetUsrAnyForID(sal_uInt16 nWID) const
+{
+ if(pCombiList && pCombiList->Count())
+ {
+ SvxIDPropertyCombine* pActual = pCombiList->First();
+ while(pActual)
+ {
+ if(pActual->nWID == nWID)
+ return &pActual->aAny;
+ pActual = pCombiList->Next();
+
+ }
+ }
+ return NULL;
+}
+
+//----------------------------------------------------------------------
+void SvxItemPropertySet::AddUsrAnyForID(const uno::Any& rAny, sal_uInt16 nWID)
+{
+ if(!pCombiList)
+ pCombiList = new SvxIDPropertyCombineList();
+
+ SvxIDPropertyCombine* pNew = new SvxIDPropertyCombine;
+ pNew->nWID = nWID;
+ pNew->aAny = rAny;
+ pCombiList->Insert(pNew);
+}
+
+/** this function checks if a SFX_METRIC_ITEM realy needs to be converted.
+ This check is for items that store either metric values if theire positiv
+ or percentage if theire negativ.
+*/
+#if 0
+sal_Bool SvxUnoCheckForConversion( const SfxItemSet&, sal_Int32 nWID, const uno::Any& rVal )
+{
+ sal_Bool bConvert = sal_True; // the default is that all metric items must be converted
+
+ switch( nWID )
+ {
+ case XATTR_FILLBMP_SIZEX:
+ case XATTR_FILLBMP_SIZEY:
+ {
+ sal_Int32 nValue = 0;
+ if( rVal >>= nValue )
+ bConvert = nValue > 0;
+ break;
+ }
+ }
+
+ // the default is to always
+ return bConvert;
+}
+#endif
+//----------------------------------------------------------------------
+uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap, const SfxItemSet& rSet, bool bSearchInParent, bool bConvert ) const
+{
+ uno::Any aVal;
+ if(!pMap || !pMap->nWID)
+ return aVal;
+
+ // item holen
+ const SfxPoolItem* pItem = 0;
+ SfxItemPool* pPool = rSet.GetPool();
+
+ // pMap->nWID != SDRATTR_XMLATTRIBUTES
+ rSet.GetItemState( pMap->nWID, bSearchInParent, &pItem );
+
+ if( NULL == pItem && pPool )
+ {
+ pItem = &(pPool->GetDefaultItem( pMap->nWID ));
+ }
+
+ const SfxMapUnit eMapUnit = pPool ? pPool->GetMetric((USHORT)pMap->nWID) : SFX_MAPUNIT_100TH_MM;
+
+ BYTE nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
+ if( eMapUnit == SFX_MAPUNIT_100TH_MM )
+ nMemberId &= (~CONVERT_TWIPS);
+
+ // item-Wert als UnoAny zurueckgeben
+ if(pItem)
+ {
+ pItem->QueryValue( aVal, nMemberId );
+
+ if( pMap->nMemberId & SFX_METRIC_ITEM )
+ {
+ // check for needed metric translation
+ if ( bConvert )
+// if(pMap->nMemberId & SFX_METRIC_ITEM && eMapUnit != SFX_MAPUNIT_100TH_MM)
+ {
+// if( SvxUnoCheckForConversion( rSet, pMap->nWID, aVal ) )
+ SvxUnoConvertToMM( eMapUnit, aVal );
+ }
+ }
+ // convert typeless SfxEnumItem to enum type
+ else if ( pMap->pType->getTypeClass() == uno::TypeClass_ENUM &&
+ aVal.getValueType() == ::getCppuType((const sal_Int32*)0) )
+ {
+ sal_Int32 nEnum;
+ aVal >>= nEnum;
+
+ aVal.setValue( &nEnum, *pMap->pType );
+ }
+ }
+ else
+ {
+ DBG_ERROR( "No SfxPoolItem found for property!" );
+ }
+
+ return aVal;
+}
+
+//----------------------------------------------------------------------
+void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal, SfxItemSet& rSet, bool bConvert ) const
+{
+ if(!pMap || !pMap->nWID)
+ return;
+
+ // item holen
+ const SfxPoolItem* pItem = 0;
+ SfxPoolItem *pNewItem = 0;
+ SfxItemState eState = rSet.GetItemState( pMap->nWID, sal_True, &pItem );
+ SfxItemPool* pPool = rSet.GetPool();
+
+ // UnoAny in item-Wert stecken
+ if(eState < SFX_ITEM_DEFAULT || pItem == NULL)
+ {
+ if( pPool == NULL )
+ {
+ DBG_ERROR( "No default item and no pool?" );
+ return;
+ }
+
+ pItem = &pPool->GetDefaultItem( pMap->nWID );
+ }
+
+ DBG_ASSERT( pItem, "Got no default for item!" );
+ if( pItem )
+ {
+ uno::Any aValue( rVal );
+
+ const SfxMapUnit eMapUnit = pPool ? pPool->GetMetric((USHORT)pMap->nWID) : SFX_MAPUNIT_100TH_MM;
+
+ if( pMap->nMemberId & SFX_METRIC_ITEM )
+ {
+ // check for needed metric translation
+ if ( bConvert )
+// if(pMap->nMemberId & SFX_METRIC_ITEM && eMapUnit != SFX_MAPUNIT_100TH_MM)
+ {
+// if( SvxUnoCheckForConversion( rSet, pMap->nWID, aValue ) )
+ SvxUnoConvertFromMM( eMapUnit, aValue );
+ }
+ }
+
+ pNewItem = pItem->Clone();
+
+ BYTE nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
+ if( eMapUnit == SFX_MAPUNIT_100TH_MM )
+ nMemberId &= (~CONVERT_TWIPS);
+
+ if( pNewItem->PutValue( aValue, nMemberId ) )
+ {
+ // neues item in itemset setzen
+ rSet.Put( *pNewItem, pMap->nWID );
+ }
+ delete pNewItem;
+ }
+}
+
+//----------------------------------------------------------------------
+uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap ) const
+{
+ // Schon ein Wert eingetragen? Dann schnell fertig
+ uno::Any* pUsrAny = GetUsrAnyForID(pMap->nWID);
+ if(pUsrAny)
+ return *pUsrAny;
+
+ // Noch kein UsrAny gemerkt, generiere Default-Eintrag und gib
+ // diesen zurueck
+
+ const SfxMapUnit eMapUnit = mrItemPool.GetMetric((USHORT)pMap->nWID);
+ BYTE nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
+ if( eMapUnit == SFX_MAPUNIT_100TH_MM )
+ nMemberId &= (~CONVERT_TWIPS);
+
+ uno::Any aVal;
+ SfxItemSet aSet( mrItemPool, pMap->nWID, pMap->nWID);
+
+ if( (pMap->nWID < OWN_ATTR_VALUE_START) && (pMap->nWID > OWN_ATTR_VALUE_END ) )
+ {
+ // Default aus ItemPool holen
+ if(mrItemPool.IsWhich(pMap->nWID))
+ aSet.Put(mrItemPool.GetDefaultItem(pMap->nWID));
+ }
+
+ if(aSet.Count())
+ {
+ const SfxPoolItem* pItem = NULL;
+ SfxItemState eState = aSet.GetItemState( pMap->nWID, sal_True, &pItem );
+ if(eState >= SFX_ITEM_DEFAULT && pItem)
+ {
+ pItem->QueryValue( aVal, nMemberId );
+ ((SvxItemPropertySet*)this)->AddUsrAnyForID(aVal, pMap->nWID);
+ }
+ }
+
+ if( pMap->nMemberId & SFX_METRIC_ITEM )
+ {
+ // check for needed metric translation
+ if(pMap->nMemberId & SFX_METRIC_ITEM && eMapUnit != SFX_MAPUNIT_100TH_MM)
+ {
+ SvxUnoConvertToMM( eMapUnit, aVal );
+ }
+ }
+
+ if ( pMap->pType->getTypeClass() == uno::TypeClass_ENUM &&
+ aVal.getValueType() == ::getCppuType((const sal_Int32*)0) )
+ {
+ sal_Int32 nEnum;
+ aVal >>= nEnum;
+
+ aVal.setValue( &nEnum, *pMap->pType );
+ }
+
+ return aVal;
+}
+
+//----------------------------------------------------------------------
+
+void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal ) const
+{
+ uno::Any* pUsrAny = GetUsrAnyForID(pMap->nWID);
+ if(!pUsrAny)
+ ((SvxItemPropertySet*)this)->AddUsrAnyForID(rVal, pMap->nWID);
+ else
+ *pUsrAny = rVal;
+}
+
+//----------------------------------------------------------------------
+
+const SfxItemPropertySimpleEntry* SvxItemPropertySet::getPropertyMapEntry(const OUString &rName) const
+{
+ return m_aPropertyMap.getByName( rName );
+ }
+
+//----------------------------------------------------------------------
+
+uno::Reference< beans::XPropertySetInfo > SvxItemPropertySet::getPropertySetInfo() const
+{
+ if( !m_xInfo.is() )
+ m_xInfo = new SfxItemPropertySetInfo( &m_aPropertyMap );
+ return m_xInfo;
+}
+
+//----------------------------------------------------------------------
+
+#ifndef TWIPS_TO_MM
+#define TWIPS_TO_MM(val) ((val * 127 + 36) / 72)
+#endif
+#ifndef MM_TO_TWIPS
+#define MM_TO_TWIPS(val) ((val * 72 + 63) / 127)
+#endif
+
+/** converts the given any with a metric to 100th/mm if needed */
+void SvxUnoConvertToMM( const SfxMapUnit eSourceMapUnit, uno::Any & rMetric ) throw()
+{
+ // map the metric of the itempool to 100th mm
+ switch(eSourceMapUnit)
+ {
+ case SFX_MAPUNIT_TWIP :
+ {
+ switch( rMetric.getValueTypeClass() )
+ {
+ case uno::TypeClass_BYTE:
+ rMetric <<= (sal_Int8)(TWIPS_TO_MM(*(sal_Int8*)rMetric.getValue()));
+ break;
+ case uno::TypeClass_SHORT:
+ rMetric <<= (sal_Int16)(TWIPS_TO_MM(*(sal_Int16*)rMetric.getValue()));
+ break;
+ case uno::TypeClass_UNSIGNED_SHORT:
+ rMetric <<= (sal_uInt16)(TWIPS_TO_MM(*(sal_uInt16*)rMetric.getValue()));
+ break;
+ case uno::TypeClass_LONG:
+ rMetric <<= (sal_Int32)(TWIPS_TO_MM(*(sal_Int32*)rMetric.getValue()));
+ break;
+ case uno::TypeClass_UNSIGNED_LONG:
+ rMetric <<= (sal_uInt32)(TWIPS_TO_MM(*(sal_uInt32*)rMetric.getValue()));
+ break;
+ default:
+ DBG_ERROR("AW: Missing unit translation to 100th mm!");
+ }
+ break;
+ }
+ default:
+ {
+ DBG_ERROR("AW: Missing unit translation to 100th mm!");
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+
+/** converts the given any with a metric from 100th/mm to the given metric if needed */
+void SvxUnoConvertFromMM( const SfxMapUnit eDestinationMapUnit, uno::Any & rMetric ) throw()
+{
+ switch(eDestinationMapUnit)
+ {
+ case SFX_MAPUNIT_TWIP :
+ {
+ switch( rMetric.getValueTypeClass() )
+ {
+ case uno::TypeClass_BYTE:
+ rMetric <<= (sal_Int8)(MM_TO_TWIPS(*(sal_Int8*)rMetric.getValue()));
+ break;
+ case uno::TypeClass_SHORT:
+ rMetric <<= (sal_Int16)(MM_TO_TWIPS(*(sal_Int16*)rMetric.getValue()));
+ break;
+ case uno::TypeClass_UNSIGNED_SHORT:
+ rMetric <<= (sal_uInt16)(MM_TO_TWIPS(*(sal_uInt16*)rMetric.getValue()));
+ break;
+ case uno::TypeClass_LONG:
+ rMetric <<= (sal_Int32)(MM_TO_TWIPS(*(sal_Int32*)rMetric.getValue()));
+ break;
+ case uno::TypeClass_UNSIGNED_LONG:
+ rMetric <<= (sal_uInt32)(MM_TO_TWIPS(*(sal_uInt32*)rMetric.getValue()));
+ break;
+ default:
+ DBG_ERROR("AW: Missing unit translation to 100th mm!");
+ }
+ break;
+ }
+ default:
+ {
+ DBG_ERROR("AW: Missing unit translation to PoolMetrics!");
+ }
+ }
+}
+
diff --git a/editeng/source/uno/unonrule.cxx b/editeng/source/uno/unonrule.cxx
new file mode 100644
index 0000000000..3b869ea59b
--- /dev/null
+++ b/editeng/source/uno/unonrule.cxx
@@ -0,0 +1,618 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unonrule.cxx,v $
+ * $Revision: 1.26 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+#define PROPERTY_NONE 0
+
+#include <com/sun/star/text/HoriOrientation.hpp>
+#include <com/sun/star/awt/XBitmap.hpp>
+
+#include <vcl/svapp.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/graph.hxx>
+#include <svtools/grfmgr.hxx>
+#include <toolkit/unohlp.hxx>
+#include <rtl/uuid.h>
+#include <rtl/memory.h>
+
+#include <editeng/brshitem.hxx>
+#include <editeng/unoprnms.hxx>
+#include <editeng/numitem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/unotext.hxx>
+#include <editeng/numitem.hxx>
+#include <editeng/unofdesc.hxx>
+#include <editeng/unonrule.hxx>
+#include <editeng/editids.hrc>
+
+using ::rtl::OUString;
+using ::com::sun::star::util::XCloneable;
+using ::com::sun::star::ucb::XAnyCompare;
+
+
+using namespace ::vos;
+using namespace ::std;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+
+const SvxAdjust aUnoToSvxAdjust[] =
+{
+ SVX_ADJUST_LEFT,
+ SVX_ADJUST_RIGHT,
+ SVX_ADJUST_CENTER,
+ SVX_ADJUST_LEFT,
+ SVX_ADJUST_LEFT,
+ SVX_ADJUST_LEFT,
+ SVX_ADJUST_BLOCK
+};
+
+const unsigned short aSvxToUnoAdjust[] =
+{
+ text::HoriOrientation::LEFT,
+ text::HoriOrientation::RIGHT,
+ text::HoriOrientation::FULL,
+ text::HoriOrientation::CENTER,
+ text::HoriOrientation::FULL,
+ text::HoriOrientation::LEFT
+};
+
+SvxAdjust ConvertUnoAdjust( unsigned short nAdjust )
+{
+ DBG_ASSERT( nAdjust <= 7, "Enum hat sich geaendert! [CL]" );
+ return aUnoToSvxAdjust[nAdjust];
+}
+
+unsigned short ConvertUnoAdjust( SvxAdjust eAdjust )
+{
+ DBG_ASSERT( eAdjust <= 6, "Enum hat sich geaendert! [CL]" );
+ return aSvxToUnoAdjust[eAdjust];
+}
+
+/******************************************************************
+ * SvxUnoNumberingRules
+ ******************************************************************/
+
+UNO3_GETIMPLEMENTATION_IMPL( SvxUnoNumberingRules );
+
+SvxUnoNumberingRules::SvxUnoNumberingRules( const SvxNumRule& rRule ) throw()
+: maRule( rRule )
+{
+}
+
+SvxUnoNumberingRules::~SvxUnoNumberingRules() throw()
+{
+}
+
+//XIndexReplace
+void SAL_CALL SvxUnoNumberingRules::replaceByIndex( sal_Int32 Index, const uno::Any& Element )
+ throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if( Index < 0 || Index >= maRule.GetLevelCount() )
+ throw IndexOutOfBoundsException();
+
+ Sequence< beans::PropertyValue > aSeq;
+
+ if( !( Element >>= aSeq) )
+ throw IllegalArgumentException();
+ setNumberingRuleByIndex( aSeq, Index );
+}
+
+// XIndexAccess
+sal_Int32 SAL_CALL SvxUnoNumberingRules::getCount() throw( RuntimeException )
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ return maRule.GetLevelCount();
+}
+
+Any SAL_CALL SvxUnoNumberingRules::getByIndex( sal_Int32 Index )
+ throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if( Index < 0 || Index >= maRule.GetLevelCount() )
+ throw IndexOutOfBoundsException();
+
+ return Any( getNumberingRuleByIndex(Index) );
+}
+
+//XElementAccess
+Type SAL_CALL SvxUnoNumberingRules::getElementType()
+ throw( RuntimeException )
+{
+ return ::getCppuType(( const Sequence< beans::PropertyValue >*)0);
+}
+
+sal_Bool SAL_CALL SvxUnoNumberingRules::hasElements() throw( RuntimeException )
+{
+ return sal_True;
+}
+
+// XAnyCompare
+sal_Int16 SAL_CALL SvxUnoNumberingRules::compare( const Any& rAny1, const Any& rAny2 ) throw(RuntimeException)
+{
+ return SvxUnoNumberingRules::Compare( rAny1, rAny2 );
+}
+
+// XCloneable
+Reference< XCloneable > SAL_CALL SvxUnoNumberingRules::createClone( ) throw (RuntimeException)
+{
+ return new SvxUnoNumberingRules(maRule);
+}
+
+// XServiceInfo
+sal_Char pSvxUnoNumberingRulesService[sizeof("com.sun.star.text.NumberingRules")] = "com.sun.star.text.NumberingRules";
+
+OUString SAL_CALL SvxUnoNumberingRules::getImplementationName( ) throw(RuntimeException)
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "SvxUnoNumberingRules" ) );
+}
+
+sal_Bool SAL_CALL SvxUnoNumberingRules::supportsService( const OUString& ServiceName ) throw(RuntimeException)
+{
+ return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( pSvxUnoNumberingRulesService ) );
+}
+
+Sequence< OUString > SAL_CALL SvxUnoNumberingRules::getSupportedServiceNames( ) throw(RuntimeException)
+{
+ OUString aService( RTL_CONSTASCII_USTRINGPARAM( pSvxUnoNumberingRulesService ) );
+ Sequence< OUString > aSeq( &aService, 1 );
+ return aSeq;
+}
+
+Sequence<beans::PropertyValue> SvxUnoNumberingRules::getNumberingRuleByIndex( sal_Int32 nIndex) const throw()
+{
+ // NumberingRule aRule;
+ const SvxNumberFormat& rFmt = maRule.GetLevel((sal_uInt16) nIndex);
+ sal_uInt16 nIdx = 0;
+
+ const int nProps = 15;
+ beans::PropertyValue* pArray = new beans::PropertyValue[nProps];
+
+ Any aVal;
+ {
+ aVal <<= rFmt.GetNumberingType();
+ beans::PropertyValue aAlignProp( OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_NUMBERINGTYPE)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+ pArray[nIdx++] = aAlignProp;
+ }
+
+ {
+ SvxAdjust eAdj = rFmt.GetNumAdjust();
+ aVal <<= ConvertUnoAdjust(eAdj);
+ pArray[nIdx++] = beans::PropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_ADJUST)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+ }
+
+ {
+ aVal <<= OUString(rFmt.GetPrefix());
+ beans::PropertyValue aPrefixProp( OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_PREFIX)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+ pArray[nIdx++] = aPrefixProp;
+ }
+
+ {
+ aVal <<= OUString(rFmt.GetSuffix());
+ beans::PropertyValue aSuffixProp( OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_SUFFIX)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+ pArray[nIdx++] = aSuffixProp;
+ }
+
+ {
+ sal_Unicode nCode = rFmt.GetBulletChar();
+ OUString aStr( &nCode, 1 );
+ aVal <<= aStr;
+ beans::PropertyValue aBulletProp( OUString(RTL_CONSTASCII_USTRINGPARAM("BulletChar")), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+ pArray[nIdx++] = aBulletProp;
+ }
+
+ if( rFmt.GetBulletFont() )
+ {
+ awt::FontDescriptor aDesc;
+ SvxUnoFontDescriptor::ConvertFromFont( *rFmt.GetBulletFont(), aDesc );
+ aVal.setValue(&aDesc, ::getCppuType((const awt::FontDescriptor*)0));
+ pArray[nIdx++] = beans::PropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_BULLET_FONT)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+ }
+
+ {
+ const SvxBrushItem* pBrush = rFmt.GetBrush();
+ if(pBrush && pBrush->GetGraphicObject())
+ {
+ const GraphicObject* pGrafObj = pBrush->GetGraphicObject();
+ OUString aURL( RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_GRAPHOBJ_URLPREFIX));
+ aURL += OUString::createFromAscii( pGrafObj->GetUniqueID().GetBuffer() );
+
+ aVal <<= aURL;
+ const beans::PropertyValue aGraphicProp( OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicURL")), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+ pArray[nIdx++] = aGraphicProp;
+ }
+ }
+
+ {
+ const Size aSize( rFmt.GetGraphicSize() );
+ const awt::Size aUnoSize( aSize.Width(), aSize.Height() );
+ aVal <<= aUnoSize;
+ const beans::PropertyValue aGraphicSizeProp(OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicSize")), -1, aVal, beans::PropertyState_DIRECT_VALUE );
+ pArray[nIdx++] = aGraphicSizeProp;
+ }
+
+ aVal <<= (sal_Int16)rFmt.GetStart();
+ pArray[nIdx++] = beans::PropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_START_WITH)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+
+ aVal <<= (sal_Int32)rFmt.GetAbsLSpace();
+ pArray[nIdx++] = beans::PropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_LEFT_MARGIN)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+
+ aVal <<= (sal_Int32)rFmt.GetFirstLineOffset();
+ pArray[nIdx++] = beans::PropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_FIRST_LINE_OFFSET)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+
+ pArray[nIdx++] = beans::PropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("SymbolTextDistance")), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+
+ aVal <<= (sal_Int32)rFmt.GetBulletColor().GetColor();
+ pArray[nIdx++] = beans::PropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_BULLET_COLOR)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+
+ aVal <<= (sal_Int16)rFmt.GetBulletRelSize();
+ pArray[nIdx++] = beans::PropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_BULLET_RELSIZE)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+
+ DBG_ASSERT( nIdx <= nProps, "FixMe: Array uebergelaufen!!!! [CL]" );
+ Sequence< beans::PropertyValue> aSeq(pArray, nIdx);
+
+ delete [] pArray;
+ return aSeq;
+}
+
+void SvxUnoNumberingRules::setNumberingRuleByIndex( const Sequence< beans::PropertyValue >& rProperties, sal_Int32 nIndex)
+ throw( RuntimeException, IllegalArgumentException )
+{
+ SvxNumberFormat aFmt(maRule.GetLevel( (sal_uInt16)nIndex ));
+ const beans::PropertyValue* pPropArray = rProperties.getConstArray();
+ for(int i = 0; i < rProperties.getLength(); i++)
+ {
+ const beans::PropertyValue& rProp = pPropArray[i];
+ const OUString& rPropName = rProp.Name;
+ const Any& aVal = rProp.Value;
+
+ if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_NUMBERINGTYPE)))
+ {
+ sal_Int16 nSet = sal_Int16();
+ aVal >>= nSet;
+
+ switch(nSet)
+ {
+ case SVX_NUM_BITMAP:
+ case SVX_NUM_CHAR_SPECIAL:
+ case SVX_NUM_ROMAN_UPPER:
+ case SVX_NUM_ROMAN_LOWER:
+ case SVX_NUM_CHARS_UPPER_LETTER:
+ case SVX_NUM_CHARS_LOWER_LETTER:
+ case SVX_NUM_ARABIC:
+ case SVX_NUM_NUMBER_NONE:
+ case SVX_NUM_CHARS_UPPER_LETTER_N:
+ case SVX_NUM_CHARS_LOWER_LETTER_N:
+ aFmt.SetNumberingType(nSet);
+ continue;
+ }
+ }
+ else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_PREFIX)))
+ {
+ OUString aPrefix;
+ if( aVal >>= aPrefix )
+ {
+ aFmt.SetPrefix(aPrefix);
+ continue;
+ }
+ }
+ else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_SUFFIX)))
+ {
+ OUString aSuffix;
+ if( aVal >>= aSuffix )
+ {
+ aFmt.SetSuffix(aSuffix);
+ continue;
+ }
+ }
+ else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_BULLETID)))
+ {
+ sal_Int16 nSet = sal_Int16();
+ if( aVal >>= nSet )
+ {
+ if(nSet < 0x100)
+ {
+ aFmt.SetBulletChar(nSet);
+ continue;
+ }
+ }
+ }
+ else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("BulletChar")))
+ {
+ OUString aStr;
+ if( aVal >>= aStr )
+ {
+ if(aStr.getLength())
+ {
+ aFmt.SetBulletChar(aStr[0]);
+ }
+ else
+ {
+ aFmt.SetBulletChar(0);
+ }
+ continue;
+ }
+ }
+ else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_ADJUST)))
+ {
+ sal_Int16 nAdjust = sal_Int16();
+ if( aVal >>= nAdjust )
+ {
+ aFmt.SetNumAdjust(ConvertUnoAdjust( (unsigned short)nAdjust ));
+ continue;
+ }
+ }
+ else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_BULLET_FONT)))
+ {
+ awt::FontDescriptor aDesc;
+ if( aVal >>= aDesc )
+ {
+ Font aFont;
+ SvxUnoFontDescriptor::ConvertToFont( aDesc, aFont );
+ aFmt.SetBulletFont(&aFont);
+ continue;
+ }
+ }
+ else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Graphic")))
+ {
+ Reference< awt::XBitmap > xBmp;
+ if( aVal >>= xBmp )
+ {
+ Graphic aGraf( VCLUnoHelper::GetBitmap( xBmp ) );
+ SvxBrushItem aBrushItem(aGraf, GPOS_AREA, SID_ATTR_BRUSH);
+ aFmt.SetGraphicBrush( &aBrushItem );
+ continue;
+ }
+ }
+ else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("GraphicURL")))
+ {
+ OUString aURL;
+ if( aVal >>= aURL )
+ {
+ GraphicObject aGrafObj( GraphicObject::CreateGraphicObjectFromURL( aURL ) );
+ SvxBrushItem aBrushItem( aGrafObj, GPOS_AREA, SID_ATTR_BRUSH );
+ aFmt.SetGraphicBrush( &aBrushItem );
+ continue;
+ }
+ }
+ else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("GraphicSize")))
+ {
+ awt::Size aUnoSize;
+ if( aVal >>= aUnoSize )
+ {
+ aFmt.SetGraphicSize( Size( aUnoSize.Width, aUnoSize.Height ) );
+ continue;
+ }
+ }
+ else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_START_WITH)))
+ {
+ sal_Int16 nStart = sal_Int16();
+ if( aVal >>= nStart )
+ {
+ aFmt.SetStart( nStart );
+ continue;
+ }
+ }
+ else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_LEFT_MARGIN)))
+ {
+ sal_Int32 nMargin = 0;
+ if( aVal >>= nMargin )
+ {
+ aFmt.SetAbsLSpace((sal_uInt16)nMargin);
+ continue;
+ }
+ }
+ else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_FIRST_LINE_OFFSET)))
+ {
+ sal_Int32 nMargin = 0;
+ if( aVal >>= nMargin )
+ {
+ aFmt.SetFirstLineOffset((sal_uInt16)nMargin);
+ continue;
+ }
+ }
+ else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("SymbolTextDistance")))
+ {
+ sal_Int32 nTextDistance = 0;
+ if( aVal >>= nTextDistance )
+ {
+ aFmt.SetCharTextDistance((sal_uInt16)nTextDistance);
+ continue;
+ }
+ }
+ else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_BULLET_COLOR)))
+ {
+ sal_Int32 nColor = 0;
+ if( aVal >>= nColor )
+ {
+ aFmt.SetBulletColor( (Color) nColor );
+ continue;
+ }
+ }
+ else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_BULLET_RELSIZE)))
+ {
+ sal_Int16 nSize = sal_Int16();
+ if( aVal >>= nSize )
+ {
+ aFmt.SetBulletRelSize( (short)nSize );
+ continue;
+ }
+ }
+ else
+ {
+ continue;
+ }
+
+ throw IllegalArgumentException();
+ }
+
+ // check that we always have a brush item for bitmap numbering
+ if( aFmt.GetNumberingType() == SVX_NUM_BITMAP )
+ {
+ if( NULL == aFmt.GetBrush() )
+ {
+ GraphicObject aGrafObj;
+ SvxBrushItem aBrushItem( aGrafObj, GPOS_AREA, SID_ATTR_BRUSH );
+ aFmt.SetGraphicBrush( &aBrushItem );
+ }
+ }
+ maRule.SetLevel( (sal_uInt16)nIndex, aFmt );
+}
+
+///////////////////////////////////////////////////////////////////////
+
+const SvxNumRule& SvxGetNumRule( Reference< XIndexReplace > xRule ) throw( IllegalArgumentException )
+{
+ SvxUnoNumberingRules* pRule = SvxUnoNumberingRules::getImplementation( xRule );
+ if( pRule == NULL )
+ throw IllegalArgumentException();
+
+ return pRule->getNumRule();
+}
+
+bool SvxGetNumRule( Reference< XIndexReplace > xRule, SvxNumRule& rNumRule )
+{
+ SvxUnoNumberingRules* pRule = SvxUnoNumberingRules::getImplementation( xRule );
+ if( pRule )
+ {
+ rNumRule = pRule->getNumRule();
+ }
+ else if( xRule.is() )
+ {
+ try
+ {
+ pRule = new SvxUnoNumberingRules( rNumRule );
+
+ Reference< XIndexReplace > xDestRule( pRule );
+
+ const sal_Int32 nCount = min( xRule->getCount(), xDestRule->getCount() );
+ sal_Int32 nLevel;
+ for( nLevel = 0; nLevel < nCount; nLevel++ )
+ {
+ xDestRule->replaceByIndex( nLevel, xRule->getByIndex( nLevel ) );
+ }
+
+ rNumRule = pRule->getNumRule();
+ }
+ catch( Exception& )
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////
+com::sun::star::uno::Reference< com::sun::star::container::XIndexReplace > SvxCreateNumRule( const SvxNumRule* pRule ) throw()
+{
+ DBG_ASSERT( pRule, "No default SvxNumRule!" );
+ if( pRule )
+ {
+ return new SvxUnoNumberingRules( *pRule );
+ }
+ else
+ {
+ SvxNumRule aDefaultRule( NUM_BULLET_REL_SIZE|NUM_BULLET_COLOR|NUM_CHAR_TEXT_DISTANCE, 10 , FALSE);
+ return new SvxUnoNumberingRules( aDefaultRule );
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////
+
+class SvxUnoNumberingRulesCompare : public ::cppu::WeakAggImplHelper1< XAnyCompare >
+{
+public:
+ virtual sal_Int16 SAL_CALL compare( const Any& Any1, const Any& Any2 ) throw(RuntimeException);
+};
+
+sal_Int16 SAL_CALL SvxUnoNumberingRulesCompare::compare( const Any& Any1, const Any& Any2 ) throw(RuntimeException)
+{
+ return SvxUnoNumberingRules::Compare( Any1, Any2 );
+}
+
+sal_Int16 SvxUnoNumberingRules::Compare( const Any& Any1, const Any& Any2 )
+{
+ Reference< XIndexReplace > x1( Any1, UNO_QUERY ), x2( Any2, UNO_QUERY );
+ if( x1.is() && x2.is() )
+ {
+ if( x1.get() == x2.get() )
+ return 0;
+
+ SvxUnoNumberingRules* pRule1 = SvxUnoNumberingRules::getImplementation( x1 );
+ if( pRule1 )
+ {
+ SvxUnoNumberingRules* pRule2 = SvxUnoNumberingRules::getImplementation( x2 );
+ if( pRule2 )
+ {
+ const SvxNumRule& rRule1 = pRule1->getNumRule();
+ const SvxNumRule& rRule2 = pRule2->getNumRule();
+
+ const USHORT nLevelCount1 = rRule1.GetLevelCount();
+ const USHORT nLevelCount2 = rRule2.GetLevelCount();
+
+ if( nLevelCount1 == 0 || nLevelCount2 == 0 )
+ return -1;
+
+ for( USHORT i = 0; (i < nLevelCount1) && (i < nLevelCount2); i++ )
+ {
+ if( rRule1.GetLevel(i) != rRule2.GetLevel(i) )
+ return -1;
+ }
+ return 0;
+ }
+ }
+ }
+
+ return -1;
+}
+
+Reference< XAnyCompare > SvxCreateNumRuleCompare() throw()
+{
+ return new SvxUnoNumberingRulesCompare();
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexReplace > SvxCreateNumRule() throw()
+{
+ SvxNumRule aTempRule( 0, 10, false );
+ return SvxCreateNumRule( &aTempRule );
+}
diff --git a/editeng/source/uno/unopracc.cxx b/editeng/source/uno/unopracc.cxx
new file mode 100644
index 0000000000..91e0bc9db7
--- /dev/null
+++ b/editeng/source/uno/unopracc.cxx
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unopracc.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+//------------------------------------------------------------------------
+//
+// Global header
+//
+//------------------------------------------------------------------------
+#include <vos/mutex.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <cppuhelper/weakref.hxx>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <cppuhelper/typeprovider.hxx>
+
+
+//------------------------------------------------------------------------
+//
+// Project-local header
+//
+//------------------------------------------------------------------------
+
+#include <editeng/unopracc.hxx>
+#include <editeng/unoedsrc.hxx>
+
+using namespace ::com::sun::star;
+
+//------------------------------------------------------------------------
+//
+// SvxAccessibleTextPropertySet implementation
+//
+//------------------------------------------------------------------------
+
+SvxAccessibleTextPropertySet::SvxAccessibleTextPropertySet( const SvxEditSource* pEditSrc, const SvxItemPropertySet* pPropSet )
+ : SvxUnoTextRangeBase( pEditSrc, pPropSet )
+{
+}
+
+SvxAccessibleTextPropertySet::~SvxAccessibleTextPropertySet() throw()
+{
+}
+
+uno::Reference< text::XText > SAL_CALL SvxAccessibleTextPropertySet::getText() throw (uno::RuntimeException)
+{
+ // TODO (empty?)
+ return uno::Reference< text::XText > ();
+}
+
+uno::Any SAL_CALL SvxAccessibleTextPropertySet::queryAggregation( const uno::Type & ) throw(uno::RuntimeException)
+{
+ // TODO (empty?)
+ return uno::Any();
+}
+
+uno::Any SAL_CALL SvxAccessibleTextPropertySet::queryInterface( const uno::Type & rType )
+ throw(uno::RuntimeException)
+{
+ return OWeakObject::queryInterface(rType);
+}
+
+void SAL_CALL SvxAccessibleTextPropertySet::acquire()
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+void SAL_CALL SvxAccessibleTextPropertySet::release()
+ throw()
+{
+ OWeakObject::release();
+}
+
+// XTypeProvider
+uno::Sequence< uno::Type > SAL_CALL SvxAccessibleTextPropertySet::getTypes() throw ( uno::RuntimeException )
+{
+ static ::cppu::OTypeCollection* pTypeCollection = NULL ;
+
+ // double-checked locking pattern.
+ if ( pTypeCollection == NULL )
+ {
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control these pointer again ... it can be, that another instance will be faster then these!
+ if ( pTypeCollection == NULL )
+ {
+ // Create a static typecollection ...
+ static ::cppu::OTypeCollection aTypeCollection(
+ ::getCppuType( static_cast< const uno::Reference< beans::XPropertySet >* > (0) ),
+ ::getCppuType( static_cast< const uno::Reference< beans::XMultiPropertySet >* > (0) ),
+ ::getCppuType( static_cast< const uno::Reference< beans::XPropertyState >* > (0) ),
+ ::getCppuType( static_cast< const uno::Reference< lang::XServiceInfo >* > (0) ),
+ ::getCppuType( static_cast< const uno::Reference< lang::XTypeProvider >* > (0) ) );
+
+ // ... and set his address to static pointer!
+ pTypeCollection = &aTypeCollection ;
+ }
+ }
+
+ return pTypeCollection->getTypes() ;
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL SvxAccessibleTextPropertySet::getImplementationId()
+ throw (uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( reinterpret_cast< sal_uInt8* > (aId.getArray()), 0, sal_True );
+ }
+ return aId;
+}
+
+// XServiceInfo
+::rtl::OUString SAL_CALL SAL_CALL SvxAccessibleTextPropertySet::getImplementationName (void) throw (uno::RuntimeException)
+{
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("SvxAccessibleTextPropertySet"));
+}
+
+sal_Bool SAL_CALL SvxAccessibleTextPropertySet::supportsService (const ::rtl::OUString& sServiceName) throw (uno::RuntimeException)
+{
+ // Iterate over all supported service names and return true if on of them
+ // matches the given name.
+ uno::Sequence< ::rtl::OUString> aSupportedServices (
+ getSupportedServiceNames ());
+ for (int i=0; i<aSupportedServices.getLength(); i++)
+ if (sServiceName == aSupportedServices[i])
+ return sal_True;
+ return sal_False;
+}
+
+uno::Sequence< ::rtl::OUString> SAL_CALL SvxAccessibleTextPropertySet::getSupportedServiceNames (void) throw (uno::RuntimeException)
+{
+ // TODO
+ return SvxUnoTextRangeBase::getSupportedServiceNames();
+}
+
+// XServiceName
+::rtl::OUString SAL_CALL SvxAccessibleTextPropertySet::getServiceName() throw (uno::RuntimeException)
+{
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.beans.PropertyValue"));
+}
+
+
diff --git a/editeng/source/uno/unotext.cxx b/editeng/source/uno/unotext.cxx
new file mode 100644
index 0000000000..189af6cb15
--- /dev/null
+++ b/editeng/source/uno/unotext.cxx
@@ -0,0 +1,2720 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unotext.cxx,v $
+ * $Revision: 1.66 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <vcl/svapp.hxx>
+#include <com/sun/star/style/LineSpacing.hpp>
+#include <com/sun/star/text/ControlCharacter.hpp>
+#include <com/sun/star/text/ControlCharacter.hpp>
+#include <com/sun/star/text/XTextField.hdl>
+#include <vos/mutex.hxx>
+#include <svl/itemset.hxx>
+#include <svl/itempool.hxx>
+#include <svl/intitem.hxx>
+#include <svl/eitem.hxx>
+#include <rtl/uuid.h>
+#include <rtl/memory.h>
+
+#include <editeng/fontitem.hxx>
+#include <editeng/tstpitem.hxx>
+#include <editeng/unoprnms.hxx>
+#include <editeng/unotext.hxx>
+#include <editeng/unoedsrc.hxx>
+#include <editeng/unonrule.hxx>
+#include <editeng/unofdesc.hxx>
+#include <editeng/unofield.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/numitem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/unoipset.hxx>
+#include <comphelper/serviceinfohelper.hxx>
+
+using namespace ::rtl;
+using namespace ::vos;
+using namespace ::cppu;
+using namespace ::com::sun::star;
+
+#define QUERYINT( xint ) \
+ if( rType == ::getCppuType((const uno::Reference< xint >*)0) ) \
+ return uno::makeAny(uno::Reference< xint >(this))
+
+const SvxItemPropertySet* ImplGetSvxUnoOutlinerTextCursorSvxPropertySet()
+{
+ static SvxItemPropertySet aTextCursorSvxPropertySet( ImplGetSvxUnoOutlinerTextCursorPropertyMap(), EditEngine::GetGlobalItemPool() );
+ return &aTextCursorSvxPropertySet;
+}
+
+const SfxItemPropertyMapEntry* ImplGetSvxTextPortionPropertyMap()
+{
+ // Propertymap fuer einen Outliner Text
+ static const SfxItemPropertyMapEntry aSvxTextPortionPropertyMap[] =
+ {
+ SVX_UNOEDIT_CHAR_PROPERTIES,
+ SVX_UNOEDIT_FONT_PROPERTIES,
+ SVX_UNOEDIT_OUTLINER_PROPERTIES,
+ SVX_UNOEDIT_PARA_PROPERTIES,
+ {MAP_CHAR_LEN("TextField"), EE_FEATURE_FIELD, &::getCppuType((const uno::Reference< text::XTextField >*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN("TextPortionType"), WID_PORTIONTYPE, &::getCppuType((const ::rtl::OUString*)0), beans::PropertyAttribute::READONLY, 0 },
+ {MAP_CHAR_LEN("TextUserDefinedAttributes"), EE_CHAR_XMLATTRIBS, &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >*)0) , 0, 0},
+ {MAP_CHAR_LEN("ParaUserDefinedAttributes"), EE_PARA_XMLATTRIBS, &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >*)0) , 0, 0},
+ {0,0,0,0,0,0}
+ };
+ return aSvxTextPortionPropertyMap;
+}
+const SvxItemPropertySet* ImplGetSvxTextPortionSvxPropertySet()
+{
+ static SvxItemPropertySet aSvxTextPortionPropertySet( ImplGetSvxTextPortionPropertyMap(), EditEngine::GetGlobalItemPool() );
+ return &aSvxTextPortionPropertySet;
+}
+
+const SfxItemPropertySet* ImplGetSvxTextPortionSfxPropertySet()
+{
+ static SfxItemPropertySet aSvxTextPortionSfxPropertySet( ImplGetSvxTextPortionPropertyMap() );
+ return &aSvxTextPortionSfxPropertySet;
+}
+
+const SfxItemPropertyMapEntry* ImplGetSvxUnoOutlinerTextCursorPropertyMap()
+{
+ // Propertymap fuer einen Outliner Text
+ static const SfxItemPropertyMapEntry aSvxUnoOutlinerTextCursorPropertyMap[] =
+ {
+ SVX_UNOEDIT_CHAR_PROPERTIES,
+ SVX_UNOEDIT_FONT_PROPERTIES,
+ SVX_UNOEDIT_OUTLINER_PROPERTIES,
+ SVX_UNOEDIT_PARA_PROPERTIES,
+ {MAP_CHAR_LEN("TextUserDefinedAttributes"), EE_CHAR_XMLATTRIBS, &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >*)0) , 0, 0},
+ {MAP_CHAR_LEN("ParaUserDefinedAttributes"), EE_PARA_XMLATTRIBS, &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >*)0) , 0, 0},
+ {0,0,0,0,0,0}
+ };
+
+ return aSvxUnoOutlinerTextCursorPropertyMap;
+}
+const SfxItemPropertySet* ImplGetSvxUnoOutlinerTextCursorSfxPropertySet()
+{
+ static SfxItemPropertySet aTextCursorSfxPropertySet( ImplGetSvxUnoOutlinerTextCursorPropertyMap() );
+ return &aTextCursorSfxPropertySet;
+}
+
+// ====================================================================
+// helper fuer Item/Property Konvertierung
+// ====================================================================
+
+void GetSelection( struct ESelection& rSel, SvxTextForwarder* pForwarder ) throw()
+{
+ DBG_ASSERT( pForwarder, "I need a valid SvxTextForwarder!" );
+ if( pForwarder )
+ {
+ sal_Int16 nParaCount = pForwarder->GetParagraphCount();
+ if(nParaCount>0)
+ nParaCount--;
+
+ rSel = ESelection( 0,0, nParaCount, pForwarder->GetTextLen( nParaCount ));
+ }
+}
+
+void CheckSelection( struct ESelection& rSel, SvxTextForwarder* pForwarder ) throw()
+{
+ DBG_ASSERT( pForwarder, "I need a valid SvxTextForwarder!" );
+ if( pForwarder )
+ {
+ if( rSel.nStartPara == 0xffff )
+ {
+ ::GetSelection( rSel, pForwarder );
+ }
+ else
+ {
+ ESelection aMaxSelection;
+ GetSelection( aMaxSelection, pForwarder );
+
+ // check start position
+ if( rSel.nStartPara < aMaxSelection.nStartPara )
+ {
+ rSel.nStartPara = aMaxSelection.nStartPara;
+ rSel.nStartPos = aMaxSelection.nStartPos;
+ }
+ else if( rSel.nStartPara > aMaxSelection.nEndPara )
+ {
+ rSel.nStartPara = aMaxSelection.nEndPara;
+ rSel.nStartPos = aMaxSelection.nEndPos;
+ }
+ else if( rSel.nStartPos > pForwarder->GetTextLen( rSel.nStartPara ) )
+ {
+ rSel.nStartPos = pForwarder->GetTextLen( rSel.nStartPara );
+ }
+
+ // check end position
+ if( rSel.nEndPara < aMaxSelection.nStartPara )
+ {
+ rSel.nEndPara = aMaxSelection.nStartPara;
+ rSel.nEndPos = aMaxSelection.nStartPos;
+ }
+ else if( rSel.nEndPara > aMaxSelection.nEndPara )
+ {
+ rSel.nEndPara = aMaxSelection.nEndPara;
+ rSel.nEndPos = aMaxSelection.nEndPos;
+ }
+ else if( rSel.nEndPos > pForwarder->GetTextLen( rSel.nEndPara ) )
+ {
+ rSel.nEndPos = pForwarder->GetTextLen( rSel.nEndPara );
+ }
+ }
+ }
+}
+
+// ====================================================================
+// class SvxUnoTextRangeBase
+// ====================================================================
+
+#ifdef DEBUG
+class check_me
+{
+public:
+ check_me() : mnAllocNum(0) {};
+ ~check_me();
+
+ void add( SvxUnoTextRangeBase* pRange );
+ void remove( SvxUnoTextRangeBase* pRange );
+
+ std::list< std::pair< sal_uInt32, SvxUnoTextRangeBase* > > maRanges;
+ sal_uInt32 mnAllocNum;
+};
+
+void check_me::add( SvxUnoTextRangeBase* pRange )
+{
+ maRanges.push_back( std::pair< sal_uInt32, SvxUnoTextRangeBase* >( mnAllocNum++, pRange ) );
+}
+
+void check_me::remove( SvxUnoTextRangeBase* pRange )
+{
+ std::list< std::pair< sal_uInt32, SvxUnoTextRangeBase* > >::iterator aIter;
+ for( aIter = maRanges.begin(); aIter != maRanges.end(); aIter++ )
+ {
+ if( pRange == (*aIter).second )
+ {
+ maRanges.erase( aIter );
+ break;
+ }
+ }
+}
+
+check_me::~check_me()
+{
+ if( !maRanges.empty() )
+ {
+ DBG_ERROR("living text range detected!");
+ std::list< std::pair< sal_uInt32, SvxUnoTextRangeBase* > >::iterator aIter;
+ for( aIter = maRanges.begin(); aIter != maRanges.end(); aIter++ )
+ {
+ sal_Int32 nAllocNum;
+ SvxUnoTextRangeBase* pRange;
+ nAllocNum = (*aIter).first;
+ pRange = (*aIter).second;
+ }
+ }
+}
+
+static check_me gNumRanges;
+#endif
+
+UNO3_GETIMPLEMENTATION_IMPL( SvxUnoTextRangeBase );
+
+SvxUnoTextRangeBase::SvxUnoTextRangeBase( const SvxItemPropertySet* _pSet ) throw()
+: mpEditSource(NULL) , mpPropSet(_pSet)
+{
+#ifdef DEBUG
+ gNumRanges.add(this);
+#endif
+}
+
+SvxUnoTextRangeBase::SvxUnoTextRangeBase( const SvxEditSource* pSource, const SvxItemPropertySet* _pSet ) throw()
+: mpPropSet(_pSet)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ DBG_ASSERT(pSource,"SvxUnoTextRangeBase: I need a valid SvxEditSource!");
+
+ mpEditSource = pSource->Clone();
+ ESelection aSelection;
+ ::GetSelection( aSelection, mpEditSource->GetTextForwarder() );
+ SetSelection( aSelection );
+
+ if( mpEditSource )
+ mpEditSource->addRange( this );
+#ifdef DEBUG
+ gNumRanges.add(this);
+#endif
+}
+
+SvxUnoTextRangeBase::SvxUnoTextRangeBase( const SvxUnoTextRangeBase& rRange ) throw()
+: text::XTextRange()
+, beans::XPropertySet()
+, beans::XMultiPropertySet()
+, beans::XMultiPropertyStates()
+, beans::XPropertyState()
+, lang::XServiceInfo()
+, text::XTextRangeCompare()
+, lang::XUnoTunnel()
+, mpPropSet(rRange.getPropertySet())
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ mpEditSource = rRange.mpEditSource ? rRange.mpEditSource->Clone() : NULL;
+
+ SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : NULL;
+ if( pForwarder )
+ {
+ maSelection = rRange.maSelection;
+ CheckSelection( maSelection, pForwarder );
+ }
+
+ if( mpEditSource )
+ mpEditSource->addRange( this );
+
+#ifdef DEBUG
+ gNumRanges.add(this);
+#endif
+}
+
+SvxUnoTextRangeBase::~SvxUnoTextRangeBase() throw()
+{
+#ifdef DEBUG
+ gNumRanges.remove(this);
+#endif
+
+ if( mpEditSource )
+ mpEditSource->removeRange( this );
+
+ delete mpEditSource;
+}
+
+void SvxUnoTextRangeBase::SetEditSource( SvxEditSource* pSource ) throw()
+{
+ DBG_ASSERT(pSource,"SvxUnoTextRangeBase: I need a valid SvxEditSource!");
+ DBG_ASSERT(mpEditSource==NULL,"SvxUnoTextRangeBase::SetEditSource called while SvxEditSource already set" );
+
+ mpEditSource = pSource;
+
+ maSelection.nStartPara = 0xffff;
+
+ if( mpEditSource )
+ mpEditSource->addRange( this );
+}
+
+/** puts a field item with a copy of the given FieldData into the itemset
+ corresponding with this range */
+void SvxUnoTextRangeBase::attachField( const SvxFieldData* pData ) throw()
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if( pData )
+ {
+ SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : NULL;
+ if( pForwarder )
+ {
+ SvxFieldItem aField( *pData, EE_FEATURE_FIELD );
+ pForwarder->QuickInsertField( aField, maSelection );
+ }
+ }
+}
+
+void SvxUnoTextRangeBase::SetSelection( const ESelection& rSelection ) throw()
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ maSelection = rSelection;
+ CheckSelection( maSelection, mpEditSource->GetTextForwarder() );
+}
+
+// Interface XTextRange ( XText )
+
+uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextRangeBase::getStart(void)
+ throw( uno::RuntimeException )
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ uno::Reference< text::XTextRange > xRange;
+
+ SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : NULL;
+ if( pForwarder )
+ {
+
+ CheckSelection( maSelection, pForwarder );
+
+ SvxUnoTextBase* pText = SvxUnoTextBase::getImplementation( getText() );
+
+ if(pText == NULL)
+ throw uno::RuntimeException();
+
+ SvxUnoTextRange* pRange = new SvxUnoTextRange( *pText );
+ xRange = pRange;
+
+ ESelection aNewSel = maSelection;
+ aNewSel.nEndPara = aNewSel.nStartPara;
+ aNewSel.nEndPos = aNewSel.nStartPos;
+ pRange->SetSelection( aNewSel );
+ }
+
+ return xRange;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextRangeBase::getEnd(void)
+ throw( uno::RuntimeException )
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ uno::Reference< text::XTextRange > xRet;
+
+ SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : NULL;
+ if( pForwarder )
+ {
+ CheckSelection( maSelection, pForwarder );
+
+ SvxUnoTextBase* pText = SvxUnoTextBase::getImplementation( getText() );
+
+ if(pText == NULL)
+ throw uno::RuntimeException();
+
+ SvxUnoTextRange* pNew = new SvxUnoTextRange( *pText );
+ xRet = pNew;
+
+ ESelection aNewSel = maSelection;
+ aNewSel.nStartPara = aNewSel.nEndPara;
+ aNewSel.nStartPos = aNewSel.nEndPos;
+ pNew->SetSelection( aNewSel );
+ }
+ return xRet;
+}
+
+OUString SAL_CALL SvxUnoTextRangeBase::getString(void)
+ throw( uno::RuntimeException )
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : NULL;
+ if( pForwarder )
+ {
+ CheckSelection( maSelection, pForwarder );
+
+ return pForwarder->GetText( maSelection );
+ }
+ else
+ {
+ const OUString aEmpty;
+ return aEmpty;
+ }
+}
+
+void SAL_CALL SvxUnoTextRangeBase::setString(const OUString& aString)
+ throw( uno::RuntimeException )
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : NULL;
+ if( pForwarder )
+ {
+ CheckSelection( maSelection, pForwarder );
+
+ String aConverted( aString );
+ aConverted.ConvertLineEnd( LINEEND_LF ); // Zeilenenden nur einfach zaehlen
+
+ pForwarder->QuickInsertText( aConverted, maSelection );
+ mpEditSource->UpdateData();
+
+ // Selektion anpassen
+ //! Wenn die EditEngine bei QuickInsertText die Selektion zurueckgeben wuerde,
+ //! waer's einfacher...
+ CollapseToStart();
+
+ sal_uInt16 nLen = aConverted.Len();
+ if (nLen)
+ GoRight( nLen, sal_True );
+ }
+}
+
+// Interface beans::XPropertySet
+uno::Reference< beans::XPropertySetInfo > SAL_CALL SvxUnoTextRangeBase::getPropertySetInfo(void)
+ throw( uno::RuntimeException )
+{
+ return mpPropSet->getPropertySetInfo();
+}
+
+void SAL_CALL SvxUnoTextRangeBase::setPropertyValue(const OUString& PropertyName, const uno::Any& aValue)
+ throw( beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException )
+{
+ _setPropertyValue( PropertyName, aValue, -1 );
+}
+
+void SAL_CALL SvxUnoTextRangeBase::_setPropertyValue( const OUString& PropertyName, const uno::Any& aValue, sal_Int32 nPara )
+ throw( beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException )
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : NULL;
+ if( pForwarder )
+ {
+
+ CheckSelection( maSelection, pForwarder );
+
+ const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry(PropertyName );
+ if ( pMap )
+ {
+ ESelection aSel( GetSelection() );
+ sal_Bool bParaAttrib = (pMap->nWID >= EE_PARA_START) && ( pMap->nWID <= EE_PARA_END );
+
+ if( nPara == -1 && !bParaAttrib )
+ {
+ SfxItemSet aOldSet( pForwarder->GetAttribs( aSel ) );
+ // we have a selection and no para attribute
+ SfxItemSet aNewSet( *aOldSet.GetPool(), aOldSet.GetRanges() );
+
+ setPropertyValue( pMap, aValue, maSelection, aOldSet, aNewSet );
+
+
+ pForwarder->QuickSetAttribs( aNewSet, GetSelection() );
+ }
+ else
+ {
+ sal_Int32 nEndPara;
+
+ if( nPara == -1 )
+ {
+ nPara = aSel.nStartPara;
+ nEndPara = aSel.nEndPara;
+ }
+ else
+ {
+ // only one paragraph
+ nEndPara = nPara;
+ }
+
+ while( nPara <= nEndPara )
+ {
+ // we have a paragraph
+ SfxItemSet aSet( pForwarder->GetParaAttribs( (USHORT)nPara ) );
+ setPropertyValue( pMap, aValue, maSelection, aSet, aSet );
+ pForwarder->SetParaAttribs( (USHORT)nPara, aSet );
+ nPara++;
+ }
+ }
+
+ GetEditSource()->UpdateData();
+ return;
+ }
+ }
+
+ throw beans::UnknownPropertyException();
+}
+
+void SvxUnoTextRangeBase::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rValue, const ESelection& rSelection, const SfxItemSet& rOldSet, SfxItemSet& rNewSet ) throw( beans::UnknownPropertyException, lang::IllegalArgumentException )
+{
+ if(!SetPropertyValueHelper( rOldSet, pMap, rValue, rNewSet, &rSelection, GetEditSource() ))
+ {
+ // Fuer Teile von zusammengesetzten Items mit mehreren Properties (z.B. Hintergrund)
+ // muss vorher das alte Item aus dem Dokument geholt werden
+ rNewSet.Put(rOldSet.Get(pMap->nWID)); // altes Item in neuen Set
+ mpPropSet->setPropertyValue(pMap, rValue, rNewSet, false);
+ }
+}
+
+sal_Bool SvxUnoTextRangeBase::SetPropertyValueHelper( const SfxItemSet&, const SfxItemPropertySimpleEntry* pMap, const uno::Any& aValue, SfxItemSet& rNewSet, const ESelection* pSelection /* = NULL */, SvxEditSource* pEditSource /* = NULL*/ ) throw( uno::RuntimeException )
+{
+ switch( pMap->nWID )
+ {
+ case WID_FONTDESC:
+ {
+ awt::FontDescriptor aDesc;
+ if(aValue >>= aDesc)
+ {
+ SvxUnoFontDescriptor::FillItemSet( aDesc, rNewSet );
+ return sal_True;
+ }
+ }
+ break;
+
+ case EE_PARA_NUMBULLET:
+ {
+ uno::Reference< container::XIndexReplace > xRule;
+ if( !aValue.hasValue() || ((aValue >>= xRule) && !xRule.is()) )
+ return sal_True;
+
+ return sal_False;
+ }
+
+ case WID_NUMLEVEL:
+ {
+ SvxTextForwarder* pForwarder = pEditSource? pEditSource->GetTextForwarder() : NULL;
+ if(pForwarder && pSelection)
+ {
+ sal_Int16 nLevel = sal_Int16();
+ if( aValue >>= nLevel )
+ {
+ // #101004# Call interface method instead of unsafe cast
+ if(! pForwarder->SetDepth( pSelection->nStartPara, nLevel ) )
+ throw lang::IllegalArgumentException();
+
+ return sal_True;
+ }
+ }
+ }
+ break;
+ case WID_NUMBERINGSTARTVALUE:
+ {
+ SvxTextForwarder* pForwarder = pEditSource? pEditSource->GetTextForwarder() : NULL;
+ if(pForwarder && pSelection)
+ {
+ sal_Int16 nStartValue = -1;
+ if( aValue >>= nStartValue )
+ {
+ pForwarder->SetNumberingStartValue( pSelection->nStartPara, nStartValue );
+ return sal_True;
+ }
+ }
+ }
+ break;
+ case WID_PARAISNUMBERINGRESTART:
+ {
+ SvxTextForwarder* pForwarder = pEditSource? pEditSource->GetTextForwarder() : NULL;
+ if(pForwarder && pSelection)
+ {
+ sal_Bool bParaIsNumberingRestart = sal_False;
+ if( aValue >>= bParaIsNumberingRestart )
+ {
+ pForwarder->SetParaIsNumberingRestart( pSelection->nStartPara, bParaIsNumberingRestart );
+ return sal_True;
+ }
+ }
+ }
+ break;
+ case EE_PARA_BULLETSTATE:
+ {
+ sal_Bool bBullet = sal_True;
+ if( aValue >>= bBullet )
+ {
+ SfxBoolItem aItem( EE_PARA_BULLETSTATE, bBullet );
+ rNewSet.Put(aItem);
+ return sal_True;
+ }
+ }
+ break;
+
+ default:
+ return sal_False;
+ }
+
+ throw lang::IllegalArgumentException();
+}
+
+uno::Any SAL_CALL SvxUnoTextRangeBase::getPropertyValue(const OUString& PropertyName)
+ throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+ return _getPropertyValue( PropertyName, -1 );
+}
+
+uno::Any SAL_CALL SvxUnoTextRangeBase::_getPropertyValue(const OUString& PropertyName, sal_Int32 nPara )
+ throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ uno::Any aAny;
+
+ SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : NULL;
+ if( pForwarder )
+ {
+ const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry(PropertyName );
+ if( pMap )
+ {
+ SfxItemSet* pAttribs = NULL;
+ if( nPara != -1 )
+ pAttribs = pForwarder->GetParaAttribs( (USHORT)nPara ).Clone();
+ else
+ pAttribs = pForwarder->GetAttribs( GetSelection() ).Clone();
+
+ // Dontcare durch Default ersetzen, damit man immer eine Reflection hat
+ pAttribs->ClearInvalidItems();
+
+ getPropertyValue( pMap, aAny, *pAttribs );
+
+ delete pAttribs;
+ return aAny;
+ }
+ }
+
+ throw beans::UnknownPropertyException();
+}
+
+void SvxUnoTextRangeBase::getPropertyValue( const SfxItemPropertySimpleEntry* pMap, uno::Any& rAny, const SfxItemSet& rSet ) throw( beans::UnknownPropertyException )
+{
+ switch( pMap->nWID )
+ {
+ case EE_FEATURE_FIELD:
+ if ( rSet.GetItemState( EE_FEATURE_FIELD, sal_False ) == SFX_ITEM_SET )
+ {
+ SvxFieldItem* pItem = (SvxFieldItem*)rSet.GetItem( EE_FEATURE_FIELD );
+ const SvxFieldData* pData = pItem->GetField();
+ uno::Reference< text::XTextRange > xAnchor( this );
+
+ // get presentation string for field
+ Color* pTColor = NULL;
+ Color* pFColor = NULL;
+
+ SvxTextForwarder* pForwarder = mpEditSource->GetTextForwarder();
+ OUString aPresentation( pForwarder->CalcFieldValue( SvxFieldItem(*pData, EE_FEATURE_FIELD), maSelection.nStartPara, maSelection.nStartPos, pTColor, pFColor ) );
+
+ delete pTColor;
+ delete pFColor;
+
+ uno::Reference< text::XTextField > xField( new SvxUnoTextField( xAnchor, aPresentation, pData ) );
+ rAny <<= xField;
+ }
+ break;
+
+ case WID_PORTIONTYPE:
+ if ( rSet.GetItemState( EE_FEATURE_FIELD, sal_False ) == SFX_ITEM_SET )
+ {
+ OUString aType( RTL_CONSTASCII_USTRINGPARAM("TextField") );
+ rAny <<= aType;
+ }
+ else
+ {
+ OUString aType( RTL_CONSTASCII_USTRINGPARAM("Text") );
+ rAny <<= aType;
+ }
+ break;
+
+ default:
+ if(!GetPropertyValueHelper( *((SfxItemSet*)(&rSet)), pMap, rAny, &maSelection, GetEditSource() ))
+ rAny = mpPropSet->getPropertyValue(pMap, rSet, false, false );
+ }
+}
+
+sal_Bool SvxUnoTextRangeBase::GetPropertyValueHelper( SfxItemSet& rSet, const SfxItemPropertySimpleEntry* pMap, uno::Any& aAny, const ESelection* pSelection /* = NULL */, SvxEditSource* pEditSource /* = NULL */ )
+ throw( uno::RuntimeException )
+{
+ switch( pMap->nWID )
+ {
+ case WID_FONTDESC:
+ {
+ awt::FontDescriptor aDesc;
+ SvxUnoFontDescriptor::FillFromItemSet( rSet, aDesc );
+ aAny <<= aDesc;
+ }
+ break;
+
+ case EE_PARA_NUMBULLET:
+ {
+ if((rSet.GetItemState( EE_PARA_NUMBULLET, sal_True ) & (SFX_ITEM_SET|SFX_ITEM_DEFAULT)) == 0)
+ throw uno::RuntimeException();
+
+ SvxNumBulletItem* pBulletItem = (SvxNumBulletItem*)rSet.GetItem( EE_PARA_NUMBULLET, sal_True );
+
+ if( pBulletItem == NULL )
+ throw uno::RuntimeException();
+
+ aAny <<= SvxCreateNumRule( pBulletItem->GetNumRule() );
+ }
+ break;
+
+ case WID_NUMLEVEL:
+ {
+ SvxTextForwarder* pForwarder = pEditSource? pEditSource->GetTextForwarder() : NULL;
+ if(pForwarder && pSelection)
+ {
+ sal_Int16 nLevel = pForwarder->GetDepth( pSelection->nStartPara );
+ if( nLevel >= 0 )
+ aAny <<= nLevel;
+ }
+ }
+ break;
+ case WID_NUMBERINGSTARTVALUE:
+ {
+ SvxTextForwarder* pForwarder = pEditSource? pEditSource->GetTextForwarder() : NULL;
+ if(pForwarder && pSelection)
+ aAny <<= pForwarder->GetNumberingStartValue( pSelection->nStartPara );
+ }
+ break;
+ case WID_PARAISNUMBERINGRESTART:
+ {
+ SvxTextForwarder* pForwarder = pEditSource? pEditSource->GetTextForwarder() : NULL;
+ if(pForwarder && pSelection)
+ aAny <<= pForwarder->IsParaIsNumberingRestart( pSelection->nStartPara );
+ }
+ break;
+
+ case EE_PARA_BULLETSTATE:
+ {
+ sal_Bool bState = sal_False;
+ if( rSet.GetItemState( EE_PARA_BULLETSTATE, sal_True ) & (SFX_ITEM_SET|SFX_ITEM_DEFAULT))
+ {
+ SfxBoolItem* pItem = (SfxBoolItem*)rSet.GetItem( EE_PARA_BULLETSTATE, sal_True );
+ bState = pItem->GetValue() ? sal_True : sal_False;
+ }
+
+ aAny <<= bState;
+ }
+ break;
+ default:
+
+ return sal_False;
+ }
+
+ return sal_True;
+}
+
+// wird (noch) nicht unterstuetzt
+void SAL_CALL SvxUnoTextRangeBase::addPropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >& ) throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) {}
+void SAL_CALL SvxUnoTextRangeBase::removePropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >& ) throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) {}
+void SAL_CALL SvxUnoTextRangeBase::addVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >& ) throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) {}
+void SAL_CALL SvxUnoTextRangeBase::removeVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >& ) throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) {}
+
+// XMultiPropertySet
+void SAL_CALL SvxUnoTextRangeBase::setPropertyValues( const uno::Sequence< ::rtl::OUString >& aPropertyNames, const uno::Sequence< uno::Any >& aValues ) throw (beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ _setPropertyValues( aPropertyNames, aValues, -1 );
+}
+
+void SAL_CALL SvxUnoTextRangeBase::_setPropertyValues( const uno::Sequence< ::rtl::OUString >& aPropertyNames, const uno::Sequence< uno::Any >& aValues, sal_Int32 nPara ) throw (beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : NULL;
+ if( pForwarder )
+ {
+ CheckSelection( maSelection, pForwarder );
+
+ ESelection aSel( GetSelection() );
+
+ const OUString* pPropertyNames = aPropertyNames.getConstArray();
+ const uno::Any* pValues = aValues.getConstArray();
+ sal_Int32 nCount = aPropertyNames.getLength();
+
+ sal_Int32 nEndPara = nPara;
+ sal_Int32 nTempPara = nPara;
+
+ if( nTempPara == -1 )
+ {
+ nTempPara = aSel.nStartPara;
+ nEndPara = aSel.nEndPara;
+ }
+
+ SfxItemSet* pOldAttrSet = NULL;
+ SfxItemSet* pNewAttrSet = NULL;
+
+ SfxItemSet* pOldParaSet = NULL;
+ SfxItemSet* pNewParaSet = NULL;
+
+ for( ; nCount; nCount--, pPropertyNames++, pValues++ )
+ {
+ const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry( *pPropertyNames );
+
+ if( pMap )
+ {
+ sal_Bool bParaAttrib = (pMap->nWID >= EE_PARA_START) && ( pMap->nWID <= EE_PARA_END );
+
+ if( (nPara == -1) && !bParaAttrib )
+ {
+ if( NULL == pNewAttrSet )
+ {
+ const SfxItemSet aSet( pForwarder->GetAttribs( aSel ) );
+ pOldAttrSet = new SfxItemSet( aSet );
+ pNewAttrSet = new SfxItemSet( *pOldAttrSet->GetPool(), pOldAttrSet->GetRanges() );
+ }
+
+ setPropertyValue( pMap, *pValues, GetSelection(), *pOldAttrSet, *pNewAttrSet );
+
+ if( pMap->nWID >= EE_ITEMS_START && pMap->nWID <= EE_ITEMS_END )
+ {
+ const SfxPoolItem* pItem;
+ if( pNewAttrSet->GetItemState( pMap->nWID, sal_True, &pItem ) == SFX_ITEM_SET )
+ {
+ pOldAttrSet->Put( *pItem );
+ }
+ }
+ }
+ else
+ {
+ if( NULL == pNewParaSet )
+ {
+ const SfxItemSet aSet( pForwarder->GetParaAttribs( (USHORT)nTempPara ) );
+ pOldParaSet = new SfxItemSet( aSet );
+ pNewParaSet = new SfxItemSet( *pOldParaSet->GetPool(), pOldParaSet->GetRanges() );
+ }
+
+ setPropertyValue( pMap, *pValues, GetSelection(), *pOldParaSet, *pNewParaSet );
+
+ if( pMap->nWID >= EE_ITEMS_START && pMap->nWID <= EE_ITEMS_END )
+ {
+ const SfxPoolItem* pItem;
+ if( pNewParaSet->GetItemState( pMap->nWID, sal_True, &pItem ) == SFX_ITEM_SET )
+ {
+ pOldParaSet->Put( *pItem );
+ }
+ }
+
+ }
+ }
+ }
+
+ sal_Bool bNeedsUpdate = sal_False;
+
+ if( pNewParaSet )
+ {
+ if( pNewParaSet->Count() )
+ {
+ while( nTempPara <= nEndPara )
+ {
+ SfxItemSet aSet( pForwarder->GetParaAttribs( (USHORT)nTempPara ) );
+ aSet.Put( *pNewParaSet );
+ pForwarder->SetParaAttribs( (USHORT)nTempPara, aSet );
+ nTempPara++;
+ }
+ bNeedsUpdate = sal_True;
+ }
+
+ delete pNewParaSet;
+ delete pOldParaSet;
+ }
+
+ if( pNewAttrSet )
+ {
+ if( pNewAttrSet->Count() )
+ {
+ pForwarder->QuickSetAttribs( *pNewAttrSet, GetSelection() );
+ bNeedsUpdate = sal_True;
+ }
+ delete pNewAttrSet;
+ delete pOldAttrSet;
+
+ }
+
+ if( bNeedsUpdate )
+ GetEditSource()->UpdateData();
+ }
+}
+
+uno::Sequence< uno::Any > SAL_CALL SvxUnoTextRangeBase::getPropertyValues( const uno::Sequence< ::rtl::OUString >& aPropertyNames ) throw (uno::RuntimeException)
+{
+ return _getPropertyValues( aPropertyNames, -1 );
+}
+
+uno::Sequence< uno::Any > SAL_CALL SvxUnoTextRangeBase::_getPropertyValues( const uno::Sequence< ::rtl::OUString >& aPropertyNames, sal_Int32 nPara ) throw (uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ sal_Int32 nCount = aPropertyNames.getLength();
+
+
+ uno::Sequence< uno::Any > aValues( nCount );
+
+ SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : NULL;
+ if( pForwarder )
+ {
+ SfxItemSet* pAttribs = NULL;
+ if( nPara != -1 )
+ pAttribs = pForwarder->GetParaAttribs( (USHORT)nPara ).Clone();
+ else
+ pAttribs = pForwarder->GetAttribs( GetSelection() ).Clone();
+
+ pAttribs->ClearInvalidItems();
+
+ const OUString* pPropertyNames = aPropertyNames.getConstArray();
+ uno::Any* pValues = aValues.getArray();
+
+ for( ; nCount; nCount--, pPropertyNames++, pValues++ )
+ {
+ const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry( *pPropertyNames );
+ if( pMap )
+ {
+ getPropertyValue( pMap, *pValues, *pAttribs );
+ }
+ }
+
+ delete pAttribs;
+
+ }
+
+ return aValues;
+}
+
+void SAL_CALL SvxUnoTextRangeBase::addPropertiesChangeListener( const uno::Sequence< ::rtl::OUString >& , const uno::Reference< beans::XPropertiesChangeListener >& ) throw (uno::RuntimeException)
+{
+}
+
+void SAL_CALL SvxUnoTextRangeBase::removePropertiesChangeListener( const uno::Reference< beans::XPropertiesChangeListener >& ) throw (uno::RuntimeException)
+{
+}
+
+void SAL_CALL SvxUnoTextRangeBase::firePropertiesChangeEvent( const uno::Sequence< ::rtl::OUString >& , const uno::Reference< beans::XPropertiesChangeListener >& ) throw (uno::RuntimeException)
+{
+}
+
+// beans::XPropertyState
+beans::PropertyState SAL_CALL SvxUnoTextRangeBase::getPropertyState( const OUString& PropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ return _getPropertyState( PropertyName, -1 );
+}
+
+static sal_uInt16 aSvxUnoFontDescriptorWhichMap[] = { EE_CHAR_FONTINFO, EE_CHAR_FONTHEIGHT, EE_CHAR_ITALIC,
+ EE_CHAR_UNDERLINE, EE_CHAR_WEIGHT, EE_CHAR_STRIKEOUT,
+ EE_CHAR_WLM, 0 };
+
+beans::PropertyState SAL_CALL SvxUnoTextRangeBase::_getPropertyState(const SfxItemPropertySimpleEntry* pMap, sal_Int32 nPara)
+ throw( beans::UnknownPropertyException, uno::RuntimeException )
+{
+ if ( pMap )
+ {
+ SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : NULL;
+ if( pForwarder )
+ {
+ SfxItemState eItemState = SFX_ITEM_UNKNOWN;
+ sal_uInt16 nWID = 0;
+
+ switch( pMap->nWID )
+ {
+ case WID_FONTDESC:
+ {
+ sal_uInt16* pWhichId = aSvxUnoFontDescriptorWhichMap;
+ SfxItemState eTempItemState;
+ while( *pWhichId )
+ {
+ if(nPara != -1)
+ eTempItemState = pForwarder->GetItemState( (USHORT)nPara, *pWhichId );
+ else
+ eTempItemState = pForwarder->GetItemState( GetSelection(), *pWhichId );
+
+ switch( eTempItemState )
+ {
+ case SFX_ITEM_DISABLED:
+ case SFX_ITEM_DONTCARE:
+ eItemState = SFX_ITEM_DONTCARE;
+ break;
+
+ case SFX_ITEM_DEFAULT:
+ if( eItemState != SFX_ITEM_DEFAULT )
+ {
+ if( eItemState == SFX_ITEM_UNKNOWN )
+ eItemState = SFX_ITEM_DEFAULT;
+ }
+ break;
+
+ case SFX_ITEM_READONLY:
+ case SFX_ITEM_SET:
+ if( eItemState != SFX_ITEM_SET )
+ {
+ if( eItemState == SFX_ITEM_UNKNOWN )
+ eItemState = SFX_ITEM_SET;
+ }
+ break;
+ default:
+ throw beans::UnknownPropertyException();
+ }
+
+ pWhichId++;
+ }
+ }
+ break;
+
+ case WID_NUMLEVEL:
+ case WID_NUMBERINGSTARTVALUE:
+ case WID_PARAISNUMBERINGRESTART:
+ eItemState = SFX_ITEM_SET;
+ break;
+
+ default:
+ nWID = pMap->nWID;
+ }
+
+ if( nWID != 0 )
+ {
+ if( nPara != -1 )
+ eItemState = pForwarder->GetItemState( (USHORT)nPara, nWID );
+ else
+ eItemState = pForwarder->GetItemState( GetSelection(), nWID );
+ }
+
+ switch( eItemState )
+ {
+ case SFX_ITEM_DONTCARE:
+ case SFX_ITEM_DISABLED:
+ return beans::PropertyState_AMBIGUOUS_VALUE;
+ case SFX_ITEM_READONLY:
+ case SFX_ITEM_SET:
+ return beans::PropertyState_DIRECT_VALUE;
+ case SFX_ITEM_DEFAULT:
+ return beans::PropertyState_DEFAULT_VALUE;
+// case SFX_ITEM_UNKNOWN:
+ }
+ }
+ }
+ throw beans::UnknownPropertyException();
+}
+
+beans::PropertyState SAL_CALL SvxUnoTextRangeBase::_getPropertyState(const OUString& PropertyName, sal_Int32 nPara /* = -1 */)
+ throw( beans::UnknownPropertyException, uno::RuntimeException )
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ return _getPropertyState( mpPropSet->getPropertyMapEntry( PropertyName ), nPara);
+}
+
+uno::Sequence< beans::PropertyState > SAL_CALL SvxUnoTextRangeBase::getPropertyStates( const uno::Sequence< OUString >& aPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ return _getPropertyStates( aPropertyName, -1 );
+}
+
+uno::Sequence< beans::PropertyState > SvxUnoTextRangeBase::_getPropertyStates(const uno::Sequence< OUString >& PropertyName, sal_Int32 nPara /* = -1 */)
+ throw( beans::UnknownPropertyException, uno::RuntimeException )
+{
+ const sal_Int32 nCount = PropertyName.getLength();
+ const OUString* pNames = PropertyName.getConstArray();
+
+ uno::Sequence< beans::PropertyState > aRet( nCount );
+ beans::PropertyState* pState = aRet.getArray();
+
+ SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : NULL;
+ if( pForwarder )
+ {
+ SfxItemSet* pSet = NULL;
+ if( nPara != -1 )
+ {
+ pSet = new SfxItemSet( pForwarder->GetParaAttribs( (USHORT)nPara ) );
+ }
+ else
+ {
+ ESelection aSel( GetSelection() );
+ CheckSelection( aSel, pForwarder );
+ pSet = new SfxItemSet( pForwarder->GetAttribs( aSel, EditEngineAttribs_OnlyHard ) );
+ }
+
+ sal_Bool bUnknownPropertyFound = sal_False;
+ for( sal_Int32 nIdx = 0; nIdx < nCount; nIdx++ )
+ {
+ const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry( *pNames++ );
+ if( NULL == pMap )
+ {
+ bUnknownPropertyFound = sal_True;
+ break;
+ }
+ bUnknownPropertyFound = !_getOnePropertyStates(pSet, pMap, *pState++);
+ }
+
+ delete pSet;
+
+ if( bUnknownPropertyFound )
+ throw beans::UnknownPropertyException();
+ }
+
+ return aRet;
+}
+
+sal_Bool SvxUnoTextRangeBase::_getOnePropertyStates(const SfxItemSet* pSet, const SfxItemPropertySimpleEntry* pMap, beans::PropertyState& rState)
+{
+ sal_Bool bUnknownPropertyFound = sal_False;
+ if(pSet && pMap)
+ {
+ SfxItemState eItemState = SFX_ITEM_UNKNOWN;
+ sal_uInt16 nWID = 0;
+
+ switch( pMap->nWID )
+ {
+ case WID_FONTDESC:
+ {
+ sal_uInt16* pWhichId = aSvxUnoFontDescriptorWhichMap;
+ SfxItemState eTempItemState;
+ while( *pWhichId )
+ {
+ eTempItemState = pSet->GetItemState( *pWhichId );
+
+ switch( eTempItemState )
+ {
+ case SFX_ITEM_DISABLED:
+ case SFX_ITEM_DONTCARE:
+ eItemState = SFX_ITEM_DONTCARE;
+ break;
+
+ case SFX_ITEM_DEFAULT:
+ if( eItemState != SFX_ITEM_DEFAULT )
+ {
+ if( eItemState == SFX_ITEM_UNKNOWN )
+ eItemState = SFX_ITEM_DEFAULT;
+ }
+ break;
+
+ case SFX_ITEM_READONLY:
+ case SFX_ITEM_SET:
+ if( eItemState != SFX_ITEM_SET )
+ {
+ if( eItemState == SFX_ITEM_UNKNOWN )
+ eItemState = SFX_ITEM_SET;
+ }
+ break;
+ default:
+ bUnknownPropertyFound = sal_True;
+ break;
+ }
+
+ pWhichId++;
+ }
+ }
+ break;
+
+ case WID_NUMLEVEL:
+ case WID_NUMBERINGSTARTVALUE:
+ case WID_PARAISNUMBERINGRESTART:
+ eItemState = SFX_ITEM_SET;
+ break;
+
+ default:
+ nWID = pMap->nWID;
+ }
+
+ if( bUnknownPropertyFound )
+ return !bUnknownPropertyFound;
+
+ if( nWID != 0 )
+ eItemState = pSet->GetItemState( nWID, sal_False );
+
+ switch( eItemState )
+ {
+ case SFX_ITEM_READONLY:
+ case SFX_ITEM_SET:
+ rState = beans::PropertyState_DIRECT_VALUE;
+ break;
+ case SFX_ITEM_DEFAULT:
+ rState = beans::PropertyState_DEFAULT_VALUE;
+ break;
+// case SFX_ITEM_UNKNOWN:
+// case SFX_ITEM_DONTCARE:
+// case SFX_ITEM_DISABLED:
+ default:
+ rState = beans::PropertyState_AMBIGUOUS_VALUE;
+ }
+ }
+ return !bUnknownPropertyFound;
+}
+
+void SAL_CALL SvxUnoTextRangeBase::setPropertyToDefault( const OUString& PropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ _setPropertyToDefault( PropertyName, -1 );
+}
+
+void SvxUnoTextRangeBase::_setPropertyToDefault(const OUString& PropertyName, sal_Int32 nPara /* = -1 */)
+ throw( beans::UnknownPropertyException, uno::RuntimeException )
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : NULL;
+
+ if( pForwarder )
+ {
+ const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry( PropertyName );
+ if ( pMap )
+ {
+ CheckSelection( maSelection, mpEditSource->GetTextForwarder() );
+ _setPropertyToDefault( pForwarder, pMap, nPara );
+ return;
+ }
+ }
+
+ throw beans::UnknownPropertyException();
+}
+
+void SvxUnoTextRangeBase::_setPropertyToDefault(SvxTextForwarder* pForwarder, const SfxItemPropertySimpleEntry* pMap, sal_Int32 nPara )
+ throw( beans::UnknownPropertyException, uno::RuntimeException )
+{
+ do
+ {
+ SfxItemSet aSet( *pForwarder->GetPool(), TRUE );
+
+ if( pMap->nWID == WID_FONTDESC )
+ {
+ SvxUnoFontDescriptor::setPropertyToDefault( aSet );
+ }
+ else if( pMap->nWID == WID_NUMLEVEL )
+ {
+ // #101004# Call interface method instead of unsafe cast
+ pForwarder->SetDepth( maSelection.nStartPara, -1 );
+ return;
+ }
+ else if( pMap->nWID == WID_NUMBERINGSTARTVALUE )
+ {
+ pForwarder->SetNumberingStartValue( maSelection.nStartPara, -1 );
+ }
+ else if( pMap->nWID == WID_PARAISNUMBERINGRESTART )
+ {
+ pForwarder->SetParaIsNumberingRestart( maSelection.nStartPara, sal_False );
+ }
+ else
+ {
+ aSet.InvalidateItem( pMap->nWID );
+ }
+
+ if(nPara != -1)
+ pForwarder->SetParaAttribs( (USHORT)nPara, aSet );
+ else
+ pForwarder->QuickSetAttribs( aSet, GetSelection() );
+
+ GetEditSource()->UpdateData();
+
+ return;
+ }
+ while(0);
+}
+
+uno::Any SAL_CALL SvxUnoTextRangeBase::getPropertyDefault( const OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : NULL;
+ if( pForwarder )
+ {
+ const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry( aPropertyName );
+ if( pMap )
+ {
+ SfxItemPool* pPool = pForwarder->GetPool();
+
+ switch( pMap->nWID )
+ {
+ case WID_FONTDESC:
+ return SvxUnoFontDescriptor::getPropertyDefault( pPool );
+
+ case WID_NUMLEVEL:
+ {
+ uno::Any aAny;
+ return aAny;
+ }
+
+ case WID_NUMBERINGSTARTVALUE:
+ return uno::Any( (sal_Int16)-1 );
+
+ case WID_PARAISNUMBERINGRESTART:
+ return uno::Any( (sal_Bool)sal_False );
+
+ default:
+ {
+ // Default aus ItemPool holen
+ if(pPool->IsWhich(pMap->nWID))
+ {
+ SfxItemSet aSet( *pPool, pMap->nWID, pMap->nWID);
+ aSet.Put(pPool->GetDefaultItem(pMap->nWID));
+ return mpPropSet->getPropertyValue(pMap, aSet, false, false);
+ }
+ }
+ }
+ }
+ }
+ throw beans::UnknownPropertyException();
+}
+
+// beans::XMultiPropertyStates
+void SAL_CALL SvxUnoTextRangeBase::setAllPropertiesToDefault( ) throw (uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : NULL;
+
+ if( pForwarder )
+ {
+ PropertyEntryVector_t aEntries = mpPropSet->getPropertyMap()->getPropertyEntries();
+ PropertyEntryVector_t::const_iterator aIt = aEntries.begin();
+ while( aIt != aEntries.end() )
+ {
+ _setPropertyToDefault( pForwarder, &(*aIt), -1 );
+ ++aIt;
+ }
+ }
+}
+
+void SAL_CALL SvxUnoTextRangeBase::setPropertiesToDefault( const uno::Sequence< OUString >& aPropertyNames ) throw (beans::UnknownPropertyException, uno::RuntimeException)
+{
+ sal_Int32 nCount = aPropertyNames.getLength();
+ for( const OUString* pName = aPropertyNames.getConstArray(); nCount; pName++, nCount-- )
+ {
+ setPropertyToDefault( *pName );
+ }
+}
+
+uno::Sequence< uno::Any > SAL_CALL SvxUnoTextRangeBase::getPropertyDefaults( const uno::Sequence< OUString >& aPropertyNames ) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ sal_Int32 nCount = aPropertyNames.getLength();
+ uno::Sequence< uno::Any > ret( nCount );
+ uno::Any* pDefaults = ret.getArray();
+
+ for( const OUString* pName = aPropertyNames.getConstArray(); nCount; pName++, nCount--, pDefaults++ )
+ {
+ *pDefaults = getPropertyDefault( *pName );
+ }
+
+ return ret;
+}
+
+// internal
+void SvxUnoTextRangeBase::CollapseToStart(void) throw()
+{
+ CheckSelection( maSelection, mpEditSource->GetTextForwarder() );
+
+ maSelection.nEndPara = maSelection.nStartPara;
+ maSelection.nEndPos = maSelection.nStartPos;
+}
+
+void SvxUnoTextRangeBase::CollapseToEnd(void) throw()
+{
+ CheckSelection( maSelection, mpEditSource->GetTextForwarder() );
+
+ maSelection.nStartPara = maSelection.nEndPara;
+ maSelection.nStartPos = maSelection.nEndPos;
+}
+
+sal_Bool SvxUnoTextRangeBase::IsCollapsed(void) throw()
+{
+ CheckSelection( maSelection, mpEditSource->GetTextForwarder() );
+
+ return ( maSelection.nStartPara == maSelection.nEndPara &&
+ maSelection.nStartPos == maSelection.nEndPos );
+}
+
+sal_Bool SvxUnoTextRangeBase::GoLeft(sal_Int16 nCount, sal_Bool Expand) throw()
+{
+ CheckSelection( maSelection, mpEditSource->GetTextForwarder() );
+
+ // #75098# use end position, as in Writer (start is anchor, end is cursor)
+ sal_uInt16 nNewPos = maSelection.nEndPos;
+ sal_uInt16 nNewPar = maSelection.nEndPara;
+
+ sal_Bool bOk = sal_True;
+ SvxTextForwarder* pForwarder = NULL;
+ while ( nCount > nNewPos && bOk )
+ {
+ if ( nNewPar == 0 )
+ bOk = sal_False;
+ else
+ {
+ if ( !pForwarder )
+ pForwarder = mpEditSource->GetTextForwarder(); // erst hier, wenn's noetig ist...
+
+ --nNewPar;
+ nCount -= nNewPos + 1;
+ nNewPos = pForwarder->GetTextLen( nNewPar );
+ }
+ }
+
+ if ( bOk )
+ {
+ nNewPos = nNewPos - nCount;
+ maSelection.nStartPara = nNewPar;
+ maSelection.nStartPos = nNewPos;
+ }
+
+ if (!Expand)
+ CollapseToStart();
+
+ return bOk;
+}
+
+sal_Bool SvxUnoTextRangeBase::GoRight(sal_Int16 nCount, sal_Bool Expand) throw()
+{
+ SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : NULL;
+ if( pForwarder )
+ {
+ CheckSelection( maSelection, pForwarder );
+
+
+ sal_uInt16 nNewPos = maSelection.nEndPos + nCount; //! Ueberlauf ???
+ sal_uInt16 nNewPar = maSelection.nEndPara;
+
+ sal_Bool bOk = sal_True;
+ sal_uInt16 nParCount = pForwarder->GetParagraphCount();
+ sal_uInt16 nThisLen = pForwarder->GetTextLen( nNewPar );
+ while ( nNewPos > nThisLen && bOk )
+ {
+ if ( nNewPar + 1 >= nParCount )
+ bOk = sal_False;
+ else
+ {
+ nNewPos -= nThisLen+1;
+ ++nNewPar;
+ nThisLen = pForwarder->GetTextLen( nNewPar );
+ }
+ }
+
+ if (bOk)
+ {
+ maSelection.nEndPara = nNewPar;
+ maSelection.nEndPos = nNewPos;
+ }
+
+ if (!Expand)
+ CollapseToEnd();
+
+ return bOk;
+ }
+ return sal_False;
+}
+
+void SvxUnoTextRangeBase::GotoStart(sal_Bool Expand) throw()
+{
+ maSelection.nStartPara = 0;
+ maSelection.nStartPos = 0;
+
+ if (!Expand)
+ CollapseToStart();
+}
+
+void SvxUnoTextRangeBase::GotoEnd(sal_Bool Expand) throw()
+{
+ CheckSelection( maSelection, mpEditSource->GetTextForwarder() );
+
+ SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : NULL;
+ if( pForwarder )
+ {
+
+ sal_uInt16 nPar = pForwarder->GetParagraphCount();
+ if (nPar)
+ --nPar;
+
+ maSelection.nEndPara = nPar;
+ maSelection.nEndPos = pForwarder->GetTextLen( nPar );
+
+ if (!Expand)
+ CollapseToEnd();
+ }
+}
+
+// lang::XServiceInfo
+sal_Bool SAL_CALL SvxUnoTextRangeBase::supportsService( const OUString& ServiceName )
+ throw(uno::RuntimeException)
+{
+ return comphelper::ServiceInfoHelper::supportsService( ServiceName, getSupportedServiceNames() );
+}
+
+uno::Sequence< OUString > SAL_CALL SvxUnoTextRangeBase::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ return getSupportedServiceNames_Static();
+}
+
+uno::Sequence< OUString > SAL_CALL SvxUnoTextRangeBase::getSupportedServiceNames_Static()
+ SAL_THROW(())
+{
+ uno::Sequence< OUString > aSeq;
+ comphelper::ServiceInfoHelper::addToSequence( aSeq, 3, "com.sun.star.style.CharacterProperties",
+ "com.sun.star.style.CharacterPropertiesComplex",
+ "com.sun.star.style.CharacterPropertiesAsian");
+ return aSeq;
+}
+
+// XTextRangeCompare
+sal_Int16 SAL_CALL SvxUnoTextRangeBase::compareRegionStarts( const uno::Reference< text::XTextRange >& xR1, const uno::Reference< text::XTextRange >& xR2 ) throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ SvxUnoTextRangeBase* pR1 = SvxUnoTextRangeBase::getImplementation( xR1 );
+ SvxUnoTextRangeBase* pR2 = SvxUnoTextRangeBase::getImplementation( xR2 );
+
+ if( (pR1 == 0) || (pR2 == 0) )
+ throw lang::IllegalArgumentException();
+
+ const ESelection& r1 = pR1->maSelection;
+ const ESelection& r2 = pR2->maSelection;
+
+ if( r1.nStartPara == r2.nStartPara )
+ {
+ if( r1.nStartPos == r2.nStartPos )
+ return 0;
+ else
+ return r1.nStartPos < r2.nStartPos ? 1 : -1;
+ }
+ else
+ {
+ return r1.nStartPara < r2.nStartPara ? 1 : -1;
+ }
+}
+
+sal_Int16 SAL_CALL SvxUnoTextRangeBase::compareRegionEnds( const uno::Reference< text::XTextRange >& xR1, const uno::Reference< text::XTextRange >& xR2 ) throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ SvxUnoTextRangeBase* pR1 = SvxUnoTextRangeBase::getImplementation( xR1 );
+ SvxUnoTextRangeBase* pR2 = SvxUnoTextRangeBase::getImplementation( xR2 );
+
+ if( (pR1 == 0) || (pR2 == 0) )
+ throw lang::IllegalArgumentException();
+
+ const ESelection& r1 = pR1->maSelection;
+ const ESelection& r2 = pR2->maSelection;
+
+ if( r1.nEndPara == r2.nEndPara )
+ {
+ if( r1.nEndPos == r2.nEndPos )
+ return 0;
+ else
+ return r1.nEndPos < r2.nEndPos ? 1 : -1;
+ }
+ else
+ {
+ return r1.nEndPara < r2.nEndPara ? 1 : -1;
+ }
+}
+
+// ====================================================================
+// class SvxUnoTextRange
+// ====================================================================
+
+uno::Sequence< uno::Type > SvxUnoTextRange::maTypeSequence;
+
+uno::Reference< uno::XInterface > SvxUnoTextRange_NewInstance()
+{
+ SvxUnoText aText;
+ uno::Reference< text::XTextRange > xRange( new SvxUnoTextRange( aText ) );
+#if (_MSC_VER < 1300)
+ return xRange;
+#else
+ return (uno::Reference< uno::XInterface >)xRange;
+#endif
+}
+
+SvxUnoTextRange::SvxUnoTextRange( const SvxUnoTextBase& rParent, sal_Bool bPortion /* = sal_False */ ) throw()
+:SvxUnoTextRangeBase( rParent.GetEditSource(), bPortion ? ImplGetSvxTextPortionSvxPropertySet() : rParent.getPropertySet() ),
+ mbPortion( bPortion )
+{
+ xParentText = (text::XText*)&rParent;
+}
+
+SvxUnoTextRange::~SvxUnoTextRange() throw()
+{
+}
+
+uno::Any SAL_CALL SvxUnoTextRange::queryAggregation( const uno::Type & rType )
+ throw(uno::RuntimeException)
+{
+ QUERYINT( text::XTextRange );
+ else if( rType == ::getCppuType((const uno::Reference< beans::XMultiPropertyStates >*)0) )
+ return uno::makeAny(uno::Reference< beans::XMultiPropertyStates >(this));
+ else if( rType == ::getCppuType((const uno::Reference< beans::XPropertySet >*)0) )
+ return uno::makeAny(uno::Reference< beans::XPropertySet >(this));
+ else QUERYINT( beans::XPropertyState );
+ else QUERYINT( text::XTextRangeCompare );
+ else if( rType == ::getCppuType((const uno::Reference< beans::XMultiPropertySet >*)0) )
+ return uno::makeAny(uno::Reference< beans::XMultiPropertySet >(this));
+ else QUERYINT( lang::XServiceInfo );
+ else QUERYINT( lang::XTypeProvider );
+ else QUERYINT( lang::XUnoTunnel );
+ else
+ return OWeakAggObject::queryAggregation( rType );
+}
+
+uno::Any SAL_CALL SvxUnoTextRange::queryInterface( const uno::Type & rType )
+ throw(uno::RuntimeException)
+{
+ return OWeakAggObject::queryInterface(rType);
+}
+
+void SAL_CALL SvxUnoTextRange::acquire()
+ throw( )
+{
+ OWeakAggObject::acquire();
+}
+
+void SAL_CALL SvxUnoTextRange::release()
+ throw( )
+{
+ OWeakAggObject::release();
+}
+
+// XTypeProvider
+
+uno::Sequence< uno::Type > SAL_CALL SvxUnoTextRange::getTypes()
+ throw (uno::RuntimeException)
+{
+ if( maTypeSequence.getLength() == 0 )
+ {
+ maTypeSequence.realloc( 9 ); // !DANGER! keep this updated
+ uno::Type* pTypes = maTypeSequence.getArray();
+
+ *pTypes++ = ::getCppuType(( const uno::Reference< text::XTextRange >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< beans::XPropertySet >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< beans::XMultiPropertySet >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< beans::XMultiPropertyStates >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< beans::XPropertyState >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< lang::XServiceInfo >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< lang::XTypeProvider >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< lang::XUnoTunnel >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< text::XTextRangeCompare >*)0);
+ }
+ return maTypeSequence;
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL SvxUnoTextRange::getImplementationId()
+ throw (uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+// XTextRange
+uno::Reference< text::XText > SAL_CALL SvxUnoTextRange::getText()
+ throw(uno::RuntimeException)
+{
+ return xParentText;
+}
+
+// lang::XServiceInfo
+OUString SAL_CALL SvxUnoTextRange::getImplementationName()
+ throw(uno::RuntimeException)
+{
+ return OUString(RTL_CONSTASCII_USTRINGPARAM("SvxUnoTextRange"));
+}
+
+// ====================================================================
+// class SvxUnoText
+// ====================================================================
+
+// UNO3_GETIMPLEMENTATION2_IMPL( SvxUnoText, SvxUnoTextRangeBase );
+
+uno::Sequence< uno::Type > SvxUnoTextBase::maTypeSequence;
+
+SvxUnoTextBase::SvxUnoTextBase() throw()
+: SvxUnoTextRangeBase( NULL )
+{
+
+}
+
+SvxUnoTextBase::SvxUnoTextBase( const SvxItemPropertySet* _pSet ) throw()
+: SvxUnoTextRangeBase( _pSet )
+{
+}
+
+SvxUnoTextBase::SvxUnoTextBase( const SvxEditSource* pSource, const SvxItemPropertySet* _pSet ) throw()
+: SvxUnoTextRangeBase( pSource, _pSet )
+{
+ ESelection aSelection;
+ ::GetSelection( aSelection, GetEditSource()->GetTextForwarder() );
+ SetSelection( aSelection );
+}
+
+SvxUnoTextBase::SvxUnoTextBase( const SvxEditSource* pSource, const SvxItemPropertySet* _pSet, uno::Reference < text::XText > xParent ) throw()
+: SvxUnoTextRangeBase( pSource, _pSet )
+{
+ xParentText = xParent;
+ ESelection aSelection;
+ ::GetSelection( aSelection, GetEditSource()->GetTextForwarder() );
+ SetSelection( aSelection );
+}
+
+SvxUnoTextBase::SvxUnoTextBase( const SvxUnoTextBase& rText ) throw()
+: SvxUnoTextRangeBase( rText )
+, text::XTextAppend()
+, text::XTextCopy()
+, container::XEnumerationAccess()
+, text::XTextRangeMover()
+, lang::XTypeProvider()
+{
+ xParentText = rText.xParentText;
+}
+
+SvxUnoTextBase::~SvxUnoTextBase() throw()
+{
+}
+
+// Internal
+ESelection SvxUnoTextBase::InsertField( const SvxFieldItem& rField ) throw()
+{
+ SvxTextForwarder* pForwarder = GetEditSource() ? GetEditSource()->GetTextForwarder() : NULL;
+ if( pForwarder )
+ {
+ pForwarder->QuickInsertField( rField, GetSelection() );
+ GetEditSource()->UpdateData();
+
+ // Selektion anpassen
+ //! Wenn die EditEngine bei QuickInsertText die Selektion zurueckgeben wuerde,
+ //! waer's einfacher...
+
+ CollapseToStart();
+ GoRight( 1, sal_True ); // Feld ist immer 1 Zeichen
+ }
+
+ return GetSelection(); // Selektion mit dem Feld
+}
+
+// XInterface
+uno::Any SAL_CALL SvxUnoTextBase::queryAggregation( const uno::Type & rType )
+ throw(uno::RuntimeException)
+{
+ QUERYINT( text::XText );
+ QUERYINT( text::XSimpleText );
+ if( rType == ::getCppuType((const uno::Reference< text::XTextRange >*)0) )
+ return uno::makeAny(uno::Reference< text::XTextRange >((text::XText*)(this)));
+ QUERYINT(container::XEnumerationAccess );
+ QUERYINT( container::XElementAccess );
+ QUERYINT( beans::XMultiPropertyStates );
+ QUERYINT( beans::XPropertySet );
+ QUERYINT( beans::XMultiPropertySet );
+ QUERYINT( beans::XPropertyState );
+ QUERYINT( text::XTextRangeCompare );
+ QUERYINT( lang::XServiceInfo );
+ QUERYINT( text::XTextRangeMover );
+ QUERYINT( text::XTextCopy );
+ QUERYINT( text::XTextAppend );
+ QUERYINT( text::XParagraphAppend );
+ QUERYINT( text::XTextPortionAppend );
+ QUERYINT( lang::XTypeProvider );
+ QUERYINT( lang::XUnoTunnel );
+
+ return uno::Any();
+}
+
+// XTypeProvider
+
+uno::Sequence< uno::Type > SAL_CALL SvxUnoTextBase::getStaticTypes() throw()
+{
+ if( maTypeSequence.getLength() == 0 )
+ {
+ maTypeSequence.realloc( 15 ); // !DANGER! keep this updated
+ uno::Type* pTypes = maTypeSequence.getArray();
+
+ *pTypes++ = ::getCppuType(( const uno::Reference< text::XText >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< container::XEnumerationAccess >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< beans::XPropertySet >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< beans::XMultiPropertySet >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< beans::XMultiPropertyStates >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< beans::XPropertyState >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< text::XTextRangeMover >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< text::XTextAppend >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< text::XTextCopy >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< text::XParagraphAppend >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< text::XTextPortionAppend >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< lang::XServiceInfo >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< lang::XTypeProvider >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< lang::XUnoTunnel >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< text::XTextRangeCompare >*)0);
+ }
+ return maTypeSequence;
+}
+
+uno::Sequence< uno::Type > SAL_CALL SvxUnoTextBase::getTypes()
+ throw (uno::RuntimeException)
+{
+ return getStaticTypes();
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL SvxUnoTextBase::getImplementationId()
+ throw (uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+uno::Reference< text::XTextCursor > SvxUnoTextBase::createTextCursorBySelection( const ESelection& rSel )
+{
+ SvxUnoTextCursor* pCursor = new SvxUnoTextCursor( *this );
+ uno::Reference< text::XTextCursor > xCursor( pCursor );
+ pCursor->SetSelection( rSel );
+ return xCursor;
+}
+
+// XSimpleText
+
+uno::Reference< text::XTextCursor > SAL_CALL SvxUnoTextBase::createTextCursor()
+ throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ return new SvxUnoTextCursor( *this );
+}
+
+uno::Reference< text::XTextCursor > SAL_CALL SvxUnoTextBase::createTextCursorByRange( const uno::Reference< text::XTextRange >& aTextPosition )
+ throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ uno::Reference< text::XTextCursor > xCursor;
+
+ if( aTextPosition.is() )
+ {
+ SvxUnoTextRangeBase* pRange = SvxUnoTextRangeBase::getImplementation( aTextPosition );
+ if(pRange)
+ xCursor = createTextCursorBySelection( pRange->GetSelection() );
+ }
+
+ return xCursor;
+}
+
+void SAL_CALL SvxUnoTextBase::insertString( const uno::Reference< text::XTextRange >& xRange, const OUString& aString, sal_Bool bAbsorb )
+ throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if( !xRange.is() )
+ return;
+
+ ESelection aSelection;
+ ::GetSelection( aSelection, GetEditSource()->GetTextForwarder() );
+ SetSelection( aSelection );
+
+ SvxUnoTextRangeBase* pRange = SvxUnoTextRange::getImplementation( xRange );
+ if(pRange)
+ {
+ // setString am SvxUnoTextRangeBase statt selber QuickInsertText und UpdateData,
+ // damit die Selektion am SvxUnoTextRangeBase angepasst wird.
+ //! Eigentlich muessten alle Cursor-Objekte dieses Textes angepasst werden!
+
+ if (!bAbsorb) // nicht ersetzen -> hinten anhaengen
+ pRange->CollapseToEnd();
+
+ pRange->setString( aString );
+
+ pRange->CollapseToEnd();
+ }
+}
+
+void SAL_CALL SvxUnoTextBase::insertControlCharacter( const uno::Reference< text::XTextRange >& xRange, sal_Int16 nControlCharacter, sal_Bool bAbsorb )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ SvxTextForwarder* pForwarder = GetEditSource() ? GetEditSource()->GetTextForwarder() : NULL;
+
+ if( pForwarder )
+ {
+ ESelection aSelection;
+ ::GetSelection( aSelection, pForwarder );
+ SetSelection( aSelection );
+
+ switch( nControlCharacter )
+ {
+ case text::ControlCharacter::PARAGRAPH_BREAK:
+ {
+ const String aText( (sal_Unicode)13 ); // '\r' geht auf'm Mac nicht
+ insertString( xRange, aText, bAbsorb );
+
+ return;
+ }
+ case text::ControlCharacter::LINE_BREAK:
+ {
+ SvxUnoTextRangeBase* pRange = SvxUnoTextRange::getImplementation( xRange );
+ if(pRange)
+ {
+ ESelection aRange = pRange->GetSelection();
+
+ if( bAbsorb )
+ {
+ const String aEmpty;
+ pForwarder->QuickInsertText( aEmpty, aRange );
+
+ aRange.nEndPos = aRange.nStartPos;
+ aRange.nEndPara = aRange.nStartPara;
+ }
+ else
+ {
+ aRange.nStartPos = aRange.nEndPos;
+ aRange.nStartPara = aRange.nStartPara;
+ }
+
+ pForwarder->QuickInsertLineBreak( aRange );
+ GetEditSource()->UpdateData();
+
+ aRange.nEndPos += 1;
+ if( !bAbsorb )
+ aRange.nStartPos += 1;
+
+ pRange->SetSelection( aRange );
+ }
+ return;
+ }
+ case text::ControlCharacter::APPEND_PARAGRAPH:
+ {
+ SvxUnoTextRangeBase* pRange = SvxUnoTextRange::getImplementation( xRange );
+ if(pRange)
+ {
+ ESelection aRange = pRange->GetSelection();
+// ESelection aOldSelection = aRange;
+
+ aRange.nStartPos = pForwarder->GetTextLen( aRange.nStartPara );
+
+ aRange.nEndPara = aRange.nStartPara;
+ aRange.nEndPos = aRange.nStartPos;
+
+ pRange->SetSelection( aRange );
+ const String aText( (sal_Unicode)13 ); // '\r' geht auf'm Mac nicht
+ pRange->setString( aText );
+
+ aRange.nStartPos = 0;
+ aRange.nStartPara += 1;
+ aRange.nEndPos = 0;
+ aRange.nEndPara += 1;
+
+ pRange->SetSelection( aRange );
+
+ return;
+ }
+ }
+ }
+ }
+
+ throw lang::IllegalArgumentException();
+}
+
+// XText
+void SAL_CALL SvxUnoTextBase::insertTextContent( const uno::Reference< text::XTextRange >& xRange, const uno::Reference< text::XTextContent >& xContent, sal_Bool bAbsorb )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ SvxTextForwarder* pForwarder = GetEditSource() ? GetEditSource()->GetTextForwarder() : NULL;
+ if( pForwarder )
+ {
+
+ SvxUnoTextRangeBase* pRange = SvxUnoTextRange::getImplementation( xRange );
+ SvxUnoTextField* pField = SvxUnoTextField::getImplementation( xContent );
+
+ if( pRange == NULL || pField == NULL )
+ throw lang::IllegalArgumentException();
+
+ ESelection aSelection = pRange->GetSelection();
+ if( !bAbsorb )
+ {
+ aSelection.nStartPara = aSelection.nEndPara;
+ aSelection.nStartPos = aSelection.nEndPos;
+ }
+
+ SvxFieldData* pFieldData = pField->CreateFieldData();
+ if( pFieldData == NULL )
+ throw lang::IllegalArgumentException();
+
+ SvxFieldItem aField( *pFieldData, EE_FEATURE_FIELD );
+ pForwarder->QuickInsertField( aField, aSelection );
+ GetEditSource()->UpdateData();
+
+ pField->SetAnchor( uno::Reference< text::XTextRange >::query( (cppu::OWeakObject*)this ) );
+
+ aSelection.nEndPos += 1;
+ aSelection.nStartPos = aSelection.nEndPos;
+ //maSelection = aSelection; //???
+ pRange->SetSelection( aSelection );
+
+ delete pFieldData;
+ }
+}
+
+void SAL_CALL SvxUnoTextBase::removeTextContent( const uno::Reference< text::XTextContent >& ) throw(container::NoSuchElementException, uno::RuntimeException)
+{
+}
+
+// XTextRange
+
+uno::Reference< text::XText > SAL_CALL SvxUnoTextBase::getText()
+ throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if (GetEditSource())
+ {
+ ESelection aSelection;
+ ::GetSelection( aSelection, GetEditSource()->GetTextForwarder() );
+ ((SvxUnoTextBase*)this)->SetSelection( aSelection );
+ }
+
+ return (text::XText*)this;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextBase::getStart()
+ throw(uno::RuntimeException)
+{
+ return SvxUnoTextRangeBase::getStart();
+}
+
+uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextBase::getEnd()
+ throw(uno::RuntimeException)
+{
+ return SvxUnoTextRangeBase::getEnd();
+}
+
+OUString SAL_CALL SvxUnoTextBase::getString() throw( uno::RuntimeException )
+{
+ return SvxUnoTextRangeBase::getString();
+}
+
+void SAL_CALL SvxUnoTextBase::setString( const OUString& aString ) throw(uno::RuntimeException)
+{
+ SvxUnoTextRangeBase::setString(aString);
+}
+
+
+// XEnumerationAccess
+uno::Reference< container::XEnumeration > SAL_CALL SvxUnoTextBase::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ ESelection aSelection;
+ ::GetSelection( aSelection, GetEditSource()->GetTextForwarder() );
+ SetSelection( aSelection );
+
+ uno::Reference< container::XEnumeration > xEnum( (container::XEnumeration*) new SvxUnoTextContentEnumeration( *this ) );
+ return xEnum;
+}
+
+// XElementAccess ( container::XEnumerationAccess )
+uno::Type SAL_CALL SvxUnoTextBase::getElementType( ) throw(uno::RuntimeException)
+{
+ return ::getCppuType((const uno::Reference< text::XTextRange >*)0 );
+}
+
+sal_Bool SAL_CALL SvxUnoTextBase::hasElements( ) throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if(GetEditSource())
+ {
+ SvxTextForwarder* pForwarder = GetEditSource()->GetTextForwarder();
+ if(pForwarder)
+ return pForwarder->GetParagraphCount() != 0;
+ }
+
+ return sal_False;
+}
+
+// text::XTextRangeMover
+void SAL_CALL SvxUnoTextBase::moveTextRange( const uno::Reference< text::XTextRange >&, sal_Int16 )
+ throw(uno::RuntimeException)
+{
+}
+
+void SvxPropertyValuesToItemSet(
+ SfxItemSet &rItemSet,
+ const uno::Sequence< beans::PropertyValue > rPropertyVaules,
+ const SfxItemPropertySet *pPropSet,
+ SvxTextForwarder *pForwarder /*needed for WID_NUMLEVEL*/,
+ USHORT nPara /*needed for WID_NUMLEVEL*/)
+ throw(lang::IllegalArgumentException, beans::UnknownPropertyException, uno::RuntimeException)
+{
+ sal_Int32 nProps = rPropertyVaules.getLength();
+ const beans::PropertyValue *pProps = rPropertyVaules.getConstArray();
+ for (sal_Int32 i = 0; i < nProps; ++i)
+ {
+ const SfxItemPropertySimpleEntry *pEntry = pPropSet->getPropertyMap()->getByName( pProps[i].Name );
+ if (pEntry)
+ {
+ // Note: there is no need to take special care of the properties
+ // TextField (EE_FEATURE_FIELD) and
+ // TextPortionType (WID_PORTIONTYPE)
+ // since they are read-only and thus are already taken care of below.
+
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ // should be PropertyVetoException which is not yet defined for the new import API's functions
+ throw uno::RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property is read-only: " ) ) + pProps[i].Name, static_cast < cppu::OWeakObject * > ( 0 ) );
+ //throw PropertyVetoException ( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property is read-only: " ) ) + pProps[i].Name, static_cast < cppu::OWeakObject * > ( 0 ) );
+
+ if (pEntry->nWID == WID_FONTDESC)
+ {
+ awt::FontDescriptor aDesc;
+ if (pProps[i].Value >>= aDesc)
+ SvxUnoFontDescriptor::FillItemSet( aDesc, rItemSet );
+ }
+ else if (pEntry->nWID == WID_NUMLEVEL)
+ {
+ if (pForwarder)
+ {
+ sal_Int16 nLevel = -1;
+ pProps[i].Value >>= nLevel;
+
+ // #101004# Call interface method instead of unsafe cast
+ if (!pForwarder->SetDepth( nPara, nLevel ))
+ throw lang::IllegalArgumentException();
+ }
+ }
+ else if (pEntry->nWID == WID_NUMBERINGSTARTVALUE )
+ {
+ if( pForwarder )
+ {
+ sal_Int16 nStartValue = -1;
+ if( !(pProps[i].Value >>= nStartValue) )
+ throw lang::IllegalArgumentException();
+
+ pForwarder->SetNumberingStartValue( nPara, nStartValue );
+ }
+ }
+ else if (pEntry->nWID == WID_PARAISNUMBERINGRESTART )
+ {
+ if( pForwarder )
+ {
+ sal_Bool bParaIsNumberingRestart = sal_False;
+ if( !(pProps[i].Value >>= bParaIsNumberingRestart) )
+ throw lang::IllegalArgumentException();
+
+ pForwarder->SetParaIsNumberingRestart( nPara, bParaIsNumberingRestart );
+ }
+ }
+ else
+ pPropSet->setPropertyValue( pProps[i].Name, pProps[i].Value, rItemSet );
+ }
+ else
+ throw beans::UnknownPropertyException(OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Unknown property: " ) ) + pProps[i].Name, static_cast < cppu::OWeakObject * > ( 0 ) );
+ }
+}
+
+// com::sun::star::text::XParagraphAppend (new import API)
+uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextBase::appendParagraph(
+ const uno::Sequence< beans::PropertyValue >& rCharAndParaProps )
+ throw (lang::IllegalArgumentException, beans::UnknownPropertyException, uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ uno::Reference< text::XTextRange > xRet;
+ SvxEditSource *pEditSource = GetEditSource();
+ SvxTextForwarder *pTextForwarder = pEditSource ? pEditSource->GetTextForwarder() : 0;
+ if (pTextForwarder)
+ {
+ USHORT nParaCount = pTextForwarder->GetParagraphCount();
+ DBG_ASSERT( nParaCount > 0, "paragraph count is 0 or negative" );
+ pTextForwarder->AppendParagraph();
+
+ // set properties for new appended (now last) paragraph
+ ESelection aSel( nParaCount, 0, nParaCount, 0 );
+ SfxItemSet aItemSet( *pTextForwarder->GetEmptyItemSetPtr() );
+ SvxPropertyValuesToItemSet( aItemSet, rCharAndParaProps,
+ ImplGetSvxUnoOutlinerTextCursorSfxPropertySet(),
+ pTextForwarder,
+ nParaCount );
+ pTextForwarder->QuickSetAttribs( aItemSet, aSel );
+ pEditSource->UpdateData();
+ SvxUnoTextRange* pRange = new SvxUnoTextRange( *this );
+ xRet = pRange;
+ pRange->SetSelection( aSel );
+ }
+ return xRet;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextBase::finishParagraph(
+ const uno::Sequence< beans::PropertyValue >& rCharAndParaProps )
+ throw (lang::IllegalArgumentException, beans::UnknownPropertyException, uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ uno::Reference< text::XTextRange > xRet;
+ SvxEditSource *pEditSource = GetEditSource();
+ SvxTextForwarder *pTextForwarder = pEditSource ? pEditSource->GetTextForwarder() : 0;
+ if (pTextForwarder)
+ {
+ USHORT nParaCount = pTextForwarder->GetParagraphCount();
+ DBG_ASSERT( nParaCount > 0, "paragraph count is 0 or negative" );
+ pTextForwarder->AppendParagraph();
+
+ // set properties for the previously last paragraph
+ USHORT nPara = nParaCount - 1;
+ ESelection aSel( nPara, 0, nPara, 0 );
+ SfxItemSet aItemSet( *pTextForwarder->GetEmptyItemSetPtr() );
+ SvxPropertyValuesToItemSet( aItemSet, rCharAndParaProps,
+ ImplGetSvxUnoOutlinerTextCursorSfxPropertySet(), pTextForwarder, nPara );
+ pTextForwarder->QuickSetAttribs( aItemSet, aSel );
+ pEditSource->UpdateData();
+ SvxUnoTextRange* pRange = new SvxUnoTextRange( *this );
+ xRet = pRange;
+ pRange->SetSelection( aSel );
+ }
+ return xRet;
+}
+
+// com::sun::star::text::XTextPortionAppend (new import API)
+uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextBase::appendTextPortion(
+ const ::rtl::OUString& rText,
+ const uno::Sequence< beans::PropertyValue >& rCharAndParaProps )
+ throw (lang::IllegalArgumentException, beans::UnknownPropertyException, uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ SvxEditSource *pEditSource = GetEditSource();
+ SvxTextForwarder *pTextForwarder = pEditSource ? pEditSource->GetTextForwarder() : 0;
+ uno::Reference< text::XTextRange > xRet;
+ if (pTextForwarder)
+ {
+ USHORT nParaCount = pTextForwarder->GetParagraphCount();
+ DBG_ASSERT( nParaCount > 0, "paragraph count is 0 or negative" );
+ USHORT nPara = nParaCount - 1;
+ SfxItemSet aSet( pTextForwarder->GetParaAttribs( nPara ) );
+ xub_StrLen nStart = pTextForwarder->AppendTextPortion( nPara, rText, aSet );
+ pEditSource->UpdateData();
+ xub_StrLen nEnd = pTextForwarder->GetTextLen( nPara );
+
+ // set properties for the new text portion
+ ESelection aSel( nPara, nStart, nPara, nEnd );
+ pTextForwarder->RemoveAttribs( aSel, sal_False, 0 );
+ pEditSource->UpdateData();
+
+ SfxItemSet aItemSet( *pTextForwarder->GetEmptyItemSetPtr() );
+ SvxPropertyValuesToItemSet( aItemSet, rCharAndParaProps,
+ ImplGetSvxTextPortionSfxPropertySet(), pTextForwarder, nPara );
+ pTextForwarder->QuickSetAttribs( aItemSet, aSel );
+ SvxUnoTextRange* pRange = new SvxUnoTextRange( *this );
+ xRet = pRange;
+ pRange->SetSelection( aSel );
+ const beans::PropertyValue* pProps = rCharAndParaProps.getConstArray();
+ for( sal_Int32 nProp = 0; nProp < rCharAndParaProps.getLength(); ++nProp )
+ pRange->setPropertyValue( pProps[nProp].Name, pProps[nProp].Value );
+ }
+ return xRet;
+}
+/*-- 25.03.2008 08:16:09---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SvxUnoTextBase::copyText(
+ const uno::Reference< text::XTextCopy >& xSource ) throw ( uno::RuntimeException )
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ uno::Reference< lang::XUnoTunnel > xUT( xSource, uno::UNO_QUERY );
+ SvxEditSource *pEditSource = GetEditSource();
+ SvxTextForwarder *pTextForwarder = pEditSource ? pEditSource->GetTextForwarder() : 0;
+ if( !pTextForwarder )
+ return;
+ if( xUT.is() )
+ {
+ SvxUnoTextBase* pSource = reinterpret_cast<SvxUnoTextBase*>(sal::static_int_cast<sal_uIntPtr>(
+ xUT->getSomething( SvxUnoTextBase::getUnoTunnelId())));
+ SvxEditSource *pSourceEditSource = pSource->GetEditSource();
+ SvxTextForwarder *pSourceTextForwarder = pSourceEditSource ? pSourceEditSource->GetTextForwarder() : 0;
+ if( pSourceTextForwarder )
+ {
+ pTextForwarder->CopyText( *pSourceTextForwarder );
+ pEditSource->UpdateData();
+ }
+ }
+ else
+ {
+ uno::Reference< text::XText > xSourceText( xSource, uno::UNO_QUERY );
+ if( xSourceText.is() )
+ {
+ setString( xSourceText->getString() );
+ }
+ }
+}
+
+// lang::XServiceInfo
+OUString SAL_CALL SvxUnoTextBase::getImplementationName()
+ throw(uno::RuntimeException)
+{
+ return OUString(RTL_CONSTASCII_USTRINGPARAM("SvxUnoTextBase"));
+}
+
+uno::Sequence< OUString > SAL_CALL SvxUnoTextBase::getSupportedServiceNames( )
+ throw(uno::RuntimeException)
+{
+ return getSupportedServiceNames_Static();
+}
+
+uno::Sequence< OUString > SAL_CALL SvxUnoTextBase::getSupportedServiceNames_Static( )
+ SAL_THROW(())
+{
+ uno::Sequence< OUString > aSeq( SvxUnoTextRangeBase::getSupportedServiceNames_Static() );
+ comphelper::ServiceInfoHelper::addToSequence( aSeq, 1, "com.sun.star.text.Text" );
+ return aSeq;
+}
+
+const uno::Sequence< sal_Int8 > & SvxUnoTextBase::getUnoTunnelId() throw()
+{
+ static uno::Sequence< sal_Int8 > * pSeq = 0;
+ if( !pSeq )
+ {
+ ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+SvxUnoTextBase* SvxUnoTextBase::getImplementation( const uno::Reference< uno::XInterface >& xInt )
+{
+ uno::Reference< lang::XUnoTunnel > xUT( xInt, uno::UNO_QUERY );
+ if( xUT.is() )
+ return reinterpret_cast<SvxUnoTextBase*>(sal::static_int_cast<sal_uIntPtr>(xUT->getSomething( SvxUnoTextBase::getUnoTunnelId())));
+ else
+ return NULL;
+}
+
+sal_Int64 SAL_CALL SvxUnoTextBase::getSomething( const uno::Sequence< sal_Int8 >& rId ) throw(uno::RuntimeException) \
+{
+ if( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
+ }
+ else
+ {
+ return SvxUnoTextRangeBase::getSomething( rId );
+ }
+}
+
+// --------------------------------------------------------------------
+
+SvxUnoText::SvxUnoText( ) throw()
+{
+}
+
+SvxUnoText::SvxUnoText( const SvxItemPropertySet* _pSet ) throw()
+: SvxUnoTextBase( _pSet )
+{
+}
+
+SvxUnoText::SvxUnoText( const SvxEditSource* pSource, const SvxItemPropertySet* _pSet, uno::Reference < text::XText > xParent ) throw()
+: SvxUnoTextBase( pSource, _pSet, xParent )
+{
+}
+
+SvxUnoText::SvxUnoText( const SvxUnoText& rText ) throw()
+: SvxUnoTextBase( rText )
+, cppu::OWeakAggObject()
+{
+}
+
+SvxUnoText::~SvxUnoText() throw()
+{
+}
+
+uno::Sequence< uno::Type > SAL_CALL getStaticTypes() throw()
+{
+ return SvxUnoTextBase::getStaticTypes();
+}
+
+// uno::XInterface
+uno::Any SAL_CALL SvxUnoText::queryAggregation( const uno::Type & rType ) throw( uno::RuntimeException )
+{
+ uno::Any aAny( SvxUnoTextBase::queryAggregation( rType ) );
+ if( !aAny.hasValue() )
+ aAny = OWeakAggObject::queryAggregation( rType );
+
+ return aAny;
+}
+
+uno::Any SAL_CALL SvxUnoText::queryInterface( const uno::Type & rType ) throw( uno::RuntimeException )
+{
+ return OWeakAggObject::queryInterface( rType );
+}
+
+void SAL_CALL SvxUnoText::acquire() throw( )
+{
+ OWeakAggObject::acquire();
+}
+
+void SAL_CALL SvxUnoText::release() throw( )
+{
+ OWeakAggObject::release();
+}
+
+// lang::XTypeProvider
+uno::Sequence< uno::Type > SAL_CALL SvxUnoText::getTypes( ) throw( uno::RuntimeException )
+{
+ return SvxUnoTextBase::getTypes();
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL SvxUnoText::getImplementationId( ) throw( uno::RuntimeException )
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+SvxUnoText* SvxUnoText::getImplementation( const uno::Reference< uno::XInterface >& xInt )
+{
+ uno::Reference< lang::XUnoTunnel > xUT( xInt, uno::UNO_QUERY );
+ if( xUT.is() )
+ return reinterpret_cast<SvxUnoText*>(sal::static_int_cast<sal_uIntPtr>(xUT->getSomething( SvxUnoText::getUnoTunnelId())));
+ else
+ return NULL;
+}
+
+const uno::Sequence< sal_Int8 > & SvxUnoText::getUnoTunnelId() throw()
+{
+ static uno::Sequence< sal_Int8 > * pSeq = 0;
+ if( !pSeq )
+ {
+ ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+sal_Int64 SAL_CALL SvxUnoText::getSomething( const uno::Sequence< sal_Int8 >& rId ) throw(uno::RuntimeException) \
+{
+ if( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
+ }
+ else
+ {
+ return SvxUnoTextBase::getSomething( rId );
+ }
+}
+
+
+// --------------------------------------------------------------------
+
+SvxDummyTextSource::~SvxDummyTextSource()
+{
+};
+
+SvxEditSource* SvxDummyTextSource::Clone() const
+{
+ return new SvxDummyTextSource();
+}
+
+SvxTextForwarder* SvxDummyTextSource::GetTextForwarder()
+{
+ return this;
+}
+
+void SvxDummyTextSource::UpdateData()
+{
+}
+
+sal_uInt16 SvxDummyTextSource::GetParagraphCount() const
+{
+ return 0;
+}
+
+sal_uInt16 SvxDummyTextSource::GetTextLen( sal_uInt16 ) const
+{
+ return 0;
+}
+
+String SvxDummyTextSource::GetText( const ESelection& ) const
+{
+ return String();
+}
+
+SfxItemSet SvxDummyTextSource::GetAttribs( const ESelection&, BOOL ) const
+{
+ // AW: Very dangerous: The former implementation used a SfxItemPool created on the
+ // fly which of course was deleted again ASAP. Thus, the returned SfxItemSet was using
+ // a deleted Pool by design.
+ return SfxItemSet(EditEngine::GetGlobalItemPool());
+}
+
+SfxItemSet SvxDummyTextSource::GetParaAttribs( sal_uInt16 ) const
+{
+ return GetAttribs(ESelection());
+}
+
+void SvxDummyTextSource::SetParaAttribs( sal_uInt16, const SfxItemSet& )
+{
+}
+
+void SvxDummyTextSource::RemoveAttribs( const ESelection& , sal_Bool , sal_uInt16 )
+{
+}
+
+void SvxDummyTextSource::GetPortions( sal_uInt16, SvUShorts& ) const
+{
+}
+
+sal_uInt16 SvxDummyTextSource::GetItemState( const ESelection&, sal_uInt16 ) const
+{
+ return 0;
+}
+
+sal_uInt16 SvxDummyTextSource::GetItemState( sal_uInt16, sal_uInt16 ) const
+{
+ return 0;
+}
+
+SfxItemPool* SvxDummyTextSource::GetPool() const
+{
+ return NULL;
+}
+
+void SvxDummyTextSource::QuickInsertText( const String&, const ESelection& )
+{
+}
+
+void SvxDummyTextSource::QuickInsertField( const SvxFieldItem&, const ESelection& )
+{
+}
+
+void SvxDummyTextSource::QuickSetAttribs( const SfxItemSet&, const ESelection& )
+{
+}
+
+void SvxDummyTextSource::QuickInsertLineBreak( const ESelection& )
+{
+};
+
+XubString SvxDummyTextSource::CalcFieldValue( const SvxFieldItem&, sal_uInt16, sal_uInt16, Color*&, Color*& )
+{
+ return XubString();
+}
+
+sal_Bool SvxDummyTextSource::IsValid() const
+{
+ return sal_False;
+}
+
+void SvxDummyTextSource::SetNotifyHdl( const Link& )
+{
+}
+
+LanguageType SvxDummyTextSource::GetLanguage( USHORT, USHORT ) const
+{
+ return LANGUAGE_DONTKNOW;
+}
+
+USHORT SvxDummyTextSource::GetFieldCount( USHORT ) const
+{
+ return 0;
+}
+
+EFieldInfo SvxDummyTextSource::GetFieldInfo( USHORT, USHORT ) const
+{
+ return EFieldInfo();
+}
+
+EBulletInfo SvxDummyTextSource::GetBulletInfo( USHORT ) const
+{
+ return EBulletInfo();
+}
+
+Rectangle SvxDummyTextSource::GetCharBounds( USHORT, USHORT ) const
+{
+ return Rectangle();
+}
+
+Rectangle SvxDummyTextSource::GetParaBounds( USHORT ) const
+{
+ return Rectangle();
+}
+
+MapMode SvxDummyTextSource::GetMapMode() const
+{
+ return MapMode();
+}
+
+OutputDevice* SvxDummyTextSource::GetRefDevice() const
+{
+ return NULL;
+}
+
+sal_Bool SvxDummyTextSource::GetIndexAtPoint( const Point&, USHORT&, USHORT& ) const
+{
+ return sal_False;
+}
+
+sal_Bool SvxDummyTextSource::GetWordIndices( USHORT, USHORT, USHORT&, USHORT& ) const
+{
+ return sal_False;
+}
+
+sal_Bool SvxDummyTextSource::GetAttributeRun( USHORT&, USHORT&, USHORT, USHORT ) const
+{
+ return sal_False;
+}
+
+USHORT SvxDummyTextSource::GetLineCount( USHORT ) const
+{
+ return 0;
+}
+
+USHORT SvxDummyTextSource::GetLineLen( USHORT, USHORT ) const
+{
+ return 0;
+}
+
+void SvxDummyTextSource::GetLineBoundaries( /*out*/USHORT &rStart, /*out*/USHORT &rEnd, USHORT /*nParagraph*/, USHORT /*nLine*/ ) const
+{
+ rStart = rEnd = 0;
+}
+
+USHORT SvxDummyTextSource::GetLineNumberAtIndex( USHORT /*nPara*/, USHORT /*nIndex*/ ) const
+{
+ return 0;
+}
+
+sal_Bool SvxDummyTextSource::QuickFormatDoc( BOOL )
+{
+ return sal_False;
+}
+
+sal_Int16 SvxDummyTextSource::GetDepth( USHORT ) const
+{
+ return -1;
+}
+
+sal_Bool SvxDummyTextSource::SetDepth( USHORT, sal_Int16 nNewDepth )
+{
+ return nNewDepth == 0 ? sal_True : sal_False;
+}
+
+sal_Bool SvxDummyTextSource::Delete( const ESelection& )
+{
+ return sal_False;
+}
+
+sal_Bool SvxDummyTextSource::InsertText( const String&, const ESelection& )
+{
+ return sal_False;
+}
+
+const SfxItemSet * SvxDummyTextSource::GetEmptyItemSetPtr()
+{
+ return 0;
+}
+
+void SvxDummyTextSource::AppendParagraph()
+{
+}
+
+xub_StrLen SvxDummyTextSource::AppendTextPortion( USHORT, const String &, const SfxItemSet & )
+{
+ return 0;
+}
+
+void SvxDummyTextSource::CopyText(const SvxTextForwarder& )
+{
+}
+
diff --git a/editeng/source/uno/unotext2.cxx b/editeng/source/uno/unotext2.cxx
new file mode 100644
index 0000000000..579d2c6dfa
--- /dev/null
+++ b/editeng/source/uno/unotext2.cxx
@@ -0,0 +1,714 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unotext2.cxx,v $
+ * $Revision: 1.27 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <vcl/svapp.hxx>
+#include <vos/mutex.hxx>
+
+#define _SVSTDARR_USHORTS
+#include <svl/svstdarr.hxx>
+
+#include <rtl/uuid.h>
+#include <rtl/memory.h>
+
+#include <editeng/eeitem.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/unofield.hxx>
+#include <editeng/unotext.hxx>
+#include <comphelper/serviceinfohelper.hxx>
+
+using namespace ::rtl;
+using namespace ::vos;
+using namespace ::cppu;
+using namespace ::com::sun::star;
+
+#define QUERYINT( xint ) \
+ if( rType == ::getCppuType((const uno::Reference< xint >*)0) ) \
+ return uno::makeAny(uno::Reference< xint >(this))
+
+// ====================================================================
+// SvxUnoTextContentEnumeration
+// ====================================================================
+
+SvxUnoTextContentEnumeration::SvxUnoTextContentEnumeration( const SvxUnoTextBase& _rText ) throw()
+: mrText( _rText )
+{
+ mxParentText = const_cast<SvxUnoTextBase*>(&_rText);
+ if( mrText.GetEditSource() )
+ mpEditSource = mrText.GetEditSource()->Clone();
+ else
+ mpEditSource = NULL;
+ mnNextParagraph = 0;
+}
+
+SvxUnoTextContentEnumeration::~SvxUnoTextContentEnumeration() throw()
+{
+ delete mpEditSource;
+}
+
+// container::XEnumeration
+sal_Bool SAL_CALL SvxUnoTextContentEnumeration::hasMoreElements(void)
+ throw( uno::RuntimeException )
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ if( mpEditSource && mpEditSource->GetTextForwarder() )
+ return mnNextParagraph < mpEditSource->GetTextForwarder()->GetParagraphCount();
+ else
+ return sal_False;
+}
+
+uno::Any SvxUnoTextContentEnumeration::nextElement(void) throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if(!hasMoreElements())
+ throw container::NoSuchElementException();
+
+ SvxUnoTextContent* pContent = 0;
+
+ const SvxUnoTextRangeBaseList& rRanges( mpEditSource->getRanges() );
+ SvxUnoTextRangeBaseList::const_iterator aIter;
+ for( aIter = rRanges.begin(); (aIter != rRanges.end()) && (pContent == 0); aIter++ )
+ {
+ SvxUnoTextContent* pIterContent = dynamic_cast< SvxUnoTextContent* >( (*aIter ) );
+ if( pIterContent && (pIterContent->mnParagraph == mnNextParagraph) )
+ pContent = pIterContent;
+ }
+
+ if( pContent == 0 )
+ pContent = new SvxUnoTextContent( mrText, mnNextParagraph );
+
+ mnNextParagraph++;
+
+ uno::Reference< text::XTextContent > xRef( pContent );
+ return uno::makeAny( xRef );
+}
+
+// ====================================================================
+// class SvxUnoTextContent
+// ====================================================================
+uno::Reference< text::XText > xDummyText;
+uno::Sequence< uno::Type > SvxUnoTextContent::maTypeSequence;
+
+static SvxUnoText* getDummyText() throw()
+{
+ if(!xDummyText.is())
+ xDummyText = new SvxUnoText();
+
+ return SvxUnoText::getImplementation( xDummyText );
+}
+
+SvxUnoTextContent::SvxUnoTextContent() throw()
+: SvxUnoTextRangeBase(*getDummyText())
+, mnParagraph(0)
+, mrParentText(*getDummyText())
+, maDisposeListeners(maDisposeContainerMutex)
+, mbDisposing( false )
+{
+}
+
+SvxUnoTextContent::SvxUnoTextContent( const SvxUnoTextBase& rText, sal_uInt16 nPara ) throw()
+: SvxUnoTextRangeBase(rText)
+, mnParagraph(nPara)
+, mrParentText(rText)
+, maDisposeListeners(maDisposeContainerMutex)
+, mbDisposing( false )
+{
+ mxParentText = const_cast<SvxUnoTextBase*>(&rText);
+ if( GetEditSource() && GetEditSource()->GetTextForwarder() )
+ SetSelection( ESelection( mnParagraph,0, mnParagraph, GetEditSource()->GetTextForwarder()->GetTextLen( mnParagraph ) ) );
+}
+
+SvxUnoTextContent::SvxUnoTextContent( const SvxUnoTextContent& rContent ) throw()
+: SvxUnoTextRangeBase(rContent)
+, text::XTextContent()
+, container::XEnumerationAccess()
+, lang::XTypeProvider()
+, cppu::OWeakAggObject()
+, mrParentText(rContent.mrParentText)
+, maDisposeListeners(maDisposeContainerMutex)
+, mbDisposing( false )
+{
+ mxParentText = rContent.mxParentText;
+ mnParagraph = rContent.mnParagraph;
+ SetSelection( rContent.GetSelection() );
+}
+
+SvxUnoTextContent::~SvxUnoTextContent() throw()
+{
+}
+
+// uno::XInterface
+uno::Any SAL_CALL SvxUnoTextContent::queryAggregation( const uno::Type & rType ) throw( uno::RuntimeException )
+{
+ QUERYINT( text::XTextRange );
+ else QUERYINT( beans::XMultiPropertyStates );
+ else QUERYINT( beans::XPropertySet );
+ else QUERYINT( beans::XMultiPropertySet );
+ else QUERYINT( beans::XPropertyState );
+ else QUERYINT( text::XTextContent );
+ else QUERYINT( text::XTextRangeCompare );
+ else QUERYINT( lang::XComponent );
+ else QUERYINT( container::XEnumerationAccess );
+ else QUERYINT( container::XElementAccess );
+ else QUERYINT( lang::XServiceInfo );
+ else QUERYINT( lang::XTypeProvider );
+ else QUERYINT( lang::XUnoTunnel );
+ else
+ return OWeakAggObject::queryAggregation( rType );
+}
+
+uno::Any SAL_CALL SvxUnoTextContent::queryInterface( const uno::Type & rType ) throw( uno::RuntimeException )
+{
+ return OWeakAggObject::queryInterface(rType);
+}
+
+void SAL_CALL SvxUnoTextContent::acquire() throw( )
+{
+ OWeakAggObject::acquire();
+}
+
+void SAL_CALL SvxUnoTextContent::release() throw( )
+{
+ OWeakAggObject::release();
+}
+
+// XTypeProvider
+
+uno::Sequence< uno::Type > SAL_CALL SvxUnoTextContent::getTypes()
+ throw (uno::RuntimeException)
+{
+ if( maTypeSequence.getLength() == 0 )
+ {
+ maTypeSequence.realloc( 11 ); // !DANGER! keep this updated
+ uno::Type* pTypes = maTypeSequence.getArray();
+
+ *pTypes++ = ::getCppuType(( const uno::Reference< text::XTextRange >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< beans::XPropertySet >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< beans::XMultiPropertySet >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< beans::XMultiPropertyStates >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< beans::XPropertyState >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< text::XTextRangeCompare >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< text::XTextContent >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< container::XEnumerationAccess >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< lang::XServiceInfo >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< lang::XTypeProvider >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< lang::XUnoTunnel >*)0);
+ }
+ return maTypeSequence;
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL SvxUnoTextContent::getImplementationId()
+ throw (uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+// text::XTextRange
+
+uno::Reference< text::XText > SAL_CALL SvxUnoTextContent::getText()
+ throw(uno::RuntimeException)
+{
+ return mxParentText;
+}
+
+// text::XTextContent
+void SAL_CALL SvxUnoTextContent::attach( const uno::Reference< text::XTextRange >& )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+}
+
+uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextContent::getAnchor() throw( uno::RuntimeException )
+{
+ return uno::Reference< text::XTextRange >::query( mxParentText );
+}
+
+// XComponent
+
+void SAL_CALL SvxUnoTextContent::dispose()
+ throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if( mbDisposing )
+ return; // catched a recursion
+
+ mbDisposing = true;
+
+ lang::EventObject aEvt;
+ aEvt.Source = *(OWeakAggObject*) this;
+ maDisposeListeners.disposeAndClear(aEvt);
+
+ if( mxParentText.is() )
+ mxParentText->removeTextContent( this );
+}
+
+void SAL_CALL SvxUnoTextContent::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ maDisposeListeners.addInterface(xListener);
+}
+
+void SAL_CALL SvxUnoTextContent::removeEventListener( const uno::Reference< lang::XEventListener >& aListener )
+ throw(uno::RuntimeException)
+{
+ maDisposeListeners.removeInterface(aListener);
+}
+
+// XEnumerationAccess
+
+uno::Reference< container::XEnumeration > SAL_CALL SvxUnoTextContent::createEnumeration( )
+ throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ return new SvxUnoTextRangeEnumeration( mrParentText, mnParagraph );
+}
+
+// XElementAccess ( container::XEnumerationAccess )
+
+uno::Type SAL_CALL SvxUnoTextContent::getElementType()
+ throw(uno::RuntimeException)
+{
+ return ::getCppuType((const uno::Reference< text::XTextRange >*)0);
+}
+
+sal_Bool SAL_CALL SvxUnoTextContent::hasElements()
+ throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ SvxTextForwarder* pForwarder = GetEditSource() ? GetEditSource()->GetTextForwarder() : NULL;
+ if( pForwarder )
+ {
+ SvUShorts aPortions;
+ pForwarder->GetPortions( mnParagraph, aPortions );
+ return aPortions.Count() > 0;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+// XPropertySet
+
+void SAL_CALL SvxUnoTextContent::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ _setPropertyValue( aPropertyName, aValue, mnParagraph );
+}
+
+uno::Any SAL_CALL SvxUnoTextContent::getPropertyValue( const OUString& PropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ return _getPropertyValue( PropertyName, mnParagraph );
+}
+
+// XMultiPropertySet
+void SAL_CALL SvxUnoTextContent::setPropertyValues( const uno::Sequence< ::rtl::OUString >& aPropertyNames, const uno::Sequence< uno::Any >& aValues ) throw (beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ _setPropertyValues( aPropertyNames, aValues, mnParagraph );
+}
+
+uno::Sequence< uno::Any > SAL_CALL SvxUnoTextContent::getPropertyValues( const uno::Sequence< ::rtl::OUString >& aPropertyNames ) throw (uno::RuntimeException)
+{
+ return _getPropertyValues( aPropertyNames, mnParagraph );
+}
+
+/*// XTolerantMultiPropertySet
+uno::Sequence< beans::SetPropertyTolerantFailed > SAL_CALL SvxUnoTextContent::setPropertyValuesTolerant( const uno::Sequence< ::rtl::OUString >& aPropertyNames, const uno::Sequence< uno::Any >& aValues ) throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ return _setPropertyValuesTolerant(aPropertyNames, aValues, mnParagraph);
+}
+
+uno::Sequence< beans::GetPropertyTolerantResult > SAL_CALL SvxUnoTextContent::getPropertyValuesTolerant( const uno::Sequence< ::rtl::OUString >& aPropertyNames ) throw (uno::RuntimeException)
+{
+ return _getPropertyValuesTolerant(aPropertyNames, mnParagraph);
+}
+
+uno::Sequence< beans::GetDirectPropertyTolerantResult > SAL_CALL SvxUnoTextContent::getDirectPropertyValuesTolerant( const uno::Sequence< ::rtl::OUString >& aPropertyNames )
+ throw (uno::RuntimeException)
+{
+ return _getDirectPropertyValuesTolerant(aPropertyNames, mnParagraph);
+}*/
+
+// beans::XPropertyState
+beans::PropertyState SAL_CALL SvxUnoTextContent::getPropertyState( const OUString& PropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ return _getPropertyState( PropertyName, mnParagraph );
+}
+
+uno::Sequence< beans::PropertyState > SAL_CALL SvxUnoTextContent::getPropertyStates( const uno::Sequence< OUString >& aPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ return _getPropertyStates( aPropertyName, mnParagraph );
+}
+
+void SAL_CALL SvxUnoTextContent::setPropertyToDefault( const OUString& PropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ _setPropertyToDefault( PropertyName, mnParagraph );
+}
+
+// lang::XServiceInfo
+
+OUString SAL_CALL SvxUnoTextContent::getImplementationName()
+ throw(uno::RuntimeException)
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM("SvxUnoTextContent") );
+}
+
+uno::Sequence< OUString > SAL_CALL SvxUnoTextContent::getSupportedServiceNames()
+ throw(uno::RuntimeException)
+{
+ uno::Sequence< OUString > aSeq( SvxUnoTextRangeBase::getSupportedServiceNames() );
+ comphelper::ServiceInfoHelper::addToSequence( aSeq, 5, "com.sun.star.style.ParagraphProperties",
+ "com.sun.star.style.ParagraphPropertiesComplex",
+ "com.sun.star.style.ParagraphPropertiesAsian",
+ "com.sun.star.text.TextContent",
+ "com.sun.star.text.Paragraph");
+ return aSeq;
+}
+
+// ====================================================================
+// class SvxUnoTextRangeEnumeration
+// ====================================================================
+
+SvxUnoTextRangeEnumeration::SvxUnoTextRangeEnumeration( const SvxUnoTextBase& rText, sal_uInt16 nPara ) throw()
+: mxParentText( const_cast<SvxUnoTextBase*>(&rText) ),
+ mrParentText( rText ),
+ mnParagraph( nPara ),
+ mnNextPortion( 0 )
+{
+ mpEditSource = rText.GetEditSource() ? rText.GetEditSource()->Clone() : NULL;
+
+ if( mpEditSource && mpEditSource->GetTextForwarder() )
+ {
+ mpPortions = new SvUShorts;
+ mpEditSource->GetTextForwarder()->GetPortions( nPara, *mpPortions );
+ }
+ else
+ {
+ mpPortions = NULL;
+ }
+}
+
+SvxUnoTextRangeEnumeration::~SvxUnoTextRangeEnumeration() throw()
+{
+ delete mpEditSource;
+ delete mpPortions;
+}
+
+// container::XEnumeration
+
+sal_Bool SAL_CALL SvxUnoTextRangeEnumeration::hasMoreElements()
+ throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ return mpPortions && mnNextPortion < mpPortions->Count();
+}
+
+uno::Any SAL_CALL SvxUnoTextRangeEnumeration::nextElement()
+ throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if( mpPortions == NULL || mnNextPortion >= mpPortions->Count() )
+ throw container::NoSuchElementException();
+
+ sal_uInt16 nStartPos = 0;
+ if (mnNextPortion > 0)
+ nStartPos = mpPortions->GetObject(mnNextPortion-1);
+ sal_uInt16 nEndPos = mpPortions->GetObject(mnNextPortion);
+ ESelection aSel( mnParagraph, nStartPos, mnParagraph, nEndPos );
+
+ uno::Reference< text::XTextRange > xRange;
+
+ const SvxUnoTextRangeBaseList& rRanges( mpEditSource->getRanges() );
+
+ SvxUnoTextRange* pRange = 0;
+
+ SvxUnoTextRangeBaseList::const_iterator aIter;
+ for( aIter = rRanges.begin(); (aIter != rRanges.end()) && (pRange == 0); aIter++ )
+ {
+ SvxUnoTextRange* pIterRange = dynamic_cast< SvxUnoTextRange* >( (*aIter ) );
+ if( pIterRange && pIterRange->mbPortion && (aSel.IsEqual( pIterRange->maSelection ) ) )
+ pRange = pIterRange;
+ }
+
+ if( pRange == 0 )
+ {
+ pRange = new SvxUnoTextRange( mrParentText, sal_True );
+ pRange->SetSelection(aSel);
+ }
+
+ xRange = pRange;
+
+ mnNextPortion++;
+
+ return uno::makeAny( xRange );
+}
+
+// ====================================================================
+// class SvxUnoTextCursor
+// ====================================================================
+
+uno::Sequence< uno::Type > SvxUnoTextCursor::maTypeSequence;
+
+uno::Reference< uno::XInterface > SvxUnoTextCursor_NewInstance()
+{
+ SvxUnoText aText;
+ uno::Reference< text::XText > xText( (text::XText*)new SvxUnoTextCursor( aText ) );
+ uno::Reference< uno::XInterface > xInt( xText, uno::UNO_QUERY );
+ return xInt;
+}
+
+SvxUnoTextCursor::SvxUnoTextCursor( const SvxUnoTextBase& rText ) throw()
+: SvxUnoTextRangeBase(rText),
+ mxParentText( const_cast<SvxUnoTextBase*>(&rText) )
+{
+}
+
+SvxUnoTextCursor::SvxUnoTextCursor( const SvxUnoTextCursor& rCursor ) throw()
+: SvxUnoTextRangeBase(rCursor)
+, text::XTextCursor()
+, lang::XTypeProvider()
+, cppu::OWeakAggObject()
+, mxParentText(rCursor.mxParentText)
+{
+}
+
+SvxUnoTextCursor::~SvxUnoTextCursor() throw()
+{
+}
+
+// automatisch auskommentiert - [getIdlClass(es) or queryInterface] - Bitte XTypeProvider benutzen!
+//sal_Bool SvxUnoTextCursor::queryInterface( uno::Uik aUIK, Reference< uno::XInterface > & xRef)
+uno::Any SAL_CALL SvxUnoTextCursor::queryAggregation( const uno::Type & rType )
+ throw(uno::RuntimeException)
+{
+ if( rType == ::getCppuType((const uno::Reference< text::XTextRange >*)0) )
+ return uno::makeAny(uno::Reference< text::XTextRange >((text::XText*)(this)));
+ else QUERYINT( text::XTextCursor );
+ else QUERYINT( beans::XMultiPropertyStates );
+ else QUERYINT( beans::XPropertySet );
+ else QUERYINT( beans::XMultiPropertySet );
+ else QUERYINT( beans::XPropertyState );
+ else QUERYINT( text::XTextRangeCompare );
+ else QUERYINT( lang::XServiceInfo );
+ else QUERYINT( lang::XTypeProvider );
+ else QUERYINT( lang::XUnoTunnel );
+ else
+ return OWeakAggObject::queryAggregation( rType );
+}
+
+uno::Any SAL_CALL SvxUnoTextCursor::queryInterface( const uno::Type & rType )
+ throw(uno::RuntimeException)
+{
+ return OWeakAggObject::queryInterface(rType);
+}
+
+void SAL_CALL SvxUnoTextCursor::acquire() throw ( )
+{
+ OWeakAggObject::acquire();
+}
+
+void SAL_CALL SvxUnoTextCursor::release() throw ( )
+{
+ OWeakAggObject::release();
+}
+
+// XTypeProvider
+uno::Sequence< uno::Type > SAL_CALL SvxUnoTextCursor::getTypes()
+ throw(uno::RuntimeException)
+{
+ if( maTypeSequence.getLength() == 0 )
+ {
+ maTypeSequence.realloc( 10 ); // !DANGER! keep this updated
+ uno::Type* pTypes = maTypeSequence.getArray();
+
+ *pTypes++ = ::getCppuType(( const uno::Reference< text::XTextRange >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< text::XTextCursor >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< beans::XPropertySet >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< beans::XMultiPropertySet >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< beans::XMultiPropertyStates >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< beans::XPropertyState >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< text::XTextRangeCompare >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< lang::XServiceInfo >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< lang::XTypeProvider >*)0);
+ *pTypes++ = ::getCppuType(( const uno::Reference< lang::XUnoTunnel >*)0);
+ }
+ return maTypeSequence;
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL SvxUnoTextCursor::getImplementationId()
+ throw (uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+// text::XTextCursor
+void SAL_CALL SvxUnoTextCursor::collapseToStart()
+ throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ CollapseToStart();
+}
+
+void SAL_CALL SvxUnoTextCursor::collapseToEnd()
+ throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ CollapseToEnd();
+}
+
+sal_Bool SAL_CALL SvxUnoTextCursor::isCollapsed()
+ throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ return IsCollapsed();
+}
+
+sal_Bool SAL_CALL SvxUnoTextCursor::goLeft( sal_Int16 nCount, sal_Bool bExpand )
+ throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ return GoLeft( nCount, bExpand );
+}
+
+sal_Bool SAL_CALL SvxUnoTextCursor::goRight( sal_Int16 nCount, sal_Bool bExpand )
+ throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ return GoRight( nCount, bExpand );
+}
+
+void SAL_CALL SvxUnoTextCursor::gotoStart( sal_Bool bExpand )
+ throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ GotoStart( bExpand );
+}
+
+void SAL_CALL SvxUnoTextCursor::gotoEnd( sal_Bool bExpand )
+ throw(uno::RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ GotoEnd( bExpand );
+}
+
+void SAL_CALL SvxUnoTextCursor::gotoRange( const uno::Reference< text::XTextRange >& xRange, sal_Bool bExpand )
+ throw(uno::RuntimeException)
+{
+ if( !xRange.is() )
+ return;
+
+ SvxUnoTextRangeBase* pRange = SvxUnoTextRangeBase::getImplementation( xRange );
+
+ if( pRange )
+ {
+ ESelection aNewSel = pRange->GetSelection();
+
+ if( bExpand )
+ {
+ const ESelection& rOldSel = GetSelection();
+ aNewSel.nStartPara = rOldSel.nStartPara;
+ aNewSel.nStartPos = rOldSel.nStartPos;
+ }
+
+ SetSelection( aNewSel );
+ }
+}
+
+// text::XTextRange (rest in SvxTextRange)
+uno::Reference< text::XText > SAL_CALL SvxUnoTextCursor::getText(void) throw( uno::RuntimeException )
+{
+ return mxParentText;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextCursor::getStart()
+ throw(uno::RuntimeException)
+{
+ return SvxUnoTextRangeBase::getStart();
+}
+
+uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextCursor::getEnd()
+ throw(uno::RuntimeException)
+{
+ return SvxUnoTextRangeBase::getEnd();
+}
+
+OUString SAL_CALL SvxUnoTextCursor::getString() throw( uno::RuntimeException )
+{
+ return SvxUnoTextRangeBase::getString();
+}
+
+void SAL_CALL SvxUnoTextCursor::setString( const OUString& aString ) throw(uno::RuntimeException)
+{
+ SvxUnoTextRangeBase::setString(aString);
+}
+// lang::XServiceInfo
+OUString SAL_CALL SvxUnoTextCursor::getImplementationName() throw(uno::RuntimeException)
+{
+ return OUString(RTL_CONSTASCII_USTRINGPARAM("SvxUnoTextCursor"));
+}
+
+sal_Bool SAL_CALL SvxUnoTextCursor::supportsService( const OUString& ServiceName ) throw(uno::RuntimeException)
+{
+ return comphelper::ServiceInfoHelper::supportsService( ServiceName, getSupportedServiceNames() );
+}
+
+uno::Sequence< OUString > SAL_CALL SvxUnoTextCursor::getSupportedServiceNames() throw(uno::RuntimeException)
+{
+ uno::Sequence< OUString > aSeq( SvxUnoTextRangeBase::getSupportedServiceNames() );
+ comphelper::ServiceInfoHelper::addToSequence( aSeq, 4,"com.sun.star.style.ParagraphProperties",
+ "com.sun.star.style.ParagraphPropertiesComplex",
+ "com.sun.star.style.ParagraphPropertiesAsian",
+ "com.sun.star.text.TextCursor");
+ return aSeq;
+}
+
+
diff --git a/editeng/source/uno/unoviwed.cxx b/editeng/source/uno/unoviwed.cxx
new file mode 100644
index 0000000000..98ca6ddfff
--- /dev/null
+++ b/editeng/source/uno/unoviwed.cxx
@@ -0,0 +1,140 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unoviwed.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <vcl/outdev.hxx>
+#include <vcl/window.hxx>
+
+#include <editeng/unoviwed.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/editeng.hxx>
+
+SvxEditEngineViewForwarder::SvxEditEngineViewForwarder( EditView& rView ) :
+ mrView( rView )
+{
+}
+
+SvxEditEngineViewForwarder::~SvxEditEngineViewForwarder()
+{
+}
+
+BOOL SvxEditEngineViewForwarder::IsValid() const
+{
+ return sal_True;
+}
+
+Rectangle SvxEditEngineViewForwarder::GetVisArea() const
+{
+ OutputDevice* pOutDev = mrView.GetWindow();
+
+ if( pOutDev )
+ {
+ Rectangle aVisArea = mrView.GetVisArea();
+
+ // figure out map mode from edit engine
+ EditEngine* pEditEngine = mrView.GetEditEngine();
+
+ if( pEditEngine )
+ {
+ MapMode aMapMode(pOutDev->GetMapMode());
+ aVisArea = OutputDevice::LogicToLogic( aVisArea,
+ pEditEngine->GetRefMapMode(),
+ aMapMode.GetMapUnit() );
+ aMapMode.SetOrigin(Point());
+ return pOutDev->LogicToPixel( aVisArea, aMapMode );
+ }
+ }
+
+ return Rectangle();
+}
+
+Point SvxEditEngineViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ OutputDevice* pOutDev = mrView.GetWindow();
+
+ if( pOutDev )
+ {
+ MapMode aMapMode(pOutDev->GetMapMode());
+ Point aPoint( OutputDevice::LogicToLogic( rPoint, rMapMode,
+ aMapMode.GetMapUnit() ) );
+ aMapMode.SetOrigin(Point());
+ return pOutDev->LogicToPixel( aPoint, aMapMode );
+ }
+
+ return Point();
+}
+
+Point SvxEditEngineViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ OutputDevice* pOutDev = mrView.GetWindow();
+
+ if( pOutDev )
+ {
+ MapMode aMapMode(pOutDev->GetMapMode());
+ aMapMode.SetOrigin(Point());
+ Point aPoint( pOutDev->PixelToLogic( rPoint, aMapMode ) );
+ return OutputDevice::LogicToLogic( aPoint,
+ aMapMode.GetMapUnit(),
+ rMapMode );
+ }
+
+ return Point();
+}
+
+sal_Bool SvxEditEngineViewForwarder::GetSelection( ESelection& rSelection ) const
+{
+ rSelection = mrView.GetSelection();
+ return sal_True;
+}
+
+sal_Bool SvxEditEngineViewForwarder::SetSelection( const ESelection& rSelection )
+{
+ mrView.SetSelection( rSelection );
+ return sal_True;
+}
+
+sal_Bool SvxEditEngineViewForwarder::Copy()
+{
+ mrView.Copy();
+ return sal_True;
+}
+
+sal_Bool SvxEditEngineViewForwarder::Cut()
+{
+ mrView.Cut();
+ return sal_True;
+}
+
+sal_Bool SvxEditEngineViewForwarder::Paste()
+{
+ mrView.Paste();
+ return sal_True;
+}
diff --git a/editeng/source/uno/unoviwou.cxx b/editeng/source/uno/unoviwou.cxx
new file mode 100644
index 0000000000..a5fe0380cc
--- /dev/null
+++ b/editeng/source/uno/unoviwou.cxx
@@ -0,0 +1,176 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unoviwou.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <vcl/outdev.hxx>
+#include <vcl/window.hxx>
+
+#include <editeng/unoviwou.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/editeng.hxx>
+
+SvxDrawOutlinerViewForwarder::SvxDrawOutlinerViewForwarder( OutlinerView& rOutl ) :
+ mrOutlinerView ( rOutl ), maTextShapeTopLeft()
+{
+}
+
+SvxDrawOutlinerViewForwarder::SvxDrawOutlinerViewForwarder( OutlinerView& rOutl, const Point& rShapePosTopLeft ) :
+ mrOutlinerView ( rOutl ), maTextShapeTopLeft( rShapePosTopLeft )
+{
+}
+
+SvxDrawOutlinerViewForwarder::~SvxDrawOutlinerViewForwarder()
+{
+}
+
+Point SvxDrawOutlinerViewForwarder::GetTextOffset() const
+{
+ // #101029# calc text offset from shape anchor
+ Rectangle aOutputRect( mrOutlinerView.GetOutputArea() );
+
+ return aOutputRect.TopLeft() - maTextShapeTopLeft;
+}
+
+BOOL SvxDrawOutlinerViewForwarder::IsValid() const
+{
+ return sal_True;
+}
+
+Rectangle SvxDrawOutlinerViewForwarder::GetVisArea() const
+{
+ OutputDevice* pOutDev = mrOutlinerView.GetWindow();
+
+ if( pOutDev )
+ {
+ Rectangle aVisArea = mrOutlinerView.GetVisArea();
+
+ // #101029#
+ Point aTextOffset( GetTextOffset() );
+ aVisArea.Move( aTextOffset.X(), aTextOffset.Y() );
+
+ // figure out map mode from edit engine
+ Outliner* pOutliner = mrOutlinerView.GetOutliner();
+
+ if( pOutliner )
+ {
+ MapMode aMapMode(pOutDev->GetMapMode());
+ aVisArea = OutputDevice::LogicToLogic( aVisArea,
+ pOutliner->GetRefMapMode(),
+ aMapMode.GetMapUnit() );
+ aMapMode.SetOrigin(Point());
+ return pOutDev->LogicToPixel( aVisArea, aMapMode );
+ }
+ }
+
+ return Rectangle();
+}
+
+Point SvxDrawOutlinerViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ OutputDevice* pOutDev = mrOutlinerView.GetWindow();
+
+ if( pOutDev )
+ {
+ Point aPoint1( rPoint );
+ Point aTextOffset( GetTextOffset() );
+
+ // #101029#
+ aPoint1.X() += aTextOffset.X();
+ aPoint1.Y() += aTextOffset.Y();
+
+ MapMode aMapMode(pOutDev->GetMapMode());
+ Point aPoint2( OutputDevice::LogicToLogic( aPoint1, rMapMode,
+ aMapMode.GetMapUnit() ) );
+ aMapMode.SetOrigin(Point());
+ return pOutDev->LogicToPixel( aPoint2, aMapMode );
+ }
+
+ return Point();
+}
+
+Point SvxDrawOutlinerViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ OutputDevice* pOutDev = mrOutlinerView.GetWindow();
+
+ if( pOutDev )
+ {
+ MapMode aMapMode(pOutDev->GetMapMode());
+ aMapMode.SetOrigin(Point());
+ Point aPoint1( pOutDev->PixelToLogic( rPoint, aMapMode ) );
+ Point aPoint2( OutputDevice::LogicToLogic( aPoint1,
+ aMapMode.GetMapUnit(),
+ rMapMode ) );
+ // #101029#
+ Point aTextOffset( GetTextOffset() );
+
+ aPoint2.X() -= aTextOffset.X();
+ aPoint2.Y() -= aTextOffset.Y();
+
+ return aPoint2;
+ }
+
+ return Point();
+}
+
+sal_Bool SvxDrawOutlinerViewForwarder::GetSelection( ESelection& rSelection ) const
+{
+ rSelection = mrOutlinerView.GetSelection();
+ return sal_True;
+}
+
+sal_Bool SvxDrawOutlinerViewForwarder::SetSelection( const ESelection& rSelection )
+{
+ mrOutlinerView.SetSelection( rSelection );
+ return sal_True;
+}
+
+sal_Bool SvxDrawOutlinerViewForwarder::Copy()
+{
+ mrOutlinerView.Copy();
+ return sal_True;
+}
+
+sal_Bool SvxDrawOutlinerViewForwarder::Cut()
+{
+ mrOutlinerView.Cut();
+ return sal_True;
+}
+
+sal_Bool SvxDrawOutlinerViewForwarder::Paste()
+{
+ mrOutlinerView.Paste();
+ return sal_True;
+}
+
+void SvxDrawOutlinerViewForwarder::SetShapePos( const Point& rShapePosTopLeft )
+{
+ maTextShapeTopLeft = rShapePosTopLeft;
+}
diff --git a/editeng/source/xml/editsource.hxx b/editeng/source/xml/editsource.hxx
new file mode 100644
index 0000000000..02702fa62f
--- /dev/null
+++ b/editeng/source/xml/editsource.hxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: editsource.hxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVX_EDITSOURCE_HXX
+#define _SVX_EDITSOURCE_HXX
+
+#include <editeng/unoedsrc.hxx>
+
+class EditEngine;
+class SvxEditEngineSourceImpl;
+
+class SvxEditEngineSource : public SvxEditSource
+{
+public:
+ SvxEditEngineSource( EditEngine* pEditEngine );
+ virtual ~SvxEditEngineSource();
+
+ virtual SvxEditSource* Clone() const;
+ virtual SvxTextForwarder* GetTextForwarder();
+ virtual void UpdateData();
+
+private:
+ SvxEditEngineSource( SvxEditEngineSourceImpl* pImpl );
+
+ SvxEditEngineSourceImpl* mpImpl;
+};
+
+#endif
diff --git a/editeng/source/xml/makefile.mk b/editeng/source/xml/makefile.mk
new file mode 100644
index 0000000000..bfcfeb70f1
--- /dev/null
+++ b/editeng/source/xml/makefile.mk
@@ -0,0 +1,50 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.12 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=editeng
+TARGET=xml
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+SLOFILES = \
+ $(SLO)$/xmltxtimp.obj \
+ $(SLO)$/xmltxtexp.obj
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/editeng/source/xml/xmltxtexp.cxx b/editeng/source/xml/xmltxtexp.cxx
new file mode 100644
index 0000000000..21bf37ac90
--- /dev/null
+++ b/editeng/source/xml/xmltxtexp.cxx
@@ -0,0 +1,503 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: xmltxtexp.cxx,v $
+ * $Revision: 1.15 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+
+/** this file implements an export of a selected EditEngine content into
+ a xml stream. See editeng/source/inc/xmledit.hxx for interface */
+#include <com/sun/star/ucb/XAnyCompareFactory.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <tools/debug.hxx>
+#include <svl/itemprop.hxx>
+#include <svl/brdcst.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <sot/storage.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlmetae.hxx>
+#include <cppuhelper/implbase4.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/streamwrap.hxx>
+#include <xmloff/xmlexp.hxx>
+#include <editeng/unoedsrc.hxx>
+#include <editeng/unofored.hxx>
+#include <editeng/unotext.hxx>
+#include <editeng/unoprnms.hxx>
+#include <editeng/unofield.hxx>
+#include <editeng/editeng.hxx>
+#include "editsource.hxx"
+#include <editeng/unonrule.hxx>
+#include <editeng/unoipset.hxx>
+
+using namespace com::sun::star;
+using namespace com::sun::star::container;
+using namespace com::sun::star::document;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::awt;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::xml::sax;
+using namespace ::rtl;
+using namespace cppu;
+
+///////////////////////////////////////////////////////////////////////
+
+class SvxEditEngineSourceImpl;
+
+///////////////////////////////////////////////////////////////////////
+
+class SvxEditEngineSourceImpl
+{
+private:
+ oslInterlockedCount maRefCount;
+
+ EditEngine* mpEditEngine;
+ SvxTextForwarder* mpTextForwarder;
+
+ ~SvxEditEngineSourceImpl();
+
+public:
+ SvxEditEngineSourceImpl( EditEngine* pEditEngine );
+
+ void SAL_CALL acquire();
+ void SAL_CALL release();
+
+ SvxTextForwarder* GetTextForwarder();
+};
+
+///////////////////////////////////////////////////////////////////////
+
+
+//------------------------------------------------------------------------
+
+SvxEditEngineSourceImpl::SvxEditEngineSourceImpl( EditEngine* pEditEngine )
+: maRefCount(0),
+ mpEditEngine( pEditEngine ),
+ mpTextForwarder(NULL)
+{
+}
+
+//------------------------------------------------------------------------
+
+SvxEditEngineSourceImpl::~SvxEditEngineSourceImpl()
+{
+ delete mpTextForwarder;
+}
+
+//------------------------------------------------------------------------
+
+void SAL_CALL SvxEditEngineSourceImpl::acquire()
+{
+ osl_incrementInterlockedCount( &maRefCount );
+}
+
+//------------------------------------------------------------------------
+
+void SAL_CALL SvxEditEngineSourceImpl::release()
+{
+ if( ! osl_decrementInterlockedCount( &maRefCount ) )
+ delete this;
+}
+
+//------------------------------------------------------------------------
+
+SvxTextForwarder* SvxEditEngineSourceImpl::GetTextForwarder()
+{
+ if (!mpTextForwarder)
+ mpTextForwarder = new SvxEditEngineForwarder( *mpEditEngine );
+
+ return mpTextForwarder;
+}
+
+// --------------------------------------------------------------------
+// SvxTextEditSource
+// --------------------------------------------------------------------
+
+SvxEditEngineSource::SvxEditEngineSource( EditEngine* pEditEngine )
+{
+ mpImpl = new SvxEditEngineSourceImpl( pEditEngine );
+ mpImpl->acquire();
+}
+
+// --------------------------------------------------------------------
+
+SvxEditEngineSource::SvxEditEngineSource( SvxEditEngineSourceImpl* pImpl )
+{
+ mpImpl = pImpl;
+ mpImpl->acquire();
+}
+
+//------------------------------------------------------------------------
+
+SvxEditEngineSource::~SvxEditEngineSource()
+{
+ mpImpl->release();
+}
+
+//------------------------------------------------------------------------
+
+SvxEditSource* SvxEditEngineSource::Clone() const
+{
+ return new SvxEditEngineSource( mpImpl );
+}
+
+//------------------------------------------------------------------------
+
+SvxTextForwarder* SvxEditEngineSource::GetTextForwarder()
+{
+ return mpImpl->GetTextForwarder();
+}
+
+//------------------------------------------------------------------------
+
+void SvxEditEngineSource::UpdateData()
+{
+}
+
+class SvxSimpleUnoModel : public cppu::WeakAggImplHelper4<
+ ::com::sun::star::frame::XModel,
+ ::com::sun::star::ucb::XAnyCompareFactory,
+ ::com::sun::star::style::XStyleFamiliesSupplier,
+ ::com::sun::star::lang::XMultiServiceFactory >
+{
+public:
+ SvxSimpleUnoModel();
+ virtual ~SvxSimpleUnoModel();
+
+
+ // XMultiServiceFactory
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstance( const ::rtl::OUString& aServiceSpecifier ) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Arguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getAvailableServiceNames( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XStyleFamiliesSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getStyleFamilies( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XAnyCompareFactory
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XAnyCompare > SAL_CALL createAnyCompareByName( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XModel
+ virtual sal_Bool SAL_CALL attachResource( const ::rtl::OUString& aURL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgs ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getURL( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getArgs( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL connectController( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >& xController ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL disconnectController( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >& xController ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL lockControllers( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL unlockControllers( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasControllersLocked( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController > SAL_CALL getCurrentController( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setCurrentController( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >& xController ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getCurrentSelection( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XComponent
+ virtual void SAL_CALL dispose( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+
+};
+
+SvxSimpleUnoModel::SvxSimpleUnoModel()
+{
+}
+
+SvxSimpleUnoModel::~SvxSimpleUnoModel()
+{
+}
+
+// XMultiServiceFactory ( SvxFmMSFactory )
+uno::Reference< uno::XInterface > SAL_CALL SvxSimpleUnoModel::createInstance( const OUString& aServiceSpecifier )
+ throw(uno::Exception, uno::RuntimeException)
+{
+ if( 0 == aServiceSpecifier.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.text.NumberingRules" ) ) )
+ {
+ return uno::Reference< uno::XInterface >(
+ SvxCreateNumRule(), uno::UNO_QUERY );
+ }
+ if ( (0 == aServiceSpecifier.reverseCompareToAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.text.textfield.DateTime")))
+ || (0 == aServiceSpecifier.reverseCompareToAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.text.TextField.DateTime")))
+ )
+ {
+ return (::cppu::OWeakObject * )new SvxUnoTextField( ID_EXT_DATEFIELD );
+ }
+
+ return SvxUnoTextCreateTextField( aServiceSpecifier );
+
+}
+
+uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SvxSimpleUnoModel::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ return createInstance( ServiceSpecifier );
+}
+
+Sequence< ::rtl::OUString > SAL_CALL SvxSimpleUnoModel::getAvailableServiceNames( ) throw(::com::sun::star::uno::RuntimeException)
+{
+ Sequence< OUString > aSeq;
+ return aSeq;
+}
+
+// XAnyCompareFactory
+uno::Reference< com::sun::star::ucb::XAnyCompare > SAL_CALL SvxSimpleUnoModel::createAnyCompareByName( const OUString& PropertyName )
+ throw(uno::RuntimeException)
+{
+ (void)PropertyName;
+ return SvxCreateNumRuleCompare();
+}
+
+// XStyleFamiliesSupplier
+uno::Reference< container::XNameAccess > SAL_CALL SvxSimpleUnoModel::getStyleFamilies( )
+ throw(uno::RuntimeException)
+{
+ uno::Reference< container::XNameAccess > xStyles;
+ return xStyles;
+}
+
+// XModel
+sal_Bool SAL_CALL SvxSimpleUnoModel::attachResource( const ::rtl::OUString& aURL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgs ) throw (::com::sun::star::uno::RuntimeException)
+{
+ (void)aURL;
+ (void)aArgs;
+ return sal_False;
+}
+
+::rtl::OUString SAL_CALL SvxSimpleUnoModel::getURL( ) throw (::com::sun::star::uno::RuntimeException)
+{
+ OUString aStr;
+ return aStr;
+}
+
+::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL SvxSimpleUnoModel::getArgs( ) throw (::com::sun::star::uno::RuntimeException)
+{
+ Sequence< beans::PropertyValue > aSeq;
+ return aSeq;
+}
+
+void SAL_CALL SvxSimpleUnoModel::connectController( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >& ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+void SAL_CALL SvxSimpleUnoModel::disconnectController( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >& ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+void SAL_CALL SvxSimpleUnoModel::lockControllers( ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+void SAL_CALL SvxSimpleUnoModel::unlockControllers( ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+sal_Bool SAL_CALL SvxSimpleUnoModel::hasControllersLocked( ) throw (::com::sun::star::uno::RuntimeException)
+{
+ return sal_True;
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::frame::XController > SAL_CALL SvxSimpleUnoModel::getCurrentController( ) throw (::com::sun::star::uno::RuntimeException)
+{
+ uno::Reference< frame::XController > xRet;
+ return xRet;
+}
+
+void SAL_CALL SvxSimpleUnoModel::setCurrentController( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >& ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException)
+{
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SvxSimpleUnoModel::getCurrentSelection( ) throw (::com::sun::star::uno::RuntimeException)
+{
+ uno::Reference< XInterface > xRet;
+ return xRet;
+}
+
+
+// XComponent
+void SAL_CALL SvxSimpleUnoModel::dispose( ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+void SAL_CALL SvxSimpleUnoModel::addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+void SAL_CALL SvxSimpleUnoModel::removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+///////////////////////////////////////////////////////////////////////
+
+class SvxXMLTextExportComponent : public SvXMLExport
+{
+public:
+ // #110680#
+ SvxXMLTextExportComponent(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ EditEngine* pEditEngine,
+ const ESelection& rSel,
+ const ::rtl::OUString& rFileName,
+ const com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler > & xHandler );
+
+ ~SvxXMLTextExportComponent();
+
+ // methods without content:
+ virtual void _ExportAutoStyles();
+ virtual void _ExportMasterStyles();
+ virtual void _ExportContent();
+
+private:
+ com::sun::star::uno::Reference< com::sun::star::text::XText > mxText;
+ EditEngine* mpEditEngine;
+ ESelection maSelection;
+};
+
+///////////////////////////////////////////////////////////////////////
+
+// #110680#
+SvxXMLTextExportComponent::SvxXMLTextExportComponent(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ EditEngine* pEditEngine,
+ const ESelection& rSel,
+ const ::rtl::OUString& rFileName,
+ const com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler > & xHandler)
+: SvXMLExport( xServiceFactory, rFileName, xHandler, ((frame::XModel*)new SvxSimpleUnoModel()), MAP_CM ),
+ mpEditEngine( pEditEngine ),
+ maSelection( rSel )
+{
+ SvxEditEngineSource aEditSource( pEditEngine );
+
+ static const SfxItemPropertyMapEntry SvxXMLTextExportComponentPropertyMap[] =
+ {
+ SVX_UNOEDIT_CHAR_PROPERTIES,
+ SVX_UNOEDIT_FONT_PROPERTIES,
+// SVX_UNOEDIT_OUTLINER_PROPERTIES,
+ {MAP_CHAR_LEN(UNO_NAME_NUMBERING_RULES), EE_PARA_NUMBULLET, &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexReplace>*)0), 0, 0 },
+ {MAP_CHAR_LEN(UNO_NAME_NUMBERING), EE_PARA_BULLETSTATE,&::getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(UNO_NAME_NUMBERING_LEVEL), EE_PARA_OUTLLEVEL, &::getCppuType((const sal_Int16*)0), 0, 0 },
+ SVX_UNOEDIT_PARA_PROPERTIES,
+ {0,0,0,0,0,0}
+ };
+ static SvxItemPropertySet aSvxXMLTextExportComponentPropertySet( SvxXMLTextExportComponentPropertyMap, EditEngine::GetGlobalItemPool() );
+
+ SvxUnoText* pUnoText = new SvxUnoText( &aEditSource, &aSvxXMLTextExportComponentPropertySet, mxText );
+ pUnoText->SetSelection( rSel );
+ mxText = pUnoText;
+
+ setExportFlags( EXPORT_AUTOSTYLES|EXPORT_CONTENT );
+}
+
+SvxXMLTextExportComponent::~SvxXMLTextExportComponent()
+{
+}
+
+void SvxWriteXML( EditEngine& rEditEngine, SvStream& rStream, const ESelection& rSel )
+{
+ try
+ {
+ do
+ {
+ // create service factory
+
+ uno::Reference< lang::XMultiServiceFactory> xServiceFactory( ::comphelper::getProcessServiceFactory() );
+
+ if( !xServiceFactory.is() )
+ {
+ DBG_ERROR( "got no service manager" );
+ break;
+ }
+
+ // create document handler
+
+ uno::Reference< uno::XInterface > xWriter( xServiceFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" ) ) ) );
+
+ if( !xWriter.is() )
+ {
+ DBG_ERROR( "com.sun.star.xml.sax.Writer service missing" );
+ break;
+ }
+
+ uno::Reference<xml::sax::XDocumentHandler> xHandler( xWriter, uno::UNO_QUERY );
+
+ // create output stream and active data source
+ uno::Reference<io::XOutputStream> xOut( new utl::OOutputStreamWrapper( rStream ) );
+
+/* testcode
+ const OUString aURL( RTL_CONSTASCII_USTRINGPARAM( "file:///e:/test.xml" ) );
+ SfxMedium aMedium( aURL, STREAM_WRITE | STREAM_TRUNC, TRUE );
+ aMedium.IsRemote();
+ uno::Reference<io::XOutputStream> xOut( new utl::OOutputStreamWrapper( *aMedium.GetOutStream() ) );
+*/
+
+
+ uno::Reference<io::XActiveDataSource> xMetaSrc( xWriter, uno::UNO_QUERY );
+ xMetaSrc->setOutputStream( xOut );
+
+ // export text
+ const OUString aName;
+
+ // #110680#
+ // SvxXMLTextExportComponent aExporter( &rEditEngine, rSel, aName, xHandler );
+ SvxXMLTextExportComponent aExporter( xServiceFactory, &rEditEngine, rSel, aName, xHandler );
+
+ aExporter.exportDoc();
+
+/* testcode
+ aMedium.Commit();
+*/
+
+ }
+ while( 0 );
+ }
+ catch( uno::Exception& )
+ {
+ DBG_ERROR("exception during xml export");
+ }
+}
+
+// methods without content:
+void SvxXMLTextExportComponent::_ExportAutoStyles()
+{
+ UniReference< XMLTextParagraphExport > xTextExport( GetTextParagraphExport() );
+
+ xTextExport->collectTextAutoStyles( mxText );
+ xTextExport->exportTextAutoStyles();
+}
+
+void SvxXMLTextExportComponent::_ExportContent()
+{
+ UniReference< XMLTextParagraphExport > xTextExport( GetTextParagraphExport() );
+
+ xTextExport->exportText( mxText );
+}
+
+void SvxXMLTextExportComponent::_ExportMasterStyles() {}
diff --git a/editeng/source/xml/xmltxtimp.cxx b/editeng/source/xml/xmltxtimp.cxx
new file mode 100644
index 0000000000..cc520b0b9d
--- /dev/null
+++ b/editeng/source/xml/xmltxtimp.cxx
@@ -0,0 +1,263 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: xmltxtimp.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <tools/debug.hxx>
+#include <com/sun/star/io/XActiveDataControl.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <comphelper/processfactory.hxx>
+#include <unotools/streamwrap.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <sot/storage.hxx>
+#include <svl/itemprop.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmlmetae.hxx>
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmlstyle.hxx>
+#include "editsource.hxx"
+#include <editeng/editeng.hxx>
+#include <editeng/unotext.hxx>
+#include <editeng/unoprnms.hxx>
+#include <editeng/unoipset.hxx>
+
+using namespace com::sun::star;
+using namespace com::sun::star::document;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::xml::sax;
+using namespace com::sun::star::text;
+using namespace ::rtl;
+using namespace cppu;
+using namespace xmloff::token;
+
+
+///////////////////////////////////////////////////////////////////////
+
+class SvxXMLTextImportContext : public SvXMLImportContext
+{
+public:
+ SvxXMLTextImportContext( SvXMLImport& rImport, USHORT nPrfx, const OUString& rLName, const uno::Reference< XAttributeList >& xAttrList, const uno::Reference< XText >& xText );
+ virtual ~SvxXMLTextImportContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList );
+
+// SvxXMLXTableImport& getImport() const { return *(SvxXMLXTableImport*)&GetImport(); }
+
+private:
+ const uno::Reference< XText > mxText;
+};
+
+///////////////////////////////////////////////////////////////////////
+
+SvxXMLTextImportContext::SvxXMLTextImportContext( SvXMLImport& rImport, USHORT nPrfx, const OUString& rLName, const uno::Reference< XAttributeList >&, const uno::Reference< XText >& xText )
+: SvXMLImportContext( rImport, nPrfx, rLName ), mxText( xText )
+{
+}
+
+SvxXMLTextImportContext::~SvxXMLTextImportContext()
+{
+}
+
+SvXMLImportContext *SvxXMLTextImportContext::CreateChildContext( USHORT nPrefix, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList )
+{
+ SvXMLImportContext* pContext = NULL;
+ if(XML_NAMESPACE_OFFICE == nPrefix && IsXMLToken( rLocalName, XML_BODY ) )
+ {
+ pContext = new SvxXMLTextImportContext( GetImport(), nPrefix, rLocalName, xAttrList, mxText );
+ }
+ else if( XML_NAMESPACE_OFFICE == nPrefix && IsXMLToken( rLocalName, XML_AUTOMATIC_STYLES ) )
+ {
+ pContext = new SvXMLStylesContext( GetImport(), nPrefix, rLocalName, xAttrList );
+ GetImport().GetTextImport()->SetAutoStyles( (SvXMLStylesContext*)pContext );
+
+ }
+ else
+ {
+ pContext = GetImport().GetTextImport()->CreateTextChildContext( GetImport(), nPrefix, rLocalName, xAttrList );
+ }
+
+ if( NULL == pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+///////////////////////////////////////////////////////////////////////
+
+class SvxXMLXTextImportComponent : public SvXMLImport
+{
+public:
+ // #110680#
+ SvxXMLXTextImportComponent(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ const uno::Reference< XText > & xText );
+
+ virtual ~SvxXMLXTextImportComponent() throw ();
+
+ static sal_Bool load( const rtl::OUString& rUrl, const com::sun::star::uno::Reference< com::sun::star::container::XNameContainer >& xTable ) throw();
+protected:
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList );
+
+private:
+ const uno::Reference< XText > mxText;
+};
+
+// --------------------------------------------------------------------
+
+// #110680#
+SvxXMLXTextImportComponent::SvxXMLXTextImportComponent(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ const uno::Reference< XText > & xText )
+: SvXMLImport(xServiceFactory),
+ mxText( xText )
+{
+ GetTextImport()->SetCursor( mxText->createTextCursor() );
+}
+
+SvxXMLXTextImportComponent::~SvxXMLXTextImportComponent() throw ()
+{
+}
+
+void SvxReadXML( EditEngine& rEditEngine, SvStream& rStream, const ESelection& rSel )
+{
+ SvxEditEngineSource aEditSource( &rEditEngine );
+
+ static const SfxItemPropertyMapEntry SvxXMLTextImportComponentPropertyMap[] =
+ {
+ SVX_UNOEDIT_CHAR_PROPERTIES,
+ SVX_UNOEDIT_FONT_PROPERTIES,
+// SVX_UNOEDIT_OUTLINER_PROPERTIES,
+ SVX_UNOEDIT_PARA_PROPERTIES,
+ {0,0,0,0,0,0}
+ };
+ static SvxItemPropertySet aSvxXMLTextImportComponentPropertySet( SvxXMLTextImportComponentPropertyMap, EditEngine::GetGlobalItemPool() );
+
+ uno::Reference<text::XText > xParent;
+ SvxUnoText* pUnoText = new SvxUnoText( &aEditSource, &aSvxXMLTextImportComponentPropertySet, xParent );
+ pUnoText->SetSelection( rSel );
+ uno::Reference<text::XText > xText( pUnoText );
+
+ try
+ {
+ do
+ {
+ uno::Reference<lang::XMultiServiceFactory> xServiceFactory( ::comphelper::getProcessServiceFactory() );
+ if( !xServiceFactory.is() )
+ {
+ DBG_ERROR( "SvxXMLXTableImport::load: got no service manager" );
+ break;
+ }
+
+ uno::Reference< xml::sax::XParser > xParser( xServiceFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Parser" ) ) ), uno::UNO_QUERY );
+ if( !xParser.is() )
+ {
+ DBG_ERROR( "com.sun.star.xml.sax.Parser service missing" );
+ break;
+ }
+
+ uno::Reference<io::XInputStream> xInputStream = new utl::OInputStreamWrapper( rStream );
+
+/* testcode
+ const OUString aURL( RTL_CONSTASCII_USTRINGPARAM( "file:///e:/test.xml" ) );
+ SfxMedium aMedium( aURL, STREAM_READ | STREAM_NOCREATE, TRUE );
+ aMedium.IsRemote();
+ uno::Reference<io::XOutputStream> xOut( new utl::OOutputStreamWrapper( *aMedium.GetOutStream() ) );
+
+ aMedium.GetInStream()->Seek( 0 );
+ uno::Reference< io::XActiveDataSource > xSource( aMedium.GetDataSource() );
+
+ if( !xSource.is() )
+ {
+ DBG_ERROR( "got no data source from medium" );
+ break;
+ }
+
+ uno::Reference< XInterface > xPipe( xServiceFactory->createInstance(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.io.Pipe") ) ) );
+ if( !xPipe.is() )
+ {
+ DBG_ERROR( "XMLReader::Read: com.sun.star.io.Pipe service missing" );
+ break;
+ }
+
+ // connect pipe's output stream to the data source
+ xSource->setOutputStream( uno::Reference< io::XOutputStream >::query( xPipe ) );
+
+ xml::sax::InputSource aParserInput;
+ aParserInput.aInputStream = uno::Reference< io::XInputStream >::query( xPipe );
+ aParserInput.sSystemId = aMedium.GetName();
+
+
+ if( xSource.is() )
+ {
+ uno::Reference< io::XActiveDataControl > xSourceControl( xSource, UNO_QUERY );
+ xSourceControl->start();
+ }
+
+*/
+
+ // #110680#
+ // uno::Reference< XDocumentHandler > xHandler( new SvxXMLXTextImportComponent( xText ) );
+ uno::Reference< XDocumentHandler > xHandler( new SvxXMLXTextImportComponent( xServiceFactory, xText ) );
+
+ xParser->setDocumentHandler( xHandler );
+
+ xml::sax::InputSource aParserInput;
+ aParserInput.aInputStream = xInputStream;
+// aParserInput.sSystemId = aMedium.GetName();
+ xParser->parseStream( aParserInput );
+ }
+ while(0);
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+SvXMLImportContext *SvxXMLXTextImportComponent::CreateChildContext( USHORT nPrefix, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList )
+{
+ SvXMLImportContext* pContext;
+ if(XML_NAMESPACE_OFFICE == nPrefix && ( IsXMLToken( rLocalName, XML_DOCUMENT ) || IsXMLToken( rLocalName, XML_DOCUMENT_CONTENT ) ) )
+ {
+ pContext = new SvxXMLTextImportContext(*this, nPrefix, rLocalName, xAttrList, mxText );
+ }
+ else
+ {
+ pContext = SvXMLImport::CreateContext(nPrefix, rLocalName, xAttrList);
+ }
+ return pContext;
+}
+