1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sc.hxx" 26 27 28 29 // INCLUDE --------------------------------------------------------------- 30 31 #include "scitems.hxx" 32 #include <editeng/eeitem.hxx> 33 34 #include <editeng/editobj.hxx> 35 #include <editeng/editstat.hxx> 36 #include <editeng/editview.hxx> 37 #include <editeng/flditem.hxx> 38 #include <svx/hlnkitem.hxx> 39 #include <editeng/langitem.hxx> 40 #include <svx/svxerr.hxx> 41 #include <editeng/unolingu.hxx> 42 43 #include <sfx2/bindings.hxx> 44 #include <sfx2/dispatch.hxx> 45 #include <sfx2/docfile.hxx> 46 #include <sfx2/fcontnr.hxx> 47 #include <svtools/langtab.hxx> 48 #include <svtools/filter.hxx> 49 #include <svl/stritem.hxx> 50 #include <svtools/transfer.hxx> 51 #include <svl/urlbmk.hxx> 52 #include <vcl/msgbox.hxx> 53 #include <avmedia/mediawindow.hxx> 54 55 #include <comphelper/storagehelper.hxx> 56 #include <comphelper/processfactory.hxx> 57 58 #include "viewfunc.hxx" 59 #include "docsh.hxx" 60 #include "docsh.hxx" 61 #include "document.hxx" 62 #include "docpool.hxx" 63 #include "globstr.hrc" 64 #include "global.hxx" 65 #include "undoblk.hxx" 66 #include "undocell.hxx" 67 #include "cell.hxx" 68 #include "scmod.hxx" 69 #include "spelleng.hxx" 70 #include "patattr.hxx" 71 #include "sc.hrc" 72 #include "tabvwsh.hxx" 73 #include "impex.hxx" 74 #include "editutil.hxx" 75 #include "editable.hxx" 76 #include "dociter.hxx" 77 #include "reffind.hxx" 78 #include "compiler.hxx" 79 80 using namespace com::sun::star; 81 82 // STATIC DATA ----------------------------------------------------------- 83 84 sal_Bool bPasteIsDrop = sal_False; 85 86 //================================================================== 87 88 void ScViewFunc::PasteRTF( SCCOL nStartCol, SCROW nStartRow, 89 const ::com::sun::star::uno::Reference< 90 ::com::sun::star::datatransfer::XTransferable >& rxTransferable ) 91 { 92 TransferableDataHelper aDataHelper( rxTransferable ); 93 if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EDITENGINE ) ) 94 { 95 HideAllCursors(); 96 97 ScDocument* pUndoDoc = NULL; 98 99 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 100 ScDocument* pDoc = pDocSh->GetDocument(); 101 SCTAB nTab = GetViewData()->GetTabNo(); 102 const sal_Bool bRecord (pDoc->IsUndoEnabled()); 103 104 const ScPatternAttr* pPattern = pDoc->GetPattern( nStartCol, nStartRow, nTab ); 105 ScTabEditEngine* pEngine = new ScTabEditEngine( *pPattern, pDoc->GetEnginePool() ); 106 pEngine->EnableUndo( sal_False ); 107 108 Window* pActWin = GetActiveWin(); 109 if (pActWin) 110 { 111 pEngine->SetPaperSize(Size(100000,100000)); 112 Window aWin( pActWin ); 113 EditView aEditView( pEngine, &aWin ); 114 aEditView.SetOutputArea(Rectangle(0,0,100000,100000)); 115 116 // same method now for clipboard or drag&drop 117 // mba: clipboard always must contain absolute URLs (could be from alien source) 118 aEditView.InsertText( rxTransferable, String(), sal_True ); 119 } 120 121 sal_uLong nParCnt = pEngine->GetParagraphCount(); 122 if (nParCnt) 123 { 124 SCROW nEndRow = nStartRow + static_cast<SCROW>(nParCnt) - 1; 125 if (nEndRow > MAXROW) 126 nEndRow = MAXROW; 127 128 if (bRecord) 129 { 130 pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); 131 pUndoDoc->InitUndo( pDoc, nTab, nTab ); 132 pDoc->CopyToDocument( nStartCol,nStartRow,nTab, nStartCol,nEndRow,nTab, IDF_ALL, sal_False, pUndoDoc ); 133 } 134 135 SCROW nRow = nStartRow; 136 for( sal_uInt16 n = 0; n < nParCnt; n++ ) 137 { 138 EditTextObject* pObject = pEngine->CreateTextObject( n ); 139 EnterData( nStartCol, nRow, nTab, pObject, sal_False, sal_True ); 140 // kein Undo, auf einfache Strings testen 141 delete pObject; 142 if( ++nRow > MAXROW ) 143 break; 144 } 145 146 if (bRecord) 147 { 148 ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO ); 149 pRedoDoc->InitUndo( pDoc, nTab, nTab ); 150 pDoc->CopyToDocument( nStartCol,nStartRow,nTab, nStartCol,nEndRow,nTab, IDF_ALL|IDF_NOCAPTIONS, sal_False, pRedoDoc ); 151 152 ScMarkData aDestMark; 153 aDestMark.SelectOneTable( nTab ); 154 pDocSh->GetUndoManager()->AddUndoAction( 155 new ScUndoPaste( pDocSh, nStartCol,nStartRow,nTab, nStartCol,nEndRow,nTab, 156 aDestMark, 157 pUndoDoc, pRedoDoc, IDF_ALL, NULL,NULL,NULL,NULL ) ); 158 } 159 } 160 161 delete pEngine; 162 163 ShowAllCursors(); 164 } 165 else 166 { 167 HideAllCursors(); 168 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 169 ScImportExport aImpEx( pDocSh->GetDocument(), 170 ScAddress( nStartCol, nStartRow, GetViewData()->GetTabNo() ) ); 171 172 ::rtl::OUString aStr; 173 SotStorageStreamRef xStream; 174 if ( aDataHelper.GetSotStorageStream( SOT_FORMAT_RTF, xStream ) && xStream.Is() ) 175 // mba: clipboard always must contain absolute URLs (could be from alien source) 176 aImpEx.ImportStream( *xStream, String(), SOT_FORMAT_RTF ); 177 else if ( aDataHelper.GetString( SOT_FORMAT_RTF, aStr ) ) 178 aImpEx.ImportString( aStr, SOT_FORMAT_RTF ); 179 180 AdjustRowHeight( nStartRow, aImpEx.GetRange().aEnd.Row() ); 181 pDocSh->UpdateOle(GetViewData()); 182 ShowAllCursors(); 183 } 184 } 185 void ScViewFunc::DoRefConversion( sal_Bool bRecord ) 186 { 187 ScDocument* pDoc = GetViewData()->GetDocument(); 188 ScMarkData& rMark = GetViewData()->GetMarkData(); 189 SCTAB nTabCount = pDoc->GetTableCount(); 190 if (bRecord && !pDoc->IsUndoEnabled()) 191 bRecord = sal_False; 192 193 ScRange aMarkRange; 194 rMark.MarkToSimple(); 195 sal_Bool bMulti = rMark.IsMultiMarked(); 196 if (bMulti) 197 rMark.GetMultiMarkArea( aMarkRange ); 198 else if (rMark.IsMarked()) 199 rMark.GetMarkArea( aMarkRange ); 200 else 201 { 202 aMarkRange = ScRange( GetViewData()->GetCurX(), 203 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ); 204 } 205 ScEditableTester aTester( pDoc, aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), 206 aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(),rMark ); 207 if (!aTester.IsEditable()) 208 { 209 ErrorMessage(aTester.GetMessageId()); 210 return; 211 } 212 213 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 214 sal_Bool bOk = sal_False; 215 216 ScDocument* pUndoDoc = NULL; 217 if (bRecord) 218 { 219 pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); 220 SCTAB nTab = aMarkRange.aStart.Tab(); 221 pUndoDoc->InitUndo( pDoc, nTab, nTab ); 222 223 if ( rMark.GetSelectCount() > 1 ) 224 { 225 for (SCTAB i=0; i<nTabCount; i++) 226 if ( rMark.GetTableSelect(i) && i != nTab ) 227 pUndoDoc->AddUndoTab( i, i ); 228 } 229 ScRange aCopyRange = aMarkRange; 230 aCopyRange.aStart.SetTab(0); 231 aCopyRange.aEnd.SetTab(nTabCount-1); 232 pDoc->CopyToDocument( aCopyRange, IDF_ALL, bMulti, pUndoDoc, &rMark ); 233 } 234 235 ScRangeListRef xRanges; 236 GetViewData()->GetMultiArea( xRanges ); 237 sal_uLong nCount = xRanges->Count(); 238 239 for (SCTAB i=0; i<nTabCount; i++) 240 { 241 if (rMark.GetTableSelect(i)) 242 { 243 for (sal_uLong j=0; j<nCount; j++) 244 { 245 ScRange aRange = *xRanges->GetObject(j); 246 aRange.aStart.SetTab(i); 247 aRange.aEnd.SetTab(i); 248 ScCellIterator aIter( pDoc, aRange ); 249 ScBaseCell* pCell = aIter.GetFirst(); 250 while ( pCell ) 251 { 252 if (pCell->GetCellType() == CELLTYPE_FORMULA) 253 { 254 String aOld; 255 ((ScFormulaCell*)pCell)->GetFormula(aOld); 256 xub_StrLen nLen = aOld.Len(); 257 ScRefFinder aFinder( aOld, pDoc ); 258 aFinder.ToggleRel( 0, nLen ); 259 if (aFinder.GetFound()) 260 { 261 ScAddress aPos = ((ScFormulaCell*)pCell)->aPos; 262 String aNew = aFinder.GetText(); 263 ScCompiler aComp( pDoc, aPos); 264 aComp.SetGrammar(pDoc->GetGrammar()); 265 ScTokenArray* pArr = aComp.CompileString( aNew ); 266 ScFormulaCell* pNewCell = new ScFormulaCell( pDoc, aPos, 267 pArr,formula::FormulaGrammar::GRAM_DEFAULT, MM_NONE ); 268 pDoc->PutCell( aPos, pNewCell ); 269 bOk = sal_True; 270 } 271 } 272 pCell = aIter.GetNext(); 273 } 274 } 275 } 276 } 277 if (bRecord) 278 { 279 ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO ); 280 SCTAB nTab = aMarkRange.aStart.Tab(); 281 pRedoDoc->InitUndo( pDoc, nTab, nTab ); 282 283 if ( rMark.GetSelectCount() > 1 ) 284 { 285 for (SCTAB i=0; i<nTabCount; i++) 286 if ( rMark.GetTableSelect(i) && i != nTab ) 287 pRedoDoc->AddUndoTab( i, i ); 288 } 289 ScRange aCopyRange = aMarkRange; 290 aCopyRange.aStart.SetTab(0); 291 aCopyRange.aEnd.SetTab(nTabCount-1); 292 pDoc->CopyToDocument( aCopyRange, IDF_ALL, bMulti, pRedoDoc, &rMark ); 293 294 pDocSh->GetUndoManager()->AddUndoAction( 295 new ScUndoRefConversion( pDocSh, 296 aMarkRange, rMark, pUndoDoc, pRedoDoc, bMulti, IDF_ALL) ); 297 } 298 299 pDocSh->PostPaint( aMarkRange, PAINT_GRID ); 300 pDocSh->UpdateOle(GetViewData()); 301 pDocSh->SetDocumentModified(); 302 CellContentChanged(); 303 304 if (!bOk) 305 ErrorMessage(STR_ERR_NOREF); 306 } 307 // Thesaurus - Undo ok 308 void ScViewFunc::DoThesaurus( sal_Bool bRecord ) 309 { 310 SCCOL nCol; 311 SCROW nRow; 312 SCTAB nTab; 313 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 314 ScDocument* pDoc = pDocSh->GetDocument(); 315 ScMarkData& rMark = GetViewData()->GetMarkData(); 316 ScSplitPos eWhich = GetViewData()->GetActivePart(); 317 CellType eCellType; 318 EESpellState eState; 319 String sOldText, sNewString; 320 EditTextObject* pOldTObj = NULL; 321 const EditTextObject* pTObject = NULL; 322 ScBaseCell* pCell = NULL; 323 EditView* pEditView = NULL; 324 ESelection* pEditSel = NULL; 325 ScEditEngineDefaulter* pThesaurusEngine; 326 sal_Bool bIsEditMode = GetViewData()->HasEditView(eWhich); 327 if (bRecord && !pDoc->IsUndoEnabled()) 328 bRecord = sal_False; 329 if (bIsEditMode) // Edit-Mode aktiv 330 { 331 GetViewData()->GetEditView(eWhich, pEditView, nCol, nRow); 332 pEditSel = new ESelection(pEditView->GetSelection()); 333 SC_MOD()->InputEnterHandler(); 334 GetViewData()->GetBindings().Update(); // sonst kommt der Sfx durcheinander... 335 } 336 else 337 { 338 nCol = GetViewData()->GetCurX(); 339 nRow = GetViewData()->GetCurY(); 340 } 341 nTab = GetViewData()->GetTabNo(); 342 343 ScEditableTester aTester( pDoc, nCol, nRow, nCol, nRow, rMark ); 344 if (!aTester.IsEditable()) 345 { 346 ErrorMessage(aTester.GetMessageId()); 347 delete pEditSel; 348 return; 349 } 350 pDoc->GetCellType(nCol, nRow, nTab, eCellType); 351 if (eCellType != CELLTYPE_STRING && eCellType != CELLTYPE_EDIT) 352 { 353 ErrorMessage(STR_THESAURUS_NO_STRING); 354 return; 355 } 356 357 com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellChecker1> 358 xSpeller = LinguMgr::GetSpellChecker(); 359 //! if (...) // thesaurus not available 360 //! { 361 //! ErrorMessage(STR_EXPORT_ASCII_WARNING); 362 //! delete pEditSel; 363 //! return; 364 //! } 365 366 pThesaurusEngine = new ScEditEngineDefaulter( pDoc->GetEnginePool() ); 367 pThesaurusEngine->SetEditTextObjectPool( pDoc->GetEditPool() ); 368 pThesaurusEngine->SetRefDevice(GetViewData()->GetActiveWin()); 369 pThesaurusEngine->SetSpeller(xSpeller); 370 MakeEditView(pThesaurusEngine, nCol, nRow ); 371 const ScPatternAttr* pPattern = NULL; 372 SfxItemSet* pEditDefaults = new SfxItemSet(pThesaurusEngine->GetEmptyItemSet()); 373 pPattern = pDoc->GetPattern(nCol, nRow, nTab); 374 if (pPattern ) 375 { 376 pPattern->FillEditItemSet( pEditDefaults ); 377 pThesaurusEngine->SetDefaults( *pEditDefaults ); 378 } 379 380 if (eCellType == CELLTYPE_STRING) 381 { 382 pDoc->GetString(nCol, nRow, nTab, sOldText); 383 pThesaurusEngine->SetText(sOldText); 384 } 385 else if (eCellType == CELLTYPE_EDIT) 386 { 387 pDoc->GetCell(nCol, nRow, nTab, pCell); 388 if (pCell) 389 { 390 ((ScEditCell*) pCell)->GetData(pTObject); 391 if (pTObject) 392 { 393 pOldTObj = pTObject->Clone(); 394 pThesaurusEngine->SetText(*pTObject); 395 } 396 } 397 } 398 else 399 { 400 DBG_ERROR("DoThesaurus: Keine String oder Editzelle"); 401 } 402 pEditView = GetViewData()->GetEditView(GetViewData()->GetActivePart());; 403 if (pEditSel) 404 pEditView->SetSelection(*pEditSel); 405 else 406 pEditView->SetSelection(ESelection(0,0,0,0)); 407 408 pThesaurusEngine->ClearModifyFlag(); 409 410 // language is now in EditEngine attributes -> no longer passed to StartThesaurus 411 412 eState = pEditView->StartThesaurus(); 413 DBG_ASSERT(eState != EE_SPELL_NOSPELLER, "No SpellChecker"); 414 415 if (eState == EE_SPELL_ERRORFOUND) // sollte spaeter durch Wrapper geschehen! 416 { 417 LanguageType eLnge = ScViewUtil::GetEffLanguage( pDoc, ScAddress( nCol, nRow, nTab ) ); 418 SvtLanguageTable aLangTab; 419 String aErr = aLangTab.GetString(eLnge); 420 aErr += ScGlobal::GetRscString( STR_SPELLING_NO_LANG ); 421 InfoBox aBox( GetViewData()->GetDialogParent(), aErr ); 422 aBox.Execute(); 423 } 424 if (pThesaurusEngine->IsModified()) 425 { 426 EditTextObject* pNewTObj = NULL; 427 if (pCell && pTObject) 428 { 429 pNewTObj = pThesaurusEngine->CreateTextObject(); 430 pCell = new ScEditCell( pNewTObj, pDoc, 431 pThesaurusEngine->GetEditTextObjectPool() ); 432 pDoc->PutCell( nCol, nRow, nTab, pCell ); 433 } 434 else 435 { 436 sNewString = pThesaurusEngine->GetText(); 437 pDoc->SetString(nCol, nRow, nTab, sNewString); 438 } 439 // erack! it's broadcasted 440 // pDoc->SetDirty(); 441 pDocSh->SetDocumentModified(); 442 if (bRecord) 443 { 444 GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction( 445 new ScUndoThesaurus( GetViewData()->GetDocShell(), 446 nCol, nRow, nTab, 447 sOldText, pOldTObj, sNewString, pNewTObj)); 448 } 449 delete pNewTObj; 450 } 451 KillEditView(sal_True); 452 delete pEditDefaults; 453 delete pThesaurusEngine; 454 delete pOldTObj; 455 delete pEditSel; 456 pDocSh->PostPaintGridAll(); 457 } 458 459 //UNUSED2008-05 // Spelling Checker - Undo ok 460 //UNUSED2008-05 void ScViewFunc::DoSpellingChecker( sal_Bool bRecord ) 461 //UNUSED2008-05 { 462 //UNUSED2008-05 DoSheetConversion( ScConversionParam( SC_CONVERSION_SPELLCHECK ), bRecord ); 463 //UNUSED2008-05 } 464 465 void ScViewFunc::DoHangulHanjaConversion( sal_Bool bRecord ) 466 { 467 ScConversionParam aConvParam( SC_CONVERSION_HANGULHANJA, LANGUAGE_KOREAN, 0, true ); 468 DoSheetConversion( aConvParam, bRecord ); 469 } 470 471 void ScViewFunc::DoSheetConversion( const ScConversionParam& rConvParam, sal_Bool bRecord ) 472 { 473 SCCOL nCol; 474 SCROW nRow; 475 SCTAB nTab; 476 ScViewData& rViewData = *GetViewData(); 477 ScDocShell* pDocSh = rViewData.GetDocShell(); 478 ScDocument* pDoc = pDocSh->GetDocument(); 479 ScMarkData& rMark = rViewData.GetMarkData(); 480 ScSplitPos eWhich = rViewData.GetActivePart(); 481 EditView* pEditView = NULL; 482 ESelection* pEditSel = NULL; 483 sal_Bool bIsEditMode = rViewData.HasEditView(eWhich); 484 if (bRecord && !pDoc->IsUndoEnabled()) 485 bRecord = sal_False; 486 if (bIsEditMode) // Edit-Mode aktiv 487 { 488 rViewData.GetEditView(eWhich, pEditView, nCol, nRow); 489 pEditSel = new ESelection(pEditView->GetSelection()); 490 SC_MOD()->InputEnterHandler(); 491 } 492 else 493 { 494 nCol = rViewData.GetCurX(); 495 nRow = rViewData.GetCurY(); 496 497 AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP); 498 } 499 nTab = rViewData.GetTabNo(); 500 501 rMark.MarkToMulti(); 502 sal_Bool bMarked = rMark.IsMultiMarked(); 503 if (bMarked) 504 { 505 ScEditableTester aTester( pDoc, rMark ); 506 if (!aTester.IsEditable()) 507 { 508 ErrorMessage(aTester.GetMessageId()); 509 delete pEditSel; 510 return; 511 } 512 } 513 514 ScDocument* pUndoDoc = NULL; 515 ScDocument* pRedoDoc = NULL; 516 if (bRecord) 517 { 518 pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); 519 pUndoDoc->InitUndo( pDoc, nTab, nTab ); 520 pRedoDoc = new ScDocument( SCDOCMODE_UNDO ); 521 pRedoDoc->InitUndo( pDoc, nTab, nTab ); 522 523 if ( rMark.GetSelectCount() > 1 ) 524 { 525 SCTAB nTabCount = pDoc->GetTableCount(); 526 for (SCTAB i=0; i<nTabCount; i++) 527 if ( rMark.GetTableSelect(i) && i != nTab ) 528 { 529 pUndoDoc->AddUndoTab( i, i ); 530 pRedoDoc->AddUndoTab( i, i ); 531 } 532 } 533 } 534 535 // ab hier kein return mehr 536 537 sal_Bool bOldDis = pDoc->IsIdleDisabled(); 538 pDoc->DisableIdle( sal_True ); // #42726# stop online spelling 539 540 // *** create and init the edit engine *** -------------------------------- 541 542 ScConversionEngineBase* pEngine = NULL; 543 switch( rConvParam.GetType() ) 544 { 545 case SC_CONVERSION_SPELLCHECK: 546 pEngine = new ScSpellingEngine( 547 pDoc->GetEnginePool(), rViewData, pUndoDoc, pRedoDoc, LinguMgr::GetSpellChecker() ); 548 break; 549 case SC_CONVERSION_HANGULHANJA: 550 case SC_CONVERSION_CHINESE_TRANSL: 551 pEngine = new ScTextConversionEngine( 552 pDoc->GetEnginePool(), rViewData, rConvParam, pUndoDoc, pRedoDoc ); 553 break; 554 default: 555 DBG_ERRORFILE( "ScViewFunc::DoSheetConversion - unknown conversion type" ); 556 } 557 558 MakeEditView( pEngine, nCol, nRow ); 559 pEngine->SetRefDevice( rViewData.GetActiveWin() ); 560 // dummy Zelle simulieren: 561 pEditView = rViewData.GetEditView( rViewData.GetActivePart() ); 562 rViewData.SetSpellingView( pEditView ); 563 Rectangle aRect( Point( 0, 0 ), Point( 0, 0 ) ); 564 pEditView->SetOutputArea( aRect ); 565 pEngine->SetControlWord( EE_CNTRL_USECHARATTRIBS ); 566 pEngine->EnableUndo( sal_False ); 567 pEngine->SetPaperSize( aRect.GetSize() ); 568 pEngine->SetText( EMPTY_STRING ); 569 570 // *** do the conversion *** ---------------------------------------------- 571 572 pEngine->ClearModifyFlag(); 573 pEngine->ConvertAll( *pEditView ); 574 575 // *** undo/redo *** ------------------------------------------------------ 576 577 if( pEngine->IsAnyModified() ) 578 { 579 if (bRecord) 580 { 581 SCCOL nNewCol = rViewData.GetCurX(); 582 SCROW nNewRow = rViewData.GetCurY(); 583 rViewData.GetDocShell()->GetUndoManager()->AddUndoAction( 584 new ScUndoConversion( 585 pDocSh, rMark, 586 nCol, nRow, nTab, pUndoDoc, 587 nNewCol, nNewRow, nTab, pRedoDoc, rConvParam ) ); 588 } 589 pDoc->SetDirty(); 590 pDocSh->SetDocumentModified(); 591 } 592 else 593 { 594 delete pUndoDoc; 595 delete pRedoDoc; 596 } 597 598 // *** final cleanup *** -------------------------------------------------- 599 600 rViewData.SetSpellingView( NULL ); 601 KillEditView(sal_True); 602 delete pEngine; 603 delete pEditSel; 604 pDocSh->PostPaintGridAll(); 605 rViewData.GetViewShell()->UpdateInputHandler(); 606 pDoc->DisableIdle(bOldDis); 607 } 608 609 610 //UNUSED2008-05 IMPL_LINK_INLINE_START( ScViewFunc, SpellError, void *, nLang ) 611 //UNUSED2008-05 { 612 //UNUSED2008-05 SvtLanguageTable aLangTab; 613 //UNUSED2008-05 String aErr = aLangTab.GetString((LanguageType) (sal_uLong) nLang); 614 //UNUSED2008-05 ErrorHandler::HandleError(*new StringErrorInfo( 615 //UNUSED2008-05 ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aErr) ); 616 //UNUSED2008-05 617 //UNUSED2008-05 return 0; 618 //UNUSED2008-05 } 619 //UNUSED2008-05 IMPL_LINK_INLINE_END( ScViewFunc, SpellError, void *, nLang ) 620 621 // Pasten von FORMAT_FILE-Items 622 // wird nicht direkt aus Drop aufgerufen, sondern asynchron -> Dialoge sind erlaubt 623 624 sal_Bool ScViewFunc::PasteFile( const Point& rPos, const String& rFile, sal_Bool bLink ) 625 { 626 INetURLObject aURL; 627 aURL.SetSmartURL( rFile ); 628 String aStrURL = aURL.GetMainURL( INetURLObject::NO_DECODE ); 629 630 // is it a media URL? 631 if( ::avmedia::MediaWindow::isMediaURL( aStrURL ) ) 632 { 633 const SfxStringItem aMediaURLItem( SID_INSERT_AVMEDIA, aStrURL ); 634 return sal_Bool( 0 != GetViewData()->GetDispatcher().Execute( 635 SID_INSERT_AVMEDIA, SFX_CALLMODE_SYNCHRON, 636 &aMediaURLItem, 0L ) ); 637 } 638 639 if (!bLink) // bei bLink nur Grafik oder URL 640 { 641 // 1. Kann ich die Datei oeffnen? 642 const SfxFilter* pFlt = NULL; 643 644 // nur nach eigenen Filtern suchen, ohne Auswahlbox (wie in ScDocumentLoader) 645 SfxFilterMatcher aMatcher( ScDocShell::Factory().GetFilterContainer()->GetName() ); 646 SfxMedium aSfxMedium( aStrURL, (STREAM_READ | STREAM_SHARE_DENYNONE), sal_False ); 647 // #i73992# GuessFilter no longer calls UseInteractionHandler. 648 // This is UI, so it can be called here. 649 aSfxMedium.UseInteractionHandler(sal_True); 650 ErrCode nErr = aMatcher.GuessFilter( aSfxMedium, &pFlt ); 651 652 if ( pFlt && !nErr ) 653 { 654 // Code aus dem SFX geklaut! 655 SfxDispatcher &rDispatcher = GetViewData()->GetDispatcher(); 656 SfxStringItem aFileNameItem( SID_FILE_NAME, aStrURL ); 657 SfxStringItem aFilterItem( SID_FILTER_NAME, pFlt->GetName() ); 658 // #i69524# add target, as in SfxApplication when the Open dialog is used 659 SfxStringItem aTargetItem( SID_TARGETNAME, String::CreateFromAscii("_default") ); 660 661 // Asynchron oeffnen, kann naemlich auch aus D&D heraus passieren 662 // und das bekommt dem MAC nicht so gut ... 663 return sal_Bool( 0 != rDispatcher.Execute( SID_OPENDOC, 664 SFX_CALLMODE_ASYNCHRON, &aFileNameItem, &aFilterItem, &aTargetItem, 0L) ); 665 } 666 } 667 668 // 2. Kann die Datei ueber die Grafik-Filter eingefuegt werden? 669 // (als Link, weil Gallery das so anbietet) 670 671 sal_uInt16 nFilterFormat; 672 Graphic aGraphic; 673 GraphicFilter* pGraphicFilter = GraphicFilter::GetGraphicFilter(); 674 675 // GraphicProgress aGraphicProgress(&aGraphicFilter); 676 677 if (!pGraphicFilter->ImportGraphic(aGraphic, aURL, 678 GRFILTER_FORMAT_DONTKNOW, &nFilterFormat )) 679 { 680 if ( bLink ) 681 { 682 String aFltName = pGraphicFilter->GetImportFormatName(nFilterFormat); 683 return PasteGraphic( rPos, aGraphic, aStrURL, aFltName ); 684 } 685 else 686 { 687 // #i76709# if bLink isn't set, pass empty URL/filter, so a non-linked image is inserted 688 return PasteGraphic( rPos, aGraphic, EMPTY_STRING, EMPTY_STRING ); 689 } 690 } 691 692 if (bLink) // bei bLink alles, was nicht Grafik ist, als URL 693 { 694 Rectangle aRect( rPos, Size(0,0) ); 695 ScRange aRange = GetViewData()->GetDocument()-> 696 GetRange( GetViewData()->GetTabNo(), aRect ); 697 SCCOL nPosX = aRange.aStart.Col(); 698 SCROW nPosY = aRange.aStart.Row(); 699 700 InsertBookmark( aStrURL, aStrURL, nPosX, nPosY ); 701 return sal_True; 702 } 703 else 704 { 705 // 3. Kann die Datei als OLE eingefuegt werden? 706 // auch nicht-Storages, z.B. Sounds (#38282#) 707 uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage(); 708 709 //TODO/LATER: what about "bLink"? 710 711 uno::Sequence < beans::PropertyValue > aMedium(1); 712 aMedium[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); 713 aMedium[0].Value <<= ::rtl::OUString( aStrURL ); 714 715 comphelper::EmbeddedObjectContainer aCnt( xStorage ); 716 ::rtl::OUString aName; 717 uno::Reference < embed::XEmbeddedObject > xObj = aCnt.InsertEmbeddedObject( aMedium, aName ); 718 if( xObj.is() ) 719 return PasteObject( rPos, xObj ); 720 721 // #105851# If an OLE object can't be created, insert a URL button 722 723 GetViewData()->GetViewShell()->InsertURLButton( aStrURL, aStrURL, EMPTY_STRING, &rPos ); 724 return sal_True; 725 } 726 } 727 728 sal_Bool ScViewFunc::PasteBookmark( sal_uLong nFormatId, 729 const ::com::sun::star::uno::Reference< 730 ::com::sun::star::datatransfer::XTransferable >& rxTransferable, 731 SCCOL nPosX, SCROW nPosY ) 732 { 733 INetBookmark aBookmark; 734 TransferableDataHelper aDataHelper( rxTransferable ); 735 if ( !aDataHelper.GetINetBookmark( nFormatId, aBookmark ) ) 736 return sal_False; 737 738 InsertBookmark( aBookmark.GetDescription(), aBookmark.GetURL(), nPosX, nPosY ); 739 return sal_True; 740 } 741 742 void ScViewFunc::InsertBookmark( const String& rDescription, const String& rURL, 743 SCCOL nPosX, SCROW nPosY, const String* pTarget, 744 sal_Bool bTryReplace ) 745 { 746 ScViewData* pViewData = GetViewData(); 747 if ( pViewData->HasEditView( pViewData->GetActivePart() ) && 748 nPosX >= pViewData->GetEditStartCol() && nPosX <= pViewData->GetEditEndCol() && 749 nPosY >= pViewData->GetEditStartRow() && nPosY <= pViewData->GetEditEndRow() ) 750 { 751 // in die gerade editierte Zelle einfuegen 752 753 String aTargetFrame; 754 if (pTarget) 755 aTargetFrame = *pTarget; 756 pViewData->GetViewShell()->InsertURLField( rDescription, rURL, aTargetFrame ); 757 return; 758 } 759 760 // in nicht editierte Zelle einfuegen 761 762 ScDocument* pDoc = GetViewData()->GetDocument(); 763 SCTAB nTab = GetViewData()->GetTabNo(); 764 ScAddress aCellPos( nPosX, nPosY, nTab ); 765 ScBaseCell* pCell = pDoc->GetCell( aCellPos ); 766 EditEngine aEngine( pDoc->GetEnginePool() ); 767 if (pCell) 768 { 769 if (pCell->GetCellType() == CELLTYPE_EDIT) 770 { 771 const EditTextObject* pOld = ((ScEditCell*)pCell)->GetData(); 772 if (pOld) 773 aEngine.SetText(*pOld); 774 } 775 else 776 { 777 String aOld; 778 pDoc->GetInputString( nPosX, nPosY, nTab, aOld ); 779 if (aOld.Len()) 780 aEngine.SetText(aOld); 781 } 782 } 783 784 sal_uInt16 nPara = aEngine.GetParagraphCount(); 785 if (nPara) 786 --nPara; 787 xub_StrLen nTxtLen = aEngine.GetTextLen(nPara); 788 ESelection aInsSel( nPara, nTxtLen, nPara, nTxtLen ); 789 790 if ( bTryReplace && HasBookmarkAtCursor( NULL ) ) 791 { 792 // if called from hyperlink slot and cell contains only a URL, 793 // replace old URL with new one 794 795 aInsSel = ESelection( 0, 0, 0, 1 ); // replace first character (field) 796 } 797 798 SvxURLField aField( rURL, rDescription, SVXURLFORMAT_APPDEFAULT ); 799 if (pTarget) 800 aField.SetTargetFrame(*pTarget); 801 aEngine.QuickInsertField( SvxFieldItem( aField, EE_FEATURE_FIELD ), aInsSel ); 802 803 EditTextObject* pData = aEngine.CreateTextObject(); 804 EnterData( nPosX, nPosY, nTab, pData ); 805 delete pData; 806 } 807 808 sal_Bool ScViewFunc::HasBookmarkAtCursor( SvxHyperlinkItem* pContent ) 809 { 810 ScAddress aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() ); 811 ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument(); 812 813 ScBaseCell* pCell = pDoc->GetCell( aPos ); 814 if ( pCell && pCell->GetCellType() == CELLTYPE_EDIT ) 815 { 816 const EditTextObject* pData = ((ScEditCell*)pCell)->GetData(); 817 if (pData) 818 { 819 sal_Bool bField = pData->IsFieldObject(); 820 if (bField) 821 { 822 const SvxFieldItem* pFieldItem = pData->GetField(); 823 if (pFieldItem) 824 { 825 const SvxFieldData* pField = pFieldItem->GetField(); 826 if ( pField && pField->ISA(SvxURLField) ) 827 { 828 if (pContent) 829 { 830 const SvxURLField* pURLField = (const SvxURLField*)pField; 831 pContent->SetName( pURLField->GetRepresentation() ); 832 pContent->SetURL( pURLField->GetURL() ); 833 pContent->SetTargetFrame( pURLField->GetTargetFrame() ); 834 } 835 return sal_True; 836 } 837 } 838 } 839 } 840 } 841 return sal_False; 842 } 843 844 845