/////////////////////////////////////////////////////////////////////////////
-// Name: treectrl.cpp
-// Purpose: wxTreeCtrl. See also Robert's generic wxTreeCtrl.
-// Author: David Webster
-// Modified by:
-// Created: 10/17/99
+// Name: src/msw/treectrl.cpp
+// Purpose: wxTreeCtrl
+// Author: Julian Smart
+// Modified by: Vadim Zeitlin to be less MSW-specific on 10.10.98
+// Created: 1997
// RCS-ID: $Id$
-// Copyright: (c) David
+// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+ #pragma implementation "treectrl.h"
+#endif
+
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
-#include "wx/window.h"
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#if wxUSE_TREECTRL
+
#include "wx/os2/private.h"
+#include "wx/app.h"
#include "wx/log.h"
#include "wx/dynarray.h"
#include "wx/imaglist.h"
-#include "wx/treectrl.h"
#include "wx/settings.h"
+#include "wx/os2/treectrl.h"
-// Bug in headers, sometimes
-#ifndef TVIS_FOCUSED
- #define TVIS_FOCUSED 0x0001
-#endif
+// a macro to hide the ugliness of nested casts
+#define HITEM(item) (HTREEITEM)(WXHTREEITEM)(item)
+
+// the native control doesn't support multiple selections under MSW and we
+// have 2 ways to emulate them: either using TVS_CHECKBOXES style and let
+// checkboxes be the selection status (checked == selected) or by really
+// emulating everything, i.e. intercepting mouse and key events &c. The first
+// approach is much easier but doesn't work with comctl32.dll < 4.71 and also
+// looks quite ugly.
+#define wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE 0
+
+// ----------------------------------------------------------------------------
+// private functions
+// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
-struct wxTreeViewItem// ??? : public TV_ITEM
+typedef struct _MYRECORD
{
- wxTreeViewItem(const wxTreeItemId& item, // the item handle
- UINT mask_, // fields which are valid
- UINT stateMask_ = 0) // for TVIF_STATE only
+ RECORDCORE m_vRecord;
+ ULONG m_ulItemId;
+ ULONG m_ulUserData;
+} MYRECORD, *PMYRECORD;
+
+struct wxTreeViewItem : public MYRECORD
+{
+ wxTreeViewItem(const wxTreeItemId& rItem)
{
- // hItem member is always valid
- mask = mask_; // | TVIF_HANDLE;
- stateMask = stateMask_;
- hItem = /*(HTREEITEM)*/ (WXHTREEITEM) item;
+ m_ulItemId = (ULONG)rItem.m_pItem;
}
- // OS/2 subs
- UINT mask;
- UINT stateMask;
- WXHTREEITEM hItem;
-};
+}; // end of STRUCT wxTreeViewItem
+
+class wxTreeItemInternalData
+{
+public:
+
+ wxTreeItemInternalData() {}
+ ~wxTreeItemInternalData()
+ {
+ if(m_pAttr)
+ {
+ delete m_pAttr;
+ m_pAttr = NULL;
+ }
+ }
+
+ wxTreeItemAttr* m_pAttr;
+ WXLPARAM m_lParam; // user data
+#if defined(C_CM_COS232)
+ PMYRECORD m_pMyRecord; // so we can set the m_ulUserData to 0 when this is deleted
+#endif
+}; // end of CLASS wxTreeItemInternalData
+
+void BumpTreeRecordIds (
+ HWND hWnd
+, PMYRECORD pRecord
+)
+{
+ while(pRecord)
+ {
+ pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( hWnd
+ ,CM_QUERYRECORD
+ ,MPFROMP(pRecord)
+ ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
+ ));
+ if (pRecord)
+ pRecord->m_ulItemId++;
+ }
+} // end of BumpTreeRecordIds
+
+PMYRECORD FindOS2TreeRecordByID (
+ HWND hWnd
+, long lItemId
+)
+{
+ PMYRECORD pRecord = NULL;
+ CNRINFO vCnrInfo;
+ unsigned long i;
+
+ if (!::WinSendMsg( hWnd
+ ,CM_QUERYCNRINFO
+ ,MPFROMP(&vCnrInfo)
+ ,(MPARAM)(USHORT)sizeof(CNRINFO)
+ ))
+ return NULL;
+ for (i = 0; i < vCnrInfo.cRecords; i++)
+ {
+ if (i == 0)
+ pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( hWnd
+ ,CM_QUERYRECORD
+ ,MPFROMP(pRecord)
+ ,MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)
+ ));
+ else
+ pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( hWnd
+ ,CM_QUERYRECORD
+ ,MPFROMP(pRecord)
+ ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
+ ));
+ if (!pRecord)
+ return NULL;
+ if (pRecord->m_ulItemId == (ULONG)lItemId)
+ break;
+ }
+ return pRecord;
+} // end of FindOS2ListRecordByID
+
+
-// a class which encapsulates the tree traversal logic: it vists all (unless
-// OnVisit() returns FALSE) items under the given one
class wxTreeTraversal
{
public:
- wxTreeTraversal(const wxTreeCtrl *tree)
+ wxTreeTraversal(const wxTreeCtrl* pTree)
{
- m_tree = tree;
+ m_pTree = pTree;
}
- // do traverse the tree: visit all items (recursively by default) under the
+ //
+ // Do traverse the tree: visit all items (recursively by default) under the
// given one; return TRUE if all items were traversed or FALSE if the
// traversal was aborted because OnVisit returned FALSE
- bool DoTraverse(const wxTreeItemId& root, bool recursively = TRUE);
+ //
+ bool DoTraverse( const wxTreeItemId& rRoot
+ ,bool bRecursively = TRUE
+ );
- // override this function to do whatever is needed for each item, return
+ //
+ // Override this function to do whatever is needed for each item, return
// FALSE to stop traversing
- virtual bool OnVisit(const wxTreeItemId& item) = 0;
+ //
+ virtual bool OnVisit(const wxTreeItemId& rItem) = 0;
protected:
- const wxTreeCtrl *GetTree() const { return m_tree; }
+ const wxTreeCtrl* GetTree(void) const { return m_pTree; }
private:
- bool Traverse(const wxTreeItemId& root, bool recursively);
+ bool Traverse( const wxTreeItemId& rRoot
+ ,bool bRecursively
+ );
- const wxTreeCtrl *m_tree;
-};
+ const wxTreeCtrl* m_pTree;
+ DECLARE_NO_COPY_CLASS(wxTreeTraversal)
+}; // end of CLASS wxTreeTraversal
-// internal class for getting the selected items
+//
+// Internal class for getting the selected items
+//
class TraverseSelections : public wxTreeTraversal
{
public:
- TraverseSelections(const wxTreeCtrl *tree,
- wxArrayTreeItemIds& selections)
- : wxTreeTraversal(tree), m_selections(selections)
- {
- m_selections.Empty();
-
- DoTraverse(tree->GetRootItem());
- }
+ TraverseSelections( const wxTreeCtrl* pTree
+ ,wxArrayTreeItemIds& raSelections
+ )
+ : wxTreeTraversal(pTree)
+ , m_aSelections(raSelections)
+ {
+ m_aSelections.Empty();
+ DoTraverse(pTree->GetRootItem());
+ }
- virtual bool OnVisit(const wxTreeItemId& item)
+ virtual bool OnVisit(const wxTreeItemId& rItem)
{
- if ( GetTree()->IsItemChecked(item) )
+ //
+ // Can't visit a virtual node.
+ //
+ if ((GetTree()->GetRootItem() == rItem) && (GetTree()->GetWindowStyle() & wxTR_HIDE_ROOT))
{
- m_selections.Add(item);
+ return TRUE;
}
-
- return TRUE;
- }
-
-private:
- wxArrayTreeItemIds& m_selections;
-};
-
-// internal class for counting tree items
-class TraverseCounter : public wxTreeTraversal
-{
-public:
- TraverseCounter(const wxTreeCtrl *tree,
- const wxTreeItemId& root,
- bool recursively)
- : wxTreeTraversal(tree)
+ PMYRECORD pRecord = FindOS2TreeRecordByID( GetTree()->GetHWND()
+ ,rItem.m_pItem
+ );
+ if (pRecord->m_vRecord.flRecordAttr & CRA_SELECTED)
{
- m_count = 0;
-
- DoTraverse(root, recursively);
+ m_aSelections.Add(rItem);
}
-
- virtual bool OnVisit(const wxTreeItemId& item)
- {
- m_count++;
-
return TRUE;
}
- size_t GetCount() const { return m_count; }
+ size_t GetCount(void) const { return m_aSelections.GetCount(); }
private:
- size_t m_count;
-};
+ wxArrayTreeItemIds& m_aSelections;
+}; // end of CLASS TraverseSelections
-// ----------------------------------------------------------------------------
-// This class is needed for support of different images: the Win32 common
-// control natively supports only 2 images (the normal one and another for the
-// selected state). We wish to provide support for 2 more of them for folder
-// items (i.e. those which have children): for expanded state and for expanded
-// selected state. For this we use this structure to store the additional items
-// images.
//
-// There is only one problem with this: when we retrieve the item's data, we
-// don't know whether we get a pointer to wxTreeItemData or
-// wxTreeItemIndirectData. So we have to maintain a list of all items which
-// have indirect data inside the listctrl itself.
-// ----------------------------------------------------------------------------
-class wxTreeItemIndirectData
+// Internal class for counting tree items
+//
+class TraverseCounter : public wxTreeTraversal
{
public:
- // ctor associates this data with the item and the real item data becomes
- // available through our GetData() method
- wxTreeItemIndirectData(wxTreeCtrl *tree, const wxTreeItemId& item)
+ TraverseCounter( const wxTreeCtrl* pTree
+ ,const wxTreeItemId& rRoot
+ ,bool bRecursively
+ )
+ : wxTreeTraversal(pTree)
{
- for ( size_t n = 0; n < WXSIZEOF(m_images); n++ )
- {
- m_images[n] = -1;
- }
-
- // save the old data
- m_data = tree->GetItemData(item);
-
- // and set ourselves as the new one
- tree->SetIndirectItemData(item, this);
+ m_nCount = 0;
+ DoTraverse(rRoot, bRecursively);
}
- // dtor deletes the associated data as well
- ~wxTreeItemIndirectData() { delete m_data; }
-
- // accessors
- // get the real data associated with the item
- wxTreeItemData *GetData() const { return m_data; }
- // change it
- void SetData(wxTreeItemData *data) { m_data = data; }
+ virtual bool OnVisit(const wxTreeItemId& WXUNUSED(rItem))
+ {
+ m_nCount++;
+ return TRUE;
+ }
- // do we have such image?
- bool HasImage(wxTreeItemIcon which) const { return m_images[which] != -1; }
- // get image
- int GetImage(wxTreeItemIcon which) const { return m_images[which]; }
- // change it
- void SetImage(int image, wxTreeItemIcon which) { m_images[which] = image; }
+ size_t GetCount(void) const { return m_nCount; }
private:
- // all the images associated with the item
- int m_images[wxTreeItemIcon_Max];
-
- wxTreeItemData *m_data;
-};
+ size_t m_nCount;
+}; // end of CLASS TraverseCounter
// ----------------------------------------------------------------------------
-// macros
+// wxWin macros
// ----------------------------------------------------------------------------
-#if !USE_SHARED_LIBRARY
- IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxControl)
-#endif
+IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxControl)
// ----------------------------------------------------------------------------
-// variables
+// constants
// ----------------------------------------------------------------------------
-// handy table for sending events
-static const wxEventType g_events[2][2] =
+// indices in gs_expandEvents table below
+enum
+{
+ IDX_COLLAPSE,
+ IDX_EXPAND,
+ IDX_WHAT_MAX
+};
+
+enum
+{
+ IDX_DONE,
+ IDX_DOING,
+ IDX_HOW_MAX
+};
+
+// handy table for sending events - it has to be initialized during run-time
+// now so can't be const any more
+static /* const */ wxEventType gs_expandEvents[IDX_WHAT_MAX][IDX_HOW_MAX];
+
+/*
+ but logically it's a const table with the following entries:
+=
{
{ wxEVT_COMMAND_TREE_ITEM_COLLAPSED, wxEVT_COMMAND_TREE_ITEM_COLLAPSING },
{ wxEVT_COMMAND_TREE_ITEM_EXPANDED, wxEVT_COMMAND_TREE_ITEM_EXPANDING }
};
+*/
// ============================================================================
// implementation
// tree traversal
// ----------------------------------------------------------------------------
-bool wxTreeTraversal::DoTraverse(const wxTreeItemId& root, bool recursively)
+bool wxTreeTraversal::DoTraverse (
+ const wxTreeItemId& rRoot
+, bool bRecursively
+)
{
- if ( !OnVisit(root) )
+ if (!OnVisit(rRoot))
return FALSE;
- return Traverse(root, recursively);
-}
-
-bool wxTreeTraversal::Traverse(const wxTreeItemId& root, bool recursively)
-{
- long cookie;
- wxTreeItemId child = m_tree->GetFirstChild(root, cookie);
- while ( child.IsOk() )
+ return Traverse( rRoot
+ ,bRecursively
+ );
+} // end of wxTreeTraversal::DoTraverse
+
+bool wxTreeTraversal::Traverse (
+ const wxTreeItemId& rRoot
+, bool bRecursively
+)
+{
+ long lCookie;
+ wxTreeItemId vChild = m_pTree->GetFirstChild( rRoot
+ ,lCookie
+ );
+ while (vChild.IsOk())
{
- // depth first traversal
- if ( recursively && !Traverse(child, TRUE) )
+ //
+ // Depth first traversal
+ //
+ if (bRecursively && !Traverse(vChild, TRUE))
return FALSE;
-
- if ( !OnVisit(child) )
+ if (!OnVisit(vChild))
return FALSE;
-
- child = m_tree->GetNextChild(root, cookie);
+ vChild = m_pTree->GetNextChild( rRoot
+ ,lCookie
+ );
}
-
return TRUE;
-}
+} // end of wxTreeTraversal::Traverse
// ----------------------------------------------------------------------------
// construction and destruction
// ----------------------------------------------------------------------------
-void wxTreeCtrl::Init()
-{
- m_imageListNormal = NULL;
- m_imageListState = NULL;
- m_textCtrl = NULL;
-}
+void wxTreeCtrl::Init ()
+{
+ m_pImageListNormal = NULL;
+ m_pImageListState = NULL;
+ m_bOwnsImageListNormal = FALSE;
+ m_bOwnsImageListState = FALSE;
+ m_bHasAnyAttr = FALSE;
+ m_pDragImage = NULL;
+
+ //
+ // Initialize the global array of events now as it can't be done statically
+ // with the wxEVT_XXX values being allocated during run-time only
+ //
+ gs_expandEvents[IDX_COLLAPSE][IDX_DONE] = wxEVT_COMMAND_TREE_ITEM_COLLAPSED;
+ gs_expandEvents[IDX_COLLAPSE][IDX_DOING] = wxEVT_COMMAND_TREE_ITEM_COLLAPSING;
+ gs_expandEvents[IDX_EXPAND][IDX_DONE] = wxEVT_COMMAND_TREE_ITEM_EXPANDED;
+ gs_expandEvents[IDX_EXPAND][IDX_DOING] = wxEVT_COMMAND_TREE_ITEM_EXPANDING;
+} // end of wxTreeCtrl::Init
+
+bool wxTreeCtrl::Create (
+ wxWindow* pParent
+, wxWindowID vId
+, const wxPoint& rPos
+, const wxSize& rSize
+, long lStyle
+, const wxValidator& rValidator
+, const wxString& rsName
+)
+{
+ CNRINFO vCnrInfo;
-bool wxTreeCtrl::Create(wxWindow *parent,
- wxWindowID id,
- const wxPoint& pos,
- const wxSize& size,
- long style,
- const wxValidator& validator,
- const wxString& name)
-{
Init();
-
- if ( !CreateControl(parent, id, pos, size, style, validator, name) )
+ if (!CreateControl( pParent
+ ,vId
+ ,rPos
+ ,rSize
+ ,lStyle
+ ,rValidator
+ ,rsName
+ ))
return FALSE;
-// TODO:
-/*
- DWORD wstyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP |
- TVS_HASLINES | TVS_SHOWSELALWAYS;
-
- if ( m_windowStyle & wxTR_HAS_BUTTONS )
- wstyle |= TVS_HASBUTTONS;
- if ( m_windowStyle & wxTR_EDIT_LABELS )
- wstyle |= TVS_EDITLABELS;
+ DWORD dwStyle = WS_VISIBLE | WS_TABSTOP;
- if ( m_windowStyle & wxTR_LINES_AT_ROOT )
- wstyle |= TVS_LINESATROOT;
-
- if ( m_windowStyle & wxTR_MULTIPLE )
- wstyle |= TVS_CHECKBOXES;
+ if (m_windowStyle & wxCLIP_SIBLINGS)
+ dwStyle |= WS_CLIPSIBLINGS;
// Create the tree control.
- if ( !OS2CreateControl(WC_TREEVIEW, wstyle) )
+ if (!OS2CreateControl( "CONTAINER"
+ ,dwStyle
+ ))
return FALSE;
-*/
- SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW));
+
+ //
+ // Now set the display attributes to show a TREE/ICON view of the
+ // OS/2 Container
+ //
+ if (!::WinSendMsg( GetHWND()
+ ,CM_QUERYCNRINFO
+ ,MPFROMP(&vCnrInfo)
+ ,(MPARAM)(USHORT)sizeof(CNRINFO)
+ ))
+
+ vCnrInfo.flWindowAttr = CV_TREE|CV_ICON;
+ vCnrInfo.flWindowAttr |= CA_DRAWBITMAP;
+ if (m_windowStyle & wxTR_NO_LINES)
+ vCnrInfo.flWindowAttr |= CA_TREELINE;
+
+ ::WinSendMsg( GetHWND()
+ ,CM_SETCNRINFO
+ ,MPFROMP(&vCnrInfo)
+ ,(MPARAM)CMA_FLWINDOWATTR
+ );
+
+ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
SetForegroundColour(wxWindow::GetParent()->GetForegroundColour());
+ SetFont(*wxSMALL_FONT);
+ SetXComp(0);
+ SetYComp(0);
+ SetSize( rPos.x
+ ,rPos.y
+ ,rSize.x
+ ,rSize.y
+ );
+ return TRUE;
+} // end of wxTreeCtrl::Create
- // VZ: this is some experimental code which may be used to get the
- // TVS_CHECKBOXES style functionality for comctl32.dll < 4.71.
- // AFAIK, the standard DLL does about the same thing anyhow.
-#if 0
- if ( m_windowStyle & wxTR_MULTIPLE )
+wxTreeCtrl::~wxTreeCtrl ()
+{
+ //
+ // Delete any attributes
+ //
+ if (m_bHasAnyAttr)
{
- wxBitmap bmp;
-
- // create the DC compatible with the current screen
- HDC hdcMem = CreateCompatibleDC(NULL);
-
- // create a mono bitmap of the standard size
- int x = GetSystemMetrics(SM_CXMENUCHECK);
- int y = GetSystemMetrics(SM_CYMENUCHECK);
- wxImageList imagelistCheckboxes(x, y, FALSE, 2);
- HBITMAP hbmpCheck = CreateBitmap(x, y, // bitmap size
- 1, // # of color planes
- 1, // # bits needed for one pixel
- 0); // array containing colour data
- SelectObject(hdcMem, hbmpCheck);
-
- // then draw a check mark into it
- RECT rect = { 0, 0, x, y };
- if ( !::DrawFrameControl(hdcMem, &rect,
- DFC_BUTTON,
- DFCS_BUTTONCHECK | DFCS_CHECKED) )
- {
- wxLogLastError(wxT("DrawFrameControl(check)"));
- }
-
- bmp.SetHBITMAP((WXHBITMAP)hbmpCheck);
- imagelistCheckboxes.Add(bmp);
-
- if ( !::DrawFrameControl(hdcMem, &rect,
- DFC_BUTTON,
- DFCS_BUTTONCHECK) )
+ for (wxNode* pNode = m_vAttrs.Next(); pNode; pNode = m_vAttrs.Next())
{
- wxLogLastError(wxT("DrawFrameControl(uncheck)"));
+ delete (wxTreeItemAttr *)pNode->Data();
}
-
- bmp.SetHBITMAP((WXHBITMAP)hbmpCheck);
- imagelistCheckboxes.Add(bmp);
-
- // clean up
- ::DeleteDC(hdcMem);
-
- // set the imagelist
- SetStateImageList(&imagelistCheckboxes);
+ m_bHasAnyAttr = FALSE;
}
-#endif // 0
-
- SetSize(pos.x, pos.y, size.x, size.y);
-
- return TRUE;
-}
-
-wxTreeCtrl::~wxTreeCtrl()
-{
DeleteTextCtrl();
- // delete user data to prevent memory leaks
-// DeleteAllItems();
-}
+ //
+ // Delete user data to prevent memory leaks
+ // also deletes hidden root node storage.
+ //
+ DeleteAllItems();
+ if (m_bOwnsImageListNormal)
+ delete m_pImageListNormal;
+ if (m_bOwnsImageListState)
+ delete m_pImageListState;
+} // end of wxTreeCtrl::~wxTreeCtrl
// ----------------------------------------------------------------------------
// accessors
// ----------------------------------------------------------------------------
-// simple wrappers which add error checking in debug mode
-
-bool wxTreeCtrl::DoGetItem(wxTreeViewItem* tvItem) const
+//
+// simple wrappers which add error checking in debug mode. These methods
+// assume the items are properly filled out already. If not, you get errors
+//
+bool wxTreeCtrl::DoGetItem (
+ wxTreeViewItem* pTvItem
+) const
{
-// TODO:
-/*
- if ( !TreeView_GetItem(GetHwnd(), tvItem) )
- {
- wxLogLastError("TreeView_GetItem");
+ PMYRECORD pRecord = FindOS2TreeRecordByID( GetHWND()
+ ,pTvItem->m_ulItemId
+ );
+ if (!pRecord)
+ {
+ wxLogLastError(wxT("Item not obtained"));
return FALSE;
}
-*/
return TRUE;
-}
-
-void wxTreeCtrl::DoSetItem(wxTreeViewItem* tvItem)
-{
-// TODO:
-/*
- if ( TreeView_SetItem(GetHwnd(), tvItem) == -1 )
+} // end of wxTreeCtrl::DoGetItem
+
+void wxTreeCtrl::DoSetItem (
+ wxTreeViewItem* pTvItem
+)
+{
+ //
+ // Just invalidate the record to redisplay it
+ //
+ if (!::WinSendMsg( GetHWND()
+ ,CM_INVALIDATERECORD
+ ,MPFROMP(pTvItem)
+ ,MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION | CMA_TEXTCHANGED)
+ ));
{
- wxLogLastError("TreeView_SetItem");
+ wxLogLastError(wxT("CM_INVALIDATERECORD"));
}
-*/
-}
+} // end of wxTreeCtrl::DoSetItem
-size_t wxTreeCtrl::GetCount() const
+size_t wxTreeCtrl::GetCount () const
{
-// return (size_t)TreeView_GetCount(GetHwnd());
- return 0;
-}
+ CNRINFO vCnrInfo;
+
+ ::WinSendMsg( GetHWND()
+ ,CM_QUERYCNRINFO
+ ,MPFROMP(&vCnrInfo)
+ ,(MPARAM)(USHORT)sizeof(CNRINFO)
+ );
+ return (size_t)vCnrInfo.cRecords;
+} // end of wxTreeCtrl::GetCount
-unsigned int wxTreeCtrl::GetIndent() const
+unsigned int wxTreeCtrl::GetIndent () const
{
-// return TreeView_GetIndent(GetHwnd());
- return 0;
-}
+ CNRINFO vCnrInfo;
+
+ ::WinSendMsg( GetHWND()
+ ,CM_QUERYCNRINFO
+ ,MPFROMP(&vCnrInfo)
+ ,(MPARAM)(USHORT)sizeof(CNRINFO)
+ );
+ return (unsigned int)vCnrInfo.cxTreeIndent;
+} // end of wxTreeCtrl::GetIndent
-void wxTreeCtrl::SetIndent(unsigned int indent)
+void wxTreeCtrl::SetIndent (
+ unsigned int uIndent
+)
{
-// TreeView_SetIndent(GetHwnd(), indent);
-}
+ CNRINFO vCnrInfo;
+
+ ::WinSendMsg( GetHWND()
+ ,CM_QUERYCNRINFO
+ ,MPFROMP(&vCnrInfo)
+ ,(MPARAM)(USHORT)sizeof(CNRINFO)
+ );
+ vCnrInfo.cxTreeIndent = (LONG)uIndent;
+ ::WinSendMsg( GetHWND()
+ ,CM_SETCNRINFO
+ ,MPFROMP(&vCnrInfo)
+ ,(MPARAM)CMA_CXTREEINDENT
+ );
+} // end of wxTreeCtrl::SetIndent
-wxImageList *wxTreeCtrl::GetImageList() const
+wxImageList* wxTreeCtrl::GetImageList () const
{
- return m_imageListNormal;
-}
+ return m_pImageListNormal;
+} // end of wxTreeCtrl::GetImageList
-wxImageList *wxTreeCtrl::GetStateImageList() const
+wxImageList* wxTreeCtrl::GetStateImageList () const
{
- return m_imageListNormal;
-}
+ return m_pImageListNormal;
+} // end of wxTreeCtrl::GetStateImageList
-void wxTreeCtrl::SetAnyImageList(wxImageList *imageList, int which)
+//
+// The SETS of imagelists really do nothing under OS2 as a RECORDCORE
+// struct has the icon imbedded in it that it uses for the icon being
+// displayed via the TREEITEMDESC member. Provided for interface
+// compatability only
+//
+void wxTreeCtrl::SetAnyImageList (
+ wxImageList* WXUNUSED(pImageList)
+, int WXUNUSED(nWhich)
+)
{
- // no error return
-// TODO:
-/*
- TreeView_SetImageList(GetHwnd(),
- imageList ? imageList->GetHIMAGELIST() : 0,
- which);
-*/
-}
+} // end of wxTreeCtrl::SetAnyImageList
-void wxTreeCtrl::SetImageList(wxImageList *imageList)
+void wxTreeCtrl::SetImageList (
+ wxImageList* WXUNUSED(pImageList)
+)
{
-// SetAnyImageList(m_imageListNormal = imageList, TVSIL_NORMAL);
-}
+ if (m_bOwnsImageListNormal)
+ delete m_pImageListNormal;
+ m_bOwnsImageListNormal = FALSE;
+} // end of wxTreeCtrl::SetImageList
-void wxTreeCtrl::SetStateImageList(wxImageList *imageList)
+void wxTreeCtrl::SetStateImageList (
+ wxImageList* WXUNUSED(pImageList)
+)
{
-// SetAnyImageList(m_imageListState = imageList, TVSIL_STATE);
-}
+ if (m_bOwnsImageListState)
+ delete m_pImageListState;
+ m_bOwnsImageListState = FALSE;
+} // end of wxTreeCtrl::SetStateImageList
-size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId& item,
- bool recursively) const
+void wxTreeCtrl::AssignImageList (
+ wxImageList* WXUNUSED(pImageList)
+)
{
- TraverseCounter counter(this, item, recursively);
+ m_bOwnsImageListNormal = TRUE;
+} // end of wxTreeCtrl::AssignImageList
- return counter.GetCount() - 1;
-}
+void wxTreeCtrl::AssignStateImageList (
+ wxImageList* WXUNUSED(pImageList)
+)
+{
+ m_bOwnsImageListState = TRUE;
+} // end of wxTreeCtrl::AssignStateImageList
+
+size_t wxTreeCtrl::GetChildrenCount (
+ const wxTreeItemId& rItem
+, bool bRecursively
+) const
+{
+ TraverseCounter vCounter( this
+ ,rItem
+ ,bRecursively
+ );
+ return vCounter.GetCount() - 1;
+} // end of wxTreeCtrl::GetChildrenCount
// ----------------------------------------------------------------------------
-// Item access
+// control colours
// ----------------------------------------------------------------------------
-wxString wxTreeCtrl::GetItemText(const wxTreeItemId& item) const
+bool wxTreeCtrl::SetBackgroundColour (
+ const wxColour& rColour
+)
{
- wxChar buf[512]; // the size is arbitrary...
-// TODO:
-/*
- wxTreeViewItem tvItem(item, TVIF_TEXT);
- tvItem.pszText = buf;
- tvItem.cchTextMax = WXSIZEOF(buf);
- if ( !DoGetItem(&tvItem) )
- {
- // don't return some garbage which was on stack, but an empty string
- buf[0] = wxT('\0');
- }
-*/
- return wxString(buf);
-}
+ ULONG ulColor = wxColourToRGB(rColour);
-void wxTreeCtrl::SetItemText(const wxTreeItemId& item, const wxString& text)
-{
-// TODO:
-/*
- wxTreeViewItem tvItem(item, TVIF_TEXT);
- tvItem.pszText = (wxChar *)text.c_str(); // conversion is ok
- DoSetItem(&tvItem);
-*/
-}
+ if ( !wxWindowBase::SetBackgroundColour(rColour) )
+ return FALSE;
+ ::WinSetPresParam( GetHWND()
+ ,PP_BACKGROUNDCOLOR
+ ,sizeof(ULONG)
+ ,&ulColor
+ );
+ return TRUE;
+} // end of wxTreeCtrl::SetBackgroundColour
-int wxTreeCtrl::DoGetItemImageFromData(const wxTreeItemId& item,
- wxTreeItemIcon which) const
+bool wxTreeCtrl::SetForegroundColour (
+ const wxColour& rColour
+)
{
-// TODO:
-/*
- wxTreeViewItem tvItem(item, TVIF_PARAM);
- if ( !DoGetItem(&tvItem) )
- {
- return -1;
- }
- return ((wxTreeItemIndirectData *)tvItem.lParam)->GetImage(which);
-*/
- return -1;
-}
+ ULONG ulColor = wxColourToRGB(rColour);
-void wxTreeCtrl::DoSetItemImageFromData(const wxTreeItemId& item,
- int image,
- wxTreeItemIcon which) const
+ if (!wxWindowBase::SetForegroundColour(rColour))
+ return FALSE;
+ ::WinSetPresParam( GetHWND()
+ ,PP_FOREGROUNDCOLOR
+ ,sizeof(ULONG)
+ ,&ulColor
+ );
+ return TRUE;
+} // end of wxTreeCtrl::SetForegroundColour
+
+// ----------------------------------------------------------------------------
+// Item access
+// ----------------------------------------------------------------------------
+
+wxString wxTreeCtrl::GetItemText (
+ const wxTreeItemId& rItem
+) const
{
-// TODO:
-/*
- wxTreeViewItem tvItem(item, TVIF_PARAM);
- if ( !DoGetItem(&tvItem) )
+ wxChar zBuf[512]; // the size is arbitrary...
+ wxTreeViewItem vTvItem(rItem);
+
+ if (!DoGetItem(&vTvItem))
{
- return;
+ //
+ // Don't return some garbage which was on stack, but an empty string
+ //
+ zBuf[0] = wxT('\0');
}
+ else
+ strcpy(zBuf, vTvItem.m_vRecord.pszTree);
+ return wxString(zBuf);
+} // end of wxTreeCtrl::GetItemText
- wxTreeItemIndirectData *data = ((wxTreeItemIndirectData *)tvItem.lParam);
+void wxTreeCtrl::SetItemText (
+ const wxTreeItemId& rItem
+, const wxString& rsText
+)
+{
+ wxTreeViewItem vTvItem(rItem);
- data->SetImage(image, which);
+ vTvItem.m_vRecord.pszTree = (wxChar *)rsText.c_str(); // conversion is ok
+ DoSetItem(&vTvItem);
+} // end of wxTreeCtrl::SetItemText
- // make sure that we have selected images as well
- if ( which == wxTreeItemIcon_Normal &&
- !data->HasImage(wxTreeItemIcon_Selected) )
+//
+// These functions under OS/2 PM are not needed. OS/2 containers in tree view
+// provide for storing a custom expanded and collapsed icons and selected
+// and non selected icons, natively. For instance, by default, a disk display
+// will display a tree list of folder icons with "+" icons (collapsed) beside
+// those folder which contain child members. Double clicking a folder changes
+// the closed folder icon to an open folder icon with hatched selection
+// highlighting indicating an ICON view container of the folder is open
+// elsewhere on the desktop. So the below is not really needed, but we will
+// simply return the appropriate icon requested out of OS/2's native PM
+// data structures.
+//
+int wxTreeCtrl::DoGetItemImageFromData (
+ const wxTreeItemId& WXUNUSED(rItem)
+, wxTreeItemIcon nWhich
+) const
+{
+ //
+ // Image handles stored in CNRINFO.
+ //
+ CNRINFO vCnrInfo;
+
+ ::WinSendMsg( GetHWND()
+ ,CM_QUERYCNRINFO
+ ,MPFROMP(&vCnrInfo)
+ ,(MPARAM)(USHORT)sizeof(CNRINFO)
+ );
+
+ //
+ // We really only have two to chose from. If not custom (set in CNRINFO
+ // then return the handle to system bitmap). OS/2 automatically provides
+ // in_use and selected bitmaps/icons
+ //
+ switch(nWhich)
{
- data->SetImage(image, wxTreeItemIcon_Selected);
- }
+ case wxTreeItemIcon_Normal:
+ if (vCnrInfo.hbmCollapsed == NULLHANDLE)
+ return (int)::WinGetSysBitmap(HWND_DESKTOP, SBMP_TREEPLUS);
+ return vCnrInfo.hbmCollapsed;
- if ( which == wxTreeItemIcon_Expanded &&
- !data->HasImage(wxTreeItemIcon_SelectedExpanded) )
- {
- data->SetImage(image, wxTreeItemIcon_SelectedExpanded);
- }
-*/
-}
-void wxTreeCtrl::DoSetItemImages(const wxTreeItemId& item,
- int image,
- int imageSel)
-{
-// TODO:
-/*
- wxTreeViewItem tvItem(item, TVIF_IMAGE | TVIF_SELECTEDIMAGE);
- tvItem.iSelectedImage = imageSel;
- tvItem.iImage = image;
- DoSetItem(&tvItem);
-*/
+ case wxTreeItemIcon_Expanded:
+ if (vCnrInfo.hbmExpanded == NULLHANDLE)
+ return (int)::WinGetSysBitmap(HWND_DESKTOP, SBMP_TREEMINUS);
+ return vCnrInfo.hbmExpanded;
+
+ default:
+ return vCnrInfo.hbmCollapsed;
+ }
}
-int wxTreeCtrl::GetItemImage(const wxTreeItemId& item,
- wxTreeItemIcon which) const
-{
- if ( HasIndirectData(item) )
+void wxTreeCtrl::DoSetItemImageFromData (
+ const wxTreeItemId& WXUNUSED(rItem)
+, int nImage
+, wxTreeItemIcon nWhich
+) const
+{
+ //
+ // Image handles stored in CNRINFO.
+ //
+ CNRINFO vCnrInfo;
+
+ ::WinSendMsg( GetHWND()
+ ,CM_QUERYCNRINFO
+ ,MPFROMP(&vCnrInfo)
+ ,(MPARAM)(USHORT)sizeof(CNRINFO)
+ );
+ if (nWhich == wxTreeItemIcon_Normal)
+ vCnrInfo.hbmCollapsed = (HBITMAP)nImage;
+ if (nWhich == wxTreeItemIcon_Expanded)
+ vCnrInfo.hbmExpanded = (HBITMAP)nImage;
+ ::WinSendMsg( GetHWND()
+ ,CM_SETCNRINFO
+ ,MPFROMP(&vCnrInfo)
+ ,(MPARAM)CMA_TREEBITMAP
+ );
+} // end of wxTreeCtrl::DoSetItemImageFromData
+
+// Useless for OS/2
+void wxTreeCtrl::DoSetItemImages (
+ const wxTreeItemId& rItem
+, int nImage
+, int nImageSel
+)
+{
+} // end of wxTreeCtrl::DoSetItemImages
+
+int wxTreeCtrl::GetItemImage (
+ const wxTreeItemId& rItem
+, wxTreeItemIcon nWhich
+) const
+{
+ if (HasIndirectData(rItem))
{
- return DoGetItemImageFromData(item, which);
+ return DoGetItemImageFromData( rItem
+ ,nWhich
+ );
}
- UINT mask;
- switch ( which )
+ CNRINFO vCnrInfo;
+
+ ::WinSendMsg( GetHWND()
+ ,CM_QUERYCNRINFO
+ ,MPFROMP(&vCnrInfo)
+ ,(MPARAM)(USHORT)sizeof(CNRINFO)
+ );
+ switch (nWhich)
{
default:
wxFAIL_MSG( wxT("unknown tree item image type") );
case wxTreeItemIcon_Normal:
-// mask = TVIF_IMAGE;
- break;
+ if (vCnrInfo.hbmCollapsed == NULLHANDLE)
+ return (int)::WinGetSysBitmap(HWND_DESKTOP, SBMP_TREEPLUS);
+ return vCnrInfo.hbmCollapsed;
- case wxTreeItemIcon_Selected:
-// mask = TVIF_SELECTEDIMAGE;
- break;
case wxTreeItemIcon_Expanded:
+ if (vCnrInfo.hbmExpanded == NULLHANDLE)
+ return (int)::WinGetSysBitmap(HWND_DESKTOP, SBMP_TREEMINUS);
+ return vCnrInfo.hbmExpanded;
+
+ case wxTreeItemIcon_Selected:
case wxTreeItemIcon_SelectedExpanded:
return -1;
}
-
- wxTreeViewItem tvItem(item, mask);
- DoGetItem(&tvItem);
-
-// return mask == TVIF_IMAGE ? tvItem.iImage : tvItem.iSelectedImage;
- return FALSE;
}
-void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image,
- wxTreeItemIcon which)
+void wxTreeCtrl::SetItemImage (
+ const wxTreeItemId& WXUNUSED(rItem)
+, int nImage
+, wxTreeItemIcon nWhich
+)
{
- int imageNormal, imageSel;
- switch ( which )
- {
- default:
- wxFAIL_MSG( wxT("unknown tree item image type") );
+ CNRINFO vCnrInfo;
+ ::WinSendMsg( GetHWND()
+ ,CM_QUERYCNRINFO
+ ,MPFROMP(&vCnrInfo)
+ ,(MPARAM)(USHORT)sizeof(CNRINFO)
+ );
+ switch (nWhich)
+ {
case wxTreeItemIcon_Normal:
- imageNormal = image;
- imageSel = GetItemSelectedImage(item);
- break;
-
- case wxTreeItemIcon_Selected:
- imageNormal = GetItemImage(item);
- imageSel = image;
+ vCnrInfo.hbmCollapsed = (HBITMAP)nImage;
break;
case wxTreeItemIcon_Expanded:
- case wxTreeItemIcon_SelectedExpanded:
- if ( !HasIndirectData(item) )
- {
- // we need to get the old images first, because after we create
- // the wxTreeItemIndirectData GetItemXXXImage() will use it to
- // get the images
- imageNormal = GetItemImage(item);
- imageSel = GetItemSelectedImage(item);
-
- // if it doesn't have it yet, add it
- wxTreeItemIndirectData *data = new
- wxTreeItemIndirectData(this, item);
-
- // copy the data to the new location
- data->SetImage(imageNormal, wxTreeItemIcon_Normal);
- data->SetImage(imageSel, wxTreeItemIcon_Selected);
- }
-
- DoSetItemImageFromData(item, image, which);
-
- // reset the normal/selected images because we won't use them any
- // more - now they're stored inside the indirect data
-// imageSel = I_IMAGECALLBACK;
+ vCnrInfo.hbmExpanded = (HBITMAP)nImage;
break;
- }
- // NB: at least in version 5.00.0518.9 of comctl32.dll we need to always
- // change both normal and selected image - otherwise the change simply
- // doesn't take place!
- DoSetItemImages(item, imageNormal, imageSel);
-}
+ default:
+ wxFAIL_MSG( wxT("unknown tree item image type") );
+ }
+ ::WinSendMsg( GetHWND()
+ ,CM_SETCNRINFO
+ ,MPFROMP(&vCnrInfo)
+ ,(MPARAM)CMA_TREEBITMAP
+ );
+} // end of wxTreeCtrl::SetItemImage
-wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const
+wxTreeItemData* wxTreeCtrl::GetItemData (
+ const wxTreeItemId& rItem
+) const
{
-// TODO:
-/*
- wxTreeViewItem tvItem(item, TVIF_PARAM);
- if ( !DoGetItem(&tvItem) )
+ wxTreeViewItem vTvItem(rItem);
+
+ if (!DoGetItem(&vTvItem))
{
return NULL;
}
- if ( HasIndirectData(item) )
- {
- return ((wxTreeItemIndirectData *)tvItem.lParam)->GetData();
- }
- else
- {
- return (wxTreeItemData *)tvItem.lParam;
- }
-*/
- return 0;
-}
+ return (wxTreeItemData *)vTvItem.m_ulUserData;
+} // end of wxTreeCtrl::GetItemData
-void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data)
+void wxTreeCtrl::SetItemData (
+ const wxTreeItemId& rItem
+, wxTreeItemData* pData
+)
{
-// TODO:
-/*
- wxTreeViewItem tvItem(item, TVIF_PARAM);
-
- if ( HasIndirectData(item) )
- {
- if ( DoGetItem(&tvItem) )
- {
- ((wxTreeItemIndirectData *)tvItem.lParam)->SetData(data);
- }
- else
- {
- wxFAIL_MSG( wxT("failed to change tree items data") );
- }
- }
- else
+ //
+ // first, associate this piece of data with this item
+ if (pData)
{
- tvItem.lParam = (MPARAM)data;
- DoSetItem(&tvItem);
+ pData->SetId(rItem);
}
-*/
-}
-void wxTreeCtrl::SetIndirectItemData(const wxTreeItemId& item,
- wxTreeItemIndirectData *data)
-{
- // this should never happen because it's unnecessary and will probably lead
- // to crash too because the code elsewhere supposes that the pointer the
- // wxTreeItemIndirectData has is a real wxItemData and not
- // wxTreeItemIndirectData as well
- wxASSERT_MSG( !HasIndirectData(item), wxT("setting indirect data twice?") );
+ wxTreeViewItem vTvItem(rItem);
- SetItemData(item, (wxTreeItemData *)data);
+ vTvItem.m_ulUserData = (ULONG)pData;
+ DoSetItem(&vTvItem);
+} // end of wxTreeCtrl::SetItemData
- m_itemsWithIndirectData.Add(item);
-}
+// The following two do nothing under OS/2
+void wxTreeCtrl::SetIndirectItemData (
+ const wxTreeItemId& WXUNUSED(rItem)
+, wxTreeItemIndirectData* WXUNUSED(pData)
+)
+{
+} // end of wxTreeCtrl::SetIndirectItemData
-bool wxTreeCtrl::HasIndirectData(const wxTreeItemId& item) const
+bool wxTreeCtrl::HasIndirectData (
+ const wxTreeItemId& WXUNUSED(rItem)
+) const
{
- return m_itemsWithIndirectData.Index(item) != wxNOT_FOUND;
-}
+ return FALSE;
+} // end of wxTreeCtrl::HasIndirectData
-void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has)
+// Irreleveant under OS/2 --- item either has child records or it doesn't.
+void wxTreeCtrl::SetItemHasChildren (
+ const wxTreeItemId& WXUNUSED(rItem)
+, bool WXUNUSED(bHas)
+)
{
-// TODO:
-/*
- wxTreeViewItem tvItem(item, TVIF_CHILDREN);
- tvItem.cChildren = (int)has;
- DoSetItem(&tvItem);
-*/
-}
+} // end of wxTreeCtrl::SetItemHasChildren
-void wxTreeCtrl::SetItemBold(const wxTreeItemId& item, bool bold)
+// Irreleveant under OS/2 --- function of the font in PM
+void wxTreeCtrl::SetItemBold (
+ const wxTreeItemId& WXUNUSED(rItem)
+, bool WXUNUSED(bBold)
+)
{
-// TODO:
-/*
- wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_BOLD);
- tvItem.state = bold ? TVIS_BOLD : 0;
- DoSetItem(&tvItem);
-*/
-}
+} // end of wxTreeCtrl::SetItemBold
-void wxTreeCtrl::SetItemDropHighlight(const wxTreeItemId& item, bool highlight)
+void wxTreeCtrl::SetItemDropHighlight (
+ const wxTreeItemId& rItem
+, bool bHighlight
+)
{
-// TODO:
-/*
- wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_DROPHILITED);
- tvItem.state = highlight ? TVIS_DROPHILITED : 0;
- DoSetItem(&tvItem);
-*/
-}
+ wxTreeViewItem vTvItem(rItem);
-// ----------------------------------------------------------------------------
-// Item status
-// ----------------------------------------------------------------------------
+ ::WinSendMsg( GetHWND()
+ ,CM_SETRECORDEMPHASIS
+ ,MPFROMP(&vTvItem)
+ ,MPFROM2SHORT(bHighlight, CRA_SELECTED)
+ );
+ DoSetItem(&vTvItem);
+} // end of wxTreeCtrl::SetItemDropHighlight
-bool wxTreeCtrl::IsVisible(const wxTreeItemId& item) const
+void wxTreeCtrl::RefreshItem (
+ const wxTreeItemId& rItem
+)
{
- // Bug in Gnu-Win32 headers, so don't use the macro TreeView_GetItemRect
-// TODO:
-/*
- RECT rect;
- return SendMessage(GetHwnd(), TVM_GETITEMRECT, FALSE, (LPARAM)&rect) != 0;
-*/
- return FALSE;
-}
+ wxTreeViewItem vTvItem(rItem);
+
+ //
+ // This just does a record invalidate causing it to be re-displayed
+ //
+ DoSetItem(&vTvItem);
+} // end of wxTreeCtrl::RefreshItem
-bool wxTreeCtrl::ItemHasChildren(const wxTreeItemId& item) const
+wxColour wxTreeCtrl::GetItemTextColour (
+ const wxTreeItemId& rItem
+) const
{
-// TODO:
-/*
- wxTreeViewItem tvItem(item, TVIF_CHILDREN);
- DoGetItem(&tvItem);
+ long lId = (long)rItem.m_pItem;
+ wxTreeItemAttr* pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
- return tvItem.cChildren != 0;
-*/
- return FALSE;
-}
+ if (!pAttr)
+ {
+ return wxNullColour;
+ }
+ return pAttr->GetTextColour();
+} // end of wxTreeCtrl::GetItemTextColour
-bool wxTreeCtrl::IsExpanded(const wxTreeItemId& item) const
+wxColour wxTreeCtrl::GetItemBackgroundColour (
+ const wxTreeItemId& rItem
+) const
{
- // probably not a good idea to put it here
- //wxASSERT( ItemHasChildren(item) );
+ long lId = (long)rItem.m_pItem;
+ wxTreeItemAttr* pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
-// TODO:
-/*
- wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_EXPANDED);
- DoGetItem(&tvItem);
-
- return (tvItem.state & TVIS_EXPANDED) != 0;
-*/
- return FALSE;
-}
+ if (!pAttr)
+ {
+ return wxNullColour;
+ }
+ return pAttr->GetBackgroundColour();
+} // end of wxTreeCtrl::GetItemBackgroundColour
-bool wxTreeCtrl::IsSelected(const wxTreeItemId& item) const
+wxFont wxTreeCtrl::GetItemFont (
+ const wxTreeItemId& rItem
+) const
{
-// TODO:
-/*
- wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_SELECTED);
- DoGetItem(&tvItem);
+ long lId = (long)rItem.m_pItem;
+ wxTreeItemAttr* pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
- return (tvItem.state & TVIS_SELECTED) != 0;
-*/
- return FALSE;
-}
+ if (!pAttr)
+ {
+ return wxNullFont;
+ }
+ return pAttr->GetFont();
+} // end of wxTreeCtrl::GetItemFont
-bool wxTreeCtrl::IsBold(const wxTreeItemId& item) const
+void wxTreeCtrl::SetItemTextColour (
+ const wxTreeItemId& rItem
+, const wxColour& rCol
+)
{
-// TODO:
-/*
- wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_BOLD);
- DoGetItem(&tvItem);
+ m_bHasAnyAttr = TRUE;
- return (tvItem.state & TVIS_BOLD) != 0;
-*/
- return FALSE;
-}
+ long lId = (long)rItem.m_pItem;
+ wxTreeItemAttr* pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
-// ----------------------------------------------------------------------------
-// navigation
-// ----------------------------------------------------------------------------
+ if (!pAttr)
+ {
+ pAttr = new wxTreeItemAttr;
+ m_vAttrs.Put(lId, (wxObject *)pAttr);
+ }
+ pAttr->SetTextColour(rCol);
+ RefreshItem(rItem);
+} // end of wxTreeCtrl::SetItemTextColour
-wxTreeItemId wxTreeCtrl::GetRootItem() const
+void wxTreeCtrl::SetItemBackgroundColour (
+ const wxTreeItemId& rItem
+, const wxColour& rCol
+)
{
-// return wxTreeItemId((WXHTREEITEM) TreeView_GetRoot(GetHwnd()));
- return 0;
-}
+ m_bHasAnyAttr = TRUE;
-wxTreeItemId wxTreeCtrl::GetSelection() const
-{
- wxCHECK_MSG( !(m_windowStyle & wxTR_MULTIPLE), (WXHTREEITEM)0,
- wxT("this only works with single selection controls") );
+ long lId = (long)rItem.m_pItem;
+ wxTreeItemAttr* pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
-// return wxTreeItemId((WXHTREEITEM) TreeView_GetSelection(GetHwnd()));
- return 0;
-}
+ if (!pAttr)
+ {
+ pAttr = new wxTreeItemAttr;
+ m_vAttrs.Put(lId, (wxObject *)pAttr);
+ }
+ pAttr->SetBackgroundColour(rCol);
+ RefreshItem(rItem);
+} // end of wxTreeCtrl::SetItemBackgroundColour
-wxTreeItemId wxTreeCtrl::GetParent(const wxTreeItemId& item) const
+void wxTreeCtrl::SetItemFont (
+ const wxTreeItemId& rItem
+, const wxFont& rFont
+)
{
-// return wxTreeItemId((WXHTREEITEM) TreeView_GetParent(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item));
- return 0;
-}
+ m_bHasAnyAttr = TRUE;
-wxTreeItemId wxTreeCtrl::GetFirstChild(const wxTreeItemId& item,
- long& _cookie) const
-{
-// TODO:
-/*
- // remember the last child returned in 'cookie'
- _cookie = (long)TreeView_GetChild(GetHwnd(), (HTREEITEM) (WXHTREEITEM)item);
+ long lId = (long)rItem.m_pItem;
+ wxTreeItemAttr* pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
- return wxTreeItemId((WXHTREEITEM)_cookie);
-*/
- return 0;
-}
+ if (!pAttr)
+ {
+ pAttr = new wxTreeItemAttr;
+ m_vAttrs.Put(lId, (wxObject *)pAttr);
+ }
+ pAttr->SetFont(rFont);
+ RefreshItem(rItem);
+} // end of wxTreeCtrl::SetItemFont
+
+// ----------------------------------------------------------------------------
+// Item status
+// ----------------------------------------------------------------------------
-wxTreeItemId wxTreeCtrl::GetNextChild(const wxTreeItemId& WXUNUSED(item),
- long& _cookie) const
+bool wxTreeCtrl::IsVisible (
+ const wxTreeItemId& rItem
+) const
{
- wxTreeItemId l = 0; //wxTreeItemId((WXHTREEITEM)TreeView_GetNextSibling(GetHwnd(),
-// (HTREEITEM)(WXHTREEITEM)_cookie));
- _cookie = (long)l;
+ // Bug in Gnu-Win32 headers, so don't use the macro TreeView_GetItemRect
+ RECTL vRectRecord;
+ RECTL vRectContainer;
+ wxRect vWxRectRecord;
+ wxRect vWxRectContainer;
+ PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
+ ,rItem.m_pItem
+ );
+ QUERYRECORDRECT vQuery;
+
+ vQuery.cb = sizeof(QUERYRECORDRECT);
+ vQuery.pRecord = (PRECORDCORE)pRecord;
+ vQuery.fRightSplitWindow = FALSE;
+ vQuery.fsExtent = CMA_TREEICON;
+
+ ::WinSendMsg( GetHWND()
+ ,CM_QUERYVIEWPORTRECT
+ ,MPFROMP(&vRectContainer)
+ ,MPFROM2SHORT(CMA_WINDOW, FALSE)
+ );
+ ::WinSendMsg( GetHWND()
+ ,CM_QUERYRECORDRECT
+ ,MPFROMP(&vRectRecord)
+ ,MPFROMP(&vQuery)
+ );
+ vWxRectRecord.SetLeft(vRectRecord.xLeft);
+ vWxRectRecord.SetTop(vRectRecord.yTop);
+ vWxRectRecord.SetRight(vRectRecord.xRight);
+ vWxRectRecord.SetBottom(vRectRecord.yBottom);
+
+ vWxRectContainer.SetLeft(vRectContainer.xLeft);
+ vWxRectContainer.SetTop(vRectContainer.yTop);
+ vWxRectContainer.SetRight(vRectContainer.xRight);
+ vWxRectContainer.SetBottom(vRectContainer.yBottom);
+ return (vWxRectContainer.Inside(wxPoint(vWxRectRecord.x, vWxRectRecord.y)));
+} // end of wxTreeCtrl::IsVisible
+
+bool wxTreeCtrl::ItemHasChildren (
+ const wxTreeItemId& rItem
+) const
+{
+ wxTreeViewItem vTvItem(rItem);
+ DoGetItem(&vTvItem);
+
+ //
+ // A tree record with children will have one of these attributes
+ //
+ return (vTvItem.m_vRecord.flRecordAttr & CRA_EXPANDED ||
+ vTvItem.m_vRecord.flRecordAttr & CRA_COLLAPSED) != 0;
+}
+
+bool wxTreeCtrl::IsExpanded (
+ const wxTreeItemId& rItem
+) const
+{
+ wxTreeViewItem vTvItem(rItem);
+ DoGetItem(&vTvItem);
+
+ return (vTvItem.m_vRecord.flRecordAttr & CRA_EXPANDED) != 0;
+} // end of wxTreeCtrl::IsExpanded
+
+bool wxTreeCtrl::IsSelected (
+ const wxTreeItemId& rItem
+) const
+{
+ wxTreeViewItem vTvItem(rItem);
+ DoGetItem(&vTvItem);
+
+ return (vTvItem.m_vRecord.flRecordAttr & CRA_SELECTED) != 0;
+} // end of wxTreeCtrl::IsSelected
+
+// Not supported
+bool wxTreeCtrl::IsBold (
+ const wxTreeItemId& rItem
+) const
+{
+ return FALSE;
+} // end of wxTreeCtrl::IsBold
- return l;
-}
+// ----------------------------------------------------------------------------
+// navigation
+// ----------------------------------------------------------------------------
-wxTreeItemId wxTreeCtrl::GetLastChild(const wxTreeItemId& item) const
+wxTreeItemId wxTreeCtrl::GetRootItem () const
{
- // can this be done more efficiently?
- long cookie;
+ PMYRECORD pRecord = NULL;
- wxTreeItemId childLast,
- child = GetFirstChild(item, cookie);
- while ( child.IsOk() )
- {
- childLast = child;
- child = GetNextChild(item, cookie);
- }
+ pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+ ,CM_QUERYRECORD
+ ,MPFROMP(pRecord)
+ ,MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)
+ ));
- return childLast;
-}
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ return wxTreeItemId((long)pRecord->m_ulItemId);
+} // end of wxTreeCtrl::GetRootItem
-wxTreeItemId wxTreeCtrl::GetNextSibling(const wxTreeItemId& item) const
+wxTreeItemId wxTreeCtrl::GetSelection () const
{
-// return wxTreeItemId((WXHTREEITEM) TreeView_GetNextSibling(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item));
- return 0;
-}
+ wxCHECK_MSG( !(m_windowStyle & wxTR_MULTIPLE), (long)(WXHTREEITEM)0,
+ wxT("this only works with single selection controls") );
-wxTreeItemId wxTreeCtrl::GetPrevSibling(const wxTreeItemId& item) const
-{
-// return wxTreeItemId((WXHTREEITEM) TreeView_GetPrevSibling(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item));
- return 0;
-}
+ PMYRECORD pRecord = NULL;
+
+ pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+ ,CM_QUERYRECORDEMPHASIS
+ ,MPARAM(CMA_FIRST)
+ ,MPARAM(CRA_SELECTED)
+ ));
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ return wxTreeItemId((long)pRecord->m_ulItemId);
+} // end of wxTreeCtrl::GetSelection
+
+wxTreeItemId wxTreeCtrl::GetItemParent (
+ const wxTreeItemId& rItem
+) const
+{
+ PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
+ ,rItem.m_pItem
+ );
+
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+ ,CM_QUERYRECORD
+ ,MPFROMP(pRecord)
+ ,MPFROM2SHORT(CMA_PARENT, CMA_ITEMORDER)
+ ));
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ return wxTreeItemId((long)pRecord->m_ulItemId);
+} // end of wxTreeCtrl::GetItemParent
+
+wxTreeItemId wxTreeCtrl::GetFirstChild (
+ const wxTreeItemId& rItem
+, long& rCookie
+) const
+{
+ PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
+ ,rItem.m_pItem
+ );
+
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+ ,CM_QUERYRECORD
+ ,MPFROMP(pRecord)
+ ,MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER)
+ ));
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ //
+ // Remember the last child returned in 'cookie'
+ //
+ rCookie = (long)pRecord->m_ulItemId;
+ return wxTreeItemId(rCookie);
+} // end of wxTreeCtrl::GetFirstChild
+
+wxTreeItemId wxTreeCtrl::GetNextChild (
+ const wxTreeItemId& WXUNUSED(rItem)
+, long& rCookie
+) const
+{
+ PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
+ ,rCookie
+ );
+
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+ ,CM_QUERYRECORD
+ ,MPFROMP(pRecord)
+ ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
+ ));
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ rCookie = (long)pRecord->m_ulItemId;
+ return wxTreeItemId(rCookie);
+} // end of wxTreeCtrl::GetNextChild
+
+wxTreeItemId wxTreeCtrl::GetLastChild (
+ const wxTreeItemId& rItem
+) const
+{
+ PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
+ ,rItem.m_pItem
+ );
+
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+ ,CM_QUERYRECORD
+ ,MPFROMP(pRecord)
+ ,MPFROM2SHORT(CMA_LASTCHILD, CMA_ITEMORDER)
+ ));
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ return wxTreeItemId((long)pRecord->m_ulItemId);
+} // end of wxTreeCtrl::GetLastChild
+
+wxTreeItemId wxTreeCtrl::GetNextSibling (
+ const wxTreeItemId& rItem
+) const
+{
+ PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
+ ,rItem.m_pItem
+ );
+
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+ ,CM_QUERYRECORD
+ ,MPFROMP(pRecord)
+ ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
+ ));
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ return wxTreeItemId((long)pRecord->m_ulItemId);
+} // end of wxTreeCtrl::GetNextSibling
+
+wxTreeItemId wxTreeCtrl::GetPrevSibling (
+ const wxTreeItemId& rItem
+) const
+{
+ PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
+ ,rItem.m_pItem
+ );
+
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+ ,CM_QUERYRECORD
+ ,MPFROMP(pRecord)
+ ,MPFROM2SHORT(CMA_PREV, CMA_ITEMORDER)
+ ));
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ return wxTreeItemId((long)pRecord->m_ulItemId);
+} // end of wxTreeCtrl::GetPrevSibling
+
+wxTreeItemId wxTreeCtrl::GetFirstVisibleItem () const
+{
+ PMYRECORD pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+ ,CM_QUERYRECORD
+ ,MPFROMP(pRecord)
+ ,MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)
+ ));
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+
+ if (IsVisible(wxTreeItemId((long)pRecord->m_ulItemId)))
+ return wxTreeItemId((long)pRecord->m_ulItemId);
+ while(pRecord)
+ {
+ pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+ ,CM_QUERYRECORD
+ ,MPFROMP(pRecord)
+ ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
+ ));
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ if (IsVisible(wxTreeItemId((long)pRecord->m_ulItemId)))
+ return wxTreeItemId((long)pRecord->m_ulItemId);
+ }
+ return wxTreeItemId(-1L);
+} // end of wxTreeCtrl::GetFirstVisibleItem
-wxTreeItemId wxTreeCtrl::GetFirstVisibleItem() const
+wxTreeItemId wxTreeCtrl::GetNextVisible (
+ const wxTreeItemId& rItem
+) const
{
-// return wxTreeItemId((WXHTREEITEM) TreeView_GetFirstVisible(GetHwnd()));
- return 0;
-}
+ wxASSERT_MSG(IsVisible(rItem), wxT("The item you call GetNextVisible() for must be visible itself!"));
-wxTreeItemId wxTreeCtrl::GetNextVisible(const wxTreeItemId& item) const
-{
- wxASSERT_MSG( IsVisible(item), wxT("The item you call GetNextVisible() "
- "for must be visible itself!"));
+ PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
+ ,rItem.m_pItem
+ );
-// return wxTreeItemId((WXHTREEITEM) TreeView_GetNextVisible(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item));
- return 0;
-}
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ while(pRecord)
+ {
+ pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+ ,CM_QUERYRECORD
+ ,MPFROMP(pRecord)
+ ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
+ ));
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ if (IsVisible(wxTreeItemId((long)pRecord->m_ulItemId)))
+ return wxTreeItemId((long)pRecord->m_ulItemId);
+ }
+ return wxTreeItemId(-1L);
+} // end of wxTreeCtrl::GetNextVisible
-wxTreeItemId wxTreeCtrl::GetPrevVisible(const wxTreeItemId& item) const
+wxTreeItemId wxTreeCtrl::GetPrevVisible (
+ const wxTreeItemId& rItem
+) const
{
- wxASSERT_MSG( IsVisible(item), wxT("The item you call GetPrevVisible() "
- "for must be visible itself!"));
+ wxASSERT_MSG( IsVisible(rItem), wxT("The item you call GetPrevVisible() for must be visible itself!"));
-// return wxTreeItemId((WXHTREEITEM) TreeView_GetPrevVisible(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item));
- return 0;
-}
+ PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
+ ,rItem.m_pItem
+ );
+
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ while(pRecord)
+ {
+ pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+ ,CM_QUERYRECORD
+ ,MPFROMP(pRecord)
+ ,MPFROM2SHORT(CMA_PREV, CMA_ITEMORDER)
+ ));
+ if (!pRecord)
+ return wxTreeItemId(-1L);
+ if (IsVisible(wxTreeItemId((long)pRecord->m_ulItemId)))
+ return wxTreeItemId((long)pRecord->m_ulItemId);
+ }
+ return wxTreeItemId(-1L);
+} // end of wxTreeCtrl::GetPrevVisible
// ----------------------------------------------------------------------------
-// multiple selections emulation
+// multiple selections emulation -- under OS/2 checked tree items is not
+// supported, but multisel is. So we'll just check for selections here.
// ----------------------------------------------------------------------------
-bool wxTreeCtrl::IsItemChecked(const wxTreeItemId& item) const
+bool wxTreeCtrl::IsItemChecked (
+ const wxTreeItemId& rItem
+) const
{
- // receive the desired information.
-// TODO:
-/*
- wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_STATEIMAGEMASK);
- DoGetItem(&tvItem);
+ wxTreeViewItem vTvItem(rItem);
- // state image indices are 1 based
- return ((tvItem.state >> 12) - 1) == 1;
-*/
- return FALSE;
-}
+ DoGetItem(&vTvItem);
+ return (vTvItem.m_vRecord.flRecordAttr & CRA_SELECTED);
+} // end of wxTreeCtrl::IsItemChecked
-void wxTreeCtrl::SetItemCheck(const wxTreeItemId& item, bool check)
+void wxTreeCtrl::SetItemCheck (
+ const wxTreeItemId& rItem
+, bool bCheck
+)
{
- // receive the desired information.
-// TODO:
-/*
- wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_STATEIMAGEMASK);
+ wxTreeViewItem vTvItem(rItem);
- // state images are one-based
- tvItem.state = (check ? 2 : 1) << 12;
+ DoGetItem(&vTvItem);
+ ::WinSendMsg( GetHWND()
+ ,CM_SETRECORDEMPHASIS
+ ,MPFROMP(&vTvItem)
+ ,MPFROM2SHORT(TRUE, CRA_SELECTED)
+ );
+ DoSetItem(&vTvItem);
+} // end of wxTreeCtrl::SetItemCheck
- DoSetItem(&tvItem);
-*/
-}
-
-size_t wxTreeCtrl::GetSelections(wxArrayTreeItemIds& selections) const
+size_t wxTreeCtrl::GetSelections (
+ wxArrayTreeItemIds& raSelections
+) const
{
- TraverseSelections selector(this, selections);
-
- return selections.GetCount();
-}
+ TraverseSelections vSelector( this
+ ,raSelections
+ );
+ return vSelector.GetCount();
+} // end of wxTreeCtrl::GetSelections
// ----------------------------------------------------------------------------
// Usual operations
// ----------------------------------------------------------------------------
-wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent,
- wxTreeItemId hInsertAfter,
- const wxString& text,
- int image, int selectedImage,
- wxTreeItemData *data)
-{
-// TODO:
-/*
- TV_INSERTSTRUCT tvIns;
- tvIns.hParent = (HTREEITEM) (WXHTREEITEM)parent;
- tvIns.hInsertAfter = (HTREEITEM) (WXHTREEITEM) hInsertAfter;
-
- // this is how we insert the item as the first child: supply a NULL
- // hInsertAfter
- if ( !tvIns.hInsertAfter )
- {
- tvIns.hInsertAfter = TVI_FIRST;
- }
-
- UINT mask = 0;
- if ( !text.IsEmpty() )
- {
- mask |= TVIF_TEXT;
- tvIns.item.pszText = (wxChar *)text.c_str(); // cast is ok
- }
-
- if ( image != -1 )
+wxTreeItemId wxTreeCtrl::DoInsertItem (
+ const wxTreeItemId& rParent
+, wxTreeItemId vInsertAfter
+, const wxString& rsText
+, int nImage
+, int selectedImage
+, wxTreeItemData* pData
+)
+{
+ PMYRECORD pRecordAfter = FindOS2TreeRecordByID( GetHWND()
+ ,vInsertAfter.m_pItem
+ );
+
+ PMYRECORD pRecordParent = FindOS2TreeRecordByID( GetHWND()
+ ,rParent.m_pItem
+ );
+
+ PMYRECORD pRecord = (PMYRECORD)::WinSendMsg( GetHWND()
+ ,CM_ALLOCRECORD
+ ,MPFROMLONG(sizeof(MYRECORD) - sizeof(RECORDCORE))
+ ,MPFROMLONG(1)
+ );
+ RECORDINSERT vInsert;
+
+ vInsert.cb = sizeof(RECORDINSERT);
+ if (rParent.m_pItem == 0L)
{
- mask |= TVIF_IMAGE;
- tvIns.item.iImage = image;
-
- if ( selectedImage == -1 )
- {
- // take the same image for selected icon if not specified
- selectedImage = image;
- }
- }
-
- if ( selectedImage != -1 )
- {
- mask |= TVIF_SELECTEDIMAGE;
- tvIns.item.iSelectedImage = selectedImage;
+ if (vInsertAfter.m_pItem == -1)
+ vInsert.pRecordOrder = (PRECORDCORE)CMA_END;
+ else
+ vInsert.pRecordOrder = (PRECORDCORE)CMA_FIRST;
+ vInsert.pRecordParent = NULL;
}
-
- if ( data != NULL )
+ else
{
- mask |= TVIF_PARAM;
- tvIns.item.lParam = (LPARAM)data;
+ if (vInsertAfter.m_pItem == 0)
+ vInsert.pRecordOrder = (PRECORDCORE)CMA_FIRST;
+ else if (vInsertAfter.m_pItem == -1)
+ vInsert.pRecordOrder = (PRECORDCORE)CMA_END;
+ else
+ vInsert.pRecordOrder = (PRECORDCORE)pRecordAfter;
+ vInsert.pRecordParent = (PRECORDCORE)pRecordParent;
}
-
- tvIns.item.mask = mask;
-
- HTREEITEM id = (HTREEITEM) TreeView_InsertItem(GetHwnd(), &tvIns);
- if ( id == 0 )
+ vInsert.fInvalidateRecord = TRUE;
+ vInsert.zOrder = CMA_TOP;
+ vInsert.cRecordsInsert = 1;
+
+ pRecord->m_vRecord.pszTree = (wxChar*)rsText.c_str();
+ pRecord->m_vRecord.hbmBitmap = nImage;
+ pRecord->m_ulItemId = pRecordAfter->m_ulItemId + 1;
+ if (pData != NULL)
{
- wxLogLastError("TreeView_InsertItem");
+ pRecord->m_ulUserData = (ULONG)pData;
}
-
- if ( data != NULL )
+ ::WinSendMsg( GetHWND()
+ ,CM_INSERTRECORD
+ ,MPFROMP(pRecord)
+ ,MPFROMP(&vInsert)
+ );
+
+ //
+ // OS/2 must mannually bump the index's of following records
+ //
+ BumpTreeRecordIds( GetHWND()
+ ,pRecord
+ );
+ if (pData != NULL)
{
- // associate the application tree item with Win32 tree item handle
- data->SetId((WXHTREEITEM)id);
+ //
+ // Associate the application tree item with PM tree item handle
+ //
+ pData->SetId((long)pRecord->m_ulItemId);
}
-
- return wxTreeItemId((WXHTREEITEM)id);
-*/
- return 0;
+ return wxTreeItemId((long)pRecord->m_ulItemId);
}
// for compatibility only
-wxTreeItemId wxTreeCtrl::InsertItem(const wxTreeItemId& parent,
- const wxString& text,
- int image, int selImage,
- long insertAfter)
-{
- return DoInsertItem(parent, (WXHTREEITEM)insertAfter, text,
- image, selImage, NULL);
-}
-
-wxTreeItemId wxTreeCtrl::AddRoot(const wxString& text,
- int image, int selectedImage,
- wxTreeItemData *data)
-{
- return DoInsertItem(wxTreeItemId((WXHTREEITEM) 0), (WXHTREEITEM) 0,
- text, image, selectedImage, data);
-}
-
-wxTreeItemId wxTreeCtrl::PrependItem(const wxTreeItemId& parent,
- const wxString& text,
- int image, int selectedImage,
- wxTreeItemData *data)
-{
-// TODO:
-/*
- return DoInsertItem(parent, (WXHTREEITEM) TVI_FIRST,
- text, image, selectedImage, data);
-*/
- return 0;
-}
-
-wxTreeItemId wxTreeCtrl::InsertItem(const wxTreeItemId& parent,
- const wxTreeItemId& idPrevious,
- const wxString& text,
- int image, int selectedImage,
- wxTreeItemData *data)
-{
- return DoInsertItem(parent, idPrevious, text, image, selectedImage, data);
-}
-
-wxTreeItemId wxTreeCtrl::AppendItem(const wxTreeItemId& parent,
- const wxString& text,
- int image, int selectedImage,
- wxTreeItemData *data)
-{
-// TODO:
-/*
- return DoInsertItem(parent, (WXHTREEITEM) TVI_LAST,
- text, image, selectedImage, data);
-*/
- return 0;
-}
-
-void wxTreeCtrl::Delete(const wxTreeItemId& item)
-{
-// TODO:
-/*
- if ( !TreeView_DeleteItem(GetHwnd(), (HTREEITEM)(WXHTREEITEM)item) )
+wxTreeItemId wxTreeCtrl::InsertItem (
+ const wxTreeItemId& rParent
+, const wxString& rsText
+, int nImage
+, int nSelImage
+, long lInsertAfter
+)
+{
+ return DoInsertItem( rParent
+ ,wxTreeItemId(lInsertAfter)
+ ,rsText
+ ,nImage
+ ,nSelImage
+ ,NULL
+ );
+} // end of wxTreeCtrl::InsertItem
+
+wxTreeItemId wxTreeCtrl::AddRoot (
+ const wxString& rsText
+, int nImage
+, int nSelectedImage
+, wxTreeItemData* pData)
+{
+
+ return DoInsertItem( wxTreeItemId((long)0)
+ ,wxTreeItemId((long)-1)
+ ,rsText
+ ,nImage
+ ,nSelectedImage
+ ,pData
+ );
+} // end of wxTreeCtrl::AddRoot
+
+wxTreeItemId wxTreeCtrl::PrependItem (
+ const wxTreeItemId& rParent
+, const wxString& rsText
+, int nImage
+, int nSelectedImage
+, wxTreeItemData* pData
+)
+{
+ return DoInsertItem( rParent
+ ,wxTreeItemId((long)0)
+ ,rsText
+ ,nImage
+ ,nSelectedImage
+ ,pData
+ );
+} // end of wxTreeCtrl::PrependItem
+
+wxTreeItemId wxTreeCtrl::InsertItem (
+ const wxTreeItemId& rParent
+, const wxTreeItemId& rIdPrevious
+, const wxString& rsText
+, int nImage
+, int nSelectedImage
+, wxTreeItemData* pData
+)
+{
+ return DoInsertItem( rParent
+ ,rIdPrevious
+ ,rsText
+ ,nImage
+ ,nSelectedImage
+ ,pData
+ );
+} // end of wxTreeCtrl::InsertItem
+
+wxTreeItemId wxTreeCtrl::InsertItem (
+ const wxTreeItemId& rParent
+, size_t nIndex
+, const wxString& rsText
+, int nImage
+, int nSelectedImage
+, wxTreeItemData* pData
+)
+{
+ return DoInsertItem( rParent
+ ,wxTreeItemId((long)nIndex)
+ ,rsText
+ ,nImage
+ ,nSelectedImage
+ ,pData
+ );
+} // end of wxTreeCtrl::InsertItem
+
+wxTreeItemId wxTreeCtrl::AppendItem (
+ const wxTreeItemId& rParent
+, const wxString& rsText
+, int nImage
+, int nSelectedImage
+, wxTreeItemData* pData
+)
+{
+ return DoInsertItem( rParent
+ ,wxTreeItemId((long)-1)
+ ,rsText
+ ,nImage
+ ,nSelectedImage
+ ,pData
+ );
+} // end of wxTreeCtrl::AppendItem
+
+void wxTreeCtrl::Delete (
+ const wxTreeItemId& rItem
+)
+{
+ //
+ // OS/2 does not generate DELETEITEM events so do it here
+ //
+ wxEventType vEventType = wxEVT_NULL;
+ wxTreeEvent vEvent( wxEVT_NULL
+ ,m_windowId
+ );
+ PMYRECORD pRecord = FindOS2TreeRecordByID( GetHWND()
+ ,rItem.m_pItem
+ );
+ vEvent.SetEventObject(this);
+ ::WinSendMsg( GetHWND()
+ ,CM_REMOVERECORD
+ ,MPFROMP(pRecord)
+ ,(MPARAM)(CMA_FREE | CMA_INVALIDATE)
+ );
+ vEvent.m_item = rItem.m_pItem;
+ if (m_bHasAnyAttr)
{
- wxLogLastError("TreeView_DeleteItem");
+ delete (wxTreeItemAttr *)m_vAttrs.Delete((long)rItem.m_pItem);
}
-*/
-}
+ vEvent.SetEventType(vEventType);
+ GetEventHandler()->ProcessEvent(vEvent);
+} // end of wxTreeCtrl::Delete
// delete all children (but don't delete the item itself)
-void wxTreeCtrl::DeleteChildren(const wxTreeItemId& item)
+void wxTreeCtrl::DeleteChildren (
+ const wxTreeItemId& rItem
+)
{
- long cookie;
+ long lCookie;
+ wxArrayLong aChildren;
+ wxTreeItemId vChild = GetFirstChild( rItem
+ ,lCookie
+ );
- wxArrayLong children;
- wxTreeItemId child = GetFirstChild(item, cookie);
- while ( child.IsOk() )
+ while (vChild.IsOk())
{
- children.Add((long)(WXHTREEITEM)child);
-
- child = GetNextChild(item, cookie);
+ aChildren.Add((long)(WXHTREEITEM)vChild);
+ vChild = GetNextChild( rItem
+ ,lCookie
+ );
}
- size_t nCount = children.Count();
-// TODO:
-/*
- for ( size_t n = 0; n < nCount; n++ )
- {
- if ( !TreeView_DeleteItem(GetHwnd(), (HTREEITEM)children[n]) )
- {
- wxLogLastError("TreeView_DeleteItem");
- }
- }
-*/
-}
+ size_t nCount = aChildren.Count();
-void wxTreeCtrl::DeleteAllItems()
-{
-// TODO:
-/*
- if ( !TreeView_DeleteAllItems(GetHwnd()) )
+ for (size_t n = 0; n < nCount; n++)
{
- wxLogLastError("TreeView_DeleteAllItems");
+ Delete(aChildren[n]);
}
-*/
-}
-
-void wxTreeCtrl::DoExpand(const wxTreeItemId& item, int flag)
-{
-// TODO:
-/*
- wxASSERT_MSG( flag == TVE_COLLAPSE ||
- flag == (TVE_COLLAPSE | TVE_COLLAPSERESET) ||
- flag == TVE_EXPAND ||
- flag == TVE_TOGGLE,
- wxT("Unknown flag in wxTreeCtrl::DoExpand") );
-
- // TreeView_Expand doesn't send TVN_ITEMEXPAND(ING) messages, so we must
- // emulate them. This behaviour has changed slightly with comctl32.dll
- // v 4.70 - now it does send them but only the first time. To maintain
- // compatible behaviour and also in order to not have surprises with the
- // future versions, don't rely on this and still do everything ourselves.
- // To avoid that the messages be sent twice when the item is expanded for
- // the first time we must clear TVIS_EXPANDEDONCE style manually.
-
- wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_EXPANDEDONCE);
- tvItem.state = 0;
- DoSetItem(&tvItem);
-
- if ( TreeView_Expand(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item, flag) != 0 )
+} // end of wxTreeCtrl::DeleteChildren
+
+void wxTreeCtrl::DeleteAllItems ()
+{
+ ::WinSendMsg( GetHWND()
+ ,CM_REMOVERECORD
+ ,NULL // Remove all
+ ,(MPARAM)(CMA_FREE | CMA_INVALIDATE)
+ );
+} // end of wxTreeCtrl::DeleteAllItems
+
+void wxTreeCtrl::DoExpand (
+ const wxTreeItemId& rItem
+, int nFlag
+)
+{
+ PMYRECORD pRecord = FindOS2TreeRecordByID( GetHWND()
+ ,rItem.m_pItem
+ );
+ switch(nFlag)
{
- wxTreeEvent event(wxEVT_NULL, m_windowId);
- event.m_item = item;
+ case wxTREE_EXPAND_EXPAND:
+ ::WinSendMsg( GetHWND()
+ ,CM_EXPANDTREE
+ ,MPFROMP(pRecord)
+ ,NULL
+ );
+ break;
- bool isExpanded = IsExpanded(item);
+ case wxTREE_EXPAND_COLLAPSE:
+ ::WinSendMsg( GetHWND()
+ ,CM_COLLAPSETREE
+ ,MPFROMP(pRecord)
+ ,NULL
+ );
+ break;
- event.SetEventObject(this);
+ case wxTREE_EXPAND_COLLAPSE_RESET:
+ ::WinSendMsg( GetHWND()
+ ,CM_COLLAPSETREE
+ ,MPFROMP(pRecord)
+ ,NULL
+ );
+ DeleteChildren(rItem);
+ break;
- // FIXME return value of {EXPAND|COLLAPS}ING event handler is discarded
- event.SetEventType(g_events[isExpanded][TRUE]);
- GetEventHandler()->ProcessEvent(event);
+ case wxTREE_EXPAND_TOGGLE:
+ if (pRecord->m_vRecord.flRecordAttr & CRA_COLLAPSED)
+ ::WinSendMsg( GetHWND()
+ ,CM_EXPANDTREE
+ ,MPFROMP(pRecord)
+ ,NULL
+ );
+ else if (pRecord->m_vRecord.flRecordAttr & CRA_EXPANDED)
+ ::WinSendMsg( GetHWND()
+ ,CM_COLLAPSETREE
+ ,MPFROMP(pRecord)
+ ,NULL
+ );
+ break;
- event.SetEventType(g_events[isExpanded][FALSE]);
- GetEventHandler()->ProcessEvent(event);
}
- //else: change didn't took place, so do nothing at all
-*/
-}
+} // end of wxTreeCtrl::DoExpand
-void wxTreeCtrl::Expand(const wxTreeItemId& item)
+void wxTreeCtrl::Expand (
+ const wxTreeItemId& rItem
+)
{
-// DoExpand(item, TVE_EXPAND);
-}
+ DoExpand( rItem
+ ,wxTREE_EXPAND_EXPAND
+ );
+} // end of wxTreeCtrl::Expand
-void wxTreeCtrl::Collapse(const wxTreeItemId& item)
+void wxTreeCtrl::Collapse (
+ const wxTreeItemId& rItem
+)
{
-// DoExpand(item, TVE_COLLAPSE);
-}
+ DoExpand( rItem
+ ,wxTREE_EXPAND_COLLAPSE
+ );
+} // end of wxTreeCtrl::Collapse
-void wxTreeCtrl::CollapseAndReset(const wxTreeItemId& item)
+void wxTreeCtrl::CollapseAndReset (
+ const wxTreeItemId& rItem
+)
{
-// DoExpand(item, TVE_COLLAPSE | TVE_COLLAPSERESET);
-}
+ DoExpand( rItem
+ ,wxTREE_EXPAND_COLLAPSE_RESET
+ );
+} // end of wxTreeCtrl::CollapseAndReset
-void wxTreeCtrl::Toggle(const wxTreeItemId& item)
+void wxTreeCtrl::Toggle (
+ const wxTreeItemId& rItem
+)
{
-// DoExpand(item, TVE_TOGGLE);
-}
+ DoExpand( rItem
+ ,wxTREE_EXPAND_TOGGLE
+ );
+} // end of wxTreeCtrl::Toggle
-void wxTreeCtrl::ExpandItem(const wxTreeItemId& item, int action)
+void wxTreeCtrl::ExpandItem (
+ const wxTreeItemId& rItem
+, int nAction
+)
{
-// DoExpand(item, action);
-}
+ DoExpand( rItem
+ ,nAction
+ );
+} // end of wxTreeCtrl::ExpandItem
-void wxTreeCtrl::Unselect()
+void wxTreeCtrl::Unselect ()
{
- wxASSERT_MSG( !(m_windowStyle & wxTR_MULTIPLE), wxT("doesn't make sense") );
+ wxASSERT_MSG( !(m_windowStyle & wxTR_MULTIPLE),
+ wxT("doesn't make sense, may be you want UnselectAll()?") );
- // just remove the selection
-// SelectItem(wxTreeItemId((WXHTREEITEM) 0));
-}
+ //
+ // Just remove the selection
+ //
+ SelectItem(wxTreeItemId((long)0));
+} // end of wxTreeCtrl::Unselect
-void wxTreeCtrl::UnselectAll()
+void wxTreeCtrl::UnselectAll ()
{
- if ( m_windowStyle & wxTR_MULTIPLE )
+ if (m_windowStyle & wxTR_MULTIPLE)
{
- wxArrayTreeItemIds selections;
- size_t count = GetSelections(selections);
- for ( size_t n = 0; n < count; n++ )
+ wxArrayTreeItemIds aSelections;
+ size_t nCount = GetSelections(aSelections);
+
+ for (size_t n = 0; n < nCount; n++)
{
- SetItemCheck(selections[n], FALSE);
+ SetItemCheck( aSelections[n]
+ ,FALSE
+ );
}
}
else
{
- // just remove the selection
+ //
+ // Just remove the selection
+ //
Unselect();
}
-}
-
-void wxTreeCtrl::SelectItem(const wxTreeItemId& item)
-{
- if ( m_windowStyle & wxTR_MULTIPLE )
- {
- // selecting the item means checking it
- SetItemCheck(item);
- }
- else
- {
- // inspite of the docs (MSDN Jan 99 edition), we don't seem to receive
- // the notification from the control (i.e. TVN_SELCHANG{ED|ING}), so
- // send them ourselves
-
- wxTreeEvent event(wxEVT_NULL, m_windowId);
- event.m_item = item;
- event.SetEventObject(this);
-
- event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGING);
-// TODO:
-/*
- if ( !GetEventHandler()->ProcessEvent(event) || event.IsAllowed() )
- {
- if ( !TreeView_SelectItem(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item) )
- {
- wxLogLastError("TreeView_SelectItem");
- }
- else
- {
- event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGED);
- (void)GetEventHandler()->ProcessEvent(event);
- }
- }
- //else: program vetoed the change
-*/
- }
-}
-
-void wxTreeCtrl::EnsureVisible(const wxTreeItemId& item)
-{
- // no error return
-// TreeView_EnsureVisible(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item);
-}
-
-void wxTreeCtrl::ScrollTo(const wxTreeItemId& item)
-{
-// TODO:
-/*
- if ( !TreeView_SelectSetFirstVisible(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item) )
- {
- wxLogLastError("TreeView_SelectSetFirstVisible");
- }
-*/
-}
-
-wxTextCtrl* wxTreeCtrl::GetEditControl() const
-{
- return m_textCtrl;
-}
-
-void wxTreeCtrl::DeleteTextCtrl()
-{
- if ( m_textCtrl )
- {
- m_textCtrl->UnsubclassWin();
- m_textCtrl->SetHWND(0);
- delete m_textCtrl;
- m_textCtrl = NULL;
- }
-}
-
-wxTextCtrl* wxTreeCtrl::EditLabel(const wxTreeItemId& item,
- wxClassInfo* textControlClass)
-{
- wxASSERT( textControlClass->IsKindOf(CLASSINFO(wxTextCtrl)) );
-
-// TODO:
-/*
- HWND hWnd = (HWND) TreeView_EditLabel(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item);
-
- // this is not an error - the TVN_BEGINLABELEDIT handler might have
- // returned FALSE
- if ( !hWnd )
- {
- return NULL;
- }
-
- DeleteTextCtrl();
-
- m_textCtrl = (wxTextCtrl *)textControlClass->CreateObject();
- m_textCtrl->SetHWND((WXHWND)hWnd);
- m_textCtrl->SubclassWin((WXHWND)hWnd);
-*/
- return m_textCtrl;
-}
+} // end of wxTreeCtrl::UnselectAll
+
+void wxTreeCtrl::SelectItem (
+ const wxTreeItemId& rItem
+)
+{
+ SetItemCheck(rItem);
+} // end of wxTreeCtrl::SelectItem
+
+void wxTreeCtrl::EnsureVisible (
+ const wxTreeItemId& rItem
+)
+{
+ wxTreeViewItem vTvItem(rItem);
+
+ DoGetItem(&vTvItem);
+ if (!::WinSendMsg( GetHWND()
+ ,CM_INVALIDATERECORD
+ ,MPFROMP(&vTvItem)
+ ,MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION | CMA_TEXTCHANGED)
+ ));
+} // end of wxTreeCtrl::EnsureVisible
+
+void wxTreeCtrl::ScrollTo (
+ const wxTreeItemId& rItem
+)
+{
+ wxTreeViewItem vTvItem(rItem);
+
+ DoGetItem(&vTvItem);
+ if (!::WinSendMsg( GetHWND()
+ ,CM_INVALIDATERECORD
+ ,MPFROMP(&vTvItem)
+ ,MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION | CMA_TEXTCHANGED)
+ ));
+}
+
+wxTextCtrl* wxTreeCtrl::EditLabel (
+ const wxTreeItemId& rItem
+, wxClassInfo* WXUNUSED(pTextControlClass)
+)
+{
+ CNREDITDATA vEdit;
+ PMYRECORD pRecord = FindOS2TreeRecordByID( GetHWND()
+ ,rItem.m_pItem
+ );
+
+ vEdit.cb = sizeof(CNREDITDATA);
+ vEdit.hwndCnr = GetHWND();
+ vEdit.pRecord = &pRecord->m_vRecord;
+ vEdit.pFieldInfo = NULL;
+ vEdit.ppszText = NULL;
+ vEdit.cbText = 0;
+ vEdit.id = 0;
+
+ ::WinSendMsg( GetHWND()
+ ,CM_OPENEDIT
+ ,MPFROMP(&vEdit)
+ ,(MPARAM)0
+ );
+ return NULL;
+} // end of wxTreeCtrl::EditLabel
// End label editing, optionally cancelling the edit
-void wxTreeCtrl::EndEditLabel(const wxTreeItemId& item, bool discardChanges)
-{
-// TreeView_EndEditLabelNow(GetHwnd(), discardChanges);
-
- DeleteTextCtrl();
-}
-
-wxTreeItemId wxTreeCtrl::HitTest(const wxPoint& point, int& flags)
-{
-// TODO:
-/*
- TV_HITTESTINFO hitTestInfo;
- hitTestInfo.pt.x = (int)point.x;
- hitTestInfo.pt.y = (int)point.y;
-
- TreeView_HitTest(GetHwnd(), &hitTestInfo);
-
- flags = 0;
-
- // avoid repetition
- #define TRANSLATE_FLAG(flag) if ( hitTestInfo.flags & TVHT_##flag ) \
- flags |= wxTREE_HITTEST_##flag
-
- TRANSLATE_FLAG(ABOVE);
- TRANSLATE_FLAG(BELOW);
- TRANSLATE_FLAG(NOWHERE);
- TRANSLATE_FLAG(ONITEMBUTTON);
- TRANSLATE_FLAG(ONITEMICON);
- TRANSLATE_FLAG(ONITEMINDENT);
- TRANSLATE_FLAG(ONITEMLABEL);
- TRANSLATE_FLAG(ONITEMRIGHT);
- TRANSLATE_FLAG(ONITEMSTATEICON);
- TRANSLATE_FLAG(TOLEFT);
- TRANSLATE_FLAG(TORIGHT);
-
- #undef TRANSLATE_FLAG
-
- return wxTreeItemId((WXHTREEITEM) hitTestInfo.hItem);
-*/
- return 0;
-}
-
-bool wxTreeCtrl::GetBoundingRect(const wxTreeItemId& item,
- wxRect& rect,
- bool textOnly) const
-{
-// TODO:
-/*
- RECT rc;
- if ( TreeView_GetItemRect(GetHwnd(), (HTREEITEM)(WXHTREEITEM)item,
- &rc, textOnly) )
- {
- rect = wxRect(wxPoint(rc.left, rc.top), wxPoint(rc.right, rc.bottom));
-
- return TRUE;
- }
+void wxTreeCtrl::EndEditLabel (
+ const wxTreeItemId& WXUNUSED(rItem)
+, bool WXUNUSED(bDiscardChanges)
+)
+{
+ ::WinSendMsg( GetHWND()
+ ,CM_CLOSEEDIT
+ ,(MPARAM)0
+ ,(MPARAM)0
+ );
+} // end of wxTreeCtrl::EndEditLabel
+
+wxTreeItemId wxTreeCtrl::HitTest (
+ const wxPoint& rPoint
+, int& WXUNUSED(rFlags)
+)
+{
+ PMYRECORD pRecord = NULL;
+ QUERYRECFROMRECT vQueryRect;
+ RECTL vRect;
+ long lHeight;
+
+ //
+ // Get height for OS/2 point conversion
+ //
+ ::WinSendMsg( GetHWND()
+ ,CM_QUERYVIEWPORTRECT
+ ,MPFROMP(&vRect)
+ ,MPFROM2SHORT(CMA_WINDOW, TRUE)
+ );
+ lHeight = vRect.yTop - vRect.yBottom;
+
+ //
+ // For now just try and get a record in the general vicinity and forget
+ // the flag
+ //
+ vRect.xLeft = rPoint.x - 2;
+ vRect.xRight = rPoint.x + 2;
+ vRect.yTop = (lHeight - rPoint.y) + 2;
+ vRect.yBottom = (lHeight - rPoint.y) - 2;
+
+ vQueryRect.cb = sizeof(QUERYRECFROMRECT);
+ vQueryRect.rect = vRect;
+ vQueryRect.fsSearch = CMA_PARTIAL;
+
+ pRecord = (PMYRECORD)::WinSendMsg( GetHWND()
+ ,CM_QUERYRECORDFROMRECT
+ ,(MPARAM)CMA_FIRST
+ ,MPFROMP(&vQueryRect)
+ );
+
+ if (!pRecord)
+ return -1L;
+ return wxTreeItemId((long)pRecord->m_ulItemId);
+} // end of wxTreeCtrl::HitTest
+
+bool wxTreeCtrl::GetBoundingRect (
+ const wxTreeItemId& rItem
+, wxRect& rRect
+, bool bTextOnly
+) const
+{
+ RECTL vRectRecord;
+ PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
+ ,rItem.m_pItem
+ );
+ QUERYRECORDRECT vQuery;
+
+ vQuery.cb = sizeof(QUERYRECORDRECT);
+ vQuery.pRecord = (PRECORDCORE)pRecord;
+ vQuery.fRightSplitWindow = FALSE;
+ if (bTextOnly)
+ vQuery.fsExtent = CMA_TEXT;
else
- {
- // couldn't retrieve rect: for example, item isn't visible
+ vQuery.fsExtent = CMA_TREEICON | CMA_TEXT;
+
+ if (!::WinSendMsg( GetHWND()
+ ,CM_QUERYRECORDRECT
+ ,MPFROMP(&vRectRecord)
+ ,MPFROMP(&vQuery)
+ ))
return FALSE;
- }
-*/
- return FALSE;
-}
+ rRect.SetLeft(vRectRecord.xLeft);
+ rRect.SetTop(vRectRecord.yTop);
+ rRect.SetRight(vRectRecord.xRight);
+ rRect.SetBottom(vRectRecord.yBottom);
+ return TRUE;
+} // end of wxTreeCtrl::GetBoundingRect
// ----------------------------------------------------------------------------
// sorting stuff
// ----------------------------------------------------------------------------
-static int TreeView_CompareCallback(wxTreeItemData *pItem1,
- wxTreeItemData *pItem2,
- wxTreeCtrl *tree)
+SHORT EXPENTRY InternalDataCompareTreeFunc (
+ PMYRECORD p1
+, PMYRECORD p2
+, PVOID pStorage
+)
{
- wxCHECK_MSG( pItem1 && pItem2, 0,
+ wxCHECK_MSG( p1 && p2, 0,
wxT("sorting tree without data doesn't make sense") );
- return tree->OnCompareItems(pItem1->GetId(), pItem2->GetId());
-}
+ wxTreeCtrl* pTree = (wxTreeCtrl*)pStorage;
+
+ return pTree->OnCompareItems( p1->m_ulItemId
+ ,p2->m_ulItemId
+ );
+} // end of wxTreeSortHelper::Compare
-int wxTreeCtrl::OnCompareItems(const wxTreeItemId& item1,
- const wxTreeItemId& item2)
+int wxTreeCtrl::OnCompareItems (
+ const wxTreeItemId& rItem1
+, const wxTreeItemId& rItem2
+)
{
- return wxStrcmp(GetItemText(item1), GetItemText(item2));
-}
+ return wxStrcmp( GetItemText(rItem1)
+ ,GetItemText(rItem2)
+ );
+} // end of wxTreeCtrl::OnCompareItems
-void wxTreeCtrl::SortChildren(const wxTreeItemId& item)
+void wxTreeCtrl::SortChildren (
+ const wxTreeItemId& rItem
+)
{
- // rely on the fact that TreeView_SortChildren does the same thing as our
- // default behaviour, i.e. sorts items alphabetically and so call it
- // directly if we're not in derived class (much more efficient!)
-// TODO:
-/*
- if ( GetClassInfo() == CLASSINFO(wxTreeCtrl) )
- {
- TreeView_SortChildren(GetHwnd(), (HTREEITEM)(WXHTREEITEM)item, 0);
- }
- else
- {
- TV_SORTCB tvSort;
- tvSort.hParent = (HTREEITEM)(WXHTREEITEM)item;
- tvSort.lpfnCompare = (PFNTVCOMPARE)TreeView_CompareCallback;
- tvSort.lParam = (LPARAM)this;
- TreeView_SortChildrenCB(GetHwnd(), &tvSort, 0);
- }
-*/
-}
+ ::WinSendMsg( GetHWND()
+ ,CM_SORTRECORD
+ ,(PFN)InternalDataCompareTreeFunc
+ ,NULL
+ );
+} // end of wxTreeCtrl::SortChildren
// ----------------------------------------------------------------------------
// implementation
// ----------------------------------------------------------------------------
-bool wxTreeCtrl::OS2Command(WXUINT cmd, WXWORD id)
+bool wxTreeCtrl::OS2Command (
+ WXUINT uCmd
+, WXWORD wId
+)
{
-// TODO:
-/*
- if ( cmd == EN_UPDATE )
+ if (uCmd == CN_ENDEDIT)
{
- wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, id);
- event.SetEventObject( this );
- ProcessCommand(event);
+ wxCommandEvent vEvent( wxEVT_COMMAND_TEXT_UPDATED
+ ,wId
+ );
+
+ vEvent.SetEventObject( this );
+ ProcessCommand(vEvent);
+ return TRUE;
}
- else if ( cmd == EN_KILLFOCUS )
+ else if (uCmd == CN_KILLFOCUS)
{
- wxCommandEvent event(wxEVT_KILL_FOCUS, id);
- event.SetEventObject( this );
- ProcessCommand(event);
+ wxCommandEvent vEvent( wxEVT_KILL_FOCUS
+ ,wId
+ );
+ vEvent.SetEventObject( this );
+ ProcessCommand(vEvent);
+ return TRUE;
}
else
- {
- // nothing done
return FALSE;
- }
-
- // command processed
- return TRUE;
-*/
- return FALSE;
-}
+} // end of wxTreeCtrl::OS2Command
-// process WM_NOTIFY Windows message
-bool wxTreeCtrl::OS2OnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
-{
-// TODO:
-/*
- wxTreeEvent event(wxEVT_NULL, m_windowId);
- wxEventType eventType = wxEVT_NULL;
- NMHDR *hdr = (NMHDR *)lParam;
-
- switch ( hdr->code )
- {
- case NM_RCLICK:
- {
- if ( wxControl::MSWOnNotify(idCtrl, lParam, result) )
- return TRUE;
-
- TV_HITTESTINFO tvhti;
- ::GetCursorPos(&(tvhti.pt));
- ::ScreenToClient(GetHwnd(),&(tvhti.pt));
- if ( TreeView_HitTest(GetHwnd(),&tvhti) )
- {
- if( tvhti.flags & TVHT_ONITEM )
- {
- event.m_item = (WXHTREEITEM) tvhti.hItem;
- eventType=wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK;
- }
- }
- break;
- }
-
- case TVN_BEGINDRAG:
- eventType = wxEVT_COMMAND_TREE_BEGIN_DRAG;
- // fall through
-
- case TVN_BEGINRDRAG:
- {
- if ( eventType == wxEVT_NULL )
- eventType = wxEVT_COMMAND_TREE_BEGIN_RDRAG;
- //else: left drag, already set above
-
- NM_TREEVIEW *tv = (NM_TREEVIEW *)lParam;
-
- event.m_item = (WXHTREEITEM) tv->itemNew.hItem;
- event.m_pointDrag = wxPoint(tv->ptDrag.x, tv->ptDrag.y);
- break;
- }
-
- case TVN_BEGINLABELEDIT:
- {
- eventType = wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT;
- TV_DISPINFO *info = (TV_DISPINFO *)lParam;
-
- event.m_item = (WXHTREEITEM) info->item.hItem;
- event.m_label = info->item.pszText;
- break;
- }
-
- case TVN_DELETEITEM:
- {
- eventType = wxEVT_COMMAND_TREE_DELETE_ITEM;
- NM_TREEVIEW *tv = (NM_TREEVIEW *)lParam;
-
- event.m_item = (WXHTREEITEM) tv->itemOld.hItem;
- break;
- }
-
- case TVN_ENDLABELEDIT:
- {
- eventType = wxEVT_COMMAND_TREE_END_LABEL_EDIT;
- TV_DISPINFO *info = (TV_DISPINFO *)lParam;
-
- event.m_item = (WXHTREEITEM)info->item.hItem;
- event.m_label = info->item.pszText;
- break;
- }
-
- case TVN_GETDISPINFO:
- eventType = wxEVT_COMMAND_TREE_GET_INFO;
- // fall through
-
- case TVN_SETDISPINFO:
- {
- if ( eventType == wxEVT_NULL )
- eventType = wxEVT_COMMAND_TREE_SET_INFO;
- //else: get, already set above
-
- TV_DISPINFO *info = (TV_DISPINFO *)lParam;
-
- event.m_item = (WXHTREEITEM) info->item.hItem;
- break;
- }
-
- case TVN_ITEMEXPANDING:
- event.m_code = FALSE;
- // fall through
-
- case TVN_ITEMEXPANDED:
- {
- NM_TREEVIEW* tv = (NM_TREEVIEW*)lParam;
-
- bool expand = FALSE;
- switch ( tv->action )
- {
- case TVE_EXPAND:
- expand = TRUE;
- break;
-
- case TVE_COLLAPSE:
- expand = FALSE;
- break;
-
- default:
- wxLogDebug(wxT("unexpected code %d in TVN_ITEMEXPAND "
- "message"), tv->action);
- }
-
- bool ing = ((int)hdr->code == TVN_ITEMEXPANDING);
- eventType = g_events[expand][ing];
-
- event.m_item = (WXHTREEITEM) tv->itemNew.hItem;
- break;
- }
-
- case TVN_KEYDOWN:
- {
- eventType = wxEVT_COMMAND_TREE_KEY_DOWN;
- TV_KEYDOWN *info = (TV_KEYDOWN *)lParam;
-
- event.m_code = wxCharCodeMSWToWX(info->wVKey);
-
- // a separate event for this case
- if ( info->wVKey == VK_SPACE || info->wVKey == VK_RETURN )
- {
- wxTreeEvent event2(wxEVT_COMMAND_TREE_ITEM_ACTIVATED,
- m_windowId);
- event2.SetEventObject(this);
-
- GetEventHandler()->ProcessEvent(event2);
- }
- break;
- }
-
- case TVN_SELCHANGED:
- eventType = wxEVT_COMMAND_TREE_SEL_CHANGED;
- // fall through
-
- case TVN_SELCHANGING:
- {
- if ( eventType == wxEVT_NULL )
- eventType = wxEVT_COMMAND_TREE_SEL_CHANGING;
- //else: already set above
-
- NM_TREEVIEW* tv = (NM_TREEVIEW *)lParam;
-
- event.m_item = (WXHTREEITEM) tv->itemNew.hItem;
- event.m_itemOld = (WXHTREEITEM) tv->itemOld.hItem;
- break;
- }
-
- default:
- return wxControl::MSWOnNotify(idCtrl, lParam, result);
- }
-
- event.SetEventObject(this);
- event.SetEventType(eventType);
-
- bool processed = GetEventHandler()->ProcessEvent(event);
-
- // post processing
- switch ( hdr->code )
+//
+// TODO: Fully implement direct manipulation when I figure it out
+//
+MRESULT wxTreeCtrl::OS2WindowProc (
+ WXUINT uMsg
+, WXWPARAM wParam
+, WXLPARAM lParam
+)
+{
+ bool bProcessed = FALSE;
+ MRESULT mRc = 0;
+ wxTreeEvent vEvent( wxEVT_NULL
+ ,m_windowId
+ );
+ wxEventType vEventType = wxEVT_NULL;
+ PCNRDRAGINIT pDragInit = NULL;
+ PCNREDITDATA pEditData = NULL;
+ PNOTIFYRECORDENTER pNotifyEnter = NULL;
+
+ vEvent.SetEventObject(this);
+ switch (uMsg)
{
- case TVN_DELETEITEM:
- {
- // NB: we might process this message using wxWindows event
- // tables, but due to overhead of wxWin event system we
- // prefer to do it here ourself (otherwise deleting a tree
- // with many items is just too slow)
- NM_TREEVIEW* tv = (NM_TREEVIEW *)lParam;
-
- wxTreeItemId item = event.m_item;
- if ( HasIndirectData(item) )
- {
- wxTreeItemIndirectData *data = (wxTreeItemIndirectData *)
- tv->itemOld.lParam;
- delete data; // can't be NULL here
-
- m_itemsWithIndirectData.Remove(item);
- }
- else
- {
- wxTreeItemData *data = (wxTreeItemData *)tv->itemOld.lParam;
- delete data; // may be NULL, ok
- }
-
- processed = TRUE; // Make sure we don't get called twice
- }
- break;
-
- case TVN_BEGINLABELEDIT:
- // return TRUE to cancel label editing
- *result = !event.IsAllowed();
- break;
-
- case TVN_ENDLABELEDIT:
- // return TRUE to set the label to the new string
- *result = event.IsAllowed();
-
- // ensure that we don't have the text ctrl which is going to be
- // deleted any more
- DeleteTextCtrl();
- break;
-
- case TVN_SELCHANGING:
- case TVN_ITEMEXPANDING:
- // return TRUE to prevent the action from happening
- *result = !event.IsAllowed();
- break;
-
- case TVN_GETDISPINFO:
- // NB: so far the user can't set the image himself anyhow, so do it
- // anyway - but this may change later
- if ( 1 // !processed && )
+ case WM_CONTROL:
+ switch(SHORT2FROMMP(wParam))
{
- wxTreeItemId item = event.m_item;
- TV_DISPINFO *info = (TV_DISPINFO *)lParam;
- if ( info->item.mask & TVIF_IMAGE )
- {
- info->item.iImage =
- DoGetItemImageFromData
- (
- item,
- IsExpanded(item) ? wxTreeItemIcon_Expanded
- : wxTreeItemIcon_Normal
- );
- }
- if ( info->item.mask & TVIF_SELECTEDIMAGE )
- {
- info->item.iSelectedImage =
- DoGetItemImageFromData
- (
- item,
- IsExpanded(item) ? wxTreeItemIcon_SelectedExpanded
- : wxTreeItemIcon_Selected
- );
- }
+ case CN_INITDRAG:
+ pDragInit = (PCNRDRAGINIT)lParam;
+ if (pDragInit)
+ {
+ PMYRECORD pRecord = (PMYRECORD)pDragInit->pRecord;
+
+ vEventType = wxEVT_COMMAND_TREE_BEGIN_DRAG;
+ vEvent.m_item = pRecord->m_ulItemId;
+ vEvent.m_pointDrag.x = pDragInit->x;
+ vEvent.m_pointDrag.y = pDragInit->y;
+ }
+ break;
+
+ case CN_BEGINEDIT:
+ pEditData = (PCNREDITDATA)lParam;
+ if (pEditData)
+ {
+ PMYRECORD pRecord = (PMYRECORD)pEditData->pRecord;
+
+ vEventType = wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT;
+ vEvent.m_item = pRecord->m_ulItemId;
+ vEvent.m_label = pRecord->m_vRecord.pszTree;
+ vEvent.m_editCancelled = FALSE;
+ }
+ break;
+
+ case CN_ENDEDIT:
+ pEditData = (PCNREDITDATA)lParam;
+ if (pEditData)
+ {
+ PMYRECORD pRecord = (PMYRECORD)pEditData->pRecord;
+
+ vEventType = wxEVT_COMMAND_TREE_END_LABEL_EDIT;
+ vEvent.m_item = pRecord->m_ulItemId;
+ vEvent.m_label = pRecord->m_vRecord.pszTree;
+ if (pRecord->m_vRecord.pszTree == NULL)
+ {
+ vEvent.m_editCancelled = TRUE;
+ }
+ else
+ {
+ vEvent.m_editCancelled = FALSE;
+ }
+ }
+ break;
+
+ case CN_EXPANDTREE:
+ {
+ PMYRECORD pRecord = (PMYRECORD)lParam;
+
+ vEventType = gs_expandEvents[IDX_EXPAND][IDX_DONE];
+ vEvent.m_item = pRecord->m_ulItemId;
+ }
+ break;
}
+ vEvent.SetEventType(vEventType);
+ bProcessed = GetEventHandler()->ProcessEvent(vEvent);
break;
-
- //default:
- // for the other messages the return value is ignored and there is
- // nothing special to do
}
-
- return processed;
-*/
- return FALSE;
-}
-
-// ----------------------------------------------------------------------------
-// Tree event
-// ----------------------------------------------------------------------------
-
-IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent, wxNotifyEvent)
-
-wxTreeEvent::wxTreeEvent(wxEventType commandType, int id)
- : wxNotifyEvent(commandType, id)
-{
- m_code = 0;
- m_itemOld = 0;
-}
-
+ if (!bProcessed)
+ mRc = wxControl::OS2WindowProc( uMsg
+ ,wParam
+ ,lParam
+ );
+ return mRc;
+} // end of wxTreeCtrl::OS2WindowProc
+
+#endif // wxUSE_TREECTRL