Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <comphelper/string.hxx>
21 : #include <hintids.hxx>
22 :
23 : #include <doc.hxx>
24 : #if OSL_DEBUG_LEVEL > 1
25 : #include <stdio.h>
26 : #endif
27 :
28 : #include <vcl/help.hxx>
29 : #include <svl/stritem.hxx>
30 : #include <unotools/securityoptions.hxx>
31 : #include <tools/urlobj.hxx>
32 : #include <txtrfmrk.hxx>
33 : #include <fmtrfmrk.hxx>
34 : #include <editeng/flditem.hxx>
35 : #include <svl/urihelper.hxx>
36 : #include <svx/svdotext.hxx>
37 : #include <editeng/outliner.hxx>
38 : #include <svl/itemiter.hxx>
39 : #include <svx/svdview.hxx>
40 : #include <svx/svdpagv.hxx>
41 : #include <swmodule.hxx>
42 : #include <modcfg.hxx>
43 : #include <view.hxx>
44 : #include <wrtsh.hxx>
45 : #include <docsh.hxx>
46 : #include <edtwin.hxx>
47 : #include <dpage.hxx>
48 : #include <shellres.hxx>
49 : #include <docufld.hxx>
50 : #include <dbfld.hxx>
51 : #include <reffld.hxx>
52 : #include <cellatr.hxx>
53 : #include <shdwcrsr.hxx>
54 : #include <fmtcol.hxx>
55 : #include <charfmt.hxx>
56 : #include <fmtftn.hxx>
57 : #include <redline.hxx>
58 : #include <tox.hxx>
59 : #include <txttxmrk.hxx>
60 : #include <uitool.hxx>
61 : #include <viewopt.hxx>
62 : #include <docvw.hrc>
63 : #include <utlui.hrc>
64 :
65 : #include <PostItMgr.hxx>
66 : #include <fmtfld.hxx>
67 :
68 : // #i104300#
69 : #include <IDocumentMarkAccess.hxx>
70 : #include <ndtxt.hxx>
71 :
72 0 : static void lcl_GetRedlineHelp( const SwRedline& rRedl, String& rTxt, sal_Bool bBalloon )
73 : {
74 0 : sal_uInt16 nResId = 0;
75 0 : switch( rRedl.GetType() )
76 : {
77 0 : case nsRedlineType_t::REDLINE_INSERT: nResId = STR_REDLINE_INSERT; break;
78 0 : case nsRedlineType_t::REDLINE_DELETE: nResId = STR_REDLINE_DELETE; break;
79 0 : case nsRedlineType_t::REDLINE_FORMAT: nResId = STR_REDLINE_FORMAT; break;
80 0 : case nsRedlineType_t::REDLINE_TABLE: nResId = STR_REDLINE_TABLE; break;
81 0 : case nsRedlineType_t::REDLINE_FMTCOLL: nResId = STR_REDLINE_FMTCOLL; break;
82 : }
83 :
84 0 : if( nResId )
85 : {
86 0 : rTxt = SW_RESSTR( nResId );
87 0 : rTxt.AppendAscii( RTL_CONSTASCII_STRINGPARAM(": " ));
88 0 : rTxt += rRedl.GetAuthorString();
89 0 : rTxt.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " - " ));
90 0 : rTxt += GetAppLangDateTimeString( rRedl.GetTimeStamp() );
91 0 : if( bBalloon && rRedl.GetComment().Len() )
92 0 : ( rTxt += '\n' ) += rRedl.GetComment();
93 : }
94 0 : }
95 :
96 :
97 0 : void SwEditWin::RequestHelp(const HelpEvent &rEvt)
98 : {
99 0 : SwWrtShell &rSh = m_rView.GetWrtShell();
100 0 : bool bQuickBalloon = 0 != (rEvt.GetMode() & ( HELPMODE_QUICK | HELPMODE_BALLOON ));
101 0 : if(bQuickBalloon && !rSh.GetViewOptions()->IsShowContentTips())
102 0 : return;
103 0 : bool bWeiter = true;
104 0 : SET_CURR_SHELL(&rSh);
105 0 : String sTxt;
106 0 : Point aPos( PixelToLogic( ScreenToOutputPixel( rEvt.GetMousePosPixel() ) ));
107 0 : sal_Bool bBalloon = static_cast< sal_Bool >(rEvt.GetMode() & HELPMODE_BALLOON);
108 :
109 0 : SdrView *pSdrView = rSh.GetDrawView();
110 :
111 0 : if( bQuickBalloon )
112 : {
113 0 : if( pSdrView )
114 : {
115 0 : SdrPageView* pPV = pSdrView->GetSdrPageView();
116 0 : SwDPage* pPage = pPV ? ((SwDPage*)pPV->GetPage()) : 0;
117 0 : bWeiter = pPage && pPage->RequestHelp(this, pSdrView, rEvt);
118 : }
119 : }
120 :
121 0 : if( bWeiter && bQuickBalloon)
122 : {
123 0 : SwRect aFldRect;
124 : SwContentAtPos aCntntAtPos( SwContentAtPos::SW_FIELD |
125 : SwContentAtPos::SW_INETATTR |
126 : SwContentAtPos::SW_FTN |
127 : SwContentAtPos::SW_REDLINE |
128 : SwContentAtPos::SW_TOXMARK |
129 : SwContentAtPos::SW_REFMARK |
130 : SwContentAtPos::SW_SMARTTAG |
131 : #ifdef DBG_UTIL
132 : SwContentAtPos::SW_TABLEBOXVALUE |
133 : ( bBalloon ? SwContentAtPos::SW_CURR_ATTRS : 0) |
134 : #endif
135 0 : SwContentAtPos::SW_TABLEBOXFML );
136 :
137 0 : if( rSh.GetContentAtPos( aPos, aCntntAtPos, sal_False, &aFldRect ) )
138 : {
139 0 : sal_uInt16 nStyle = 0; // style of quick help
140 0 : switch( aCntntAtPos.eCntntAtPos )
141 : {
142 : case SwContentAtPos::SW_TABLEBOXFML:
143 0 : sTxt.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "= " ));
144 0 : sTxt += ((SwTblBoxFormula*)aCntntAtPos.aFnd.pAttr)->GetFormula();
145 0 : break;
146 : #ifdef DBG_UTIL
147 : case SwContentAtPos::SW_TABLEBOXVALUE:
148 : {
149 : sTxt = OStringToOUString(OString::valueOf(
150 : ((SwTblBoxValue*)aCntntAtPos.aFnd.pAttr)->GetValue()),
151 : osl_getThreadTextEncoding());
152 : }
153 : break;
154 : case SwContentAtPos::SW_CURR_ATTRS:
155 : sTxt = aCntntAtPos.sStr;
156 : break;
157 : #endif
158 :
159 : case SwContentAtPos::SW_INETATTR:
160 : {
161 0 : sTxt = ((SfxStringItem*)aCntntAtPos.aFnd.pAttr)->GetValue();
162 0 : sTxt = URIHelper::removePassword( sTxt,
163 : INetURLObject::WAS_ENCODED,
164 0 : INetURLObject::DECODE_UNAMBIGUOUS);
165 : //#i63832# remove the link target type
166 0 : xub_StrLen nFound = sTxt.Search(cMarkSeparator);
167 0 : if( nFound != STRING_NOTFOUND && (++nFound) < sTxt.Len() )
168 : {
169 0 : String sSuffix( sTxt.Copy(nFound) );
170 0 : if( sSuffix.EqualsAscii( pMarkToTable ) ||
171 0 : sSuffix.EqualsAscii( pMarkToFrame ) ||
172 0 : sSuffix.EqualsAscii( pMarkToRegion ) ||
173 0 : sSuffix.EqualsAscii( pMarkToOutline ) ||
174 0 : sSuffix.EqualsAscii( pMarkToText ) ||
175 0 : sSuffix.EqualsAscii( pMarkToGraphic ) ||
176 0 : sSuffix.EqualsAscii( pMarkToOLE ))
177 0 : sTxt = sTxt.Copy( 0, nFound - 1);
178 : }
179 : // #i104300#
180 : // special handling if target is a cross-reference bookmark
181 : {
182 0 : String sTmpSearchStr = sTxt.Copy( 1, sTxt.Len() );
183 : IDocumentMarkAccess* const pMarkAccess =
184 0 : rSh.getIDocumentMarkAccess();
185 : IDocumentMarkAccess::const_iterator_t ppBkmk =
186 0 : pMarkAccess->findBookmark( sTmpSearchStr );
187 0 : if ( ppBkmk != pMarkAccess->getBookmarksEnd() &&
188 0 : IDocumentMarkAccess::GetType( *(ppBkmk->get()) )
189 : == IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK )
190 : {
191 0 : SwTxtNode* pTxtNode = ppBkmk->get()->GetMarkStart().nNode.GetNode().GetTxtNode();
192 0 : if ( pTxtNode )
193 : {
194 0 : sTxt = pTxtNode->GetExpandTxt( 0, pTxtNode->Len(), true, true );
195 :
196 0 : if( sTxt.Len() )
197 : {
198 0 : sTxt = comphelper::string::remove(sTxt, 0xad);
199 0 : for( sal_Unicode* p = sTxt.GetBufferAccess(); *p; ++p )
200 : {
201 0 : if( *p < 0x20 )
202 0 : *p = 0x20;
203 0 : else if(*p == 0x2011)
204 0 : *p = '-';
205 : }
206 : }
207 : }
208 0 : }
209 : }
210 : // #i80029#
211 0 : sal_Bool bExecHyperlinks = m_rView.GetDocShell()->IsReadOnly();
212 0 : if ( !bExecHyperlinks )
213 : {
214 0 : SvtSecurityOptions aSecOpts;
215 0 : bExecHyperlinks = !aSecOpts.IsOptionSet( SvtSecurityOptions::E_CTRLCLICK_HYPERLINK );
216 :
217 0 : if ( !bExecHyperlinks )
218 : {
219 0 : sTxt.InsertAscii( ": ", 0 );
220 0 : sTxt.Insert( ViewShell::GetShellRes()->aHyperlinkClick, 0 );
221 0 : }
222 : }
223 0 : break;
224 : }
225 : case SwContentAtPos::SW_SMARTTAG:
226 : {
227 0 : sTxt = SW_RESSTR(STR_SMARTTAG_CLICK);
228 :
229 0 : KeyCode aCode( KEY_SPACE );
230 0 : KeyCode aModifiedCode( KEY_SPACE, KEY_MOD1 );
231 0 : String aModStr( aModifiedCode.GetName() );
232 0 : aModStr.SearchAndReplace( aCode.GetName(), String() );
233 0 : aModStr.SearchAndReplaceAllAscii( "+", String() );
234 0 : sTxt.SearchAndReplaceAllAscii( "%s", aModStr );
235 : }
236 0 : break;
237 :
238 : case SwContentAtPos::SW_FTN:
239 0 : if( aCntntAtPos.pFndTxtAttr && aCntntAtPos.aFnd.pAttr )
240 : {
241 0 : const SwFmtFtn* pFtn = (SwFmtFtn*)aCntntAtPos.aFnd.pAttr;
242 0 : pFtn->GetFtnText( sTxt );
243 0 : sTxt.Insert( SW_RESSTR( pFtn->IsEndNote()
244 0 : ? STR_ENDNOTE : STR_FTNNOTE ), 0 );
245 0 : bBalloon = sal_True;
246 0 : if( aCntntAtPos.IsInRTLText() )
247 0 : nStyle |= QUICKHELP_BIDI_RTL;
248 : }
249 0 : break;
250 :
251 : case SwContentAtPos::SW_REDLINE:
252 0 : lcl_GetRedlineHelp( *aCntntAtPos.aFnd.pRedl, sTxt, bBalloon );
253 0 : break;
254 :
255 : case SwContentAtPos::SW_TOXMARK:
256 0 : sTxt = aCntntAtPos.sStr;
257 0 : if( sTxt.Len() && aCntntAtPos.pFndTxtAttr )
258 : {
259 : const SwTOXType* pTType = aCntntAtPos.pFndTxtAttr->
260 0 : GetTOXMark().GetTOXType();
261 0 : if( pTType && pTType->GetTypeName().Len() )
262 : {
263 0 : sTxt.InsertAscii( ": ", 0 );
264 0 : sTxt.Insert( pTType->GetTypeName(), 0 );
265 : }
266 : }
267 0 : break;
268 : case SwContentAtPos::SW_REFMARK:
269 0 : if(aCntntAtPos.aFnd.pAttr)
270 : {
271 0 : sTxt = SW_RESSTR(STR_CONTENT_TYPE_SINGLE_REFERENCE);
272 0 : sTxt.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ": "));
273 0 : sTxt += ((const SwFmtRefMark*)aCntntAtPos.aFnd.pAttr)->GetRefName();
274 : }
275 0 : break;
276 :
277 : default:
278 : {
279 0 : SwModuleOptions* pModOpt = SW_MOD()->GetModuleConfig();
280 0 : if(!pModOpt->IsHideFieldTips())
281 : {
282 0 : const SwField* pFld = aCntntAtPos.aFnd.pFld;
283 0 : switch( pFld->Which() )
284 : {
285 : case RES_SETEXPFLD:
286 : case RES_TABLEFLD:
287 : case RES_GETEXPFLD:
288 : {
289 0 : sal_uInt16 nOldSubType = pFld->GetSubType();
290 0 : ((SwField*)pFld)->SetSubType(nsSwExtendedSubType::SUB_CMD);
291 0 : sTxt = pFld->ExpandField(true);
292 0 : ((SwField*)pFld)->SetSubType(nOldSubType);
293 : }
294 0 : break;
295 :
296 : case RES_POSTITFLD:
297 : {
298 0 : break;
299 : }
300 : case RES_INPUTFLD: // BubbleHelp, because the suggestion could be quite long
301 0 : bBalloon = sal_True;
302 : /* no break */
303 : case RES_JUMPEDITFLD:
304 0 : sTxt = pFld->GetPar2();
305 0 : break;
306 :
307 : case RES_DBFLD:
308 0 : sTxt = pFld->GetFieldName();
309 0 : break;
310 :
311 : case RES_USERFLD:
312 : case RES_HIDDENTXTFLD:
313 0 : sTxt = pFld->GetPar1();
314 0 : break;
315 :
316 : case RES_DOCSTATFLD:
317 0 : break;
318 :
319 : case RES_MACROFLD:
320 0 : sTxt = ((const SwMacroField*)pFld)->GetMacro();
321 0 : break;
322 :
323 : case RES_GETREFFLD:
324 : {
325 : // #i85090#
326 0 : const SwGetRefField* pRefFld( dynamic_cast<const SwGetRefField*>(pFld) );
327 : OSL_ENSURE( pRefFld,
328 : "<SwEditWin::RequestHelp(..)> - unexpected type of <pFld>" );
329 0 : if ( pRefFld )
330 : {
331 0 : if ( pRefFld->IsRefToHeadingCrossRefBookmark() ||
332 0 : pRefFld->IsRefToNumItemCrossRefBookmark() )
333 : {
334 0 : sTxt = pRefFld->GetExpandedTxtOfReferencedTxtNode();
335 0 : if ( sTxt.Len() > 80 )
336 : {
337 0 : sTxt.Erase( 80 );
338 0 : sTxt += '.';
339 0 : sTxt += '.';
340 0 : sTxt += '.';
341 : }
342 : }
343 : else
344 : {
345 0 : sTxt = ((SwGetRefField*)pFld)->GetSetRefName();
346 : }
347 : }
348 : }
349 0 : break;
350 : }
351 : }
352 :
353 0 : if( !sTxt.Len() )
354 : {
355 0 : aCntntAtPos.eCntntAtPos = SwContentAtPos::SW_REDLINE;
356 0 : if( rSh.GetContentAtPos( aPos, aCntntAtPos, sal_False, &aFldRect ) )
357 : lcl_GetRedlineHelp( *aCntntAtPos.aFnd.pRedl,
358 0 : sTxt, bBalloon );
359 : }
360 : }
361 : }
362 0 : if (sTxt.Len() )
363 : {
364 0 : if( bBalloon )
365 0 : Help::ShowBalloon( this, rEvt.GetMousePosPixel(), sTxt );
366 : else
367 : {
368 : // the show the help
369 0 : Rectangle aRect( aFldRect.SVRect() );
370 0 : Point aPt( OutputToScreenPixel( LogicToPixel( aRect.TopLeft() )));
371 0 : aRect.Left() = aPt.X();
372 0 : aRect.Top() = aPt.Y();
373 0 : aPt = OutputToScreenPixel( LogicToPixel( aRect.BottomRight() ));
374 0 : aRect.Right() = aPt.X();
375 0 : aRect.Bottom() = aPt.Y();
376 0 : Help::ShowQuickHelp( this, aRect, sTxt, nStyle );
377 : }
378 : }
379 :
380 0 : bWeiter = false;
381 : }
382 0 : if( bWeiter )
383 : {
384 0 : sal_uInt8 nTabCols = rSh.WhichMouseTabCol(aPos);
385 0 : sal_uInt16 nTabRes = 0;
386 0 : switch(nTabCols)
387 : {
388 : case SW_TABCOL_HORI:
389 : case SW_TABCOL_VERT:
390 0 : nTabRes = STR_TABLE_COL_ADJUST;
391 0 : break;
392 : case SW_TABROW_HORI:
393 : case SW_TABROW_VERT:
394 0 : nTabRes = STR_TABLE_ROW_ADJUST;
395 0 : break;
396 : // #i32329# Enhanced table selection
397 : case SW_TABSEL_HORI:
398 : case SW_TABSEL_HORI_RTL:
399 : case SW_TABSEL_VERT:
400 0 : nTabRes = STR_TABLE_SELECT_ALL;
401 0 : break;
402 : case SW_TABROWSEL_HORI:
403 : case SW_TABROWSEL_HORI_RTL:
404 : case SW_TABROWSEL_VERT:
405 0 : nTabRes = STR_TABLE_SELECT_ROW;
406 0 : break;
407 : case SW_TABCOLSEL_HORI:
408 : case SW_TABCOLSEL_VERT:
409 0 : nTabRes = STR_TABLE_SELECT_COL;
410 0 : break;
411 : }
412 0 : if(nTabRes)
413 : {
414 0 : sTxt = SW_RESSTR(nTabRes);
415 0 : Size aTxtSize( GetTextWidth(sTxt), GetTextHeight());
416 0 : Rectangle aRect(rEvt.GetMousePosPixel(), aTxtSize);
417 0 : Help::ShowQuickHelp(this, aRect, sTxt);
418 : }
419 0 : bWeiter = false;
420 0 : }
421 : }
422 :
423 0 : if( bWeiter && pSdrView && bQuickBalloon)
424 : {
425 0 : SdrViewEvent aVEvt;
426 0 : SdrHitKind eHit = pSdrView->PickAnything(aPos, aVEvt);
427 : const SvxURLField *pField;
428 0 : SdrObject* pObj = NULL;
429 :
430 0 : if ((pField = aVEvt.pURLField) != 0)
431 : {
432 : // hit an URL field
433 0 : if (pField)
434 : {
435 0 : pObj = aVEvt.pObj;
436 0 : sTxt = pField->GetURL();
437 :
438 0 : bWeiter = false;
439 : }
440 : }
441 0 : if (bWeiter && eHit == SDRHIT_TEXTEDIT)
442 : {
443 : // look for URL field in DrawText object that is opened for editing
444 0 : OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView();
445 : const SvxFieldItem* pFieldItem;
446 :
447 0 : if (pSdrView->AreObjectsMarked())
448 : {
449 0 : const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
450 :
451 0 : if (rMarkList.GetMarkCount() == 1)
452 0 : pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
453 : }
454 :
455 0 : if (pObj && pObj->ISA(SdrTextObj) && pOLV &&
456 : (pFieldItem = pOLV->GetFieldUnderMousePointer()) != 0)
457 : {
458 0 : pField = dynamic_cast<const SvxURLField*>(pFieldItem->GetField());
459 :
460 0 : if (pField )
461 : {
462 0 : sTxt = ((const SvxURLField*) pField)->GetURL();
463 0 : bWeiter = false;
464 : }
465 : }
466 : }
467 0 : if (sTxt.Len() && pObj)
468 : {
469 0 : sTxt = URIHelper::removePassword( sTxt, INetURLObject::WAS_ENCODED,
470 0 : INetURLObject::DECODE_UNAMBIGUOUS);
471 :
472 0 : Rectangle aLogicPix = LogicToPixel(pObj->GetLogicRect());
473 0 : Rectangle aScreenRect(OutputToScreenPixel(aLogicPix.TopLeft()),
474 0 : OutputToScreenPixel(aLogicPix.BottomRight()));
475 :
476 0 : if (bBalloon)
477 0 : Help::ShowBalloon(this, rEvt.GetMousePosPixel(), aScreenRect, sTxt);
478 : else
479 0 : Help::ShowQuickHelp(this, aScreenRect, sTxt);
480 0 : }
481 : }
482 :
483 0 : if( bWeiter )
484 0 : Window::RequestHelp( rEvt );
485 : }
486 :
487 5303 : void SwEditWin::PrePaint()
488 : {
489 5303 : SwWrtShell* pWrtShell = GetView().GetWrtShellPtr();
490 :
491 5303 : if(pWrtShell)
492 : {
493 5303 : pWrtShell->PrePaint();
494 : }
495 5303 : }
496 :
497 2866 : void SwEditWin::Paint(const Rectangle& rRect)
498 : {
499 2866 : SwWrtShell* pWrtShell = GetView().GetWrtShellPtr();
500 2866 : if(!pWrtShell)
501 2866 : return;
502 2866 : bool bPaintShadowCrsr = false;
503 2866 : if( m_pShadCrsr )
504 : {
505 0 : Rectangle aRect( m_pShadCrsr->GetRect());
506 : // fully resides inside?
507 0 : if( rRect.IsInside( aRect ) )
508 : // dann aufheben
509 0 : delete m_pShadCrsr, m_pShadCrsr = 0;
510 0 : else if( rRect.IsOver( aRect ))
511 : {
512 : // resides somewhat above, then everything is clipped outside
513 : // and we have to make the "inner part" at the end of the
514 : // Paint visible again. Otherwise Paint errors occur!
515 0 : bPaintShadowCrsr = true;
516 : }
517 : }
518 :
519 5732 : if ( GetView().GetVisArea().GetWidth() <= 0 ||
520 2866 : GetView().GetVisArea().GetHeight() <= 0 )
521 0 : Invalidate( rRect );
522 : else
523 2866 : pWrtShell->Paint( rRect );
524 :
525 2866 : if( bPaintShadowCrsr )
526 0 : m_pShadCrsr->Paint();
527 99 : }
528 :
529 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|