visualruby 1.0.12
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.
- checksums.yaml +7 -0
- data/bin/editor/VR_Document.rb +219 -0
- data/bin/editor/VR_TabSearch.rb +50 -0
- data/bin/editor/VR_Tabs.rb +99 -0
- data/bin/editor/VR_TextShell.rb +83 -0
- data/bin/editor/VR_TextViewCommon.rb +65 -0
- data/bin/editor/glade/VR_Document.glade +160 -0
- data/bin/main/GemTree.rb +23 -0
- data/bin/main/NewProjectGUI.rb +28 -0
- data/bin/main/ProjectChooserGUI.rb +41 -0
- data/bin/main/ProjectChooserView.rb +39 -0
- data/bin/main/RubygemsAPI.rb +93 -0
- data/bin/main/Splash.rb +22 -0
- data/bin/main/VR_ENV.rb +61 -0
- data/bin/main/VR_ENV_GLOBAL.rb +64 -0
- data/bin/main/VR_File_Tree.rb +120 -0
- data/bin/main/VR_Local_Gem_Tree.rb +80 -0
- data/bin/main/VR_Main.rb +313 -0
- data/bin/main/VR_Remote_Gem_Tree.rb +70 -0
- data/bin/main/glade/NewProjectGUI.glade +141 -0
- data/bin/main/glade/ProjectChooserGUI.glade +140 -0
- data/bin/main/glade/RubygemsAPI.glade +130 -0
- data/bin/main/glade/Splash.glade +18 -0
- data/bin/main/glade/VR_ENV.glade +168 -0
- data/bin/main/glade/VR_ENV_GLOBAL.glade +268 -0
- data/bin/main/glade/VR_File_Tree.glade +65 -0
- data/bin/main/glade/VR_Local_Gem_Tree.glade +45 -0
- data/bin/main/glade/VR_Main.glade +707 -0
- data/bin/main/glade/VR_Remote_Gem_Tree.glade +76 -0
- data/bin/tools/VR_Tools.rb +120 -0
- data/img/close.png +0 -0
- data/img/folder.png +0 -0
- data/img/glade.png +0 -0
- data/img/gtk-edit.png +0 -0
- data/img/obj.png +0 -0
- data/img/png.png +0 -0
- data/img/rb.png +0 -0
- data/img/ruby.png +0 -0
- data/img/splash.png +0 -0
- data/img/unknown.png +0 -0
- data/skeleton/document/New.glade +13 -0
- data/skeleton/document/NewWindow.rb +15 -0
- data/skeleton/project/bin/MyClass.rb +15 -0
- data/skeleton/project/bin/glade/MyClass.glade +45 -0
- data/skeleton/project/main.rb +14 -0
- data/visualruby_examples/active_record/.vr_settings.yaml +47 -0
- data/visualruby_examples/active_record/active_record.rb +52 -0
- data/visualruby_examples/active_record/bin/ChoosePerson.rb +17 -0
- data/visualruby_examples/active_record/bin/Person.rb +13 -0
- data/visualruby_examples/active_record/bin/glade/ChoosePerson.glade +61 -0
- data/visualruby_examples/active_record/bin/glade/Person.glade +148 -0
- data/visualruby_examples/active_record/db/development.sqlite3 +0 -0
- data/visualruby_examples/active_record2/.vr_settings.yaml +48 -0
- data/visualruby_examples/active_record2/active_record2.rb +142 -0
- data/visualruby_examples/active_record2/bin/CompanyGUI.rb +54 -0
- data/visualruby_examples/active_record2/bin/Employee.rb +20 -0
- data/visualruby_examples/active_record2/bin/Employer.rb +11 -0
- data/visualruby_examples/active_record2/bin/Paycheck.rb +11 -0
- data/visualruby_examples/active_record2/bin/glade/CompanyGUI.glade +167 -0
- data/visualruby_examples/active_record2/bin/glade/Employee.glade +123 -0
- data/visualruby_examples/active_record2/bin/glade/Employer.glade +147 -0
- data/visualruby_examples/active_record2/bin/glade/Paycheck.glade +145 -0
- data/visualruby_examples/active_record2/db/development.sqlite3 +0 -0
- data/visualruby_examples/all_widgets/.vr_settings.yaml +20 -0
- data/visualruby_examples/all_widgets/all_widgets.rb +13 -0
- data/visualruby_examples/all_widgets/bin/AllWidgets.rb +43 -0
- data/visualruby_examples/all_widgets/bin/glade/AllWidgets.glade +166 -0
- data/visualruby_examples/all_widgets/bin/splash.png +0 -0
- data/visualruby_examples/calculator/.vr_settings.yaml +21 -0
- data/visualruby_examples/calculator/bin/Calculator.rb +63 -0
- data/visualruby_examples/calculator/bin/glade/Calculator.glade +243 -0
- data/visualruby_examples/calculator/main.rb +13 -0
- data/visualruby_examples/child_window/.vr_settings.yaml +46 -0
- data/visualruby_examples/child_window/bin/ChildWindowDemo.rb +41 -0
- data/visualruby_examples/child_window/bin/MyChildClass.rb +42 -0
- data/visualruby_examples/child_window/bin/glade/ChildWindowDemo.glade +101 -0
- data/visualruby_examples/child_window/bin/glade/MyChildClass.glade +58 -0
- data/visualruby_examples/child_window/main.rb +13 -0
- data/visualruby_examples/drag_drop/.vr_settings.yaml +19 -0
- data/visualruby_examples/drag_drop/bin/DragDropDemo.rb +45 -0
- data/visualruby_examples/drag_drop/bin/glade/DragDropDemo.glade +143 -0
- data/visualruby_examples/drag_drop/img/folder.png +0 -0
- data/visualruby_examples/drag_drop/img/glade.png +0 -0
- data/visualruby_examples/drag_drop/img/gtk-edit.png +0 -0
- data/visualruby_examples/drag_drop/img/obj.png +0 -0
- data/visualruby_examples/drag_drop/img/png.png +0 -0
- data/visualruby_examples/drag_drop/img/rb.png +0 -0
- data/visualruby_examples/drag_drop/img/ruby.png +0 -0
- data/visualruby_examples/drag_drop/img/unknown.png +0 -0
- data/visualruby_examples/drag_drop/main.rb +14 -0
- data/visualruby_examples/listview/.vr_settings.yaml +46 -0
- data/visualruby_examples/listview/bin/SongListView.rb +89 -0
- data/visualruby_examples/listview/bin/SongListViewGUI.rb +67 -0
- data/visualruby_examples/listview/bin/audio-x-generic.png +0 -0
- data/visualruby_examples/listview/bin/glade/SongListViewGUI.glade +220 -0
- data/visualruby_examples/listview/main.rb +19 -0
- data/visualruby_examples/listview_objects/.vr_settings.yaml +46 -0
- data/visualruby_examples/listview_objects/bin/DataObject.rb +32 -0
- data/visualruby_examples/listview_objects/bin/DataObjectGUI.rb +41 -0
- data/visualruby_examples/listview_objects/bin/ListViewObjects.rb +34 -0
- data/visualruby_examples/listview_objects/bin/ListViewObjectsGUI.rb +18 -0
- data/visualruby_examples/listview_objects/bin/glade/DataObject.glade +198 -0
- data/visualruby_examples/listview_objects/bin/glade/ListViewObjectsGUI.glade +102 -0
- data/visualruby_examples/listview_objects/main.rb +13 -0
- data/visualruby_examples/simple_ruby_gui/.vr_settings.yaml +45 -0
- data/visualruby_examples/simple_ruby_gui/bin/DataObjectGUI.rb +20 -0
- data/visualruby_examples/simple_ruby_gui/bin/glade/DataObjectGUI.glade +163 -0
- data/visualruby_examples/simple_ruby_gui/simple_ruby_gui +16 -0
- data/visualruby_examples/treeview/.vr_settings.yaml +18 -0
- data/visualruby_examples/treeview/bin/MyClass.rb +28 -0
- data/visualruby_examples/treeview/bin/glade/MyClass.glade +48 -0
- data/visualruby_examples/treeview/main.rb +14 -0
- data/vr +40 -0
- metadata +202 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: e3fdd5836b0c063c6fc9bfb295b933f841130cde
|
|
4
|
+
data.tar.gz: 0815d5f397c03c87f9247b42a29159ec444e7bcf
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: d0a1de91c075ab198f8fdfc8b76535d2be3fb42093d24c5586dcfab7d4e9612b4adc6dc56c00fbbe7d28a7eeff72d4c9481d46482a62c2865ffb487736bd7827
|
|
7
|
+
data.tar.gz: 92d81ed542f22aefa6e0bebe966699ff5882949610b932678c1a0f3378c46f051222241cfaee796a3488f34cd3fe2e638e81edf29542b7c5ad04b59f6b553d15
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
|
|
2
|
+
class VR_Document < Gtk::SourceView
|
|
3
|
+
|
|
4
|
+
include GladeGUI
|
|
5
|
+
include VR_TextViewCommon
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
attr_accessor :full_path_file
|
|
9
|
+
|
|
10
|
+
def initialize(full_path_file, title_label, main)
|
|
11
|
+
@main = main
|
|
12
|
+
super()
|
|
13
|
+
@title = title_label #reference to label on tab
|
|
14
|
+
reload_from_disk(full_path_file)
|
|
15
|
+
signal_connect("visibility_notify_event") { scroll_to_cursor() }
|
|
16
|
+
hilight_current_line = true
|
|
17
|
+
show_right_margin = true
|
|
18
|
+
right_margin_position = 80
|
|
19
|
+
auto_indent = true
|
|
20
|
+
lang = Gtk::SourceLanguageManager.new.get_language(get_language(full_path_file)) # 'ruby') if [".rb", "", ".gemspec"].include? File.extname(full_path_file)
|
|
21
|
+
buffer.language = lang
|
|
22
|
+
buffer.highlight_syntax = true
|
|
23
|
+
# buffer.highlight_matching_brackets = true
|
|
24
|
+
wrap_mode = Gtk::TextTag::WRAP_WORD
|
|
25
|
+
buffer.create_tag("hilight", { "background" => "#FFF0A0" })
|
|
26
|
+
buffer.create_tag("hilight_red",{ "background" => "#FFC0C0" })
|
|
27
|
+
buffer.signal_connect("changed") { remove_tag("hilight") }
|
|
28
|
+
self.show_line_numbers = true
|
|
29
|
+
load_glade(__FILE__) #for save dialogs
|
|
30
|
+
update_style()
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def get_language(fn)
|
|
34
|
+
case File.extname(full_path_file)
|
|
35
|
+
when ".rb", "", ".gemspec" ; return "ruby"
|
|
36
|
+
when ".erb", ".html" ; return "html"
|
|
37
|
+
else ; return ""
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def update_style()
|
|
42
|
+
modify_font(Pango::FontDescription.new($VR_ENV_GLOBAL.font_name))
|
|
43
|
+
tab_array = Pango::TabArray.new(1, true)
|
|
44
|
+
tab_array.set_tab(0, Pango::TAB_LEFT, $VR_ENV_GLOBAL.tab_spaces * 8)
|
|
45
|
+
set_tabs(tab_array)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def reload_from_disk(fn = @full_path_file)
|
|
49
|
+
@full_path_file = fn
|
|
50
|
+
@title.label = File.basename(@full_path_file)
|
|
51
|
+
buffer.text = File.open(@full_path_file, "r").read if File.file?(@full_path_file.to_s) #protect against nil to_s
|
|
52
|
+
buffer.modified = false
|
|
53
|
+
@modified_time = mod_time()
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def modified_time_matches()
|
|
57
|
+
return true if @modified_time == mod_time()
|
|
58
|
+
d = @builder["dialogModifiedTime"]
|
|
59
|
+
@builder["labelModified"].markup = "<big><big><b>WARNING!</b></big></big>\n\nThe file: <b>#{@full_path_file}</b>\n has been modified since you loaded it:\n\nYou loaded: #{@modified_time}\nOn disk: #{mod_time().to_s}\n\nDo you wnat to keep this version?\n"
|
|
60
|
+
resp = d.run
|
|
61
|
+
d.hide
|
|
62
|
+
if resp == 2 # Keep Current Version
|
|
63
|
+
write_to_disk()
|
|
64
|
+
return true
|
|
65
|
+
elsif resp == 1 # Reload From Disk
|
|
66
|
+
reload_from_disk()
|
|
67
|
+
end
|
|
68
|
+
return false #abort!
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def try_to_save(ask = true)
|
|
72
|
+
return false if not modified_time_matches()
|
|
73
|
+
return true if empty?
|
|
74
|
+
if (@title.label == "Untitled")
|
|
75
|
+
return save_changes?
|
|
76
|
+
elsif (buffer.modified? and ask)
|
|
77
|
+
return save_changes?
|
|
78
|
+
elsif buffer.modified?
|
|
79
|
+
write_to_disk()
|
|
80
|
+
return true
|
|
81
|
+
else
|
|
82
|
+
return true
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def write_to_disk(fn = @full_path_file)
|
|
87
|
+
# modify_base(Gtk::STATE_NORMAL, Gdk::Color.parse("#FFFFFF"))
|
|
88
|
+
@full_path_file = fn
|
|
89
|
+
File.open(fn, "w") { |f| f.puts(buffer.text) }
|
|
90
|
+
buffer.modified = false
|
|
91
|
+
@modified_time = mod_time()
|
|
92
|
+
@title.label = File.basename(fn)
|
|
93
|
+
return true
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def save_changes?
|
|
97
|
+
d = @builder["dialogSave"]
|
|
98
|
+
@builder["labelSave"].markup = "Save changes to: <b>#{File.basename(@full_path_file)}</b>?"
|
|
99
|
+
resp = d.run
|
|
100
|
+
d.hide
|
|
101
|
+
if resp == 2 # Save Changes
|
|
102
|
+
return @title.label == "Untitled" ? save_as() : write_to_disk()
|
|
103
|
+
elsif resp == 1 # Discard Changes
|
|
104
|
+
reload_from_disk()
|
|
105
|
+
return true #continue without saving
|
|
106
|
+
else
|
|
107
|
+
return false #abort!
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
#todo update file tree, parent window?
|
|
112
|
+
def save_as() # returns false or complete file name.
|
|
113
|
+
dialog = Gtk::FileChooserDialog.new("Save File As...",
|
|
114
|
+
@builder['window1'],
|
|
115
|
+
Gtk::FileChooser::ACTION_SAVE,
|
|
116
|
+
nil,
|
|
117
|
+
[Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
|
|
118
|
+
[Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_ACCEPT])
|
|
119
|
+
dialog.current_folder = File.dirname(@full_path_file)
|
|
120
|
+
dialog.current_name = VR_Document.get_class_title(buffer.text)
|
|
121
|
+
resp = dialog.run
|
|
122
|
+
dialog.hide
|
|
123
|
+
if resp == Gtk::Dialog::RESPONSE_ACCEPT
|
|
124
|
+
write_to_disk(dialog.filename)
|
|
125
|
+
@main.file_tree.insert(dialog.filename)
|
|
126
|
+
return true
|
|
127
|
+
end
|
|
128
|
+
return false
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def jump_to_line(line_num, search_str="")
|
|
132
|
+
hilight_line(line_num)
|
|
133
|
+
iter = buffer.get_iter_at_line(line_num)
|
|
134
|
+
mark = buffer.create_mark("error", iter, true)
|
|
135
|
+
scroll_to_mark(mark, 0.0, true, 0.0, 0.5)
|
|
136
|
+
buffer.place_cursor(iter)
|
|
137
|
+
scroll_to_cursor
|
|
138
|
+
select_text(line_num, search_str)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def hilight_line(line)
|
|
142
|
+
remove_tag("hilight")
|
|
143
|
+
apply_tag_to_line(line, "hilight", nil)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def indent(spaces)
|
|
147
|
+
s,e = get_selected_lines()
|
|
148
|
+
(s..e).each do |i|
|
|
149
|
+
iter = buffer.get_iter_at_line(i)
|
|
150
|
+
buffer.insert(iter, " " * spaces)
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def unindent(spaces)
|
|
155
|
+
s,e = get_selected_lines()
|
|
156
|
+
(s..e).each do |i|
|
|
157
|
+
iter, iter_end = get_line_iters(i)
|
|
158
|
+
if iter_end.offset >= iter.offset + 2
|
|
159
|
+
iter_end.offset = iter.offset + 2
|
|
160
|
+
t = buffer.get_text(iter, iter_end)
|
|
161
|
+
buffer.delete(iter, iter_end)
|
|
162
|
+
buffer.insert(iter,t.lstrip)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def comment()
|
|
168
|
+
s,e = get_selected_lines()
|
|
169
|
+
(s..e).each do |i|
|
|
170
|
+
iter, iter_end = get_line_iters(i)
|
|
171
|
+
iter_end.offset = iter.offset+1
|
|
172
|
+
chr = buffer.get_text(iter, iter_end)
|
|
173
|
+
buffer.insert(iter, "#")
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def un_comment()
|
|
178
|
+
s,e = get_selected_lines()
|
|
179
|
+
(s..e).each do |i|
|
|
180
|
+
iter, iter_end = get_line_iters(i)
|
|
181
|
+
next if iter_end.offset <= iter.offset + 1
|
|
182
|
+
iter_end.offset = iter.offset+1
|
|
183
|
+
chr = buffer.get_text(iter, iter_end)
|
|
184
|
+
buffer.delete(iter, iter_end) if chr == "#"
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def get_selected_lines()
|
|
189
|
+
s,e = buffer.selection_bounds
|
|
190
|
+
return s.line, e.line
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def replace(str)
|
|
194
|
+
return unless buffer.has_selection?
|
|
195
|
+
s,e = buffer.selection_bounds
|
|
196
|
+
buffer.delete(s,e)
|
|
197
|
+
buffer.insert_at_cursor(str)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def selected_text()
|
|
201
|
+
s,e = buffer.selection_bounds
|
|
202
|
+
buffer.get_text(s, e)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def empty?()
|
|
206
|
+
return buffer.text.strip == ''
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def self.get_class_title(source_code)
|
|
210
|
+
cn = /^\s*class\s+(\b\w+\b)/.match(source_code)
|
|
211
|
+
cn == nil ? "Untitled" : cn[1] + ".rb"
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def mod_time()
|
|
215
|
+
return File.file?(@full_path_file) ? File.stat(@full_path_file).mtime : nil
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
end
|
|
219
|
+
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
|
|
2
|
+
module VR_TabSearch #grh
|
|
3
|
+
|
|
4
|
+
def find_in_tabs(str)
|
|
5
|
+
out = "Search Results for: " + str + "\n"
|
|
6
|
+
out += scan_for_text(str, @docs[self.page].buffer.text, @docs[self.page].full_path_file)
|
|
7
|
+
(0..self.n_pages-1).each do |i|
|
|
8
|
+
if i != self.page
|
|
9
|
+
out += scan_for_text(str, @docs[i].buffer.text, @docs[i].full_path_file)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
return out
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def find_in_all(str)
|
|
16
|
+
out = "Search Res ults for: " + str + "\n"
|
|
17
|
+
Find.find(Dir.pwd) do |path|
|
|
18
|
+
Find.prune if path =~ /\/glade$/ or path =~ /\/doc$/ #or File.directory?(path)
|
|
19
|
+
if (File.extname(path) == ".rb" or File.extname(path) == ".erb") and not File.directory?(path)
|
|
20
|
+
txt = File.open(path, "r").read
|
|
21
|
+
out += scan_for_text(str, txt, path)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
return out
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def replace(str_replacement)
|
|
28
|
+
@docs[self.page].replace(str_replacement)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def scan_for_text(str, txt, path)
|
|
32
|
+
i = 1
|
|
33
|
+
out = ''
|
|
34
|
+
txt.each_line do |line|
|
|
35
|
+
match = line.scan(str)
|
|
36
|
+
out += path + ':' + i.to_s + ": Found: "+ str + "\n" if match.size > 0
|
|
37
|
+
i += 1
|
|
38
|
+
end
|
|
39
|
+
return out
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def jump_to(line)
|
|
43
|
+
return if line.nil?
|
|
44
|
+
if not switch_to(line[:path]) #full path file
|
|
45
|
+
load_tab(line[:path])
|
|
46
|
+
end
|
|
47
|
+
@docs[self.page].jump_to_line(line[:line] - 1, line[:search_str])
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
|
|
2
|
+
class VR_Tabs < Gtk::Notebook
|
|
3
|
+
|
|
4
|
+
attr_reader :docs
|
|
5
|
+
|
|
6
|
+
include VR_TabSearch
|
|
7
|
+
|
|
8
|
+
def initialize(main)
|
|
9
|
+
@docs = Array.new
|
|
10
|
+
@main = main
|
|
11
|
+
@pix_close = Gdk::Pixbuf.new(File.dirname(__FILE__) + '/../../img/close.png')
|
|
12
|
+
super()
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def update_style_all()
|
|
16
|
+
@docs.each { |doc| doc.update_style() }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
#todo update file_tree!
|
|
20
|
+
def try_to_save_all(ask = true)
|
|
21
|
+
@docs.each do |doc|
|
|
22
|
+
return false unless doc.try_to_save(ask)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
#todo update file_tree!
|
|
27
|
+
def try_to_close_all(ask = true)
|
|
28
|
+
return false unless try_to_save_all(ask)
|
|
29
|
+
(n_pages).times { destroy_tab() }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def switch_to(path)
|
|
34
|
+
i = @docs.index{ |d| d.full_path_file == path }
|
|
35
|
+
return false if i.nil?
|
|
36
|
+
self.page = i if i != self.page
|
|
37
|
+
return true
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def set_contents(text)
|
|
41
|
+
if @docs[self.page].buffer.text == ""
|
|
42
|
+
@docs[self.page].buffer.text = text
|
|
43
|
+
@docs[self.page].buffer.modified = false
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def load_tab(full_path_file = Dir.pwd + "/Untitled")
|
|
48
|
+
return if switch_to(full_path_file)
|
|
49
|
+
tab = Gtk::HBox.new
|
|
50
|
+
box = Gtk::EventBox.new
|
|
51
|
+
img = Gtk::Image.new(@pix_close)
|
|
52
|
+
box.add(img)
|
|
53
|
+
title = Gtk::Label.new(File.basename(full_path_file))
|
|
54
|
+
tab.pack_start(title, true, true, 2)
|
|
55
|
+
tab.pack_start(box)
|
|
56
|
+
tab.show_all
|
|
57
|
+
text = VR_Document.new(full_path_file, title, @main)
|
|
58
|
+
child = Gtk::ScrolledWindow.new
|
|
59
|
+
child.add(text)
|
|
60
|
+
box.signal_connect("button_release_event") {remove_id(text.object_id)}
|
|
61
|
+
#remove blank tab
|
|
62
|
+
if @docs.size == 1 and @docs[0].buffer.text.strip == ""
|
|
63
|
+
@docs[0] = text
|
|
64
|
+
self.remove_page(0)
|
|
65
|
+
end
|
|
66
|
+
append_page(child, tab)
|
|
67
|
+
@main.builder['window1'].show_all
|
|
68
|
+
self.page = self.n_pages-1
|
|
69
|
+
@docs[self.page] = text
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
#used when little 'x' image is clicked to close.
|
|
73
|
+
def remove_id(object_id)
|
|
74
|
+
i = @docs.index { |doc| doc.object_id == object_id }
|
|
75
|
+
destroy_tab(i) if @docs[i].try_to_save()
|
|
76
|
+
# remove_tab(i) #if not i.nil?
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
#if its there, destroys it
|
|
80
|
+
def destroy_file_tab(file_name)
|
|
81
|
+
destroy_tab() if switch_to(file_name)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def destroy_tab(tab = self.page)
|
|
85
|
+
@docs.delete_at(tab)
|
|
86
|
+
self.remove_page(tab)
|
|
87
|
+
load_tab() if @docs.empty?
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def get_open_fn()
|
|
91
|
+
@docs.inject([]) { |ar, doc| ar << doc.full_path_file }
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def open_file_names(ar)
|
|
95
|
+
ar.each { |fn| load_tab(fn) if File.file?(fn) and fn.include? Dir.pwd}
|
|
96
|
+
load_tab() if @docs.empty?
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
|
|
2
|
+
class VR_TextShell < Gtk::TextView
|
|
3
|
+
|
|
4
|
+
include VR_TextViewCommon
|
|
5
|
+
|
|
6
|
+
def initialize(tabs)
|
|
7
|
+
super()
|
|
8
|
+
@tabs = tabs
|
|
9
|
+
@current_line = 0
|
|
10
|
+
@lines = [] #needed
|
|
11
|
+
self.editable = false
|
|
12
|
+
buffer.create_tag("blue", { "foreground" => "#0000A0", "underline" => Pango::UNDERLINE_SINGLE })
|
|
13
|
+
buffer.create_tag("hilight", { "background" => "#FFF0A0" } )
|
|
14
|
+
signal_connect("button_release_event") { jump_to(line_at_cursor() +1) } #buffer's lines start at 1
|
|
15
|
+
signal_connect("key_release_event") { jump_to(line_at_cursor() +1) } #buffer's lines start at 1
|
|
16
|
+
# self.buffer.signal_connect("changed") { buffer__changed() }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @buffer.signal_connect("changed") {
|
|
20
|
+
# eob_mark =
|
|
21
|
+
#@output.buffer.create_mark(nil,@output.buffer.start_iter.forward_to_end,false)
|
|
22
|
+
# @output.scroll_mark_onscreen(eob_mark)
|
|
23
|
+
# }
|
|
24
|
+
|
|
25
|
+
def buffer__move_cursor
|
|
26
|
+
remove_tag("hilight")
|
|
27
|
+
# place_cursor_onscreen
|
|
28
|
+
line = line_at_cursor()
|
|
29
|
+
apply_tag_to_line(line, "hilight")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# def buffer__changed
|
|
33
|
+
# iter = buffer.end_iter
|
|
34
|
+
# scroll_to_iter(iter, 0.0, false, 0, 0)
|
|
35
|
+
# self.queue_draw
|
|
36
|
+
## self.hide
|
|
37
|
+
#
|
|
38
|
+
## self.show
|
|
39
|
+
#
|
|
40
|
+
# end
|
|
41
|
+
|
|
42
|
+
def hilight_links(text, jump_to_first)
|
|
43
|
+
self.buffer.text = text
|
|
44
|
+
first_valid_line = load_lines()
|
|
45
|
+
(0..@lines.size - 1).each do |i|
|
|
46
|
+
next if @lines[i].nil?
|
|
47
|
+
apply_tag_to_line(i, "blue", @lines[i][:file_name] + ":" + @lines[i][:line].to_s)
|
|
48
|
+
end
|
|
49
|
+
@current_line = 0
|
|
50
|
+
@tabs.jump_to(first_valid_line) if jump_to_first and first_valid_line
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def load_lines()
|
|
56
|
+
@lines = []
|
|
57
|
+
first = nil
|
|
58
|
+
reg = /^.*(#{Dir.pwd}[\w+|\/]*)\/([\w|\.]+):(\d+):/
|
|
59
|
+
reg_str = /Found:\s(.+)$/
|
|
60
|
+
self.buffer.text. each_line do |l|
|
|
61
|
+
m = reg.match(l)
|
|
62
|
+
if m.nil?
|
|
63
|
+
@lines << nil
|
|
64
|
+
else
|
|
65
|
+
m2 = reg_str.match(l)
|
|
66
|
+
search_str = (m2.nil?) ? "" : m2[1]
|
|
67
|
+
@lines << { :path => m[1] + "/" + m[2], :file_name => m[2], :line => m[3].to_i, :search_str => search_str }
|
|
68
|
+
first ||= @lines.last
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
return first
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def jump_to(line_no = @current_line+1)
|
|
75
|
+
return false if line_no > @lines.size - 1
|
|
76
|
+
@current_line = line_no
|
|
77
|
+
remove_tag("hilight")
|
|
78
|
+
apply_tag_to_line(@current_line, "hilight", nil)
|
|
79
|
+
@tabs.jump_to(@lines[@current_line])
|
|
80
|
+
return false #must return false for button_up event
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
module VR_TextViewCommon
|
|
4
|
+
|
|
5
|
+
def get_line_text(line)
|
|
6
|
+
return nil if line > buffer.line_count - 1
|
|
7
|
+
iter, iter_end = get_line_iters(line)
|
|
8
|
+
return buffer.get_text(iter, iter_end)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def get_line_iters(line, search_str = nil)
|
|
12
|
+
s = buffer.get_iter_at_line(line)
|
|
13
|
+
e = get_end_iter(s)
|
|
14
|
+
if !search_str.nil?
|
|
15
|
+
s, e = s.forward_search(search_str, Gtk::TextIter::SEARCH_TEXT_ONLY, e)
|
|
16
|
+
end
|
|
17
|
+
return s, e
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def select_text(line, search_str = nil)
|
|
21
|
+
s, e = get_line_iters(line, search_str)
|
|
22
|
+
buffer.move_mark("insert",s)
|
|
23
|
+
buffer.move_mark("selection_bound", e)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# def get_text_scan_iters(line_num, search_str)
|
|
28
|
+
# st, en = get_line_iters(line_num)
|
|
29
|
+
# s, e = st.forward_search(search_str, Gtk::TextIter::SEARCH_TEXT_ONLY, en)
|
|
30
|
+
# end
|
|
31
|
+
|
|
32
|
+
def apply_tag_to_line(line, tag, search_str = nil)
|
|
33
|
+
s, e = get_line_iters(line, search_str)
|
|
34
|
+
buffer.apply_tag(tag, s, e)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_end_iter(iter)
|
|
40
|
+
if iter.line == buffer.line_count - 1 # last line
|
|
41
|
+
return buffer.end_iter
|
|
42
|
+
end
|
|
43
|
+
return buffer.get_iter_at_line(iter.line+1)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def remove_tag(tag)
|
|
47
|
+
s, e = buffer.bounds
|
|
48
|
+
buffer.remove_tag(tag, s, e)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def line_at_cursor()
|
|
53
|
+
cursor_pos = buffer.cursor_position
|
|
54
|
+
iter = buffer.get_iter_at_offset(cursor_pos)
|
|
55
|
+
return iter.line-1
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def scroll_to_cursor()
|
|
59
|
+
os = buffer.cursor_position
|
|
60
|
+
return if os > buffer.char_count - 1 or os == 0
|
|
61
|
+
iter = buffer.get_iter_at_offset(os)
|
|
62
|
+
scroll_to_iter(iter, 0.0, true, 1.0, 0.5)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<interface>
|
|
3
|
+
<requires lib="gtk+" version="2.16"/>
|
|
4
|
+
<!-- interface-naming-policy project-wide -->
|
|
5
|
+
<object class="GtkDialog" id="dialogSave">
|
|
6
|
+
<property name="border_width">5</property>
|
|
7
|
+
<property name="title" translatable="yes">Save Changes?</property>
|
|
8
|
+
<property name="modal">True</property>
|
|
9
|
+
<property name="type_hint">normal</property>
|
|
10
|
+
<child internal-child="vbox">
|
|
11
|
+
<object class="GtkVBox" id="dialog-vbox1">
|
|
12
|
+
<property name="visible">True</property>
|
|
13
|
+
<property name="spacing">2</property>
|
|
14
|
+
<child>
|
|
15
|
+
<object class="GtkLabel" id="labelSave">
|
|
16
|
+
<property name="visible">True</property>
|
|
17
|
+
<property name="label" translatable="yes">label</property>
|
|
18
|
+
</object>
|
|
19
|
+
<packing>
|
|
20
|
+
<property name="padding">20</property>
|
|
21
|
+
<property name="position">1</property>
|
|
22
|
+
</packing>
|
|
23
|
+
</child>
|
|
24
|
+
<child internal-child="action_area">
|
|
25
|
+
<object class="GtkHButtonBox" id="dialog-action_area1">
|
|
26
|
+
<property name="visible">True</property>
|
|
27
|
+
<property name="layout_style">end</property>
|
|
28
|
+
<child>
|
|
29
|
+
<object class="GtkButton" id="button1">
|
|
30
|
+
<property name="label" translatable="yes">Save Changes</property>
|
|
31
|
+
<property name="visible">True</property>
|
|
32
|
+
<property name="can_focus">True</property>
|
|
33
|
+
<property name="receives_default">True</property>
|
|
34
|
+
</object>
|
|
35
|
+
<packing>
|
|
36
|
+
<property name="expand">False</property>
|
|
37
|
+
<property name="fill">False</property>
|
|
38
|
+
<property name="position">0</property>
|
|
39
|
+
</packing>
|
|
40
|
+
</child>
|
|
41
|
+
<child>
|
|
42
|
+
<object class="GtkButton" id="button2">
|
|
43
|
+
<property name="label" translatable="yes">Discard Changes</property>
|
|
44
|
+
<property name="visible">True</property>
|
|
45
|
+
<property name="can_focus">True</property>
|
|
46
|
+
<property name="receives_default">True</property>
|
|
47
|
+
<property name="xalign">0.52999997138977051</property>
|
|
48
|
+
</object>
|
|
49
|
+
<packing>
|
|
50
|
+
<property name="expand">False</property>
|
|
51
|
+
<property name="fill">False</property>
|
|
52
|
+
<property name="position">1</property>
|
|
53
|
+
</packing>
|
|
54
|
+
</child>
|
|
55
|
+
<child>
|
|
56
|
+
<object class="GtkButton" id="button3">
|
|
57
|
+
<property name="label" translatable="yes">Cancel</property>
|
|
58
|
+
<property name="visible">True</property>
|
|
59
|
+
<property name="can_focus">True</property>
|
|
60
|
+
<property name="receives_default">True</property>
|
|
61
|
+
</object>
|
|
62
|
+
<packing>
|
|
63
|
+
<property name="expand">False</property>
|
|
64
|
+
<property name="fill">False</property>
|
|
65
|
+
<property name="position">2</property>
|
|
66
|
+
</packing>
|
|
67
|
+
</child>
|
|
68
|
+
</object>
|
|
69
|
+
<packing>
|
|
70
|
+
<property name="expand">False</property>
|
|
71
|
+
<property name="pack_type">end</property>
|
|
72
|
+
<property name="position">0</property>
|
|
73
|
+
</packing>
|
|
74
|
+
</child>
|
|
75
|
+
</object>
|
|
76
|
+
</child>
|
|
77
|
+
<action-widgets>
|
|
78
|
+
<action-widget response="2">button1</action-widget>
|
|
79
|
+
<action-widget response="1">button2</action-widget>
|
|
80
|
+
<action-widget response="0">button3</action-widget>
|
|
81
|
+
</action-widgets>
|
|
82
|
+
</object>
|
|
83
|
+
<object class="GtkDialog" id="dialogModifiedTime">
|
|
84
|
+
<property name="border_width">5</property>
|
|
85
|
+
<property name="title" translatable="yes">WARNING! File Altered!</property>
|
|
86
|
+
<property name="type_hint">normal</property>
|
|
87
|
+
<child internal-child="vbox">
|
|
88
|
+
<object class="GtkVBox" id="dialog-vbox2">
|
|
89
|
+
<property name="visible">True</property>
|
|
90
|
+
<property name="spacing">2</property>
|
|
91
|
+
<child>
|
|
92
|
+
<object class="GtkLabel" id="labelModified">
|
|
93
|
+
<property name="visible">True</property>
|
|
94
|
+
<property name="label" translatable="yes">label</property>
|
|
95
|
+
<property name="use_markup">True</property>
|
|
96
|
+
</object>
|
|
97
|
+
<packing>
|
|
98
|
+
<property name="padding">10</property>
|
|
99
|
+
<property name="position">1</property>
|
|
100
|
+
</packing>
|
|
101
|
+
</child>
|
|
102
|
+
<child internal-child="action_area">
|
|
103
|
+
<object class="GtkHButtonBox" id="dialog-action_area2">
|
|
104
|
+
<property name="visible">True</property>
|
|
105
|
+
<property name="layout_style">end</property>
|
|
106
|
+
<child>
|
|
107
|
+
<object class="GtkButton" id="button4">
|
|
108
|
+
<property name="label" translatable="yes">Keep Current Version</property>
|
|
109
|
+
<property name="visible">True</property>
|
|
110
|
+
<property name="can_focus">True</property>
|
|
111
|
+
<property name="receives_default">True</property>
|
|
112
|
+
</object>
|
|
113
|
+
<packing>
|
|
114
|
+
<property name="expand">False</property>
|
|
115
|
+
<property name="fill">False</property>
|
|
116
|
+
<property name="position">0</property>
|
|
117
|
+
</packing>
|
|
118
|
+
</child>
|
|
119
|
+
<child>
|
|
120
|
+
<object class="GtkButton" id="button5">
|
|
121
|
+
<property name="label" translatable="yes">Reload From Disk</property>
|
|
122
|
+
<property name="visible">True</property>
|
|
123
|
+
<property name="can_focus">True</property>
|
|
124
|
+
<property name="receives_default">True</property>
|
|
125
|
+
</object>
|
|
126
|
+
<packing>
|
|
127
|
+
<property name="expand">False</property>
|
|
128
|
+
<property name="fill">False</property>
|
|
129
|
+
<property name="position">1</property>
|
|
130
|
+
</packing>
|
|
131
|
+
</child>
|
|
132
|
+
<child>
|
|
133
|
+
<object class="GtkButton" id="button6">
|
|
134
|
+
<property name="label" translatable="yes">Cancel</property>
|
|
135
|
+
<property name="visible">True</property>
|
|
136
|
+
<property name="can_focus">True</property>
|
|
137
|
+
<property name="receives_default">True</property>
|
|
138
|
+
</object>
|
|
139
|
+
<packing>
|
|
140
|
+
<property name="expand">False</property>
|
|
141
|
+
<property name="fill">False</property>
|
|
142
|
+
<property name="position">2</property>
|
|
143
|
+
</packing>
|
|
144
|
+
</child>
|
|
145
|
+
</object>
|
|
146
|
+
<packing>
|
|
147
|
+
<property name="expand">False</property>
|
|
148
|
+
<property name="pack_type">end</property>
|
|
149
|
+
<property name="position">0</property>
|
|
150
|
+
</packing>
|
|
151
|
+
</child>
|
|
152
|
+
</object>
|
|
153
|
+
</child>
|
|
154
|
+
<action-widgets>
|
|
155
|
+
<action-widget response="2">button4</action-widget>
|
|
156
|
+
<action-widget response="1">button5</action-widget>
|
|
157
|
+
<action-widget response="0">button6</action-widget>
|
|
158
|
+
</action-widgets>
|
|
159
|
+
</object>
|
|
160
|
+
</interface>
|