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
PasteRTF(SCCOL nStartCol,SCROW nStartRow,const::com::sun::star::uno::Reference<::com::sun::star::datatransfer::XTransferable> & rxTransferable)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_uInt32 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 }
DoRefConversion(sal_Bool bRecord)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
DoThesaurus(sal_Bool bRecord)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
DoHangulHanjaConversion(sal_Bool bRecord)465 void ScViewFunc::DoHangulHanjaConversion( sal_Bool bRecord )
466 {
467 ScConversionParam aConvParam( SC_CONVERSION_HANGULHANJA, LANGUAGE_KOREAN, 0, true );
468 DoSheetConversion( aConvParam, bRecord );
469 }
470
DoSheetConversion(const ScConversionParam & rConvParam,sal_Bool bRecord)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
PasteFile(const Point & rPos,const String & rFile,sal_Bool bLink)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
PasteBookmark(sal_uLong nFormatId,const::com::sun::star::uno::Reference<::com::sun::star::datatransfer::XTransferable> & rxTransferable,SCCOL nPosX,SCROW nPosY)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
InsertBookmark(const String & rDescription,const String & rURL,SCCOL nPosX,SCROW nPosY,const String * pTarget,sal_Bool bTryReplace)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_uInt32 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
HasBookmarkAtCursor(SvxHyperlinkItem * pContent)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