Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 192, column 9
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name newhelp.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SFX2_DLLIMPLEMENTATION -D ENABLE_CUPS -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sfx2/inc -I /home/maarten/src/libreoffice/core/sfx2/source/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sfx2/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx

/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx

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
21#include "newhelp.hxx"
22#include <sfx2/sfxresid.hxx>
23#include "helpinterceptor.hxx"
24#include <helper.hxx>
25#include <srchdlg.hxx>
26#include <sfx2/sfxhelp.hxx>
27#include <sal/log.hxx>
28#include <osl/diagnose.h>
29#include <tools/debug.hxx>
30#include <tools/diagnose_ex.h>
31
32#include <sfx2/strings.hrc>
33#include <helpids.h>
34#include <bitmaps.hlst>
35
36#include <rtl/ustrbuf.hxx>
37#include <comphelper/configurationhelper.hxx>
38#include <comphelper/processfactory.hxx>
39#include <comphelper/string.hxx>
40#include <toolkit/helper/vclunohelper.hxx>
41#include <com/sun/star/awt/PosSize.hpp>
42#include <com/sun/star/beans/PropertyValue.hpp>
43#include <com/sun/star/beans/XPropertySetInfo.hpp>
44#include <com/sun/star/container/XIndexAccess.hpp>
45#include <com/sun/star/frame/XComponentLoader.hpp>
46#include <com/sun/star/frame/XTitle.hpp>
47#include <com/sun/star/frame/XLayoutManager.hpp>
48#include <com/sun/star/frame/XController.hpp>
49#include <com/sun/star/frame/XDispatch.hpp>
50#include <com/sun/star/frame/XDispatchProvider.hpp>
51#include <com/sun/star/frame/Frame.hpp>
52#include <com/sun/star/i18n/XBreakIterator.hpp>
53#include <com/sun/star/i18n/WordType.hpp>
54#include <com/sun/star/lang/XComponent.hpp>
55#include <com/sun/star/style/XStyle.hpp>
56#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
57#include <com/sun/star/text/XText.hpp>
58#include <com/sun/star/text/XTextCursor.hpp>
59#include <com/sun/star/text/XTextDocument.hpp>
60#include <com/sun/star/text/XTextViewCursor.hpp>
61#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
62#include <com/sun/star/ucb/CommandAbortedException.hpp>
63#include <com/sun/star/util/URL.hpp>
64#include <com/sun/star/util/XSearchable.hpp>
65#include <com/sun/star/util/XSearchDescriptor.hpp>
66#include <com/sun/star/util/URLTransformer.hpp>
67#include <com/sun/star/util/XURLTransformer.hpp>
68#include <com/sun/star/util/XModifiable.hpp>
69#include <com/sun/star/util/XCloseable.hpp>
70#include <com/sun/star/util/CloseVetoException.hpp>
71#include <com/sun/star/view/XSelectionSupplier.hpp>
72#include <com/sun/star/view/XViewSettingsSupplier.hpp>
73#include <unotools/historyoptions.hxx>
74#include <svtools/menuoptions.hxx>
75#include <unotools/viewoptions.hxx>
76#include <tools/urlobj.hxx>
77#include <svtools/imagemgr.hxx>
78#include <svtools/miscopt.hxx>
79#include <vcl/commandevent.hxx>
80#include <vcl/event.hxx>
81#include <vcl/i18nhelp.hxx>
82#include <vcl/layout.hxx>
83#include <vcl/taskpanelist.hxx>
84#include <vcl/settings.hxx>
85#include <vcl/svapp.hxx>
86#include <vcl/unohelp.hxx>
87#include <vcl/weld.hxx>
88
89#include <ucbhelper/content.hxx>
90#include <unotools/ucbhelper.hxx>
91
92#include <unordered_map>
93#include <vector>
94
95using namespace ::ucbhelper;
96using namespace ::com::sun::star::ucb;
97
98using namespace ::com::sun::star;
99using namespace ::com::sun::star::beans;
100using namespace ::com::sun::star::container;
101using namespace ::com::sun::star::frame;
102using namespace ::com::sun::star::i18n;
103using namespace ::com::sun::star::lang;
104using namespace ::com::sun::star::style;
105using namespace ::com::sun::star::text;
106using namespace ::com::sun::star::uno;
107using namespace ::com::sun::star::util;
108using namespace ::com::sun::star::view;
109using namespace ::com::sun::star::ui;
110
111using namespace ::comphelper;
112
113// defines ---------------------------------------------------------------
114
115#define CONFIGNAME_HELPWIN"OfficeHelp" "OfficeHelp"
116#define CONFIGNAME_INDEXWIN"OfficeHelpIndex" "OfficeHelpIndex"
117#define CONFIGNAME_SEARCHPAGE"OfficeHelpSearch" "OfficeHelpSearch"
118#define IMAGE_URL"private:factory/" "private:factory/"
119
120#define PROPERTY_KEYWORDLIST"KeywordList" "KeywordList"
121#define PROPERTY_KEYWORDREF"KeywordRef" "KeywordRef"
122#define PROPERTY_ANCHORREF"KeywordAnchorForRef" "KeywordAnchorForRef"
123#define PROPERTY_TITLEREF"KeywordTitleForRef" "KeywordTitleForRef"
124#define PROPERTY_TITLE"Title" "Title"
125#define HELP_URL"vnd.sun.star.help://" "vnd.sun.star.help://"
126#define HELP_SEARCH_TAG"/?Query=" "/?Query="
127#define USERITEM_NAME"UserItem" "UserItem"
128
129#define PACKAGE_SETUP"/org.openoffice.Setup" "/org.openoffice.Setup"
130#define PATH_OFFICE_FACTORIES"Office/Factories/" "Office/Factories/"
131#define KEY_HELP_ON_OPEN"ooSetupFactoryHelpOnOpen" "ooSetupFactoryHelpOnOpen"
132#define KEY_UI_NAME"ooSetupFactoryUIName" "ooSetupFactoryUIName"
133
134namespace sfx2
135{
136
137
138 /** Prepare a search string for searching or selecting.
139 For searching every search word needs the postfix '*' and the delimiter ' ' if necessary.
140 For selecting the delimiter '|' is required to search with regular expressions.
141 Samples:
142 search string | output for searching | output for selecting
143 -----------------------------------------------------------
144 "text" | "text*" | "text"
145 "text*" | "text*" | "text"
146 "text menu" | "text* menu*" | "text|menu"
147 */
148 static OUString PrepareSearchString( const OUString& rSearchString,
149 const Reference< XBreakIterator >& xBreak, bool bForSearch )
150 {
151 OUStringBuffer sSearchStr;
152 sal_Int32 nStartPos = 0;
153 const lang::Locale aLocale = Application::GetSettings().GetUILanguageTag().getLocale();
154 Boundary aBoundary = xBreak->getWordBoundary(
155 rSearchString, nStartPos, aLocale, WordType::ANYWORD_IGNOREWHITESPACES, true );
156
157 while ( aBoundary.startPos < aBoundary.endPos )
158 {
159 nStartPos = aBoundary.endPos;
160 OUString sSearchToken( rSearchString.copy(
161 static_cast<sal_uInt16>(aBoundary.startPos), static_cast<sal_uInt16>(aBoundary.endPos) - static_cast<sal_uInt16>(aBoundary.startPos) ) );
162 if ( !sSearchToken.isEmpty() && ( sSearchToken.getLength() > 1 || sSearchToken[0] != '.' ) )
163 {
164 if ( bForSearch && sSearchToken[ sSearchToken.getLength() - 1 ] != '*' )
165 sSearchToken += "*";
166
167 if ( sSearchToken.getLength() > 1 ||
168 ( sSearchToken.getLength() > 0 && sSearchToken[ 0 ] != '*' ) )
169 {
170 if ( !sSearchStr.isEmpty() )
171 {
172 if ( bForSearch )
173 sSearchStr.append(" ");
174 else
175 sSearchStr.append("|");
176 }
177 sSearchStr.append(sSearchToken);
178 }
179 }
180 aBoundary = xBreak->nextWord( rSearchString, nStartPos,
181 aLocale, WordType::ANYWORD_IGNOREWHITESPACES );
182 }
183
184 return sSearchStr.makeStringAndClear();
185 }
186
187// namespace sfx2
188}
189
190
191// struct IndexEntry_Impl ------------------------------------------------
192
193namespace {
194
195struct IndexEntry_Impl
196{
197 bool m_bSubEntry;
198 OUString m_aURL;
199
200 IndexEntry_Impl( const OUString& rURL, bool bSubEntry ) :
201 m_bSubEntry( bSubEntry ), m_aURL( rURL ) {}
202};
203
204// struct ContentEntry_Impl ----------------------------------------------
205
206struct ContentEntry_Impl
207{
208 OUString aURL;
209 bool bIsFolder;
210
211 ContentEntry_Impl( const OUString& rURL, bool bFolder ) :
212 aURL( rURL ), bIsFolder( bFolder ) {}
213};
214
215}
216
217void ContentTabPage_Impl::InitRoot()
218{
219 std::vector< OUString > aList =
220 SfxContentHelper::GetHelpTreeViewContents( "vnd.sun.star.hier://com.sun.star.help.TreeView/" );
221
222 for (const OUString & aRow : aList)
223 {
224 sal_Int32 nIdx = 0;
225 OUString aTitle = aRow.getToken( 0, '\t', nIdx );
226 OUString aURL = aRow.getToken( 0, '\t', nIdx );
227 sal_Unicode cFolder = aRow.getToken( 0, '\t', nIdx )[0];
228 bool bIsFolder = ( '1' == cFolder );
229 OUString sId;
230 if (bIsFolder)
231 sId = OUString::number(reinterpret_cast<sal_Int64>(new ContentEntry_Impl(aURL, true)));
232 m_xContentBox->insert(nullptr, -1, &aTitle, &sId, nullptr, nullptr, true, m_xScratchIter.get());
233 m_xContentBox->set_image(*m_xScratchIter, aClosedBookImage);
234 }
235}
236
237void ContentTabPage_Impl::ClearChildren(const weld::TreeIter* pParent)
238{
239 std::unique_ptr<weld::TreeIter> xEntry = m_xContentBox->make_iterator(pParent);
240 bool bEntry = m_xContentBox->iter_children(*xEntry);
241 while (bEntry)
242 {
243 ClearChildren(xEntry.get());
244 delete reinterpret_cast<ContentEntry_Impl*>(m_xContentBox->get_id(*xEntry).toInt64());
245 bEntry = m_xContentBox->iter_next_sibling(*xEntry);
246 }
247
248}
249
250IMPL_LINK(ContentTabPage_Impl, ExpandingHdl, const weld::TreeIter&, rIter, bool)bool ContentTabPage_Impl::LinkStubExpandingHdl(void * instance
, const weld::TreeIter& data) { return static_cast<ContentTabPage_Impl
*>(instance)->ExpandingHdl(data); } bool ContentTabPage_Impl
::ExpandingHdl(const weld::TreeIter& rIter)
251{
252 ContentEntry_Impl* pContentEntry = reinterpret_cast<ContentEntry_Impl*>(m_xContentBox->get_id(rIter).toInt64());
253 if (!m_xContentBox->iter_has_child(rIter))
254 {
255 try
256 {
257 if (pContentEntry)
258 {
259 std::vector<OUString > aList = SfxContentHelper::GetHelpTreeViewContents(pContentEntry->aURL);
260
261 for (const OUString & aRow : aList)
262 {
263 sal_Int32 nIdx = 0;
264 OUString aTitle = aRow.getToken( 0, '\t', nIdx );
265 OUString aURL = aRow.getToken( 0, '\t', nIdx );
266 sal_Unicode cFolder = aRow.getToken( 0, '\t', nIdx )[0];
267 bool bIsFolder = ( '1' == cFolder );
268 if ( bIsFolder )
269 {
270 OUString sId = OUString::number(reinterpret_cast<sal_Int64>(new ContentEntry_Impl(aURL, true)));
271 m_xContentBox->insert(&rIter, -1, &aTitle, &sId, nullptr, nullptr, true, m_xScratchIter.get());
272 m_xContentBox->set_image(*m_xScratchIter, aClosedBookImage);
273 }
274 else
275 {
276 Any aAny( ::utl::UCBContentHelper::GetProperty( aURL, "TargetURL" ) );
277 OUString sId;
278 OUString aTargetURL;
279 if ( aAny >>= aTargetURL )
280 sId = OUString::number(reinterpret_cast<sal_Int64>(new ContentEntry_Impl(aTargetURL, false)));
281 m_xContentBox->insert(&rIter, -1, &aTitle, &sId, nullptr, nullptr, false, m_xScratchIter.get());
282 m_xContentBox->set_image(*m_xScratchIter, aDocumentImage);
283 }
284 }
285 }
286 }
287 catch (const Exception&)
288 {
289 OSL_FAIL( "ContentListBox_Impl::RequestingChildren(): unexpected exception" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "289" ": "), "%s", "ContentListBox_Impl::RequestingChildren(): unexpected exception"
); } } while (false)
;
290 }
291 }
292
293 if (!pContentEntry || pContentEntry->bIsFolder)
294 m_xContentBox->set_image(rIter, aOpenBookImage);
295
296 return true;
297}
298
299IMPL_LINK(ContentTabPage_Impl, CollapsingHdl, const weld::TreeIter&, rIter, bool)bool ContentTabPage_Impl::LinkStubCollapsingHdl(void * instance
, const weld::TreeIter& data) { return static_cast<ContentTabPage_Impl
*>(instance)->CollapsingHdl(data); } bool ContentTabPage_Impl
::CollapsingHdl(const weld::TreeIter& rIter)
300{
301 ContentEntry_Impl* pContentEntry = reinterpret_cast<ContentEntry_Impl*>(m_xContentBox->get_id(rIter).toInt64());
302 if (!pContentEntry || pContentEntry->bIsFolder)
303 m_xContentBox->set_image(rIter, aClosedBookImage);
304
305 return true;
306}
307
308OUString ContentTabPage_Impl::GetSelectedEntry() const
309{
310 OUString aRet;
311 ContentEntry_Impl* pEntry = reinterpret_cast<ContentEntry_Impl*>(m_xContentBox->get_selected_id().toInt64());
312 if (pEntry && !pEntry->bIsFolder)
313 aRet = pEntry->aURL;
314 return aRet;
315}
316
317// class HelpTabPage_Impl ------------------------------------------------
318HelpTabPage_Impl::HelpTabPage_Impl(weld::Widget* pParent, SfxHelpIndexWindow_Impl* pIdxWin,
319 const OString& rID, const OUString& rUIXMLDescription)
320 : BuilderPage(pParent, nullptr, rUIXMLDescription, rID)
321 , m_pIdxWin(pIdxWin)
322{
323}
324
325HelpTabPage_Impl::~HelpTabPage_Impl()
326{
327}
328
329// class ContentTabPage_Impl ---------------------------------------------
330ContentTabPage_Impl::ContentTabPage_Impl(weld::Widget* pParent, SfxHelpIndexWindow_Impl* pIdxWin)
331 : HelpTabPage_Impl(pParent, pIdxWin, "HelpContentPage",
332 "sfx/ui/helpcontentpage.ui")
333 , m_xContentBox(m_xBuilder->weld_tree_view("content"))
334 , m_xScratchIter(m_xContentBox->make_iterator())
335 , aOpenBookImage(BMP_HELP_CONTENT_BOOK_OPEN"sfx2/res/hlpbookopen.png")
336 , aClosedBookImage(BMP_HELP_CONTENT_BOOK_CLOSED"sfx2/res/hlpbookclosed.png")
337 , aDocumentImage(BMP_HELP_CONTENT_DOC"sfx2/res/hlpdoc.png")
338{
339 m_xContentBox->set_size_request(m_xContentBox->get_approximate_digit_width() * 30,
340 m_xContentBox->get_height_rows(20));
341 m_xContentBox->connect_row_activated(LINK(this, ContentTabPage_Impl, DoubleClickHdl)::tools::detail::makeLink( ::tools::detail::castTo<ContentTabPage_Impl
*>(this), &ContentTabPage_Impl::LinkStubDoubleClickHdl
)
);
342 m_xContentBox->connect_expanding(LINK(this, ContentTabPage_Impl, ExpandingHdl)::tools::detail::makeLink( ::tools::detail::castTo<ContentTabPage_Impl
*>(this), &ContentTabPage_Impl::LinkStubExpandingHdl)
);
343 m_xContentBox->connect_collapsing(LINK(this, ContentTabPage_Impl, CollapsingHdl)::tools::detail::makeLink( ::tools::detail::castTo<ContentTabPage_Impl
*>(this), &ContentTabPage_Impl::LinkStubCollapsingHdl
)
);
344
345 InitRoot();
346}
347
348IMPL_LINK_NOARG(ContentTabPage_Impl, DoubleClickHdl, weld::TreeView&, bool)bool ContentTabPage_Impl::LinkStubDoubleClickHdl(void * instance
, weld::TreeView& data) { return static_cast<ContentTabPage_Impl
*>(instance)->DoubleClickHdl(data); } bool ContentTabPage_Impl
::DoubleClickHdl(__attribute__ ((unused)) weld::TreeView&
)
349{
350 aDoubleClickHdl.Call(nullptr);
351 return false;
352}
353
354void ContentTabPage_Impl::SetDoubleClickHdl(const Link<LinkParamNone*, void>& rLink)
355{
356 aDoubleClickHdl = rLink;
357}
358
359ContentTabPage_Impl::~ContentTabPage_Impl()
360{
361 std::unique_ptr<weld::TreeIter> xEntry = m_xContentBox->make_iterator();
362 bool bEntry = m_xContentBox->get_iter_first(*xEntry);
363 while (bEntry)
364 {
365 ClearChildren(xEntry.get());
366 delete reinterpret_cast<ContentEntry_Impl*>(m_xContentBox->get_id(*xEntry).toInt64());
367 bEntry = m_xContentBox->iter_next_sibling(*xEntry);
368 }
369}
370
371void IndexTabPage_Impl::SelectExecutableEntry()
372{
373 sal_Int32 nPos = m_xIndexList->find_text(m_xIndexEntry->get_text());
374 if (nPos == -1)
375 return;
376
377 sal_Int32 nOldPos = nPos;
378 OUString aEntryText;
379 IndexEntry_Impl* pEntry = reinterpret_cast<IndexEntry_Impl*>(m_xIndexList->get_id(nPos).toInt64());
380 sal_Int32 nCount = m_xIndexList->n_children();
381 while ( nPos < nCount && ( !pEntry || pEntry->m_aURL.isEmpty() ) )
382 {
383 pEntry = reinterpret_cast<IndexEntry_Impl*>(m_xIndexList->get_id(++nPos).toInt64());
384 aEntryText = m_xIndexList->get_text(nPos);
385 }
386
387 if ( nOldPos != nPos )
388 m_xIndexEntry->set_text(aEntryText);
389}
390
391// class IndexTabPage_Impl -----------------------------------------------
392IndexTabPage_Impl::IndexTabPage_Impl(weld::Widget* pParent, SfxHelpIndexWindow_Impl* pIdxWin)
393 : HelpTabPage_Impl(pParent, pIdxWin, "HelpIndexPage", "sfx/ui/helpindexpage.ui")
394 , m_xIndexEntry(m_xBuilder->weld_entry("termentry"))
395 , m_xIndexList(m_xBuilder->weld_tree_view("termlist"))
396 , m_xOpenBtn(m_xBuilder->weld_button("display"))
397 , aFactoryIdle("sfx2 appl IndexTabPage_Impl Factory")
398 , aAutoCompleteIdle("sfx2 appl IndexTabPage_Impl AutoComplete")
399 , bIsActivated(false)
400 , nRowHeight(m_xIndexList->get_height_rows(1))
401 , nAllHeight(0)
402{
403 m_xIndexList->set_size_request(m_xIndexList->get_approximate_digit_width() * 30, -1);
404
405 m_xOpenBtn->connect_clicked(LINK(this, IndexTabPage_Impl, OpenHdl)::tools::detail::makeLink( ::tools::detail::castTo<IndexTabPage_Impl
*>(this), &IndexTabPage_Impl::LinkStubOpenHdl)
);
406 aFactoryIdle.SetInvokeHandler( LINK(this, IndexTabPage_Impl, IdleHdl )::tools::detail::makeLink( ::tools::detail::castTo<IndexTabPage_Impl
*>(this), &IndexTabPage_Impl::LinkStubIdleHdl)
);
407 aAutoCompleteIdle.SetInvokeHandler( LINK(this, IndexTabPage_Impl, AutoCompleteHdl )::tools::detail::makeLink( ::tools::detail::castTo<IndexTabPage_Impl
*>(this), &IndexTabPage_Impl::LinkStubAutoCompleteHdl
)
);
408 aKeywordTimer.SetInvokeHandler( LINK( this, IndexTabPage_Impl, TimeoutHdl )::tools::detail::makeLink( ::tools::detail::castTo<IndexTabPage_Impl
*>(this), &IndexTabPage_Impl::LinkStubTimeoutHdl)
);
409 m_xIndexList->connect_row_activated(LINK(this, IndexTabPage_Impl, DoubleClickHdl)::tools::detail::makeLink( ::tools::detail::castTo<IndexTabPage_Impl
*>(this), &IndexTabPage_Impl::LinkStubDoubleClickHdl)
);
410 m_xIndexList->connect_changed(LINK(this, IndexTabPage_Impl, TreeChangeHdl)::tools::detail::makeLink( ::tools::detail::castTo<IndexTabPage_Impl
*>(this), &IndexTabPage_Impl::LinkStubTreeChangeHdl)
);
411 m_xIndexList->connect_custom_get_size(LINK(this, IndexTabPage_Impl, CustomGetSizeHdl)::tools::detail::makeLink( ::tools::detail::castTo<IndexTabPage_Impl
*>(this), &IndexTabPage_Impl::LinkStubCustomGetSizeHdl
)
);
412 m_xIndexList->connect_custom_render(LINK(this, IndexTabPage_Impl, CustomRenderHdl)::tools::detail::makeLink( ::tools::detail::castTo<IndexTabPage_Impl
*>(this), &IndexTabPage_Impl::LinkStubCustomRenderHdl
)
);
413 m_xIndexList->set_column_custom_renderer(0, true);
414 m_xIndexList->connect_size_allocate(LINK(this, IndexTabPage_Impl, ResizeHdl)::tools::detail::makeLink( ::tools::detail::castTo<IndexTabPage_Impl
*>(this), &IndexTabPage_Impl::LinkStubResizeHdl)
);
415 m_xIndexEntry->connect_key_press(LINK(this, IndexTabPage_Impl, KeyInputHdl)::tools::detail::makeLink( ::tools::detail::castTo<IndexTabPage_Impl
*>(this), &IndexTabPage_Impl::LinkStubKeyInputHdl)
);
416 m_xIndexEntry->connect_changed(LINK(this, IndexTabPage_Impl, EntryChangeHdl)::tools::detail::makeLink( ::tools::detail::castTo<IndexTabPage_Impl
*>(this), &IndexTabPage_Impl::LinkStubEntryChangeHdl)
);
417 m_xIndexEntry->connect_activate(LINK(this, IndexTabPage_Impl, ActivateHdl)::tools::detail::makeLink( ::tools::detail::castTo<IndexTabPage_Impl
*>(this), &IndexTabPage_Impl::LinkStubActivateHdl)
);
418}
419
420IMPL_LINK(IndexTabPage_Impl, ResizeHdl, const Size&, rSize, void)void IndexTabPage_Impl::LinkStubResizeHdl(void * instance, const
Size& data) { return static_cast<IndexTabPage_Impl *>
(instance)->ResizeHdl(data); } void IndexTabPage_Impl::ResizeHdl
(const Size& rSize)
421{
422 nAllHeight = rSize.Height();
423}
424
425IMPL_LINK_NOARG(IndexTabPage_Impl, CustomGetSizeHdl, weld::TreeView::get_size_args, Size)Size IndexTabPage_Impl::LinkStubCustomGetSizeHdl(void * instance
, weld::TreeView::get_size_args data) { return static_cast<
IndexTabPage_Impl *>(instance)->CustomGetSizeHdl(data);
} Size IndexTabPage_Impl::CustomGetSizeHdl(__attribute__ ((unused
)) weld::TreeView::get_size_args)
426{
427 return Size(m_xIndexList->get_size_request().Width(), nRowHeight);
428}
429
430IMPL_LINK(IndexTabPage_Impl, CustomRenderHdl, weld::TreeView::render_args, aPayload, void)void IndexTabPage_Impl::LinkStubCustomRenderHdl(void * instance
, weld::TreeView::render_args data) { return static_cast<IndexTabPage_Impl
*>(instance)->CustomRenderHdl(data); } void IndexTabPage_Impl
::CustomRenderHdl(weld::TreeView::render_args aPayload)
431{
432 vcl::RenderContext& rRenderContext = std::get<0>(aPayload);
433 const ::tools::Rectangle& rRect = std::get<1>(aPayload);
434 bool bSelected = std::get<2>(aPayload);
435 const OUString& rId = std::get<3>(aPayload);
436
437 rRenderContext.Push(PushFlags::TEXTCOLOR);
438 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
439 if (bSelected)
440 rRenderContext.SetTextColor(rStyleSettings.GetHighlightTextColor());
441 else
442 rRenderContext.SetTextColor(rStyleSettings.GetDialogTextColor());
443
444 Point aPos(rRect.TopLeft());
445 aPos.AdjustY((rRect.GetHeight() - rRenderContext.GetTextHeight()) / 2);
446
447 int nIndex = m_xIndexList->find_id(rId);
448 OUString aEntry(m_xIndexList->get_text(nIndex));
449
450 IndexEntry_Impl* pEntry = reinterpret_cast<IndexEntry_Impl*>(rId.toInt64());
451 if (pEntry && pEntry->m_bSubEntry)
452 {
453 // indent sub entries
454 aPos.AdjustX(8);
455 sal_Int32 nPos = aEntry.indexOf(';');
456 rRenderContext.DrawText(aPos, (nPos !=-1) ? aEntry.copy(nPos + 1) : aEntry);
457 }
458 else
459 rRenderContext.DrawText(aPos, aEntry);
460
461 rRenderContext.Pop();
462}
463
464IMPL_LINK_NOARG(IndexTabPage_Impl, TreeChangeHdl, weld::TreeView&, void)void IndexTabPage_Impl::LinkStubTreeChangeHdl(void * instance
, weld::TreeView& data) { return static_cast<IndexTabPage_Impl
*>(instance)->TreeChangeHdl(data); } void IndexTabPage_Impl
::TreeChangeHdl(__attribute__ ((unused)) weld::TreeView&)
465{
466 m_xIndexEntry->set_text(m_xIndexList->get_selected_text());
467}
468
469IMPL_LINK_NOARG(IndexTabPage_Impl, EntryChangeHdl, weld::Entry&, void)void IndexTabPage_Impl::LinkStubEntryChangeHdl(void * instance
, weld::Entry& data) { return static_cast<IndexTabPage_Impl
*>(instance)->EntryChangeHdl(data); } void IndexTabPage_Impl
::EntryChangeHdl(__attribute__ ((unused)) weld::Entry&)
470{
471 aAutoCompleteIdle.Start();
472}
473
474IMPL_LINK(IndexTabPage_Impl, KeyInputHdl, const KeyEvent&, rKEvt, bool)bool IndexTabPage_Impl::LinkStubKeyInputHdl(void * instance, const
KeyEvent& data) { return static_cast<IndexTabPage_Impl
*>(instance)->KeyInputHdl(data); } bool IndexTabPage_Impl
::KeyInputHdl(const KeyEvent& rKEvt)
475{
476 const vcl::KeyCode& rKCode = rKEvt.GetKeyCode();
477 if (rKCode.GetModifier()) // only with no modifiers held
478 return false;
479
480 sal_uInt16 nCode = rKCode.GetCode();
481
482 if (nCode == KEY_UP || nCode == KEY_PAGEUP ||
483 nCode == KEY_DOWN || nCode == KEY_PAGEDOWN)
484 {
485// disable_notify_events();
486 sal_Int32 nIndex = m_xIndexList->get_selected_index();
487 sal_Int32 nOrigIndex = nIndex;
488 sal_Int32 nCount = m_xIndexList->n_children();
489 if (nIndex == -1)
490 {
491 m_xIndexList->set_cursor(0);
492 m_xIndexList->select(0);
493 m_xIndexEntry->set_text(m_xIndexList->get_selected_text());
494 }
495 else
496 {
497 if (nCode == KEY_UP)
498 --nIndex;
499 else if (nCode == KEY_DOWN)
500 ++nIndex;
501 else if (nCode == KEY_PAGEUP)
502 {
503 int nVisRows = nAllHeight / nRowHeight;
504 nIndex -= nVisRows;
505 }
506 else if (nCode == KEY_PAGEDOWN)
507 {
508 int nVisRows = nAllHeight / nRowHeight;
509 nIndex += nVisRows;
510 }
511
512 if (nIndex < 0)
513 nIndex = 0;
514 if (nIndex >= nCount)
515 nIndex = nCount - 1;
516
517 if (nIndex != nOrigIndex)
518 {
519 m_xIndexList->set_cursor(nIndex);
520 m_xIndexList->select(nIndex);
521 m_xIndexEntry->set_text(m_xIndexList->get_selected_text());
522 }
523
524// m_xIndexList->grab_focus();
525// g_signal_emit_by_name(pWidget, "key-press-event", pEvent, &ret);
526// m_xIndexEntry->set_text(m_xIndexList->get_selected_text());
527// m_xIndexEntry->grab_focus();
528 }
529 m_xIndexEntry->select_region(0, -1);
530// enable_notify_events();
531// m_bTreeChange = true;
532// m_pEntry->fire_signal_changed();
533// m_bTreeChange = false;
534 return true;
535 }
536 return false;
537}
538
539IndexTabPage_Impl::~IndexTabPage_Impl()
540{
541 ClearIndex();
542}
543
544namespace sfx2 {
545
546 typedef std::unordered_map< OUString, int > KeywordInfo;
547}
548
549void IndexTabPage_Impl::InitializeIndex()
550{
551 weld::WaitObject aWaitCursor(m_pIdxWin->GetFrameWeld());
552
553 // By now more than 256 equal entries are not allowed
554 sal_Unicode append[256];
555 for(sal_Unicode & k : append)
556 k = ' ';
557
558 sfx2::KeywordInfo aInfo;
559 m_xIndexList->freeze();
560
561 try
562 {
563 OUStringBuffer aURL = HELP_URL"vnd.sun.star.help://";
564 aURL.append(sFactory);
565 AppendConfigToken(aURL, true);
566
567 Content aCnt( aURL.makeStringAndClear(), Reference< css::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
568 css::uno::Reference< css::beans::XPropertySetInfo > xInfo = aCnt.getProperties();
569 if ( xInfo->hasPropertyByName( PROPERTY_ANCHORREF"KeywordAnchorForRef" ) )
570 {
571 css::uno::Sequence< OUString > aPropSeq( 4 );
572 aPropSeq[0] = PROPERTY_KEYWORDLIST"KeywordList";
573 aPropSeq[1] = PROPERTY_KEYWORDREF"KeywordRef";
574 aPropSeq[2] = PROPERTY_ANCHORREF"KeywordAnchorForRef";
575 aPropSeq[3] = PROPERTY_TITLEREF"KeywordTitleForRef";
576
577 // abi: use one possibly remote call only
578 css::uno::Sequence< css::uno::Any > aAnySeq =
579 aCnt.getPropertyValues( aPropSeq );
580
581 css::uno::Sequence< OUString > aKeywordList;
582 css::uno::Sequence< css::uno::Sequence< OUString > > aKeywordRefList;
583 css::uno::Sequence< css::uno::Sequence< OUString > > aAnchorRefList;
584 css::uno::Sequence< css::uno::Sequence< OUString > > aTitleRefList;
585
586 if ( ( aAnySeq[0] >>= aKeywordList ) && ( aAnySeq[1] >>= aKeywordRefList ) &&
587 ( aAnySeq[2] >>= aAnchorRefList ) && ( aAnySeq[3] >>= aTitleRefList ) )
588 {
589 int ndx,tmp;
590 OUString aIndex, aTempString;
591 OUStringBuffer aData( 128 ); // Capacity of up to 128 characters
592 sfx2::KeywordInfo::iterator it;
593
594 for ( int i = 0; i < aKeywordList.getLength(); ++i )
595 {
596 // abi: Do not copy, but use references
597 const OUString& aKeywordPair = aKeywordList[i];
598 DBG_ASSERT( !aKeywordPair.isEmpty(), "invalid help index" )do { if (true && (!(!aKeywordPair.isEmpty()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "598" ": "), "%s", "invalid help index"); } } while (false
)
;
599 const css::uno::Sequence< OUString >& aRefList = aKeywordRefList[i];
600 const css::uno::Sequence< OUString >& aAnchorList = aAnchorRefList[i];
601 const css::uno::Sequence< OUString >& aTitleList = aTitleRefList[i];
602
603 DBG_ASSERT( aRefList.getLength() == aAnchorList.getLength(),"reference list and title list of different length" )do { if (true && (!(aRefList.getLength() == aAnchorList
.getLength()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "603" ": "), "%s", "reference list and title list of different length"
); } } while (false)
;
604
605 ndx = aKeywordPair.indexOf( ';' );
606 const bool insert = ndx != -1;
607
608 OUString sId;
609
610 if ( insert )
611 {
612 aTempString = aKeywordPair.copy( 0, ndx );
613 if ( aIndex != aTempString )
614 {
615 aIndex = aTempString;
616 it = aInfo.emplace(aTempString, 0).first;
617 sId = OUString::number(reinterpret_cast<sal_Int64>(new IndexEntry_Impl(OUString(), false)));
618 if ( (tmp = it->second++) != 0)
619 m_xIndexList->append(sId, aTempString + OUString(append, tmp));
620 else
621 m_xIndexList->append(sId, aTempString);
622 }
623 }
624 else
625 aIndex.clear();
626
627 sal_uInt32 nRefListLen = aRefList.getLength();
628
629 DBG_ASSERT( aAnchorList.hasElements(), "*IndexTabPage_Impl::InitializeIndex(): AnchorList is empty!" )do { if (true && (!(aAnchorList.hasElements()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "629" ": "), "%s", "*IndexTabPage_Impl::InitializeIndex(): AnchorList is empty!"
); } } while (false)
;
630 DBG_ASSERT( nRefListLen, "*IndexTabPage_Impl::InitializeIndex(): RefList is empty!" )do { if (true && (!(nRefListLen))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "630" ": "), "%s", "*IndexTabPage_Impl::InitializeIndex(): RefList is empty!"
); } } while (false)
;
631
632 if ( aAnchorList.hasElements() && nRefListLen )
633 {
634 if ( aAnchorList[0].getLength() > 0 )
635 {
636 aData.append( aRefList[0] ).append( '#' ).append( aAnchorList[0] );
637 sId = OUString::number(reinterpret_cast<sal_Int64>(new IndexEntry_Impl(aData.makeStringAndClear(), insert)));
638 }
639 else
640 sId = OUString::number(reinterpret_cast<sal_Int64>(new IndexEntry_Impl(aRefList[0], insert)));
641 }
642
643 // Assume the token is trimmed
644 it = aInfo.emplace(aKeywordPair, 0).first;
645 if ((tmp = it->second++) != 0)
646 m_xIndexList->append(sId, aKeywordPair + OUString(append, tmp));
647 else
648 m_xIndexList->append(sId, aKeywordPair);
649
650 for ( sal_uInt32 j = 1; j < nRefListLen ; ++j )
651 {
652 aData
653 .append( aKeywordPair )
654 .append( ' ' )
655 .append( '-' )
656 .append( ' ' )
657 .append( aTitleList[j] );
658
659 aTempString = aData.makeStringAndClear();
660
661 if ( aAnchorList[j].getLength() > 0 )
662 {
663 aData.append( aRefList[j] ).append( '#' ).append( aAnchorList[j] );
664 sId = OUString::number(reinterpret_cast<sal_Int64>(new IndexEntry_Impl(aData.makeStringAndClear(), insert)));
665 }
666 else
667 sId = OUString::number(reinterpret_cast<sal_Int64>(new IndexEntry_Impl(aRefList[j], insert)));
668
669 it = aInfo.emplace(aTempString, 0).first;
670 if ( (tmp = it->second++) != 0 )
671 m_xIndexList->append(sId, aTempString + OUString(append, tmp));
672 else
673 m_xIndexList->append(sId, aTempString);
674 }
675 }
676 }
677 }
678 }
679 catch( Exception& )
680 {
681 OSL_FAIL( "IndexTabPage_Impl::InitializeIndex(): unexpected exception" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "681" ": "), "%s", "IndexTabPage_Impl::InitializeIndex(): unexpected exception"
); } } while (false)
;
682 }
683
684 m_xIndexList->thaw();
685
686 if ( !sKeyword.isEmpty() )
687 aKeywordLink.Call( *this );
688}
689
690void IndexTabPage_Impl::ClearIndex()
691{
692 const sal_Int32 nCount = m_xIndexList->n_children();
693 for ( sal_Int32 i = 0; i < nCount; ++i )
694 delete reinterpret_cast<IndexEntry_Impl*>(m_xIndexList->get_id(i).toInt64());
695 m_xIndexList->clear();
696}
697
698IMPL_LINK_NOARG(IndexTabPage_Impl, OpenHdl, weld::Button&, void)void IndexTabPage_Impl::LinkStubOpenHdl(void * instance, weld
::Button& data) { return static_cast<IndexTabPage_Impl
*>(instance)->OpenHdl(data); } void IndexTabPage_Impl::
OpenHdl(__attribute__ ((unused)) weld::Button&)
699{
700 aDoubleClickHdl.Call(nullptr);
701}
702
703IMPL_LINK_NOARG(IndexTabPage_Impl, ActivateHdl, weld::Entry&, bool)bool IndexTabPage_Impl::LinkStubActivateHdl(void * instance, weld
::Entry& data) { return static_cast<IndexTabPage_Impl *
>(instance)->ActivateHdl(data); } bool IndexTabPage_Impl
::ActivateHdl(__attribute__ ((unused)) weld::Entry&)
704{
705 aDoubleClickHdl.Call(nullptr);
706 return true;
707}
708
709IMPL_LINK_NOARG(IndexTabPage_Impl, DoubleClickHdl, weld::TreeView&, bool)bool IndexTabPage_Impl::LinkStubDoubleClickHdl(void * instance
, weld::TreeView& data) { return static_cast<IndexTabPage_Impl
*>(instance)->DoubleClickHdl(data); } bool IndexTabPage_Impl
::DoubleClickHdl(__attribute__ ((unused)) weld::TreeView&
)
710{
711 aDoubleClickHdl.Call(nullptr);
712 return true;
713}
714
715IMPL_LINK_NOARG(IndexTabPage_Impl, IdleHdl, Timer*, void)void IndexTabPage_Impl::LinkStubIdleHdl(void * instance, Timer
* data) { return static_cast<IndexTabPage_Impl *>(instance
)->IdleHdl(data); } void IndexTabPage_Impl::IdleHdl(__attribute__
((unused)) Timer*)
716{
717 InitializeIndex();
718}
719
720int IndexTabPage_Impl::starts_with(const OUString& rStr, int nStartRow, bool bCaseSensitive)
721{
722 const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
723
724 int nRet = nStartRow;
725 int nCount = m_xIndexList->n_children();
726 while (nRet < nCount)
727 {
728 OUString aStr(m_xIndexList->get_text(nRet));
729 const bool bMatch = !bCaseSensitive ? rI18nHelper.MatchString(rStr, aStr) : aStr.startsWith(rStr);
730 if (bMatch)
731 return nRet;
732 ++nRet;
733 }
734
735 return -1;
736}
737
738IMPL_LINK_NOARG(IndexTabPage_Impl, AutoCompleteHdl, Timer*, void)void IndexTabPage_Impl::LinkStubAutoCompleteHdl(void * instance
, Timer* data) { return static_cast<IndexTabPage_Impl *>
(instance)->AutoCompleteHdl(data); } void IndexTabPage_Impl
::AutoCompleteHdl(__attribute__ ((unused)) Timer*)
739{
740 OUString aStartText = m_xIndexEntry->get_text();
741 int nStartPos, nEndPos;
742 m_xIndexEntry->get_selection_bounds(nStartPos, nEndPos);
743 int nMaxSelection = std::max(nStartPos, nEndPos);
744 if (nMaxSelection != aStartText.getLength())
745 return;
746
747 int nActive = m_xIndexList->get_selected_index();
748 int nStart = nActive;
749
750 if (nStart == -1)
751 nStart = 0;
752
753 // Try match case insensitive from current position
754 int nPos = starts_with(aStartText, nStart, false);
755 if (nPos == -1 && nStart != 0)
756 {
757 // Try match case insensitive, but from start
758 nPos = starts_with(aStartText, 0, false);
759 }
760
761 if (nPos == -1)
762 {
763 // Try match case sensitive from current position
764 nPos = starts_with(aStartText, nStart, true);
765 if (nPos == -1 && nStart != 0)
766 {
767 // Try match case sensitive, but from start
768 nPos = starts_with(aStartText, 0, true);
769 }
770 }
771
772 if (nPos != -1)
773 {
774 m_xIndexList->set_cursor(nPos);
775 m_xIndexList->select(nPos);
776 OUString aText = m_xIndexList->get_text(nPos);
777 if (aText != aStartText)
778 m_xIndexEntry->set_text(aText);
779 m_xIndexEntry->select_region(aText.getLength(), aStartText.getLength());
780 }
781}
782
783IMPL_LINK( IndexTabPage_Impl, TimeoutHdl, Timer*, pTimer, void)void IndexTabPage_Impl::LinkStubTimeoutHdl(void * instance, Timer
* data) { return static_cast<IndexTabPage_Impl *>(instance
)->TimeoutHdl(data); } void IndexTabPage_Impl::TimeoutHdl(
Timer* pTimer)
784{
785 if(&aKeywordTimer == pTimer && !sKeyword.isEmpty())
786 aKeywordLink.Call(*this);
787}
788
789void IndexTabPage_Impl::Activate()
790{
791 if ( !bIsActivated )
792 {
793 bIsActivated = true;
794 aFactoryIdle.Start();
795 }
796}
797
798void IndexTabPage_Impl::SetDoubleClickHdl(const Link<LinkParamNone*, void>& rLink)
799{
800 aDoubleClickHdl = rLink;
801}
802
803void IndexTabPage_Impl::SetFactory( const OUString& rFactory )
804{
805 OUString sNewFactory( rFactory );
806 DBG_ASSERT( !sNewFactory.isEmpty(), "empty factory" )do { if (true && (!(!sNewFactory.isEmpty()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "806" ": "), "%s", "empty factory"); } } while (false)
;
807 bool bValid = m_pIdxWin->IsValidFactory( rFactory );
808
809 if ( sFactory.isEmpty() && !bValid )
810 {
811 sNewFactory = SfxHelp::GetDefaultHelpModule();
812 bValid = true;
813 }
814
815 if ( sNewFactory != sFactory && bValid )
816 {
817 sFactory = sNewFactory;
818 ClearIndex();
819 if ( bIsActivated )
820 aFactoryIdle.Start();
821 }
822}
823
824OUString IndexTabPage_Impl::GetSelectedEntry() const
825{
826 OUString aRet;
827 IndexEntry_Impl* pEntry = reinterpret_cast<IndexEntry_Impl*>(m_xIndexList->get_id(m_xIndexList->find_text(m_xIndexEntry->get_text())).toInt64());
828 if (pEntry)
829 aRet = pEntry->m_aURL;
830 return aRet;
831}
832
833void IndexTabPage_Impl::SetKeyword( const OUString& rKeyword )
834{
835 sKeyword = rKeyword;
836
837 if (m_xIndexList->n_children() > 0)
838 aKeywordTimer.Start();
839 else if ( !bIsActivated )
840 aFactoryIdle.Start();
841}
842
843
844bool IndexTabPage_Impl::HasKeyword() const
845{
846 bool bRet = false;
847 if ( !sKeyword.isEmpty() )
848 {
849 sal_Int32 nPos = m_xIndexList->find_text( sKeyword );
850 bRet = nPos != -1;
851 }
852
853 return bRet;
854}
855
856
857bool IndexTabPage_Impl::HasKeywordIgnoreCase()
858{
859 bool bRet = false;
860 if ( !sKeyword.isEmpty() )
861 {
862 sal_Int32 nEntries = m_xIndexList->n_children();
863 const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetLocaleI18nHelper();
864 for ( sal_Int32 n = 0; n < nEntries; n++)
865 {
866 const OUString sIndexItem {m_xIndexList->get_text(n)};
867 if (rI18nHelper.MatchString( sIndexItem, sKeyword ))
868 {
869 sKeyword = sIndexItem;
870 bRet = true;
871 }
872 }
873 }
874
875 return bRet;
876}
877
878void IndexTabPage_Impl::OpenKeyword()
879{
880 if ( !sKeyword.isEmpty() )
881 {
882 m_xIndexEntry->set_text(sKeyword);
883 aDoubleClickHdl.Call(nullptr);
884 sKeyword.clear();
885 }
886}
887
888IMPL_LINK_NOARG(SearchTabPage_Impl, ActivateHdl, weld::ComboBox&, bool)bool SearchTabPage_Impl::LinkStubActivateHdl(void * instance,
weld::ComboBox& data) { return static_cast<SearchTabPage_Impl
*>(instance)->ActivateHdl(data); } bool SearchTabPage_Impl
::ActivateHdl(__attribute__ ((unused)) weld::ComboBox&)
889{
890 Search();
891 return true;
892}
893
894// class SearchTabPage_Impl ----------------------------------------------
895
896SearchTabPage_Impl::SearchTabPage_Impl(weld::Widget* pParent, SfxHelpIndexWindow_Impl* pIdxWin)
897 : HelpTabPage_Impl(pParent, pIdxWin, "HelpSearchPage",
898 "sfx/ui/helpsearchpage.ui")
899 , m_xSearchED(m_xBuilder->weld_combo_box("search"))
900 , m_xSearchBtn(m_xBuilder->weld_button("find"))
901 , m_xFullWordsCB(m_xBuilder->weld_check_button("completewords"))
902 , m_xScopeCB(m_xBuilder->weld_check_button("headings"))
903 , m_xResultsLB(m_xBuilder->weld_tree_view("results"))
904 , m_xOpenBtn(m_xBuilder->weld_button("display"))
905 , xBreakIterator(vcl::unohelper::CreateBreakIterator())
906{
907 m_xResultsLB->set_size_request(m_xResultsLB->get_approximate_digit_width() * 30,
908 m_xResultsLB->get_height_rows(15));
909
910 m_xSearchBtn->connect_clicked(LINK(this, SearchTabPage_Impl, ClickHdl)::tools::detail::makeLink( ::tools::detail::castTo<SearchTabPage_Impl
*>(this), &SearchTabPage_Impl::LinkStubClickHdl)
);
911 m_xSearchED->connect_changed(LINK(this, SearchTabPage_Impl, ModifyHdl)::tools::detail::makeLink( ::tools::detail::castTo<SearchTabPage_Impl
*>(this), &SearchTabPage_Impl::LinkStubModifyHdl)
);
912 m_xSearchED->connect_entry_activate(LINK(this, SearchTabPage_Impl, ActivateHdl)::tools::detail::makeLink( ::tools::detail::castTo<SearchTabPage_Impl
*>(this), &SearchTabPage_Impl::LinkStubActivateHdl)
);
913 m_xOpenBtn->connect_clicked(LINK(this, SearchTabPage_Impl, OpenHdl)::tools::detail::makeLink( ::tools::detail::castTo<SearchTabPage_Impl
*>(this), &SearchTabPage_Impl::LinkStubOpenHdl)
);
914 m_xResultsLB->connect_row_activated(LINK(this, SearchTabPage_Impl, DoubleClickHdl)::tools::detail::makeLink( ::tools::detail::castTo<SearchTabPage_Impl
*>(this), &SearchTabPage_Impl::LinkStubDoubleClickHdl
)
);
915
916 SvtViewOptions aViewOpt( EViewType::TabPage, CONFIGNAME_SEARCHPAGE"OfficeHelpSearch" );
917 if ( aViewOpt.Exists() )
918 {
919 OUString aUserData;
920 Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME"UserItem" );
921 if ( aUserItem >>= aUserData )
922 {
923 sal_Int32 nIdx {0};
924 bool bChecked = aUserData.getToken(0, ';', nIdx).toInt32() == 1;
925 m_xFullWordsCB->set_active(bChecked);
926 bChecked = aUserData.getToken(0, ';', nIdx).toInt32() == 1;
927 m_xScopeCB->set_active(bChecked);
928
929 while ( nIdx > 0 )
930 {
931 m_xSearchED->append_text( INetURLObject::decode(
932 aUserData.getToken(0, ';', nIdx),
933 INetURLObject::DecodeMechanism::WithCharset ) );
934 }
935 }
936 }
937
938 ModifyHdl(*m_xSearchED);
939}
940
941SearchTabPage_Impl::~SearchTabPage_Impl()
942{
943 SvtViewOptions aViewOpt( EViewType::TabPage, CONFIGNAME_SEARCHPAGE"OfficeHelpSearch" );
944 OUStringBuffer aUserData;
945 aUserData.append(OUString::number(m_xFullWordsCB->get_active() ? 1 : 0))
946 .append(";")
947 .append(OUString::number( m_xScopeCB->get_active() ? 1 : 0 ));
948 sal_Int32 nCount = std::min(m_xSearchED->get_count(), 10); // save only 10 entries
949
950 for ( sal_Int32 i = 0; i < nCount; ++i )
951 {
952 aUserData.append(";").append(INetURLObject::encode(
953 m_xSearchED->get_text(i),
954 INetURLObject::PART_UNO_PARAM_VALUE,
955 INetURLObject::EncodeMechanism::All ));
956 }
957
958 Any aUserItem = makeAny( aUserData.makeStringAndClear() );
959 aViewOpt.SetUserItem( USERITEM_NAME"UserItem", aUserItem );
960
961 m_xSearchED.reset();
962 m_xSearchBtn.reset();
963 m_xFullWordsCB.reset();
964 m_xScopeCB.reset();
965 m_xResultsLB.reset();
966 m_xOpenBtn.reset();
967}
968
969void SearchTabPage_Impl::ClearSearchResults()
970{
971 m_xResultsLB->clear();
972}
973
974void SearchTabPage_Impl::RememberSearchText( const OUString& rSearchText )
975{
976 for (sal_Int32 i = 0, nEntryCount = m_xSearchED->get_count(); i < nEntryCount; ++i)
977 {
978 if (rSearchText == m_xSearchED->get_text(i))
979 {
980 m_xSearchED->remove(i);
981 break;
982 }
983 }
984
985 m_xSearchED->insert_text(0, rSearchText);
986}
987
988IMPL_LINK_NOARG(SearchTabPage_Impl, ClickHdl, weld::Button&, void)void SearchTabPage_Impl::LinkStubClickHdl(void * instance, weld
::Button& data) { return static_cast<SearchTabPage_Impl
*>(instance)->ClickHdl(data); } void SearchTabPage_Impl
::ClickHdl(__attribute__ ((unused)) weld::Button&)
989{
990 Search();
991}
992
993void SearchTabPage_Impl::Search()
994{
995 OUString aSearchText = comphelper::string::strip(m_xSearchED->get_active_text(), ' ');
996 if ( aSearchText.isEmpty() )
997 return;
998
999 std::unique_ptr<weld::WaitObject> xWaitCursor(new weld::WaitObject(m_pIdxWin->GetFrameWeld()));
1000 ClearSearchResults();
1001 RememberSearchText( aSearchText );
1002 OUStringBuffer aSearchURL(HELP_URL"vnd.sun.star.help://");
1003 aSearchURL.append(aFactory);
1004 aSearchURL.append(HELP_SEARCH_TAG"/?Query=");
1005 if (!m_xFullWordsCB->get_active())
1006 aSearchText = sfx2::PrepareSearchString( aSearchText, xBreakIterator, true );
1007 aSearchURL.append(aSearchText);
1008 AppendConfigToken(aSearchURL, false);
1009 if (m_xScopeCB->get_active())
1010 aSearchURL.append("&Scope=Heading");
1011 std::vector< OUString > aFactories = SfxContentHelper::GetResultSet(aSearchURL.makeStringAndClear());
1012 for (const OUString & rRow : aFactories)
1013 {
1014 sal_Int32 nIdx = 0;
1015 OUString aTitle = rRow.getToken(0, '\t', nIdx);
1016 OUString sURL(rRow.getToken(1, '\t', nIdx));
1017 m_xResultsLB->append(sURL, aTitle);
1018 }
1019 xWaitCursor.reset();
1020
1021 if ( aFactories.empty() )
1022 {
1023 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xContainer.get(),
1024 VclMessageType::Info, VclButtonsType::Ok,
1025 SfxResId(STR_INFO_NOSEARCHRESULTSreinterpret_cast<char const *>("STR_INFO_NOSEARCHRESULTS"
"\004" u8"No topics found.")
)));
1026 xBox->run();
1027 }
1028}
1029
1030IMPL_LINK_NOARG(SearchTabPage_Impl, OpenHdl, weld::Button&, void)void SearchTabPage_Impl::LinkStubOpenHdl(void * instance, weld
::Button& data) { return static_cast<SearchTabPage_Impl
*>(instance)->OpenHdl(data); } void SearchTabPage_Impl
::OpenHdl(__attribute__ ((unused)) weld::Button&)
1031{
1032 aDoubleClickHdl.Call(nullptr);
1033}
1034
1035IMPL_LINK(SearchTabPage_Impl, ModifyHdl, weld::ComboBox&, rComboBox, void)void SearchTabPage_Impl::LinkStubModifyHdl(void * instance, weld
::ComboBox& data) { return static_cast<SearchTabPage_Impl
*>(instance)->ModifyHdl(data); } void SearchTabPage_Impl
::ModifyHdl(weld::ComboBox& rComboBox)
1036{
1037 OUString aSearchText = comphelper::string::strip(m_xSearchED->get_active_text(), ' ');
1038 m_xSearchBtn->set_sensitive(!aSearchText.isEmpty());
1039
1040 if (rComboBox.changed_by_direct_pick())
1041 Search();
1042}
1043
1044IMPL_LINK_NOARG(SearchTabPage_Impl, DoubleClickHdl, weld::TreeView&, bool)bool SearchTabPage_Impl::LinkStubDoubleClickHdl(void * instance
, weld::TreeView& data) { return static_cast<SearchTabPage_Impl
*>(instance)->DoubleClickHdl(data); } bool SearchTabPage_Impl
::DoubleClickHdl(__attribute__ ((unused)) weld::TreeView&
)
1045{
1046 aDoubleClickHdl.Call(nullptr);
1047 return true;
1048}
1049
1050void SearchTabPage_Impl::SetDoubleClickHdl(const Link<LinkParamNone*, void>& rLink)
1051{
1052 aDoubleClickHdl = rLink;
1053}
1054
1055OUString SearchTabPage_Impl::GetSelectedEntry() const
1056{
1057 return m_xResultsLB->get_selected_id();
1058}
1059
1060void SearchTabPage_Impl::ClearPage()
1061{
1062 ClearSearchResults();
1063 m_xSearchED->set_entry_text(OUString());
1064}
1065
1066bool SearchTabPage_Impl::OpenKeyword( const OUString& rKeyword )
1067{
1068 bool bRet = false;
1069 m_xSearchED->set_entry_text(rKeyword);
1070 Search();
1071 if (m_xResultsLB->n_children() > 0)
1072 {
1073 // found keyword -> open it
1074 m_xResultsLB->select(0);
1075 OpenHdl(*m_xOpenBtn);
1076 bRet = true;
1077 }
1078 return bRet;
1079}
1080
1081// class BookmarksTabPage_Impl -------------------------------------------
1082static void GetBookmarkEntry_Impl
1083(
1084 const Sequence< PropertyValue >& aBookmarkEntry,
1085 OUString& rTitle,
1086 OUString& rURL
1087)
1088{
1089 for ( const PropertyValue& aValue : aBookmarkEntry )
1090 {
1091 if ( aValue.Name == HISTORY_PROPERTYNAME_URL"URL" )
1092 aValue.Value >>= rURL;
1093 else if ( aValue.Name == HISTORY_PROPERTYNAME_TITLE"Title" )
1094 aValue.Value >>= rTitle;
1095 }
1096}
1097
1098void BookmarksTabPage_Impl::DoAction(const OString& rAction)
1099{
1100 if (rAction == "display")
1101 aDoubleClickHdl.Call(nullptr);
1102 else if (rAction == "rename")
1103 {
1104 sal_Int32 nPos = m_xBookmarksBox->get_selected_index();
1105 if (nPos != -1)
1106 {
1107 SfxAddHelpBookmarkDialog_Impl aDlg(m_xBookmarksBox.get(), true);
1108 aDlg.SetTitle(m_xBookmarksBox->get_text(nPos));
1109 if (aDlg.run() == RET_OK)
1110 {
1111 OUString sURL = m_xBookmarksBox->get_id(nPos);
1112 m_xBookmarksBox->remove(nPos);
1113 m_xBookmarksBox->append(sURL, aDlg.GetTitle(), SvFileInformationManager::GetImageId(INetURLObject(IMAGE_URL"private:factory/"+INetURLObject(sURL).GetHost())));
1114 m_xBookmarksBox->select(m_xBookmarksBox->n_children() - 1);
1115 }
1116 }
1117 }
1118 else if (rAction == "delete")
1119 {
1120 sal_Int32 nPos = m_xBookmarksBox->get_selected_index();
1121 if (nPos != -1)
1122 {
1123 m_xBookmarksBox->remove(nPos);
1124 const sal_Int32 nCount = m_xBookmarksBox->n_children();
1125 if (nCount)
1126 {
1127 if (nPos >= nCount)
1128 nPos = nCount - 1;
1129 m_xBookmarksBox->select(nPos);
1130 }
1131 }
1132 }
1133}
1134
1135IMPL_LINK(BookmarksTabPage_Impl, CommandHdl, const CommandEvent&, rCEvt, bool)bool BookmarksTabPage_Impl::LinkStubCommandHdl(void * instance
, const CommandEvent& data) { return static_cast<BookmarksTabPage_Impl
*>(instance)->CommandHdl(data); } bool BookmarksTabPage_Impl
::CommandHdl(const CommandEvent& rCEvt)
1136{
1137 if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
1138 return false;
1139
1140 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xBookmarksBox.get(), "sfx/ui/bookmarkmenu.ui"));
1141 std::unique_ptr<weld::Menu> xMenu = xBuilder->weld_menu("menu");
1142
1143 OString sIdent = xMenu->popup_at_rect(m_xBookmarksBox.get(), ::tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1)));
1144 if (!sIdent.isEmpty())
1145 DoAction(sIdent);
1146 return true;
1147}
1148
1149IMPL_LINK(BookmarksTabPage_Impl, KeyInputHdl, const KeyEvent&, rKEvt, bool)bool BookmarksTabPage_Impl::LinkStubKeyInputHdl(void * instance
, const KeyEvent& data) { return static_cast<BookmarksTabPage_Impl
*>(instance)->KeyInputHdl(data); } bool BookmarksTabPage_Impl
::KeyInputHdl(const KeyEvent& rKEvt)
1150{
1151 bool bHandled = false;
1152 sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
1153 if (KEY_DELETE == nCode && m_xBookmarksBox->n_children() > 0)
1154 {
1155 DoAction("delete");
1156 bHandled = true;
1157 }
1158 return bHandled;
1159}
1160
1161// class BookmarksTabPage_Impl -------------------------------------------
1162BookmarksTabPage_Impl::BookmarksTabPage_Impl(weld::Widget* pParent, SfxHelpIndexWindow_Impl* _pIdxWin)
1163 : HelpTabPage_Impl(pParent, _pIdxWin, "HelpBookmarkPage",
1164 "sfx/ui/helpbookmarkpage.ui")
1165 , m_xBookmarksBox(m_xBuilder->weld_tree_view("bookmarks"))
1166 , m_xBookmarksPB(m_xBuilder->weld_button("display"))
1167{
1168 m_xBookmarksBox->set_size_request(m_xBookmarksBox->get_approximate_digit_width() * 30,
1169 m_xBookmarksBox->get_height_rows(20));
1170
1171 m_xBookmarksPB->connect_clicked( LINK(this, BookmarksTabPage_Impl, OpenHdl)::tools::detail::makeLink( ::tools::detail::castTo<BookmarksTabPage_Impl
*>(this), &BookmarksTabPage_Impl::LinkStubOpenHdl)
);
1172 m_xBookmarksBox->connect_row_activated(LINK(this, BookmarksTabPage_Impl, DoubleClickHdl)::tools::detail::makeLink( ::tools::detail::castTo<BookmarksTabPage_Impl
*>(this), &BookmarksTabPage_Impl::LinkStubDoubleClickHdl
)
);
1173 m_xBookmarksBox->connect_popup_menu(LINK(this, BookmarksTabPage_Impl, CommandHdl)::tools::detail::makeLink( ::tools::detail::castTo<BookmarksTabPage_Impl
*>(this), &BookmarksTabPage_Impl::LinkStubCommandHdl)
);
1174 m_xBookmarksBox->connect_key_press(LINK(this, BookmarksTabPage_Impl, KeyInputHdl)::tools::detail::makeLink( ::tools::detail::castTo<BookmarksTabPage_Impl
*>(this), &BookmarksTabPage_Impl::LinkStubKeyInputHdl
)
);
1175
1176 // load bookmarks from configuration
1177 const Sequence< Sequence< PropertyValue > > aBookmarkSeq = SvtHistoryOptions().GetList( eHELPBOOKMARKS );
1178
1179 OUString aTitle;
1180 OUString aURL;
1181
1182 for ( const auto& rBookmark : aBookmarkSeq )
1183 {
1184 GetBookmarkEntry_Impl( rBookmark, aTitle, aURL );
1185 AddBookmarks( aTitle, aURL );
1186 }
1187}
1188
1189BookmarksTabPage_Impl::~BookmarksTabPage_Impl()
1190{
1191 // save bookmarks to configuration
1192 SvtHistoryOptions aHistOpt;
1193 aHistOpt.Clear( eHELPBOOKMARKS );
1194 const sal_Int32 nCount = m_xBookmarksBox->n_children();
1195 for (sal_Int32 i = 0; i < nCount; ++i)
1196 aHistOpt.AppendItem(eHELPBOOKMARKS, m_xBookmarksBox->get_id(i), "", m_xBookmarksBox->get_text(i), std::nullopt);
1197
1198 m_xBookmarksBox.reset();
1199 m_xBookmarksPB.reset();
1200}
1201
1202IMPL_LINK_NOARG(BookmarksTabPage_Impl, OpenHdl, weld::Button&, void)void BookmarksTabPage_Impl::LinkStubOpenHdl(void * instance, weld
::Button& data) { return static_cast<BookmarksTabPage_Impl
*>(instance)->OpenHdl(data); } void BookmarksTabPage_Impl
::OpenHdl(__attribute__ ((unused)) weld::Button&)
1203{
1204 aDoubleClickHdl.Call(nullptr);
1205}
1206
1207IMPL_LINK_NOARG(BookmarksTabPage_Impl, DoubleClickHdl, weld::TreeView&, bool)bool BookmarksTabPage_Impl::LinkStubDoubleClickHdl(void * instance
, weld::TreeView& data) { return static_cast<BookmarksTabPage_Impl
*>(instance)->DoubleClickHdl(data); } bool BookmarksTabPage_Impl
::DoubleClickHdl(__attribute__ ((unused)) weld::TreeView&
)
1208{
1209 aDoubleClickHdl.Call(nullptr);
1210 return true;
1211}
1212
1213void BookmarksTabPage_Impl::SetDoubleClickHdl(const Link<LinkParamNone*, void>& rLink)
1214{
1215 aDoubleClickHdl = rLink;
1216}
1217
1218OUString BookmarksTabPage_Impl::GetSelectedEntry() const
1219{
1220 return m_xBookmarksBox->get_selected_id();
1221}
1222
1223void BookmarksTabPage_Impl::AddBookmarks(const OUString& rTitle, const OUString& rURL)
1224{
1225 const OUString aImageURL {IMAGE_URL"private:factory/" + INetURLObject(rURL).GetHost()};
1226 m_xBookmarksBox->append(rURL, rTitle, SvFileInformationManager::GetImageId(INetURLObject(aImageURL)));
1227}
1228
1229OUString SfxHelpWindow_Impl::buildHelpURL(const OUString& sFactory ,
1230 const OUString& sContent ,
1231 const OUString& sAnchor)
1232{
1233 OUStringBuffer sHelpURL(256);
1234 sHelpURL.append(HELP_URL"vnd.sun.star.help://");
1235 sHelpURL.append(sFactory);
1236 sHelpURL.append(sContent);
1237 AppendConfigToken(sHelpURL, true/*bUseQuestionMark*/);
1238 if (!sAnchor.isEmpty())
1239 sHelpURL.append(sAnchor);
1240 return sHelpURL.makeStringAndClear();
1241}
1242
1243void SfxHelpWindow_Impl::loadHelpContent(const OUString& sHelpURL, bool bAddToHistory)
1244{
1245 Reference< XComponentLoader > xLoader(getTextFrame(), UNO_QUERY);
1246 if (!xLoader.is())
1247 return;
1248
1249 // If a print job runs do not open a new page
1250 Reference< XFrame2 > xTextFrame = pTextWin->getFrame();
1251 Reference< XController > xTextController ;
1252 if (xTextFrame.is())
1253 xTextController = xTextFrame->getController ();
1254 if ( xTextController.is() && !xTextController->suspend( true ) )
1255 {
1256 xTextController->suspend( false );
1257 return;
1258 }
1259
1260 // save url to history
1261 if (bAddToHistory)
1262 pHelpInterceptor->addURL(sHelpURL);
1263
1264 if ( !IsWait() )
1265 EnterWait();
1266 bool bSuccess = false;
1267// TODO implement locale fallback ... see below while(true)
1268 {
1269 try
1270 {
1271 Reference< XComponent > xContent = xLoader->loadComponentFromURL(sHelpURL, "_self", 0, Sequence< PropertyValue >());
1272 if (xContent.is())
1273 {
1274 bSuccess = true;
1275 }
1276 }
1277 catch(const RuntimeException&)
1278 { throw; }
1279 catch(const Exception&)
1280 { /*break;*/ }
1281
1282 /* TODO try next locale ...
1283 no further locale available? => break loop and show error page
1284 */
1285 }
1286 openDone(sHelpURL, bSuccess);
1287 if ( IsWait() )
1288 LeaveWait();
1289}
1290
1291IMPL_LINK(SfxHelpIndexWindow_Impl, ActivatePageHdl, const OString&, rPage, void)void SfxHelpIndexWindow_Impl::LinkStubActivatePageHdl(void * instance
, const OString& data) { return static_cast<SfxHelpIndexWindow_Impl
*>(instance)->ActivatePageHdl(data); } void SfxHelpIndexWindow_Impl
::ActivatePageHdl(const OString& rPage)
1292{
1293 GetPage(rPage)->Activate();
1294}
1295
1296SfxHelpIndexWindow_Impl::SfxHelpIndexWindow_Impl(SfxHelpWindow_Impl* _pParent, weld::Container* pContainer)
1297 : m_xBuilder(Application::CreateBuilder(pContainer, "sfx/ui/helpcontrol.ui"))
1298 , m_xContainer(m_xBuilder->weld_container("HelpControl"))
1299 , m_xActiveLB(m_xBuilder->weld_combo_box("active"))
1300 , m_xTabCtrl(m_xBuilder->weld_notebook("tabcontrol"))
1301 , aIdle("sfx2 appl SfxHelpIndexWindow_Impl")
1302 , aIndexKeywordLink(LINK(this, SfxHelpIndexWindow_Impl, KeywordHdl)::tools::detail::makeLink( ::tools::detail::castTo<SfxHelpIndexWindow_Impl
*>(this), &SfxHelpIndexWindow_Impl::LinkStubKeywordHdl
)
)
1303 , pParentWin(_pParent)
1304 , bIsInitDone(false)
1305{
1306 // create the pages
1307 GetContentPage();
1308 GetIndexPage();
1309 GetSearchPage();
1310 GetBookmarksPage();
1311
1312 OString sPageId("index");
1313 SvtViewOptions aViewOpt( EViewType::TabDialog, CONFIGNAME_INDEXWIN"OfficeHelpIndex" );
1314 if ( aViewOpt.Exists() )
1315 sPageId = aViewOpt.GetPageID();
1316 m_xTabCtrl->set_current_page(sPageId);
1317 ActivatePageHdl(sPageId);
1318 m_xActiveLB->connect_changed(LINK(this, SfxHelpIndexWindow_Impl, SelectHdl)::tools::detail::makeLink( ::tools::detail::castTo<SfxHelpIndexWindow_Impl
*>(this), &SfxHelpIndexWindow_Impl::LinkStubSelectHdl
)
);
1319
1320 m_xTabCtrl->connect_enter_page(LINK(this, SfxHelpIndexWindow_Impl, ActivatePageHdl)::tools::detail::makeLink( ::tools::detail::castTo<SfxHelpIndexWindow_Impl
*>(this), &SfxHelpIndexWindow_Impl::LinkStubActivatePageHdl
)
);
1321
1322 aIdle.SetInvokeHandler( LINK( this, SfxHelpIndexWindow_Impl, InitHdl )::tools::detail::makeLink( ::tools::detail::castTo<SfxHelpIndexWindow_Impl
*>(this), &SfxHelpIndexWindow_Impl::LinkStubInitHdl)
);
1323 aIdle.Start();
1324
1325 m_xContainer->show();
1326}
1327
1328SfxHelpIndexWindow_Impl::~SfxHelpIndexWindow_Impl()
1329{
1330 SvtViewOptions aViewOpt(EViewType::TabDialog, CONFIGNAME_INDEXWIN"OfficeHelpIndex");
1331 aViewOpt.SetPageID(m_xTabCtrl->get_current_page_ident());
1332
1333 xCPage.reset();
1334 xIPage.reset();
1335 xSPage.reset();
1336 xBPage.reset();
1337}
1338
1339void SfxHelpIndexWindow_Impl::Initialize()
1340{
1341 OUStringBuffer aHelpURL(HELP_URL"vnd.sun.star.help://");
1342 AppendConfigToken(aHelpURL, true);
1343 std::vector<OUString> aFactories = SfxContentHelper::GetResultSet(aHelpURL.makeStringAndClear());
1344 for (const OUString & rRow : aFactories)
1345 {
1346 sal_Int32 nIdx = 0;
1347 OUString aTitle = rRow.getToken( 0, '\t', nIdx ); // token 0
1348 OUString aURL = rRow.getToken( 1, '\t', nIdx ); // token 2
1349 OUString aFactory(INetURLObject(aURL).GetHost());
1350 m_xActiveLB->append(aFactory, aTitle);
1351 }
1352
1353 if (m_xActiveLB->get_active() == -1)
1354 SetActiveFactory();
1355}
1356
1357void SfxHelpIndexWindow_Impl::SetActiveFactory()
1358{
1359 DBG_ASSERT( xIPage, "index page not initialized" )do { if (true && (!(xIPage))) { sal_detail_logFormat(
(SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "1359" ": "), "%s", "index page not initialized"); } } while
(false)
;
1360 if (!bIsInitDone && !m_xActiveLB->get_count())
1361 {
1362 aIdle.Stop();
1363 InitHdl( nullptr );
1364 }
1365
1366 for (sal_Int32 i = 0, nEntryCount = m_xActiveLB->get_count(); i < nEntryCount; ++i)
1367 {
1368 OUString aFactory = m_xActiveLB->get_id(i);
1369 aFactory = aFactory.toAsciiLowerCase();
1370 if (aFactory == xIPage->GetFactory())
1371 {
1372 if (m_xActiveLB->get_active() != i)
1373 {
1374 m_xActiveLB->set_active(i);
1375 aSelectFactoryLink.Call(nullptr);
1376 }
1377 break;
1378 }
1379 }
1380}
1381
1382HelpTabPage_Impl* SfxHelpIndexWindow_Impl::GetPage(const OString& rName)
1383{
1384 HelpTabPage_Impl* pPage = nullptr;
1385
1386 if (rName == "contents")
1387 pPage = GetContentPage();
1388 else if (rName == "index")
1389 pPage = GetIndexPage();
1390 else if (rName == "find")
1391 pPage = GetSearchPage();
1392 else if (rName == "bookmarks")
1393 pPage = GetBookmarksPage();
1394
1395 assert(pPage && "SfxHelpIndexWindow_Impl::GetCurrentPage(): no current page")(static_cast <bool> (pPage && "SfxHelpIndexWindow_Impl::GetCurrentPage(): no current page"
) ? void (0) : __assert_fail ("pPage && \"SfxHelpIndexWindow_Impl::GetCurrentPage(): no current page\""
, "/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
, 1395, __extension__ __PRETTY_FUNCTION__))
;
1396
1397 return pPage;
1398}
1399
1400IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, SelectHdl, weld::ComboBox&, void)void SfxHelpIndexWindow_Impl::LinkStubSelectHdl(void * instance
, weld::ComboBox& data) { return static_cast<SfxHelpIndexWindow_Impl
*>(instance)->SelectHdl(data); } void SfxHelpIndexWindow_Impl
::SelectHdl(__attribute__ ((unused)) weld::ComboBox&)
1401{
1402 aIdle.Start();
1403}
1404
1405IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, InitHdl, Timer *, void)void SfxHelpIndexWindow_Impl::LinkStubInitHdl(void * instance
, Timer * data) { return static_cast<SfxHelpIndexWindow_Impl
*>(instance)->InitHdl(data); } void SfxHelpIndexWindow_Impl
::InitHdl(__attribute__ ((unused)) Timer *)
1406{
1407 bIsInitDone = true;
1408 Initialize();
1409
1410 // now use the timer for selection
1411 aIdle.SetInvokeHandler( LINK( this, SfxHelpIndexWindow_Impl, SelectFactoryHdl )::tools::detail::makeLink( ::tools::detail::castTo<SfxHelpIndexWindow_Impl
*>(this), &SfxHelpIndexWindow_Impl::LinkStubSelectFactoryHdl
)
);
1412 aIdle.SetPriority( TaskPriority::LOWEST );
1413}
1414
1415IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, SelectFactoryHdl, Timer *, void)void SfxHelpIndexWindow_Impl::LinkStubSelectFactoryHdl(void *
instance, Timer * data) { return static_cast<SfxHelpIndexWindow_Impl
*>(instance)->SelectFactoryHdl(data); } void SfxHelpIndexWindow_Impl
::SelectFactoryHdl(__attribute__ ((unused)) Timer *)
1416{
1417 OUString aFactory = m_xActiveLB->get_active_id();
1418 if (!aFactory.isEmpty())
1419 {
1420 SetFactory(aFactory.toAsciiLowerCase(), false);
1421 aSelectFactoryLink.Call(this);
1422 }
1423}
1424
1425IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, KeywordHdl, IndexTabPage_Impl&, void)void SfxHelpIndexWindow_Impl::LinkStubKeywordHdl(void * instance
, IndexTabPage_Impl& data) { return static_cast<SfxHelpIndexWindow_Impl
*>(instance)->KeywordHdl(data); } void SfxHelpIndexWindow_Impl
::KeywordHdl(__attribute__ ((unused)) IndexTabPage_Impl&)
1426{
1427 // keyword found on index?
1428 bool bIndex = xIPage->HasKeyword();
1429
1430 if( !bIndex)
1431 bIndex = xIPage->HasKeywordIgnoreCase();
1432 // then set index or search page as current.
1433 OString sPageId = bIndex ? "index" : "find";
1434 if (sPageId != m_xTabCtrl->get_current_page_ident())
1435 m_xTabCtrl->set_current_page(sPageId);
1436
1437 // at last we open the keyword
1438 if ( bIndex )
1439 xIPage->OpenKeyword();
1440 else if ( !xSPage->OpenKeyword( sKeyword ) )
1441 pParentWin->ShowStartPage();
1442}
1443
1444IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, IndexTabPageDoubleClickHdl, LinkParamNone*, void)void SfxHelpIndexWindow_Impl::LinkStubIndexTabPageDoubleClickHdl
(void * instance, LinkParamNone* data) { return static_cast<
SfxHelpIndexWindow_Impl *>(instance)->IndexTabPageDoubleClickHdl
(data); } void SfxHelpIndexWindow_Impl::IndexTabPageDoubleClickHdl
(__attribute__ ((unused)) LinkParamNone*)
1445{
1446 aPageDoubleClickLink.Call(nullptr);
1447}
1448
1449void SfxHelpIndexWindow_Impl::SetDoubleClickHdl(const Link<LinkParamNone*, void>& rLink)
1450{
1451 aPageDoubleClickLink = rLink;
1452}
1453
1454IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, ContentTabPageDoubleClickHdl, LinkParamNone*, void)void SfxHelpIndexWindow_Impl::LinkStubContentTabPageDoubleClickHdl
(void * instance, LinkParamNone* data) { return static_cast<
SfxHelpIndexWindow_Impl *>(instance)->ContentTabPageDoubleClickHdl
(data); } void SfxHelpIndexWindow_Impl::ContentTabPageDoubleClickHdl
(__attribute__ ((unused)) LinkParamNone*)
1455{
1456 aPageDoubleClickLink.Call(nullptr);
1457}
1458
1459IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, TabPageDoubleClickHdl, LinkParamNone*, void)void SfxHelpIndexWindow_Impl::LinkStubTabPageDoubleClickHdl(void
* instance, LinkParamNone* data) { return static_cast<SfxHelpIndexWindow_Impl
*>(instance)->TabPageDoubleClickHdl(data); } void SfxHelpIndexWindow_Impl
::TabPageDoubleClickHdl(__attribute__ ((unused)) LinkParamNone
*)
1460{
1461 aPageDoubleClickLink.Call(nullptr);
1462}
1463
1464void SfxHelpIndexWindow_Impl::SetFactory( const OUString& rFactory, bool bActive )
1465{
1466 if ( !rFactory.isEmpty() )
1467 {
1468 GetIndexPage()->SetFactory( rFactory );
1469 // the index page made a check if rFactory is valid,
1470 // so the index page always returns a valid factory
1471 GetSearchPage()->SetFactory( GetIndexPage()->GetFactory() );
1472 if ( bActive )
1473 SetActiveFactory();
1474 }
1475}
1476
1477OUString SfxHelpIndexWindow_Impl::GetSelectedEntry() const
1478{
1479 OUString sRet;
1480
1481 OString sName(m_xTabCtrl->get_current_page_ident());
1482
1483 if (sName == "contents")
1484 {
1485 sRet = xCPage->GetSelectedEntry();
1486 }
1487 else if (sName == "index")
1488 {
1489 sRet = xIPage->GetSelectedEntry();
1490 }
1491 else if (sName == "find")
1492 {
1493 sRet = xSPage->GetSelectedEntry();
1494 }
1495 else if (sName == "bookmarks")
1496 {
1497 sRet = xBPage->GetSelectedEntry();
1498 }
1499
1500 return sRet;
1501}
1502
1503void SfxHelpIndexWindow_Impl::AddBookmarks( const OUString& rTitle, const OUString& rURL )
1504{
1505 GetBookmarksPage()->AddBookmarks( rTitle, rURL );
1506}
1507
1508bool SfxHelpIndexWindow_Impl::IsValidFactory( const OUString& _rFactory )
1509{
1510 bool bValid = false;
1511 for (sal_Int32 i = 0, nEntryCount = m_xActiveLB->get_count(); i < nEntryCount; ++i)
1512 {
1513 OUString aFactory = m_xActiveLB->get_id(i);
1514 if (aFactory == _rFactory)
1515 {
1516 bValid = true;
1517 break;
1518 }
1519 }
1520 return bValid;
1521}
1522
1523void SfxHelpIndexWindow_Impl::ClearSearchPage()
1524{
1525 if ( xSPage )
1526 xSPage->ClearPage();
1527}
1528
1529void SfxHelpIndexWindow_Impl::GrabFocusBack()
1530{
1531 OString sName(m_xTabCtrl->get_current_page_ident());
1532
1533 if (sName == "contents" && xCPage)
1534 xCPage->SetFocusOnBox();
1535 else if (sName == "index" && xIPage)
1536 xIPage->SetFocusOnBox();
1537 else if (sName == "find" && xSPage)
1538 xSPage->SetFocusOnBox();
1539 else if (sName == "bookmarks" && xBPage)
1540 xBPage->SetFocusOnBox();
1541}
1542
1543bool SfxHelpIndexWindow_Impl::HasFocusOnEdit() const
1544{
1545 bool bRet = false;
1546 OString sName(m_xTabCtrl->get_current_page_ident());
1547 if (sName == "index" && xIPage)
1548 bRet = xIPage->HasFocusOnEdit();
1549 else if (sName == "find" && xSPage)
1550 bRet = xSPage->HasFocusOnEdit();
1551 return bRet;
1552}
1553
1554OUString SfxHelpIndexWindow_Impl::GetSearchText() const
1555{
1556 OUString sRet;
1557 OString sName(m_xTabCtrl->get_current_page_ident());
1558 if (sName == "find" && xSPage)
1559 sRet = xSPage->GetSearchText();
1560 return sRet;
1561}
1562
1563bool SfxHelpIndexWindow_Impl::IsFullWordSearch() const
1564{
1565 bool bRet = false;
1566 OString sName(m_xTabCtrl->get_current_page_ident());
1567 if (sName == "find" && xSPage)
1568 bRet = xSPage->IsFullWordSearch();
1569 return bRet;
1570}
1571
1572void SfxHelpIndexWindow_Impl::OpenKeyword( const OUString& rKeyword )
1573{
1574 sKeyword = rKeyword;
1575 DBG_ASSERT( xIPage, "invalid index page" )do { if (true && (!(xIPage))) { sal_detail_logFormat(
(SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "1575" ": "), "%s", "invalid index page"); } } while (false
)
;
1576 xIPage->SetKeyword( sKeyword );
1577}
1578
1579void SfxHelpIndexWindow_Impl::SelectExecutableEntry()
1580{
1581 OString sName(m_xTabCtrl->get_current_page_ident());
1582 if (sName == "index" && xIPage )
1583 xIPage->SelectExecutableEntry();
1584}
1585
1586weld::Window* SfxHelpIndexWindow_Impl::GetFrameWeld() const
1587{
1588 return pParentWin->GetFrameWeld();
1589}
1590
1591// class TextWin_Impl ----------------------------------------------------
1592TextWin_Impl::TextWin_Impl( vcl::Window* p ) : DockingWindow( p, 0 )
1593{
1594}
1595
1596bool TextWin_Impl::EventNotify( NotifyEvent& rNEvt )
1597{
1598 if( ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT ) && rNEvt.GetKeyEvent()->GetKeyCode().GetCode() == KEY_TAB )
1599 return GetParent()->EventNotify( rNEvt );
1600 else
1601 return DockingWindow::EventNotify( rNEvt );
1602}
1603
1604
1605// remove docking area acceptor from layoutmanager, so it will not layout anything further .-)
1606static void lcl_disableLayoutOfFrame(const Reference< XFrame2 >& xFrame)
1607{
1608 xFrame->setLayoutManager( Reference< XLayoutManager >() );
1609}
1610
1611// class SfxHelpTextWindow_Impl ------------------------------------------
1612
1613SfxHelpTextWindow_Impl::SfxHelpTextWindow_Impl(SfxHelpWindow_Impl* pHelpWin, weld::Builder& rBuilder, vcl::Window* pParent) :
1614
1615 Window( pParent, WB_CLIPCHILDREN | WB_TABSTOP | WB_DIALOGCONTROL ),
1616
1617 xToolBox ( rBuilder.weld_toolbar("toolbar") ),
1618 xOnStartupCB ( rBuilder.weld_check_button("checkbutton") ),
1619 xMenu ( rBuilder.weld_menu("menu") ),
1620 aSelectIdle ( "sfx2 appl SfxHelpTextWindow_Impl Select" ),
1621 aIndexOnImage ( BMP_HELP_TOOLBOX_INDEX_ON"sfx2/res/indexon_small.png" ),
1622 aIndexOffImage ( BMP_HELP_TOOLBOX_INDEX_OFF"sfx2/res/indexoff_small.png" ),
1623 aIndexOnText ( SfxResId( STR_HELP_BUTTON_INDEX_ONreinterpret_cast<char const *>("STR_HELP_BUTTON_INDEX_ON"
"\004" u8"Show Navigation Pane")
) ),
1624 aIndexOffText ( SfxResId( STR_HELP_BUTTON_INDEX_OFFreinterpret_cast<char const *>("STR_HELP_BUTTON_INDEX_OFF"
"\004" u8"Hide Navigation Pane")
) ),
1625 aOnStartupText ( SfxResId( RID_HELP_ONSTARTUP_TEXTreinterpret_cast<char const *>("RID_HELP_ONSTARTUP_TEXT"
"\004" u8"~Display %PRODUCTNAME %MODULENAME Help at Startup"
)
) ),
1626 xHelpWin ( pHelpWin ),
1627 pTextWin ( VclPtr<TextWin_Impl>::Create( this ) ),
1628 bIsDebug ( false ),
1629 bIsIndexOn ( false ),
1630 bIsInClose ( false ),
1631 bIsFullWordSearch ( false )
1632{
1633 xFrame = Frame::create( ::comphelper::getProcessComponentContext() );
1634 xFrame->initialize( VCLUnoHelper::GetInterface ( pTextWin ) );
1635 xFrame->setName( "OFFICE_HELP" );
1636 lcl_disableLayoutOfFrame(xFrame);
1637
1638 xToolBox->set_help_id(HID_HELP_TOOLBOX"SFX2_HID_HELP_TOOLBOX");
1639
1640 xToolBox->set_item_tooltip_text("index", aIndexOffText );
1641 xToolBox->set_item_help_id("index", HID_HELP_TOOLBOXITEM_INDEX"SFX2_HID_HELP_TOOLBOXITEM_INDEX");
1642 xToolBox->set_item_help_id("backward", HID_HELP_TOOLBOXITEM_BACKWARD"SFX2_HID_HELP_TOOLBOXITEM_BACKWARD");
1643 xToolBox->set_item_help_id("forward", HID_HELP_TOOLBOXITEM_FORWARD"SFX2_HID_HELP_TOOLBOXITEM_FORWARD");
1644 xToolBox->set_item_help_id("start", HID_HELP_TOOLBOXITEM_START"SFX2_HID_HELP_TOOLBOXITEM_START");
1645 xToolBox->set_item_help_id("print", HID_HELP_TOOLBOXITEM_PRINT"SFX2_HID_HELP_TOOLBOXITEM_PRINT");
1646 xToolBox->set_item_help_id("bookmarks", HID_HELP_TOOLBOXITEM_BOOKMARKS"SFX2_HID_HELP_TOOLBOXITEM_BOOKMARKS" );
1647 xToolBox->set_item_help_id("searchdialog", HID_HELP_TOOLBOXITEM_SEARCHDIALOG"SFX2_HID_HELP_TOOLBOXITEM_SEARCHDIALOG");
1648
1649 InitToolBoxImages();
1650 InitOnStartupBox();
1651 xOnStartupCB->connect_clicked(LINK(this, SfxHelpTextWindow_Impl, CheckHdl)::tools::detail::makeLink( ::tools::detail::castTo<SfxHelpTextWindow_Impl
*>(this), &SfxHelpTextWindow_Impl::LinkStubCheckHdl)
);
1652
1653 aSelectIdle.SetInvokeHandler( LINK( this, SfxHelpTextWindow_Impl, SelectHdl )::tools::detail::makeLink( ::tools::detail::castTo<SfxHelpTextWindow_Impl
*>(this), &SfxHelpTextWindow_Impl::LinkStubSelectHdl)
);
1654 aSelectIdle.SetPriority( TaskPriority::LOWEST );
1655
1656 char* pEnv = getenv( "help_debug" );
1657 if ( pEnv )
1658 bIsDebug = true;
1659
1660 SvtMiscOptions().AddListenerLink( LINK( this, SfxHelpTextWindow_Impl, NotifyHdl )::tools::detail::makeLink( ::tools::detail::castTo<SfxHelpTextWindow_Impl
*>(this), &SfxHelpTextWindow_Impl::LinkStubNotifyHdl)
);
1661}
1662
1663SfxHelpTextWindow_Impl::~SfxHelpTextWindow_Impl()
1664{
1665 disposeOnce();
1666}
1667
1668void SfxHelpTextWindow_Impl::dispose()
1669{
1670 bIsInClose = true;
1671 SvtMiscOptions().RemoveListenerLink( LINK( this, SfxHelpTextWindow_Impl, NotifyHdl )::tools::detail::makeLink( ::tools::detail::castTo<SfxHelpTextWindow_Impl
*>(this), &SfxHelpTextWindow_Impl::LinkStubNotifyHdl)
);
1672 m_xSrchDlg.reset();
1673 xToolBox.reset();
1674 xOnStartupCB.reset();
1675 xHelpWin.clear();
1676 pTextWin.disposeAndClear();
1677 vcl::Window::dispose();
1678}
1679
1680bool SfxHelpTextWindow_Impl::HasSelection() const
1681{
1682 // is there any selection in the text and not only a cursor?
1683 bool bRet = false;
1684 Reference < XTextRange > xRange = getCursor();
1685 if ( xRange.is() )
1686 {
1687 Reference < XText > xText = xRange->getText();
1688 Reference < XTextCursor > xCursor = xText->createTextCursorByRange( xRange );
1689 bRet = !xCursor->isCollapsed();
1690 }
1691
1692 return bRet;
1693}
1694
1695void SfxHelpTextWindow_Impl::InitToolBoxImages()
1696{
1697 xToolBox->set_item_icon_name("index", bIsIndexOn ? aIndexOffImage : aIndexOnImage);
1698}
1699
1700void SfxHelpTextWindow_Impl::InitOnStartupBox()
1701{
1702 sCurrentFactory = SfxHelp::GetCurrentModuleIdentifier();
1703
1704 Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1705 const OUString sPath { PATH_OFFICE_FACTORIES"Office/Factories/" + sCurrentFactory };
1706
1707 // Attention: This check boy knows two states:
1708 // 1) Reading of the config key fails with an exception or by getting an empty Any (!) => check box must be hidden
1709 // 2) We read sal_True/sal_False => check box must be shown and enabled/disabled
1710
1711 bool bHideBox = true;
1712 bool bHelpAtStartup = false;
1713 try
1714 {
1715 xConfiguration = ConfigurationHelper::openConfig(
1716 xContext, PACKAGE_SETUP"/org.openoffice.Setup", EConfigurationModes::Standard );
1717 if ( xConfiguration.is() )
1718 {
1719 Any aAny = ConfigurationHelper::readRelativeKey( xConfiguration, sPath, KEY_HELP_ON_OPEN"ooSetupFactoryHelpOnOpen" );
1720 if (aAny >>= bHelpAtStartup)
1721 bHideBox = false;
1722 }
1723 }
1724 catch( Exception& )
1725 {
1726 bHideBox = true;
1727 }
1728
1729 if ( bHideBox )
1730 xOnStartupCB->hide();
1731 else
1732 {
1733 // detect module name
1734 OUString sModuleName;
1735
1736 if ( xConfiguration.is() )
1737 {
1738 OUString sTemp;
1739 try
1740 {
1741 Any aAny = ConfigurationHelper::readRelativeKey( xConfiguration, sPath, KEY_UI_NAME"ooSetupFactoryUIName" );
1742 aAny >>= sTemp;
1743 }
1744 catch( Exception const & )
1745 {
1746 TOOLS_WARN_EXCEPTION( "sfx.appl", "SfxHelpTextWindow_Impl::InitOnStartupBox()" )do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.appl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "SfxHelpTextWindow_Impl::InitOnStartupBox()"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"sfx.appl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "1746" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxHelpTextWindow_Impl::InitOnStartupBox()"
<< " " << exceptionToString(tools_warn_exception
)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxHelpTextWindow_Impl::InitOnStartupBox()" <<
" " << exceptionToString(tools_warn_exception); ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.appl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "1746" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxHelpTextWindow_Impl::InitOnStartupBox()" <<
" " << exceptionToString(tools_warn_exception)) == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.appl"
), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "1746" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxHelpTextWindow_Impl::InitOnStartupBox()"
<< " " << exceptionToString(tools_warn_exception
)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxHelpTextWindow_Impl::InitOnStartupBox()" <<
" " << exceptionToString(tools_warn_exception); ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.appl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "1746" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
1747 }
1748 sModuleName = sTemp;
1749 }
1750
1751 if ( !sModuleName.isEmpty() )
1752 {
1753 // set module name in checkbox text
1754 xOnStartupCB->set_label(aOnStartupText.replaceFirst("%MODULENAME", sModuleName));
1755 // and show it
1756 xOnStartupCB->show();
1757 // set check state
1758 xOnStartupCB->set_active(bHelpAtStartup);
1759 xOnStartupCB->save_state();
1760 }
1761 }
1762}
1763
1764Reference< XBreakIterator > const & SfxHelpTextWindow_Impl::GetBreakIterator()
1765{
1766 if ( !xBreakIterator.is() )
1767 xBreakIterator = vcl::unohelper::CreateBreakIterator();
1768 DBG_ASSERT( xBreakIterator.is(), "Could not create BreakIterator" )do { if (true && (!(xBreakIterator.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "1768" ": "), "%s", "Could not create BreakIterator"); }
} while (false)
;
1769 return xBreakIterator;
1770}
1771
1772Reference< XTextRange > SfxHelpTextWindow_Impl::getCursor() const
1773{
1774 // return the current cursor
1775 Reference< XTextRange > xCursor;
1776
1777 try
1778 {
1779 Reference < XSelectionSupplier > xSelSup( xFrame->getController(), UNO_QUERY );
1780 if ( xSelSup.is() )
1781 {
1782 Any aAny = xSelSup->getSelection();
1783 Reference < XIndexAccess > xSelection;
1784 if ( aAny >>= xSelection )
1785 {
1786 if ( xSelection->getCount() == 1 )
1787 {
1788 aAny = xSelection->getByIndex(0);
1789 aAny >>= xCursor;
1790 }
1791 }
1792 }
1793 }
1794 catch( Exception& )
1795 {
1796 OSL_FAIL( "SfxHelpTextWindow_Impl::getCursor(): unexpected exception" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "1796" ": "), "%s", "SfxHelpTextWindow_Impl::getCursor(): unexpected exception"
); } } while (false)
;
1797 }
1798
1799 return xCursor;
1800}
1801
1802
1803bool SfxHelpTextWindow_Impl::isHandledKey( const vcl::KeyCode& _rKeyCode )
1804{
1805 bool bRet = false;
1806 sal_uInt16 nCode = _rKeyCode.GetCode();
1807
1808 // the keys <CTRL><A> (select all), <CTRL><C> (copy),
1809 // <CTRL><F> (find), <CTRL><P> (print) and <CTRL><W> (close window)
1810 // were handled in help
1811 if ( _rKeyCode.IsMod1() &&
1812 ( KEY_A == nCode || KEY_C == nCode || KEY_F == nCode || KEY_P == nCode || KEY_W == nCode ) )
1813 {
1814 if ( KEY_F == nCode )
1815 DoSearch();
1816 else
1817 bRet = true;
1818 }
1819
1820 return bRet;
1821}
1822
1823
1824IMPL_LINK_NOARG(SfxHelpTextWindow_Impl, SelectHdl, Timer *, void)void SfxHelpTextWindow_Impl::LinkStubSelectHdl(void * instance
, Timer * data) { return static_cast<SfxHelpTextWindow_Impl
*>(instance)->SelectHdl(data); } void SfxHelpTextWindow_Impl
::SelectHdl(__attribute__ ((unused)) Timer *)
1825{
1826 try
1827 {
1828 // select the words, which are equal to the search text of the search page
1829 Reference < XController > xController = xFrame->getController();
1830 if ( xController.is() )
1831 {
1832 // get document
1833 Reference < XSearchable > xSearchable( xController->getModel(), UNO_QUERY );
1834 if ( xSearchable.is() )
1835 {
1836 // create descriptor, set string and find all words
1837 Reference < XSearchDescriptor > xSrchDesc = xSearchable->createSearchDescriptor();
1838 xSrchDesc->setPropertyValue( "SearchRegularExpression", makeAny( true ) );
1839 if ( bIsFullWordSearch )
1840 xSrchDesc->setPropertyValue( "SearchWords", makeAny( true ) );
1841
1842 xSrchDesc->setSearchString( sfx2::PrepareSearchString( aSearchText, GetBreakIterator(), false ) );
1843 Reference< XIndexAccess > xSelection = xSearchable->findAll( xSrchDesc );
1844
1845 // then select all found words
1846 Reference < XSelectionSupplier > xSelectionSup( xController, UNO_QUERY );
1847 if ( xSelectionSup.is() )
1848 {
1849 xSelectionSup->select( Any(xSelection) );
1850 }
1851 }
1852 }
1853 }
1854 catch( Exception& )
1855 {
1856 OSL_FAIL( "SfxHelpTextWindow_Impl::SelectHdl(): unexpected exception" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "1856" ": "), "%s", "SfxHelpTextWindow_Impl::SelectHdl(): unexpected exception"
); } } while (false)
;
1857 }
1858}
1859
1860
1861IMPL_LINK_NOARG( SfxHelpTextWindow_Impl, NotifyHdl, LinkParamNone*, void )void SfxHelpTextWindow_Impl::LinkStubNotifyHdl(void * instance
, LinkParamNone* data) { return static_cast<SfxHelpTextWindow_Impl
*>(instance)->NotifyHdl(data); } void SfxHelpTextWindow_Impl
::NotifyHdl(__attribute__ ((unused)) LinkParamNone*)
1862{
1863 InitToolBoxImages();
1864 Resize();
1865}
1866
1867IMPL_LINK( SfxHelpTextWindow_Impl, FindHdl, sfx2::SearchDialog&, rDlg, void )void SfxHelpTextWindow_Impl::LinkStubFindHdl(void * instance,
sfx2::SearchDialog& data) { return static_cast<SfxHelpTextWindow_Impl
*>(instance)->FindHdl(data); } void SfxHelpTextWindow_Impl
::FindHdl(sfx2::SearchDialog& rDlg)
1868{
1869 FindHdl(&rDlg);
1870}
1871void SfxHelpTextWindow_Impl::FindHdl(sfx2::SearchDialog* pDlg)
1872{
1873 bool bWrapAround = ( nullptr == pDlg );
1874 if ( bWrapAround )
1875 pDlg = m_xSrchDlg.get();
1876 DBG_ASSERT( pDlg, "invalid search dialog" )do { if (true && (!(pDlg))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "1876" ": "), "%s", "invalid search dialog"); } } while (
false)
;
1877 try
1878 {
1879 // select the words, which are equal to the search text of the search page
1880 Reference < XController > xController = xFrame->getController();
1881 if ( xController.is() )
1882 {
1883 // get document
1884 Reference < XSearchable > xSearchable( xController->getModel(), UNO_QUERY );
1885 if ( xSearchable.is() )
1886 {
1887 // create descriptor, set string and find all words
1888 Reference < XSearchDescriptor > xSrchDesc = xSearchable->createSearchDescriptor();
1889 xSrchDesc->setPropertyValue( "SearchWords", makeAny(pDlg->IsOnlyWholeWords()) );
1890 xSrchDesc->setPropertyValue( "SearchCaseSensitive", makeAny(pDlg->IsMarchCase()) );
1891 xSrchDesc->setPropertyValue( "SearchBackwards", makeAny(pDlg->IsSearchBackwards()) );
1892 xSrchDesc->setSearchString( pDlg->GetSearchText() );
1893 Reference< XInterface > xSelection;
1894 Reference< XTextRange > xCursor = getCursor();
1895
1896 if ( xCursor.is() )
1897 {
1898 if ( pDlg->IsSearchBackwards() )
1899 xCursor = xCursor->getStart();
1900 xSelection = xSearchable->findNext( xCursor, xSrchDesc );
1901 }
1902 else
1903 xSelection = xSearchable->findFirst( xSrchDesc );
1904
1905 // then select the found word
1906 if ( xSelection.is() )
1907 {
1908 Reference < XSelectionSupplier > xSelectionSup( xController, UNO_QUERY );
1909 if ( xSelectionSup.is() )
1910 {
1911 xSelectionSup->select( Any(xSelection) );
1912 }
1913 }
1914 else if ( pDlg->IsWrapAround() && !bWrapAround )
1915 {
1916 Reference < text::XTextViewCursorSupplier > xCrsrSupp( xController, uno::UNO_QUERY );
1917 Reference < text::XTextViewCursor > xTVCrsr = xCrsrSupp->getViewCursor();
1918 if ( xTVCrsr.is() )
1919 {
1920 Reference < text::XTextDocument > xDoc( xController->getModel(), uno::UNO_QUERY );
1921 Reference < text::XText > xText = xDoc->getText();
1922 if ( xText.is() )
1923 {
1924 if ( pDlg->IsSearchBackwards() )
1925 xTVCrsr->gotoRange( xText->getEnd(), false );
1926 else
1927 xTVCrsr->gotoRange( xText->getStart(), false );
1928 FindHdl( nullptr );
1929 }
1930 }
1931 }
1932 else
1933 {
1934 assert(m_xSrchDlg && "no search dialog")(static_cast <bool> (m_xSrchDlg && "no search dialog"
) ? void (0) : __assert_fail ("m_xSrchDlg && \"no search dialog\""
, "/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
, 1934, __extension__ __PRETTY_FUNCTION__))
;
1935 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xSrchDlg->getDialog(),
1936 VclMessageType::Info, VclButtonsType::Ok, SfxResId(STR_INFO_NOSEARCHTEXTFOUNDreinterpret_cast<char const *>("STR_INFO_NOSEARCHTEXTFOUND"
"\004" u8"The text you entered was not found.")
)));
1937 xBox->run();
1938 m_xSrchDlg->SetFocusOnEdit();
1939 }
1940 }
1941 }
1942 }
1943 catch( Exception& )
1944 {
1945 OSL_FAIL( "SfxHelpTextWindow_Impl::SelectHdl(): unexpected exception" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "1945" ": "), "%s", "SfxHelpTextWindow_Impl::SelectHdl(): unexpected exception"
); } } while (false)
;
1946 }
1947}
1948
1949IMPL_LINK_NOARG(SfxHelpTextWindow_Impl, CloseHdl, LinkParamNone*, void)void SfxHelpTextWindow_Impl::LinkStubCloseHdl(void * instance
, LinkParamNone* data) { return static_cast<SfxHelpTextWindow_Impl
*>(instance)->CloseHdl(data); } void SfxHelpTextWindow_Impl
::CloseHdl(__attribute__ ((unused)) LinkParamNone*)
1950{
1951 m_xSrchDlg.reset();
1952}
1953
1954IMPL_LINK_NOARG(SfxHelpTextWindow_Impl, CheckHdl, weld::Button&, void)void SfxHelpTextWindow_Impl::LinkStubCheckHdl(void * instance
, weld::Button& data) { return static_cast<SfxHelpTextWindow_Impl
*>(instance)->CheckHdl(data); } void SfxHelpTextWindow_Impl
::CheckHdl(__attribute__ ((unused)) weld::Button&)
1955{
1956 if ( !xConfiguration.is() )
1957 return;
1958
1959 bool bChecked = xOnStartupCB->get_active();
1960 try
1961 {
1962 ConfigurationHelper::writeRelativeKey(
1963 xConfiguration, PATH_OFFICE_FACTORIES"Office/Factories/" + sCurrentFactory, KEY_HELP_ON_OPEN"ooSetupFactoryHelpOnOpen", makeAny( bChecked ) );
1964 ConfigurationHelper::flush( xConfiguration );
1965 }
1966 catch( Exception const & )
1967 {
1968 TOOLS_WARN_EXCEPTION( "sfx.appl", "SfxHelpTextWindow_Impl::CheckHdl()" )do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.appl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "SfxHelpTextWindow_Impl::CheckHdl()"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"sfx.appl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "1968" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxHelpTextWindow_Impl::CheckHdl()"
<< " " << exceptionToString(tools_warn_exception
)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxHelpTextWindow_Impl::CheckHdl()" << " " <<
exceptionToString(tools_warn_exception); ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.appl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "1968" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxHelpTextWindow_Impl::CheckHdl()" << " "
<< exceptionToString(tools_warn_exception)) == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.appl"), (
"/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "1968" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxHelpTextWindow_Impl::CheckHdl()"
<< " " << exceptionToString(tools_warn_exception
)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxHelpTextWindow_Impl::CheckHdl()" << " " <<
exceptionToString(tools_warn_exception); ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.appl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "1968" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
1969 }
1970}
1971
1972void SfxHelpTextWindow_Impl::Resize()
1973{
1974 Size aSize = GetOutputSizePixel();
1975 pTextWin->SetPosSizePixel( Point(0, 0), aSize );
1976}
1977
1978bool SfxHelpTextWindow_Impl::PreNotify( NotifyEvent& rNEvt )
1979{
1980 bool bDone = false;
1981 MouseNotifyEvent nType = rNEvt.GetType();
1982 if ( MouseNotifyEvent::COMMAND == nType && rNEvt.GetCommandEvent() )
1983 {
1984 const CommandEvent* pCmdEvt = rNEvt.GetCommandEvent();
1985 vcl::Window* pCmdWin = rNEvt.GetWindow();
1986
1987 if ( pCmdEvt->GetCommand() == CommandEventId::ContextMenu && pCmdWin != this )
1988 {
1989 Point aPos;
1990 if ( pCmdEvt->IsMouseEvent() )
1991 aPos = pCmdEvt->GetMousePosPixel();
1992 else
1993 aPos = Point( pTextWin->GetPosPixel().X() + 20, 20 );
1994
1995 xMenu->clear();
1996
1997 if (bIsIndexOn)
1998 xMenu->append("index", aIndexOffText, BMP_HELP_TOOLBOX_INDEX_OFF"sfx2/res/indexoff_small.png");
1999 else
2000 xMenu->append("index", aIndexOnText, BMP_HELP_TOOLBOX_INDEX_ON"sfx2/res/indexon_small.png");
2001
2002 xMenu->append_separator("separator1");
2003 xMenu->append("backward", SfxResId(STR_HELP_BUTTON_PREVreinterpret_cast<char const *>("STR_HELP_BUTTON_PREV" "\004"
u8"Previous Page")
), BMP_HELP_TOOLBOX_PREV"res/sc06301.png");
2004 xMenu->set_sensitive("backward", xHelpWin->HasHistoryPredecessor());
2005 xMenu->append("forward", SfxResId(STR_HELP_BUTTON_NEXTreinterpret_cast<char const *>("STR_HELP_BUTTON_NEXT" "\004"
u8"Next Page")
), BMP_HELP_TOOLBOX_NEXT"res/sc06300.png");
2006 xMenu->set_sensitive("forward", xHelpWin->HasHistorySuccessor());
2007 xMenu->append("start", SfxResId(STR_HELP_BUTTON_STARTreinterpret_cast<char const *>("STR_HELP_BUTTON_START" "\004"
u8"First Page")
), BMP_HELP_TOOLBOX_START"res/sc06303.png");
2008 xMenu->append_separator("separator2");
2009 xMenu->append("print", SfxResId(STR_HELP_BUTTON_PRINTreinterpret_cast<char const *>("STR_HELP_BUTTON_PRINT" "\004"
u8"Print...")
), BMP_HELP_TOOLBOX_PRINT"res/sc05504.png");
2010 xMenu->append("bookmarks", SfxResId(STR_HELP_BUTTON_ADDBOOKMARKreinterpret_cast<char const *>("STR_HELP_BUTTON_ADDBOOKMARK"
"\004" u8"Add to Bookmarks...")
), BMP_HELP_TOOLBOX_BOOKMARKS"sfx2/res/favourite.png");
2011 xMenu->append("searchdialog", SfxResId(STR_HELP_BUTTON_SEARCHDIALOGreinterpret_cast<char const *>("STR_HELP_BUTTON_SEARCHDIALOG"
"\004" u8"Find on this Page...")
), BMP_HELP_TOOLBOX_SEARCHDIALOG"sfx2/res/sc05961.png");
2012 xMenu->append_separator("separator3");
2013 xMenu->append_check("selectionmode", SfxResId(STR_HELP_MENU_TEXT_SELECTION_MODEreinterpret_cast<char const *>("STR_HELP_MENU_TEXT_SELECTION_MODE"
"\004" u8"Select Text")
));
2014 URL aURL;
2015 aURL.Complete = ".uno:SelectTextMode";
2016 Reference< util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
2017 xTrans->parseStrict(aURL);
2018 Reference < XDispatch > xDisp = xFrame->queryDispatch( aURL, OUString(), 0 );
2019 if(xDisp.is())
2020 {
2021 rtl::Reference<HelpStatusListener_Impl> pStateListener =
2022 new HelpStatusListener_Impl(xDisp, aURL );
2023 FeatureStateEvent rEvent = pStateListener->GetStateEvent();
2024 bool bCheck = false;
2025 rEvent.State >>= bCheck;
2026 xMenu->set_active("selectionmode", bCheck);
2027 }
2028 xMenu->append_separator("separator4");
2029 xMenu->append("copy", SfxResId(STR_HELP_MENU_TEXT_COPYreinterpret_cast<char const *>("STR_HELP_MENU_TEXT_COPY"
"\004" u8"~Copy")
), BMP_HELP_TOOLBOX_COPY"sfx2/res/sc05711.png");
2030 xMenu->set_sensitive("copy", HasSelection());
2031
2032 if ( bIsDebug )
2033 {
2034 xMenu->append_separator("separator5");
2035 xMenu->append("sourceview", SfxResId(STR_HELP_BUTTON_SOURCEVIEWreinterpret_cast<char const *>("STR_HELP_BUTTON_SOURCEVIEW"
"\004" u8"HTML Source")
));
2036 }
2037
2038 int x, y, width, height;
2039 weld::Window* pTopLevel = GetFrameWeld();
2040 xHelpWin->GetContainer()->get_extents_relative_to(*pTopLevel, x, y, width, height);
2041 aPos.AdjustX(x);
2042 aPos.AdjustY(y);
2043
2044 xHelpWin->DoAction(xMenu->popup_at_rect(pTopLevel, tools::Rectangle(aPos, Size(1,1))));
2045 bDone = true;
2046 }
2047 }
2048 else if ( MouseNotifyEvent::KEYINPUT == nType && rNEvt.GetKeyEvent() )
2049 {
2050 const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
2051 const vcl::KeyCode& rKeyCode = pKEvt->GetKeyCode();
2052 sal_uInt16 nKeyGroup = rKeyCode.GetGroup();
2053 sal_uInt16 nKey = rKeyCode.GetCode();
2054 if ( KEYGROUP_ALPHA == nKeyGroup && !isHandledKey( rKeyCode ) )
2055 {
2056 // do nothing disables the writer accelerators
2057 bDone = true;
2058 }
2059 else if ( rKeyCode.IsMod1() && ( KEY_F4 == nKey || KEY_W == nKey ) )
2060 {
2061 // <CTRL><F4> or <CTRL><W> -> close top frame
2062 xHelpWin->CloseWindow();
2063 bDone = true;
2064 }
2065 else if ( KEY_TAB == nKey && xOnStartupCB->has_focus() )
2066 {
2067 xToolBox->grab_focus();
2068 bDone = true;
2069 }
2070 }
2071
2072 return bDone || Window::PreNotify( rNEvt );
2073}
2074
2075
2076void SfxHelpTextWindow_Impl::GetFocus()
2077{
2078 if ( bIsInClose )
2079 return;
2080
2081 try
2082 {
2083 if( xFrame.is() )
2084 {
2085 Reference< css::awt::XWindow > xWindow = xFrame->getComponentWindow();
2086 if( xWindow.is() )
2087 xWindow->setFocus();
2088 }
2089 }
2090 catch( Exception const & )
2091 {
2092 TOOLS_WARN_EXCEPTION( "sfx.appl", "SfxHelpTextWindow_Impl::GetFocus()" )do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.appl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "SfxHelpTextWindow_Impl::GetFocus()"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"sfx.appl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2092" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxHelpTextWindow_Impl::GetFocus()"
<< " " << exceptionToString(tools_warn_exception
)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxHelpTextWindow_Impl::GetFocus()" << " " <<
exceptionToString(tools_warn_exception); ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.appl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2092" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxHelpTextWindow_Impl::GetFocus()" << " "
<< exceptionToString(tools_warn_exception)) == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.appl"), (
"/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2092" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxHelpTextWindow_Impl::GetFocus()"
<< " " << exceptionToString(tools_warn_exception
)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxHelpTextWindow_Impl::GetFocus()" << " " <<
exceptionToString(tools_warn_exception); ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.appl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2092" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
2093 }
2094}
2095
2096
2097void SfxHelpTextWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt )
2098{
2099 Window::DataChanged( rDCEvt );
2100
2101 if ( ( ( rDCEvt.GetType() == DataChangedEventType::SETTINGS ) ||
2102 ( rDCEvt.GetType() == DataChangedEventType::DISPLAY ) ) &&
2103 ( rDCEvt.GetFlags() & AllSettingsFlags::STYLE ) )
2104 {
2105 SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFaceColor() ) );
2106 InitToolBoxImages();
2107 }
2108}
2109
2110void SfxHelpTextWindow_Impl::ToggleIndex( bool bOn )
2111{
2112 bIsIndexOn = bOn;
2113 if ( bIsIndexOn )
2114 {
2115 xToolBox->set_item_icon_name("index", aIndexOffImage);
2116 xToolBox->set_item_tooltip_text("index", aIndexOffText);
2117 }
2118 else
2119 {
2120 xToolBox->set_item_icon_name("index", aIndexOnImage);
2121 xToolBox->set_item_tooltip_text("index", aIndexOnText);
2122 }
2123}
2124
2125void SfxHelpTextWindow_Impl::SelectSearchText( const OUString& rSearchText, bool _bIsFullWordSearch )
2126{
2127 aSearchText = rSearchText;
2128 bIsFullWordSearch = _bIsFullWordSearch;
2129 aSelectIdle.Start();
2130}
2131
2132
2133void SfxHelpTextWindow_Impl::SetPageStyleHeaderOff() const
2134{
2135 bool bSetOff = false;
2136 // set off the pagestyle header to prevent print output of the help URL
2137 try
2138 {
2139 Reference < XController > xController = xFrame->getController();
2140 Reference < XSelectionSupplier > xSelSup( xController, UNO_QUERY );
2141 if ( xSelSup.is() )
2142 {
2143 Reference < XIndexAccess > xSelection;
2144 if ( xSelSup->getSelection() >>= xSelection )
2145 {
2146 Reference < XTextRange > xRange;
2147 if ( xSelection->getByIndex(0) >>= xRange )
2148 {
2149 Reference < XText > xText = xRange->getText();
2150 Reference < XPropertySet > xProps( xText->createTextCursorByRange( xRange ), UNO_QUERY );
2151 OUString sStyleName;
2152 if ( xProps->getPropertyValue( "PageStyleName" ) >>= sStyleName )
2153 {
2154 Reference < XStyleFamiliesSupplier > xStyles( xController->getModel(), UNO_QUERY );
2155 Reference < XNameContainer > xContainer;
2156 if ( xStyles->getStyleFamilies()->getByName( "PageStyles" )
2157 >>= xContainer )
2158 {
2159 Reference < XStyle > xStyle;
2160 if ( xContainer->getByName( sStyleName ) >>= xStyle )
2161 {
2162 Reference < XPropertySet > xPropSet( xStyle, UNO_QUERY );
2163 xPropSet->setPropertyValue( "HeaderIsOn", makeAny( false ) );
2164
2165 Reference< XModifiable > xReset(xStyles, UNO_QUERY);
2166 xReset->setModified(false);
2167 bSetOff = true;
2168 }
2169 }
2170 }
2171 }
2172 }
2173 }
2174 }
2175 catch( Exception const & )
2176 {
2177 TOOLS_WARN_EXCEPTION( "sfx.appl", "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff()" )do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.appl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff()"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"sfx.appl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2177" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff()"
<< " " << exceptionToString(tools_warn_exception
)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff()" <<
" " << exceptionToString(tools_warn_exception); ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.appl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2177" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff()"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"sfx.appl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2177" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff()"
<< " " << exceptionToString(tools_warn_exception
)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff()" <<
" " << exceptionToString(tools_warn_exception); ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.appl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2177" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
2178 }
2179
2180 SAL_WARN_IF( !bSetOff, "sfx.appl", "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): set off failed" )do { if (true && (!bSetOff)) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "sfx.appl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): set off failed"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.appl"
), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2180" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): set off failed"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): set off failed"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.appl"
), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2180" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): set off failed"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.appl"
), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2180" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): set off failed"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): set off failed"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.appl"
), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2180" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2181}
2182
2183
2184void SfxHelpTextWindow_Impl::CloseFrame()
2185{
2186 bIsInClose = true;
2187 try
2188 {
2189 css::uno::Reference< css::util::XCloseable > xCloseable ( xFrame, css::uno::UNO_QUERY );
2190 if (xCloseable.is())
2191 xCloseable->close(true);
2192 }
2193 catch( css::util::CloseVetoException& )
2194 {
2195 }
2196}
2197
2198
2199void SfxHelpTextWindow_Impl::DoSearch()
2200{
2201 if (m_xSrchDlg)
2202 return;
2203
2204 // create the search dialog
2205 m_xSrchDlg = std::make_shared<sfx2::SearchDialog>(pTextWin->GetFrameWeld(), "HelpSearchDialog");
2206 // set handler
2207 m_xSrchDlg->SetFindHdl( LINK( this, SfxHelpTextWindow_Impl, FindHdl )::tools::detail::makeLink( ::tools::detail::castTo<SfxHelpTextWindow_Impl
*>(this), &SfxHelpTextWindow_Impl::LinkStubFindHdl)
);
2208 m_xSrchDlg->SetCloseHdl( LINK( this, SfxHelpTextWindow_Impl, CloseHdl )::tools::detail::makeLink( ::tools::detail::castTo<SfxHelpTextWindow_Impl
*>(this), &SfxHelpTextWindow_Impl::LinkStubCloseHdl)
);
2209 // get selected text of the help page to set it as the search text
2210 Reference< XTextRange > xCursor = getCursor();
2211 if ( xCursor.is() )
2212 {
2213 OUString sText = xCursor->getString();
2214 if ( !sText.isEmpty() )
2215 m_xSrchDlg->SetSearchText( sText );
2216 }
2217 sfx2::SearchDialog::runAsync(m_xSrchDlg);
2218}
2219
2220void SfxHelpWindow_Impl::GetFocus()
2221{
2222 if (pTextWin)
2223 pTextWin->GrabFocus();
2224 else
2225 DockingWindow::GetFocus();
2226}
2227
2228void SfxHelpWindow_Impl::MakeLayout()
2229{
2230 Split();
2231
2232 m_xHelpPaneWindow->set_visible(bIndex);
2233}
2234
2235IMPL_LINK(SfxHelpWindow_Impl, ResizeHdl, const Size&, rSize, void)void SfxHelpWindow_Impl::LinkStubResizeHdl(void * instance, const
Size& data) { return static_cast<SfxHelpWindow_Impl *
>(instance)->ResizeHdl(data); } void SfxHelpWindow_Impl
::ResizeHdl(const Size& rSize)
2236{
2237 int nNewWidth = rSize.Width();
2238 if (!nNewWidth)
2239 return;
2240 if (bSplit)
2241 nIndexSize = round(m_xContainer->get_position() * 100.0 / nNewWidth);
2242 nWidth = nNewWidth;
2243 Split();
2244 nIndexSize = round(m_xContainer->get_position() * 100.0 / nWidth);
2245}
2246
2247void SfxHelpWindow_Impl::Split()
2248{
2249 if (!nWidth)
2250 return;
2251 m_xContainer->set_position(nWidth * nIndexSize / 100);
2252 bSplit = true;
2253}
2254
2255void SfxHelpWindow_Impl::LoadConfig()
2256{
2257 SvtViewOptions aViewOpt( EViewType::Window, CONFIGNAME_HELPWIN"OfficeHelp" );
2258 if ( !aViewOpt.Exists() )
2259 return;
2260 bIndex = aViewOpt.IsVisible();
2261
2262 Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME"UserItem" );
2263 OUString aUserData;
2264 if ( aUserItem >>= aUserData )
2265 {
2266 DBG_ASSERT( comphelper::string::getTokenCount(aUserData, ';') == 6, "invalid user data" )do { if (true && (!(comphelper::string::getTokenCount
(aUserData, ';') == 6))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2266" ": "), "%s", "invalid user data"); } } while (false
)
;
2267 sal_Int32 nIdx = 0;
2268 nIndexSize = aUserData.getToken( 0, ';', nIdx ).toInt32();
2269 aUserData.getToken(0, ';', nIdx); // ignore nTextSize
2270 sal_Int32 nOldWidth = aUserData.getToken( 0, ';', nIdx ).toInt32();
2271 sal_Int32 nOldHeight = aUserData.getToken( 0, ';', nIdx ).toInt32();
2272 aWinSize = Size(nOldWidth, nOldHeight);
2273 aWinPos.setX( aUserData.getToken( 0, ';', nIdx ).toInt32() );
2274 aWinPos.setY( aUserData.getToken( 0, ';', nIdx ).toInt32() );
2275 }
2276
2277 pTextWin->ToggleIndex( bIndex );
2278}
2279
2280void SfxHelpWindow_Impl::SaveConfig()
2281{
2282 SvtViewOptions aViewOpt( EViewType::Window, CONFIGNAME_HELPWIN"OfficeHelp" );
2283 sal_Int32 nW = 0, nH = 0;
2284
2285 if ( xWindow.is() )
2286 {
2287 css::awt::Rectangle aRect = xWindow->getPosSize();
2288 nW = aRect.Width;
2289 nH = aRect.Height;
2290 }
2291
2292 aViewOpt.SetVisible( bIndex );
2293 VclPtr<vcl::Window> pScreenWin = VCLUnoHelper::GetWindow( xWindow );
2294 aWinPos = pScreenWin->GetWindowExtentsRelative( nullptr ).TopLeft();
2295 if (bSplit)
2296 nIndexSize = round(m_xContainer->get_position() * 100.0 / nWidth);
2297 const OUString aUserData = OUString::number( nIndexSize )
2298 + ";" + OUString::number( 100 - nIndexSize )
2299 + ";" + OUString::number( nW )
2300 + ";" + OUString::number( nH )
2301 + ";" + OUString::number( aWinPos.X() )
2302 + ";" + OUString::number( aWinPos.Y() );
2303
2304 aViewOpt.SetUserItem( USERITEM_NAME"UserItem", makeAny( aUserData ) );
2305}
2306
2307void SfxHelpWindow_Impl::ShowStartPage()
2308{
2309 loadHelpContent(SfxHelpWindow_Impl::buildHelpURL(xIndexWin->GetFactory(), "/start", OUString()));
2310}
2311
2312IMPL_LINK(SfxHelpWindow_Impl, SelectHdl, const OString&, rCurItem, void)void SfxHelpWindow_Impl::LinkStubSelectHdl(void * instance, const
OString& data) { return static_cast<SfxHelpWindow_Impl
*>(instance)->SelectHdl(data); } void SfxHelpWindow_Impl
::SelectHdl(const OString& rCurItem)
2313{
2314 bGrabFocusToToolBox = pTextWin->GetToolBox().has_focus();
2315 DoAction(rCurItem);
2316}
2317
2318IMPL_LINK_NOARG(SfxHelpWindow_Impl, OpenHdl, LinkParamNone*, void)void SfxHelpWindow_Impl::LinkStubOpenHdl(void * instance, LinkParamNone
* data) { return static_cast<SfxHelpWindow_Impl *>(instance
)->OpenHdl(data); } void SfxHelpWindow_Impl::OpenHdl(__attribute__
((unused)) LinkParamNone*)
2319{
2320 xIndexWin->SelectExecutableEntry();
2321 OUString aEntry = xIndexWin->GetSelectedEntry();
2322
2323 if ( aEntry.isEmpty() )
2324 return;
2325
2326 OUString sHelpURL;
2327
2328 bool bComplete = aEntry.toAsciiLowerCase().match("vnd.sun.star.help");
2329
2330 if (bComplete)
2331 sHelpURL = aEntry;
2332 else
2333 {
2334 OUString aId;
2335 OUString aAnchor('#');
2336 if ( comphelper::string::getTokenCount(aEntry, '#') == 2 )
2337 {
2338 sal_Int32 nIdx{ 0 };
2339 aId = aEntry.getToken( 0, '#', nIdx );
2340 aAnchor += aEntry.getToken( 0, '#', nIdx );
2341 }
2342 else
2343 aId = aEntry;
2344
2345 sHelpURL = SfxHelpWindow_Impl::buildHelpURL(xIndexWin->GetFactory(), "/" + aId, aAnchor);
2346 }
2347
2348 loadHelpContent(sHelpURL);
2349}
2350
2351IMPL_LINK( SfxHelpWindow_Impl, SelectFactoryHdl, SfxHelpIndexWindow_Impl* , pWin, void )void SfxHelpWindow_Impl::LinkStubSelectFactoryHdl(void * instance
, SfxHelpIndexWindow_Impl* data) { return static_cast<SfxHelpWindow_Impl
*>(instance)->SelectFactoryHdl(data); } void SfxHelpWindow_Impl
::SelectFactoryHdl(SfxHelpIndexWindow_Impl* pWin)
2352{
2353 if ( sTitle.isEmpty() )
2354 sTitle = GetParent()->GetText();
2355
2356 Reference< XTitle > xTitle(xFrame, UNO_QUERY);
2357 if (xTitle.is ())
2358 xTitle->setTitle(sTitle + " - " + xIndexWin->GetActiveFactoryTitle());
2359
2360 if ( pWin )
2361 ShowStartPage();
2362 xIndexWin->ClearSearchPage();
2363}
2364
2365
2366IMPL_LINK( SfxHelpWindow_Impl, ChangeHdl, HelpListener_Impl&, rListener, void )void SfxHelpWindow_Impl::LinkStubChangeHdl(void * instance, HelpListener_Impl
& data) { return static_cast<SfxHelpWindow_Impl *>(
instance)->ChangeHdl(data); } void SfxHelpWindow_Impl::ChangeHdl
(HelpListener_Impl& rListener)
2367{
2368 SetFactory( rListener.GetFactory() );
2369}
2370
2371
2372void SfxHelpWindow_Impl::openDone(const OUString& sURL ,
2373 bool bSuccess)
2374{
2375 INetURLObject aObj( sURL );
2376 if ( aObj.GetProtocol() == INetProtocol::VndSunStarHelp )
2377 SetFactory( aObj.GetHost() );
2378 if ( IsWait() )
2379 LeaveWait();
2380 if ( bGrabFocusToToolBox )
2381 {
2382 pTextWin->GetToolBox().grab_focus();
2383 bGrabFocusToToolBox = false;
2384 }
2385 else
2386 xIndexWin->GrabFocusBack();
2387 if ( !bSuccess )
2388 return;
2389
2390 // set some view settings: "prevent help tips" and "helpid == 68245"
2391 try
2392 {
2393 Reference < XController > xController = pTextWin->getFrame()->getController();
2394 if ( xController.is() )
2395 {
2396 Reference < XViewSettingsSupplier > xSettings( xController, UNO_QUERY );
2397 Reference < XPropertySet > xViewProps = xSettings->getViewSettings();
2398 Reference< XPropertySetInfo > xInfo = xViewProps->getPropertySetInfo();
2399 xViewProps->setPropertyValue( "ShowContentTips", makeAny( false ) );
2400 xViewProps->setPropertyValue( "ShowGraphics", makeAny( true ) );
2401 xViewProps->setPropertyValue( "ShowTables", makeAny( true ) );
2402 xViewProps->setPropertyValue( "HelpURL", makeAny( OUString("HID:SFX2_HID_HELP_ONHELP") ) );
2403 OUString sProperty( "IsExecuteHyperlinks" );
2404 if ( xInfo->hasPropertyByName( sProperty ) )
2405 xViewProps->setPropertyValue( sProperty, makeAny( true ) );
2406 xController->restoreViewData(Any());
2407 }
2408 }
2409 catch( Exception& )
2410 {
2411 OSL_FAIL( "SfxHelpWindow_Impl::OpenDoneHdl(): unexpected exception" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2411" ": "), "%s", "SfxHelpWindow_Impl::OpenDoneHdl(): unexpected exception"
); } } while (false)
;
2412 }
2413
2414 // When the SearchPage opens the help doc, then select all words, which are equal to its text
2415 OUString sSearchText = comphelper::string::strip(xIndexWin->GetSearchText(), ' ');
2416 if ( !sSearchText.isEmpty() )
2417 pTextWin->SelectSearchText( sSearchText, xIndexWin->IsFullWordSearch() );
2418
2419 // no page style header -> this prevents a print output of the URL
2420 pTextWin->SetPageStyleHeaderOff();
2421}
2422
2423
2424SfxHelpWindow_Impl::SfxHelpWindow_Impl(
2425 const css::uno::Reference < css::frame::XFrame2 >& rFrame,
2426 vcl::Window* pParent ) :
2427
2428 DockingWindow(pParent, "DockingWindow", "sfx/ui/dockingwindow.ui"),
2429
2430 xFrame ( rFrame ),
2431 pTextWin ( nullptr ),
2432 pHelpInterceptor ( new HelpInterceptor_Impl() ),
2433 pHelpListener ( new HelpListener_Impl( pHelpInterceptor ) ),
2434 bIndex ( true ),
2435 bGrabFocusToToolBox ( false ),
2436 bSplit ( false ),
2437 nWidth ( 0 ),
2438 nIndexSize ( 40 ), // % of width
2439 aWinPos ( 0, 0 ),
2440 aWinSize ( 0, 0 ),
2441 sTitle ( pParent->GetText() )
2442{
2443 SetStyle(GetStyle() & ~WB_DOCKABLE);
2444
2445 SetHelpId( HID_HELP_WINDOW"SFX2_HID_HELP_WINDOW" );
2446
2447 m_xVclContentArea = VclPtr<VclVBox>::Create(this);
2448 m_xVclContentArea->Show();
2449 m_xBuilder.reset(Application::CreateInterimBuilder(m_xVclContentArea, "sfx/ui/helpwindow.ui", false));
2450 m_xContainer = m_xBuilder->weld_paned("HelpWindow");
2451 m_xContainer->connect_size_allocate(LINK(this, SfxHelpWindow_Impl, ResizeHdl)::tools::detail::makeLink( ::tools::detail::castTo<SfxHelpWindow_Impl
*>(this), &SfxHelpWindow_Impl::LinkStubResizeHdl)
);
2452 m_xHelpPaneWindow = m_xBuilder->weld_container("helppanewindow");
2453 m_xHelpTextWindow = m_xBuilder->weld_container("helptextwindow");
2454 m_xHelpTextWindow->set_size_request(m_xHelpTextWindow->get_approximate_digit_width() * 120, -1);
2455 m_xHelpTextXWindow = m_xHelpTextWindow->CreateChildFrame();
2456
2457 pHelpInterceptor->InitWaiter( this );
2458 xIndexWin.reset(new SfxHelpIndexWindow_Impl(this, m_xHelpPaneWindow.get()));
2459 xIndexWin->SetDoubleClickHdl( LINK( this, SfxHelpWindow_Impl, OpenHdl )::tools::detail::makeLink( ::tools::detail::castTo<SfxHelpWindow_Impl
*>(this), &SfxHelpWindow_Impl::LinkStubOpenHdl)
);
2460 xIndexWin->SetSelectFactoryHdl( LINK( this, SfxHelpWindow_Impl, SelectFactoryHdl )::tools::detail::makeLink( ::tools::detail::castTo<SfxHelpWindow_Impl
*>(this), &SfxHelpWindow_Impl::LinkStubSelectFactoryHdl
)
);
2461
2462 pTextWin = VclPtr<SfxHelpTextWindow_Impl>::Create(this, *m_xBuilder, VCLUnoHelper::GetWindow(m_xHelpTextXWindow));
2463 Reference < XFrames > xFrames = rFrame->getFrames();
2464 xFrames->append( Reference<XFrame>(pTextWin->getFrame(), UNO_QUERY_THROW) );
2465 pTextWin->SetSelectHdl( LINK( this, SfxHelpWindow_Impl, SelectHdl )::tools::detail::makeLink( ::tools::detail::castTo<SfxHelpWindow_Impl
*>(this), &SfxHelpWindow_Impl::LinkStubSelectHdl)
);
2466 pTextWin->Show();
2467 pHelpInterceptor->setInterception( Reference<XFrame>(pTextWin->getFrame(), UNO_QUERY_THROW) );
2468 pHelpListener->SetChangeHdl( LINK( this, SfxHelpWindow_Impl, ChangeHdl )::tools::detail::makeLink( ::tools::detail::castTo<SfxHelpWindow_Impl
*>(this), &SfxHelpWindow_Impl::LinkStubChangeHdl)
);
2469 LoadConfig();
2470}
2471
2472SfxHelpWindow_Impl::~SfxHelpWindow_Impl()
2473{
2474 disposeOnce();
2475}
2476
2477void SfxHelpWindow_Impl::dispose()
2478{
2479 SaveConfig();
2480 xIndexWin.reset();
2481 pTextWin->CloseFrame();
2482 pTextWin.disposeAndClear();
1
Calling 'VclPtr::disposeAndClear'
2483
2484 m_xHelpTextXWindow->dispose();
2485 m_xHelpTextXWindow.clear();
2486 m_xHelpTextWindow.reset();
2487 m_xHelpPaneWindow.reset();
2488 m_xContainer.reset();
2489 m_xBuilder.reset();
2490 m_xVclContentArea.disposeAndClear();
2491
2492 DockingWindow::dispose();
2493}
2494
2495bool SfxHelpWindow_Impl::PreNotify( NotifyEvent& rNEvt )
2496{
2497 bool bHandled = false;
2498 if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
2499 {
2500 // Backward == <ALT><LEFT> or <BACKSPACE> Forward == <ALT><RIGHT>
2501 const vcl::KeyCode& rKeyCode = rNEvt.GetKeyEvent()->GetKeyCode();
2502 sal_uInt16 nKey = rKeyCode.GetCode();
2503 if ( ( rKeyCode.IsMod2() && ( KEY_LEFT == nKey || KEY_RIGHT == nKey ) ) ||
2504 ( !rKeyCode.GetModifier() && KEY_BACKSPACE == nKey && !xIndexWin->HasFocusOnEdit() ) )
2505 {
2506 DoAction( rKeyCode.GetCode() == KEY_RIGHT ? "forward" : "backward" );
2507 bHandled = true;
2508 }
2509 else if ( rKeyCode.IsMod1() && ( KEY_F4 == nKey || KEY_W == nKey ) )
2510 {
2511 // <CTRL><F4> or <CTRL><W> -> close top frame
2512 CloseWindow();
2513 bHandled = true;
2514 }
2515 }
2516 return bHandled || Window::PreNotify( rNEvt );
2517}
2518
2519void SfxHelpWindow_Impl::setContainerWindow( const Reference < css::awt::XWindow >& xWin )
2520{
2521 xWindow = xWin;
2522 MakeLayout();
2523 if (xWindow.is())
2524 {
2525 VclPtr<vcl::Window> pScreenWin = VCLUnoHelper::GetWindow(xWindow);
2526 if (aWinSize.Width() && aWinSize.Height())
2527 pScreenWin->SetPosSizePixel(aWinPos, aWinSize);
2528 else
2529 pScreenWin->SetPosPixel(aWinPos);
2530 }
2531}
2532
2533void SfxHelpWindow_Impl::SetFactory( const OUString& rFactory )
2534{
2535 xIndexWin->SetFactory( rFactory, true );
2536}
2537
2538void SfxHelpWindow_Impl::SetHelpURL( const OUString& rURL )
2539{
2540 INetURLObject aObj( rURL );
2541 if ( aObj.GetProtocol() == INetProtocol::VndSunStarHelp )
2542 SetFactory( aObj.GetHost() );
2543}
2544
2545void SfxHelpWindow_Impl::DoAction(const OString& rActionId)
2546{
2547 if (rActionId == "index")
2548 {
2549 bIndex = !bIndex;
2550 MakeLayout();
2551 pTextWin->ToggleIndex( bIndex );
2552 }
2553 else if (rActionId == "start")
2554 {
2555 ShowStartPage();
2556 }
2557 else if (rActionId == "backward" || rActionId == "forward")
2558 {
2559 URL aURL;
2560 aURL.Complete = ".uno:Backward";
2561 if (rActionId == "forward")
2562 aURL.Complete = ".uno:Forward";
2563 Reference< util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
2564 xTrans->parseStrict(aURL);
2565 pHelpInterceptor->dispatch( aURL, Sequence < PropertyValue >() );
2566 }
2567 else if (rActionId == "searchdialog")
2568 {
2569 pTextWin->DoSearch();
2570 }
2571 else if (rActionId == "print" || rActionId == "sourceview" || rActionId == "copy" || rActionId == "selectionmode")
2572 {
2573 Reference < XDispatchProvider > xProv = pTextWin->getFrame();
2574 if ( xProv.is() )
2575 {
2576 URL aURL;
2577 if (rActionId == "print")
2578 aURL.Complete = ".uno:Print";
2579 else if (rActionId == "sourceview")
2580 aURL.Complete = ".uno:SourceView";
2581 else if (rActionId == "copy")
2582 aURL.Complete = ".uno:Copy";
2583 else // rActionId == "selectionmode"
2584 aURL.Complete = ".uno:SelectTextMode";
2585 Reference< util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
2586 xTrans->parseStrict(aURL);
2587 Reference < XDispatch > xDisp = xProv->queryDispatch( aURL, OUString(), 0 );
2588 if ( xDisp.is() )
2589 xDisp->dispatch( aURL, Sequence < PropertyValue >() );
2590 }
2591 }
2592 else if (rActionId == "bookmarks")
2593 {
2594 OUString aURL = pHelpInterceptor->GetCurrentURL();
2595 if ( !aURL.isEmpty() )
2596 {
2597 try
2598 {
2599 Content aCnt( aURL, Reference< css::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
2600 css::uno::Reference< css::beans::XPropertySetInfo > xInfo = aCnt.getProperties();
2601 if ( xInfo->hasPropertyByName( PROPERTY_TITLE"Title" ) )
2602 {
2603 css::uno::Any aAny = aCnt.getPropertyValue( PROPERTY_TITLE"Title" );
2604 OUString aValue;
2605 if ( aAny >>= aValue )
2606 {
2607 SfxAddHelpBookmarkDialog_Impl aDlg(GetFrameWeld(), false);
2608 aDlg.SetTitle(aValue);
2609 if (aDlg.run() == RET_OK )
2610 {
2611 xIndexWin->AddBookmarks( aDlg.GetTitle(), aURL );
2612 }
2613 }
2614 }
2615 }
2616 catch( Exception& )
2617 {
2618 OSL_FAIL( "SfxHelpWindow_Impl::DoAction(): unexpected exception" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2618" ": "), "%s", "SfxHelpWindow_Impl::DoAction(): unexpected exception"
); } } while (false)
;
2619 }
2620 }
2621 }
2622}
2623
2624void SfxHelpWindow_Impl::CloseWindow()
2625{
2626 try
2627 {
2628 // search for top frame
2629 Reference< XFramesSupplier > xCreator = getTextFrame()->getCreator();
2630 while ( xCreator.is() && !xCreator->isTop() )
2631 {
2632 xCreator = xCreator->getCreator();
2633 }
2634
2635 // when found, close it
2636 if ( xCreator.is() && xCreator->isTop() )
2637 {
2638 Reference < XCloseable > xCloser( xCreator, UNO_QUERY );
2639 if ( xCloser.is() )
2640 xCloser->close( false );
2641 }
2642 }
2643 catch( Exception const & )
2644 {
2645 TOOLS_WARN_EXCEPTION( "sfx.appl", "SfxHelpWindow_Impl::CloseWindow()" )do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.appl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "SfxHelpWindow_Impl::CloseWindow()"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"sfx.appl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2645" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxHelpWindow_Impl::CloseWindow()" <<
" " << exceptionToString(tools_warn_exception)), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxHelpWindow_Impl::CloseWindow()" << " " <<
exceptionToString(tools_warn_exception); ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.appl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2645" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxHelpWindow_Impl::CloseWindow()" << " " <<
exceptionToString(tools_warn_exception)) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.appl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2645" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxHelpWindow_Impl::CloseWindow()" <<
" " << exceptionToString(tools_warn_exception)), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxHelpWindow_Impl::CloseWindow()" << " " <<
exceptionToString(tools_warn_exception); ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.appl"), ("/home/maarten/src/libreoffice/core/sfx2/source/appl/newhelp.cxx"
":" "2645" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
2646 }
2647}
2648
2649
2650void SfxHelpWindow_Impl::UpdateToolbox()
2651{
2652 pTextWin->GetToolBox().set_item_sensitive("backward", pHelpInterceptor->HasHistoryPred());
2653 pTextWin->GetToolBox().set_item_sensitive("forward", pHelpInterceptor->HasHistorySucc());
2654}
2655
2656
2657bool SfxHelpWindow_Impl::HasHistoryPredecessor() const
2658{
2659 return pHelpInterceptor->HasHistoryPred();
2660}
2661
2662
2663bool SfxHelpWindow_Impl::HasHistorySuccessor() const
2664{
2665 return pHelpInterceptor->HasHistorySucc();
2666}
2667
2668// class SfxAddHelpBookmarkDialog_Impl -----------------------------------
2669
2670SfxAddHelpBookmarkDialog_Impl::SfxAddHelpBookmarkDialog_Impl(weld::Widget* pParent, bool bRename)
2671 : GenericDialogController(pParent, "sfx/ui/bookmarkdialog.ui", "BookmarkDialog")
2672 , m_xTitleED(m_xBuilder->weld_entry("entry"))
2673 , m_xAltTitle(m_xBuilder->weld_label("alttitle"))
2674{
2675 if (bRename)
2676 m_xDialog->set_title(m_xAltTitle->get_label());
2677}
2678
2679void SfxAddHelpBookmarkDialog_Impl::SetTitle(const OUString& rTitle)
2680{
2681 m_xTitleED->set_text(rTitle);
2682 m_xTitleED->select_region(0, -1);
2683}
2684
2685/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx

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#ifndef INCLUDED_VCL_PTR_HXX
21#define INCLUDED_VCL_PTR_HXX
22
23#include <sal/config.h>
24
25#include <rtl/ref.hxx>
26
27#include <utility>
28#include <type_traits>
29
30#ifdef DBG_UTIL
31#ifndef _WIN32
32#include <vcl/vclmain.hxx>
33#endif
34#endif
35
36class VclReferenceBase;
37
38namespace vcl::detail {
39
40template<typename>
41constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; }
42
43template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase(
44 int (*)[sizeof(T)])
45{ return std::is_base_of<VclReferenceBase, T>::value; }
46
47} // namespace vcl::detail
48
49/**
50 * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
51 *
52 * For more details on the design please see vcl/README.lifecycle
53 *
54 * @param reference_type must be a subclass of vcl::Window
55 */
56template <class reference_type>
57class VclPtr
58{
59 static_assert(
60 vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>(
61 nullptr),
62 "template argument type must be derived from VclReferenceBase");
63
64 ::rtl::Reference<reference_type> m_rInnerRef;
65
66public:
67 /** Constructor...
68 */
69 VclPtr()
70 : m_rInnerRef()
71 {}
72
73 /** Constructor...
74 */
75 VclPtr (reference_type * pBody)
76 : m_rInnerRef(pBody)
77 {}
78
79 /** Constructor... that doesn't take a ref.
80 */
81 VclPtr (reference_type * pBody, __sal_NoAcquire)
82 : m_rInnerRef(pBody, SAL_NO_ACQUIRE)
83 {}
84
85 /** Up-casting conversion constructor: Copies interface reference.
86
87 Does not work for up-casts to ambiguous bases. For the special case of
88 up-casting to Reference< XInterface >, see the corresponding conversion
89 operator.
90
91 @param rRef another reference
92 */
93 template< class derived_type >
94 VclPtr(
95 const VclPtr< derived_type > & rRef,
96 typename std::enable_if<
97 std::is_base_of<reference_type, derived_type>::value, int>::type
98 = 0 )
99 : m_rInnerRef( static_cast<reference_type*>(rRef) )
100 {
101 }
102
103#if defined(DBG_UTIL) && !defined(_WIN32)
104 virtual ~VclPtr()
105 {
106 assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain
::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 106, __extension__ __PRETTY_FUNCTION__))
;
107 // We can be one of the intermediate counts, but if we are the last
108 // VclPtr keeping this object alive, then something forgot to call dispose().
109 assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
110 && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
;
111 }
112 VclPtr(VclPtr const &) = default;
113 VclPtr(VclPtr &&) = default;
114 VclPtr & operator =(VclPtr const &) = default;
115 VclPtr & operator =(VclPtr &&) = default;
116#endif
117
118 /**
119 * A construction helper for VclPtr. Since VclPtr types are created
120 * with a reference-count of one - to help fit into the existing
121 * code-flow; this helps us to construct them easily.
122 *
123 * For more details on the design please see vcl/README.lifecycle
124 *
125 * @tparam reference_type must be a subclass of vcl::Window
126 */
127 template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg)
128 {
129 return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE );
130 }
131
132 /** Probably most common used: handle->someBodyOp().
133 */
134 reference_type * operator->() const
135 {
136 return m_rInnerRef.get();
137 }
138
139 /** Get the body. Can be used instead of operator->().
140 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
141 are the same.
142 */
143 reference_type * get() const
144 {
145 return m_rInnerRef.get();
146 }
147
148 void set(reference_type *pBody)
149 {
150 m_rInnerRef.set(pBody);
151 }
152
153 void reset(reference_type *pBody)
154 {
155 m_rInnerRef.set(pBody);
156 }
157
158 /** Up-casting copy assignment operator.
159
160 Does not work for up-casts to ambiguous bases.
161
162 @param rRef another reference
163 */
164 template<typename derived_type>
165 typename std::enable_if<
166 std::is_base_of<reference_type, derived_type>::value,
167 VclPtr &>::type
168 operator =(VclPtr<derived_type> const & rRef)
169 {
170 m_rInnerRef.set(rRef.get());
171 return *this;
172 }
173
174 VclPtr & operator =(reference_type * pBody)
175 {
176 m_rInnerRef.set(pBody);
177 return *this;
178 }
179
180 operator reference_type * () const
181 {
182 return m_rInnerRef.get();
183 }
184
185 explicit operator bool () const
186 {
187 return m_rInnerRef.get() != nullptr;
188 }
189
190 void clear()
191 {
192 m_rInnerRef.clear();
193 }
194
195 void reset()
196 {
197 m_rInnerRef.clear();
198 }
199
200 void disposeAndClear()
201 {
202 // hold it alive for the lifetime of this method
203 ::rtl::Reference<reference_type> aTmp(m_rInnerRef);
204 m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
2
Calling 'Reference::clear'
9
Returning; memory was released
205 if (aTmp.get()) {
10
Calling 'Reference::get'
206 aTmp->disposeOnce();
207 }
208 }
209
210 /** Needed to place VclPtr's into STL collection.
211 */
212 bool operator< (const VclPtr<reference_type> & handle) const
213 {
214 return (m_rInnerRef < handle.m_rInnerRef);
215 }
216}; // class VclPtr
217
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
261 return !(p1 == p2);
262}
263
264/**
265 * A construction helper for a temporary VclPtr. Since VclPtr types
266 * are created with a reference-count of one - to help fit into
267 * the existing code-flow; this helps us to construct them easily.
268 * see also VclPtr::Create and ScopedVclPtr
269 *
270 * For more details on the design please see vcl/README.lifecycle
271 *
272 * @param reference_type must be a subclass of vcl::Window
273 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
278 template<typename... Arg> VclPtrInstance(Arg &&... arg)
279 : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
280 {
281 }
282
283 /**
284 * Override and disallow this, to prevent people accidentally calling it and actually
285 * getting VclPtr::Create and getting a naked VclPtr<> instance
286 */
287 template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete;
288};
289
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
294 /** Constructor...
295 */
296 ScopedVclPtr()
297 : VclPtr<reference_type>()
298 {}
299
300 /** Constructor
301 */
302 ScopedVclPtr (reference_type * pBody)
303 : VclPtr<reference_type>(pBody)
304 {}
305
306 /** Copy constructor...
307 */
308 ScopedVclPtr (const VclPtr<reference_type> & handle)
309 : VclPtr<reference_type>(handle)
310 {}
311
312 /**
313 Assignment that releases the last reference.
314 */
315 void disposeAndReset(reference_type *pBody)
316 {
317 if (pBody != this->get()) {
318 VclPtr<reference_type>::disposeAndClear();
319 VclPtr<reference_type>::set(pBody);
320 }
321 }
322
323 /**
324 Assignment that releases the last reference.
325 */
326 ScopedVclPtr<reference_type>& operator = (reference_type * pBody)
327 {
328 disposeAndReset(pBody);
329 return *this;
330 }
331
332 /** Up-casting conversion constructor: Copies interface reference.
333
334 Does not work for up-casts to ambiguous bases. For the special case of
335 up-casting to Reference< XInterface >, see the corresponding conversion
336 operator.
337
338 @param rRef another reference
339 */
340 template< class derived_type >
341 ScopedVclPtr(
342 const VclPtr< derived_type > & rRef,
343 typename std::enable_if<
344 std::is_base_of<reference_type, derived_type>::value, int>::type
345 = 0 )
346 : VclPtr<reference_type>( rRef )
347 {
348 }
349
350 /** Up-casting assignment operator.
351
352 Does not work for up-casts to ambiguous bases.
353
354 @param rRef another VclPtr
355 */
356 template<typename derived_type>
357 typename std::enable_if<
358 std::is_base_of<reference_type, derived_type>::value,
359 ScopedVclPtr &>::type
360 operator =(VclPtr<derived_type> const & rRef)
361 {
362 disposeAndReset(rRef.get());
363 return *this;
364 }
365
366 /**
367 * Override and disallow this, to prevent people accidentally calling it and actually
368 * getting VclPtr::Create and getting a naked VclPtr<> instance
369 */
370 template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete;
371
372 ~ScopedVclPtr()
373 {
374 VclPtr<reference_type>::disposeAndClear();
375 assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get(
) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // make sure there are no lingering references
376 }
377
378private:
379 // Most likely we don't want this default copy-constructor.
380 ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete;
381 // And certainly we don't want a default assignment operator.
382 ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete;
383 // And disallow reset as that doesn't call disposeAndClear on the original reference
384 void reset() = delete;
385 void reset(reference_type *pBody) = delete;
386
387protected:
388 ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
389 : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
390 {}
391};
392
393/**
394 * A construction helper for ScopedVclPtr. Since VclPtr types are created
395 * with a reference-count of one - to help fit into the existing
396 * code-flow; this helps us to construct them easily.
397 *
398 * For more details on the design please see vcl/README.lifecycle
399 *
400 * @param reference_type must be a subclass of vcl::Window
401 */
402#if defined _MSC_VER
403#pragma warning(push)
404#pragma warning(disable: 4521) // " multiple copy constructors specified"
405#endif
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
410 template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
411 : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
412 {
413 }
414
415 /**
416 * Override and disallow this, to prevent people accidentally calling it and actually
417 * getting VclPtr::Create and getting a naked VclPtr<> instance
418 */
419 template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete;
420
421private:
422 // Prevent the above perfect forwarding ctor from hijacking (accidental)
423 // attempts at ScopedVclPtrInstance copy construction (where the hijacking
424 // would typically lead to somewhat obscure error messages); both non-const
425 // and const variants are needed here, as the ScopedVclPtr base class has a
426 // const--variant copy ctor, so the implicitly declared copy ctor for
427 // ScopedVclPtrInstance would also be the const variant, so non-const copy
428 // construction attempts would be hijacked by the perfect forwarding ctor;
429 // but if we only declared a non-const variant here, the const variant would
430 // no longer be implicitly declared (as there would already be an explicitly
431 // declared copy ctor), so const copy construction attempts would then be
432 // hijacked by the perfect forwarding ctor:
433 ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete;
434 ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete;
435};
436#if defined _MSC_VER
437#pragma warning(pop)
438#endif
439
440#endif // INCLUDED_VCL_PTR_HXX
441
442/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/ref.hxx

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#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody)
113 m_pBody->release();
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody
2.1
Field 'm_pBody' is non-null
2.1
Field 'm_pBody' is non-null
2.1
Field 'm_pBody' is non-null
2.1
Field 'm_pBody' is non-null
)
3
Taking true branch
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
4
Calling 'VclReferenceBase::release'
8
Returning; memory was released
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
11
Use of memory after it is freed
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.hxx

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#ifndef INCLUDED_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
5
Assuming the condition is true
6
Taking true branch
40 delete this;
7
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif