xref: /aoo4110/main/sw/source/ui/wrtsh/wrtsh2.cxx (revision b1cdbd2c)
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