]> git.saurik.com Git - wxWidgets.git/blobdiff - src/xrc/xh_listc.cpp
better variant support, fixes #11114
[wxWidgets.git] / src / xrc / xh_listc.cpp
index ee21109f221e7a8fddc0c426215bfe0467d6aa2a..a6499e422aa3c91e967892019fc809235fd56d55 100644 (file)
@@ -1,16 +1,13 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        xh_listc.cpp
-// Purpose:     XML resource for wxListCtrl
-// Author:      Brian Gavin
+// Name:        src/xrc/xh_listc.cpp
+// Purpose:     XRC resource for wxListCtrl
+// Author:      Brian Gavin, Kinaou HervĂ©, Vadim Zeitlin
 // Created:     2000/09/09
 // RCS-ID:      $Id$
 // Copyright:   (c) 2000 Brian Gavin
+//              (c) 2009 Vadim Zeitlin
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
-#ifdef __GNUG__
-#pragma implementation "xh_listc.h"
-#endif
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
     #pragma hdrstop
 #endif
 
-#include "wx/textctrl.h"
+#if wxUSE_XRC && wxUSE_LISTCTRL
+
 #include "wx/xrc/xh_listc.h"
+
+#ifndef WX_PRECOMP
+    #include "wx/textctrl.h"
+#endif
+
 #include "wx/listctrl.h"
+#include "wx/imaglist.h"
+
+namespace
+{
 
+const char *LISTCTRL_CLASS_NAME = "wxListCtrl";
+const char *LISTITEM_CLASS_NAME = "listitem";
+const char *LISTCOL_CLASS_NAME = "listcol";
 
-wxListCtrlXmlHandler::wxListCtrlXmlHandler() 
-: wxXmlResourceHandler() 
+} // anonymous namespace
+
+
+IMPLEMENT_DYNAMIC_CLASS(wxListCtrlXmlHandler, wxXmlResourceHandler)
+
+wxListCtrlXmlHandler::wxListCtrlXmlHandler()
+    : wxXmlResourceHandler()
 {
-    ADD_STYLE(wxLC_LIST);
-    ADD_STYLE(wxLC_REPORT);
-    ADD_STYLE(wxLC_ICON);
-    ADD_STYLE(wxLC_SMALL_ICON);
-    ADD_STYLE(wxLC_ALIGN_TOP);
-    ADD_STYLE(wxLC_ALIGN_LEFT);
-    ADD_STYLE(wxLC_AUTOARRANGE);
-    ADD_STYLE(wxLC_USER_TEXT);
-    ADD_STYLE(wxLC_EDIT_LABELS);
-    ADD_STYLE(wxLC_NO_HEADER);
-    ADD_STYLE(wxLC_SINGLE_SEL);
-    ADD_STYLE(wxLC_SORT_ASCENDING);
-    ADD_STYLE(wxLC_SORT_DESCENDING);
+    // wxListItem styles
+    XRC_ADD_STYLE(wxLIST_FORMAT_LEFT);
+    XRC_ADD_STYLE(wxLIST_FORMAT_RIGHT);
+    XRC_ADD_STYLE(wxLIST_FORMAT_CENTRE);
+    XRC_ADD_STYLE(wxLIST_MASK_STATE);
+    XRC_ADD_STYLE(wxLIST_MASK_TEXT);
+    XRC_ADD_STYLE(wxLIST_MASK_IMAGE);
+    XRC_ADD_STYLE(wxLIST_MASK_DATA);
+    XRC_ADD_STYLE(wxLIST_MASK_WIDTH);
+    XRC_ADD_STYLE(wxLIST_MASK_FORMAT);
+    XRC_ADD_STYLE(wxLIST_STATE_FOCUSED);
+    XRC_ADD_STYLE(wxLIST_STATE_SELECTED);
+
+    // wxListCtrl styles
+    XRC_ADD_STYLE(wxLC_LIST);
+    XRC_ADD_STYLE(wxLC_REPORT);
+    XRC_ADD_STYLE(wxLC_ICON);
+    XRC_ADD_STYLE(wxLC_SMALL_ICON);
+    XRC_ADD_STYLE(wxLC_ALIGN_TOP);
+    XRC_ADD_STYLE(wxLC_ALIGN_LEFT);
+    XRC_ADD_STYLE(wxLC_AUTOARRANGE);
+    XRC_ADD_STYLE(wxLC_USER_TEXT);
+    XRC_ADD_STYLE(wxLC_EDIT_LABELS);
+    XRC_ADD_STYLE(wxLC_NO_HEADER);
+    XRC_ADD_STYLE(wxLC_SINGLE_SEL);
+    XRC_ADD_STYLE(wxLC_SORT_ASCENDING);
+    XRC_ADD_STYLE(wxLC_SORT_DESCENDING);
+    XRC_ADD_STYLE(wxLC_VIRTUAL);
+    XRC_ADD_STYLE(wxLC_HRULES);
+    XRC_ADD_STYLE(wxLC_VRULES);
+    XRC_ADD_STYLE(wxLC_NO_SORT_HEADER);
     AddWindowStyles();
 }
 
-
 wxObject *wxListCtrlXmlHandler::DoCreateResource()
-{ 
-    wxListCtrl *list = new wxListCtrl(m_parentAsWindow,
-                                    GetID(),
-                                    GetPosition(), GetSize(),
-                                    GetStyle(),
-                                    wxDefaultValidator,
-                                    GetName());
-    /* TODO: columns definition */
-    
+{
+    if ( m_class == LISTITEM_CLASS_NAME )
+    {
+        HandleListItem();
+    }
+    else if ( m_class == LISTCOL_CLASS_NAME )
+    {
+        HandleListCol();
+    }
+    else
+    {
+        wxASSERT_MSG( m_class == LISTCTRL_CLASS_NAME,
+                        "can't handle unknown node" );
+
+        return HandleListCtrl();
+    }
+
+    return m_parentAsWindow;
+}
+
+bool wxListCtrlXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, LISTCTRL_CLASS_NAME) ||
+            IsOfClass(node, LISTITEM_CLASS_NAME) ||
+             IsOfClass(node, LISTCOL_CLASS_NAME);
+}
+
+void wxListCtrlXmlHandler::HandleCommonItemAttrs(wxListItem& item)
+{
+    if (HasParam(wxT("align")))
+        item.SetAlign((wxListColumnFormat)GetStyle(wxT("align")));
+    if (HasParam(wxT("text")))
+        item.SetText(GetText(wxT("text")));
+}
+
+void wxListCtrlXmlHandler::HandleListCol()
+{
+    wxListCtrl * const list = wxDynamicCast(m_parentAsWindow, wxListCtrl);
+    wxCHECK_RET( list, "must have wxListCtrl parent" );
+
+    if ( !list->HasFlag(wxLC_REPORT) )
+    {
+        ReportError("Only report mode list controls can have columns.");
+        return;
+    }
+
+    wxListItem item;
+
+    HandleCommonItemAttrs(item);
+    if (HasParam(wxT("width")))
+        item.SetWidth((int)GetLong(wxT("width")));
+
+    list->InsertColumn(list->GetColumnCount(), item);
+}
+
+void wxListCtrlXmlHandler::HandleListItem()
+{
+    wxListCtrl * const list = wxDynamicCast(m_parentAsWindow, wxListCtrl);
+    wxCHECK_RET( list, "must have wxListCtrl parent" );
+
+    wxListItem item;
+
+    HandleCommonItemAttrs(item);
+
+    if (HasParam(wxT("bg")))
+        item.SetBackgroundColour(GetColour(wxT("bg")));
+    if (HasParam(wxT("col")))
+        item.SetColumn((int)GetLong(wxT("col")));
+    if (HasParam(wxT("data")))
+        item.SetData(GetLong(wxT("data")));
+    if (HasParam(wxT("font")))
+        item.SetFont(GetFont());
+    if (HasParam(wxT("state")))
+        item.SetState(GetStyle(wxT("state")));
+    if (HasParam(wxT("textcolour")))
+        item.SetTextColour(GetColour(wxT("textcolour")));
+    if (HasParam(wxT("textcolor")))
+        item.SetTextColour(GetColour(wxT("textcolor")));
+
+    // the list control icon style, may be 0
+    int image;
+    if ( list->HasFlag(wxLC_ICON) )
+        image = GetImageIndex(list, wxIMAGE_LIST_NORMAL);
+    else if ( list->HasFlag(wxLC_SMALL_ICON) )
+        image = GetImageIndex(list, wxIMAGE_LIST_SMALL);
+    else
+        image = wxNOT_FOUND;
+
+    if ( image != wxNOT_FOUND )
+        item.SetImage(image);
+
+    // append the list item to the control
+    item.SetId(list->GetItemCount());
+
+    list->InsertItem(item);
+}
+
+wxListCtrl *wxListCtrlXmlHandler::HandleListCtrl()
+{
+    XRC_MAKE_INSTANCE(list, wxListCtrl)
+
+    list->Create(m_parentAsWindow,
+                 GetID(),
+                 GetPosition(), GetSize(),
+                 GetStyle(),
+                 wxDefaultValidator,
+                 GetName());
+
+    // we can optionally have normal and/or small image lists
+    wxImageList *imagelist;
+    imagelist = GetImageList(wxT("imagelist"));
+    if ( imagelist )
+        list->AssignImageList(imagelist, wxIMAGE_LIST_NORMAL);
+    imagelist = GetImageList(wxT("imagelist-small"));
+    if ( imagelist )
+        list->AssignImageList(imagelist, wxIMAGE_LIST_SMALL);
+
+    CreateChildrenPrivately(list);
     SetupWindow(list);
-    
+
     return list;
 }
 
+long wxListCtrlXmlHandler::GetImageIndex(wxListCtrl *listctrl, int which)
+{
+    // use different tag names depending on whether we need a normal or small
+    // image
+    wxString
+        bmpParam("bitmap"),
+        imgParam("image");
+    switch ( which )
+    {
+        case wxIMAGE_LIST_SMALL:
+            bmpParam += "-small";
+            imgParam += "-small";
+            break;
 
+        case wxIMAGE_LIST_NORMAL:
+            // nothing to do
+            break;
 
-bool wxListCtrlXmlHandler::CanHandle(wxXmlNode *node)
-{
-    return IsOfClass(node, wxT("wxListCtrl"));
+        default:
+            wxFAIL_MSG( "unsupported image list kind" );
+            return wxNOT_FOUND;
+    }
+
+    // look for either bitmap or image tags
+    int imgIndex = wxNOT_FOUND;
+    if ( HasParam(bmpParam) )
+    {
+        // we implicitly construct an image list containing the specified
+        // bitmaps
+        wxBitmap bmp = GetBitmap(bmpParam, wxART_OTHER);
+
+        // create the image list on demand for the first bitmap
+        wxImageList *imgList = listctrl->GetImageList(which);
+        if ( !imgList )
+        {
+            imgList = new wxImageList( bmp.GetWidth(), bmp.GetHeight() );
+            listctrl->AssignImageList( imgList, which );
+        }
+
+        imgIndex = imgList->Add(bmp);
+    }
+
+    if ( HasParam(imgParam) )
+    {
+        if ( imgIndex != wxNOT_FOUND )
+        {
+            // TODO: we should really check that only bitmap or only image tags
+            //       are used across all items of the control, not just in this
+            //       one
+            ReportError(wxString::Format(
+                "listitem %s attribute ignored because %s is also specified",
+                bmpParam, imgParam));
+        }
+
+        // just use the specified index directly
+        imgIndex = GetLong(imgParam);
+    }
+
+    return imgIndex;
 }
+
+#endif // wxUSE_XRC && wxUSE_LISTCTRL