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