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