1 /* thread index cell renderer: 2 * 3 * the heart of showing threads in a fancy / sexy way. renders a 4 * nice looking thread entry based on a notmuch thread object - 5 * preferably without loading the message file. 6 * 7 */ 8 9 # include <iostream> 10 # include <time.h> 11 12 # include <gtkmm/image.h> 13 # include <boost/property_tree/ptree.hpp> 14 15 # include <notmuch.h> 16 17 # include "thread_index.hh" 18 # include "thread_index_list_cell_renderer.hh" 19 # include "db.hh" 20 # include "utils/utils.hh" 21 # include "crypto.hh" 22 # ifndef DISABLE_PLUGINS 23 # include "plugin/manager.hh" 24 # endif 25 26 using namespace std; 27 using boost::property_tree::ptree; 28 29 namespace Astroid { 30 ThreadIndexListCellRenderer(ThreadIndex * _ti)31 ThreadIndexListCellRenderer::ThreadIndexListCellRenderer (ThreadIndex * _ti) { 32 ptree ti = astroid->config ("thread_index.cell"); 33 hidden_tags = VectorUtils::split_and_trim (ti.get<string> ("hidden_tags"), ","); 34 std::sort (hidden_tags.begin (), hidden_tags.end ()); 35 36 thread_index = _ti; 37 38 /* load font settings */ 39 font_desc_string = ti.get<string> ("font_description"); 40 if (font_desc_string == "" || font_desc_string == "default") { 41 auto settings = Gio::Settings::create ("org.gnome.desktop.interface"); 42 font_desc_string = settings->get_string ("monospace-font-name"); 43 } 44 45 font_description = Pango::FontDescription (font_desc_string); 46 47 /* https://developer.gnome.org/pangomm/stable/classPango_1_1FontDescription.html#details */ 48 if (font_description.get_size () == 0) { 49 LOG (warn) << "thread_index.cell.font_description: no size specified, expect weird behaviour."; 50 } 51 52 line_spacing = ti.get<int> ("line_spacing"); 53 date_len = ti.get<int> ("date_length"); 54 message_count_len = ti.get<int> ("message_count_length"); 55 authors_len = ti.get<int> ("authors_length"); 56 tags_len = ti.get<int> ("tags_length"); 57 58 subject_color = ti.get<string> ("subject_color"); 59 subject_color_selected = ti.get<string> ("subject_color_selected"); 60 background_color_selected = ti.get<string> ("background_color_selected"); 61 62 background_color_marked = ti.get<string> ("background_color_marked"); 63 background_color_marked_selected = ti.get<string> ("background_color_marked_selected"); 64 65 } 66 render_vfunc(const::Cairo::RefPtr<::Cairo::Context> & cr,Gtk::Widget & widget,const Gdk::Rectangle & background_area,const Gdk::Rectangle & cell_area,Gtk::CellRendererState flags)67 void ThreadIndexListCellRenderer::render_vfunc ( 68 const ::Cairo::RefPtr< ::Cairo::Context>&cr, 69 Gtk::Widget &widget, 70 const Gdk::Rectangle & background_area, 71 const Gdk::Rectangle &cell_area, 72 Gtk::CellRendererState flags) 73 { 74 // calculate text width, we don't need to do this every time, 75 // but we need access to the context. 76 if (!height_set) { 77 refptr<Pango::Context> pango_cr = widget.create_pango_context (); 78 font_metrics = pango_cr->get_metrics (font_description); 79 80 int char_width = font_metrics.get_approximate_char_width () / Pango::SCALE; 81 padding = char_width; 82 83 content_height = calculate_height (widget); 84 line_height = content_height + line_spacing; 85 height_set = true; 86 87 left_icons_size = content_height - (2 * left_icons_padding); 88 left_icons_width = left_icons_size; 89 90 date_start = left_icons_width_n * left_icons_width + 91 (left_icons_width_n-1) * left_icons_padding + padding; 92 date_width = char_width * date_len; 93 message_count_width = char_width * message_count_len; 94 message_count_start = date_start + date_width + padding; 95 authors_width = char_width * authors_len; 96 authors_start = message_count_start + message_count_width + padding; 97 tags_width = char_width * tags_len; 98 tags_start = authors_start + authors_width + padding; 99 subject_start = tags_start + tags_width + padding; 100 101 height = content_height + line_spacing; 102 } 103 104 if (thread->unread) { 105 font_description.set_weight (Pango::WEIGHT_BOLD); 106 } else { 107 font_description.set_weight (Pango::WEIGHT_NORMAL); 108 } 109 110 render_background (cr, widget, background_area, flags); 111 render_date (cr, widget, cell_area); // returns height 112 113 if (thread->total_messages > 1) 114 render_message_count (cr, widget, cell_area); 115 116 render_authors (cr, widget, cell_area); 117 118 tags_width = render_tags (cr, widget, cell_area, flags); // returns width 119 subject_start = tags_start + tags_width / Pango::SCALE + ((tags_width > 0) ? padding : 0); 120 121 render_subject (cr, widget, cell_area, flags); 122 123 /* 124 if (!last) 125 render_delimiter (cr, widget, cell_area); 126 */ 127 128 if (thread->flagged) 129 render_flagged (cr, widget, cell_area); 130 131 if (thread->attachment) 132 render_attachment (cr, widget, cell_area); 133 134 /* 135 if (marked) 136 render_marked (cr, widget, cell_area); 137 */ 138 139 } 140 ~ThreadIndexListCellRenderer()141 ThreadIndexListCellRenderer::~ThreadIndexListCellRenderer () { 142 LOG (debug) << "til cr: deconstruct."; 143 } 144 render_background(const::Cairo::RefPtr<::Cairo::Context> & cr,Gtk::Widget &,const Gdk::Rectangle & background_area,Gtk::CellRendererState flags)145 void ThreadIndexListCellRenderer::render_background ( // {{{ 146 const ::Cairo::RefPtr< ::Cairo::Context>&cr, 147 Gtk::Widget & /* widget */, 148 const Gdk::Rectangle &background_area, 149 Gtk::CellRendererState flags) { 150 151 int y = background_area.get_y (); 152 int x = background_area.get_x (); 153 154 int w = background_area.get_width (); 155 int h = background_area.get_height (); 156 157 Gdk::Color bg; 158 bool set = true; 159 160 if ((flags & Gtk::CELL_RENDERER_SELECTED) != 0) { 161 if (!marked) { 162 if (background_color_selected.length () > 0) { 163 bg = Gdk::Color (background_color_selected); 164 } else { 165 set = false; 166 } 167 } else { 168 bg = Gdk::Color (background_color_marked_selected); 169 } 170 } else { 171 if (!marked) { 172 set = false; 173 } else { 174 bg = Gdk::Color (background_color_marked); 175 } 176 } 177 178 if (set) { 179 cr->set_source_rgb (bg.get_red_p(), bg.get_green_p(), bg.get_blue_p()); 180 181 cr->rectangle (x, y, w, h); 182 cr->fill (); 183 } 184 } // }}} 185 186 /* render icons {{{ */ render_marked(const::Cairo::RefPtr<::Cairo::Context> & cr,Gtk::Widget &,const Gdk::Rectangle & cell_area)187 void ThreadIndexListCellRenderer::render_marked ( 188 const ::Cairo::RefPtr< ::Cairo::Context>&cr, 189 Gtk::Widget & /* widget */, 190 const Gdk::Rectangle &cell_area ) { 191 192 193 if (!marked_icon) { 194 Glib::RefPtr<Gtk::IconTheme> theme = Gtk::IconTheme::get_default(); 195 Glib::RefPtr<Gdk::Pixbuf> pixbuf = theme->load_icon ( 196 "object-select-symbolic", 197 left_icons_size, 198 Gtk::ICON_LOOKUP_USE_BUILTIN | Gtk::ICON_LOOKUP_FORCE_SIZE); 199 200 201 marked_icon = pixbuf->scale_simple (left_icons_size, left_icons_size, 202 Gdk::INTERP_BILINEAR); 203 } 204 205 int y = cell_area.get_y() + left_icons_padding + line_spacing / 2; 206 int x = cell_area.get_x(); 207 208 Gdk::Cairo::set_source_pixbuf (cr, marked_icon, x, y); 209 210 cr->rectangle (x, y, left_icons_size, left_icons_size); 211 cr->fill (); 212 } 213 render_flagged(const::Cairo::RefPtr<::Cairo::Context> & cr,Gtk::Widget &,const Gdk::Rectangle & cell_area)214 void ThreadIndexListCellRenderer::render_flagged ( 215 const ::Cairo::RefPtr< ::Cairo::Context>&cr, 216 Gtk::Widget & /* widget */, 217 const Gdk::Rectangle &cell_area ) { 218 219 220 if (!flagged_icon) { 221 Glib::RefPtr<Gtk::IconTheme> theme = Gtk::IconTheme::get_default(); 222 Glib::RefPtr<Gdk::Pixbuf> pixbuf = theme->load_icon ( 223 "starred-symbolic", 224 left_icons_size, 225 Gtk::ICON_LOOKUP_USE_BUILTIN | Gtk::ICON_LOOKUP_FORCE_SIZE); 226 227 flagged_icon = pixbuf->scale_simple (left_icons_size, left_icons_size, 228 Gdk::INTERP_BILINEAR); 229 } 230 231 int y = cell_area.get_y() + left_icons_padding + line_spacing / 2; 232 int x = cell_area.get_x() + 0 * (left_icons_width + left_icons_padding); 233 234 Gdk::Cairo::set_source_pixbuf (cr, flagged_icon, x, y); 235 236 cr->rectangle (x, y, left_icons_size,left_icons_size); 237 cr->fill (); 238 } 239 240 render_attachment(const::Cairo::RefPtr<::Cairo::Context> & cr,Gtk::Widget &,const Gdk::Rectangle & cell_area)241 void ThreadIndexListCellRenderer::render_attachment ( 242 const ::Cairo::RefPtr< ::Cairo::Context>&cr, 243 Gtk::Widget & /* widget */, 244 const Gdk::Rectangle &cell_area ) { 245 246 247 if (!attachment_icon) { 248 Glib::RefPtr<Gtk::IconTheme> theme = Gtk::IconTheme::get_default(); 249 Glib::RefPtr<Gdk::Pixbuf> pixbuf = theme->load_icon ( 250 "mail-attachment-symbolic", 251 left_icons_size, 252 Gtk::ICON_LOOKUP_USE_BUILTIN | Gtk::ICON_LOOKUP_FORCE_SIZE); 253 254 255 attachment_icon = pixbuf->scale_simple (left_icons_size, left_icons_size, 256 Gdk::INTERP_BILINEAR); 257 } 258 259 int y = cell_area.get_y() + left_icons_padding + line_spacing / 2; 260 int x = cell_area.get_x() + (1 * (left_icons_width + left_icons_padding)); 261 262 Gdk::Cairo::set_source_pixbuf (cr, attachment_icon, x, y); 263 264 cr->rectangle (x, y, left_icons_size, left_icons_size); 265 cr->fill (); 266 } // }}} 267 render_delimiter(const::Cairo::RefPtr<::Cairo::Context> & cr,Gtk::Widget &,const Gdk::Rectangle & cell_area)268 void ThreadIndexListCellRenderer::render_delimiter ( // {{{ 269 const ::Cairo::RefPtr< ::Cairo::Context>&cr, 270 Gtk::Widget & /*widget */, 271 const Gdk::Rectangle &cell_area ) { 272 273 cr->set_line_width(0.5); 274 Gdk::Color gray; 275 gray.set_grey_p (0.1); 276 cr->set_source_rgb (gray.get_red_p(), gray.get_green_p(), gray.get_blue_p()); 277 278 cr->move_to(cell_area.get_x(), cell_area.get_y() + cell_area.get_height()); 279 cr->line_to(cell_area.get_x() + cell_area.get_width(), cell_area.get_y() + cell_area.get_height()); 280 cr->stroke (); 281 282 } // }}} 283 render_subject(const::Cairo::RefPtr<::Cairo::Context> & cr,Gtk::Widget & widget,const Gdk::Rectangle & cell_area,Gtk::CellRendererState flags)284 void ThreadIndexListCellRenderer::render_subject ( // {{{ 285 const ::Cairo::RefPtr< ::Cairo::Context>&cr, 286 Gtk::Widget &widget, 287 const Gdk::Rectangle &cell_area, 288 Gtk::CellRendererState flags) { 289 290 Glib::RefPtr<Pango::Layout> pango_layout = widget.create_pango_layout (""); 291 292 pango_layout->set_font_description (font_description); 293 294 /* set color */ 295 Glib::RefPtr<Gtk::StyleContext> stylecontext = widget.get_style_context(); 296 297 Gdk::RGBA color = stylecontext->get_color(Gtk::STATE_FLAG_NORMAL); 298 cr->set_source_rgb (color.get_red(), color.get_green(), color.get_blue()); 299 ustring color_str; 300 if ((flags & Gtk::CELL_RENDERER_SELECTED) != 0) { 301 color_str = subject_color_selected; 302 } else { 303 color_str = subject_color; 304 } 305 306 pango_layout->set_markup (ustring::compose ("<span color=\"%1\">%2</span>", 307 color_str, 308 Glib::Markup::escape_text(thread->subject))); 309 310 /* align in the middle */ 311 int w, h; 312 pango_layout->get_size (w, h); 313 int y = max(0,(line_height / 2) - ((h / Pango::SCALE) / 2)); 314 315 cr->move_to (cell_area.get_x() + subject_start, cell_area.get_y() + y); 316 pango_layout->show_in_cairo_context (cr); 317 318 } // }}} 319 render_tags(const::Cairo::RefPtr<::Cairo::Context> & cr,Gtk::Widget & widget,const Gdk::Rectangle & cell_area,Gtk::CellRendererState flags)320 int ThreadIndexListCellRenderer::render_tags ( // {{{ 321 const ::Cairo::RefPtr< ::Cairo::Context>&cr, 322 Gtk::Widget &widget, 323 const Gdk::Rectangle &cell_area, 324 Gtk::CellRendererState flags) { 325 326 Glib::RefPtr<Pango::Layout> pango_layout = widget.create_pango_layout (""); 327 328 pango_layout->set_font_description (font_description); 329 330 /* set color */ 331 Glib::RefPtr<Gtk::StyleContext> stylecontext = widget.get_style_context(); 332 333 Gdk::RGBA color = stylecontext->get_color(Gtk::STATE_FLAG_NORMAL); 334 cr->set_source_rgb (color.get_red(), color.get_green(), color.get_blue()); 335 336 /* subtract hidden tags */ 337 vector<ustring> tags; 338 set_difference (thread->tags.begin(), 339 thread->tags.end(), 340 hidden_tags.begin (), 341 hidden_tags.end (), 342 back_inserter(tags)); 343 344 ustring tag_string; 345 346 Gdk::Color bg; 347 348 if ((flags & Gtk::CELL_RENDERER_SELECTED) != 0) { 349 bg = Gdk::Color (background_color_selected); 350 cr->set_source_rgb (bg.get_red_p(), bg.get_green_p(), bg.get_blue_p()); 351 } else { 352 bg.set_grey_p (1.); 353 } 354 355 /* first try plugin */ 356 # ifndef DISABLE_PLUGINS 357 if (!thread_index->plugins->format_tags (tags, bg.to_string (), (flags & Gtk::CELL_RENDERER_SELECTED) != 0, tag_string)) { 358 # endif 359 360 unsigned char cv[3] = { (unsigned char) bg.get_red (), 361 (unsigned char) bg.get_green (), 362 (unsigned char) bg.get_blue () }; 363 364 tag_string = VectorUtils::concat_tags_color (tags, true, tags_len, cv); 365 # ifndef DISABLE_PLUGINS 366 } 367 # endif 368 369 pango_layout->set_markup (tag_string); 370 371 /* align in the middle */ 372 int w, h; 373 pango_layout->get_size (w, h); 374 int y = max(0,(line_height / 2) - ((h / Pango::SCALE) / 2)); 375 376 cr->move_to (cell_area.get_x() + tags_start, cell_area.get_y() + y); 377 pango_layout->show_in_cairo_context (cr); 378 379 return w; 380 381 } // }}} 382 render_date(const::Cairo::RefPtr<::Cairo::Context> & cr,Gtk::Widget & widget,const Gdk::Rectangle & cell_area)383 int ThreadIndexListCellRenderer::render_date ( // {{{ 384 const ::Cairo::RefPtr< ::Cairo::Context>&cr, 385 Gtk::Widget &widget, 386 const Gdk::Rectangle &cell_area ) { 387 388 ustring date = Date::pretty_print (thread->newest_date); 389 390 Glib::RefPtr<Pango::Layout> pango_layout = widget.create_pango_layout (date); 391 392 pango_layout->set_font_description (font_description); 393 394 /* set color */ 395 Glib::RefPtr<Gtk::StyleContext> stylecontext = widget.get_style_context(); 396 Gdk::RGBA color = stylecontext->get_color(Gtk::STATE_FLAG_NORMAL); 397 cr->set_source_rgb (color.get_red(), color.get_green(), color.get_blue()); 398 399 /* align in the middle */ 400 int w, h; 401 pango_layout->get_size (w, h); 402 int y = max(0,(line_height / 2) - ((h / Pango::SCALE) / 2)); 403 404 /* update subject start */ 405 //subject_start = date_start + (w / Pango::SCALE) + padding; 406 407 cr->move_to (cell_area.get_x() + date_start, cell_area.get_y() + y); 408 pango_layout->show_in_cairo_context (cr); 409 410 return h; // return height! 411 412 } // }}} 413 render_message_count(const::Cairo::RefPtr<::Cairo::Context> & cr,Gtk::Widget & widget,const Gdk::Rectangle & cell_area)414 void ThreadIndexListCellRenderer::render_message_count ( // {{{ 415 const ::Cairo::RefPtr< ::Cairo::Context>&cr, 416 Gtk::Widget &widget, 417 const Gdk::Rectangle &cell_area ) { 418 419 # define BUFLEN 24 420 char buf[BUFLEN]; 421 snprintf (buf, BUFLEN, "(%d)", thread->total_messages); 422 423 424 Glib::RefPtr<Pango::Layout> pango_layout = widget.create_pango_layout (buf); 425 426 pango_layout->set_font_description (font_description); 427 428 /* set color */ 429 Glib::RefPtr<Gtk::StyleContext> stylecontext = widget.get_style_context(); 430 Gdk::RGBA color = stylecontext->get_color(Gtk::STATE_FLAG_NORMAL); 431 cr->set_source_rgb (color.get_red(), color.get_green(), color.get_blue()); 432 433 /* align in the middle */ 434 int w, h; 435 pango_layout->get_size (w, h); 436 int y = max(0,(line_height / 2) - ((h / Pango::SCALE) / 2)); 437 438 /* update subject start */ 439 //subject_start = date_start + (w / Pango::SCALE) + padding; 440 441 cr->move_to (cell_area.get_x() + message_count_start, cell_area.get_y() + y); 442 pango_layout->show_in_cairo_context (cr); 443 444 } // }}} 445 render_authors(const::Cairo::RefPtr<::Cairo::Context> & cr,Gtk::Widget & widget,const Gdk::Rectangle & cell_area)446 void ThreadIndexListCellRenderer::render_authors ( // {{{ 447 const ::Cairo::RefPtr< ::Cairo::Context>&cr, 448 Gtk::Widget &widget, 449 const Gdk::Rectangle &cell_area ) { 450 451 /* format authors string */ 452 ustring authors; 453 454 if (thread->authors.size () == 1) { 455 /* if only one, show full name */ 456 ustring an = get<0>(thread->authors[0]); 457 458 if (static_cast<int>(an.size()) >= authors_len) { 459 an = an.substr (0, authors_len); 460 UstringUtils::trim_right(an); 461 an += "."; 462 } 463 464 if (get<1>(thread->authors[0])) { 465 authors = ustring::compose ("<b>%1</b>", 466 Glib::Markup::escape_text (an)); 467 } else { 468 authors = Glib::Markup::escape_text (an); 469 } 470 471 } else { 472 /* show first names separated by comma */ 473 bool first = true; 474 475 int len = 0; 476 for (auto &a : thread->authors) { 477 if (!first) len += 1; // comma 478 479 ustring an = get<0>(a); 480 481 size_t pos = an.find_first_of (",. @"); 482 if (an[pos] == ',' || an[pos] == '.') { // last name, first name format or initial/title. 483 an = an.substr (pos + 1, an.size ()); 484 UstringUtils::trim_left (an); 485 pos = an.find_first_of (" @"); 486 an = an.substr (0, pos); 487 } else { 488 an = an.substr (0, pos); 489 } 490 491 int tlen = static_cast<int>(an.size()); 492 if ((len + tlen) >= authors_len) { 493 an = an.substr (0, authors_len - len); 494 UstringUtils::trim_right (an); 495 an += "."; 496 tlen = authors_len - len; 497 } 498 499 len += tlen; 500 501 if (!first) { 502 authors += ","; 503 } else { 504 first = false; 505 } 506 507 if (get<1>(a)) { 508 authors += ustring::compose ("<b>%1</b>", Glib::Markup::escape_text (an)); 509 } else { 510 authors += Glib::Markup::escape_text (an); 511 } 512 513 514 if (len >= authors_len) { 515 break; 516 } 517 } 518 } 519 520 521 Glib::RefPtr<Pango::Layout> pango_layout = widget.create_pango_layout (""); 522 pango_layout->set_markup (authors); 523 524 if (thread->unread) { 525 font_description.set_weight (Pango::WEIGHT_NORMAL); 526 } 527 528 pango_layout->set_font_description (font_description); 529 530 if (thread->unread) { 531 font_description.set_weight (Pango::WEIGHT_BOLD); 532 } 533 534 /* set color */ 535 Glib::RefPtr<Gtk::StyleContext> stylecontext = widget.get_style_context(); 536 Gdk::RGBA color = stylecontext->get_color(Gtk::STATE_FLAG_NORMAL); 537 cr->set_source_rgb (color.get_red(), color.get_green(), color.get_blue()); 538 539 /* align in the middle */ 540 int w, h; 541 pango_layout->get_size (w, h); 542 int y = max(0,(line_height / 2) - ((h / Pango::SCALE) / 2)); 543 544 /* update subject start */ 545 //subject_start = date_start + (w / Pango::SCALE) + padding; 546 547 cr->move_to (cell_area.get_x() + authors_start, cell_area.get_y() + y); 548 pango_layout->show_in_cairo_context (cr); 549 550 } // }}} 551 552 /* cellrenderer overloads {{{ */ get_height()553 int ThreadIndexListCellRenderer::get_height () { 554 if (height_set) return line_height; 555 else return 0; 556 } 557 calculate_height(Gtk::Widget & widget) const558 int ThreadIndexListCellRenderer::calculate_height (Gtk::Widget &widget) const { 559 if (height_set) return content_height; 560 561 /* figure out font height */ 562 Glib::RefPtr<Pango::Layout> pango_layout = widget.create_pango_layout ("TEST HEIGHT STRING"); 563 564 pango_layout->set_font_description (font_description); 565 566 int w, h; 567 pango_layout->get_pixel_size (w, h); 568 569 int content_height = h; 570 571 return content_height; 572 } 573 get_request_mode_vfunc() const574 Gtk::SizeRequestMode ThreadIndexListCellRenderer::get_request_mode_vfunc () const { 575 return Gtk::SIZE_REQUEST_CONSTANT_SIZE; 576 } 577 get_preferred_height_vfunc(Gtk::Widget & widget,int & minimum_height,int & natural_height) const578 void ThreadIndexListCellRenderer::get_preferred_height_vfunc ( 579 Gtk::Widget& widget, 580 int& minimum_height, 581 int& natural_height) const { 582 583 int height = calculate_height (widget) + line_spacing; 584 585 minimum_height = height; 586 natural_height = height; 587 } 588 get_preferred_height_for_width_vfunc(Gtk::Widget & widget,int,int & minimum_height,int & natural_height) const589 void ThreadIndexListCellRenderer::get_preferred_height_for_width_vfunc ( 590 Gtk::Widget& widget, 591 int /* width */, 592 int& minimum_height, 593 int& natural_height) const { 594 595 /* wrap non-width dependent */ 596 get_preferred_height_vfunc (widget, minimum_height, natural_height); 597 598 } 599 get_preferred_width_vfunc(Gtk::Widget &,int & minimum_width,int & natural_width) const600 void ThreadIndexListCellRenderer::get_preferred_width_vfunc ( 601 Gtk::Widget& /* widget*/, 602 int& minimum_width, 603 int& natural_width) const { 604 605 minimum_width = 100; 606 natural_width = minimum_width; 607 } 608 activate_vfunc(GdkEvent *,Gtk::Widget &,const Glib::ustring &,const Gdk::Rectangle &,const Gdk::Rectangle &,Gtk::CellRendererState)609 bool ThreadIndexListCellRenderer::activate_vfunc( 610 GdkEvent* /* event */, 611 Gtk::Widget& /* widget */, 612 const Glib::ustring& /* path */, 613 const Gdk::Rectangle& /* background_area */, 614 const Gdk::Rectangle& /* cell_area */, 615 Gtk::CellRendererState /* flags */) 616 { 617 return false; 618 } 619 // }}} 620 621 } 622 623