cui/source/dialogs/pastedlg.cxx | 24 +++- cui/source/factory/dlgfact.cxx | 5 cui/source/factory/dlgfact.hxx | 1 cui/source/inc/pastedlg.hxx | 3 include/sfx2/sfxdlg.hxx | 1 include/sfx2/sfxsids.hrc | 1 include/vcl/commandinfoprovider.hxx | 2 officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu | 11 + sc/sdi/cellsh.sdi | 1 sc/source/ui/docshell/impex.cxx | 4 sc/source/ui/view/cellsh.cxx | 3 sc/source/ui/view/cellsh1.cxx | 59 ++++++++++ sfx2/sdi/sfx.sdi | 16 ++ vcl/source/helper/commandinfoprovider.cxx | 8 + 14 files changed, 137 insertions(+), 2 deletions(-)
New commits: commit eeeed08b428685dd7934c4576f1bf4aa7436f96a Author: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> AuthorDate: Tue Mar 3 13:57:24 2020 +0100 Commit: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> CommitDate: Wed Mar 11 12:43:44 2020 +0100 tdf#125440 Allow raising text import dialog for paste This adds an entry to the "Paste special" dialog to raise the Text Import Dialog. This way, users can correctly import CSV/TSV, even when pasting just one line of formatted input. Change-Id: Ic09d7d60a05b14906f166668b38ec0eb8ead2d19 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89886 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> diff --git a/cui/source/dialogs/pastedlg.cxx b/cui/source/dialogs/pastedlg.cxx index f9d9a76318ab..375a966c7786 100644 --- a/cui/source/dialogs/pastedlg.cxx +++ b/cui/source/dialogs/pastedlg.cxx @@ -26,6 +26,8 @@ #include <svtools/strings.hrc> #include <svtools/svtresid.hxx> #include <tools/lineend.hxx> +#include <comphelper/propertysequence.hxx> +#include <comphelper/dispatchcommand.hxx> SvPasteObjectDialog::SvPasteObjectDialog(weld::Window* pParent) : GenericDialogController(pParent, "cui/ui/pastespecial.ui", "PasteSpecialDialog") @@ -70,6 +72,13 @@ void SvPasteObjectDialog::Insert( SotClipboardFormatId nFormat, const OUString& aSupplementMap.insert( std::make_pair( nFormat, rFormatName ) ); } +void SvPasteObjectDialog::InsertUno(const OUString& sCmd, const OUString& sLabel) +{ + aExtraCommand.first = sCmd; + aExtraCommand.second = sLabel; +} + + void SvPasteObjectDialog::PreGetFormat( const TransferableDataHelper &rHelper ) { //TODO/LATER: why is the Descriptor never used?! @@ -286,6 +295,11 @@ SotClipboardFormatId SvPasteObjectDialog::GetFormat( const TransferableDataHelpe } } + if (!aExtraCommand.first.isEmpty()) + { + ObjectLB().append(aExtraCommand.first, aExtraCommand.second); + } + ObjectLB().thaw(); SelectObject(); @@ -302,7 +316,15 @@ SotClipboardFormatId SvPasteObjectDialog::GetFormat( const TransferableDataHelpe if (run() == RET_OK) { - nSelFormat = static_cast<SotClipboardFormatId>(ObjectLB().get_selected_id().toUInt32()); + if (ObjectLB().get_selected_id().startsWithIgnoreAsciiCase(".uno")) + { + comphelper::dispatchCommand(aExtraCommand.first, {}); + nSelFormat = SotClipboardFormatId::NONE; + } + else + { + nSelFormat = static_cast<SotClipboardFormatId>(ObjectLB().get_selected_id().toUInt32()); + } } return nSelFormat; diff --git a/cui/source/factory/dlgfact.cxx b/cui/source/factory/dlgfact.cxx index 600882742427..d7868049d4c7 100644 --- a/cui/source/factory/dlgfact.cxx +++ b/cui/source/factory/dlgfact.cxx @@ -533,6 +533,11 @@ void AbstractPasteDialog_Impl::Insert(SotClipboardFormatId nFormat, const OUStri m_xDlg->Insert(nFormat, rFormatName); } +void AbstractPasteDialog_Impl::InsertUno(const OUString& sCmd, const OUString& sLabel) +{ + m_xDlg->InsertUno(sCmd, sLabel); +} + void AbstractPasteDialog_Impl::SetObjName(const SvGlobalName & rClass, const OUString& rObjName) { m_xDlg->SetObjName(rClass, rObjName); diff --git a/cui/source/factory/dlgfact.hxx b/cui/source/factory/dlgfact.hxx index 0181e293f49d..cd4b4d36a9dd 100644 --- a/cui/source/factory/dlgfact.hxx +++ b/cui/source/factory/dlgfact.hxx @@ -609,6 +609,7 @@ public: virtual bool StartExecuteAsync(AsyncContext &rCtx) override; public: virtual void Insert( SotClipboardFormatId nFormat, const OUString & rFormatName ) override; + virtual void InsertUno( const OUString & sCmd, const OUString& sLabel ) override; virtual void SetObjName( const SvGlobalName & rClass, const OUString & rObjName ) override; virtual void PreGetFormat( const TransferableDataHelper& aHelper ) override; virtual SotClipboardFormatId GetFormatOnly() override; diff --git a/cui/source/inc/pastedlg.hxx b/cui/source/inc/pastedlg.hxx index 565101d7fe19..a9a691b4f8f8 100644 --- a/cui/source/inc/pastedlg.hxx +++ b/cui/source/inc/pastedlg.hxx @@ -32,6 +32,8 @@ class TransferableDataHelper; class SvPasteObjectDialog : public weld::GenericDialogController { std::map< SotClipboardFormatId, OUString > aSupplementMap; + // Additional UNO command to be displayed along the supported paste formats + std::pair<OUString, OUString> aExtraCommand; SvGlobalName aObjClassName; OUString aObjName; @@ -49,6 +51,7 @@ public: SvPasteObjectDialog(weld::Window* pParent); void Insert( SotClipboardFormatId nFormat, const OUString & rFormatName ); + void InsertUno( const OUString& sUnoCmd, const OUString& sLabel); void SetObjName( const SvGlobalName & rClass, const OUString & rObjName ); /** * @brief PreGetFormat Prepares the dialog for running to get format of paste as a SotClipboardFormatId value by calling GetFormatOnly() diff --git a/include/sfx2/sfxdlg.hxx b/include/sfx2/sfxdlg.hxx index b82db9001359..4515dc9266ca 100644 --- a/include/sfx2/sfxdlg.hxx +++ b/include/sfx2/sfxdlg.hxx @@ -91,6 +91,7 @@ protected: virtual ~SfxAbstractPasteDialog() override = default; public: virtual void Insert( SotClipboardFormatId nFormat, const OUString & rFormatName ) = 0; + virtual void InsertUno( const OUString& sCmd, const OUString& sLabel ) = 0; virtual void SetObjName( const SvGlobalName & rClass, const OUString & rObjName ) = 0; virtual void PreGetFormat( const TransferableDataHelper& aHelper ) = 0; virtual SotClipboardFormatId GetFormatOnly() = 0; diff --git a/include/sfx2/sfxsids.hrc b/include/sfx2/sfxsids.hrc index d7367587db1d..ff2854861930 100644 --- a/include/sfx2/sfxsids.hrc +++ b/include/sfx2/sfxsids.hrc @@ -428,6 +428,7 @@ class SvxSearchItem; #define SID_PASTE_ONLY_TEXT (SID_SFX_START + 802) #define SID_PASTE_ONLY_FORMULA (SID_SFX_START + 803) #define SID_PASTE_ONLY_VALUE (SID_SFX_START + 804) +#define SID_PASTE_TEXTIMPORT_DIALOG (SID_SFX_START + 805) // Used for redaction #define SID_SHAPE_NAME (SID_SFX_START + 808) diff --git a/include/vcl/commandinfoprovider.hxx b/include/vcl/commandinfoprovider.hxx index d4ae3a008bd2..da79c18b7ced 100644 --- a/include/vcl/commandinfoprovider.hxx +++ b/include/vcl/commandinfoprovider.hxx @@ -53,6 +53,8 @@ namespace vcl { namespace CommandInfoProvider { VCL_DLLPUBLIC OUString GetPopupLabelForCommand(const css::uno::Sequence<css::beans::PropertyValue>& rProperties); + VCL_DLLPUBLIC OUString GetTooltipLabelForCommand(const css::uno::Sequence<css::beans::PropertyValue>& rProperties); + /** Return a tooltip for the given command. Falls back to label if command has no tooltip. @param rsCommandName The command name is expected to start with .uno: diff --git a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu index 099c1f249d21..b83a5362535b 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu @@ -2564,6 +2564,17 @@ <value>1</value> </prop> </node> + <node oor:name=".uno:PasteTextImportDialog" oor:op="replace"> + <prop oor:name="Label" oor:type="xs:string"> + <value xml:lang="en-US">Use Text Import Dialog</value> + </prop> + <prop oor:name="TooltipLabel" oor:type="xs:string"> + <value xml:lang="en-US">Use text import dialog</value> + </prop> + <prop oor:name="Properties" oor:type="xs:int"> + <value>1</value> + </prop> + </node> <node oor:name=".uno:ColumnOperations" oor:op="replace"> <prop oor:name="Label" oor:type="xs:string"> <value xml:lang="en-US">Column</value> diff --git a/sc/sdi/cellsh.sdi b/sc/sdi/cellsh.sdi index 4f2cd4d234b4..d5e936b06cf0 100644 --- a/sc/sdi/cellsh.sdi +++ b/sc/sdi/cellsh.sdi @@ -177,6 +177,7 @@ interface CellSelection SID_PASTE_ONLY_TEXT [ ExecMethod = ExecuteEdit; StateMethod = GetClipState; ] SID_PASTE_ONLY_FORMULA [ ExecMethod = ExecuteEdit; StateMethod = GetClipState; ] SID_PASTE_ONLY_VALUE [ ExecMethod = ExecuteEdit; StateMethod = GetClipState; ] + SID_PASTE_TEXTIMPORT_DIALOG [ ExecMethod = ExecuteEdit; StateMethod = GetClipState; ] SID_CLIPBOARD_FORMAT_ITEMS [ ExecMethod = ExecuteEdit; StateMethod = GetClipState; ] SID_EXTERNAL_SOURCE [ ExecMethod = ExecuteEdit; StateMethod = GetBlockState; ] FID_MERGE_ON [ ExecMethod = Execute; StateMethod = GetState; ] diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx index 493f3473c4db..ea7b3364d159 100644 --- a/sc/source/ui/view/cellsh.cxx +++ b/sc/source/ui/view/cellsh.cxx @@ -223,6 +223,7 @@ void ScCellShell::GetBlockState( SfxItemSet& rSet ) case SID_PASTE_ONLY_VALUE: case SID_PASTE_ONLY_TEXT: case SID_PASTE_ONLY_FORMULA: + case SID_PASTE_TEXTIMPORT_DIALOG: bDisable = GetViewData()->SelectionForbidsCellFill(); break; @@ -528,6 +529,7 @@ IMPL_LINK( ScCellShell, ClipboardChanged, TransferableDataHelper*, pDataHelper, rBindings.Invalidate( SID_PASTE_ONLY_VALUE ); rBindings.Invalidate( SID_PASTE_ONLY_TEXT ); rBindings.Invalidate( SID_PASTE_ONLY_FORMULA ); + rBindings.Invalidate( SID_PASTE_TEXTIMPORT_DIALOG ); rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS ); } @@ -621,6 +623,7 @@ void ScCellShell::GetClipState( SfxItemSet& rSet ) rSet.DisableItem( SID_PASTE_ONLY_VALUE ); rSet.DisableItem( SID_PASTE_ONLY_TEXT ); rSet.DisableItem( SID_PASTE_ONLY_FORMULA ); + rSet.DisableItem( SID_PASTE_TEXTIMPORT_DIALOG ); rSet.DisableItem( SID_CLIPBOARD_FORMAT_ITEMS ); } else if ( rSet.GetItemState( SID_CLIPBOARD_FORMAT_ITEMS ) != SfxItemState::UNKNOWN ) diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx index 483f2e5f2d8c..547015996923 100644 --- a/sc/source/ui/view/cellsh1.cxx +++ b/sc/source/ui/view/cellsh1.cxx @@ -34,6 +34,7 @@ #include <svl/zformat.hxx> #include <sfx2/dispatch.hxx> #include <sfx2/request.hxx> +#include <vcl/commandinfoprovider.hxx> #include <vcl/svapp.hxx> #include <vcl/weld.hxx> #include <svx/svxdlg.hxx> @@ -74,6 +75,7 @@ #include <condformatdlg.hxx> #include <attrib.hxx> #include <condformatdlgitem.hxx> +#include <impex.hxx> #include <globstr.hrc> #include <scresid.hxx> @@ -1493,6 +1495,56 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) rReq.SetReturnValue(SfxInt16Item(nSlot, 0)); // 0 = fail break; } + case SID_PASTE_TEXTIMPORT_DIALOG: + { + vcl::Window* pWin = GetViewData()->GetActiveWin(); + TransferableDataHelper aDataHelper( + TransferableDataHelper::CreateFromSystemClipboard(pWin)); + const uno::Reference<datatransfer::XTransferable>& xTransferable + = aDataHelper.GetTransferable(); + SotClipboardFormatId format = SotClipboardFormatId::STRING; + if (xTransferable.is() && HasClipboardFormat(format)) + { + auto pStrBuffer = std::make_shared<OUString>(); + aDataHelper.GetString(format, *pStrBuffer); + auto pStrm = std::make_shared<ScImportStringStream>(*pStrBuffer); + ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); + VclPtr<AbstractScImportAsciiDlg> pDlg(pFact->CreateScImportAsciiDlg( + pWin ? pWin->GetFrameWeld() : nullptr, OUString(), pStrm.get(), SC_PASTETEXT)); + ScRange aRange; + SCCOL nPosX = 0; + SCROW nPosY = 0; + if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE) + { + nPosX = aRange.aStart.Col(); + nPosY = aRange.aStart.Row(); + } + else + { + nPosX = GetViewData()->GetCurX(); + nPosY = GetViewData()->GetCurY(); + } + ScAddress aCellPos(nPosX, nPosY, GetViewData()->GetTabNo()); + auto pObj = std::make_shared<ScImportExport>(GetViewData()->GetDocument(), aCellPos); + pObj->SetOverwriting(true); + if (pDlg->Execute()) { + ScAsciiOptions aOptions; + pDlg->GetOptions(aOptions); + pDlg->SaveParameters(); + pObj->SetExtOptions(aOptions); + pObj->ImportString(*pStrBuffer, format); + } + pDlg->disposeOnce(); + rReq.SetReturnValue(SfxInt16Item(nSlot, 1)); // 1 = success, 0 = fail + rReq.Done(); + } + else + { + rReq.SetReturnValue(SfxInt16Item(nSlot, 0)); // 0 = fail + rReq.Ignore(); + } + } + break; case SID_PASTE_SPECIAL: // differentiate between own cell data and draw objects/external data // this makes FID_INS_CELL_CONTENTS superfluous @@ -1557,6 +1609,13 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) pDlg->Insert( nFormatId, aName ); } + SfxViewFrame* pViewFrame = pTabViewShell->GetViewFrame(); + auto xFrame = pViewFrame->GetFrame().GetFrameInterface(); + const OUString aModuleName(vcl::CommandInfoProvider::GetModuleIdentifier(xFrame)); + auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(".uno:PasteTextImportDialog", aModuleName); + OUString sLabel(vcl::CommandInfoProvider::GetTooltipLabelForCommand(aProperties)); + pDlg->InsertUno(".uno:PasteTextImportDialog", sLabel); + TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) ); SotClipboardFormatId nFormat = pDlg->GetFormat( aDataHelper.GetTransferable() ); diff --git a/sfx2/sdi/sfx.sdi b/sfx2/sdi/sfx.sdi index 624abe196661..a7d68e7d0a55 100644 --- a/sfx2/sdi/sfx.sdi +++ b/sfx2/sdi/sfx.sdi @@ -3143,6 +3143,22 @@ SfxVoidItem PasteOnlyValue SID_PASTE_ONLY_VALUE GroupId = SfxGroupId::Edit; ] +SfxVoidItem PasteTextImportDialog SID_PASTE_TEXTIMPORT_DIALOG + +[ + AutoUpdate = FALSE, + FastCall = FALSE, + ReadOnlyDoc = TRUE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + AccelConfig = TRUE, + MenuConfig = TRUE, + ToolBoxConfig = TRUE, + GroupId = SfxGroupId::Edit; +] SfxStringItem DocPath SID_DOCPATH diff --git a/vcl/source/helper/commandinfoprovider.cxx b/vcl/source/helper/commandinfoprovider.cxx index 1b010a9d50fc..805aa7ad693f 100644 --- a/vcl/source/helper/commandinfoprovider.cxx +++ b/vcl/source/helper/commandinfoprovider.cxx @@ -262,6 +262,14 @@ OUString GetPopupLabelForCommand(const css::uno::Sequence<css::beans::PropertyVa return GetCommandProperty("Label", rProperties); } +OUString GetTooltipLabelForCommand(const css::uno::Sequence<css::beans::PropertyValue>& rProperties) +{ + OUString sLabel(GetCommandProperty("TooltipLabel", rProperties)); + if (!sLabel.isEmpty()) + return sLabel; + return GetCommandProperty("Label", rProperties); +} + OUString GetTooltipForCommand( const OUString& rsCommandName, const css::uno::Sequence<css::beans::PropertyValue>& rProperties, commit dc4a291b900fd4786e9e9e7515c3a8675a8c3467 Author: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> AuthorDate: Wed Jan 22 15:59:01 2020 +0100 Commit: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> CommitDate: Wed Mar 11 12:43:35 2020 +0100 tdf#125440 When inserting TSV, consider quotes as field markers The problem is that this is "plain text" from the clipboard format, but actually contains TSV (tab separated values). So treat them accordingly, so that each value gets its own cell. Change-Id: I0029e6ace90fc542c3269dd82bb7531654157a69 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87194 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> diff --git a/sc/source/ui/docshell/impex.cxx b/sc/source/ui/docshell/impex.cxx index 6b475eccba0e..f99a8ce5fff5 100644 --- a/sc/source/ui/docshell/impex.cxx +++ b/sc/source/ui/docshell/impex.cxx @@ -889,6 +889,8 @@ bool ScImportExport::Text2Doc( SvStream& rStrm ) for( ;; ) { rStrm.ReadUniOrByteStringLine( aLine, rStrm.GetStreamCharSet(), nArbitraryLineLengthLimit ); + // tdf#125440 When inserting tab separated string, consider quotes as field markers + DoubledQuoteMode mode = aLine.indexOf("\t") >= 0 ? DoubledQuoteMode::ESCAPE : DoubledQuoteMode::KEEP_ALL; if( rStrm.eof() ) break; SCCOL nCol = nStartCol; @@ -901,7 +903,7 @@ bool ScImportExport::Text2Doc( SvStream& rStrm ) { // Always look for a pairing quote and ignore separator in between. while (*p && *p == cStr) - q = p = lcl_ScanString( p, aCell, pSeps, cStr, DoubledQuoteMode::KEEP_ALL, bOverflowCell ); + q = p = lcl_ScanString( p, aCell, pSeps, cStr, mode, bOverflowCell ); // All until next separator or quote. while (*p && *p != cSep && *p != cStr) ++p; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits