X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2Ftreelistctrl.cpp;fp=src%2Ftreelistctrl.cpp;h=0000000000000000000000000000000000000000;hb=916a5e3008de7387aaf45e9d4e4ebbe6503205c3;hp=c3762047718ad030993979e6419c6741c305a9e5;hpb=fc9f416364ea520257fac4163be2de826491fe60;p=creaImageIO.git diff --git a/src/treelistctrl.cpp b/src/treelistctrl.cpp deleted file mode 100644 index c376204..0000000 --- a/src/treelistctrl.cpp +++ /dev/null @@ -1,4791 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: treelistctrl.cpp -// Purpose: multi column tree control implementation -// Author: Robert Roebling -// Maintainer: Otto Wyss -// Created: 01/02/97 -// RCS-ID: $Id: treelistctrl.cpp,v 1.4 2009/03/20 14:43:12 davila Exp $ -// Copyright: (c) 2004 Robert Roebling, Julian Smart, Alberto Griggio, -// Vadim Zeitlin, Otto Wyss -// Licence: wxWindows -///////////////////////////////////////////////////////////////////////////// - -// =========================================================================== -// declarations -// =========================================================================== - -// --------------------------------------------------------------------------- -// headers -// --------------------------------------------------------------------------- - - - - -#if defined(__GNUG__) && !defined(__APPLE__) - #pragma implementation "treelistctrl.h" -#endif - - - -#include -#include -#include -#include -#include -#include -#include -#include - - - - -//#include "wx/treelistctrl.h" -#include "treelistctrl.h" - -#ifdef __WXMAC__ - #include "wx/mac/private.h" -#endif - - -// --------------------------------------------------------------------------- -// array types -// --------------------------------------------------------------------------- - -class wxTreeListItem; - -#if !wxCHECK_VERSION(2, 5, 0) -WX_DEFINE_ARRAY(wxTreeListItem *, wxArrayTreeListItems); -#else -WX_DEFINE_ARRAY_PTR(wxTreeListItem *, wxArrayTreeListItems); -#endif - -#include -WX_DECLARE_OBJARRAY(wxTreeListColumnInfo, wxArrayTreeListColumnInfo); -#include -WX_DEFINE_OBJARRAY(wxArrayTreeListColumnInfo); - -#if !wxCHECK_VERSION(2, 3, 3) -WX_DEFINE_ARRAY(short, wxArrayShort); -#endif - - -// -------------------------------------------------------------------------- -// constants -// -------------------------------------------------------------------------- - -static const int NO_IMAGE = -1; - -static const int LINEHEIGHT = 10; -static const int LINEATROOT = 5; -static const int MARGIN = 2; -static const int MININDENT = 16; -static const int BTNWIDTH = 9; -static const int BTNHEIGHT = 9; -static const int EXTRA_WIDTH = 4; -static const int EXTRA_HEIGHT = 4; -static const int HEADER_OFFSET_X = 1; -static const int HEADER_OFFSET_Y = 1; - -static const int DRAG_TIMER_TICKS = 250; // minimum drag wait time in ms -static const int FIND_TIMER_TICKS = 500; // minimum find wait time in ms -static const int RENAME_TIMER_TICKS = 250; // minimum rename wait time in ms - -const wxChar* wxTreeListCtrlNameStr = _T("treelistctrl"); - -static wxTreeListColumnInfo wxInvalidTreeListColumnInfo; - - -// --------------------------------------------------------------------------- -// private classes -// --------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// wxTreeListHeaderWindow (internal) -//----------------------------------------------------------------------------- - -class CREAIMAGEIO_EXPORT wxTreeListHeaderWindow : public wxWindow -{ -protected: - wxTreeListMainWindow *m_owner; - const wxCursor *m_currentCursor; - const wxCursor *m_resizeCursor; - bool m_isDragging; - - // column being resized - int m_column; - - // divider line position in logical (unscrolled) coords - int m_currentX; - - // minimal position beyond which the divider line can't be dragged in - // logical coords - int m_minX; - - wxArrayTreeListColumnInfo m_columns; - - // total width of the columns - int m_total_col_width; - - -public: - wxTreeListHeaderWindow(); - - wxTreeListHeaderWindow( wxWindow *win, - wxWindowID id, - wxTreeListMainWindow *owner, - const wxPoint &pos = wxDefaultPosition, - const wxSize &size = wxDefaultSize, - long style = 0, - const wxString &name = _T("wxtreelistctrlcolumntitles") ); - - virtual ~wxTreeListHeaderWindow(); - - void DoDrawRect( wxDC *dc, int x, int y, int w, int h ); - void DrawCurrent(); - void AdjustDC(wxDC& dc); - - void OnPaint( wxPaintEvent &event ); - void OnMouse( wxMouseEvent &event ); - void OnSetFocus( wxFocusEvent &event ); - - // total width of all columns - int GetWidth() const { return m_total_col_width; } - - // column manipulation - int GetColumnCount() const { return m_columns.GetCount(); } - - void AddColumn (const wxTreeListColumnInfo& colInfo); - - void InsertColumn (int before, const wxTreeListColumnInfo& colInfo); - - void RemoveColumn (int column); - - // column information manipulation - const wxTreeListColumnInfo& GetColumn (int column) const{ - wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()), - wxInvalidTreeListColumnInfo, _T("Invalid column")); - return m_columns[column]; - } - wxTreeListColumnInfo& GetColumn (int column) { - wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()), - wxInvalidTreeListColumnInfo, _T("Invalid column")); - return m_columns[column]; - } - void SetColumn (int column, const wxTreeListColumnInfo& info); - - wxString GetColumnText (int column) const { - wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()), - wxEmptyString, _T("Invalid column")); - return m_columns[column].GetText(); - } - void SetColumnText (int column, const wxString& text) { - wxCHECK_RET ((column >= 0) && (column < GetColumnCount()), - _T("Invalid column")); - m_columns[column].SetText (text); - } - - int GetColumnAlignment (int column) const { - wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()), - wxALIGN_LEFT, _T("Invalid column")); - return m_columns[column].GetAlignment(); - } - void SetColumnAlignment (int column, int flag) { - wxCHECK_RET ((column >= 0) && (column < GetColumnCount()), - _T("Invalid column")); - m_columns[column].SetAlignment (flag); - } - - int GetColumnWidth (int column) const { - wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()), - -1, _T("Invalid column")); - return m_columns[column].GetWidth(); - } - void SetColumnWidth (int column, int width); - - bool IsColumnEditable (int column) const { - wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()), - false, _T("Invalid column")); - return m_columns[column].IsEditable(); - } - - bool IsColumnShown (int column) const { - wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()), - true, _T("Invalid column")); - return m_columns[column].IsShown(); - } - - // needs refresh - bool m_dirty; - -private: - // common part of all ctors - void Init(); - - void SendListEvent(wxEventType type, wxPoint pos); - -//EED -// DECLARE_DYNAMIC_CLASS(wxTreeListHeaderWindow) - DECLARE_CLASS(wxTreeListHeaderWindow) - DECLARE_EVENT_TABLE() -}; - - -// this is the "true" control -class wxTreeListMainWindow: public wxScrolledWindow -{ -public: - // creation - // -------- - wxTreeListMainWindow() { Init(); } - - wxTreeListMainWindow (wxTreeListCtrl *parent, wxWindowID id = -1, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxTR_DEFAULT_STYLE, - const wxValidator &validator = wxDefaultValidator, - const wxString& name = _T("wxtreelistmainwindow")) - { - Init(); - Create (parent, id, pos, size, style, validator, name); - } - - virtual ~wxTreeListMainWindow(); - - bool Create(wxTreeListCtrl *parent, wxWindowID id = -1, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxTR_DEFAULT_STYLE, - const wxValidator &validator = wxDefaultValidator, - const wxString& name = _T("wxtreelistctrl")); - - // accessors - // --------- - - // return true if this is a virtual list control - bool IsVirtual() const { return HasFlag(wxTR_VIRTUAL); } - - // get the total number of items in the control - size_t GetCount() const; - - // indent is the number of pixels the children are indented relative to - // the parents position. SetIndent() also redraws the control - // immediately. - unsigned int GetIndent() const { return m_indent; } - void SetIndent(unsigned int indent); - - // see wxTreeListCtrl for the meaning - unsigned int GetLineSpacing() const { return m_linespacing; } - void SetLineSpacing(unsigned int spacing); - - // image list: these functions allow to associate an image list with - // the control and retrieve it. Note that when assigned with - // SetImageList, the control does _not_ delete - // the associated image list when it's deleted in order to allow image - // lists to be shared between different controls. If you use - // AssignImageList, the control _does_ delete the image list. - - // The normal image list is for the icons which correspond to the - // normal tree item state (whether it is selected or not). - // Additionally, the application might choose to show a state icon - // which corresponds to an app-defined item state (for example, - // checked/unchecked) which are taken from the state image list. - wxImageList *GetImageList() const { return m_imageListNormal; } - wxImageList *GetStateImageList() const { return m_imageListState; } - wxImageList *GetButtonsImageList() const { return m_imageListButtons; } - - void SetImageList(wxImageList *imageList); - void SetStateImageList(wxImageList *imageList); - void SetButtonsImageList(wxImageList *imageList); - void AssignImageList(wxImageList *imageList); - void AssignStateImageList(wxImageList *imageList); - void AssignButtonsImageList(wxImageList *imageList); - - // Functions to work with tree ctrl items. - - // accessors - // --------- - - // retrieve item's label - wxString GetItemText (const wxTreeItemId& item) const - { return GetItemText (item, GetMainColumn()); } - wxString GetItemText (const wxTreeItemId& item, int column) const; - wxString GetItemText (wxTreeItemData* item, int column) const; - - // get one of the images associated with the item (normal by default) - int GetItemImage (const wxTreeItemId& item, - wxTreeItemIcon which = wxTreeItemIcon_Normal) const - { return GetItemImage (item, GetMainColumn(), which); } - int GetItemImage (const wxTreeItemId& item, int column, - wxTreeItemIcon which = wxTreeItemIcon_Normal) const; - - // get the data associated with the item - wxTreeItemData *GetItemData(const wxTreeItemId& item) const; - - bool GetItemBold(const wxTreeItemId& item) const; - wxColour GetItemTextColour(const wxTreeItemId& item) const; - wxColour GetItemBackgroundColour(const wxTreeItemId& item) const; - wxFont GetItemFont(const wxTreeItemId& item) const; - - // modifiers - // --------- - - // set item's label - void SetItemText (const wxTreeItemId& item, const wxString& text) - { SetItemText (item, GetMainColumn(), text); } - void SetItemText (const wxTreeItemId& item, int column, const wxString& text); - - // get one of the images associated with the item (normal by default) - void SetItemImage (const wxTreeItemId& item, int image, - wxTreeItemIcon which = wxTreeItemIcon_Normal) - { SetItemImage (item, GetMainColumn(), image, which); } - void SetItemImage (const wxTreeItemId& item, int column, int image, - wxTreeItemIcon which = wxTreeItemIcon_Normal); - - // associate some data with the item - void SetItemData(const wxTreeItemId& item, wxTreeItemData *data); - - // force appearance of [+] button near the item. This is useful to - // allow the user to expand the items which don't have any children now - // - but instead add them only when needed, thus minimizing memory - // usage and loading time. - void SetItemHasChildren(const wxTreeItemId& item, bool has = true); - - // the item will be shown in bold - void SetItemBold(const wxTreeItemId& item, bool bold = true); - - // set the item's text colour - void SetItemTextColour(const wxTreeItemId& item, const wxColour& colour); - - // set the item's background colour - void SetItemBackgroundColour(const wxTreeItemId& item, const wxColour& colour); - - // set the item's font (should be of the same height for all items) - void SetItemFont(const wxTreeItemId& item, const wxFont& font); - - // set the window font - virtual bool SetFont( const wxFont &font ); - - // set the styles. No need to specify a GetWindowStyle here since - // the base wxWindow member function will do it for us - void SetWindowStyle(const long styles); - - // item status inquiries - // --------------------- - - // is the item visible (it might be outside the view or not expanded)? - bool IsVisible(const wxTreeItemId& item, bool fullRow) const; - // does the item has any children? - bool HasChildren(const wxTreeItemId& item) const; - // is the item expanded (only makes sense if HasChildren())? - bool IsExpanded(const wxTreeItemId& item) const; - // is this item currently selected (the same as has focus)? - bool IsSelected(const wxTreeItemId& item) const; - // is item text in bold font? - bool IsBold(const wxTreeItemId& item) const; - // does the layout include space for a button? - - // number of children - // ------------------ - - // if 'recursively' is false, only immediate children count, otherwise - // the returned number is the number of all items in this branch - size_t GetChildrenCount(const wxTreeItemId& item, bool recursively = true); - - // navigation - // ---------- - - // wxTreeItemId.IsOk() will return false if there is no such item - - // get the root tree item - wxTreeItemId GetRootItem() const { return m_rootItem; } - - // get the item currently selected, only if a single item is selected - // wxTreeItemId GetSelection() const { return m_selectItem; } - wxTreeItemId GetCurrent() const { return m_curItem; } - - // get all the items currently selected, return count of items - size_t GetSelections(wxArrayTreeItemIds&) const; - - // returns the number of currently selected items - size_t GetSelectionSize() const; - - // get the parent of this item (may return NULL if root) - wxTreeItemId GetItemParent(const wxTreeItemId& item) const; - - // for this enumeration function you must pass in a "cookie" parameter - // which is opaque for the application but is necessary for the library - // to make these functions reentrant (i.e. allow more than one - // enumeration on one and the same object simultaneously). Of course, - // the "cookie" passed to GetFirstChild() and GetNextChild() should be - // the same! - - // get child of this item -#if !wxCHECK_VERSION(2, 5, 0) - wxTreeItemId GetFirstChild(const wxTreeItemId& item, long& cookie) const; - wxTreeItemId GetNextChild(const wxTreeItemId& item, long& cookie) const; - wxTreeItemId GetPrevChild(const wxTreeItemId& item, long& cookie) const; - wxTreeItemId GetLastChild(const wxTreeItemId& item, long& cookie) const; -#else - wxTreeItemId GetFirstChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const; - wxTreeItemId GetNextChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const; - wxTreeItemId GetPrevChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const; - wxTreeItemId GetLastChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const; -#endif - - // get sibling of this item - wxTreeItemId GetNextSibling(const wxTreeItemId& item) const; - wxTreeItemId GetPrevSibling(const wxTreeItemId& item) const; - - // get item in the full tree (currently only for internal use) - wxTreeItemId GetNext(const wxTreeItemId& item, bool fulltree = true) const; - wxTreeItemId GetPrev(const wxTreeItemId& item, bool fulltree = true) const; - - // get expanded item, see IsExpanded() - wxTreeItemId GetFirstExpandedItem() const; - wxTreeItemId GetNextExpanded(const wxTreeItemId& item) const; - wxTreeItemId GetPrevExpanded(const wxTreeItemId& item) const; - - // get visible item, see IsVisible() - wxTreeItemId GetFirstVisibleItem(bool fullRow) const; - wxTreeItemId GetNextVisible(const wxTreeItemId& item, bool fullRow) const; - wxTreeItemId GetPrevVisible(const wxTreeItemId& item, bool fullRow) const; - - // operations - // ---------- - - // add the root node to the tree - wxTreeItemId AddRoot (const wxString& text, - int image = -1, int selectedImage = -1, - wxTreeItemData *data = NULL); - - // insert a new item in as the first child of the parent - wxTreeItemId PrependItem(const wxTreeItemId& parent, - const wxString& text, - int image = -1, int selectedImage = -1, - wxTreeItemData *data = NULL); - - // insert a new item after a given one - wxTreeItemId InsertItem(const wxTreeItemId& parent, - const wxTreeItemId& idPrevious, - const wxString& text, - int image = -1, int selectedImage = -1, - wxTreeItemData *data = NULL); - - // insert a new item before the one with the given index - wxTreeItemId InsertItem(const wxTreeItemId& parent, - size_t index, - const wxString& text, - int image = -1, int selectedImage = -1, - wxTreeItemData *data = NULL); - - // insert a new item in as the last child of the parent - wxTreeItemId AppendItem(const wxTreeItemId& parent, - const wxString& text, - int image = -1, int selectedImage = -1, - wxTreeItemData *data = NULL); - - // delete this item and associated data if any - void Delete(const wxTreeItemId& item); - // delete all children (but don't delete the item itself) - // NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events - void DeleteChildren(const wxTreeItemId& item); - // delete the root and all its children from the tree - // NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events - void DeleteRoot(); - - // expand this item - void Expand(const wxTreeItemId& item); - // expand this item and all subitems recursively - void ExpandAll(const wxTreeItemId& item); - // collapse the item without removing its children - void Collapse(const wxTreeItemId& item); - // collapse the item and remove all children - void CollapseAndReset(const wxTreeItemId& item); - // toggles the current state - void Toggle(const wxTreeItemId& item); - - // remove the selection from currently selected item (if any) - // void Unselect(wxTreeListItem* item); - // void Unselect(); - void UnselectAll(); - // select this item - void SelectItem(const wxTreeItemId& item, const wxTreeItemId& prev = (wxTreeItemId*)NULL, - bool unselect_others = true); - void SelectAll(); - void RemoveFromSelection( wxTreeListItem *item ); - void AddToSelection( wxTreeListItem *item ); - - // make sure this item is visible (expanding the parent item and/or - // scrolling to this item if necessary) - void EnsureVisible(const wxTreeItemId& item); - // scroll to this item (but don't expand its parent) - void ScrollTo(const wxTreeItemId& item); - void AdjustMyScrollbars(); - - // The first function is more portable (because easier to implement - // on other platforms), but the second one returns some extra info. - wxTreeItemId HitTest (const wxPoint& point) - { int flags; int column; return HitTest (point, flags, column); } - wxTreeItemId HitTest (const wxPoint& point, int& flags) - { int column; return HitTest (point, flags, column); } - wxTreeItemId HitTest (const wxPoint& point, int& flags, int& column); - - - // get the bounding rectangle of the item (or of its label only) - bool GetBoundingRect(const wxTreeItemId& item, - wxRect& rect, - bool textOnly = false) const; - - // Start editing the item label: this (temporarily) replaces the item - // with a one line edit control. The item will be selected if it hadn't - // been before. - void EditLabel (const wxTreeItemId& item, int column); - - // sorting - // this function is called to compare 2 items and should return -1, 0 - // or +1 if the first item is less than, equal to or greater than the - // second one. The base class version performs alphabetic comparaison - // of item labels (GetText) - virtual int OnCompareItems(const wxTreeItemId& item1, - const wxTreeItemId& item2); - // sort the children of this item using OnCompareItems - // - // NB: this function is not reentrant and not MT-safe (FIXME)! - void SortChildren(const wxTreeItemId& item); - - // searching - wxTreeItemId FindItem (const wxTreeItemId& item, const wxString& str, int mode = 0); - - // implementation only from now on - - // overridden base class virtuals - virtual bool SetBackgroundColour(const wxColour& colour); - virtual bool SetForegroundColour(const wxColour& colour); - - // drop over item - void SetDragItem (const wxTreeItemId& item = (wxTreeItemId*)NULL); - - // callbacks - void OnPaint( wxPaintEvent &event ); - void OnSetFocus( wxFocusEvent &event ); - void OnKillFocus( wxFocusEvent &event ); - void OnChar( wxKeyEvent &event ); - void OnMouse( wxMouseEvent &event ); - void OnIdle( wxIdleEvent &event ); - void OnScroll(wxScrollWinEvent& event); - - // implementation helpers - void SendDeleteEvent(wxTreeListItem *itemBeingDeleted); - - int GetColumnCount() const - { return m_owner->GetHeaderWindow()->GetColumnCount(); } - - void SetMainColumn (int column) - { if ((column >= 0) && (column < GetColumnCount())) m_main_column = column; } - - int GetMainColumn() const { return m_main_column; } - - int GetBestColumnWidth (int column, wxTreeItemId parent = wxTreeItemId()); - int GetItemWidth (int column, wxTreeListItem *item); - wxFont GetItemFont (wxTreeListItem *item); - - void SetFocus(); - -protected: - wxTreeListCtrl* m_owner; - - int m_main_column; - - friend class wxTreeListItem; - friend class wxTreeListRenameTimer; - friend class wxEditTextCtrl; - - wxFont m_normalFont; - wxFont m_boldFont; - - wxTreeListItem *m_rootItem; // root item - wxTreeListItem *m_curItem; // current item, either selected or marked - wxTreeListItem *m_shiftItem; // item, where the shift key was pressed - wxTreeListItem *m_editItem; // item, which is currently edited - // wxTreeListItem *m_selectItem; // current selected item, not with wxTR_MULTIPLE - // LG - wxArrayTreeListItems m_selected; // currently selected items - - int m_curColumn; - - int m_btnWidth, m_btnWidth2; - int m_btnHeight, m_btnHeight2; - int m_imgWidth, m_imgWidth2; - int m_imgHeight, m_imgHeight2; - unsigned short m_indent; - int m_lineHeight; - unsigned short m_linespacing; - wxPen m_dottedPen; - wxBrush *m_hilightBrush, - *m_hilightUnfocusedBrush; - bool m_hasFocus; -public: - bool m_dirty; -protected: - bool m_ownsImageListNormal, - m_ownsImageListState, - m_ownsImageListButtons; - bool m_isDragging; // true between BEGIN/END drag events - bool m_renameAccept; - bool m_lastOnSame; // last click on the same item as prev - bool m_left_down_selection; - - wxImageList *m_imageListNormal, - *m_imageListState, - *m_imageListButtons; - - int m_dragCount; - wxTimer *m_dragTimer; - wxTreeListItem *m_dragItem; - - wxTimer *m_renameTimer; - wxString m_renameRes; - - // char navigation - wxTimer *m_findTimer; - wxString m_findStr; - - // the common part of all ctors - void Init(); - - // misc helpers - wxTreeItemId DoInsertItem(const wxTreeItemId& parent, - size_t previous, - const wxString& text, - int image, int selectedImage, - wxTreeItemData *data); - bool HasButtons(void) const - { return (m_imageListButtons) || HasFlag (wxTR_TWIST_BUTTONS|wxTR_HAS_BUTTONS); } - -protected: - void CalculateLineHeight(); - int GetLineHeight(wxTreeListItem *item) const; - void PaintLevel( wxTreeListItem *item, wxDC& dc, int level, int &y, - int x_maincol); - void PaintItem( wxTreeListItem *item, wxDC& dc); - - void CalculateLevel( wxTreeListItem *item, wxDC &dc, int level, int &y, - int x_maincol); - void CalculatePositions(); - void CalculateSize( wxTreeListItem *item, wxDC &dc ); - - void RefreshSubtree (wxTreeListItem *item); - void RefreshLine (wxTreeListItem *item); - - // redraw all selected items - void RefreshSelected(); - - // RefreshSelected() recursive helper - void RefreshSelectedUnder (wxTreeListItem *item); - - void OnRenameTimer(); - void OnRenameAccept(); - - void FillArray(wxTreeListItem*, wxArrayTreeItemIds&) const; - bool SelectAllChildrenUntilLast (wxTreeListItem *crt_item, wxTreeListItem *last_item); - bool SelectNextChildren (wxTreeListItem *crt_item, wxTreeListItem *last_item); - // void UnselectAllChildren (wxTreeListItem *item ); - -private: - DECLARE_EVENT_TABLE() - DECLARE_DYNAMIC_CLASS(wxTreeListMainWindow) -}; - - -// timer used for enabling in-place edit -class wxTreeListRenameTimer: public wxTimer -{ -public: - wxTreeListRenameTimer( wxTreeListMainWindow *owner ); - - void Notify(); - -private: - wxTreeListMainWindow *m_owner; -}; - -// control used for in-place edit -class wxEditTextCtrl: public wxTextCtrl -{ -public: - wxEditTextCtrl (wxWindow *parent, - const wxWindowID id, - bool *accept, - wxString *res, - wxTreeListMainWindow *owner, - const wxString &value = wxEmptyString, - const wxPoint &pos = wxDefaultPosition, - const wxSize &size = wxDefaultSize, - int style = 0, - const wxValidator& validator = wxDefaultValidator, - const wxString &name = wxTextCtrlNameStr ); - - void OnChar( wxKeyEvent &event ); - void OnKeyUp( wxKeyEvent &event ); - void OnKillFocus( wxFocusEvent &event ); - -private: - bool *m_accept; - wxString *m_res; - wxTreeListMainWindow *m_owner; - wxString m_startValue; - bool m_finished; - - DECLARE_EVENT_TABLE() -}; - -// a tree item -class wxTreeListItem -{ -public: - // ctors & dtor - wxTreeListItem() { m_data = NULL; } - wxTreeListItem( wxTreeListMainWindow *owner, - wxTreeListItem *parent, - const wxArrayString& text, - int image, - int selImage, - wxTreeItemData *data ); - - ~wxTreeListItem(); - - // trivial accessors - wxArrayTreeListItems& GetChildren() { return m_children; } - - const wxString GetText() const - { - return GetText(0); - } - const wxString GetText (int column) const - { - if(m_text.GetCount() > 0) - { - if( IsVirtual() ) return m_owner->GetItemText( m_data, column ); - else return m_text[column]; - } - return wxEmptyString; - } - - int GetImage (wxTreeItemIcon which = wxTreeItemIcon_Normal) const - { return m_images[which]; } - int GetImage (int column, wxTreeItemIcon which=wxTreeItemIcon_Normal) const - { - if(column == m_owner->GetMainColumn()) return m_images[which]; - if(column < (int)m_col_images.GetCount()) return m_col_images[column]; - return NO_IMAGE; - } - - wxTreeItemData *GetData() const { return m_data; } - - // returns the current image for the item (depending on its - // selected/expanded/whatever state) - int GetCurrentImage() const; - - void SetText (const wxString &text ); - void SetText (int column, const wxString& text) - { - if (column < (int)m_text.GetCount()) { - m_text[column] = text; - }else if (column < m_owner->GetColumnCount()) { - int howmany = m_owner->GetColumnCount(); - for (int i = m_text.GetCount(); i < howmany; ++i) m_text.Add (wxEmptyString); - m_text[column] = text; - } - } - void SetImage (int image, wxTreeItemIcon which) { m_images[which] = image; } - void SetImage (int column, int image, wxTreeItemIcon which) - { - if (column == m_owner->GetMainColumn()) { - m_images[which] = image; - }else if (column < (int)m_col_images.GetCount()) { - m_col_images[column] = image; - }else if (column < m_owner->GetColumnCount()) { - int howmany = m_owner->GetColumnCount(); - for (int i = m_col_images.GetCount(); i < howmany; ++i) m_col_images.Add (NO_IMAGE); - m_col_images[column] = image; - } - } - - void SetData(wxTreeItemData *data) { m_data = data; } - - void SetHasPlus(bool has = true) { m_hasPlus = has; } - - void SetBold(bool bold) { m_isBold = bold; } - - int GetX() const { return m_x; } - int GetY() const { return m_y; } - - void SetX (int x) { m_x = x; } - void SetY (int y) { m_y = y; } - - int GetHeight() const { return m_height; } - int GetWidth() const { return m_width; } - - void SetHeight (int height) { m_height = height; } - void SetWidth (int width) { m_width = width; } - - int GetTextX() const { return m_text_x; } - void SetTextX (int text_x) { m_text_x = text_x; } - - wxTreeListItem *GetItemParent() const { return m_parent; } - - // operations - // deletes all children notifying the treectrl about it if !NULL - // pointer given - void DeleteChildren(wxTreeListMainWindow *tree = NULL); - - // get count of all children (and grand children if 'recursively') - size_t GetChildrenCount(bool recursively = true) const; - - void Insert(wxTreeListItem *child, size_t index) - { m_children.Insert(child, index); } - - void GetSize( int &x, int &y, const wxTreeListMainWindow* ); - - // return the item at given position (or NULL if no item), onButton is - // true if the point belongs to the item's button, otherwise it lies - // on the button's label - wxTreeListItem *HitTest (const wxPoint& point, - const wxTreeListMainWindow *, - int &flags, int& column, int level); - - void Expand() { m_isCollapsed = false; } - void Collapse() { m_isCollapsed = true; } - - void SetSelected( bool set = true ) { m_hasHilight = set; } - - // status inquiries - bool HasChildren() const { return !m_children.IsEmpty(); } - bool IsSelected() const { return m_hasHilight != 0; } - bool IsExpanded() const { return !m_isCollapsed; } - bool HasPlus() const { return m_hasPlus || HasChildren(); } - bool IsBold() const { return m_isBold != 0; } - bool IsVirtual() const { return m_owner->IsVirtual(); } - - // attributes - // get them - may be NULL - wxTreeItemAttr *GetAttributes() const { return m_attr; } - // get them ensuring that the pointer is not NULL - wxTreeItemAttr& Attr() - { - if ( !m_attr ) - { - m_attr = new wxTreeItemAttr; - m_ownsAttr = true; - } - return *m_attr; - } - // set them - void SetAttributes(wxTreeItemAttr *attr) - { - if ( m_ownsAttr ) delete m_attr; - m_attr = attr; - m_ownsAttr = false; - } - // set them and delete when done - void AssignAttributes(wxTreeItemAttr *attr) - { - SetAttributes(attr); - m_ownsAttr = true; - } - -private: - wxTreeListMainWindow *m_owner; // control the item belongs to - - // since there can be very many of these, we save size by chosing - // the smallest representation for the elements and by ordering - // the members to avoid padding. - wxArrayString m_text; // labels to be rendered for item - - wxTreeItemData *m_data; // user-provided data - - wxArrayTreeListItems m_children; // list of children - wxTreeListItem *m_parent; // parent of this item - - wxTreeItemAttr *m_attr; // attributes??? - - // tree ctrl images for the normal, selected, expanded and - // expanded+selected states - short m_images[wxTreeItemIcon_Max]; - wxArrayShort m_col_images; // images for the various columns (!= main) - - // main column item positions - wxCoord m_x; // (virtual) offset from left (vertical line) - wxCoord m_y; // (virtual) offset from top - wxCoord m_text_x; // item offset from left - short m_width; // width of this item - unsigned char m_height; // height of this item - - // use bitfields to save size - int m_isCollapsed :1; - int m_hasHilight :1; // same as focused - int m_hasPlus :1; // used for item which doesn't have - // children but has a [+] button - int m_isBold :1; // render the label in bold font - int m_ownsAttr :1; // delete attribute when done -}; - -// =========================================================================== -// implementation -// =========================================================================== - -// --------------------------------------------------------------------------- -// wxTreeListRenameTimer (internal) -// --------------------------------------------------------------------------- - -wxTreeListRenameTimer::wxTreeListRenameTimer( wxTreeListMainWindow *owner ) -{ - m_owner = owner; -} - -void wxTreeListRenameTimer::Notify() -{ - m_owner->OnRenameTimer(); -} - -//----------------------------------------------------------------------------- -// wxEditTextCtrl (internal) -//----------------------------------------------------------------------------- - -BEGIN_EVENT_TABLE (wxEditTextCtrl,wxTextCtrl) - EVT_CHAR (wxEditTextCtrl::OnChar) - EVT_KEY_UP (wxEditTextCtrl::OnKeyUp) - EVT_KILL_FOCUS (wxEditTextCtrl::OnKillFocus) -END_EVENT_TABLE() - -wxEditTextCtrl::wxEditTextCtrl (wxWindow *parent, - const wxWindowID id, - bool *accept, - wxString *res, - wxTreeListMainWindow *owner, - const wxString &value, - const wxPoint &pos, - const wxSize &size, - int style, - const wxValidator& validator, - const wxString &name) - : wxTextCtrl (parent, id, value, pos, size, style|wxSIMPLE_BORDER, validator, name) -{ - m_res = res; - m_accept = accept; - m_owner = owner; - (*m_accept) = false; - (*m_res) = wxEmptyString; - m_startValue = value; - m_finished = false; -} - -void wxEditTextCtrl::OnChar( wxKeyEvent &event ) -{ - if (event.GetKeyCode() == WXK_RETURN) - { - (*m_accept) = true; - (*m_res) = GetValue(); - - if ((*m_res) != m_startValue) - m_owner->OnRenameAccept(); - - if (!wxPendingDelete.Member(this)) - wxPendingDelete.Append(this); - - m_finished = true; - m_owner->SetFocus(); // This doesn't work. TODO. - - return; - } - if (event.GetKeyCode() == WXK_ESCAPE) - { - (*m_accept) = false; - (*m_res) = wxEmptyString; - - if (!wxPendingDelete.Member(this)) - wxPendingDelete.Append(this); - - m_finished = true; - m_owner->SetFocus(); // This doesn't work. TODO. - - return; - } - event.Skip(); -} - -void wxEditTextCtrl::OnKeyUp( wxKeyEvent &event ) -{ - if (m_finished) - { - event.Skip(); - return; - } - - // auto-grow the textctrl: - wxSize parentSize = m_owner->GetSize(); - wxPoint myPos = GetPosition(); - wxSize mySize = GetSize(); - int sx, sy; - GetTextExtent(GetValue() + _T("M"), &sx, &sy); - if (myPos.x + sx > parentSize.x) sx = parentSize.x - myPos.x; - if (mySize.x > sx) sx = mySize.x; - SetSize(sx, -1); - - event.Skip(); -} - -void wxEditTextCtrl::OnKillFocus( wxFocusEvent &event ) -{ - if (m_finished) - { - event.Skip(); - return; - } - - if (!wxPendingDelete.Member(this)) - wxPendingDelete.Append(this); - - (*m_accept) = true; - (*m_res) = GetValue(); - - if ((*m_res) != m_startValue) - m_owner->OnRenameAccept(); -} - -//----------------------------------------------------------------------------- -// wxTreeListHeaderWindow -//----------------------------------------------------------------------------- - - - -//EED -//IMPLEMENT_DYNAMIC_CLASS(wxTreeListHeaderWindow,wxNotifyEvent); -IMPLEMENT_CLASS(wxTreeListHeaderWindow,wxNotifyEvent); - -BEGIN_EVENT_TABLE(wxTreeListHeaderWindow,wxWindow) - EVT_PAINT (wxTreeListHeaderWindow::OnPaint) - EVT_MOUSE_EVENTS (wxTreeListHeaderWindow::OnMouse) - EVT_SET_FOCUS (wxTreeListHeaderWindow::OnSetFocus) -END_EVENT_TABLE() - - - - -void wxTreeListHeaderWindow::Init() -{ - m_currentCursor = (wxCursor *) NULL; - m_isDragging = false; - m_dirty = false; - m_total_col_width = 0; -} - -wxTreeListHeaderWindow::wxTreeListHeaderWindow() -{ - Init(); - - m_owner = (wxTreeListMainWindow *) NULL; - m_resizeCursor = (wxCursor *) NULL; -} - -wxTreeListHeaderWindow::wxTreeListHeaderWindow( wxWindow *win, - wxWindowID id, - wxTreeListMainWindow *owner, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString &name ) - : wxWindow( win, id, pos, size, style, name ) -{ - Init(); - - m_owner = owner; - m_resizeCursor = new wxCursor(wxCURSOR_SIZEWE); - -#if !wxCHECK_VERSION(2, 5, 0) - SetBackgroundColour (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_BTNFACE)); -#else - SetBackgroundColour (wxSystemSettings::GetColour (wxSYS_COLOUR_BTNFACE)); -#endif -} - -wxTreeListHeaderWindow::~wxTreeListHeaderWindow() -{ - delete m_resizeCursor; -} - -void wxTreeListHeaderWindow::DoDrawRect( wxDC *dc, int x, int y, int w, int h ) -{ -#if !wxCHECK_VERSION(2, 5, 0) - wxPen pen (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_BTNSHADOW ), 1, wxSOLID); -#else - wxPen pen (wxSystemSettings::GetColour (wxSYS_COLOUR_BTNSHADOW ), 1, wxSOLID); -#endif - - const int m_corner = 1; - - dc->SetBrush( *wxTRANSPARENT_BRUSH ); -#if defined( __WXMAC__ ) - dc->SetPen (pen); -#else // !GTK, !Mac - dc->SetPen( *wxBLACK_PEN ); -#endif - dc->DrawLine( x+w-m_corner+1, y, x+w, y+h ); // right (outer) - dc->DrawRectangle( x, y+h, w+1, 1 ); // bottom (outer) - -#if defined( __WXMAC__ ) - - // EED - // wxPen pen( wxColour( 0x88 , 0x88 , 0x88 ), 1, wxSOLID ); - pen.SetColour( wxColour( 0x88 , 0x88 , 0x88 ) ); - -#endif - dc->SetPen( pen ); - dc->DrawLine( x+w-m_corner, y, x+w-1, y+h ); // right (inner) - dc->DrawRectangle( x+1, y+h-1, w-2, 1 ); // bottom (inner) - - dc->SetPen( *wxWHITE_PEN ); - dc->DrawRectangle( x, y, w-m_corner+1, 1 ); // top (outer) - dc->DrawRectangle( x, y, 1, h ); // left (outer) - dc->DrawLine( x, y+h-1, x+1, y+h-1 ); - dc->DrawLine( x+w-1, y, x+w-1, y+1 ); -} - -// shift the DC origin to match the position of the main window horz -// scrollbar: this allows us to always use logical coords -void wxTreeListHeaderWindow::AdjustDC(wxDC& dc) -{ - int xpix; - m_owner->GetScrollPixelsPerUnit( &xpix, NULL ); - int x; - m_owner->GetViewStart( &x, NULL ); - - // account for the horz scrollbar offset - dc.SetDeviceOrigin( -x * xpix, 0 ); -} - -void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) -{ -#ifdef __WXGTK__ - wxClientDC dc( this ); -#else - wxPaintDC dc( this ); -#endif - - PrepareDC( dc ); - AdjustDC( dc ); - dc.SetFont( GetFont() ); - - // width and height of the entire header window - int w, h; - GetClientSize( &w, &h ); - m_owner->CalcUnscrolledPosition(w, 0, &w, NULL); - dc.SetBackgroundMode(wxTRANSPARENT); - - // do *not* use the listctrl colour for headers - one day we will have a - // function to set it separately - //dc.SetTextForeground( *wxBLACK ); -#if !wxCHECK_VERSION(2, 5, 0) - dc.SetTextForeground (wxSystemSettings::GetSystemColour( wxSYS_COLOUR_WINDOWTEXT )); -#else - dc.SetTextForeground (wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT )); -#endif - - int x = HEADER_OFFSET_X; - - int numColumns = GetColumnCount(); - for ( int i = 0; i < numColumns && x < w; i++ ) - { - if (!IsColumnShown (i)) continue; // do next colume if not shown - - wxTreeListColumnInfo& column = GetColumn(i); - int wCol = column.GetWidth(); - - // the width of the rect to draw: make it smaller to fit entirely - // inside the column rect - int cw = wCol - 2; - - dc.SetPen( *wxWHITE_PEN ); - DoDrawRect( &dc, x, HEADER_OFFSET_Y, cw, h-2 ); - - // if we have an image, draw it on the right of the label - int image = column.GetImage(); //item.m_image; - int ix = -2, iy = 0; - wxImageList* imageList = m_owner->GetImageList(); - if ((image != -1) && imageList) { - imageList->GetSize (image, ix, iy); - } - - // extra margins around the text label - int text_width = 0; - int text_x = x; - int image_offset = cw - ix - 1; - - switch(column.GetAlignment()) { - case wxALIGN_LEFT: - text_x += EXTRA_WIDTH; - cw -= ix + 2; - break; - case wxALIGN_RIGHT: - dc.GetTextExtent (column.GetText(), &text_width, NULL); - text_x += cw - text_width - EXTRA_WIDTH - MARGIN; - image_offset = 0; - break; - case wxALIGN_CENTER: - dc.GetTextExtent(column.GetText(), &text_width, NULL); - text_x += (cw - text_width)/2 + ix + 2; - image_offset = (cw - text_width - ix - 2)/2 - MARGIN; - break; - } - - // draw the image - if ((image != -1) && imageList) { - imageList->Draw (image, dc, x + image_offset/*cw - ix - 1*/, - HEADER_OFFSET_Y + (h - 4 - iy)/2, - wxIMAGELIST_DRAW_TRANSPARENT); - } - - // draw the text clipping it so that it doesn't overwrite the column boundary - wxDCClipper clipper(dc, x, HEADER_OFFSET_Y, cw, h - 4 ); - dc.DrawText (column.GetText(), text_x, HEADER_OFFSET_Y + EXTRA_HEIGHT ); - - // next column - x += wCol; - } - - int more_w = m_owner->GetSize().x - x - HEADER_OFFSET_X; - if (more_w > 0) { - DoDrawRect (&dc, x, HEADER_OFFSET_Y, more_w, h-2 ); - } - -} - -void wxTreeListHeaderWindow::DrawCurrent() -{ - int x1 = m_currentX; - int y1 = 0; - ClientToScreen (&x1, &y1); - - int x2 = m_currentX-1; -#ifdef __WXMSW__ - ++x2; // but why ???? -#endif - int y2 = 0; - m_owner->GetClientSize( NULL, &y2 ); - m_owner->ClientToScreen( &x2, &y2 ); - - wxScreenDC dc; - dc.SetLogicalFunction (wxINVERT); - dc.SetPen (wxPen (*wxBLACK, 2, wxSOLID)); - dc.SetBrush (*wxTRANSPARENT_BRUSH); - - AdjustDC(dc); - dc.DrawLine (x1, y1, x2, y2); - dc.SetLogicalFunction (wxCOPY); - dc.SetPen (wxNullPen); - dc.SetBrush (wxNullBrush); -} - -void wxTreeListHeaderWindow::OnMouse (wxMouseEvent &event) { - - // we want to work with logical coords - int x; - m_owner->CalcUnscrolledPosition(event.GetX(), 0, &x, NULL); - int y = event.GetY(); - - if (m_isDragging) { - - SendListEvent (wxEVT_COMMAND_LIST_COL_DRAGGING, event.GetPosition()); - - // we don't draw the line beyond our window, but we allow dragging it - // there - int w = 0; - GetClientSize( &w, NULL ); - m_owner->CalcUnscrolledPosition(w, 0, &w, NULL); - w -= 6; - - // erase the line if it was drawn - if (m_currentX < w) DrawCurrent(); - - if (event.ButtonUp()) { - m_isDragging = false; - if (HasCapture()) ReleaseMouse(); - m_dirty = true; - SetColumnWidth (m_column, m_currentX - m_minX); - Refresh(); - SendListEvent (wxEVT_COMMAND_LIST_COL_END_DRAG, event.GetPosition()); - }else{ - m_currentX = wxMax (m_minX + 7, x); - - // draw in the new location - if (m_currentX < w) DrawCurrent(); - } - - }else{ // not dragging - - m_minX = 0; - bool hit_border = false; - - // end of the current column - int xpos = 0; - - // find the column where this event occured - int countCol = GetColumnCount(); - for (int column = 0; column < countCol; column++) { - if (!IsColumnShown (column)) continue; // do next if not shown - - xpos += GetColumnWidth (column); - m_column = column; - if ((abs (x-xpos) < 3) && (y < 22)) { - // near the column border - hit_border = true; - break; - } - - if (x < xpos) { - // inside the column - break; - } - - m_minX = xpos; - } - - if (event.LeftDown() || event.RightUp()) { - if (hit_border && event.LeftDown()) { - m_isDragging = true; - CaptureMouse(); - m_currentX = x; - DrawCurrent(); - SendListEvent (wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, event.GetPosition()); - }else{ // click on a column - wxEventType evt = event.LeftDown()? wxEVT_COMMAND_LIST_COL_CLICK: - wxEVT_COMMAND_LIST_COL_RIGHT_CLICK; - SendListEvent (evt, event.GetPosition()); - } - }else if (event.LeftDClick() && hit_border) { - SetColumnWidth (m_column, m_owner->GetBestColumnWidth (m_column)); - Refresh(); - - }else if (event.Moving()) { - bool setCursor; - if (hit_border) { - setCursor = m_currentCursor == wxSTANDARD_CURSOR; - m_currentCursor = m_resizeCursor; - }else{ - setCursor = m_currentCursor != wxSTANDARD_CURSOR; - m_currentCursor = wxSTANDARD_CURSOR; - } - if (setCursor) SetCursor (*m_currentCursor); - } - - } -} - -void wxTreeListHeaderWindow::OnSetFocus (wxFocusEvent &WXUNUSED(event)) { - m_owner->SetFocus(); -} - -void wxTreeListHeaderWindow::SendListEvent (wxEventType type, wxPoint pos) { - wxWindow *parent = GetParent(); - wxListEvent le (type, parent->GetId()); - le.SetEventObject (parent); - le.m_pointDrag = pos; - - // the position should be relative to the parent window, not - // this one for compatibility with MSW and common sense: the - // user code doesn't know anything at all about this header - // window, so why should it get positions relative to it? - le.m_pointDrag.y -= GetSize().y; - le.m_col = m_column; - parent->GetEventHandler()->ProcessEvent (le); -} - -void wxTreeListHeaderWindow::AddColumn (const wxTreeListColumnInfo& colInfo) { - m_columns.Add (colInfo); - m_total_col_width += colInfo.GetWidth(); - m_owner->AdjustMyScrollbars(); - m_owner->m_dirty = true; -} - -void wxTreeListHeaderWindow::SetColumnWidth (int column, int width) { - wxCHECK_RET ((column >= 0) && (column < GetColumnCount()), _T("Invalid column")); - m_total_col_width -= m_columns[column].GetWidth(); - m_columns[column].SetWidth(width); - m_total_col_width += width; - m_owner->AdjustMyScrollbars(); - m_owner->m_dirty = true; -} - -void wxTreeListHeaderWindow::InsertColumn (int before, const wxTreeListColumnInfo& colInfo) { - wxCHECK_RET ((before >= 0) && (before < GetColumnCount()), _T("Invalid column")); - m_columns.Insert (colInfo, before); - m_total_col_width += colInfo.GetWidth(); - m_owner->AdjustMyScrollbars(); - m_owner->m_dirty = true; -} - -void wxTreeListHeaderWindow::RemoveColumn (int column) { - wxCHECK_RET ((column >= 0) && (column < GetColumnCount()), _T("Invalid column")); - m_total_col_width -= m_columns[column].GetWidth(); - m_columns.RemoveAt (column); - m_owner->AdjustMyScrollbars(); - m_owner->m_dirty = true; -} - -void wxTreeListHeaderWindow::SetColumn (int column, const wxTreeListColumnInfo& info) { - wxCHECK_RET ((column >= 0) && (column < GetColumnCount()), _T("Invalid column")); - int w = m_columns[column].GetWidth(); - m_columns[column] = info; - if (w != info.GetWidth()) { - m_total_col_width += info.GetWidth() - w; - m_owner->AdjustMyScrollbars(); - } - m_owner->m_dirty = true; -} - -// --------------------------------------------------------------------------- -// wxTreeListItem -// --------------------------------------------------------------------------- - -wxTreeListItem::wxTreeListItem (wxTreeListMainWindow *owner, - wxTreeListItem *parent, - const wxArrayString& text, - int image, int selImage, - wxTreeItemData *data) - : m_text (text) { - - m_images[wxTreeItemIcon_Normal] = image; - m_images[wxTreeItemIcon_Selected] = selImage; - m_images[wxTreeItemIcon_Expanded] = NO_IMAGE; - m_images[wxTreeItemIcon_SelectedExpanded] = NO_IMAGE; - - m_data = data; - m_x = 0; - m_y = 0; - m_text_x = 0; - - m_isCollapsed = true; - m_hasHilight = false; - m_hasPlus = false; - m_isBold = false; - - m_owner = owner; - m_parent = parent; - - m_attr = (wxTreeItemAttr *)NULL; - m_ownsAttr = false; - - // We don't know the height here yet. - m_width = 0; - m_height = 0; -} - -wxTreeListItem::~wxTreeListItem() { - delete m_data; - if (m_ownsAttr) delete m_attr; - - wxASSERT_MSG( m_children.IsEmpty(), _T("please call DeleteChildren() before destructor")); -} - -void wxTreeListItem::DeleteChildren (wxTreeListMainWindow *tree) { - size_t count = m_children.Count(); - for (size_t n = 0; n < count; n++) { - wxTreeListItem *child = m_children[n]; - if (tree) { - tree->SendDeleteEvent (child); - // LG - tree->RemoveFromSelection(child); - /* - if (child->IsSelected()) - { - tree->Unselect(child); - } - */ - // if (tree->m_selectItem == child) tree->m_selectItem = (wxTreeListItem*)NULL; - } - child->DeleteChildren (tree); - delete child; - } - m_children.Empty(); -} - -void wxTreeListItem::SetText (const wxString &text) { - if (m_text.GetCount() > 0) { - m_text[0] = text; - }else{ - m_text.Add (text); - } -} - -size_t wxTreeListItem::GetChildrenCount (bool recursively) const { - size_t count = m_children.Count(); - if (!recursively) return count; - - size_t total = count; - for (size_t n = 0; n < count; ++n) { - total += m_children[n]->GetChildrenCount(); - } - return total; -} - -void wxTreeListItem::GetSize (int &x, int &y, const wxTreeListMainWindow *theButton) { - int bottomY = m_y + theButton->GetLineHeight (this); - if (y < bottomY) y = bottomY; - int width = m_x + m_width; - if ( x < width ) x = width; - - if (IsExpanded()) { - size_t count = m_children.Count(); - for (size_t n = 0; n < count; ++n ) { - m_children[n]->GetSize (x, y, theButton); - } - } -} - -wxTreeListItem *wxTreeListItem::HitTest (const wxPoint& point, - const wxTreeListMainWindow *theCtrl, - int &flags, int& column, int level) { - - // for a hidden root node, don't evaluate it, but do evaluate children - if (!theCtrl->HasFlag(wxTR_HIDE_ROOT) || (level > 0)) { - - // reset any previous hit infos - flags = 0; - column = -1; - wxTreeListHeaderWindow* header_win = theCtrl->m_owner->GetHeaderWindow(); - - // check for right of all columns (outside) - if (point.x > header_win->GetWidth()) return (wxTreeListItem*) NULL; - - // evaluate if y-pos is okay - int h = theCtrl->GetLineHeight (this); - if ((point.y >= m_y) && (point.y <= m_y + h)) { - - int maincol = theCtrl->GetMainColumn(); - - // check for above/below middle - int y_mid = m_y + h/2; - if (point.y < y_mid) { - flags |= wxTREE_HITTEST_ONITEMUPPERPART; - }else{ - flags |= wxTREE_HITTEST_ONITEMLOWERPART; - } - - // check for button hit - if (HasPlus() && theCtrl->HasButtons()) { - int bntX = m_x - theCtrl->m_btnWidth2; - int bntY = y_mid - theCtrl->m_btnHeight2; - if ((point.x >= bntX) && (point.x <= (bntX + theCtrl->m_btnWidth)) && - (point.y >= bntY) && (point.y <= (bntY + theCtrl->m_btnHeight))) { - flags |= wxTREE_HITTEST_ONITEMBUTTON; - column = maincol; - return this; - } - } - - // check for image hit - if (theCtrl->m_imgWidth > 0) { - int imgX = m_text_x - theCtrl->m_imgWidth - MARGIN; - int imgY = y_mid - theCtrl->m_imgHeight2; - if ((point.x >= imgX) && (point.x <= (imgX + theCtrl->m_imgWidth)) && - (point.y >= imgY) && (point.y <= (imgY + theCtrl->m_imgHeight))) { - flags |= wxTREE_HITTEST_ONITEMICON; - column = maincol; - return this; - } - } - - // check for label hit - if ((point.x >= m_text_x) && (point.x <= (m_text_x + m_width))) { - flags |= wxTREE_HITTEST_ONITEMLABEL; - column = maincol; - return this; - } - - // check for indent hit after button and image hit - if (point.x < m_x) { - flags |= wxTREE_HITTEST_ONITEMINDENT; - column = -1; // considered not belonging to main column - return this; - } - - // check for right of label - int end = 0; - for (int i = 0; i <= maincol; ++i) end += header_win->GetColumnWidth (i); - if ((point.x > (m_text_x + m_width)) && (point.x <= end)) { - flags |= wxTREE_HITTEST_ONITEMRIGHT; - column = -1; // considered not belonging to main column - return this; - } - - // else check for each column except main - int x = 0; - for (int j = 0; j < theCtrl->GetColumnCount(); ++j) { - if (!header_win->IsColumnShown(j)) continue; - int w = header_win->GetColumnWidth (j); - if ((j != maincol) && (point.x >= x && point.x < x+w)) { - flags |= wxTREE_HITTEST_ONITEMCOLUMN; - column = j; - return this; - } - x += w; - } - - // no special flag or column found - return this; - - } - - // if children not expanded, return no item - if (!IsExpanded()) return (wxTreeListItem*) NULL; - } - - // in any case evaluate children - wxTreeListItem *child; - size_t count = m_children.Count(); - for (size_t n = 0; n < count; n++) { - child = m_children[n]->HitTest (point, theCtrl, flags, column, level+1); - if (child) return child; - } - - // not found - return (wxTreeListItem*) NULL; -} - -int wxTreeListItem::GetCurrentImage() const { - int image = NO_IMAGE; - if (IsExpanded()) { - if (IsSelected()) { - image = GetImage (wxTreeItemIcon_SelectedExpanded); - }else{ - image = GetImage (wxTreeItemIcon_Expanded); - } - }else{ // not expanded - if (IsSelected()) { - image = GetImage (wxTreeItemIcon_Selected); - }else{ - image = GetImage (wxTreeItemIcon_Normal); - } - } - - // maybe it doesn't have the specific image, try the default one instead - if (image == NO_IMAGE) image = GetImage(); - - return image; -} - -// --------------------------------------------------------------------------- -// wxTreeListMainWindow implementation -// --------------------------------------------------------------------------- - -IMPLEMENT_DYNAMIC_CLASS(wxTreeListMainWindow, wxScrolledWindow) - -BEGIN_EVENT_TABLE(wxTreeListMainWindow, wxScrolledWindow) - EVT_PAINT (wxTreeListMainWindow::OnPaint) - EVT_MOUSE_EVENTS (wxTreeListMainWindow::OnMouse) - EVT_CHAR (wxTreeListMainWindow::OnChar) - EVT_SET_FOCUS (wxTreeListMainWindow::OnSetFocus) - EVT_KILL_FOCUS (wxTreeListMainWindow::OnKillFocus) - EVT_IDLE (wxTreeListMainWindow::OnIdle) - EVT_SCROLLWIN (wxTreeListMainWindow::OnScroll) -END_EVENT_TABLE() - - -// --------------------------------------------------------------------------- -// construction/destruction -// --------------------------------------------------------------------------- - -void wxTreeListMainWindow::Init() { - - m_rootItem = (wxTreeListItem*)NULL; - m_curItem = (wxTreeListItem*)NULL; - m_shiftItem = (wxTreeListItem*)NULL; - m_editItem = (wxTreeListItem*)NULL; - // LG - // m_selectItem = (wxTreeListItem*)NULL; - - m_curColumn = -1; // no current column - - m_hasFocus = false; - m_dirty = false; - - m_lineHeight = LINEHEIGHT; - m_indent = MININDENT; // min. indent - m_linespacing = 4; - -#if !wxCHECK_VERSION(2, 5, 0) - m_hilightBrush = new wxBrush (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_HIGHLIGHT), wxSOLID); - m_hilightUnfocusedBrush = new wxBrush (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_BTNSHADOW), wxSOLID); -#else - m_hilightBrush = new wxBrush (wxSystemSettings::GetColour (wxSYS_COLOUR_HIGHLIGHT), wxSOLID); - m_hilightUnfocusedBrush = new wxBrush (wxSystemSettings::GetColour (wxSYS_COLOUR_BTNSHADOW), wxSOLID); -#endif - - m_imageListNormal = (wxImageList *) NULL; - m_imageListButtons = (wxImageList *) NULL; - m_imageListState = (wxImageList *) NULL; - m_ownsImageListNormal = m_ownsImageListButtons = - m_ownsImageListState = false; - - m_imgWidth = 0, m_imgWidth2 = 0; - m_imgHeight = 0, m_imgHeight2 = 0; - m_btnWidth = 0, m_btnWidth2 = 0; - m_btnHeight = 0, m_btnHeight2 = 0; - - m_dragCount = 0; - m_isDragging = false; - m_dragTimer = new wxTimer (this, -1); - m_dragItem = (wxTreeListItem*)NULL; - - m_renameTimer = new wxTreeListRenameTimer (this); - m_lastOnSame = false; - m_left_down_selection = false; - - m_findTimer = new wxTimer (this, -1); - -#if defined( __WXMAC__ ) && defined(__WXMAC_CARBON__) - m_normalFont.MacCreateThemeFont (kThemeViewsFont); -#else - m_normalFont = wxSystemSettings::GetFont (wxSYS_DEFAULT_GUI_FONT); -#endif - m_boldFont = wxFont( m_normalFont.GetPointSize(), - m_normalFont.GetFamily(), - m_normalFont.GetStyle(), - wxBOLD, - m_normalFont.GetUnderlined(), - m_normalFont.GetFaceName(), - m_normalFont.GetEncoding()); -} - -bool wxTreeListMainWindow::Create (wxTreeListCtrl *parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style, - const wxValidator &validator, - const wxString& name) { - -#ifdef __WXMAC__ - if (style & wxTR_HAS_BUTTONS) style |= wxTR_MAC_BUTTONS; - if (style & wxTR_HAS_BUTTONS) style &= ~wxTR_HAS_BUTTONS; - style &= ~wxTR_LINES_AT_ROOT; - style |= wxTR_NO_LINES; - - int major,minor; - wxGetOsVersion( &major, &minor ); - if (major < 10) style |= wxTR_ROW_LINES; -#endif - - wxScrolledWindow::Create (parent, id, pos, size, style|wxHSCROLL|wxVSCROLL, name); - -#if wxUSE_VALIDATORS - SetValidator(validator); -#endif - -#if !wxCHECK_VERSION(2, 5, 0) - SetBackgroundColour (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_LISTBOX)); -#else - SetBackgroundColour (wxSystemSettings::GetColour (wxSYS_COLOUR_LISTBOX)); -#endif - -#ifdef __WXMSW__ - { - int i, j; - wxBitmap bmp(8, 8); - wxMemoryDC bdc; - bdc.SelectObject(bmp); - bdc.SetPen(*wxGREY_PEN); - bdc.DrawRectangle(-1, -1, 10, 10); - for (i = 0; i < 8; i++) { - for (j = 0; j < 8; j++) { - if (!((i + j) & 1)) { - bdc.DrawPoint(i, j); - } - } - } - - m_dottedPen = wxPen(bmp, 1); - } -#else -//? m_dottedPen = wxPen( *wxGREY_PEN, 1, wxDOT ); // too slow under XFree86 - m_dottedPen = wxPen( _T("grey"), 0, 0 ); // Bitmap based pen is not supported by GTK! -#endif - - m_owner = parent; - m_main_column = 0; - - return true; -} - -wxTreeListMainWindow::~wxTreeListMainWindow() { - delete m_hilightBrush; - delete m_hilightUnfocusedBrush; - - delete m_dragTimer; - delete m_renameTimer; - delete m_findTimer; - if (m_ownsImageListNormal) delete m_imageListNormal; - if (m_ownsImageListState) delete m_imageListState; - if (m_ownsImageListButtons) delete m_imageListButtons; - - DeleteRoot(); -} - - -//----------------------------------------------------------------------------- -// accessors -//----------------------------------------------------------------------------- - -size_t wxTreeListMainWindow::GetCount() const { - return m_rootItem == NULL? 0: m_rootItem->GetChildrenCount(); -} - -void wxTreeListMainWindow::SetIndent (unsigned int indent) { - m_indent = wxMax (MININDENT, indent); - m_dirty = true; -} - -void wxTreeListMainWindow::SetLineSpacing (unsigned int spacing) { - m_linespacing = spacing; - m_dirty = true; - CalculateLineHeight(); -} - -size_t wxTreeListMainWindow::GetChildrenCount (const wxTreeItemId& item, - bool recursively) { - wxCHECK_MSG (item.IsOk(), 0u, _T("invalid tree item")); - return ((wxTreeListItem*)item.m_pItem)->GetChildrenCount (recursively); -} - -void wxTreeListMainWindow::SetWindowStyle (const long styles) { - // right now, just sets the styles. Eventually, we may - // want to update the inherited styles, but right now - // none of the parents has updatable styles - m_windowStyle = styles; - m_dirty = true; -} - -//----------------------------------------------------------------------------- -// functions to work with tree items -//----------------------------------------------------------------------------- - -int wxTreeListMainWindow::GetItemImage (const wxTreeItemId& item, int column, - wxTreeItemIcon which) const { - wxCHECK_MSG (item.IsOk(), -1, _T("invalid tree item")); - return ((wxTreeListItem*) item.m_pItem)->GetImage (column, which); -} - -wxTreeItemData *wxTreeListMainWindow::GetItemData (const wxTreeItemId& item) const { - wxCHECK_MSG (item.IsOk(), NULL, _T("invalid tree item")); - return ((wxTreeListItem*) item.m_pItem)->GetData(); -} - -bool wxTreeListMainWindow::GetItemBold (const wxTreeItemId& item) const { - wxCHECK_MSG(item.IsOk(), false, _T("invalid tree item")); - return ((wxTreeListItem *)item.m_pItem)->IsBold(); -} - -wxColour wxTreeListMainWindow::GetItemTextColour (const wxTreeItemId& item) const { - wxCHECK_MSG (item.IsOk(), wxNullColour, _T("invalid tree item")); - wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; - return pItem->Attr().GetTextColour(); -} - -wxColour wxTreeListMainWindow::GetItemBackgroundColour (const wxTreeItemId& item) const { - wxCHECK_MSG (item.IsOk(), wxNullColour, _T("invalid tree item")); - wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; - return pItem->Attr().GetBackgroundColour(); -} - -wxFont wxTreeListMainWindow::GetItemFont (const wxTreeItemId& item) const { - wxCHECK_MSG (item.IsOk(), wxNullFont, _T("invalid tree item")); - wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; - return pItem->Attr().GetFont(); -} - -void wxTreeListMainWindow::SetItemImage (const wxTreeItemId& item, int column, - int image, wxTreeItemIcon which) { - wxCHECK_RET (item.IsOk(), _T("invalid tree item")); - wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; - pItem->SetImage (column, image, which); - wxClientDC dc (this); - CalculateSize (pItem, dc); - RefreshLine (pItem); -} - -void wxTreeListMainWindow::SetItemData (const wxTreeItemId& item, - wxTreeItemData *data) { - wxCHECK_RET (item.IsOk(), _T("invalid tree item")); - ((wxTreeListItem*) item.m_pItem)->SetData(data); -} - -void wxTreeListMainWindow::SetItemHasChildren (const wxTreeItemId& item, - bool has) { - wxCHECK_RET (item.IsOk(), _T("invalid tree item")); - wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; - pItem->SetHasPlus (has); - RefreshLine (pItem); -} - -void wxTreeListMainWindow::SetItemBold (const wxTreeItemId& item, bool bold) { - wxCHECK_RET (item.IsOk(), _T("invalid tree item")); - wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; - if (pItem->IsBold() != bold) { // avoid redrawing if no real change - pItem->SetBold (bold); - RefreshLine (pItem); - } -} - -void wxTreeListMainWindow::SetItemTextColour (const wxTreeItemId& item, - const wxColour& colour) { - wxCHECK_RET (item.IsOk(), _T("invalid tree item")); - wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; - pItem->Attr().SetTextColour (colour); - RefreshLine (pItem); -} - -void wxTreeListMainWindow::SetItemBackgroundColour (const wxTreeItemId& item, - const wxColour& colour) { - wxCHECK_RET (item.IsOk(), _T("invalid tree item")); - wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; - pItem->Attr().SetBackgroundColour (colour); - RefreshLine (pItem); -} - -void wxTreeListMainWindow::SetItemFont (const wxTreeItemId& item, - const wxFont& font) { - wxCHECK_RET (item.IsOk(), _T("invalid tree item")); - wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; - pItem->Attr().SetFont (font); - RefreshLine (pItem); -} - -bool wxTreeListMainWindow::SetFont (const wxFont &font) { - wxScrolledWindow::SetFont (font); - m_normalFont = font; - m_boldFont = wxFont (m_normalFont.GetPointSize(), - m_normalFont.GetFamily(), - m_normalFont.GetStyle(), - wxBOLD, - m_normalFont.GetUnderlined(), - m_normalFont.GetFaceName()); - CalculateLineHeight(); - return true; -} - - -// ---------------------------------------------------------------------------- -// item status inquiries -// ---------------------------------------------------------------------------- - -bool wxTreeListMainWindow::IsVisible (const wxTreeItemId& item, bool fullRow) const { - wxCHECK_MSG (item.IsOk(), false, _T("invalid tree item")); - - // An item is only visible if it's not a descendant of a collapsed item - wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; - wxTreeListItem* parent = pItem->GetItemParent(); - while (parent) { - if (parent == m_rootItem && HasFlag(wxTR_HIDE_ROOT)) break; - if (!parent->IsExpanded()) return false; - parent = parent->GetItemParent(); - } - - wxSize clientSize = GetClientSize(); - wxRect rect; - if ((!GetBoundingRect (item, rect)) || - ((!fullRow && rect.GetWidth() == 0) || rect.GetHeight() == 0) || - (rect.GetBottom() < 0 || rect.GetTop() > clientSize.y) || - (!fullRow && (rect.GetRight() < 0 || rect.GetLeft() > clientSize.x))) return false; - - return true; -} - -bool wxTreeListMainWindow::HasChildren (const wxTreeItemId& item) const { - wxCHECK_MSG (item.IsOk(), false, _T("invalid tree item")); - - // consider that the item does have children if it has the "+" button: it - // might not have them (if it had never been expanded yet) but then it - // could have them as well and it's better to err on this side rather than - // disabling some operations which are restricted to the items with - // children for an item which does have them - return ((wxTreeListItem*) item.m_pItem)->HasPlus(); -} - -bool wxTreeListMainWindow::IsExpanded (const wxTreeItemId& item) const { - wxCHECK_MSG (item.IsOk(), false, _T("invalid tree item")); - return ((wxTreeListItem*) item.m_pItem)->IsExpanded(); -} - -bool wxTreeListMainWindow::IsSelected (const wxTreeItemId& item) const { - wxCHECK_MSG (item.IsOk(), false, _T("invalid tree item")); - return ((wxTreeListItem*) item.m_pItem)->IsSelected(); -} - -bool wxTreeListMainWindow::IsBold (const wxTreeItemId& item) const { - wxCHECK_MSG (item.IsOk(), false, _T("invalid tree item")); - return ((wxTreeListItem*) item.m_pItem)->IsBold(); -} - -// ---------------------------------------------------------------------------- -// navigation -// ---------------------------------------------------------------------------- - -wxTreeItemId wxTreeListMainWindow::GetItemParent (const wxTreeItemId& item) const { - wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); - return ((wxTreeListItem*) item.m_pItem)->GetItemParent(); -} - -#if !wxCHECK_VERSION(2, 5, 0) -wxTreeItemId wxTreeListMainWindow::GetFirstChild (const wxTreeItemId& item, - long& cookie) const { -#else -wxTreeItemId wxTreeListMainWindow::GetFirstChild (const wxTreeItemId& item, - wxTreeItemIdValue& cookie) const { -#endif - wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); - wxArrayTreeListItems& children = ((wxTreeListItem*) item.m_pItem)->GetChildren(); - cookie = 0; - return (!children.IsEmpty())? wxTreeItemId(children.Item(0)): wxTreeItemId(); -} - -#if !wxCHECK_VERSION(2, 5, 0) -wxTreeItemId wxTreeListMainWindow::GetNextChild (const wxTreeItemId& item, - long& cookie) const { -#else -wxTreeItemId wxTreeListMainWindow::GetNextChild (const wxTreeItemId& item, - wxTreeItemIdValue& cookie) const { -#endif - wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); - wxArrayTreeListItems& children = ((wxTreeListItem*) item.m_pItem)->GetChildren(); - // it's ok to cast cookie to long, we never have indices which overflow "void*" - long *pIndex = ((long*)&cookie); - return ((*pIndex)+1 < (long)children.Count())? wxTreeItemId(children.Item(++(*pIndex))): wxTreeItemId(); -} - -#if !wxCHECK_VERSION(2, 5, 0) -wxTreeItemId wxTreeListMainWindow::GetPrevChild (const wxTreeItemId& item, - long& cookie) const { -#else -wxTreeItemId wxTreeListMainWindow::GetPrevChild (const wxTreeItemId& item, - wxTreeItemIdValue& cookie) const { -#endif - wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); - wxArrayTreeListItems& children = ((wxTreeListItem*) item.m_pItem)->GetChildren(); - // it's ok to cast cookie to long, we never have indices which overflow "void*" - long *pIndex = (long*)&cookie; - return ((*pIndex)-1 >= 0)? wxTreeItemId(children.Item(--(*pIndex))): wxTreeItemId(); -} - -#if !wxCHECK_VERSION(2, 5, 0) -wxTreeItemId wxTreeListMainWindow::GetLastChild (const wxTreeItemId& item, - long& cookie) const { -#else -wxTreeItemId wxTreeListMainWindow::GetLastChild (const wxTreeItemId& item, - wxTreeItemIdValue& cookie) const { -#endif - wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); - wxArrayTreeListItems& children = ((wxTreeListItem*) item.m_pItem)->GetChildren(); - // it's ok to cast cookie to long, we never have indices which overflow "void*" - long *pIndex = ((long*)&cookie); - (*pIndex) = children.Count(); - return (!children.IsEmpty())? wxTreeItemId(children.Last()): wxTreeItemId(); -} - -wxTreeItemId wxTreeListMainWindow::GetNextSibling (const wxTreeItemId& item) const { - wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); - - // get parent - wxTreeListItem *i = (wxTreeListItem*) item.m_pItem; - wxTreeListItem *parent = i->GetItemParent(); - if (!parent) return wxTreeItemId(); // root item doesn't have any siblings - - // get index - wxArrayTreeListItems& siblings = parent->GetChildren(); - size_t index = siblings.Index (i); - wxASSERT (index != wxNOT_FOUND); // I'm not a child of my parent? - return (index < siblings.Count()-1)? wxTreeItemId(siblings[index+1]): wxTreeItemId(); -} - -wxTreeItemId wxTreeListMainWindow::GetPrevSibling (const wxTreeItemId& item) const { - wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); - - // get parent - wxTreeListItem *i = (wxTreeListItem*) item.m_pItem; - wxTreeListItem *parent = i->GetItemParent(); - if (!parent) return wxTreeItemId(); // root item doesn't have any siblings - - // get index - wxArrayTreeListItems& siblings = parent->GetChildren(); - size_t index = siblings.Index(i); - wxASSERT (index != wxNOT_FOUND); // I'm not a child of my parent? - return (index >= 1)? wxTreeItemId(siblings[index-1]): wxTreeItemId(); -} - -// Only for internal use right now, but should probably be public -wxTreeItemId wxTreeListMainWindow::GetNext (const wxTreeItemId& item, bool fulltree) const { - wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); - - // if there are any children, return first child - if (fulltree || ((wxTreeListItem*)item.m_pItem)->IsExpanded()) { - wxArrayTreeListItems& children = ((wxTreeListItem*)item.m_pItem)->GetChildren(); - if (children.GetCount() > 0) return children.Item (0); - } - - // get sibling of this item or of the ancestors instead - wxTreeItemId next; - wxTreeItemId parent = item; - do { - next = GetNextSibling (parent); - parent = GetItemParent (parent); - } while (!next.IsOk() && parent.IsOk()); - return next; -} - -// Only for internal use right now, but should probably be public -wxTreeItemId wxTreeListMainWindow::GetPrev (const wxTreeItemId& item, bool fulltree) const { - wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); - - // if there are any children, return last child - if (fulltree || ((wxTreeListItem*)item.m_pItem)->IsExpanded()) { - wxArrayTreeListItems& children = ((wxTreeListItem*)item.m_pItem)->GetChildren(); - if (children.GetCount() > 0) return children.Item (children.GetCount()-1); - } - - // get sibling of this item or of the ancestors instead - wxTreeItemId next; - wxTreeItemId parent = item; - do { - next = GetPrevSibling (parent); - parent = GetItemParent (parent); - } while (!next.IsOk() && parent.IsOk()); - return next; -} - -wxTreeItemId wxTreeListMainWindow::GetFirstExpandedItem() const { - return GetNextExpanded (GetRootItem()); -} - -wxTreeItemId wxTreeListMainWindow::GetNextExpanded (const wxTreeItemId& item) const { - wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); - return GetNext (item, false); -} - -wxTreeItemId wxTreeListMainWindow::GetPrevExpanded (const wxTreeItemId& item) const { - wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); - return GetPrev (item, false); -} - -wxTreeItemId wxTreeListMainWindow::GetFirstVisibleItem (bool fullRow) const { - return GetNextVisible (GetRootItem(), fullRow); -} - -wxTreeItemId wxTreeListMainWindow::GetNextVisible (const wxTreeItemId& item, bool fullRow) const { - wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); - wxTreeItemId id = GetNext (item, false); - while (id.IsOk()) { - if (IsVisible (id, fullRow)) return id; - id = GetNext (id, false); - } - return wxTreeItemId(); -} - -wxTreeItemId wxTreeListMainWindow::GetPrevVisible (const wxTreeItemId& item, bool fullRow) const { - wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); - wxTreeItemId id = GetPrev (item, true); - while (id.IsOk()) { - if (IsVisible (id, fullRow)) return id; - id = GetPrev(id, true); - } - return wxTreeItemId(); -} - -// ---------------------------------------------------------------------------- -// operations -// ---------------------------------------------------------------------------- - -wxTreeItemId wxTreeListMainWindow::DoInsertItem (const wxTreeItemId& parentId, - size_t previous, - const wxString& text, - int image, int selImage, - wxTreeItemData *data) { - wxTreeListItem *parent = (wxTreeListItem*)parentId.m_pItem; - wxCHECK_MSG (parent, wxTreeItemId(), _T("item must have a parent, at least root!") ); - m_dirty = true; // do this first so stuff below doesn't cause flicker - - wxArrayString arr; - arr.Alloc (GetColumnCount()); - for (int i = 0; i < (int)GetColumnCount(); ++i) arr.Add (wxEmptyString); - arr[m_main_column] = text; - wxTreeListItem *item = new wxTreeListItem (this, parent, arr, image, selImage, data); - if (data != NULL) { -#if !wxCHECK_VERSION(2, 5, 0) - data->SetId ((long)item); -#else - data->SetId (item); -#endif - } - parent->Insert (item, previous); - - return item; -} - -wxTreeItemId wxTreeListMainWindow::AddRoot (const wxString& text, - int image, int selImage, - wxTreeItemData *data) { - wxCHECK_MSG(!m_rootItem, wxTreeItemId(), _T("tree can have only one root")); - wxCHECK_MSG(GetColumnCount(), wxTreeItemId(), _T("Add column(s) before adding the root item")); - m_dirty = true; // do this first so stuff below doesn't cause flicker - - wxArrayString arr; - arr.Alloc (GetColumnCount()); - for (int i = 0; i < (int)GetColumnCount(); ++i) arr.Add (wxEmptyString); - arr[m_main_column] = text; - m_rootItem = new wxTreeListItem (this, (wxTreeListItem *)NULL, arr, image, selImage, data); - if (data != NULL) { -#if !wxCHECK_VERSION(2, 5, 0) - data->SetId((long)m_rootItem); -#else - data->SetId(m_rootItem); -#endif - } - if (HasFlag(wxTR_HIDE_ROOT)) { - // if we will hide the root, make sure children are visible - m_rootItem->SetHasPlus(); - m_rootItem->Expand(); -#if !wxCHECK_VERSION(2, 5, 0) - long cookie = 0; -#else - wxTreeItemIdValue cookie = 0; -#endif - m_curItem = (wxTreeListItem*)GetFirstChild (m_rootItem, cookie).m_pItem; - } - return m_rootItem; -} - -wxTreeItemId wxTreeListMainWindow::PrependItem (const wxTreeItemId& parent, - const wxString& text, - int image, int selImage, - wxTreeItemData *data) { - return DoInsertItem (parent, 0u, text, image, selImage, data); -} - -wxTreeItemId wxTreeListMainWindow::InsertItem (const wxTreeItemId& parentId, - const wxTreeItemId& idPrevious, - const wxString& text, - int image, int selImage, - wxTreeItemData *data) { - wxTreeListItem *parent = (wxTreeListItem*)parentId.m_pItem; - wxCHECK_MSG (parent, wxTreeItemId(), _T("item must have a parent, at least root!") ); - - int index = parent->GetChildren().Index((wxTreeListItem*) idPrevious.m_pItem); - wxASSERT_MSG( index != wxNOT_FOUND, - _T("previous item in wxTreeListMainWindow::InsertItem() is not a sibling") ); - - return DoInsertItem (parentId, ++index, text, image, selImage, data); -} - -wxTreeItemId wxTreeListMainWindow::InsertItem (const wxTreeItemId& parentId, - size_t before, - const wxString& text, - int image, int selImage, - wxTreeItemData *data) { - wxTreeListItem *parent = (wxTreeListItem*)parentId.m_pItem; - wxCHECK_MSG (parent, wxTreeItemId(), _T("item must have a parent, at least root!") ); - - return DoInsertItem (parentId, before, text, image, selImage, data); -} - -wxTreeItemId wxTreeListMainWindow::AppendItem (const wxTreeItemId& parentId, - const wxString& text, - int image, int selImage, - wxTreeItemData *data) { - wxTreeListItem *parent = (wxTreeListItem*) parentId.m_pItem; - wxCHECK_MSG (parent, wxTreeItemId(), _T("item must have a parent, at least root!") ); - - return DoInsertItem (parent, parent->GetChildren().Count(), text, image, selImage, data); -} - -void wxTreeListMainWindow::SendDeleteEvent (wxTreeListItem *item) { - // send event to user code - wxTreeEvent event (wxEVT_COMMAND_TREE_DELETE_ITEM, m_owner->GetId()); -#if !wxCHECK_VERSION(2, 5, 0) - event.SetItem ((long)item); -#else - event.SetItem (item); -#endif - event.SetEventObject (m_owner); - m_owner->ProcessEvent (event); -} - -void wxTreeListMainWindow::Delete (const wxTreeItemId& itemId) { - wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; - wxCHECK_RET (item != m_rootItem, _T("invalid item, root may not be deleted this way!")); - m_dirty = true; // do this first so stuff below doesn't cause flicker - - // don't stay with invalid m_shiftItem or we will crash in the next call to OnChar() - bool changeKeyCurrent = false; - wxTreeListItem *itemKey = m_shiftItem; - while (itemKey) { - if (itemKey == item) { // m_shiftItem is a descendant of the item being deleted - changeKeyCurrent = true; - break; - } - itemKey = itemKey->GetItemParent(); - } - - wxTreeListItem *parent = item->GetItemParent(); - if (parent) { - parent->GetChildren().Remove (item); // remove by value - } - if (changeKeyCurrent) m_shiftItem = parent; - - SendDeleteEvent (item); - // LG - RemoveFromSelection(item); - // if (item->IsSelected()) Unselect(item); - //if (m_selectItem == item) m_selectItem = (wxTreeListItem*)NULL; - item->DeleteChildren (this); - delete item; -} - -void wxTreeListMainWindow::DeleteChildren (const wxTreeItemId& itemId) { - wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; - m_dirty = true; // do this first so stuff below doesn't cause flicker - - item->DeleteChildren (this); -} - -void wxTreeListMainWindow::DeleteRoot() { - if (m_rootItem) { - m_dirty = true; - SendDeleteEvent (m_rootItem); - m_curItem = (wxTreeListItem*)NULL; - // LG - // m_selectItem= (wxTreeListItem*)NULL; - UnselectAll(); - m_rootItem->DeleteChildren (this); - delete m_rootItem; - m_rootItem = NULL; - } -} - -void wxTreeListMainWindow::Expand (const wxTreeItemId& itemId) { - wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; - wxCHECK_RET (item, _T("invalid item in wxTreeListMainWindow::Expand") ); - - if (!item->HasPlus() || item->IsExpanded()) return; - - // send event to user code - wxTreeEvent event (wxEVT_COMMAND_TREE_ITEM_EXPANDING, m_owner->GetId()); -#if !wxCHECK_VERSION(2, 5, 0) - event.SetItem ((long)item); -#else - event.SetItem (item); -#endif - event.SetEventObject (m_owner); - if (m_owner->ProcessEvent (event) && !event.IsAllowed()) return; // expand canceled - - item->Expand(); - m_dirty = true; - - // send event to user code - event.SetEventType (wxEVT_COMMAND_TREE_ITEM_EXPANDED); - m_owner->ProcessEvent (event); -} - -void wxTreeListMainWindow::ExpandAll (const wxTreeItemId& itemId) { - Expand (itemId); - if (!IsExpanded (itemId)) return; -#if !wxCHECK_VERSION(2, 5, 0) - long cookie; -#else - wxTreeItemIdValue cookie; -#endif - wxTreeItemId child = GetFirstChild (itemId, cookie); - while (child.IsOk()) { - ExpandAll (child); - child = GetNextChild (itemId, cookie); - } -} - -void wxTreeListMainWindow::Collapse (const wxTreeItemId& itemId) { - wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; - wxCHECK_RET (item, _T("invalid item in wxTreeListMainWindow::Collapse") ); - - if (!item->HasPlus() || !item->IsExpanded()) return; - - // send event to user code - wxTreeEvent event (wxEVT_COMMAND_TREE_ITEM_COLLAPSING, m_owner->GetId() ); -#if !wxCHECK_VERSION(2, 5, 0) - event.SetItem ((long)item); -#else - event.SetItem (item); -#endif - event.SetEventObject (m_owner); - if (m_owner->ProcessEvent (event) && !event.IsAllowed()) return; // collapse canceled - - item->Collapse(); - m_dirty = true; - - // send event to user code - event.SetEventType (wxEVT_COMMAND_TREE_ITEM_COLLAPSED); - ProcessEvent (event); -} - -void wxTreeListMainWindow::CollapseAndReset (const wxTreeItemId& item) { - Collapse (item); - DeleteChildren (item); -} - -void wxTreeListMainWindow::Toggle (const wxTreeItemId& itemId) { - if (IsExpanded (itemId)) { - Collapse (itemId); - }else{ - Expand (itemId); - } -} -/* -void wxTreeListMainWindow::Unselect() { - if (m_selectItem) { - m_selectItem->SetHilight (false); - RefreshLine (m_selectItem); - m_selectItem = (wxTreeListItem*)NULL; - } -} -*/ -// LG 19/09/08 : Added -/* -void wxTreeListMainWindow::Unselect(wxTreeListItem* item) -{ - if (item->IsSelected()) { - item->SetSelected (false); - RefreshLine (item); - m_selected.Remove(item); - // LG : TODO : Remove from array - // if (item == m_selectItem) m_selectItem = (wxTreeListItem*)NULL; - } -} -*/ -/* -void wxTreeListMainWindow::UnselectAllChildren (wxTreeListItem *item) { - if (item->IsSelected()) { - item->SetHilight (false); - RefreshLine (item); - if (item == m_selectItem) m_selectItem = (wxTreeListItem*)NULL; - } - if (item->HasChildren()) { - wxArrayTreeListItems& children = item->GetChildren(); - size_t count = children.Count(); - for (size_t n = 0; n < count; ++n) { - UnselectAllChildren (children[n]); - } - } -} -*/ -void wxTreeListMainWindow::UnselectAll() { - - size_t count = m_selected.Count(); - for (size_t n = 0; n < count; ++n) - { - m_selected[n]->SetSelected (false); - RefreshLine (m_selected[n]); - } - m_selected.Empty(); - - //UnselectAllChildren ((wxTreeListItem*)GetRootItem().m_pItem); -} - -// Recursive function ! -// To stop we must have crt_itemGetItemParent(); - - if (!parent) {// This is root item - return SelectAllChildrenUntilLast (crt_item, last_item); - } - - wxArrayTreeListItems& children = parent->GetChildren(); - int index = children.Index(crt_item); - wxASSERT (index != wxNOT_FOUND); // I'm not a child of my parent? - - if ((parent->HasChildren() && parent->IsExpanded()) || - ((parent == (wxTreeListItem*)GetRootItem().m_pItem) && HasFlag(wxTR_HIDE_ROOT))) { - size_t count = children.Count(); - for (size_t n = (index+1); n < count; ++n) { - if (SelectAllChildrenUntilLast (children[n], last_item)) return true; - } - } - - return SelectNextChildren (parent, last_item); -} - - bool wxTreeListMainWindow::SelectAllChildrenUntilLast (wxTreeListItem *crt_item, - wxTreeListItem *last_item) { - if (!crt_item->IsSelected()) - { - // LG : Send event to user to know is selection is accepted - // send event to the user code - wxTreeEvent event( wxEVT_COMMAND_TREE_SEL_CHANGING, m_owner->GetId() ); -#if !wxCHECK_VERSION(2, 5, 0) - event.SetItem ((long)crt_item); -#else - event.SetItem (crt_item); -#endif - event.SetEventObject (m_owner); - if (m_owner->GetEventHandler()->ProcessEvent (event) && event.IsAllowed()) - { - AddToSelection(crt_item); - } - } - - if (crt_item==last_item) return true; - - if (crt_item->HasChildren() && crt_item->IsExpanded()) { - wxArrayTreeListItems& children = crt_item->GetChildren(); - size_t count = children.Count(); - for (size_t n = 0; n < count; ++n) { - if (SelectAllChildrenUntilLast (children[n], last_item)) return true; - } - } - - return false; -} - - void wxTreeListMainWindow::RemoveFromSelection( wxTreeListItem *item ) - { - if (!item->IsSelected()) return; - item->SetSelected(false); - m_selected.Remove(item); - RefreshLine(item); - - } - void wxTreeListMainWindow::AddToSelection( wxTreeListItem *item ) - { - if (item->IsSelected()) return; - item->SetSelected(true); - m_selected.Add(item); - RefreshLine(item); - } - -void wxTreeListMainWindow::SelectItem (const wxTreeItemId& itemId, - const wxTreeItemId& lastId, - bool unselect_others) { - wxCHECK_RET (itemId.IsOk(), _T("invalid tree item") ); - - bool is_single = !HasFlag(wxTR_MULTIPLE); - wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; - - - // single selection requires unselect others - if (is_single) unselect_others = true; - - // unselect all if unselect other items - bool unselected = false; // see that UnselectAll is done only once - if (unselect_others) { - /* - if (is_single) { - Unselect(); // to speed up thing - }else{ - */ - UnselectAll(); - unselected = true; - // } - } - - // LG : Update current item - wxTreeListItem *old_curItem = m_curItem; - m_curItem = item; - if (old_curItem) RefreshLine (old_curItem); - - // select item or item range - if (lastId.IsOk() && (itemId != lastId)) - { - - - if (!unselected) UnselectAll(); - wxTreeListItem *last = (wxTreeListItem*) lastId.m_pItem; - - // LG : Update current item - // wxTreeListItem *old_curItem = m_curItem; - // m_curItem = last; - // if (old_curItem) RefreshLine (old_curItem); - - // ensure that the position of the item it calculated in any case - if (m_dirty) CalculatePositions(); - - // select item range according Y-position - if (last->GetY() < item->GetY()) { - if (!SelectAllChildrenUntilLast (last, item)) { - SelectNextChildren (last, item); - } - }else{ - if (!SelectAllChildrenUntilLast (item, last)) { - SelectNextChildren (item, last); - } - } - - } - else - { - - // send event to the user code - wxTreeEvent event( wxEVT_COMMAND_TREE_SEL_CHANGING, m_owner->GetId() ); -#if !wxCHECK_VERSION(2, 5, 0) - event.SetItem ((long)item); - event.SetOldItem ((long)m_curItem); -#else - event.SetItem (item); - event.SetOldItem (m_curItem); -#endif - event.SetEventObject (m_owner); - - - - if (m_owner->GetEventHandler()->ProcessEvent (event) && - event.IsAllowed()) - { - // select item according its old selection - if (item->IsSelected()) - RemoveFromSelection(item); - else - AddToSelection(item); - } - } - - // send event to user code - wxTreeEvent event( wxEVT_COMMAND_TREE_SEL_CHANGED, m_owner->GetId() ); - m_owner->GetEventHandler()->ProcessEvent (event); -} - -void wxTreeListMainWindow::SelectAll() { - wxCHECK_RET (HasFlag(wxTR_MULTIPLE), _T("invalid tree style")); - -#if !wxCHECK_VERSION(2, 5, 0) - long cookie = 0; -#else - wxTreeItemIdValue cookie = 0; -#endif - wxTreeItemId root = GetRootItem(); - wxTreeListItem *first = (wxTreeListItem *)GetFirstChild (root, cookie).m_pItem; - wxTreeListItem *last = (wxTreeListItem *)GetLastChild (root, cookie).m_pItem; - if (!SelectAllChildrenUntilLast (first, last)) { - SelectNextChildren (first, last); - } - - // send event to user code - wxTreeEvent event( wxEVT_COMMAND_TREE_SEL_CHANGED, m_owner->GetId() ); - m_owner->GetEventHandler()->ProcessEvent (event); -} - -void wxTreeListMainWindow::FillArray (wxTreeListItem *item, - wxArrayTreeItemIds &array) const { - if (item->IsSelected()) array.Add (wxTreeItemId(item)); - - if (item->HasChildren()) { - wxArrayTreeListItems& children = item->GetChildren(); - size_t count = children.GetCount(); - for (size_t n = 0; n < count; ++n) FillArray (children[n], array); - } -} - - -// returns the number of currently selected items - size_t wxTreeListMainWindow::GetSelectionSize() const - { - return m_selected.GetCount(); - } - -size_t wxTreeListMainWindow::GetSelections (wxArrayTreeItemIds &array) const { - /* - LG : NOT OK AS IS NOT IN TREE ORDER - array.Empty(); - size_t count = m_selected.GetCount(); - for (size_t n = 0; n < count; ++n) array.Add(m_selected[n]); - */ - wxTreeItemId idRoot = GetRootItem(); - if (idRoot.IsOk()) FillArray ((wxTreeListItem*) idRoot.m_pItem, array); - return array.Count(); -} - -void wxTreeListMainWindow::EnsureVisible (const wxTreeItemId& item) { - if (!item.IsOk()) return; // do nothing if no item - - // first expand all parent branches - wxTreeListItem *gitem = (wxTreeListItem*) item.m_pItem; - wxTreeListItem *parent = gitem->GetItemParent(); - while (parent) { - Expand (parent); - parent = parent->GetItemParent(); - } - - ScrollTo (item); - RefreshLine (gitem); -} - -void wxTreeListMainWindow::ScrollTo (const wxTreeItemId &item) { - if (!item.IsOk()) return; // do nothing if no item - - // ensure that the position of the item it calculated in any case - if (m_dirty) CalculatePositions(); - - wxTreeListItem *gitem = (wxTreeListItem*) item.m_pItem; - - // now scroll to the item - int item_y = gitem->GetY(); - - int xUnit, yUnit; - GetScrollPixelsPerUnit (&xUnit, &yUnit); - int start_x = 0; - int start_y = 0; - GetViewStart (&start_x, &start_y); - start_y *= yUnit; - - int client_h = 0; - int client_w = 0; - GetClientSize (&client_w, &client_h); - - int x = 0; - int y = 0; - m_rootItem->GetSize (x, y, this); - x = m_owner->GetHeaderWindow()->GetWidth(); - y += yUnit + 2; // one more scrollbar unit + 2 pixels - int x_pos = GetScrollPos( wxHORIZONTAL ); - - if (item_y < start_y+3) { - // going down, item should appear at top - SetScrollbars (xUnit, yUnit, xUnit ? x/xUnit : 0, yUnit ? y/yUnit : 0, x_pos, yUnit ? item_y/yUnit : 0); - }else if (item_y+GetLineHeight(gitem) > start_y+client_h) { - // going up, item should appear at bottom - item_y += yUnit + 2; - SetScrollbars (xUnit, yUnit, xUnit ? x/xUnit : 0, yUnit ? y/yUnit : 0, x_pos, yUnit ? (item_y+GetLineHeight(gitem)-client_h)/yUnit : 0 ); - } -} - -// FIXME: tree sorting functions are not reentrant and not MT-safe! -static wxTreeListMainWindow *s_treeBeingSorted = NULL; - -static int LINKAGEMODE tree_ctrl_compare_func(wxTreeListItem **item1, - wxTreeListItem **item2) -{ - wxCHECK_MSG (s_treeBeingSorted, 0, _T("bug in wxTreeListMainWindow::SortChildren()") ); - - return s_treeBeingSorted->OnCompareItems(*item1, *item2); -} - -int wxTreeListMainWindow::OnCompareItems(const wxTreeItemId& item1, - const wxTreeItemId& item2) -{ - return m_owner->OnCompareItems (item1, item2); -} - -void wxTreeListMainWindow::SortChildren (const wxTreeItemId& itemId) { - wxCHECK_RET (itemId.IsOk(), _T("invalid tree item")); - - wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; - - wxCHECK_RET (!s_treeBeingSorted, - _T("wxTreeListMainWindow::SortChildren is not reentrant") ); - - wxArrayTreeListItems& children = item->GetChildren(); - if ( children.Count() > 1 ) { - m_dirty = true; - s_treeBeingSorted = this; - children.Sort(tree_ctrl_compare_func); - s_treeBeingSorted = NULL; - } -} - -wxTreeItemId wxTreeListMainWindow::FindItem (const wxTreeItemId& item, const wxString& str, int mode) { - wxString itemText; - // determine start item - wxTreeItemId next = item; - if (next.IsOk()) { - if (mode & wxTL_MODE_NAV_LEVEL) { - next = GetNextSibling (next); - }else if (mode & wxTL_MODE_NAV_VISIBLE) { // - next = GetNextVisible (next, false); - }else if (mode & wxTL_MODE_NAV_EXPANDED) { - next = GetNextExpanded (next); - }else{ // (mode & wxTL_MODE_NAV_FULLTREE) default - next = GetNext (next, true); - } - } - -#if !wxCHECK_VERSION(2, 5, 0) - long cookie = 0; -#else - wxTreeItemIdValue cookie = 0; -#endif - if (!next.IsOk()) { - next = (wxTreeListItem*)GetRootItem().m_pItem; - if (HasFlag(wxTR_HIDE_ROOT)) { - next = (wxTreeListItem*)GetFirstChild (GetRootItem().m_pItem, cookie).m_pItem; - } - } - if (!next.IsOk()) return (wxTreeItemId*)NULL; - - // start checking the next items - while (next.IsOk() && (next != item)) { - if (mode & wxTL_MODE_FIND_PARTIAL) { - itemText = GetItemText (next).Mid (0, str.Length()); - }else{ - itemText = GetItemText (next); - } - if (mode & wxTL_MODE_FIND_NOCASE) { - if (itemText.CmpNoCase (str) == 0) return next; - }else{ - if (itemText.Cmp (str) == 0) return next; - } - if (mode & wxTL_MODE_NAV_LEVEL) { - next = GetNextSibling (next); - }else if (mode & wxTL_MODE_NAV_VISIBLE) { // - next = GetNextVisible (next, false); - }else if (mode & wxTL_MODE_NAV_EXPANDED) { - next = GetNextExpanded (next); - }else{ // (mode & wxTL_MODE_NAV_FULLTREE) default - next = GetNext (next, true); - } - if (!next.IsOk() && item.IsOk()) { - next = (wxTreeListItem*)GetRootItem().m_pItem; - if (HasFlag(wxTR_HIDE_ROOT)) { - next = (wxTreeListItem*)GetNextChild (GetRootItem().m_pItem, cookie).m_pItem; - } - } - } - return (wxTreeItemId*)NULL; -} - -void wxTreeListMainWindow::SetDragItem (const wxTreeItemId& item) { - wxTreeListItem *prevItem = m_dragItem; - m_dragItem = (wxTreeListItem*) item.m_pItem; - if (prevItem) RefreshLine (prevItem); - if (m_dragItem) RefreshLine (m_dragItem); -} - -void wxTreeListMainWindow::CalculateLineHeight() { - wxClientDC dc (this); - dc.SetFont (m_normalFont); - m_lineHeight = (int)(dc.GetCharHeight() + m_linespacing); - - if (m_imageListNormal) { - // Calculate a m_lineHeight value from the normal Image sizes. - // May be toggle off. Then wxTreeListMainWindow will spread when - // necessary (which might look ugly). - int n = m_imageListNormal->GetImageCount(); - for (int i = 0; i < n ; i++) { - int width = 0, height = 0; - m_imageListNormal->GetSize(i, width, height); - if (height > m_lineHeight) m_lineHeight = height + m_linespacing; - } - } - - if (m_imageListButtons) { - // Calculate a m_lineHeight value from the Button image sizes. - // May be toggle off. Then wxTreeListMainWindow will spread when - // necessary (which might look ugly). - int n = m_imageListButtons->GetImageCount(); - for (int i = 0; i < n ; i++) { - int width = 0, height = 0; - m_imageListButtons->GetSize(i, width, height); - if (height > m_lineHeight) m_lineHeight = height + m_linespacing; - } - } - - if (m_lineHeight < 30) { // add 10% space if greater than 30 pixels - m_lineHeight += 2; // minimal 2 pixel space - }else{ - m_lineHeight += m_lineHeight / 10; // otherwise 10% space - } -} - -void wxTreeListMainWindow::SetImageList (wxImageList *imageList) { - if (m_ownsImageListNormal) delete m_imageListNormal; - m_imageListNormal = imageList; - m_ownsImageListNormal = false; - m_dirty = true; - CalculateLineHeight(); -} - -void wxTreeListMainWindow::SetStateImageList (wxImageList *imageList) { - if (m_ownsImageListState) delete m_imageListState; - m_imageListState = imageList; - m_ownsImageListState = false; -} - -void wxTreeListMainWindow::SetButtonsImageList (wxImageList *imageList) { - if (m_ownsImageListButtons) delete m_imageListButtons; - m_imageListButtons = imageList; - m_ownsImageListButtons = false; - m_dirty = true; - CalculateLineHeight(); -} - -void wxTreeListMainWindow::AssignImageList (wxImageList *imageList) { - SetImageList(imageList); - m_ownsImageListNormal = true; -} - -void wxTreeListMainWindow::AssignStateImageList (wxImageList *imageList) { - SetStateImageList(imageList); - m_ownsImageListState = true; -} - -void wxTreeListMainWindow::AssignButtonsImageList (wxImageList *imageList) { - SetButtonsImageList(imageList); - m_ownsImageListButtons = true; -} - -// ---------------------------------------------------------------------------- -// helpers -// ---------------------------------------------------------------------------- - -void wxTreeListMainWindow::AdjustMyScrollbars() { - if (m_rootItem) { - int xUnit, yUnit; - GetScrollPixelsPerUnit (&xUnit, &yUnit); - if (xUnit == 0) xUnit = GetCharWidth(); - if (yUnit == 0) yUnit = m_lineHeight; - int x = 0, y = 0; - m_rootItem->GetSize (x, y, this); - y += yUnit + 2; // one more scrollbar unit + 2 pixels - int x_pos = GetScrollPos (wxHORIZONTAL); - int y_pos = GetScrollPos (wxVERTICAL); - x = m_owner->GetHeaderWindow()->GetWidth() + 2; - if (x < GetClientSize().GetWidth()) x_pos = 0; - SetScrollbars (xUnit, yUnit, x/xUnit, y/yUnit, x_pos, y_pos); - }else{ - SetScrollbars (0, 0, 0, 0); - } -} - -int wxTreeListMainWindow::GetLineHeight (wxTreeListItem *item) const { - if (GetWindowStyleFlag() & wxTR_HAS_VARIABLE_ROW_HEIGHT) { - return item->GetHeight(); - }else{ - return m_lineHeight; - } -} - -void wxTreeListMainWindow::PaintItem (wxTreeListItem *item, wxDC& dc) { - - wxTreeItemAttr *attr = item->GetAttributes(); - - dc.SetFont (GetItemFont (item)); - - wxColour colText; - if (attr && attr->HasTextColour()) { - colText = attr->GetTextColour(); - }else{ - colText = GetForegroundColour(); - } -#if !wxCHECK_VERSION(2, 5, 0) - wxColour colTextHilight = wxSystemSettings::GetSystemColour (wxSYS_COLOUR_HIGHLIGHTTEXT); -#else - wxColour colTextHilight = wxSystemSettings::GetColour (wxSYS_COLOUR_HIGHLIGHTTEXT); -#endif - - int total_w = m_owner->GetHeaderWindow()->GetWidth(); - int total_h = GetLineHeight(item); - int off_h = HasFlag(wxTR_ROW_LINES) ? 1 : 0; - // std::cout << "off_h="<GetY(), total_w, total_h); // only within line - - int text_w = 0, text_h = 0; - dc.GetTextExtent( item->GetText(GetMainColumn()), &text_w, &text_h ); - - // determine background and show it - wxColour colBg; - if (attr && attr->HasBackgroundColour()) { - colBg = attr->GetBackgroundColour(); - }else{ - colBg = m_backgroundColour; - } - dc.SetBrush (wxBrush (colBg, wxSOLID)); - dc.SetPen (*wxTRANSPARENT_PEN); - if (HasFlag (wxTR_FULL_ROW_HIGHLIGHT)) { - if (item == m_dragItem) { - dc.SetBrush (*m_hilightBrush); -#ifndef __WXMAC__ // don't draw rect outline if we already have the background color - dc.SetPen ((item == m_dragItem)? *wxBLACK_PEN: *wxTRANSPARENT_PEN); -#endif // !__WXMAC__ - dc.SetTextForeground (colTextHilight); - }else if (item->IsSelected()) { - if (!m_isDragging && m_hasFocus) { - dc.SetBrush (*m_hilightBrush); -#ifndef __WXMAC__ // don't draw rect outline if we already have the background color - // LG : dc.SetPen (*wxBLACK_PEN); - dc.SetPen (*wxTRANSPARENT_PEN); -#endif // !__WXMAC__ - }else{ - dc.SetBrush (*m_hilightUnfocusedBrush); -#ifndef __WXMAC__ // don't draw rect outline if we already have the background color - dc.SetPen (*wxTRANSPARENT_PEN); -#endif // !__WXMAC__ - } - dc.SetTextForeground (colTextHilight); - } - // LG - else if (item == m_curItem) { - dc.SetPen (m_hasFocus? *wxBLACK_PEN: *wxTRANSPARENT_PEN); - } - else{ - dc.SetTextForeground (colText); - } - // LG - dc.DrawRectangle (0, item->GetY() + off_h, total_w, total_h - off_h); - }else{ - dc.SetTextForeground (colText); - } - - int text_extraH = (total_h > text_h) ? (total_h - text_h)/2 : 0; - int img_extraH = (total_h > m_imgHeight)? (total_h-m_imgHeight)/2: 0; - int x_colstart = 0; - for (int i = 0; i < GetColumnCount(); ++i ) { - if (!m_owner->GetHeaderWindow()->IsColumnShown(i)) continue; - - int col_w = m_owner->GetHeaderWindow()->GetColumnWidth(i); - wxDCClipper clipper (dc, x_colstart, item->GetY(), col_w, total_h); // only within column - - int x = 0; - int image = NO_IMAGE; - int image_w = 0; - if(i == GetMainColumn()) { - x = item->GetX() + MARGIN; - if (HasButtons()) { - x += (m_btnWidth-m_btnWidth2) + LINEATROOT; - }else{ - x -= m_indent/2; - } - if (m_imageListNormal) image = item->GetCurrentImage(); - }else{ - x = x_colstart + MARGIN; - image = item->GetImage(i); - } - if (image != NO_IMAGE) image_w = m_imgWidth + MARGIN; - - // honor text alignment - wxString text = item->GetText(i); - int w = 0; - switch ( m_owner->GetHeaderWindow()->GetColumn(i).GetAlignment() ) { - case wxALIGN_LEFT: - // nothing to do, already left aligned - break; - case wxALIGN_RIGHT: - dc.GetTextExtent (text, &text_w, NULL); - w = col_w - (image_w + text_w + MARGIN); - x += (w > 0)? w: 0; - break; - case wxALIGN_CENTER: - dc.GetTextExtent(text, &text_w, NULL); - w = (col_w - (image_w + text_w + MARGIN))/2; - x += (w > 0)? w: 0; - break; - } - int text_x = x + image_w; - if (i == GetMainColumn()) item->SetTextX (text_x); - - if (!HasFlag (wxTR_FULL_ROW_HIGHLIGHT)) { - if (i == GetMainColumn()) { - if (item == m_dragItem) { - dc.SetBrush (*m_hilightBrush); -#ifndef __WXMAC__ // don't draw rect outline if we already have the background color - dc.SetPen ((item == m_dragItem)? *wxBLACK_PEN: *wxTRANSPARENT_PEN); -#endif // !__WXMAC__ - dc.SetTextForeground (colTextHilight); - }else if (item->IsSelected()) { - if (!m_isDragging && m_hasFocus) { - dc.SetBrush (*m_hilightBrush); -#ifndef __WXMAC__ // don't draw rect outline if we already have the background color - dc.SetPen (*wxBLACK_PEN); -#endif // !__WXMAC__ - }else{ - dc.SetBrush (*m_hilightUnfocusedBrush); -#ifndef __WXMAC__ // don't draw rect outline if we already have the background color - dc.SetPen (*wxTRANSPARENT_PEN); -#endif // !__WXMAC__ - } - dc.SetTextForeground (colTextHilight); - } - // LG - else if (item == m_curItem) { - dc.SetPen (m_hasFocus? *wxBLACK_PEN: *wxTRANSPARENT_PEN); - } - else{ - dc.SetTextForeground (colText); - } - dc.DrawRectangle (text_x, item->GetY() + off_h, text_w, total_h - off_h); - }else{ - dc.SetTextForeground (colText); - } - } - - dc.SetBackgroundMode (wxTRANSPARENT); - - if (image != NO_IMAGE) { - int y = item->GetY() + img_extraH; - m_imageListNormal->Draw (image, dc, x, y, wxIMAGELIST_DRAW_TRANSPARENT ); - } - int text_y = item->GetY() + text_extraH; - dc.DrawText (text, (wxCoord)text_x, (wxCoord)text_y); - - x_colstart += col_w; - } - - // restore normal font - dc.SetFont( m_normalFont ); -} - -// Now y stands for the top of the item, whereas it used to stand for middle ! -void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc, - int level, int &y, int x_maincol) { - - // Handle hide root (only level 0) - // LG : test - // int nth = 2; - //if (HasFlag(wxTR_HIDE_ROOT) && (level < nth)) { - if (HasFlag(wxTR_HIDE_ROOT) && (level == 0)) { - - wxArrayTreeListItems& children = item->GetChildren(); - for (size_t n = 0; n < children.Count(); n++) { - PaintLevel (children[n], dc, 1, y, x_maincol); - } - // end after expanding root - return; - } - - // calculate position of vertical lines - int x = x_maincol + MARGIN; // start of column - if (HasFlag(wxTR_LINES_AT_ROOT)) x += LINEATROOT; // space for lines at root - if (HasButtons()) { - x += (m_btnWidth-m_btnWidth2); // half button space - }else{ - x += (m_indent-m_indent/2); - } - if (HasFlag(wxTR_HIDE_ROOT)) { - // LG - // x += m_indent * (level-nth); // indent but not level 1 - x += m_indent * (level-1); // indent but not level 1 - - }else{ - x += m_indent * level; // indent according to level - } - - // set position of vertical line - item->SetX (x); - item->SetY (y); - - int h = GetLineHeight (item); - int y_top = y; - int y_mid = y_top + (h/2); - y += h; - - int exposed_x = dc.LogicalToDeviceX(0); - int exposed_y = dc.LogicalToDeviceY(y_top); - - if (IsExposed(exposed_x, exposed_y, 10000, h)) { // 10000 = very much - - if (HasFlag(wxTR_ROW_LINES)) { // horizontal lines between rows - //dc.DestroyClippingRegion(); - int total_width = m_owner->GetHeaderWindow()->GetWidth(); - // if the background colour is white, choose a - // contrasting color for the lines - dc.SetPen (*((GetBackgroundColour() == *wxWHITE)? - wxMEDIUM_GREY_PEN : wxWHITE_PEN)); - dc.DrawLine(0, y_top, total_width, y_top); - dc.DrawLine(0, y_top+h, total_width, y_top+h); - } - - // draw item - PaintItem (item, dc); - - // restore DC objects - dc.SetBrush(*wxWHITE_BRUSH); - dc.SetPen(m_dottedPen); - - // clip to the column width - int clip_width = m_owner->GetHeaderWindow()-> - GetColumn(m_main_column).GetWidth(); - wxDCClipper clipper(dc, x_maincol, y_top, clip_width, 10000); - - if (!HasFlag(wxTR_NO_LINES)) { // connection lines - - // draw the horizontal line here - dc.SetPen(m_dottedPen); - int x2 = x - m_indent; - if (x2 < (x_maincol + MARGIN)) x2 = x_maincol + MARGIN; - int x3 = x + (m_btnWidth-m_btnWidth2); - if (HasButtons()) { - if (item->HasPlus()) { - dc.DrawLine (x2, y_mid, x - m_btnWidth2, y_mid); - dc.DrawLine (x3, y_mid, x3 + LINEATROOT, y_mid); - }else{ - dc.DrawLine (x2, y_mid, x3 + LINEATROOT, y_mid); - } - }else{ - dc.DrawLine (x2, y_mid, x - m_indent/2, y_mid); - } - } - - if (item->HasPlus() && HasButtons()) { // should the item show a button? - - if (m_imageListButtons) { - - // draw the image button here - int image = wxTreeItemIcon_Normal; - if (item->IsExpanded()) image = wxTreeItemIcon_Expanded; - if (item->IsSelected()) image += wxTreeItemIcon_Selected - wxTreeItemIcon_Normal; - int xx = x - m_btnWidth2 + MARGIN; - int yy = y_mid - m_btnHeight2; - dc.SetClippingRegion(xx, yy, m_btnWidth, m_btnHeight); - m_imageListButtons->Draw (image, dc, xx, yy, wxIMAGELIST_DRAW_TRANSPARENT); - dc.DestroyClippingRegion(); - - }else if (HasFlag (wxTR_TWIST_BUTTONS)) { - - // draw the twisty button here - dc.SetPen(*wxBLACK_PEN); - dc.SetBrush(*m_hilightBrush); - wxPoint button[3]; - if (item->IsExpanded()) { - button[0].x = x - (m_btnWidth2+1); - button[0].y = y_mid - (m_btnHeight/3); - button[1].x = x + (m_btnWidth2+1); - button[1].y = button[0].y; - button[2].x = x; - button[2].y = button[0].y + (m_btnHeight2+1); - }else{ - button[0].x = x - (m_btnWidth/3); - button[0].y = y_mid - (m_btnHeight2+1); - button[1].x = button[0].x; - button[1].y = y_mid + (m_btnHeight2+1); - button[2].x = button[0].x + (m_btnWidth2+1); - button[2].y = y_mid; - } - dc.DrawPolygon(3, button); - - }else{ // if (HasFlag(wxTR_HAS_BUTTONS)) - - // draw the plus sign here - dc.SetPen(*wxGREY_PEN); - dc.SetBrush(*wxWHITE_BRUSH); - dc.DrawRectangle (x-m_btnWidth2, y_mid-m_btnHeight2, m_btnWidth, m_btnHeight); - dc.SetPen(*wxBLACK_PEN); - dc.DrawLine (x-(m_btnWidth2-2), y_mid, x+(m_btnWidth2-1), y_mid); - if (!item->IsExpanded()) { // change "-" to "+" - dc.DrawLine (x, y_mid-(m_btnHeight2-2), x, y_mid+(m_btnHeight2-1)); - } - - } - - } - - } - - // restore DC objects - dc.SetBrush(*wxWHITE_BRUSH); - dc.SetPen(m_dottedPen); - dc.SetTextForeground(*wxBLACK); - - if (item->IsExpanded()) - { - wxArrayTreeListItems& children = item->GetChildren(); - - // clip to the column width - int clip_width = m_owner->GetHeaderWindow()-> - GetColumn(m_main_column).GetWidth(); - - // process lower levels - int oldY; - if (m_imgWidth > 0) { - oldY = y_mid + m_imgHeight2; - }else{ - oldY = y_mid + h/2; - } - int y2; - for (size_t n = 0; n < children.Count(); ++n) { - - y2 = y + h/2; - PaintLevel (children[n], dc, level+1, y, x_maincol); - - // draw vertical line - wxDCClipper clipper(dc, x_maincol, y_top, clip_width, 10000); - if (!HasFlag (wxTR_NO_LINES)) { - x = item->GetX(); - dc.DrawLine (x, oldY, x, y2); - oldY = y2; - } - } - } -} - - -// ---------------------------------------------------------------------------- -// wxWindows callbacks -// ---------------------------------------------------------------------------- - -void wxTreeListMainWindow::OnPaint (wxPaintEvent &WXUNUSED(event)) { - - wxPaintDC dc (this); - PrepareDC (dc); - - if (!m_rootItem || (GetColumnCount() <= 0)) return; - - // calculate button size - if (m_imageListButtons) { - m_imageListButtons->GetSize (0, m_btnWidth, m_btnHeight); - }else if (HasButtons()) { - m_btnWidth = BTNWIDTH; - m_btnHeight = BTNHEIGHT; - } - m_btnWidth2 = m_btnWidth/2; - m_btnHeight2 = m_btnHeight/2; - - // calculate image size - if (m_imageListNormal) { - m_imageListNormal->GetSize (0, m_imgWidth, m_imgHeight); - } - m_imgWidth2 = m_imgWidth/2; - m_imgHeight2 = m_imgHeight/2; - - // calculate indent size - if (m_imageListButtons) { - m_indent = wxMax (MININDENT, m_btnWidth + MARGIN); - }else if (HasButtons()) { - m_indent = wxMax (MININDENT, m_btnWidth + LINEATROOT); - } - - // set default values - dc.SetFont( m_normalFont ); - dc.SetPen( m_dottedPen ); - - // calculate column start and paint - int x_maincol = 0; - int i = 0; - for (i = 0; i < (int)GetMainColumn(); ++i) { - if (!m_owner->GetHeaderWindow()->IsColumnShown(i)) continue; - x_maincol += m_owner->GetHeaderWindow()->GetColumnWidth (i); - } - int y = 0; - PaintLevel (m_rootItem, dc, 0, y, x_maincol); -} - -void wxTreeListMainWindow::OnSetFocus (wxFocusEvent &event) { - - m_hasFocus = true; - RefreshSelected(); - if (m_curItem) RefreshLine (m_curItem); - event.Skip(); -} - -void wxTreeListMainWindow::OnKillFocus( wxFocusEvent &event ) -{ - m_hasFocus = false; - RefreshSelected(); - if (m_curItem) RefreshLine (m_curItem); - event.Skip(); -} - -void wxTreeListMainWindow::OnChar (wxKeyEvent &event) { - // send event to user code - wxTreeEvent nevent (wxEVT_COMMAND_TREE_KEY_DOWN, m_owner->GetId()); - nevent.SetKeyEvent (event); - nevent.SetEventObject (m_owner); - if (m_owner->GetEventHandler()->ProcessEvent (nevent)) return; // handled in user code - - // determine first current if none - bool curItemSet = false; - if (!m_curItem) { - m_curItem = (wxTreeListItem*)GetRootItem().m_pItem; - if (HasFlag(wxTR_HIDE_ROOT)) { -#if !wxCHECK_VERSION(2, 5, 0) - long cookie = 0; -#else - wxTreeItemIdValue cookie = 0; -#endif - m_curItem = (wxTreeListItem*)GetFirstChild (m_curItem, cookie).m_pItem; - } - curItemSet = true; - } - if (!m_curItem) return; // do nothing if empty tree - - // remember item at shift down - if (HasFlag(wxTR_MULTIPLE) && event.ShiftDown()) { - if (!m_shiftItem) m_shiftItem = m_curItem; - }else{ - m_shiftItem = (wxTreeListItem*)NULL; - } - - // process all cases - wxTreeItemId newItem = (wxTreeItemId*)NULL; - switch (event.GetKeyCode()) { - - // '+': Expand subtree - case '+': - case WXK_ADD: { - if (m_curItem->HasPlus() && !IsExpanded (m_curItem)) Expand (m_curItem); - }break; - - // '-': collapse subtree - case '-': - case WXK_SUBTRACT: { - if (m_curItem->HasPlus() && IsExpanded (m_curItem)) Collapse (m_curItem); - }break; - - // '*': expand/collapse all subtrees // TODO: Mak it more useful - case '*': - case WXK_MULTIPLY: { - if (m_curItem->HasPlus() && !IsExpanded (m_curItem)) { - ExpandAll (m_curItem); - }else if (m_curItem->HasPlus()) { - Collapse (m_curItem); // TODO: CollapseAll - } - }break; - - // ' ': toggle current item - case ' ': { - SelectItem (m_curItem, (wxTreeListItem*)NULL, false); - }break; - - // : activate current item - case WXK_RETURN: { - wxTreeEvent aevent (wxEVT_COMMAND_TREE_ITEM_ACTIVATED, m_owner->GetId()); -#if !wxCHECK_VERSION(2, 5, 0) - aevent.SetItem ((long)m_curItem); -#else - aevent.SetItem (m_curItem); -#endif - aevent.SetEventObject (m_owner); - m_owner->GetEventHandler()->ProcessEvent (aevent); - }break; - - // : go to the parent without collapsing - case WXK_BACK: { - newItem = GetItemParent (m_curItem); - if ((newItem == GetRootItem()) && HasFlag(wxTR_HIDE_ROOT)) { - newItem = GetPrevSibling (m_curItem); // get sibling instead of root - } - }break; - - // : go to the previous sibling or to the last of its children, to the parent - case WXK_UP: { - newItem = GetPrevSibling (m_curItem); - if (newItem) { -#if !wxCHECK_VERSION(2, 5, 0) - long cookie = 0; -#else - wxTreeItemIdValue cookie = 0; -#endif - while (IsExpanded (newItem) && HasChildren (newItem)) { - newItem = GetLastChild (newItem, cookie); - } - }else { - newItem = GetItemParent (m_curItem); - if ((newItem == GetRootItem()) && HasFlag(wxTR_HIDE_ROOT)) { - newItem = (wxTreeItemId*)NULL; // don't go to root if it is hidden - } - } - }break; - - // : if expanded collapse subtree, else go to the parent - case WXK_LEFT: { - if (IsExpanded (m_curItem)) { - Collapse (m_curItem); - }else{ - newItem = GetItemParent (m_curItem); - if ((newItem == GetRootItem()) && HasFlag(wxTR_HIDE_ROOT)) { - newItem = GetPrevSibling (m_curItem); // go to sibling if it is hidden - } - } - }break; - - // : if possible expand subtree, else go go to the first child - case WXK_RIGHT: { - if (m_curItem->HasPlus() && !IsExpanded (m_curItem)) { - Expand (m_curItem); - }else{ - if (IsExpanded (m_curItem) && HasChildren (m_curItem)) { -#if !wxCHECK_VERSION(2, 5, 0) - long cookie = 0; -#else - wxTreeItemIdValue cookie = 0; -#endif - newItem = GetFirstChild (m_curItem, cookie); - } - } - }break; - - // : if expanded go to the first child, else to the next sibling, ect - case WXK_DOWN: { - if (curItemSet) { - newItem = m_curItem; - }else{ - if (IsExpanded (m_curItem) && HasChildren (m_curItem)) { -#if !wxCHECK_VERSION(2, 5, 0) - long cookie = 0; -#else - wxTreeItemIdValue cookie = 0; -#endif - newItem = GetFirstChild( m_curItem, cookie ); - } - if (!newItem) { - wxTreeItemId parent = m_curItem; - do { - newItem = GetNextSibling (parent); - parent = GetItemParent (parent); - } while (!newItem && parent); - } - } - }break; - - // : go to last item of the root - case WXK_END: { -#if !wxCHECK_VERSION(2, 5, 0) - long cookie = 0; -#else - wxTreeItemIdValue cookie = 0; -#endif - newItem = GetLastChild (GetRootItem(), cookie); - }break; - - // : go to root - case WXK_HOME: { - newItem = GetRootItem(); - if (HasFlag(wxTR_HIDE_ROOT)) { -#if !wxCHECK_VERSION(2, 5, 0) - long cookie = 0; -#else - wxTreeItemIdValue cookie = 0; -#endif - newItem = GetFirstChild (newItem, cookie); - } - }break; - - // any char: go to the next matching string - default: - if (event.GetKeyCode() >= (int)' ') { - if (!m_findTimer->IsRunning()) m_findStr.Clear(); - m_findStr.Append (event.GetKeyCode()); - m_findTimer->Start (FIND_TIMER_TICKS, wxTIMER_ONE_SHOT); - wxTreeItemId prev = m_curItem? (wxTreeItemId*)m_curItem: (wxTreeItemId*)NULL; - while (true) { - newItem = FindItem (prev, m_findStr, wxTL_MODE_NAV_EXPANDED | - wxTL_MODE_FIND_PARTIAL | - wxTL_MODE_FIND_NOCASE); - if (newItem || (m_findStr.Length() <= 1)) break; - m_findStr.RemoveLast(); - }; - } - event.Skip(); - - } - - // select and show the new item - if (newItem) { - if (!event.ControlDown()) { - bool unselect_others = !((event.ShiftDown() || event.ControlDown()) && - HasFlag(wxTR_MULTIPLE)); - SelectItem (newItem, m_shiftItem, unselect_others); - } - EnsureVisible (newItem); - wxTreeListItem *oldItem = m_curItem; - m_curItem = (wxTreeListItem*)newItem.m_pItem; // make the new item the current item - RefreshLine (oldItem); - } - -} - -wxTreeItemId wxTreeListMainWindow::HitTest (const wxPoint& point, int& flags, int& column) { - - int w, h; - GetSize(&w, &h); - flags=0; - column = -1; - if (point.x<0) flags |= wxTREE_HITTEST_TOLEFT; - if (point.x>w) flags |= wxTREE_HITTEST_TORIGHT; - if (point.y<0) flags |= wxTREE_HITTEST_ABOVE; - if (point.y>h) flags |= wxTREE_HITTEST_BELOW; - if (flags) return wxTreeItemId(); - - if (!m_rootItem) { - flags = wxTREE_HITTEST_NOWHERE; - column = -1; - return wxTreeItemId(); - } - - wxTreeListItem *hit = m_rootItem->HitTest (CalcUnscrolledPosition(point), - this, flags, column, 0); - if (!hit) { - flags = wxTREE_HITTEST_NOWHERE; - column = -1; - return wxTreeItemId(); - } - return hit; -} - -// get the bounding rectangle of the item (or of its label only) -bool wxTreeListMainWindow::GetBoundingRect (const wxTreeItemId& itemId, wxRect& rect, - bool WXUNUSED(textOnly)) const { - wxCHECK_MSG (itemId.IsOk(), false, _T("invalid item in wxTreeListMainWindow::GetBoundingRect") ); - - wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; - - int xUnit, yUnit; - GetScrollPixelsPerUnit (&xUnit, &yUnit); - int startX, startY; - GetViewStart(& startX, & startY); - - rect.x = item->GetX() - startX * xUnit; - rect.y = item->GetY() - startY * yUnit; - rect.width = item->GetWidth(); - rect.height = GetLineHeight (item); - - return true; -} - -/* **** */ - -void wxTreeListMainWindow::EditLabel (const wxTreeItemId& item, int column) { - if (!item.IsOk()) return; - if (!((column >= 0) && (column < GetColumnCount()))) return; - - m_editItem = (wxTreeListItem*) item.m_pItem; - - wxTreeEvent te( wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, m_owner->GetId() ); -#if !wxCHECK_VERSION(2, 5, 0) - te.SetItem ((long)m_editItem); -#else - te.SetItem (m_editItem); -#endif - te.SetInt (column); - te.SetEventObject (m_owner ); - m_owner->GetEventHandler()->ProcessEvent (te); - - if (!te.IsAllowed()) return; - - // ensure that the position of the item it calculated in any case - if (m_dirty) CalculatePositions(); - - wxTreeListHeaderWindow* header_win = m_owner->GetHeaderWindow(); - int x = 0; - int y = m_editItem->GetY() + 1; // wxTextCtrl needs 1 pixels above the text - int w = 0; - int h = m_editItem->GetHeight(); - long style = 0; - if (column == GetMainColumn()) { - x += m_editItem->GetTextX() - 2; // wxTextCtrl needs 2 pixels before the text - w = wxMin (m_editItem->GetWidth(), m_owner->GetHeaderWindow()->GetWidth() - x); - }else{ - for (int i = 0; i < column; ++i) x += header_win->GetColumnWidth (i); // start of column - switch (header_win->GetColumnAlignment (column)) { - case wxALIGN_LEFT: {style = wxTE_LEFT; break;} - case wxALIGN_RIGHT: {style = wxTE_RIGHT; break;} - case wxALIGN_CENTER: {style = wxTE_CENTER; break;} - } - w = header_win->GetColumnWidth (column); // width of column - } - - wxClientDC dc (this); - PrepareDC (dc); - x = dc.LogicalToDeviceX (x); - y = dc.LogicalToDeviceY (y); - - wxEditTextCtrl *text = new wxEditTextCtrl (this, -1, &m_renameAccept, &m_renameRes, - this, m_editItem->GetText (column), - wxPoint (x, y), wxSize (w, h), style); - text->SetFocus(); -} - -void wxTreeListMainWindow::OnRenameTimer() { - EditLabel (m_curItem, m_curColumn); -} - -void wxTreeListMainWindow::OnRenameAccept() { - - // TODO if the validator fails this causes a crash - wxTreeEvent le( wxEVT_COMMAND_TREE_END_LABEL_EDIT, m_owner->GetId() ); -#if !wxCHECK_VERSION(2, 5, 0) - le.SetItem((long)m_editItem); -#else - le.SetItem(m_editItem); -#endif - le.SetEventObject( /*this*/m_owner ); - le.SetLabel( m_renameRes ); - m_owner->GetEventHandler()->ProcessEvent( le ); - - if (!le.IsAllowed()) return; - - SetItemText (m_editItem, m_curColumn, m_renameRes); -} - -void wxTreeListMainWindow::OnMouse (wxMouseEvent &event) { - if (!m_rootItem) return; - - // we process left mouse up event (enables in-place edit), right down - // (pass to the user code), left dbl click (activate item) and - // dragging/moving events for items drag-and-drop - if (!(event.LeftDown() || - event.LeftUp() || - event.RightDown() || - event.RightUp() || - event.LeftDClick() || - event.Dragging() || - (event.GetWheelRotation() != 0 )/*? TODO || - event.Moving()?*/)) { - m_owner->GetEventHandler()->ProcessEvent (event); - return; - } - - // set focus if window clicked - if (event.LeftDown() || event.RightDown()) SetFocus(); - - // determine event - wxPoint p = wxPoint (event.GetX(), event.GetY()); - int flags = 0; - wxTreeListItem *item = m_rootItem->HitTest (CalcUnscrolledPosition (p), - this, flags, m_curColumn, 0); - - // we only process dragging here - if (event.Dragging()){ - if (m_isDragging) return; // nothing to do, already done - if (item == NULL) return; // we need an item to dragging - - // determine drag start - if (m_dragCount == 0) { - m_dragTimer->Start (DRAG_TIMER_TICKS, wxTIMER_ONE_SHOT); - } - m_dragCount++; - if (m_dragCount < 3) return; // minimum drag 3 pixel - if (m_dragTimer->IsRunning()) return; - - // we're going to drag - m_dragCount = 0; - m_isDragging = true; - CaptureMouse(); - RefreshSelected(); - - // send drag start event - wxEventType command = event.LeftIsDown() - ? wxEVT_COMMAND_TREE_BEGIN_DRAG - : wxEVT_COMMAND_TREE_BEGIN_RDRAG; - wxTreeEvent nevent (command, m_owner->GetId()); - nevent.SetEventObject (m_owner); -#if !wxCHECK_VERSION(2, 5, 0) - nevent.SetItem ((long)item); // the item the drag is ended -#else - nevent.SetItem (item); // the item the drag is ended -#endif - nevent.Veto(); // dragging must be explicit allowed! - m_owner->GetEventHandler()->ProcessEvent (nevent); - - }else if (m_isDragging) { // any other event but not event.Dragging() - - // end dragging - m_dragCount = 0; - m_isDragging = false; - if (HasCapture()) ReleaseMouse(); - RefreshSelected(); - - // send drag end event event - wxTreeEvent nevent (wxEVT_COMMAND_TREE_END_DRAG, m_owner->GetId()); - nevent.SetEventObject (m_owner); -#if !wxCHECK_VERSION(2, 5, 0) - nevent.SetItem ((long)item); // the item the drag is started -#else - nevent.SetItem (item); // the item the drag is started -#endif - nevent.SetPoint (p); - m_owner->GetEventHandler()->ProcessEvent (nevent); - - }else if (m_dragCount > 0) { // just in case dragging is initiated - - // end dragging - m_dragCount = 0; - - } - - // we process only the messages which happen on tree items - if (item == NULL) { - m_owner->GetEventHandler()->ProcessEvent (event); - return; - } - - // remember item at shift down - if (event.ShiftDown()) { - if (!m_shiftItem) m_shiftItem = m_curItem; - }else{ - m_shiftItem = (wxTreeListItem*)NULL; - } - - if (event.RightUp()) { - - SetFocus(); - wxTreeEvent nevent (wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK, m_owner->GetId()); - nevent.SetEventObject (m_owner); -#if !wxCHECK_VERSION(2, 5, 0) - nevent.SetItem ((long)item); // the item clicked -#else - nevent.SetItem (item); // the item clicked -#endif - nevent.SetInt (m_curColumn); // the colum clicked - nevent.SetPoint (p); - m_owner->GetEventHandler()->ProcessEvent (nevent); - - }else if (event.LeftUp()) { - - if (m_lastOnSame) { - if ((item == m_curItem) && (m_curColumn != -1) && - (m_owner->GetHeaderWindow()->IsColumnEditable (m_curColumn)) && - (flags & (wxTREE_HITTEST_ONITEMLABEL | wxTREE_HITTEST_ONITEMCOLUMN))){ - m_renameTimer->Start (RENAME_TIMER_TICKS, wxTIMER_ONE_SHOT); - } - m_lastOnSame = false; - } - - if (((flags & wxTREE_HITTEST_ONITEMBUTTON) || - (flags & wxTREE_HITTEST_ONITEMICON)) && - HasButtons() && item->HasPlus()) { - - - // only toggle the item for a single click, double click on - // the button doesn't do anything (it toggles the item twice) - if (event.LeftDown()) Toggle (item); - - // don't select the item if the button was clicked - return; - } - - // determine the selection if not done by left down - if (!m_left_down_selection) { - bool unselect_others = !((event.ShiftDown() || event.ControlDown()) && - HasFlag(wxTR_MULTIPLE)); - - SelectItem (item, m_shiftItem, unselect_others); - EnsureVisible (item); - // LG m_curItem = item; // make the new item the current item - }else{ - m_left_down_selection = false; - } - - }else if (event.LeftDown() || event.RightDown() || event.LeftDClick()) { - - if (event.LeftDown() || event.RightDown()) { - SetFocus(); - m_lastOnSame = item == m_curItem; - } - - if (((flags & wxTREE_HITTEST_ONITEMBUTTON) || - (flags & wxTREE_HITTEST_ONITEMICON)) && - item->HasPlus()) { - - // only toggle the item for a single click, double click on - // the button doesn't do anything (it toggles the item twice) - - if (event.LeftDown()) Toggle (item); - - // don't select the item if the button was clicked - return; - } - - // determine the selection if the current item is not selected - if (!item->IsSelected()) { - bool unselect_others = !((event.ShiftDown() || event.ControlDown()) && - HasFlag(wxTR_MULTIPLE)); - SelectItem (item, m_shiftItem, unselect_others); - EnsureVisible (item); - // LG m_curItem = item; // make the new item the current item - m_left_down_selection = true; - } - - // For some reason, Windows isn't recognizing a left double-click, - // so we need to simulate it here. Allow 200 milliseconds for now. - if (event.LeftDClick()) { - - // double clicking should not start editing the item label - m_renameTimer->Stop(); - m_lastOnSame = false; - - // send activate event first - wxTreeEvent nevent (wxEVT_COMMAND_TREE_ITEM_ACTIVATED, m_owner->GetId()); - nevent.SetEventObject (m_owner); -#if !wxCHECK_VERSION(2, 5, 0) - nevent.SetItem ((long)item); // the item clicked -#else - nevent.SetItem (item); // the item clicked -#endif - nevent.SetInt (m_curColumn); // the colum clicked - nevent.SetPoint (p); - if (!m_owner->GetEventHandler()->ProcessEvent (nevent)) { - - // if the user code didn't process the activate event, - // handle it ourselves by toggling the item when it is - // double clicked - - if (item->HasPlus()) Toggle(item); - } - } - - }else{ // any other event skip just in case - - event.Skip(); - - } -} - -void wxTreeListMainWindow::OnIdle (wxIdleEvent &WXUNUSED(event)) { - /* after all changes have been done to the tree control, - * we actually redraw the tree when everything is over */ - - if (!m_dirty) return; - - m_dirty = false; - - CalculatePositions(); - Refresh(); - AdjustMyScrollbars(); -} - -void wxTreeListMainWindow::OnScroll (wxScrollWinEvent& event) { - // FIXME -#if defined(__WXGTK__) && !defined(__WXUNIVERSAL__) - wxScrolledWindow::OnScroll(event); -#else - HandleOnScroll( event ); -#endif - - if(event.GetOrientation() == wxHORIZONTAL) { - m_owner->GetHeaderWindow()->Refresh(); - m_owner->GetHeaderWindow()->Update(); - } -} - -void wxTreeListMainWindow::CalculateSize (wxTreeListItem *item, wxDC &dc) { - wxCoord text_w = 0; - wxCoord text_h = 0; - - dc.SetFont (GetItemFont (item)); - - dc.GetTextExtent (item->GetText (m_main_column), &text_w, &text_h); - - // restore normal font - dc.SetFont (m_normalFont); - - int total_h = (m_imgHeight > text_h) ? m_imgHeight : text_h; - if (total_h < 30) { // add 10% space if greater than 30 pixels - total_h += 2; // minimal 2 pixel space - }else{ - total_h += total_h / 10; // otherwise 10% space - } - - item->SetHeight (total_h); - if (total_h > m_lineHeight) m_lineHeight = total_h; - item->SetWidth(m_imgWidth + text_w +2); -} - -// ----------------------------------------------------------------------------- -void wxTreeListMainWindow::CalculateLevel (wxTreeListItem *item, wxDC &dc, - int level, int &y, int x_colstart) { - - // calculate position of vertical lines - int x = x_colstart + MARGIN; // start of column - if (HasFlag(wxTR_LINES_AT_ROOT)) x += LINEATROOT; // space for lines at root - if (HasButtons()) { - x += (m_btnWidth-m_btnWidth2); // half button space - }else{ - x += (m_indent-m_indent/2); - } - if (HasFlag(wxTR_HIDE_ROOT)) { - // LG - // x += m_indent * (level-2); // indent but not level 1 - x += m_indent * (level-1); // indent but not level 1 - - }else{ - x += m_indent * level; // indent according to level - } - - // a hidden root is not evaluated, but its children are always - if (HasFlag(wxTR_HIDE_ROOT) && (level == 0)) goto Recurse; - - CalculateSize( item, dc ); - - // set its position - item->SetX (x); - item->SetY (y); - y += GetLineHeight(item); - - // we don't need to calculate collapsed branches - if ( !item->IsExpanded() ) return; - -Recurse: - wxArrayTreeListItems& children = item->GetChildren(); - long n, count = (long)children.Count(); - ++level; - for (n = 0; n < count; ++n) { - CalculateLevel( children[n], dc, level, y, x_colstart ); // recurse - } -} - -void wxTreeListMainWindow::CalculatePositions() { - if ( !m_rootItem ) return; - - wxClientDC dc(this); - PrepareDC( dc ); - - dc.SetFont( m_normalFont ); - - dc.SetPen( m_dottedPen ); - //if(GetImageList() == NULL) - // m_lineHeight = (int)(dc.GetCharHeight() + 4); - - int y = 2; - int x_colstart = 0; - for (int i = 0; i < (int)GetMainColumn(); ++i) { - if (!m_owner->GetHeaderWindow()->IsColumnShown(i)) continue; - x_colstart += m_owner->GetHeaderWindow()->GetColumnWidth(i); - } - CalculateLevel( m_rootItem, dc, 0, y, x_colstart ); // start recursion -} - -void wxTreeListMainWindow::RefreshSubtree (wxTreeListItem *item) { - if (m_dirty) return; - - wxClientDC dc(this); - PrepareDC(dc); - - int cw = 0; - int ch = 0; - GetVirtualSize( &cw, &ch ); - - wxRect rect; - rect.x = dc.LogicalToDeviceX( 0 ); - rect.width = cw; - rect.y = dc.LogicalToDeviceY( item->GetY() - 2 ); - rect.height = ch; - - Refresh (true, &rect ); - AdjustMyScrollbars(); -} - -void wxTreeListMainWindow::RefreshLine (wxTreeListItem *item) { - - // return; - // std::cout << "RefreshLine = "<GetY() ); - rect.width = cw; - rect.height = GetLineHeight(item); //dc.GetCharHeight() + 6; - - Refresh (true, &rect); -} - -void wxTreeListMainWindow::RefreshSelected() -{ - - long count = m_selected.GetCount(); - for (long n = 0; n < count; n++ ) - { - RefreshLine (m_selected[n]); - } -} - -/* -void wxTreeListMainWindow::RefreshSelectedUnder (wxTreeListItem *item) { - if (item->IsSelected()) { - RefreshLine (item); - } - - const wxArrayTreeListItems& children = item->GetChildren(); - long count = children.GetCount(); - for (long n = 0; n < count; n++ ) { - RefreshSelectedUnder (children[n]); - } -} -*/ - -// ---------------------------------------------------------------------------- -// changing colours: we need to refresh the tree control -// ---------------------------------------------------------------------------- - -bool wxTreeListMainWindow::SetBackgroundColour (const wxColour& colour) { - if (!wxWindow::SetBackgroundColour(colour)) return false; - - Refresh(); - return true; -} - -bool wxTreeListMainWindow::SetForegroundColour (const wxColour& colour) { - if (!wxWindow::SetForegroundColour(colour)) return false; - - Refresh(); - return true; -} - -void wxTreeListMainWindow::SetItemText (const wxTreeItemId& itemId, int column, - const wxString& text) { - wxCHECK_RET (itemId.IsOk(), _T("invalid tree item")); - - wxClientDC dc (this); - wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; - item->SetText (column, text); - CalculateSize (item, dc); - RefreshLine (item); -} - -wxString wxTreeListMainWindow::GetItemText (const wxTreeItemId& itemId, - int column) const { - wxCHECK_MSG (itemId.IsOk(), _T(""), _T("invalid tree item") ); - - if( IsVirtual() ) return m_owner->OnGetItemText(((wxTreeListItem*) itemId.m_pItem)->GetData(),column); - else return ((wxTreeListItem*) itemId.m_pItem)->GetText (column); -} - -wxString wxTreeListMainWindow::GetItemText (wxTreeItemData* item, -int column) const { - wxASSERT_MSG( IsVirtual(), _T("can be used only with virtual control") ); - return m_owner->OnGetItemText(item,column); -} - -void wxTreeListMainWindow::SetFocus() { - wxWindow::SetFocus(); -} - -wxFont wxTreeListMainWindow::GetItemFont (wxTreeListItem *item) { - wxTreeItemAttr *attr = item->GetAttributes(); - - if (attr && attr->HasFont()) { - return attr->GetFont(); - }else if (item->IsBold()) { - return m_boldFont; - }else{ - return m_normalFont; - } -} - -int wxTreeListMainWindow::GetItemWidth (int column, wxTreeListItem *item) { - if (!item) return 0; - - // determine item width - int w = 0, h = 0; - wxFont font = GetItemFont (item); - GetTextExtent (item->GetText (column), &w, &h, NULL, NULL, font.Ok()? &font: NULL); - w += 2*MARGIN; - - // calculate width - int width = w + 2*MARGIN; - if (column == GetMainColumn()) { - width += MARGIN; - if (HasFlag(wxTR_LINES_AT_ROOT)) width += LINEATROOT; - if (HasButtons()) width += m_btnWidth + LINEATROOT; - if (item->GetCurrentImage() != NO_IMAGE) width += m_imgWidth; - - // count indent level - int level = 0; - wxTreeListItem *parent = item->GetItemParent(); - wxTreeListItem *root = (wxTreeListItem*)GetRootItem().m_pItem; - while (parent && (!HasFlag(wxTR_HIDE_ROOT) || (parent != root))) { - level++; - parent = parent->GetItemParent(); - } - if (level) width += level * GetIndent(); - } - - return width; -} - -int wxTreeListMainWindow::GetBestColumnWidth (int column, wxTreeItemId parent) { - int maxWidth, h; - GetClientSize (&maxWidth, &h); - int width = 0; - - // get root if on item - if (!parent.IsOk()) parent = GetRootItem(); - - // add root width - if (!HasFlag(wxTR_HIDE_ROOT)) { - int w = GetItemWidth (column, (wxTreeListItem*)parent.m_pItem); - if (width < w) width = w; - if (width > maxWidth) return maxWidth; - } - - wxTreeItemIdValue cookie = 0; - wxTreeItemId item = GetFirstChild (parent, cookie); - while (item.IsOk()) { - int w = GetItemWidth (column, (wxTreeListItem*)item.m_pItem); - if (width < w) width = w; - if (width > maxWidth) return maxWidth; - - // check the children of this item - if (((wxTreeListItem*)item.m_pItem)->IsExpanded()) { - int w = GetBestColumnWidth (column, item); - if (width < w) width = w; - if (width > maxWidth) return maxWidth; - } - - // next sibling - item = GetNextChild (parent, cookie); - } - - return width; -} - - -//----------------------------------------------------------------------------- -// wxTreeListCtrl -//----------------------------------------------------------------------------- - -//IMPLEMENT_DYNAMIC_CLASS(wxTreeListCtrl, wxControl); -//IMPLEMENT_CLASS(wxTreeListCtrl, wxControl); - -BEGIN_EVENT_TABLE(wxTreeListCtrl, wxControl) - EVT_SIZE(wxTreeListCtrl::OnSize) -END_EVENT_TABLE(); - -bool wxTreeListCtrl::Create(wxWindow *parent, wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style, const wxValidator &validator, - const wxString& name) -{ - long main_style = style & ~(wxSIMPLE_BORDER|wxSUNKEN_BORDER|wxDOUBLE_BORDER| - wxRAISED_BORDER|wxSTATIC_BORDER); - long ctrl_style = style & ~(wxVSCROLL|wxHSCROLL); - - if (!wxControl::Create(parent, id, pos, size, ctrl_style, validator, name)) { - return false; - } - m_main_win = new wxTreeListMainWindow (this, -1, wxPoint(0, 0), size, - main_style, validator); - m_header_win = new wxTreeListHeaderWindow (this, -1, m_main_win, - wxPoint(0, 0), wxDefaultSize, - wxTAB_TRAVERSAL); - CalculateAndSetHeaderHeight(); - return true; -} - -void wxTreeListCtrl::CalculateAndSetHeaderHeight() -{ - if (m_header_win) { - - // we use 'g' to get the descent, too - int w, h, d; - m_header_win->GetTextExtent(_T("Hg"), &w, &h, &d); - h += d + 2 * HEADER_OFFSET_Y + EXTRA_HEIGHT; - h = 0 ; - // only update if changed - if (h != m_headerHeight) { - m_headerHeight = h; - DoHeaderLayout(); - } - } -} - -void wxTreeListCtrl::DoHeaderLayout() -{ - int w, h; - GetClientSize(&w, &h); - if (m_header_win) { - m_header_win->SetSize (0, 0, w, m_headerHeight); - m_header_win->Refresh(); - } - if (m_main_win) { - m_main_win->SetSize (0, m_headerHeight + 1, w, h - m_headerHeight - 1); - } -} - -void wxTreeListCtrl::OnSize(wxSizeEvent& WXUNUSED(event)) -{ - DoHeaderLayout(); -} - -size_t wxTreeListCtrl::GetCount() const { return m_main_win->GetCount(); } - -unsigned int wxTreeListCtrl::GetIndent() const -{ return m_main_win->GetIndent(); } - -void wxTreeListCtrl::SetIndent(unsigned int indent) -{ m_main_win->SetIndent(indent); } - -unsigned int wxTreeListCtrl::GetLineSpacing() const -{ return m_main_win->GetLineSpacing(); } - -void wxTreeListCtrl::SetLineSpacing(unsigned int spacing) -{ m_main_win->SetLineSpacing(spacing); } - -wxImageList* wxTreeListCtrl::GetImageList() const -{ return m_main_win->GetImageList(); } - -wxImageList* wxTreeListCtrl::GetStateImageList() const -{ return m_main_win->GetStateImageList(); } - -wxImageList* wxTreeListCtrl::GetButtonsImageList() const -{ return m_main_win->GetButtonsImageList(); } - -void wxTreeListCtrl::SetImageList(wxImageList* imageList) -{ m_main_win->SetImageList(imageList); } - -void wxTreeListCtrl::SetStateImageList(wxImageList* imageList) -{ m_main_win->SetStateImageList(imageList); } - -void wxTreeListCtrl::SetButtonsImageList(wxImageList* imageList) -{ m_main_win->SetButtonsImageList(imageList); } - -void wxTreeListCtrl::AssignImageList(wxImageList* imageList) -{ m_main_win->AssignImageList(imageList); } - -void wxTreeListCtrl::AssignStateImageList(wxImageList* imageList) -{ m_main_win->AssignStateImageList(imageList); } - -void wxTreeListCtrl::AssignButtonsImageList(wxImageList* imageList) -{ m_main_win->AssignButtonsImageList(imageList); } - -wxString wxTreeListCtrl::GetItemText(const wxTreeItemId& item, int column) const -{ return m_main_win->GetItemText (item, column); } - -int wxTreeListCtrl::GetItemImage(const wxTreeItemId& item, int column, - wxTreeItemIcon which) const -{ return m_main_win->GetItemImage(item, column, which); } - -wxTreeItemData* wxTreeListCtrl::GetItemData(const wxTreeItemId& item) const -{ return m_main_win->GetItemData(item); } - -bool wxTreeListCtrl::GetItemBold(const wxTreeItemId& item) const -{ return m_main_win->GetItemBold(item); } - -wxColour wxTreeListCtrl::GetItemTextColour(const wxTreeItemId& item) const -{ return m_main_win->GetItemTextColour(item); } - -wxColour wxTreeListCtrl::GetItemBackgroundColour(const wxTreeItemId& item) - const -{ return m_main_win->GetItemBackgroundColour(item); } - -wxFont wxTreeListCtrl::GetItemFont(const wxTreeItemId& item) const -{ return m_main_win->GetItemFont(item); } - - -void wxTreeListCtrl::SetItemText(const wxTreeItemId& item, int column, - const wxString& text) -{ m_main_win->SetItemText (item, column, text); } - -void wxTreeListCtrl::SetItemImage(const wxTreeItemId& item, - int column, - int image, - wxTreeItemIcon which) -{ m_main_win->SetItemImage(item, column, image, which); } - -void wxTreeListCtrl::SetItemData(const wxTreeItemId& item, - wxTreeItemData* data) -{ m_main_win->SetItemData(item, data); } - -void wxTreeListCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has) -{ m_main_win->SetItemHasChildren(item, has); } - -void wxTreeListCtrl::SetItemBold(const wxTreeItemId& item, bool bold) -{ m_main_win->SetItemBold(item, bold); } - -void wxTreeListCtrl::SetItemTextColour(const wxTreeItemId& item, - const wxColour& colour) -{ m_main_win->SetItemTextColour(item, colour); } - -void wxTreeListCtrl::SetItemBackgroundColour(const wxTreeItemId& item, - const wxColour& colour) -{ m_main_win->SetItemBackgroundColour(item, colour); } - -void wxTreeListCtrl::SetItemFont(const wxTreeItemId& item, - const wxFont& font) -{ m_main_win->SetItemFont(item, font); } - -bool wxTreeListCtrl::SetFont(const wxFont& font) -{ - if (m_header_win) { - m_header_win->SetFont(font); - CalculateAndSetHeaderHeight(); - m_header_win->Refresh(); - } - if (m_main_win) { - return m_main_win->SetFont(font); - }else{ - return false; - } -} - -void wxTreeListCtrl::SetWindowStyle(const long style) -{ - if(m_main_win) - m_main_win->SetWindowStyle(style); - m_windowStyle = style; - // TODO: provide something like wxTL_NO_HEADERS to hide m_header_win -} - -long wxTreeListCtrl::GetWindowStyle() const -{ - long style = m_windowStyle; - if(m_main_win) - style |= m_main_win->GetWindowStyle(); - return style; -} - -bool wxTreeListCtrl::IsVisible(const wxTreeItemId& item, bool fullRow) const -{ return m_main_win->IsVisible(item, fullRow); } - -bool wxTreeListCtrl::HasChildren(const wxTreeItemId& item) const -{ return m_main_win->HasChildren(item); } - -bool wxTreeListCtrl::IsExpanded(const wxTreeItemId& item) const -{ return m_main_win->IsExpanded(item); } - -bool wxTreeListCtrl::IsSelected(const wxTreeItemId& item) const -{ return m_main_win->IsSelected(item); } - -bool wxTreeListCtrl::IsBold(const wxTreeItemId& item) const -{ return m_main_win->IsBold(item); } - -size_t wxTreeListCtrl::GetChildrenCount(const wxTreeItemId& item, bool rec) -{ return m_main_win->GetChildrenCount(item, rec); } - -wxTreeItemId wxTreeListCtrl::GetRootItem() const -{ return m_main_win->GetRootItem(); } - -//wxTreeItemId wxTreeListCtrl::GetSelection() const -//{ return m_main_win->GetSelection(); } - wxTreeItemId wxTreeListCtrl::GetCurrent() const - { return m_main_win->GetCurrent(); } - - // returns the number of currently selected items - size_t wxTreeListCtrl::GetSelectionSize() const - { return m_main_win->GetSelectionSize(); } - -size_t wxTreeListCtrl::GetSelections(wxArrayTreeItemIds& arr) const -{ return m_main_win->GetSelections(arr); } - -wxTreeItemId wxTreeListCtrl::GetItemParent(const wxTreeItemId& item) const -{ return m_main_win->GetItemParent(item); } - -#if !wxCHECK_VERSION(2, 5, 0) -wxTreeItemId wxTreeListCtrl::GetFirstChild (const wxTreeItemId& item, - long& cookie) const -#else -wxTreeItemId wxTreeListCtrl::GetFirstChild (const wxTreeItemId& item, - wxTreeItemIdValue& cookie) const -#endif -{ return m_main_win->GetFirstChild(item, cookie); } - -#if !wxCHECK_VERSION(2, 5, 0) -wxTreeItemId wxTreeListCtrl::GetNextChild (const wxTreeItemId& item, - long& cookie) const -#else -wxTreeItemId wxTreeListCtrl::GetNextChild (const wxTreeItemId& item, - wxTreeItemIdValue& cookie) const -#endif -{ return m_main_win->GetNextChild(item, cookie); } - -#if !wxCHECK_VERSION(2, 5, 0) -wxTreeItemId wxTreeListCtrl::GetPrevChild (const wxTreeItemId& item, - long& cookie) const -#else -wxTreeItemId wxTreeListCtrl::GetPrevChild (const wxTreeItemId& item, - wxTreeItemIdValue& cookie) const -#endif -{ return m_main_win->GetPrevChild(item, cookie); } - -#if !wxCHECK_VERSION(2, 5, 0) -wxTreeItemId wxTreeListCtrl::GetLastChild (const wxTreeItemId& item, - long& cookie) const -#else -wxTreeItemId wxTreeListCtrl::GetLastChild (const wxTreeItemId& item, - wxTreeItemIdValue& cookie) const -#endif -{ return m_main_win->GetLastChild(item, cookie); } - - -wxTreeItemId wxTreeListCtrl::GetNextSibling(const wxTreeItemId& item) const -{ return m_main_win->GetNextSibling(item); } - -wxTreeItemId wxTreeListCtrl::GetPrevSibling(const wxTreeItemId& item) const -{ return m_main_win->GetPrevSibling(item); } - -wxTreeItemId wxTreeListCtrl::GetNext(const wxTreeItemId& item) const -{ return m_main_win->GetNext(item, true); } - -wxTreeItemId wxTreeListCtrl::GetPrev(const wxTreeItemId& item) const -{ return m_main_win->GetPrev(item, true); } - -wxTreeItemId wxTreeListCtrl::GetFirstExpandedItem() const -{ return m_main_win->GetFirstExpandedItem(); } - -wxTreeItemId wxTreeListCtrl::GetNextExpanded(const wxTreeItemId& item) const -{ return m_main_win->GetNextExpanded(item); } - -wxTreeItemId wxTreeListCtrl::GetPrevExpanded(const wxTreeItemId& item) const -{ return m_main_win->GetPrevExpanded(item); } - -wxTreeItemId wxTreeListCtrl::GetFirstVisibleItem(bool fullRow) const -{ return m_main_win->GetFirstVisibleItem(fullRow); } - -wxTreeItemId wxTreeListCtrl::GetNextVisible(const wxTreeItemId& item, bool fullRow) const -{ return m_main_win->GetNextVisible(item, fullRow); } - -wxTreeItemId wxTreeListCtrl::GetPrevVisible(const wxTreeItemId& item, bool fullRow) const -{ return m_main_win->GetPrevVisible(item, fullRow); } - -wxTreeItemId wxTreeListCtrl::AddRoot (const wxString& text, int image, - int selectedImage, wxTreeItemData* data) -{ return m_main_win->AddRoot (text, image, selectedImage, data); } - -wxTreeItemId wxTreeListCtrl::PrependItem(const wxTreeItemId& parent, - const wxString& text, int image, - int selectedImage, - wxTreeItemData* data) -{ return m_main_win->PrependItem(parent, text, image, selectedImage, data); } - -wxTreeItemId wxTreeListCtrl::InsertItem(const wxTreeItemId& parent, - const wxTreeItemId& previous, - const wxString& text, int image, - int selectedImage, - wxTreeItemData* data) -{ - return m_main_win->InsertItem(parent, previous, text, image, - selectedImage, data); -} - -wxTreeItemId wxTreeListCtrl::InsertItem(const wxTreeItemId& parent, - size_t index, - const wxString& text, int image, - int selectedImage, - wxTreeItemData* data) -{ - return m_main_win->InsertItem(parent, index, text, image, - selectedImage, data); -} - -wxTreeItemId wxTreeListCtrl::AppendItem(const wxTreeItemId& parent, - const wxString& text, int image, - int selectedImage, - wxTreeItemData* data) -{ return m_main_win->AppendItem(parent, text, image, selectedImage, data); } - -void wxTreeListCtrl::Delete(const wxTreeItemId& item) -{ m_main_win->Delete(item); } - -void wxTreeListCtrl::DeleteChildren(const wxTreeItemId& item) -{ m_main_win->DeleteChildren(item); } - -void wxTreeListCtrl::DeleteRoot() -{ m_main_win->DeleteRoot(); } - -void wxTreeListCtrl::Expand(const wxTreeItemId& item) -{ m_main_win->Expand(item); } - -void wxTreeListCtrl::ExpandAll(const wxTreeItemId& item) -{ m_main_win->ExpandAll(item); } - -void wxTreeListCtrl::Collapse(const wxTreeItemId& item) -{ m_main_win->Collapse(item); } - -void wxTreeListCtrl::CollapseAndReset(const wxTreeItemId& item) -{ m_main_win->CollapseAndReset(item); } - -void wxTreeListCtrl::Toggle(const wxTreeItemId& item) -{ m_main_win->Toggle(item); } - -//void wxTreeListCtrl::Unselect() -//{ m_main_win->Unselect(); } - -// LG 19/09/08 : Added -//void wxTreeListCtrl::Unselect(wxTreeItemId& item) -//{ m_main_win->Unselect((wxTreeListItem*)item.m_pItem); } - -void wxTreeListCtrl::UnselectAll() -{ m_main_win->UnselectAll(); } - -void wxTreeListCtrl::SelectItem(const wxTreeItemId& item, const wxTreeItemId& last, - bool unselect_others) -{ m_main_win->SelectItem (item, last, unselect_others); } - -void wxTreeListCtrl::SelectAll() -{ m_main_win->SelectAll(); } - -void wxTreeListCtrl::EnsureVisible(const wxTreeItemId& item) -{ m_main_win->EnsureVisible(item); } - -void wxTreeListCtrl::ScrollTo(const wxTreeItemId& item) -{ m_main_win->ScrollTo(item); } - -wxTreeItemId wxTreeListCtrl::HitTest(const wxPoint& pos, int& flags, int& column) -{ - wxPoint p = m_main_win->ScreenToClient (ClientToScreen (pos)); - return m_main_win->HitTest (p, flags, column); -} - -bool wxTreeListCtrl::GetBoundingRect(const wxTreeItemId& item, wxRect& rect, - bool textOnly) const -{ return m_main_win->GetBoundingRect(item, rect, textOnly); } - -void wxTreeListCtrl::EditLabel (const wxTreeItemId& item, int column) -{ m_main_win->EditLabel (item, column); } - -int wxTreeListCtrl::OnCompareItems(const wxTreeItemId& item1, - const wxTreeItemId& item2) -{ - // do the comparison here, and not delegate to m_main_win, in order - // to let the user override it - //return m_main_win->OnCompareItems(item1, item2); - return wxStrcmp(GetItemText(item1), GetItemText(item2)); -} - -void wxTreeListCtrl::SortChildren(const wxTreeItemId& item) -{ m_main_win->SortChildren(item); } - -wxTreeItemId wxTreeListCtrl::FindItem (const wxTreeItemId& item, const wxString& str, int mode) -{ return m_main_win->FindItem (item, str, mode); } - -void wxTreeListCtrl::SetDragItem (const wxTreeItemId& item) -{ m_main_win->SetDragItem (item); } - -bool wxTreeListCtrl::SetBackgroundColour(const wxColour& colour) -{ - if (!m_main_win) return false; - return m_main_win->SetBackgroundColour(colour); -} - -bool wxTreeListCtrl::SetForegroundColour(const wxColour& colour) -{ - if (!m_main_win) return false; - return m_main_win->SetForegroundColour(colour); -} - -int wxTreeListCtrl::GetColumnCount() const -{ return m_main_win->GetColumnCount(); } - -void wxTreeListCtrl::SetColumnWidth(int column, int width) -{ - m_header_win->SetColumnWidth (column, width); - m_header_win->Refresh(); -} - -int wxTreeListCtrl::GetColumnWidth(int column) const -{ return m_header_win->GetColumnWidth(column); } - -void wxTreeListCtrl::SetMainColumn(int column) -{ m_main_win->SetMainColumn(column); } - -int wxTreeListCtrl::GetMainColumn() const -{ return m_main_win->GetMainColumn(); } - -void wxTreeListCtrl::SetColumnText(int column, const wxString& text) -{ - m_header_win->SetColumnText (column, text); - m_header_win->Refresh(); -} - -wxString wxTreeListCtrl::GetColumnText(int column) const -{ return m_header_win->GetColumnText(column); } - -void wxTreeListCtrl::AddColumn(const wxTreeListColumnInfo& colInfo) -{ - m_header_win->AddColumn (colInfo); - DoHeaderLayout(); -} - -void wxTreeListCtrl::InsertColumn(int before, const wxTreeListColumnInfo& colInfo) -{ - m_header_win->InsertColumn (before, colInfo); - m_header_win->Refresh(); -} - -void wxTreeListCtrl::RemoveColumn(int column) -{ - m_header_win->RemoveColumn (column); - m_header_win->Refresh(); -} - -void wxTreeListCtrl::SetColumn(int column, const wxTreeListColumnInfo& colInfo) -{ - m_header_win->SetColumn (column, colInfo); - m_header_win->Refresh(); -} - -const wxTreeListColumnInfo& wxTreeListCtrl::GetColumn(int column) const -{ return m_header_win->GetColumn(column); } - -wxTreeListColumnInfo& wxTreeListCtrl::GetColumn(int column) -{ return m_header_win->GetColumn(column); } - -void wxTreeListCtrl::SetColumnImage(int column, int image) -{ - m_header_win->SetColumn (column, GetColumn(column).SetImage(image)); - m_header_win->Refresh(); -} - -int wxTreeListCtrl::GetColumnImage(int column) const -{ - return m_header_win->GetColumn(column).GetImage(); -} - -void wxTreeListCtrl::SetColumnEditable(int column, bool shown) -{ - m_header_win->SetColumn (column, GetColumn(column).SetEditable(shown)); -} - -void wxTreeListCtrl::SetColumnShown(int column, bool shown) -{ - wxASSERT_MSG (column != GetMainColumn(), _T("The main column may not be hidden") ); - m_header_win->SetColumn (column, GetColumn(column).SetShown(GetMainColumn()==column? true: shown)); - m_header_win->Refresh(); -} - -bool wxTreeListCtrl::IsColumnEditable(int column) const -{ - return m_header_win->GetColumn(column).IsEditable(); -} - -bool wxTreeListCtrl::IsColumnShown(int column) const -{ - return m_header_win->GetColumn(column).IsShown(); -} - -void wxTreeListCtrl::SetColumnAlignment (int column, int flag) -{ - m_header_win->SetColumn(column, GetColumn(column).SetAlignment(flag)); - m_header_win->Refresh(); -} - -int wxTreeListCtrl::GetColumnAlignment(int column) const -{ - return m_header_win->GetColumn(column).GetAlignment(); -} - -void wxTreeListCtrl::Refresh(bool erase, const wxRect* rect) -{ - m_main_win->Refresh (erase, rect); - m_header_win->Refresh (erase, rect); -} - -void wxTreeListCtrl::SetFocus() -{ m_main_win->SetFocus(); } - -wxSize wxTreeListCtrl::DoGetBestSize() const -{ - // something is better than nothing... - return wxSize (200,200); // but it should be specified values! FIXME -} - -wxString wxTreeListCtrl::OnGetItemText( wxTreeItemData* WXUNUSED(item), long WXUNUSED(column)) const -{ - return wxEmptyString; -}