1 /*************************************************************************
2  *
3  *  The Contents of this file are made available subject to the terms of
4  *  the BSD license.
5  *
6  *  Copyright 2000, 2010 Oracle and/or its affiliates.
7  *  All rights reserved.
8  *
9  *  Redistribution and use in source and binary forms, with or without
10  *  modification, are permitted provided that the following conditions
11  *  are met:
12  *  1. Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  *  2. Redistributions in binary form must reproduce the above copyright
15  *     notice, this list of conditions and the following disclaimer in the
16  *     documentation and/or other materials provided with the distribution.
17  *  3. Neither the name of Sun Microsystems, Inc. nor the names of its
18  *     contributors may be used to endorse or promote products derived
19  *     from this software without specific prior written permission.
20  *
21  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  *************************************************************************/
34 // __________ Imports __________
35 
36 import com.sun.star.uno.UnoRuntime;
37 
38 import java.awt.*;
39 import javax.swing.*;
40 import java.lang.String;
41 import java.awt.event.*;
42 import java.awt.*;
43 
44 // __________ Implementation __________
45 
46 /**
47  * Makes it possible to change some states of currently loaded
48  * document (e.g. enable/disable menubar, toolbar, objectbar)
49  *
50  * @author     Andreas Schlüns
51  * @created    20.06.2002 09:28
52  */
53 public class CustomizeView extends    JPanel
54                            implements IShutdownListener
55 {
56     // ____________________
57     // const
58 
59     /**
60      * These const URL's describe feature for toggling some properties of loaded document.
61      * Dispatch it with the corresponding parameter to the frame.
62      */
63     private static final String FEATUREURL_MENUBAR      = "slot:6661"         ;
64     private static final String FEATUREURL_TOOLBAR      = "slot:5909"         ;
65     private static final String FEATUREURL_OBJECTBAR    = "slot:5905"         ;
66 
67     private static final String FEATUREPROP_MENUBAR     = "MenuBarVisible"    ;
68     private static final String FEATUREPROP_TOOLBAR     = "ToolBarVisible"    ;
69     private static final String FEATUREPROP_OBJECTBAR   = "ObjectBarVisible"  ;
70 
71     private static final String ACTION_MENUBAR          = "toogle_menu"       ;
72     private static final String ACTION_TOOLBAR          = "toogle_toolbar"    ;
73     private static final String ACTION_OBJECTBAR        = "toogle_objectbar"  ;
74 
75     private static final String MENUBAR_ON              = "menubar on"        ;
76     private static final String TOOLBAR_ON              = "toolbar on"        ;
77     private static final String OBJECTBAR_ON            = "objectbar on"      ;
78 
79     private static final String MENUBAR_OFF             = "menubar off"       ;
80     private static final String TOOLBAR_OFF             = "toolbar off"       ;
81     private static final String OBJECTBAR_OFF           = "objectbar off"     ;
82 
83     // ____________________
84     // member
85 
86     /**
87      * @member  m_cbMenuBar             reference to checkbox for toggling menubar
88      * @member  m_cbToolBar             reference to checkbox for toggling toolbar
89      * @member  m_cbObjectBar           reference to checkbox for toggling objectbar
90      *
91      * @member  m_aMenuBarListener      listener for status events of the menu bar
92      * @member  m_aToolBarListener      listener for status events of the tool bar
93      * @member  m_aObjectBarListener    listener for status events of the object bar
94      */
95     private JCheckBox           m_cbMenuBar         ;
96     private JCheckBox           m_cbToolBar         ;
97     private JCheckBox           m_cbObjectBar       ;
98 
99     private StatusListener      m_aMenuBarListener  ;
100     private StatusListener      m_aToolBarListener  ;
101     private StatusListener      m_aObjectBarListener;
102 
103     // ____________________
104 
105     /**
106      * ctor
107      * Create view controls on startup and initialize it.
108      * We don't start listening here. see setFrame()!
109      */
110     CustomizeView()
111     {
112         this.setLayout(new GridLayout(3,0));
113 
114         m_cbMenuBar   = new JCheckBox(MENUBAR_OFF  , false);
115         m_cbToolBar   = new JCheckBox(TOOLBAR_OFF  , false);
116         m_cbObjectBar = new JCheckBox(OBJECTBAR_OFF, false);
117 
118         m_cbMenuBar.setEnabled  (false);
119         m_cbToolBar.setEnabled  (false);
120         m_cbObjectBar.setEnabled(false);
121 
122         m_cbMenuBar.setActionCommand  (ACTION_MENUBAR  );
123         m_cbToolBar.setActionCommand  (ACTION_TOOLBAR  );
124         m_cbObjectBar.setActionCommand(ACTION_OBJECTBAR);
125 
126         this.add(m_cbMenuBar  );
127         this.add(m_cbToolBar  );
128         this.add(m_cbObjectBar);
129     }
130 
131     // ____________________
132 
133     /**
134      * set new frame for this view
135      * We start listening for frame action/status and click events instandly.
136      * If an event occure we use it to synchronize our controls
137      * with states of a (my be) new document view of this frame.
138      *
139      * @param xFrame
140      *          the reference to the frame, which provides the
141      *          possibility to get the required status informations
142      *
143      *          Attention: We don't accept new frames here.
144      *          We get one after startup and work with him.
145      *          That's it!
146      */
147     public void setFrame(com.sun.star.frame.XFrame xFrame)
148     {
149         if (xFrame==null)
150             return;
151 
152         // be listener for click events
153         // They will toogle the UI controls.
154         ClickListener aMenuBarHandler   = new ClickListener(FEATUREURL_MENUBAR  ,FEATUREPROP_MENUBAR  ,xFrame);
155         ClickListener aToolBarHandler   = new ClickListener(FEATUREURL_TOOLBAR  ,FEATUREPROP_TOOLBAR  ,xFrame);
156         ClickListener aObjectBarHandler = new ClickListener(FEATUREURL_OBJECTBAR,FEATUREPROP_OBJECTBAR,xFrame);
157 
158         m_cbMenuBar.addActionListener  (aMenuBarHandler  );
159         m_cbToolBar.addActionListener  (aToolBarHandler  );
160         m_cbObjectBar.addActionListener(aObjectBarHandler);
161 
162         // be frame action listener
163         // The callback will update listener connections
164         // for status updates automaticly!
165         m_aMenuBarListener   = new StatusListener(m_cbMenuBar  ,MENUBAR_ON  ,MENUBAR_OFF  ,xFrame, FEATUREURL_MENUBAR  );
166         m_aToolBarListener   = new StatusListener(m_cbToolBar  ,TOOLBAR_ON  ,TOOLBAR_OFF  ,xFrame, FEATUREURL_TOOLBAR  );
167         m_aObjectBarListener = new StatusListener(m_cbObjectBar,OBJECTBAR_ON,OBJECTBAR_OFF,xFrame, FEATUREURL_OBJECTBAR);
168 
169         m_aMenuBarListener.startListening();
170         m_aToolBarListener.startListening();
171         m_aObjectBarListener.startListening();
172     }
173 
174     // ____________________
175 
176     /**
177      * react for click events of the used check boxes
178      * We use our internal set dispatch objects to
179      * call it. This calls toogle the menu/object- or toolbar.
180      * Note: Because we are listener status events too - hopefully
181      * we get a notification, if toogling was successfully or not.
182      * We use this information to update our check boxes again.
183      * But such update doesn't force (hopefully) an action event. Otherwhise
184      * we can produce a never ending recursion!
185      *
186      * @param aEvent
187      *          describes the used check box and his current state
188      *          we can use to dispatch the right URL to the office
189      */
190     class ClickListener implements ActionListener,
191                                    com.sun.star.lang.XEventListener
192     {
193         /// URL, to toogle the requested UI item
194         String m_sURL;
195         /// name of the property which must be used in combination with the URL
196         String m_sProp;
197         /// we must use this frame to dispatch a request
198         com.sun.star.frame.XFrame m_xFrame;
199 
200         //_____________________
201 
202         /**
203          * ctor
204          * It initialize an instance of this clas only.
205          */
206         ClickListener( String                    sURL   ,
207                        String                    sProp  ,
208                        com.sun.star.frame.XFrame xFrame )
209         {
210             m_sURL   = sURL  ;
211             m_sProp  = sProp ;
212             m_xFrame = xFrame;
213         }
214 
215         //_____________________
216 
217         /**
218          * callback for action events
219          * Such events occure if somehwere click the
220          * JCheckBox control on which we are registered.
221          * Such events doesn't occure if we set it programmaticly
222          * (e.g. if we get status events to -> see class StatusListener too)
223          *
224          * @param aEvent
225          *          describes the check box and his state
226          *          we can use to toogle the requested office
227          *          ressource.
228          */
229         public void actionPerformed(ActionEvent aEvent)
230         {
231             synchronized(this)
232             {
233                 if (m_xFrame==null)
234                     return;
235             }
236 
237             // define parameters for following dispatch
238             boolean bState = ((JCheckBox)aEvent.getSource()).isSelected();
239 
240             // prepare the dispatch
241             com.sun.star.util.URL aURL = FunctionHelper.parseURL(m_sURL);
242             if (aURL==null)
243                 return;
244 
245             com.sun.star.beans.PropertyValue[] lProperties = new com.sun.star.beans.PropertyValue[1];
246             lProperties[0]       = new com.sun.star.beans.PropertyValue();
247             lProperties[0].Name  = m_sProp;
248             lProperties[0].Value = new Boolean(bState);
249 
250             // execute (dispatch) it into the frame
251             if (m_xFrame==null)
252                 return;
253             FunctionHelper.execute(m_xFrame,aURL,lProperties,null);
254         }
255 
256         // ____________________
257 
258         /**
259          * callback for disposing events
260          * Internaly we save a reference to an office frame.
261          * Of course he can die and inform us then. We should react
262          * and forget his reference.
263          *
264          * @param aEvent
265          *          describes the source which fire this event
266          *          Must be our internal saved frame. Otherwhise
267          *          somewhere know us without a registration ...
268          */
269         public void disposing(com.sun.star.lang.EventObject aEvent)
270         {
271             synchronized(this)
272             {
273                 m_xFrame = null;
274             }
275         }
276     }
277 
278     // ____________________
279 
280     /**
281      * If this java application shutdown - we must cancel all current existing
282      * listener connections. Otherwhise the office will run into some
283      * DisposedExceptions if it tries to use these forgotten listener references.
284      * And of course it can die doing that.
285      * We are registered at a central object to be informed if the VM will exit.
286      * So we can react.
287      */
288     public void shutdown()
289     {
290         m_aMenuBarListener.shutdown();
291         m_aToolBarListener.shutdown();
292         m_aObjectBarListener.shutdown();
293 
294         m_aMenuBarListener   = null;
295         m_aToolBarListener   = null;
296         m_aObjectBarListener = null;
297     }
298 }
299