Class PopUpMenu
In: lib/json/editor.rb
Parent: Object

This class creates the popup menu, that opens when clicking onto the treeview.

Methods

Included Modules

MenuExtension

Public Instance methods

Append a new node to the selected Hash or Array.

[Source]

# File lib/json/editor.rb, line 388
      def append_new_node(item)
        if parent = selection.selected
          parent_type = parent.type
          case parent_type
          when 'Hash'
            key, type, content = ask_for_hash_pair(parent)
            key or return
            iter = create_node(parent, 'Key', key)
            iter = create_node(iter, type, content)
            toplevel.display_status(
              "Added a (key, value)-pair to '#{parent_type}'.")
            window.change
          when 'Array'
            type, content = ask_for_element(parent)
            type or return
            iter = create_node(parent, type, content)
            window.change
            toplevel.display_status("Appendend an element to '#{parent_type}'.")
          else
            toplevel.display_status("Cannot append to '#{parent_type}'!")
          end
        else
          type, content = ask_for_element
          type or return
          iter = create_node(nil, type, content)
          window.change
        end
      end

Change the type or content of the selected node.

[Source]

# File lib/json/editor.rb, line 265
      def change_node(item)
        if current = selection.selected
          parent = current.parent
          old_type, old_content = current.type, current.content
          if ALL_TYPES.include?(old_type)
            @clipboard_data = Editor.model2data(current)
            type, content = ask_for_element(parent, current.type,
              current.content)
            if type
              current.type, current.content = type, content
              current.remove_subtree(model)
              toplevel.display_status("Changed a node in tree.")
              window.change
            end
          else
            toplevel.display_status(
              "Cannot change node of type #{old_type} in tree!")
          end
        end
      end

Recursively collapse/expand a subtree starting from the selected node.

[Source]

# File lib/json/editor.rb, line 444
      def collapse_expand(item)
        if current = selection.selected
          if row_expanded?(current.path)
            collapse_row(current.path)
          else
            expand_row(current.path, true)
          end
        else
            toplevel.display_status("Append a node into the root first!")
        end
      end

Copy the selected node and its subtree, and save it into the clipboard.

[Source]

# File lib/json/editor.rb, line 305
      def copy_node(item)
        if current = selection.selected
          if current and current.type == 'Key'
            @clipboard_data = {
              current.content => Editor.model2data(current.first_child)
            }
          else
            @clipboard_data = Editor.model2data(current)
          end
          window.change
          toplevel.display_status("Copied a node from tree.")
        end
      end

Create the menu.

[Source]

# File lib/json/editor.rb, line 457
      def create
        add_item("Change node", ?n, &method(:change_node))
        add_separator
        add_item("Cut node", ?X, &method(:cut_node))
        add_item("Copy node", ?C, &method(:copy_node))
        add_item("Paste node (appending)", ?A, &method(:paste_node_appending))
        add_item("Paste node (inserting before)", ?I,
          &method(:paste_node_inserting_before))
        add_separator
        add_item("Append new node", ?a, &method(:append_new_node))
        add_item("Insert new node before", ?i, &method(:insert_new_node))
        add_separator 
        add_item("Collapse/Expand node (recursively)", ?e,
          &method(:collapse_expand))

        menu.show_all
        signal_connect(:button_press_event) do |widget, event|
          if event.kind_of? Gdk::EventButton and event.button == 3
            menu.popup(nil, nil, event.button, event.time)
          end
        end
        signal_connect(:popup_menu) do
          menu.popup(nil, nil, 0, Gdk::Event::CURRENT_TIME)
        end
      end

Cut the selected node and its subtree, and save it into the clipboard.

[Source]

# File lib/json/editor.rb, line 288
      def cut_node(item)
        if current = selection.selected
          if current and current.type == 'Key'
            @clipboard_data = {
              current.content => Editor.model2data(current.first_child)
            }
          else
            @clipboard_data = Editor.model2data(current)
          end
          model.remove(current)
          window.change
          toplevel.display_status("Cut a node from tree.")
        end
      end

Insert a new node into an Array before the selected element.

[Source]

# File lib/json/editor.rb, line 418
      def insert_new_node(item)
        if current = selection.selected
          parent = current.parent or return
          parent_parent = parent.parent
          parent_type = parent.type
          if parent_type == 'Array'
            selected_index = parent.each_with_index do |c, i|
              break i if c == current
            end
            type, content = ask_for_element(parent)
            type or return
            iter = model.insert_before(parent, current)
            iter.type, iter.content = type, content
            toplevel.display_status("Inserted an element to " +
              "'#{parent_type}' before index #{selected_index}.")
            window.change
          else
            toplevel.display_status(
              "Cannot insert node below '#{parent_type}'!")
          end
        else
            toplevel.display_status("Append a node into the root first!")
        end
      end

Paste the data in the clipboard into the selected Array or Hash by appending it.

[Source]

# File lib/json/editor.rb, line 321
      def paste_node_appending(item)
        if current = selection.selected
          if @clipboard_data
            case current.type
            when 'Array'
              Editor.data2model(@clipboard_data, model, current)
              expand_collapse(current)
            when 'Hash'
              if @clipboard_data.is_a? Hash
                parent = current.parent
                hash = Editor.model2data(current)
                model.remove(current)
                hash.update(@clipboard_data)
                Editor.data2model(hash, model, parent)
                if parent
                  expand_collapse(parent)
                elsif @expanded
                  expand_all
                end
                window.change
              else
                toplevel.display_status(
                  "Cannot paste non-#{current.type} data into '#{current.type}'!")
              end
            else
              toplevel.display_status(
                "Cannot paste node below '#{current.type}'!")
            end
          else
            toplevel.display_status("Nothing to paste in clipboard!")
          end
        else
            toplevel.display_status("Append a node into the root first!")
        end
      end

Paste the data in the clipboard into the selected Array inserting it before the selected element.

[Source]

# File lib/json/editor.rb, line 359
      def paste_node_inserting_before(item)
        if current = selection.selected
          if @clipboard_data
            parent = current.parent or return
            parent_type = parent.type
            if parent_type == 'Array'
              selected_index = parent.each_with_index do |c, i|
                break i if c == current
              end
              Editor.data2model(@clipboard_data, model, parent) do |m|
                m.insert_before(parent, current)
              end
              expand_collapse(current)
              toplevel.display_status("Inserted an element to " +
                "'#{parent_type}' before index #{selected_index}.")
              window.change
            else
              toplevel.display_status(
                "Cannot insert node below '#{parent_type}'!")
            end
          else
            toplevel.display_status("Nothing to paste in clipboard!")
          end
        else
            toplevel.display_status("Append a node into the root first!")
        end
      end

[Validate]