Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/chart2/source/model/main/UndoManager.cxx
Line
Count
Source
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 "UndoManager.hxx"
21
#include <ChartModel.hxx>
22
#include <ChartViewHelper.hxx>
23
24
#include <com/sun/star/lang/DisposedException.hpp>
25
#include <com/sun/star/lang/NoSupportException.hpp>
26
27
#include <framework/undomanagerhelper.hxx>
28
#include <framework/imutex.hxx>
29
#include <officecfg/Office/Common.hxx>
30
#include <svl/undo.hxx>
31
32
namespace chart
33
{
34
35
    using ::com::sun::star::uno::Reference;
36
    using ::com::sun::star::uno::XInterface;
37
    using ::com::sun::star::uno::Sequence;
38
    using ::com::sun::star::lang::DisposedException;
39
    using ::com::sun::star::document::XUndoManager;
40
    using ::com::sun::star::document::XUndoAction;
41
    using ::com::sun::star::document::XUndoManagerListener;
42
    using ::com::sun::star::lang::NoSupportException;
43
    using ::com::sun::star::util::XModifyListener;
44
45
    namespace impl
46
    {
47
        class UndoManager_Impl : public ::framework::IUndoManagerImplementation
48
        {
49
        public:
50
            UndoManager_Impl( UndoManager& i_antiImpl, ::chart::ChartModel& i_parent, ::osl::Mutex& i_mutex )
51
0
                :m_rAntiImpl( i_antiImpl )
52
0
                ,m_rParent( i_parent )
53
0
                ,m_rMutex( i_mutex )
54
0
                ,m_bDisposed( false )
55
0
                ,m_aUndoHelper( *this )
56
0
            {
57
0
                m_aUndoManager.SetMaxUndoActionCount(
58
0
                    officecfg::Office::Common::Undo::Steps::get());
59
0
            }
60
61
            virtual ~UndoManager_Impl()
62
0
            {
63
0
            }
64
65
            ::osl::Mutex&                       getMutex();
66
            // IUndoManagerImplementation
67
            virtual SfxUndoManager&             getImplUndoManager() override;
68
            virtual Reference< XUndoManager >   getThis() override;
69
70
            // attribute access
71
0
            ::chart::ChartModel&                getParent() { return m_rParent; }
72
0
            ::framework::UndoManagerHelper&     getUndoHelper() { return m_aUndoHelper; }
73
74
            // public interface
75
76
            /// is called when the owner of the UndoManager is being disposed
77
            void    disposing();
78
79
            /// checks whether we're already disposed, throws a DisposedException if so
80
            void    checkDisposed_lck();
81
82
        private:
83
            UndoManager&                        m_rAntiImpl;
84
            ::chart::ChartModel&                m_rParent;
85
            ::osl::Mutex&                       m_rMutex;
86
            bool                                m_bDisposed;
87
88
            SfxUndoManager                      m_aUndoManager;
89
            ::framework::UndoManagerHelper      m_aUndoHelper;
90
        };
91
92
        ::osl::Mutex& UndoManager_Impl::getMutex()
93
0
        {
94
0
            return m_rMutex;
95
0
        }
96
97
        SfxUndoManager& UndoManager_Impl::getImplUndoManager()
98
0
        {
99
0
            return m_aUndoManager;
100
0
        }
101
102
        Reference< XUndoManager > UndoManager_Impl::getThis()
103
0
        {
104
0
            return &m_rAntiImpl;
105
0
        }
106
107
        void UndoManager_Impl::disposing()
108
0
        {
109
0
            {
110
0
                ::osl::MutexGuard aGuard( m_rMutex );
111
0
                m_bDisposed = true;
112
0
            }
113
0
            m_aUndoHelper.disposing();
114
0
        }
115
116
        void UndoManager_Impl::checkDisposed_lck()
117
0
        {
118
0
            if ( m_bDisposed )
119
0
                throw DisposedException( OUString(), getThis() );
120
0
        }
121
122
        namespace {
123
124
        /** guard for public UNO methods of the UndoManager
125
126
            The only purpose of this guard is to check for the instance being disposed already. Everything else,
127
            in particular the IMutexGuard functionality required by the UndoManagerHelper class, is a dummy only,
128
            as all involved classes (means we ourselves, the UndoManagerHelper, the SfxUndoManager, and the Undo actions
129
            we create) are inherently thread-safe, thus need no external lock (in particular no SolarMutex!).
130
        */
131
        class UndoManagerMethodGuard : public ::framework::IMutexGuard
132
        {
133
        public:
134
            explicit UndoManagerMethodGuard( UndoManager_Impl& i_impl )
135
0
            {
136
0
                ::osl::MutexGuard aGuard( i_impl.getMutex() );
137
                // throw if the instance is already disposed
138
0
                i_impl.checkDisposed_lck();
139
0
            }
140
            virtual ~UndoManagerMethodGuard()
141
0
            {
142
0
            }
143
144
            // IMutexGuard
145
            virtual void clear() override;
146
            virtual ::framework::IMutex& getGuardedMutex() override;
147
        };
148
149
        class DummyMutex : public ::framework::IMutex
150
        {
151
        public:
152
0
            virtual ~DummyMutex() {}
153
0
            virtual void acquire() override { }
154
0
            virtual void release() override { }
155
        };
156
157
        }
158
159
        ::framework::IMutex& UndoManagerMethodGuard::getGuardedMutex()
160
0
        {
161
0
            static DummyMutex s_aDummyMutex;
162
0
            return s_aDummyMutex;
163
0
        }
164
165
        void UndoManagerMethodGuard::clear()
166
0
        {
167
            // nothing to do. This interface implementation is a dummy.
168
0
        }
169
    }
170
171
    using impl::UndoManagerMethodGuard;
172
173
    UndoManager::UndoManager( ::chart::ChartModel& i_parent, ::osl::Mutex& i_mutex )
174
0
        :m_pImpl( new impl::UndoManager_Impl( *this, i_parent, i_mutex ) )
175
0
    {
176
0
    }
177
178
    UndoManager::~UndoManager()
179
0
    {
180
0
    }
181
182
    void SAL_CALL UndoManager::acquire() noexcept
183
0
    {
184
0
        m_pImpl->getParent().acquire();
185
0
    }
186
187
    void SAL_CALL UndoManager::release() noexcept
188
0
    {
189
0
        m_pImpl->getParent().release();
190
0
    }
191
192
    void UndoManager::disposing()
193
0
    {
194
0
        m_pImpl->disposing();
195
0
    }
196
197
    void SAL_CALL UndoManager::enterUndoContext( const OUString& i_title )
198
0
    {
199
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
200
0
        m_pImpl->getUndoHelper().enterUndoContext( i_title, aGuard );
201
0
    }
202
203
    void SAL_CALL UndoManager::enterHiddenUndoContext(  )
204
0
    {
205
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
206
0
        m_pImpl->getUndoHelper().enterHiddenUndoContext( aGuard );
207
0
    }
208
209
    void SAL_CALL UndoManager::leaveUndoContext(  )
210
0
    {
211
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
212
0
        m_pImpl->getUndoHelper().leaveUndoContext( aGuard );
213
0
    }
214
215
    void SAL_CALL UndoManager::addUndoAction( const Reference< XUndoAction >& i_action )
216
0
    {
217
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
218
0
        m_pImpl->getUndoHelper().addUndoAction( i_action, aGuard );
219
0
    }
220
221
    void SAL_CALL UndoManager::undo(  )
222
0
    {
223
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
224
0
        m_pImpl->getUndoHelper().undo( aGuard );
225
226
0
        ChartViewHelper::setViewToDirtyState( &m_pImpl->getParent() );
227
0
    }
228
229
    void SAL_CALL UndoManager::redo(  )
230
0
    {
231
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
232
0
        m_pImpl->getUndoHelper().redo( aGuard );
233
234
0
        ChartViewHelper::setViewToDirtyState( &m_pImpl->getParent() );
235
0
    }
236
237
    sal_Bool SAL_CALL UndoManager::isUndoPossible(  )
238
0
    {
239
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
240
0
        return m_pImpl->getUndoHelper().isUndoPossible();
241
0
    }
242
243
    sal_Bool SAL_CALL UndoManager::isRedoPossible(  )
244
0
    {
245
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
246
0
        return m_pImpl->getUndoHelper().isRedoPossible();
247
0
    }
248
249
    OUString SAL_CALL UndoManager::getCurrentUndoActionTitle(  )
250
0
    {
251
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
252
0
        return m_pImpl->getUndoHelper().getCurrentUndoActionTitle();
253
0
    }
254
255
    OUString SAL_CALL UndoManager::getCurrentRedoActionTitle(  )
256
0
    {
257
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
258
0
        return m_pImpl->getUndoHelper().getCurrentRedoActionTitle();
259
0
    }
260
261
    Sequence< OUString > SAL_CALL UndoManager::getAllUndoActionTitles(  )
262
0
    {
263
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
264
0
        return m_pImpl->getUndoHelper().getAllUndoActionTitles();
265
0
    }
266
267
    Sequence< OUString > SAL_CALL UndoManager::getAllRedoActionTitles(  )
268
0
    {
269
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
270
0
        return m_pImpl->getUndoHelper().getAllRedoActionTitles();
271
0
    }
272
273
    void SAL_CALL UndoManager::clear(  )
274
0
    {
275
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
276
0
        m_pImpl->getUndoHelper().clear( aGuard );
277
0
    }
278
279
    void SAL_CALL UndoManager::clearRedo(  )
280
0
    {
281
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
282
0
        m_pImpl->getUndoHelper().clearRedo( aGuard );
283
0
    }
284
285
    void SAL_CALL UndoManager::reset(  )
286
0
    {
287
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
288
0
        m_pImpl->getUndoHelper().reset( aGuard );
289
0
    }
290
291
    void SAL_CALL UndoManager::addUndoManagerListener( const Reference< XUndoManagerListener >& i_listener )
292
0
    {
293
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
294
0
        m_pImpl->getUndoHelper().addUndoManagerListener( i_listener );
295
0
    }
296
297
    void SAL_CALL UndoManager::removeUndoManagerListener( const Reference< XUndoManagerListener >& i_listener )
298
0
    {
299
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
300
0
        m_pImpl->getUndoHelper().removeUndoManagerListener( i_listener );
301
0
    }
302
303
    void SAL_CALL UndoManager::lock(  )
304
0
    {
305
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
306
0
        m_pImpl->getUndoHelper().lock();
307
0
    }
308
309
    void SAL_CALL UndoManager::unlock(  )
310
0
    {
311
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
312
0
        m_pImpl->getUndoHelper().unlock();
313
0
    }
314
315
    sal_Bool SAL_CALL UndoManager::isLocked(  )
316
0
    {
317
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
318
0
        return m_pImpl->getUndoHelper().isLocked();
319
0
    }
320
321
    Reference< XInterface > SAL_CALL UndoManager::getParent(  )
322
0
    {
323
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
324
0
        return m_pImpl->getParent();
325
0
    }
326
327
    void SAL_CALL UndoManager::setParent( const Reference< XInterface >& )
328
0
    {
329
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
330
0
        throw NoSupportException( OUString(), m_pImpl->getThis() );
331
0
    }
332
333
    void SAL_CALL UndoManager::addModifyListener( const Reference< XModifyListener >& i_listener )
334
0
    {
335
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
336
0
        m_pImpl->getUndoHelper().addModifyListener( i_listener );
337
0
    }
338
339
    void SAL_CALL UndoManager::removeModifyListener( const Reference< XModifyListener >& i_listener )
340
0
    {
341
0
        UndoManagerMethodGuard aGuard( *m_pImpl );
342
0
        m_pImpl->getUndoHelper().removeModifyListener( i_listener );
343
0
    }
344
345
} // namespace chart
346
347
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */