LibreOffice Module reportdesign (master) 1
Navigator.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <Navigator.hxx>
21
22#include <strings.hxx>
23#include <bitmaps.hlst>
24#include <ReportController.hxx>
25#include <UITools.hxx>
26#include <reportformula.hxx>
27#include <com/sun/star/report/XFixedText.hpp>
28#include <com/sun/star/report/XFixedLine.hpp>
29#include <com/sun/star/report/XFormattedField.hpp>
30#include <com/sun/star/report/XImageControl.hpp>
31#include <com/sun/star/report/XShape.hpp>
32#include <helpids.h>
33#include <strings.hrc>
34#include <rptui_slotid.hrc>
40#include <utility>
41#include <vcl/svapp.hxx>
42#include <vcl/weld.hxx>
43#include <vcl/commandevent.hxx>
44#include <ReportVisitor.hxx>
45#include <core_resource.hxx>
46#include <rtl/ref.hxx>
47#include <svx/svxids.hrc>
48
49#include <memory>
50#include <string_view>
51
52namespace rptui
53{
54using namespace ::com::sun::star;
55using namespace utl;
56using namespace ::comphelper;
57
58static OUString lcl_getImageId(const uno::Reference< report::XReportComponent>& _xElement)
59{
60 OUString sId;
61 uno::Reference< report::XFixedLine> xFixedLine(_xElement,uno::UNO_QUERY);
62 if ( uno::Reference< report::XFixedText>(_xElement,uno::UNO_QUERY).is() )
63 sId = RID_SVXBMP_FM_FIXEDTEXT;
64 else if ( xFixedLine.is() )
65 sId = xFixedLine->getOrientation() ? OUString(RID_SVXBMP_INSERT_VFIXEDLINE) : OUString(RID_SVXBMP_INSERT_HFIXEDLINE);
66 else if ( uno::Reference< report::XFormattedField>(_xElement,uno::UNO_QUERY).is() )
67 sId = RID_SVXBMP_FM_EDIT;
68 else if ( uno::Reference< report::XImageControl>(_xElement,uno::UNO_QUERY).is() )
69 sId = RID_SVXBMP_FM_IMAGECONTROL;
70 else if ( uno::Reference< report::XShape>(_xElement,uno::UNO_QUERY).is() )
71 sId = RID_SVXBMP_DRAWTBX_CS_BASIC;
72 return sId;
73}
74
75static OUString lcl_getName(const uno::Reference< beans::XPropertySet>& _xElement)
76{
77 OSL_ENSURE(_xElement.is(),"Found report element which is NULL!");
78 OUString sTempName;
79 _xElement->getPropertyValue(PROPERTY_NAME) >>= sTempName;
80 OUStringBuffer sName(sTempName);
81 uno::Reference< report::XFixedText> xFixedText(_xElement,uno::UNO_QUERY);
82 uno::Reference< report::XReportControlModel> xReportModel(_xElement,uno::UNO_QUERY);
83 if ( xFixedText.is() )
84 {
85 sName.append(" : ");
86 sName.append(xFixedText->getLabel());
87 }
88 else if ( xReportModel.is() && _xElement->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATAFIELD) )
89 {
90 ReportFormula aFormula( xReportModel->getDataField() );
91 if ( aFormula.isValid() )
92 {
93 sName.append(" : ");
94 sName.append( aFormula.getUndecoratedContent() );
95 }
96 }
97 return sName.makeStringAndClear();
98}
99
104{
105 class UserData;
106 friend class UserData;
110 {
111 uno::Reference< uno::XInterface > m_xContent;
115 public:
116 UserData(NavigatorTree* pTree, uno::Reference<uno::XInterface> xContent);
117 virtual ~UserData() override;
118
119 const uno::Reference< uno::XInterface >& getContent() const { return m_xContent; }
120 void setContent(const uno::Reference< uno::XInterface >& _xContent) { m_xContent = _xContent; }
121
122 protected:
123 // OPropertyChangeListener
124 virtual void _propertyChanged(const beans::PropertyChangeEvent& _rEvent) override;
125
126 // OContainerListener
127 virtual void _elementInserted( const container::ContainerEvent& _rEvent ) override;
128 virtual void _elementRemoved( const container::ContainerEvent& Event ) override;
129 virtual void _elementReplaced( const container::ContainerEvent& _rEvent ) override;
130 virtual void _disposing(const lang::EventObject& _rSource) override;
131 };
132
133 std::unique_ptr<weld::TreeView> m_xTreeView;
135 std::unique_ptr<weld::TreeIter> m_xMasterReport;
138
139 void insertEntry(const OUString& rName, const weld::TreeIter* pParent, const OUString& rImageId, int nPosition, const UserData* pData, weld::TreeIter& rRet);
140
141 void traverseSection(const uno::Reference<report::XSection>& xSection, const weld::TreeIter* pParent, const OUString& rImageId, int nPosition = -1);
142 void traverseFunctions(const uno::Reference< report::XFunctions>& xFunctions, const weld::TreeIter* pParent);
143
144protected:
145 // OSelectionChangeListener
146 virtual void _disposing(const lang::EventObject& _rSource) override;
147
148 // OPropertyChangeListener
149 virtual void _propertyChanged(const beans::PropertyChangeEvent& _rEvent) override;
150
151 // OContainerListener Helper
152 void _elementInserted( const container::ContainerEvent& _rEvent );
153 void _elementRemoved( const container::ContainerEvent& Event );
154 void _elementReplaced( const container::ContainerEvent& _rEvent );
155
156public:
157 NavigatorTree(std::unique_ptr<weld::TreeView>, OReportController& rController);
158 virtual ~NavigatorTree() override;
159
160 DECL_LINK(OnEntrySelDesel, weld::TreeView&, void);
161 DECL_LINK(CommandHdl, const CommandEvent&, bool);
162
163 virtual void _selectionChanged( const lang::EventObject& aEvent ) override;
164
165 // ITraverseReport
166 virtual void traverseReport(const uno::Reference< report::XReportDefinition>& xReport) override;
167 virtual void traverseReportFunctions(const uno::Reference< report::XFunctions>& xFunctions) override;
168 virtual void traverseReportHeader(const uno::Reference< report::XSection>& xSection) override;
169 virtual void traverseReportFooter(const uno::Reference< report::XSection>& xSection) override;
170 virtual void traversePageHeader(const uno::Reference< report::XSection>& xSection) override;
171 virtual void traversePageFooter(const uno::Reference< report::XSection>& xSection) override;
172
173 virtual void traverseGroups(const uno::Reference< report::XGroups>& xGroups) override;
174 virtual void traverseGroup(const uno::Reference< report::XGroup>& xGroup) override;
175 virtual void traverseGroupFunctions(const uno::Reference< report::XFunctions>& xFunctions) override;
176 virtual void traverseGroupHeader(const uno::Reference< report::XSection>& xSection) override;
177 virtual void traverseGroupFooter(const uno::Reference< report::XSection>& xSection) override;
178
179 virtual void traverseDetail(const uno::Reference< report::XSection>& xSection) override;
180
181 bool find(const uno::Reference<uno::XInterface>& xContent, weld::TreeIter& rIter);
182 void removeEntry(const weld::TreeIter& rEntry, bool bRemove = true);
183
184 void grab_focus() { m_xTreeView->grab_focus(); }
185
186 void set_text(const weld::TreeIter& rIter, const OUString& rStr)
187 {
188 m_xTreeView->set_text(rIter, rStr);
189 }
190
191 void expand_row(const weld::TreeIter& rIter)
192 {
193 m_xTreeView->expand_row(rIter);
194 }
195
196 std::unique_ptr<weld::TreeIter> make_iterator() const
197 {
198 return m_xTreeView->make_iterator();
199 }
200
201 int iter_n_children(const weld::TreeIter& rIter) const
202 {
203 return m_xTreeView->iter_n_children(rIter);
204 }
205};
206
207NavigatorTree::NavigatorTree(std::unique_ptr<weld::TreeView> xTreeView, OReportController& rController)
209 , m_xTreeView(std::move(xTreeView))
210 , m_rController(rController)
211{
212 m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * 25, m_xTreeView->get_height_rows(18));
213
219
221
223
224 m_xTreeView->set_selection_mode(SelectionMode::Multiple);
225
226 m_xTreeView->connect_changed(LINK(this, NavigatorTree, OnEntrySelDesel));
227 m_xTreeView->connect_popup_menu(LINK(this, NavigatorTree, CommandHdl));
228}
229
231{
232 m_xTreeView->all_foreach([this](weld::TreeIter& rIter) {
233 UserData* pData = weld::fromId<UserData*>(m_xTreeView->get_id(rIter));
234 delete pData;
235 return false;
236 });
237 m_pSelectionListener->dispose();
238 m_pReportListener->dispose();
239}
240
241namespace
242{
243 sal_uInt16 mapIdent(std::string_view rIdent)
244 {
245 if (rIdent == "sorting")
246 return SID_SORTINGANDGROUPING;
247 else if (rIdent == "page")
248 return SID_PAGEHEADERFOOTER;
249 else if (rIdent == "report")
250 return SID_REPORTHEADERFOOTER;
251 else if (rIdent == "function")
252 return SID_RPT_NEW_FUNCTION;
253 else if (rIdent == "properties")
254 return SID_SHOW_PROPERTYBROWSER;
255 else if (rIdent == "delete")
256 return SID_DELETE;
257 return 0;
258 }
259}
260
261IMPL_LINK(NavigatorTree, CommandHdl, const CommandEvent&, rEvt, bool)
262{
263 bool bHandled = false;
264 switch( rEvt.GetCommand())
265 {
266 case CommandEventId::ContextMenu:
267 {
268 UserData* pData = weld::fromId<UserData*>(m_xTreeView->get_selected_id());
269 if (!pData)
270 break;
271
272 uno::Reference< report::XFunctionsSupplier> xSupplier(pData->getContent(),uno::UNO_QUERY);
273 uno::Reference< report::XFunctions> xFunctions(pData->getContent(),uno::UNO_QUERY);
274 uno::Reference< report::XGroup> xGroup(pData->getContent(),uno::UNO_QUERY);
275 bool bDeleteAllowed = m_rController.isEditable() && (xGroup.is() ||
276 uno::Reference< report::XFunction>(pData->getContent(),uno::UNO_QUERY).is());
277
278 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xTreeView.get(), "modules/dbreport/ui/navigatormenu.ui"));
279 std::unique_ptr<weld::Menu> xContextMenu(xBuilder->weld_menu("menu"));
280
281 const OString aIds[] = { "sorting", "page", "report", "function", "properties", "delete" };
282 for (size_t i = 0; i < SAL_N_ELEMENTS(aIds); ++i)
283 {
284 sal_uInt16 nSId = mapIdent(aIds[i]);
285
286 if (aIds[i] == "page" || aIds[i] == "report" || aIds[i] == "properties")
287 xContextMenu->set_active(aIds[i], m_rController.isCommandChecked(nSId));
288 bool bEnabled = m_rController.isCommandEnabled(nSId);
289 if (nSId == SID_RPT_NEW_FUNCTION)
290 xContextMenu->set_sensitive(aIds[i], m_rController.isEditable() && (xSupplier.is() || xFunctions.is()));
291 // special condition, check for function and group
292 else if (nSId == SID_DELETE)
293 xContextMenu->set_sensitive(aIds[i], bDeleteAllowed);
294 else
295 xContextMenu->set_sensitive(aIds[i], bEnabled);
296 }
297
298 // the point that was clicked on
299 ::Point aWhere(rEvt.GetMousePosPixel());
300 OString sCurItemIdent = xContextMenu->popup_at_rect(m_xTreeView.get(), tools::Rectangle(aWhere, Size(1,1)));
301 if (!sCurItemIdent.isEmpty())
302 {
303 sal_uInt16 nId = mapIdent(sCurItemIdent);
304 uno::Sequence< beans::PropertyValue> aArgs;
305 if ( nId == SID_RPT_NEW_FUNCTION )
306 {
307 aArgs.realloc(1);
308 aArgs.getArray()[0].Value <<= (xFunctions.is() ? xFunctions : xSupplier->getFunctions());
309 }
310 else if ( nId == SID_DELETE )
311 {
312 if ( xGroup.is() )
313 nId = SID_GROUP_REMOVE;
314 aArgs = { comphelper::makePropertyValue(PROPERTY_GROUP, pData->getContent()) };
315 }
316 m_rController.executeUnChecked(nId,aArgs);
317 }
318
319 bHandled = true;
320 }
321 break;
322 default: break;
323 }
324
325 return bHandled;
326}
327
329{
330 if ( !m_pSelectionListener->locked() )
331 {
332 m_pSelectionListener->lock();
333 std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
334 bool bEntry = m_xTreeView->get_cursor(xEntry.get());
335 uno::Any aSelection;
336 if (bEntry && m_xTreeView->is_selected(*xEntry))
337 aSelection <<= weld::fromId<UserData*>(m_xTreeView->get_id(*xEntry))->getContent();
338 m_rController.select(aSelection);
339 m_pSelectionListener->unlock();
340 }
341}
342
343void NavigatorTree::_selectionChanged( const lang::EventObject& aEvent )
344{
345 m_pSelectionListener->lock();
346 uno::Reference< view::XSelectionSupplier> xSelectionSupplier(aEvent.Source,uno::UNO_QUERY);
347 uno::Any aSec = xSelectionSupplier->getSelection();
348 uno::Sequence< uno::Reference< report::XReportComponent > > aSelection;
349 aSec >>= aSelection;
350 std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
351 if ( !aSelection.hasElements() )
352 {
353 uno::Reference< uno::XInterface> xSelection(aSec,uno::UNO_QUERY);
354 bool bEntry = find(xSelection, *xEntry);
355 if (bEntry && !m_xTreeView->is_selected(*xEntry))
356 {
357 m_xTreeView->select(*xEntry);
358 m_xTreeView->set_cursor(*xEntry);
359 }
360 else if (!bEntry)
361 m_xTreeView->unselect_all();
362 }
363 else
364 {
365 for (const uno::Reference<report::XReportComponent>& rElem : std::as_const(aSelection))
366 {
367 bool bEntry = find(rElem, *xEntry);
368 if (bEntry && !m_xTreeView->is_selected(*xEntry))
369 {
370 m_xTreeView->select(*xEntry);
371 m_xTreeView->set_cursor(*xEntry);
372 }
373 }
374 }
375 m_pSelectionListener->unlock();
376}
377
378void NavigatorTree::insertEntry(const OUString& rName, const weld::TreeIter* pParent, const OUString& rImageId,
379 int nPosition, const UserData* pData, weld::TreeIter& rRet)
380{
381 OUString sId = pData ? weld::toId(pData) : OUString();
382 m_xTreeView->insert(pParent, nPosition, &rName, &sId, nullptr, nullptr, false, &rRet);
383 if (!rImageId.isEmpty())
384 m_xTreeView->set_image(rRet, rImageId);
385}
386
387void NavigatorTree::traverseSection(const uno::Reference<report::XSection>& xSection, const weld::TreeIter* pParent, const OUString& rImageId, int nPosition)
388{
389 std::unique_ptr<weld::TreeIter> xSectionIter = m_xTreeView->make_iterator();
390 std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator();
391 insertEntry(xSection->getName(), pParent, rImageId, nPosition, new UserData(this, xSection), *xSectionIter);
392 const sal_Int32 nCount = xSection->getCount();
393 for (sal_Int32 i = 0; i < nCount; ++i)
394 {
395 uno::Reference< report::XReportComponent> xElement(xSection->getByIndex(i), uno::UNO_QUERY_THROW);
396 insertEntry(lcl_getName(xElement), xSectionIter.get(), lcl_getImageId(xElement), -1, new UserData(this, xElement), *xScratch);
397 uno::Reference< report::XReportDefinition> xSubReport(xElement,uno::UNO_QUERY);
398 if ( xSubReport.is() )
399 {
400 bool bMasterReport = find(xSection->getReportDefinition(), *xScratch);
401 if (!bMasterReport)
402 m_xMasterReport.reset();
403 else
404 m_xMasterReport = m_xTreeView->make_iterator(xScratch.get());
405 reportdesign::OReportVisitor aSubVisitor(this);
406 aSubVisitor.start(xSubReport);
407 }
408 }
409}
410
411void NavigatorTree::traverseFunctions(const uno::Reference< report::XFunctions>& xFunctions, const weld::TreeIter* pParent)
412{
413 std::unique_ptr<weld::TreeIter> xFunctionIter = m_xTreeView->make_iterator();
414 std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator();
415 insertEntry(RptResId(RID_STR_FUNCTIONS), pParent, RID_SVXBMP_RPT_NEW_FUNCTION, -1, new UserData(this, xFunctions), *xFunctionIter);
416 const sal_Int32 nCount = xFunctions->getCount();
417 for (sal_Int32 i = 0; i< nCount; ++i)
418 {
419 uno::Reference< report::XFunction> xElement(xFunctions->getByIndex(i),uno::UNO_QUERY);
420 insertEntry(xElement->getName(), xFunctionIter.get(), RID_SVXBMP_RPT_NEW_FUNCTION, -1, new UserData(this,xElement), *xScratch);
421 }
422}
423
424bool NavigatorTree::find(const uno::Reference<uno::XInterface>& xContent, weld::TreeIter& rRet)
425{
426 bool bRet = false;
427 if (xContent.is())
428 {
429 m_xTreeView->all_foreach([this, &xContent, &bRet, &rRet](weld::TreeIter& rIter) {
430 UserData* pData = weld::fromId<UserData*>(m_xTreeView->get_id(rIter));
431 if (pData->getContent() == xContent)
432 {
433 m_xTreeView->copy_iterator(rIter, rRet);
434 bRet = true;
435 return true;
436 }
437 return false;
438 });
439 }
440 return bRet;
441}
442
443// ITraverseReport
444
445void NavigatorTree::traverseReport(const uno::Reference< report::XReportDefinition>& xReport)
446{
447 std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator();
448 insertEntry(xReport->getName(), m_xMasterReport.get(), RID_SVXBMP_SELECT_REPORT,-1, new UserData(this, xReport), *xScratch);
449}
450
451void NavigatorTree::traverseReportFunctions(const uno::Reference< report::XFunctions>& xFunctions)
452{
453 std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
454 bool bReport = find(xFunctions->getParent(), *xReport);
455 if (!bReport)
456 xReport.reset();
457 traverseFunctions(xFunctions, xReport.get());
458}
459
460void NavigatorTree::traverseReportHeader(const uno::Reference< report::XSection>& xSection)
461{
462 std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
463 bool bReport = find(xSection->getReportDefinition(), *xReport);
464 if (!bReport)
465 xReport.reset();
466 traverseSection(xSection, xReport.get(), RID_SVXBMP_REPORTHEADERFOOTER);
467}
468
469void NavigatorTree::traverseReportFooter(const uno::Reference< report::XSection>& xSection)
470{
471 std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
472 bool bReport = find(xSection->getReportDefinition(), *xReport);
473 if (!bReport)
474 xReport.reset();
475 traverseSection(xSection, xReport.get(), RID_SVXBMP_REPORTHEADERFOOTER);
476}
477
478void NavigatorTree::traversePageHeader(const uno::Reference< report::XSection>& xSection)
479{
480 std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
481 bool bReport = find(xSection->getReportDefinition(), *xReport);
482 if (!bReport)
483 xReport.reset();
484 traverseSection(xSection, xReport.get(), RID_SVXBMP_PAGEHEADERFOOTER);
485}
486
487void NavigatorTree::traversePageFooter(const uno::Reference< report::XSection>& xSection)
488{
489 std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
490 bool bReport = find(xSection->getReportDefinition(), *xReport);
491 if (!bReport)
492 xReport.reset();
493 traverseSection(xSection, xReport.get(), RID_SVXBMP_PAGEHEADERFOOTER);
494}
495
496void NavigatorTree::traverseGroups(const uno::Reference< report::XGroups>& xGroups)
497{
498 std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
499 bool bReport = find(xGroups->getReportDefinition(), *xReport);
500 if (!bReport)
501 xReport.reset();
502 std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator();
503 insertEntry(RptResId(RID_STR_GROUPS), xReport.get(), RID_SVXBMP_SORTINGANDGROUPING, -1, new UserData(this, xGroups), *xScratch);
504}
505
506void NavigatorTree::traverseGroup(const uno::Reference< report::XGroup>& xGroup)
507{
508 uno::Reference< report::XGroups> xGroups(xGroup->getParent(),uno::UNO_QUERY);
509 std::unique_ptr<weld::TreeIter> xGroupsIter = m_xTreeView->make_iterator();
510 bool bGroups = find(xGroups, *xGroupsIter);
511 OSL_ENSURE(bGroups, "No Groups inserted so far. Why!");
512 if (!bGroups)
513 xGroupsIter.reset();
514 std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator();
515 insertEntry(xGroup->getExpression(), xGroupsIter.get(), RID_SVXBMP_GROUP, rptui::getPositionInIndexAccess(xGroups,xGroup), new UserData(this,xGroup), *xScratch);
516}
517
518void NavigatorTree::traverseGroupFunctions(const uno::Reference< report::XFunctions>& xFunctions)
519{
520 std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
521 bool bReport = find(xFunctions->getParent(), *xReport);
522 if (!bReport)
523 xReport.reset();
524 traverseFunctions(xFunctions, xReport.get());
525}
526
527void NavigatorTree::traverseGroupHeader(const uno::Reference< report::XSection>& xSection)
528{
529 std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
530 bool bReport = find(xSection->getGroup(), *xReport);
531 OSL_ENSURE(bReport, "No group found");
532 if (!bReport)
533 xReport.reset();
534 traverseSection(xSection, xReport.get(), RID_SVXBMP_GROUPHEADER, 1);
535}
536
537void NavigatorTree::traverseGroupFooter(const uno::Reference< report::XSection>& xSection)
538{
539 std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
540 bool bReport = find(xSection->getGroup(), *xReport);
541 OSL_ENSURE(bReport, "No group found");
542 if (!bReport)
543 xReport.reset();
544 traverseSection(xSection, xReport.get(), RID_SVXBMP_GROUPFOOTER);
545}
546
547void NavigatorTree::traverseDetail(const uno::Reference< report::XSection>& xSection)
548{
549 uno::Reference< report::XReportDefinition> xReport = xSection->getReportDefinition();
550 std::unique_ptr<weld::TreeIter> xParent = m_xTreeView->make_iterator();
551 bool bParent = find(xReport, *xParent);
552 if (!bParent)
553 xParent.reset();
554 traverseSection(xSection, xParent.get(), RID_SVXBMP_ICON_DETAIL);
555}
556
557void NavigatorTree::_propertyChanged(const beans::PropertyChangeEvent& _rEvent)
558{
559 uno::Reference< report::XReportDefinition> xReport(_rEvent.Source,uno::UNO_QUERY);
560 if ( !xReport.is() )
561 return;
562
563 bool bEnabled = false;
564 _rEvent.NewValue >>= bEnabled;
565 if ( !bEnabled )
566 return;
567
568 std::unique_ptr<weld::TreeIter> xParent = m_xTreeView->make_iterator();
569 bool bParent = find(xReport, *xParent);
570 if (!bParent)
571 xParent.reset();
572 if ( _rEvent.PropertyName == PROPERTY_REPORTHEADERON )
573 {
574 sal_uLong nPos = xReport->getReportHeaderOn() ? 2 : 1;
575 traverseSection(xReport->getReportHeader(),xParent.get(),RID_SVXBMP_REPORTHEADERFOOTER,nPos);
576 }
577 else if ( _rEvent.PropertyName == PROPERTY_PAGEHEADERON )
578 {
579 traverseSection(xReport->getPageHeader(),xParent.get(), RID_SVXBMP_PAGEHEADERFOOTER,1);
580 }
581 else if ( _rEvent.PropertyName == PROPERTY_PAGEFOOTERON )
582 traverseSection(xReport->getPageFooter(),xParent.get(), RID_SVXBMP_PAGEHEADERFOOTER);
583 else if ( _rEvent.PropertyName == PROPERTY_REPORTFOOTERON )
584 {
585 int nPos = -1;
586 if (xReport->getPageFooterOn() && xParent)
587 nPos = m_xTreeView->iter_n_children(*xParent) - 1;
588 traverseSection(xReport->getReportFooter(),xParent.get(),RID_SVXBMP_REPORTHEADERFOOTER,nPos);
589 }
590}
591
592void NavigatorTree::_elementInserted( const container::ContainerEvent& _rEvent )
593{
594 std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
595 bool bEntry = find(_rEvent.Source, *xEntry);
596 if (!bEntry)
597 xEntry.reset();
598 uno::Reference<beans::XPropertySet> xProp(_rEvent.Element,uno::UNO_QUERY_THROW);
599 OUString sName;
600 uno::Reference< beans::XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
601 if ( xInfo.is() )
602 {
603 if ( xInfo->hasPropertyByName(PROPERTY_NAME) )
604 xProp->getPropertyValue(PROPERTY_NAME) >>= sName;
605 else if ( xInfo->hasPropertyByName(PROPERTY_EXPRESSION) )
606 xProp->getPropertyValue(PROPERTY_EXPRESSION) >>= sName;
607 }
608 uno::Reference< report::XGroup> xGroup(xProp,uno::UNO_QUERY);
609 if ( xGroup.is() )
610 {
611 reportdesign::OReportVisitor aSubVisitor(this);
612 aSubVisitor.start(xGroup);
613 }
614 else
615 {
616 uno::Reference< report::XReportComponent> xElement(xProp,uno::UNO_QUERY);
617 if ( xProp.is() )
618 sName = lcl_getName(xProp);
619 std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator();
620 insertEntry(sName, xEntry.get(), (!xElement.is() ? OUString(RID_SVXBMP_RPT_NEW_FUNCTION) : lcl_getImageId(xElement)),
621 -1, new UserData(this,xProp), *xScratch);
622 }
623 if (bEntry && !m_xTreeView->get_row_expanded(*xEntry))
624 m_xTreeView->expand_row(*xEntry);
625}
626
627void NavigatorTree::_elementRemoved( const container::ContainerEvent& _rEvent )
628{
629 uno::Reference<beans::XPropertySet> xProp(_rEvent.Element,uno::UNO_QUERY);
630 std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
631 bool bEntry = find(xProp, *xEntry);
632 OSL_ENSURE(bEntry,"NavigatorTree::_elementRemoved: No Entry found!");
633
634 if (bEntry)
635 {
636 removeEntry(*xEntry);
637 }
638}
639
640void NavigatorTree::_elementReplaced( const container::ContainerEvent& _rEvent )
641{
642 uno::Reference<beans::XPropertySet> xProp(_rEvent.ReplacedElement,uno::UNO_QUERY);
643 std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
644 bool bEntry = find(xProp, *xEntry);
645 if (bEntry)
646 {
647 UserData* pData = weld::fromId<UserData*>(m_xTreeView->get_id(*xEntry));
648 xProp.set(_rEvent.Element,uno::UNO_QUERY);
649 pData->setContent(xProp);
650 OUString sName;
651 xProp->getPropertyValue(PROPERTY_NAME) >>= sName;
652 m_xTreeView->set_text(*xEntry, sName);
653 }
654}
655
656void NavigatorTree::_disposing(const lang::EventObject& _rSource)
657{
658 std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
659 if (find(_rSource.Source, *xEntry))
660 removeEntry(*xEntry);
661}
662
663void NavigatorTree::removeEntry(const weld::TreeIter& rEntry, bool bRemove)
664{
665 std::unique_ptr<weld::TreeIter> xChild = m_xTreeView->make_iterator(&rEntry);
666 bool bChild = m_xTreeView->iter_children(*xChild);
667 while (bChild)
668 {
669 removeEntry(*xChild, false);
670 bChild = m_xTreeView->iter_next_sibling(*xChild);
671 }
672 delete weld::fromId<UserData*>(m_xTreeView->get_id(rEntry));
673 if (bRemove)
674 m_xTreeView->remove(rEntry);
675}
676
677NavigatorTree::UserData::UserData(NavigatorTree* pTree,uno::Reference<uno::XInterface> xContent)
680 , m_xContent(std::move(xContent))
681 , m_pTree(pTree)
682{
683 uno::Reference<beans::XPropertySet> xProp(m_xContent,uno::UNO_QUERY);
684 if ( xProp.is() )
685 {
686 uno::Reference< beans::XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
687 if ( xInfo.is() )
688 {
689 m_pListener = new ::comphelper::OPropertyChangeMultiplexer(this,xProp);
690 if ( xInfo->hasPropertyByName(PROPERTY_NAME) )
691 m_pListener->addProperty(PROPERTY_NAME);
692 else if ( xInfo->hasPropertyByName(PROPERTY_EXPRESSION) )
693 m_pListener->addProperty(PROPERTY_EXPRESSION);
694 if ( xInfo->hasPropertyByName(PROPERTY_DATAFIELD) )
695 m_pListener->addProperty(PROPERTY_DATAFIELD);
696 if ( xInfo->hasPropertyByName(PROPERTY_LABEL) )
697 m_pListener->addProperty(PROPERTY_LABEL);
698 if ( xInfo->hasPropertyByName(PROPERTY_HEADERON) )
699 m_pListener->addProperty(PROPERTY_HEADERON);
700 if ( xInfo->hasPropertyByName(PROPERTY_FOOTERON) )
701 m_pListener->addProperty(PROPERTY_FOOTERON);
702 }
703 }
704 uno::Reference< container::XContainer> xContainer(m_xContent,uno::UNO_QUERY);
705 if ( xContainer.is() )
706 {
707 m_pContainerListener = new ::comphelper::OContainerListenerAdapter(this,xContainer);
708 }
709}
710
712{
713 if ( m_pContainerListener.is() )
714 m_pContainerListener->dispose();
715 if ( m_pListener.is() )
716 m_pListener->dispose();
717}
718
719// OPropertyChangeListener
720void NavigatorTree::UserData::_propertyChanged(const beans::PropertyChangeEvent& _rEvent)
721{
722 std::unique_ptr<weld::TreeIter> xEntry = m_pTree->make_iterator();
723 bool bEntry = m_pTree->find(_rEvent.Source, *xEntry);
724 OSL_ENSURE(bEntry,"No entry could be found! Why not!");
725 if (!bEntry)
726 return;
727 const bool bFooterOn = (PROPERTY_FOOTERON == _rEvent.PropertyName);
728 try
729 {
730 if ( bFooterOn || PROPERTY_HEADERON == _rEvent.PropertyName )
731 {
732 sal_Int32 nPos = 1;
733 uno::Reference< report::XGroup> xGroup(_rEvent.Source,uno::UNO_QUERY);
734 ::std::function<bool(OGroupHelper *)> pIsOn = ::std::mem_fn(&OGroupHelper::getHeaderOn);
735 ::std::function<uno::Reference<report::XSection>(OGroupHelper *)> pMemFunSection = ::std::mem_fn(&OGroupHelper::getHeader);
736 if ( bFooterOn )
737 {
738 pIsOn = ::std::mem_fn(&OGroupHelper::getFooterOn);
739 pMemFunSection = ::std::mem_fn(&OGroupHelper::getFooter);
740 nPos = m_pTree->iter_n_children(*xEntry) - 1;
741 }
742
743 OGroupHelper aGroupHelper(xGroup);
744 if ( pIsOn(&aGroupHelper) )
745 {
746 if ( bFooterOn )
747 ++nPos;
748 m_pTree->traverseSection(pMemFunSection(&aGroupHelper),xEntry.get(),bFooterOn ? OUString(RID_SVXBMP_GROUPFOOTER) : OUString(RID_SVXBMP_GROUPHEADER),nPos);
749 }
750 }
751 else if ( PROPERTY_EXPRESSION == _rEvent.PropertyName)
752 {
753 OUString sNewName;
754 _rEvent.NewValue >>= sNewName;
755 m_pTree->set_text(*xEntry, sNewName);
756 }
757 else if ( PROPERTY_DATAFIELD == _rEvent.PropertyName || PROPERTY_LABEL == _rEvent.PropertyName || PROPERTY_NAME == _rEvent.PropertyName )
758 {
759 uno::Reference<beans::XPropertySet> xProp(_rEvent.Source,uno::UNO_QUERY);
760 m_pTree->set_text(*xEntry, lcl_getName(xProp));
761 }
762 }
763 catch(const uno::Exception &)
764 {}
765}
766
767void NavigatorTree::UserData::_elementInserted( const container::ContainerEvent& _rEvent )
768{
769 m_pTree->_elementInserted( _rEvent );
770}
771
772void NavigatorTree::UserData::_elementRemoved( const container::ContainerEvent& _rEvent )
773{
774 m_pTree->_elementRemoved( _rEvent );
775}
776
777void NavigatorTree::UserData::_elementReplaced( const container::ContainerEvent& _rEvent )
778{
779 m_pTree->_elementReplaced( _rEvent );
780}
781
782void NavigatorTree::UserData::_disposing(const lang::EventObject& _rSource)
783{
784 m_pTree->_disposing( _rSource );
785}
786
788 : GenericDialogController(pParent, "modules/dbreport/ui/floatingnavigator.ui", "FloatingNavigator")
789 , m_xReport(rController.getReportDefinition())
790 , m_xNavigatorTree(std::make_unique<NavigatorTree>(m_xBuilder->weld_tree_view("treeview"), rController))
791{
793 aVisitor.start(m_xReport);
794 std::unique_ptr<weld::TreeIter> xScratch = m_xNavigatorTree->make_iterator();
795 if (m_xNavigatorTree->find(m_xReport, *xScratch))
796 m_xNavigatorTree->expand_row(*xScratch);
797 lang::EventObject aEvent(rController);
798 m_xNavigatorTree->_selectionChanged(aEvent);
799 m_xNavigatorTree->grab_focus();
800
801 m_xDialog->connect_container_focus_changed(LINK(this, ONavigator, FocusChangeHdl));
802}
803
805{
806}
807
809{
810 if (m_xDialog->has_toplevel_focus())
811 m_xNavigatorTree->grab_focus();
812}
813
814} // rptui
815
816/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
uno::Reference< ucb::XContent > m_xContent
Reference< XExecutableDialog > m_xDialog
AnyEventRef aEvent
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
friend friend class OPropertyChangeMultiplexer
friend friend class OSelectionChangeMultiplexer
ClassificationCategoriesController & m_rController
void start(const css::uno::Reference< css::report::XReportDefinition > &_xReportDefinition)
::rtl::Reference< comphelper::OContainerListenerAdapter > m_pContainerListener
Definition: Navigator.cxx:113
virtual void _propertyChanged(const beans::PropertyChangeEvent &_rEvent) override
Definition: Navigator.cxx:720
virtual void _elementRemoved(const container::ContainerEvent &Event) override
Definition: Navigator.cxx:772
virtual void _disposing(const lang::EventObject &_rSource) override
Definition: Navigator.cxx:782
::rtl::Reference< comphelper::OPropertyChangeMultiplexer > m_pListener
Definition: Navigator.cxx:112
uno::Reference< uno::XInterface > m_xContent
Definition: Navigator.cxx:111
virtual void _elementInserted(const container::ContainerEvent &_rEvent) override
Definition: Navigator.cxx:767
UserData(NavigatorTree *pTree, uno::Reference< uno::XInterface > xContent)
Definition: Navigator.cxx:677
const uno::Reference< uno::XInterface > & getContent() const
Definition: Navigator.cxx:119
virtual ~UserData() override
Definition: Navigator.cxx:711
void setContent(const uno::Reference< uno::XInterface > &_xContent)
Definition: Navigator.cxx:120
virtual void _elementReplaced(const container::ContainerEvent &_rEvent) override
Definition: Navigator.cxx:777
NavigatorTree(std::unique_ptr< weld::TreeView >, OReportController &rController)
Definition: Navigator.cxx:207
virtual void traverseReportHeader(const uno::Reference< report::XSection > &xSection) override
Definition: Navigator.cxx:460
void removeEntry(const weld::TreeIter &rEntry, bool bRemove=true)
Definition: Navigator.cxx:663
void _elementReplaced(const container::ContainerEvent &_rEvent)
Definition: Navigator.cxx:640
virtual void traverseGroupFunctions(const uno::Reference< report::XFunctions > &xFunctions) override
Definition: Navigator.cxx:518
int iter_n_children(const weld::TreeIter &rIter) const
Definition: Navigator.cxx:201
void _elementInserted(const container::ContainerEvent &_rEvent)
Definition: Navigator.cxx:592
DECL_LINK(CommandHdl, const CommandEvent &, bool)
virtual void traverseGroups(const uno::Reference< report::XGroups > &xGroups) override
Definition: Navigator.cxx:496
virtual void _propertyChanged(const beans::PropertyChangeEvent &_rEvent) override
Definition: Navigator.cxx:557
void traverseSection(const uno::Reference< report::XSection > &xSection, const weld::TreeIter *pParent, const OUString &rImageId, int nPosition=-1)
Definition: Navigator.cxx:387
std::unique_ptr< weld::TreeIter > m_xMasterReport
Definition: Navigator.cxx:135
std::unique_ptr< weld::TreeIter > make_iterator() const
Definition: Navigator.cxx:196
bool find(const uno::Reference< uno::XInterface > &xContent, weld::TreeIter &rIter)
Definition: Navigator.cxx:424
virtual void _disposing(const lang::EventObject &_rSource) override
Definition: Navigator.cxx:656
void traverseFunctions(const uno::Reference< report::XFunctions > &xFunctions, const weld::TreeIter *pParent)
Definition: Navigator.cxx:411
virtual void traverseReportFunctions(const uno::Reference< report::XFunctions > &xFunctions) override
Definition: Navigator.cxx:451
::rtl::Reference< comphelper::OSelectionChangeMultiplexer > m_pSelectionListener
Definition: Navigator.cxx:137
void _elementRemoved(const container::ContainerEvent &Event)
Definition: Navigator.cxx:627
void set_text(const weld::TreeIter &rIter, const OUString &rStr)
Definition: Navigator.cxx:186
virtual void traversePageFooter(const uno::Reference< report::XSection > &xSection) override
Definition: Navigator.cxx:487
virtual void traverseGroup(const uno::Reference< report::XGroup > &xGroup) override
Definition: Navigator.cxx:506
virtual void traverseReport(const uno::Reference< report::XReportDefinition > &xReport) override
Definition: Navigator.cxx:445
virtual ~NavigatorTree() override
Definition: Navigator.cxx:230
virtual void traverseReportFooter(const uno::Reference< report::XSection > &xSection) override
Definition: Navigator.cxx:469
std::unique_ptr< weld::TreeView > m_xTreeView
Definition: Navigator.cxx:133
virtual void _selectionChanged(const lang::EventObject &aEvent) override
Definition: Navigator.cxx:343
virtual void traverseDetail(const uno::Reference< report::XSection > &xSection) override
Definition: Navigator.cxx:547
OReportController & m_rController
Definition: Navigator.cxx:134
void insertEntry(const OUString &rName, const weld::TreeIter *pParent, const OUString &rImageId, int nPosition, const UserData *pData, weld::TreeIter &rRet)
Definition: Navigator.cxx:378
virtual void traverseGroupHeader(const uno::Reference< report::XSection > &xSection) override
Definition: Navigator.cxx:527
virtual void traverseGroupFooter(const uno::Reference< report::XSection > &xSection) override
Definition: Navigator.cxx:537
DECL_LINK(OnEntrySelDesel, weld::TreeView &, void)
friend class UserData
Definition: Navigator.cxx:105
virtual void traversePageHeader(const uno::Reference< report::XSection > &xSection) override
Definition: Navigator.cxx:478
::rtl::Reference< comphelper::OPropertyChangeMultiplexer > m_pReportListener
Definition: Navigator.cxx:136
void expand_row(const weld::TreeIter &rIter)
Definition: Navigator.cxx:191
Helper class to allow std::mem_fun for SAL_CALL.
Definition: UndoActions.hxx:49
css::uno::Reference< css::report::XSection > getHeader()
Definition: UndoActions.hxx:58
css::uno::Reference< css::report::XSection > getFooter()
Definition: UndoActions.hxx:59
std::unique_ptr< NavigatorTree > m_xNavigatorTree
Definition: Navigator.hxx:33
css::uno::Reference< css::report::XReportDefinition > m_xReport
Definition: Navigator.hxx:32
ONavigator(const ONavigator &)=delete
const css::uno::Reference< css::report::XReportDefinition > & getReportDefinition() const
gives access to the report definition
bool isValid() const
returns whether the object denotes a valid formula
const OUString & getUndecoratedContent() const
gets the undecorated formula content
std::shared_ptr< weld::Dialog > m_xDialog
OUString RptResId(TranslateId aId)
int nCount
constexpr OStringLiteral HID_REPORT_NAVIGATOR_TREE
Definition: helpids.h:77
std::mutex m_aMutex
sal_uInt16 nPos
#define SAL_N_ELEMENTS(arr)
std::unique_ptr< sal_Int32[]> pData
const char * sName
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
int i
static OUString lcl_getName(const uno::Reference< beans::XPropertySet > &_xElement)
Definition: Navigator.cxx:75
static OUString lcl_getImageId(const uno::Reference< report::XReportComponent > &_xElement)
Definition: Navigator.cxx:58
IMPL_LINK_NOARG(OAddFieldWindow, FocusChangeHdl, weld::Container &, void)
Definition: AddField.cxx:120
sal_Int32 getPositionInIndexAccess(const css::uno::Reference< css::container::XIndexAccess > &_xCollection, const css::uno::Reference< T > &_xSearch)
returns the position of the object inside the index container
Definition: UITools.hxx:52
IMPL_LINK(OAddFieldWindow, DragBeginHdl, bool &, rUnsetDragIcon, bool)
Definition: AddField.cxx:50
OUString toId(const void *pValue)
sal_Int16 nId
sal_uIntPtr sal_uLong
constexpr OUStringLiteral PROPERTY_EXPRESSION
Definition: strings.hxx:52
constexpr OUStringLiteral PROPERTY_REPORTHEADERON
Definition: strings.hxx:67
constexpr OUStringLiteral PROPERTY_LABEL
Definition: strings.hxx:89
constexpr OUStringLiteral PROPERTY_NAME
Definition: strings.hxx:36
constexpr OUStringLiteral PROPERTY_PAGEFOOTERON
Definition: strings.hxx:70
constexpr OUStringLiteral PROPERTY_GROUP
Definition: strings.hxx:48
constexpr OUStringLiteral PROPERTY_PAGEHEADERON
Definition: strings.hxx:69
constexpr OUStringLiteral PROPERTY_DATAFIELD
Definition: strings.hxx:78
constexpr OUStringLiteral PROPERTY_REPORTFOOTERON
Definition: strings.hxx:68
constexpr OUStringLiteral PROPERTY_HEADERON
Definition: strings.hxx:71
constexpr OUStringLiteral PROPERTY_FOOTERON
Definition: strings.hxx:72
OUString sId