📄 wmain.cc
字号:
G_CALLBACK(on_elementtree_select), this); g_signal_connect(_elist_view, "row-activated", G_CALLBACK(on_elementtree_row_activated), this); g_signal_connect(G_OBJECT(lookup_widget(_window, "eview_close")), "clicked", G_CALLBACK(on_eview_close_clicked), this); g_signal_connect(G_OBJECT(lookup_widget(_window, "eview_refresh")), "clicked", G_CALLBACK(on_eview_refresh_clicked), this); } else gtk_tree_store_clear(_elist_store); if (router()) fill_elements_tree_store(_elist_store, router()); element_show(_eview_name, 0, false); diagram()->element_show(_eview_name, false);}/***** * * Error views * */void wmain::error_unhighlight(){ if (_error_highlight_index >= 0) { GatherErrorHandler *gerrh = error_handler(); GatherErrorHandler::iterator gi = gerrh->begin() + _error_highlight_index; GtkTextIter i1, i2; if (gi->errpos1 < gi->errpos2) { 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_error_highlight_tag, &i1, &i2); } gtk_text_buffer_get_iter_at_offset(_error_buffer, &i1, gi->offset1); gtk_text_buffer_get_iter_at_offset(_error_buffer, &i2, gi->offset2()); gtk_text_buffer_remove_tag(_error_buffer, _error_highlight_tag, &i1, &i2); _error_highlight_index = -1; }}bool wmain::error_view_motion_offsets(int off1, int off2, int eindex){ if (eindex != _error_hover_index) { GtkTextIter i1, i2; GatherErrorHandler *gerrh = error_handler(); if (_error_hover_index >= 0) { GatherErrorHandler::iterator gi = gerrh->begin() + _error_hover_index; gtk_text_buffer_get_iter_at_offset(_error_buffer, &i1, gi->offset1); gtk_text_buffer_get_iter_at_offset(_error_buffer, &i2, gi->offset2()); gtk_text_buffer_remove_tag(_error_buffer, _error_hover_tag, &i1, &i2); } if (off1 != off2) { gtk_text_buffer_get_iter_at_offset(_error_buffer, &i1, off1); gtk_text_buffer_get_iter_at_offset(_error_buffer, &i2, off2); gtk_text_buffer_apply_tag(_error_buffer, _error_hover_tag, &i1, &i2); gdk_window_set_cursor(gtk_text_view_get_window(GTK_TEXT_VIEW(_error_view), GTK_TEXT_WINDOW_TEXT), _link_cursor); } else gdk_window_set_cursor(gtk_text_view_get_window(GTK_TEXT_VIEW(_error_view), GTK_TEXT_WINDOW_TEXT), _normal_cursor); _error_hover_index = eindex; return true; } else return false;}bool wmain::error_view_motion_position(gint x, gint y){ gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(_error_view), GTK_TEXT_WINDOW_WIDGET, x, y, &x, &y); GtkTextIter i; gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(_error_view), &i, x, y); GatherErrorHandler *gerrh = error_handler(); GatherErrorHandler::iterator message = gerrh->find_offset(gtk_text_iter_get_offset(&i)); // get buffer positions if (message != gerrh->end() && !_config_clean_errors) message->errpos1 = message->errpos2 = 0; if (message != gerrh->end() && message->errpos1 == 0 && message->errpos2 == 0) { const char *next; unsigned lineno; if (message->message.length() > 8 && memcmp(message->message.data(), "config:", 7) == 0 && (next = cp_integer(message->message.begin() + 7, message->message.end(), 10, &lineno)) < message->message.end() && *next == ':' && lineno <= (unsigned) gtk_text_buffer_get_line_count(_config_buffer)) { GtkTextIter iter1, iter2; gtk_text_buffer_get_iter_at_line_offset(_config_buffer, &iter1, lineno - 1, 0); iter2 = iter1; gtk_text_iter_forward_line(&iter2); message->errpos1 = gtk_text_iter_get_offset(&iter1); message->errpos2 = gtk_text_iter_get_offset(&iter2); } } // scroll to named position bool result; if (message == gerrh->end() || message->errpos1 >= message->errpos2) result = error_view_motion_offsets(0, 0, -1); else result = error_view_motion_offsets(message->offset1, message->offset2(), message - gerrh->begin()); // get more motion events GdkModifierType mod; (void) gdk_window_get_pointer(_error_view->window, &x, &y, &mod); return result;}gboolean wmain::error_view_event(GdkEvent *event){ if (event->type == GDK_MOTION_NOTIFY) error_view_motion_position((gint) event->motion.x, (gint) event->motion.y); else if (event->type == GDK_LEAVE_NOTIFY && event->crossing.mode == GDK_CROSSING_NORMAL) error_view_motion_offsets(0, 0, -1); else if (event->type == GDK_BUTTON_PRESS && event->button.button == 1) { error_unhighlight(); if (_error_hover_index >= 0) { _error_highlight_x = event->button.x; _error_highlight_y = event->button.y; } } else if (event->type == GDK_BUTTON_PRESS && event->button.button == 1) error_unhighlight(); else if (event->type == GDK_BUTTON_RELEASE && event->button.button == 1 && _error_hover_index >= 0 && fabs(event->button.x - _error_highlight_x) <= 10 && fabs(event->button.y - _error_highlight_y) <= 10) { GatherErrorHandler *gerrh = error_handler(); GatherErrorHandler::iterator gi = gerrh->begin() + _error_hover_index; if (gi->errpos1 < gi->errpos2) { _error_highlight_index = _error_hover_index; GatherErrorHandler::iterator gi = gerrh->begin() + _error_highlight_index; GtkTextIter i1, i2; gtk_text_buffer_get_iter_at_offset(_config_buffer, &i1, gi->errpos1); gtk_text_buffer_get_iter_at_offset(_config_buffer, &i2, gi->errpos2); gtk_text_buffer_apply_tag(_config_buffer, _config_error_highlight_tag, &i1, &i2); 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); gtk_text_buffer_get_iter_at_offset(_error_buffer, &i1, gi->offset1); gtk_text_buffer_get_iter_at_offset(_error_buffer, &i2, gi->offset2()); gtk_text_buffer_apply_tag(_error_buffer, _error_highlight_tag, &i1, &i2); } } return FALSE;}extern "C" {static gboolean on_error_view_event(GtkWidget *, GdkEvent *event, gpointer user_data){ wmain *rw = reinterpret_cast<wmain *>(user_data); return rw->error_view_event(event);}static gboolean on_error_scroll_timeout(gpointer user_data){ reinterpret_cast<wmain *>(user_data)->on_error_scroll_timeout(); return FALSE;}}void wmain::on_error(bool replace, const String &dialog){ GatherErrorHandler *gerrh = error_handler(); if (!gerrh->size()) { gtk_widget_hide(lookup_widget(_window, "errorviewbox")); gtk_widget_show(lookup_widget(_window, "elementtreelabel")); gtk_widget_hide(lookup_widget(_window, "elementtreeexpander")); gtk_widget_show(lookup_widget(_window, "elementtreewindow")); gtk_widget_show(lookup_widget(_window, "elementtreesort")); gtk_paned_set_position(GTK_PANED(lookup_widget(_window, "errorpane")), 0); gtk_text_buffer_set_text(_error_buffer, "", 0); return; } // set up window gtk_widget_show(lookup_widget(_window, "errorviewbox")); gtk_widget_hide(lookup_widget(_window, "elementtreelabel")); GtkWidget *treeexpander = lookup_widget(_window, "elementtreeexpander"); gtk_widget_show(treeexpander); GtkPaned *pane = GTK_PANED(lookup_widget(_window, "errorpane")); GtkWidget *treewindow = lookup_widget(_window, "elementtreewindow"); if (gerrh->nerrors() && replace) { if (!_show_list) set_show_list(true); gtk_widget_hide(treewindow); gtk_widget_hide(lookup_widget(_window, "elementtreesort")); gtk_paned_set_position(pane, 2147483647); } gtk_expander_set_expanded(GTK_EXPANDER(treeexpander), GTK_WIDGET_VISIBLE(treewindow)); if ((!gerrh->nerrors() || !replace) && GTK_WIDGET_VISIBLE(treewindow)) gtk_paned_set_position(pane, GTK_WIDGET(pane)->allocation.height / 3); // strip filename errors from error list if (replace) { _error_endpos = 0; gtk_text_buffer_set_text(_error_buffer, "", 0); } gerrh->translate_prefix(landmark() + ": ", "", _error_endpos); StringAccum sa; for (GatherErrorHandler::iterator gi = gerrh->begin() + _error_endpos; gi != gerrh->end(); ++gi) sa << gi->message; if (sa.length()) { GtkTextIter iter; gtk_text_buffer_get_end_iter(_error_buffer, &iter); gtk_text_buffer_insert(_error_buffer, &iter, sa.data(), sa.length()); } _error_endpos = gerrh->size(); if (_error_scroller) g_source_remove(_error_scroller); // show the error dialog if (dialog) { gtk_widget_show(_window); GtkWidget *dwidget = gtk_message_dialog_new(GTK_WINDOW(_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", dialog.c_str()); gtk_dialog_run(GTK_DIALOG(dwidget)); gtk_widget_destroy(dwidget); } _error_scroller = g_timeout_add(20, clicky::on_error_scroll_timeout, this);}void wmain::on_error_scroll_timeout(){ GtkWidget *error_scrolled = lookup_widget(_window, "errorviewwindow"); GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(error_scrolled)); gtk_adjustment_set_value(vadj, vadj->upper - vadj->page_size); _error_scroller = 0;}extern "C" {static void error_expanders_callback(GObject *object, GParamSpec *, gpointer){ GtkExpander *e = GTK_EXPANDER(object); GtkExpander *listex = GTK_EXPANDER(lookup_widget(GTK_WIDGET(e), "elementtreeexpander")); GtkExpander *errorex = GTK_EXPANDER(lookup_widget(GTK_WIDGET(e), "errorviewexpander")); if (!gtk_expander_get_expanded(listex) && !gtk_expander_get_expanded(errorex)) gtk_expander_set_expanded(e == listex ? errorex : listex, TRUE); const char *child_name = (e == listex ? "elementtreewindow" : "errorviewwindow"); GtkPaned *pane = GTK_PANED(lookup_widget(GTK_WIDGET(e), "errorpane")); if (gtk_expander_get_expanded(e)) { gtk_widget_show(lookup_widget(GTK_WIDGET(e), child_name)); if (e == listex) gtk_widget_show(lookup_widget(GTK_WIDGET(e), "elementtreesort")); if (gtk_expander_get_expanded(e == listex ? errorex : listex)) gtk_paned_set_position(pane, GTK_WIDGET(pane)->allocation.height / 2); } else { gtk_widget_hide(lookup_widget(GTK_WIDGET(e), child_name)); if (e == listex) gtk_widget_hide(lookup_widget(GTK_WIDGET(e), "elementtreesort")); gtk_paned_set_position(pane, (e == listex ? 2147483647 : 0)); }}static void elementtreesort_callback(GtkButton *, gpointer user_data){ reinterpret_cast<wmain *>(user_data)->element_tree_sort(-1);}}/***** * * Configuration editing * */extern "C" {static void on_eview_classexpander_expanded(GObject *object, GParamSpec *, gpointer){ GtkExpander *e = GTK_EXPANDER(object); GtkWidget *other = lookup_widget(GTK_WIDGET(e), "eview_classinfo"); if (gtk_expander_get_expanded(e)) gtk_widget_show(other); else gtk_widget_hide(other);}static void config_changed(GtkTextBuffer *, gpointer user_data){ reinterpret_cast<wmain *>(user_data)->on_config_changed();}}void wmain::config_changed_initialize(bool check, bool save){ if (!_config_changed_signal) _config_changed_signal = g_signal_connect(_config_buffer, "changed", G_CALLBACK(clicky::config_changed), this); if (check) gtk_widget_set_sensitive(lookup_widget(_window, "toolbar_check"), FALSE); if (save && _savefile) gtk_widget_set_sensitive(lookup_widget(_window, "toolbar_save"), FALSE);}void wmain::on_config_changed(){ if (_config_changed_signal) g_signal_handler_disconnect(_config_buffer, _config_changed_signal); _config_changed_signal = 0; _config_clean_errors = _config_clean_elements = false; error_unhighlight(); element_unhighlight(); gtk_widget_set_sensitive(lookup_widget(_window, "toolbar_check"), TRUE); gtk_widget_set_sensitive(lookup_widget(_window, "toolbar_save"), TRUE);}void wmain::config_check(bool install){ GtkTextIter i1, i2; gtk_text_buffer_get_start_iter(_config_buffer, &i1); gtk_text_buffer_get_end_iter(_config_buffer, &i2); gchar *str = gtk_text_buffer_get_text(_config_buffer, &i1, &i2, FALSE); String config; RouterT *r = router(); if (r && r->narchive()) { Vector<ArchiveElement> ar(r->archive()); ArchiveElement ae = init_archive_element("config", 0600); ae.data = String(str); ar.push_back(ae); config = ArchiveElement::unparse(ar); } else config = str; g_free(str); if (install) if (cdriver *cd = driver()) { cd->do_write("hotconfig", config, cdriver::dflag_clear); cd->do_read("list", String(), 0); } set_landmark("config"); set_config(config, install || !driver());}/***** * * Diagram mode * */void wmain::set_diagram_mode(bool diagram){ if (diagram) { g_object_set(G_OBJECT(lookup_widget(_window, "menu_view_diagram")), "active", TRUE, (const char *) NULL); gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(lookup_widget(_window, "toolbar_diagram")), TRUE); gtk_widget_show(lookup_widget(_window, "diagramwindow")); gtk_widget_hide(lookup_widget(_window, "configwindow")); gtk_widget_set_sensitive(lookup_widget(_window, "menu_zoom_in"), TRUE); gtk_widget_set_sensitive(lookup_widget(_window, "menu_zoom_out"), TRUE); gtk_widget_set_sensitive(lookup_widget(_window, "menu_normal_size"), TRUE); gtk_widget_set_sensitive(lookup_widget(_window, "menu_zoom_fit"), TRUE); } else { g_object_set(G_OBJECT(lookup_widget(_window, "menu_view_configuration")), "active", TRUE, (const char *) NULL); gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(lookup_widget(_window, "toolbar_diagram")), FALSE); gtk_widget_hide(lookup_widget(_window, "diagramwindow")); gtk_widget_show(lookup_widget(_window, "configwindow")); gtk_widget_set_sensitive(lookup_widget(_window, "menu_zoom_in"), FALSE); gtk_widget_set_sensitive(lookup_widget(_window, "menu_zoom_out"), FALSE); gtk_widget_set_sensitive(lookup_widget(_window, "menu_normal_size"), FALSE); gtk_widget_set_sensitive(lookup_widget(_window, "menu_zoom_fit"), FALSE); }}void wmain::repaint(const rectangle &rect){ if (_diagram->visible()) _diagram->redraw(rect);}void wmain::repaint_if_visible(const rectangle &rect, double dimen){ if (_diagram->visible() && fabs(dimen * _diagram->scale()) > 0.5) _diagram->redraw(rect);}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -