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