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 : #include <osl/thread.h>
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 OUString lcl_GetRedlineHelp( const SwRangeRedline& rRedl, 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 : OUStringBuffer sBuf;
85 0 : if( nResId )
86 : {
87 0 : sBuf.append(SW_RESSTR(nResId));
88 0 : sBuf.append(": ");
89 0 : sBuf.append(rRedl.GetAuthorString());
90 0 : sBuf.append(" - ");
91 0 : sBuf.append(GetAppLangDateTimeString(rRedl.GetTimeStamp()));
92 0 : if( bBalloon && !rRedl.GetComment().isEmpty() )
93 0 : sBuf.append('\n').append(rRedl.GetComment());
94 : }
95 0 : return sBuf.makeStringAndClear();
96 : }
97 :
98 0 : void SwEditWin::RequestHelp(const HelpEvent &rEvt)
99 : {
100 0 : SwWrtShell &rSh = m_rView.GetWrtShell();
101 0 : bool bQuickBalloon = 0 != (rEvt.GetMode() & ( HELPMODE_QUICK | HELPMODE_BALLOON ));
102 0 : if(bQuickBalloon && !rSh.GetViewOptions()->IsShowContentTips())
103 0 : return;
104 0 : bool bContinue = true;
105 0 : SET_CURR_SHELL(&rSh);
106 0 : OUString sTxt;
107 0 : Point aPos( PixelToLogic( ScreenToOutputPixel( rEvt.GetMousePosPixel() ) ));
108 0 : sal_Bool bBalloon = static_cast< sal_Bool >(rEvt.GetMode() & HELPMODE_BALLOON);
109 :
110 0 : SdrView *pSdrView = rSh.GetDrawView();
111 :
112 0 : if( bQuickBalloon )
113 : {
114 0 : if( pSdrView )
115 : {
116 0 : SdrPageView* pPV = pSdrView->GetSdrPageView();
117 0 : SwDPage* pPage = pPV ? ((SwDPage*)pPV->GetPage()) : 0;
118 0 : bContinue = pPage && pPage->RequestHelp(this, pSdrView, rEvt);
119 : }
120 : }
121 :
122 0 : if( bContinue && bQuickBalloon)
123 : {
124 0 : SwRect aFldRect;
125 : SwContentAtPos aCntntAtPos( SwContentAtPos::SW_FIELD |
126 : SwContentAtPos::SW_INETATTR |
127 : SwContentAtPos::SW_FTN |
128 : SwContentAtPos::SW_REDLINE |
129 : SwContentAtPos::SW_TOXMARK |
130 : SwContentAtPos::SW_REFMARK |
131 : SwContentAtPos::SW_SMARTTAG |
132 : #ifdef DBG_UTIL
133 : SwContentAtPos::SW_TABLEBOXVALUE |
134 : ( bBalloon ? SwContentAtPos::SW_CURR_ATTRS : 0) |
135 : #endif
136 0 : SwContentAtPos::SW_TABLEBOXFML );
137 :
138 0 : if( rSh.GetContentAtPos( aPos, aCntntAtPos, sal_False, &aFldRect ) )
139 : {
140 0 : sal_uInt16 nStyle = 0; // style of quick help
141 0 : switch( aCntntAtPos.eCntntAtPos )
142 : {
143 : case SwContentAtPos::SW_TABLEBOXFML:
144 0 : sTxt = "= ";
145 0 : sTxt += ((SwTblBoxFormula*)aCntntAtPos.aFnd.pAttr)->GetFormula();
146 0 : break;
147 : #ifdef DBG_UTIL
148 : case SwContentAtPos::SW_TABLEBOXVALUE:
149 : {
150 : sTxt = OStringToOUString(OString::number(
151 : ((SwTblBoxValue*)aCntntAtPos.aFnd.pAttr)->GetValue()),
152 : osl_getThreadTextEncoding());
153 : }
154 : break;
155 : case SwContentAtPos::SW_CURR_ATTRS:
156 : sTxt = aCntntAtPos.sStr;
157 : break;
158 : #endif
159 :
160 : case SwContentAtPos::SW_INETATTR:
161 : {
162 0 : sTxt = ((SfxStringItem*)aCntntAtPos.aFnd.pAttr)->GetValue();
163 0 : sTxt = URIHelper::removePassword( sTxt,
164 : INetURLObject::WAS_ENCODED,
165 0 : INetURLObject::DECODE_UNAMBIGUOUS);
166 : //#i63832# remove the link target type
167 0 : sal_Int32 nFound = sTxt.indexOf(cMarkSeparator);
168 0 : if( nFound != -1 && (++nFound) < sTxt.getLength() )
169 : {
170 0 : OUString sSuffix( sTxt.copy(nFound) );
171 0 : if( sSuffix == "table" ||
172 0 : sSuffix == "frame" ||
173 0 : sSuffix == "region" ||
174 0 : sSuffix == "outline" ||
175 0 : sSuffix == "text" ||
176 0 : sSuffix == "graphic" ||
177 0 : sSuffix == "ole" )
178 0 : sTxt = sTxt.copy( 0, nFound - 1);
179 : }
180 : // #i104300#
181 : // special handling if target is a cross-reference bookmark
182 : {
183 0 : OUString sTmpSearchStr = sTxt.copy( 1 );
184 : IDocumentMarkAccess* const pMarkAccess =
185 0 : rSh.getIDocumentMarkAccess();
186 : IDocumentMarkAccess::const_iterator_t ppBkmk =
187 0 : pMarkAccess->findBookmark( sTmpSearchStr );
188 0 : if ( ppBkmk != pMarkAccess->getBookmarksEnd() &&
189 0 : IDocumentMarkAccess::GetType( *(ppBkmk->get()) )
190 : == IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK )
191 : {
192 0 : SwTxtNode* pTxtNode = ppBkmk->get()->GetMarkStart().nNode.GetNode().GetTxtNode();
193 0 : if ( pTxtNode )
194 : {
195 0 : sTxt = pTxtNode->GetExpandTxt( 0, pTxtNode->Len(), true, true );
196 :
197 0 : if( !sTxt.isEmpty() )
198 : {
199 0 : OUStringBuffer sTmp(comphelper::string::remove(sTxt, 0xad));
200 0 : for (sal_Int32 i = 0; i < sTmp.getLength(); ++i)
201 : {
202 0 : if (sTmp[i] < 0x20)
203 0 : sTmp[i] = 0x20;
204 0 : else if (sTmp[i] == 0x2011)
205 0 : sTmp[i] = '-';
206 : }
207 0 : sTxt = sTmp.makeStringAndClear();
208 : }
209 : }
210 0 : }
211 : }
212 : // #i80029#
213 0 : sal_Bool bExecHyperlinks = m_rView.GetDocShell()->IsReadOnly();
214 0 : if ( !bExecHyperlinks )
215 : {
216 0 : SvtSecurityOptions aSecOpts;
217 0 : bExecHyperlinks = !aSecOpts.IsOptionSet( SvtSecurityOptions::E_CTRLCLICK_HYPERLINK );
218 :
219 0 : sTxt = ": " + sTxt;
220 0 : if ( !bExecHyperlinks )
221 0 : sTxt = SwViewShell::GetShellRes()->aLinkCtrlClick + sTxt;
222 : else
223 0 : sTxt = SwViewShell::GetShellRes()->aLinkClick + sTxt;
224 : }
225 0 : break;
226 : }
227 : case SwContentAtPos::SW_SMARTTAG:
228 : {
229 0 : KeyCode aCode( KEY_SPACE );
230 0 : KeyCode aModifiedCode( KEY_SPACE, KEY_MOD1 );
231 0 : OUString aModStr( aModifiedCode.GetName() );
232 0 : aModStr = aModStr.replaceFirst(aCode.GetName(), OUString());
233 0 : aModStr = aModStr.replaceAll("+", OUString());
234 0 : sTxt = SW_RESSTR(STR_SMARTTAG_CLICK).replaceAll("%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 : OUString sTmp;
243 0 : pFtn->GetFtnText( sTmp );
244 0 : sTxt = SW_RESSTR( pFtn->IsEndNote()
245 0 : ? STR_ENDNOTE : STR_FTNNOTE ) + sTmp;
246 0 : bBalloon = sal_True;
247 0 : if( aCntntAtPos.IsInRTLText() )
248 0 : nStyle |= QUICKHELP_BIDI_RTL;
249 : }
250 0 : break;
251 :
252 : case SwContentAtPos::SW_REDLINE:
253 0 : sTxt = lcl_GetRedlineHelp(*aCntntAtPos.aFnd.pRedl, bBalloon);
254 0 : break;
255 :
256 : case SwContentAtPos::SW_TOXMARK:
257 0 : sTxt = aCntntAtPos.sStr;
258 0 : if( !sTxt.isEmpty() && aCntntAtPos.pFndTxtAttr )
259 : {
260 : const SwTOXType* pTType = aCntntAtPos.pFndTxtAttr->
261 0 : GetTOXMark().GetTOXType();
262 0 : if( pTType && !pTType->GetTypeName().isEmpty() )
263 : {
264 0 : sTxt = ": " + sTxt;
265 0 : sTxt = pTType->GetTypeName() + sTxt;
266 : }
267 : }
268 0 : break;
269 : case SwContentAtPos::SW_REFMARK:
270 0 : if(aCntntAtPos.aFnd.pAttr)
271 : {
272 0 : sTxt = SW_RESSTR(STR_CONTENT_TYPE_SINGLE_REFERENCE);
273 0 : sTxt += ": ";
274 0 : sTxt += ((const SwFmtRefMark*)aCntntAtPos.aFnd.pAttr)->GetRefName();
275 : }
276 0 : break;
277 :
278 : default:
279 : {
280 0 : SwModuleOptions* pModOpt = SW_MOD()->GetModuleConfig();
281 0 : if(!pModOpt->IsHideFieldTips())
282 : {
283 0 : const SwField* pFld = aCntntAtPos.aFnd.pFld;
284 0 : switch( pFld->Which() )
285 : {
286 : case RES_SETEXPFLD:
287 : case RES_TABLEFLD:
288 : case RES_GETEXPFLD:
289 : {
290 0 : sal_uInt16 nOldSubType = pFld->GetSubType();
291 0 : ((SwField*)pFld)->SetSubType(nsSwExtendedSubType::SUB_CMD);
292 0 : sTxt = pFld->ExpandField(true);
293 0 : ((SwField*)pFld)->SetSubType(nOldSubType);
294 : }
295 0 : break;
296 :
297 : case RES_POSTITFLD:
298 : {
299 0 : break;
300 : }
301 : case RES_INPUTFLD: // BubbleHelp, because the suggestion could be quite long
302 0 : bBalloon = sal_True;
303 : /* no break */
304 : case RES_JUMPEDITFLD:
305 0 : sTxt = pFld->GetPar2();
306 0 : break;
307 :
308 : case RES_DBFLD:
309 0 : sTxt = pFld->GetFieldName();
310 0 : break;
311 :
312 : case RES_USERFLD:
313 : case RES_HIDDENTXTFLD:
314 0 : sTxt = pFld->GetPar1();
315 0 : break;
316 :
317 : case RES_DOCSTATFLD:
318 0 : break;
319 :
320 : case RES_MACROFLD:
321 0 : sTxt = ((const SwMacroField*)pFld)->GetMacro();
322 0 : break;
323 :
324 : case RES_GETREFFLD:
325 : {
326 : // #i85090#
327 0 : const SwGetRefField* pRefFld( dynamic_cast<const SwGetRefField*>(pFld) );
328 : OSL_ENSURE( pRefFld,
329 : "<SwEditWin::RequestHelp(..)> - unexpected type of <pFld>" );
330 0 : if ( pRefFld )
331 : {
332 0 : if ( pRefFld->IsRefToHeadingCrossRefBookmark() ||
333 0 : pRefFld->IsRefToNumItemCrossRefBookmark() )
334 : {
335 0 : sTxt = pRefFld->GetExpandedTxtOfReferencedTxtNode();
336 0 : if ( sTxt.getLength() > 80 )
337 : {
338 0 : sTxt = sTxt.copy(0, 80) + "...";
339 : }
340 : }
341 : else
342 : {
343 0 : sTxt = ((SwGetRefField*)pFld)->GetSetRefName();
344 : }
345 : }
346 : }
347 0 : break;
348 : }
349 : }
350 :
351 0 : if( sTxt.isEmpty() )
352 : {
353 0 : aCntntAtPos.eCntntAtPos = SwContentAtPos::SW_REDLINE;
354 0 : if( rSh.GetContentAtPos( aPos, aCntntAtPos, sal_False, &aFldRect ) )
355 0 : sTxt = lcl_GetRedlineHelp(*aCntntAtPos.aFnd.pRedl, bBalloon);
356 : }
357 : }
358 : }
359 0 : if (!sTxt.isEmpty())
360 : {
361 0 : if( bBalloon )
362 0 : Help::ShowBalloon( this, rEvt.GetMousePosPixel(), sTxt );
363 : else
364 : {
365 : // the show the help
366 0 : Rectangle aRect( aFldRect.SVRect() );
367 0 : Point aPt( OutputToScreenPixel( LogicToPixel( aRect.TopLeft() )));
368 0 : aRect.Left() = aPt.X();
369 0 : aRect.Top() = aPt.Y();
370 0 : aPt = OutputToScreenPixel( LogicToPixel( aRect.BottomRight() ));
371 0 : aRect.Right() = aPt.X();
372 0 : aRect.Bottom() = aPt.Y();
373 0 : Help::ShowQuickHelp( this, aRect, sTxt, nStyle );
374 : }
375 : }
376 :
377 0 : bContinue = false;
378 : }
379 0 : if( bContinue )
380 : {
381 0 : sal_uInt8 nTabCols = rSh.WhichMouseTabCol(aPos);
382 0 : sal_uInt16 nTabRes = 0;
383 0 : switch(nTabCols)
384 : {
385 : case SW_TABCOL_HORI:
386 : case SW_TABCOL_VERT:
387 0 : nTabRes = STR_TABLE_COL_ADJUST;
388 0 : break;
389 : case SW_TABROW_HORI:
390 : case SW_TABROW_VERT:
391 0 : nTabRes = STR_TABLE_ROW_ADJUST;
392 0 : break;
393 : // #i32329# Enhanced table selection
394 : case SW_TABSEL_HORI:
395 : case SW_TABSEL_HORI_RTL:
396 : case SW_TABSEL_VERT:
397 0 : nTabRes = STR_TABLE_SELECT_ALL;
398 0 : break;
399 : case SW_TABROWSEL_HORI:
400 : case SW_TABROWSEL_HORI_RTL:
401 : case SW_TABROWSEL_VERT:
402 0 : nTabRes = STR_TABLE_SELECT_ROW;
403 0 : break;
404 : case SW_TABCOLSEL_HORI:
405 : case SW_TABCOLSEL_VERT:
406 0 : nTabRes = STR_TABLE_SELECT_COL;
407 0 : break;
408 : }
409 0 : if(nTabRes)
410 : {
411 0 : sTxt = SW_RESSTR(nTabRes);
412 0 : Size aTxtSize( GetTextWidth(sTxt), GetTextHeight());
413 0 : Rectangle aRect(rEvt.GetMousePosPixel(), aTxtSize);
414 0 : Help::ShowQuickHelp(this, aRect, sTxt);
415 : }
416 0 : bContinue = false;
417 0 : }
418 : }
419 :
420 0 : if( bContinue )
421 0 : Window::RequestHelp( rEvt );
422 : }
423 :
424 0 : void SwEditWin::PrePaint()
425 : {
426 0 : SwWrtShell* pWrtShell = GetView().GetWrtShellPtr();
427 :
428 0 : if(pWrtShell)
429 : {
430 0 : pWrtShell->PrePaint();
431 : }
432 0 : }
433 :
434 0 : void SwEditWin::Paint(const Rectangle& rRect)
435 : {
436 0 : SwWrtShell* pWrtShell = GetView().GetWrtShellPtr();
437 0 : if(!pWrtShell)
438 0 : return;
439 0 : bool bPaintShadowCrsr = false;
440 0 : if( m_pShadCrsr )
441 : {
442 0 : Rectangle aRect( m_pShadCrsr->GetRect());
443 : // fully resides inside?
444 0 : if( rRect.IsInside( aRect ) )
445 : // dann aufheben
446 0 : delete m_pShadCrsr, m_pShadCrsr = 0;
447 0 : else if( rRect.IsOver( aRect ))
448 : {
449 : // resides somewhat above, then everything is clipped outside
450 : // and we have to make the "inner part" at the end of the
451 : // Paint visible again. Otherwise Paint errors occur!
452 0 : bPaintShadowCrsr = true;
453 : }
454 : }
455 :
456 0 : if ( GetView().GetVisArea().GetWidth() <= 0 ||
457 0 : GetView().GetVisArea().GetHeight() <= 0 )
458 0 : Invalidate( rRect );
459 : else
460 0 : pWrtShell->Paint( rRect );
461 :
462 0 : if( bPaintShadowCrsr )
463 0 : m_pShadCrsr->Paint();
464 : }
465 :
466 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|