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(); 93 inline ListBox & GetListBox() { return *pListBox; } 94 inline FixedInfo & GetInfo() { return aInfo; } 95 96 sal_Bool IsUserSelected() const { return bUserSel; } 97 void SetUserSelected( sal_Bool bVal ) { bUserSel = bVal; } 98 /*virtual*/Window* GetPreferredKeyInputWindow(); 99 }; 100 101 ///////////////////////////////////////////////////////////////// 102 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 120 SvxPopupWindowListBox::~SvxPopupWindowListBox() 121 { 122 delete pListBox; 123 } 124 125 126 SfxPopupWindow* SvxPopupWindowListBox::Clone() const 127 { 128 return new SvxPopupWindowListBox( GetId(), maCommandURL, nTbxId, rToolBox ); 129 } 130 131 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 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 155 void SvxPopupWindowListBox::StartSelection() 156 { 157 rToolBox.StartSelection(); 158 } 159 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 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 181 SvxListBoxControl::~SvxListBoxControl() 182 { 183 } 184 185 186 SfxPopupWindow* SvxListBoxControl::CreatePopupWindow() 187 { 188 DBG_ERROR( "not implemented" ); 189 return 0; 190 } 191 192 193 SfxPopupWindowType SvxListBoxControl::GetPopupWindowType() const 194 { 195 return SFX_POPUPWINDOW_ONTIMEOUT; 196 } 197 198 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 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 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 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 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 275 SvxUndoRedoControl::~SvxUndoRedoControl() 276 { 277 } 278 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 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