diff options
author | David Robillard <d@drobilla.net> | 2008-08-22 03:26:33 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2008-08-22 03:26:33 +0000 |
commit | 4637ceb876904731d2628563e96a89961f9b7781 (patch) | |
tree | b20bd41c8fcdee1b8a5e76a0aa4a3ca213f82473 /src/ProjectList.cpp | |
parent | 503944e72ce146e5bed2556e7b2caa5a41edd7ea (diff) | |
download | patchage-4637ceb876904731d2628563e96a89961f9b7781.tar.gz patchage-4637ceb876904731d2628563e96a89961f9b7781.tar.bz2 patchage-4637ceb876904731d2628563e96a89961f9b7781.zip |
Lash D-Bus support and projects list from LADI Patchage, with improvements/cleanup/sanification/etc.
Remove liblash stuff (meh, what the hell... here's to new beginnings).
Enable/disable/hide/etc patchage widgets better based on available (compiled in) functionality.
git-svn-id: http://svn.drobilla.net/lad/patchage@1462 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/ProjectList.cpp')
-rw-r--r-- | src/ProjectList.cpp | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/src/ProjectList.cpp b/src/ProjectList.cpp new file mode 100644 index 0000000..4b87e31 --- /dev/null +++ b/src/ProjectList.cpp @@ -0,0 +1,305 @@ +// -*- Mode: C++ ; indent-tabs-mode: t -*- +/* This file is part of Patchage. + * Copyright (C) 2008 Nedko Arnaudov <nedko@arnaudov.name> + * + * Patchage 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. + * + * Patchage 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 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., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <iostream> +#include <gtkmm.h> +#include <libglademm/xml.h> + +#include "ProjectList.hpp" +#include "Widget.hpp" +#include "Session.hpp" +#include "Project.hpp" +#include "ProjectPropertiesDialog.hpp" +#include "LashClient.hpp" +#include "LashProxy.hpp" + +using boost::shared_ptr; +using namespace std; + +struct ProjectList_column_record : public Gtk::TreeModel::ColumnRecord { + Gtk::TreeModelColumn<Glib::ustring> name; + Gtk::TreeModelColumn< shared_ptr<Project> > project; +}; + +struct ProjectListImpl : public sigc::trackable { + Patchage* _app; + Widget<Gtk::TreeView> _widget; + ProjectList_column_record _columns; + Glib::RefPtr<Gtk::TreeStore> _model; + Gtk::Menu _menu_popup; + + ProjectListImpl( + Glib::RefPtr<Gnome::Glade::Xml> xml, + Patchage* app); + + void project_added(shared_ptr<Project> project); + void project_closed(shared_ptr<Project> project); + void project_renamed(Gtk::TreeModel::iterator iter); + void client_added(shared_ptr<LashClient> client, Gtk::TreeModel::iterator iter); + void client_removed(shared_ptr<LashClient> client, Gtk::TreeModel::iterator iter); + + bool on_button_press_event(GdkEventButton * event); + + void on_menu_popup_load_project(); + void on_menu_popup_save_all_projects(); + void on_menu_popup_save_project(shared_ptr<Project> project); + void on_menu_popup_close_project(shared_ptr<Project> project); + void on_menu_popup_project_properties(shared_ptr<Project> project); + void on_menu_popup_close_all_projects(); +}; + +ProjectList::ProjectList( + Patchage* app, + Session* session) +{ + _impl = new ProjectListImpl(app->xml(), app); + session->_signal_project_added.connect(mem_fun(_impl, &ProjectListImpl::project_added)); + session->_signal_project_closed.connect(mem_fun(_impl, &ProjectListImpl::project_closed)); +} + +ProjectList::~ProjectList() +{ + delete _impl; +} + +ProjectListImpl::ProjectListImpl(Glib::RefPtr<Gnome::Glade::Xml> xml, Patchage* app) + : _app(app) + , _widget(xml, "projects_list") +{ + _columns.add(_columns.name); + _columns.add(_columns.project); + + _model = Gtk::TreeStore::create(_columns); + _widget->set_model(_model); + + _widget->append_column("LASH projects", _columns.name); + + _menu_popup.accelerate(*_widget); + + _widget->signal_button_press_event().connect(sigc::mem_fun(*this, &ProjectListImpl::on_button_press_event), false); +} + +bool +ProjectListImpl::on_button_press_event(GdkEventButton* event) +{ + // Then do our custom stuff: + if (event->type == GDK_BUTTON_PRESS && event->button == 3) { + Glib::RefPtr<Gtk::TreeView::Selection> selection = _widget->get_selection(); + + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn * column_ptr; + int cell_x; + int cell_y; + + Gtk::Menu::MenuList& menulist = _menu_popup.items(); + + menulist.clear(); + + menulist.push_back(Gtk::Menu_Helpers::MenuElem("_Load project...", sigc::mem_fun(*this, &ProjectListImpl::on_menu_popup_load_project))); + + menulist.push_back(Gtk::Menu_Helpers::MenuElem("Save _all projects", sigc::mem_fun(*this, &ProjectListImpl::on_menu_popup_save_all_projects))); + + if (_widget->get_path_at_pos((int)event->x, (int)event->y, path, column_ptr, cell_x, cell_y)) { + //cout << path.to_string() << endl; + selection->unselect_all(); + selection->select(path); + + Gtk::TreeIter iter = selection->get_selected(); + shared_ptr<Project> project = (*iter)[_columns.project]; + + if (project) { + const string& name = project->get_name(); + + menulist.push_back(Gtk::Menu_Helpers::MenuElem( + (string)"_Save project '" + name + "'", + sigc::bind( + sigc::mem_fun(*this, + &ProjectListImpl::on_menu_popup_save_project), + project))); + + menulist.push_back(Gtk::Menu_Helpers::MenuElem( + (string)"_Close project '" + name + "'", + sigc::bind( + sigc::mem_fun(*this, + &ProjectListImpl::on_menu_popup_close_project), + project))); + + menulist.push_back(Gtk::Menu_Helpers::MenuElem( + (string)"_Project '" + name + "' properties", + sigc::bind( + sigc::mem_fun(*this, + &ProjectListImpl::on_menu_popup_project_properties), + project))); + } + } else { + //cout << "No row" << endl; + selection->unselect_all(); + } + + menulist.push_back(Gtk::Menu_Helpers::MenuElem("Cl_ose all projects", sigc::mem_fun(*this, &ProjectListImpl::on_menu_popup_close_all_projects))); + + _menu_popup.popup(event->button, event->time); + + return true; + } + + return false; +} + +void +ProjectListImpl::on_menu_popup_load_project() +{ + _app->show_load_project_dialog(); +} + +void +ProjectListImpl::on_menu_popup_save_all_projects() +{ + _app->lash_proxy()->save_all_projects(); +} + +void +ProjectListImpl::on_menu_popup_save_project(shared_ptr<Project> project) +{ + _app->lash_proxy()->save_project(project->get_name()); +} + +void +ProjectListImpl::on_menu_popup_close_project(shared_ptr<Project> project) +{ + _app->lash_proxy()->close_project(project->get_name()); +} + +void +ProjectListImpl::on_menu_popup_project_properties(shared_ptr<Project> project) +{ + ProjectPropertiesDialog dialog(_app->xml()); + dialog.run(project); +} + +void +ProjectListImpl::on_menu_popup_close_all_projects() +{ + _app->lash_proxy()->close_all_projects(); +} + +void +ProjectListImpl::project_added( + shared_ptr<Project> project) +{ + Gtk::TreeModel::iterator iter; + Gtk::TreeModel::iterator child_iter; + Gtk::TreeModel::Row row; + string project_name = project->get_name(); + + if (project->get_modified_status()) { + project_name += " *"; + } + + iter = _model->append(); + row = *iter; + row[_columns.name] = project_name; + row[_columns.project] = project; + + project->_signal_renamed.connect(bind(mem_fun(this, &ProjectListImpl::project_renamed), iter)); + project->_signal_modified_status_changed.connect(bind(mem_fun(this, &ProjectListImpl::project_renamed), iter)); + project->_signal_client_added.connect(bind(mem_fun(this, &ProjectListImpl::client_added), iter)); + project->_signal_client_removed.connect(bind(mem_fun(this, &ProjectListImpl::client_removed), iter)); +} + +void +ProjectListImpl::project_closed( + shared_ptr<Project> project) +{ + shared_ptr<Project> temp_project; + Gtk::TreeModel::Children children = _model->children(); + Gtk::TreeModel::Children::iterator iter = children.begin(); + + while (iter != children.end()) { + Gtk::TreeModel::Row row = *iter; + + temp_project = row[_columns.project]; + + if (temp_project == project) { + _model->erase(iter); + return; + } + + iter++; + } +} + +void +ProjectListImpl::project_renamed( + Gtk::TreeModel::iterator iter) +{ + shared_ptr<Project> project; + + Gtk::TreeModel::Row row = *iter; + + project = row[_columns.project]; + string project_name = project->get_name(); + + if (project->get_modified_status()) + project_name += " *"; + + row[_columns.name] = project_name; +} + +void +ProjectListImpl::client_added( + shared_ptr<LashClient> client, + Gtk::TreeModel::iterator iter) +{ + Gtk::TreeModel::Path path = _model->get_path(iter); + Gtk::TreeModel::Row row = *iter; + + iter = _model->append(row.children()); + row = *iter; + row[_columns.name] = client->get_name(); + + _widget->expand_row(path, false); +} + +void +ProjectListImpl::client_removed( + shared_ptr<LashClient> client, + Gtk::TreeModel::iterator iter) +{ + Gtk::TreeModel::Path path = _model->get_path(iter); + Gtk::TreeModel::Row row = *iter; + + Gtk::TreeNodeChildren childs = row.children(); + + for (Gtk::TreeModel::iterator child_iter = childs.begin(); iter != childs.end(); child_iter++) { + row = *child_iter; + + if (row[_columns.name] == client->get_name()) { + _widget->expand_row(path, false); + _model->erase(child_iter); + return; + } + } +} + +void +ProjectList::set_lash_available(bool lash_active) +{ + _impl->_widget->set_sensitive(lash_active); +} + |