i implemented the filter and i never want to think about Gtk.TreeIter again
This commit is contained in:
parent
4c212c4c21
commit
605c34a9f5
3 changed files with 355 additions and 83 deletions
|
@ -47,11 +47,13 @@ namespace Buypeeb {
|
|||
private Box selectionViewBox;
|
||||
private Label endingLabel;
|
||||
private bool queueActive;
|
||||
private Dictionary<string, CheckButton> filterChecks = new Dictionary<string, CheckButton>();
|
||||
|
||||
// ...to here.
|
||||
|
||||
static SemaphoreSlim taskLimit = new SemaphoreSlim(6);
|
||||
private Queue<string> updateQueue = new Queue<string>();
|
||||
private IEnumerable<YahooAuctionsItem> filterQuery;
|
||||
|
||||
private YahooAuctionsItem selectedItem {
|
||||
get {
|
||||
|
@ -106,13 +108,33 @@ namespace Buypeeb {
|
|||
|
||||
this.selectionViewBox = (Box)builder.GetObject("SelectionViewBox");
|
||||
this.endingLabel = (Label)builder.GetObject("LabelSelectedEnding");
|
||||
foreach (var name in new List<string> { "Favourites", "NonFavourites", "Active", "Ended", "EndingToday", "EndingAfterToday", "WithWinPrice", "WithNoWinPrice" }) {
|
||||
this.filterChecks.Add(name, (CheckButton)builder.GetObject($"CheckButtonFilter{name}"));
|
||||
this.filterChecks[name].Active = false;
|
||||
}
|
||||
|
||||
// father forgive me for i have lynned
|
||||
this.filterQuery =
|
||||
from item in this.settings.watchlist.Values.ToList()
|
||||
where (item.favourite != this.filterChecks["Favourites"].Active ||
|
||||
item.favourite == this.filterChecks["NonFavourites"].Active) &&
|
||||
(item.available != this.filterChecks["Active"].Active ||
|
||||
item.available == this.filterChecks["Ended"].Active) &&
|
||||
(item.endingToday != this.filterChecks["EndingToday"].Active ||
|
||||
item.endingToday == this.filterChecks["EndingAfterToday"].Active) &&
|
||||
(item.hasWinPrice != this.filterChecks["WithWinPrice"].Active ||
|
||||
item.hasWinPrice == this.filterChecks["WithNoWinPrice"].Active)
|
||||
select item;
|
||||
|
||||
Console.WriteLine(this.filterChecks["Favourites"].Active);
|
||||
|
||||
// bind treeview columns to watchlist instead of needing to manually sync its liststore
|
||||
this.itemTreeView = (TreeView)builder.GetObject("TreeViewItems");
|
||||
this.items = new ListStore(typeof(YahooAuctionsItem));
|
||||
this.RenderList();
|
||||
var filteredItems = new TreeModelFilter(this.items, null);
|
||||
filteredItems.VisibleFunc = this.ItemFilter;
|
||||
|
||||
this.itemTreeView.Model = this.items;
|
||||
this.itemTreeView.Model = filteredItems;
|
||||
TreeCellDataFunc[] funcs = {
|
||||
new TreeCellDataFunc(this.RenderColumnFavourite),
|
||||
new TreeCellDataFunc(this.RenderColumnName),
|
||||
|
@ -127,6 +149,7 @@ namespace Buypeeb {
|
|||
c.SetCellDataFunc(c.Cells[0], funcs[i]);
|
||||
}
|
||||
|
||||
this.RenderList();
|
||||
this.UpdateItems();
|
||||
GLib.Timeout.Add(1000, new GLib.TimeoutHandler(UpdateSelectionEndTime));
|
||||
|
||||
|
@ -144,11 +167,13 @@ namespace Buypeeb {
|
|||
// TODO: surely there's a better way to do this
|
||||
TreeIter iter;
|
||||
this.itemTreeView.Model.GetIterFirst(out iter);
|
||||
var m = (TreeModelFilter)this.itemTreeView.Model;
|
||||
|
||||
for (int i = 0; i < this.itemTreeView.Model.IterNChildren(); i++) {
|
||||
var x = (YahooAuctionsItem)this.itemTreeView.Model.GetValue(iter, 0);
|
||||
Console.WriteLine(x);
|
||||
if (x.id == id) {
|
||||
return (this.itemTreeView.Model.GetPath(iter), iter);
|
||||
return (m.ConvertPathToChildPath(m.GetPath(iter)), m.ConvertIterToChildIter(iter));
|
||||
}
|
||||
else {
|
||||
this.itemTreeView.Model.IterNext(ref iter);
|
||||
|
@ -183,7 +208,9 @@ namespace Buypeeb {
|
|||
Gtk.Application.Invoke(delegate {
|
||||
// TODO: find a way to not have to do this. i think we need to avoid actually modifying the items outside of the main thread :/
|
||||
var pathAndIter = this.GetRow(id);
|
||||
if (pathAndIter.path != null) {
|
||||
this.items.EmitRowChanged(pathAndIter.path, pathAndIter.iter);
|
||||
}
|
||||
});
|
||||
|
||||
using (WebClient client = new WebClient()) {
|
||||
|
@ -195,7 +222,9 @@ namespace Buypeeb {
|
|||
|
||||
Gtk.Application.Invoke(delegate {
|
||||
var pathAndIter = this.GetRow(id);
|
||||
if (pathAndIter.path != null) {
|
||||
this.items.EmitRowChanged(pathAndIter.path, pathAndIter.iter);
|
||||
}
|
||||
if (item == this.selectedItem) {
|
||||
// if the user has this item selected and it just became ready, enable the selection box
|
||||
this.selectionViewBox.Sensitive = true;
|
||||
|
@ -370,6 +399,8 @@ namespace Buypeeb {
|
|||
foreach (var item in this.settings.watchlist.Values) {
|
||||
items.AppendValues(item);
|
||||
}
|
||||
var m = (TreeModelFilter)this.itemTreeView.Model;
|
||||
m.Refilter();
|
||||
}
|
||||
|
||||
// event handlers
|
||||
|
@ -598,8 +629,10 @@ namespace Buypeeb {
|
|||
|
||||
// i don't know why this is necessary
|
||||
var pathAndIter = this.GetRow(this.selectedItem.id);
|
||||
if (pathAndIter.path != null) {
|
||||
this.items.EmitRowChanged(pathAndIter.path, pathAndIter.iter);
|
||||
}
|
||||
}
|
||||
|
||||
// timers
|
||||
|
||||
|
@ -681,5 +714,34 @@ namespace Buypeeb {
|
|||
}
|
||||
(cell as Gtk.CellRendererText).Text = item.ready ? ending : "...";
|
||||
}
|
||||
|
||||
// tree filter
|
||||
|
||||
private bool ItemFilter(ITreeModel model, TreeIter iter) {
|
||||
var item = (YahooAuctionsItem)model.GetValue(iter, 0);
|
||||
|
||||
bool Filtered(string name) {
|
||||
return this.filterChecks[name].Active;
|
||||
}
|
||||
|
||||
// first, check to see if any filters are set that would exclude everything, such as hiding both active and ended auctions
|
||||
// if so, there's no need to run the more expensive linq query
|
||||
if (
|
||||
(Filtered("Favourites") && Filtered("NonFavourites")) ||
|
||||
(Filtered("Active") && Filtered("Ended")) ||
|
||||
(Filtered("EndingToday") && Filtered("EndingAfterToday")) ||
|
||||
(Filtered("WithWinPrice") && Filtered("WithNoWinPrice"))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// this.filterQuery.ToList().ForEach(Console.WriteLine);
|
||||
return this.filterQuery.Contains(item);
|
||||
}
|
||||
|
||||
private void RunFilter(object sender, EventArgs a) {
|
||||
var m = (TreeModelFilter)this.itemTreeView.Model;
|
||||
m.Refilter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,32 +45,13 @@ namespace Buypeeb {
|
|||
}
|
||||
}
|
||||
|
||||
public string priceJPY {
|
||||
get {
|
||||
return $"¥{this.price}";
|
||||
}
|
||||
}
|
||||
|
||||
public string winPriceJPY {
|
||||
get {
|
||||
return $"¥{this.winPrice}";
|
||||
}
|
||||
}
|
||||
|
||||
public string priceAUD {
|
||||
get {
|
||||
double aud = this.price / 75.0;
|
||||
return $"${aud:f2}";
|
||||
}
|
||||
}
|
||||
|
||||
public string winPriceAUD {
|
||||
get {
|
||||
double aud = this.winPrice / 75.0;
|
||||
return $"${aud:f2}";
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: don't serialise this stuff
|
||||
public string priceJPY { get { return $"¥{this.price}"; } }
|
||||
public string winPriceJPY { get { return $"¥{this.winPrice}"; } }
|
||||
public string priceAUD { get { return $"${(this.price / 75.0):f2}"; } }
|
||||
public string winPriceAUD { get { return $"${(this.winPrice / 75.0):f2}"; } }
|
||||
public bool endingToday { get { return this.endDate.DayOfYear == DateTime.UtcNow.DayOfYear; } }
|
||||
public bool hasWinPrice { get { return this.winPrice != 0; } }
|
||||
private bool success { get; set; } // TODO: custom setter that throws an exception if set to false or something idk
|
||||
|
||||
public YahooAuctionsItem(string id, string name) {
|
||||
|
@ -129,5 +110,9 @@ namespace Buypeeb {
|
|||
this.autoExtension = (m.Groups[1].Value == "あり");
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return $"{this.id}: {this.name}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
225
ui/main.glade
225
ui/main.glade
|
@ -3,6 +3,171 @@
|
|||
<interface>
|
||||
<requires lib="gtk+" version="3.22"/>
|
||||
<object class="GtkTextBuffer" id="TextBufferSelectedNotes"/>
|
||||
<object class="GtkPopover" id="popover1">
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_start">5</property>
|
||||
<property name="margin_end">5</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">3</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="label" translatable="yes">Items to hide:</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="CheckButtonFilterFavourites">
|
||||
<property name="label" translatable="yes">Favourites</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="RunFilter" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="CheckButtonFilterNonFavourites">
|
||||
<property name="label" translatable="yes">Non-favourites</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="RunFilter" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="CheckButtonFilterActive">
|
||||
<property name="label" translatable="yes">Active</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="RunFilter" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="CheckButtonFilterEnded">
|
||||
<property name="label" translatable="yes">Ended</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="RunFilter" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="CheckButtonFilterEndingToday">
|
||||
<property name="label" translatable="yes">Ending today</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="RunFilter" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="CheckButtonFilterEndingAfterToday">
|
||||
<property name="label" translatable="yes">Ending after today</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="RunFilter" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="CheckButtonFilterWithWinPrice">
|
||||
<property name="label" translatable="yes">With win price</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="RunFilter" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">7</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="CheckButtonFilterWithNoWinPrice">
|
||||
<property name="label" translatable="yes">With no win price</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="RunFilter" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">8</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Show all</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">9</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkWindow" id="wndMain">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="default_width">810</property>
|
||||
|
@ -278,6 +443,58 @@
|
|||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_start">3</property>
|
||||
<property name="margin_end">3</property>
|
||||
<property name="spacing">3</property>
|
||||
<child>
|
||||
<object class="GtkSearchEntry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="primary_icon_name">edit-find-symbolic</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="primary_icon_sensitive">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="popover">popover1</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
|
@ -291,6 +508,7 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="rules_hint">True</property>
|
||||
<property name="enable_search">False</property>
|
||||
<property name="search_column">1</property>
|
||||
<property name="activate_on_single_click">True</property>
|
||||
<child internal-child="selection">
|
||||
|
@ -357,6 +575,13 @@
|
|||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">True</property>
|
||||
<property name="shrink">True</property>
|
||||
|
|
Loading…
Reference in a new issue