Logo Search packages:      
Sourcecode: galaxium version File versions  Download package

GalaxiumTreeView.cs

/*
 * Galaxium Messenger
 * Copyright (C) 2008 Paul Burton <paulburton89@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;

using GLib;
using Gtk;

using Anculus.Core;

namespace Galaxium.Gui.GtkGui
{
      public partial class GalaxiumTreeView : TreeView
      {
            struct TreeRow
            {
                  public object Data;
            }
            
#region Private Fields
            TreeStore _store;
            TreeModelSort _sortedModel;
            TreeModelFilter _filterModel;
            
            bool _sort = true;
            SortOrder _sortOrder;
            
            string _filterString = null;
            bool _filterCaseSensitive = false;
#endregion
            
#region Properties
            public bool Sort
            {
                  get { return _sort; }
                  set
                  {
                        if (_sort == value)
                              return;
                        
                        _sort = value;
                        
                        if (_sort)
                              Resort ();
                  }
            }
            
            public SortOrder SortOrder
            {
                  get { return _sortOrder; }
                  set
                  {
                        if (_sortOrder == value)
                              return;
                        
                        _sortOrder = value;
                        
                        if (_sort)
                              _sortedModel.SetSortColumnId (0, _sortOrder == SortOrder.Ascending ? SortType.Ascending : SortType.Descending);
                  }
            }
            
            public string Filter
            {
                  get { return _filterString; }
                  set
                  {
                        if (_filterString == value)
                              return;
                        
                        _filterString = value;
                        Refilter ();
                  }
            }
            
            public bool FilterCaseSensitive
            {
                  get { return _filterCaseSensitive; }
                  set
                  {
                        if (_filterCaseSensitive == value)
                              return;
                        
                        _filterCaseSensitive = value;
                        Refilter ();
                  }
            }
            
            public TreeStore Store
            {
                  get { return _store; }
            }
#endregion
            
            public GalaxiumTreeView ()
            {
                  _store = new TreeStore (typeof (TreeRow));
                  
                  _sortedModel = new TreeModelSort (_store);
                  _sortedModel.SetSortFunc (0, SortedModelSortFunc);
                  
                  _filterModel = new TreeModelFilter (_sortedModel, null);
                  _filterModel.VisibleFunc = new TreeModelFilterVisibleFunc (FilterModelVisibleFunc);
                  
                  Model = _filterModel;
            }
            
#region Sorting
            public virtual void Resort ()
            {
                  if (_sort)
                  {
                        //Anculus.Core.Log.Debug ("Resort");
                        
                        //TODO: the following is a really ugly hack... is there no better way to force a resort?
                        _sortedModel.SetSortColumnId (0, _sortOrder == SortOrder.Ascending ? SortType.Descending : SortType.Ascending);
                        _sortedModel.SetSortColumnId (0, _sortOrder == SortOrder.Ascending ? SortType.Ascending : SortType.Descending);
                  }
            }
            
            int SortedModelSortFunc (TreeModel model, TreeIter iter1, TreeIter iter2)
            {
                  if (model == null)
                        return 0;
                  
                  object data1 = GetModelData (model, iter1);
                  object data2 = GetModelData (model, iter2);
                  
                  //Anculus.Core.Log.Debug ("Compare {0} to {1}", data1, data2);
                  
                  if (data1 == null)
                  {
                        if (data2 == null)
                              return 0;
                        else
                              return 1;
                  }
                  else if (data2 == null)
                        return -1;
                  
                  return Compare (data1, data2);
            }
            
            protected virtual int Compare (object obj1, object obj2)
            {
                  return obj1.ToString ().CompareTo (obj2.ToString ());
            }
#endregion
            
#region Filtering
            public virtual void Refilter ()
            {
                  _filterModel.Refilter ();
            }
            
            bool FilterModelVisibleFunc (TreeModel model, TreeIter iter)
            {
                  if (string.IsNullOrEmpty (_filterString))
                        return true;
                  
                  object data = GetModelData (model, iter);
                  
                  return FilterShouldDisplay (data);
            }
            
            protected virtual bool FilterShouldDisplay (object data)
            {
                  return true;
            }
#endregion
            
#region Row Handling
            public TreeRowReference AddRow (object data)
            {
                  TreeRow treeRow = new TreeRow ();
                  treeRow.Data = data;
                  
                  TreeIter iter = _store.AppendValues (treeRow);
                  return new TreeRowReference (_store, _store.GetPath (iter));
            }
            
            public TreeRowReference AddRow (TreeRowReference parent, object data)
            {
                  TreeIter parentIter;
                  _store.GetIter (out parentIter, parent.Path);
                  
                  TreeIter iter = _store.AppendNode (parentIter);
                  SetModelData (_store, iter, data);
                  return new TreeRowReference (_store, _store.GetPath (iter));
            }
            
            public void RemoveRow (TreeRowReference rowRef)
            {
                  TreeIter iter;
                  _store.GetIter (out iter, rowRef.Path);
                  _store.Remove (ref iter);
            }
            
            public void RowChanged (TreeRowReference rowRef)
            {
                  TreeIter iter;
                  TreePath path = rowRef.Path;
                  _store.GetIter (out iter, path);
                  _store.EmitRowChanged (path, iter);
            }
#endregion
            
#region Row Data
            public object GetData (TreeRowReference rowRef)
            {
                  return GetData (rowRef.Path);
            }
            
            public object GetData (TreePath path)
            {
                  TreeIter iter;
                  _store.GetIter (out iter, path);
                  
                  return GetModelData (_store, iter);
            }
            
            public object GetModelData (TreePath path)
            {
                  TreeIter iter;
                  if (!Model.GetIter (out iter, path))
                        return null;
                  
                  return GetModelData (iter);
            }
            
            public object GetModelData (TreeIter iter)
            {
                  return GetModelData (Model, iter);
            }
            
            public object GetModelData (TreeModel model, TreeIter iter)
            {
                  object val = model.GetValue (iter, 0);
                  
                  if (val is TreeRow)
                        return ((TreeRow)val).Data;
                  
                  return null;
            }
            
            public void SetData (TreeRowReference rowRef, object data)
            {
                  SetData (rowRef.Path, data);
            }
            
            public void SetData (TreePath path, object data)
            {
                  TreeIter iter;
                  _store.GetIter (out iter, path);
                  
                  SetModelData (_store, iter, data);
            }
            
            public void SetModelData (TreePath path, object data)
            {
                  TreeIter iter;
                  if (!Model.GetIter (out iter, path))
                        return;
                  
                  SetModelData (iter, data);
            }
            
            public void SetModelData (TreeIter iter, object data)
            {
                  SetModelData (Model, iter, data);
            }
            
            public void SetModelData (TreeModel model, TreeIter iter, object data)
            {
                  TreeRow row = new TreeRow ();
                  row.Data = data;
                  
                  model.SetValue (iter, 0, row);
            }
#endregion
            
            public TreePath GetModelPath (TreePath dataPath)
            {
                  return _sortedModel.ConvertChildPathToPath (_filterModel.ConvertChildPathToPath (dataPath));
            }
            
            protected void AllRowsChanged ()
            {
                  Store.Foreach (delegate (TreeModel model, TreePath path, TreeIter iter)
                  {
                        model.EmitRowChanged (path, iter);
                        return false;
                  });
            }
            
            protected virtual Menu CreateContextMenu (TreePath treePath, object data)
            {
                  return null;
            }
            
            protected override bool OnButtonPressEvent (Gdk.EventButton e)
            {
                  bool retVal = base.OnButtonPressEvent (e);
                  
                  if (e.Button != 3)
                        return retVal;
                  
                  TreePath path;
                  if (!GetPathAtPos ((int)e.X, (int)e.Y, out path))
                        return retVal;
                  
                  object val = GetModelData (path);
                  Menu menu = CreateContextMenu (path, val);
                  
                  if (menu != null)
                  {
                        menu.Popup (null, null, null, e.Button, e.Time);
                        menu.ShowAll ();
                  }
                  
                  return retVal;
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index