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_svtools.hxx" 30 #include <svtools/editbrowsebox.hxx> 31 #include <vcl/decoview.hxx> 32 #include <svtools/fmtfield.hxx> 33 #include <svtools/xtextedt.hxx> 34 35 #include <algorithm> 36 37 // ....................................................................... 38 namespace svt 39 { 40 // ....................................................................... 41 42 TYPEINIT0(CellController); 43 TYPEINIT1(EditCellController, CellController); 44 TYPEINIT1(SpinCellController, CellController); 45 TYPEINIT1(CheckBoxCellController, CellController); 46 TYPEINIT1(ComboBoxCellController, CellController); 47 TYPEINIT1(ListBoxCellController, CellController); 48 49 TYPEINIT1( FormattedFieldCellController, EditCellController ); 50 51 //================================================================== 52 //= ComboBoxControl 53 //================================================================== 54 ComboBoxControl::ComboBoxControl(Window* pParent, WinBits nWinStyle) 55 :ComboBox(pParent, nWinStyle|WB_DROPDOWN|WB_NOBORDER) 56 { 57 EnableAutoSize(sal_False); 58 EnableAutocomplete(sal_True); 59 SetDropDownLineCount(5); 60 } 61 62 //------------------------------------------------------------------ 63 long ComboBoxControl::PreNotify( NotifyEvent& rNEvt ) 64 { 65 switch (rNEvt.GetType()) 66 { 67 case EVENT_KEYINPUT: 68 if (!IsInDropDown()) 69 { 70 const KeyEvent *pEvt = rNEvt.GetKeyEvent(); 71 const KeyCode rKey = pEvt->GetKeyCode(); 72 73 if ((rKey.GetCode() == KEY_UP || rKey.GetCode() == KEY_DOWN) && 74 (!pEvt->GetKeyCode().IsShift() && pEvt->GetKeyCode().IsMod1())) 75 { 76 // select next resp. previous entry 77 int nPos = GetEntryPos(GetText()); 78 nPos = nPos + (rKey.GetCode() == KEY_DOWN ? 1 : -1); 79 if (nPos < 0) 80 nPos = 0; 81 if (nPos >= GetEntryCount()) 82 nPos = GetEntryCount() - 1; 83 SetText(GetEntry(sal::static_int_cast< sal_uInt16 >(nPos))); 84 return 1; 85 } 86 } 87 break; 88 } 89 return ComboBox::PreNotify(rNEvt); 90 } 91 92 //================================================================== 93 //= ComboBoxCellController 94 //================================================================== 95 //------------------------------------------------------------------ 96 ComboBoxCellController::ComboBoxCellController(ComboBoxControl* pWin) 97 :CellController(pWin) 98 { 99 } 100 101 //------------------------------------------------------------------ 102 sal_Bool ComboBoxCellController::MoveAllowed(const KeyEvent& rEvt) const 103 { 104 ComboBoxControl& rBox = GetComboBox(); 105 switch (rEvt.GetKeyCode().GetCode()) 106 { 107 case KEY_END: 108 case KEY_RIGHT: 109 { 110 Selection aSel = rBox.GetSelection(); 111 return !aSel && aSel.Max() == rBox.GetText().Len(); 112 } 113 case KEY_HOME: 114 case KEY_LEFT: 115 { 116 Selection aSel = rBox.GetSelection(); 117 return !aSel && aSel.Min() == 0; 118 } 119 case KEY_UP: 120 case KEY_DOWN: 121 if (rBox.IsInDropDown()) 122 return sal_False; 123 if (!rEvt.GetKeyCode().IsShift() && 124 rEvt.GetKeyCode().IsMod1()) 125 return sal_False; 126 // drop down the list box 127 else if (rEvt.GetKeyCode().IsMod2() && rEvt.GetKeyCode().GetCode() == KEY_DOWN) 128 return sal_False; 129 case KEY_PAGEUP: 130 case KEY_PAGEDOWN: 131 case KEY_RETURN: 132 if (rBox.IsInDropDown()) 133 return sal_False; 134 default: 135 return sal_True; 136 } 137 } 138 139 //------------------------------------------------------------------ 140 sal_Bool ComboBoxCellController::IsModified() const 141 { 142 return GetComboBox().GetSavedValue() != GetComboBox().GetText(); 143 } 144 145 //------------------------------------------------------------------ 146 void ComboBoxCellController::ClearModified() 147 { 148 GetComboBox().SaveValue(); 149 } 150 151 //------------------------------------------------------------------ 152 void ComboBoxCellController::SetModifyHdl(const Link& rLink) 153 { 154 GetComboBox().SetModifyHdl(rLink); 155 } 156 157 //================================================================== 158 //= ListBoxControl 159 //================================================================== 160 //------------------------------------------------------------------ 161 ListBoxControl::ListBoxControl(Window* pParent, WinBits nWinStyle) 162 :ListBox(pParent, nWinStyle|WB_DROPDOWN|WB_NOBORDER) 163 { 164 EnableAutoSize(sal_False); 165 EnableMultiSelection(sal_False); 166 SetDropDownLineCount(20); 167 } 168 169 //------------------------------------------------------------------ 170 long ListBoxControl::PreNotify( NotifyEvent& rNEvt ) 171 { 172 switch (rNEvt.GetType()) 173 { 174 case EVENT_KEYINPUT: 175 if (!IsInDropDown()) 176 { 177 const KeyEvent *pEvt = rNEvt.GetKeyEvent(); 178 const KeyCode rKey = pEvt->GetKeyCode(); 179 180 if ((rKey.GetCode() == KEY_UP || rKey.GetCode() == KEY_DOWN) && 181 (!pEvt->GetKeyCode().IsShift() && pEvt->GetKeyCode().IsMod1())) 182 { 183 // select next resp. previous entry 184 int nPos = GetSelectEntryPos(); 185 nPos = nPos + (rKey.GetCode() == KEY_DOWN ? 1 : -1); 186 if (nPos < 0) 187 nPos = 0; 188 if (nPos >= GetEntryCount()) 189 nPos = GetEntryCount() - 1; 190 SelectEntryPos(sal::static_int_cast< sal_uInt16 >(nPos)); 191 Select(); // for calling Modify 192 return 1; 193 } 194 else if (GetParent()->PreNotify(rNEvt)) 195 return 1; 196 } 197 break; 198 } 199 return ListBox::PreNotify(rNEvt); 200 } 201 202 //================================================================== 203 //= ListBoxCellController 204 //================================================================== 205 //------------------------------------------------------------------ 206 ListBoxCellController::ListBoxCellController(ListBoxControl* pWin) 207 :CellController(pWin) 208 { 209 } 210 211 //------------------------------------------------------------------ 212 sal_Bool ListBoxCellController::MoveAllowed(const KeyEvent& rEvt) const 213 { 214 ListBoxControl& rBox = GetListBox(); 215 switch (rEvt.GetKeyCode().GetCode()) 216 { 217 case KEY_UP: 218 case KEY_DOWN: 219 if (!rEvt.GetKeyCode().IsShift() && 220 rEvt.GetKeyCode().IsMod1()) 221 return sal_False; 222 // drop down the list box 223 else 224 if (rEvt.GetKeyCode().IsMod2() && rEvt.GetKeyCode().GetCode() == KEY_DOWN) 225 return sal_False; 226 case KEY_PAGEUP: 227 case KEY_PAGEDOWN: 228 if (rBox.IsTravelSelect()) 229 return sal_False; 230 default: 231 return sal_True; 232 } 233 } 234 235 //------------------------------------------------------------------ 236 sal_Bool ListBoxCellController::IsModified() const 237 { 238 return GetListBox().GetSelectEntryPos() != GetListBox().GetSavedValue(); 239 } 240 241 //------------------------------------------------------------------ 242 void ListBoxCellController::ClearModified() 243 { 244 GetListBox().SaveValue(); 245 } 246 247 //------------------------------------------------------------------ 248 void ListBoxCellController::SetModifyHdl(const Link& rLink) 249 { 250 GetListBox().SetSelectHdl(rLink); 251 } 252 253 //================================================================== 254 //= CheckBoxControl 255 //================================================================== 256 //------------------------------------------------------------------ 257 CheckBoxControl::CheckBoxControl(Window* pParent, WinBits nWinStyle) 258 :Control(pParent, nWinStyle) 259 { 260 const Wallpaper& rParentBackground = pParent->GetBackground(); 261 if ( (pParent->GetStyle() & WB_CLIPCHILDREN) || rParentBackground.IsFixed() ) 262 SetBackground( rParentBackground ); 263 else 264 { 265 SetPaintTransparent( sal_True ); 266 SetBackground(); 267 } 268 269 EnableChildTransparentMode(); 270 271 pBox = new TriStateBox(this,WB_CENTER|WB_VCENTER); 272 pBox->EnableChildTransparentMode(); 273 pBox->SetPaintTransparent( sal_True ); 274 pBox->SetClickHdl( LINK( this, CheckBoxControl, OnClick ) ); 275 pBox->Show(); 276 } 277 278 //------------------------------------------------------------------ 279 CheckBoxControl::~CheckBoxControl() 280 { 281 delete pBox; 282 } 283 284 //------------------------------------------------------------------ 285 IMPL_LINK( CheckBoxControl, OnClick, void*, EMPTYARG ) 286 { 287 m_aClickLink.Call(pBox); 288 return m_aModifyLink.Call(pBox); 289 } 290 291 //------------------------------------------------------------------ 292 void CheckBoxControl::Resize() 293 { 294 Control::Resize(); 295 pBox->SetPosSizePixel(Point(0,0),GetSizePixel()); 296 } 297 298 //------------------------------------------------------------------------------ 299 void CheckBoxControl::DataChanged( const DataChangedEvent& _rEvent ) 300 { 301 if ( _rEvent.GetType() == DATACHANGED_SETTINGS ) 302 pBox->SetSettings( GetSettings() ); 303 } 304 305 //------------------------------------------------------------------------------ 306 void CheckBoxControl::StateChanged( StateChangedType nStateChange ) 307 { 308 Control::StateChanged(nStateChange); 309 if ( nStateChange == STATE_CHANGE_ZOOM ) 310 pBox->SetZoom(GetZoom()); 311 } 312 313 //------------------------------------------------------------------ 314 void CheckBoxControl::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags ) 315 { 316 pBox->Draw(pDev,rPos,rSize,nFlags); 317 } 318 319 //------------------------------------------------------------------ 320 void CheckBoxControl::GetFocus() 321 { 322 pBox->GrabFocus(); 323 } 324 325 //------------------------------------------------------------------ 326 void CheckBoxControl::Paint(const Rectangle& rClientRect) 327 { 328 Control::Paint(rClientRect); 329 if (HasFocus()) 330 ShowFocus(aFocusRect); 331 } 332 333 //------------------------------------------------------------------ 334 long CheckBoxControl::PreNotify(NotifyEvent& rEvt) 335 { 336 switch (rEvt.GetType()) 337 { 338 case EVENT_GETFOCUS: 339 ShowFocus(aFocusRect); 340 break; 341 case EVENT_LOSEFOCUS: 342 HideFocus(); 343 } 344 return Control::PreNotify(rEvt); 345 } 346 347 //================================================================== 348 //= CheckBoxCellController 349 //================================================================== 350 //------------------------------------------------------------------ 351 sal_Bool CheckBoxCellController::WantMouseEvent() const 352 { 353 return sal_True; 354 } 355 356 //------------------------------------------------------------------ 357 CheckBox& CheckBoxCellController::GetCheckBox() const 358 { 359 return ((CheckBoxControl &)GetWindow()).GetBox(); 360 } 361 362 //------------------------------------------------------------------ 363 sal_Bool CheckBoxCellController::IsModified() const 364 { 365 return GetCheckBox().GetSavedValue() != GetCheckBox().GetState(); 366 } 367 368 //------------------------------------------------------------------ 369 void CheckBoxCellController::ClearModified() 370 { 371 GetCheckBox().SaveValue(); 372 } 373 374 //------------------------------------------------------------------ 375 void CheckBoxCellController::SetModifyHdl(const Link& rLink) 376 { 377 ((CheckBoxControl &)GetWindow()).SetModifyHdl(rLink); 378 } 379 380 //================================================================== 381 //= MultiLineEditImplementation 382 //================================================================== 383 //------------------------------------------------------------------ 384 String MultiLineEditImplementation::GetText( LineEnd aSeparator ) const 385 { 386 return const_cast< MultiLineEditImplementation* >( this )->GetEditWindow().GetText( aSeparator ); 387 } 388 389 //------------------------------------------------------------------ 390 String MultiLineEditImplementation::GetSelected( LineEnd aSeparator ) const 391 { 392 return const_cast< MultiLineEditImplementation* >( this )->GetEditWindow().GetSelected( aSeparator ); 393 } 394 395 //================================================================== 396 //= EditCellController 397 //================================================================== 398 //------------------------------------------------------------------ 399 EditCellController::EditCellController( Edit* _pEdit ) 400 :CellController( _pEdit ) 401 ,m_pEditImplementation( new EditImplementation( *_pEdit ) ) 402 ,m_bOwnImplementation( sal_True ) 403 { 404 } 405 406 //------------------------------------------------------------------ 407 EditCellController::EditCellController( MultiLineTextCell* _pEdit ) 408 :CellController( _pEdit ) 409 ,m_pEditImplementation( new MultiLineEditImplementation( *_pEdit ) ) 410 ,m_bOwnImplementation( sal_True ) 411 { 412 } 413 414 //------------------------------------------------------------------ 415 EditCellController::EditCellController( IEditImplementation* _pImplementation ) 416 :CellController( &_pImplementation->GetControl() ) 417 ,m_pEditImplementation( _pImplementation ) 418 ,m_bOwnImplementation( sal_False ) 419 { 420 } 421 422 //----------------------------------------------------------------------------- 423 EditCellController::~EditCellController( ) 424 { 425 if ( m_bOwnImplementation ) 426 DELETEZ( m_pEditImplementation ); 427 } 428 429 //----------------------------------------------------------------------------- 430 void EditCellController::SetModified() 431 { 432 m_pEditImplementation->SetModified(); 433 } 434 435 //----------------------------------------------------------------------------- 436 void EditCellController::ClearModified() 437 { 438 m_pEditImplementation->ClearModified(); 439 } 440 441 //------------------------------------------------------------------ 442 sal_Bool EditCellController::MoveAllowed(const KeyEvent& rEvt) const 443 { 444 sal_Bool bResult; 445 switch (rEvt.GetKeyCode().GetCode()) 446 { 447 case KEY_END: 448 case KEY_RIGHT: 449 { 450 Selection aSel = m_pEditImplementation->GetSelection(); 451 bResult = !aSel && aSel.Max() == m_pEditImplementation->GetText( LINEEND_LF ).Len(); 452 } break; 453 case KEY_HOME: 454 case KEY_LEFT: 455 { 456 Selection aSel = m_pEditImplementation->GetSelection(); 457 bResult = !aSel && aSel.Min() == 0; 458 } break; 459 default: 460 bResult = sal_True; 461 } 462 return bResult; 463 } 464 465 //------------------------------------------------------------------ 466 sal_Bool EditCellController::IsModified() const 467 { 468 return m_pEditImplementation->IsModified(); 469 } 470 471 //------------------------------------------------------------------ 472 void EditCellController::SetModifyHdl(const Link& rLink) 473 { 474 m_pEditImplementation->SetModifyHdl(rLink); 475 } 476 477 //================================================================== 478 //= SpinCellController 479 //================================================================== 480 //------------------------------------------------------------------ 481 SpinCellController::SpinCellController(SpinField* pWin) 482 :CellController(pWin) 483 { 484 } 485 486 //----------------------------------------------------------------------------- 487 void SpinCellController::SetModified() 488 { 489 GetSpinWindow().SetModifyFlag(); 490 } 491 492 //----------------------------------------------------------------------------- 493 void SpinCellController::ClearModified() 494 { 495 GetSpinWindow().ClearModifyFlag(); 496 } 497 498 //------------------------------------------------------------------ 499 sal_Bool SpinCellController::MoveAllowed(const KeyEvent& rEvt) const 500 { 501 sal_Bool bResult; 502 switch (rEvt.GetKeyCode().GetCode()) 503 { 504 case KEY_END: 505 case KEY_RIGHT: 506 { 507 Selection aSel = GetSpinWindow().GetSelection(); 508 bResult = !aSel && aSel.Max() == GetSpinWindow().GetText().Len(); 509 } break; 510 case KEY_HOME: 511 case KEY_LEFT: 512 { 513 Selection aSel = GetSpinWindow().GetSelection(); 514 bResult = !aSel && aSel.Min() == 0; 515 } break; 516 default: 517 bResult = sal_True; 518 } 519 return bResult; 520 } 521 522 //------------------------------------------------------------------ 523 sal_Bool SpinCellController::IsModified() const 524 { 525 return GetSpinWindow().IsModified(); 526 } 527 528 //------------------------------------------------------------------ 529 void SpinCellController::SetModifyHdl(const Link& rLink) 530 { 531 GetSpinWindow().SetModifyHdl(rLink); 532 } 533 534 //================================================================== 535 //= FormattedFieldCellController 536 //================================================================== 537 //------------------------------------------------------------------ 538 FormattedFieldCellController::FormattedFieldCellController( FormattedField* _pFormatted ) 539 :EditCellController( _pFormatted ) 540 { 541 } 542 543 //------------------------------------------------------------------ 544 void FormattedFieldCellController::CommitModifications() 545 { 546 static_cast< FormattedField& >( GetWindow() ).Commit(); 547 } 548 549 //================================================================== 550 //= MultiLineTextCell 551 //================================================================== 552 //------------------------------------------------------------------ 553 void MultiLineTextCell::Modify() 554 { 555 GetTextEngine()->SetModified( sal_True ); 556 MultiLineEdit::Modify(); 557 } 558 559 //------------------------------------------------------------------ 560 sal_Bool MultiLineTextCell::dispatchKeyEvent( const KeyEvent& _rEvent ) 561 { 562 Selection aOldSelection( GetSelection() ); 563 564 sal_Bool bWasModified = IsModified(); 565 ClearModifyFlag( ); 566 567 sal_Bool bHandled = GetTextView()->KeyInput( _rEvent ); 568 569 sal_Bool bIsModified = IsModified(); 570 if ( bWasModified && !bIsModified ) 571 // not sure whether this can really happen 572 SetModifyFlag(); 573 574 if ( bHandled ) // the view claimed it handled the key input 575 { 576 // unfortunately, KeyInput also returns <TRUE/> (means "I handled this key input") 577 // when nothing really changed. Let's care for this. 578 Selection aNewSelection( GetSelection() ); 579 if ( aNewSelection != aOldSelection // selection changed 580 || bIsModified // or some other modification 581 ) 582 return sal_True; 583 } 584 return sal_False; 585 } 586 587 //------------------------------------------------------------------ 588 long MultiLineTextCell::PreNotify( NotifyEvent& rNEvt ) 589 { 590 if ( rNEvt.GetType() == EVENT_KEYINPUT ) 591 { 592 if ( IsWindowOrChild( rNEvt.GetWindow() ) ) 593 { 594 // give the text view a chance to handle the keys 595 // this is necessary since a lot of keys which are normally handled 596 // by this view (in KeyInput) are intercepted by the EditBrowseBox, 597 // which uses them for other reasons. An example is the KeyUp key, 598 // which is used by both the text view and the edit browse box 599 600 const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent(); 601 const KeyCode& rKeyCode = pKeyEvent->GetKeyCode(); 602 sal_uInt16 nCode = rKeyCode.GetCode(); 603 604 if ( ( nCode == KEY_RETURN ) && ( rKeyCode.GetModifier() == KEY_MOD1 ) ) 605 { 606 KeyEvent aEvent( pKeyEvent->GetCharCode(), 607 KeyCode( KEY_RETURN ), 608 pKeyEvent->GetRepeat() 609 ); 610 if ( dispatchKeyEvent( aEvent ) ) 611 return 1; 612 } 613 614 if ( ( nCode != KEY_TAB ) && ( nCode != KEY_RETURN ) ) // everything but tab and enter 615 { 616 if ( dispatchKeyEvent( *pKeyEvent ) ) 617 return 1; 618 } 619 } 620 } 621 return MultiLineEdit::PreNotify( rNEvt ); 622 } 623 624 // ....................................................................... 625 } // namespace svt 626 // ....................................................................... 627 628 629