xref: /aoo41x/main/sw/source/ui/wrtsh/wrtsh2.cxx (revision 332f371a)
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 
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                 EndPara();
104                 const SwPosition rEndPos( *GetCurrentShellCursor().GetPoint() );
105                 pAnnotationTextRange = new SwPaM( rStartPos, rEndPos );
106             }
107             else
108             {
109                 NormalizePam( sal_False );
110                 const SwPaM& rCurrPaM = GetCurrentShellCursor();
111                 pAnnotationTextRange = new SwPaM( *rCurrPaM.GetPoint(), *rCurrPaM.GetMark() );
112                 ClearMark();
113             }
114         }
115         else
116         {
117             bDeleted = DelRight() != 0;
118         }
119     }
120 
121     SwEditShell::Insert2(rFld, bDeleted);
122 
123     if ( pAnnotationTextRange != NULL )
124     {
125         if ( GetDoc() != NULL )
126         {
127             IDocumentMarkAccess* pMarksAccess = GetDoc()->getIDocumentMarkAccess();
128             pMarksAccess->makeAnnotationMark( *pAnnotationTextRange, ::rtl::OUString() );
129         }
130         delete pAnnotationTextRange;
131     }
132 
133     EndUndo();
134     EndAllAction();
135 }
136 
137 /*--------------------------------------------------------------------
138 	Beschreibung: Felder Update anschmeissen
139  --------------------------------------------------------------------*/
140 
141 
142 
143 void SwWrtShell::UpdateInputFlds( SwInputFieldList* pLst )
144 {
145     // ueber die Liste der Eingabefelder gehen und Updaten
146     SwInputFieldList* pTmp = pLst;
147     if( !pTmp )
148         pTmp = new SwInputFieldList( this );
149 
150     const sal_uInt16 nCnt = pTmp->Count();
151     if(nCnt)
152     {
153         pTmp->PushCrsr();
154 
155         sal_Bool bCancel = sal_False;
156         ByteString aDlgPos;
157         for( sal_uInt16 i = 0; i < nCnt && !bCancel; ++i )
158         {
159             pTmp->GotoFieldPos( i );
160             SwField* pField = pTmp->GetField( i );
161             if(pField->GetTyp()->Which() == RES_DROPDOWN)
162                 bCancel = StartDropDownFldDlg( pField, sal_True, &aDlgPos );
163             else
164                 bCancel = StartInputFldDlg( pField, sal_True, 0, &aDlgPos);
165 
166             // Sonst Updatefehler bei Multiselektion:
167             pTmp->GetField( i )->GetTyp()->UpdateFlds();
168         }
169         pTmp->PopCrsr();
170     }
171 
172     if( !pLst )
173         delete pTmp;
174 }
175 
176 
177 /*--------------------------------------------------------------------
178 	Beschreibung: EingabeDialog fuer ein bestimmtes Feld starten
179  --------------------------------------------------------------------*/
180 
181 
182 
183 sal_Bool SwWrtShell::StartInputFldDlg( SwField* pFld, sal_Bool bNextButton,
184                                     Window* pParentWin, ByteString* pWindowState )
185 {
186 //JP 14.08.96: Bug 30332 - nach Umbau der modularietaet im SFX, muss jetzt
187 //				das TopWindow der Application benutzt werden.
188 //	SwFldInputDlg* pDlg = new SwFldInputDlg( GetWin(), *this, pFld );
189 
190     SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
191     DBG_ASSERT(pFact, "Dialogdiet fail!");
192     AbstractFldInputDlg* pDlg = pFact->CreateFldInputDlg( DLG_FLD_INPUT,
193                                                         pParentWin, *this, pFld, bNextButton);
194     DBG_ASSERT(pDlg, "Dialogdiet fail!");
195 	if(pWindowState && pWindowState->Len())
196         pDlg->SetWindowState(*pWindowState);
197 	sal_Bool bRet = RET_CANCEL == pDlg->Execute();
198     if(pWindowState)
199         *pWindowState = pDlg->GetWindowState();
200 
201 	delete pDlg;
202 	GetWin()->Update();
203 	return bRet;
204 }
205 /* -----------------17.06.2003 10:18-----------------
206 
207  --------------------------------------------------*/
208 sal_Bool SwWrtShell::StartDropDownFldDlg(SwField* pFld, sal_Bool bNextButton, ByteString* pWindowState)
209 {
210     SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
211     DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!");
212 
213     AbstractDropDownFieldDialog* pDlg = pFact->CreateDropDownFieldDialog( NULL, *this, pFld, DLG_FLD_DROPDOWN ,bNextButton );
214     DBG_ASSERT(pDlg, "Dialogdiet fail!");
215     if(pWindowState && pWindowState->Len())
216         pDlg->SetWindowState(*pWindowState);
217     sal_uInt16 nRet = pDlg->Execute();
218     if(pWindowState)
219         *pWindowState = pDlg->GetWindowState();
220     delete pDlg;
221     sal_Bool bRet = RET_CANCEL == nRet;
222     GetWin()->Update();
223     if(RET_YES == nRet)
224     {
225         GetView().GetViewFrame()->GetDispatcher()->Execute(FN_EDIT_FIELD, SFX_CALLMODE_SYNCHRON);
226     }
227     return bRet;
228 }
229 
230 /*--------------------------------------------------------------------
231 	Beschreibung: Verzeichnis einfuegen Selektion loeschen
232  --------------------------------------------------------------------*/
233 
234 
235 
236 void SwWrtShell::InsertTableOf(const SwTOXBase& rTOX, const SfxItemSet* pSet)
237 {
238 	if(!_CanInsert())
239 		return;
240 
241 	if(HasSelection())
242 		DelRight();
243 
244 	SwEditShell::InsertTableOf(rTOX, pSet);
245 }
246 
247 
248 /*--------------------------------------------------------------------
249 	Beschreibung: Verzeichnis Updaten Selektion loeschen
250  --------------------------------------------------------------------*/
251 
252 sal_Bool SwWrtShell::UpdateTableOf(const SwTOXBase& rTOX, const SfxItemSet* pSet)
253 {
254     sal_Bool bResult = sal_False;
255 
256 	if(_CanInsert())
257     {
258         bResult = SwEditShell::UpdateTableOf(rTOX, pSet);
259 
260         if (pSet == NULL)
261         {
262             SwDoc *const pDoc_ = GetDoc();
263             if (pDoc_)
264             {
265                 pDoc_->GetIDocumentUndoRedo().DelAllUndoObj();
266             }
267         }
268     }
269 
270     return bResult;
271 }
272 
273 // handler for click on the field given as parameter.
274 // the cursor is positioned on the field.
275 
276 
277 void SwWrtShell::ClickToField( const SwField& rFld )
278 {
279 	bIsInClickToEdit = sal_True;
280 	switch( rFld.GetTyp()->Which() )
281 	{
282 	case RES_JUMPEDITFLD:
283 		{
284 			sal_uInt16 nSlotId = 0;
285 			switch( rFld.GetFormat() )
286 			{
287 			case JE_FMT_TABLE:
288 				nSlotId = FN_INSERT_TABLE;
289 				break;
290 
291 			case JE_FMT_FRAME:
292 				nSlotId = FN_INSERT_FRAME;
293 				break;
294 
295 			case JE_FMT_GRAPHIC:	nSlotId = SID_INSERT_GRAPHIC;		break;
296 			case JE_FMT_OLE:        nSlotId = SID_INSERT_OBJECT;		break;
297 
298 //			case JE_FMT_TEXT:
299 			}
300 
301 			Right( CRSR_SKIP_CHARS, sal_True, 1, sal_False );		// Feld selektieren
302 
303 			if( nSlotId )
304 			{
305 				StartUndo( UNDO_START );
306 				//#97295# immediately select the right shell
307                 GetView().StopShellTimer();
308                 GetView().GetViewFrame()->GetDispatcher()->Execute( nSlotId,
309 							SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD );
310 				EndUndo( UNDO_END );
311 			}
312 		}
313 		break;
314 
315 	case RES_MACROFLD:
316 		{
317 			const SwMacroField *pFld = (const SwMacroField*)&rFld;
318 			String sText( rFld.GetPar2() );
319 			String sRet( sText );
320 			ExecMacro( pFld->GetSvxMacro(), &sRet );
321 
322 			// return Wert veraendert?
323 			if( sRet != sText )
324 			{
325 				StartAllAction();
326 				((SwField&)rFld).SetPar2( sRet );
327 				((SwField&)rFld).GetTyp()->UpdateFlds();
328 				EndAllAction();
329 			}
330 		}
331 		break;
332 
333 	case RES_GETREFFLD:
334 		StartAllAction();
335 		SwCrsrShell::GotoRefMark( ((SwGetRefField&)rFld).GetSetRefName(),
336 									((SwGetRefField&)rFld).GetSubType(),
337 									((SwGetRefField&)rFld).GetSeqNo() );
338 		EndAllAction();
339 		break;
340 
341     case RES_INPUTFLD:
342         {
343             const SwInputField* pInputField = dynamic_cast<const SwInputField*>(&rFld);
344             if ( pInputField == NULL )
345             {
346                 StartInputFldDlg( (SwField*)&rFld, sal_False );
347             }
348         }
349         break;
350 
351     case RES_SETEXPFLD:
352         if( ((SwSetExpField&)rFld).GetInputFlag() )
353             StartInputFldDlg( (SwField*)&rFld, sal_False );
354         break;
355     case RES_DROPDOWN :
356         StartDropDownFldDlg( (SwField*)&rFld, sal_False );
357     break;
358     }
359 
360 	bIsInClickToEdit = sal_False;
361 }
362 
363 
364 void SwWrtShell::ClickToINetAttr( const SwFmtINetFmt& rItem, sal_uInt16 nFilter )
365 {
366 	if( !rItem.GetValue().Len() )
367 		return ;
368 
369 	bIsInClickToEdit = sal_True;
370 
371 	// erstmal das evt. gesetzte ObjectSelect Macro ausfuehren
372 	const SvxMacro* pMac = rItem.GetMacro( SFX_EVENT_MOUSECLICK_OBJECT );
373 	if( pMac )
374 	{
375 		SwCallMouseEvent aCallEvent;
376 		aCallEvent.Set( &rItem );
377 		GetDoc()->CallEvent( SFX_EVENT_MOUSECLICK_OBJECT, aCallEvent, sal_False );
378 	}
379 
380 	// damit die Vorlagenumsetzung sofort angezeigt wird
381 	::LoadURL( rItem.GetValue(), this, nFilter, &rItem.GetTargetFrame() );
382     const SwTxtINetFmt* pTxtAttr = rItem.GetTxtINetFmt();
383     if( pTxtAttr )
384     {
385         const_cast<SwTxtINetFmt*>(pTxtAttr)->SetVisited( true );
386         const_cast<SwTxtINetFmt*>(pTxtAttr)->SetVisitedValid( true );
387     }
388 
389 	bIsInClickToEdit = sal_False;
390 }
391 
392 
393 
394 sal_Bool SwWrtShell::ClickToINetGrf( const Point& rDocPt, sal_uInt16 nFilter )
395 {
396 	sal_Bool bRet = sal_False;
397 	String sURL;
398 	String sTargetFrameName;
399 	const SwFrmFmt* pFnd = IsURLGrfAtPos( rDocPt, &sURL, &sTargetFrameName );
400 	if( pFnd && sURL.Len() )
401 	{
402 		bRet = sal_True;
403 		// erstmal das evt. gesetzte ObjectSelect Macro ausfuehren
404 		const SvxMacro* pMac = &pFnd->GetMacro().GetMacro( SFX_EVENT_MOUSECLICK_OBJECT );
405 		if( pMac )
406 		{
407 			SwCallMouseEvent aCallEvent;
408 			aCallEvent.Set( EVENT_OBJECT_URLITEM, pFnd );
409 			GetDoc()->CallEvent( SFX_EVENT_MOUSECLICK_OBJECT, aCallEvent, sal_False );
410 		}
411 
412 		::LoadURL( sURL, this, nFilter, &sTargetFrameName);
413 	}
414 	return bRet;
415 }
416 
417 
418 void LoadURL( const String& rURL, ViewShell* pVSh, sal_uInt16 nFilter,
419 			  const String *pTargetFrameName )
420 {
421 	ASSERT( rURL.Len() && pVSh, "was soll hier geladen werden?" );
422 	if( !rURL.Len() || !pVSh )
423 		return ;
424 
425 	// die Shell kann auch 0 sein !!!!!
426 	SwWrtShell *pSh = 0;
427 	if ( pVSh && pVSh->ISA(SwCrsrShell) )
428 	{
429 		//Eine CrsrShell ist auch immer eine WrtShell
430 		pSh = (SwWrtShell*)pVSh;
431 	}
432 	else
433 		return;
434 
435 	SwDocShell* pDShell = pSh->GetView().GetDocShell();
436 	DBG_ASSERT( pDShell, "No DocShell?!");
437 	String sTargetFrame;
438 	if( pTargetFrameName && pTargetFrameName->Len() )
439 		sTargetFrame = *pTargetFrameName;
440 	else if( pDShell ) {
441         using namespace ::com::sun::star;
442         uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
443             pDShell->GetModel(), uno::UNO_QUERY_THROW);
444         uno::Reference<document::XDocumentProperties> xDocProps
445             = xDPS->getDocumentProperties();
446         sTargetFrame = xDocProps->getDefaultTarget();
447     }
448 
449 	String sReferer;
450 	if( pDShell && pDShell->GetMedium() )
451 		sReferer = pDShell->GetMedium()->GetName();
452 	SfxViewFrame* pViewFrm = pSh->GetView().GetViewFrame();
453 	SfxFrameItem aView( SID_DOCFRAME, pViewFrm );
454 	SfxStringItem aName( SID_FILE_NAME, rURL );
455 	SfxStringItem aTargetFrameName( SID_TARGETNAME, sTargetFrame );
456 	SfxStringItem aReferer( SID_REFERER, sReferer );
457 
458 	SfxBoolItem aNewView( SID_OPEN_NEW_VIEW, sal_False );
459 	//#39076# Silent kann lt. SFX entfernt werden.
460 //	SfxBoolItem aSilent( SID_SILENT, sal_True );
461 	SfxBoolItem aBrowse( SID_BROWSE, sal_True );
462 
463 	if( nFilter & URLLOAD_NEWVIEW )
464 		aTargetFrameName.SetValue( String::CreateFromAscii("_blank") );
465 
466 	const SfxPoolItem* aArr[] = {
467 				&aName,
468                 &aNewView, /*&aSilent,*/
469 				&aReferer,
470 				&aView, &aTargetFrameName,
471 				&aBrowse,
472 				0L
473 	};
474 
475 	pViewFrm->GetDispatcher()->GetBindings()->Execute( SID_OPENDOC, aArr,
476 			SFX_CALLMODE_ASYNCHRON|SFX_CALLMODE_RECORD );
477 }
478 
479 void SwWrtShell::NavigatorPaste( const NaviContentBookmark& rBkmk,
480 									const sal_uInt16 nAction )
481 {
482 	if( EXCHG_IN_ACTION_COPY == nAction )
483 	{
484 		// Einfuegen
485 		String sURL = rBkmk.GetURL();
486 		//handelt es sich um ein Sprung innerhalb des akt. Docs?
487 		const SwDocShell* pDocShell = GetView().GetDocShell();
488 		if(pDocShell->HasName())
489 		{
490             const String rName = pDocShell->GetMedium()->GetURLObject().GetURLNoMark();
491 
492 			if(COMPARE_EQUAL == sURL.CompareTo(rName, rName.Len()))
493 				sURL.Erase(0, rName.Len());
494 		}
495 		SwFmtINetFmt aFmt( sURL, aEmptyStr );
496 		InsertURL( aFmt, rBkmk.GetDescription() );
497 	}
498 	else
499 	{
500         SwSectionData aSection( FILE_LINK_SECTION, GetUniqueSectionName( 0 ) );
501 		String aLinkFile( rBkmk.GetURL().GetToken(0, '#') );
502         aLinkFile += sfx2::cTokenSeperator;
503         aLinkFile += sfx2::cTokenSeperator;
504 		aLinkFile += rBkmk.GetURL().GetToken(1, '#');
505 		aSection.SetLinkFileName( aLinkFile );
506         aSection.SetProtectFlag( true );
507 		const SwSection* pIns = InsertSection( aSection );
508 		if( EXCHG_IN_ACTION_MOVE == nAction && pIns )
509 		{
510             aSection = SwSectionData(*pIns);
511 			aSection.SetLinkFileName( aEmptyStr );
512 			aSection.SetType( CONTENT_SECTION );
513             aSection.SetProtectFlag( false );
514 
515 			// the update of content from linked section at time delete
516 			// the undostack. Then the change of the section dont create
517 			// any undoobject. -  BUG 69145
518 			sal_Bool bDoesUndo = DoesUndo();
519             SwUndoId nLastUndoId(UNDO_EMPTY);
520             if (GetLastUndoInfo(0, & nLastUndoId))
521             {
522                 if (UNDO_INSSECTION != nLastUndoId)
523                 {
524                     DoUndo(false);
525                 }
526             }
527             UpdateSection( GetSectionFmtPos( *pIns->GetFmt() ), aSection );
528 			DoUndo( bDoesUndo );
529 		}
530 	}
531 }
532 
533 
534