tdf#165004 sc: Insert multiple images via the insert dialog and DnD.

Added support for selecting multiple images in the insert dialog. Fixed an issue with inserting multiple images via DnD.

When inserting a single image into a shape with a background or onto another existing image - they are replaced.
If insert multiple images into a shape or onto an existing image - they are inserted instead of being replaced.
To achieve this, SetMultiInsertState(...) and isMultiInsert() methods have been added for DnD, and the boolean
variable isMultiInsert is passed for insertion via lcl_InsertGraphic(...).

Change-Id: Id299be0112ffe0bdf1aafb534edbfb216859dbf4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200891
Tested-by: Jenkins
Reviewed-by: Roman Kuznetsov <antilibreoffice@gmail.com>
This commit is contained in:
Irgaliev Amin
2026-06-27 16:31:56 +02:00
committed by Roman Kuznetsov
parent 9f8489fbcd
commit 4df292a3ca
8 changed files with 54 additions and 17 deletions
+3
View File
@@ -21,6 +21,7 @@
#include <memory>
#include <sfx2/dllapi.h>
#include <rtl/ustring.hxx>
#include <com/sun/star/uno/Sequence.hxx>
namespace com::sun::star::ui::dialogs { class XFilePickerControlAccess; }
namespace com::sun::star::uno { template <class interface_type> class Reference; }
@@ -42,6 +43,8 @@ public:
void SetPath( const OUString& rPath, bool bLinkState );
OUString GetPath() const;
css::uno::Sequence< OUString > GetSelectedFiles() const;
void setMultiSelect(bool bEnable);
ErrCode GetGraphic(Graphic&) const;
+26 -9
View File
@@ -34,6 +34,7 @@
#include <svx/svxids.hrc>
#include <vcl/graphicfilter.hxx>
#include <svl/stritem.hxx>
#include <svl/slstitm.hxx>
#include <avmedia/mediawindow.hxx>
#include <vcl/svapp.hxx>
#include <vcl/weld/Window.hxx>
@@ -111,7 +112,7 @@ void ScLimitSizeOnDrawPage( Size& rSize, Point& rPos, const Size& rPage )
static void lcl_InsertGraphic( const Graphic& rGraphic,
const OUString& rFileName, bool bAsLink, bool bApi,
ScTabViewShell& rViewSh, const vcl::Window* pWindow, SdrView* pView,
ScAnchorType aAnchorType = SCA_CELL )
ScAnchorType aAnchorType = SCA_CELL, bool bMultiInsert = false )
{
Graphic& rGraphic1 = const_cast<Graphic &>(rGraphic);
GraphicNativeMetadata aMetadata;
@@ -132,7 +133,7 @@ static void lcl_InsertGraphic( const Graphic& rGraphic,
if(pDrawView)
{
const SdrMarkList& rMarkList = pDrawView->GetMarkedObjectList();
if (1 == rMarkList.GetMarkCount())
if (1 == rMarkList.GetMarkCount() && !bMultiInsert)
{
SdrObject* pPickObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
@@ -306,6 +307,7 @@ FuInsertGraphic::FuInsertGraphic( ScTabViewShell& rViewSh,
SvxOpenGraphicDialog aDlg(ScResId(STR_INSERTGRAPHIC), pWin ? pWin->GetFrameWeld() : nullptr,
ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_ANCHOR);
aDlg.setMultiSelect(true);
Reference<ui::dialogs::XFilePickerControlAccess> xCtrlAcc = aDlg.GetFilePickerControlAccess();
sal_Int16 nSelect = 0;
Sequence<OUString> aListBoxEntries {
@@ -335,16 +337,19 @@ FuInsertGraphic::FuInsertGraphic( ScTabViewShell& rViewSh,
ErrCode nError = aDlg.GetGraphic(aGraphic);
if( nError == ERRCODE_NONE )
{
OUString aFileName = aDlg.GetPath();
Sequence < OUString > aFileNames = aDlg.GetSelectedFiles();
const OUString& aFilterName = aDlg.GetDetectedFilter();
bool bAsLink = aDlg.IsAsLink();
// really store as link only?
if( bAsLink && officecfg::Office::Common::Misc::ShowLinkWarningDialog::get() )
{
SvxLinkWarningDialog aWarnDlg(pWin ? pWin->GetFrameWeld() : nullptr, aFileName);
if (aWarnDlg.run() != RET_OK)
bAsLink = false; // don't store as link
for (const auto& aFileName : aFileNames)
{
SvxLinkWarningDialog aWarnDlg(pWin ? pWin->GetFrameWeld() : nullptr, aFileName);
if (aWarnDlg.run() != RET_OK)
bAsLink = false; // don't store as link
}
}
// Anchor to cell or to page?
@@ -364,18 +369,30 @@ FuInsertGraphic::FuInsertGraphic( ScTabViewShell& rViewSh,
else
aAnchorType = SCA_DONTKNOW;
lcl_InsertGraphic( aGraphic, aFileName, bAsLink, false, rViewSh, pWindow, pView, aAnchorType );
// append items for recording
rReq.AppendItem( SfxStringItem( SID_INSERT_GRAPHIC, aFileName ) );
SfxStringListItem aItem(SID_INSERT_GRAPHIC);
aItem.SetStringList(aFileNames);
rReq.AppendItem(aItem);
rReq.AppendItem( SfxStringItem( FN_PARAM_FILTER, aFilterName ) );
rReq.AppendItem( SfxBoolItem( FN_PARAM_1, bAsLink ) );
for (const auto& aFileName : aFileNames)
{
nError = GraphicFilter::LoadGraphic(aFileName, aFilterName, aGraphic, &GraphicFilter::GetGraphicFilter());
// format not equal to current filter (with autodetection)
if (nError == ERRCODE_GRFILTER_FORMATERROR)
nError = GraphicFilter::LoadGraphic(aFileName, OUString(), aGraphic, &GraphicFilter::GetGraphicFilter());
if (nError == ERRCODE_NONE)
lcl_InsertGraphic( aGraphic, aFileName, bAsLink, false, rViewSh, pWindow, pView, aAnchorType, aFileNames.getLength() > 1);
else
SAL_WARN("sc", "Failed to load graphic: " << aFileName);
}
rReq.Done();
}
else
{
// error is handled in SvxOpenGraphicDialog::GetGraphic
}
aDlg.setMultiSelect(false);
}
}
}
+4
View File
@@ -73,6 +73,7 @@ private:
ScAddress aFormatSource; // for automatic extension of formatting
ScRange aFormatArea;
bool bFormatValid;
bool mbMultiInsert;
public:
ScViewFunc( vcl::Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell );
@@ -150,6 +151,9 @@ public:
SCCOL nPosX, SCROW nPosY, const Point* pLogicPos,
bool bLink = false, bool bAllowDialogs = false, bool useSavedPrefs = false );
bool isMultiInsert() { return mbMultiInsert; }
void SetMultiInsertState( bool bMultiInsert ) { mbMultiInsert = bMultiInsert; }
bool PasteFile( const Point&, const OUString&, bool bLink );
bool PasteObject( const Point&, const css::uno::Reference < css::embed::XEmbeddedObject >&, const Size*, const Graphic* = nullptr, const OUString& = OUString(), sal_Int64 nAspect = css::embed::Aspects::MSOLE_CONTENT );
bool PasteBitmap( const Point&, const Bitmap& );
+2 -1
View File
@@ -1097,7 +1097,8 @@ SdrObject* ScDrawView::ApplyGraphicToObject(
ReplaceObjectAtView(&rHitObject, *GetSdrPageView(), pNewGrafObj.get());
// set in all cases - the Clone() will have copied an existing link (!)
pNewGrafObj->SetGraphicLink( rFile );
if (!rFile.isEmpty())
pNewGrafObj->SetGraphicLink(rFile);
EndUndo();
return pNewGrafObj.get();
+1
View File
@@ -389,6 +389,7 @@ bool ScViewFunc::PasteDataFormat( SotClipboardFormatId nFormatId,
if ( aDataHelper.GetFileList( nFormatId, aFileList ) )
{
sal_uLong nCount = aFileList.Count();
SetMultiInsertState(nCount > 1);
for( sal_uLong i = 0; i < nCount ; i++ )
{
OUString aFile = aFileList.GetFile( i );
+1 -1
View File
@@ -396,7 +396,7 @@ bool ScViewFunc::PasteGraphic( const Point& rPos, const Graphic& rGraphic,
if (pPageView)
{
SdrObject* pPickObj = pScDrawView->PickObj(rPos, pScDrawView->getHitTolLog(), pPageView);
if (pPickObj)
if (pPickObj && !isMultiInsert())
{
const OUString aBeginUndo(ScResId(STR_UNDO_DRAGDROP));
SdrObject* pResult = pScDrawView->ApplyGraphicToObject(
+10
View File
@@ -74,6 +74,11 @@ struct SvxOpenGrf_Impl
};
void SvxOpenGraphicDialog::setMultiSelect(bool bEnable)
{
mpImpl->aFileDlg.GetFilePicker()->setMultiSelectionMode(bEnable);
}
SvxOpenGrf_Impl::SvxOpenGrf_Impl(weld::Window* pPreferredParent,
sal_Int16 nDialogType)
: aFileDlg(nDialogType, FileDialogFlags::Graphic, pPreferredParent)
@@ -260,6 +265,11 @@ OUString SvxOpenGraphicDialog::GetPath() const
return mpImpl->aFileDlg.GetPath();
}
Sequence< OUString > SvxOpenGraphicDialog::GetSelectedFiles() const
{
return mpImpl->aFileDlg.GetSelectedFiles();
}
OUString SvxOpenGraphicDialog::GetCurrentFilter() const
{
return mpImpl->aFileDlg.GetCurrentFilter();
+7 -6
View File
@@ -838,16 +838,17 @@ ErrCode FileDialogHelper_Impl::getGraphic( Graphic& rGraphic )
// rhbz#1079672 do not return maGraphic, it needs not to be the selected file
OUString aPath;
Sequence<OUString> aPathSeq = mxFileDlg->getSelectedFiles();
if (aPathSeq.getLength() == 1)
if (aPathSeq.getLength() > 0)
{
aPath = aPathSeq[0];
for (const auto& fileName : aPathSeq)
{
nRet = getGraphic(fileName, rGraphic);
if (nRet != ERRCODE_NONE)
return nRet;
}
}
if (!aPath.isEmpty())
nRet = getGraphic(aPath, rGraphic);
else
nRet = ERRCODE_IO_GENERAL;