Class MainWindow
In: lib/json/editor.rb
Parent: Gtk::Window
OptionsMenu EditMenu PopUpMenu FileMenu JSONTreeView MainWindow ParserError NestingError GeneratorError CircularDatastructure StandardError JSONError MissingUnicodeSupport StringScanner Parser State Enumerable TreeIter Gtk::TreeView Gtk::Window MenuExtension lib/json/common.rb Ext lib/json/pure/parser.rb lib/json/pure/generator.rb Integer FalseClass Array Hash Float NilClass Object TrueClass Extend String GeneratorMethods Generator Pure Editor JSON Editor lib/json/editor.rb Gtk dot/f_1.png

The editor main window

Methods

Included Modules

Gtk

Public Class methods

[Source]

      # File lib/json/editor.rb, line 1041
1041:       def initialize(encoding)
1042:         @changed  = false
1043:         @encoding = encoding
1044:         super(TOPLEVEL)
1045:         display_title
1046:         set_default_size(800, 600)
1047:         signal_connect(:delete_event) { quit }
1048: 
1049:         vbox = VBox.new(false, 0)
1050:         add(vbox)
1051:         #vbox.border_width = 0
1052: 
1053:         @treeview = JSONTreeView.new(self)
1054:         @treeview.signal_connect('cursor-changed''cursor-changed') do
1055:           display_status('')
1056:         end
1057: 
1058:         menu_bar = create_menu_bar
1059:         vbox.pack_start(menu_bar, false, false, 0)
1060: 
1061:         sw = ScrolledWindow.new(nil, nil)
1062:         sw.shadow_type = SHADOW_ETCHED_IN
1063:         sw.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
1064:         vbox.pack_start(sw, true, true, 0)
1065:         sw.add(@treeview)
1066: 
1067:         @status_bar = Statusbar.new
1068:         vbox.pack_start(@status_bar, false, false, 0)
1069: 
1070:         @filename ||= nil
1071:         if @filename
1072:           data = read_data(@filename)
1073:           view_new_model Editor.data2model(data)
1074:         end
1075: 
1076:         signal_connect(:button_release_event) do |_,event|
1077:           if event.button == 2
1078:             c = Gtk::Clipboard.get(Gdk::Selection::PRIMARY)
1079:             if url = c.wait_for_text
1080:               location_open url
1081:             end
1082:             false
1083:           else
1084:             true
1085:           end
1086:         end
1087:       end

Public Instance methods

Ask for location URI a to load data from. Returns the URI as a string.

[Source]

      # File lib/json/editor.rb, line 1311
1311:       def ask_for_location
1312:         dialog = Dialog.new(
1313:           "Load data from location...",
1314:           nil, nil,
1315:           [ Stock::OK, Dialog::RESPONSE_ACCEPT ],
1316:           [ Stock::CANCEL, Dialog::RESPONSE_REJECT ]
1317:         )
1318:         hbox = HBox.new(false, 5)
1319: 
1320:         hbox.pack_start(Label.new("Location:"), false)
1321:         hbox.pack_start(location_input = Entry.new)
1322:         location_input.width_chars = 60
1323:         location_input.text = @location || ''
1324: 
1325:         dialog.vbox.pack_start(hbox, false)
1326: 
1327:         dialog.signal_connect('key-press-event''key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER)
1328:         dialog.show_all
1329:         dialog.run do |response| 
1330:           if response == Dialog::RESPONSE_ACCEPT
1331:             return @location = location_input.text
1332:           end
1333:         end
1334:         return
1335:       ensure
1336:         dialog.destroy if dialog
1337:       end

Opens a dialog, asking, if changes should be saved to a file.

[Source]

      # File lib/json/editor.rb, line 1132
1132:       def ask_save
1133:         if Editor.question_dialog(self,
1134:           "Unsaved changes to JSON model. Save?")
1135:           if @filename
1136:             file_save
1137:           else
1138:             file_save_as
1139:           end
1140:         end
1141:       end

Sets editor status to changed, to indicate that the edited data containts unsaved changes.

[Source]

      # File lib/json/editor.rb, line 1103
1103:       def change
1104:         @changed = true
1105:         display_title
1106:       end

Clear the current model, after asking to save all unsaved changes.

[Source]

      # File lib/json/editor.rb, line 1162
1162:       def clear
1163:         ask_save if @changed
1164:         @filename = nil
1165:         self.view_new_model nil
1166:       end

Creates the menu bar with the pulldown menus and returns it.

[Source]

      # File lib/json/editor.rb, line 1090
1090:       def create_menu_bar
1091:         menu_bar = MenuBar.new
1092:         @file_menu = FileMenu.new(@treeview)
1093:         menu_bar.append @file_menu.create
1094:         @edit_menu = EditMenu.new(@treeview)
1095:         menu_bar.append @edit_menu.create
1096:         @options_menu = OptionsMenu.new(@treeview)
1097:         menu_bar.append @options_menu.create
1098:         menu_bar
1099:       end

Displays text in the status bar.

[Source]

      # File lib/json/editor.rb, line 1124
1124:       def display_status(text)
1125:         @cid ||= nil
1126:         @status_bar.pop(@cid) if @cid
1127:         @cid = @status_bar.get_context_id('dummy')
1128:         @status_bar.push(@cid, text)
1129:       end

Display the new title according to the editor‘s current state.

[Source]

      # File lib/json/editor.rb, line 1154
1154:       def display_title
1155:         title = TITLE.dup
1156:         title << ": #@filename" if @filename
1157:         title << " *" if @changed
1158:         self.title = title
1159:       end

Edit the string json in the editor.

[Source]

      # File lib/json/editor.rb, line 1193
1193:       def edit(json)
1194:         if json.respond_to? :read
1195:           json = json.read
1196:         end
1197:         data = parse_json json
1198:         view_new_model Editor.data2model(data)
1199:       end

Open the file filename or call the select_file method to ask for a filename.

[Source]

      # File lib/json/editor.rb, line 1186
1186:       def file_open(filename = nil)
1187:         filename = select_file('Open as a JSON file') unless filename
1188:         data = load_file(filename) or return
1189:         view_new_model Editor.data2model(data)
1190:       end

Save the current file.

[Source]

      # File lib/json/editor.rb, line 1202
1202:       def file_save
1203:         if @filename
1204:           store_file(@filename)
1205:         else
1206:           file_save_as
1207:         end
1208:       end

Save the current file as the filename

[Source]

      # File lib/json/editor.rb, line 1211
1211:       def file_save_as
1212:         filename = select_file('Save as a JSON file')
1213:         store_file(filename)
1214:       end

Load the file named filename into the editor as a JSON document.

[Source]

      # File lib/json/editor.rb, line 1238
1238:       def load_file(filename)
1239:         if filename
1240:           if File.directory?(filename)
1241:             Editor.error_dialog(self, "Try to select a JSON file!")
1242:             nil
1243:           else
1244:             @filename = filename
1245:             if data = read_data(filename)
1246:               toplevel.display_status("Loaded data from '#@filename'.")
1247:             end
1248:             display_title
1249:             data
1250:           end
1251:         end
1252:       end

Load the data at location uri into the editor as a JSON document.

[Source]

      # File lib/json/editor.rb, line 1255
1255:       def load_location(uri)
1256:         data = read_data(uri) or return
1257:         @filename = nil
1258:         toplevel.display_status("Loaded data from '#{uri}'.")
1259:         display_title
1260:         data
1261:       end

Open the data at the location uri, if given. Otherwise open a dialog to ask for the uri.

[Source]

      # File lib/json/editor.rb, line 1176
1176:       def location_open(uri = nil)
1177:         uri = ask_for_location unless uri
1178:         uri or return
1179:         ask_save if @changed
1180:         data = load_location(uri) or return
1181:         view_new_model Editor.data2model(data)
1182:       end

Quit this editor, that is, leave this editor‘s main loop.

[Source]

      # File lib/json/editor.rb, line 1144
1144:       def quit
1145:         ask_save if @changed
1146:         if Gtk.main_level > 0
1147:           destroy
1148:           Gtk.main_quit
1149:         end
1150:         nil
1151:       end

Read a JSON document from the file named filename, parse it into a ruby data structure, and return the data.

[Source]

      # File lib/json/editor.rb, line 1275
1275:       def read_data(filename)
1276:         open(filename) do |f|
1277:           json = f.read
1278:           return parse_json(json)
1279:         end
1280:       rescue => e
1281:         Editor.error_dialog(self, "Failed to parse JSON file: #{e}!")
1282:         return
1283:       end

Open a file selecton dialog, displaying message, and return the selected filename or nil, if no file was selected.

[Source]

      # File lib/json/editor.rb, line 1287
1287:       def select_file(message)
1288:         filename = nil
1289:         fs = FileSelection.new(message)
1290:         fs.set_modal(true)
1291:         @default_dir = File.join(Dir.pwd, '') unless @default_dir
1292:         fs.set_filename(@default_dir)
1293:         fs.set_transient_for(self)
1294:         fs.signal_connect(:destroy) { Gtk.main_quit }
1295:         fs.ok_button.signal_connect(:clicked) do
1296:           filename = fs.filename
1297:           @default_dir = File.join(File.dirname(filename), '')
1298:           fs.destroy
1299:           Gtk.main_quit
1300:         end
1301:         fs.cancel_button.signal_connect(:clicked) do
1302:           fs.destroy
1303:           Gtk.main_quit
1304:         end
1305:         fs.show_all
1306:         Gtk.main
1307:         filename
1308:       end

Store the current JSON document to path.

[Source]

      # File lib/json/editor.rb, line 1217
1217:       def store_file(path)
1218:         if path
1219:           data = Editor.model2data(@treeview.model.iter_first)
1220:           File.open(path + '.tmp', 'wb') do |output|
1221:             data or break
1222:             if @options_menu.pretty_item.active?
1223:               output.puts JSON.pretty_generate(data, :max_nesting => false)
1224:             else
1225:               output.write JSON.generate(data, :max_nesting => false)
1226:             end
1227:           end
1228:           File.rename path + '.tmp', path
1229:           @filename = path
1230:           toplevel.display_status("Saved data to '#@filename'.")
1231:           unchange
1232:         end
1233:       rescue SystemCallError => e
1234:         Editor.error_dialog(self, "Failed to store JSON file: #{e}!")
1235:       end

Sets editor status to unchanged, to indicate that the edited data doesn‘t containt unsaved changes.

[Source]

      # File lib/json/editor.rb, line 1110
1110:       def unchange
1111:         @changed = false
1112:         display_title
1113:       end

Puts a new model model into the Gtk::TreeView to be edited.

[Source]

      # File lib/json/editor.rb, line 1116
1116:       def view_new_model(model)
1117:         @treeview.model     = model
1118:         @treeview.expanded  = true
1119:         @treeview.expand_all
1120:         unchange
1121:       end

Private Instance methods

[Source]

      # File lib/json/editor.rb, line 1168
1168:       def check_pretty_printed(json)
1169:         pretty = !!((nl_index = json.index("\n")) && nl_index != json.size - 1)
1170:         @options_menu.pretty_item.active = pretty
1171:       end

[Source]

      # File lib/json/editor.rb, line 1263
1263:       def parse_json(json)
1264:         check_pretty_printed(json)
1265:         if @encoding && !/^utf8$/i.match(@encoding)
1266:           iconverter = Iconv.new('utf8', @encoding)
1267:           json = iconverter.iconv(json)
1268:         end
1269:         JSON::parse(json, :max_nesting => false, :create_additions => false)
1270:       end

[Validate]