include/vcl/unohelp2.hxx | 60 ++++++++-------- include/vcl/weld/TextWidget.hxx | 2 solenv/clang-format/excludelist | 2 vcl/inc/qt5/QtInstanceEntry.hxx | 1 vcl/inc/qt5/QtInstanceTextView.hxx | 1 vcl/qt5/QtInstanceEntry.cxx | 2 vcl/qt5/QtInstanceTextView.cxx | 2 vcl/source/app/unohelp2.cxx | 134 ++++++++++++++++++------------------- vcl/source/weld/TextWidget.cxx | 17 ++++ 9 files changed, 117 insertions(+), 104 deletions(-)
New commits: commit 8e03af5d8cd90918a5856a732272096e79244b33 Author: Michael Weghorn <[email protected]> AuthorDate: Sat Jan 3 15:40:14 2026 +0100 Commit: Michael Weghorn <[email protected]> CommitDate: Sun Jan 4 15:04:21 2026 +0100 tdf#130857 weld: Implement TextWidget::copy_clipboard in base Add an implementation of TextWidget::copy_clipboard right in the abstract base class, as it provides all relevant API to do that. Drop the QtInstanceEntry and QtInstanceTextView overrides that would so far only assert. For now, leave the GTK and vcl implementations/overrides in place. While it's probably not relevant in practice, those might be more efficient than operating on the whole text of the widget to extract the relevant substring to copy. Change-Id: I9333ce659cecc5155f4bcf424ad1989919623142 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196453 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/include/vcl/weld/TextWidget.hxx b/include/vcl/weld/TextWidget.hxx index 8301868272d3..e9e6976912dc 100644 --- a/include/vcl/weld/TextWidget.hxx +++ b/include/vcl/weld/TextWidget.hxx @@ -54,7 +54,7 @@ public: virtual void set_font_color(const Color& rColor) = 0; virtual void cut_clipboard() = 0; - virtual void copy_clipboard() = 0; + virtual void copy_clipboard(); virtual void paste_clipboard() = 0; void save_value() { m_sSavedValue = get_text(); } diff --git a/vcl/inc/qt5/QtInstanceEntry.hxx b/vcl/inc/qt5/QtInstanceEntry.hxx index b3e304953a41..e4a1b1d7e9bc 100644 --- a/vcl/inc/qt5/QtInstanceEntry.hxx +++ b/vcl/inc/qt5/QtInstanceEntry.hxx @@ -47,7 +47,6 @@ public: virtual void set_font_color(const Color& rColor) override; virtual void cut_clipboard() override; - virtual void copy_clipboard() override; virtual void paste_clipboard() override; virtual void set_alignment(TxtAlign eXAlign) override; diff --git a/vcl/inc/qt5/QtInstanceTextView.hxx b/vcl/inc/qt5/QtInstanceTextView.hxx index 2b6af1a6d196..3b20370b7508 100644 --- a/vcl/inc/qt5/QtInstanceTextView.hxx +++ b/vcl/inc/qt5/QtInstanceTextView.hxx @@ -41,7 +41,6 @@ public: virtual bool can_move_cursor_with_down() const override; virtual void cut_clipboard() override; - virtual void copy_clipboard() override; virtual void paste_clipboard() override; virtual void set_alignment(TxtAlign eXAlign) override; diff --git a/vcl/qt5/QtInstanceEntry.cxx b/vcl/qt5/QtInstanceEntry.cxx index daef32e454e8..822720a1feee 100644 --- a/vcl/qt5/QtInstanceEntry.cxx +++ b/vcl/qt5/QtInstanceEntry.cxx @@ -182,8 +182,6 @@ void QtInstanceEntry::set_font_color(const Color& rColor) { setFontColor(rColor) void QtInstanceEntry::cut_clipboard() { assert(false && "Not implemented yet"); } -void QtInstanceEntry::copy_clipboard() { assert(false && "Not implemented yet"); } - void QtInstanceEntry::paste_clipboard() { assert(false && "Not implemented yet"); } void QtInstanceEntry::set_alignment(TxtAlign eXAlign) diff --git a/vcl/qt5/QtInstanceTextView.cxx b/vcl/qt5/QtInstanceTextView.cxx index 3a446d7b59f1..ce449f19b087 100644 --- a/vcl/qt5/QtInstanceTextView.cxx +++ b/vcl/qt5/QtInstanceTextView.cxx @@ -126,8 +126,6 @@ bool QtInstanceTextView::can_move_cursor_with_down() const void QtInstanceTextView::cut_clipboard() { assert(false && "Not implemented yet"); } -void QtInstanceTextView::copy_clipboard() { assert(false && "Not implemented yet"); } - void QtInstanceTextView::paste_clipboard() { assert(false && "Not implemented yet"); } void QtInstanceTextView::set_alignment(TxtAlign) { assert(false && "Not implemented yet"); } diff --git a/vcl/source/weld/TextWidget.cxx b/vcl/source/weld/TextWidget.cxx index 6d7c496ad334..0590d9cd4804 100644 --- a/vcl/source/weld/TextWidget.cxx +++ b/vcl/source/weld/TextWidget.cxx @@ -7,6 +7,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp> +#include <vcl/unohelp2.hxx> #include <vcl/weld/TextWidget.hxx> namespace weld @@ -31,6 +33,21 @@ void TextWidget::replace_selection(const OUString& rText) do_replace_selection(rText); enable_notify_events(); } + +void TextWidget::copy_clipboard() +{ + int nSelectionStart = 0; + int nSelectionEnd = 0; + if (!get_selection_bounds(nSelectionStart, nSelectionEnd)) + return; + + const OUString sText = get_text(); + assert(nSelectionStart >= 0 && nSelectionStart <= sText.getLength() && nSelectionEnd >= 0 + && nSelectionEnd <= sText.getLength()); + const OUString sSelectedText = sText.copy(std::min(nSelectionStart, nSelectionEnd), + std::abs(nSelectionEnd - nSelectionStart)); + vcl::unohelper::TextDataObject::CopyStringTo(sSelectedText, get_clipboard()); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ commit c9a294c39de269ddaefc3f4ab157d2ce7e82bf05 Author: Michael Weghorn <[email protected]> AuthorDate: Sat Jan 3 15:05:07 2026 +0100 Commit: Michael Weghorn <[email protected]> CommitDate: Sun Jan 4 15:04:11 2026 +0100 vcl: clang-format vcl::unohelper::TextDataObject code This in particular gets rid of an extra indentation level. Change-Id: I69c8a7bd52f3e2c9d6c0ef1a82a36f8129d7134e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196452 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/include/vcl/unohelp2.hxx b/include/vcl/unohelp2.hxx index 5dbdda777f00..69037ed5cf0f 100644 --- a/include/vcl/unohelp2.hxx +++ b/include/vcl/unohelp2.hxx @@ -26,42 +26,44 @@ #include <vcl/dllapi.h> #include <vcl/IDialogRenderable.hxx> -namespace com::sun::star::datatransfer::clipboard { - class XClipboard; +namespace com::sun::star::datatransfer::clipboard +{ +class XClipboard; } -namespace vcl::unohelper { +namespace vcl::unohelper +{ +class VCL_DLLPUBLIC TextDataObject final : public css::datatransfer::XTransferable, + public ::cppu::OWeakObject +{ +private: + OUString maText; - class VCL_DLLPUBLIC TextDataObject final : - public css::datatransfer::XTransferable, - public ::cppu::OWeakObject - { - private: - OUString maText; +public: + TextDataObject(OUString aText); + SAL_DLLPRIVATE virtual ~TextDataObject() override; - public: - TextDataObject( OUString aText ); - SAL_DLLPRIVATE virtual ~TextDataObject() override; + // css::uno::XInterface + SAL_DLLPRIVATE css::uno::Any SAL_CALL queryInterface(const css::uno::Type& rType) override; + void SAL_CALL acquire() noexcept override { OWeakObject::acquire(); } + void SAL_CALL release() noexcept override { OWeakObject::release(); } - // css::uno::XInterface - SAL_DLLPRIVATE css::uno::Any SAL_CALL queryInterface( const css::uno::Type & rType ) override; - void SAL_CALL acquire() noexcept override { OWeakObject::acquire(); } - void SAL_CALL release() noexcept override { OWeakObject::release(); } + // css::datatransfer::XTransferable + SAL_DLLPRIVATE css::uno::Any SAL_CALL + getTransferData(const css::datatransfer::DataFlavor& aFlavor) override; + SAL_DLLPRIVATE css::uno::Sequence<css::datatransfer::DataFlavor> + SAL_CALL getTransferDataFlavors() override; + SAL_DLLPRIVATE sal_Bool SAL_CALL + isDataFlavorSupported(const css::datatransfer::DataFlavor& aFlavor) override; - // css::datatransfer::XTransferable - SAL_DLLPRIVATE css::uno::Any SAL_CALL getTransferData( const css::datatransfer::DataFlavor& aFlavor ) override; - SAL_DLLPRIVATE css::uno::Sequence< css::datatransfer::DataFlavor > SAL_CALL getTransferDataFlavors( ) override; - SAL_DLLPRIVATE sal_Bool SAL_CALL isDataFlavorSupported( const css::datatransfer::DataFlavor& aFlavor ) override; + /// copies a given string to a given clipboard + static void + CopyStringTo(const OUString& rContent, + const css::uno::Reference<css::datatransfer::clipboard::XClipboard>& rxClipboard, + const vcl::ILibreOfficeKitNotifier* pNotifier = nullptr); +}; - /// copies a given string to a given clipboard - static void CopyStringTo( - const OUString& rContent, - const css::uno::Reference< css::datatransfer::clipboard::XClipboard >& rxClipboard, - const vcl::ILibreOfficeKitNotifier* pNotifier = nullptr - ); - }; - -} // namespace vcl::unohelper +} // namespace vcl::unohelper #endif // INCLUDED_VCL_UNOHELP2_HXX diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist index 63ee192570a5..9840853e0ee7 100644 --- a/solenv/clang-format/excludelist +++ b/solenv/clang-format/excludelist @@ -6195,7 +6195,6 @@ include/vcl/txtattr.hxx include/vcl/uitest/uiobject.hxx include/vcl/uitest/uitest.hxx include/vcl/unohelp.hxx -include/vcl/unohelp2.hxx include/vcl/vclenum.hxx include/vcl/vclevent.hxx include/vcl/vcllayout.hxx @@ -14446,7 +14445,6 @@ vcl/source/app/svdata.cxx vcl/source/app/svmain.cxx vcl/source/app/timer.cxx vcl/source/app/unohelp.cxx -vcl/source/app/unohelp2.cxx vcl/source/app/vclevent.cxx vcl/source/bitmap/BitmapScaleConvolutionFilter.cxx vcl/source/bitmap/BitmapScaleSuperFilter.cxx diff --git a/vcl/source/app/unohelp2.cxx b/vcl/source/app/unohelp2.cxx index 575b9c74417c..2d8816dd8041 100644 --- a/vcl/source/app/unohelp2.cxx +++ b/vcl/source/app/unohelp2.cxx @@ -33,81 +33,83 @@ using namespace ::com::sun::star; -namespace vcl::unohelper { - - TextDataObject::TextDataObject( OUString aText ) : maText(std::move( aText )) - { - } - - TextDataObject::~TextDataObject() +namespace vcl::unohelper +{ +TextDataObject::TextDataObject(OUString aText) + : maText(std::move(aText)) +{ +} + +TextDataObject::~TextDataObject() {} + +void TextDataObject::CopyStringTo( + const OUString& rContent, + const uno::Reference<datatransfer::clipboard::XClipboard>& rxClipboard, + const vcl::ILibreOfficeKitNotifier* pNotifier) +{ + SAL_WARN_IF(!rxClipboard.is(), "vcl", "TextDataObject::CopyStringTo: invalid clipboard!"); + if (!rxClipboard.is()) + return; + + rtl::Reference<TextDataObject> pDataObj = new TextDataObject(rContent); + + SolarMutexReleaser aReleaser; + try { - } - - void TextDataObject::CopyStringTo( const OUString& rContent, - const uno::Reference< datatransfer::clipboard::XClipboard >& rxClipboard, - const vcl::ILibreOfficeKitNotifier* pNotifier) - { - SAL_WARN_IF( !rxClipboard.is(), "vcl", "TextDataObject::CopyStringTo: invalid clipboard!" ); - if ( !rxClipboard.is() ) - return; - - rtl::Reference<TextDataObject> pDataObj = new TextDataObject( rContent ); - - SolarMutexReleaser aReleaser; - try - { - rxClipboard->setContents( pDataObj, nullptr ); - - uno::Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( rxClipboard, uno::UNO_QUERY ); - if( xFlushableClipboard.is() ) - xFlushableClipboard->flushClipboard(); + rxClipboard->setContents(pDataObj, nullptr); - if (pNotifier != nullptr && comphelper::LibreOfficeKit::isActive()) - { - boost::property_tree::ptree aTree; - aTree.put("content", rContent); - aTree.put("mimeType", "text/plain"); - std::stringstream aStream; - boost::property_tree::write_json(aStream, aTree); - pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_CLIPBOARD_CHANGED, OString(aStream.str())); - } - } - catch( const uno::Exception& ) - { - } - } + uno::Reference<datatransfer::clipboard::XFlushableClipboard> xFlushableClipboard( + rxClipboard, uno::UNO_QUERY); + if (xFlushableClipboard.is()) + xFlushableClipboard->flushClipboard(); - // css::uno::XInterface - uno::Any TextDataObject::queryInterface( const uno::Type & rType ) - { - uno::Any aRet = ::cppu::queryInterface( rType, static_cast< datatransfer::XTransferable* >(this) ); - return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType )); - } - - // css::datatransfer::XTransferable - uno::Any TextDataObject::getTransferData( const datatransfer::DataFlavor& rFlavor ) - { - SotClipboardFormatId nT = SotExchange::GetFormat( rFlavor ); - if ( nT != SotClipboardFormatId::STRING ) + if (pNotifier != nullptr && comphelper::LibreOfficeKit::isActive()) { - throw datatransfer::UnsupportedFlavorException(); + boost::property_tree::ptree aTree; + aTree.put("content", rContent); + aTree.put("mimeType", "text/plain"); + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); + pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_CLIPBOARD_CHANGED, + OString(aStream.str())); } - return uno::Any(maText); } - - uno::Sequence< datatransfer::DataFlavor > TextDataObject::getTransferDataFlavors( ) + catch (const uno::Exception&) { - uno::Sequence< datatransfer::DataFlavor > aDataFlavors(1); - SotExchange::GetFormatDataFlavor( SotClipboardFormatId::STRING, aDataFlavors.getArray()[0] ); - return aDataFlavors; } - - sal_Bool TextDataObject::isDataFlavorSupported( const datatransfer::DataFlavor& rFlavor ) +} + +// css::uno::XInterface +uno::Any TextDataObject::queryInterface(const uno::Type& rType) +{ + uno::Any aRet = ::cppu::queryInterface(rType, static_cast<datatransfer::XTransferable*>(this)); + return (aRet.hasValue() ? aRet : OWeakObject::queryInterface(rType)); +} + +// css::datatransfer::XTransferable +uno::Any TextDataObject::getTransferData(const datatransfer::DataFlavor& rFlavor) +{ + SotClipboardFormatId nT = SotExchange::GetFormat(rFlavor); + if (nT != SotClipboardFormatId::STRING) { - SotClipboardFormatId nT = SotExchange::GetFormat( rFlavor ); - return ( nT == SotClipboardFormatId::STRING ); + throw datatransfer::UnsupportedFlavorException(); } - -} // namespace vcl::unohelper + return uno::Any(maText); +} + +uno::Sequence<datatransfer::DataFlavor> TextDataObject::getTransferDataFlavors() +{ + uno::Sequence<datatransfer::DataFlavor> aDataFlavors(1); + SotExchange::GetFormatDataFlavor(SotClipboardFormatId::STRING, aDataFlavors.getArray()[0]); + return aDataFlavors; +} + +sal_Bool TextDataObject::isDataFlavorSupported(const datatransfer::DataFlavor& rFlavor) +{ + SotClipboardFormatId nT = SotExchange::GetFormat(rFlavor); + return (nT == SotClipboardFormatId::STRING); +} + +} // namespace vcl::unohelper /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
