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