daemon: fix memory leak (virtualizer struct)
[ladish.git] / gui / load_projects_dialog.cpp
blobd93a817c85931cadcb49eacb5f12fb37945da34a
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2008 Dave Robillard <dave@drobilla.net>
6 * Copyright (C) 2008 Nedko Arnaudov <nedko@arnaudov.name>
8 **************************************************************************
9 * This file contains implementation of the load project dialog
10 **************************************************************************
12 * LADI Session Handler is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * LADI Session Handler is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
24 * or write to the Free Software Foundation, Inc.,
25 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include "common.h"
29 #include "lash_proxy.hpp"
30 #include "load_projects_dialog.hpp"
31 #include "Patchage.hpp"
32 #include "globals.hpp"
34 struct LoadProjectDialog
36 LoadProjectDialog();
38 void run(std::list<lash_project_info>& projects);
40 void load_selected_project();
41 bool on_button_press_event(GdkEventButton* event_ptr);
42 bool on_key_press_event(GdkEventKey* event_ptr);
44 int mtime_sorter(Gtk::TreeModel::iterator a, Gtk::TreeModel::iterator b);
46 struct Record : public Gtk::TreeModel::ColumnRecord
48 Gtk::TreeModelColumn<Glib::ustring> name;
49 Gtk::TreeModelColumn<Glib::ustring> modified;
50 Gtk::TreeModelColumn<Glib::ustring> description;
51 Gtk::TreeModelColumn<time_t> mtime;
54 Widget<Gtk::Dialog> _dialog;
55 Widget<Gtk::TreeView> _widget;
56 Record _columns;
57 Glib::RefPtr<Gtk::ListStore> _model;
60 static
61 void
62 convert_timestamp_to_string(
63 const time_t timestamp,
64 std::string& timestamp_string)
66 GDate mtime, now;
67 gint days_diff;
68 struct tm tm_mtime;
69 time_t time_now;
70 const gchar *format;
71 gchar buf[256];
73 if (timestamp == 0)
75 timestamp_string = "Unknown";
76 return;
79 localtime_r(&timestamp, &tm_mtime);
81 g_date_set_time_t(&mtime, timestamp);
82 time_now = time(NULL);
83 g_date_set_time_t(&now, time_now);
85 days_diff = g_date_get_julian(&now) - g_date_get_julian(&mtime);
87 if (days_diff == 0)
89 format = "Today at %H:%M";
91 else if (days_diff == 1)
93 format = "Yesterday at %H:%M";
95 else
97 if (days_diff > 1 && days_diff < 7)
99 format = "%A"; /* Days from last week */
101 else
103 format = "%x"; /* Any other date */
107 if (strftime(buf, sizeof(buf), format, &tm_mtime) != 0)
109 timestamp_string = buf;
111 else
113 timestamp_string = "Unknown";
118 LoadProjectDialog::LoadProjectDialog()
119 : _dialog(g_xml, "load_project_dialog")
120 , _widget(g_xml, "loadable_projects_list")
122 _dialog.init(g_xml, "load_project_dialog");
123 _widget.init(g_xml, "loadable_projects_list");
125 _columns.add(_columns.name);
126 _columns.add(_columns.modified);
127 _columns.add(_columns.description);
128 _columns.add(_columns.mtime);
130 _model = Gtk::ListStore::create(_columns);
131 _widget->set_model(_model);
133 _widget->remove_all_columns();
135 _widget->append_column("Project Name", _columns.name);
136 _widget->get_column(0)->set_sort_column(_columns.name);
138 _widget->append_column("Modified", _columns.modified);
139 _model->set_sort_func(_columns.modified, sigc::mem_fun(this, &LoadProjectDialog::mtime_sorter));
140 _widget->get_column(1)->set_sort_column(_columns.modified);
141 _model->set_sort_column(_columns.modified, Gtk::SORT_ASCENDING);
143 _widget->append_column("Description", _columns.description);
144 _widget->get_column(2)->set_sort_column(_columns.description);
148 LoadProjectDialog::mtime_sorter(Gtk::TreeModel::iterator a, Gtk::TreeModel::iterator b)
150 time_t ta = (*a)[_columns.mtime];
151 time_t tb = (*b)[_columns.mtime];
153 return ta > tb ? -1 : (ta == tb ? 0 : 1);
156 void
157 LoadProjectDialog::run(std::list<lash_project_info>& projects)
159 Gtk::TreeModel::Row row;
160 int result;
162 for (std::list<lash_project_info>::iterator iter = projects.begin(); iter != projects.end(); iter++)
164 std::string str;
165 row = *(_model->append());
166 row[_columns.name] = iter->name;
167 convert_timestamp_to_string(iter->modification_time, str);
168 row[_columns.modified] = str;
169 row[_columns.description] = iter->description;
170 row[_columns.mtime] = iter->modification_time;
173 _widget->signal_button_press_event().connect(sigc::mem_fun(*this, &LoadProjectDialog::on_button_press_event), false);
174 _widget->signal_key_press_event().connect(sigc::mem_fun(*this, &LoadProjectDialog::on_key_press_event), false);
176 loop:
177 result = _dialog->run();
179 if (result == 2)
181 Glib::RefPtr<Gtk::TreeView::Selection> selection = _widget->get_selection();
182 Gtk::TreeIter iter = selection->get_selected();
183 if (!iter)
185 goto loop;
188 Glib::ustring project_name = (*iter)[_columns.name];
189 g_app->load_project(project_name);
192 _dialog->hide();
196 void
197 LoadProjectDialog::load_selected_project()
199 Glib::RefPtr<Gtk::TreeView::Selection> selection = _widget->get_selection();
200 Glib::ustring name = (*selection->get_selected())[_columns.name];
201 g_app->load_project(name);
202 _dialog->hide();
206 bool
207 LoadProjectDialog::on_button_press_event(GdkEventButton * event_ptr)
209 if (event_ptr->type == GDK_2BUTTON_PRESS && event_ptr->button == 1)
211 load_selected_project();
212 return true;
214 return false;
218 bool
219 LoadProjectDialog::on_key_press_event(GdkEventKey * event_ptr)
221 if (event_ptr->type == GDK_KEY_PRESS &&
222 (event_ptr->keyval == GDK_Return ||
223 event_ptr->keyval == GDK_KP_Enter))
225 load_selected_project();
226 return true;
229 return false;
232 void run_load_project_dialog(std::list<lash_project_info>& projects)
234 LoadProjectDialog dialog;
235 dialog.run(projects);