📄 wmain.cc
字号:
* initializing configuration * */void wmain::show(){ gtk_widget_show(_window);}void wmain::set_show_toolbar(bool show_toolbar){ _show_toolbar = show_toolbar; GtkWidget *toolbar = lookup_widget(_window, "toolbar1"); if (_show_toolbar) gtk_widget_show(toolbar); else gtk_widget_hide(toolbar); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(lookup_widget(_window, "menu_view_toolbar")), _show_toolbar);}/***** * * control socket connection * */void wmain::on_handler_create(handler_value *hv, bool was_empty){ if (was_empty) { // first load, read style const delt *e = _diagram->elt(hv->element_name()); ref_ptr<dhandler_style> dhs = ccss()->handler_style(this, e, hv); if (dhs) { hv->set_flags(this, (hv->flags() & ~dhs->flags_mask) | dhs->flags); if (dhs->autorefresh_period > 0 && dhs->autorefresh_period < hv->autorefresh_period()) hv->set_autorefresh_period(dhs->autorefresh_period); } } if (hv->notify_delt()) _diagram->notify_read(hv); crouter::on_handler_create(hv, was_empty);}void wmain::on_handler_read(const String &hname, const String &hparam, const String &hvalue, int status, messagevector &messages){ if (hname == "list") { _handlers->clear(); const char *s = hvalue.begin(); int line = 0, nelements = 0; while (s != hvalue.end()) { const char *x = s; while (x != hvalue.end() && !isspace((unsigned char) *x)) ++x; String name = hvalue.substring(s, x); // first line is count of elements if (++line == 1 && !cp_integer(name, &nelements)) /* syntax error */; else if (line > 1) _handlers->notify_element(name); for (s = x; s != hvalue.end() && isspace((unsigned char) *s); ) ++s; } } crouter::on_handler_read(hname, hparam, hvalue, status, messages);}void wmain::on_handler_read(handler_value *hv, bool changed){ if (changed && hv->notify_whandlers()) _handlers->notify_read(hv); if (hv->notify_delt(changed)) _diagram->notify_read(hv); crouter::on_handler_read(hv, changed);}void wmain::on_handler_write(const String &hname, const String &hvalue, int status, messagevector &messages){ _handlers->notify_write(hname, hvalue, status); crouter::on_handler_write(hname, hvalue, status, messages);}void wmain::on_handler_check_write(const String &hname, int status, messagevector &messages){ if (hname == "hotconfig" && status < 300) { // allow install handlers from now on gtk_widget_set_sensitive(lookup_widget(_window, "toolbar_install"), TRUE); gtk_widget_set_sensitive(lookup_widget(_window, "menu_install"), TRUE); } crouter::on_handler_check_write(hname, status, messages);}/***** * * element list * */void wmain::set_show_list(bool show_list){ _show_list = show_list; GtkWidget *errorpane = lookup_widget(_window, "errorpane"); if (_show_list) gtk_widget_show(errorpane); else gtk_widget_hide(errorpane); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(lookup_widget(_window, "menu_view_list")), _show_list);}void wmain::element_unhighlight(){ if (_element_highlight) { GtkTextIter i1, i2; gtk_text_buffer_get_start_iter(_config_buffer, &i1); gtk_text_buffer_get_end_iter(_config_buffer, &i2); gtk_text_buffer_remove_tag(_config_buffer, _config_element_highlight_tag, &i1, &i2); _element_highlight = 0; }}void wmain::element_show(String ename, int expand, bool incremental){ // check if element exists RouterT *r = router(); ScopeChain chain(r); ElementT *element = chain.push_element(ename); if (!element) ename = String(); if (_eview_name == ename && incremental) /* do not change existing widgets, but continue to potentially expand pane below */; else if (!r || !ename) { element_unhighlight(); _eview_name = String(); GtkLabel *l = GTK_LABEL(lookup_widget(_window, "eview_label")); gtk_label_set_text(l, "Element"); GtkWidget *n = lookup_widget(_window, "eview_elementbox"); gtk_widget_hide(n); n = lookup_widget(_window, "eview_classinfo_ports"); gtk_label_set_text(GTK_LABEL(n), ""); n = lookup_widget(_window, "eview_classinfo_processing"); gtk_label_set_text(GTK_LABEL(n), ""); n = lookup_widget(_window, "eview_classinfo_flow"); gtk_label_set_text(GTK_LABEL(n), ""); incremental = false; } else { element_unhighlight(); _eview_name = ename; ElementClassT *eclass = chain.resolved_type(element); String config = chain.resolved_config(element->config()); // set element name, class, and config GtkLabel *l = GTK_LABEL(lookup_widget(_window, "eview_label")); gtk_label_set_text(l, ename.c_str()); GtkWidget *n = lookup_widget(_window, "eview_class"); gtk_entry_set_text(GTK_ENTRY(n), element->type_name_c_str()); gtk_widget_show(gtk_widget_get_parent(n)); n = lookup_widget(_window, "eview_config"); GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(n)); gtk_text_buffer_set_text(buffer, config.data(), config.length()); ElementMap::push_default(element_map()); n = lookup_widget(_window, "eview_classinfo_ports"); gtk_label_set_text(GTK_LABEL(n), eclass->port_count_code().c_str()); n = lookup_widget(_window, "eview_classinfo_processing"); gtk_label_set_text(GTK_LABEL(n), eclass->processing_code().c_str()); n = lookup_widget(_window, "eview_classinfo_flow"); gtk_label_set_text(GTK_LABEL(n), element->flow_code().c_str()); ElementMap::pop_default(); // clear handlers n = lookup_widget(_window, "eview_refresh"); if (driver()) gtk_widget_show(n); else gtk_widget_hide(n); // highlight config and diagram if (element->landmarkt().offset1() != element->landmarkt().offset2() && expand >= 0 && _config_clean_elements) _element_highlight = element; } // expand and highlight whether or not viewed element changed if (expand != 0) { GtkWidget *n = lookup_widget(_window, "eviewbox"); if (expand > 0 && !GTK_WIDGET_VISIBLE(n)) { gtk_widget_show(n); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(lookup_widget(_window, "menu_view_element")), TRUE); GtkPaned *paned = GTK_PANED(lookup_widget(_window, "eviewpane")); if (GTK_WIDGET(paned)->allocation.width > 275) gtk_paned_set_position(paned, GTK_WIDGET(paned)->allocation.width - 225); else gtk_paned_set_position(paned, GTK_WIDGET(paned)->allocation.width - (guint) (GTK_WIDGET(paned)->allocation.width * 225. / 275.)); } else if (expand < 0) { gtk_widget_hide(n); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(lookup_widget(_window, "menu_view_element")), FALSE); } } // display in handlers _handlers->display(_eview_name, incremental); // highlight config if (_element_highlight && expand >= 0) { GtkTextIter i1, i2; gtk_text_buffer_get_iter_at_offset(_config_buffer, &i1, _element_highlight->landmarkt().offset1()); gtk_text_buffer_get_iter_at_offset(_config_buffer, &i2, _element_highlight->landmarkt().offset2()); gtk_text_buffer_apply_tag(_config_buffer, _config_element_highlight_tag, &i1, &i2); if (expand > 0) { gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(_config_view), &i2, 0, FALSE, 0, 0); gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(_config_view), &i1, 0, FALSE, 0, 0); } }}extern "C" {static void on_elementtree_row_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *, gpointer user_data){ wmain *rw = reinterpret_cast<wmain *>(user_data); GtkTreeIter iter; char *ename; GtkTreeModel *model = gtk_tree_view_get_model(treeview); if (gtk_tree_model_get_iter(model, &iter, path)) { gtk_tree_model_get(model, &iter, 1, &ename, -1); rw->element_show(ename, 1, true); rw->diagram()->element_show(ename, true); g_free(ename); }}static void on_elementtree_select(GtkTreeSelection *selection, gpointer user_data){ wmain *rw = reinterpret_cast<wmain *>(user_data); GtkTreeIter iter; GtkTreeModel *model; char *ename; if (gtk_tree_selection_get_selected(selection, &model, &iter)) { gtk_tree_model_get(model, &iter, 1, &ename, -1); rw->element_show(ename, 0, true); rw->diagram()->element_show(ename, false); g_free(ename); }}static void on_eview_close_clicked(GtkButton *button, gpointer){ gtk_widget_hide(lookup_widget(GTK_WIDGET(button), "eviewbox"));}static void on_eview_refresh_clicked(GtkButton *, gpointer user_data){ wmain *rw = reinterpret_cast<wmain *>(user_data); rw->handlers()->refresh_all(true);}}namespace {bool ename_sorter(const wmain::element_lister &a, const wmain::element_lister &b) { return click_strcmp(a.compound + a.name, b.compound + b.name) < 0;}bool eclass_sorter(const wmain::element_lister &a, const wmain::element_lister &b) { int c = click_strcmp(a.element->type_name(), b.element->type_name()); if (c == 0) return click_strcmp(a.name, b.name) < 0; else return c < 0;}}void wmain::fill_elements(RouterT *r, const String &compound, bool only_primitive, const VariableEnvironment &scope, Vector<element_lister> &v){ for (RouterT::iterator i = r->begin_elements(); i != r->end_elements(); ++i) { if (i->tunnel()) continue; element_lister el; el.compound = compound; el.name = i->name(); el.element = i; VariableEnvironment new_scope(0); ElementClassT *eclass = i->resolve(scope, &new_scope); RouterT *subr = eclass->cast_router(); if (!only_primitive || !subr) v.push_back(el); if (subr) fill_elements(subr, el.compound + el.name + "/", only_primitive, new_scope, v); }}Vector<wmain::element_lister>::iterator wmain::fill_elements_tree_store_helper(GtkTreeStore *store, GtkTreeIter *parent, Vector<element_lister>::iterator it, Vector<element_lister>::iterator end){ StringAccum sa1, sa2; GtkTreeIter li; gtk_tree_store_append(store, &li, parent); if (_elist_sort == elist_sort_class) sa1 << it->element->printable_type_name() << ' ' << it->compound << it->name; else sa1 << it->name << " :: " << it->element->printable_type_name(); sa2 << it->compound << it->name; gtk_tree_store_set(store, &li, 0, sa1.c_str(), 1, sa2.c_str(), -1); Vector<element_lister>::iterator next = it + 1; while (next != end && next->compound.length() > it->compound.length() && _elist_sort != elist_sort_class && next->compound == it->compound + it->name + "/") next = fill_elements_tree_store_helper(store, &li, next, end); return next;}void wmain::fill_elements_tree_store(GtkTreeStore *store, RouterT *r){ Vector<element_lister> v; fill_elements(r, "", (_elist_sort == elist_sort_class), VariableEnvironment(0), v); if (_elist_sort == elist_sort_name) std::sort(v.begin(), v.end(), ename_sorter); else if (_elist_sort == elist_sort_class) std::sort(v.begin(), v.end(), eclass_sorter); Vector<element_lister>::iterator it = v.begin(); while (it != v.end()) it = fill_elements_tree_store_helper(store, 0, it, v.end());}void wmain::element_tree_sort(int state){ if (state >= 0 && state <= 2 && _elist_sort == state) return; if (state >= 0 && state <= 2) _elist_sort = state; else _elist_sort = (_elist_sort + 1) % 3; GtkButton *b = GTK_BUTTON(lookup_widget(_window, "elementtreesort")); if (_elist_sort == elist_sort_none) gtk_button_set_label(b, "Sort: None"); else if (_elist_sort == elist_sort_name) gtk_button_set_label(b, "Sort: Name"); else if (_elist_sort == elist_sort_class) gtk_button_set_label(b, "Sort: Class"); gtk_tree_store_clear(_elist_store); fill_elements_tree_store(_elist_store, router());}void wmain::etree_fill() { // elements list _elist_view = GTK_TREE_VIEW(lookup_widget(_window, "elementtree")); if (!_elist_store) { GtkTreeViewColumn *col = gtk_tree_view_column_new(); gtk_tree_view_append_column(_elist_view, col); GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(col, renderer, TRUE); gtk_tree_view_column_add_attribute(col, renderer, "text", 0); _elist_store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_STRING); GtkTreeModel *model = GTK_TREE_MODEL(_elist_store); gtk_tree_view_set_model(_elist_view, model); g_object_unref(model); GtkTreeSelection *selection = gtk_tree_view_get_selection(_elist_view); gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); g_signal_connect(selection, "changed",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -