ifmapper 0.9.9 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,13 +7,18 @@
7
7
  class FXMapFileDialog < FXFileDialog
8
8
  @@last_path = nil
9
9
 
10
- KNOWN_EXTENSIONS = [
11
- "Map Files (*.map,*.gmp,*.ifm,*.inf,*.t,*.t3m)",
12
- "All Files (*)",
10
+ KNOWN_LOAD_EXTENSIONS = [
11
+ "#{EXT_MAP_FILES} (*.map,*.gmp,*.ifm,*.inf,*.t,*.t3m)",
12
+ EXT_ALL_FILES,
13
+ ]
14
+
15
+ KNOWN_SAVE_EXTENSIONS = [
16
+ "#{EXT_MAP_FILES} (*.map,*.gmp,*.ifm,*.inf,*.inform,*.t,*.t3m)",
17
+ EXT_ALL_FILES,
13
18
  ]
14
19
 
15
20
 
16
- def initialize(parent, title, patterns = KNOWN_EXTENSIONS)
21
+ def initialize(parent, title, patterns = KNOWN_LOAD_EXTENSIONS)
17
22
  opts = 0
18
23
  if RUBY_PLATFORM =~ /mswin/
19
24
  opts |= FILEMATCH_NOESCAPE
@@ -1,8 +1,31 @@
1
1
 
2
+ begin
3
+ require 'iconv'
4
+ rescue LoadError
5
+ $stderr.puts 'Iconv could not be loaded. Languages other than English will have problems'
6
+ class Iconv
7
+ def initialize(to, from)
8
+ end
9
+
10
+ def iconv(a)
11
+ a
12
+ end
13
+ end
14
+ end
15
+
16
+
2
17
  #
3
18
  # This class contains the applicatio and map's settings
4
19
  #
5
20
  class FXMapperSettings < Hash
21
+
22
+ class UnknownParameter < StandardError; end;
23
+
24
+ #
25
+ # Return the home location
26
+ #
27
+ # Result: home location for user
28
+ #
6
29
  def home
7
30
  if ENV['HOME']
8
31
  homedir = File.expand_path('~')
@@ -17,6 +40,12 @@ class FXMapperSettings < Hash
17
40
  return homedir
18
41
  end
19
42
 
43
+
44
+ #
45
+ # Write out the preferences to disk.
46
+ #
47
+ # Result: none
48
+ #
20
49
  def write
21
50
  begin
22
51
  file = home + '/.ifmapper'
@@ -29,47 +58,148 @@ class FXMapperSettings < Hash
29
58
  end
30
59
  end
31
60
 
61
+
62
+ if RUBY_PLATFORM =~ /mswin/
63
+ require 'Win32API'
64
+ LOCALE_USER_DEFAULT = 0x400
65
+ LOCALE_SLANGUAGE = 0x1001
66
+
67
+ FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000
68
+ FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000
69
+ FormatMessage = Win32API.new("kernel32","FormatMessage","LPLLPLP","L")
70
+ GetLastError = Win32API.new("kernel32","GetLastError",[],"L")
71
+ GetLocaleInfo = Win32API.new('Kernel32.dll', 'GetLocaleInfo',
72
+ %w{l l p i}, 'i')
73
+
74
+ LANGUAGES = {
75
+ /English/ => 'en',
76
+ /Spanish/ => 'es',
77
+ # todo1
78
+ /German/ => 'de',
79
+ /Italian/ => 'it',
80
+ /French/ => 'fr',
81
+ /Japanese/ => 'ja',
82
+ /Chinese/ => 'ch',
83
+ /Korean/ => 'ko',
84
+ /Arabic/ => 'ar',
85
+ /Hebrew/ => 'he',
86
+ }
87
+ end
88
+
89
+
90
+ #
91
+ # Restore user preferences
92
+ #
93
+ # Result:
94
+ #
32
95
  def initialize
96
+ has_yaml = true
33
97
  begin
98
+ require 'yaml'
34
99
  f = home + '/.ifmapper'
35
100
  self.replace( YAML.load_file(f) )
101
+ rescue LoadError
102
+ has_yaml = false
36
103
  rescue
37
104
  end
38
105
 
106
+ if RUBY_PLATFORM =~ /mswin/
107
+ lcid = LOCALE_USER_DEFAULT
108
+ lctype = LOCALE_SLANGUAGE
109
+ slanguage = '\0' * 256
110
+ len = 256
111
+ ret = GetLocaleInfo.call lcid, lctype, slanguage, len
112
+ if ret == 0
113
+ error_code = GetLastError.call
114
+ msg = " " * 255
115
+ FormatMessage.call(
116
+ FORMAT_MESSAGE_FROM_SYSTEM +
117
+ FORMAT_MESSAGE_ARGUMENT_ARRAY,
118
+ '',
119
+ error_code,
120
+ 0,
121
+ msg,
122
+ 255,
123
+ ''
124
+ )
125
+ msg.gsub!(/\000/, '')
126
+ msg.strip!
127
+ $stderr.puts msg
128
+ end
129
+ language = 'en'
130
+ LANGUAGES.each { |re, locale|
131
+ if slanguage =~ re
132
+ language = locale
133
+ break
134
+ end
135
+ }
136
+ else
137
+ locale = ENV['LC_ALL'] || ENV['LC_CTYPE'] || 'en_US'
138
+ language = locale[0,2]
139
+ end
140
+
141
+ while ARGV.size > 0
142
+ param = ARGV.shift
143
+ case param
144
+ when /^-l(anguage)?$/
145
+ language = ARGV.shift
146
+ language = language[0,2].downcase
147
+ self['Language'] = language
148
+ else
149
+ $stderr.puts "Unknown parameter '#{param}'."
150
+ exit(1)
151
+ end
152
+ end
153
+
39
154
  defaults = {
40
- # Colors
41
- 'BG Color' => 'dark grey',
42
- 'Arrow Color' => 'black',
43
- 'Box BG Color' => 'white',
44
- 'Box Darkness Color' => 'grey',
45
- 'Box Border Color' => 'black',
46
- 'Box Number Color' => 'grey',
47
-
48
- # Fonts
49
- 'Font Text' => 'Times',
50
- 'Font Objects' => 'Times',
51
-
52
- # Creation options
53
- 'Create on Connection' => true,
54
- 'Edit on Creation' => false,
55
- 'Automatic Connection' => true,
56
-
57
-
58
- # Display options
59
- 'Use Room Cursor' => false,
60
- 'Paths as Curves' => true,
61
-
62
- # Location options
63
- 'Location Tasks' => true,
64
- 'Location Description' => false,
65
- 'Location Numbers' => true,
66
-
67
- # Grid options
68
- 'Grid Boxes' => true,
69
- 'Grid Straight Connections' => true,
70
- 'Grid Diagonal Connections' => false,
71
- }
155
+ # Language
156
+ 'Language' => language,
157
+
158
+ # Colors
159
+ 'BG Color' => 'dark grey',
160
+ 'Arrow Color' => 'black',
161
+ 'Box BG Color' => 'white',
162
+ 'Box Darkness Color' => 'grey',
163
+ 'Box Border Color' => 'black',
164
+ 'Box Number Color' => 'grey',
165
+
166
+ # Fonts
167
+ 'Font Text' => 'Times',
168
+ 'Font Objects' => 'Times',
169
+
170
+ # Creation options
171
+ 'Create on Connection' => true,
172
+ 'Edit on Creation' => false,
173
+ 'Automatic Connection' => true,
174
+
175
+
176
+ # Display options
177
+ 'Use Room Cursor' => false,
178
+ 'Paths as Curves' => true,
179
+
180
+ # Location options
181
+ 'Location Tasks' => true,
182
+ 'Location Description' => false,
183
+ 'Location Numbers' => true,
184
+
185
+ # Grid options
186
+ 'Grid Boxes' => true,
187
+ 'Grid Straight Connections' => true,
188
+ 'Grid Diagonal Connections' => false,
189
+
190
+ }
72
191
 
73
192
  self.replace( defaults.merge(self) )
193
+ language = self['Language']
194
+
195
+ begin
196
+ require "IFMapper/locales/#{language}/Messages.rb"
197
+ rescue LoadError => e
198
+ puts "Language '#{language}' was not found."
199
+ end
200
+
201
+ unless has_yaml
202
+ $stderr.puts ERR_NO_YAML
203
+ end
74
204
  end
75
205
  end
@@ -1,4 +1,5 @@
1
1
 
2
+
2
3
  begin
3
4
  $rubygems = false
4
5
  require 'rubygems'
@@ -7,9 +8,9 @@ rescue LoadError
7
8
  end
8
9
 
9
10
  def no_fox
10
- $stderr.puts "Please install the FXRuby (FOX) library v1.2 or later."
11
+ $stderr.puts ERR_NO_FOX
11
12
  if $rubygems
12
- $stderr.puts "You can usually do so if you do 'gem install -r fxruby'."
13
+ $stderr.puts ERR_HAS_GEMS
13
14
  end
14
15
  exit(1)
15
16
  end
@@ -33,39 +34,38 @@ def get_fox
33
34
  no_fox if ver.to_i < 1 or rev.to_i < 2
34
35
  end
35
36
 
37
+
36
38
  get_fox
37
39
  include Fox
38
40
 
39
- begin
40
- require 'yaml'
41
- rescue LoadError => e
42
- $stderr.puts "Please install the yaml library."
43
- $stderr.puts "Without it, preferences cannot be loaded or saved."
44
- end
45
-
46
-
47
-
48
41
  require 'IFMapper/FXMap'
49
42
  require 'IFMapper/FXMapperSettings'
50
43
  require 'IFMapper/FXWarningBox'
51
- require 'IFMapper/FXAboutDialogBox'
52
- require 'IFMapper/FXSearchDialogBox'
53
- require 'IFMapper/FXMapFileDialog'
54
- require 'IFMapper/FXMapColorBox'
55
- require 'IFMapper/FXRoomList'
56
-
57
44
 
58
45
 
59
46
  class FXMapperWindow < FXMainWindow
60
47
 
61
48
  PROGRAM_NAME = "Interactive Fiction Mapper"
62
- VERSION = '0.9.8'
63
- AUTHOR = "Gonzalo Garramuno"
64
- TITLE = "#{PROGRAM_NAME} v#{VERSION} - Written by #{AUTHOR}"
49
+ VERSION = '1.0.0'
50
+ AUTHOR = "Gonzalo Garramuño"
65
51
 
66
52
  @@copy_buffer = nil
67
53
  @@default_options = FXMapperSettings.new
68
54
 
55
+ LANGUAGES = {
56
+ 'English' => 'en',
57
+ 'Español' => 'es',
58
+ # todo1
59
+ 'Deutsch' => 'de',
60
+ 'Italiano' => 'it',
61
+ 'Fran�ais' => 'fr',
62
+ # todo2
63
+ 'Japanese' => 'ja',
64
+ 'Chinese' => 'ch',
65
+ 'Korean' => 'ko',
66
+ 'Arabic' => 'ar',
67
+ }
68
+
69
69
  def open_map(file)
70
70
  tmp = nil
71
71
  begin
@@ -151,7 +151,8 @@ class FXMapperWindow < FXMainWindow
151
151
  # Callback to Open File
152
152
  #
153
153
  def open_cb(sender, sel, ptr)
154
- file = FXMapFileDialog.new(self, "Load New Map").filename
154
+ require 'IFMapper/FXMapFileDialog'
155
+ file = FXMapFileDialog.new(self, MSG_LOAD_MAP).filename
155
156
  return if file == ''
156
157
 
157
158
  # First, make sure we don't have it loaded already...
@@ -182,7 +183,7 @@ class FXMapperWindow < FXMainWindow
182
183
  else
183
184
  map = @maps[0]
184
185
  end
185
- status "Loading '#{file}'..."
186
+ status "#{MSG_LOADING} '#{file}'..."
186
187
 
187
188
  tmp = nil
188
189
  if file =~ /\.ifm$/i
@@ -202,7 +203,7 @@ class FXMapperWindow < FXMainWindow
202
203
  w = FXWarningBox.new( self,
203
204
  "#{tmp}")
204
205
  w.execute
205
- status "Could not load '#{file}'."
206
+ status "#{ERR_COULD_NOT_LOAD} '#{file}'."
206
207
  if make_new_map
207
208
  if map.close_cb
208
209
  @maps.delete(map)
@@ -220,7 +221,7 @@ class FXMapperWindow < FXMainWindow
220
221
  map.window.create
221
222
  map.modified = false
222
223
  update_map
223
- status "Loaded '#{file}'."
224
+ status "#{MSG_LOADED} '#{file}'."
224
225
  end
225
226
 
226
227
  #
@@ -269,11 +270,21 @@ class FXMapperWindow < FXMainWindow
269
270
  m.window.create
270
271
  end
271
272
 
273
+ #
274
+ # Callback used to change language
275
+ #
276
+ def language_cb(sender, msg, opts)
277
+ @@default_options['Language'] = LANGUAGES[sender.text]
278
+
279
+ require "IFMapper/locales/#{language}/Messages.rb"
280
+ recreate
281
+ end
282
+
272
283
  #
273
284
  # Create a new map
274
285
  #
275
286
  def new_map
276
- mapname = "Empty Map \##{@maps.size+1}"
287
+ mapname = "#{MSG_EMPTY_MAP} \##{@maps.size+1}"
277
288
  @maps.push( FXMap.new(mapname, @mdiclient, @@default_options.dup,
278
289
  @mdiicon, @mdimenu, MDI_NORMAL, 0, 0, 790, 500) )
279
290
  map = @maps[-1]
@@ -309,7 +320,7 @@ class FXMapperWindow < FXMainWindow
309
320
  }
310
321
  icon
311
322
  rescue
312
- raise RuntimeError, "Couldn't load icon: #{filename}"
323
+ raise RuntimeError, "#{ERR_NO_ICON} #{filename}"
313
324
  end
314
325
  end
315
326
 
@@ -334,7 +345,7 @@ class FXMapperWindow < FXMainWindow
334
345
  #
335
346
  # Popup a printer dialog and return the settings or false if user cancels
336
347
  #
337
- def printer_dialog(title = 'Print Map')
348
+ def printer_dialog(title = MSG_PRINT_MAP)
338
349
  map = current_map
339
350
  dlg = FXPrintDialog.new(self, title + " for #{map.name}")
340
351
  dlg.printer.flags |= PRINT_DEST_PAPER
@@ -349,13 +360,11 @@ class FXMapperWindow < FXMainWindow
349
360
  map = current_map
350
361
  return unless map
351
362
 
352
- w = FXWarningBox.new( self,
353
- "Sorry, but printing is not yet implemented\n" +
354
- "in this version.")
363
+ w = FXWarningBox.new( self, ERR_NO_PRINTING)
355
364
  w.execute
356
365
  return
357
366
 
358
- printer = printer_dialog "Print Locations"
367
+ printer = printer_dialog MSG_PRINT_LOC
359
368
  map.print_locations( printer ) if printer
360
369
  end
361
370
 
@@ -366,9 +375,10 @@ class FXMapperWindow < FXMainWindow
366
375
  map = current_map
367
376
  return unless map
368
377
 
369
- d = FXMapFileDialog.new(self, "Save Map as IFM File",
378
+ require 'IFMapper/FXMapFileDialog'
379
+ d = FXMapFileDialog.new(self, MSG_SAVE_MAP_AS_IFM,
370
380
  [
371
- "IFM Map (*.ifm)"
381
+ FMT_IFM
372
382
  ])
373
383
  map.export_ifm(d.filename) if d.filename != ''
374
384
  end
@@ -380,9 +390,10 @@ class FXMapperWindow < FXMainWindow
380
390
  map = current_map
381
391
  return unless map
382
392
 
383
- d = FXMapFileDialog.new(self, "Save Map as Inform Files",
393
+ require 'IFMapper/FXMapFileDialog'
394
+ d = FXMapFileDialog.new(self, MSG_SAVE_MAP_AS_INFORM,
384
395
  [
385
- "Inform Source Code (*.inf,*.inform)",
396
+ FMT_INFORM,
386
397
  ])
387
398
  map.export_inform( d.filename ) if d.filename != ''
388
399
  end
@@ -396,10 +407,10 @@ class FXMapperWindow < FXMainWindow
396
407
  return unless map
397
408
 
398
409
  require 'IFMapper/TADSWriter'
399
-
400
- d = FXMapFileDialog.new(self, "Save Map as TADS Files",
410
+ require 'IFMapper/FXMapFileDialog'
411
+ d = FXMapFileDialog.new(self, MSG_SAVE_MAP_AS_TADS,
401
412
  [
402
- "TADS Source Code (*.t)"
413
+ FMT_TADS
403
414
  ])
404
415
  map.export_tads( d.filename ) if d.filename != ''
405
416
  end
@@ -420,9 +431,10 @@ class FXMapperWindow < FXMainWindow
420
431
  return
421
432
  end
422
433
 
423
- d = FXMapFileDialog.new(self, "Save Acrobat PDF File",
434
+ require 'IFMapper/FXMapFileDialog'
435
+ d = FXMapFileDialog.new(self, MSG_SAVE_MAP_AS_PDF,
424
436
  [
425
- "Acrobat PDF (*.pdf)"
437
+ FMT_PDF
426
438
  ])
427
439
  if d.filename != ''
428
440
  map.pdf_export(d.filename)
@@ -436,9 +448,7 @@ class FXMapperWindow < FXMainWindow
436
448
  map = current_map
437
449
  return unless map
438
450
 
439
- w = FXWarningBox.new( self,
440
- "Sorry, but printing is not yet implemented\n" +
441
- "in this version.")
451
+ w = FXWarningBox.new( self, ERR_NO_PRINTING )
442
452
  w.execute
443
453
  return
444
454
  require 'IFMapper/MapPrinting'
@@ -540,8 +550,7 @@ class FXMapperWindow < FXMainWindow
540
550
  sel = @@copy_buffer
541
551
  pos = map.find_empty_area( sel[0] )
542
552
  if not pos
543
- w = FXWarningBox.new( map.window,
544
- "Sorry. No free room in map to paste the nodes.")
553
+ w = FXWarningBox.new( map.window, ERR_NO_FREE_ROOM)
545
554
  w.execute
546
555
  else
547
556
  map.clear_selection
@@ -627,7 +636,7 @@ class FXMapperWindow < FXMainWindow
627
636
  #
628
637
  def hilite_matches(map, matches, re, idx = 0 )
629
638
  if matches.size == 0
630
- status "No matches for regex '#{re}'."
639
+ status "#{ERR_NO_MATCHES} '#{re}'."
631
640
  return
632
641
  end
633
642
 
@@ -650,7 +659,7 @@ class FXMapperWindow < FXMainWindow
650
659
  map.center_view_on_room( room )
651
660
  update_section
652
661
 
653
- status "'#{room.name}' matches. #{matches.size} matches in map, #{num.size} in section."
662
+ status "'#{room.name}' #{MSG_MATCHES}. #{matches.size} #{MSG_MATCHES_IN_MAP}, #{num.size} #{MSG_MATCHES_IN_SECTION}."
654
663
  map.draw
655
664
  end
656
665
 
@@ -678,8 +687,9 @@ class FXMapperWindow < FXMainWindow
678
687
  map = current_map
679
688
  return unless map
680
689
 
681
- title = "Find Location In Map"
690
+ title = MSG_FIND_LOCATION_IN_MAP
682
691
  if not @search
692
+ require 'IFMapper/FXSearchDialogBox'
683
693
  @search = FXSearchDialogBox.new(self)
684
694
  end
685
695
  @search.proc = method(:find_in_map)
@@ -711,8 +721,9 @@ class FXMapperWindow < FXMainWindow
711
721
  map = current_map
712
722
  return unless map
713
723
 
714
- title = "Find Location in this Section"
724
+ title = MSG_FIND_LOCATION_IN_SECTION
715
725
  if not @search
726
+ require 'IFMapper/FXSearchDialogBox'
716
727
  @search = FXSearchDialogBox.new(self)
717
728
  end
718
729
  @search.proc = method(:find_in_section)
@@ -768,8 +779,9 @@ class FXMapperWindow < FXMainWindow
768
779
  map = current_map
769
780
  return unless map
770
781
 
771
- title = "Find Object In Map"
782
+ title = MSG_FIND_OBJECT_IN_MAP
772
783
  if not @search
784
+ require 'IFMapper/FXSearchDialogBox'
773
785
  @search = FXSearchDialogBox.new(self)
774
786
  end
775
787
  @search.proc = method(:find_object_in_map)
@@ -785,8 +797,9 @@ class FXMapperWindow < FXMainWindow
785
797
  map = current_map
786
798
  return unless map
787
799
 
788
- title = "Find Task In Map"
800
+ title = MSG_FIND_TASK_IN_MAP
789
801
  if not @search
802
+ require 'IFMapper/FXSearchDialogBox'
790
803
  @search = FXSearchDialogBox.new(self)
791
804
  end
792
805
  @search.proc = method(:find_task_in_map)
@@ -822,8 +835,9 @@ class FXMapperWindow < FXMainWindow
822
835
  map = current_map
823
836
  return unless map
824
837
 
825
- title = "Find In Description In Map"
838
+ title = MSG_FIND_DESCRIPTION_IN_MAP
826
839
  if not @search
840
+ require 'IFMapper/FXSearchDialogBox'
827
841
  @search = FXSearchDialogBox.new(self)
828
842
  end
829
843
  @search.proc = method(:find_desc_in_map)
@@ -832,6 +846,7 @@ class FXMapperWindow < FXMainWindow
832
846
  @search.show
833
847
  end
834
848
 
849
+
835
850
  #
836
851
  # Pop-up color preferences
837
852
  #
@@ -840,6 +855,7 @@ class FXMapperWindow < FXMainWindow
840
855
  return if not map
841
856
 
842
857
  if not @colors
858
+ require 'IFMapper/FXMapColorBox'
843
859
  @colors = FXMapColorBox.new(self)
844
860
  else
845
861
  @colors.show
@@ -879,24 +895,12 @@ class FXMapperWindow < FXMainWindow
879
895
 
880
896
 
881
897
  def about_cb(sender, id, event )
882
- FXAboutDialogBox.new(self, "About This Software...", <<"EOF").execute
883
- #{PROGRAM_NAME} - #{VERSION}
884
- Written by Gonzalo Garramuno.
885
-
886
- FXRuby Version: #{Fox::fxrubyversion}
887
-
888
- A WYSIWYG mapping tool for interactive fiction.
889
-
890
- ggarra@advancedsl.com.ar
891
- |_|0|_|
892
- |_|_|0|
893
- |0|0|0|
894
-
895
- EOF
898
+ require 'IFMapper/FXAboutDialogBox'
899
+ FXAboutDialogBox.new(self, MSG_ABOUT_SOFTWARE,
900
+ eval("\"#{MSG_ABOUT}\"")).execute
896
901
  end
897
902
 
898
903
 
899
-
900
904
  def create_menus
901
905
  # Construct these icons
902
906
  newdoc = load_icon("filenew")
@@ -906,126 +910,123 @@ EOF
906
910
 
907
911
  # File Menu
908
912
  filemenu = FXMenuPane.new(self)
909
- FXMenuTitle.new(@menubar, "&File", nil, filemenu)
910
- cmd = FXMenuCommand.new(filemenu, "&New...\tCtl-N\tCreate new document.", newdoc)
913
+ FXMenuTitle.new(@menubar, MENU_FILE, nil, filemenu)
914
+ cmd = FXMenuCommand.new(filemenu, MENU_NEW, newdoc)
911
915
  cmd.connect(SEL_COMMAND, method(:new_map_cb))
912
916
 
913
- cmd = FXMenuCommand.new(filemenu, "&Open...\tCtl-O\tOpen document file.", opendoc)
917
+ cmd = FXMenuCommand.new(filemenu, MENU_OPEN, opendoc)
914
918
  cmd.connect(SEL_COMMAND, method(:open_cb))
915
- cmd = FXMenuCommand.new(filemenu, "&Save\tCtl-S\tSave document.", savedoc)
919
+ cmd = FXMenuCommand.new(filemenu, MENU_SAVE, savedoc)
916
920
  cmd.connect(SEL_COMMAND, method(:save_cb))
917
- cmd = FXMenuCommand.new(filemenu, "Save &As...\t\tSave document to another file.",
921
+ cmd = FXMenuCommand.new(filemenu, MENU_SAVE_AS,
918
922
  saveasdoc)
919
923
  cmd.connect(SEL_COMMAND, method(:save_as_cb))
920
924
 
921
925
  # Export submenu
922
926
  submenu = FXMenuPane.new(self)
923
927
 
924
- cmd = FXMenuCommand.new(submenu, "&Export as PDF...\t\tExport map as Acrobat PDF document.", nil)
928
+ cmd = FXMenuCommand.new(submenu, MENU_EXPORT_PDF, nil)
925
929
  cmd.connect(SEL_COMMAND, method(:pdf_export_cb))
926
930
 
927
- cmd = FXMenuCommand.new(submenu, "&Export as IFM...\t\tExport map as an IFM map.", nil)
931
+ cmd = FXMenuCommand.new(submenu, MENU_EXPORT_IFM, nil)
928
932
  cmd.connect(SEL_COMMAND, method(:ifm_export_cb))
929
933
 
930
- cmd = FXMenuCommand.new(submenu, "&Export as Inform Source...\t\tExport map as an Inform source code file.", nil)
934
+ cmd = FXMenuCommand.new(submenu, MENU_EXPORT_INFORM, nil)
931
935
  cmd.connect(SEL_COMMAND, method(:inform_export_cb))
932
936
 
933
- cmd = FXMenuCommand.new(submenu, "&Export as TADS3 Source...\t\tExport map as a TADS3 source code file.", nil)
937
+ cmd = FXMenuCommand.new(submenu, MENU_EXPORT_TADS, nil)
934
938
  cmd.connect(SEL_COMMAND, method(:tads_export_cb))
935
939
 
936
- FXMenuCascade.new(filemenu, "Export", nil, submenu)
940
+ FXMenuCascade.new(filemenu, MENU_EXPORT, nil, submenu)
937
941
 
938
942
 
939
943
  submenu = FXMenuPane.new(self)
940
- cmd = FXMenuCommand.new(submenu, "&Map...\t\tPrint map (as graph).",
941
- nil)
944
+ cmd = FXMenuCommand.new(submenu, MENU_PRINT_MAP, nil)
942
945
  cmd.connect(SEL_COMMAND, method(:print_cb))
943
946
 
944
- cmd = FXMenuCommand.new(submenu, "Map &Locations...\t\tPrint map locations as text list.", nil)
947
+ cmd = FXMenuCommand.new(submenu, MENU_PRINT_LOCATIONS, nil)
945
948
  cmd.connect(SEL_COMMAND, method(:print_locations_cb))
946
- FXMenuCascade.new(filemenu, "Print", nil, submenu)
947
-
949
+ FXMenuCascade.new(filemenu, MENU_PRINT, nil, submenu)
948
950
 
949
- cmd = FXMenuCommand.new(filemenu, "&Quit\tCtl-Q\tQuit the application.", nil)
951
+ cmd = FXMenuCommand.new(filemenu, MENU_QUIT, nil)
950
952
  cmd.connect( SEL_COMMAND, method(:close_cb) )
951
953
 
952
954
  # Edit Menu
953
955
  editmenu = FXMenuPane.new(self)
954
- FXMenuTitle.new(@menubar, "&Edit", nil, editmenu)
955
- cmd = FXMenuCommand.new(editmenu, "&Copy\tCtl-C\tCopy Location Data", nil)
956
+ FXMenuTitle.new(@menubar, MENU_EDIT, nil, editmenu)
957
+ cmd = FXMenuCommand.new(editmenu, MENU_COPY, nil)
956
958
  cmd.connect(SEL_COMMAND, method(:copy_selected_cb))
957
- cmd = FXMenuCommand.new(editmenu, "Cu&t\tCtl-X\tCut Location", nil)
959
+ cmd = FXMenuCommand.new(editmenu, MENU_CUT, nil)
958
960
  cmd.connect(SEL_COMMAND, method(:cut_selected_cb))
959
- cmd = FXMenuCommand.new(editmenu, "&Paste\tCtl-V\tPaste Location Data",
960
- nil)
961
+ cmd = FXMenuCommand.new(editmenu, MENU_PASTE, nil)
961
962
  cmd.connect(SEL_COMMAND, method(:paste_selected_cb))
962
963
 
963
964
  # Select submenu
964
965
  FXMenuSeparator.new(editmenu)
965
966
  submenu = FXMenuPane.new(self)
966
- cmd = FXMenuCommand.new(submenu, "&All Locations\tAlt-A\tSelect all locations in section")
967
+ cmd = FXMenuCommand.new( submenu, MENU_SELECT_ALL )
967
968
  cmd.connect(SEL_COMMAND, method(:select_all_cb))
968
- cmd = FXMenuCommand.new(submenu, "&None\tAlt-N\tClear selection in section.")
969
+ cmd = FXMenuCommand.new( submenu, MENU_SELECT_NONE )
969
970
  cmd.connect(SEL_COMMAND, method(:select_none_cb))
970
- FXMenuCascade.new(editmenu, "Select", nil, submenu)
971
+ FXMenuCascade.new( editmenu, MENU_SELECT, nil, submenu )
971
972
 
972
973
  # Searching submenu
973
974
  FXMenuSeparator.new(editmenu)
974
975
  submenu = FXMenuPane.new(self)
975
- cmd = FXMenuCommand.new(submenu, "&Location in Map\tCtl-F\tFind a Location Name in Map")
976
+ cmd = FXMenuCommand.new(submenu, MENU_SEARCH_MAP)
976
977
  cmd.connect(SEL_COMMAND, method(:find_in_map_cb))
977
- cmd = FXMenuCommand.new(submenu, "Location in &Section\tAlt-F\tFind a Location Name in Current Section")
978
+ cmd = FXMenuCommand.new(submenu, MENU_SEARCH_SECTION)
978
979
  cmd.connect(SEL_COMMAND, method(:find_in_section_cb))
979
- cmd = FXMenuCommand.new(submenu, "&Object in Map\tAlt-O\tFind Location with an Object in the Map")
980
+ cmd = FXMenuCommand.new(submenu, MENU_SEARCH_OBJECT)
980
981
  cmd.connect(SEL_COMMAND, method(:find_object_in_map_cb))
981
- cmd = FXMenuCommand.new(submenu, "&Task in Map\tAlt-T\tFind Location with a Task in the Map")
982
+ cmd = FXMenuCommand.new(submenu, MENU_SEARCH_TASK)
982
983
  cmd.connect(SEL_COMMAND, method(:find_task_in_map_cb))
983
- cmd = FXMenuCommand.new(submenu, "&Keyword in Descriptions\tAlt-D\tFind Location with Description Keyword in the Map")
984
+ cmd = FXMenuCommand.new(submenu, MENU_SEARCH_DESCRIPTION)
984
985
  cmd.connect(SEL_COMMAND, method(:find_desc_in_map_cb))
985
- FXMenuCascade.new(editmenu, "Search", nil, submenu)
986
+ FXMenuCascade.new(editmenu, MENU_SEARCH, nil, submenu)
986
987
 
987
988
  # Complex Connection
988
989
  FXMenuSeparator.new(editmenu)
989
- cmd = FXMenuCommand.new(editmenu, "Comple&x Connection\tx\tCreate a complex connection.", nil)
990
- cmd.connect( SEL_COMMAND, method(:complex_connection_cb))
990
+ cmd = FXMenuCommand.new(editmenu, MENU_COMPLEX_CONNECTION, nil)
991
+ cmd.connect( SEL_COMMAND, method(:complex_connection_cb) )
991
992
 
992
993
  FXMenuSeparator.new(editmenu)
993
- cmd = FXMenuCommand.new(editmenu, "Delete\tDel\tDelete selected locations or connections.", nil)
994
+ cmd = FXMenuCommand.new(editmenu, MENU_DELETE, nil)
994
995
  cmd.connect( SEL_COMMAND, method(:delete_selected_cb) )
995
996
 
996
997
  # Map menu
997
998
  mapmenu = FXMenuPane.new(self)
998
999
 
999
- cmd = FXMenuCommand.new(mapmenu, "Map Information\t\tChange map information.")
1000
+ cmd = FXMenuCommand.new(mapmenu, MENU_MAP_INFO)
1000
1001
  cmd.connect(SEL_COMMAND) { map_properties }
1001
1002
 
1002
- cmd = FXMenuCommand.new(mapmenu, "Room List\t\tList all rooms in map.")
1003
+ cmd = FXMenuCommand.new(mapmenu, MENU_ROOM_LIST)
1003
1004
  cmd.connect(SEL_COMMAND, method(:roomlist) )
1004
1005
 
1005
1006
  # Automap submenu
1006
1007
  #
1007
1008
  submenu = FXMenuPane.new(self)
1008
- cmd = FXMenuCommand.new(submenu, "&Start...\tCtl-T\tStart creating map from transcript file.")
1009
+ cmd = FXMenuCommand.new(submenu, MENU_AUTOMAP_START)
1009
1010
  cmd.connect(SEL_COMMAND, method(:start_automap_cb))
1010
- cmd = FXMenuCommand.new(submenu, "S&top...\tCtl-P\tStop autocreating map.")
1011
+ cmd = FXMenuCommand.new(submenu, MENU_AUTOMAP_STOP)
1011
1012
  cmd.connect(SEL_COMMAND, method(:stop_automap_cb))
1012
1013
  FXMenuSeparator.new(submenu)
1013
- cmd = FXMenuCommand.new(submenu, "&Properties...\tCtl-H\tTranscript properties.")
1014
+ cmd = FXMenuCommand.new(submenu, MENU_AUTOMAP_PROPERTIES)
1014
1015
  cmd.connect(SEL_COMMAND, method(:automap_properties_cb))
1015
- FXMenuCascade.new(mapmenu, "Automap", nil, submenu)
1016
+ FXMenuCascade.new(mapmenu, MENU_AUTOMAP, nil, submenu)
1016
1017
 
1017
1018
  # Sections submenu
1018
1019
  submenu = FXMenuPane.new(self)
1019
- cmd = FXMenuCommand.new(submenu, "Next Section\t\tGo to Next Map Section.")
1020
+ cmd = FXMenuCommand.new(submenu, MENU_NEXT_SECTION)
1020
1021
  cmd.connect(SEL_COMMAND) {
1021
1022
  next_section
1022
1023
  }
1023
- cmd = FXMenuCommand.new(submenu, "Previous Section\t\tGo to Previous Map Section.")
1024
+ cmd = FXMenuCommand.new(submenu, MENU_PREVIOUS_SECTION)
1024
1025
  cmd.connect(SEL_COMMAND) {
1025
1026
  previous_section
1026
1027
  }
1027
1028
  FXMenuSeparator.new(submenu)
1028
- cmd = FXMenuCommand.new(submenu, "Add Section\t\tAdd a New Section to Map.")
1029
+ cmd = FXMenuCommand.new(submenu, MENU_ADD_SECTION)
1029
1030
  cmd.connect(SEL_COMMAND) {
1030
1031
  map = current_map
1031
1032
  if map
@@ -1034,7 +1035,7 @@ EOF
1034
1035
  update_section
1035
1036
  end
1036
1037
  }
1037
- cmd = FXMenuCommand.new(submenu, "Rename Section\t\tRename Current Section.")
1038
+ cmd = FXMenuCommand.new(submenu, MENU_RENAME_SECTION)
1038
1039
  cmd.connect(SEL_COMMAND) {
1039
1040
  map = current_map
1040
1041
  if map
@@ -1043,7 +1044,7 @@ EOF
1043
1044
  end
1044
1045
  }
1045
1046
  FXMenuSeparator.new(submenu)
1046
- cmd = FXMenuCommand.new(submenu, "Delete Section\t\tDelete Current Section from Map.")
1047
+ cmd = FXMenuCommand.new(submenu, MENU_DELETE_SECTION)
1047
1048
  cmd.connect(SEL_COMMAND) {
1048
1049
  map = current_map
1049
1050
  if map
@@ -1052,14 +1053,14 @@ EOF
1052
1053
  update_section
1053
1054
  end
1054
1055
  }
1055
- FXMenuCascade.new(mapmenu, "Sections", nil, submenu)
1056
+ FXMenuCascade.new(mapmenu, MENU_SECTIONS, nil, submenu)
1056
1057
 
1057
1058
  #
1058
1059
  # Zoom submenu
1059
1060
  #
1060
1061
  submenu = FXMenuPane.new(self)
1061
1062
  [25, 50, 75, 100, 125].each { |v|
1062
- cmd = FXMenuCommand.new(submenu, v.to_s + "%\t\tZoom page to #{v}%.")
1063
+ cmd = FXMenuCommand.new(submenu, eval("\"#{MENU_ZOOM_PERCENT}\""))
1063
1064
  cmd.connect(SEL_COMMAND) {
1064
1065
  map = current_map
1065
1066
  if map
@@ -1068,11 +1069,11 @@ EOF
1068
1069
  end
1069
1070
  }
1070
1071
  }
1071
- FXMenuCascade.new(mapmenu, "Zoom", nil, submenu)
1072
+ FXMenuCascade.new(mapmenu, MENU_ZOOM, nil, submenu)
1072
1073
 
1073
1074
  submenu = FXMenuPane.new(self)
1074
1075
 
1075
- cmd = FXMenuCheck.new(submenu, "Edit on Creation\t\tEdit locations on creation.")
1076
+ cmd = FXMenuCheck.new(submenu, MENU_EDIT_ON_CREATION)
1076
1077
  cmd.check = @@default_options['Edit on Creation']
1077
1078
  cmd.connect(SEL_COMMAND) { |s, m, e|
1078
1079
  map = current_map
@@ -1085,7 +1086,7 @@ EOF
1085
1086
  s.check = map.options['Edit on Creation'] if map
1086
1087
  }
1087
1088
 
1088
- cmd = FXMenuCheck.new(submenu, "Automatic Connection\t\tConnect new location to adjacent one .")
1089
+ cmd = FXMenuCheck.new(submenu, MENU_AUTOMATIC_CONNECTION)
1089
1090
  cmd.check = @@default_options['Automatic Connection']
1090
1091
  cmd.connect(SEL_COMMAND) { |s, m, e|
1091
1092
  map = current_map
@@ -1098,7 +1099,7 @@ EOF
1098
1099
  s.check = map.options['Automatic Connection'] if map
1099
1100
  }
1100
1101
 
1101
- cmd = FXMenuCheck.new(submenu, "Create on Connectionn\t\tCreate missing locations when creating a connection.")
1102
+ cmd = FXMenuCheck.new(submenu, MENU_CREATE_ON_CONNECTION)
1102
1103
  cmd.check = @@default_options['Create on Connection']
1103
1104
  cmd.connect(SEL_COMMAND) { |s, m, e|
1104
1105
  map = current_map
@@ -1109,13 +1110,13 @@ EOF
1109
1110
  s.check = map.options['Create on Connection'] if map
1110
1111
  }
1111
1112
 
1112
- FXMenuCascade.new(mapmenu, "Options", nil, submenu)
1113
+ FXMenuCascade.new(mapmenu, MENU_OPTIONS, nil, submenu)
1113
1114
 
1114
1115
  ##########################
1115
1116
  # Display submenu
1116
1117
  #########################
1117
1118
  submenu = FXMenuPane.new(self)
1118
- cmd = FXMenuCheck.new(submenu, "Use Room Cursor\t\tMake your mouse cursor a room showing the direction of exit.")
1119
+ cmd = FXMenuCheck.new(submenu, MENU_USE_ROOM_CURSOR)
1119
1120
  cmd.check = @@default_options['Use Room Cursor']
1120
1121
  cmd.connect(SEL_COMMAND) { |s, m, e|
1121
1122
  map = current_map
@@ -1129,7 +1130,7 @@ EOF
1129
1130
  s.check = map.options['Use Room Cursor'] if map
1130
1131
  }
1131
1132
 
1132
- cmd = FXMenuCheck.new(submenu, "Paths as Curves\t\tDraw complex paths as curves.")
1133
+ cmd = FXMenuCheck.new(submenu, MENU_PATHS_AS_CURVES)
1133
1134
  cmd.check = @@default_options['Paths as Curves']
1134
1135
  cmd.connect(SEL_COMMAND) { |s, m, e|
1135
1136
  map = current_map
@@ -1142,7 +1143,7 @@ EOF
1142
1143
  map = current_map
1143
1144
  s.check = map.options['Paths as Curves'] if map
1144
1145
  }
1145
- cmd = FXMenuCheck.new(submenu, "Location Numbers\t\tShow Location Numbers.")
1146
+ cmd = FXMenuCheck.new(submenu, MENU_LOCATION_NUMBERS)
1146
1147
  cmd.check = @@default_options['Location Numbers']
1147
1148
  cmd.connect(SEL_COMMAND) { |s, m, e|
1148
1149
  map = current_map
@@ -1156,7 +1157,7 @@ EOF
1156
1157
  s.check = map.options['Location Numbers'] if map
1157
1158
  }
1158
1159
 
1159
- cmd = FXMenuCheck.new(submenu, "Location Tasks\t\tShow Tasks in Location Edit Box.")
1160
+ cmd = FXMenuCheck.new(submenu, MENU_LOCATION_TASKS)
1160
1161
  cmd.check = @@default_options['Location Tasks']
1161
1162
  cmd.connect(SEL_COMMAND) { |s, m, e|
1162
1163
  map = current_map
@@ -1170,7 +1171,7 @@ EOF
1170
1171
  s.check = map.options['Location Tasks'] if map
1171
1172
  }
1172
1173
 
1173
- cmd = FXMenuCheck.new(submenu, "Location Description\t\tShow Description in Location Edit Box.")
1174
+ cmd = FXMenuCheck.new(submenu, MENU_LOCATION_DESC)
1174
1175
  cmd.check = @@default_options['Location Description']
1175
1176
  cmd.connect(SEL_COMMAND) { |s, m, e|
1176
1177
  map = current_map
@@ -1184,7 +1185,7 @@ EOF
1184
1185
  s.check = map.options['Location Description'] if map
1185
1186
  }
1186
1187
 
1187
- cmd = FXMenuCheck.new(submenu, "Boxes\t\tDraw dashed box guidelines.")
1188
+ cmd = FXMenuCheck.new(submenu, MENU_BOXES)
1188
1189
  cmd.check = @@default_options['Grid Boxes']
1189
1190
  cmd.connect(SEL_COMMAND) { |s, m, e|
1190
1191
  map = current_map
@@ -1198,7 +1199,7 @@ EOF
1198
1199
  s.check = map.options['Grid Boxes'] if map
1199
1200
  }
1200
1201
 
1201
- cmd = FXMenuCheck.new(submenu, "Straight Connections\t\tDraw dashed N/S/E/W guidelines")
1202
+ cmd = FXMenuCheck.new(submenu, MENU_STRAIGHT_CONN)
1202
1203
  cmd.check = @@default_options['Grid Straight Connections']
1203
1204
  cmd.connect(SEL_COMMAND) { |s, m, e|
1204
1205
  map = current_map
@@ -1212,7 +1213,7 @@ EOF
1212
1213
  s.check = map.options['Grid Straight Connections'] if map
1213
1214
  }
1214
1215
 
1215
- cmd = FXMenuCheck.new(submenu, "Diagonal Connections\t\tDraw dashed NW/NE/SW/SE guidelines")
1216
+ cmd = FXMenuCheck.new(submenu, MENU_DIAGONAL_CONN)
1216
1217
  cmd.check = @@default_options['Grid Diagonal Connections']
1217
1218
  cmd.connect(SEL_COMMAND) { |s, m, e|
1218
1219
  map = current_map
@@ -1226,31 +1227,42 @@ EOF
1226
1227
  s.check = map.options['Grid Diagonal Connections'] if map
1227
1228
  }
1228
1229
 
1229
- FXMenuCascade.new(mapmenu, 'Display', nil, submenu)
1230
+ FXMenuCascade.new(mapmenu, MENU_DISPLAY, nil, submenu)
1230
1231
 
1231
1232
  submenu = FXMenuPane.new(self)
1232
- cmd = FXMenuCommand.new(submenu, "Colors\t\tChange map colors.")
1233
+
1234
+ cmd = FXMenuCommand.new(submenu, MENU_COLORS)
1233
1235
  cmd.connect(SEL_COMMAND, method(:colors_cb))
1234
1236
 
1237
+ # langmenu = FXMenuPane.new(self)
1238
+ # LANGUAGES.each { |k, v|
1239
+ # next unless File.exists?( "lib/IFMapper/locales/#{v}/Messages.rb" )
1240
+ # cmd = FXMenuCheck.new(langmenu, k)
1241
+ # cmd.connect(SEL_COMMAND, method(:language_cb))
1242
+ # }
1243
+
1244
+ # FXMenuCascade.new(mapmenu, MENU_LANGUAGE, nil, langmenu)
1245
+
1246
+
1235
1247
  FXMenuSeparator.new(submenu)
1236
- cmd = FXMenuCommand.new(submenu, "Save Preferences\t\tSave Preferences for Startup")
1248
+ cmd = FXMenuCommand.new(submenu, MENU_SAVE_PREFS)
1237
1249
  cmd.connect(SEL_COMMAND) {
1238
1250
  map = current_map
1239
1251
  map.options.write if map
1240
1252
  }
1241
- FXMenuCascade.new(mapmenu, 'Preferences', nil, submenu)
1253
+ FXMenuCascade.new(mapmenu, MENU_PREFS, nil, submenu)
1242
1254
 
1243
- FXMenuTitle.new(@menubar,"&Map", nil, mapmenu)
1255
+ FXMenuTitle.new(@menubar, MENU_MAP, nil, mapmenu)
1244
1256
 
1245
1257
  # Window menu
1246
1258
  windowmenu = FXMenuPane.new(self)
1247
- FXMenuCommand.new(windowmenu, "Tile &Horizontally", nil,
1259
+ FXMenuCommand.new(windowmenu, MENU_TILE_HORIZONTALLY, nil,
1248
1260
  @mdiclient, FXMDIClient::ID_MDI_TILEHORIZONTAL)
1249
- FXMenuCommand.new(windowmenu, "Tile &Vertically", nil,
1261
+ FXMenuCommand.new(windowmenu, MENU_TILE_VERTICALLY, nil,
1250
1262
  @mdiclient, FXMDIClient::ID_MDI_TILEVERTICAL)
1251
- FXMenuCommand.new(windowmenu, "C&ascade", nil,
1263
+ FXMenuCommand.new(windowmenu, MENU_CASCADE, nil,
1252
1264
  @mdiclient, FXMDIClient::ID_MDI_CASCADE)
1253
- FXMenuCommand.new(windowmenu, "&Close", nil,
1265
+ FXMenuCommand.new(windowmenu, MENU_CLOSE, nil,
1254
1266
  @mdiclient, FXMDIClient::ID_MDI_CLOSE)
1255
1267
  sep1 = FXMenuSeparator.new(windowmenu)
1256
1268
  sep1.setTarget(@mdiclient)
@@ -1259,21 +1271,23 @@ EOF
1259
1271
  FXMenuCommand.new(windowmenu, nil, nil, @mdiclient, FXMDIClient::ID_MDI_2)
1260
1272
  FXMenuCommand.new(windowmenu, nil, nil, @mdiclient, FXMDIClient::ID_MDI_3)
1261
1273
  FXMenuCommand.new(windowmenu, nil, nil, @mdiclient, FXMDIClient::ID_MDI_4)
1262
- FXMenuCommand.new(windowmenu, "&Others...", nil, @mdiclient, FXMDIClient::ID_MDI_OVER_5)
1263
- FXMenuTitle.new(@menubar,"&Window", nil, windowmenu)
1274
+ FXMenuCommand.new(windowmenu, MENU_OTHERS, nil, @mdiclient,
1275
+ FXMDIClient::ID_MDI_OVER_5)
1276
+ FXMenuTitle.new(@menubar, MENU_WINDOW, nil, windowmenu)
1264
1277
 
1265
1278
  # Help menu
1266
1279
  helpmenu = FXMenuPane.new(self)
1267
- cmd = FXMenuCommand.new(helpmenu, "&Hotkeys", nil)
1280
+ cmd = FXMenuCommand.new(helpmenu, MENU_HOTKEYS, nil)
1268
1281
  cmd.connect(SEL_COMMAND, method(:hotkeys))
1269
- cmd = FXMenuCommand.new(helpmenu, "&Instructions", nil)
1282
+ cmd = FXMenuCommand.new(helpmenu, MENU_INSTRUCTIONS, nil)
1270
1283
  cmd.connect(SEL_COMMAND, method(:docs))
1271
1284
  FXMenuSeparator.new(helpmenu)
1272
- cmd = FXMenuCommand.new(helpmenu, "&About", nil)
1285
+ cmd = FXMenuCommand.new(helpmenu, MENU_ABOUT, nil)
1273
1286
  cmd.connect(SEL_COMMAND, method(:about_cb))
1274
1287
 
1275
- cmd = FXMenuCommand.new(helpmenu, "&Resource Code", nil)
1288
+ cmd = FXMenuCommand.new(helpmenu, MENU_RESOURCE, nil)
1276
1289
  cmd.connect(SEL_COMMAND) {
1290
+ require 'IFMapper/FXMapFileDialog'
1277
1291
  file = FXMapFileDialog.new(self, "Resource a Ruby File",
1278
1292
  ['Ruby File (*.rb)']).filename
1279
1293
  if file != ''
@@ -1284,59 +1298,35 @@ EOF
1284
1298
  end
1285
1299
  end
1286
1300
  }
1287
- FXMenuTitle.new(@menubar,"&Help", nil, helpmenu)
1301
+ FXMenuTitle.new(@menubar, MENU_HELP, nil, helpmenu)
1288
1302
  end
1289
1303
 
1304
+ def language
1305
+ return @@default_options['Language']
1306
+ end
1290
1307
 
1291
1308
  def docs(*opts)
1292
- f = File.open('README.txt')
1293
- text = f.readlines.join("")
1294
- f.close
1295
- FXAboutDialogBox.new(self, "Instructions", text).show
1309
+ browsers = [ 'firefox', 'opera', 'explorer' ]
1310
+ address = 'docs/' + language + '/start.html'
1311
+ status "#{MSG_OPENING_WEB_PAGE} #{address}..."
1312
+ ok = false
1313
+ browsers.each { |cmd|
1314
+ if RUBY_PLATFORM =~ /mswin/
1315
+ ok = system("start #{cmd} #{address}")
1316
+ else
1317
+ ok = system("#{cmd} #{address} &")
1318
+ end
1319
+ break if ok
1320
+ }
1321
+ if not ok
1322
+ status ERR_COULD_NOT_OPEN_WEB_BROWSER
1323
+ end
1296
1324
  end
1297
1325
 
1298
- def hotkeys(*opts)
1299
- FXAboutDialogBox.new(self, "Hotkeys", <<'EOF').show
1300
-
1301
- LMB - Left Mouse Button
1302
- MMB - Middle Mouse Button
1303
- RMB - Right Mouse Button
1304
-
1305
- Mouse controls
1306
- --------------
1307
-
1308
- Use LMB to add new locations or connections among rooms.
1309
-
1310
- Click with LMB on any room or connection to select it.
1311
-
1312
- Double click on rooms or connections to access their properties.
1313
-
1314
- Click several times on an existing connecion to establish a one-way
1315
- connection.
1316
-
1317
- Drag with MMB or ALT + LMB to scroll around the page.
1318
-
1319
- Use mousewheel to zoom in and out.
1320
-
1321
- Use RMB after selecting a connection to bring a menu to allow you
1322
- to flip its direction or to attach it to some other exit in one
1323
- of the rooms.
1324
1326
 
1325
- Keyboard controls
1326
- -----------------
1327
-
1328
- Use 'x' to start a new complex connection (ie. a connection across
1329
- rooms that are not neighbors), then click on each exit of each room.
1330
-
1331
- Use 'Delete' or 'Backspace' to remove any selected connection or room.
1332
-
1333
- Use arrow keys or numeric keypad to move selected rooms around
1334
- the page, one unit at a time.
1335
-
1336
- Use CTRL + LMB when adding a connection to create a dead-end
1337
- connection (one that loops onto itself)
1338
-
1339
- EOF
1327
+ def hotkeys(*opts)
1328
+ require 'IFMapper/FXAboutDialogBox'
1329
+ FXAboutDialogBox.new(self, BOX_HOTKEYS, MSG_HOTKEYS).show
1340
1330
  end
1341
1331
 
1342
1332
  def create_toolbar(toolbar)
@@ -1348,15 +1338,15 @@ EOF
1348
1338
  saveasdoc = load_icon("filesaveas")
1349
1339
 
1350
1340
  # File manipulation
1351
- cmd = FXButton.new(toolbar, "\tNew\tCreate new document.", newdoc, nil, 0,
1341
+ cmd = FXButton.new(toolbar, ICON_NEW, newdoc, nil, 0,
1352
1342
  FRAME_THICK|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT)
1353
1343
  cmd.connect(SEL_COMMAND, method(:new_map_cb))
1354
1344
 
1355
- cmd = FXButton.new(toolbar, "\tOpen\tOpen document file.", opendoc, nil, 0,
1345
+ cmd = FXButton.new(toolbar, ICON_OPEN, opendoc, nil, 0,
1356
1346
  FRAME_THICK|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT)
1357
1347
  cmd.connect(SEL_COMMAND, method(:open_cb))
1358
1348
 
1359
- cmd = FXButton.new(toolbar, "\tSave\tSave document.", savedoc, nil, 0,
1349
+ cmd = FXButton.new(toolbar, ICON_SAVE, savedoc, nil, 0,
1360
1350
  FRAME_THICK|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT)
1361
1351
  cmd.connect(SEL_COMMAND, method(:save_cb))
1362
1352
  cmd.connect(SEL_UPDATE) { |sender, sel, ptr|
@@ -1364,7 +1354,7 @@ EOF
1364
1354
  message = map ? FXWindow::ID_ENABLE : FXWindow::ID_DISABLE
1365
1355
  sender.handle(self, MKUINT(message, SEL_COMMAND), nil)
1366
1356
  }
1367
- cmd = FXButton.new(toolbar, "\tSave As\tSave document to another file.",
1357
+ cmd = FXButton.new(toolbar, ICON_SAVE_AS,
1368
1358
  saveasdoc, nil, 0, FRAME_THICK|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT)
1369
1359
  cmd.connect(SEL_COMMAND, method(:save_as_cb))
1370
1360
  cmd.connect(SEL_UPDATE) { |sender, sel, ptr|
@@ -1376,7 +1366,7 @@ EOF
1376
1366
  # Print
1377
1367
  FXFrame.new(toolbar,
1378
1368
  LAYOUT_TOP|LAYOUT_LEFT|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, 0, 0, 4, 20)
1379
- cmd = FXButton.new(toolbar, "\tPrint Map\tPrint map (as graph).",
1369
+ cmd = FXButton.new(toolbar, ICON_PRINT,
1380
1370
  load_icon("printicon"), @mdiclient, FXGLViewer::ID_PRINT_IMAGE,
1381
1371
  BUTTON_AUTOGRAY|FRAME_THICK|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT)
1382
1372
  cmd.connect(SEL_COMMAND, method(:print_cb))
@@ -1389,7 +1379,7 @@ EOF
1389
1379
  # Editing
1390
1380
  FXFrame.new(toolbar,
1391
1381
  LAYOUT_TOP|LAYOUT_LEFT|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, 0, 0, 4, 20)
1392
- cmd = FXButton.new(toolbar, "\tCut", load_icon("cut"), @mdiclient,
1382
+ cmd = FXButton.new(toolbar, ICON_CUT, load_icon("cut"), @mdiclient,
1393
1383
  FXGLViewer::ID_CUT_SEL, (BUTTON_AUTOGRAY|FRAME_THICK|FRAME_RAISED|
1394
1384
  LAYOUT_TOP|LAYOUT_LEFT))
1395
1385
  cmd.connect(SEL_COMMAND, method(:cut_selected_cb))
@@ -1398,7 +1388,7 @@ EOF
1398
1388
  message = map ? FXWindow::ID_ENABLE : FXWindow::ID_DISABLE
1399
1389
  sender.handle(self, MKUINT(message, SEL_COMMAND), nil)
1400
1390
  }
1401
- cmd = FXButton.new(toolbar, "\tCopy", load_icon("copy"), @mdiclient,
1391
+ cmd = FXButton.new(toolbar, ICON_COPY, load_icon("copy"), @mdiclient,
1402
1392
  FXGLViewer::ID_COPY_SEL, (BUTTON_AUTOGRAY|FRAME_THICK|FRAME_RAISED|
1403
1393
  LAYOUT_TOP|LAYOUT_LEFT))
1404
1394
  cmd.connect(SEL_COMMAND, method(:copy_selected_cb))
@@ -1407,7 +1397,7 @@ EOF
1407
1397
  message = map ? FXWindow::ID_ENABLE : FXWindow::ID_DISABLE
1408
1398
  sender.handle(self, MKUINT(message, SEL_COMMAND), nil)
1409
1399
  }
1410
- cmd = FXButton.new(toolbar, "\tPaste", load_icon("paste"), @mdiclient,
1400
+ cmd = FXButton.new(toolbar, ICON_PASTE, load_icon("paste"), @mdiclient,
1411
1401
  FXGLViewer::ID_PASTE_SEL, (BUTTON_AUTOGRAY|FRAME_THICK|FRAME_RAISED|
1412
1402
  LAYOUT_TOP|LAYOUT_LEFT))
1413
1403
  cmd.connect(SEL_COMMAND, method(:paste_selected_cb))
@@ -1420,11 +1410,11 @@ EOF
1420
1410
  # Zooming
1421
1411
  FXFrame.new(toolbar,
1422
1412
  LAYOUT_TOP|LAYOUT_LEFT|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, 0, 0, 4, 20)
1423
- cmd = FXButton.new(toolbar, "+\tZoom In", load_icon("zoom"), @mdiclient,
1413
+ cmd = FXButton.new(toolbar, ICON_ZOOM_IN, load_icon("zoom"), @mdiclient,
1424
1414
  0, FRAME_THICK|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT)
1425
1415
  cmd.connect(SEL_COMMAND) { zoom_in }
1426
1416
 
1427
- cmd = FXButton.new(toolbar, "-\tZoom Out", load_icon("zoom"), @mdiclient,
1417
+ cmd = FXButton.new(toolbar, ICON_ZOOM_OUT, load_icon("zoom"), @mdiclient,
1428
1418
  0, FRAME_THICK|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT)
1429
1419
  cmd.connect(SEL_COMMAND) { zoom_out }
1430
1420
 
@@ -1432,7 +1422,7 @@ EOF
1432
1422
  # Section travel
1433
1423
  frame = FXHorizontalFrame.new(toolbar,
1434
1424
  LAYOUT_RIGHT|FRAME_THICK|FRAME_RAISED)
1435
- cmd = FXButton.new(frame, "\tPrevious Section", load_icon("prevpage"),
1425
+ cmd = FXButton.new(frame, ICON_PREV_SECTION, load_icon("prevpage"),
1436
1426
  @mdiclient,
1437
1427
  0, FRAME_THICK|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT)
1438
1428
  cmd.connect(SEL_COMMAND) { previous_section }
@@ -1455,7 +1445,7 @@ EOF
1455
1445
  update_section if map
1456
1446
  }
1457
1447
 
1458
- cmd = FXButton.new(frame, "\tNext Section", load_icon("nextpage"),
1448
+ cmd = FXButton.new(frame, ICON_NEXT_SECTION, load_icon("nextpage"),
1459
1449
  @mdiclient,
1460
1450
  0, FRAME_THICK|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT)
1461
1451
  cmd.connect(SEL_COMMAND) { next_section }
@@ -1529,9 +1519,7 @@ EOF
1529
1519
  end
1530
1520
 
1531
1521
 
1532
- def initialize(app)
1533
- super(app, TITLE, nil, nil, DECOR_ALL, 0, 0, 800, 600)
1534
-
1522
+ def create_widgets
1535
1523
  # Menubar
1536
1524
  @menubar = FXMenuBar.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
1537
1525
 
@@ -1553,6 +1541,12 @@ EOF
1553
1541
 
1554
1542
  self.connect(SEL_CLOSE, method(:close_cb))
1555
1543
  show
1544
+ end
1545
+
1546
+ def initialize(app)
1547
+ super(app, eval("\"#{TITLE}\""), nil, nil, DECOR_ALL, 0, 0, 800, 600)
1548
+
1549
+ create_widgets
1556
1550
 
1557
1551
  # Trap CTRL-C signals and exit nicely
1558
1552
  trap('SIGINT') {
@@ -1573,4 +1567,5 @@ EOF
1573
1567
  }
1574
1568
  self.close if exit
1575
1569
  end
1570
+
1576
1571
  end