📄 wmain.cc
字号:
#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <click/config.h>#include "wmain.hh"#include "wdiagram.hh"#include "whandler.hh"#include "cdriver.hh"#include "dstyle.hh"#include "scopechain.hh"#include <clicktool/routert.hh>#include <clicktool/lexert.hh>#include <clicktool/lexertinfo.hh>#include <clicktool/toolutils.hh>#include <clicktool/elementmap.hh>#include <clicktool/processingt.hh>#include <click/straccum.hh>#include <click/confparse.hh>#include <click/pathvars.h>#include <math.h>#include <algorithm>#include <unistd.h>#include <fcntl.h>#include <sys/ioctl.h>extern "C" {#include "interface.h"#include "support.h"}namespace clicky {extern "C" {static void error_expanders_callback(GObject *, GParamSpec *, gpointer);static void on_eview_classexpander_expanded(GObject *, GParamSpec *, gpointer);static void elementtreesort_callback(GtkButton *, gpointer);static gboolean on_error_view_event(GtkWidget *, GdkEvent *, gpointer);}String wmain::last_savefile;static int num_main_windows = 0;extern "C" {static void destroy(gpointer data) { delete reinterpret_cast<wmain *>(data);}}wmain::wmain(bool show_toolbar, bool show_list, gint width, gint height) : _window(create_mainw()), _config_clean_errors(true), _config_clean_elements(true), _error_hover_tag(0), _error_highlight_tag(0), _error_endpos(0), _error_hover_index(-1), _config_error_highlight_tag(0), _error_highlight_index(-1), _error_highlight_x(-1), _error_highlight_y(-1), _error_scroller(0), _elist_view(0), _elist_store(0), _elist_sort(elist_sort_none), _config_element_highlight_tag(0), _element_highlight(0), _config_changed_signal(0), _binary_tag(0){ g_object_set_data_full(G_OBJECT(_window), "wmain", this, destroy); if (width != -1 || height != -1) gtk_window_set_default_size(GTK_WINDOW(_window), width, height); // settings set_show_toolbar(show_toolbar); set_show_list(show_list); // look up widgets _config_view = lookup_widget(_window, "configview"); _config_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(_config_view)); _error_view = lookup_widget(_window, "errorview"); _error_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(_error_view)); // cursors _normal_cursor = gdk_cursor_new(GDK_LEFT_PTR); gdk_cursor_ref(_normal_cursor); _link_cursor = gdk_cursor_new(GDK_HAND2); gdk_cursor_ref(_link_cursor); gtk_widget_realize(_error_view); gdk_window_set_cursor(gtk_text_view_get_window(GTK_TEXT_VIEW(_error_view), GTK_TEXT_WINDOW_TEXT), _normal_cursor); // signals g_signal_connect(lookup_widget(_window, "elementtreeexpander"), "notify::expanded", G_CALLBACK(error_expanders_callback), this); g_signal_connect(lookup_widget(_window, "errorviewexpander"), "notify::expanded", G_CALLBACK(error_expanders_callback), this); g_signal_connect(lookup_widget(_window, "eview_classexpander"), "notify::expanded", G_CALLBACK(on_eview_classexpander_expanded), this); gtk_widget_set_name(lookup_widget(_window, "eviewbox"), "eviewbox"); gtk_widget_set_name(lookup_widget(_window, "eview_titlebox"), "eview_titlebox"); g_signal_connect(lookup_widget(_window, "elementtreesort"), "clicked", G_CALLBACK(elementtreesort_callback), this); g_signal_connect(_error_view, "event", G_CALLBACK(on_error_view_event), this); gtk_widget_add_events(_error_view, GDK_LEAVE_NOTIFY_MASK); // label precision _bold_attr = pango_attr_list_new(); PangoAttribute *a = pango_attr_weight_new(PANGO_WEIGHT_BOLD); a->start_index = 0; a->end_index = G_MAXUINT; pango_attr_list_insert(_bold_attr, a); _small_attr = pango_attr_list_new(); a = pango_attr_scale_new(PANGO_SCALE_SMALL); a->start_index = 0; a->end_index = G_MAXUINT; pango_attr_list_insert(_small_attr, a); _small_bold_attr = pango_attr_list_new(); a = pango_attr_scale_new(PANGO_SCALE_SMALL); a->start_index = 0; a->end_index = G_MAXUINT; pango_attr_list_insert(_small_bold_attr, a); a = pango_attr_weight_new(PANGO_WEIGHT_BOLD); a->start_index = 0; a->end_index = G_MAXUINT; pango_attr_list_insert(_small_bold_attr, a); gtk_label_set_attributes(GTK_LABEL(lookup_widget(_window, "eview_label")), _bold_attr); gtk_label_set_attributes(GTK_LABEL(lookup_widget(_window, "eview_classinfo_ports")), _small_attr); gtk_label_set_attributes(GTK_LABEL(lookup_widget(_window, "eview_classinfo_processing")), _small_attr); gtk_label_set_attributes(GTK_LABEL(lookup_widget(_window, "eview_classinfo_flow")), _small_attr); // text tags for configuration (order is important for overriding) (void) gtk_text_buffer_create_tag(_config_buffer, "comment", "foreground", "grey50", NULL); (void) gtk_text_buffer_create_tag(_config_buffer, "keyword", "foreground", "blue", NULL); (void) gtk_text_buffer_create_tag(_config_buffer, "error", "foreground", "red", NULL); _config_element_highlight_tag = gtk_text_buffer_create_tag(_config_buffer, "element_current", "background", "dark blue", "foreground", "white", NULL); _config_error_highlight_tag = gtk_text_buffer_create_tag(_config_buffer, "error_current", "background", "red", "foreground", "white", "weight", PANGO_WEIGHT_BOLD, NULL); _error_hover_tag = gtk_text_buffer_create_tag(_error_buffer, "error_current", "underline", PANGO_UNDERLINE_SINGLE, "foreground", "red", NULL); _error_highlight_tag = gtk_text_buffer_create_tag(_error_buffer, "error_highlight", "foreground", "red", NULL); _binary_tag_table = gtk_text_tag_table_new(); _binary_tag = gtk_text_tag_new("binary"); g_object_set(G_OBJECT(_binary_tag), "foreground", "white", "background", "black", (const char *) NULL); gtk_text_tag_table_add(_binary_tag_table, _binary_tag); // subsystems _handlers = new whandler(this); _diagram = new wdiagram(this); dialogs_connect(); config_changed_initialize(true, false); set_diagram_mode(true); gtk_quit_add_destroy(1, GTK_OBJECT(_window)); ++num_main_windows;}wmain::~wmain(){ // only call from GtkWidget destruction clear(false); gdk_cursor_unref(_normal_cursor); gdk_cursor_unref(_link_cursor); pango_attr_list_unref(_small_attr); pango_attr_list_unref(_bold_attr); pango_attr_list_unref(_small_bold_attr); delete _diagram; delete _handlers; if (!--num_main_windows) gtk_main_quit();}// xxxclass ClickyLexerTInfo : public LexerTInfo { public: ClickyLexerTInfo(GtkTextBuffer *buffer, const String &config, GatherErrorHandler *gerrh) : _buffer(buffer), _tt(gtk_text_buffer_get_tag_table(buffer)), _comment_tag(0), _keyword_tag(0), _error_tag(0), _config(config), _gerrh(gerrh) { } void apply_tag(const char *pos1, const char *pos2, GtkTextTag *tag) { GtkTextIter i1, i2; gtk_text_buffer_get_iter_at_offset(_buffer, &i1, pos1 - _config.begin()); gtk_text_buffer_get_iter_at_offset(_buffer, &i2, pos2 - _config.begin()); gtk_text_buffer_apply_tag(_buffer, tag, &i1, &i2); } void notify_comment(const char *pos1, const char *pos2) { if (!_comment_tag) _comment_tag = gtk_text_tag_table_lookup(_tt, "comment"); apply_tag(pos1, pos2, _comment_tag); } void notify_keyword(const String &, const char *pos1, const char *pos2) { if (!_keyword_tag) _keyword_tag = gtk_text_tag_table_lookup(_tt, "keyword"); apply_tag(pos1, pos2, _keyword_tag); } void notify_error(const String &, const char *pos1, const char *pos2) { if (_gerrh) _gerrh->set_next_errpos(pos1 - _config.begin(), pos2 - _config.begin()); else { if (!_error_tag) _error_tag = gtk_text_tag_table_lookup(_tt, "error"); apply_tag(pos1, pos2, _error_tag); } }#if 0 void add_item(const char *pos1, const String &s1, const char *pos2, const String &s2) { ::add_item(pos1 - _config.begin(), s1, pos2 - _config.begin(), s2); } void add_item(const char *pos1, ElementT *e1, const char *pos2, const String &s2) { ::add_item(pos1 - _config.begin(), e1, pos2 - _config.begin(), s2); } void add_item(const char *pos1, ElementClassT *e1, const char *pos2, const String &s2) { ::add_item(pos1 - _config.begin(), e1, pos2 - _config.begin(), s2); } void notify_comment(const char *pos1, const char *pos2) { add_item(pos1, "<span class='c-cmt'>", pos2, "</span>"); } void notify_error(const String &what, const char *pos1, const char *pos2) { add_item(pos1, "<span class='c-err' title='" + html_quote_attr(what) + "'>", pos2, "</span>"); } void notify_keyword(const String &, const char *pos1, const char *pos2) { add_item(pos1, "<span class='c-kw'>", pos2, "</span>"); } void notify_config_string(const char *pos1, const char *pos2) { add_item(pos1, "<span class='c-cfg'>", pos2, "</span>"); } void notify_class_declaration(ElementClassT *ec, bool anonymous, const char *decl_pos1, const char *name_pos1, const char *) { if (!anonymous) add_item(name_pos1, "<a name='" + link_class_decl(ec) + "'><span class='c-cd'>", name_pos1 + ec->name().length(), "</span></a>"); else add_item(decl_pos1, "<a name='" + link_class_decl(ec) + "'>", decl_pos1 + 1, "</a>"); add_class_href(ec, "#" + link_class_decl(ec)); } void notify_class_extension(ElementClassT *ec, const char *pos1, const char *pos2) { add_item(pos1, ec, pos2, ""); } void notify_class_reference(ElementClassT *ec, const char *pos1, const char *pos2) { add_item(pos1, ec, pos2, ""); } void notify_element_declaration(ElementT *e, const char *pos1, const char *pos2, const char *decl_pos2) { add_item(pos1, "<a name='" + link_element_decl(e) + "'>", pos2, "</a>"); add_item(pos1, "<span class='c-ed'>", decl_pos2, "</span>"); notify_element_reference(e, pos1, decl_pos2); } void notify_element_reference(ElementT *e, const char *pos1, const char *pos2) { add_item(pos1, e, pos2, "</span>"); }#endif GtkTextBuffer *_buffer; GtkTextTagTable *_tt; GtkTextTag *_comment_tag; GtkTextTag *_keyword_tag; GtkTextTag *_error_tag; String _config; GatherErrorHandler *_gerrh;};void wmain::clear(bool alive){ crouter::clear(alive); _error_endpos = 0; _savefile = String(); _config_clean_errors = _config_clean_elements = true; _error_hover_index = -1; _error_highlight_index = -1; _error_highlight_x = _error_highlight_y = -1; _element_highlight = 0; _eview_name = String(); if (_config_changed_signal && alive) g_signal_handler_disconnect(_config_buffer, _config_changed_signal); _config_changed_signal = 0; if (_error_scroller) g_source_remove(_error_scroller); _error_scroller = 0; // XXX _hvalues.clear(); _handlers->clear(); _diagram->router_create(false, false); // Initialize window state if (alive) { gtk_text_buffer_set_text(_config_buffer, "", 0); element_show(String(), 0, false); etree_fill(); on_error(true, String()); }}void wmain::on_landmark_changed(){ if (landmark()) { String title = "Clicky: " + landmark(); gtk_window_set_title(GTK_WINDOW(_window), title.c_str()); } else gtk_window_set_title(GTK_WINDOW(_window), "Clicky");}void wmain::on_ccss_changed(){ _diagram->on_ccss_changed();}LexerTInfo *wmain::on_config_changed_prepare(){ _error_endpos = 0; gtk_text_buffer_set_text(_error_buffer, "", 0); error_unhighlight(); element_unhighlight(); String conf = config(); gtk_text_buffer_set_text(_config_buffer, conf.data(), conf.length()); config_changed_initialize(true, false); _config_clean_errors = true; return new ClickyLexerTInfo(_config_buffer, conf, error_handler());}void wmain::on_config_changed(bool replace, LexerTInfo *linfo){ String conf = config(); GatherErrorHandler *gerrh = error_handler(); ClickyLexerTInfo *cinfo = dynamic_cast<ClickyLexerTInfo *>(linfo); const char *conf_begin = conf.begin(); GtkTextTag *error_tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(_config_buffer), "error"); for (GatherErrorHandler::iterator gi = gerrh->begin(); gi != gerrh->end(); ++gi) if (gi->errpos1 < gi->errpos2 && gi->level <= ErrorHandler::el_error) cinfo->apply_tag(conf_begin + gi->errpos1, conf_begin + gi->errpos2, error_tag); _diagram->router_create(false, false); _config_clean_elements = true; config_choose_driver(); if (router() && replace) etree_fill(); if (gerrh->nerrors() || gerrh->nwarnings()) on_error(true, String());}void wmain::set_save_file(const String &savefile, bool loading){ _savefile = last_savefile = savefile; if (loading) config_changed_initialize(false, true);}/***** * * Throbber * */static GdkPixbufAnimation *throbber_img = 0;static bool throbber_loaded = false;void wmain::on_throbber_changed(bool show){ GtkWidget *throbberw = lookup_widget(_window, "throbber"); if (show) { if (!throbber_loaded) { throbber_loaded = true; String throbber_file = clickpath_find_file("throbber.gif", "share/" PACKAGE, PACKAGE_DATA_DIR "/" PACKAGE); // support for running before installing if (!throbber_file && g_file_test("src/clicky", G_FILE_TEST_EXISTS)) throbber_file = clickpath_find_file("throbber.gif", "", "./images"); if (throbber_file) throbber_img = gdk_pixbuf_animation_new_from_file(throbber_file.c_str(), NULL); } if (throbber_img) gtk_image_set_from_animation(GTK_IMAGE(throbberw), throbber_img); else gtk_image_set_from_stock(GTK_IMAGE(throbberw), GTK_STOCK_NETWORK, GTK_ICON_SIZE_LARGE_TOOLBAR); gtk_widget_show(throbberw); } else { gtk_image_clear(GTK_IMAGE(throbberw)); }}/***** *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -