// 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 #include #include #include #include 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. * * *

i18n

* * The strings used in this class can be translated by overriding * the default values for the following localization keys: * - Wt.WAbstractItemView.PageIOfN: {1} of {2} * - 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 alignment); /*! \brief Returns the horizontal header alignment for a column * (deprecated). * * \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 (deprecated). * 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 editTriggers); /*! \brief Returns the editing triggers. * * \sa setEditTriggers() */ WFlags editTriggers() const { return editTriggers_; } /*! \brief Configures editing options. * * The default value is SingleEditor; */ void setEditOptions(WFlags options); /*! \brief Returns the editing options. * * \sa setEditOptions() */ WFlags 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 an item is clicked. * * \sa doubleClicked() */ Signal& clicked() { return clicked_; } /*! \brief %Signal emitted when an item is double clicked. * * \sa clicked() */ Signal& doubleClicked() { return doubleClicked_; } /*! \brief %Signal emitted when a mouse button is pressed down. * * \sa mouseWentUp() */ Signal& mouseWentDown() { return mouseWentDown_; } /*! \brief %Signal emitted when the mouse button is released. * * \sa mouseWentDown() */ Signal& 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& 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 * (deprecated) * * 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. * (deprecated) * * \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 modelConnections_; WSignalMapper *clickedMapper_; mutable std::vector 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); void handleClick(const WModelIndex& index, const WMouseEvent& event); void handleDoubleClick(const WModelIndex& index, const WMouseEvent& event); void handleMouseDown(const WModelIndex& index, const WMouseEvent& event); 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 shiftEditors(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 columnWidthChanged_; Signal columnResized_; WCssTemplateRule *headerHeightRule_; mutable int nextColumnId_; WSignalMapper *clickedForSortMapper_, *clickedForExpandMapper_, *clickedForCollapseMapper_; bool alternatingRowColors_; JSlot resizeHandleMDownJS_; typedef std::map EditorMap; EditorMap editedItems_; Signal clicked_; Signal doubleClicked_; Signal mouseWentDown_; Signal mouseWentUp_; Signal<> selectionChanged_; Signal<> pageChanged_; WFlags editTriggers_; WFlags 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 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_