1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #pragma once 21 22 #include <config_options.h> 23 #include <memory> 24 #include <svtools/svtdllapi.h> 25 #include <tools/ref.hxx> 26 27 #include <svtools/brwbox.hxx> 28 #include <svtools/brwhead.hxx> 29 #include <tools/lineend.hxx> 30 #include <vcl/InterimItemWindow.hxx> 31 #include <vcl/weldutils.hxx> 32 #include <o3tl/typed_flags_set.hxx> 33 34 class BrowserDataWin; 35 36 // EditBrowseBoxFlags (EBBF) 37 enum class EditBrowseBoxFlags 38 { 39 NONE = 0x0000, 40 /** if this bit is _not_ set, the handle column will be invalidated upon 41 changing the row in the browse box. This is for forcing the row picture to 42 be repainted. If you do not have row pictures or text, you don't need this 43 invalidation, then you would specify this bit to prevent flicker 44 */ 45 NO_HANDLE_COLUMN_CONTENT = 0x0001, 46 /** set this bit to activate the cell on a MouseButtonDown, not a MouseButtonUp event 47 */ 48 ACTIVATE_ON_BUTTONDOWN = 0x0002, 49 /** if this bit is set and EditBrowseBoxFlags::NO_HANDLE_COLUMN_CONTENT is _not_ set, the handle 50 column is drawn with the text contained in column 0 instead of an image 51 */ 52 HANDLE_COLUMN_TEXT = 0x0004, 53 54 /** If this bit is set, tab traveling is somewhat modified<br/> 55 If the control gets the focus because the user pressed the TAB key, then the 56 first or last cell (depending on whether the traveling was cycling forward or backward) 57 gets activated. 58 @see Window::GetGetFocusFlags 59 @see GETFOCUS_* 60 */ 61 SMART_TAB_TRAVEL = 0x0008, 62 63 }; 64 namespace o3tl 65 { 66 template<> struct typed_flags<EditBrowseBoxFlags> : is_typed_flags<EditBrowseBoxFlags, 0x0f> {}; 67 } 68 69 namespace svt 70 { 71 class SVT_DLLPUBLIC CellController : public SvRefBase 72 { 73 friend class EditBrowseBox; 74 Link<LinkParamNone*, void> maModifyHdl; 75 76 VclPtr<Control> pWindow; 77 bool bSuspended; // <true> if the window is hidden and disabled 78 79 public: 80 81 CellController(Control* pW); 82 virtual ~CellController() override; 83 GetWindow() const84 Control& GetWindow() const { return *const_cast< CellController* >( this )->pWindow; } 85 86 virtual void SaveValue() = 0; 87 virtual bool IsValueChangedFromSaved() const = 0; 88 89 // commit any current changes. Especially, do any reformatting you need (from input formatting 90 // to output formatting) here 91 virtual void CommitModifications(); 92 93 // suspending the controller is not cumulative! 94 void suspend( ); 95 void resume( ); isSuspended() const96 bool isSuspended( ) const { return bSuspended; } 97 98 protected: 99 virtual bool MoveAllowed(const KeyEvent& rEvt) const; SetModifyHdl(const Link<LinkParamNone *,void> & rLink)100 void SetModifyHdl(const Link<LinkParamNone*,void>& rLink) { maModifyHdl = rLink; } 101 virtual void ActivatingMouseEvent(const BrowserMouseEvent& rEvt, bool bUp); callModifyHdl()102 virtual void callModifyHdl() { maModifyHdl.Call(nullptr); } 103 }; 104 105 typedef tools::SvRef<CellController> CellControllerRef; 106 107 108 //= IEditImplementation 109 UNLESS_MERGELIBS(SVT_DLLPUBLIC)110 class UNLESS_MERGELIBS(SVT_DLLPUBLIC) IEditImplementation 111 { 112 public: 113 virtual ~IEditImplementation() = 0; 114 115 virtual Control& GetControl() = 0; 116 117 virtual OUString GetText( LineEnd aSeparator ) const = 0; 118 virtual void SetText( const OUString& _rStr ) = 0; 119 120 virtual bool IsReadOnly() const = 0; 121 virtual void SetReadOnly( bool bReadOnly ) = 0; 122 123 virtual sal_Int32 GetMaxTextLen() const = 0; 124 virtual void SetMaxTextLen( sal_Int32 _nMaxLen ) = 0; 125 126 virtual Selection GetSelection() const = 0; 127 virtual void SetSelection( const Selection& _rSelection ) = 0; 128 129 virtual void ReplaceSelected( const OUString& _rStr ) = 0; 130 virtual OUString GetSelected( LineEnd aSeparator ) const = 0; 131 132 virtual bool IsValueChangedFromSaved() const = 0; 133 virtual void SaveValue() = 0; 134 135 virtual bool CanUp() const = 0; 136 virtual bool CanDown() const = 0; 137 138 virtual void Cut() = 0; 139 virtual void Copy() = 0; 140 virtual void Paste() = 0; 141 142 // sets a link to call when the text is changed by the user 143 void SetModifyHdl(const Link<LinkParamNone*,void>& rLink) 144 { 145 m_aModify1Hdl = rLink; 146 } 147 148 // sets an additional link to call when the text is changed by the user 149 void SetAuxModifyHdl(const Link<LinkParamNone*,void>& rLink) 150 { 151 m_aModify2Hdl = rLink; 152 } 153 154 private: 155 Link<LinkParamNone*,void> m_aModify1Hdl; 156 Link<LinkParamNone*,void> m_aModify2Hdl; 157 158 protected: 159 void CallModifyHdls() 160 { 161 m_aModify1Hdl.Call(nullptr); 162 m_aModify2Hdl.Call(nullptr); 163 } 164 }; 165 166 class SVT_DLLPUBLIC ControlBase : public InterimItemWindow 167 { 168 public: 169 ControlBase(BrowserDataWin* pParent, const OUString& rUIXMLDescription, const OString& rID); 170 171 virtual void SetEditableReadOnly(bool bReadOnly); 172 173 virtual bool ProcessKey(const KeyEvent& rKEvt); 174 175 virtual void SetPointFont(const vcl::Font& rFont) = 0; 176 177 // chain after the FocusInHdl 178 void SetFocusInHdl(const Link<LinkParamNone*,void>& rHdl) 179 { 180 m_aFocusInHdl = rHdl; 181 } 182 183 // chain after the FocusOutHdl 184 void SetFocusOutHdl(const Link<LinkParamNone*,void>& rHdl) 185 { 186 m_aFocusOutHdl = rHdl; 187 } 188 189 void SetMousePressHdl(const Link<const MouseEvent&,void>& rHdl) 190 { 191 m_aMousePressHdl = rHdl; 192 } 193 194 void SetMouseReleaseHdl(const Link<const MouseEvent&,void>& rHdl) 195 { 196 m_aMouseReleaseHdl = rHdl; 197 } 198 199 void SetMouseMoveHdl(const Link<const MouseEvent&,void>& rHdl) 200 { 201 m_aMouseMoveHdl = rHdl; 202 } 203 204 protected: 205 DECL_LINK(KeyInputHdl, const KeyEvent&, bool); 206 DECL_LINK(FocusInHdl, weld::Widget&, void); 207 DECL_LINK(FocusOutHdl, weld::Widget&, void); 208 DECL_LINK(MousePressHdl, const MouseEvent&, bool); 209 DECL_LINK(MouseReleaseHdl, const MouseEvent&, bool); 210 DECL_LINK(MouseMoveHdl, const MouseEvent&, bool); 211 private: 212 Link<LinkParamNone*,void> m_aFocusInHdl; 213 Link<LinkParamNone*,void> m_aFocusOutHdl; 214 Link<const MouseEvent&,void> m_aMousePressHdl; 215 Link<const MouseEvent&,void> m_aMouseReleaseHdl; 216 Link<const MouseEvent&,void> m_aMouseMoveHdl; 217 }; 218 219 class SVT_DLLPUBLIC EditControlBase : public ControlBase 220 { 221 public: 222 EditControlBase(BrowserDataWin* pParent); 223 224 virtual void SetEditableReadOnly(bool bReadOnly) override 225 { 226 m_pEntry->set_editable(!bReadOnly); 227 } 228 229 virtual void SetPointFont(const vcl::Font& rFont) override 230 { 231 m_pEntry->set_font(rFont); 232 } 233 234 virtual void dispose() override; 235 236 weld::Entry& get_widget() { return *m_pEntry; } 237 238 virtual void connect_changed(const Link<weld::Entry&, void>& rLink) = 0; 239 virtual void connect_focus_out(const Link<weld::Widget&, void>& rLink) = 0; 240 241 protected: 242 void InitEditControlBase(weld::Entry* pEntry); 243 244 private: 245 weld::Entry* m_pEntry; 246 }; 247 248 class SVT_DLLPUBLIC EditControl : public EditControlBase 249 { 250 public: 251 EditControl(BrowserDataWin* pParent); 252 253 virtual void dispose() override; 254 255 virtual void connect_changed(const Link<weld::Entry&, void>& rLink) override 256 { 257 m_xWidget->connect_changed(rLink); 258 } 259 260 virtual void connect_focus_out(const Link<weld::Widget&, void>& rLink) override 261 { 262 m_xWidget->connect_focus_out(rLink); 263 } 264 265 protected: 266 std::unique_ptr<weld::Entry> m_xWidget; 267 }; 268 269 class SVT_DLLPUBLIC EntryImplementation : public IEditImplementation 270 { 271 EditControlBase& m_rEdit; 272 int m_nMaxTextLen; 273 274 DECL_LINK(ModifyHdl, weld::Entry&, void); 275 public: 276 EntryImplementation(EditControlBase& rEdit) 277 : m_rEdit(rEdit) 278 , m_nMaxTextLen(0) 279 { 280 m_rEdit.connect_changed(LINK(this, EntryImplementation, ModifyHdl)); 281 } 282 283 virtual Control& GetControl() override 284 { 285 return m_rEdit; 286 } 287 288 virtual OUString GetText( LineEnd /*aSeparator*/ ) const override 289 { 290 // ignore the line end - this base implementation does not support it 291 return m_rEdit.get_widget().get_text(); 292 } 293 294 virtual void SetText( const OUString& _rStr ) override 295 { 296 return m_rEdit.get_widget().set_text(_rStr); 297 } 298 299 virtual bool IsReadOnly() const override 300 { 301 return !m_rEdit.get_widget().get_editable(); 302 } 303 304 virtual void SetReadOnly( bool bReadOnly ) override 305 { 306 m_rEdit.SetEditableReadOnly(bReadOnly); 307 } 308 309 virtual sal_Int32 GetMaxTextLen() const override 310 { 311 return m_nMaxTextLen; 312 } 313 314 virtual void SetMaxTextLen( sal_Int32 nMaxLen ) override 315 { 316 m_nMaxTextLen = nMaxLen; 317 m_rEdit.get_widget().set_max_length(m_nMaxTextLen); 318 } 319 320 virtual Selection GetSelection() const override 321 { 322 int nStartPos, nEndPos; 323 m_rEdit.get_widget().get_selection_bounds(nStartPos, nEndPos); 324 return Selection(nStartPos, nEndPos); 325 } 326 327 virtual void SetSelection( const Selection& rSelection ) override 328 { 329 auto nMin = rSelection.Min(); 330 auto nMax = rSelection.Max(); 331 m_rEdit.get_widget().select_region(nMin < 0 ? 0 : nMin, nMax == SELECTION_MAX ? -1 : nMax); 332 } 333 334 virtual void ReplaceSelected( const OUString& rStr ) override 335 { 336 m_rEdit.get_widget().replace_selection(rStr); 337 } 338 339 virtual OUString GetSelected( LineEnd /*aSeparator*/ ) const override 340 // ignore the line end - this base implementation does not support it 341 { 342 int nStartPos, nEndPos; 343 weld::Entry& rEntry = m_rEdit.get_widget(); 344 rEntry.get_selection_bounds(nStartPos, nEndPos); 345 return rEntry.get_text().copy(nStartPos, nEndPos - nStartPos); 346 } 347 348 virtual bool IsValueChangedFromSaved() const override 349 { 350 return m_rEdit.get_widget().get_value_changed_from_saved(); 351 } 352 353 virtual void SaveValue() override 354 { 355 m_rEdit.get_widget().save_value(); 356 } 357 358 virtual bool CanUp() const override 359 { 360 return false; 361 } 362 363 virtual bool CanDown() const override 364 { 365 return false; 366 } 367 368 virtual void Cut() override 369 { 370 m_rEdit.get_widget().cut_clipboard(); 371 } 372 373 virtual void Copy() override 374 { 375 m_rEdit.get_widget().copy_clipboard(); 376 } 377 378 virtual void Paste() override 379 { 380 m_rEdit.get_widget().paste_clipboard(); 381 } 382 }; 383 384 //= MultiLineTextCell 385 386 /** a multi line edit which can be used in a cell of an EditBrowseBox 387 */ 388 class UNLESS_MERGELIBS(SVT_DLLPUBLIC) MultiLineTextCell final : public ControlBase 389 { 390 public: 391 MultiLineTextCell(BrowserDataWin* pParent); 392 393 virtual void SetEditableReadOnly(bool bReadOnly) override 394 { 395 m_xWidget->set_editable(!bReadOnly); 396 } 397 398 virtual void SetPointFont(const vcl::Font& rFont) override 399 { 400 m_xWidget->set_font(rFont); 401 } 402 403 virtual void GetFocus() override; 404 405 virtual void dispose() override; 406 407 void connect_changed(const Link<weld::TextView&, void>& rLink) 408 { 409 m_xWidget->connect_changed(rLink); 410 } 411 412 weld::TextView& get_widget() { return *m_xWidget; } 413 414 private: 415 std::unique_ptr<weld::TextView> m_xWidget; 416 417 virtual bool ProcessKey(const KeyEvent& rKEvt) override; 418 }; 419 420 class SVT_DLLPUBLIC MultiLineEditImplementation : public IEditImplementation 421 { 422 MultiLineTextCell& m_rEdit; 423 int m_nMaxTextLen; 424 425 DECL_LINK(ModifyHdl, weld::TextView&, void); 426 public: 427 MultiLineEditImplementation(MultiLineTextCell& rEdit) 428 : m_rEdit(rEdit) 429 , m_nMaxTextLen(0) 430 { 431 m_rEdit.connect_changed(LINK(this, MultiLineEditImplementation, ModifyHdl)); 432 } 433 434 virtual Control& GetControl() override 435 { 436 return m_rEdit; 437 } 438 439 virtual OUString GetText(LineEnd aSeparator) const override; 440 441 virtual void SetText(const OUString& rStr) override 442 { 443 return m_rEdit.get_widget().set_text(rStr); 444 } 445 446 virtual bool IsReadOnly() const override 447 { 448 return !m_rEdit.get_widget().get_editable(); 449 } 450 451 virtual void SetReadOnly( bool bReadOnly ) override 452 { 453 m_rEdit.SetEditableReadOnly(bReadOnly); 454 } 455 456 virtual sal_Int32 GetMaxTextLen() const override 457 { 458 return m_nMaxTextLen; 459 } 460 461 virtual void SetMaxTextLen( sal_Int32 nMaxLen ) override 462 { 463 m_nMaxTextLen = nMaxLen; 464 m_rEdit.get_widget().set_max_length(m_nMaxTextLen); 465 } 466 467 virtual Selection GetSelection() const override 468 { 469 int nStartPos, nEndPos; 470 m_rEdit.get_widget().get_selection_bounds(nStartPos, nEndPos); 471 return Selection(nStartPos, nEndPos); 472 } 473 474 virtual void SetSelection( const Selection& rSelection ) override 475 { 476 auto nMin = rSelection.Min(); 477 auto nMax = rSelection.Max(); 478 m_rEdit.get_widget().select_region(nMin < 0 ? 0 : nMin, nMax == SELECTION_MAX ? -1 : nMax); 479 } 480 481 virtual void ReplaceSelected( const OUString& rStr ) override 482 { 483 m_rEdit.get_widget().replace_selection(rStr); 484 } 485 486 virtual OUString GetSelected( LineEnd aSeparator ) const override; 487 488 virtual bool IsValueChangedFromSaved() const override 489 { 490 return m_rEdit.get_widget().get_value_changed_from_saved(); 491 } 492 493 virtual void SaveValue() override 494 { 495 m_rEdit.get_widget().save_value(); 496 } 497 498 virtual bool CanUp() const override 499 { 500 return m_rEdit.get_widget().can_move_cursor_with_up(); 501 } 502 503 virtual bool CanDown() const override 504 { 505 return m_rEdit.get_widget().can_move_cursor_with_down(); 506 } 507 508 virtual void Cut() override 509 { 510 m_rEdit.get_widget().cut_clipboard(); 511 } 512 513 virtual void Copy() override 514 { 515 m_rEdit.get_widget().copy_clipboard(); 516 } 517 518 virtual void Paste() override 519 { 520 m_rEdit.get_widget().paste_clipboard(); 521 } 522 }; 523 524 525 //= EditCellController 526 class SVT_DLLPUBLIC EditCellController : public CellController 527 { 528 IEditImplementation* m_pEditImplementation; 529 bool m_bOwnImplementation; // did we create m_pEditImplementation? 530 531 public: 532 EditCellController( EditControlBase* _pEdit ); 533 EditCellController( IEditImplementation* _pImplementation ); 534 virtual ~EditCellController( ) override; 535 536 const IEditImplementation* GetEditImplementation( ) const { return m_pEditImplementation; } 537 IEditImplementation* GetEditImplementation( ) { return m_pEditImplementation; } 538 539 virtual bool IsValueChangedFromSaved() const override; 540 virtual void SaveValue() override; 541 542 void Modify() 543 { 544 ModifyHdl(nullptr); 545 } 546 547 protected: 548 virtual bool MoveAllowed(const KeyEvent& rEvt) const override; 549 private: 550 DECL_LINK(ModifyHdl, LinkParamNone*, void); 551 }; 552 553 //= CheckBoxControl 554 class SVT_DLLPUBLIC CheckBoxControl final : public ControlBase 555 { 556 std::unique_ptr<weld::CheckButton> m_xBox; 557 weld::TriStateEnabled m_aModeState; 558 Link<weld::CheckButton&,void> m_aToggleLink; 559 Link<LinkParamNone*,void> m_aModify1Hdl; 560 Link<LinkParamNone*,void> m_aModify2Hdl; 561 562 public: 563 CheckBoxControl(BrowserDataWin* pParent); 564 virtual ~CheckBoxControl() override; 565 virtual void dispose() override; 566 567 virtual void SetPointFont(const vcl::Font& rFont) override; 568 569 void SetToggleHdl(const Link<weld::CheckButton&,void>& rHdl) {m_aToggleLink = rHdl;} 570 571 // sets a link to call when the text is changed by the user 572 void SetModifyHdl(const Link<LinkParamNone*,void>& rHdl) 573 { 574 m_aModify1Hdl = rHdl; 575 } 576 577 // sets an additional link to call when the text is changed by the user 578 void SetAuxModifyHdl(const Link<LinkParamNone*,void>& rLink) 579 { 580 m_aModify2Hdl = rLink; 581 } 582 583 void SetState(TriState eState); 584 TriState GetState() const { return m_xBox->get_state(); } 585 586 void EnableTriState(bool bTriState); 587 588 weld::CheckButton& GetBox() {return *m_xBox;}; 589 590 // for pseudo-click when initially clicking in a cell activates 591 // the cell and performs a state change on the button as if 592 // it was clicked on 593 void Clicked(); 594 595 private: 596 DECL_LINK(OnToggle, weld::Toggleable&, void); 597 598 void CallModifyHdls() 599 { 600 m_aModify1Hdl.Call(nullptr); 601 m_aModify2Hdl.Call(nullptr); 602 } 603 }; 604 605 //= CheckBoxCellController 606 class SVT_DLLPUBLIC CheckBoxCellController final : public CellController 607 { 608 public: 609 610 CheckBoxCellController(CheckBoxControl* pWin); 611 weld::CheckButton& GetCheckBox() const; 612 613 virtual bool IsValueChangedFromSaved() const override; 614 virtual void SaveValue() override; 615 616 private: 617 virtual void ActivatingMouseEvent(const BrowserMouseEvent& rEvt, bool bUp) override; 618 DECL_LINK(ModifyHdl, LinkParamNone*, void); 619 }; 620 621 //= ComboBoxControl 622 class SVT_DLLPUBLIC ComboBoxControl final : public ControlBase 623 { 624 private: 625 std::unique_ptr<weld::ComboBox> m_xWidget; 626 Link<LinkParamNone*,void> m_aModify1Hdl; 627 Link<bool,void> m_aModify2Hdl; 628 629 friend class ComboBoxCellController; 630 631 public: 632 ComboBoxControl(BrowserDataWin* pParent); 633 634 virtual void SetPointFont(const vcl::Font& rFont) override; 635 636 virtual void SetEditableReadOnly(bool bReadOnly) override 637 { 638 m_xWidget->set_entry_editable(!bReadOnly); 639 } 640 641 weld::ComboBox& get_widget() { return *m_xWidget; } 642 643 // sets a link to call when the selection is changed by the user 644 void SetModifyHdl(const Link<LinkParamNone*,void>& rHdl) 645 { 646 m_aModify1Hdl = rHdl; 647 } 648 649 // sets an additional link to call when the selection is changed by the user 650 // bool arg is true when triggered interactively by the user 651 void SetAuxModifyHdl(const Link<bool,void>& rLink) 652 { 653 m_aModify2Hdl = rLink; 654 } 655 656 void TriggerAuxModify() 657 { 658 m_aModify2Hdl.Call(false); 659 } 660 661 virtual void dispose() override; 662 663 private: 664 DECL_LINK(SelectHdl, weld::ComboBox&, void); 665 666 void CallModifyHdls() 667 { 668 m_aModify1Hdl.Call(nullptr); 669 m_aModify2Hdl.Call(true); 670 } 671 }; 672 673 //= ComboBoxCellController 674 class SVT_DLLPUBLIC ComboBoxCellController : public CellController 675 { 676 public: 677 678 ComboBoxCellController(ComboBoxControl* pParent); 679 weld::ComboBox& GetComboBox() const { return static_cast<ComboBoxControl&>(GetWindow()).get_widget(); } 680 681 virtual bool IsValueChangedFromSaved() const override; 682 virtual void SaveValue() override; 683 684 protected: 685 virtual bool MoveAllowed(const KeyEvent& rEvt) const override; 686 private: 687 DECL_LINK(ModifyHdl, LinkParamNone*, void); 688 }; 689 690 //= ListBoxControl 691 class SVT_DLLPUBLIC ListBoxControl final : public ControlBase 692 { 693 private: 694 std::unique_ptr<weld::ComboBox> m_xWidget; 695 Link<LinkParamNone*,void> m_aModify1Hdl; 696 Link<bool,void> m_aModify2Hdl; 697 698 friend class ListBoxCellController; 699 700 public: 701 ListBoxControl(BrowserDataWin* pParent); 702 703 virtual void SetPointFont(const vcl::Font& rFont) override; 704 705 weld::ComboBox& get_widget() { return *m_xWidget; } 706 707 // sets a link to call when the selection is changed by the user 708 void SetModifyHdl(const Link<LinkParamNone*,void>& rHdl) 709 { 710 m_aModify1Hdl = rHdl; 711 } 712 713 // sets an additional link to call when the selection is changed, 714 // bool arg is true when triggered interactively by the user 715 void SetAuxModifyHdl(const Link<bool,void>& rLink) 716 { 717 m_aModify2Hdl = rLink; 718 } 719 720 void TriggerAuxModify() 721 { 722 m_aModify2Hdl.Call(false); 723 } 724 725 virtual void dispose() override; 726 private: 727 DECL_LINK(SelectHdl, weld::ComboBox&, void); 728 729 void CallModifyHdls() 730 { 731 m_aModify1Hdl.Call(nullptr); 732 m_aModify2Hdl.Call(true); 733 } 734 }; 735 736 //= ListBoxCellController 737 class SVT_DLLPUBLIC ListBoxCellController : public CellController 738 { 739 public: 740 741 ListBoxCellController(ListBoxControl* pParent); 742 weld::ComboBox& GetListBox() const { return static_cast<ListBoxControl&>(GetWindow()).get_widget(); } 743 744 virtual bool IsValueChangedFromSaved() const override; 745 virtual void SaveValue() override; 746 747 protected: 748 virtual bool MoveAllowed(const KeyEvent& rEvt) const override; 749 private: 750 DECL_LINK(ListBoxSelectHdl, LinkParamNone*, void); 751 }; 752 753 class SVT_DLLPUBLIC FormattedControlBase : public EditControlBase 754 { 755 public: 756 FormattedControlBase(BrowserDataWin* pParent, bool bSpinVariant); 757 758 virtual void dispose() override; 759 760 virtual void connect_changed(const Link<weld::Entry&, void>& rLink) override; 761 virtual void connect_focus_out(const Link<weld::Widget&, void>& rLink) override; 762 763 weld::EntryFormatter& get_formatter(); 764 765 protected: 766 bool m_bSpinVariant; 767 std::unique_ptr<weld::Entry> m_xEntry; 768 std::unique_ptr<weld::FormattedSpinButton> m_xSpinButton; 769 std::unique_ptr<weld::EntryFormatter> m_xEntryFormatter; 770 771 void InitFormattedControlBase(); 772 }; 773 774 class SVT_DLLPUBLIC FormattedControl : public FormattedControlBase 775 { 776 public: 777 FormattedControl(BrowserDataWin* pParent, bool bSpinVariant); 778 }; 779 780 class SVT_DLLPUBLIC DoubleNumericControl : public FormattedControlBase 781 { 782 public: 783 DoubleNumericControl(BrowserDataWin* pParent, bool bSpinVariant); 784 }; 785 786 class SVT_DLLPUBLIC LongCurrencyControl : public FormattedControlBase 787 { 788 public: 789 LongCurrencyControl(BrowserDataWin* pParent, bool bSpinVariant); 790 }; 791 792 class SVT_DLLPUBLIC TimeControl : public FormattedControlBase 793 { 794 public: 795 TimeControl(BrowserDataWin* pParent, bool bSpinVariant); 796 }; 797 798 class SVT_DLLPUBLIC DateControl : public FormattedControlBase 799 { 800 public: 801 DateControl(BrowserDataWin* pParent, bool bDropDown); 802 803 void SetDate(const Date& rDate); 804 805 virtual void dispose() override; 806 private: 807 std::unique_ptr<weld::MenuButton> m_xMenuButton; 808 std::unique_ptr<weld::Builder> m_xCalendarBuilder; 809 std::unique_ptr<weld::Widget> m_xTopLevel; 810 std::unique_ptr<weld::Calendar> m_xCalendar; 811 std::unique_ptr<weld::Widget> m_xExtras; 812 std::unique_ptr<weld::Button> m_xTodayBtn; 813 std::unique_ptr<weld::Button> m_xNoneBtn; 814 815 DECL_LINK(ToggleHdl, weld::Toggleable&, void); 816 DECL_LINK(ActivateHdl, weld::Calendar&, void); 817 DECL_LINK(ImplClickHdl, weld::Button&, void); 818 }; 819 820 class SVT_DLLPUBLIC PatternControl final : public EditControl 821 { 822 public: 823 PatternControl(BrowserDataWin* pParent); 824 825 weld::PatternFormatter& get_formatter() { return *m_xEntryFormatter; } 826 827 virtual void connect_changed(const Link<weld::Entry&, void>& rLink) override; 828 virtual void connect_focus_out(const Link<weld::Widget&, void>& rLink) override; 829 830 virtual void dispose() override; 831 private: 832 std::unique_ptr<weld::PatternFormatter> m_xEntryFormatter; 833 }; 834 835 //= FormattedFieldCellController 836 class SVT_DLLPUBLIC FormattedFieldCellController final : public EditCellController 837 { 838 public: 839 FormattedFieldCellController( FormattedControlBase* _pFormatted ); 840 841 virtual void CommitModifications() override; 842 }; 843 844 //= EditBrowserHeader 845 class SVT_DLLPUBLIC EditBrowserHeader : public BrowserHeader 846 { 847 public: 848 EditBrowserHeader( BrowseBox* pParent, WinBits nWinBits = WB_BUTTONSTYLE ) 849 :BrowserHeader(pParent, nWinBits){} 850 851 protected: 852 virtual void DoubleClick() override; 853 }; 854 855 856 //= EditBrowseBox 857 class EditBrowseBoxImpl; 858 class SVT_DLLPUBLIC EditBrowseBox: public BrowseBox 859 { 860 friend class EditBrowserHeader; 861 862 enum BrowseInfo 863 { 864 COLSELECT = 1, 865 ROWSELECT = 2, 866 ROWCHANGE = 4, 867 COLCHANGE = 8 868 }; 869 870 public: 871 enum RowStatus 872 { 873 CLEAN = 0, 874 CURRENT = 1, 875 CURRENTNEW = 2, 876 MODIFIED = 3, 877 NEW = 4, 878 DELETED = 5, 879 PRIMARYKEY = 6, 880 CURRENT_PRIMARYKEY = 7, 881 FILTER = 8, 882 HEADERFOOTER = 9 883 }; 884 885 private: 886 EditBrowseBox(EditBrowseBox const &) = delete; 887 EditBrowseBox& operator=(EditBrowseBox const &) = delete; 888 889 class BrowserMouseEventPtr 890 { 891 std::unique_ptr<BrowserMouseEvent> pEvent; 892 bool bDown; 893 894 public: 895 BrowserMouseEventPtr() 896 : bDown(false) 897 { 898 } 899 900 bool Is() const {return pEvent != nullptr;} 901 bool IsDown() const {return bDown;} 902 const BrowserMouseEvent* operator->() const {return pEvent.get();} 903 904 SVT_DLLPUBLIC void Clear(); 905 void Set(const BrowserMouseEvent* pEvt, bool bIsDown); 906 } aMouseEvent; 907 908 CellControllerRef aController, 909 aOldController; 910 911 ImplSVEvent * nStartEvent, * nEndEvent, * nCellModifiedEvent; // event ids 912 VclPtr<vcl::Window> m_pFocusWhileRequest; 913 // In ActivateCell, we grab the focus asynchronously, but if between requesting activation 914 // and the asynchronous event the focus has changed, we won't grab it for ourself. 915 916 sal_Int32 nPaintRow; // row being painted 917 sal_Int32 nEditRow; 918 sal_uInt16 nEditCol; 919 920 bool bHasFocus : 1; 921 mutable bool bPaintStatus : 1; // paint a status (image) in the handle column 922 bool bActiveBeforeTracking; 923 924 VclPtr<CheckBoxControl> pCheckBoxPaint; 925 926 EditBrowseBoxFlags m_nBrowserFlags; 927 std::unique_ptr< EditBrowseBoxImpl> m_aImpl; 928 929 protected: 930 VclPtr<BrowserHeader> pHeader; 931 932 BrowserMouseEventPtr& getMouseEvent() { return aMouseEvent; } 933 934 protected: 935 BrowserHeader* GetHeaderBar() const {return pHeader;} 936 937 virtual VclPtr<BrowserHeader> CreateHeaderBar(BrowseBox* pParent) override; 938 939 // if you want to have an own header ... 940 virtual VclPtr<BrowserHeader> imp_CreateHeaderBar(BrowseBox* pParent); 941 942 virtual void ColumnMoved(sal_uInt16 nId) override; 943 virtual void ColumnResized(sal_uInt16 nColId) override; 944 virtual void Resize() override; 945 virtual void ArrangeControls(sal_uInt16& nX, sal_uInt16 nY); 946 virtual bool SeekRow(sal_Int32 nRow) override; 947 948 virtual void GetFocus() override; 949 virtual void LoseFocus() override; 950 virtual void KeyInput(const KeyEvent& rEvt) override; 951 virtual void MouseButtonDown(const BrowserMouseEvent& rEvt) override; 952 virtual void MouseButtonUp(const BrowserMouseEvent& rEvt) override; 953 virtual void StateChanged( StateChangedType nType ) override; 954 virtual void DataChanged( const DataChangedEvent& rDCEvt ) override; 955 956 using BrowseBox::MouseButtonUp; 957 using BrowseBox::MouseButtonDown; 958 959 virtual bool PreNotify(NotifyEvent& rNEvt ) override; 960 virtual bool EventNotify(NotifyEvent& rNEvt) override; 961 962 virtual void EndScroll() override; 963 964 // should be used instead of GetFieldRectPixel, 'cause this method here takes into account the borders 965 tools::Rectangle GetCellRect(sal_Int32 nRow, sal_uInt16 nColId, bool bRelToBrowser = true) const; 966 virtual sal_uInt32 GetTotalCellWidth(sal_Int32 nRow, sal_uInt16 nColId); 967 sal_uInt32 GetAutoColumnWidth(sal_uInt16 nColId); 968 969 virtual void PaintStatusCell(OutputDevice& rDev, const tools::Rectangle& rRect) const; 970 virtual void PaintCell(OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColId) const = 0; 971 972 virtual RowStatus GetRowStatus(sal_Int32 nRow) const; 973 974 virtual void RowHeightChanged() override; 975 976 // callbacks for the data window 977 virtual void ImplStartTracking() override; 978 virtual void ImplEndTracking() override; 979 980 // when changing a row: 981 // CursorMoving: cursor is being moved, but GetCurRow() still provides the old row 982 virtual bool CursorMoving(sal_Int32 nNewRow, sal_uInt16 nNewCol); 983 984 // cursor has been moved 985 virtual void CursorMoved() override; 986 987 virtual void CellModified(); // called whenever a cell has been modified 988 virtual bool SaveModified(); // called whenever a cell should be left, and it's content should be saved 989 // return sal_False prevents leaving the cell 990 virtual bool SaveRow(); // commit the current row 991 992 virtual bool IsModified() const {return aController.is() && aController->IsValueChangedFromSaved();} 993 994 virtual CellController* GetController(sal_Int32 nRow, sal_uInt16 nCol); 995 virtual void InitController(CellControllerRef& rController, sal_Int32 nRow, sal_uInt16 nCol); 996 static void ResizeController(CellControllerRef const & rController, const tools::Rectangle&); 997 virtual void DoubleClick(const BrowserMouseEvent&) override; 998 999 void ActivateCell() { ActivateCell(GetCurRow(), GetCurColumnId()); } 1000 1001 // retrieve the image for the row status 1002 Image GetImage(RowStatus) const; 1003 1004 // inserting columns 1005 // if you don't set a width, this will be calculated automatically 1006 // if the id isn't set the smallest unused will do it ... 1007 virtual sal_uInt16 AppendColumn(const OUString& rName, sal_uInt16 nWidth, sal_uInt16 nPos = HEADERBAR_APPEND, sal_uInt16 nId = sal_uInt16(-1)); 1008 1009 // called whenever (Shift)Tab or Enter is pressed. If true is returned, these keys 1010 // result in traveling to the next or to th previous cell 1011 virtual bool IsTabAllowed(bool bForward) const; 1012 1013 virtual bool IsCursorMoveAllowed(sal_Int32 nNewRow, sal_uInt16 nNewColId) const override; 1014 1015 void PaintTristate(const tools::Rectangle& rRect, const TriState& eState, bool _bEnabled=true) const; 1016 1017 void AsynchGetFocus(); 1018 // secure starting of StartEditHdl 1019 1020 public: 1021 EditBrowseBox(vcl::Window* pParent, EditBrowseBoxFlags nBrowserFlags, WinBits nBits, BrowserMode nMode = BrowserMode::NONE ); 1022 virtual ~EditBrowseBox() override; 1023 virtual void dispose() override; 1024 1025 bool IsEditing() const {return aController.is();} 1026 void InvalidateStatusCell(sal_Int32 nRow) {RowModified(nRow, 0);} 1027 void InvalidateHandleColumn(); 1028 1029 // late construction 1030 virtual void Init(); 1031 virtual void RemoveRows(); 1032 virtual void Dispatch(sal_uInt16 nId); 1033 1034 const CellControllerRef& Controller() const { return aController; } 1035 EditBrowseBoxFlags GetBrowserFlags() const { return m_nBrowserFlags; } 1036 void SetBrowserFlags(EditBrowseBoxFlags nFlags); 1037 1038 virtual void ActivateCell(sal_Int32 nRow, sal_uInt16 nCol, bool bSetCellFocus = true); 1039 virtual void DeactivateCell(bool bUpdate = true); 1040 // Children --------------------------------------------------------------- 1041 1042 /** @return The count of additional controls of the control area. */ 1043 virtual sal_Int32 GetAccessibleControlCount() const override; 1044 1045 /** Creates the accessible object of an additional control. 1046 @param nIndex 1047 The 0-based index of the control. 1048 @return 1049 The XAccessible interface of the specified control. */ 1050 virtual css::uno::Reference< css::accessibility::XAccessible > 1051 CreateAccessibleControl( sal_Int32 nIndex ) override; 1052 1053 /** Sets focus to current cell of the data table. */ 1054 virtual void GrabTableFocus() override; 1055 1056 virtual tools::Rectangle GetFieldCharacterBounds(sal_Int32 _nRow,sal_Int32 _nColumnPos,sal_Int32 nIndex) override; 1057 virtual sal_Int32 GetFieldIndexAtPoint(sal_Int32 _nRow,sal_Int32 _nColumnPos,const Point& _rPoint) override; 1058 1059 virtual bool ProcessKey(const KeyEvent& rEvt) override; 1060 1061 virtual void ChildFocusIn() override; 1062 virtual void ChildFocusOut() override; 1063 1064 css::uno::Reference< css::accessibility::XAccessible > CreateAccessibleCheckBoxCell(sal_Int32 _nRow, sal_uInt16 _nColumnPos,const TriState& eState); 1065 bool ControlHasFocus() const; 1066 protected: 1067 // creates the accessible which wraps the active cell 1068 void implCreateActiveAccessible( ); 1069 1070 private: 1071 virtual void PaintField(vcl::RenderContext& rDev, const tools::Rectangle& rRect, 1072 sal_uInt16 nColumnId ) const override; 1073 using Control::ImplInitSettings; 1074 SVT_DLLPRIVATE void ImplInitSettings( bool bFont, bool bForeground, bool bBackground ); 1075 SVT_DLLPRIVATE void DetermineFocus( const GetFocusFlags _nGetFocusFlags = GetFocusFlags::NONE); 1076 inline void EnableAndShow() const; 1077 1078 SVT_DLLPRIVATE void implActivateCellOnMouseEvent(const BrowserMouseEvent& _rEvt, bool _bUp); 1079 1080 DECL_DLLPRIVATE_LINK( ModifyHdl, LinkParamNone*, void ); 1081 DECL_DLLPRIVATE_LINK( StartEditHdl, void*, void ); 1082 DECL_DLLPRIVATE_LINK( EndEditHdl, void*, void ); 1083 DECL_DLLPRIVATE_LINK( CellModifiedHdl, void*, void ); 1084 }; 1085 1086 1087 } // namespace svt 1088 1089 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 1090