|
|
@ -1,16 +1,6 @@
|
|
|
|
#include <cstring>
|
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// every day is assert day
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
|
|
|
#include <cassert>
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
#define NDEBUG
|
|
|
|
|
|
|
|
#include <cassert>
|
|
|
|
|
|
|
|
#undef NDEBUG
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
#include <cassert>
|
|
|
|
|
|
|
|
|
|
|
|
#include "graph_browser.hpp"
|
|
|
|
#include "graph_browser.hpp"
|
|
|
|
|
|
|
|
|
|
|
@ -29,10 +19,13 @@ namespace {
|
|
|
|
return s;
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::string toCommaSeparatedList(const std::vector<std::string>& v)
|
|
|
|
std::string toCommaSeparatedList(const std::vector<std::string>& v, const std::string& skip)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::string s;
|
|
|
|
std::string s;
|
|
|
|
for (size_t i = 0; i < v.size()-1; ++i) {
|
|
|
|
for (size_t i = 0; i < v.size()-1; ++i) {
|
|
|
|
|
|
|
|
if (v[i] == skip)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
s += v[i];
|
|
|
|
s += v[i];
|
|
|
|
s += ",";
|
|
|
|
s += ",";
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -64,14 +57,23 @@ namespace {
|
|
|
|
|
|
|
|
|
|
|
|
void GraphBrowser::init()
|
|
|
|
void GraphBrowser::init()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
assert(initscr());
|
|
|
|
int r = 0;
|
|
|
|
assert(cbreak() == OK);
|
|
|
|
WINDOW* w;
|
|
|
|
assert(noecho() == OK);
|
|
|
|
|
|
|
|
assert(keypad(stdscr, TRUE) == OK);
|
|
|
|
w = initscr();
|
|
|
|
|
|
|
|
assert(w);
|
|
|
|
|
|
|
|
r = cbreak();
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
r = noecho();
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
r = keypad(stdscr, TRUE);
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
|
|
|
|
//Needed to have ‘immediate’ ESC-Key behavior:
|
|
|
|
//Needed to have ‘immediate’ ESC-Key behavior:
|
|
|
|
if (getenv ("ESCDELAY") == NULL)
|
|
|
|
if (getenv ("ESCDELAY") == NULL) {
|
|
|
|
assert(set_escdelay(25) == OK);
|
|
|
|
r = set_escdelay(25);
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GraphBrowser::destroy()
|
|
|
|
void GraphBrowser::destroy()
|
|
|
@ -96,69 +98,99 @@ GraphBrowser::GraphBrowser(Graph<std::string>& g)
|
|
|
|
|
|
|
|
|
|
|
|
void GraphBrowser::initLayout()
|
|
|
|
void GraphBrowser::initLayout()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// window of the current node
|
|
|
|
int r;
|
|
|
|
menu_ = new_menu((ITEM **)0);
|
|
|
|
|
|
|
|
assert(menu_);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
current_win_ = newwin(window_height, current_window_width, 1, 0);
|
|
|
|
current_win_ = newwin(window_height, current_window_width, 1, 0);
|
|
|
|
assert(current_win_);
|
|
|
|
assert(current_win_);
|
|
|
|
assert(keypad(current_win_, TRUE) == OK);
|
|
|
|
r = keypad(current_win_, TRUE);
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
|
|
|
|
assert(set_menu_win(menu_, current_win_) == E_OK);
|
|
|
|
menu_ = new_menu((ITEM **)0);
|
|
|
|
|
|
|
|
assert(menu_);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r = set_menu_win(menu_, current_win_);
|
|
|
|
|
|
|
|
assert(r == E_OK);
|
|
|
|
menu_subwindow_ = derwin(current_win_, window_height-2, current_window_width-2, 1, 1);
|
|
|
|
menu_subwindow_ = derwin(current_win_, window_height-2, current_window_width-2, 1, 1);
|
|
|
|
assert(menu_subwindow_);
|
|
|
|
assert(menu_subwindow_);
|
|
|
|
assert(set_menu_sub(menu_, menu_subwindow_) == E_OK);
|
|
|
|
r = set_menu_sub(menu_, menu_subwindow_);
|
|
|
|
const int r = set_menu_format(menu_, window_height-2, 1);
|
|
|
|
assert(r == E_OK);
|
|
|
|
assert(set_menu_mark(menu_, " ") == E_OK);
|
|
|
|
r = set_menu_format(menu_, window_height-2, 1);
|
|
|
|
|
|
|
|
assert(r == E_OK); // @bug NOT connected
|
|
|
|
assert(wborder(current_win_,
|
|
|
|
r = set_menu_mark(menu_, " ");
|
|
|
|
ACS_VLINE, ACS_VLINE, ACS_HLINE, ACS_HLINE,
|
|
|
|
assert(r == E_OK);
|
|
|
|
ACS_ULCORNER, ACS_TTEE, ACS_LLCORNER, ACS_BTEE) == OK);
|
|
|
|
|
|
|
|
assert(refresh() == OK);
|
|
|
|
r = wborder(current_win_,
|
|
|
|
assert(wrefresh(current_win_) == OK);
|
|
|
|
ACS_VLINE, ACS_VLINE, ACS_HLINE, ACS_HLINE,
|
|
|
|
|
|
|
|
ACS_ULCORNER, ACS_TTEE, ACS_LLCORNER, ACS_BTEE);
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
r = refresh();
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
r = wrefresh(current_win_);
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
|
|
|
|
n_win_ = newwin(window_height, n_window_width, 1, current_window_width);
|
|
|
|
n_win_ = newwin(window_height, n_window_width, 1, current_window_width);
|
|
|
|
assert(n_win_);
|
|
|
|
assert(n_win_);
|
|
|
|
assert(wborder(n_win_,
|
|
|
|
r = wborder(n_win_,
|
|
|
|
' ', ' ', ACS_HLINE, ACS_HLINE,
|
|
|
|
' ', ' ', ACS_HLINE, ACS_HLINE,
|
|
|
|
ACS_HLINE, ACS_HLINE, ACS_HLINE, ACS_HLINE) == OK);
|
|
|
|
ACS_HLINE, ACS_HLINE, ACS_HLINE, ACS_HLINE);
|
|
|
|
assert(refresh() == OK);
|
|
|
|
assert(r == OK);
|
|
|
|
assert(wrefresh(n_win_) == OK);
|
|
|
|
r = refresh();
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
r = wrefresh(n_win_);
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
|
|
|
|
// window of the neighbours'neighbours of the current vertex
|
|
|
|
// window of the neighbours'neighbours of the current vertex
|
|
|
|
n_of_n_win_ = newwin(window_height, term_max_x_-current_window_width-n_window_width,
|
|
|
|
n_of_n_win_ = newwin(window_height, term_max_x_-current_window_width-n_window_width,
|
|
|
|
1, n_window_width+current_window_width);
|
|
|
|
1, n_window_width+current_window_width);
|
|
|
|
assert(n_of_n_win_);
|
|
|
|
assert(n_of_n_win_);
|
|
|
|
assert(wborder(n_of_n_win_,
|
|
|
|
r = wborder(n_of_n_win_,
|
|
|
|
ACS_VLINE, ACS_VLINE, ACS_HLINE, ACS_HLINE,
|
|
|
|
ACS_VLINE, ACS_VLINE, ACS_HLINE, ACS_HLINE,
|
|
|
|
ACS_TTEE, ACS_URCORNER, ACS_BTEE, ACS_LRCORNER) == OK);
|
|
|
|
ACS_TTEE, ACS_URCORNER, ACS_BTEE, ACS_LRCORNER);
|
|
|
|
assert(refresh() == OK);
|
|
|
|
assert(r == OK);
|
|
|
|
assert(wrefresh(n_of_n_win_) == OK);
|
|
|
|
r = refresh();
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
r = wrefresh(n_of_n_win_);
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
|
|
|
|
// bottom text
|
|
|
|
// bottom text
|
|
|
|
/// @note should we assert as a minimum width?
|
|
|
|
/// @note should we assert as a minimum width?
|
|
|
|
mvprintw(term_max_y_-1, 0, "ESC:exit, cursors:navigate, d/i:del/ins edge, D/I:del/ins node");
|
|
|
|
mvprintw(term_max_y_-1, 0, "ESC:exit, cursors:navigate, d/i:del/ins edge, D/I:del/ins node");
|
|
|
|
assert(refresh() == OK);
|
|
|
|
r = refresh();
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GraphBrowser::cleanUp()
|
|
|
|
void GraphBrowser::cleanUp()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
assert(endwin() == OK);
|
|
|
|
int r;
|
|
|
|
assert(refresh() == OK);
|
|
|
|
|
|
|
|
assert(clear() == OK);
|
|
|
|
r = endwin();
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
r = refresh();
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
r = clear();
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
|
|
|
|
ITEM** old_items = menu_items(menu_);
|
|
|
|
ITEM** old_items = menu_items(menu_);
|
|
|
|
const int old_items_count = item_count(menu_);
|
|
|
|
const int old_items_count = item_count(menu_);
|
|
|
|
if (old_items_count > 0)
|
|
|
|
if (old_items_count > 0) {
|
|
|
|
assert(unpost_menu(menu_) == E_OK);
|
|
|
|
r = unpost_menu(menu_);
|
|
|
|
assert(free_menu(menu_) == E_OK);
|
|
|
|
assert(r == E_OK);
|
|
|
|
for (int i = 0; i < old_items_count; ++i)
|
|
|
|
}
|
|
|
|
assert(free_item(old_items[i]) == E_OK);
|
|
|
|
r = free_menu(menu_);
|
|
|
|
|
|
|
|
assert(r == E_OK);
|
|
|
|
assert(delwin(menu_subwindow_) == OK);
|
|
|
|
for (int i = 0; i < old_items_count; ++i) {
|
|
|
|
assert(delwin(current_win_) == OK);
|
|
|
|
r = free_item(old_items[i]);
|
|
|
|
assert(delwin(n_win_) == OK);
|
|
|
|
assert(r == E_OK);
|
|
|
|
assert(delwin(n_of_n_win_) == OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r = delwin(menu_subwindow_);
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
r = delwin(current_win_);
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
r = delwin(n_win_);
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
r = delwin(n_of_n_win_);
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GraphBrowser::~GraphBrowser()
|
|
|
|
GraphBrowser::~GraphBrowser()
|
|
|
@ -277,19 +309,26 @@ void GraphBrowser::updateCurrent(const std::string& s, bool first_run)
|
|
|
|
addItems(n, first_run);
|
|
|
|
addItems(n, first_run);
|
|
|
|
updateNeighbours();
|
|
|
|
updateNeighbours();
|
|
|
|
|
|
|
|
|
|
|
|
assert(mvprintw(0, 0, "%s",std::string(term_max_x_,' ').c_str()) == OK);
|
|
|
|
int r;
|
|
|
|
assert(mvprintw(0, 0, historyToString(history_, term_max_x_).c_str()) == OK);
|
|
|
|
r = mvprintw(0, 0, "%s",std::string(term_max_x_,' ').c_str());
|
|
|
|
refresh();
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
r = mvprintw(0, 0, historyToString(history_, term_max_x_).c_str());
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r = refresh();
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GraphBrowser::updateNeighbours()
|
|
|
|
void GraphBrowser::updateNeighbours()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
int r;
|
|
|
|
const size_t n_width = n_window_width-1;
|
|
|
|
const size_t n_width = n_window_width-1;
|
|
|
|
const size_t n_of_n_width = term_max_x_-current_window_width-n_window_width-2;
|
|
|
|
const size_t n_of_n_width = term_max_x_-current_window_width-n_window_width-2;
|
|
|
|
for (int i = 1; i < window_height-1; ++i) {
|
|
|
|
for (int i = 1; i < window_height-1; ++i) {
|
|
|
|
assert(mvwprintw(n_win_, i, 1, "%s", std::string(n_width,' ').c_str()) == OK);
|
|
|
|
r = mvwprintw(n_win_, i, 1, "%s", std::string(n_width,' ').c_str());
|
|
|
|
assert(mvwprintw(n_of_n_win_, i, 1, "%s", std::string(n_of_n_width,' ').c_str()) == OK);
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
r = mvwprintw(n_of_n_win_, i, 1, "%s", std::string(n_of_n_width,' ').c_str());
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ITEM* c_item = current_item(menu_);
|
|
|
|
ITEM* c_item = current_item(menu_);
|
|
|
@ -298,29 +337,35 @@ void GraphBrowser::updateNeighbours()
|
|
|
|
const std::vector<std::string>& n = graph_.neighboursOf(current);
|
|
|
|
const std::vector<std::string>& n = graph_.neighboursOf(current);
|
|
|
|
for (size_t i = 0; i < n.size() && i < window_height-2; ++i) {
|
|
|
|
for (size_t i = 0; i < n.size() && i < window_height-2; ++i) {
|
|
|
|
const size_t n_win_w = std::min(n[i].length(), n_width);
|
|
|
|
const size_t n_win_w = std::min(n[i].length(), n_width);
|
|
|
|
assert(mvwprintw(n_win_, i+1, 1, std::string(n[i], 0, n_win_w).c_str()) == OK);
|
|
|
|
r = mvwprintw(n_win_, i+1, 1, std::string(n[i], 0, n_win_w).c_str());
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
|
|
|
|
const std::vector<std::string>& n_of_n = graph_.neighboursOf(n[i]);
|
|
|
|
const std::vector<std::string>& n_of_n = graph_.neighboursOf(n[i]);
|
|
|
|
const std::string n_of_n_string = toCommaSeparatedList(n_of_n);
|
|
|
|
const std::string n_of_n_string = toCommaSeparatedList(n_of_n, current);
|
|
|
|
const size_t n_of_n_win__w = std::min(n_of_n_string.length(), n_of_n_width-1);
|
|
|
|
const size_t n_of_n_win__w = std::min(n_of_n_string.length(), n_of_n_width-1);
|
|
|
|
assert(mvwprintw(n_of_n_win_, i+1, 2,
|
|
|
|
r = mvwprintw(n_of_n_win_, i+1, 2,
|
|
|
|
std::string(n_of_n_string, 0, n_of_n_win__w).c_str()) == OK);
|
|
|
|
std::string(n_of_n_string, 0, n_of_n_win__w).c_str());
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
assert(wrefresh(n_win_) == E_OK);
|
|
|
|
r = wrefresh(n_win_);
|
|
|
|
assert(wrefresh(n_of_n_win_) == E_OK);
|
|
|
|
assert(r == E_OK);
|
|
|
|
|
|
|
|
r = wrefresh(n_of_n_win_);
|
|
|
|
|
|
|
|
assert(r == E_OK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GraphBrowser::addItems(const std::vector<std::string>& stringVector, bool first_run)
|
|
|
|
void GraphBrowser::addItems(const std::vector<std::string>& stringVector, bool first_run)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
|
|
// keep pointed to deallocate old items
|
|
|
|
// keep pointed to deallocate old items
|
|
|
|
ITEM** old_items = menu_items(menu_);
|
|
|
|
ITEM** old_items = menu_items(menu_);
|
|
|
|
const int old_items_count = item_count(menu_);
|
|
|
|
const int old_items_count = item_count(menu_);
|
|
|
|
|
|
|
|
|
|
|
|
if (old_items_count > 0) {
|
|
|
|
if (old_items_count > 0) {
|
|
|
|
const int u = unpost_menu(menu_);
|
|
|
|
r = unpost_menu(menu_);
|
|
|
|
assert (u == E_OK || first_run && u == E_NOT_POSTED);
|
|
|
|
assert (r == E_OK || first_run && r == E_NOT_POSTED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const int number_of_new_items = stringVector.size();
|
|
|
|
const int number_of_new_items = stringVector.size();
|
|
|
@ -333,17 +378,23 @@ void GraphBrowser::addItems(const std::vector<std::string>& stringVector, bool f
|
|
|
|
}
|
|
|
|
}
|
|
|
|
new_items[number_of_new_items] = 0; // terminating empty item
|
|
|
|
new_items[number_of_new_items] = 0; // terminating empty item
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert(set_menu_items(menu_, new_items) == E_OK);
|
|
|
|
r = set_menu_items(menu_, new_items);
|
|
|
|
|
|
|
|
assert(r == E_OK);
|
|
|
|
|
|
|
|
|
|
|
|
if (number_of_new_items > 0) {
|
|
|
|
if (number_of_new_items > 0) {
|
|
|
|
assert(set_menu_format(menu_, window_height-2, 1) == E_OK);
|
|
|
|
r = set_menu_format(menu_, window_height-2, 1);
|
|
|
|
assert(post_menu(menu_) == E_OK);
|
|
|
|
assert(r == E_OK);
|
|
|
|
|
|
|
|
r = post_menu(menu_);
|
|
|
|
|
|
|
|
assert(r == E_OK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert(wrefresh(current_win_) == OK);
|
|
|
|
r = wrefresh(current_win_);
|
|
|
|
|
|
|
|
assert(r == OK);
|
|
|
|
|
|
|
|
|
|
|
|
// deallocate old items
|
|
|
|
// deallocate old items
|
|
|
|
for (int i = 0; i < old_items_count; ++i)
|
|
|
|
for (int i = 0; i < old_items_count; ++i) {
|
|
|
|
assert(free_item(old_items[i]) == E_OK);
|
|
|
|
r = free_item(old_items[i]);
|
|
|
|
|
|
|
|
assert(r == E_OK);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GraphBrowser::updateDimensions()
|
|
|
|
void GraphBrowser::updateDimensions()
|
|
|
|