1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_features.h>
23 #include <editeng/eeitem.hxx>
25 #include <editeng/editobj.hxx>
26 #include <editeng/editstat.hxx>
27 #include <editeng/editview.hxx>
28 #include <editeng/flditem.hxx>
29 #include <sot/storage.hxx>
30 #include <svx/hlnkitem.hxx>
31 #include <editeng/unolingu.hxx>
33 #include <sfx2/bindings.hxx>
34 #include <sfx2/dispatch.hxx>
35 #include <sfx2/docfile.hxx>
36 #include <sfx2/docfilt.hxx>
37 #include <sfx2/fcontnr.hxx>
38 #include <svtools/langtab.hxx>
39 #include <vcl/graphicfilter.hxx>
40 #include <svl/stritem.hxx>
41 #include <vcl/transfer.hxx>
42 #include <svl/urlbmk.hxx>
43 #include <svl/sharedstringpool.hxx>
44 #include <vcl/svapp.hxx>
45 #include <vcl/weld.hxx>
46 #include <avmedia/mediawindow.hxx>
47 #include <osl/diagnose.h>
49 #include <comphelper/propertyvalue.hxx>
50 #include <comphelper/storagehelper.hxx>
52 #include <viewfunc.hxx>
54 #include <document.hxx>
55 #include <globstr.hrc>
57 #include <scresid.hxx>
58 #include <undoblk.hxx>
59 #include <undocell.hxx>
60 #include <formulacell.hxx>
62 #include <spelleng.hxx>
63 #include <patattr.hxx>
64 #include <tabvwsh.hxx>
66 #include <editutil.hxx>
67 #include <editable.hxx>
68 #include <dociter.hxx>
69 #include <reffind.hxx>
70 #include <compiler.hxx>
71 #include <tokenarray.hxx>
72 #include <refupdatecontext.hxx>
73 #include <gridwin.hxx>
74 #include <refundo.hxx>
76 using namespace com::sun::star
;
78 void ScViewFunc::PasteRTF( SCCOL nStartCol
, SCROW nStartRow
,
79 const css::uno::Reference
< css::datatransfer::XTransferable
>& rxTransferable
)
81 TransferableDataHelper
aDataHelper( rxTransferable
);
82 if ( aDataHelper
.HasFormat( SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT
) )
86 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
87 ScDocument
& rDoc
= pDocSh
->GetDocument();
88 SCTAB nTab
= GetViewData().GetTabNo();
89 const bool bRecord (rDoc
.IsUndoEnabled());
91 const ScPatternAttr
* pPattern
= rDoc
.GetPattern( nStartCol
, nStartRow
, nTab
);
92 std::optional
<ScTabEditEngine
> pEngine(std::in_place
, *pPattern
, rDoc
.GetEnginePool(), &rDoc
);
93 pEngine
->EnableUndo( false );
95 vcl::Window
* pActWin
= GetActiveWin();
98 pEngine
->SetPaperSize(Size(100000,100000));
99 ScopedVclPtrInstance
< vcl::Window
> aWin( pActWin
);
100 EditView
aEditView( &*pEngine
, aWin
.get() );
101 aEditView
.SetOutputArea(tools::Rectangle(0,0,100000,100000));
103 // same method now for clipboard or drag&drop
104 // mba: clipboard always must contain absolute URLs (could be from alien source)
105 aEditView
.InsertText( rxTransferable
, OUString(), true );
108 sal_Int32 nParCnt
= pEngine
->GetParagraphCount();
111 SCROW nEndRow
= nStartRow
+ static_cast<SCROW
>(nParCnt
) - 1;
112 if (nEndRow
> rDoc
.MaxRow())
113 nEndRow
= rDoc
.MaxRow();
115 ScDocumentUniquePtr pUndoDoc
;
118 pUndoDoc
.reset(new ScDocument( SCDOCMODE_UNDO
));
119 pUndoDoc
->InitUndo( rDoc
, nTab
, nTab
);
120 rDoc
.CopyToDocument( nStartCol
,nStartRow
,nTab
, nStartCol
,nEndRow
,nTab
, InsertDeleteFlags::ALL
, false, *pUndoDoc
);
123 SCROW nRow
= nStartRow
;
125 // Temporarily turn off undo generation for this lot
126 bool bUndoEnabled
= rDoc
.IsUndoEnabled();
127 rDoc
.EnableUndo( false );
128 for( sal_Int32 n
= 0; n
< nParCnt
; n
++ )
130 std::unique_ptr
<EditTextObject
> pObject(pEngine
->CreateTextObject(n
));
131 EnterData(nStartCol
, nRow
, nTab
, *pObject
, true);
132 if( ++nRow
> rDoc
.MaxRow() )
135 rDoc
.EnableUndo(bUndoEnabled
);
139 ScDocumentUniquePtr
pRedoDoc(new ScDocument( SCDOCMODE_UNDO
));
140 pRedoDoc
->InitUndo( rDoc
, nTab
, nTab
);
141 rDoc
.CopyToDocument( nStartCol
,nStartRow
,nTab
, nStartCol
,nEndRow
,nTab
, InsertDeleteFlags::ALL
|InsertDeleteFlags::NOCAPTIONS
, false, *pRedoDoc
);
143 ScRange
aMarkRange(nStartCol
, nStartRow
, nTab
, nStartCol
, nEndRow
, nTab
);
144 ScMarkData
aDestMark(rDoc
.GetSheetLimits());
145 aDestMark
.SetMarkArea( aMarkRange
);
146 pDocSh
->GetUndoManager()->AddUndoAction(
147 std::make_unique
<ScUndoPaste
>( pDocSh
, aMarkRange
, aDestMark
,
148 std::move(pUndoDoc
), std::move(pRedoDoc
), InsertDeleteFlags::ALL
, nullptr));
159 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
160 ScImportExport
aImpEx( pDocSh
->GetDocument(),
161 ScAddress( nStartCol
, nStartRow
, GetViewData().GetTabNo() ) );
164 std::unique_ptr
<SvStream
> xStream
;
165 if ( (xStream
= aDataHelper
.GetSotStorageStream( SotClipboardFormatId::RTF
)) )
166 // mba: clipboard always must contain absolute URLs (could be from alien source)
167 aImpEx
.ImportStream( *xStream
, OUString(), SotClipboardFormatId::RTF
);
168 else if ( aDataHelper
.GetString( SotClipboardFormatId::RTF
, aStr
) )
169 aImpEx
.ImportString( aStr
, SotClipboardFormatId::RTF
);
170 else if ( (xStream
= aDataHelper
.GetSotStorageStream( SotClipboardFormatId::RICHTEXT
)) )
171 aImpEx
.ImportStream( *xStream
, OUString(), SotClipboardFormatId::RICHTEXT
);
172 else if ( aDataHelper
.GetString( SotClipboardFormatId::RICHTEXT
, aStr
) )
173 aImpEx
.ImportString( aStr
, SotClipboardFormatId::RICHTEXT
);
175 AdjustRowHeight( nStartRow
, aImpEx
.GetRange().aEnd
.Row(), true );
176 pDocSh
->UpdateOle(GetViewData());
180 void ScViewFunc::DoRefConversion()
182 ScDocument
& rDoc
= GetViewData().GetDocument();
183 ScMarkData
& rMark
= GetViewData().GetMarkData();
184 SCTAB nTabCount
= rDoc
.GetTableCount();
186 if (!rDoc
.IsUndoEnabled())
190 rMark
.MarkToSimple();
191 bool bMulti
= rMark
.IsMultiMarked();
193 aMarkRange
= rMark
.GetMultiMarkArea();
194 else if (rMark
.IsMarked())
195 aMarkRange
= rMark
.GetMarkArea();
198 aMarkRange
= ScRange( GetViewData().GetCurX(),
199 GetViewData().GetCurY(), GetViewData().GetTabNo() );
201 ScEditableTester
aTester( rDoc
, aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(),
202 aMarkRange
.aEnd
.Col(), aMarkRange
.aEnd
.Row(),rMark
);
203 if (!aTester
.IsEditable())
205 ErrorMessage(aTester
.GetMessageId());
209 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
212 ScDocumentUniquePtr pUndoDoc
;
215 pUndoDoc
.reset( new ScDocument( SCDOCMODE_UNDO
) );
216 SCTAB nTab
= aMarkRange
.aStart
.Tab();
217 pUndoDoc
->InitUndo( rDoc
, nTab
, nTab
);
219 if ( rMark
.GetSelectCount() > 1 )
221 for (const auto& rTab
: rMark
)
223 pUndoDoc
->AddUndoTab( rTab
, rTab
);
225 ScRange aCopyRange
= aMarkRange
;
226 aCopyRange
.aStart
.SetTab(0);
227 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
228 rDoc
.CopyToDocument( aCopyRange
, InsertDeleteFlags::ALL
, bMulti
, *pUndoDoc
, &rMark
);
231 ScRangeListRef xRanges
;
232 GetViewData().GetMultiArea( xRanges
);
233 size_t nCount
= xRanges
->size();
235 for (const SCTAB
& i
: rMark
)
237 for (size_t j
= 0; j
< nCount
; ++j
)
239 ScRange aRange
= (*xRanges
)[j
];
240 aRange
.aStart
.SetTab(i
);
241 aRange
.aEnd
.SetTab(i
);
242 ScCellIterator
aIter( rDoc
, aRange
);
243 for (bool bHas
= aIter
.first(); bHas
; bHas
= aIter
.next())
245 if (aIter
.getType() != CELLTYPE_FORMULA
)
248 ScFormulaCell
* pCell
= aIter
.getFormulaCell();
249 ScMatrixMode eMatrixMode
= pCell
->GetMatrixFlag();
250 if (eMatrixMode
== ScMatrixMode::Reference
)
253 OUString aOld
= pCell
->GetFormula();
254 sal_Int32 nLen
= aOld
.getLength();
255 if (eMatrixMode
== ScMatrixMode::Formula
)
257 assert(nLen
>= 2 && aOld
[0] == '{' && aOld
[nLen
-1] == '}');
259 aOld
= aOld
.copy( 1, nLen
);
261 ScRefFinder
aFinder( aOld
, aIter
.GetPos(), rDoc
, rDoc
.GetAddressConvention() );
262 aFinder
.ToggleRel( 0, nLen
);
263 if (aFinder
.GetFound())
265 ScAddress aPos
= pCell
->aPos
;
266 const OUString
& aNew
= aFinder
.GetText();
267 ScCompiler
aComp( rDoc
, aPos
, rDoc
.GetGrammar());
268 std::unique_ptr
<ScTokenArray
> pArr(aComp
.CompileString(aNew
));
269 ScFormulaCell
* pNewCell
=
271 rDoc
, aPos
, *pArr
, formula::FormulaGrammar::GRAM_DEFAULT
, eMatrixMode
);
273 rDoc
.SetFormulaCell(aPos
, pNewCell
);
281 ScDocumentUniquePtr
pRedoDoc(new ScDocument( SCDOCMODE_UNDO
));
282 SCTAB nTab
= aMarkRange
.aStart
.Tab();
283 pRedoDoc
->InitUndo( rDoc
, nTab
, nTab
);
285 if ( rMark
.GetSelectCount() > 1 )
287 for (const auto& rTab
: rMark
)
289 pRedoDoc
->AddUndoTab( rTab
, rTab
);
291 ScRange aCopyRange
= aMarkRange
;
292 aCopyRange
.aStart
.SetTab(0);
293 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
294 rDoc
.CopyToDocument( aCopyRange
, InsertDeleteFlags::ALL
, bMulti
, *pRedoDoc
, &rMark
);
296 pDocSh
->GetUndoManager()->AddUndoAction(
297 std::make_unique
<ScUndoRefConversion
>( pDocSh
,
298 aMarkRange
, rMark
, std::move(pUndoDoc
), std::move(pRedoDoc
), bMulti
) );
301 pDocSh
->PostPaint( aMarkRange
, PaintPartFlags::Grid
);
302 pDocSh
->UpdateOle(GetViewData());
303 pDocSh
->SetDocumentModified();
304 CellContentChanged();
307 ErrorMessage(STR_ERR_NOREF
);
310 // Thesaurus - Undo ok
311 void ScViewFunc::DoThesaurus()
316 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
317 ScDocument
& rDoc
= pDocSh
->GetDocument();
318 ScMarkData
& rMark
= GetViewData().GetMarkData();
319 ScSplitPos eWhich
= GetViewData().GetActivePart();
321 EditView
* pEditView
= nullptr;
322 std::unique_ptr
<ESelection
> pEditSel
;
323 std::unique_ptr
<ScEditEngineDefaulter
> pThesaurusEngine
;
324 bool bIsEditMode
= GetViewData().HasEditView(eWhich
);
326 if (!rDoc
.IsUndoEnabled())
328 if (bIsEditMode
) // edit mode active
330 GetViewData().GetEditView(eWhich
, pEditView
, nCol
, nRow
);
331 pEditSel
.reset(new ESelection(pEditView
->GetSelection()));
332 ScModule::get()->InputEnterHandler();
333 GetViewData().GetBindings().Update(); // otherwise the Sfx becomes mixed-up...
337 nCol
= GetViewData().GetCurX();
338 nRow
= GetViewData().GetCurY();
340 nTab
= GetViewData().GetTabNo();
342 ScAddress
aPos(nCol
, nRow
, nTab
);
343 ScEditableTester
aTester( rDoc
, nCol
, nRow
, nCol
, nRow
, rMark
);
344 if (!aTester
.IsEditable())
346 ErrorMessage(aTester
.GetMessageId());
350 ScCellValue aOldText
;
351 aOldText
.assign(rDoc
, aPos
);
352 if (aOldText
.getType() != CELLTYPE_STRING
&& aOldText
.getType() != CELLTYPE_EDIT
)
354 ErrorMessage(STR_THESAURUS_NO_STRING
);
358 uno::Reference
<linguistic2::XSpellChecker1
> xSpeller
= LinguMgr::GetSpellChecker();
360 pThesaurusEngine
.reset(new ScEditEngineDefaulter(rDoc
.GetEnginePool()));
361 pThesaurusEngine
->SetEditTextObjectPool( rDoc
.GetEditPool() );
362 pThesaurusEngine
->SetRefDevice(GetViewData().GetActiveWin()->GetOutDev());
363 pThesaurusEngine
->SetSpeller(xSpeller
);
364 MakeEditView(pThesaurusEngine
.get(), nCol
, nRow
);
365 const ScPatternAttr
* pPattern
= rDoc
.GetPattern(nCol
, nRow
, nTab
);
368 auto pEditDefaults
= std::make_unique
<SfxItemSet
>(pThesaurusEngine
->GetEmptyItemSet());
369 pPattern
->FillEditItemSet(pEditDefaults
.get());
370 pThesaurusEngine
->SetDefaults(std::move(pEditDefaults
));
373 if (aOldText
.getType() == CELLTYPE_EDIT
)
374 pThesaurusEngine
->SetTextCurrentDefaults(*aOldText
.getEditText());
376 pThesaurusEngine
->SetTextCurrentDefaults(aOldText
.getString(rDoc
));
378 pEditView
= GetViewData().GetEditView(GetViewData().GetActivePart());
380 pEditView
->SetSelection(*pEditSel
);
382 pEditView
->SetSelection(ESelection());
384 pThesaurusEngine
->ClearModifyFlag();
386 // language is now in EditEngine attributes -> no longer passed to StartThesaurus
388 eState
= pEditView
->StartThesaurus(GetViewData().GetDialogParent());
389 OSL_ENSURE(eState
!= EESpellState::NoSpeller
, "No SpellChecker");
391 if (eState
== EESpellState::ErrorFound
) // should happen later through Wrapper!
393 LanguageType eLnge
= ScViewUtil::GetEffLanguage( rDoc
, ScAddress( nCol
, nRow
, nTab
) );
394 OUString aErr
= SvtLanguageTable::GetLanguageString(eLnge
) + ScResId( STR_SPELLING_NO_LANG
);
396 std::unique_ptr
<weld::MessageDialog
> xInfoBox(Application::CreateMessageDialog(GetViewData().GetDialogParent(),
397 VclMessageType::Info
, VclButtonsType::Ok
,
401 if (pThesaurusEngine
->IsModified())
403 ScCellValue aNewText
;
405 if (aOldText
.getType() == CELLTYPE_EDIT
)
407 // The cell will own the text object instance.
408 std::unique_ptr
<EditTextObject
> pText
= pThesaurusEngine
->CreateTextObject();
409 auto tmp
= pText
.get();
410 if (rDoc
.SetEditText(ScAddress(nCol
,nRow
,nTab
), std::move(pText
)))
415 OUString aStr
= pThesaurusEngine
->GetText();
416 aNewText
.set(rDoc
.GetSharedStringPool().intern(aStr
));
417 rDoc
.SetString(nCol
, nRow
, nTab
, aStr
);
420 pDocSh
->SetDocumentModified();
423 GetViewData().GetDocShell()->GetUndoManager()->AddUndoAction(
424 std::make_unique
<ScUndoThesaurus
>(
425 GetViewData().GetDocShell(), nCol
, nRow
, nTab
, aOldText
, aNewText
));
430 pDocSh
->PostPaintGridAll();
433 void ScViewFunc::DoHangulHanjaConversion()
435 ScConversionParam
aConvParam( SC_CONVERSION_HANGULHANJA
, LANGUAGE_KOREAN
, 0, true );
436 DoSheetConversion( aConvParam
);
439 void ScViewFunc::DoSheetConversion( const ScConversionParam
& rConvParam
)
444 ScViewData
& rViewData
= GetViewData();
445 ScDocShell
* pDocSh
= rViewData
.GetDocShell();
446 ScDocument
& rDoc
= pDocSh
->GetDocument();
447 ScMarkData
& rMark
= rViewData
.GetMarkData();
448 ScSplitPos eWhich
= rViewData
.GetActivePart();
449 EditView
* pEditView
= nullptr;
450 bool bIsEditMode
= rViewData
.HasEditView(eWhich
);
452 if (!rDoc
.IsUndoEnabled())
454 if (bIsEditMode
) // edit mode active
456 rViewData
.GetEditView(eWhich
, pEditView
, nCol
, nRow
);
457 ScModule::get()->InputEnterHandler();
461 nCol
= rViewData
.GetCurX();
462 nRow
= rViewData
.GetCurY();
464 AlignToCursor( nCol
, nRow
, SC_FOLLOW_JUMP
);
466 nTab
= rViewData
.GetTabNo();
469 bool bMarked
= rMark
.IsMultiMarked();
472 ScEditableTester
aTester( rDoc
, rMark
);
473 if (!aTester
.IsEditable())
475 ErrorMessage(aTester
.GetMessageId());
480 ScDocumentUniquePtr pUndoDoc
;
481 ScDocumentUniquePtr pRedoDoc
;
484 pUndoDoc
.reset( new ScDocument( SCDOCMODE_UNDO
) );
485 pUndoDoc
->InitUndo( rDoc
, nTab
, nTab
);
486 pRedoDoc
.reset( new ScDocument( SCDOCMODE_UNDO
) );
487 pRedoDoc
->InitUndo( rDoc
, nTab
, nTab
);
489 if ( rMark
.GetSelectCount() > 1 )
491 for (const auto& rTab
: rMark
)
494 pUndoDoc
->AddUndoTab( rTab
, rTab
);
495 pRedoDoc
->AddUndoTab( rTab
, rTab
);
500 // from here no return
502 bool bOldEnabled
= rDoc
.IsIdleEnabled();
503 rDoc
.EnableIdle(false); // stop online spelling
505 // *** create and init the edit engine *** --------------------------------
507 std::unique_ptr
<ScConversionEngineBase
> pEngine
;
508 switch( rConvParam
.GetType() )
510 case SC_CONVERSION_SPELLCHECK
:
511 pEngine
.reset(new ScSpellingEngine(
512 rDoc
.GetEnginePool(), rViewData
, pUndoDoc
.get(), pRedoDoc
.get(), LinguMgr::GetSpellChecker() ));
514 case SC_CONVERSION_HANGULHANJA
:
515 case SC_CONVERSION_CHINESE_TRANSL
:
516 pEngine
.reset(new ScTextConversionEngine(
517 rDoc
.GetEnginePool(), rViewData
, rConvParam
, pUndoDoc
.get(), pRedoDoc
.get() ));
521 assert(pEngine
&& "all cases result in pEngine set");
523 MakeEditView( pEngine
.get(), nCol
, nRow
);
524 pEngine
->SetRefDevice( rViewData
.GetActiveWin()->GetOutDev() );
525 // simulate dummy cell:
526 pEditView
= rViewData
.GetEditView( rViewData
.GetActivePart() );
527 rViewData
.SetSpellingView( pEditView
);
528 tools::Rectangle
aRect( Point( 0, 0 ), Point( 0, 0 ) );
529 pEditView
->SetOutputArea( aRect
);
530 pEngine
->SetControlWord( EEControlBits::USECHARATTRIBS
);
531 pEngine
->EnableUndo( false );
532 pEngine
->SetPaperSize( aRect
.GetSize() );
533 pEngine
->SetTextCurrentDefaults( OUString() );
535 // *** do the conversion *** ----------------------------------------------
537 pEngine
->ClearModifyFlag();
538 pEngine
->ConvertAll(GetViewData().GetDialogParent(), *pEditView
);
540 // *** undo/redo *** ------------------------------------------------------
542 if( pEngine
->IsAnyModified() )
546 SCCOL nNewCol
= rViewData
.GetCurX();
547 SCROW nNewRow
= rViewData
.GetCurY();
548 rViewData
.GetDocShell()->GetUndoManager()->AddUndoAction(
549 std::make_unique
<ScUndoConversion
>(
551 nCol
, nRow
, nTab
, std::move(pUndoDoc
),
552 nNewCol
, nNewRow
, nTab
, std::move(pRedoDoc
), rConvParam
) );
555 sc::SetFormulaDirtyContext aCxt
;
556 rDoc
.SetAllFormulasDirty(aCxt
);
558 pDocSh
->SetDocumentModified();
566 // *** final cleanup *** --------------------------------------------------
568 rViewData
.SetSpellingView( nullptr );
571 pDocSh
->PostPaintGridAll();
572 rViewData
.GetViewShell()->UpdateInputHandler();
573 rDoc
.EnableIdle(bOldEnabled
);
576 // past from SotClipboardFormatId::FILE items
577 // is not called directly from Drop, but asynchronously -> dialogs are allowed
579 bool ScViewFunc::PasteFile( const Point
& rPos
, const OUString
& rFile
, bool bLink
)
582 aURL
.SetSmartURL( rFile
);
583 OUString aStrURL
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
585 // is it a media URL?
586 #if HAVE_FEATURE_AVMEDIA
587 if( ::avmedia::MediaWindow::isMediaURL( aStrURL
, u
""_ustr
/*TODO?*/ ) )
589 const SfxStringItem
aMediaURLItem( SID_INSERT_AVMEDIA
, aStrURL
);
590 const SfxPoolItemHolder
aResult(GetViewData().GetDispatcher().ExecuteList(
591 SID_INSERT_AVMEDIA
, SfxCallMode::SYNCHRON
,
592 { &aMediaURLItem
}));
597 if (!bLink
) // for bLink only graphics or URL
599 // 1. can I open the file?
600 std::shared_ptr
<const SfxFilter
> pFlt
;
602 // search only for its own filters, without selection box (as in ScDocumentLoader)
603 SfxFilterMatcher
aMatcher( ScDocShell::Factory().GetFilterContainer()->GetName() );
604 SfxMedium
aSfxMedium( aStrURL
, (StreamMode::READ
| StreamMode::SHARE_DENYNONE
) );
605 // #i73992# GuessFilter no longer calls UseInteractionHandler.
606 // This is UI, so it can be called here.
607 aSfxMedium
.UseInteractionHandler(true);
608 ErrCode nErr
= aMatcher
.GuessFilter( aSfxMedium
, pFlt
);
612 // code stolen from the SFX!
613 SfxDispatcher
&rDispatcher
= GetViewData().GetDispatcher();
614 SfxStringItem
aFileNameItem( SID_FILE_NAME
, aStrURL
);
615 SfxStringItem
aFilterItem( SID_FILTER_NAME
, pFlt
->GetName() );
616 // #i69524# add target, as in SfxApplication when the Open dialog is used
617 SfxStringItem
aTargetItem( SID_TARGETNAME
, u
"_default"_ustr
);
619 // Open Asynchronously, because it can also happen from D&D
620 // and that is not so good for the MAC...
621 const SfxPoolItemHolder
aResult(rDispatcher
.ExecuteList(SID_OPENDOC
,
622 SfxCallMode::ASYNCHRON
,
623 { &aFileNameItem
, &aFilterItem
, &aTargetItem
}));
628 // 2. can the file be inserted using the graphics filter?
629 // (as a link, since the Gallery provides it in this way)
632 GraphicFilter
& rGraphicFilter
= GraphicFilter::GetGraphicFilter();
634 if (!rGraphicFilter
.ImportGraphic(aGraphic
, aURL
,
635 GRFILTER_FORMAT_DONTKNOW
))
639 return PasteGraphic( rPos
, aGraphic
, aStrURL
);
643 // #i76709# if bLink isn't set, pass empty URL/filter, so a non-linked image is inserted
644 return PasteGraphic( rPos
, aGraphic
, OUString() );
648 if (bLink
) // for bLink everything, which is not graphics, as URL
650 tools::Rectangle
aRect( rPos
, Size(0,0) );
651 ScRange aRange
= GetViewData().GetDocument().
652 GetRange( GetViewData().GetTabNo(), aRect
);
653 SCCOL nPosX
= aRange
.aStart
.Col();
654 SCROW nPosY
= aRange
.aStart
.Row();
656 InsertBookmark( aStrURL
, aStrURL
, nPosX
, nPosY
);
661 // 3. can the file be inserted as OLE?
662 // also non-storages, for instance sounds (#38282#)
663 uno::Reference
< embed::XStorage
> xStorage
= comphelper::OStorageHelper::GetTemporaryStorage();
665 //TODO/LATER: what about "bLink"?
667 uno::Sequence
< beans::PropertyValue
> aMedium
{ comphelper::makePropertyValue(u
"URL"_ustr
,
670 comphelper::EmbeddedObjectContainer
aCnt( xStorage
);
672 uno::Reference
< embed::XEmbeddedObject
> xObj
= aCnt
.InsertEmbeddedObject( aMedium
, aName
);
674 return PasteObject( rPos
, xObj
, nullptr );
676 // If an OLE object can't be created, insert a URL button
678 GetViewData().GetViewShell()->InsertURLButton( aStrURL
, aStrURL
, OUString(), &rPos
);
683 bool ScViewFunc::PasteBookmark( SotClipboardFormatId nFormatId
,
684 const css::uno::Reference
< css::datatransfer::XTransferable
>& rxTransferable
,
685 SCCOL nPosX
, SCROW nPosY
)
687 INetBookmark aBookmark
;
688 TransferableDataHelper
aDataHelper( rxTransferable
);
689 if ( !aDataHelper
.GetINetBookmark( nFormatId
, aBookmark
) )
692 InsertBookmark( aBookmark
.GetDescription(), aBookmark
.GetURL(), nPosX
, nPosY
);
696 void ScViewFunc::InsertBookmark( const OUString
& rDescription
, const OUString
& rURL
,
697 SCCOL nPosX
, SCROW nPosY
, const OUString
* pTarget
,
700 ScViewData
& rViewData
= GetViewData();
701 if ( rViewData
.HasEditView( rViewData
.GetActivePart() ) &&
702 nPosX
>= rViewData
.GetEditStartCol() && nPosX
<= rViewData
.GetEditEndCol() &&
703 nPosY
>= rViewData
.GetEditStartRow() && nPosY
<= rViewData
.GetEditEndRow() )
705 // insert into the cell which just got edited
707 OUString aTargetFrame
;
709 aTargetFrame
= *pTarget
;
710 rViewData
.GetViewShell()->InsertURLField( rDescription
, rURL
, aTargetFrame
);
714 // insert into not edited cell
716 ScDocument
& rDoc
= GetViewData().GetDocument();
717 SCTAB nTab
= GetViewData().GetTabNo();
718 ScAddress
aCellPos( nPosX
, nPosY
, nTab
);
719 EditEngine
aEngine( rDoc
.GetEnginePool() );
721 const EditTextObject
* pOld
= rDoc
.GetEditText(aCellPos
);
723 aEngine
.SetText(*pOld
);
726 OUString aOld
= rDoc
.GetInputString(nPosX
, nPosY
, nTab
);
728 aEngine
.SetText(aOld
);
731 ESelection
aInsSel(ESelection::AtEnd());
733 if ( bTryReplace
&& HasBookmarkAtCursor( nullptr ) )
735 // if called from hyperlink slot and cell contains only a URL,
736 // replace old URL with new one
738 aInsSel
= ESelection( 0, 0, 0, 1 ); // replace first character (field)
741 SvxURLField
aField( rURL
, rDescription
, SvxURLFormat::AppDefault
);
743 aField
.SetTargetFrame(*pTarget
);
744 aEngine
.QuickInsertField( SvxFieldItem( aField
, EE_FEATURE_FIELD
), aInsSel
);
746 std::unique_ptr
<EditTextObject
> pData(aEngine
.CreateTextObject());
747 EnterData(nPosX
, nPosY
, nTab
, *pData
);
750 bool ScViewFunc::HasBookmarkAtCursor( SvxHyperlinkItem
* pContent
)
752 ScAddress
aPos( GetViewData().GetCurX(), GetViewData().GetCurY(), GetViewData().GetTabNo() );
753 ScDocument
& rDoc
= GetViewData().GetDocShell()->GetDocument();
755 const EditTextObject
* pData
= rDoc
.GetEditText(aPos
);
759 if (!pData
->IsFieldObject())
760 // not a field object.
763 const SvxFieldItem
* pFieldItem
= pData
->GetField();
765 // doesn't have a field item.
768 const SvxFieldData
* pField
= pFieldItem
->GetField();
770 // doesn't have a field item data.
773 if (pField
->GetClassId() != css::text::textfield::Type::URL
)
779 const SvxURLField
* pURLField
= static_cast<const SvxURLField
*>(pField
);
780 pContent
->SetName( pURLField
->GetRepresentation() );
781 pContent
->SetURL( pURLField
->GetURL() );
782 pContent
->SetTargetFrame( pURLField
->GetTargetFrame() );
787 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */