| Class | JSON::Editor::JSONTreeView |
| In: |
lib/json/editor.rb
|
| Parent: | Gtk::TreeView |
This class inherits from Gtk::TreeView, to configure it and to add a lot of behaviour to it.
| expanded | [RW] | Returns true, if nodes are autoexpanding, false otherwise. |
| window | [R] | Returns the MainWindow instance of this JSONTreeView. |
Creates a JSONTreeView instance, the parameter window is a MainWindow instance and used for self delegation.
# File lib/json/editor.rb, line 647
647: def initialize(window)
648: @window = window
649: super(TreeStore.new(Gdk::Pixbuf, String, String))
650: self.selection.mode = SELECTION_BROWSE
651:
652: @expanded = false
653: self.headers_visible = false
654: add_columns
655: add_popup_menu
656: end
Ask for an element to be appended parent.
# File lib/json/editor.rb, line 839
839: def ask_for_element(parent = nil, default_type = nil, value_text = @content)
840: type_input = value_input = nil
841:
842: dialog = Dialog.new(
843: "New element into #{parent ? parent.type : 'root'}",
844: nil, nil,
845: [ Stock::OK, Dialog::RESPONSE_ACCEPT ],
846: [ Stock::CANCEL, Dialog::RESPONSE_REJECT ]
847: )
848: hbox = HBox.new(false, 5)
849: hbox.add(Label.new("Type:"))
850: hbox.pack_start(type_input = ComboBox.new(true))
851: default_active = 0
852: ALL_TYPES.each_with_index do |t, i|
853: type_input.append_text(t)
854: if t == default_type
855: default_active = i
856: end
857: end
858: type_input.active = default_active
859: dialog.vbox.add(hbox)
860: type_input.signal_connect(:changed) do
861: configure_value(value_input, ALL_TYPES[type_input.active])
862: end
863:
864: hbox = HBox.new(false, 5)
865: hbox.add(Label.new("Value:"))
866: hbox.pack_start(value_input = Entry.new)
867: value_input.text = value_text if value_text
868: configure_value(value_input, ALL_TYPES[type_input.active])
869:
870: dialog.vbox.add(hbox)
871:
872: dialog.show_all
873: dialog.run do |response|
874: if response == Dialog::RESPONSE_ACCEPT
875: type = ALL_TYPES[type_input.active]
876: @content = case type
877: when 'Numeric'
878: Integer(value_input.text) rescue Float(value_input.text) rescue 0
879: else
880: value_input.text
881: end.to_s
882: return type, @content
883: end
884: end
885: return
886: ensure
887: dialog.destroy if dialog
888: end
Ask for a find term to search for in the tree. Returns the term as a string.
# File lib/json/editor.rb, line 923
923: def ask_for_find_term
924: dialog = Dialog.new(
925: "Find a node matching regex in tree.",
926: nil, nil,
927: [ Stock::OK, Dialog::RESPONSE_ACCEPT ],
928: [ Stock::CANCEL, Dialog::RESPONSE_REJECT ]
929: )
930: hbox = HBox.new(false, 5)
931:
932: hbox.add(Label.new("Regex:"))
933: hbox.pack_start(regex_input = Entry.new)
934: regex_input.text = @regex || ''
935:
936: dialog.vbox.add(hbox)
937:
938: dialog.show_all
939: dialog.run do |response|
940: if response == Dialog::RESPONSE_ACCEPT
941: return @regex = regex_input.text
942: end
943: end
944: return
945: ensure
946: dialog.destroy if dialog
947: end
Ask for a hash key, value pair to be added to the Hash node parent.
# File lib/json/editor.rb, line 772
772: def ask_for_hash_pair(parent)
773: key_input = type_input = value_input = nil
774:
775: dialog = Dialog.new("New (key, value) pair for Hash", nil, nil,
776: [ Stock::OK, Dialog::RESPONSE_ACCEPT ],
777: [ Stock::CANCEL, Dialog::RESPONSE_REJECT ]
778: )
779:
780: hbox = HBox.new(false, 5)
781: hbox.pack_start(Label.new("Key:"))
782: hbox.pack_start(key_input = Entry.new)
783: key_input.text = @key || ''
784: dialog.vbox.add(hbox)
785: key_input.signal_connect(:activate) do
786: if parent.any? { |c| c.content == key_input.text }
787: toplevel.display_status('Key already exists in Hash!')
788: key_input.text = ''
789: else
790: toplevel.display_status('Key has been changed.')
791: end
792: end
793:
794: hbox = HBox.new(false, 5)
795: hbox.add(Label.new("Type:"))
796: hbox.pack_start(type_input = ComboBox.new(true))
797: ALL_TYPES.each { |t| type_input.append_text(t) }
798: type_input.active = @type || 0
799: dialog.vbox.add(hbox)
800:
801: type_input.signal_connect(:changed) do
802: value_input.editable = false
803: case ALL_TYPES[type_input.active]
804: when 'Array', 'Hash'
805: value_input.text = ''
806: when 'TrueClass'
807: value_input.text = 'true'
808: when 'FalseClass'
809: value_input.text = 'false'
810: when 'NilClass'
811: value_input.text = 'null'
812: else
813: value_input.text = ''
814: value_input.editable = true
815: end
816: end
817:
818: hbox = HBox.new(false, 5)
819: hbox.add(Label.new("Value:"))
820: hbox.pack_start(value_input = Entry.new)
821: value_input.text = @value || ''
822: dialog.vbox.add(hbox)
823:
824: dialog.show_all
825: dialog.run do |response|
826: if response == Dialog::RESPONSE_ACCEPT
827: @key = key_input.text
828: type = ALL_TYPES[@type = type_input.active]
829: content = value_input.text
830: return @key, type, content
831: end
832: end
833: return
834: ensure
835: dialog.destroy
836: end
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 lib/json/editor.rb, line 893
893: def ask_for_order
894: dialog = Dialog.new(
895: "Give an order criterium for 'x'.",
896: nil, nil,
897: [ Stock::OK, Dialog::RESPONSE_ACCEPT ],
898: [ Stock::CANCEL, Dialog::RESPONSE_REJECT ]
899: )
900: hbox = HBox.new(false, 5)
901:
902: hbox.add(Label.new("Order:"))
903: hbox.pack_start(order_input = Entry.new)
904: order_input.text = @order || 'x'
905:
906: hbox.pack_start(reverse_checkbox = CheckButton.new('Reverse'))
907:
908: dialog.vbox.add(hbox)
909:
910: dialog.show_all
911: dialog.run do |response|
912: if response == Dialog::RESPONSE_ACCEPT
913: return @order = order_input.text, reverse_checkbox.active?
914: end
915: end
916: return
917: ensure
918: dialog.destroy if dialog
919: end
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 lib/json/editor.rb, line 758
758: def create_node(parent, type, content)
759: iter = if parent
760: model.append(parent)
761: else
762: new_model = Editor.data2model(nil)
763: toplevel.view_new_model(new_model)
764: new_model.iter_first
765: end
766: iter.type, iter.content = type, content
767: expand_collapse(parent) if parent
768: iter
769: end
Expand or collapse row pointed to by iter according to the expanded attribute.
# File lib/json/editor.rb, line 951
951: def expand_collapse(iter)
952: if expanded
953: expand_row(iter.path, true)
954: else
955: collapse_row(iter.path)
956: end
957: end
# File lib/json/editor.rb, line 666
666: def add_columns
667: cell = CellRendererPixbuf.new
668: column = TreeViewColumn.new('Icon', cell,
669: 'pixbuf' => ICON_COL
670: )
671: append_column(column)
672:
673: cell = CellRendererText.new
674: column = TreeViewColumn.new('Type', cell,
675: 'text' => TYPE_COL
676: )
677: append_column(column)
678:
679: cell = CellRendererText.new
680: cell.editable = true
681: column = TreeViewColumn.new('Content', cell,
682: 'text' => CONTENT_COL
683: )
684: cell.signal_connect(:edited, &method(:cell_edited))
685: append_column(column)
686: end
# File lib/json/editor.rb, line 748
748: def add_popup_menu
749: menu = PopUpMenu.new(self)
750: menu.create
751: end
# File lib/json/editor.rb, line 701
701: def cell_edited(cell, path, value)
702: iter = model.get_iter(path)
703: case iter.type
704: when 'Key'
705: unify_key(iter, value)
706: toplevel.display_status('Key has been changed.')
707: when 'FalseClass'
708: value.downcase!
709: if value == 'true'
710: iter.type, iter.content = 'TrueClass', 'true'
711: end
712: when 'TrueClass'
713: value.downcase!
714: if value == 'false'
715: iter.type, iter.content = 'FalseClass', 'false'
716: end
717: when 'Numeric'
718: iter.content = (Integer(value) rescue Float(value) rescue 0).to_s
719: when 'String'
720: iter.content = value
721: when 'Hash', 'Array'
722: return
723: else
724: fail "Unknown type found in model: #{iter.type}"
725: end
726: window.change
727: end
# File lib/json/editor.rb, line 729
729: def configure_value(value, type)
730: value.editable = false
731: case type
732: when 'Array', 'Hash'
733: value.text = ''
734: when 'TrueClass'
735: value.text = 'true'
736: when 'FalseClass'
737: value.text = 'false'
738: when 'NilClass'
739: value.text = 'null'
740: when 'Numeric', 'String'
741: value.text ||= ''
742: value.editable = true
743: else
744: raise ArgumentError, "unknown type '#{type}' encountered"
745: end
746: end
# File lib/json/editor.rb, line 688
688: def unify_key(iter, key)
689: return unless iter.type == 'Key'
690: parent = iter.parent
691: if parent.any? { |c| c != iter and c.content == key }
692: old_key = key
693: i = 0
694: begin
695: key = sprintf("%s.%d", old_key, i += 1)
696: end while parent.any? { |c| c != iter and c.content == key }
697: end
698: iter.content = key
699: end