<commit_before>#include "main_window.h"

#include <fstream>

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QAction>
#include <QHeaderView>
#include <QMenuBar>
#include <QAction>
#include <QMessageBox>
#include <QFileDialog>
#include <QDockWidget>
#include <QApplication>
#include <QDesktopWidget>

#include <bind.h>
#include <dependency_graph/attr.inl>
#include <dependency_graph/metadata.inl>
#include <dependency_graph/values.inl>
#include <dependency_graph/io/graph.h>

#include "adaptor.h"
#include "node_data.h"
#include "metadata.h"
#include "io/io.h"

namespace {

QAction* makeAction(QString title, std::function<void()> fn, QWidget* parent) {
	QAction* result = new QAction(title, parent);
	node_editor::qt_bind(result, SIGNAL(triggered(bool)), fn);
	return result;
}

}

MainWindow::MainWindow() : QMainWindow(), m_nodeCounter(0) {
	// initialise the graph with some nodes (to be removed)
	{
		auto& add = m_graph.nodes().add(Metadata::instance("addition"), "add1");
		add.setBlindData(NodeData{QPointF(100, 20)});

		auto& mult = m_graph.nodes().add(Metadata::instance("multiplication"), "mult1");
		mult.setBlindData(NodeData{QPointF(300, 20)});

		add.port(2).connect(mult.port(0));
	}

	m_viewport = new Viewport();
	setCentralWidget(m_viewport);

	m_properties = new Properties();
	QDockWidget* propDock = new QDockWidget("Properties", this);
	propDock->setWidget(m_properties);
	addDockWidget(Qt::RightDockWidgetArea, propDock);

	m_adaptor = new Adaptor(&m_graph);
	auto geom = m_adaptor->sizeHint();
	geom.setWidth(QApplication::desktop()->screenGeometry().width() / 2 - 200);
	m_adaptor->setSizeHint(geom);

	QDockWidget* graphDock = new QDockWidget("Graph", this);
	graphDock->setWidget(m_adaptor);
	addDockWidget(Qt::LeftDockWidgetArea, graphDock);

	// connect the selection signal
	m_adaptor->scene().setNodeSelectionCallback(
	[&](std::set<std::reference_wrapper<node_editor::Node>, node_editor::GraphScene::NodeRefComparator> selection) {
		m_properties->show(m_adaptor->selectedNodes());
	}
	);

	// create the context click menu
	m_adaptor->setContextMenuPolicy(Qt::ActionsContextMenu);

	for(auto& m : Metadata::instances()) {
		m_adaptor->addAction(makeAction(("Add " + m.type() + " node").c_str(), [&m, this]() {
			QPointF pos = m_adaptor->mapToScene(m_adaptor->mapFromGlobal(QCursor::pos()));
			m_graph.nodes().add(m, m.type() + "_" + std::to_string(m_nodeCounter++), NodeData{pos});
		}, m_adaptor));
	}

	QAction* separator = new QAction(m_adaptor);
	separator->setSeparator(true);
	m_adaptor->addAction(separator);

	QAction* deleteAction = new QAction("Delete selected items", m_adaptor);
	deleteAction->setShortcut(QKeySequence::Delete);
	m_adaptor->addAction(deleteAction);
	node_editor::qt_bind(deleteAction, SIGNAL(triggered()), [this]() {
		m_adaptor->deleteSelected();
	});

	// drawing callback
	connect(m_viewport, SIGNAL(render(float)), this, SLOT(draw(float)));<commit_msg>Structured menu for adding nodes, based on splitting type names by /<commit_after>#include "main_window.h"

#include <fstream>

#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QAction>
#include <QHeaderView>
#include <QMenuBar>
#include <QAction>
#include <QMessageBox>
#include <QFileDialog>
#include <QDockWidget>
#include <QApplication>
#include <QDesktopWidget>

#include <bind.h>
#include <dependency_graph/attr.inl>
#include <dependency_graph/metadata.inl>
#include <dependency_graph/values.inl>
#include <dependency_graph/io/graph.h>

#include "adaptor.h"
#include "node_data.h"
#include "metadata.h"
#include "io/io.h"

namespace {

QAction* makeAction(QString title, std::function<void()> fn, QWidget* parent) {
	QAction* result = new QAction(title, parent);
	node_editor::qt_bind(result, SIGNAL(triggered(bool)), fn);
	return result;
}

}

MainWindow::MainWindow() : QMainWindow(), m_nodeCounter(0) {
	// initialise the graph with some nodes (to be removed)
	{
		auto& add = m_graph.nodes().add(Metadata::instance("addition"), "add1");
		add.setBlindData(NodeData{QPointF(100, 20)});

		auto& mult = m_graph.nodes().add(Metadata::instance("multiplication"), "mult1");
		mult.setBlindData(NodeData{QPointF(300, 20)});

		add.port(2).connect(mult.port(0));
	}

	m_viewport = new Viewport();
	setCentralWidget(m_viewport);

	m_properties = new Properties();
	QDockWidget* propDock = new QDockWidget("Properties", this);
	propDock->setWidget(m_properties);
	addDockWidget(Qt::RightDockWidgetArea, propDock);

	m_adaptor = new Adaptor(&m_graph);
	auto geom = m_adaptor->sizeHint();
	geom.setWidth(QApplication::desktop()->screenGeometry().width() / 2 - 200);
	m_adaptor->setSizeHint(geom);

	QDockWidget* graphDock = new QDockWidget("Graph", this);
	graphDock->setWidget(m_adaptor);
	addDockWidget(Qt::LeftDockWidgetArea, graphDock);

	// connect the selection signal
	m_adaptor->scene().setNodeSelectionCallback(
	[&](std::set<std::reference_wrapper<node_editor::Node>, node_editor::GraphScene::NodeRefComparator> selection) {
		m_properties->show(m_adaptor->selectedNodes());
	}
	);

	// create the context click menu
	m_adaptor->setContextMenuPolicy(Qt::CustomContextMenu);

	{
		QMenu* contextMenu = new QMenu(m_adaptor);
		connect(m_adaptor, &Adaptor::customContextMenuRequested, [contextMenu, this](QPoint pos) {
			contextMenu->popup(m_adaptor->mapToGlobal(pos));
		});

		{
			std::map<std::string, QMenu*> groups;

			for(auto& m : Metadata::instances()) {
				std::vector<std::string> pieces;
				boost::split(pieces, m.type(), boost::algorithm::is_any_of("/"));

				QMenu* current = contextMenu;
				for(unsigned a=0;a<pieces.size()-1;++a) {
					if(groups[pieces[a]] == nullptr)
						groups[pieces[a]] = current->addMenu(pieces[a].c_str());

					current = groups[pieces[a]];
				}

				current->addAction(makeAction(pieces.back().c_str(), [&m, &pieces, this]() {
					QPointF pos = m_adaptor->mapToScene(m_adaptor->mapFromGlobal(QCursor::pos()));
					m_graph.nodes().add(m, pieces.back() + "_" + std::to_string(m_nodeCounter++), NodeData{pos});
				}, m_adaptor));
			}
		}

		QAction* separator = new QAction(m_adaptor);
		separator->setSeparator(true);
		contextMenu->addAction(separator);

		QAction* deleteAction = new QAction("Delete selected items", m_adaptor);
		deleteAction->setShortcut(QKeySequence::Delete);
		contextMenu->addAction(deleteAction);
		m_adaptor->addAction(deleteAction);
		node_editor::qt_bind(deleteAction, SIGNAL(triggered()), [this]() {
			m_adaptor->deleteSelected();
		});
	}

	// drawing callback
	connect(m_viewport, SIGNAL(render(float)), this, SLOT(draw(float)));
{'fraction_non_alphanumeric': 0.16483846731780616, 'fraction_numerical': 0.006010518407212622, 'mean_word_length': 6.606857142857143, 'pattern_counts': {'":': 0, '<': 48, '<?xml version=': 0, '>': 85, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5198616', 'n_tokens_mistral': 2532, 'n_tokens_neox': 2320, 'n_words': 395}