# # patch "rev_file_info.cc" # from [33d3e34996aa1ee822b9a03018cbb87370e67fac] # to [455cef600d8716d948c7075f51464a935edb1246] # # patch "rev_file_info.hh" # from [73ee71dfbd46328c3aa905c1fdc0eaf354568c85] # to [d44b55176f4b984d5a98b1bc85992578f018012f] # ======================================================================== --- rev_file_info.cc 33d3e34996aa1ee822b9a03018cbb87370e67fac +++ rev_file_info.cc 455cef600d8716d948c7075f51464a935edb1246 @@ -1,23 +1,72 @@ // Copyright 2005 Timothy Brownawell // Licensed to the public under the GNU GPL v2, see COPYING #include "rev_file_info.hh" +#include + rev_file_info::rev_file_info() { fcontents.set_editable(false); fdiff.set_editable(false); + current = fcontents.get_buffer()->create_tag(); + current->property_foreground() = "brown"; fcommwin.add(fcomment); fcontwin.add(fcontents); fdiffwin.add(fdiff); append_page(fdiffwin, "File diff"); append_page(fcontwin, "File contents"); append_page(fcommwin, "File comment"); - fcontents.set_editable(false); Glib::RefPtr b = fcomment.get_buffer(); commentend = b->create_mark(b->end()); + fdiff.signal_button_press_event() + .connect_notify(sigc::mem_fun(*this, &rev_file_info::diff_clicked)); } +void rev_file_info::diff_clicked(GdkEventButton *b) +{ +// Gtk::TextIter i; +// fdiff.get_iter_at_location(i, int(b->x), int(b->y)); +// std::cout<<"Click!\n"; +} + +Glib::RefPtr +rev_file_info::hypertag(Glib::RefPtr b, int line, int eline) +{ + Glib::RefPtr t = b->create_tag(); + t->property_underline() = Pango::UNDERLINE_SINGLE; + t->property_foreground() = "blue"; + link_tag_to(t, line, eline); + return t; +} + +void rev_file_info::link_tag_to(Glib::RefPtr &t, + int line, int eline) +{ + t->signal_event().connect(sigc::bind( + sigc::bind(sigc::mem_fun(*this, + &rev_file_info::tag_event), + eline), line)); +} +bool rev_file_info::tag_event(Glib::RefPtr const &p, + GdkEvent *e, Gtk::TextIter const &it, + int line, int eline) +{ + GdkEventType et = e->type; + if (et == GDK_BUTTON_RELEASE) + { + Glib::RefPtr b = fcontents.get_buffer(); + Gtk::TextIter i = b->get_iter_at_line(line); + Gtk::TextIter j = b->get_iter_at_line(eline+1)--; + fcontents.scroll_to(i); + b->remove_tag(current, b->begin(), b->end()); + b->apply_tag(current, i, j); + property_page() = 1; + GdkEventButton *be = &e->button; + } + return false; +} + void rev_file_info::set_contents(Glib::ustring const & s) { @@ -33,6 +82,29 @@ { Glib::RefPtr b = fdiff.get_buffer(); b->set_text(s); + + try { + // every line "@@ -a,b +c,d @@" gets linked to line c of "File contents" + int n = 0, m = 0; + while ((n = s.find("\n@@", m)) != s.npos && n >= m) + { + m = s.find("@@\n", n); + if (m == s.npos) + break; + int plus = s.find("+", n); + int comma = s.find(",", plus); + int space = s.find(" ", comma); + if (plus > comma || comma > space || space > m) + continue; + Glib::ustring line = s.substr(plus, comma-plus); + Glib::ustring size = s.substr(comma+1, space-comma-1); + int l = boost::lexical_cast(line); + int s = boost::lexical_cast(size); + Glib::RefPtr t = hypertag(b, l, l+s); + b->apply_tag(t, b->get_iter_at_offset(n+1), b->get_iter_at_offset(m+2)); + } + } catch (std::exception &) {} + Glib::RefPtr t = b->create_tag(); t->property_family() = "monospace"; b->apply_tag(t, b->begin(), b->end()); ======================================================================== --- rev_file_info.hh 73ee71dfbd46328c3aa905c1fdc0eaf354568c85 +++ rev_file_info.hh d44b55176f4b984d5a98b1bc85992578f018012f @@ -29,6 +29,15 @@ Gtk::ScrolledWindow fcontwin; Gtk::ScrolledWindow fdiffwin; Glib::RefPtr commentend; + Glib::RefPtr current; + + void diff_clicked(GdkEventButton *b); + Glib::RefPtr + hypertag(Glib::RefPtr b, int line, int eline); + bool tag_event(Glib::RefPtr const &p, + GdkEvent *e, Gtk::TextIter const &it, + int line, int eline); + void link_tag_to(Glib::RefPtr &t, int line, int eline); public: rev_file_info();