This file is indexed.

/usr/include/Wt/WAbstractItemView is in libwt-dev 3.3.0-1build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
// This may look like C code, but it's really -*- C++ -*-
/*
 * Copyright (C) 2009 Emweb bvba, Kessel-Lo, Belgium.
 *
 * See the LICENSE file for terms of use.
 */
#ifndef WT_WABSTRACTITEMVIEW_H_
#define WT_WABSTRACTITEMVIEW_H_

#include <Wt/WCompositeWidget>
#include <Wt/WModelIndex>
#include <Wt/WSignalMapper>
#include <Wt/WItemSelectionModel>
#include <Wt/WValidator>

namespace Wt {

  class WAbstractItemDelegate;
  class WAbstractItemModel;
  class WApplication;
  class WCssTemplateRule;

/*! \class WAbstractItemView Wt/WAbstractItemView Wt/WAbstractItemView
 *  \brief An abstract base class for item Views.
 *
 * See WTableView or WTreeView for a description.
 *
 *
 * <h3>i18n</h3>
 *
 * The strings used in this class can be translated by overriding
 * the default values for the following localization keys:
 * - Wt.WAbstractItemView.PageIOfN: <b>{1}</b> of <b>{2}</b>
 * - Wt.WAbstractItemView.PageBar.First: &\#xc2ab; First
 * - Wt.WAbstractItemView.PageBar.Previous: &\#xe280b9; Previous
 * - Wt.WAbstractItemView.PageBar.Next: Next &\#xe280ba;
 * - Wt.WAbstractItemView.PageBar.Last: Last &\#xc2bb;
 *
 * \ingroup modelview
 */
class WT_API WAbstractItemView : public WCompositeWidget
{
public:
  /*! \brief Enumeration that specifies the user action that triggers editing.
   *
   * \sa setEditTriggers(), edit()
   */
  enum EditTrigger {
    NoEditTrigger = 0x0,  //!< Do not allow user to initiate editing
    SingleClicked = 0x1,  //!< Edit an item when clicked
    DoubleClicked = 0x2,  //!< Edit an item when double clicked
    SelectedClicked = 0x4 //!< Edit a selected item that is clicked again
  };

  /*! \brief Enumeration that specifies editing options.
   *
   * \sa setEditOptions()
   */
  enum EditOption {
    SingleEditor = 0x1,    //!< Never show more than one active editor
    MultipleEditors = 0x2, //!< Allow multiple editors at the same time
    SaveWhenClosed = 0x4,  //!< Always save the current edit value when closing
    LeaveEditorsOpen = 0x8 //!< Editors can only be closed using closeEditor()
  };

  /*! \brief Enumeration that specifies a scrolling option.
   *
   * \sa scrollTo()
   */
  enum ScrollHint {
    EnsureVisible,         //!< Scrolls minimally to make it visible
    PositionAtTop,         //!< Positions the item at the top of the viewport
    PositionAtBottom,      //!< Positions the item at the bottom of the viewport
    PositionAtCenter       //!< Positions the item at the center of the viewport
  };

  virtual ~WAbstractItemView();

  /*! \brief Sets the model.
   *
   * The View will display data of the given \p model and changes in
   * the model are reflected by the View.
   *
   * The initial model is \c 0.
   *
   * \if cpp
   * Ownership of the model is not transferred (and thus the
   * previously set model is not deleted). A model may not be deleted as
   * long as a view exists for it.
   * \endif
   *
   * \sa setRootIndex()
   */
  virtual void setModel(WAbstractItemModel *model);

  /*! \brief Returns the model.
   *
   * \sa setModel()
   */
  WAbstractItemModel *model() const { return model_; }

  /*! \brief Sets the root index.
   *
   * The root index is the model index that is considered the root
   * node. This node itself is not rendered, but its children are.
   *
   * \if cpp
   * The default value is an invalid model index, corresponding to the model's
   * root node.
   * \endif
   * \if java
   * The default value is \c null, corresponding to the model's root node.
   * \endif
   *
   * \sa setModel()
   */
  void setRootIndex(const WModelIndex& rootIndex);

  /*! \brief Returns the root index.
   *
   * \sa setRootIndex()
   */
  const WModelIndex& rootIndex() const { return rootIndex_; }

  /*! \brief Sets the default item delegate.
   *
   * The previous delegate is not deleted. This item delegate is for
   * all columns for which no specific item delegate is set.
   *
   * The default item delegate is a WItemDelegate.
   *
   * \sa setItemDelegateForColumn()
   */
  void setItemDelegate(WAbstractItemDelegate *delegate);

  /*! \brief Returns the default item delegate.
   *
   * \sa setItemDelegate()
   */
  WAbstractItemDelegate *itemDelegate() const { return itemDelegate_; }

  /*! \brief Sets the delegate for a column.
   *
   * A delegate previously set (if any) is not deleted.
   *
   * \sa setItemDelegate()
   */
  void setItemDelegateForColumn(int column, WAbstractItemDelegate *delegate);

  /*! \brief Returns the delegate that was set for a column.
   *
   * Returns \c 0 if no delegate was set for the column.
   *
   * \sa setItemDelegateForColumn()
   */
  WAbstractItemDelegate *itemDelegateForColumn(int column) const;

  /*! \brief Returns the delegate for rendering an item.
   *
   * \sa setItemDelegateForColumn(), setItemDelegate()
   */
  WAbstractItemDelegate *itemDelegate(const WModelIndex& index) const;

  /*! \brief Returns the delegate for a column.
   *
   * Returns either the delegate that was set for the column, or the default
   * delegate.
   */
  WAbstractItemDelegate *itemDelegate(int column) const;

  /*! \brief Returns the widget that renders an item.
   *
   * This returns the widget that renders the given item. This may return 0
   * if the item is currently not rendered.
   *
   * This widget has been created by an item delegate, and usually an item
   * delegate is involved when updating it.
   */
  virtual WWidget *itemWidget(const WModelIndex& index) const = 0;

  /*! \brief Sets the header item delegate.
   *
   * This item delegate is used for rendering items in the header.
   *
   * The previous delegate is not deleted. This item delegate is for
   * all columns for which no specific item delegate is set.
   *
   * The default item delegate is a WItemDelegate.
   */
  void setHeaderItemDelegate(WAbstractItemDelegate *delegate);

  /*! \brief Returns the header item delegate.
   *
   * \sa setHeaderItemDelegate()
   */
  WAbstractItemDelegate *headerItemDelegate() const;

  /*! \brief Sets the content alignment for a column.
   *
   * The default value is Wt::AlignLeft.
   *
   * \sa setHeaderAlignment()
   */
  virtual void setColumnAlignment(int column, AlignmentFlag alignment);

  /*! \brief Returns the content alignment for a column.
   *
   * \sa setColumnAlignment()
   */
  virtual AlignmentFlag columnAlignment(int column) const;

  /*! \brief Sets the header alignment for a column.
   *
   * The default alignemnt is horizontally left, and vertically centered.
   * (Wt::AlignLeft | Wt::AlignMiddle).
   *
   * Valid options for horizontal alignment are Wt::AlignLeft,
   * Wt::AlignCenter or Wt::AlignRight.
   *
   * Valid options for vertical alignment are Wt::AlignMiddle or
   * Wt::AlignTop. In the latter case, other contents may be added
   * below the label in createExtraHeaderWidget().
   *
   * \sa setColumnAlignment()
   */
  virtual void setHeaderAlignment(int column, WFlags<AlignmentFlag> alignment);

  /*! \brief Returns the horizontal header alignment for a column
   *         (<b>deprecated</b>).
   *
   * \sa setHeaderAlignment()
   *
   * \deprecated use horizontalHeaderAlignment() instead.
   */
  AlignmentFlag headerAlignment(int column) const;

  /*! \brief Returns the horizontal header alignment for a column.
   *
   * \sa setHeaderAlignment()
   */
  AlignmentFlag horizontalHeaderAlignment(int column) const;

  /*! \brief Returns the vertical header alignment for a column.
   *
   * \sa setHeaderAlignment()
   */
  AlignmentFlag verticalHeaderAlignment(int column) const;

  /*! \brief Configures header text wrapping.
   *
   * This setting only affects a multiline header, and the default
   * value is \c true. When set to \c false, the header itself will not
   * wrap (as with a vertically centered header), and thus extra widgets
   * will not shift down when there is a long header label.
   */
  void setHeaderWordWrap(int column, bool enabled);

  bool headerWordWrap(int column) const;

  /*! \brief Sets if alternating row colors are to be used.
   *
   * Configure whether rows get alternating background colors, defined by the
   * current CSS theme.
   *
   * The default value is \c false.
   */
  virtual void setAlternatingRowColors(bool enable);

  /*! \brief Returns whether alternating row colors are used.
   *
   * When enabled, rows are displayed in alternating row colors, according
   * to the current theme's definition.
   *
   * \sa setAlternatingRowColors()
   */
  virtual bool alternatingRowColors() const { return alternatingRowColors_; }
  
  /*! \brief Sorts the data according to a column.
   *
   * Sorts the data according to data in column \p column and sort
   * order \p order.
   *
   * The default sorting column is -1: the model is unsorted.
   *
   * \sa WAbstractItemModel::sort()
   */
  void sortByColumn(int column, SortOrder order);

  /*! \brief Returns the current sorting columm.
   *
   * \sa sortByColumn(), sortOrder()
   */
  int sortColumn() const;

  /*! \brief Returns the current sorting order.
   *
   * \sa sortByColumn(), sortColumn()
   */
  SortOrder sortOrder() const;

  /*! \brief Enables or disables sorting for all columns.
   *
   * Enable or disable sorting by the user on all columns.
   *
   * Sorting is enabled by default.
   *
   * \sa WAbstractItemModel::sort()
   */
  void setSortingEnabled(bool enabled);

  /*! \brief Enables or disables sorting for a single column.
   *
   * Enable or disable sorting by the user for a specific column.
   *
   * Sorting is enabled by default.
   *
   * \sa WAbstractItemModel::sort()
   */
  void setSortingEnabled(int column, bool enabled);

  /*! \brief Returns whether sorting is enabled.
   *
   * \sa setSortingEnabled()
   */
  bool isSortingEnabled() const { return sorting_; }

  /*! \brief Returns whether sorting is enabled for a single column.
   *
   * \sa setSortingEnabled()
   */
  bool isSortingEnabled(int column) const;

  /*! \brief Enables interactive column resizing
   *
   * Enable or disable column resize handles for interactive resizing of
   * the columns.
   *
   * Column resizing is enabled by default when JavaScript is available.
   *
   * \sa setColumnResizeEnabled()
   */
  void setColumnResizeEnabled(bool enabled);

  /*! \brief Returns whether column resizing is enabled.
   *
   * \sa setColumnResizeEnabled()
   */
  bool isColumnResizeEnabled() const { return columnResize_; }

  /*! \brief Changes the selection behaviour.
   *
   * The selection behavior indicates whether whole rows or individual
   * items can be selected. It is a property of the selectionModel().
   *
   * By default, selection operates on rows (\link Wt::SelectRows
   * SelectRows\endlink), in which case model indexes will always be
   * in the first column (column \c 0).
   *
   * Alternatively, you can allow selection for individual items
   * (\link Wt::SelectItems SelectItems\endlink).
   *
   * \sa WItemSelectionModel::setSelectionBehavior(), setSelectionMode()
   */
  void setSelectionBehavior(SelectionBehavior behavior);

  /*! \brief Returns the selection behaviour.
   *
   * \sa setSelectionBehavior()
   */
  SelectionBehavior selectionBehavior() const;

  /*! \brief Sets the selection mode.
   *
   * By default selection is disabled (\link Wt::NoSelection
   * NoSelection \endlink).
   *
   * \sa setSelectionBehavior()
   */
  void setSelectionMode(SelectionMode mode);

  /*! \brief Returns the selection mode.
   *
   * \sa setSelectionMode()
   */
  SelectionMode selectionMode() const { return selectionMode_; }

  /*! \brief Returns the selection model.
   *
   * The selection model keeps track of the currently selected items.
   */
  WItemSelectionModel *selectionModel() const { return selectionModel_; }

  /*! \brief Sets the selected items
   *
   * Replaces the current selection with \p indexes.
   * 
   * When selection operates on rows (\link Wt::SelectRows SelectRows\endlink), 
   * it is sufficient to pass the first element in a row (column \c 0 )
   * to select the entire row.
   *
   * \sa select(), selectionModel()
   */
  void setSelectedIndexes(const WModelIndexSet& indexes);

  /*! \brief Selects a single item.
   *
   * \sa setSelectedIndexes(), selectionModel()
   */
  void select(const WModelIndex& index, SelectionFlag option = Select);

  /*! \brief Returns wheter an item is selected.
   *
   * When selection operates on rows (\link Wt::SelectRows SelectRows\endlink),
   * this method returns true for each element in a selected row.
   *
   * This is a convenience method for:
   * \code
   * selectionModel()->isSelected(index)
   * \endcode
   *
   * \sa selectedIndexes(), select(), selectionModel()
   */
  bool isSelected(const WModelIndex& index) const;

  /*! \brief Returns the set of selected items.
   *
   * The model indexes are returned as a set, topologically ordered (in
   * the order they appear in the view).
   *
   * When selection operates on rows (\link Wt::SelectRows SelectRows\endlink),
   * this method only returns the model index of first column's element of the 
   * selected rows.
   *
   * This is a convenience method for:
   * \code
   * selectionModel()->selectedIndexes()
   * \endcode
   *
   * \sa setSelectedIndexes()
   */
  WModelIndexSet selectedIndexes() const;
  
  /*! \brief Enables the selection to be dragged (drag & drop).
   *
   * To enable dragging of the selection, you first need to enable
   * selection using setSelectionMode().
   *
   * Whether an individual item may be dragged is controlled by the
   * item's \link Wt::ItemIsDragEnabled ItemIsDragEnabled \endlink
   * flag. The selection can be dragged only if all items currently
   * selected can be dragged.
   *
   * \sa setDropsEnabled() 
   */
  void setDragEnabled(bool enable);

  /*! \brief Enables drop operations (drag & drop).
   *
   * When drop is enabled, the tree view will indicate that something
   * may be dropped when the mime-type of the dragged object is
   * compatible with one of the model's accepted drop mime-types (see
   * WAbstractItemModel::acceptDropMimeTypes()) or this widget's
   * accepted drop mime-types (see WWidget::acceptDrops()), and the
   * target item has drop enabled (which is controlled by the item's
   * \link Wt::ItemIsDropEnabled ItemIsDropEnabled \endlink flag).
   *
   * Drop events must be handled in dropEvent().
   *
   * \sa setDragEnabled(), dropEvent()
   */
  void setDropsEnabled(bool enable);

  /*! \brief Sets the row height.
   *
   * The view renders all rows with a same height. This method
   * configures this row height.
   *
   * The default value is 20 pixels.
   *
   * \note The height must be specified in WLength::Pixel units.
   *
   * \sa setColumnWidth()
   */
  virtual void setRowHeight(const WLength& rowHeight);

  /*! \brief Returns the row height.
   */
  const WLength& rowHeight() const { return rowHeight_; }

  /*! \brief Sets the column width.
   *
   * The default column width is 150 pixels.
   *
   * \note The actual space occupied by each column is the column width
   *       augmented by 7 pixels for internal padding and a border.
   */
  virtual void setColumnWidth(int column, const WLength& width) = 0;
 
  /*! \brief Returns the column width.
   *
   * \sa setColumnWidth()
   */
  WLength columnWidth(int column) const;

  /*! \brief Changes the visibility of a column.
   *
   * \sa isColumnHidden()
   */
  virtual void setColumnHidden(int column, bool hide);

  /*! \brief Returns if a column is hidden.
   *
   * \sa setColumnHidden()
   */
  bool isColumnHidden(int column) const;

  /*! \brief Hides a column.
   *
   * \sa showColumn(), setColumnHidden()
   */
  void hideColumn(int column);

  /*! \brief Shows a column.
   *
   * \sa hideColumn(), setColumnHidden()
   */
  void showColumn(int column);

  /*! \brief Sets the column border color
   *
   * The default border color is defined by the CSS theme. 
   */
  virtual void setColumnBorder(const WColor& color) = 0;

  /*! \brief Sets the header height.
   *
   * The default value is 20 pixels.
   */
  virtual void setHeaderHeight(const WLength& height);

  /*! \brief Sets the header height, and vertical alignment (<b>deprecated</b>). 
   * By default, the header text is a single line that is centered vertically.
   *
   * Along with setting the header height, this also configures vertical
   * aligment and header label word wrapping. This has been deprecated in
   * favour of the more fine grained control using setHeaderAlignment() and
   * setHeaderWordWrap().
   *
   * When \p multiLine is \c false, the header alignment is set to
   * Wt::AlignMiddle. When \p multiLine is \c true, the header
   * alignment is set to Wt::AlignTop and header word wrap is set to
   * \c true.
   *
   * \deprecated use setHeaderHeight(), setHeaderAlignment()
   *             and setHeaderWordWrap() instead.
   */
  void setHeaderHeight(const WLength& height, bool multiLine);

  /*! \brief Returns the header height.
   *
   * \sa setHeaderHeight()
   */
  const WLength& headerHeight() const { return headerLineHeight_; } ;

  /*! \brief Returns the number of pages.
   *
   * When Ajax/JavaScript is not available, the view will use a paging
   * navigation bar to allow scrolling through the data. This returns the
   * number of pages currently shown.
   *
   * \sa createPageNavigationBar(), pageChanged()
   */
  virtual int pageCount() const = 0;

  /*! \brief Returns the page size.
   *
   * When Ajax/JavaScript is not available, the view will use a paging
   * navigation bar to allow scrolling through the data. This returns the
   * number of items per page.
   *
   * \sa createPageNavigationBar(), pageChanged()
   */
  virtual int pageSize() const = 0;

  /*! \brief Returns the current page.
   *
   * When Ajax/JavaScript is not available, the view will use a paging
   * navigation bar to allow scrolling through the data. This returns the
   * current page (between 0 and pageCount() - 1).
   *
   * \sa createPageNavigationBar(), pageChanged()
   */
  virtual int currentPage() const = 0;

  /*! \brief Sets the current page.
   *
   * When Ajax/JavaScript is not available, the view will use a paging
   * navigation bar to allow scrolling through the data. This method can
   * be used to change the current page.
   *
   * \sa createPageNavigationBar(), pageChanged()
   */
  virtual void setCurrentPage(int page) = 0;

  /*! \brief Scrolls the view to an item.
   *
   * Scrolls the view to ensure that the item which represents the
   * provided \p index is visible. A \p hint may indicate how the item
   * should appear in the viewport (if possible).
   *
   * \note Currently only implemented to scroll to the correct row, not
   *       taking into account the column.
   */
  virtual void scrollTo(const WModelIndex& index,
			ScrollHint hint = EnsureVisible) = 0;

  /*! \brief Configures what actions should trigger editing.
   *
   * The default value is DoubleClicked.
   *
   * \sa edit()
   */
  void setEditTriggers(WFlags<EditTrigger> editTriggers);

  /*! \brief Returns the editing triggers.
   *
   * \sa setEditTriggers()
   */
  WFlags<EditTrigger> editTriggers() const { return editTriggers_; }

  /*! \brief Configures editing options.
   *
   * The default value is SingleEditor;
   */
  void setEditOptions(WFlags<EditOption> options);

  /*! \brief Returns the editing options.
   *
   * \sa setEditOptions()
   */
  WFlags<EditOption> editOptions() const { return editOptions_; }

  /*! \brief Opens an editor for the given index.
   *
   * Unless multiple editors are enabled, any other open editor is closed
   * first.
   *
   * \sa setEditTriggers(), setEditOptions(), closeEditor()
   */
  void edit(const WModelIndex& index);

  /*! \brief Closes the editor for the given index.
   *
   * If \p saveData is true, then the currently edited value is saved first
   * to the model.
   *
   * \sa edit()
   */
  void closeEditor(const WModelIndex& index, bool saveData = true);

  /*! \brief Closes all open editors.
   *
   * If \p saveData is true, then the currently edited values are saved
   * to the model before closing the editor.
   *
   * \sa closeEditor()
   */
  void closeEditors(bool saveData = true);

  /*! \brief Validates the editor for the given index.
   * 
   * Validation is done by invoking WAbstractItemDelegate::validate().
   */
  WValidator::State validateEditor(const WModelIndex& index);

  /*! \brief Validates all editors.
   * 
   * \sa validateEditor().
   */
  WValidator::State validateEditors();

  /*! \brief Returns whether an editor is open for a given index.
   *
   * \sa edit()
   */
  bool isEditing(const WModelIndex& index) const;
  
  /*! \brief Returns whether an editor's state is valid.
   */
  bool isValid(const WModelIndex& index) const;

  bool isEditing() const;

  /*! \brief %Signal emitted when clicked.
   *
   * When the event happened over an item, the first argument
   * indicates the item that was clicked on.

   * \sa doubleClicked()
   */
  Signal<WModelIndex, WMouseEvent>& clicked() { return clicked_; }

  /*! \brief %Signal emitted when double clicked.
   *
   * When the event happened over an item, the first argument
   * indicates the item that was double clicked on.
   *
   * \sa clicked()
   */
  Signal<WModelIndex, WMouseEvent>& doubleClicked() { return doubleClicked_; }

  /*! \brief %Signal emitted when a mouse button is pressed down.
   *
   * When the event happened over an item, the first argument
   * indicates the item where the mouse went down.
   *
   * \sa mouseWentUp()
   */
  Signal<WModelIndex, WMouseEvent>& mouseWentDown() { return mouseWentDown_; }

  /*! \brief %Signal emitted when the mouse button is released.
   *
   * When the event happened over an item, the first argument
   * indicates the item where the mouse went up.
   *
   * \sa mouseWentDown()
   */
  Signal<WModelIndex, WMouseEvent>& mouseWentUp() { return mouseWentUp_; }

  /*! \brief %Signal emitted when the selection is changed.
   *
   * \sa select(), setSelectionMode(), setSelectionBehavior()
   */
  Signal<>& selectionChanged() { return selectionChanged_; }

  /*! \brief %Signal emitted when page information was updated.
   *
   * When Ajax/JavaScript is not available, the view will use a paging
   * navigation bar to allow scrolling through the data. This signal
   * is emitted when page-related information changed (e.g. the
   * current page was changed, or the number of rows was changed).
   *
   * \sa createPageNavigationBar()
   */
  Signal<>& pageChanged() { return pageChanged_; }

  /*! \brief Returns the signal emitted when a column is resized by the user.
   *
   * The arguments of the signal are: the column index and the new
   * width of the column.
   */
  Signal<int, WLength>& columnResized() { return columnResized_; }

  /*! \brief Configures the number of columns that are used as row
   *         headers.
   *
   * An item view does not use the vertical header data from the model
   * in any way, but instead you can configure data in the first
   * column(s) to be used as a row headers.
   *
   * These columns will not scroll horizontally together with the rest
   * of the model.
   *
   * The default value is 0.
   *
   * \note Currently, this property must be set before any other settings of
   *       the view and only a value of 0 or 1 is supported.
   */
  virtual void setRowHeaderCount(int count);

  /*! \brief Returns the number of columns that are used as row headers.
   *
   * \sa setRowHeaderCount()
   */
  int rowHeaderCount() const { return rowHeaderCount_; }

  /*! \brief Configures whether horizontal scrolling includes the first column
   *         (<b>deprecated</b>)
   *
   * To display a model with many columns, this option allows you to
   * keep the first column fixed while scrolling through the other
   * columns of the model.
   *
   * The default value is \c false.
   *
   * \deprecated Use setRowHeaderCount() instead.
   */
  void setColumn1Fixed(bool enable);

  /*! \brief Returns whether horizontal scrolling includes the first column.
   *         (<b>deprecated</b>)
   *
   * \sa setColumn1Fixed()
   *
   * \deprecated Use rowHeaderCount() instead.
   */
  bool column1Fixed() const { return rowHeaderCount_ == 1; }

protected:
  /*! \brief Creates a new item view.
   */
  WAbstractItemView(WContainerWidget *parent = 0);

  /*! \brief Handles a drop event (drag & drop).
   *
   * The \p event object contains details about the drop
   * operation, identifying the source (which provides the data) and
   * the mime-type of the data. The drop was received on the
   * \p target item.
   *
   * The drop event can be handled either by the view itself, or by
   * the model. The default implementation checks if the mime-type is
   * accepted by the model, and if so passes the drop event to the
   * model. If the source is the view's own selection model, then the
   * drop event will be handled as a \link Wt::MoveAction
   * MoveAction\endlink, otherwise the drop event will be handled as a
   * \link Wt::CopyAction CopyAction\endlink.
   *
   * \sa WAbstractItemModel::dropEvent()
   */
  virtual void dropEvent(const WDropEvent& event, const WModelIndex& target);

  /*! \brief Create an extra widget in the header.
   *
   * You may reimplement this method to provide an extra widget to be placed
   * below the header label. The extra widget will be visible only if
   * a multi-line header is configured using setHeaderHeight().
   *
   * The widget is created only once, but this method may be called
   * repeatedly for a column for which prior calls returned \c 0
   * (i.e. each time the header is rerendered).
   *
   * The default implementation returns \c 0.
   *
   * \sa setHeaderHeight(), extraHeaderWidget()
   */
  virtual WWidget *createExtraHeaderWidget(int column);

  /*! \brief Returns the extra header widget.
   *
   * Returns the widget previously created using createExtraHeaderWidget()
   *
   * \sa createExtraHeaderWidget()
   */
  WWidget *extraHeaderWidget(int column);

  /*! \brief Returns a page navigation widget.
   *
   * When Ajax/JavaScript is not available, the view will use a paging
   * navigation bar to allow scrolling through the data, created by this
   * method. The default implementation displays a simple navigation bar
   * with (First, Prevous, Next, Last) buttons and a page counter.
   *
   * You may want to reimplement this method to provide a custom page
   * navigation bar. You can use the currentPage(), pageCount(), and
   * setCurrentPage() methods to set or get the page information, and
   * listen to the pageChanged() signal to react to changes.
   */
  virtual WWidget *createPageNavigationBar();

protected:
  struct ColumnInfo {
    WCssTemplateRule *styleRule;
    int id;
    SortOrder sortOrder;
    AlignmentFlag alignment;
    AlignmentFlag headerHAlignment, headerVAlignment;
    bool headerWordWrap;
    WLength width;
    WWidget *extraHeaderWidget;
    bool sorting, hidden;
    WAbstractItemDelegate *itemDelegate_;

    std::string styleClass() const;

    ColumnInfo(const WAbstractItemView *view, int id);
  };

  enum RenderState {
    RenderOk = 0,
    NeedAdjustViewPort = 1,
    NeedRerenderData = 2,
    NeedRerenderHeader = 3,
    NeedRerender = 4
  };

  WContainerWidget *impl_;
  RenderState renderState_;
  std::vector<boost::signals::connection> modelConnections_;

  WSignalMapper<WModelIndex, WMouseEvent> *clickedMapper_;

  mutable std::vector<ColumnInfo> columns_;
  int currentSortColumn_;

  bool dragEnabled_, dropsEnabled_;
  WWidget *dragWidget_;

  virtual void scheduleRerender(RenderState what);

  virtual void modelDataChanged(const WModelIndex& topLeft,
				const WModelIndex& bottomRight) = 0;
  virtual void modelLayoutAboutToBeChanged();
  virtual void modelLayoutChanged();
  void modelHeaderDataChanged(Orientation orientation, int start, int end);
  void modelReset();

  ColumnInfo& columnInfo(int column) const;
  int columnById(int columnid) const;

  int columnCount() const;
  int visibleColumnCount() const;
  int visibleColumnIndex(int modelColumn) const;
  int modelColumnIndex(int visibleColumn) const;

  virtual ColumnInfo createColumnInfo(int column) const;

  void saveExtraHeaderWidgets();
  WWidget *createHeaderWidget(WApplication *app, int column);
  WText *headerTextWidget(int column);

  /*! \brief Handles a click event.
   *
   * This processes the event for internal purposes (such as
   * selection or editing) and emits the clicked() signal.
   *
   * You may want to override this signal to override the built-in
   * selection or editing behaviour.
   */
  virtual void handleClick(const WModelIndex& index, const WMouseEvent& event);

  /*! \brief Handles a double click event.
   *
   * This processes the event for internal purposes (such as
   * editing) and emits the doubleClicked() signal.
   *
   * You may want to override this signal to override the built-in
   * editing behaviour.
   */
  virtual void handleDoubleClick(const WModelIndex& index,
				 const WMouseEvent& event);

  /*! \brief Handles a mouse down event.
   *
   * This emits the mouseWentDown() signal.
   */
  virtual void handleMouseDown(const WModelIndex& index,
			       const WMouseEvent& event);

  /*! \brief Handles a mouse up event.
   *
   * This emits the mouseWentUp() signal.
   */
  virtual void handleMouseUp(const WModelIndex& index,
			     const WMouseEvent& event);

  virtual bool internalSelect(const WModelIndex& index, SelectionFlag option);

  void setEditState(const WModelIndex& index, const boost::any& editState);
  boost::any editState(const WModelIndex& index) const;
  bool hasEditFocus(const WModelIndex& index) const;

  void setEditorWidget(const WModelIndex& index, WWidget *editor);

  void bindObjJS(JSlot& slot, const std::string& jsMethod);
  void connectObjJS(EventSignalBase& s, const std::string& jsMethod);
  bool shiftEditorRows(const WModelIndex& parent, int start, int count,
		       bool persistWhenShifted);
  bool shiftEditorColumns(const WModelIndex& parent, int start, int count,
			  bool persistWhenShifted);
  void persistEditor(const WModelIndex& index);

private:
  struct Editor {
    Editor() :
      widget(0),
      stateSaved(false),
      valid(false) {
      editState = boost::any();
    }
    WWidget *widget;
    boost::any editState;
    bool stateSaved;
    bool valid;
  };

  WAbstractItemModel *model_, *headerModel_;
  WModelIndex rootIndex_;
  WAbstractItemDelegate *itemDelegate_;
  WAbstractItemDelegate *headerItemDelegate_;
  WItemSelectionModel *selectionModel_;
  WLength rowHeight_, headerLineHeight_;
  SelectionMode selectionMode_;
  bool sorting_, columnResize_;
  AlignmentFlag defaultHeaderVAlignment_;
  bool defaultHeaderWordWrap_;
  int rowHeaderCount_;
  WString computedDragMimeType_;

  JSignal<int, int>    columnWidthChanged_;
  Signal<int, WLength> columnResized_;

  WCssTemplateRule *headerHeightRule_;

  mutable int nextColumnId_;
  
  WSignalMapper<int>
    *clickedForSortMapper_, *clickedForExpandMapper_,
    *clickedForCollapseMapper_;

  bool alternatingRowColors_;

  JSlot resizeHandleMDownJS_;

  typedef std::map<WModelIndex, Editor> EditorMap;
  EditorMap editedItems_;

  Signal<WModelIndex, WMouseEvent> clicked_;
  Signal<WModelIndex, WMouseEvent> doubleClicked_;
  Signal<WModelIndex, WMouseEvent> mouseWentDown_;
  Signal<WModelIndex, WMouseEvent> mouseWentUp_;
  Signal<> selectionChanged_;
  Signal<> pageChanged_;

  WFlags<EditTrigger> editTriggers_;
  WFlags<EditOption> editOptions_;

  void closeEditorWidget(WWidget *editor, bool saveData);
  void saveEditedValue(const WModelIndex& index, Editor& editor);
  void persistEditor(const WModelIndex& index, Editor& editor);

  virtual WWidget *headerWidget(int column, bool contentsOnly = true) = 0;
  virtual WText *headerSortIconWidget(int column);

  void selectionHandleClick(const WModelIndex& index,
			    WFlags<KeyboardModifier> modifiers);
  void clearSelection();
  void extendSelection(const WModelIndex& index);
  virtual void selectRange(const WModelIndex& first, const WModelIndex& last)
    = 0;

  void checkDragSelection();
  void configureModelDragDrop();

  void toggleSortColumn(int columnid);
  void updateColumnWidth(int columnId, int width);

  virtual WContainerWidget* headerContainer() = 0;

  int headerLevel(int column) const;
  int headerLevelCount() const;

  void expandColumn(int columnid);
  void collapseColumn(int columnid);

  void initDragDrop();
};

W_DECLARE_OPERATORS_FOR_FLAGS(WAbstractItemView::EditOption);
W_DECLARE_OPERATORS_FOR_FLAGS(WAbstractItemView::EditTrigger);

}

#endif // WT_WABSTRACTITEMVIEW_H_