gvcsfx 0.3

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.
@@ -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