Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / ui / view / viewfun4.cxx
blobc46cbd578ab560700eb4873097e5e4e97410a92b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 "scitems.hxx"
21 #include <editeng/eeitem.hxx>
23 #include <editeng/editobj.hxx>
24 #include <editeng/editstat.hxx>
25 #include <editeng/editview.hxx>
26 #include <editeng/flditem.hxx>
27 #include <sot/storage.hxx>
28 #include <svx/hlnkitem.hxx>
29 #include <editeng/langitem.hxx>
30 #include <svx/svxerr.hxx>
31 #include <editeng/unolingu.hxx>
33 #include <sfx2/bindings.hxx>
34 #include <sfx2/dispatch.hxx>
35 #include <sfx2/docfile.hxx>
36 #include <sfx2/fcontnr.hxx>
37 #include <svtools/langtab.hxx>
38 #include <vcl/graphicfilter.hxx>
39 #include <svl/stritem.hxx>
40 #include <svtools/transfer.hxx>
41 #include <svl/urlbmk.hxx>
42 #include <svl/sharedstringpool.hxx>
43 #include <vcl/msgbox.hxx>
44 #include <avmedia/mediawindow.hxx>
46 #include <comphelper/storagehelper.hxx>
47 #include <comphelper/processfactory.hxx>
49 #include "viewfunc.hxx"
50 #include "docsh.hxx"
51 #include "document.hxx"
52 #include "docpool.hxx"
53 #include "globstr.hrc"
54 #include "global.hxx"
55 #include "undoblk.hxx"
56 #include "undocell.hxx"
57 #include "formulacell.hxx"
58 #include "scmod.hxx"
59 #include "spelleng.hxx"
60 #include "patattr.hxx"
61 #include "sc.hrc"
62 #include "tabvwsh.hxx"
63 #include "impex.hxx"
64 #include "editutil.hxx"
65 #include "editable.hxx"
66 #include "dociter.hxx"
67 #include "reffind.hxx"
68 #include "compiler.hxx"
69 #include "tokenarray.hxx"
70 #include <refupdatecontext.hxx>
71 #include <gridwin.hxx>
73 using namespace com::sun::star;
75 bool bPasteIsDrop = false;
77 void ScViewFunc::PasteRTF( SCCOL nStartCol, SCROW nStartRow,
78 const css::uno::Reference< css::datatransfer::XTransferable >& rxTransferable )
80 TransferableDataHelper aDataHelper( rxTransferable );
81 if ( aDataHelper.HasFormat( SotClipboardFormatId::EDITENGINE ) )
83 HideAllCursors();
85 ScDocShell* pDocSh = GetViewData().GetDocShell();
86 ScDocument& rDoc = pDocSh->GetDocument();
87 SCTAB nTab = GetViewData().GetTabNo();
88 const bool bRecord (rDoc.IsUndoEnabled());
90 const ScPatternAttr* pPattern = rDoc.GetPattern( nStartCol, nStartRow, nTab );
91 std::unique_ptr<ScTabEditEngine> pEngine(new ScTabEditEngine( *pPattern, rDoc.GetEnginePool() ));
92 pEngine->EnableUndo( false );
94 vcl::Window* pActWin = GetActiveWin();
95 if (pActWin)
97 pEngine->SetPaperSize(Size(100000,100000));
98 ScopedVclPtrInstance< vcl::Window > aWin( pActWin );
99 EditView aEditView( pEngine.get(), aWin.get() );
100 aEditView.SetOutputArea(Rectangle(0,0,100000,100000));
102 // same method now for clipboard or drag&drop
103 // mba: clipboard always must contain absolute URLs (could be from alien source)
104 aEditView.InsertText( rxTransferable, OUString(), true );
107 sal_Int32 nParCnt = pEngine->GetParagraphCount();
108 if (nParCnt)
110 SCROW nEndRow = nStartRow + static_cast<SCROW>(nParCnt) - 1;
111 if (nEndRow > MAXROW)
112 nEndRow = MAXROW;
114 ScDocument* pUndoDoc = nullptr;
115 if (bRecord)
117 pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
118 pUndoDoc->InitUndo( &rDoc, nTab, nTab );
119 rDoc.CopyToDocument( nStartCol,nStartRow,nTab, nStartCol,nEndRow,nTab, InsertDeleteFlags::ALL, false, pUndoDoc );
122 SCROW nRow = nStartRow;
124 // Temporarily turn off undo generation for this lot
125 bool bUndoEnabled = rDoc.IsUndoEnabled();
126 rDoc.EnableUndo( false );
127 for( sal_Int32 n = 0; n < nParCnt; n++ )
129 std::unique_ptr<EditTextObject> pObject(pEngine->CreateTextObject(n));
130 EnterData(nStartCol, nRow, nTab, *pObject, true);
131 if( ++nRow > MAXROW )
132 break;
134 rDoc.EnableUndo(bUndoEnabled);
136 if (bRecord)
138 ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
139 pRedoDoc->InitUndo( &rDoc, nTab, nTab );
140 rDoc.CopyToDocument( nStartCol,nStartRow,nTab, nStartCol,nEndRow,nTab, InsertDeleteFlags::ALL|InsertDeleteFlags::NOCAPTIONS, false, pRedoDoc );
142 ScRange aMarkRange(nStartCol, nStartRow, nTab, nStartCol, nEndRow, nTab);
143 ScMarkData aDestMark;
144 aDestMark.SetMarkArea( aMarkRange );
145 pDocSh->GetUndoManager()->AddUndoAction(
146 new ScUndoPaste( pDocSh, aMarkRange, aDestMark,
147 pUndoDoc, pRedoDoc, InsertDeleteFlags::ALL, nullptr));
151 pEngine.reset();
153 ShowAllCursors();
155 else
157 HideAllCursors();
158 ScDocShell* pDocSh = GetViewData().GetDocShell();
159 ScImportExport aImpEx( &pDocSh->GetDocument(),
160 ScAddress( nStartCol, nStartRow, GetViewData().GetTabNo() ) );
162 OUString aStr;
163 tools::SvRef<SotStorageStream> xStream;
164 if ( aDataHelper.GetSotStorageStream( SotClipboardFormatId::RTF, xStream ) && xStream.Is() )
165 // mba: clipboard always must contain absolute URLs (could be from alien source)
166 aImpEx.ImportStream( *xStream, OUString(), SotClipboardFormatId::RTF );
167 else if ( aDataHelper.GetString( SotClipboardFormatId::RTF, aStr ) )
168 aImpEx.ImportString( aStr, SotClipboardFormatId::RTF );
170 AdjustRowHeight( nStartRow, aImpEx.GetRange().aEnd.Row() );
171 pDocSh->UpdateOle(&GetViewData());
172 ShowAllCursors();
175 void ScViewFunc::DoRefConversion()
177 ScDocument* pDoc = GetViewData().GetDocument();
178 ScMarkData& rMark = GetViewData().GetMarkData();
179 SCTAB nTabCount = pDoc->GetTableCount();
180 bool bRecord = true;
181 if (!pDoc->IsUndoEnabled())
182 bRecord = false;
184 ScRange aMarkRange;
185 rMark.MarkToSimple();
186 bool bMulti = rMark.IsMultiMarked();
187 if (bMulti)
188 rMark.GetMultiMarkArea( aMarkRange );
189 else if (rMark.IsMarked())
190 rMark.GetMarkArea( aMarkRange );
191 else
193 aMarkRange = ScRange( GetViewData().GetCurX(),
194 GetViewData().GetCurY(), GetViewData().GetTabNo() );
196 ScEditableTester aTester( pDoc, aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
197 aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(),rMark );
198 if (!aTester.IsEditable())
200 ErrorMessage(aTester.GetMessageId());
201 return;
204 ScDocShell* pDocSh = GetViewData().GetDocShell();
205 bool bOk = false;
207 ScDocument* pUndoDoc = nullptr;
208 if (bRecord)
210 pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
211 SCTAB nTab = aMarkRange.aStart.Tab();
212 pUndoDoc->InitUndo( pDoc, nTab, nTab );
214 if ( rMark.GetSelectCount() > 1 )
216 ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
217 for (; itr != itrEnd; ++itr)
218 if ( *itr != nTab )
219 pUndoDoc->AddUndoTab( *itr, *itr );
221 ScRange aCopyRange = aMarkRange;
222 aCopyRange.aStart.SetTab(0);
223 aCopyRange.aEnd.SetTab(nTabCount-1);
224 pDoc->CopyToDocument( aCopyRange, InsertDeleteFlags::ALL, bMulti, pUndoDoc, &rMark );
227 ScRangeListRef xRanges;
228 GetViewData().GetMultiArea( xRanges );
229 size_t nCount = xRanges->size();
231 ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
232 for (; itr != itrEnd; ++itr)
234 SCTAB i = *itr;
235 for (size_t j = 0; j < nCount; ++j)
237 ScRange aRange = *(*xRanges)[j];
238 aRange.aStart.SetTab(i);
239 aRange.aEnd.SetTab(i);
240 ScCellIterator aIter( pDoc, aRange );
241 for (bool bHas = aIter.first(); bHas; bHas = aIter.next())
243 if (aIter.getType() != CELLTYPE_FORMULA)
244 continue;
246 ScFormulaCell* pCell = aIter.getFormulaCell();
247 OUString aOld;
248 pCell->GetFormula(aOld);
249 sal_Int32 nLen = aOld.getLength();
250 ScRefFinder aFinder( aOld, aIter.GetPos(), pDoc, pDoc->GetAddressConvention() );
251 aFinder.ToggleRel( 0, nLen );
252 if (aFinder.GetFound())
254 ScAddress aPos = pCell->aPos;
255 OUString aNew = aFinder.GetText();
256 ScCompiler aComp( pDoc, aPos);
257 aComp.SetGrammar(pDoc->GetGrammar());
258 std::unique_ptr<ScTokenArray> pArr(aComp.CompileString(aNew));
259 ScFormulaCell* pNewCell =
260 new ScFormulaCell(
261 pDoc, aPos, *pArr, formula::FormulaGrammar::GRAM_DEFAULT, MM_NONE);
263 pDoc->SetFormulaCell(aPos, pNewCell);
264 bOk = true;
269 if (bRecord)
271 ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
272 SCTAB nTab = aMarkRange.aStart.Tab();
273 pRedoDoc->InitUndo( pDoc, nTab, nTab );
275 if ( rMark.GetSelectCount() > 1 )
277 itr = rMark.begin();
278 for (; itr != itrEnd; ++itr)
279 if ( *itr != nTab )
280 pRedoDoc->AddUndoTab( *itr, *itr );
282 ScRange aCopyRange = aMarkRange;
283 aCopyRange.aStart.SetTab(0);
284 aCopyRange.aEnd.SetTab(nTabCount-1);
285 pDoc->CopyToDocument( aCopyRange, InsertDeleteFlags::ALL, bMulti, pRedoDoc, &rMark );
287 pDocSh->GetUndoManager()->AddUndoAction(
288 new ScUndoRefConversion( pDocSh,
289 aMarkRange, rMark, pUndoDoc, pRedoDoc, bMulti, InsertDeleteFlags::ALL) );
292 pDocSh->PostPaint( aMarkRange, PAINT_GRID );
293 pDocSh->UpdateOle(&GetViewData());
294 pDocSh->SetDocumentModified();
295 CellContentChanged();
297 if (!bOk)
298 ErrorMessage(STR_ERR_NOREF);
300 // Thesaurus - Undo ok
301 void ScViewFunc::DoThesaurus()
303 SCCOL nCol;
304 SCROW nRow;
305 SCTAB nTab;
306 ScDocShell* pDocSh = GetViewData().GetDocShell();
307 ScDocument& rDoc = pDocSh->GetDocument();
308 ScMarkData& rMark = GetViewData().GetMarkData();
309 ScSplitPos eWhich = GetViewData().GetActivePart();
310 EESpellState eState;
311 EditView* pEditView = nullptr;
312 std::unique_ptr<ESelection> pEditSel;
313 std::unique_ptr<ScEditEngineDefaulter> pThesaurusEngine;
314 bool bIsEditMode = GetViewData().HasEditView(eWhich);
315 bool bRecord = true;
316 if (!rDoc.IsUndoEnabled())
317 bRecord = false;
318 if (bIsEditMode) // edit mode active
320 GetViewData().GetEditView(eWhich, pEditView, nCol, nRow);
321 pEditSel.reset(new ESelection(pEditView->GetSelection()));
322 SC_MOD()->InputEnterHandler();
323 GetViewData().GetBindings().Update(); // otherwise the Sfx becomes mixed-up...
325 else
327 nCol = GetViewData().GetCurX();
328 nRow = GetViewData().GetCurY();
330 nTab = GetViewData().GetTabNo();
332 ScAddress aPos(nCol, nRow, nTab);
333 ScEditableTester aTester( &rDoc, nCol, nRow, nCol, nRow, rMark );
334 if (!aTester.IsEditable())
336 ErrorMessage(aTester.GetMessageId());
337 return;
340 ScCellValue aOldText;
341 aOldText.assign(rDoc, aPos);
342 if (aOldText.meType != CELLTYPE_STRING && aOldText.meType != CELLTYPE_EDIT)
344 ErrorMessage(STR_THESAURUS_NO_STRING);
345 return;
348 uno::Reference<linguistic2::XSpellChecker1> xSpeller = LinguMgr::GetSpellChecker();
350 pThesaurusEngine.reset(new ScEditEngineDefaulter(rDoc.GetEnginePool()));
351 pThesaurusEngine->SetEditTextObjectPool( rDoc.GetEditPool() );
352 pThesaurusEngine->SetRefDevice(GetViewData().GetActiveWin());
353 pThesaurusEngine->SetSpeller(xSpeller);
354 MakeEditView(pThesaurusEngine.get(), nCol, nRow );
355 const ScPatternAttr* pPattern = nullptr;
356 std::unique_ptr<SfxItemSet> pEditDefaults(
357 new SfxItemSet(pThesaurusEngine->GetEmptyItemSet()));
358 pPattern = rDoc.GetPattern(nCol, nRow, nTab);
359 if (pPattern)
361 pPattern->FillEditItemSet( pEditDefaults.get() );
362 pThesaurusEngine->SetDefaults( *pEditDefaults );
365 if (aOldText.meType == CELLTYPE_EDIT)
366 pThesaurusEngine->SetText(*aOldText.mpEditText);
367 else
368 pThesaurusEngine->SetText(aOldText.getString(&rDoc));
370 pEditView = GetViewData().GetEditView(GetViewData().GetActivePart());
371 if (pEditSel)
372 pEditView->SetSelection(*pEditSel);
373 else
374 pEditView->SetSelection(ESelection(0,0,0,0));
376 pThesaurusEngine->ClearModifyFlag();
378 // language is now in EditEngine attributes -> no longer passed to StartThesaurus
380 eState = pEditView->StartThesaurus();
381 OSL_ENSURE(eState != EE_SPELL_NOSPELLER, "No SpellChecker");
383 if (eState == EE_SPELL_ERRORFOUND) // should happen later through Wrapper!
385 LanguageType eLnge = ScViewUtil::GetEffLanguage( &rDoc, ScAddress( nCol, nRow, nTab ) );
386 OUString aErr = SvtLanguageTable::GetLanguageString(eLnge);
387 aErr += ScGlobal::GetRscString( STR_SPELLING_NO_LANG );
388 ScopedVclPtrInstance< InfoBox > aBox( GetViewData().GetDialogParent(), aErr );
389 aBox->Execute();
391 if (pThesaurusEngine->IsModified())
393 ScCellValue aNewText;
395 if (aOldText.meType == CELLTYPE_EDIT)
397 // The cell will own the text object instance.
398 EditTextObject* pText = pThesaurusEngine->CreateTextObject();
399 if (rDoc.SetEditText(ScAddress(nCol,nRow,nTab), pText))
400 aNewText.set(*pText);
402 else
404 OUString aStr = pThesaurusEngine->GetText();
405 aNewText.set(rDoc.GetSharedStringPool().intern(aStr));
406 rDoc.SetString(nCol, nRow, nTab, aStr);
409 pDocSh->SetDocumentModified();
410 if (bRecord)
412 GetViewData().GetDocShell()->GetUndoManager()->AddUndoAction(
413 new ScUndoThesaurus(
414 GetViewData().GetDocShell(), nCol, nRow, nTab, aOldText, aNewText));
418 KillEditView(true);
419 pDocSh->PostPaintGridAll();
422 void ScViewFunc::DoHangulHanjaConversion()
424 ScConversionParam aConvParam( SC_CONVERSION_HANGULHANJA, LANGUAGE_KOREAN, 0, true );
425 DoSheetConversion( aConvParam );
428 void ScViewFunc::DoSheetConversion( const ScConversionParam& rConvParam )
430 SCCOL nCol;
431 SCROW nRow;
432 SCTAB nTab;
433 ScViewData& rViewData = GetViewData();
434 ScDocShell* pDocSh = rViewData.GetDocShell();
435 ScDocument& rDoc = pDocSh->GetDocument();
436 ScMarkData& rMark = rViewData.GetMarkData();
437 ScSplitPos eWhich = rViewData.GetActivePart();
438 EditView* pEditView = nullptr;
439 bool bIsEditMode = rViewData.HasEditView(eWhich);
440 bool bRecord = true;
441 if (!rDoc.IsUndoEnabled())
442 bRecord = false;
443 if (bIsEditMode) // edit mode active
445 rViewData.GetEditView(eWhich, pEditView, nCol, nRow);
446 SC_MOD()->InputEnterHandler();
448 else
450 nCol = rViewData.GetCurX();
451 nRow = rViewData.GetCurY();
453 AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP);
455 nTab = rViewData.GetTabNo();
457 rMark.MarkToMulti();
458 bool bMarked = rMark.IsMultiMarked();
459 if (bMarked)
461 ScEditableTester aTester( &rDoc, rMark );
462 if (!aTester.IsEditable())
464 ErrorMessage(aTester.GetMessageId());
465 return;
469 ScDocument* pUndoDoc = nullptr;
470 ScDocument* pRedoDoc = nullptr;
471 if (bRecord)
473 pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
474 pUndoDoc->InitUndo( &rDoc, nTab, nTab );
475 pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
476 pRedoDoc->InitUndo( &rDoc, nTab, nTab );
478 if ( rMark.GetSelectCount() > 1 )
480 ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
481 for (; itr != itrEnd; ++itr)
482 if ( *itr != nTab )
484 pUndoDoc->AddUndoTab( *itr, *itr );
485 pRedoDoc->AddUndoTab( *itr, *itr );
490 // from here no return
492 bool bOldEnabled = rDoc.IsIdleEnabled();
493 rDoc.EnableIdle(false); // stop online spelling
495 // *** create and init the edit engine *** --------------------------------
497 std::unique_ptr<ScConversionEngineBase> pEngine;
498 switch( rConvParam.GetType() )
500 case SC_CONVERSION_SPELLCHECK:
501 pEngine.reset(new ScSpellingEngine(
502 rDoc.GetEnginePool(), rViewData, pUndoDoc, pRedoDoc, LinguMgr::GetSpellChecker() ));
503 break;
504 case SC_CONVERSION_HANGULHANJA:
505 case SC_CONVERSION_CHINESE_TRANSL:
506 pEngine.reset(new ScTextConversionEngine(
507 rDoc.GetEnginePool(), rViewData, rConvParam, pUndoDoc, pRedoDoc ));
508 break;
509 default:
510 OSL_FAIL( "ScViewFunc::DoSheetConversion - unknown conversion type" );
513 MakeEditView( pEngine.get(), nCol, nRow );
514 pEngine->SetRefDevice( rViewData.GetActiveWin() );
515 // simulate dummy cell:
516 pEditView = rViewData.GetEditView( rViewData.GetActivePart() );
517 rViewData.SetSpellingView( pEditView );
518 Rectangle aRect( Point( 0, 0 ), Point( 0, 0 ) );
519 pEditView->SetOutputArea( aRect );
520 pEngine->SetControlWord( EEControlBits::USECHARATTRIBS );
521 pEngine->EnableUndo( false );
522 pEngine->SetPaperSize( aRect.GetSize() );
523 pEngine->SetText( EMPTY_OUSTRING );
525 // *** do the conversion *** ----------------------------------------------
527 pEngine->ClearModifyFlag();
528 pEngine->ConvertAll( *pEditView );
530 // *** undo/redo *** ------------------------------------------------------
532 if( pEngine->IsAnyModified() )
534 if (bRecord)
536 SCCOL nNewCol = rViewData.GetCurX();
537 SCROW nNewRow = rViewData.GetCurY();
538 rViewData.GetDocShell()->GetUndoManager()->AddUndoAction(
539 new ScUndoConversion(
540 pDocSh, rMark,
541 nCol, nRow, nTab, pUndoDoc,
542 nNewCol, nNewRow, nTab, pRedoDoc, rConvParam ) );
545 sc::SetFormulaDirtyContext aCxt;
546 rDoc.SetAllFormulasDirty(aCxt);
548 pDocSh->SetDocumentModified();
550 else
552 delete pUndoDoc;
553 delete pRedoDoc;
556 // *** final cleanup *** --------------------------------------------------
558 rViewData.SetSpellingView( nullptr );
559 KillEditView(true);
560 pEngine.reset();
561 pDocSh->PostPaintGridAll();
562 rViewData.GetViewShell()->UpdateInputHandler();
563 rDoc.EnableIdle(bOldEnabled);
566 // past from SotClipboardFormatId::FILE items
567 // is not called directly from Drop, but asynchronously -> dialogs are allowed
569 bool ScViewFunc::PasteFile( const Point& rPos, const OUString& rFile, bool bLink )
571 INetURLObject aURL;
572 aURL.SetSmartURL( rFile );
573 OUString aStrURL = aURL.GetMainURL( INetURLObject::NO_DECODE );
575 // is it a media URL?
576 if( ::avmedia::MediaWindow::isMediaURL( aStrURL, ""/*TODO?*/ ) )
578 const SfxStringItem aMediaURLItem( SID_INSERT_AVMEDIA, aStrURL );
579 return ( nullptr != GetViewData().GetDispatcher().ExecuteList(
580 SID_INSERT_AVMEDIA, SfxCallMode::SYNCHRON,
581 { &aMediaURLItem }) );
584 if (!bLink) // for bLink only graphics or URL
586 // 1. can I open the file?
587 std::shared_ptr<const SfxFilter> pFlt;
589 // search only for its own filters, without selection box (as in ScDocumentLoader)
590 SfxFilterMatcher aMatcher( ScDocShell::Factory().GetFilterContainer()->GetName() );
591 SfxMedium aSfxMedium( aStrURL, (StreamMode::READ | StreamMode::SHARE_DENYNONE) );
592 // #i73992# GuessFilter no longer calls UseInteractionHandler.
593 // This is UI, so it can be called here.
594 aSfxMedium.UseInteractionHandler(true);
595 ErrCode nErr = aMatcher.GuessFilter( aSfxMedium, pFlt );
597 if ( pFlt && !nErr )
599 // code stolen from the SFX!
600 SfxDispatcher &rDispatcher = GetViewData().GetDispatcher();
601 SfxStringItem aFileNameItem( SID_FILE_NAME, aStrURL );
602 SfxStringItem aFilterItem( SID_FILTER_NAME, pFlt->GetName() );
603 // #i69524# add target, as in SfxApplication when the Open dialog is used
604 SfxStringItem aTargetItem( SID_TARGETNAME, OUString("_default") );
606 // Open Asynchronously, because it can also happen from D&D
607 // and that is not so good for the MAC...
608 return (nullptr != rDispatcher.ExecuteList(SID_OPENDOC,
609 SfxCallMode::ASYNCHRON,
610 { &aFileNameItem, &aFilterItem, &aTargetItem}));
614 // 2. can the file be inserted using the graphics filter?
615 // (as a link, since the Gallery provides it in this way)
617 sal_uInt16 nFilterFormat;
618 Graphic aGraphic;
619 GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
621 if (!rGraphicFilter.ImportGraphic(aGraphic, aURL,
622 GRFILTER_FORMAT_DONTKNOW, &nFilterFormat ))
624 if ( bLink )
626 OUString aFltName = rGraphicFilter.GetImportFormatName(nFilterFormat);
627 return PasteGraphic( rPos, aGraphic, aStrURL, aFltName );
629 else
631 // #i76709# if bLink isn't set, pass empty URL/filter, so a non-linked image is inserted
632 return PasteGraphic( rPos, aGraphic, EMPTY_OUSTRING, EMPTY_OUSTRING );
636 if (bLink) // for bLink everything, which is not graphics, as URL
638 Rectangle aRect( rPos, Size(0,0) );
639 ScRange aRange = GetViewData().GetDocument()->
640 GetRange( GetViewData().GetTabNo(), aRect );
641 SCCOL nPosX = aRange.aStart.Col();
642 SCROW nPosY = aRange.aStart.Row();
644 InsertBookmark( aStrURL, aStrURL, nPosX, nPosY );
645 return true;
647 else
649 // 3. can the file be inserted as OLE?
650 // also non-storages, for instance sounds (#38282#)
651 uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
653 //TODO/LATER: what about "bLink"?
655 uno::Sequence < beans::PropertyValue > aMedium(1);
656 aMedium[0].Name = "URL";
657 aMedium[0].Value <<= OUString( aStrURL );
659 comphelper::EmbeddedObjectContainer aCnt( xStorage );
660 OUString aName;
661 uno::Reference < embed::XEmbeddedObject > xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
662 if( xObj.is() )
663 return PasteObject( rPos, xObj );
665 // If an OLE object can't be created, insert a URL button
667 GetViewData().GetViewShell()->InsertURLButton( aStrURL, aStrURL, EMPTY_OUSTRING, &rPos );
668 return true;
672 bool ScViewFunc::PasteBookmark( SotClipboardFormatId nFormatId,
673 const css::uno::Reference< css::datatransfer::XTransferable >& rxTransferable,
674 SCCOL nPosX, SCROW nPosY )
676 INetBookmark aBookmark;
677 TransferableDataHelper aDataHelper( rxTransferable );
678 if ( !aDataHelper.GetINetBookmark( nFormatId, aBookmark ) )
679 return false;
681 InsertBookmark( aBookmark.GetDescription(), aBookmark.GetURL(), nPosX, nPosY );
682 return true;
685 void ScViewFunc::InsertBookmark( const OUString& rDescription, const OUString& rURL,
686 SCCOL nPosX, SCROW nPosY, const OUString* pTarget,
687 bool bTryReplace )
689 ScViewData& rViewData = GetViewData();
690 if ( rViewData.HasEditView( rViewData.GetActivePart() ) &&
691 nPosX >= rViewData.GetEditStartCol() && nPosX <= rViewData.GetEditEndCol() &&
692 nPosY >= rViewData.GetEditStartRow() && nPosY <= rViewData.GetEditEndRow() )
694 // insert into the cell which just got edited
696 OUString aTargetFrame;
697 if (pTarget)
698 aTargetFrame = *pTarget;
699 rViewData.GetViewShell()->InsertURLField( rDescription, rURL, aTargetFrame );
700 return;
703 // insert into not edited cell
705 ScDocument* pDoc = GetViewData().GetDocument();
706 SCTAB nTab = GetViewData().GetTabNo();
707 ScAddress aCellPos( nPosX, nPosY, nTab );
708 EditEngine aEngine( pDoc->GetEnginePool() );
710 const EditTextObject* pOld = pDoc->GetEditText(aCellPos);
711 if (pOld)
712 aEngine.SetText(*pOld);
713 else
715 OUString aOld;
716 pDoc->GetInputString(nPosX, nPosY, nTab, aOld);
717 if (!aOld.isEmpty())
718 aEngine.SetText(aOld);
721 sal_Int32 nPara = aEngine.GetParagraphCount();
722 if (nPara)
723 --nPara;
724 sal_Int32 nTxtLen = aEngine.GetTextLen(nPara);
725 ESelection aInsSel( nPara, nTxtLen, nPara, nTxtLen );
727 if ( bTryReplace && HasBookmarkAtCursor( nullptr ) )
729 // if called from hyperlink slot and cell contains only a URL,
730 // replace old URL with new one
732 aInsSel = ESelection( 0, 0, 0, 1 ); // replace first character (field)
735 SvxURLField aField( rURL, rDescription, SVXURLFORMAT_APPDEFAULT );
736 if (pTarget)
737 aField.SetTargetFrame(*pTarget);
738 aEngine.QuickInsertField( SvxFieldItem( aField, EE_FEATURE_FIELD ), aInsSel );
740 std::unique_ptr<EditTextObject> pData(aEngine.CreateTextObject());
741 EnterData(nPosX, nPosY, nTab, *pData);
744 bool ScViewFunc::HasBookmarkAtCursor( SvxHyperlinkItem* pContent )
746 ScAddress aPos( GetViewData().GetCurX(), GetViewData().GetCurY(), GetViewData().GetTabNo() );
747 ScDocument& rDoc = GetViewData().GetDocShell()->GetDocument();
749 const EditTextObject* pData = rDoc.GetEditText(aPos);
750 if (!pData)
751 return false;
753 if (!pData->IsFieldObject())
754 // not a field object.
755 return false;
757 const SvxFieldItem* pFieldItem = pData->GetField();
758 if (!pFieldItem)
759 // doesn't have a field item.
760 return false;
762 const SvxFieldData* pField = pFieldItem->GetField();
763 if (!pField)
764 // doesn't have a field item data.
765 return false;
767 if (pField->GetClassId() != css::text::textfield::Type::URL)
768 // not a URL field.
769 return false;
771 if (pContent)
773 const SvxURLField* pURLField = static_cast<const SvxURLField*>(pField);
774 pContent->SetName( pURLField->GetRepresentation() );
775 pContent->SetURL( pURLField->GetURL() );
776 pContent->SetTargetFrame( pURLField->GetTargetFrame() );
778 return true;
781 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */