1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_chart2.hxx"
26 
27 #include "UndoCommandDispatch.hxx"
28 #include "ResId.hxx"
29 #include "macros.hxx"
30 
31 #include <com/sun/star/util/XModifyBroadcaster.hpp>
32 #include <com/sun/star/document/XUndoManagerSupplier.hpp>
33 
34 #include <vos/mutex.hxx>
35 #include <vcl/svapp.hxx>
36 #include <tools/diagnose_ex.h>
37 
38 // for ressource strings STR_UNDO and STR_REDO
39 #include <svtools/svtools.hrc>
40 #include <svtools/svtdata.hxx>
41 
42 using namespace ::com::sun::star;
43 
44 using ::com::sun::star::uno::Reference;
45 using ::com::sun::star::uno::Sequence;
46 using ::rtl::OUString;
47 
48 namespace chart
49 {
50 
51 UndoCommandDispatch::UndoCommandDispatch(
52     const Reference< uno::XComponentContext > & xContext,
53     const Reference< frame::XModel > & xModel ) :
54         CommandDispatch( xContext ),
55         m_xModel( xModel )
56 {
57     uno::Reference< document::XUndoManagerSupplier > xSuppUndo( m_xModel, uno::UNO_QUERY_THROW );
58     m_xUndoManager.set( xSuppUndo->getUndoManager(), uno::UNO_QUERY_THROW );
59 }
60 
61 UndoCommandDispatch::~UndoCommandDispatch()
62 {}
63 
64 void UndoCommandDispatch::initialize()
65 {
66     Reference< util::XModifyBroadcaster > xBroadcaster( m_xUndoManager, uno::UNO_QUERY );
67     ENSURE_OR_RETURN_VOID( xBroadcaster.is(), "UndoCommandDispatch::initialize: missing modification broadcaster interface!" );
68     xBroadcaster->addModifyListener( this );
69 }
70 
71 void UndoCommandDispatch::fireStatusEvent(
72     const OUString & rURL,
73     const Reference< frame::XStatusListener > & xSingleListener /* = 0 */ )
74 {
75     if( m_xUndoManager.is() )
76     {
77         bool bFireAll = (rURL.getLength() == 0);
78         uno::Any aUndoState, aRedoState;
79         if( m_xUndoManager->isUndoPossible())
80         {
81             // using assignment for broken gcc 3.3
82             OUString aUndo = OUString( String( SvtResId( STR_UNDO )));
83             aUndoState <<= ( aUndo + m_xUndoManager->getCurrentUndoActionTitle());
84         }
85         if( m_xUndoManager->isRedoPossible())
86         {
87             // using assignment for broken gcc 3.3
88             OUString aRedo = OUString( String( SvtResId( STR_REDO )));
89             aRedoState <<= ( aRedo + m_xUndoManager->getCurrentRedoActionTitle());
90         }
91 
92         if( bFireAll || rURL.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(".uno:Undo")))
93             fireStatusEventForURL( C2U(".uno:Undo"), aUndoState, m_xUndoManager->isUndoPossible(), xSingleListener );
94         if( bFireAll || rURL.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(".uno:Redo")))
95             fireStatusEventForURL( C2U(".uno:Redo"), aRedoState, m_xUndoManager->isRedoPossible(), xSingleListener );
96     }
97 }
98 
99 // ____ XDispatch ____
100 void SAL_CALL UndoCommandDispatch::dispatch(
101     const util::URL& URL,
102     const Sequence< beans::PropertyValue >& /* Arguments */ )
103     throw (uno::RuntimeException)
104 {
105     if( m_xUndoManager.is() )
106     {
107         // why is it necessary to lock the solar mutex here?
108         // /--
109         ::vos::OGuard aSolarGuard( Application::GetSolarMutex());
110         try
111         {
112             if( URL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Undo" )))
113                 m_xUndoManager->undo();
114             else
115                 m_xUndoManager->redo();
116         }
117         catch( const document::UndoFailedException& )
118         {
119             // silently ignore
120         }
121         catch( const uno::Exception& )
122         {
123         	DBG_UNHANDLED_EXCEPTION();
124         }
125         // \--
126     }
127 }
128 
129 // ____ WeakComponentImplHelperBase ____
130 /// is called when this is disposed
131 void SAL_CALL UndoCommandDispatch::disposing()
132 {
133     Reference< util::XModifyBroadcaster > xBroadcaster( m_xUndoManager, uno::UNO_QUERY );
134     OSL_ENSURE( xBroadcaster.is(), "UndoCommandDispatch::initialize: missing modification broadcaster interface!" );
135     if( xBroadcaster.is() )
136     {
137         xBroadcaster->removeModifyListener( this );
138     }
139 
140     m_xUndoManager.clear();
141     m_xModel.clear();
142 }
143 
144 // ____ XEventListener (base of XModifyListener) ____
145 void SAL_CALL UndoCommandDispatch::disposing( const lang::EventObject& /* Source */ )
146     throw (uno::RuntimeException)
147 {
148     m_xUndoManager.clear();
149     m_xModel.clear();
150 }
151 
152 } //  namespace chart
153