In Files

  • json/lib/json/editor.rb

JSON::Editor::JSONTreeView

This class inherits from Gtk::TreeView, to configure it and to add a lot of behaviour to it.

Attributes

expanded[RW]

Returns true, if nodes are autoexpanding, false otherwise.

window[R]

Returns the MainWindow instance of this JSONTreeView.

Public Class Methods

new(window) click to toggle source

Creates a JSONTreeView instance, the parameter window is a MainWindow instance and used for self delegation.

 
               # File json/lib/json/editor.rb, line 701
def initialize(window)
  @window = window
  super(TreeStore.new(Gdk::Pixbuf, String, String))
  self.selection.mode = SELECTION_BROWSE

  @expanded = false
  self.headers_visible = false
  add_columns
  add_popup_menu
end
            

Public Instance Methods

ask_for_element(parent = nil, default_type = nil, value_text = @content) click to toggle source

Ask for an element to be appended parent.

 
               # File json/lib/json/editor.rb, line 902
def ask_for_element(parent = nil, default_type = nil, value_text = @content)
  type_input = value_input = nil

  dialog = Dialog.new(
    "New element into #{parent ? parent.type : 'root'}",
    nil, nil,
    [ Stock::OK, Dialog::RESPONSE_ACCEPT ],
    [ Stock::CANCEL, Dialog::RESPONSE_REJECT ]
  )
  hbox = HBox.new(false, 5)
  hbox.pack_start(Label.new("Type:"), false)
  hbox.pack_start(type_input = ComboBox.new(true))
  default_active = 0
  types = parent ? ALL_TYPES : CONTAINER_TYPES
  types.each_with_index do |t, i|
    type_input.append_text(t)
    if t == default_type
      default_active = i
    end
  end
  type_input.active = default_active
  dialog.vbox.pack_start(hbox, false)
  type_input.signal_connect(:changed) do
    configure_value(value_input, types[type_input.active])
  end

  hbox = HBox.new(false, 5)
  hbox.pack_start(Label.new("Value:"), false)
  hbox.pack_start(value_input = Entry.new)
  value_input.width_chars = 60
  value_input.text = value_text if value_text
  configure_value(value_input, types[type_input.active])

  dialog.vbox.pack_start(hbox, false)

  dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER)
  dialog.show_all
  self.focus = dialog
  dialog.run do |response| 
    if response == Dialog::RESPONSE_ACCEPT
      type = types[type_input.active]
      @content = case type
      when 'Numeric'
        if (t = value_input.text) == 'Infinity'
          1 / 0.0
        else
          Integer(t) rescue Float(t) rescue 0
        end
      else
        value_input.text
      end.to_s
      return type, @content
    end
  end
  return
ensure
  dialog.destroy if dialog
end
            
ask_for_find_term(search = nil) click to toggle source

Ask for a find term to search for in the tree. Returns the term as a string.

 
               # File json/lib/json/editor.rb, line 997
def ask_for_find_term(search = nil)
  dialog = Dialog.new(
    "Find a node matching regex in tree.",
    nil, nil,
    [ Stock::OK, Dialog::RESPONSE_ACCEPT ],
    [ Stock::CANCEL, Dialog::RESPONSE_REJECT ]
  )
  hbox = HBox.new(false, 5)

  hbox.pack_start(Label.new("Regex:"), false)
  hbox.pack_start(regex_input = Entry.new)
  hbox.pack_start(icase_checkbox = CheckButton.new('Icase'), false)
  regex_input.width_chars = 60
  if search
    regex_input.text = search.source
    icase_checkbox.active = search.casefold?
  end

  dialog.vbox.pack_start(hbox, false)

  dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER)
  dialog.show_all
  self.focus = dialog
  dialog.run do |response| 
    if response == Dialog::RESPONSE_ACCEPT
      begin
        return Regexp.new(regex_input.text, icase_checkbox.active? ? Regexp::IGNORECASE : 0)
      rescue => e
        Editor.error_dialog(self, "Evaluation of regex /#{regex_input.text}/ failed: #{e}!")
        return
      end
    end
  end
  return
ensure
  dialog.destroy if dialog
end
            
ask_for_hash_pair(parent) click to toggle source

Ask for a hash key, value pair to be added to the Hash node parent.

 
               # File json/lib/json/editor.rb, line 831
def ask_for_hash_pair(parent)
  key_input = type_input = value_input = nil

  dialog = Dialog.new("New (key, value) pair for Hash", nil, nil,
    [ Stock::OK, Dialog::RESPONSE_ACCEPT ],
    [ Stock::CANCEL, Dialog::RESPONSE_REJECT ]
  )
  dialog.width_request = 640

  hbox = HBox.new(false, 5)
  hbox.pack_start(Label.new("Key:"), false)
  hbox.pack_start(key_input = Entry.new)
  key_input.text = @key || ''
  dialog.vbox.pack_start(hbox, false)
  key_input.signal_connect(:activate) do
    if parent.any? { |c| c.content == key_input.text }
      toplevel.display_status('Key already exists in Hash!')
      key_input.text = ''
    else
      toplevel.display_status('Key has been changed.')
    end
  end

  hbox = HBox.new(false, 5)
  hbox.pack_start(Label.new("Type:"), false)
  hbox.pack_start(type_input = ComboBox.new(true))
  ALL_TYPES.each { |t| type_input.append_text(t) }
  type_input.active = @type || 0
  dialog.vbox.pack_start(hbox, false)

  type_input.signal_connect(:changed) do
    value_input.editable = false
    case ALL_TYPES[type_input.active]
    when 'Array', 'Hash'
      value_input.text = ''
    when 'TrueClass'
      value_input.text = 'true'
    when 'FalseClass'
      value_input.text = 'false'
    when 'NilClass'
      value_input.text = 'null'
    else
      value_input.text = ''
      value_input.editable = true
    end
  end

  hbox = HBox.new(false, 5)
  hbox.pack_start(Label.new("Value:"), false)
  hbox.pack_start(value_input = Entry.new)
  value_input.width_chars = 60
  value_input.text = @value || ''
  dialog.vbox.pack_start(hbox, false)

  dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER)
  dialog.show_all
  self.focus = dialog
  dialog.run do |response| 
    if response == Dialog::RESPONSE_ACCEPT
      @key = key_input.text
      type = ALL_TYPES[@type = type_input.active]
      content = value_input.text
      return @key, type, content
    end
  end
  return
ensure
  dialog.destroy
end
            
ask_for_order() click to toggle source

Ask for an order criteria for sorting, using x for the element in question. Returns the order criterium, and true/false for reverse sorting.

 
               # File json/lib/json/editor.rb, line 964
def ask_for_order
  dialog = Dialog.new(
    "Give an order criterium for 'x'.",
    nil, nil,
    [ Stock::OK, Dialog::RESPONSE_ACCEPT ],
    [ Stock::CANCEL, Dialog::RESPONSE_REJECT ]
  )
  hbox = HBox.new(false, 5)

  hbox.pack_start(Label.new("Order:"), false)
  hbox.pack_start(order_input = Entry.new)
  order_input.text = @order || 'x'
  order_input.width_chars = 60

  hbox.pack_start(reverse_checkbox = CheckButton.new('Reverse'), false)

  dialog.vbox.pack_start(hbox, false)

  dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER)
  dialog.show_all
  self.focus = dialog
  dialog.run do |response| 
    if response == Dialog::RESPONSE_ACCEPT
      return @order = order_input.text, reverse_checkbox.active?
    end
  end
  return
ensure
  dialog.destroy if dialog
end
            
create_node(parent, type, content) click to toggle source

Create a type node with content content, and add it to parent in the model. If parent is nil, create a new model and put it into the editor treeview.

 
               # File json/lib/json/editor.rb, line 817
def create_node(parent, type, content)
  iter = if parent
    model.append(parent)
  else
    new_model = Editor.data2model(nil)
    toplevel.view_new_model(new_model)
    new_model.iter_first
  end
  iter.type, iter.content = type, content
  expand_collapse(parent) if parent
  iter
end
            
expand_collapse(iter) click to toggle source

Expand or collapse row pointed to by iter according to the expanded attribute.

 
               # File json/lib/json/editor.rb, line 1037
def expand_collapse(iter)
  if expanded
    expand_row(iter.path, true)
  else
    collapse_row(iter.path)
  end
end