diff options
-rw-r--r-- | chart2/source/controller/dialogs/TitleDialogData.cxx | 2 | ||||
-rw-r--r-- | chart2/source/controller/inc/ChartController.hxx | 5 | ||||
-rw-r--r-- | chart2/source/controller/inc/SelectionHelper.hxx | 1 | ||||
-rw-r--r-- | chart2/source/controller/main/ChartController.cxx | 6 | ||||
-rw-r--r-- | chart2/source/controller/main/ChartController_TextEdit.cxx | 93 | ||||
-rw-r--r-- | chart2/source/controller/main/ChartController_Tools.cxx | 11 | ||||
-rw-r--r-- | chart2/source/controller/main/ChartController_Window.cxx | 10 | ||||
-rw-r--r-- | chart2/source/controller/main/ControllerCommandDispatch.cxx | 6 | ||||
-rw-r--r-- | chart2/source/controller/main/SelectionHelper.cxx | 5 | ||||
-rw-r--r-- | chart2/source/controller/sidebar/ChartElementsPanel.cxx | 3 | ||||
-rw-r--r-- | chart2/source/inc/TitleHelper.hxx | 4 | ||||
-rw-r--r-- | chart2/source/tools/TitleHelper.cxx | 72 | ||||
-rw-r--r-- | chart2/uiconfig/menubar/menubar.xml | 1 | ||||
-rw-r--r-- | chart2/uiconfig/toolbar/toolbar.xml | 1 |
14 files changed, 180 insertions, 40 deletions
diff --git a/chart2/source/controller/dialogs/TitleDialogData.cxx b/chart2/source/controller/dialogs/TitleDialogData.cxx index 45dda2c897b0..b8f3ed6d9429 100644 --- a/chart2/source/controller/dialogs/TitleDialogData.cxx +++ b/chart2/source/controller/dialogs/TitleDialogData.cxx @@ -99,7 +99,7 @@ bool TitleDialogData::writeDifferenceToModel( TitleHelper::getTitle( static_cast< TitleHelper::eTitleType >( nN ), xChartModel ) ); if(xTitle.is()) { - TitleHelper::setCompleteString( aTextList[nN], xTitle, xContext ); + TitleHelper::setCompleteString( aTextList[nN], xTitle, xContext, nullptr, true ); bChanged = true; } } diff --git a/chart2/source/controller/inc/ChartController.hxx b/chart2/source/controller/inc/ChartController.hxx index d1e95efafac3..737d0cf3768f 100644 --- a/chart2/source/controller/inc/ChartController.hxx +++ b/chart2/source/controller/inc/ChartController.hxx @@ -323,6 +323,7 @@ public: void setDrawMode( ChartDrawMode eMode ) { m_eDrawMode = eMode; } bool isShapeContext() const; + bool IsTextEdit() const; ViewElementListProvider getViewElementListProvider(); DrawModelWrapper* GetDrawModelWrapper(); @@ -484,6 +485,8 @@ private: void executeDispatch_MoveSeries( bool bForward ); bool EndTextEdit(); + css::uno::Sequence< css::uno::Reference<css::chart2::XFormattedString >> GetFormattedTitle( + const EditTextObject& aEdit, const css::uno::Reference< css::drawing::XShape >& xShape ); void executeDispatch_View3D(); void executeDispatch_PositionAndSize( const ::css::uno::Sequence< ::css::beans::PropertyValue >* pArgs = nullptr ); @@ -514,7 +517,7 @@ private: const css::uno::Sequence< css::beans::PropertyValue >& rArgs ); DECL_LINK( DoubleClickWaitingHdl, Timer*, void ); - void execute_DoubleClick( const Point* pMousePixel ); + void execute_DoubleClick( const Point* pMousePixel, bool &bEditText ); void startDoubleClickWaiting(); void stopDoubleClickWaiting(); diff --git a/chart2/source/controller/inc/SelectionHelper.hxx b/chart2/source/controller/inc/SelectionHelper.hxx index ff0e95eee27a..119640bd4300 100644 --- a/chart2/source/controller/inc/SelectionHelper.hxx +++ b/chart2/source/controller/inc/SelectionHelper.hxx @@ -39,6 +39,7 @@ public: //methods bool isResizeableObjectSelected() const; bool isRotateableObjectSelected( const rtl::Reference<::chart::ChartModel>& xChartModel ) const; + bool isTitleObjectSelected() const; bool isDragableObjectSelected() const; bool isAdditionalShapeSelected() const; diff --git a/chart2/source/controller/main/ChartController.cxx b/chart2/source/controller/main/ChartController.cxx index 661cf327b39f..2bd0bf549e89 100644 --- a/chart2/source/controller/main/ChartController.cxx +++ b/chart2/source/controller/main/ChartController.cxx @@ -1233,7 +1233,9 @@ void SAL_CALL ChartController::dispatch( this->executeDispatch_PositionAndSize(); } } - else if( lcl_isFormatObjectCommand(aCommand) ) + else if ( aCommand == "FontDialog" ) + this->impl_ShapeControllerDispatch(rURL, rArgs); + else if (lcl_isFormatObjectCommand(aCommand)) this->executeDispatch_FormatObject(rURL.Path); //more format else if( aCommand == "DiagramType" ) @@ -1604,7 +1606,7 @@ const o3tl::sorted_vector< OUString >& ChartController::impl_getAvailableCommand "InsertMenuDataTable", "InsertDataTable", "DeleteDataTable", //format objects - "FormatSelection", "TransformDialog", + "FormatSelection", "FontDialog", "TransformDialog", "DiagramType", "View3D", "Forward", "Backward", "MainTitle", "SubTitle", diff --git a/chart2/source/controller/main/ChartController_TextEdit.cxx b/chart2/source/controller/main/ChartController_TextEdit.cxx index aa105883aadf..c88f06a66e45 100644 --- a/chart2/source/controller/main/ChartController_TextEdit.cxx +++ b/chart2/source/controller/main/ChartController_TextEdit.cxx @@ -30,6 +30,7 @@ #include <TitleHelper.hxx> #include <ObjectIdentifier.hxx> #include <ControllerLockGuard.hxx> +#include <comphelper/diagnose_ex.hxx> #if !ENABLE_WASM_STRIP_ACCESSIBILITY #include <AccessibleTextHelper.hxx> #endif @@ -43,8 +44,12 @@ #include <editeng/editids.hrc> #include <vcl/svapp.hxx> #include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/text/XTextCursor.hpp> +#include <com/sun/star/chart2/FormattedString.hpp> #include <svl/stritem.hxx> #include <editeng/fontitem.hxx> +#include <editeng/section.hxx> #include <memory> namespace chart @@ -143,8 +148,30 @@ bool ChartController::EndTextEdit() // lock controllers till end of block ControllerLockGuardUNO aCLGuard( getChartModel() ); + uno::Sequence< uno::Reference< chart2::XFormattedString > > aNewFormattedTitle = + GetFormattedTitle(pParaObj->GetTextObject(), pTextObject->getUnoShape()); + Title* pTitle = dynamic_cast<Title*>(xPropSet.get()); - TitleHelper::setCompleteString( aString, pTitle, m_xCC ); + if (pTitle && aNewFormattedTitle.hasElements()) + { + bool bStacked = false; + if (xPropSet.is()) + xPropSet->getPropertyValue("StackCharacters") >>= bStacked; + + if (bStacked) + { + for (uno::Reference< chart2::XFormattedString >const& formattedStr : aNewFormattedTitle) + { + formattedStr->setString(TitleHelper::getUnstackedStr(formattedStr->getString())); + } + } + + pTitle->setText(aNewFormattedTitle); + } + else + { + TitleHelper::setCompleteString(aString, pTitle, m_xCC); + } OSL_ENSURE(m_pTextActionUndoGuard, "ChartController::EndTextEdit: no TextUndoGuard!"); if (m_pTextActionUndoGuard) @@ -154,6 +181,70 @@ bool ChartController::EndTextEdit() return true; } +uno::Sequence< uno::Reference< chart2::XFormattedString > > ChartController::GetFormattedTitle( + const EditTextObject& aEdit, const uno::Reference< drawing::XShape >& xShape ) +{ + std::vector < uno::Reference< chart2::XFormattedString > > aNewStrings; + if (!xShape.is()) + return comphelper::containerToSequence(aNewStrings); + + uno::Reference< text::XText > xText(xShape, uno::UNO_QUERY); + if (!xText.is()) + return comphelper::containerToSequence(aNewStrings); + + uno::Reference< text::XTextCursor > xSelectionCursor(xText->createTextCursor()); + if (!xSelectionCursor.is()) + return comphelper::containerToSequence(aNewStrings); + + xSelectionCursor->gotoStart(false); + + std::vector<editeng::Section> aSecAttrs; + aEdit.GetAllSections(aSecAttrs); + + for (editeng::Section const& rSection : aSecAttrs) + { + if (!xSelectionCursor->isCollapsed()) + xSelectionCursor->collapseToEnd(); + + xSelectionCursor->goRight(rSection.mnEnd - rSection.mnStart, true); + + OUString aNewString = xSelectionCursor->getString(); + + bool bNextPara = (aEdit.GetParagraphCount() > 1 && rSection.mnParagraph != aEdit.GetParagraphCount() - 1 && + aEdit.GetTextLen(rSection.mnParagraph) <= rSection.mnEnd); + + uno::Reference< chart2::XFormattedString2 > xFmtStr = chart2::FormattedString::create(m_xCC); + if (bNextPara) + aNewString = aNewString + OUStringChar('\n'); + xFmtStr->setString(aNewString); + aNewStrings.emplace_back(xFmtStr); + + uno::Reference< beans::XPropertySetInfo > xInfo = xFmtStr->getPropertySetInfo(); + uno::Reference< beans::XPropertySet > xSelectionProp(xSelectionCursor, uno::UNO_QUERY); + try + { + for (const beans::Property& rProp : xSelectionProp->getPropertySetInfo()->getProperties()) + { + if (xInfo.is() && xInfo->hasPropertyByName(rProp.Name)) + { + const uno::Any aValue = xSelectionProp->getPropertyValue(rProp.Name); + xFmtStr->setPropertyValue(rProp.Name, aValue); + } + } + } + catch ( const uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + aNewStrings.clear(); + } + + if (bNextPara) + xSelectionCursor->goRight(1, false); // next paragraph + } + + return comphelper::containerToSequence(aNewStrings); +} + void ChartController::executeDispatch_InsertSpecialCharacter() { SolarMutexGuard aGuard; diff --git a/chart2/source/controller/main/ChartController_Tools.cxx b/chart2/source/controller/main/ChartController_Tools.cxx index 6cf3a22e41ad..539516de7466 100644 --- a/chart2/source/controller/main/ChartController_Tools.cxx +++ b/chart2/source/controller/main/ChartController_Tools.cxx @@ -313,8 +313,8 @@ void ChartController::executeDispatch_Paste() if( m_pDrawViewWrapper ) { OutlinerView* pOutlinerView = m_pDrawViewWrapper->GetTextEditOutlinerView(); - if( pOutlinerView )//in case of edit mode insert into edited string - pOutlinerView->InsertText( aString ); + if (pOutlinerView)//in case of edit mode insert the formatted string + pOutlinerView->PasteSpecial(); else { impl_PasteStringAsTextShape( aString, awt::Point( 0, 0 ) ); @@ -582,6 +582,13 @@ bool ChartController::isShapeContext() const ( m_pDrawViewWrapper->GetCurrentObjIdentifier() == SdrObjKind::Text ) ); } +bool ChartController::IsTextEdit() const +{ + // only Title objects are editable textshapes + return m_aSelection.isTitleObjectSelected() && + m_pDrawViewWrapper && m_pDrawViewWrapper->IsTextEdit(); +} + void ChartController::impl_ClearSelection() { if( m_aSelection.hasSelection()) diff --git a/chart2/source/controller/main/ChartController_Window.cxx b/chart2/source/controller/main/ChartController_Window.cxx index 116e65090126..375c2824a8a1 100644 --- a/chart2/source/controller/main/ChartController_Window.cxx +++ b/chart2/source/controller/main/ChartController_Window.cxx @@ -743,6 +743,7 @@ void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt ) bool bMouseUpWithoutMouseDown = !m_bWaitingForMouseUp; m_bWaitingForMouseUp = false; bool bNotifySelectionChange = false; + bool bEditText = false; { SolarMutexGuard aGuard; @@ -919,7 +920,7 @@ void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt ) if( isDoubleClick(rMEvt) && !bMouseUpWithoutMouseDown /*#i106966#*/ ) { Point aMousePixel = rMEvt.GetPosPixel(); - execute_DoubleClick( &aMousePixel ); + execute_DoubleClick( &aMousePixel, bEditText ); } if( m_aSelection.isSelectionDifferentFromBeforeMouseDown() ) @@ -928,18 +929,17 @@ void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt ) impl_SetMousePointer( rMEvt ); - if(bNotifySelectionChange) + if(bNotifySelectionChange || bEditText) impl_notifySelectionChangeListeners(); } -void ChartController::execute_DoubleClick( const Point* pMousePixel ) +void ChartController::execute_DoubleClick( const Point* pMousePixel, bool &bEditText ) { const SfxViewShell* pViewShell = SfxViewShell::Current(); bool notAllowed = pViewShell && (pViewShell->isLOKMobilePhone() || pViewShell->IsLokReadOnlyView()); if (notAllowed) return; - bool bEditText = false; if ( m_aSelection.hasSelection() ) { OUString aCID( m_aSelection.getSelectedCID() ); @@ -1034,6 +1034,8 @@ void ChartController::execute_Command( const CommandEvent& rCEvt ) OUString aFormatCommand( lcl_getFormatCommandForObjectCID( m_aSelection.getSelectedCID() ) ); lcl_insertMenuCommand( xPopupMenu, nUniqueId++, aFormatCommand ); + if (eObjectType == OBJECTTYPE_TITLE && m_pDrawViewWrapper->IsTextEdit()) + lcl_insertMenuCommand( xPopupMenu, nUniqueId++, ".uno:FontDialog" ); //some commands for dataseries and points: diff --git a/chart2/source/controller/main/ControllerCommandDispatch.cxx b/chart2/source/controller/main/ControllerCommandDispatch.cxx index 201dd24f499c..8d7bc490e569 100644 --- a/chart2/source/controller/main/ControllerCommandDispatch.cxx +++ b/chart2/source/controller/main/ControllerCommandDispatch.cxx @@ -531,6 +531,7 @@ void ControllerCommandDispatch::updateCommandAvailability() // read-only bool bIsWritable = bModelStateIsValid && (! m_apModelState->bIsReadOnly); bool bShapeContext = m_xChartController.is() && m_xChartController->isShapeContext(); + bool bIsTextEdit = m_xChartController.is() && m_xChartController->IsTextEdit(); bool bEnableDataTableDialog = false; bool bCanCreateDataProvider = false; @@ -597,9 +598,10 @@ void ControllerCommandDispatch::updateCommandAvailability() // format objects bool bFormatObjectAvailable = bIsWritable && bControllerStateIsValid && m_apControllerState->bIsFormateableObjectSelected; - m_aCommandAvailability[ ".uno:FormatSelection" ] = bFormatObjectAvailable; + m_aCommandAvailability[ ".uno:FormatSelection" ] = bFormatObjectAvailable && !bIsTextEdit; + m_aCommandAvailability[ ".uno:FontDialog" ] = bFormatObjectAvailable && bIsTextEdit; m_aCommandAvailability[ ".uno:FormatAxis" ] = bFormatObjectAvailable; - m_aCommandAvailability[ ".uno:FormatTitle" ] = bFormatObjectAvailable; + m_aCommandAvailability[ ".uno:FormatTitle" ] = bFormatObjectAvailable && !bIsTextEdit; m_aCommandAvailability[ ".uno:FormatDataSeries" ] = bFormatObjectAvailable; m_aCommandAvailability[ ".uno:FormatDataPoint" ] = bFormatObjectAvailable; m_aCommandAvailability[ ".uno:FormatDataLabels" ] = bFormatObjectAvailable; diff --git a/chart2/source/controller/main/SelectionHelper.cxx b/chart2/source/controller/main/SelectionHelper.cxx index 93cd20dfee86..864df9c2a95d 100644 --- a/chart2/source/controller/main/SelectionHelper.cxx +++ b/chart2/source/controller/main/SelectionHelper.cxx @@ -312,6 +312,11 @@ bool Selection::isDragableObjectSelected() const return m_aSelectedOID.isDragableObject(); } +bool Selection::isTitleObjectSelected() const +{ + return m_aSelectedOID.getObjectType() == OBJECTTYPE_TITLE; +} + bool Selection::isAdditionalShapeSelected() const { return m_aSelectedOID.isAdditionalShape(); diff --git a/chart2/source/controller/sidebar/ChartElementsPanel.cxx b/chart2/source/controller/sidebar/ChartElementsPanel.cxx index 9b55fc6c77ef..1e5e6e9403fa 100644 --- a/chart2/source/controller/sidebar/ChartElementsPanel.cxx +++ b/chart2/source/controller/sidebar/ChartElementsPanel.cxx @@ -634,7 +634,8 @@ IMPL_LINK(ChartElementsPanel, EditHdl, weld::Entry&, rEdit, void) // set it OUString aText(rEdit.get_text()); - TitleHelper::setCompleteString(aText, TitleHelper::getTitle(aTitleType, mxModel), comphelper::getProcessComponentContext()); + TitleHelper::setCompleteString(aText, TitleHelper::getTitle(aTitleType, mxModel), + comphelper::getProcessComponentContext(), nullptr, true); } IMPL_LINK_NOARG(ChartElementsPanel, LegendPosHdl, weld::ComboBox&, void) diff --git a/chart2/source/inc/TitleHelper.hxx b/chart2/source/inc/TitleHelper.hxx index bd9a1836605d..f2a8a0830b21 100644 --- a/chart2/source/inc/TitleHelper.hxx +++ b/chart2/source/inc/TitleHelper.hxx @@ -77,10 +77,12 @@ public: , const rtl::Reference< ::chart::ChartModel >& xModel ); static OUString getCompleteString( const rtl::Reference< ::chart::Title >& xTitle ); + static OUString getUnstackedStr( const OUString& rNewText ); static void setCompleteString( const OUString& rNewText , const rtl::Reference< ::chart::Title >& xTitle , const css::uno::Reference< css::uno::XComponentContext > & xContext - , const float * pDefaultCharHeight = nullptr ); + , const float * pDefaultCharHeight = nullptr + , bool bDialogTitle = false ); static bool getTitleType( eTitleType& rType , const rtl::Reference< ::chart::Title >& xTitle diff --git a/chart2/source/tools/TitleHelper.cxx b/chart2/source/tools/TitleHelper.cxx index b6aff7c4f4c7..ca137cb6e072 100644 --- a/chart2/source/tools/TitleHelper.cxx +++ b/chart2/source/tools/TitleHelper.cxx @@ -303,12 +303,36 @@ OUString TitleHelper::getCompleteString( const rtl::Reference< Title >& xTitle ) return aRet.makeStringAndClear(); } +OUString TitleHelper::getUnstackedStr(const OUString& rNewText) +{ + //#i99841# remove linebreaks that were added for vertical stacking + OUStringBuffer aUnstackedStr; + OUStringBuffer aSource(rNewText); + + bool bBreakIgnored = false; + sal_Int32 nLen = rNewText.getLength(); + for (sal_Int32 nPos = 0; nPos < nLen; ++nPos) + { + sal_Unicode aChar = aSource[nPos]; + if (aChar != '\n') + { + aUnstackedStr.append(aChar); + bBreakIgnored = false; + } + else if (aChar == '\n' && bBreakIgnored) + aUnstackedStr.append(aChar); + else + bBreakIgnored = true; + } + return aUnstackedStr.makeStringAndClear(); +} + void TitleHelper::setCompleteString( const OUString& rNewText , const rtl::Reference< Title >& xTitle , const uno::Reference< uno::XComponentContext > & xContext - , const float * pDefaultCharHeight /* = 0 */ ) + , const float * pDefaultCharHeight /* = 0 */ + , bool bDialogTitle /*= false*/ ) { - //the format of the first old text portion will be maintained if there is any if(!xTitle.is()) return; @@ -318,37 +342,35 @@ void TitleHelper::setCompleteString( const OUString& rNewText if( xTitle.is() ) xTitle->getPropertyValue( "StackCharacters" ) >>= bStacked; + uno::Sequence< uno::Reference< XFormattedString > > aOldStringList = xTitle->getText(); if( bStacked ) { - //#i99841# remove linebreaks that were added for vertical stacking - OUStringBuffer aUnstackedStr; - OUStringBuffer aSource(rNewText); - - bool bBreakIgnored = false; - sal_Int32 nLen = rNewText.getLength(); - for( sal_Int32 nPos = 0; nPos < nLen; ++nPos ) + aNewText = getUnstackedStr(rNewText); + for (uno::Reference< XFormattedString >const & formattedStr : aOldStringList) { - sal_Unicode aChar = aSource[nPos]; - if( aChar != '\n' ) - { - aUnstackedStr.append( aChar ); - bBreakIgnored = false; - } - else if( aChar == '\n' && bBreakIgnored ) - aUnstackedStr.append( aChar ); - else - bBreakIgnored = true; + formattedStr->setString(getUnstackedStr(formattedStr->getString())); } - aNewText = aUnstackedStr.makeStringAndClear(); } uno::Sequence< uno::Reference< XFormattedString > > aNewStringList; - - uno::Sequence< uno::Reference< XFormattedString > > aOldStringList = xTitle->getText(); - if( aOldStringList.hasElements() ) + if( aOldStringList.hasElements()) { - aNewStringList = { aOldStringList[0] }; - aNewStringList[0]->setString( aNewText ); + const OUString aFullString = getCompleteString(xTitle); + if (bDialogTitle && aNewText.equals(getUnstackedStr(aFullString))) + { + // If the new title setted from a dialog window to a new string + // the first old text portion will be maintained if its a new string, + // otherwise we use the original one. + aNewStringList = aOldStringList; + } + else + { + // If the new title setted from a dialog to a new string the first + // old text portion will be maintained if there was any. Also in case of ODF + // import which still not support non-uniform formatted titles + aNewStringList = { aOldStringList[0] }; + aNewStringList[0]->setString(aNewText); + } } else { diff --git a/chart2/uiconfig/menubar/menubar.xml b/chart2/uiconfig/menubar/menubar.xml index 58c84d6cbc33..e295d77a3943 100644 --- a/chart2/uiconfig/menubar/menubar.xml +++ b/chart2/uiconfig/menubar/menubar.xml @@ -120,6 +120,7 @@ <menu:menuitem menu:id=".uno:View3D"/> <menu:menuseparator/> <menu:menuitem menu:id=".uno:FormatSelection" menu:style="text"/> + <menu:menuitem menu:id=".uno:FontDialog" menu:style="text"/> <menu:menuitem menu:id=".uno:TransformDialog" menu:style="text"/> <menu:menu menu:id=".uno:ArrangeRow"> <menu:menupopup> diff --git a/chart2/uiconfig/toolbar/toolbar.xml b/chart2/uiconfig/toolbar/toolbar.xml index 809174ba206d..21105871c095 100644 --- a/chart2/uiconfig/toolbar/toolbar.xml +++ b/chart2/uiconfig/toolbar/toolbar.xml @@ -20,6 +20,7 @@ <toolbar:toolbar xmlns:toolbar="http://openoffice.org/2001/toolbar" xmlns:xlink="http://www.w3.org/1999/xlink"> <toolbar:toolbaritem xlink:href=".uno:ChartElementSelector"/> <toolbar:toolbaritem xlink:href=".uno:FormatSelection"/> + <toolbar:toolbaritem xlink:href=".uno:FontDialog"/> <toolbar:toolbarseparator/> <toolbar:toolbaritem xlink:href=".uno:DiagramType"/> <toolbar:toolbaritem xlink:href=".uno:DiagramArea"/> |