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