gvcsfx 0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,277 @@
1
+ # Copyright (C) 2020 Chris Liaw <chrisliaw@antrapol.com>
2
+ # Author: Chris Liaw <chrisliaw@antrapol.com>
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+
18
+
19
+ module GvcsFx
20
+ module TabRepos
21
+
22
+ class GvcsFxRepository
23
+ include javafx.beans.value.ObservableValue
24
+ attr_reader :repos, :branch
25
+ def initialize(repos,branch)
26
+ @repos = repos
27
+ @branch = branch
28
+ end
29
+
30
+ def addListener(list)
31
+ end
32
+
33
+ def removeListener(list)
34
+ end
35
+
36
+ def value
37
+ self
38
+ end
39
+ end
40
+
41
+ class URLTableCell < javafx.scene.control.TableCell
42
+ def updateItem(itm, isEmpty)
43
+ super
44
+ if item.nil?
45
+ setGraphic(nil)
46
+ else
47
+ repos = itm.repos
48
+ br = itm.branch
49
+ #st = []
50
+ #st << repos.url
51
+ #st << "Push to / Pull from current branch : #{br}"
52
+ #lbl = javafx.scene.control.Label.new(st.join("\n"))
53
+ lbl = javafx.scene.control.Label.new(repos.url)
54
+ setGraphic(lbl)
55
+ end
56
+ end
57
+ end
58
+
59
+ def init_tab_repos
60
+
61
+ @tblRepos.placeholder = javafx.scene.control.Label.new("No remote repository configured")
62
+
63
+ @tblRepos.columns.clear
64
+ @tblRepos.column_resize_policy = javafx.scene.control.TableView::CONSTRAINED_RESIZE_POLICY
65
+
66
+ cols = []
67
+ colName = TableColumn.new("Name")
68
+ colName.cell_value_factory = Proc.new do |c|
69
+ SimpleStringProperty.new(c.value.repos.name)
70
+ end
71
+ cols << colName
72
+
73
+ colUrl = TableColumn.new("URL")
74
+ colUrl.cell_value_factory = Proc.new do |c|
75
+ c.value
76
+ end
77
+ colUrl.cell_factory = Proc.new do |tc|
78
+ URLTableCell.new
79
+ end
80
+ cols << colUrl
81
+
82
+ #@cmbRepoBranches = javafx.scene.control.ComboBox.new
83
+ #colBranches = TableColumn.new("Branch")
84
+ #colBranches.cell_factory = Proc.new do |tc|
85
+ # @tblCelReposBranch = ReposBranchTableCell.new
86
+ # @tblCelReposBranch
87
+ #end
88
+ #colBranches.cell_value_factory = Proc.new do |p|
89
+ # p.value.branches
90
+ #end
91
+ #colBranches.cell_value_factory = Proc.new do |p|
92
+ # SimpleStringProperty.new(p.value.url)
93
+ #end
94
+ #cols << colBranches
95
+
96
+ @tblRepos.columns.add_all(cols)
97
+
98
+ colName.pref_width = 180.0
99
+ colName.max_width = 280.0
100
+ colName.min_width = 160.0
101
+
102
+ #colBranches.pref_width = 180.0
103
+ #colBranches.max_width = 220.0
104
+ #colBranches.min_width = 168.0
105
+
106
+ @tblRepos.selection_model.selection_mode = javafx.scene.control.SelectionMode::SINGLE
107
+
108
+ #@tblRepos.add_event_handler(javafx.scene.input.MouseEvent::MOUSE_CLICKED, Proc.new do |evt|
109
+ # if evt.button == javafx.scene.input.MouseButton::SECONDARY
110
+ # # right click on item
111
+ # changes_ctxmenu.show(@tblChanges, evt.screen_x, evt.screen_y)
112
+ # elsif evt.button == javafx.scene.input.MouseButton::PRIMARY and evt.click_count == 2
113
+ # # double click on item - view file
114
+ # sel = @tblChanges.selection_model.selected_items
115
+ # if sel.length > 0
116
+ # sel.each do |s|
117
+ # view_file(s.path)
118
+ # end
119
+ # end
120
+
121
+ # end
122
+ #end)
123
+
124
+ end
125
+
126
+ def refresh_tab_repos
127
+
128
+ @txtReposName.clear
129
+ @txtReposUrl.clear
130
+
131
+ st, @currBr = @selWs.current_branch
132
+ @currBr = "<unknown>" if not st
133
+
134
+ @lblReposMessage.text = "Operation push & pull always based on current branch [Current branch is '#{@currBr}'].\nIf you want to push / pull to different branch, change it at the 'Branches' tab before come here."
135
+
136
+ refresh_repos_list
137
+
138
+ end
139
+
140
+ def refresh_repos_list
141
+
142
+ @tblRepos.items.clear
143
+
144
+ st, res = @selWs.remote_config
145
+ if st
146
+ rp = []
147
+ res.each do |k,v|
148
+ #repos = Gvcs::Repository.new(k,v)
149
+ repos = Gvcs::Repository.new(k,v)
150
+ rp << GvcsFxRepository.new(repos,"")
151
+ #st, br = @selWs.current_branch
152
+ #if st
153
+ # rp << GvcsFxRepository.new(repos,br)
154
+ #else
155
+ # rp << GvcsFxRepository.new(repos,"<unknown>")
156
+ #end
157
+ #rp << repos
158
+ end
159
+
160
+ @tblRepos.items.add_all(rp)
161
+
162
+ end
163
+
164
+ end
165
+
166
+ def repos_key_released(evt)
167
+
168
+ if evt.code == javafx.scene.input.KeyCode::DELETE
169
+ sel = @tblRepos.selection_model.selected_items.to_a
170
+ if sel.length > 0
171
+ nm = sel.first.repos.name
172
+ pa = sel.first.repos.url
173
+ res = fx_alert_confirmation("Delete Repository '#{nm} - #{pa}' from system?", nil, "Remove Repository?", main_stage)
174
+ if res == :ok
175
+ st, rres = @selWs.remove_remote(nm)
176
+ if st
177
+ refresh_repos_list
178
+ log_debug "Remote repository '#{nm} - #{pa}' removed from workspace"
179
+ set_success_gmsg("Remote repository '#{nm} - #{pa}' removed from workspace")
180
+ else
181
+ fx_alert_error(rres,"Remove Repository Exception",main_stage)
182
+ end
183
+ end
184
+ end
185
+
186
+ end
187
+
188
+ end
189
+
190
+ def add_repository(evt)
191
+
192
+ nm = @txtReposName.text
193
+ pa = @txtReposUrl.text
194
+
195
+ if is_empty?(nm)
196
+ fx_alert_error("Repository name cannot be empty","Repository Name Empty",main_stage)
197
+ elsif is_empty?(pa)
198
+ fx_alert_error("Repository URL cannot be empty","Repository URL Empty",main_stage)
199
+ else
200
+ st, res = @selWs.add_remote(nm,pa)
201
+ if st
202
+
203
+ @txtReposName.clear
204
+ @txtReposUrl.clear
205
+
206
+ refresh_repos_list
207
+ else
208
+ fx_alert_error(res.strip, "Add Repository Exception", main_stage)
209
+ end
210
+ end
211
+
212
+ end
213
+
214
+ def txtReposUrl_key_released(evt)
215
+
216
+ if evt.code == javafx.scene.input.KeyCode::ENTER
217
+ add_repository(nil)
218
+ evt.consume
219
+ end
220
+
221
+ end
222
+
223
+ def butRepositoryOpen_onAction(evt)
224
+ dc = javafx.stage.DirectoryChooser.new
225
+ dc.title = "Select Local Repository"
226
+ wsDir = dc.showDialog(main_stage)
227
+
228
+ @txtReposUrl.text = wsDir.absolute_path if not_empty?(wsDir)
229
+ end
230
+
231
+ def repos_pull(evt)
232
+ sel = @tblRepos.selection_model.selected_items.to_a
233
+ if sel.length > 0
234
+ selRepos = sel.first
235
+
236
+ repos = selRepos.repos.name
237
+ @selWs.add_repos(selRepos.repos)
238
+ ret, msg = @selWs.pull(repos, @currBr)
239
+ if ret
240
+ set_success_gmsg(msg)
241
+ else
242
+ fx_alert_error(msg, "GVCS Repository Pull Exception", main_stage)
243
+ end
244
+
245
+ else
246
+ fx_alert_error("No repository selected. Please select one repository to pull.", "No Repository Selected", main_stage)
247
+ end
248
+ end
249
+
250
+ def repos_push(evt)
251
+ sel = @tblRepos.selection_model.selected_items.to_a
252
+ if sel.length > 0
253
+
254
+ selRepos = sel.first
255
+ withTag = @chkPushWithTag.isSelected
256
+
257
+ repos = selRepos.repos.name
258
+ @selWs.add_repos(selRepos.repos)
259
+ if withTag
260
+ ret, msg = @selWs.push_changes_with_tags(repos, @currBr)
261
+ else
262
+ ret, msg = @selWs.push_changes(repos, @currBr)
263
+ end
264
+
265
+ if ret
266
+ set_success_gmsg(msg)
267
+ else
268
+ fx_alert_error(msg, "GVCS Repository Push Exception", main_stage)
269
+ end
270
+
271
+ else
272
+ fx_alert_error("No repository selected. Please select one repository to push.", "No Repository Selected", main_stage)
273
+ end
274
+ end
275
+
276
+ end
277
+ end
@@ -0,0 +1,571 @@
1
+ # Copyright (C) 2020 Chris Liaw <chrisliaw@antrapol.com>
2
+ # Author: Chris Liaw <chrisliaw@antrapol.com>
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+
18
+ java_import javafx.scene.control.TableColumn
19
+
20
+ require_relative 'show_text_controller'
21
+
22
+ module GvcsFx
23
+ module TabState
24
+
25
+ ###########
26
+ class VcsElement
27
+ attr_accessor :ctype, :path, :ftype
28
+ def initialize(ctype, path, ftype)
29
+ @ctype = ctype
30
+ @path = path
31
+ @ftype = ftype
32
+ end
33
+ end
34
+ class ModifiedFile < VcsElement
35
+ def initialize(path, ftype)
36
+ super("M",path, ftype)
37
+ end
38
+ end
39
+ class ConflictedFile < VcsElement
40
+ def initialize(path, ftype)
41
+ super("C",path, ftype)
42
+ end
43
+ end
44
+ class NewFile < VcsElement
45
+ def initialize(path, ftype)
46
+ super("N",path, ftype)
47
+ end
48
+ end
49
+ class DeletedFile < VcsElement
50
+ def initialize(path, ftype)
51
+ super("D",path, ftype)
52
+ end
53
+ end
54
+ #############
55
+
56
+ def init_tab_state
57
+ @tblChanges.placeholder = javafx.scene.control.Label.new("Changeset is empty. Please select a workspace or the selected workspace has no changes ")
58
+
59
+ @tblChanges.columns.clear
60
+ @tblChanges.column_resize_policy = javafx.scene.control.TableView::CONSTRAINED_RESIZE_POLICY
61
+
62
+ cols = []
63
+ colState = TableColumn.new("State")
64
+ colState.cell_value_factory = Proc.new do |p|
65
+ SimpleStringProperty.new(p.value.ctype)
66
+ end
67
+ cols << colState
68
+
69
+ colUrl = TableColumn.new("Path")
70
+ colUrl.cell_value_factory = Proc.new do |p|
71
+ SimpleStringProperty.new(p.value.path)
72
+ end
73
+ cols << colUrl
74
+
75
+ @tblChanges.columns.add_all(cols)
76
+
77
+ # set column width
78
+ #colState.pref_width_property.bind(@tblChanges.width_property.multiply(0.1))
79
+ #colState.max_width_property.bind(colState.pref_width_property)
80
+ #colState.resizable = false
81
+ colState.pref_width = 80.0
82
+ colState.max_width = 100.0
83
+ colState.min_width = 60.0
84
+
85
+ @tblChanges.selection_model.selection_mode = javafx.scene.control.SelectionMode::MULTIPLE
86
+
87
+ # mouse event
88
+ @tblChanges.add_event_handler(javafx.scene.input.MouseEvent::MOUSE_CLICKED, Proc.new do |evt|
89
+ if evt.button == javafx.scene.input.MouseButton::SECONDARY
90
+ # right click on item
91
+ changes_ctxmenu.show(@tblChanges, evt.screen_x, evt.screen_y)
92
+ elsif evt.button == javafx.scene.input.MouseButton::PRIMARY and evt.click_count == 2
93
+ # double click on item - diff file
94
+ sel = @tblChanges.selection_model.selected_items
95
+ if sel.length > 0
96
+ sel.each do |s|
97
+ st, res = @selWs.diff_file(s.path)
98
+ if st
99
+
100
+ show_content_win("Diff Output", "Diff Result - #{s.path}", res)
101
+
102
+ else
103
+ set_err_gmsg("Diff for '#{s.path}' failed. [#{res}]")
104
+ end
105
+
106
+ end
107
+ end
108
+
109
+ end
110
+ end) # end mouse event
111
+
112
+ @msgHistory = []
113
+ @cmbCommitMsg.items.clear
114
+ end
115
+
116
+ # hooked to but Commit on action
117
+ def vcs_commit(evt)
118
+ sel = @tblChanges.selection_model.selected_items
119
+ msg = @cmbCommitMsg.value
120
+ if sel.length == 0
121
+ fx_alert_error "Cannot commit on empty changes selection. Please select at least a file from the table above.", "No Files Selected", main_stage
122
+ elsif (msg.nil? or msg.empty?)
123
+ fx_alert_error "Commit message must be present.", "Empty Commit Message", main_stage
124
+ else
125
+ commit_changes(sel, msg)
126
+ if not @msgHistory.include?(msg)
127
+ @cmbCommitMsg.items.add(msg)
128
+ @msgHistory << msg
129
+ end
130
+ refresh_tab_state
131
+ end
132
+ end
133
+
134
+ # hooked to but Refresh on action
135
+ def refresh_vcs_status(evt = nil)
136
+
137
+ if not (@selWs.nil?)
138
+
139
+ mst, mods_dirs, mods_files = @selWs.modified_files
140
+ cst, cflt_dirs, cflt_files = @selWs.conflicted_files
141
+ nst, news_dirs, news_files = @selWs.new_files
142
+ dst, dels_dirs, dels_files = @selWs.deleted_files
143
+
144
+ data = []
145
+ mods_dirs.each do |f|
146
+ data << ModifiedFile.new(f,:dir)
147
+ end
148
+ mods_files.each do |f|
149
+ data << ModifiedFile.new(f,:file)
150
+ end
151
+
152
+ cflt_dirs.each do |f|
153
+ data << ConflictedFile.new(f,:dir)
154
+ end
155
+ cflt_files.each do |f|
156
+ data << ConflictedFile.new(f,:file)
157
+ end
158
+
159
+ news_dirs.each do |f|
160
+ data << NewFile.new(f,:dir)
161
+ end
162
+ news_files.each do |f|
163
+ data << NewFile.new(f,:file)
164
+ end
165
+ dels_dirs.each do |f|
166
+ data << DeletedFile.new(f,:dir)
167
+ end
168
+ dels_files.each do |f|
169
+ data << DeletedFile.new(f,:file)
170
+ end
171
+
172
+ bst, currBranch = @selWs.current_branch
173
+ if bst
174
+ @lblCurrBranch.text = currBranch
175
+ else
176
+ @lblCurrBranch.text = "<Exception while reading branch [#{currBranch}]>"
177
+ end
178
+
179
+
180
+ @tblChanges.items.clear
181
+ @tblChanges.items.add_all(data)
182
+ end
183
+
184
+ end
185
+
186
+ def refresh_tab_state
187
+ refresh_vcs_status(nil)
188
+ @cmbCommitMsg.selection_model.clear_selection
189
+ @cmbCommitMsg.value = nil
190
+ end
191
+
192
+ # hooked to on_key_typed
193
+ def is_cmbCommit_enter(evt)
194
+ if (not evt.nil?) and evt.code == javafx.scene.input.KeyCode::ENTER
195
+ vcs_commit(nil)
196
+ end
197
+ end
198
+
199
+ # hooked to the button "not ready to commit just yet..."
200
+ def stash_changes(evt)
201
+ mst, mods_dirs, mods_files = @selWs.modified_files
202
+ cst, cflt_dirs, cflt_files = @selWs.conflicted_files
203
+ nst, news_dirs, news_files = @selWs.new_files
204
+ dst, dels_dirs, dels_files = @selWs.deleted_files
205
+
206
+ if mods_dirs.length > 0 or mods_files.length > 0 \
207
+ or cflt_dirs.length > 0 or cflt_files.length > 0 \
208
+ or news_dirs.length > 0 or news_files.length > 0 \
209
+ or dels_dirs.length > 0 or dels_files.length > 0
210
+
211
+ msg = []
212
+ msg << "System detected there are existing uncommitted changes in the current workspace:\n"
213
+ msg << "\tModified folder(s) : \t\t#{mods_dirs.length}\n"
214
+ msg << "\tModified file(s) : \t\t#{mods_files.length}\n"
215
+ msg << "\tConflicted folder(s) : \t#{cflt_dirs.length}\n"
216
+ msg << "\tConflicted file(s) : \t\t#{cflt_files.length}\n"
217
+ msg << "\tDeleted folder(s) : \t\t#{dels_dirs.length}\n"
218
+ msg << "\tDeleted file(s) : \t\t#{dels_files.length}\n"
219
+ msg << "\tNew folder(s) : \t\t#{news_dirs.length}\n"
220
+ msg << "\tNew file(s) : \t\t\t#{news_files.length}\n"
221
+
222
+ st, name = fx_alert_input("Temporary Save Changes To Branch",msg.join, "Please give a descriptive name of this temporary changes.\nIt is recommended but not mandatory")
223
+ if st
224
+ # this means user click ok, but the text can still be empty
225
+ sst, res = @selWs.stash_changes(name)
226
+ if sst
227
+ set_info_gmsg(res)
228
+ refresh_vcs_status
229
+ else
230
+ prompt_error("Failed to stash the changes. Error was : #{res}")
231
+ end
232
+ end
233
+
234
+ else
235
+ fx_alert_info("Workspace is clean. No uncommitted changes found")
236
+ end
237
+ end
238
+
239
+ private
240
+ def commit_changes(selected, msg)
241
+ raise_if_empty(selected, "No file given to commit", GvcsFxException)
242
+ raise_if_empty(msg, "No message given to commit", GvcsFxException)
243
+
244
+ @emptyDirCommit = []
245
+ @processed = []
246
+ selected.each do |f|
247
+ begin
248
+ fullPath = File.join(@selWs.path,f.path.strip)
249
+ if File.directory?(fullPath)
250
+ # check if the directory is empty...
251
+ if Dir.entries(fullPath).length == 2
252
+ # empty!
253
+ keepPath = File.join(fullPath,".keep")
254
+ FileUtils.touch keepPath
255
+
256
+ @selWs.add(keepPath)
257
+ @emptyDirCommit << File.join(f.path.strip,".keep")
258
+ else
259
+ @selWs.add(f.path)
260
+ @processed << f.path.strip
261
+ end
262
+ else
263
+ @selWs.add(f.path)
264
+ @processed << f.path.strip
265
+ end
266
+ rescue Exception => ex
267
+ log_error "Error while GVCS add to staging operation:"
268
+ log_error ex.message
269
+ log_error ex.backtrace.join("\n")
270
+ reset_add_commit_error(@processed,@emptyDirCommit)
271
+ end
272
+ end
273
+
274
+ begin
275
+ cst, res = @selWs.commit(msg)
276
+ if cst
277
+ @cmbCommitMsg.items.add(msg)
278
+ else
279
+ reset_add_commit_error(@processed,@emptyDirCommit)
280
+ log_error("Commit failed. Error was : #{res.strip}")
281
+ prompt_error("Error while committing changes. Error was:\n#{res.strip}", "Commit Error", GvcsFxException)
282
+ #set_err_gmsg("Error while committing changes. Error was:\n#{res.strip}")
283
+ end
284
+ rescue Exception => ex
285
+ reset_add_commit_error(@processed,@emptyDirCommit)
286
+ end
287
+ end
288
+
289
+ def reset_add_commit_error(files, emptyFolders = [])
290
+
291
+ if not_empty?(files)
292
+ files.each do |f|
293
+ begin
294
+ @selWs.remove_from_staging(f)
295
+ rescue Exception => ex
296
+ log_error "Exception while removing file from staging. Error was: "
297
+ log_error ex.message
298
+ log_error ex.backtrace[0..5].join("\n")
299
+ end
300
+ end
301
+ end
302
+
303
+ if not_empty?(emptyFolders)
304
+ emptyFolders.each do |f|
305
+ @selWs.remove_from_staging(f)
306
+ # not removing the created .keep file because it is an exception case
307
+ # Exception case doesn't mean the intention to check in the directory is incorrect.
308
+ # the intention to check in still there therefore the .keep file shall remain
309
+ end
310
+ end
311
+
312
+ end # reset_add_commit_error
313
+
314
+ def view_file(path)
315
+
316
+ javafx.application.Platform.run_later do
317
+ stage = javafx.stage.Stage.new
318
+ stage.title = "View Content"
319
+ stage.initModality(javafx.stage.Modality::WINDOW_MODAL)
320
+ #stage.initOwner(main_stage)
321
+ dlg = ShowTextController.load_into(stage)
322
+ dlg.set_title("File Content - #{path}")
323
+ File.open(File.join(@selWs.path,path),"r") do |f|
324
+ @cont = f.read
325
+ end
326
+ dlg.set_content(@cont)
327
+ stage.showAndWait
328
+ end
329
+
330
+ end
331
+
332
+ def changes_ctxmenu
333
+
334
+ @selChanges = @tblChanges.selection_model.selected_items
335
+
336
+
337
+ @changesCtxMenu = javafx.scene.control.ContextMenu.new
338
+
339
+ if @selChanges.length > 0
340
+
341
+ #
342
+ # View file menu item
343
+ #
344
+ diffMnuItm = javafx.scene.control.MenuItem.new("Diff")
345
+ diffMnuItm.on_action do |evt|
346
+
347
+ @selChanges.each do |s|
348
+
349
+ st, res = @selWs.diff_file(s.path)
350
+ if st
351
+ show_content_win("Diff Output", "Diff Result - #{s.path}", res)
352
+ else
353
+ prompt_error("Diff for '#{s.path}' failed. [#{res}]")
354
+ end
355
+
356
+ end
357
+
358
+ end
359
+ @changesCtxMenu.items.add(diffMnuItm)
360
+ #
361
+ # end diff menu item
362
+ #
363
+
364
+ #
365
+ # View file menu item
366
+ #
367
+ vfMnuItm = javafx.scene.control.MenuItem.new("View file")
368
+ vfMnuItm.on_action do |evt|
369
+
370
+ @selChanges.each do |s|
371
+
372
+ fullPath = File.join(@selWs.path,s.path.strip)
373
+ if not File.directory?(fullPath)
374
+ view_file(s.path)
375
+ end
376
+
377
+ end
378
+
379
+ end
380
+ @changesCtxMenu.items.add(vfMnuItm)
381
+ #
382
+ # end diff menu item
383
+ #
384
+
385
+ #
386
+ # Remove from VCS
387
+ #
388
+ @changesCtxMenu.items.add(javafx.scene.control.SeparatorMenuItem.new)
389
+
390
+ rmvVcsMnuItm = javafx.scene.control.MenuItem.new("Remove from VCS")
391
+ rmvVcsMnuItm.on_action do |evt|
392
+
393
+ @selChanges.each do |s|
394
+ @selWs.remove_from_vcs(s.path)
395
+ @selWs.ignore(s.path)
396
+
397
+ set_info_gmsg("File '#{s.path}' removed from VCS")
398
+ end
399
+
400
+ refresh_vcs_status(nil)
401
+
402
+ end
403
+ @changesCtxMenu.items.add(rmvVcsMnuItm)
404
+ #
405
+ # end remove from VCS
406
+ #
407
+
408
+ #delMnuItm = javafx.scene.control.MenuItem.new("Delete physical file")
409
+ #delMnuItm.on_action do |evt|
410
+ # puts "Del physical file"
411
+ #end
412
+ #@changesCtxMenu.items.add(delMnuItm)
413
+
414
+ @changesCtxMenu.items.add(javafx.scene.control.SeparatorMenuItem.new)
415
+
416
+ #
417
+ # Add to ignore list
418
+ #
419
+ ignMnuItm = javafx.scene.control.MenuItem.new("Add to ignore list")
420
+ ignMnuItm.on_action do |evt|
421
+
422
+ igPat = []
423
+ @selChanges.each do |s|
424
+ fullPath = File.join(@selWs.path, s.path)
425
+ if File.directory?(fullPath)
426
+
427
+ res = fx_alert_confirmation("Add folder '#{s.path}' to ignore list?\nAll changes under this folder shall be ignored if done so.", nil, "Confirmation to Ignore Directory", main_stage)
428
+ if res == :ok
429
+ # is the folder already in version control?
430
+ if s.is_a?(NewFile)
431
+ igPat << s.path
432
+ elsif s.is_a?(DeletedFile)
433
+ fx_alert_info("Folder '#{s.path}' is marked deleted but not yet committed.\nFolder shall be put inside ignore rules but shall only reflect after you've committed the changes.")
434
+ igPat << s.path
435
+ elsif s.is_a?(ModifiedFile)
436
+ res = fx_alert_confirmation("Folder being ignored is already tracked under the VCS.\nRemove folder from VCS and put it under ignore rule?", nil, "Confirmation to Ignore Tracked Folder", main_stage)
437
+ if res == :ok
438
+ @selWs.remove_from_vcs(s.path)
439
+ igPat << s.path
440
+ end
441
+ end
442
+
443
+ cnt = igPat.join("\n")
444
+ st, res = @selWs.ignore(cnt)
445
+
446
+ if st
447
+ set_success_gmsg(res)
448
+ refresh_vcs_status(nil)
449
+ else
450
+ set_err_gmsg("Add to ignore list for '#{igPat.join(",")}' failed. [#{res}]")
451
+ end
452
+
453
+ end # res == :0k
454
+
455
+ else
456
+ # is the file already in version control?
457
+ if s.is_a?(NewFile)
458
+ igPat << s.path
459
+ elsif s.is_a?(DeletedFile)
460
+ fx_alert_info("File '#{s.path}' is marked deleted but not yet committed.\nFile shall be put inside ignore rules but shall only reflect after you've committed the changes.")
461
+ igPat << s.path
462
+ elsif s.is_a?(ModifiedFile)
463
+ res = fx_alert_confirmation("File being ignored is already tracked under the VCS.\nRemove file from VCS and put it under ignore rule?", nil, "Confirmation to Ignore Tracked File", main_stage)
464
+ if res == :ok
465
+ @selWs.remove_from_vcs(s.path)
466
+ igPat << s.path
467
+ end
468
+ end
469
+
470
+ cnt = igPat.join("\n")
471
+ st, res = @selWs.ignore(cnt)
472
+
473
+ if st
474
+ set_success_gmsg(res)
475
+ refresh_vcs_status(nil)
476
+ else
477
+ set_err_gmsg("Add to ignore list for '#{igPat.join(",")}' failed. [#{res}]")
478
+ end
479
+
480
+ end
481
+ end
482
+
483
+ #cnt = igPat.join("\n")
484
+ #st, res = @selWs.ignore(cnt)
485
+
486
+ #if st
487
+ # refresh_vcs_status(nil)
488
+ #else
489
+ # set_err_gmsg("Add to ignore list for '#{igPat.join(",")}' failed. [#{res}]")
490
+ #end
491
+
492
+ end
493
+ @changesCtxMenu.items.add(ignMnuItm)
494
+ #
495
+ # end Add to ignore list
496
+ #
497
+
498
+ #
499
+ # Add extension to ignore list
500
+ #
501
+ ignExtMnuItm = javafx.scene.control.MenuItem.new("Add extension to ignore list")
502
+ ignExtMnuItm.on_action do |evt|
503
+
504
+ igPat = []
505
+ @selChanges.each do |s|
506
+ fullPath = File.join(@selWs.path, s.path)
507
+ if File.directory?(fullPath)
508
+ fx_alert_warning("Given file '#{s.path}' to add extension to ignore list is a folder.\nPlease use 'Add to ignore list' option if indeed that is the intention.","Folder has no extension",main_stage)
509
+ else
510
+ igPat << "*#{File.extname(s.path)}"
511
+ end
512
+ end
513
+
514
+ cnt = igPat.join("\n")
515
+ st, res = @selWs.ignore(cnt)
516
+
517
+ if st
518
+ refresh_vcs_status(nil)
519
+ else
520
+ set_err_gmsg("Add extension '#{igPat.join(",")}' to ignore list failed. [#{res}]")
521
+ end
522
+
523
+ end
524
+ @changesCtxMenu.items.add(ignExtMnuItm)
525
+ #
526
+ # end Add extension to ignore list
527
+ #
528
+
529
+ @changesCtxMenu.items.add(javafx.scene.control.SeparatorMenuItem.new)
530
+
531
+ #
532
+ # Revert changes
533
+ #
534
+ revertExtMnuItm = javafx.scene.control.MenuItem.new("Revert Changes")
535
+ revertExtMnuItm.on_action do |evt|
536
+
537
+ igPat = []
538
+ @selChanges.each do |s|
539
+ res = fx_alert_confirmation("Revert '#{s.path}' to version from last commit?\nAll changes made to the fill will be discarded!.", nil, "Confirmation to Revert Changes", main_stage)
540
+ if res == :ok
541
+ igPat << s.path
542
+ end
543
+
544
+ end
545
+
546
+ cnt = igPat.join("\n")
547
+ st, res = @selWs.reset_file_changes(cnt)
548
+
549
+ if st
550
+ set_info_gmsg(res)
551
+ refresh_vcs_status(nil)
552
+ else
553
+ set_err_gmsg("Add extension '#{igPat.join(",")}' to ignore list failed. [#{res}]")
554
+ end
555
+
556
+ end
557
+ @changesCtxMenu.items.add(revertExtMnuItm)
558
+ #
559
+ # end Add extension to ignore list
560
+ #
561
+
562
+
563
+ end
564
+
565
+
566
+ @changesCtxMenu
567
+
568
+ end
569
+
570
+ end
571
+ end