LibreOffice Module svl (master) 1
lstner.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 <svl/lstner.hxx>
21
23#include <sal/backtrace.hxx>
24#include <sal/log.hxx>
25
26#include <algorithm>
27#include <cassert>
28#include <vector>
29#include <memory>
30
31// copy ctor of class SfxListener
32
34 : maBCs( rOther.maBCs )
35{
36 for ( size_t n = 0; n < maBCs.size(); ++n )
37 {
38 maBCs[n]->AddListener(*this);
39#ifdef DBG_UTIL
40 maCallStacks.emplace( maBCs[n], sal::backtrace_get(10) );
41#endif
42 }
43}
44
45// unregisters the SfxListener from its SfxBroadcasters
46
47SfxListener::~SfxListener() COVERITY_NOEXCEPT_FALSE
48{
49 // unregister at all remaining broadcasters
50 for ( size_t nPos = 0; nPos < maBCs.size(); ++nPos )
51 {
53 pBC->RemoveListener(*this);
54 }
55}
56
57
58// unregisters a specific SfxBroadcaster
59
61{
62 auto it = std::find( maBCs.begin(), maBCs.end(), &rBroadcaster );
63 if (it != maBCs.end()) {
64 maBCs.erase( it );
65#ifdef DBG_UTIL
66 maCallStacks.erase( &rBroadcaster );
67#endif
68 }
69}
70
71
72
79void SfxListener::StartListening(SfxBroadcaster& rBroadcaster, DuplicateHandling eDuplicateHanding)
80{
81 bool bListeningAlready = IsListening( rBroadcaster );
82
83#ifdef DBG_UTIL
84 if (bListeningAlready && eDuplicateHanding == DuplicateHandling::Unexpected)
85 {
86 auto f = maCallStacks.find( &rBroadcaster );
87 SAL_WARN("svl", "previous StartListening call came from: " << sal::backtrace_to_string(f->second.get()));
88 }
89#endif
90 assert(!(bListeningAlready && eDuplicateHanding == DuplicateHandling::Unexpected) && "duplicate listener, try building with DBG_UTIL to find the other insert site.");
91
92 if (!bListeningAlready || eDuplicateHanding != DuplicateHandling::Prevent)
93 {
94 rBroadcaster.AddListener(*this);
95 maBCs.push_back( &rBroadcaster );
96#ifdef DBG_UTIL
97 maCallStacks.emplace( &rBroadcaster, sal::backtrace_get(10) );
98#endif
99 assert(IsListening(rBroadcaster) && "StartListening failed");
100 }
101}
102
103// unregisters a specific SfxBroadcaster
104
105void SfxListener::EndListening( SfxBroadcaster& rBroadcaster, bool bRemoveAllDuplicates )
106{
107 auto beginIt = maBCs.begin();
108 do
109 {
110 auto it = std::find( beginIt, maBCs.end(), &rBroadcaster );
111 if ( it == maBCs.end() )
112 {
113 break;
114 }
115 rBroadcaster.RemoveListener(*this);
116 beginIt = maBCs.erase( it );
117#ifdef DBG_UTIL
118 maCallStacks.erase( &rBroadcaster );
119#endif
120 }
121 while ( bRemoveAllDuplicates );
122}
123
124
125// unregisters all Broadcasters
126
128{
129 std::vector<SfxBroadcaster*> aBroadcasters;
130 std::swap(maBCs, aBroadcasters);
131 for (SfxBroadcaster *pBC : aBroadcasters)
132 pBC->RemoveListener(*this);
133#ifdef DBG_UTIL
134 maCallStacks.clear();
135#endif
136}
137
138
139bool SfxListener::IsListening( SfxBroadcaster& rBroadcaster ) const
140{
141 return maBCs.end() != std::find( maBCs.begin(), maBCs.end(), &rBroadcaster );
142}
143
145{
146 return maBCs.size();
147}
148
150{
151 return maBCs[nNo];
152}
153
154
155// base implementation of notification handler
156
157void SfxListener::Notify( SfxBroadcaster& rBroadcaster, const SfxHint& )
158{
159 (void) rBroadcaster;
160 assert(IsListening(rBroadcaster));
161}
162
163/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void RemoveListener(SfxListener &rListener)
void AddListener(SfxListener &rListener)
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
Registers a specific SfxBroadcaster.
Definition: lstner.cxx:79
SfxListener()
Definition: lstner.hxx:56
SfxBroadcaster * GetBroadcasterJOE(sal_uInt16 nNo) const
Definition: lstner.cxx:149
virtual ~SfxListener() COVERITY_NOEXCEPT_FALSE
Definition: lstner.cxx:47
std::vector< SfxBroadcaster * > maBCs
Definition: lstner.hxx:45
void RemoveBroadcaster_Impl(SfxBroadcaster &rBC)
Definition: lstner.cxx:60
bool IsListening(SfxBroadcaster &rBroadcaster) const
Definition: lstner.cxx:139
void EndListeningAll()
Definition: lstner.cxx:127
sal_uInt16 GetBroadcasterCount() const
Definition: lstner.cxx:144
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
Definition: lstner.cxx:105
std::map< SfxBroadcaster *, std::unique_ptr< sal::BacktraceState > > maCallStacks
Definition: lstner.hxx:48
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint)
Definition: lstner.cxx:157
sal_Int64 n
sal_uInt16 nPos
#define SAL_WARN(area, stream)
DuplicateHandling
Definition: lstner.hxx:41