summaryrefslogtreecommitdiffstats
path: root/src/gui/LoadGraphWindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/LoadGraphWindow.cpp')
-rw-r--r--src/gui/LoadGraphWindow.cpp257
1 files changed, 257 insertions, 0 deletions
diff --git a/src/gui/LoadGraphWindow.cpp b/src/gui/LoadGraphWindow.cpp
new file mode 100644
index 00000000..a8bbd94a
--- /dev/null
+++ b/src/gui/LoadGraphWindow.cpp
@@ -0,0 +1,257 @@
+/*
+ This file is part of Ingen.
+ Copyright 2007-2015 David Robillard <http://drobilla.net/>
+
+ Ingen is free software: you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free
+ Software Foundation, either version 3 of the License, or any later version.
+
+ Ingen 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 Affero General Public License for details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Ingen. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <cassert>
+#include <list>
+#include <string>
+
+#include <boost/optional.hpp>
+#include <glibmm/miscutils.h>
+
+#include "ingen/Configuration.hpp"
+#include "ingen/Interface.hpp"
+#include "ingen/client/BlockModel.hpp"
+#include "ingen/client/ClientStore.hpp"
+#include "ingen/client/GraphModel.hpp"
+#include "ingen/runtime_paths.hpp"
+
+#include "App.hpp"
+#include "GraphView.hpp"
+#include "LoadGraphWindow.hpp"
+#include "Style.hpp"
+#include "ThreadedLoader.hpp"
+
+namespace ingen {
+
+using namespace client;
+
+namespace gui {
+
+LoadGraphWindow::LoadGraphWindow(BaseObjectType* cobject,
+ const Glib::RefPtr<Gtk::Builder>& xml)
+ : Gtk::FileChooserDialog(cobject)
+ , _app(nullptr)
+ , _merge_ports(false)
+{
+ xml->get_widget("load_graph_symbol_label", _symbol_label);
+ xml->get_widget("load_graph_symbol_entry", _symbol_entry);
+ xml->get_widget("load_graph_ports_label", _ports_label);
+ xml->get_widget("load_graph_merge_ports_radio", _merge_ports_radio);
+ xml->get_widget("load_graph_insert_ports_radio", _insert_ports_radio);
+ xml->get_widget("load_graph_poly_voices_radio", _poly_voices_radio);
+ xml->get_widget("load_graph_poly_from_file_radio", _poly_from_file_radio);
+ xml->get_widget("load_graph_poly_spinbutton", _poly_spinbutton);
+ xml->get_widget("load_graph_ok_button", _ok_button);
+ xml->get_widget("load_graph_cancel_button", _cancel_button);
+
+ _cancel_button->signal_clicked().connect(
+ sigc::mem_fun(this, &LoadGraphWindow::cancel_clicked));
+ _ok_button->signal_clicked().connect(
+ sigc::mem_fun(this, &LoadGraphWindow::ok_clicked));
+ _merge_ports_radio->signal_toggled().connect(
+ sigc::mem_fun(this, &LoadGraphWindow::merge_ports_selected));
+ _insert_ports_radio->signal_toggled().connect(
+ sigc::mem_fun(this, &LoadGraphWindow::insert_ports_selected));
+ _poly_from_file_radio->signal_toggled().connect(
+ sigc::bind(sigc::mem_fun(_poly_spinbutton, &Gtk::SpinButton::set_sensitive),
+ false));
+ _poly_voices_radio->signal_toggled().connect(
+ sigc::bind(sigc::mem_fun(_poly_spinbutton, &Gtk::SpinButton::set_sensitive),
+ true));
+
+ signal_selection_changed().connect(
+ sigc::mem_fun(this, &LoadGraphWindow::selection_changed));
+
+ Gtk::FileFilter file_filter;
+ file_filter.add_pattern("*.ttl");
+ file_filter.set_name("Ingen graph files (*.ttl)");
+ add_filter(file_filter);
+
+ Gtk::FileFilter bundle_filter;
+ bundle_filter.add_pattern("*.ingen");
+ bundle_filter.set_name("Ingen bundles (*.ingen)");
+ add_filter(bundle_filter);
+
+ property_select_multiple() = true;
+
+ // Add global examples directory to "shortcut folders" (bookmarks)
+ const FilePath examples_dir = ingen::data_file_path("graphs");
+ if (Glib::file_test(examples_dir, Glib::FILE_TEST_IS_DIR)) {
+ add_shortcut_folder(examples_dir.string());
+ }
+}
+
+void
+LoadGraphWindow::present(SPtr<const GraphModel> graph,
+ bool import,
+ Properties data)
+{
+ _import = import;
+ set_graph(graph);
+ _symbol_label->property_visible() = !import;
+ _symbol_entry->property_visible() = !import;
+ _ports_label->property_visible() = _import;
+ _merge_ports_radio->property_visible() = _import;
+ _insert_ports_radio->property_visible() = _import;
+ _initial_data = data;
+ Gtk::Window::present();
+}
+
+/** Sets the graph model for this window and initializes everything.
+ *
+ * This function MUST be called before using the window in any way!
+ */
+void
+LoadGraphWindow::set_graph(SPtr<const GraphModel> graph)
+{
+ _graph = graph;
+ _symbol_entry->set_text("");
+ _symbol_entry->set_sensitive(!_import);
+ _poly_spinbutton->set_value(graph->internal_poly());
+}
+
+void
+LoadGraphWindow::on_show()
+{
+ const Atom& dir = _app->world()->conf().option("graph-directory");
+ if (dir.is_valid()) {
+ set_current_folder(dir.ptr<char>());
+ }
+ Gtk::FileChooserDialog::on_show();
+}
+
+void
+LoadGraphWindow::merge_ports_selected()
+{
+ _merge_ports = true;
+}
+
+void
+LoadGraphWindow::insert_ports_selected()
+{
+ _merge_ports = false;
+}
+
+void
+LoadGraphWindow::ok_clicked()
+{
+ if (!_graph) {
+ hide();
+ return;
+ }
+
+ const URIs& uris = _app->uris();
+
+ if (_poly_voices_radio->get_active()) {
+ _initial_data.emplace(
+ uris.ingen_polyphony,
+ _app->forge().make(_poly_spinbutton->get_value_as_int()));
+ }
+
+ if (get_uri() == "") {
+ return;
+ }
+
+ if (_import) {
+ // If unset load_graph will load value
+ boost::optional<Raul::Path> parent;
+ boost::optional<Raul::Symbol> symbol;
+ if (!_graph->path().is_root()) {
+ parent = _graph->path().parent();
+ symbol = _graph->symbol();
+ }
+
+ _app->loader()->load_graph(
+ true, FilePath(get_filename()), parent, symbol, _initial_data);
+
+ } else {
+ std::list<Glib::ustring> uri_list = get_filenames();
+ for (auto u : uri_list) {
+ // Cascade
+ Atom& x = _initial_data.find(uris.ingen_canvasX)->second;
+ x = _app->forge().make(x.get<float>() + 20.0f);
+ Atom& y = _initial_data.find(uris.ingen_canvasY)->second;
+ y = _app->forge().make(y.get<float>() + 20.0f);
+
+ Raul::Symbol symbol(symbol_from_filename(u));
+ if (uri_list.size() == 1 && _symbol_entry->get_text() != "") {
+ symbol = Raul::Symbol::symbolify(_symbol_entry->get_text());
+ }
+
+ symbol = avoid_symbol_clash(symbol);
+
+ _app->loader()->load_graph(
+ false, FilePath(URI(u).path()), _graph->path(), symbol, _initial_data);
+ }
+ }
+
+ _graph.reset();
+ hide();
+
+ _app->world()->conf().set(
+ "graph-directory",
+ _app->world()->forge().alloc(get_current_folder()));
+}
+
+void
+LoadGraphWindow::cancel_clicked()
+{
+ _graph.reset();
+ hide();
+}
+
+Raul::Symbol
+LoadGraphWindow::symbol_from_filename(const Glib::ustring& filename)
+{
+ std::string symbol_str = Glib::path_get_basename(get_filename());
+ symbol_str = symbol_str.substr(0, symbol_str.find('.'));
+ return Raul::Symbol::symbolify(symbol_str);
+}
+
+Raul::Symbol
+LoadGraphWindow::avoid_symbol_clash(const Raul::Symbol& symbol)
+{
+ unsigned offset = _app->store()->child_name_offset(
+ _graph->path(), symbol);
+
+ if (offset != 0) {
+ std::stringstream ss;
+ ss << symbol << "_" << offset;
+ return Raul::Symbol(ss.str());
+ } else {
+ return symbol;
+ }
+}
+
+void
+LoadGraphWindow::selection_changed()
+{
+ if (_import) {
+ return;
+ }
+
+ if (get_filenames().size() != 1) {
+ _symbol_entry->set_text("");
+ _symbol_entry->set_sensitive(false);
+ } else {
+ _symbol_entry->set_text(
+ avoid_symbol_clash(symbol_from_filename(get_filename())).c_str());
+ _symbol_entry->set_sensitive(true);
+ }
+}
+
+} // namespace gui
+} // namespace ingen