xref: /AOO41X/main/svx/source/tbxctrls/lboxctrl.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 #ifdef   _TOOLS_DEBUG_HXX
32 #include <tools/debug.hxx>
33 #endif
34 #include <vcl/lstbox.hxx>
35 #include <vcl/toolbox.hxx>
36 #include <vcl/event.hxx>
37 #include <sfx2/app.hxx>
38 #include <sfx2/tbxctrl.hxx>
39 #include <sfx2/bindings.hxx>
40 #include <sfx2/dispatch.hxx>
41 #include <sfx2/viewsh.hxx>
42 #include <tools/gen.hxx>
43 #include <svl/intitem.hxx>
44 #include <svl/eitem.hxx>
45 #include <svtools/stdctrl.hxx>
46 #include <svl/slstitm.hxx>
47 #include <svl/stritem.hxx>
48 #include <svx/dialmgr.hxx>
49 #include <svx/lboxctrl.hxx>
50 #ifndef _VCL_MNEMONIC_HXX_
51 #include <vcl/mnemonic.hxx>
52 #endif
53 #include <tools/urlobj.hxx>
54 
55 #include <svx/svxids.hrc>
56 #include <svx/dialogs.hrc>
57 
58 #include "lboxctrl.hrc"
59 
60 
61 using namespace ::com::sun::star::uno;
62 using namespace ::com::sun::star::beans;
63 using namespace ::com::sun::star::frame;
64 
65 class SvxPopupWindowListBox;
66 
67 /////////////////////////////////////////////////////////////////
68 
69 class SvxPopupWindowListBox : public SfxPopupWindow
70 {
71 	using FloatingWindow::StateChanged;
72 
73 	FixedInfo		aInfo;
74 	ListBox	*		pListBox;
75 	ToolBox &		rToolBox;
76 	sal_Bool			bUserSel;
77     sal_uInt16          nTbxId;
78     rtl::OUString   maCommandURL;
79 	// disallow copy-constructor and assignment-operator
80 
81 	SvxPopupWindowListBox(const int& );
82 	SvxPopupWindowListBox & operator = (const int& );
83 
84 //	SvxPopupWindowListBox( sal_uInt16 nSlotId, ToolBox& rTbx, sal_uInt16 nTbxItemId );
85 
86 public:
87     SvxPopupWindowListBox( sal_uInt16 nSlotId, const rtl::OUString& rCommandURL, sal_uInt16 nTbxId, ToolBox& rTbx );
88 	virtual ~SvxPopupWindowListBox();
89 
90 	// SfxPopupWindow
91 	virtual SfxPopupWindow * 	Clone() const;
92 	virtual void 				PopupModeEnd();
93 	virtual void 				StateChanged( sal_uInt16 nSID, SfxItemState eState,
94 											  const SfxPoolItem* pState );
95 
96 	void 						StartSelection();
97 	inline ListBox &			GetListBox()	{ return *pListBox; }
98 	inline FixedInfo &			GetInfo()		{ return aInfo; }
99 
100 	sal_Bool						IsUserSelected() const			{ return bUserSel; }
101 	void						SetUserSelected( sal_Bool bVal )	{ bUserSel = bVal; }
102     /*virtual*/Window*                     GetPreferredKeyInputWindow();
103 };
104 
105 /////////////////////////////////////////////////////////////////
106 
107 SvxPopupWindowListBox::SvxPopupWindowListBox( sal_uInt16 nSlotId, const rtl::OUString& rCommandURL, sal_uInt16 nId, ToolBox& rTbx ) :
108     SfxPopupWindow( nSlotId, Reference< XFrame >(), SVX_RES( RID_SVXTBX_UNDO_REDO_CTRL ) ),
109 	aInfo		( this, SVX_RES( FT_NUM_OPERATIONS ) ),
110 	rToolBox	( rTbx ),
111 	bUserSel	( sal_False ),
112     nTbxId      ( nId ),
113     maCommandURL( rCommandURL )
114 {
115 	DBG_ASSERT( nSlotId == GetId(), "id mismatch" );
116     pListBox = new ListBox( this, SVX_RES( LB_SVXTBX_UNDO_REDO_CTRL ) );
117 	FreeResource();
118     pListBox->EnableMultiSelection( sal_True, sal_True );
119 	SetBackground( GetSettings().GetStyleSettings().GetDialogColor() );
120     AddStatusListener( rCommandURL );
121 }
122 
123 
124 SvxPopupWindowListBox::~SvxPopupWindowListBox()
125 {
126 	delete pListBox;
127 }
128 
129 
130 SfxPopupWindow* SvxPopupWindowListBox::Clone() const
131 {
132     return new SvxPopupWindowListBox( GetId(), maCommandURL, nTbxId, rToolBox );
133 }
134 
135 
136 void SvxPopupWindowListBox::PopupModeEnd()
137 {
138 	rToolBox.EndSelection();
139 	SfxPopupWindow::PopupModeEnd();
140 	//FloatingWindow::PopupModeEnd();
141 
142 	if( SfxViewShell::Current() )
143 	{
144 	    Window* pShellWnd = SfxViewShell::Current()->GetWindow();
145 		if (pShellWnd)
146 			pShellWnd->GrabFocus();
147 	}
148 }
149 
150 
151 void SvxPopupWindowListBox::StateChanged(
152 		sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState )
153 {
154     rToolBox.EnableItem( nTbxId, ( SfxToolBoxControl::GetItemState( pState ) != SFX_ITEM_DISABLED) );
155 	SfxPopupWindow::StateChanged( nSID, eState, pState );
156 }
157 
158 
159 void SvxPopupWindowListBox::StartSelection()
160 {
161 	rToolBox.StartSelection();
162 }
163 
164 Window* SvxPopupWindowListBox::GetPreferredKeyInputWindow()
165 {
166     // allows forwarding key events in the correct window
167     // without setting the focus
168     return pListBox->GetPreferredKeyInputWindow();
169 }
170 
171 /////////////////////////////////////////////////////////////////
172 
173 SFX_IMPL_TOOLBOX_CONTROL( SvxListBoxControl, SfxStringItem );
174 
175 
176 SvxListBoxControl::SvxListBoxControl( sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx )
177 	:SfxToolBoxControl( nSlotId, nId, rTbx ),
178 	pPopupWin	( 0 )
179 {
180 	rTbx.SetItemBits( nId, TIB_DROPDOWN | rTbx.GetItemBits( nId ) );
181 	rTbx.Invalidate();
182 }
183 
184 
185 SvxListBoxControl::~SvxListBoxControl()
186 {
187 }
188 
189 
190 SfxPopupWindow* SvxListBoxControl::CreatePopupWindow()
191 {
192 	DBG_ERROR( "not implemented" );
193 	return 0;
194 }
195 
196 
197 SfxPopupWindowType SvxListBoxControl::GetPopupWindowType() const
198 {
199 	return SFX_POPUPWINDOW_ONTIMEOUT;
200 }
201 
202 
203 void SvxListBoxControl::StateChanged(
204 		sal_uInt16, SfxItemState, const SfxPoolItem* pState )
205 {
206 	GetToolBox().EnableItem( GetId(),
207 							SFX_ITEM_DISABLED != GetItemState(pState) );
208 }
209 
210 
211 IMPL_LINK( SvxListBoxControl, PopupModeEndHdl, void *, EMPTYARG )
212 {
213 	if( pPopupWin && 0 == pPopupWin->GetPopupModeFlags()  &&
214 		pPopupWin->IsUserSelected() )
215 	{
216         sal_uInt16 nCount = pPopupWin->GetListBox().GetSelectEntryCount();
217 
218         INetURLObject aObj( m_aCommandURL );
219 
220         Sequence< PropertyValue > aArgs( 1 );
221         aArgs[0].Name   = aObj.GetURLPath();
222         aArgs[0].Value  = makeAny( sal_Int16( nCount ));
223         SfxToolBoxControl::Dispatch( m_aCommandURL, aArgs );
224 	}
225 	return 0;
226 }
227 
228 
229 void SvxListBoxControl::Impl_SetInfo( sal_uInt16 nCount )
230 {
231     DBG_ASSERT( pPopupWin, "NULL pointer, PopupWindow missing" );
232 
233 //    ListBox &rListBox = pPopupWin->GetListBox();
234 
235     sal_uInt16 nId;
236     if (nCount == 1)
237         nId = SID_UNDO == GetSlotId() ? RID_SVXSTR_NUM_UNDO_ACTION : RID_SVXSTR_NUM_REDO_ACTION;
238     else
239         nId = SID_UNDO == GetSlotId() ? RID_SVXSTR_NUM_UNDO_ACTIONS : RID_SVXSTR_NUM_REDO_ACTIONS;
240 
241     aActionStr = String(SVX_RES(nId));
242 
243     String aText( aActionStr );
244     aText.SearchAndReplaceAllAscii( "$(ARG1)", String::CreateFromInt32( nCount ) );
245     pPopupWin->GetInfo().SetText( aText );
246 }
247 
248 
249 IMPL_LINK( SvxListBoxControl, SelectHdl, void *, EMPTYARG )
250 {
251     if (pPopupWin)
252     {
253         //pPopupWin->SetUserSelected( sal_False );
254 
255         ListBox &rListBox = pPopupWin->GetListBox();
256         if (rListBox.IsTravelSelect())
257             Impl_SetInfo( rListBox.GetSelectEntryCount() );
258         else
259         {
260             pPopupWin->SetUserSelected( sal_True );
261             pPopupWin->EndPopupMode( 0 );
262         }
263     }
264 	return 0;
265 }
266 
267 /////////////////////////////////////////////////////////////////
268 
269 SFX_IMPL_TOOLBOX_CONTROL( SvxUndoRedoControl, SfxStringItem );
270 
271 SvxUndoRedoControl::SvxUndoRedoControl( sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx )
272 	: SvxListBoxControl( nSlotId, nId, rTbx )
273 {
274 	rTbx.SetItemBits( nId, TIB_DROPDOWN | rTbx.GetItemBits( nId ) );
275 	rTbx.Invalidate();
276     aDefaultText = MnemonicGenerator::EraseAllMnemonicChars( rTbx.GetItemText( nId ) );
277 }
278 
279 SvxUndoRedoControl::~SvxUndoRedoControl()
280 {
281 }
282 
283 void SvxUndoRedoControl::StateChanged(
284     sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState )
285 {
286     if ( nSID == SID_UNDO || nSID == SID_REDO )
287     {
288         if ( eState == SFX_ITEM_DISABLED )
289         {
290             ToolBox& rBox = GetToolBox();
291             rBox.SetQuickHelpText( GetId(), aDefaultText );
292         }
293         else if ( pState && pState->ISA( SfxStringItem ) )
294         {
295             SfxStringItem& rItem = *(SfxStringItem *)pState;
296             ToolBox& rBox = GetToolBox();
297             String aQuickHelpText = MnemonicGenerator::EraseAllMnemonicChars( rItem.GetValue() );
298             rBox.SetQuickHelpText( GetId(), aQuickHelpText );
299         }
300         SvxListBoxControl::StateChanged( nSID, eState, pState );
301     }
302     else
303     {
304         aUndoRedoList.clear();
305 
306         if ( pState && pState->ISA( SfxStringListItem ) )
307         {
308             SfxStringListItem &rItem = *(SfxStringListItem *)pState;
309 		    const List* pLst = rItem.GetList();
310 		    DBG_ASSERT( pLst, "no undo actions available" );
311 		    if ( pLst )
312             {
313 			    for( long nI = 0, nEnd = pLst->Count(); nI < nEnd; ++nI )
314                     aUndoRedoList.push_back( rtl::OUString( *(String *)pLst->GetObject( nI )));
315             }
316         }
317     }
318 }
319 
320 SfxPopupWindow* SvxUndoRedoControl::CreatePopupWindow()
321 {
322 	DBG_ASSERT(( SID_UNDO == GetSlotId() || SID_REDO == GetSlotId() ), "mismatching ids" );
323 
324     if ( m_aCommandURL.equalsAscii( ".uno:Undo" ))
325         updateStatus( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GetUndoStrings" )));
326     else
327         updateStatus( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GetRedoStrings" )));
328 
329     ToolBox& rBox = GetToolBox();
330 
331     pPopupWin = new SvxPopupWindowListBox( GetSlotId(), m_aCommandURL, GetId(), rBox );
332 	pPopupWin->SetPopupModeEndHdl( LINK( this, SvxUndoRedoControl,
333 											PopupModeEndHdl ) );
334     ListBox &rListBox = pPopupWin->GetListBox();
335     rListBox.SetSelectHdl( LINK( this, SvxUndoRedoControl, SelectHdl ) );
336 
337 	for( sal_uInt32 n = 0; n < aUndoRedoList.size(); n++ )
338 		rListBox.InsertEntry( String( aUndoRedoList[n] ));
339 
340     rListBox.SelectEntryPos( 0 );
341     aActionStr = String( SVX_RES( SID_UNDO == GetSlotId() ?
342                                   RID_SVXSTR_NUM_UNDO_ACTIONS : RID_SVXSTR_NUM_REDO_ACTIONS ) );
343     Impl_SetInfo( rListBox.GetSelectEntryCount() );
344 
345     // move focus in floating window without
346     // closing it (GrabFocus() would close it!)
347     pPopupWin->StartPopupMode( &rBox, FLOATWIN_POPUPMODE_GRABFOCUS );
348     //pPopupWin->GetListBox().GrabFocus();
349 
350     return pPopupWin;
351 }
352