1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26
27 #include <hintids.hxx> // define ITEMIDs
28 #include <svl/macitem.hxx>
29 #include <sfx2/frame.hxx>
30 #include <vcl/msgbox.hxx>
31 #include <svl/urihelper.hxx>
32 #include <svl/eitem.hxx>
33 #include <svl/stritem.hxx>
34 #include <sfx2/docfile.hxx>
35 #include <sfx2/fcontnr.hxx>
36 #include <sfx2/dispatch.hxx>
37 #include <sfx2/linkmgr.hxx>
38 #include <fmtinfmt.hxx>
39 #include <frmatr.hxx>
40 #include <swtypes.hxx> // SET_CURR_SHELL
41 #include <wrtsh.hxx>
42 #include <docsh.hxx>
43 #include <fldbas.hxx> // Felder
44 #include <expfld.hxx>
45 #include <ddefld.hxx>
46 #include <docufld.hxx>
47 #include <reffld.hxx>
48 #include <swundo.hxx>
49 #include <doc.hxx>
50 #include <IDocumentUndoRedo.hxx>
51 #include <viewopt.hxx> // SwViewOptions
52 #include <frmfmt.hxx> // fuer UpdateTable
53 #include <swtable.hxx> // fuer UpdateTable
54 #include <mdiexp.hxx>
55 #include <view.hxx>
56 #include <swevent.hxx>
57 #include <poolfmt.hxx>
58 #include <section.hxx>
59 #include <navicont.hxx>
60 #include <navipi.hxx>
61 #include <crsskip.hxx>
62 #include <txtinet.hxx>
63 #include <cmdid.h>
64 #include <wrtsh.hrc>
65 #include "swabstdlg.hxx"
66 #include "fldui.hrc"
67 #include <SwRewriter.hxx>
68
69 #include <com/sun/star/document/XDocumentProperties.hpp>
70 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
71
72
73 /*------------------------------------------------------------------------
74 Beschreibung:
75 ------------------------------------------------------------------------*/
76
Insert(SwField & rFld)77 void SwWrtShell::Insert( SwField& rFld )
78 {
79 ResetCursorStack();
80 if(!_CanInsert())
81 return;
82 StartAllAction();
83
84 SwRewriter aRewriter;
85 aRewriter.AddRule(UNDO_ARG1, rFld.GetDescription());
86
87 StartUndo(UNDO_INSERT, &aRewriter);
88
89 bool bDeleted = false;
90 const SwPaM* pAnnotationTextRange = NULL;
91 if ( HasSelection() )
92 {
93 if ( rFld.GetTyp()->Which() == RES_POSTITFLD )
94 {
95 // for annotation fields:
96 // - keep the current selection in order to create a corresponding annotation mark
97 // - collapse cursor to its end
98 if ( IsTableMode() )
99 {
100 GetTblCrs()->Normalize( sal_False );
101 const SwPosition rStartPos( *(GetTblCrs()->GetMark()->nNode.GetNode().GetCntntNode()), 0 );
102 KillPams();
103 if ( !IsEndOfPara() )
104 {
105 EndPara();
106 }
107 const SwPosition rEndPos( *GetCurrentShellCursor().GetPoint() );
108 pAnnotationTextRange = new SwPaM( rStartPos, rEndPos );
109 }
110 else
111 {
112 NormalizePam( sal_False );
113 const SwPaM& rCurrPaM = GetCurrentShellCursor();
114 pAnnotationTextRange = new SwPaM( *rCurrPaM.GetPoint(), *rCurrPaM.GetMark() );
115 ClearMark();
116 }
117 }
118 else
119 {
120 bDeleted = DelRight() != 0;
121 }
122 }
123
124 SwEditShell::Insert2(rFld, bDeleted);
125
126 if ( pAnnotationTextRange != NULL )
127 {
128 if ( GetDoc() != NULL )
129 {
130 IDocumentMarkAccess* pMarksAccess = GetDoc()->getIDocumentMarkAccess();
131 pMarksAccess->makeAnnotationMark( *pAnnotationTextRange, ::rtl::OUString() );
132 }
133 delete pAnnotationTextRange;
134 }
135
136 EndUndo();
137 EndAllAction();
138 }
139
140 /*--------------------------------------------------------------------
141 Beschreibung: Felder Update anschmeissen
142 --------------------------------------------------------------------*/
143
144
145
UpdateInputFlds(SwInputFieldList * pLst)146 void SwWrtShell::UpdateInputFlds( SwInputFieldList* pLst )
147 {
148 // ueber die Liste der Eingabefelder gehen und Updaten
149 SwInputFieldList* pTmp = pLst;
150 if( !pTmp )
151 pTmp = new SwInputFieldList( this );
152
153 const sal_uInt16 nCnt = pTmp->Count();
154 if(nCnt)
155 {
156 pTmp->PushCrsr();
157
158 sal_Bool bCancel = sal_False;
159 ByteString aDlgPos;
160 for( sal_uInt16 i = 0; i < nCnt && !bCancel; ++i )
161 {
162 pTmp->GotoFieldPos( i );
163 SwField* pField = pTmp->GetField( i );
164 if(pField->GetTyp()->Which() == RES_DROPDOWN)
165 bCancel = StartDropDownFldDlg( pField, sal_True, &aDlgPos );
166 else
167 bCancel = StartInputFldDlg( pField, sal_True, 0, &aDlgPos);
168
169 // Sonst Updatefehler bei Multiselektion:
170 pTmp->GetField( i )->GetTyp()->UpdateFlds();
171 }
172 pTmp->PopCrsr();
173 }
174
175 if( !pLst )
176 delete pTmp;
177 }
178
179
180 /*--------------------------------------------------------------------
181 Beschreibung: EingabeDialog fuer ein bestimmtes Feld starten
182 --------------------------------------------------------------------*/
183
184
185
StartInputFldDlg(SwField * pFld,sal_Bool bNextButton,Window * pParentWin,ByteString * pWindowState)186 sal_Bool SwWrtShell::StartInputFldDlg( SwField* pFld, sal_Bool bNextButton,
187 Window* pParentWin, ByteString* pWindowState )
188 {
189 //JP 14.08.96: Bug 30332 - nach Umbau der modularietaet im SFX, muss jetzt
190 // das TopWindow der Application benutzt werden.
191 // SwFldInputDlg* pDlg = new SwFldInputDlg( GetWin(), *this, pFld );
192
193 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
194 DBG_ASSERT(pFact, "Dialogdiet fail!");
195 AbstractFldInputDlg* pDlg = pFact->CreateFldInputDlg( DLG_FLD_INPUT,
196 pParentWin, *this, pFld, bNextButton);
197 DBG_ASSERT(pDlg, "Dialogdiet fail!");
198 if(pWindowState && pWindowState->Len())
199 pDlg->SetWindowState(*pWindowState);
200 sal_Bool bRet = RET_CANCEL == pDlg->Execute();
201 if(pWindowState)
202 *pWindowState = pDlg->GetWindowState();
203
204 delete pDlg;
205 GetWin()->Update();
206 return bRet;
207 }
208 /* -----------------17.06.2003 10:18-----------------
209
210 --------------------------------------------------*/
StartDropDownFldDlg(SwField * pFld,sal_Bool bNextButton,ByteString * pWindowState)211 sal_Bool SwWrtShell::StartDropDownFldDlg(SwField* pFld, sal_Bool bNextButton, ByteString* pWindowState)
212 {
213 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
214 DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!");
215
216 AbstractDropDownFieldDialog* pDlg = pFact->CreateDropDownFieldDialog( NULL, *this, pFld, DLG_FLD_DROPDOWN ,bNextButton );
217 DBG_ASSERT(pDlg, "Dialogdiet fail!");
218 if(pWindowState && pWindowState->Len())
219 pDlg->SetWindowState(*pWindowState);
220 sal_uInt16 nRet = pDlg->Execute();
221 if(pWindowState)
222 *pWindowState = pDlg->GetWindowState();
223 delete pDlg;
224 sal_Bool bRet = RET_CANCEL == nRet;
225 GetWin()->Update();
226 if(RET_YES == nRet)
227 {
228 GetView().GetViewFrame()->GetDispatcher()->Execute(FN_EDIT_FIELD, SFX_CALLMODE_SYNCHRON);
229 }
230 return bRet;
231 }
232
233 /*--------------------------------------------------------------------
234 Beschreibung: Verzeichnis einfuegen Selektion loeschen
235 --------------------------------------------------------------------*/
236
237
238
InsertTableOf(const SwTOXBase & rTOX,const SfxItemSet * pSet)239 void SwWrtShell::InsertTableOf(const SwTOXBase& rTOX, const SfxItemSet* pSet)
240 {
241 if(!_CanInsert())
242 return;
243
244 if(HasSelection())
245 DelRight();
246
247 SwEditShell::InsertTableOf(rTOX, pSet);
248 }
249
250
251 /*--------------------------------------------------------------------
252 Beschreibung: Verzeichnis Updaten Selektion loeschen
253 --------------------------------------------------------------------*/
254
UpdateTableOf(const SwTOXBase & rTOX,const SfxItemSet * pSet)255 sal_Bool SwWrtShell::UpdateTableOf(const SwTOXBase& rTOX, const SfxItemSet* pSet)
256 {
257 sal_Bool bResult = sal_False;
258
259 if(_CanInsert())
260 {
261 bResult = SwEditShell::UpdateTableOf(rTOX, pSet);
262
263 if (pSet == NULL)
264 {
265 SwDoc *const pDoc_ = GetDoc();
266 if (pDoc_)
267 {
268 pDoc_->GetIDocumentUndoRedo().DelAllUndoObj();
269 }
270 }
271 }
272
273 return bResult;
274 }
275
276 // handler for click on the field given as parameter.
277 // the cursor is positioned on the field.
278
279
ClickToField(const SwField & rFld)280 void SwWrtShell::ClickToField( const SwField& rFld )
281 {
282 bIsInClickToEdit = sal_True;
283 switch( rFld.GetTyp()->Which() )
284 {
285 case RES_JUMPEDITFLD:
286 {
287 sal_uInt16 nSlotId = 0;
288 switch( rFld.GetFormat() )
289 {
290 case JE_FMT_TABLE:
291 nSlotId = FN_INSERT_TABLE;
292 break;
293
294 case JE_FMT_FRAME:
295 nSlotId = FN_INSERT_FRAME;
296 break;
297
298 case JE_FMT_GRAPHIC: nSlotId = SID_INSERT_GRAPHIC; break;
299 case JE_FMT_OLE: nSlotId = SID_INSERT_OBJECT; break;
300
301 // case JE_FMT_TEXT:
302 }
303
304 Right( CRSR_SKIP_CHARS, sal_True, 1, sal_False ); // Feld selektieren
305
306 if( nSlotId )
307 {
308 StartUndo( UNDO_START );
309 //#97295# immediately select the right shell
310 GetView().StopShellTimer();
311 GetView().GetViewFrame()->GetDispatcher()->Execute( nSlotId,
312 SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD );
313 EndUndo( UNDO_END );
314 }
315 }
316 break;
317
318 case RES_MACROFLD:
319 {
320 const SwMacroField *pFld = (const SwMacroField*)&rFld;
321 String sText( rFld.GetPar2() );
322 String sRet( sText );
323 ExecMacro( pFld->GetSvxMacro(), &sRet );
324
325 // return Wert veraendert?
326 if( sRet != sText )
327 {
328 StartAllAction();
329 ((SwField&)rFld).SetPar2( sRet );
330 ((SwField&)rFld).GetTyp()->UpdateFlds();
331 EndAllAction();
332 }
333 }
334 break;
335
336 case RES_GETREFFLD:
337 StartAllAction();
338 SwCrsrShell::GotoRefMark( ((SwGetRefField&)rFld).GetSetRefName(),
339 ((SwGetRefField&)rFld).GetSubType(),
340 ((SwGetRefField&)rFld).GetSeqNo() );
341 EndAllAction();
342 break;
343
344 case RES_INPUTFLD:
345 {
346 const SwInputField* pInputField = dynamic_cast<const SwInputField*>(&rFld);
347 if ( pInputField == NULL )
348 {
349 StartInputFldDlg( (SwField*)&rFld, sal_False );
350 }
351 }
352 break;
353
354 case RES_SETEXPFLD:
355 if( ((SwSetExpField&)rFld).GetInputFlag() )
356 StartInputFldDlg( (SwField*)&rFld, sal_False );
357 break;
358 case RES_DROPDOWN :
359 StartDropDownFldDlg( (SwField*)&rFld, sal_False );
360 break;
361 }
362
363 bIsInClickToEdit = sal_False;
364 }
365
366
ClickToINetAttr(const SwFmtINetFmt & rItem,sal_uInt16 nFilter)367 void SwWrtShell::ClickToINetAttr( const SwFmtINetFmt& rItem, sal_uInt16 nFilter )
368 {
369 if( !rItem.GetValue().Len() )
370 return ;
371
372 bIsInClickToEdit = sal_True;
373
374 // erstmal das evt. gesetzte ObjectSelect Macro ausfuehren
375 const SvxMacro* pMac = rItem.GetMacro( SFX_EVENT_MOUSECLICK_OBJECT );
376 if( pMac )
377 {
378 SwCallMouseEvent aCallEvent;
379 aCallEvent.Set( &rItem );
380 GetDoc()->CallEvent( SFX_EVENT_MOUSECLICK_OBJECT, aCallEvent, sal_False );
381 }
382
383 // damit die Vorlagenumsetzung sofort angezeigt wird
384 ::LoadURL( rItem.GetValue(), this, nFilter, &rItem.GetTargetFrame() );
385 const SwTxtINetFmt* pTxtAttr = rItem.GetTxtINetFmt();
386 if( pTxtAttr )
387 {
388 const_cast<SwTxtINetFmt*>(pTxtAttr)->SetVisited( true );
389 const_cast<SwTxtINetFmt*>(pTxtAttr)->SetVisitedValid( true );
390 }
391
392 bIsInClickToEdit = sal_False;
393 }
394
395
396
ClickToINetGrf(const Point & rDocPt,sal_uInt16 nFilter)397 sal_Bool SwWrtShell::ClickToINetGrf( const Point& rDocPt, sal_uInt16 nFilter )
398 {
399 sal_Bool bRet = sal_False;
400 String sURL;
401 String sTargetFrameName;
402 const SwFrmFmt* pFnd = IsURLGrfAtPos( rDocPt, &sURL, &sTargetFrameName );
403 if( pFnd && sURL.Len() )
404 {
405 bRet = sal_True;
406 // erstmal das evt. gesetzte ObjectSelect Macro ausfuehren
407 const SvxMacro* pMac = &pFnd->GetMacro().GetMacro( SFX_EVENT_MOUSECLICK_OBJECT );
408 if( pMac )
409 {
410 SwCallMouseEvent aCallEvent;
411 aCallEvent.Set( EVENT_OBJECT_URLITEM, pFnd );
412 GetDoc()->CallEvent( SFX_EVENT_MOUSECLICK_OBJECT, aCallEvent, sal_False );
413 }
414
415 ::LoadURL( sURL, this, nFilter, &sTargetFrameName);
416 }
417 return bRet;
418 }
419
420
LoadURL(const String & rURL,ViewShell * pVSh,sal_uInt16 nFilter,const String * pTargetFrameName)421 void LoadURL( const String& rURL, ViewShell* pVSh, sal_uInt16 nFilter,
422 const String *pTargetFrameName )
423 {
424 ASSERT( rURL.Len() && pVSh, "was soll hier geladen werden?" );
425 if( !rURL.Len() || !pVSh )
426 return ;
427
428 // die Shell kann auch 0 sein !!!!!
429 SwWrtShell *pSh = 0;
430 if ( pVSh && pVSh->ISA(SwCrsrShell) )
431 {
432 //Eine CrsrShell ist auch immer eine WrtShell
433 pSh = (SwWrtShell*)pVSh;
434 }
435 else
436 return;
437
438 SwDocShell* pDShell = pSh->GetView().GetDocShell();
439 DBG_ASSERT( pDShell, "No DocShell?!");
440 String sTargetFrame;
441 if( pTargetFrameName && pTargetFrameName->Len() )
442 sTargetFrame = *pTargetFrameName;
443 else if( pDShell ) {
444 using namespace ::com::sun::star;
445 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
446 pDShell->GetModel(), uno::UNO_QUERY_THROW);
447 uno::Reference<document::XDocumentProperties> xDocProps
448 = xDPS->getDocumentProperties();
449 sTargetFrame = xDocProps->getDefaultTarget();
450 }
451
452 String sReferer;
453 if( pDShell && pDShell->GetMedium() )
454 sReferer = pDShell->GetMedium()->GetName();
455 SfxViewFrame* pViewFrm = pSh->GetView().GetViewFrame();
456 SfxFrameItem aView( SID_DOCFRAME, pViewFrm );
457 SfxStringItem aName( SID_FILE_NAME, rURL );
458 SfxStringItem aTargetFrameName( SID_TARGETNAME, sTargetFrame );
459 SfxStringItem aReferer( SID_REFERER, sReferer );
460
461 SfxBoolItem aNewView( SID_OPEN_NEW_VIEW, sal_False );
462 //#39076# Silent kann lt. SFX entfernt werden.
463 // SfxBoolItem aSilent( SID_SILENT, sal_True );
464 SfxBoolItem aBrowse( SID_BROWSE, sal_True );
465
466 if( nFilter & URLLOAD_NEWVIEW )
467 aTargetFrameName.SetValue( String::CreateFromAscii("_blank") );
468
469 const SfxPoolItem* aArr[] = {
470 &aName,
471 &aNewView, /*&aSilent,*/
472 &aReferer,
473 &aView, &aTargetFrameName,
474 &aBrowse,
475 0L
476 };
477
478 pViewFrm->GetDispatcher()->GetBindings()->Execute( SID_OPENDOC, aArr,
479 SFX_CALLMODE_ASYNCHRON|SFX_CALLMODE_RECORD );
480 }
481
NavigatorPaste(const NaviContentBookmark & rBkmk,const sal_uInt16 nAction)482 void SwWrtShell::NavigatorPaste( const NaviContentBookmark& rBkmk,
483 const sal_uInt16 nAction )
484 {
485 if( EXCHG_IN_ACTION_COPY == nAction )
486 {
487 // Einfuegen
488 String sURL = rBkmk.GetURL();
489 //handelt es sich um ein Sprung innerhalb des akt. Docs?
490 const SwDocShell* pDocShell = GetView().GetDocShell();
491 if(pDocShell->HasName())
492 {
493 const String rName = pDocShell->GetMedium()->GetURLObject().GetURLNoMark();
494
495 if(COMPARE_EQUAL == sURL.CompareTo(rName, rName.Len()))
496 sURL.Erase(0, rName.Len());
497 }
498 SwFmtINetFmt aFmt( sURL, aEmptyStr );
499 InsertURL( aFmt, rBkmk.GetDescription() );
500 }
501 else
502 {
503 SwSectionData aSection( FILE_LINK_SECTION, GetUniqueSectionName( 0 ) );
504 String aLinkFile( rBkmk.GetURL().GetToken(0, '#') );
505 aLinkFile += sfx2::cTokenSeperator;
506 aLinkFile += sfx2::cTokenSeperator;
507 aLinkFile += rBkmk.GetURL().GetToken(1, '#');
508 aSection.SetLinkFileName( aLinkFile );
509 aSection.SetProtectFlag( true );
510 const SwSection* pIns = InsertSection( aSection );
511 if( EXCHG_IN_ACTION_MOVE == nAction && pIns )
512 {
513 aSection = SwSectionData(*pIns);
514 aSection.SetLinkFileName( aEmptyStr );
515 aSection.SetType( CONTENT_SECTION );
516 aSection.SetProtectFlag( false );
517
518 // the update of content from linked section at time delete
519 // the undostack. Then the change of the section dont create
520 // any undoobject. - BUG 69145
521 sal_Bool bDoesUndo = DoesUndo();
522 SwUndoId nLastUndoId(UNDO_EMPTY);
523 if (GetLastUndoInfo(0, & nLastUndoId))
524 {
525 if (UNDO_INSSECTION != nLastUndoId)
526 {
527 DoUndo(false);
528 }
529 }
530 UpdateSection( GetSectionFmtPos( *pIns->GetFmt() ), aSection );
531 DoUndo( bDoesUndo );
532 }
533 }
534 }
535
536
537