Horizon
column_chooser.hpp
1 #pragma once
2 #include <gtkmm.h>
3 #include "util/changeable.hpp"
4 
5 namespace horizon {
6 class ColumnChooser : public Gtk::Grid, public Changeable {
7 public:
8  class IAdapter {
9  public:
10  virtual std::string get_column_name(int col) const = 0;
11  virtual std::map<int, std::string> get_column_names() const = 0;
12  virtual std::vector<int> get_columns() const = 0;
13  virtual bool has_column(int col) const = 0;
14  virtual void include_column(int col) = 0;
15  virtual void exclude_column(int col) = 0;
16  virtual void move_column(int col, bool up) = 0;
17  };
18 
19  ColumnChooser(BaseObjectType *cobject, const Glib::RefPtr<Gtk::Builder> &x, IAdapter &adap);
20  static ColumnChooser *create(IAdapter &adap);
21 
22 
23  template <typename T> class Adapter : public IAdapter {
24  public:
25  Adapter(std::vector<T> &cols) : columns(cols)
26  {
27  }
28 
29  bool has_column(int col) const override
30  {
31  return std::count(columns.begin(), columns.end(), static_cast<T>(col));
32  };
33 
34  void include_column(int col) override
35  {
36  auto c = std::count(columns.begin(), columns.end(), static_cast<T>(col));
37 
38  if (c == 0)
39  columns.push_back(static_cast<T>(col));
40  }
41 
42  void exclude_column(int col) override
43  {
44  auto c = std::count(columns.begin(), columns.end(), static_cast<T>(col));
45  if (c != 0)
46  columns.erase(std::remove(columns.begin(), columns.end(), static_cast<T>(col)), columns.end());
47  }
48 
49  void move_column(int col, bool up) override
50  {
51  auto it = std::find(columns.begin(), columns.end(), static_cast<T>(col));
52  if (it == columns.end())
53  return;
54 
55  if (up && it == columns.begin()) // already at the top
56  return;
57 
58  if (!up && it == columns.end() - 1) // already at the bottom
59  return;
60 
61  auto it_other = it + (up ? -1 : +1);
62 
63  std::swap(*it_other, *it);
64  }
65 
66  std::vector<int> get_columns() const override
67  {
68  std::vector<int> r;
69  std::transform(columns.begin(), columns.end(), std::back_inserter(r),
70  [](auto x) { return static_cast<int>(x); });
71  return r;
72  }
73 
74  private:
75  std::vector<T> &columns;
76  };
77 
78 private:
79  IAdapter &adapter;
80 
81  class ListColumns : public Gtk::TreeModelColumnRecord {
82  public:
83  ListColumns()
84  {
85  Gtk::TreeModelColumnRecord::add(name);
86  Gtk::TreeModelColumnRecord::add(column);
87  }
88  Gtk::TreeModelColumn<int> column;
89  Gtk::TreeModelColumn<Glib::ustring> name;
90  };
91  ListColumns list_columns;
92 
93  Glib::RefPtr<Gtk::ListStore> columns_store;
94  Glib::RefPtr<Gtk::TreeModelFilter> columns_available;
95 
96  Glib::RefPtr<Gtk::ListStore> columns_store_included;
97 
98  Gtk::TreeView *cols_available_tv = nullptr;
99  Gtk::TreeView *cols_included_tv = nullptr;
100  Gtk::TreeView *preview_tv = nullptr;
101 
102  Gtk::Button *col_inc_button = nullptr;
103  Gtk::Button *col_excl_button = nullptr;
104  Gtk::Button *col_up_button = nullptr;
105  Gtk::Button *col_down_button = nullptr;
106 
107  void incl_excl_col(bool incl);
108  void up_down_col(bool up);
109  void update_incl_excl_sensitivity();
110  void update_cols_included();
111 };
112 } // namespace horizon