blob: 6b6b61d2f2d332b07e1a76d3232ab384624241b9 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
// INCLUDE ---------------------------------------------------------------
#include "scitems.hxx"
#include <editeng/eeitem.hxx>
#include <editeng/editobj.hxx>
#include <editeng/editstat.hxx>
#include <editeng/editview.hxx>
#include <editeng/flditem.hxx>
#include <svx/hlnkitem.hxx>
#include <editeng/langitem.hxx>
#include <svx/svxerr.hxx>
#include <editeng/unolingu.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/fcontnr.hxx>
#include <svtools/langtab.hxx>
#include <svtools/filter.hxx>
#include <svl/stritem.hxx>
#include <svtools/transfer.hxx>
#include <svl/urlbmk.hxx>
#include <vcl/msgbox.hxx>
#include <avmedia/mediawindow.hxx>
#include <comphelper/storagehelper.hxx>
#include <comphelper/processfactory.hxx>
#include "viewfunc.hxx"
#include "docsh.hxx"
#include "docsh.hxx"
#include "document.hxx"
#include "docpool.hxx"
#include "globstr.hrc"
#include "global.hxx"
#include "undoblk.hxx"
#include "undocell.hxx"
#include "cell.hxx"
#include "scmod.hxx"
#include "spelleng.hxx"
#include "patattr.hxx"
#include "sc.hrc"
#include "tabvwsh.hxx"
#include "impex.hxx"
#include "editutil.hxx"
#include "editable.hxx"
#include "dociter.hxx"
#include "reffind.hxx"
#include "compiler.hxx"
using namespace com::sun::star;
// STATIC DATA -----------------------------------------------------------
sal_Bool bPasteIsDrop = sal_False;
//==================================================================
void ScViewFunc::PasteRTF( SCCOL nStartCol, SCROW nStartRow,
const ::com::sun::star::uno::Reference<
::com::sun::star::datatransfer::XTransferable >& rxTransferable )
{
TransferableDataHelper aDataHelper( rxTransferable );
if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EDITENGINE ) )
{
HideAllCursors();
ScDocument* pUndoDoc = NULL;
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
SCTAB nTab = GetViewData()->GetTabNo();
const sal_Bool bRecord (pDoc->IsUndoEnabled());
const ScPatternAttr* pPattern = pDoc->GetPattern( nStartCol, nStartRow, nTab );
ScTabEditEngine* pEngine = new ScTabEditEngine( *pPattern, pDoc->GetEnginePool() );
pEngine->EnableUndo( sal_False );
Window* pActWin = GetActiveWin();
if (pActWin)
{
pEngine->SetPaperSize(Size(100000,100000));
Window aWin( pActWin );
EditView aEditView( pEngine, &aWin );
aEditView.SetOutputArea(Rectangle(0,0,100000,100000));
// same method now for clipboard or drag&drop
// mba: clipboard always must contain absolute URLs (could be from alien source)
aEditView.InsertText( rxTransferable, String(), sal_True );
}
sal_uLong nParCnt = pEngine->GetParagraphCount();
if (nParCnt)
{
SCROW nEndRow = nStartRow + static_cast<SCROW>(nParCnt) - 1;
if (nEndRow > MAXROW)
nEndRow = MAXROW;
if (bRecord)
{
pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
pUndoDoc->InitUndo( pDoc, nTab, nTab );
pDoc->CopyToDocument( nStartCol,nStartRow,nTab, nStartCol,nEndRow,nTab, IDF_ALL, sal_False, pUndoDoc );
}
SCROW nRow = nStartRow;
for( sal_uInt16 n = 0; n < nParCnt; n++ )
{
EditTextObject* pObject = pEngine->CreateTextObject( n );
EnterData( nStartCol, nRow, nTab, pObject, sal_False, sal_True );
// kein Undo, auf einfache Strings testen
delete pObject;
if( ++nRow > MAXROW )
break;
}
if (bRecord)
{
ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
pRedoDoc->InitUndo( pDoc, nTab, nTab );
pDoc->CopyToDocument( nStartCol,nStartRow,nTab, nStartCol,nEndRow,nTab, IDF_ALL|IDF_NOCAPTIONS, sal_False, pRedoDoc );
ScMarkData aDestMark;
aDestMark.SelectOneTable( nTab );
pDocSh->GetUndoManager()->AddUndoAction(
new ScUndoPaste( pDocSh, nStartCol,nStartRow,nTab, nStartCol,nEndRow,nTab,
aDestMark,
pUndoDoc, pRedoDoc, IDF_ALL, NULL,NULL,NULL,NULL ) );
}
}
delete pEngine;
ShowAllCursors();
}
else
{
HideAllCursors();
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScImportExport aImpEx( pDocSh->GetDocument(),
ScAddress( nStartCol, nStartRow, GetViewData()->GetTabNo() ) );
::rtl::OUString aStr;
SotStorageStreamRef xStream;
if ( aDataHelper.GetSotStorageStream( SOT_FORMAT_RTF, xStream ) && xStream.Is() )
// mba: clipboard always must contain absolute URLs (could be from alien source)
aImpEx.ImportStream( *xStream, String(), SOT_FORMAT_RTF );
else if ( aDataHelper.GetString( SOT_FORMAT_RTF, aStr ) )
aImpEx.ImportString( aStr, SOT_FORMAT_RTF );
AdjustRowHeight( nStartRow, aImpEx.GetRange().aEnd.Row() );
pDocSh->UpdateOle(GetViewData());
ShowAllCursors();
}
}
void ScViewFunc::DoRefConversion( sal_Bool bRecord )
{
ScDocument* pDoc = GetViewData()->GetDocument();
ScMarkData& rMark = GetViewData()->GetMarkData();
SCTAB nTabCount = pDoc->GetTableCount();
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = sal_False;
ScRange aMarkRange;
rMark.MarkToSimple();
sal_Bool bMulti = rMark.IsMultiMarked();
if (bMulti)
rMark.GetMultiMarkArea( aMarkRange );
else if (rMark.IsMarked())
rMark.GetMarkArea( aMarkRange );
else
{
aMarkRange = ScRange( GetViewData()->GetCurX(),
GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
}
ScEditableTester aTester( pDoc, aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(),rMark );
if (!aTester.IsEditable())
{
ErrorMessage(aTester.GetMessageId());
return;
}
ScDocShell* pDocSh = GetViewData()->GetDocShell();
sal_Bool bOk = sal_False;
ScDocument* pUndoDoc = NULL;
if (bRecord)
{
pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
SCTAB nTab = aMarkRange.aStart.Tab();
pUndoDoc->InitUndo( pDoc, nTab, nTab );
if ( rMark.GetSelectCount() > 1 )
{
for (SCTAB i=0; i<nTabCount; i++)
if ( rMark.GetTableSelect(i) && i != nTab )
pUndoDoc->AddUndoTab( i, i );
}
ScRange aCopyRange = aMarkRange;
aCopyRange.aStart.SetTab(0);
aCopyRange.aEnd.SetTab(nTabCount-1);
pDoc->CopyToDocument( aCopyRange, IDF_ALL, bMulti, pUndoDoc, &rMark );
}
ScRangeListRef xRanges;
GetViewData()->GetMultiArea( xRanges );
sal_uLong nCount = xRanges->Count();
for (SCTAB i=0; i<nTabCount; i++)
{
if (rMark.GetTableSelect(i))
{
for (sal_uLong j=0; j<nCount; j++)
{
ScRange aRange = *xRanges->GetObject(j);
aRange.aStart.SetTab(i);
aRange.aEnd.SetTab(i);
ScCellIterator aIter( pDoc, aRange );
ScBaseCell* pCell = aIter.GetFirst();
while ( pCell )
{
if (pCell->GetCellType() == CELLTYPE_FORMULA)
{
String aOld;
((ScFormulaCell*)pCell)->GetFormula(aOld);
xub_StrLen nLen = aOld.Len();
ScRefFinder aFinder( aOld, pDoc );
aFinder.ToggleRel( 0, nLen );
if (aFinder.GetFound())
{
ScAddress aPos = ((ScFormulaCell*)pCell)->aPos;
String aNew = aFinder.GetText();
ScCompiler aComp( pDoc, aPos);
aComp.SetGrammar(pDoc->GetGrammar());
ScTokenArray* pArr = aComp.CompileString( aNew );
ScFormulaCell* pNewCell = new ScFormulaCell( pDoc, aPos,
pArr,formula::FormulaGrammar::GRAM_DEFAULT, MM_NONE );
pDoc->PutCell( aPos, pNewCell );
bOk = sal_True;
}
}
pCell = aIter.GetNext();
}
}
}
}
if (bRecord)
{
ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
SCTAB nTab = aMarkRange.aStart.Tab();
pRedoDoc->InitUndo( pDoc, nTab, nTab );
if ( rMark.GetSelectCount() > 1 )
{
for (SCTAB i=0; i<nTabCount; i++)
if ( rMark.GetTableSelect(i) && i != nTab )
pRedoDoc->AddUndoTab( i, i );
}
ScRange aCopyRange = aMarkRange;
aCopyRange.aStart.SetTab(0);
aCopyRange.aEnd.SetTab(nTabCount-1);
pDoc->CopyToDocument( aCopyRange, IDF_ALL, bMulti, pRedoDoc, &rMark );
pDocSh->GetUndoManager()->AddUndoAction(
new ScUndoRefConversion( pDocSh,
aMarkRange, rMark, pUndoDoc, pRedoDoc, bMulti, IDF_ALL) );
}
pDocSh->PostPaint( aMarkRange, PAINT_GRID );
pDocSh->UpdateOle(GetViewData());
pDocSh->SetDocumentModified();
CellContentChanged();
if (!bOk)
ErrorMessage(STR_ERR_NOREF);
}
// Thesaurus - Undo ok
void ScViewFunc::DoThesaurus( sal_Bool bRecord )
{
SCCOL nCol;
SCROW nRow;
SCTAB nTab;
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
ScMarkData& rMark = GetViewData()->GetMarkData();
ScSplitPos eWhich = GetViewData()->GetActivePart();
CellType eCellType;
EESpellState eState;
String sOldText, sNewString;
EditTextObject* pOldTObj = NULL;
const EditTextObject* pTObject = NULL;
ScBaseCell* pCell = NULL;
EditView* pEditView = NULL;
ESelection* pEditSel = NULL;
ScEditEngineDefaulter* pThesaurusEngine;
sal_Bool bIsEditMode = GetViewData()->HasEditView(eWhich);
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = sal_False;
if (bIsEditMode) // Edit-Mode aktiv
{
GetViewData()->GetEditView(eWhich, pEditView, nCol, nRow);
pEditSel = new ESelection(pEditView->GetSelection());
SC_MOD()->InputEnterHandler();
GetViewData()->GetBindings().Update(); // sonst kommt der Sfx durcheinander...
}
else
{
nCol = GetViewData()->GetCurX();
nRow = GetViewData()->GetCurY();
}
nTab = GetViewData()->GetTabNo();
ScEditableTester aTester( pDoc, nCol, nRow, nCol, nRow, rMark );
if (!aTester.IsEditable())
{
ErrorMessage(aTester.GetMessageId());
delete pEditSel;
return;
}
pDoc->GetCellType(nCol, nRow, nTab, eCellType);
if (eCellType != CELLTYPE_STRING && eCellType != CELLTYPE_EDIT)
{
ErrorMessage(STR_THESAURUS_NO_STRING);
return;
}
com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellChecker1>
xSpeller = LinguMgr::GetSpellChecker();
//! if (...) // thesaurus not available
//! {
//! ErrorMessage(STR_EXPORT_ASCII_WARNING);
//! delete pEditSel;
//! return;
//! }
pThesaurusEngine = new ScEditEngineDefaulter( pDoc->GetEnginePool() );
pThesaurusEngine->SetEditTextObjectPool( pDoc->GetEditPool() );
pThesaurusEngine->SetRefDevice(GetViewData()->GetActiveWin());
pThesaurusEngine->SetSpeller(xSpeller);
MakeEditView(pThesaurusEngine, nCol, nRow );
const ScPatternAttr* pPattern = NULL;
SfxItemSet* pEditDefaults = new SfxItemSet(pThesaurusEngine->GetEmptyItemSet());
pPattern = pDoc->GetPattern(nCol, nRow, nTab);
if (pPattern )
{
pPattern->FillEditItemSet( pEditDefaults );
pThesaurusEngine->SetDefaults( *pEditDefaults );
}
if (eCellType == CELLTYPE_STRING)
{
pDoc->GetString(nCol, nRow, nTab, sOldText);
pThesaurusEngine->SetText(sOldText);
}
else if (eCellType == CELLTYPE_EDIT)
{
pDoc->GetCell(nCol, nRow, nTab, pCell);
if (pCell)
{
((ScEditCell*) pCell)->GetData(pTObject);
if (pTObject)
{
pOldTObj = pTObject->Clone();
pThesaurusEngine->SetText(*pTObject);
}
}
}
else
{
DBG_ERROR("DoThesaurus: Keine String oder Editzelle");
}
pEditView = GetViewData()->GetEditView(GetViewData()->GetActivePart());;
if (pEditSel)
pEditView->SetSelection(*pEditSel);
else
pEditView->SetSelection(ESelection(0,0,0,0));
pThesaurusEngine->ClearModifyFlag();
// language is now in EditEngine attributes -> no longer passed to StartThesaurus
eState = pEditView->StartThesaurus();
DBG_ASSERT(eState != EE_SPELL_NOSPELLER, "No SpellChecker");
if (eState == EE_SPELL_ERRORFOUND) // sollte spaeter durch Wrapper geschehen!
{
LanguageType eLnge = ScViewUtil::GetEffLanguage( pDoc, ScAddress( nCol, nRow, nTab ) );
SvtLanguageTable aLangTab;
String aErr = aLangTab.GetString(eLnge);
aErr += ScGlobal::GetRscString( STR_SPELLING_NO_LANG );
InfoBox aBox( GetViewData()->GetDialogParent(), aErr );
aBox.Execute();
}
if (pThesaurusEngine->IsModified())
{
EditTextObject* pNewTObj = NULL;
if (pCell && pTObject)
{
pNewTObj = pThesaurusEngine->CreateTextObject();
pCell = new ScEditCell( pNewTObj, pDoc,
pThesaurusEngine->GetEditTextObjectPool() );
pDoc->PutCell( nCol, nRow, nTab, pCell );
}
else
{
sNewString = pThesaurusEngine->GetText();
pDoc->SetString(nCol, nRow, nTab, sNewString);
}
// erack! it's broadcasted
// pDoc->SetDirty();
pDocSh->SetDocumentModified();
if (bRecord)
{
GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
new ScUndoThesaurus( GetViewData()->GetDocShell(),
nCol, nRow, nTab,
sOldText, pOldTObj, sNewString, pNewTObj));
}
delete pNewTObj;
}
KillEditView(sal_True);
delete pEditDefaults;
delete pThesaurusEngine;
delete pOldTObj;
delete pEditSel;
pDocSh->PostPaintGridAll();
}
//UNUSED2008-05 // Spelling Checker - Undo ok
//UNUSED2008-05 void ScViewFunc::DoSpellingChecker( sal_Bool bRecord )
//UNUSED2008-05 {
//UNUSED2008-05 DoSheetConversion( ScConversionParam( SC_CONVERSION_SPELLCHECK ), bRecord );
//UNUSED2008-05 }
void ScViewFunc::DoHangulHanjaConversion( sal_Bool bRecord )
{
ScConversionParam aConvParam( SC_CONVERSION_HANGULHANJA, LANGUAGE_KOREAN, 0, true );
DoSheetConversion( aConvParam, bRecord );
}
void ScViewFunc::DoSheetConversion( const ScConversionParam& rConvParam, sal_Bool bRecord )
{
SCCOL nCol;
SCROW nRow;
SCTAB nTab;
ScViewData& rViewData = *GetViewData();
ScDocShell* pDocSh = rViewData.GetDocShell();
ScDocument* pDoc = pDocSh->GetDocument();
ScMarkData& rMark = rViewData.GetMarkData();
ScSplitPos eWhich = rViewData.GetActivePart();
EditView* pEditView = NULL;
ESelection* pEditSel = NULL;
sal_Bool bIsEditMode = rViewData.HasEditView(eWhich);
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = sal_False;
if (bIsEditMode) // Edit-Mode aktiv
{
rViewData.GetEditView(eWhich, pEditView, nCol, nRow);
pEditSel = new ESelection(pEditView->GetSelection());
SC_MOD()->InputEnterHandler();
}
else
{
nCol = rViewData.GetCurX();
nRow = rViewData.GetCurY();
AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP);
}
nTab = rViewData.GetTabNo();
rMark.MarkToMulti();
sal_Bool bMarked = rMark.IsMultiMarked();
if (bMarked)
{
ScEditableTester aTester( pDoc, rMark );
if (!aTester.IsEditable())
{
ErrorMessage(aTester.GetMessageId());
delete pEditSel;
return;
}
}
ScDocument* pUndoDoc = NULL;
ScDocument* pRedoDoc = NULL;
if (bRecord)
{
pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
pUndoDoc->InitUndo( pDoc, nTab, nTab );
pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
pRedoDoc->InitUndo( pDoc, nTab, nTab );
if ( rMark.GetSelectCount() > 1 )
{
SCTAB nTabCount = pDoc->GetTableCount();
for (SCTAB i=0; i<nTabCount; i++)
if ( rMark.GetTableSelect(i) && i != nTab )
{
pUndoDoc->AddUndoTab( i, i );
pRedoDoc->AddUndoTab( i, i );
}
}
}
// ab hier kein return mehr
sal_Bool bOldDis = pDoc->IsIdleDisabled();
pDoc->DisableIdle( sal_True ); // #42726# stop online spelling
// *** create and init the edit engine *** --------------------------------
ScConversionEngineBase* pEngine = NULL;
switch( rConvParam.GetType() )
{
case SC_CONVERSION_SPELLCHECK:
pEngine = new ScSpellingEngine(
pDoc->GetEnginePool(), rViewData, pUndoDoc, pRedoDoc, LinguMgr::GetSpellChecker() );
break;
case SC_CONVERSION_HANGULHANJA:
case SC_CONVERSION_CHINESE_TRANSL:
pEngine = new ScTextConversionEngine(
pDoc->GetEnginePool(), rViewData, rConvParam, pUndoDoc, pRedoDoc );
break;
default:
DBG_ERRORFILE( "ScViewFunc::DoSheetConversion - unknown conversion type" );
}
MakeEditView( pEngine, nCol, nRow );
pEngine->SetRefDevice( rViewData.GetActiveWin() );
// dummy Zelle simulieren:
pEditView = rViewData.GetEditView( rViewData.GetActivePart() );
rViewData.SetSpellingView( pEditView );
Rectangle aRect( Point( 0, 0 ), Point( 0, 0 ) );
pEditView->SetOutputArea( aRect );
pEngine->SetControlWord( EE_CNTRL_USECHARATTRIBS );
pEngine->EnableUndo( sal_False );
pEngine->SetPaperSize( aRect.GetSize() );
pEngine->SetText( EMPTY_STRING );
// *** do the conversion *** ----------------------------------------------
pEngine->ClearModifyFlag();
pEngine->ConvertAll( *pEditView );
// *** undo/redo *** ------------------------------------------------------
if( pEngine->IsAnyModified() )
{
if (bRecord)
{
SCCOL nNewCol = rViewData.GetCurX();
SCROW nNewRow = rViewData.GetCurY();
rViewData.GetDocShell()->GetUndoManager()->AddUndoAction(
new ScUndoConversion(
pDocSh, rMark,
nCol, nRow, nTab, pUndoDoc,
nNewCol, nNewRow, nTab, pRedoDoc, rConvParam ) );
}
pDoc->SetDirty();
pDocSh->SetDocumentModified();
}
else
{
delete pUndoDoc;
delete pRedoDoc;
}
// *** final cleanup *** --------------------------------------------------
rViewData.SetSpellingView( NULL );
KillEditView(sal_True);
delete pEngine;
delete pEditSel;
pDocSh->PostPaintGridAll();
rViewData.GetViewShell()->UpdateInputHandler();
pDoc->DisableIdle(bOldDis);
}
//UNUSED2008-05 IMPL_LINK_INLINE_START( ScViewFunc, SpellError, void *, nLang )
//UNUSED2008-05 {
//UNUSED2008-05 SvtLanguageTable aLangTab;
//UNUSED2008-05 String aErr = aLangTab.GetString((LanguageType) (sal_uLong) nLang);
//UNUSED2008-05 ErrorHandler::HandleError(*new StringErrorInfo(
//UNUSED2008-05 ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aErr) );
//UNUSED2008-05
//UNUSED2008-05 return 0;
//UNUSED2008-05 }
//UNUSED2008-05 IMPL_LINK_INLINE_END( ScViewFunc, SpellError, void *, nLang )
// Pasten von FORMAT_FILE-Items
// wird nicht direkt aus Drop aufgerufen, sondern asynchron -> Dialoge sind erlaubt
sal_Bool ScViewFunc::PasteFile( const Point& rPos, const String& rFile, sal_Bool bLink )
{
INetURLObject aURL;
aURL.SetSmartURL( rFile );
String aStrURL = aURL.GetMainURL( INetURLObject::NO_DECODE );
// is it a media URL?
if( ::avmedia::MediaWindow::isMediaURL( aStrURL ) )
{
const SfxStringItem aMediaURLItem( SID_INSERT_AVMEDIA, aStrURL );
return sal_Bool( 0 != GetViewData()->GetDispatcher().Execute(
SID_INSERT_AVMEDIA, SFX_CALLMODE_SYNCHRON,
&aMediaURLItem, 0L ) );
}
if (!bLink) // bei bLink nur Grafik oder URL
{
// 1. Kann ich die Datei oeffnen?
const SfxFilter* pFlt = NULL;
// nur nach eigenen Filtern suchen, ohne Auswahlbox (wie in ScDocumentLoader)
SfxFilterMatcher aMatcher( ScDocShell::Factory().GetFilterContainer()->GetName() );
SfxMedium aSfxMedium( aStrURL, (STREAM_READ | STREAM_SHARE_DENYNONE), sal_False );
// #i73992# GuessFilter no longer calls UseInteractionHandler.
// This is UI, so it can be called here.
aSfxMedium.UseInteractionHandler(sal_True);
ErrCode nErr = aMatcher.GuessFilter( aSfxMedium, &pFlt );
if ( pFlt && !nErr )
{
// Code aus dem SFX geklaut!
SfxDispatcher &rDispatcher = GetViewData()->GetDispatcher();
SfxStringItem aFileNameItem( SID_FILE_NAME, aStrURL );
SfxStringItem aFilterItem( SID_FILTER_NAME, pFlt->GetName() );
// #i69524# add target, as in SfxApplication when the Open dialog is used
SfxStringItem aTargetItem( SID_TARGETNAME, String::CreateFromAscii("_default") );
// Asynchron oeffnen, kann naemlich auch aus D&D heraus passieren
// und das bekommt dem MAC nicht so gut ...
return sal_Bool( 0 != rDispatcher.Execute( SID_OPENDOC,
SFX_CALLMODE_ASYNCHRON, &aFileNameItem, &aFilterItem, &aTargetItem, 0L) );
}
}
// 2. Kann die Datei ueber die Grafik-Filter eingefuegt werden?
// (als Link, weil Gallery das so anbietet)
sal_uInt16 nFilterFormat;
Graphic aGraphic;
GraphicFilter* pGraphicFilter = GraphicFilter::GetGraphicFilter();
// GraphicProgress aGraphicProgress(&aGraphicFilter);
if (!pGraphicFilter->ImportGraphic(aGraphic, aURL,
GRFILTER_FORMAT_DONTKNOW, &nFilterFormat ))
{
if ( bLink )
{
String aFltName = pGraphicFilter->GetImportFormatName(nFilterFormat);
return PasteGraphic( rPos, aGraphic, aStrURL, aFltName );
}
else
{
// #i76709# if bLink isn't set, pass empty URL/filter, so a non-linked image is inserted
return PasteGraphic( rPos, aGraphic, EMPTY_STRING, EMPTY_STRING );
}
}
if (bLink) // bei bLink alles, was nicht Grafik ist, als URL
{
Rectangle aRect( rPos, Size(0,0) );
ScRange aRange = GetViewData()->GetDocument()->
GetRange( GetViewData()->GetTabNo(), aRect );
SCCOL nPosX = aRange.aStart.Col();
SCROW nPosY = aRange.aStart.Row();
InsertBookmark( aStrURL, aStrURL, nPosX, nPosY );
return sal_True;
}
else
{
// 3. Kann die Datei als OLE eingefuegt werden?
// auch nicht-Storages, z.B. Sounds (#38282#)
uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
//TODO/LATER: what about "bLink"?
uno::Sequence < beans::PropertyValue > aMedium(1);
aMedium[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
aMedium[0].Value <<= ::rtl::OUString( aStrURL );
comphelper::EmbeddedObjectContainer aCnt( xStorage );
::rtl::OUString aName;
uno::Reference < embed::XEmbeddedObject > xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
if( xObj.is() )
return PasteObject( rPos, xObj );
// #105851# If an OLE object can't be created, insert a URL button
GetViewData()->GetViewShell()->InsertURLButton( aStrURL, aStrURL, EMPTY_STRING, &rPos );
return sal_True;
}
}
sal_Bool ScViewFunc::PasteBookmark( sal_uLong nFormatId,
const ::com::sun::star::uno::Reference<
::com::sun::star::datatransfer::XTransferable >& rxTransferable,
SCCOL nPosX, SCROW nPosY )
{
INetBookmark aBookmark;
TransferableDataHelper aDataHelper( rxTransferable );
if ( !aDataHelper.GetINetBookmark( nFormatId, aBookmark ) )
return sal_False;
InsertBookmark( aBookmark.GetDescription(), aBookmark.GetURL(), nPosX, nPosY );
return sal_True;
}
void ScViewFunc::InsertBookmark( const String& rDescription, const String& rURL,
SCCOL nPosX, SCROW nPosY, const String* pTarget,
sal_Bool bTryReplace )
{
ScViewData* pViewData = GetViewData();
if ( pViewData->HasEditView( pViewData->GetActivePart() ) &&
nPosX >= pViewData->GetEditStartCol() && nPosX <= pViewData->GetEditEndCol() &&
nPosY >= pViewData->GetEditStartRow() && nPosY <= pViewData->GetEditEndRow() )
{
// in die gerade editierte Zelle einfuegen
String aTargetFrame;
if (pTarget)
aTargetFrame = *pTarget;
pViewData->GetViewShell()->InsertURLField( rDescription, rURL, aTargetFrame );
return;
}
// in nicht editierte Zelle einfuegen
ScDocument* pDoc = GetViewData()->GetDocument();
SCTAB nTab = GetViewData()->GetTabNo();
ScAddress aCellPos( nPosX, nPosY, nTab );
ScBaseCell* pCell = pDoc->GetCell( aCellPos );
EditEngine aEngine( pDoc->GetEnginePool() );
if (pCell)
{
if (pCell->GetCellType() == CELLTYPE_EDIT)
{
const EditTextObject* pOld = ((ScEditCell*)pCell)->GetData();
if (pOld)
aEngine.SetText(*pOld);
}
else
{
String aOld;
pDoc->GetInputString( nPosX, nPosY, nTab, aOld );
if (aOld.Len())
aEngine.SetText(aOld);
}
}
sal_uInt16 nPara = aEngine.GetParagraphCount();
if (nPara)
--nPara;
xub_StrLen nTxtLen = aEngine.GetTextLen(nPara);
ESelection aInsSel( nPara, nTxtLen, nPara, nTxtLen );
if ( bTryReplace && HasBookmarkAtCursor( NULL ) )
{
// if called from hyperlink slot and cell contains only a URL,
// replace old URL with new one
aInsSel = ESelection( 0, 0, 0, 1 ); // replace first character (field)
}
SvxURLField aField( rURL, rDescription, SVXURLFORMAT_APPDEFAULT );
if (pTarget)
aField.SetTargetFrame(*pTarget);
aEngine.QuickInsertField( SvxFieldItem( aField, EE_FEATURE_FIELD ), aInsSel );
EditTextObject* pData = aEngine.CreateTextObject();
EnterData( nPosX, nPosY, nTab, pData );
delete pData;
}
sal_Bool ScViewFunc::HasBookmarkAtCursor( SvxHyperlinkItem* pContent )
{
ScAddress aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
ScBaseCell* pCell = pDoc->GetCell( aPos );
if ( pCell && pCell->GetCellType() == CELLTYPE_EDIT )
{
const EditTextObject* pData = ((ScEditCell*)pCell)->GetData();
if (pData)
{
sal_Bool bField = pData->IsFieldObject();
if (bField)
{
const SvxFieldItem* pFieldItem = pData->GetField();
if (pFieldItem)
{
const SvxFieldData* pField = pFieldItem->GetField();
if ( pField && pField->ISA(SvxURLField) )
{
if (pContent)
{
const SvxURLField* pURLField = (const SvxURLField*)pField;
pContent->SetName( pURLField->GetRepresentation() );
pContent->SetURL( pURLField->GetURL() );
pContent->SetTargetFrame( pURLField->GetTargetFrame() );
}
return sal_True;
}
}
}
}
}
return sal_False;
}