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 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_sw.hxx"
24 #include <tools/ref.hxx>
25 #include <hintids.hxx>
26
27 #include <doc.hxx>
28 #ifdef DBG_UTIL
29 #include <stdio.h>
30 #endif
31
32 #include <vcl/help.hxx>
33 #include <svl/stritem.hxx>
34 #include <unotools/securityoptions.hxx>
35 #include <tools/urlobj.hxx>
36 #include <txtrfmrk.hxx>
37 #include <fmtrfmrk.hxx>
38 #include <editeng/flditem.hxx>
39 #include <svl/urihelper.hxx>
40 #include <svx/svdotext.hxx>
41 #include <editeng/outliner.hxx>
42 #include <svl/itemiter.hxx>
43 #include <svx/svdview.hxx>
44 #include <svx/svdpagv.hxx>
45 #include <swmodule.hxx>
46 #include <modcfg.hxx>
47 #include <view.hxx>
48 #include <wrtsh.hxx>
49 #include <docsh.hxx>
50 #include <edtwin.hxx>
51 #include <dpage.hxx>
52 #include <shellres.hxx>
53 #include <docufld.hxx>
54 #include <dbfld.hxx>
55 #include <reffld.hxx>
56 #include <cellatr.hxx>
57 #include <shdwcrsr.hxx>
58 #include <fmtcol.hxx>
59 #include <charfmt.hxx>
60 #include <fmtftn.hxx>
61 #include <redline.hxx>
62 #include <tox.hxx>
63 #include <txttxmrk.hxx>
64 #include <uitool.hxx>
65 #include <viewopt.hxx>
66 #include <docvw.hrc>
67 #include <utlui.hrc>
68
69 #include <PostItMgr.hxx>
70 #include <fmtfld.hxx>
71
72 // --> OD 2009-08-18 #i104300#
73 #include <IDocumentMarkAccess.hxx>
74 #include <ndtxt.hxx>
75 // <--
76
77 /*--------------------------------------------------------------------
78 KeyEvents
79 --------------------------------------------------------------------*/
lcl_GetRedlineHelp(const SwRedline & rRedl,String & rTxt,sal_Bool bBalloon)80 static void lcl_GetRedlineHelp( const SwRedline& rRedl, String& rTxt, sal_Bool bBalloon )
81 {
82 sal_uInt16 nResId = 0;
83 switch( rRedl.GetType() )
84 {
85 case nsRedlineType_t::REDLINE_INSERT: nResId = STR_REDLINE_INSERT; break;
86 case nsRedlineType_t::REDLINE_DELETE: nResId = STR_REDLINE_DELETE; break;
87 case nsRedlineType_t::REDLINE_FORMAT: nResId = STR_REDLINE_FORMAT; break;
88 case nsRedlineType_t::REDLINE_TABLE: nResId = STR_REDLINE_TABLE; break;
89 case nsRedlineType_t::REDLINE_FMTCOLL: nResId = STR_REDLINE_FMTCOLL; break;
90 }
91
92 if( nResId )
93 {
94 rTxt = SW_RESSTR( nResId );
95 rTxt.AppendAscii( RTL_CONSTASCII_STRINGPARAM(": " ));
96 rTxt += rRedl.GetAuthorString();
97 rTxt.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " - " ));
98 rTxt += GetAppLangDateTimeString( rRedl.GetTimeStamp() );
99 if( bBalloon && rRedl.GetComment().Len() )
100 ( rTxt += '\n' ) += rRedl.GetComment();
101 }
102 }
103
RequestHelp(const HelpEvent & rEvt)104 void SwEditWin::RequestHelp(const HelpEvent &rEvt)
105 {
106 SwWrtShell &rSh = rView.GetWrtShell();
107 sal_Bool bQuickBalloon = 0 != (rEvt.GetMode() & ( HELPMODE_QUICK | HELPMODE_BALLOON ));
108 if(bQuickBalloon && !rSh.GetViewOptions()->IsShowContentTips())
109 return;
110 sal_Bool bWeiter = sal_True;
111 SET_CURR_SHELL(&rSh);
112 String sTxt;
113 Point aPos( PixelToLogic( ScreenToOutputPixel( rEvt.GetMousePosPixel() ) ));
114 sal_Bool bBalloon = static_cast< sal_Bool >(rEvt.GetMode() & HELPMODE_BALLOON);
115
116 SdrView *pSdrView = rSh.GetDrawView();
117
118 if( bQuickBalloon )
119 {
120 if( pSdrView )
121 {
122 SdrPageView* pPV = pSdrView->GetSdrPageView();
123 SwDPage* pPage = pPV ? ((SwDPage*)pPV->GetPage()) : 0;
124 bWeiter = pPage && pPage->RequestHelp(this, pSdrView, rEvt);
125 }
126 }
127
128 if( bWeiter && bQuickBalloon)
129 {
130 SwRect aFldRect;
131 sal_uInt16 nStyle = 0; // style of quick help
132 SwContentAtPos aCntntAtPos( SwContentAtPos::SW_FIELD |
133 SwContentAtPos::SW_INETATTR |
134 SwContentAtPos::SW_FTN |
135 SwContentAtPos::SW_REDLINE |
136 SwContentAtPos::SW_TOXMARK |
137 SwContentAtPos::SW_REFMARK |
138 SwContentAtPos::SW_SMARTTAG |
139 #ifdef DBG_UTIL
140 SwContentAtPos::SW_TABLEBOXVALUE |
141 ( bBalloon ? SwContentAtPos::SW_CURR_ATTRS : 0) |
142 #endif
143 SwContentAtPos::SW_TABLEBOXFML );
144
145 if( rSh.GetContentAtPos( aPos, aCntntAtPos, sal_False, &aFldRect ) )
146 {
147 switch( aCntntAtPos.eCntntAtPos )
148 {
149 case SwContentAtPos::SW_TABLEBOXFML:
150 sTxt.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "=" ));
151 sTxt += ((SwTblBoxFormula*)aCntntAtPos.aFnd.pAttr)->GetFormula();
152 break;
153 #ifdef DBG_UTIL
154 case SwContentAtPos::SW_TABLEBOXVALUE:
155 {
156 sTxt = UniString(
157 ByteString::CreateFromDouble(
158 ((SwTblBoxValue*)aCntntAtPos.aFnd.pAttr)->GetValue() )
159 , gsl_getSystemTextEncoding());
160 }
161 break;
162 case SwContentAtPos::SW_CURR_ATTRS:
163 sTxt = aCntntAtPos.sStr;
164 break;
165 #endif
166
167 case SwContentAtPos::SW_INETATTR:
168 {
169 sTxt = ((SfxStringItem*)aCntntAtPos.aFnd.pAttr)->GetValue();
170 sTxt = URIHelper::removePassword( sTxt,
171 INetURLObject::WAS_ENCODED,
172 INetURLObject::DECODE_UNAMBIGUOUS);
173 //#i63832# remove the link target type
174 xub_StrLen nFound = sTxt.Search(cMarkSeperator);
175 if( nFound != STRING_NOTFOUND && (++nFound) < sTxt.Len() )
176 {
177 String sSuffix( sTxt.Copy(nFound) );
178 if( sSuffix.EqualsAscii( pMarkToTable ) ||
179 sSuffix.EqualsAscii( pMarkToFrame ) ||
180 sSuffix.EqualsAscii( pMarkToRegion ) ||
181 sSuffix.EqualsAscii( pMarkToOutline ) ||
182 sSuffix.EqualsAscii( pMarkToText ) ||
183 sSuffix.EqualsAscii( pMarkToGraphic ) ||
184 sSuffix.EqualsAscii( pMarkToOLE ))
185 sTxt = sTxt.Copy( 0, nFound - 1);
186 }
187 // special handling if target is a cross-reference bookmark
188 {
189 String sTmpSearchStr = sTxt.Copy( 1, sTxt.Len() );
190 IDocumentMarkAccess* const pMarkAccess = rSh.getIDocumentMarkAccess();
191 IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->findBookmark( sTmpSearchStr );
192 if ( ppBkmk != pMarkAccess->getBookmarksEnd()
193 && IDocumentMarkAccess::GetType( *(ppBkmk->get()) ) == IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK )
194 {
195 SwTxtNode* pTxtNode = ppBkmk->get()->GetMarkStart().nNode.GetNode().GetTxtNode();
196 if ( pTxtNode )
197 {
198 sTxt = pTxtNode->GetExpandTxt( 0, pTxtNode->Len(), true, true );
199
200 if( sTxt.Len() )
201 {
202 sTxt.EraseAllChars( 0xad );
203 for( sal_Unicode* p = sTxt.GetBufferAccess(); *p; ++p )
204 {
205 if( *p < 0x20 )
206 *p = 0x20;
207 else if(*p == 0x2011)
208 *p = '-';
209 }
210 }
211 }
212 }
213 }
214
215 sal_Bool bExecHyperlinks = rView.GetDocShell()->IsReadOnly();
216 if ( !bExecHyperlinks )
217 {
218 SvtSecurityOptions aSecOpts;
219 bExecHyperlinks = !aSecOpts.IsOptionSet( SvtSecurityOptions::E_CTRLCLICK_HYPERLINK );
220
221 if ( !bExecHyperlinks )
222 {
223 sTxt.InsertAscii( ": ", 0 );
224 sTxt.Insert( ViewShell::GetShellRes()->aHyperlinkClick, 0 );
225 }
226 }
227 break;
228 }
229 case SwContentAtPos::SW_SMARTTAG:
230 {
231 sTxt = SW_RESSTR(STR_SMARTTAG_CLICK);
232
233 KeyCode aCode( KEY_SPACE );
234 KeyCode aModifiedCode( KEY_SPACE, KEY_MOD1 );
235 String aModStr( aModifiedCode.GetName() );
236 aModStr.SearchAndReplace( aCode.GetName(), String() );
237 aModStr.SearchAndReplaceAllAscii( "+", String() );
238 sTxt.SearchAndReplaceAllAscii( "%s", aModStr );
239 }
240 break;
241
242 case SwContentAtPos::SW_FTN:
243 if( aCntntAtPos.pFndTxtAttr && aCntntAtPos.aFnd.pAttr )
244 {
245 const SwFmtFtn* pFtn = (SwFmtFtn*)aCntntAtPos.aFnd.pAttr;
246 pFtn->GetFtnText( sTxt );
247 sTxt.Insert( SW_RESSTR( pFtn->IsEndNote()
248 ? STR_ENDNOTE : STR_FOOTNOTE ), 0 );
249 if( aCntntAtPos.IsInRTLText() )
250 nStyle |= QUICKHELP_BIDI_RTL;
251 }
252 break;
253
254 case SwContentAtPos::SW_REDLINE:
255 lcl_GetRedlineHelp( *aCntntAtPos.aFnd.pRedl, sTxt, bBalloon );
256 break;
257
258 case SwContentAtPos::SW_TOXMARK:
259 sTxt = aCntntAtPos.sStr;
260 if( sTxt.Len() && aCntntAtPos.pFndTxtAttr )
261 {
262 const SwTOXType* pTType = aCntntAtPos.pFndTxtAttr->
263 GetTOXMark().GetTOXType();
264 if( pTType && pTType->GetTypeName().Len() )
265 {
266 sTxt.InsertAscii( ": ", 0 );
267 sTxt.Insert( pTType->GetTypeName(), 0 );
268 }
269 }
270 break;
271
272 case SwContentAtPos::SW_REFMARK:
273 if(aCntntAtPos.aFnd.pAttr)
274 {
275 sTxt = SW_RES(STR_CONTENT_TYPE_SINGLE_REFERENCE);
276 sTxt.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ": "));
277 sTxt += ((const SwFmtRefMark*)aCntntAtPos.aFnd.pAttr)->GetRefName();
278 }
279 break;
280
281 default:
282 {
283 SwModuleOptions* pModOpt = SW_MOD()->GetModuleConfig();
284 if(!pModOpt->IsHideFieldTips())
285 {
286 const SwField* pFld = aCntntAtPos.aFnd.pFld;
287 switch( pFld->Which() )
288 {
289 case RES_SETEXPFLD:
290 case RES_TABLEFLD:
291 case RES_GETEXPFLD:
292 {
293 sal_uInt16 nOldSubType = pFld->GetSubType();
294 ((SwField*)pFld)->SetSubType(nsSwExtendedSubType::SUB_CMD);
295 sTxt = pFld->ExpandField(true);
296 ((SwField*)pFld)->SetSubType(nOldSubType);
297 }
298 break;
299
300 case RES_POSTITFLD:
301 {
302 break;
303 }
304 case RES_INPUTFLD: // BubbleHelp, da der Hinweis ggf ziemlich lang sein kann
305 bBalloon = sal_True;
306 /* no break */
307 case RES_JUMPEDITFLD:
308 sTxt = pFld->GetPar2();
309 break;
310
311 case RES_DBFLD:
312 sTxt = pFld->GetFieldName();
313 break;
314
315 case RES_USERFLD:
316 case RES_HIDDENTXTFLD:
317 sTxt = pFld->GetPar1();
318 break;
319
320 case RES_DOCSTATFLD:
321 break;
322
323 case RES_MACROFLD:
324 sTxt = ((const SwMacroField*)pFld)->GetMacro();
325 break;
326
327 case RES_GETREFFLD:
328 {
329 const SwGetRefField* pRefFld( dynamic_cast<const SwGetRefField*>(pFld) );
330 ASSERT( pRefFld,
331 "<SwEditWin::RequestHelp(..)> - unexpected type of <pFld>" );
332 if ( pRefFld )
333 {
334 if ( pRefFld->IsRefToHeadingCrossRefBookmark() ||
335 pRefFld->IsRefToNumItemCrossRefBookmark() )
336 {
337 sTxt = pRefFld->GetExpandedTxtOfReferencedTxtNode();
338 if ( sTxt.Len() > 80 )
339 {
340 sTxt.Erase( 80 );
341 sTxt += '.';
342 sTxt += '.';
343 sTxt += '.';
344 }
345 }
346 else
347 {
348 sTxt = ((SwGetRefField*)pFld)->GetSetRefName();
349 }
350 }
351 }
352 break;
353 }
354 }
355
356 if( !sTxt.Len() )
357 {
358 aCntntAtPos.eCntntAtPos = SwContentAtPos::SW_REDLINE;
359 if( rSh.GetContentAtPos( aPos, aCntntAtPos, sal_False, &aFldRect ) )
360 lcl_GetRedlineHelp( *aCntntAtPos.aFnd.pRedl, sTxt, bBalloon );
361 }
362 }
363 }
364 if (sTxt.Len() )
365 {
366 if( bBalloon )
367 Help::ShowBalloon( this, rEvt.GetMousePosPixel(), sTxt );
368 else
369 {
370 // dann zeige die Hilfe mal an:
371 Rectangle aRect( aFldRect.SVRect() );
372 Point aPt( OutputToScreenPixel( LogicToPixel( aRect.TopLeft() )));
373 aRect.Left() = aPt.X();
374 aRect.Top() = aPt.Y();
375 aPt = OutputToScreenPixel( LogicToPixel( aRect.BottomRight() ));
376 aRect.Right() = aPt.X();
377 aRect.Bottom() = aPt.Y();
378 Help::ShowQuickHelp( this, aRect, sTxt, nStyle );
379 }
380 }
381
382 bWeiter = sal_False;
383 }
384 // Removed tooltips for table selection
385 /*
386 if( bWeiter )
387 {
388 sal_uInt8 nTabCols = rSh.WhichMouseTabCol(aPos);
389 sal_uInt16 nTabRes = 0;
390 switch(nTabCols)
391 {
392 case SW_TABCOL_HORI:
393 case SW_TABCOL_VERT:
394 nTabRes = STR_TABLE_COL_ADJUST;
395 break;
396 case SW_TABROW_HORI:
397 case SW_TABROW_VERT:
398 nTabRes = STR_TABLE_ROW_ADJUST;
399 break;
400 case SW_TABSEL_HORI:
401 case SW_TABSEL_HORI_RTL:
402 case SW_TABSEL_VERT:
403 nTabRes = STR_TABLE_SELECT_ALL;
404 break;
405 case SW_TABROWSEL_HORI:
406 case SW_TABROWSEL_HORI_RTL:
407 case SW_TABROWSEL_VERT:
408 nTabRes = STR_TABLE_SELECT_ROW;
409 break;
410 case SW_TABCOLSEL_HORI:
411 case SW_TABCOLSEL_VERT:
412 nTabRes = STR_TABLE_SELECT_COL;
413 break;
414 }
415 if(nTabRes)
416 {
417 sTxt = SW_RESSTR(nTabRes);
418 Size aTxtSize( GetTextWidth(sTxt), GetTextHeight());
419 Rectangle aRect(rEvt.GetMousePosPixel(), aTxtSize);
420 Help::ShowQuickHelp(this, aRect, sTxt);
421 }
422 bWeiter = sal_False;
423 }
424 */
425 }
426
427 /*
428 aktuelle Zeichenvorlage anzeigen?
429 if( bWeiter && rEvt.GetMode() & ( HELPMODE_QUICK | HELPMODE_BALLOON ))
430 {
431 SwCharFmt* pChrFmt = rSh.GetCurCharFmt();
432 }
433 */
434 if( bWeiter && pSdrView && bQuickBalloon)
435 {
436 SdrViewEvent aVEvt;
437 SdrHitKind eHit = pSdrView->PickAnything(aPos, aVEvt);
438 const SvxURLField *pField;
439 SdrObject* pObj = NULL;
440
441 if ((pField = aVEvt.pURLField) != 0)
442 {
443 // URL-Feld getroffen
444 if (pField)
445 {
446 pObj = aVEvt.pObj;
447 sTxt = pField->GetURL();
448
449 bWeiter = sal_False;
450 }
451 }
452 if (bWeiter && eHit == SDRHIT_TEXTEDIT)
453 {
454 // URL-Feld in zum Editieren geöffneten DrawText-Objekt suchen
455 OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView();
456 const SvxFieldItem* pFieldItem;
457
458 if (pSdrView->AreObjectsMarked())
459 {
460 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
461
462 if (rMarkList.GetMarkCount() == 1)
463 pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
464 }
465
466 if (pObj && pObj->ISA(SdrTextObj) && pOLV &&
467 (pFieldItem = pOLV->GetFieldUnderMousePointer()) != 0)
468 {
469 pField = dynamic_cast<const SvxURLField*>(pFieldItem->GetField());
470
471 if (pField )
472 {
473 sTxt = ((const SvxURLField*) pField)->GetURL();
474 bWeiter = sal_False;
475 }
476 }
477 }
478 if (sTxt.Len() && pObj)
479 {
480 sTxt = URIHelper::removePassword( sTxt, INetURLObject::WAS_ENCODED,
481 INetURLObject::DECODE_UNAMBIGUOUS);
482
483 Rectangle aLogicPix = LogicToPixel(pObj->GetLogicRect());
484 Rectangle aScreenRect(OutputToScreenPixel(aLogicPix.TopLeft()),
485 OutputToScreenPixel(aLogicPix.BottomRight()));
486
487 if (bBalloon)
488 Help::ShowBalloon(this, rEvt.GetMousePosPixel(), aScreenRect, sTxt);
489 else
490 Help::ShowQuickHelp(this, aScreenRect, sTxt);
491 }
492 }
493
494 if( bWeiter )
495 Window::RequestHelp( rEvt );
496 }
497
PrePaint()498 void SwEditWin::PrePaint()
499 {
500 SwWrtShell* pWrtShell = GetView().GetWrtShellPtr();
501
502 if(pWrtShell)
503 {
504 pWrtShell->PrePaint();
505 }
506 }
507
Paint(const Rectangle & rRect)508 void SwEditWin::Paint(const Rectangle& rRect)
509 {
510 #if defined(MYDEBUG)
511 // StartUp-Statistik
512 if ( pTickList )
513 {
514 SYSTICK( "Start SwEditWin::Paint" );
515 READ_FIRST_TICKS()
516 FLUSH_TICKS()
517 }
518 #endif
519
520 SwWrtShell* pWrtShell = GetView().GetWrtShellPtr();
521 if(!pWrtShell)
522 return;
523 sal_Bool bPaintShadowCrsr = sal_False;
524 if( pShadCrsr )
525 {
526 Rectangle aRect( pShadCrsr->GetRect());
527 // liegt vollständig drin?
528 if( rRect.IsInside( aRect ) )
529 // dann aufheben
530 delete pShadCrsr, pShadCrsr = 0;
531 else if( rRect.IsOver( aRect ))
532 {
533 // liegt irgendwie drüber, dann ist alles ausserhalb geclippt
534 // und wir müssen den "inneren Teil" am Ende vom Paint
535 // wieder sichtbar machen. Sonst kommt es zu Paintfehlern!
536 bPaintShadowCrsr = sal_True;
537 }
538 }
539 /*
540 // TODO/LATER: What's the replacement for this? Do we need it?
541 SwDocShell* pDocShell = GetView().GetDocShell();
542
543 SvInPlaceEnvironment *pIpEnv = pDocShell ?
544 pDocShell->GetIPEnv() : 0;
545 if ( pIpEnv && pIpEnv->GetRectsChangedLockCount() )
546 // Wir stehen in Größenverhandlungen (MM), Paint verzögern
547 Invalidate( rRect );
548 else */
549 if ( GetView().GetVisArea().GetWidth() <= 0 ||
550 GetView().GetVisArea().GetHeight() <= 0 )
551 Invalidate( rRect );
552 else
553 pWrtShell->Paint( rRect );
554
555 if( bPaintShadowCrsr )
556 pShadCrsr->Paint();
557 }
558
559 /* vim: set noet sw=4 ts=4: */
560