File: editable_iconview.cpp

package info (click to toggle)
mysql-workbench 6.3.8%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 113,932 kB
  • ctags: 87,814
  • sloc: ansic: 955,521; cpp: 427,465; python: 59,728; yacc: 59,129; xml: 54,204; sql: 7,091; objc: 965; makefile: 638; sh: 613; java: 237; perl: 30; ruby: 6; php: 1
file content (97 lines) | stat: -rw-r--r-- 3,679 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include "editable_iconview.h"
#include <gtk/gtk.h>

//------------------------------------------------------------------------------
EditableIconView::EditableIconView(const Glib::RefPtr<Gtk::TreeModel> & model)
         : Gtk::IconView(model)
{
#if GTK_MINOR_VERSION >= 18
  gtk_icon_view_set_item_padding(gobj(), 4);
#endif
}

//------------------------------------------------------------------------------
EditableIconView::EditableIconView()
         : Gtk::IconView()
{}

//------------------------------------------------------------------------------
bool EditableIconView::on_button_press_event(GdkEventButton *event)
{
  // Handle Gtk::IconView event first so it can do its logic before we are in
  const bool ret = Gtk::IconView::on_button_press_event(event);
  
  // Recheck here if we have correct model set for the IconView. It is possible
  // that we are dealing with Gtk::ListStore
  if (_model)
  {
    // Get the item at the mouse position, it is the one we need to decide on editing
    Gtk::TreeModel::Path path;

    if (get_item_at_pos((int)event->x, (int)event->y, path))
    {
      const bec::NodeId node(_model->get_node_for_path(path));

      Gtk::CellRenderer *cell(0);
      get_item_at_pos((int)event->x, (int)event->y, path, cell);
            
      if (node.is_valid() && _model->get_be_model()->is_editable(node))
      {
        // Check if it was the item selected before. We do not want to start edit
        // on newly clicked item
        if (_selected_path.gobj() && _selected_path.to_string() == path.to_string())
        {
          if ( cell && GTK_IS_CELL_RENDERER_TEXT(cell->gobj()) )
          {
            Gtk::CellRendererText* rend = static_cast<Gtk::CellRendererText*>(cell);
            // Enable editing, without that we are not able to start editing as gtk's code checks 
            // for cellrenderer to be editable
            rend->property_editable() = true;
            // connect signal so we can handle editing_done. Handling editing_done allows
            // us to update model, otherwise gtk won't pass new value to the model
            _start_conn = rend->signal_editing_started().connect(sigc::mem_fun(this, &EditableIconView::edit_started));
#if GTK_VERSION_GT(2,14)
            set_cursor(path, *cell, true);
#else
	    // gtkmm shipped with RHEL5.4 doesn't have set_cursor(), even tho gtk does
            gtk_icon_view_set_cursor(gobj(), path.gobj(), cell->gobj(), TRUE);
#endif
            // Disable editing, otherwise we will start edit on the next clicking on a different item
            rend->property_editable() = false;
          }
        }
      }
    }
    // Update selected path so we can detect second single click on the item
    _selected_path = path;
  }
  
  return ret;
}

//------------------------------------------------------------------------------
void EditableIconView::edit_started(Gtk::CellEditable* editable, const Glib::ustring& path)
{
  _start_conn.disconnect();
  if (editable)
    _done_conn = editable->signal_editing_done().connect(sigc::bind(sigc::mem_fun(this, &EditableIconView::edit_done), editable));
}

//------------------------------------------------------------------------------
void EditableIconView::edit_done(Gtk::CellEditable* editable)
{
  Gtk::Entry* entry = static_cast<Gtk::Entry*>(editable);
  if (entry)
  {
    Gtk::TreeModel::iterator iter = _model->get_iter(_selected_path);
    Gtk::TreeModel::Row row = *iter;
    if (row)
    {
      std::string data("");
      row.get_value(get_text_column(), data);
      if (data != entry->get_text())
        row.set_value(get_text_column(), entry->get_text());
    }
  }
  _done_conn.disconnect();
}