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 :
21 : #include <hintids.hxx> // define ITEMIDs
22 : #include <svl/macitem.hxx>
23 : #include <sfx2/frame.hxx>
24 : #include <vcl/msgbox.hxx>
25 : #include <svl/urihelper.hxx>
26 : #include <svl/eitem.hxx>
27 : #include <svl/stritem.hxx>
28 : #include <sfx2/docfile.hxx>
29 : #include <sfx2/fcontnr.hxx>
30 : #include <sfx2/dispatch.hxx>
31 : #include <sfx2/linkmgr.hxx>
32 : #include <fmtinfmt.hxx>
33 : #include <frmatr.hxx>
34 : #include <swtypes.hxx> // SET_CURR_SHELL
35 : #include <wrtsh.hxx>
36 : #include <docsh.hxx>
37 : #include <fldbas.hxx> // Felder
38 : #include <expfld.hxx>
39 : #include <ddefld.hxx>
40 : #include <docufld.hxx>
41 : #include <reffld.hxx>
42 : #include <swundo.hxx>
43 : #include <doc.hxx>
44 : #include <IDocumentUndoRedo.hxx>
45 : #include <viewopt.hxx> // SwViewOptions
46 : #include <frmfmt.hxx> // fuer UpdateTable
47 : #include <swtable.hxx> // fuer UpdateTable
48 : #include <mdiexp.hxx>
49 : #include <view.hxx>
50 : #include <swevent.hxx>
51 : #include <poolfmt.hxx>
52 : #include <section.hxx>
53 : #include <navicont.hxx>
54 : #include <navipi.hxx>
55 : #include <crsskip.hxx>
56 : #include <txtinet.hxx>
57 : #include <cmdid.h>
58 : #include <wrtsh.hrc>
59 : #include "swabstdlg.hxx"
60 : #include "fldui.hrc"
61 : #include <SwRewriter.hxx>
62 :
63 : #include <com/sun/star/document/XDocumentProperties.hpp>
64 : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
65 :
66 : #include <xmloff/odffields.hxx>
67 :
68 0 : void SwWrtShell::Insert(SwField &rFld, SwPaM *pCommentRange)
69 : {
70 0 : ResetCursorStack();
71 0 : if(!CanInsert())
72 0 : return;
73 0 : StartAllAction();
74 :
75 0 : SwRewriter aRewriter;
76 0 : aRewriter.AddRule(UndoArg1, rFld.GetDescription());
77 :
78 0 : StartUndo(UNDO_INSERT, &aRewriter);
79 :
80 0 : if (pCommentRange && GetDoc())
81 : {
82 : // If an annotation field is inserted, take care of the relevant fieldmark.
83 0 : IDocumentMarkAccess* pMarksAccess = GetDoc()->getIDocumentMarkAccess();
84 0 : sw::mark::IFieldmark* pFieldmark = pMarksAccess->makeFieldBookmark(*pCommentRange, OUString(), ODF_COMMENTRANGE);
85 0 : ((SwPostItField&)rFld).SetName(pFieldmark->GetName());
86 : }
87 :
88 0 : bool bDeleted = false;
89 0 : if( HasSelection() )
90 : {
91 0 : bDeleted = DelRight() != 0;
92 : }
93 :
94 0 : SwEditShell::Insert2(rFld, bDeleted);
95 0 : EndUndo();
96 0 : EndAllAction();
97 : }
98 :
99 : /*--------------------------------------------------------------------
100 : Beschreibung: Felder Update anschmeissen
101 : --------------------------------------------------------------------*/
102 :
103 :
104 :
105 0 : void SwWrtShell::UpdateInputFlds( SwInputFieldList* pLst, sal_Bool bOnlyInSel )
106 : {
107 : // ueber die Liste der Eingabefelder gehen und Updaten
108 0 : SwInputFieldList* pTmp = pLst;
109 0 : if( !pTmp )
110 0 : pTmp = new SwInputFieldList( this );
111 :
112 0 : if (bOnlyInSel)
113 0 : pTmp->RemoveUnselectedFlds();
114 :
115 0 : const sal_uInt16 nCnt = pTmp->Count();
116 0 : if(nCnt)
117 : {
118 0 : pTmp->PushCrsr();
119 :
120 0 : sal_Bool bCancel = sal_False;
121 0 : rtl::OString aDlgPos;
122 0 : for( sal_uInt16 i = 0; i < nCnt && !bCancel; ++i )
123 : {
124 0 : pTmp->GotoFieldPos( i );
125 0 : SwField* pField = pTmp->GetField( i );
126 0 : if(pField->GetTyp()->Which() == RES_DROPDOWN)
127 0 : bCancel = StartDropDownFldDlg( pField, sal_True, &aDlgPos );
128 : else
129 0 : bCancel = StartInputFldDlg( pField, sal_True, 0, &aDlgPos);
130 :
131 : // Sonst Updatefehler bei Multiselektion:
132 0 : pTmp->GetField( i )->GetTyp()->UpdateFlds();
133 : }
134 0 : pTmp->PopCrsr();
135 : }
136 :
137 0 : if( !pLst )
138 0 : delete pTmp;
139 0 : }
140 :
141 :
142 : /*--------------------------------------------------------------------
143 : Beschreibung: EingabeDialog fuer ein bestimmtes Feld starten
144 : --------------------------------------------------------------------*/
145 :
146 :
147 :
148 0 : sal_Bool SwWrtShell::StartInputFldDlg( SwField* pFld, sal_Bool bNextButton,
149 : Window* pParentWin, rtl::OString* pWindowState )
150 : {
151 :
152 0 : SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
153 : OSL_ENSURE(pFact, "Dialogdiet fail!");
154 : AbstractFldInputDlg* pDlg = pFact->CreateFldInputDlg( DLG_FLD_INPUT,
155 0 : pParentWin, *this, pFld, bNextButton);
156 : OSL_ENSURE(pDlg, "Dialogdiet fail!");
157 0 : if(pWindowState && !pWindowState->isEmpty())
158 0 : pDlg->SetWindowState(*pWindowState);
159 0 : sal_Bool bRet = RET_CANCEL == pDlg->Execute();
160 0 : if(pWindowState)
161 0 : *pWindowState = pDlg->GetWindowState();
162 :
163 0 : delete pDlg;
164 0 : GetWin()->Update();
165 0 : return bRet;
166 : }
167 :
168 0 : sal_Bool SwWrtShell::StartDropDownFldDlg(SwField* pFld, sal_Bool bNextButton, rtl::OString* pWindowState)
169 : {
170 0 : SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
171 : OSL_ENSURE(pFact, "SwAbstractDialogFactory fail!");
172 :
173 0 : AbstractDropDownFieldDialog* pDlg = pFact->CreateDropDownFieldDialog( NULL, *this, pFld, DLG_FLD_DROPDOWN ,bNextButton );
174 : OSL_ENSURE(pDlg, "Dialogdiet fail!");
175 0 : if(pWindowState && !pWindowState->isEmpty())
176 0 : pDlg->SetWindowState(*pWindowState);
177 0 : sal_uInt16 nRet = pDlg->Execute();
178 0 : if(pWindowState)
179 0 : *pWindowState = pDlg->GetWindowState();
180 0 : delete pDlg;
181 0 : sal_Bool bRet = RET_CANCEL == nRet;
182 0 : GetWin()->Update();
183 0 : if(RET_YES == nRet)
184 : {
185 0 : GetView().GetViewFrame()->GetDispatcher()->Execute(FN_EDIT_FIELD, SFX_CALLMODE_SYNCHRON);
186 : }
187 0 : return bRet;
188 : }
189 :
190 : /*--------------------------------------------------------------------
191 : Beschreibung: Verzeichnis einfuegen Selektion loeschen
192 : --------------------------------------------------------------------*/
193 :
194 :
195 :
196 0 : void SwWrtShell::InsertTableOf(const SwTOXBase& rTOX, const SfxItemSet* pSet)
197 : {
198 0 : if(!CanInsert())
199 0 : return;
200 :
201 0 : if(HasSelection())
202 0 : DelRight();
203 :
204 0 : SwEditShell::InsertTableOf(rTOX, pSet);
205 : }
206 :
207 :
208 : /*--------------------------------------------------------------------
209 : Beschreibung: Verzeichnis Updaten Selektion loeschen
210 : --------------------------------------------------------------------*/
211 :
212 0 : sal_Bool SwWrtShell::UpdateTableOf(const SwTOXBase& rTOX, const SfxItemSet* pSet)
213 : {
214 0 : sal_Bool bResult = sal_False;
215 :
216 0 : if(CanInsert())
217 : {
218 0 : bResult = SwEditShell::UpdateTableOf(rTOX, pSet);
219 :
220 0 : if (pSet == NULL)
221 : {
222 0 : SwDoc *const pDoc_ = GetDoc();
223 0 : if (pDoc_)
224 : {
225 0 : pDoc_->GetIDocumentUndoRedo().DelAllUndoObj();
226 : }
227 : }
228 : }
229 :
230 0 : return bResult;
231 : }
232 :
233 : // handler for click on the field given as parameter.
234 : // the cursor is positioned on the field.
235 :
236 :
237 0 : void SwWrtShell::ClickToField( const SwField& rFld )
238 : {
239 0 : bIsInClickToEdit = sal_True;
240 0 : switch( rFld.GetTyp()->Which() )
241 : {
242 : case RES_JUMPEDITFLD:
243 : {
244 0 : sal_uInt16 nSlotId = 0;
245 0 : switch( rFld.GetFormat() )
246 : {
247 : case JE_FMT_TABLE:
248 0 : nSlotId = FN_INSERT_TABLE;
249 0 : break;
250 :
251 : case JE_FMT_FRAME:
252 0 : nSlotId = FN_INSERT_FRAME;
253 0 : break;
254 :
255 0 : case JE_FMT_GRAPHIC: nSlotId = SID_INSERT_GRAPHIC; break;
256 0 : case JE_FMT_OLE: nSlotId = SID_INSERT_OBJECT; break;
257 :
258 : }
259 :
260 0 : StartAllAction();
261 0 : Right( CRSR_SKIP_CHARS, true, 0, false ); // Select the field.
262 0 : NormalizePam(); // Cursor at the beginning of it.
263 0 : EndAllAction();
264 :
265 0 : if( nSlotId )
266 : {
267 0 : StartUndo( UNDO_START );
268 : //#97295# immediately select the right shell
269 0 : GetView().StopShellTimer();
270 0 : GetView().GetViewFrame()->GetDispatcher()->Execute( nSlotId,
271 0 : SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD );
272 0 : EndUndo( UNDO_END );
273 : }
274 : }
275 0 : break;
276 :
277 : case RES_MACROFLD:
278 : {
279 0 : const SwMacroField *pFld = (const SwMacroField*)&rFld;
280 0 : String sText( rFld.GetPar2() );
281 0 : String sRet( sText );
282 0 : ExecMacro( pFld->GetSvxMacro(), &sRet );
283 :
284 : // return Wert veraendert?
285 0 : if( sRet != sText )
286 : {
287 0 : StartAllAction();
288 0 : ((SwField&)rFld).SetPar2( sRet );
289 0 : ((SwField&)rFld).GetTyp()->UpdateFlds();
290 0 : EndAllAction();
291 0 : }
292 : }
293 0 : break;
294 :
295 : case RES_GETREFFLD:
296 0 : StartAllAction();
297 0 : SwCrsrShell::GotoRefMark( ((SwGetRefField&)rFld).GetSetRefName(),
298 0 : ((SwGetRefField&)rFld).GetSubType(),
299 0 : ((SwGetRefField&)rFld).GetSeqNo() );
300 0 : EndAllAction();
301 0 : break;
302 :
303 : case RES_INPUTFLD:
304 0 : StartInputFldDlg( (SwField*)&rFld, sal_False );
305 0 : break;
306 :
307 : case RES_SETEXPFLD:
308 0 : if( ((SwSetExpField&)rFld).GetInputFlag() )
309 0 : StartInputFldDlg( (SwField*)&rFld, sal_False );
310 0 : break;
311 : case RES_DROPDOWN :
312 0 : StartDropDownFldDlg( (SwField*)&rFld, sal_False );
313 0 : break;
314 : }
315 :
316 0 : bIsInClickToEdit = sal_False;
317 0 : }
318 :
319 :
320 :
321 0 : void SwWrtShell::ClickToINetAttr( const SwFmtINetFmt& rItem, sal_uInt16 nFilter )
322 : {
323 0 : if( !rItem.GetValue().Len() )
324 0 : return ;
325 :
326 0 : bIsInClickToEdit = sal_True;
327 :
328 : // erstmal das evt. gesetzte ObjectSelect Macro ausfuehren
329 0 : const SvxMacro* pMac = rItem.GetMacro( SFX_EVENT_MOUSECLICK_OBJECT );
330 0 : if( pMac )
331 : {
332 0 : SwCallMouseEvent aCallEvent;
333 0 : aCallEvent.Set( &rItem );
334 0 : GetDoc()->CallEvent( SFX_EVENT_MOUSECLICK_OBJECT, aCallEvent, false );
335 : }
336 :
337 : // damit die Vorlagenumsetzung sofort angezeigt wird
338 0 : ::LoadURL( *this, rItem.GetValue(), nFilter, rItem.GetTargetFrame() );
339 0 : const SwTxtINetFmt* pTxtAttr = rItem.GetTxtINetFmt();
340 0 : if( pTxtAttr )
341 : {
342 0 : const_cast<SwTxtINetFmt*>(pTxtAttr)->SetVisited( true );
343 0 : const_cast<SwTxtINetFmt*>(pTxtAttr)->SetVisitedValid( true );
344 : }
345 :
346 0 : bIsInClickToEdit = sal_False;
347 : }
348 :
349 :
350 :
351 0 : sal_Bool SwWrtShell::ClickToINetGrf( const Point& rDocPt, sal_uInt16 nFilter )
352 : {
353 0 : sal_Bool bRet = sal_False;
354 0 : String sURL;
355 0 : String sTargetFrameName;
356 0 : const SwFrmFmt* pFnd = IsURLGrfAtPos( rDocPt, &sURL, &sTargetFrameName );
357 0 : if( pFnd && sURL.Len() )
358 : {
359 0 : bRet = sal_True;
360 : // erstmal das evt. gesetzte ObjectSelect Macro ausfuehren
361 0 : const SvxMacro* pMac = &pFnd->GetMacro().GetMacro( SFX_EVENT_MOUSECLICK_OBJECT );
362 0 : if( pMac )
363 : {
364 0 : SwCallMouseEvent aCallEvent;
365 0 : aCallEvent.Set( EVENT_OBJECT_URLITEM, pFnd );
366 0 : GetDoc()->CallEvent( SFX_EVENT_MOUSECLICK_OBJECT, aCallEvent, false );
367 : }
368 :
369 0 : ::LoadURL(*this, sURL, nFilter, sTargetFrameName);
370 : }
371 0 : return bRet;
372 : }
373 :
374 :
375 0 : void LoadURL( ViewShell& rVSh, const rtl::OUString& rURL, sal_uInt16 nFilter,
376 : const rtl::OUString& rTargetFrameName )
377 : {
378 : OSL_ENSURE( !rURL.isEmpty(), "what should be loaded here?" );
379 0 : if( rURL.isEmpty() )
380 : return ;
381 :
382 : // die Shell kann auch 0 sein !!!!!
383 0 : if ( !rVSh.ISA(SwCrsrShell) )
384 : return;
385 :
386 : //Eine CrsrShell ist auch immer eine WrtShell
387 0 : SwWrtShell &rSh = (SwWrtShell&)rVSh;
388 :
389 0 : SwDocShell* pDShell = rSh.GetView().GetDocShell();
390 : OSL_ENSURE( pDShell, "No DocShell?!");
391 0 : rtl::OUString sTargetFrame(rTargetFrameName);
392 0 : if (sTargetFrame.isEmpty() && pDShell)
393 : {
394 : using namespace ::com::sun::star;
395 : uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
396 0 : pDShell->GetModel(), uno::UNO_QUERY_THROW);
397 : uno::Reference<document::XDocumentProperties> xDocProps
398 0 : = xDPS->getDocumentProperties();
399 0 : sTargetFrame = xDocProps->getDefaultTarget();
400 : }
401 :
402 0 : String sReferer;
403 0 : if( pDShell && pDShell->GetMedium() )
404 0 : sReferer = pDShell->GetMedium()->GetName();
405 0 : SfxViewFrame* pViewFrm = rSh.GetView().GetViewFrame();
406 0 : SfxFrameItem aView( SID_DOCFRAME, pViewFrm );
407 0 : SfxStringItem aName( SID_FILE_NAME, rURL );
408 0 : SfxStringItem aTargetFrameName( SID_TARGETNAME, sTargetFrame );
409 0 : SfxStringItem aReferer( SID_REFERER, sReferer );
410 :
411 0 : SfxBoolItem aNewView( SID_OPEN_NEW_VIEW, sal_False );
412 : //#39076# Silent kann lt. SFX entfernt werden.
413 0 : SfxBoolItem aBrowse( SID_BROWSE, sal_True );
414 :
415 0 : if( nFilter & URLLOAD_NEWVIEW )
416 0 : aTargetFrameName.SetValue( rtl::OUString("_blank") );
417 :
418 : const SfxPoolItem* aArr[] = {
419 : &aName,
420 : &aNewView, /*&aSilent,*/
421 : &aReferer,
422 : &aView, &aTargetFrameName,
423 : &aBrowse,
424 : 0L
425 0 : };
426 :
427 : pViewFrm->GetDispatcher()->GetBindings()->Execute( SID_OPENDOC, aArr,
428 0 : SFX_CALLMODE_ASYNCHRON|SFX_CALLMODE_RECORD );
429 : }
430 :
431 0 : void SwWrtShell::NavigatorPaste( const NaviContentBookmark& rBkmk,
432 : const sal_uInt16 nAction )
433 : {
434 0 : if( EXCHG_IN_ACTION_COPY == nAction )
435 : {
436 : // Einfuegen
437 0 : String sURL = rBkmk.GetURL();
438 : //handelt es sich um ein Sprung innerhalb des akt. Docs?
439 0 : const SwDocShell* pDocShell = GetView().GetDocShell();
440 0 : if(pDocShell->HasName())
441 : {
442 0 : const String rName = pDocShell->GetMedium()->GetURLObject().GetURLNoMark();
443 :
444 0 : if(COMPARE_EQUAL == sURL.CompareTo(rName, rName.Len()))
445 0 : sURL.Erase(0, rName.Len());
446 : }
447 0 : SwFmtINetFmt aFmt( sURL, aEmptyStr );
448 0 : InsertURL( aFmt, rBkmk.GetDescription() );
449 : }
450 : else
451 : {
452 0 : SwSectionData aSection( FILE_LINK_SECTION, GetUniqueSectionName( 0 ) );
453 0 : String aLinkFile( rBkmk.GetURL().GetToken(0, '#') );
454 0 : aLinkFile += sfx2::cTokenSeperator;
455 0 : aLinkFile += sfx2::cTokenSeperator;
456 0 : aLinkFile += rBkmk.GetURL().GetToken(1, '#');
457 0 : aSection.SetLinkFileName( aLinkFile );
458 0 : aSection.SetProtectFlag( true );
459 0 : const SwSection* pIns = InsertSection( aSection );
460 0 : if( EXCHG_IN_ACTION_MOVE == nAction && pIns )
461 : {
462 0 : aSection = SwSectionData(*pIns);
463 0 : aSection.SetLinkFileName( aEmptyStr );
464 0 : aSection.SetType( CONTENT_SECTION );
465 0 : aSection.SetProtectFlag( false );
466 :
467 : // the update of content from linked section at time delete
468 : // the undostack. Then the change of the section dont create
469 : // any undoobject. - BUG 69145
470 0 : sal_Bool bDoesUndo = DoesUndo();
471 0 : SwUndoId nLastUndoId(UNDO_EMPTY);
472 0 : if (GetLastUndoInfo(0, & nLastUndoId))
473 : {
474 0 : if (UNDO_INSSECTION != nLastUndoId)
475 : {
476 0 : DoUndo(false);
477 : }
478 : }
479 0 : UpdateSection( GetSectionFmtPos( *pIns->GetFmt() ), aSection );
480 0 : DoUndo( bDoesUndo );
481 0 : }
482 : }
483 30 : }
484 :
485 :
486 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|