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 <sot/storage.hxx>
28 : #include <svx/hlnkitem.hxx>
29 : #include <editeng/langitem.hxx>
30 : #include <svx/svxerr.hxx>
31 : #include <editeng/unolingu.hxx>
32 :
33 : #include <sfx2/bindings.hxx>
34 : #include <sfx2/dispatch.hxx>
35 : #include <sfx2/docfile.hxx>
36 : #include <sfx2/fcontnr.hxx>
37 : #include <svtools/langtab.hxx>
38 : #include <vcl/graphicfilter.hxx>
39 : #include <svl/stritem.hxx>
40 : #include <svtools/transfer.hxx>
41 : #include <svl/urlbmk.hxx>
42 : #include <svl/sharedstringpool.hxx>
43 : #include <vcl/msgbox.hxx>
44 : #include <avmedia/mediawindow.hxx>
45 :
46 : #include <comphelper/storagehelper.hxx>
47 : #include <comphelper/processfactory.hxx>
48 :
49 : #include "viewfunc.hxx"
50 : #include "docsh.hxx"
51 : #include "document.hxx"
52 : #include "docpool.hxx"
53 : #include "globstr.hrc"
54 : #include "global.hxx"
55 : #include "undoblk.hxx"
56 : #include "undocell.hxx"
57 : #include "formulacell.hxx"
58 : #include "scmod.hxx"
59 : #include "spelleng.hxx"
60 : #include "patattr.hxx"
61 : #include "sc.hrc"
62 : #include "tabvwsh.hxx"
63 : #include "impex.hxx"
64 : #include "editutil.hxx"
65 : #include "editable.hxx"
66 : #include "dociter.hxx"
67 : #include "reffind.hxx"
68 : #include "compiler.hxx"
69 : #include "tokenarray.hxx"
70 : #include <refupdatecontext.hxx>
71 : #include <gridwin.hxx>
72 :
73 : #include <boost/scoped_ptr.hpp>
74 :
75 : using namespace com::sun::star;
76 :
77 : // STATIC DATA -----------------------------------------------------------
78 :
79 : bool bPasteIsDrop = false;
80 :
81 0 : void ScViewFunc::PasteRTF( SCCOL nStartCol, SCROW nStartRow,
82 : const ::com::sun::star::uno::Reference<
83 : ::com::sun::star::datatransfer::XTransferable >& rxTransferable )
84 : {
85 0 : TransferableDataHelper aDataHelper( rxTransferable );
86 0 : if ( aDataHelper.HasFormat( SotClipboardFormatId::EDITENGINE ) )
87 : {
88 0 : HideAllCursors();
89 :
90 0 : ScDocShell* pDocSh = GetViewData().GetDocShell();
91 0 : ScDocument& rDoc = pDocSh->GetDocument();
92 0 : SCTAB nTab = GetViewData().GetTabNo();
93 0 : const bool bRecord (rDoc.IsUndoEnabled());
94 :
95 0 : const ScPatternAttr* pPattern = rDoc.GetPattern( nStartCol, nStartRow, nTab );
96 0 : boost::scoped_ptr<ScTabEditEngine> pEngine(new ScTabEditEngine( *pPattern, rDoc.GetEnginePool() ));
97 0 : pEngine->EnableUndo( false );
98 :
99 0 : vcl::Window* pActWin = GetActiveWin();
100 0 : if (pActWin)
101 : {
102 0 : pEngine->SetPaperSize(Size(100000,100000));
103 0 : VclPtrInstance< vcl::Window > aWin( pActWin );
104 0 : EditView aEditView( pEngine.get(), aWin.get() );
105 0 : aEditView.SetOutputArea(Rectangle(0,0,100000,100000));
106 :
107 : // same method now for clipboard or drag&drop
108 : // mba: clipboard always must contain absolute URLs (could be from alien source)
109 0 : aEditView.InsertText( rxTransferable, OUString(), true );
110 : }
111 :
112 0 : sal_Int32 nParCnt = pEngine->GetParagraphCount();
113 0 : if (nParCnt)
114 : {
115 0 : SCROW nEndRow = nStartRow + static_cast<SCROW>(nParCnt) - 1;
116 0 : if (nEndRow > MAXROW)
117 0 : nEndRow = MAXROW;
118 :
119 0 : ScDocument* pUndoDoc = NULL;
120 0 : if (bRecord)
121 : {
122 0 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
123 0 : pUndoDoc->InitUndo( &rDoc, nTab, nTab );
124 0 : rDoc.CopyToDocument( nStartCol,nStartRow,nTab, nStartCol,nEndRow,nTab, IDF_ALL, false, pUndoDoc );
125 : }
126 :
127 0 : SCROW nRow = nStartRow;
128 :
129 : // Temporarily turn off undo generation for this lot
130 0 : bool bUndoEnabled = rDoc.IsUndoEnabled();
131 0 : rDoc.EnableUndo( false );
132 0 : for( sal_Int32 n = 0; n < nParCnt; n++ )
133 : {
134 0 : boost::scoped_ptr<EditTextObject> pObject(pEngine->CreateTextObject(n));
135 0 : EnterData(nStartCol, nRow, nTab, *pObject, true);
136 0 : if( ++nRow > MAXROW )
137 0 : break;
138 0 : }
139 0 : rDoc.EnableUndo(bUndoEnabled);
140 :
141 0 : if (bRecord)
142 : {
143 0 : ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
144 0 : pRedoDoc->InitUndo( &rDoc, nTab, nTab );
145 0 : rDoc.CopyToDocument( nStartCol,nStartRow,nTab, nStartCol,nEndRow,nTab, IDF_ALL|IDF_NOCAPTIONS, false, pRedoDoc );
146 :
147 0 : ScRange aMarkRange(nStartCol, nStartRow, nTab, nStartCol, nEndRow, nTab);
148 0 : ScMarkData aDestMark;
149 0 : aDestMark.SetMarkArea( aMarkRange );
150 0 : pDocSh->GetUndoManager()->AddUndoAction(
151 : new ScUndoPaste( pDocSh, aMarkRange, aDestMark,
152 0 : pUndoDoc, pRedoDoc, IDF_ALL, NULL));
153 : }
154 : }
155 :
156 0 : pEngine.reset();
157 :
158 0 : ShowAllCursors();
159 : }
160 : else
161 : {
162 0 : HideAllCursors();
163 0 : ScDocShell* pDocSh = GetViewData().GetDocShell();
164 0 : ScImportExport aImpEx( &pDocSh->GetDocument(),
165 0 : ScAddress( nStartCol, nStartRow, GetViewData().GetTabNo() ) );
166 :
167 0 : OUString aStr;
168 0 : tools::SvRef<SotStorageStream> xStream;
169 0 : if ( aDataHelper.GetSotStorageStream( SotClipboardFormatId::RTF, xStream ) && xStream.Is() )
170 : // mba: clipboard always must contain absolute URLs (could be from alien source)
171 0 : aImpEx.ImportStream( *xStream, OUString(), SotClipboardFormatId::RTF );
172 0 : else if ( aDataHelper.GetString( SotClipboardFormatId::RTF, aStr ) )
173 0 : aImpEx.ImportString( aStr, SotClipboardFormatId::RTF );
174 :
175 0 : AdjustRowHeight( nStartRow, aImpEx.GetRange().aEnd.Row() );
176 0 : pDocSh->UpdateOle(&GetViewData());
177 0 : ShowAllCursors();
178 0 : }
179 0 : }
180 0 : void ScViewFunc::DoRefConversion( bool bRecord )
181 : {
182 0 : ScDocument* pDoc = GetViewData().GetDocument();
183 0 : ScMarkData& rMark = GetViewData().GetMarkData();
184 0 : SCTAB nTabCount = pDoc->GetTableCount();
185 0 : if (bRecord && !pDoc->IsUndoEnabled())
186 0 : bRecord = false;
187 :
188 0 : ScRange aMarkRange;
189 0 : rMark.MarkToSimple();
190 0 : bool bMulti = rMark.IsMultiMarked();
191 0 : if (bMulti)
192 0 : rMark.GetMultiMarkArea( aMarkRange );
193 0 : else if (rMark.IsMarked())
194 0 : rMark.GetMarkArea( aMarkRange );
195 : else
196 : {
197 0 : aMarkRange = ScRange( GetViewData().GetCurX(),
198 0 : GetViewData().GetCurY(), GetViewData().GetTabNo() );
199 : }
200 0 : ScEditableTester aTester( pDoc, aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
201 0 : aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(),rMark );
202 0 : if (!aTester.IsEditable())
203 : {
204 0 : ErrorMessage(aTester.GetMessageId());
205 0 : return;
206 : }
207 :
208 0 : ScDocShell* pDocSh = GetViewData().GetDocShell();
209 0 : bool bOk = false;
210 :
211 0 : ScDocument* pUndoDoc = NULL;
212 0 : if (bRecord)
213 : {
214 0 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
215 0 : SCTAB nTab = aMarkRange.aStart.Tab();
216 0 : pUndoDoc->InitUndo( pDoc, nTab, nTab );
217 :
218 0 : if ( rMark.GetSelectCount() > 1 )
219 : {
220 0 : ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
221 0 : for (; itr != itrEnd; ++itr)
222 0 : if ( *itr != nTab )
223 0 : pUndoDoc->AddUndoTab( *itr, *itr );
224 : }
225 0 : ScRange aCopyRange = aMarkRange;
226 0 : aCopyRange.aStart.SetTab(0);
227 0 : aCopyRange.aEnd.SetTab(nTabCount-1);
228 0 : pDoc->CopyToDocument( aCopyRange, IDF_ALL, bMulti, pUndoDoc, &rMark );
229 : }
230 :
231 0 : ScRangeListRef xRanges;
232 0 : GetViewData().GetMultiArea( xRanges );
233 0 : size_t nCount = xRanges->size();
234 :
235 0 : ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
236 0 : for (; itr != itrEnd; ++itr)
237 : {
238 0 : SCTAB i = *itr;
239 0 : for (size_t j = 0; j < nCount; ++j)
240 : {
241 0 : ScRange aRange = *(*xRanges)[j];
242 0 : aRange.aStart.SetTab(i);
243 0 : aRange.aEnd.SetTab(i);
244 0 : ScCellIterator aIter( pDoc, aRange );
245 0 : for (bool bHas = aIter.first(); bHas; bHas = aIter.next())
246 : {
247 0 : if (aIter.getType() != CELLTYPE_FORMULA)
248 0 : continue;
249 :
250 0 : ScFormulaCell* pCell = aIter.getFormulaCell();
251 0 : OUString aOld;
252 0 : pCell->GetFormula(aOld);
253 0 : sal_Int32 nLen = aOld.getLength();
254 0 : ScRefFinder aFinder( aOld, aIter.GetPos(), pDoc, pDoc->GetAddressConvention() );
255 0 : aFinder.ToggleRel( 0, nLen );
256 0 : if (aFinder.GetFound())
257 : {
258 0 : ScAddress aPos = pCell->aPos;
259 0 : OUString aNew = aFinder.GetText();
260 0 : ScCompiler aComp( pDoc, aPos);
261 0 : aComp.SetGrammar(pDoc->GetGrammar());
262 0 : boost::scoped_ptr<ScTokenArray> pArr(aComp.CompileString(aNew));
263 : ScFormulaCell* pNewCell =
264 : new ScFormulaCell(
265 0 : pDoc, aPos, *pArr, formula::FormulaGrammar::GRAM_DEFAULT, MM_NONE);
266 :
267 0 : pDoc->SetFormulaCell(aPos, pNewCell);
268 0 : bOk = true;
269 : }
270 0 : }
271 0 : }
272 : }
273 0 : if (bRecord)
274 : {
275 0 : ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
276 0 : SCTAB nTab = aMarkRange.aStart.Tab();
277 0 : pRedoDoc->InitUndo( pDoc, nTab, nTab );
278 :
279 0 : if ( rMark.GetSelectCount() > 1 )
280 : {
281 0 : itr = rMark.begin();
282 0 : for (; itr != itrEnd; ++itr)
283 0 : if ( *itr != nTab )
284 0 : pRedoDoc->AddUndoTab( *itr, *itr );
285 : }
286 0 : ScRange aCopyRange = aMarkRange;
287 0 : aCopyRange.aStart.SetTab(0);
288 0 : aCopyRange.aEnd.SetTab(nTabCount-1);
289 0 : pDoc->CopyToDocument( aCopyRange, IDF_ALL, bMulti, pRedoDoc, &rMark );
290 :
291 0 : pDocSh->GetUndoManager()->AddUndoAction(
292 : new ScUndoRefConversion( pDocSh,
293 0 : aMarkRange, rMark, pUndoDoc, pRedoDoc, bMulti, IDF_ALL) );
294 : }
295 :
296 0 : pDocSh->PostPaint( aMarkRange, PAINT_GRID );
297 0 : pDocSh->UpdateOle(&GetViewData());
298 0 : pDocSh->SetDocumentModified();
299 0 : CellContentChanged();
300 :
301 0 : if (!bOk)
302 0 : ErrorMessage(STR_ERR_NOREF);
303 : }
304 : // Thesaurus - Undo ok
305 0 : void ScViewFunc::DoThesaurus( bool bRecord )
306 : {
307 : SCCOL nCol;
308 : SCROW nRow;
309 : SCTAB nTab;
310 0 : ScDocShell* pDocSh = GetViewData().GetDocShell();
311 0 : ScDocument& rDoc = pDocSh->GetDocument();
312 0 : ScMarkData& rMark = GetViewData().GetMarkData();
313 0 : ScSplitPos eWhich = GetViewData().GetActivePart();
314 : EESpellState eState;
315 0 : EditView* pEditView = NULL;
316 0 : boost::scoped_ptr<ESelection> pEditSel;
317 0 : boost::scoped_ptr<ScEditEngineDefaulter> pThesaurusEngine;
318 0 : bool bIsEditMode = GetViewData().HasEditView(eWhich);
319 0 : if (bRecord && !rDoc.IsUndoEnabled())
320 0 : bRecord = false;
321 0 : if (bIsEditMode) // Edit-Mode aktiv
322 : {
323 0 : GetViewData().GetEditView(eWhich, pEditView, nCol, nRow);
324 0 : pEditSel.reset(new ESelection(pEditView->GetSelection()));
325 0 : SC_MOD()->InputEnterHandler();
326 0 : GetViewData().GetBindings().Update(); // sonst kommt der Sfx durcheinander...
327 : }
328 : else
329 : {
330 0 : nCol = GetViewData().GetCurX();
331 0 : nRow = GetViewData().GetCurY();
332 : }
333 0 : nTab = GetViewData().GetTabNo();
334 :
335 0 : ScAddress aPos(nCol, nRow, nTab);
336 0 : ScEditableTester aTester( &rDoc, nCol, nRow, nCol, nRow, rMark );
337 0 : if (!aTester.IsEditable())
338 : {
339 0 : ErrorMessage(aTester.GetMessageId());
340 0 : return;
341 : }
342 :
343 0 : ScCellValue aOldText;
344 0 : aOldText.assign(rDoc, aPos);
345 0 : if (aOldText.meType != CELLTYPE_STRING && aOldText.meType != CELLTYPE_EDIT)
346 : {
347 0 : ErrorMessage(STR_THESAURUS_NO_STRING);
348 0 : return;
349 : }
350 :
351 0 : uno::Reference<linguistic2::XSpellChecker1> xSpeller = LinguMgr::GetSpellChecker();
352 :
353 0 : pThesaurusEngine.reset(new ScEditEngineDefaulter(rDoc.GetEnginePool()));
354 0 : pThesaurusEngine->SetEditTextObjectPool( rDoc.GetEditPool() );
355 0 : pThesaurusEngine->SetRefDevice(GetViewData().GetActiveWin());
356 0 : pThesaurusEngine->SetSpeller(xSpeller);
357 0 : MakeEditView(pThesaurusEngine.get(), nCol, nRow );
358 0 : const ScPatternAttr* pPattern = NULL;
359 : boost::scoped_ptr<SfxItemSet> pEditDefaults(
360 0 : new SfxItemSet(pThesaurusEngine->GetEmptyItemSet()));
361 0 : pPattern = rDoc.GetPattern(nCol, nRow, nTab);
362 0 : if (pPattern)
363 : {
364 0 : pPattern->FillEditItemSet( pEditDefaults.get() );
365 0 : pThesaurusEngine->SetDefaults( *pEditDefaults );
366 : }
367 :
368 0 : if (aOldText.meType == CELLTYPE_EDIT)
369 0 : pThesaurusEngine->SetText(*aOldText.mpEditText);
370 : else
371 0 : pThesaurusEngine->SetText(aOldText.getString(&rDoc));
372 :
373 0 : pEditView = GetViewData().GetEditView(GetViewData().GetActivePart());
374 0 : if (pEditSel)
375 0 : pEditView->SetSelection(*pEditSel);
376 : else
377 0 : pEditView->SetSelection(ESelection(0,0,0,0));
378 :
379 0 : pThesaurusEngine->ClearModifyFlag();
380 :
381 : // language is now in EditEngine attributes -> no longer passed to StartThesaurus
382 :
383 0 : eState = pEditView->StartThesaurus();
384 : OSL_ENSURE(eState != EE_SPELL_NOSPELLER, "No SpellChecker");
385 :
386 0 : if (eState == EE_SPELL_ERRORFOUND) // sollte spaeter durch Wrapper geschehen!
387 : {
388 0 : LanguageType eLnge = ScViewUtil::GetEffLanguage( &rDoc, ScAddress( nCol, nRow, nTab ) );
389 0 : OUString aErr = SvtLanguageTable::GetLanguageString(eLnge);
390 0 : aErr += ScGlobal::GetRscString( STR_SPELLING_NO_LANG );
391 0 : ScopedVclPtrInstance< 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 : if (rDoc.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(rDoc.GetSharedStringPool().intern(aStr));
409 0 : rDoc.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& rDoc = 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 && !rDoc.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( &rDoc, 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( &rDoc, nTab, nTab );
477 0 : pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
478 0 : pRedoDoc->InitUndo( &rDoc, 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 = rDoc.IsIdleEnabled();
495 0 : rDoc.EnableIdle(false); // stop online spelling
496 :
497 : // *** create and init the edit engine *** --------------------------------
498 :
499 0 : boost::scoped_ptr<ScConversionEngineBase> pEngine;
500 0 : switch( rConvParam.GetType() )
501 : {
502 : case SC_CONVERSION_SPELLCHECK:
503 : pEngine.reset(new ScSpellingEngine(
504 0 : rDoc.GetEnginePool(), rViewData, pUndoDoc, pRedoDoc, LinguMgr::GetSpellChecker() ));
505 0 : break;
506 : case SC_CONVERSION_HANGULHANJA:
507 : case SC_CONVERSION_CHINESE_TRANSL:
508 : pEngine.reset(new ScTextConversionEngine(
509 0 : rDoc.GetEnginePool(), rViewData, rConvParam, pUndoDoc, pRedoDoc ));
510 0 : break;
511 : default:
512 : OSL_FAIL( "ScViewFunc::DoSheetConversion - unknown conversion type" );
513 : }
514 :
515 0 : MakeEditView( pEngine.get(), 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( EEControlBits::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 : rDoc.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 : pEngine.reset();
563 0 : pDocSh->PostPaintGridAll();
564 0 : rViewData.GetViewShell()->UpdateInputHandler();
565 0 : rDoc.EnableIdle(bOldEnabled);
566 : }
567 :
568 : // Pasten von SotClipboardFormatId::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, SfxCallMode::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, (StreamMode::READ | StreamMode::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 : SfxCallMode::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 0 : if (!rGraphicFilter.ImportGraphic(aGraphic, aURL,
623 0 : GRFILTER_FORMAT_DONTKNOW, &nFilterFormat ))
624 : {
625 0 : if ( bLink )
626 : {
627 0 : OUString aFltName = rGraphicFilter.GetImportFormatName(nFilterFormat);
628 0 : return PasteGraphic( rPos, aGraphic, aStrURL, aFltName );
629 : }
630 : else
631 : {
632 : // #i76709# if bLink isn't set, pass empty URL/filter, so a non-linked image is inserted
633 0 : return PasteGraphic( rPos, aGraphic, EMPTY_OUSTRING, EMPTY_OUSTRING );
634 : }
635 : }
636 :
637 0 : if (bLink) // bei bLink alles, was nicht Grafik ist, als URL
638 : {
639 0 : Rectangle aRect( rPos, Size(0,0) );
640 0 : ScRange aRange = GetViewData().GetDocument()->
641 0 : GetRange( GetViewData().GetTabNo(), aRect );
642 0 : SCCOL nPosX = aRange.aStart.Col();
643 0 : SCROW nPosY = aRange.aStart.Row();
644 :
645 0 : InsertBookmark( aStrURL, aStrURL, nPosX, nPosY );
646 0 : return true;
647 : }
648 : else
649 : {
650 : // 3. Kann die Datei als OLE eingefuegt werden?
651 : // auch nicht-Storages, z.B. Sounds (#38282#)
652 0 : uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
653 :
654 : //TODO/LATER: what about "bLink"?
655 :
656 0 : uno::Sequence < beans::PropertyValue > aMedium(1);
657 0 : aMedium[0].Name = "URL";
658 0 : aMedium[0].Value <<= OUString( aStrURL );
659 :
660 0 : comphelper::EmbeddedObjectContainer aCnt( xStorage );
661 0 : OUString aName;
662 0 : uno::Reference < embed::XEmbeddedObject > xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
663 0 : if( xObj.is() )
664 0 : return PasteObject( rPos, xObj );
665 :
666 : // If an OLE object can't be created, insert a URL button
667 :
668 0 : GetViewData().GetViewShell()->InsertURLButton( aStrURL, aStrURL, EMPTY_OUSTRING, &rPos );
669 0 : return true;
670 0 : }
671 : }
672 :
673 0 : bool ScViewFunc::PasteBookmark( SotClipboardFormatId nFormatId,
674 : const ::com::sun::star::uno::Reference<
675 : ::com::sun::star::datatransfer::XTransferable >& rxTransferable,
676 : SCCOL nPosX, SCROW nPosY )
677 : {
678 0 : INetBookmark aBookmark;
679 0 : TransferableDataHelper aDataHelper( rxTransferable );
680 0 : if ( !aDataHelper.GetINetBookmark( nFormatId, aBookmark ) )
681 0 : return false;
682 :
683 0 : InsertBookmark( aBookmark.GetDescription(), aBookmark.GetURL(), nPosX, nPosY );
684 0 : return true;
685 : }
686 :
687 0 : void ScViewFunc::InsertBookmark( const OUString& rDescription, const OUString& rURL,
688 : SCCOL nPosX, SCROW nPosY, const OUString* pTarget,
689 : bool bTryReplace )
690 : {
691 0 : ScViewData& rViewData = GetViewData();
692 0 : if ( rViewData.HasEditView( rViewData.GetActivePart() ) &&
693 0 : nPosX >= rViewData.GetEditStartCol() && nPosX <= rViewData.GetEditEndCol() &&
694 0 : nPosY >= rViewData.GetEditStartRow() && nPosY <= rViewData.GetEditEndRow() )
695 : {
696 : // in die gerade editierte Zelle einfuegen
697 :
698 0 : OUString aTargetFrame;
699 0 : if (pTarget)
700 0 : aTargetFrame = *pTarget;
701 0 : rViewData.GetViewShell()->InsertURLField( rDescription, rURL, aTargetFrame );
702 0 : return;
703 : }
704 :
705 : // in nicht editierte Zelle einfuegen
706 :
707 0 : ScDocument* pDoc = GetViewData().GetDocument();
708 0 : SCTAB nTab = GetViewData().GetTabNo();
709 0 : ScAddress aCellPos( nPosX, nPosY, nTab );
710 0 : EditEngine aEngine( pDoc->GetEnginePool() );
711 :
712 0 : const EditTextObject* pOld = pDoc->GetEditText(aCellPos);
713 0 : if (pOld)
714 0 : aEngine.SetText(*pOld);
715 : else
716 : {
717 0 : OUString aOld;
718 0 : pDoc->GetInputString(nPosX, nPosY, nTab, aOld);
719 0 : if (!aOld.isEmpty())
720 0 : aEngine.SetText(aOld);
721 : }
722 :
723 0 : sal_Int32 nPara = aEngine.GetParagraphCount();
724 0 : if (nPara)
725 0 : --nPara;
726 0 : sal_Int32 nTxtLen = aEngine.GetTextLen(nPara);
727 0 : ESelection aInsSel( nPara, nTxtLen, nPara, nTxtLen );
728 :
729 0 : if ( bTryReplace && HasBookmarkAtCursor( NULL ) )
730 : {
731 : // if called from hyperlink slot and cell contains only a URL,
732 : // replace old URL with new one
733 :
734 0 : aInsSel = ESelection( 0, 0, 0, 1 ); // replace first character (field)
735 : }
736 :
737 0 : SvxURLField aField( rURL, rDescription, SVXURLFORMAT_APPDEFAULT );
738 0 : if (pTarget)
739 0 : aField.SetTargetFrame(*pTarget);
740 0 : aEngine.QuickInsertField( SvxFieldItem( aField, EE_FEATURE_FIELD ), aInsSel );
741 :
742 0 : boost::scoped_ptr<EditTextObject> pData(aEngine.CreateTextObject());
743 0 : EnterData(nPosX, nPosY, nTab, *pData);
744 : }
745 :
746 0 : bool ScViewFunc::HasBookmarkAtCursor( SvxHyperlinkItem* pContent )
747 : {
748 0 : ScAddress aPos( GetViewData().GetCurX(), GetViewData().GetCurY(), GetViewData().GetTabNo() );
749 0 : ScDocument& rDoc = GetViewData().GetDocShell()->GetDocument();
750 :
751 0 : const EditTextObject* pData = rDoc.GetEditText(aPos);
752 0 : if (!pData)
753 0 : return false;
754 :
755 0 : if (!pData->IsFieldObject())
756 : // not a field object.
757 0 : return false;
758 :
759 0 : const SvxFieldItem* pFieldItem = pData->GetField();
760 0 : if (!pFieldItem)
761 : // doesn't have a field item.
762 0 : return false;
763 :
764 0 : const SvxFieldData* pField = pFieldItem->GetField();
765 0 : if (!pField)
766 : // doesn't have a field item data.
767 0 : return false;
768 :
769 0 : if (pField->GetClassId() != com::sun::star::text::textfield::Type::URL)
770 : // not a URL field.
771 0 : return false;
772 :
773 0 : if (pContent)
774 : {
775 0 : const SvxURLField* pURLField = static_cast<const SvxURLField*>(pField);
776 0 : pContent->SetName( pURLField->GetRepresentation() );
777 0 : pContent->SetURL( pURLField->GetURL() );
778 0 : pContent->SetTargetFrame( pURLField->GetTargetFrame() );
779 : }
780 0 : return true;
781 156 : }
782 :
783 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|