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 : #include <gridwin.hxx>
71 :
72 : #include <boost/scoped_ptr.hpp>
73 :
74 : using namespace com::sun::star;
75 :
76 : // STATIC DATA -----------------------------------------------------------
77 :
78 : bool bPasteIsDrop = false;
79 :
80 0 : void ScViewFunc::PasteRTF( SCCOL nStartCol, SCROW nStartRow,
81 : const ::com::sun::star::uno::Reference<
82 : ::com::sun::star::datatransfer::XTransferable >& rxTransferable )
83 : {
84 0 : TransferableDataHelper aDataHelper( rxTransferable );
85 0 : if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EDITENGINE ) )
86 : {
87 0 : HideAllCursors();
88 :
89 0 : ScDocShell* pDocSh = GetViewData().GetDocShell();
90 0 : ScDocument& rDoc = pDocSh->GetDocument();
91 0 : SCTAB nTab = GetViewData().GetTabNo();
92 0 : const bool bRecord (rDoc.IsUndoEnabled());
93 :
94 0 : const ScPatternAttr* pPattern = rDoc.GetPattern( nStartCol, nStartRow, nTab );
95 0 : boost::scoped_ptr<ScTabEditEngine> pEngine(new ScTabEditEngine( *pPattern, rDoc.GetEnginePool() ));
96 0 : pEngine->EnableUndo( false );
97 :
98 0 : vcl::Window* pActWin = GetActiveWin();
99 0 : if (pActWin)
100 : {
101 0 : pEngine->SetPaperSize(Size(100000,100000));
102 0 : vcl::Window aWin( pActWin );
103 0 : EditView aEditView( pEngine.get(), &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( &rDoc, nTab, nTab );
123 0 : rDoc.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 = rDoc.IsUndoEnabled();
130 0 : rDoc.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 : rDoc.EnableUndo(bUndoEnabled);
139 :
140 0 : if (bRecord)
141 : {
142 0 : ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
143 0 : pRedoDoc->InitUndo( &rDoc, nTab, nTab );
144 0 : rDoc.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 : pEngine.reset();
156 :
157 0 : ShowAllCursors();
158 : }
159 : else
160 : {
161 0 : HideAllCursors();
162 0 : ScDocShell* pDocSh = GetViewData().GetDocShell();
163 0 : 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& rDoc = 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 && !rDoc.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( &rDoc, 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(rDoc, 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(rDoc.GetEnginePool()));
353 0 : pThesaurusEngine->SetEditTextObjectPool( rDoc.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 = rDoc.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(&rDoc));
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( &rDoc, ScAddress( nCol, nRow, nTab ) );
388 0 : OUString aErr = SvtLanguageTable::GetLanguageString(eLnge);
389 0 : aErr += ScGlobal::GetRscString( STR_SPELLING_NO_LANG );
390 0 : InfoBox aBox( GetViewData().GetDialogParent(), aErr );
391 0 : aBox.Execute();
392 : }
393 0 : if (pThesaurusEngine->IsModified())
394 : {
395 0 : ScCellValue aNewText;
396 :
397 0 : if (aOldText.meType == CELLTYPE_EDIT)
398 : {
399 : // The cell will own the text object instance.
400 0 : EditTextObject* pText = pThesaurusEngine->CreateTextObject();
401 0 : rDoc.SetEditText(ScAddress(nCol,nRow,nTab), pText);
402 0 : aNewText.set(*pText);
403 : }
404 : else
405 : {
406 0 : OUString aStr = pThesaurusEngine->GetText();
407 0 : aNewText.set(rDoc.GetSharedStringPool().intern(aStr));
408 0 : rDoc.SetString(nCol, nRow, nTab, aStr);
409 : }
410 :
411 0 : pDocSh->SetDocumentModified();
412 0 : if (bRecord)
413 : {
414 0 : GetViewData().GetDocShell()->GetUndoManager()->AddUndoAction(
415 : new ScUndoThesaurus(
416 0 : GetViewData().GetDocShell(), nCol, nRow, nTab, aOldText, aNewText));
417 0 : }
418 : }
419 :
420 0 : KillEditView(true);
421 0 : pDocSh->PostPaintGridAll();
422 : }
423 :
424 0 : void ScViewFunc::DoHangulHanjaConversion( bool bRecord )
425 : {
426 0 : ScConversionParam aConvParam( SC_CONVERSION_HANGULHANJA, LANGUAGE_KOREAN, 0, true );
427 0 : DoSheetConversion( aConvParam, bRecord );
428 0 : }
429 :
430 0 : void ScViewFunc::DoSheetConversion( const ScConversionParam& rConvParam, bool bRecord )
431 : {
432 : SCCOL nCol;
433 : SCROW nRow;
434 : SCTAB nTab;
435 0 : ScViewData& rViewData = GetViewData();
436 0 : ScDocShell* pDocSh = rViewData.GetDocShell();
437 0 : ScDocument& rDoc = pDocSh->GetDocument();
438 0 : ScMarkData& rMark = rViewData.GetMarkData();
439 0 : ScSplitPos eWhich = rViewData.GetActivePart();
440 0 : EditView* pEditView = NULL;
441 0 : bool bIsEditMode = rViewData.HasEditView(eWhich);
442 0 : if (bRecord && !rDoc.IsUndoEnabled())
443 0 : bRecord = false;
444 0 : if (bIsEditMode) // Edit-Mode aktiv
445 : {
446 0 : rViewData.GetEditView(eWhich, pEditView, nCol, nRow);
447 0 : SC_MOD()->InputEnterHandler();
448 : }
449 : else
450 : {
451 0 : nCol = rViewData.GetCurX();
452 0 : nRow = rViewData.GetCurY();
453 :
454 0 : AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP);
455 : }
456 0 : nTab = rViewData.GetTabNo();
457 :
458 0 : rMark.MarkToMulti();
459 0 : bool bMarked = rMark.IsMultiMarked();
460 0 : if (bMarked)
461 : {
462 0 : ScEditableTester aTester( &rDoc, rMark );
463 0 : if (!aTester.IsEditable())
464 : {
465 0 : ErrorMessage(aTester.GetMessageId());
466 0 : return;
467 : }
468 : }
469 :
470 0 : ScDocument* pUndoDoc = NULL;
471 0 : ScDocument* pRedoDoc = NULL;
472 0 : if (bRecord)
473 : {
474 0 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
475 0 : pUndoDoc->InitUndo( &rDoc, nTab, nTab );
476 0 : pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
477 0 : pRedoDoc->InitUndo( &rDoc, nTab, nTab );
478 :
479 0 : if ( rMark.GetSelectCount() > 1 )
480 : {
481 0 : ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
482 0 : for (; itr != itrEnd; ++itr)
483 0 : if ( *itr != nTab )
484 : {
485 0 : pUndoDoc->AddUndoTab( *itr, *itr );
486 0 : pRedoDoc->AddUndoTab( *itr, *itr );
487 : }
488 : }
489 : }
490 :
491 : // ab hier kein return mehr
492 :
493 0 : bool bOldEnabled = rDoc.IsIdleEnabled();
494 0 : rDoc.EnableIdle(false); // stop online spelling
495 :
496 : // *** create and init the edit engine *** --------------------------------
497 :
498 0 : boost::scoped_ptr<ScConversionEngineBase> pEngine;
499 0 : switch( rConvParam.GetType() )
500 : {
501 : case SC_CONVERSION_SPELLCHECK:
502 : pEngine.reset(new ScSpellingEngine(
503 0 : rDoc.GetEnginePool(), rViewData, pUndoDoc, pRedoDoc, LinguMgr::GetSpellChecker() ));
504 0 : break;
505 : case SC_CONVERSION_HANGULHANJA:
506 : case SC_CONVERSION_CHINESE_TRANSL:
507 : pEngine.reset(new ScTextConversionEngine(
508 0 : rDoc.GetEnginePool(), rViewData, rConvParam, pUndoDoc, pRedoDoc ));
509 0 : break;
510 : default:
511 : OSL_FAIL( "ScViewFunc::DoSheetConversion - unknown conversion type" );
512 : }
513 :
514 0 : MakeEditView( pEngine.get(), nCol, nRow );
515 0 : pEngine->SetRefDevice( rViewData.GetActiveWin() );
516 : // dummy Zelle simulieren:
517 0 : pEditView = rViewData.GetEditView( rViewData.GetActivePart() );
518 0 : rViewData.SetSpellingView( pEditView );
519 0 : Rectangle aRect( Point( 0, 0 ), Point( 0, 0 ) );
520 0 : pEditView->SetOutputArea( aRect );
521 0 : pEngine->SetControlWord( EE_CNTRL_USECHARATTRIBS );
522 0 : pEngine->EnableUndo( false );
523 0 : pEngine->SetPaperSize( aRect.GetSize() );
524 0 : pEngine->SetText( EMPTY_OUSTRING );
525 :
526 : // *** do the conversion *** ----------------------------------------------
527 :
528 0 : pEngine->ClearModifyFlag();
529 0 : pEngine->ConvertAll( *pEditView );
530 :
531 : // *** undo/redo *** ------------------------------------------------------
532 :
533 0 : if( pEngine->IsAnyModified() )
534 : {
535 0 : if (bRecord)
536 : {
537 0 : SCCOL nNewCol = rViewData.GetCurX();
538 0 : SCROW nNewRow = rViewData.GetCurY();
539 0 : rViewData.GetDocShell()->GetUndoManager()->AddUndoAction(
540 : new ScUndoConversion(
541 : pDocSh, rMark,
542 : nCol, nRow, nTab, pUndoDoc,
543 0 : nNewCol, nNewRow, nTab, pRedoDoc, rConvParam ) );
544 : }
545 :
546 0 : sc::SetFormulaDirtyContext aCxt;
547 0 : rDoc.SetAllFormulasDirty(aCxt);
548 :
549 0 : pDocSh->SetDocumentModified();
550 : }
551 : else
552 : {
553 0 : delete pUndoDoc;
554 0 : delete pRedoDoc;
555 : }
556 :
557 : // *** final cleanup *** --------------------------------------------------
558 :
559 0 : rViewData.SetSpellingView( NULL );
560 0 : KillEditView(true);
561 0 : pEngine.reset();
562 0 : pDocSh->PostPaintGridAll();
563 0 : rViewData.GetViewShell()->UpdateInputHandler();
564 0 : rDoc.EnableIdle(bOldEnabled);
565 : }
566 :
567 : // Pasten von FORMAT_FILE-Items
568 : // wird nicht direkt aus Drop aufgerufen, sondern asynchron -> Dialoge sind erlaubt
569 :
570 0 : bool ScViewFunc::PasteFile( const Point& rPos, const OUString& rFile, bool bLink )
571 : {
572 0 : INetURLObject aURL;
573 0 : aURL.SetSmartURL( rFile );
574 0 : OUString aStrURL = aURL.GetMainURL( INetURLObject::NO_DECODE );
575 :
576 : // is it a media URL?
577 0 : if( ::avmedia::MediaWindow::isMediaURL( aStrURL, ""/*TODO?*/ ) )
578 : {
579 0 : const SfxStringItem aMediaURLItem( SID_INSERT_AVMEDIA, aStrURL );
580 0 : return ( 0 != GetViewData().GetDispatcher().Execute(
581 : SID_INSERT_AVMEDIA, SfxCallMode::SYNCHRON,
582 0 : &aMediaURLItem, 0L ) );
583 : }
584 :
585 0 : if (!bLink) // bei bLink nur Grafik oder URL
586 : {
587 : // 1. Kann ich die Datei oeffnen?
588 0 : const SfxFilter* pFlt = NULL;
589 :
590 : // nur nach eigenen Filtern suchen, ohne Auswahlbox (wie in ScDocumentLoader)
591 0 : SfxFilterMatcher aMatcher( ScDocShell::Factory().GetFilterContainer()->GetName() );
592 0 : SfxMedium aSfxMedium( aStrURL, (STREAM_READ | STREAM_SHARE_DENYNONE) );
593 : // #i73992# GuessFilter no longer calls UseInteractionHandler.
594 : // This is UI, so it can be called here.
595 0 : aSfxMedium.UseInteractionHandler(true);
596 0 : ErrCode nErr = aMatcher.GuessFilter( aSfxMedium, &pFlt );
597 :
598 0 : if ( pFlt && !nErr )
599 : {
600 : // Code aus dem SFX geklaut!
601 0 : SfxDispatcher &rDispatcher = GetViewData().GetDispatcher();
602 0 : SfxStringItem aFileNameItem( SID_FILE_NAME, aStrURL );
603 0 : SfxStringItem aFilterItem( SID_FILTER_NAME, pFlt->GetName() );
604 : // #i69524# add target, as in SfxApplication when the Open dialog is used
605 0 : SfxStringItem aTargetItem( SID_TARGETNAME, OUString("_default") );
606 :
607 : // Asynchron oeffnen, kann naemlich auch aus D&D heraus passieren
608 : // und das bekommt dem MAC nicht so gut ...
609 : return ( 0 != rDispatcher.Execute( SID_OPENDOC,
610 0 : SfxCallMode::ASYNCHRON, &aFileNameItem, &aFilterItem, &aTargetItem, 0L) );
611 0 : }
612 : }
613 :
614 : // 2. Kann die Datei ueber die Grafik-Filter eingefuegt werden?
615 : // (als Link, weil Gallery das so anbietet)
616 :
617 : sal_uInt16 nFilterFormat;
618 0 : Graphic aGraphic;
619 0 : GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
620 :
621 0 : if (!rGraphicFilter.ImportGraphic(aGraphic, aURL,
622 0 : GRFILTER_FORMAT_DONTKNOW, &nFilterFormat ))
623 : {
624 0 : if ( bLink )
625 : {
626 0 : OUString aFltName = rGraphicFilter.GetImportFormatName(nFilterFormat);
627 0 : return PasteGraphic( rPos, aGraphic, aStrURL, aFltName );
628 : }
629 : else
630 : {
631 : // #i76709# if bLink isn't set, pass empty URL/filter, so a non-linked image is inserted
632 0 : return PasteGraphic( rPos, aGraphic, EMPTY_OUSTRING, EMPTY_OUSTRING );
633 : }
634 : }
635 :
636 0 : if (bLink) // bei bLink alles, was nicht Grafik ist, als URL
637 : {
638 0 : Rectangle aRect( rPos, Size(0,0) );
639 0 : ScRange aRange = GetViewData().GetDocument()->
640 0 : GetRange( GetViewData().GetTabNo(), aRect );
641 0 : SCCOL nPosX = aRange.aStart.Col();
642 0 : SCROW nPosY = aRange.aStart.Row();
643 :
644 0 : InsertBookmark( aStrURL, aStrURL, nPosX, nPosY );
645 0 : return true;
646 : }
647 : else
648 : {
649 : // 3. Kann die Datei als OLE eingefuegt werden?
650 : // auch nicht-Storages, z.B. Sounds (#38282#)
651 0 : uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
652 :
653 : //TODO/LATER: what about "bLink"?
654 :
655 0 : uno::Sequence < beans::PropertyValue > aMedium(1);
656 0 : aMedium[0].Name = "URL";
657 0 : aMedium[0].Value <<= OUString( aStrURL );
658 :
659 0 : comphelper::EmbeddedObjectContainer aCnt( xStorage );
660 0 : OUString aName;
661 0 : uno::Reference < embed::XEmbeddedObject > xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
662 0 : if( xObj.is() )
663 0 : return PasteObject( rPos, xObj );
664 :
665 : // If an OLE object can't be created, insert a URL button
666 :
667 0 : GetViewData().GetViewShell()->InsertURLButton( aStrURL, aStrURL, EMPTY_OUSTRING, &rPos );
668 0 : return true;
669 0 : }
670 : }
671 :
672 0 : bool ScViewFunc::PasteBookmark( sal_uLong nFormatId,
673 : const ::com::sun::star::uno::Reference<
674 : ::com::sun::star::datatransfer::XTransferable >& rxTransferable,
675 : SCCOL nPosX, SCROW nPosY )
676 : {
677 0 : INetBookmark aBookmark;
678 0 : TransferableDataHelper aDataHelper( rxTransferable );
679 0 : if ( !aDataHelper.GetINetBookmark( nFormatId, aBookmark ) )
680 0 : return false;
681 :
682 0 : InsertBookmark( aBookmark.GetDescription(), aBookmark.GetURL(), nPosX, nPosY );
683 0 : return true;
684 : }
685 :
686 0 : void ScViewFunc::InsertBookmark( const OUString& rDescription, const OUString& rURL,
687 : SCCOL nPosX, SCROW nPosY, const OUString* pTarget,
688 : bool bTryReplace )
689 : {
690 0 : ScViewData& rViewData = GetViewData();
691 0 : if ( rViewData.HasEditView( rViewData.GetActivePart() ) &&
692 0 : nPosX >= rViewData.GetEditStartCol() && nPosX <= rViewData.GetEditEndCol() &&
693 0 : nPosY >= rViewData.GetEditStartRow() && nPosY <= rViewData.GetEditEndRow() )
694 : {
695 : // in die gerade editierte Zelle einfuegen
696 :
697 0 : OUString aTargetFrame;
698 0 : if (pTarget)
699 0 : aTargetFrame = *pTarget;
700 0 : rViewData.GetViewShell()->InsertURLField( rDescription, rURL, aTargetFrame );
701 0 : return;
702 : }
703 :
704 : // in nicht editierte Zelle einfuegen
705 :
706 0 : ScDocument* pDoc = GetViewData().GetDocument();
707 0 : SCTAB nTab = GetViewData().GetTabNo();
708 0 : ScAddress aCellPos( nPosX, nPosY, nTab );
709 0 : EditEngine aEngine( pDoc->GetEnginePool() );
710 :
711 0 : const EditTextObject* pOld = pDoc->GetEditText(aCellPos);
712 0 : if (pOld)
713 0 : aEngine.SetText(*pOld);
714 : else
715 : {
716 0 : OUString aOld;
717 0 : pDoc->GetInputString(nPosX, nPosY, nTab, aOld);
718 0 : if (!aOld.isEmpty())
719 0 : aEngine.SetText(aOld);
720 : }
721 :
722 0 : sal_Int32 nPara = aEngine.GetParagraphCount();
723 0 : if (nPara)
724 0 : --nPara;
725 0 : sal_Int32 nTxtLen = aEngine.GetTextLen(nPara);
726 0 : ESelection aInsSel( nPara, nTxtLen, nPara, nTxtLen );
727 :
728 0 : if ( bTryReplace && HasBookmarkAtCursor( NULL ) )
729 : {
730 : // if called from hyperlink slot and cell contains only a URL,
731 : // replace old URL with new one
732 :
733 0 : aInsSel = ESelection( 0, 0, 0, 1 ); // replace first character (field)
734 : }
735 :
736 0 : SvxURLField aField( rURL, rDescription, SVXURLFORMAT_APPDEFAULT );
737 0 : if (pTarget)
738 0 : aField.SetTargetFrame(*pTarget);
739 0 : aEngine.QuickInsertField( SvxFieldItem( aField, EE_FEATURE_FIELD ), aInsSel );
740 :
741 0 : boost::scoped_ptr<EditTextObject> pData(aEngine.CreateTextObject());
742 0 : EnterData(nPosX, nPosY, nTab, *pData);
743 : }
744 :
745 0 : bool ScViewFunc::HasBookmarkAtCursor( SvxHyperlinkItem* pContent )
746 : {
747 0 : ScAddress aPos( GetViewData().GetCurX(), GetViewData().GetCurY(), GetViewData().GetTabNo() );
748 0 : ScDocument& rDoc = GetViewData().GetDocShell()->GetDocument();
749 :
750 0 : const EditTextObject* pData = rDoc.GetEditText(aPos);
751 0 : if (!pData)
752 0 : return false;
753 :
754 0 : if (!pData->IsFieldObject())
755 : // not a field object.
756 0 : return false;
757 :
758 0 : const SvxFieldItem* pFieldItem = pData->GetField();
759 0 : if (!pFieldItem)
760 : // doesn't have a field item.
761 0 : return false;
762 :
763 0 : const SvxFieldData* pField = pFieldItem->GetField();
764 0 : if (!pField)
765 : // doesn't have a field item data.
766 0 : return false;
767 :
768 0 : if (pField->GetClassId() != com::sun::star::text::textfield::Type::URL)
769 : // not a URL field.
770 0 : return false;
771 :
772 0 : if (pContent)
773 : {
774 0 : const SvxURLField* pURLField = static_cast<const SvxURLField*>(pField);
775 0 : pContent->SetName( pURLField->GetRepresentation() );
776 0 : pContent->SetURL( pURLField->GetURL() );
777 0 : pContent->SetTargetFrame( pURLField->GetTargetFrame() );
778 : }
779 0 : return true;
780 228 : }
781 :
782 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|