tdf#127675 Treat Biff12 when pasting
Prior to Biff8, Biff12 is tested as format for pasting. The new format is read using SfxObjectShell::DoLoad. Since the import must be to an ScDocument in SCDOCMODE_CLIP mode, a new ctor was added for SfxObjectShell, that initializes the document with needed mode. The change in MS_Excel_2007_Binary.xcu enables GetFilter4ClipBoardId to return the correct filter. Since clipboard documents don't have a chart listener collection, we must not call SetChartListenerCollectionNeedsUpdate from SetChanged; otherwise, ScDocument::UpdateChartListenerCollection would crash. Change-Id: If57b1ffb9a2f8d0573cf77b9eb82f81aa4250b5e Co-authored-by: Mike Kaganski <mike.kaganski@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190077 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
This commit is contained in:
committed by
Mike Kaganski
co-authored by
Mike Kaganski
parent
efd69fbd84
commit
ba49c9249f
@@ -23,5 +23,5 @@
|
||||
<prop oor:name="Preferred"><value>false</value></prop>
|
||||
<prop oor:name="PreferredFilter"><value>Calc MS Excel 2007 Binary</value></prop>
|
||||
<prop oor:name="UIName"><value xml:lang="en-US">Microsoft Excel 2007 Binary</value></prop>
|
||||
<prop oor:name="ClipboardFormat"/>
|
||||
<prop oor:name="ClipboardFormat"><value>Biff12</value></prop>
|
||||
</node>
|
||||
|
||||
@@ -180,8 +180,9 @@ enum class SotClipboardFormatId : sal_uInt32
|
||||
PDF = 147,
|
||||
SVG = 148,
|
||||
MARKDOWN = 149,
|
||||
BIFF_12 = 150,
|
||||
// the point at which we start allocating "runtime" format IDs
|
||||
USER_END = MARKDOWN
|
||||
USER_END = BIFF_12
|
||||
};
|
||||
|
||||
/** Make it easier to iterate over format IDs */
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
#define STR_FORMAT_ID_MARKDOWN NC_("STR_FORMAT_ID_MARKDOWN", "Markdown")
|
||||
#define STR_FORMAT_ID_BIFF_5 NC_("STR_FORMAT_ID_BIFF_5", "Microsoft Excel Binary Interchange Format 5.0/95 (Biff5)")
|
||||
#define STR_FORMAT_ID_BIFF_8 NC_("STR_FORMAT_ID_BIFF_8", "Microsoft Excel Binary Interchange Format 97/2000/XP/2003 (Biff8)")
|
||||
#define STR_FORMAT_ID_BIFF_12 NC_("STR_FORMAT_ID_BIFF_12", "Microsoft Excel Binary Interchange Format 2007 (Biff12)")
|
||||
#define STR_FORMAT_ID_SYLK NC_("STR_FORMAT_ID_SYLK", "Sylk")
|
||||
#define STR_FORMAT_ID_LINK NC_("STR_FORMAT_ID_LINK", "Dynamic Data Exchange (DDE link)" )
|
||||
#define STR_FORMAT_ID_DIF NC_("STR_FORMAT_ID_DIF", "Data Interchange Format (DIF)")
|
||||
|
||||
@@ -2917,7 +2917,7 @@ void ScDrawLayer::SetGlobalDrawPersist(SfxObjectShell* pPersist)
|
||||
|
||||
void ScDrawLayer::SetChanged( bool bFlg /* = true */ )
|
||||
{
|
||||
if ( bFlg && pDoc )
|
||||
if (bFlg && pDoc && pDoc->GetChartListenerCollection()) // clip documents don't have it
|
||||
pDoc->SetChartListenerCollectionNeedsUpdate( true );
|
||||
FmFormModel::SetChanged( bFlg );
|
||||
}
|
||||
|
||||
@@ -2966,6 +2966,11 @@ std::unique_ptr<ScDocFunc> ScDocShell::CreateDocFunc()
|
||||
return std::make_unique<ScDocFuncDirect>( *this );
|
||||
}
|
||||
|
||||
ScDocShell::ScDocShell(const SfxModelFlags i_nSfxCreationFlags, ScDocumentMode docMode)
|
||||
: ScDocShell(i_nSfxCreationFlags, std::make_shared<ScDocument>(docMode, this))
|
||||
{
|
||||
}
|
||||
|
||||
ScDocShell::ScDocShell( const SfxModelFlags i_nSfxCreationFlags, const std::shared_ptr<ScDocument>& pDoc ) :
|
||||
SfxObjectShell( i_nSfxCreationFlags ),
|
||||
m_pDocument ( pDoc ? pDoc : std::make_shared<ScDocument>( SCDOCMODE_DOCUMENT, this )),
|
||||
|
||||
@@ -171,6 +171,7 @@ private:
|
||||
public:
|
||||
explicit ScDocShell( const ScDocShell& rDocShell ) = delete;
|
||||
SC_DLLPUBLIC explicit ScDocShell( const SfxModelFlags i_nSfxCreationFlags = SfxModelFlags::EMBEDDED_OBJECT, const std::shared_ptr<ScDocument>& pDoc = {} );
|
||||
explicit ScDocShell(const SfxModelFlags i_nSfxCreationFlags, ScDocumentMode);
|
||||
virtual ~ScDocShell() override;
|
||||
|
||||
SC_DLLPUBLIC virtual SfxUndoManager* GetUndoManager() override;
|
||||
|
||||
@@ -418,6 +418,9 @@ private:
|
||||
SCCOL nEndCol, SCROW nEndRow, sal_uLong nCount );
|
||||
|
||||
bool CheckSheetViewProtection(sc::Operation eOperation);
|
||||
|
||||
void PasteFromExcelClip(ScDocument& rClipDoc, SCTAB nSrcTab, SCCOL nPosX, SCROW nPosY,
|
||||
const Point* pLogicPos, bool bAllowDialogs);
|
||||
};
|
||||
|
||||
extern bool bPasteIsMove;
|
||||
|
||||
@@ -492,6 +492,7 @@ void ScCellShell::GetPossibleClipboardFormats( SvxClipboardFormatItem& rFormats
|
||||
lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::RICHTEXT );
|
||||
lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::HTML );
|
||||
lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::HTML_SIMPLE );
|
||||
lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::BIFF_12 );
|
||||
lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::BIFF_8 );
|
||||
lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::BIFF_5 );
|
||||
}
|
||||
|
||||
@@ -4466,6 +4466,8 @@ static SotClipboardFormatId lcl_GetDropFormatId( const uno::Reference<datatransf
|
||||
nFormatId = SotClipboardFormatId::SBA_DATAEXCHANGE;
|
||||
else if ( aDataHelper.HasFormat( SotClipboardFormatId::SBA_FIELDDATAEXCHANGE ) )
|
||||
nFormatId = SotClipboardFormatId::SBA_FIELDDATAEXCHANGE;
|
||||
else if ( aDataHelper.HasFormat( SotClipboardFormatId::BIFF_12 ) )
|
||||
nFormatId = SotClipboardFormatId::BIFF_12;
|
||||
else if ( aDataHelper.HasFormat( SotClipboardFormatId::BIFF_8 ) )
|
||||
nFormatId = SotClipboardFormatId::BIFF_8;
|
||||
else if ( aDataHelper.HasFormat( SotClipboardFormatId::BIFF_5 ) )
|
||||
|
||||
@@ -517,6 +517,7 @@ void ScViewFunc::PasteFromSystem(bool useSavedPrefs)
|
||||
TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
|
||||
|
||||
{
|
||||
SotClipboardFormatId nBiff12= SotExchange::RegisterFormatName(u"Biff12"_ustr);
|
||||
SotClipboardFormatId nBiff8 = SotExchange::RegisterFormatName(u"Biff8"_ustr);
|
||||
SotClipboardFormatId nBiff5 = SotExchange::RegisterFormatName(u"Biff5"_ustr);
|
||||
|
||||
@@ -602,7 +603,9 @@ void ScViewFunc::PasteFromSystem(bool useSavedPrefs)
|
||||
else if (aDataHelper.HasFormat( SotClipboardFormatId::EMBEDDED_OBJ_OLE ))
|
||||
PasteFromSystem( SotClipboardFormatId::EMBEDDED_OBJ_OLE );
|
||||
// SotClipboardFormatId::PRIVATE no longer here (can't work if pOwnClip is NULL)
|
||||
else if (aDataHelper.HasFormat(nBiff8)) // before xxx_OLE formats
|
||||
else if (aDataHelper.HasFormat(nBiff12)) // before xxx_OLE formats
|
||||
PasteFromSystem(nBiff12);
|
||||
else if (aDataHelper.HasFormat(nBiff8))
|
||||
PasteFromSystem(nBiff8);
|
||||
else if (aDataHelper.HasFormat(nBiff5))
|
||||
PasteFromSystem(nBiff5);
|
||||
@@ -656,6 +659,7 @@ void ScViewFunc::PasteFromTransferable( const uno::Reference<datatransfer::XTran
|
||||
else
|
||||
{
|
||||
TransferableDataHelper aDataHelper( rxTransferable );
|
||||
SotClipboardFormatId nBiff12 = SotExchange::RegisterFormatName(u"Biff12"_ustr);
|
||||
SotClipboardFormatId nBiff8 = SotExchange::RegisterFormatName(u"Biff8"_ustr);
|
||||
SotClipboardFormatId nBiff5 = SotExchange::RegisterFormatName(u"Biff5"_ustr);
|
||||
SotClipboardFormatId nFormatId = SotClipboardFormatId::NONE;
|
||||
@@ -688,7 +692,9 @@ void ScViewFunc::PasteFromTransferable( const uno::Reference<datatransfer::XTran
|
||||
else if (aDataHelper.HasFormat( SotClipboardFormatId::EMBEDDED_OBJ_OLE ))
|
||||
nFormatId = SotClipboardFormatId::EMBEDDED_OBJ_OLE;
|
||||
// SotClipboardFormatId::PRIVATE no longer here (can't work if pOwnClip is NULL)
|
||||
else if (aDataHelper.HasFormat(nBiff8)) // before xxx_OLE formats
|
||||
else if (aDataHelper.HasFormat(nBiff12)) // before xxx_OLE formats
|
||||
nFormatId = nBiff12;
|
||||
else if (aDataHelper.HasFormat(nBiff8))
|
||||
nFormatId = nBiff8;
|
||||
else if (aDataHelper.HasFormat(nBiff5))
|
||||
nFormatId = nBiff5;
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <svx/GenericDropDownFieldDialog.hxx>
|
||||
#include <sfx2/dispatch.hxx>
|
||||
#include <sfx2/docfile.hxx>
|
||||
#include <sfx2/fcontnr.hxx>
|
||||
#include <comphelper/classids.hxx>
|
||||
#include <sot/formats.hxx>
|
||||
#include <sot/filelist.hxx>
|
||||
@@ -83,6 +84,48 @@
|
||||
|
||||
using namespace com::sun::star;
|
||||
|
||||
void ScViewFunc::PasteFromExcelClip(ScDocument& rClipDoc, SCTAB nSrcTab, SCCOL nPosX, SCROW nPosY,
|
||||
const Point* pLogicPos, bool bAllowDialogs)
|
||||
{
|
||||
ScRange aSource;
|
||||
const ScExtDocOptions* pExtOpt = rClipDoc.GetExtDocOptions();
|
||||
const ScExtTabSettings* pTabSett = pExtOpt ? pExtOpt->GetTabSettings(nSrcTab) : nullptr;
|
||||
if (pTabSett && pTabSett->maUsedArea.IsValid())
|
||||
{
|
||||
aSource = pTabSett->maUsedArea;
|
||||
// ensure correct sheet indexes
|
||||
aSource.aStart.SetTab(nSrcTab);
|
||||
aSource.aEnd.SetTab(nSrcTab);
|
||||
// don't use selection area: if cursor is moved in Excel after Copy, selection
|
||||
// represents the new cursor position and not the copied area
|
||||
}
|
||||
else
|
||||
{
|
||||
// Biff12 goes here
|
||||
SCCOL nFirstCol, nLastCol;
|
||||
SCROW nFirstRow, nLastRow;
|
||||
if (rClipDoc.GetDataStart(nSrcTab, nFirstCol, nFirstRow))
|
||||
rClipDoc.GetCellArea(nSrcTab, nLastCol, nLastRow);
|
||||
else
|
||||
{
|
||||
nFirstCol = nLastCol = 0;
|
||||
nFirstRow = nLastRow = 0;
|
||||
}
|
||||
aSource = ScRange(nFirstCol, nFirstRow, nSrcTab, nLastCol, nLastRow, nSrcTab);
|
||||
}
|
||||
|
||||
if (pLogicPos)
|
||||
{
|
||||
// position specified (Drag&Drop) - change selection
|
||||
MoveCursorAbs(nPosX, nPosY, SC_FOLLOW_NONE, false, false);
|
||||
Unmark();
|
||||
}
|
||||
|
||||
rClipDoc.SetClipArea(aSource);
|
||||
PasteFromClip(InsertDeleteFlags::ALL, &rClipDoc, ScPasteFunc::NONE, false,
|
||||
false, false, INS_NONE, InsertDeleteFlags::NONE, bAllowDialogs);
|
||||
}
|
||||
|
||||
bool ScViewFunc::PasteDataFormat( SotClipboardFormatId nFormatId,
|
||||
const uno::Reference<datatransfer::XTransferable>& rxTransferable,
|
||||
SCCOL nPosX, SCROW nPosY, const Point* pLogicPos, bool bLink, bool bAllowDialogs, bool useSavedPrefs )
|
||||
@@ -290,6 +333,29 @@ bool ScViewFunc::PasteDataFormat( SotClipboardFormatId nFormatId,
|
||||
bRet = true;
|
||||
}
|
||||
}
|
||||
else if (nFormatId == SotClipboardFormatId::BIFF_12)
|
||||
{
|
||||
if (auto xStm = aDataHelper.GetInputStream(nFormatId, {}))
|
||||
{
|
||||
SfxFilterMatcher aMatcher(ScDocShell::Factory().GetFilterContainer()->GetName());
|
||||
if (auto pFilter = aMatcher.GetFilter4ClipBoardId(SotClipboardFormatId::BIFF_12))
|
||||
{
|
||||
ScDocShellRef pClipShell(new ScDocShell(SfxModelFlags::NONE, SCDOCMODE_CLIP));
|
||||
SCTAB nSrcTab = 0;
|
||||
pClipShell->GetDocument().ResetClip(&rDoc, nSrcTab);
|
||||
SfxMedium aMed;
|
||||
aMed.GetItemSet().Put(SfxUnoAnyItem(SID_INPUTSTREAM, uno::Any(xStm)));
|
||||
aMed.SetFilter(pFilter);
|
||||
|
||||
if (pClipShell->DoLoad(&aMed))
|
||||
{
|
||||
PasteFromExcelClip(pClipShell->GetDocument(), nSrcTab, nPosX, nPosY, pLogicPos,
|
||||
bAllowDialogs);
|
||||
bRet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( (nFormatId == SotClipboardFormatId::BIFF_5) || (nFormatId == SotClipboardFormatId::BIFF_8) )
|
||||
{
|
||||
// do excel import into a clipboard document
|
||||
@@ -306,45 +372,7 @@ bool ScViewFunc::PasteDataFormat( SotClipboardFormatId nFormatId,
|
||||
ErrCode eErr = ScFormatFilter::Get().ScImportExcel( aMed, &aInsDoc, EIF_AUTO );
|
||||
if ( eErr == ERRCODE_NONE )
|
||||
{
|
||||
ScRange aSource;
|
||||
const ScExtDocOptions* pExtOpt = aInsDoc.GetExtDocOptions();
|
||||
const ScExtTabSettings* pTabSett = pExtOpt ? pExtOpt->GetTabSettings( nSrcTab ) : nullptr;
|
||||
if( pTabSett && pTabSett->maUsedArea.IsValid() )
|
||||
{
|
||||
aSource = pTabSett->maUsedArea;
|
||||
// ensure correct sheet indexes
|
||||
aSource.aStart.SetTab( nSrcTab );
|
||||
aSource.aEnd.SetTab( nSrcTab );
|
||||
// don't use selection area: if cursor is moved in Excel after Copy, selection
|
||||
// represents the new cursor position and not the copied area
|
||||
}
|
||||
else
|
||||
{
|
||||
OSL_FAIL("no dimension"); //! possible?
|
||||
SCCOL nFirstCol, nLastCol;
|
||||
SCROW nFirstRow, nLastRow;
|
||||
if ( aInsDoc.GetDataStart( nSrcTab, nFirstCol, nFirstRow ) )
|
||||
aInsDoc.GetCellArea( nSrcTab, nLastCol, nLastRow );
|
||||
else
|
||||
{
|
||||
nFirstCol = nLastCol = 0;
|
||||
nFirstRow = nLastRow = 0;
|
||||
}
|
||||
aSource = ScRange( nFirstCol, nFirstRow, nSrcTab,
|
||||
nLastCol, nLastRow, nSrcTab );
|
||||
}
|
||||
|
||||
if ( pLogicPos )
|
||||
{
|
||||
// position specified (Drag&Drop) - change selection
|
||||
MoveCursorAbs( nPosX, nPosY, SC_FOLLOW_NONE, false, false );
|
||||
Unmark();
|
||||
}
|
||||
|
||||
aInsDoc.SetClipArea( aSource );
|
||||
PasteFromClip( InsertDeleteFlags::ALL, &aInsDoc,
|
||||
ScPasteFunc::NONE, false, false, false, INS_NONE, InsertDeleteFlags::NONE,
|
||||
bAllowDialogs );
|
||||
PasteFromExcelClip(aInsDoc, nSrcTab, nPosX, nPosY, pLogicPos, bAllowDialogs);
|
||||
bRet = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,6 +198,7 @@ const DataFlavor* FormatArray_Impl()
|
||||
/*147 PDF*/ { u"application/pdf"_ustr, u"PDF Document"_ustr, cppu::UnoType<Sequence<sal_Int8>>::get() },
|
||||
/*148 SVG*/ { u"image/svg+xml;windows_formatname=\"image/svg+xml\""_ustr, u"SVG"_ustr, cppu::UnoType<Sequence<sal_Int8>>::get() },
|
||||
/*149 MARKDOWN*/ { u"text/markdown"_ustr, u"Markdown"_ustr, cppu::UnoType<Sequence<sal_Int8>>::get() },
|
||||
/*150 BIFF_12*/ { u"application/x-openoffice-biff-12;windows_formatname=\"Biff12\""_ustr, u"Biff12"_ustr, cppu::UnoType<Sequence<sal_Int8>>::get() },
|
||||
};
|
||||
assert(std::size(aInstance) == size_t(SotClipboardFormatId::USER_END) + 1);
|
||||
return &aInstance[0];
|
||||
|
||||
@@ -1017,6 +1017,7 @@ SotAction_Impl const aEXCHG_DEST_SCDOC_FREE_AREA_Move[] =
|
||||
{ SotClipboardFormatId::LINK, EXCHG_OUT_ACTION_INSERT_DDE, SotExchangeActionFlags::InsertTargetUrl, 0 },
|
||||
{ SotClipboardFormatId::SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP, SotExchangeActionFlags::InsertTargetUrl, 0 },
|
||||
{ SotClipboardFormatId::BIFF_8, EXCHG_IN_ACTION_MOVE, SotExchangeActionFlags::InsertTargetUrl, 0 },
|
||||
{ SotClipboardFormatId::BIFF_12, EXCHG_IN_ACTION_MOVE, SotExchangeActionFlags::InsertTargetUrl, 0 },
|
||||
};
|
||||
SotAction_Impl const aEXCHG_DEST_SCDOC_FREE_AREA_Copy[] =
|
||||
{
|
||||
@@ -1045,6 +1046,7 @@ SotAction_Impl const aEXCHG_DEST_SCDOC_FREE_AREA_Copy[] =
|
||||
{ SotClipboardFormatId::LINK, EXCHG_OUT_ACTION_INSERT_DDE, SotExchangeActionFlags::InsertTargetUrl, 0 },
|
||||
{ SotClipboardFormatId::SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP, SotExchangeActionFlags::InsertTargetUrl, 0 },
|
||||
{ SotClipboardFormatId::BIFF_8, EXCHG_IN_ACTION_COPY, SotExchangeActionFlags::InsertTargetUrl, 0 },
|
||||
{ SotClipboardFormatId::BIFF_12, EXCHG_IN_ACTION_COPY, SotExchangeActionFlags::InsertTargetUrl, 0 },
|
||||
};
|
||||
SotAction_Impl const aEXCHG_DEST_SCDOC_FREE_AREA_Link[] =
|
||||
{
|
||||
|
||||
@@ -208,6 +208,7 @@ OUString SvPasteObjectHelper::GetSotFormatUIName( SotClipboardFormatId nId )
|
||||
{ SotClipboardFormatId::HTML_SIMPLE, STR_FORMAT_ID_HTML_SIMPLE },
|
||||
{ SotClipboardFormatId::BIFF_5, STR_FORMAT_ID_BIFF_5 },
|
||||
{ SotClipboardFormatId::BIFF_8, STR_FORMAT_ID_BIFF_8 },
|
||||
{ SotClipboardFormatId::BIFF_12, STR_FORMAT_ID_BIFF_12 },
|
||||
{ SotClipboardFormatId::SYLK, STR_FORMAT_ID_SYLK },
|
||||
{ SotClipboardFormatId::LINK, STR_FORMAT_ID_LINK },
|
||||
{ SotClipboardFormatId::DIF, STR_FORMAT_ID_DIF },
|
||||
|
||||
@@ -177,6 +177,7 @@ auto initTranslTable()
|
||||
FormatEntry(xFactory, SotClipboardFormatId::BIFF_5),
|
||||
FormatEntry(xFactory, SotClipboardFormatId::BIFF__5),
|
||||
FormatEntry(xFactory, SotClipboardFormatId::BIFF_8),
|
||||
FormatEntry(xFactory, SotClipboardFormatId::BIFF_12),
|
||||
FormatEntry(xFactory, SotClipboardFormatId::SYLK_BIGCAPS),
|
||||
FormatEntry(xFactory, SotClipboardFormatId::LINK),
|
||||
FormatEntry(xFactory, SotClipboardFormatId::STARDRAW_TABBAR),
|
||||
|
||||
Reference in New Issue
Block a user