kgem 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/kgem.rb ADDED
@@ -0,0 +1,327 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # 2010 by ruby.twiddler@gmail.com
4
+ #
5
+ # Ruby Gem with KDE GUI
6
+ #
7
+
8
+ $KCODE = 'UTF8'
9
+ require 'ftools'
10
+
11
+ APP_FILE = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
12
+ APP_NAME = File.basename(APP_FILE).sub(/\.rb/, '')
13
+ APP_DIR = File::dirname(File.expand_path(File.dirname(APP_FILE)))
14
+ LIB_DIR = File::join(APP_DIR, "lib")
15
+ APP_VERSION = "0.1.0"
16
+
17
+
18
+ # standard libs
19
+ require 'fileutils'
20
+ require 'rubygems'
21
+ require 'rubygems/specification'
22
+ require 'json'
23
+ require 'uri'
24
+ require 'net/http'
25
+ require 'shellwords'
26
+
27
+ # additional libs
28
+ require 'korundum4'
29
+ require 'ktexteditor'
30
+
31
+ #
32
+ # my libraries and programs
33
+ #
34
+ $:.unshift(LIB_DIR)
35
+ require "mylibs"
36
+ require "settings"
37
+ require "gemitem"
38
+ require "installedwin"
39
+ require "searchwin"
40
+ require "downloadedwin"
41
+ require "previewwin"
42
+ require "gemcmddlgs"
43
+ require "gemviews"
44
+ require "gemhelpdlg"
45
+
46
+ #--------------------------------------------------------------------
47
+ #--------------------------------------------------------------------
48
+ #
49
+ #
50
+ #
51
+ class MainWindow < KDE::MainWindow
52
+ def initialize
53
+ super(nil)
54
+ setCaption(APP_NAME)
55
+
56
+ @actions = KDE::ActionCollection.new(self)
57
+ createWidgets
58
+ createMenu
59
+ createDlg
60
+ @actions.readSettings
61
+ setAutoSaveSettings
62
+ end
63
+
64
+
65
+ def createMenu
66
+ # file menu
67
+ quitAction = @actions.addNew('Quit', self, \
68
+ { :icon => 'exit', :shortCut => 'Ctrl+Q', :triggered => :close })
69
+ fileMenu = KDE::Menu.new(i18n('&File'), self)
70
+ fileMenu.addAction(quitAction)
71
+
72
+ # tool menu
73
+ updateSystemAction = @actions.addNew('Update Gem System', self, \
74
+ { :icon => 'checkbox', :shortCut => 'F4', \
75
+ :triggered => [@gemViewer, :updateSystem ] })
76
+ checkStaleAction = @actions.addNew('Check Stale', self, \
77
+ { :icon => 'checkbox', :shortCut => 'F7', \
78
+ :triggered => [@gemViewer, :checkStale] })
79
+ checkAlienAction = @actions.addNew('Check Alien', self, \
80
+ { :icon => 'checkbox', :shortCut => 'F8', \
81
+ :triggered => [@gemViewer, :checkAlien] })
82
+ cleanUpAction = @actions.addNew('Clean Up', self, \
83
+ { :icon => 'edit-clear', :shortCut => 'F9', \
84
+ :triggered => [@gemViewer, :cleanUp] })
85
+ updateAllAction = @actions.addNew('Update All', self, \
86
+ { :icon => 'checkbox', :shortCut => 'F10', \
87
+ :triggered => [@gemViewer, :updateAll] })
88
+ pristineAllAction = @actions.addNew('Pristine All', self, \
89
+ { :icon => 'checkbox', :shortCut => 'F11', \
90
+ :triggered => [@gemViewer, :pristineAll] })
91
+
92
+ toolsMenu = KDE::Menu.new(i18n('&Tools'), self)
93
+ toolsMenu.addAction(updateSystemAction)
94
+ toolsMenu.addSeparator
95
+ toolsMenu.addAction(checkStaleAction)
96
+ toolsMenu.addAction(checkAlienAction)
97
+ toolsMenu.addSeparator
98
+ toolsMenu.addAction(cleanUpAction)
99
+ toolsMenu.addAction(updateAllAction)
100
+ toolsMenu.addAction(pristineAllAction)
101
+
102
+
103
+ # settings menu
104
+ configureShortCutAction = @actions.addNew(i18n('Configure Shortcuts'), self, \
105
+ { :icon => 'configure-shortcuts', :shortCut => 'F3', :triggered => :configureShortCut })
106
+ configureAppAction = @actions.addNew(i18n('Configure Kgem'), self, \
107
+ { :icon => 'configure', :shortCut => 'F2', :triggered => :configureApp })
108
+ detailWinAction = @detailWin.toggleViewAction
109
+ fileListWinAction = @fileListWin.toggleViewAction
110
+ termilanWinAction = @terminalWin.toggleViewAction
111
+
112
+ settingsMenu = KDE::Menu.new(i18n('&Settings'), self)
113
+ settingsMenu.addAction(detailWinAction)
114
+ settingsMenu.addAction(fileListWinAction)
115
+ settingsMenu.addAction(termilanWinAction)
116
+ settingsMenu.addSeparator
117
+ settingsMenu.addAction(configureShortCutAction)
118
+ settingsMenu.addAction(configureAppAction)
119
+
120
+
121
+ # Help menu
122
+ aboutDlg = KDE::AboutApplicationDialog.new($about)
123
+ gemHelpAction = @actions.addNew(i18n('Gem Command Line Help'), self, \
124
+ { :icon => 'help-about', :shortCut => 'F1', :triggered => :gemCommandHelp })
125
+ openAboutAction = @actions.addNew(i18n('About kgem'), self, \
126
+ { :icon => 'help-about', :triggered => [ aboutDlg, :exec ] })
127
+ openDocUrlAction = @actions.addNew(i18n('Open Document Wiki'), self, \
128
+ { :icon => 'help-contents', :triggered => :openDocUrl })
129
+ openReportIssueUrlAction = @actions.addNew(i18n('Report Bug'), self, \
130
+ { :icon => 'tools-report-bug', :triggered => :openReportIssueUrl })
131
+ openSourceAction = @actions.addNew(i18n('Open Source Folder'), self, \
132
+ { :icon => 'document-open-folder', :triggered => :openSource })
133
+ openRdocAction = @actions.addNew(i18n('Open Rdoc'), self, \
134
+ { :icon => 'help-contents', :triggered => :openRdoc })
135
+ envAction = @actions.addNew(i18n('Check Gem Environment'), self, \
136
+ { :triggered => :checkEnv })
137
+
138
+ helpMenu = KDE::Menu.new(i18n('&Help'), self)
139
+ helpMenu.addAction(openDocUrlAction)
140
+ helpMenu.addAction(openReportIssueUrlAction)
141
+ helpMenu.addAction(openRdocAction)
142
+ helpMenu.addAction(openSourceAction)
143
+ helpMenu.addAction(envAction)
144
+ helpMenu.addAction(gemHelpAction)
145
+ helpMenu.addSeparator
146
+ helpMenu.addAction(openAboutAction)
147
+
148
+
149
+ # insert menus in MenuBar
150
+ menu = KDE::MenuBar.new
151
+ menu.addMenu( fileMenu )
152
+ menu.addMenu( toolsMenu )
153
+ menu.addMenu( settingsMenu )
154
+ menu.addMenu( helpMenu )
155
+ setMenuBar(menu)
156
+ end
157
+
158
+
159
+
160
+ def createWidgets
161
+ # dockable window
162
+ @detailWin = DetailWin.new(self)
163
+ addDockWidget(Qt::BottomDockWidgetArea, @detailWin)
164
+ @fileListWin = FileListWin.new(self)
165
+ tabifyDockWidget(@detailWin, @fileListWin)
166
+ @terminalWin = TerminalWin.new(self)
167
+ tabifyDockWidget(@fileListWin, @terminalWin)
168
+
169
+ @previewWin = PreviewWin.new
170
+ @gemEnvDlg = GemEnvDlg.new
171
+
172
+ # tab windows
173
+ @gemViewer = DockGemViewer.new(self, @detailWin, @fileListWin, @terminalWin, @previewWin)
174
+ @installedGemWin = InstalledGemWin.new(self) do |w|
175
+ w.gemViewer = @gemViewer
176
+ @gemViewer.addInstallWatcher(w)
177
+ @gemViewer.setInstallWin(w)
178
+ end
179
+ @searchWin = SearchWin.new(self) do |w|
180
+ w.gemViewer = @gemViewer
181
+ end
182
+ @downloadedWin = DownloadedWin.new(self) do |w|
183
+ w.gemViewer = @gemViewer
184
+ @gemViewer.addInstallWatcher(w)
185
+ @gemViewer.addDownloadWatcher(w)
186
+ end
187
+
188
+
189
+ # layout
190
+ @mainTab = KDE::TabWidget.new
191
+ @mainTab.tabBar.movable = true
192
+ @mainTab.addTab(@searchWin, i18n("Search"))
193
+ @mainTab.addTab(@installedGemWin, i18n('Installed Gems'))
194
+ @mainTab.addTab(@downloadedWin, i18n("Downloaded Gems"))
195
+
196
+ setCentralWidget(@mainTab)
197
+ end
198
+
199
+ def createDlg
200
+ @settingsDlg = SettingsDlg.new(self)
201
+ @gemHelpdlg = GemHelpDlg.new(self)
202
+ end
203
+
204
+
205
+
206
+ #------------------------------------
207
+ #
208
+ # virtual slot
209
+ def closeEvent(ev)
210
+ @actions.writeSettings
211
+ @searchWin.writeSettings
212
+ @installedGemWin.writeSettings
213
+ @downloadedWin.writeSettings
214
+ @gemHelpdlg.closeEvent(ev)
215
+ @previewWin.writeSettings
216
+ super(ev)
217
+ $config.sync # important! qtruby can't invoke destructor properly.
218
+ end
219
+
220
+
221
+ #------------------------------------
222
+ #
223
+ #
224
+ slots :openDocUrl
225
+ def openDocUrl
226
+ openUrlDocument('http://github.com/rubytwiddler/kgem/wiki')
227
+ end
228
+
229
+ slots :openReportIssueUrl
230
+ def openReportIssueUrl
231
+ openUrlDocument('http://github.com/rubytwiddler/kgem/issues')
232
+ end
233
+
234
+ slots :openSource
235
+ def openSource
236
+ openDirectory(APP_DIR)
237
+ end
238
+
239
+ slots :openRdoc
240
+ def openRdoc
241
+ @gemViewer.viewGemRdoc(GemItem::getGemfromPath(APP_NAME))
242
+ end
243
+
244
+ slots :checkEnv
245
+ def checkEnv
246
+ @gemEnvDlg.displayEnv
247
+ end
248
+
249
+ def openUrlDocument(url)
250
+ cmd= Mime::services('.html').first.exec
251
+ cmd.gsub!(/%\w+/, url)
252
+ fork do exec(cmd) end
253
+ end
254
+
255
+ slots :configureShortCut
256
+ def configureShortCut
257
+ KDE::ShortcutsDialog.configure(@actions)
258
+ end
259
+
260
+ slots :configureApp
261
+ def configureApp
262
+ Settings.updateWidgets(@settingsDlg)
263
+ @settingsDlg.exec == Qt::Dialog::Accepted
264
+ end
265
+
266
+ slots :gemCommandHelp
267
+ def gemCommandHelp
268
+ @gemHelpdlg.show
269
+ end
270
+ end
271
+
272
+
273
+ #------------------------------------------------------------
274
+ #
275
+ #
276
+ class GemEnvDlg < Qt::Dialog
277
+ def initialize(parent=nil)
278
+ super(parent)
279
+ createWidget
280
+ end
281
+
282
+ def createWidget
283
+ @textEdit = Qt::TextEdit.new
284
+ @textEdit.readOnly = true
285
+ @closeBtn = KDE::PushButton.new(KDE::Icon.new('dialog-close'), i18n('Close'))
286
+ connect(@closeBtn, SIGNAL(:clicked), self, SLOT(:accept))
287
+
288
+ # layout
289
+ lo = Qt::VBoxLayout.new do |l|
290
+ l.addWidget(@textEdit)
291
+ l.addWidgets(nil, @closeBtn)
292
+ end
293
+ setLayout(lo)
294
+ end
295
+
296
+ def writeEnvData
297
+ @textEdit.setPlainText( %x{ gem env } )
298
+ resize(460,440)
299
+ @wroteEnv = true
300
+ end
301
+
302
+ def displayEnv
303
+ writeEnvData unless @wroteEnv
304
+ exec
305
+ end
306
+ end
307
+
308
+
309
+ #------------------------------------------------------------------------------
310
+ #
311
+ # main start
312
+ #
313
+
314
+ $about = KDE::AboutData.new(APP_NAME, nil, KDE::ki18n(APP_NAME), APP_VERSION,
315
+ KDE::ki18n('Gem Utitlity with KDE GUI.')
316
+ )
317
+ $about.addLicenseTextFile(APP_DIR + '/MIT-LICENSE')
318
+ KDE::CmdLineArgs.init(ARGV, $about)
319
+
320
+ $app = KDE::Application.new
321
+ args = KDE::CmdLineArgs.parsedArgs()
322
+ $config = KDE::Global::config
323
+ win = MainWindow.new
324
+ $app.setTopWidget(win)
325
+
326
+ win.show
327
+ $app.exec
data/ext/Rakefile ADDED
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'ftools'
4
+
5
+ APP_DIR = File::dirname(File.expand_path(File.dirname(__FILE__)))
6
+ RES_DIR = File::join(APP_DIR, "pkg_resources")
7
+
8
+ def install_console_helper(console_helper_name, target_cmd_name)
9
+ etc_dir = ENV['sysconf_dir'] || ENV['etc_dir'] || '/etc'
10
+
11
+ console_helper_link = File.join(APP_DIR, 'bin', console_helper_name)
12
+ cmd_path = File.join(APP_DIR, 'bin', target_cmd_name)
13
+ pam_src_path = File.join( RES_DIR, console_helper_name + '.pam' )
14
+ pam_dst_path = File.join(etc_dir, 'pam.d', console_helper_name)
15
+ console_app_file = File.join(etc_dir, 'security', 'console.apps', console_helper_name)
16
+ console_helper_target = %x{ which consolehelper }.strip!
17
+
18
+ puts "cp #{pam_src_path} #{pam_dst_path}"
19
+ puts "ln -s #{console_helper_target} #{console_helper_link}"
20
+ puts "write #{console_app_file}"
21
+
22
+ File.cp(pam_src_path, pam_dst_path)
23
+ if File.exist?(console_helper_link) then
24
+ File.unlink(console_helper_link)
25
+ end
26
+ File.symlink(console_helper_target, console_helper_link)
27
+
28
+ open(console_app_file, 'w') do |f|
29
+ f.write(<<-EOF
30
+ USER=root
31
+ PROGRAM=#{cmd_path}
32
+ FALLBACK=false
33
+ SESSION=true
34
+ EOF
35
+ )
36
+ end
37
+ end
38
+
39
+ desc "Install consolehelper files."
40
+ task :install_consolehelper do
41
+ install_console_helper('gemcmdwin-super.rb', 'gemcmdwin.rb')
42
+ end
43
+
44
+ desc "Install Application Menu"
45
+ task :install_menu do
46
+ menuDir = %x{ kde4-config --install xdgdata-apps }.strip
47
+ menuEntryFile = File.join(menuDir, 'kgem.desktop')
48
+ open(menuEntryFile,'w') do |f|
49
+ f.write(<<-EOF
50
+ [Desktop Entry]
51
+ Name=Kgem
52
+ Comment=Ruby Gem Tool with KDE GUI
53
+ Exec=kgem %f
54
+ Icon=kgem
55
+ Terminal=false
56
+ Type=Application
57
+ Categories=Qt;KDE;Utility;
58
+ MimeType=application/x-gem;
59
+ EOF
60
+ )
61
+ %x{ update-menus }
62
+ end
63
+ end
64
+
65
+ task :default => [ :install_consolehelper, :install_menu ]
@@ -0,0 +1,251 @@
1
+ class FetchedGem
2
+ attr_accessor :fileName, :directory, :installed
3
+
4
+ def filePath
5
+ File.join(@directory, @fileName)
6
+ end
7
+
8
+ def installed_str
9
+ @installed ? 'installed' : ''
10
+ end
11
+ end
12
+
13
+ #
14
+ #
15
+ #
16
+ class DownloadedTable < Qt::TableWidget
17
+ #
18
+ class Item < Qt::TableWidgetItem
19
+ def initialize(text)
20
+ super(text)
21
+ self.flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled
22
+ end
23
+ end
24
+
25
+ def initialize
26
+ super(0,3)
27
+
28
+ self.windowTitle = i18n('Search Result')
29
+ setHorizontalHeaderLabels(['file name', 'directory', 'installed'])
30
+ self.horizontalHeader.stretchLastSection = true
31
+ self.selectionBehavior = Qt::AbstractItemView::SelectRows
32
+ self.selectionMode = Qt::AbstractItemView::SingleSelection
33
+ self.alternatingRowColors = true
34
+ self.sortingEnabled = true
35
+ sortByColumn(0, Qt::AscendingOrder)
36
+ @fetchedGems = {}
37
+ end
38
+
39
+ def addPackage(row, fetchedGem)
40
+ nameItem = Item.new(fetchedGem.fileName)
41
+ @fetchedGems[nameItem] = fetchedGem # 0 column item is hash key.
42
+ setItem( row, 0, nameItem )
43
+ setItem( row, 1, Item.new(fetchedGem.directory) )
44
+ setItem( row, 2, Item.new(fetchedGem.installed_str) )
45
+ end
46
+
47
+ def updateGemList(gemList)
48
+ sortFlag = self.sortingEnabled
49
+ self.sortingEnabled = false
50
+
51
+ clearContents
52
+ self.rowCount = gemList.length
53
+ gemList.each_with_index do |g,r|
54
+ addPackage(r, g)
55
+ end
56
+
57
+ self.sortingEnabled = sortFlag
58
+ end
59
+
60
+ def gem(item)
61
+ gemAtRow(item.row)
62
+ end
63
+
64
+ def gemAtRow(row)
65
+ @fetchedGems[item(row,0)] # use 0 column item as hash key.
66
+ end
67
+
68
+ def currentGem
69
+ gemAtRow(currentRow)
70
+ end
71
+
72
+ def showall
73
+ rowCount.times do |r|
74
+ showRow(r)
75
+ end
76
+ end
77
+
78
+ slots 'filterChanged(const QString &)'
79
+ def filterChanged(text)
80
+ unless text && !text.empty?
81
+ showall
82
+ return
83
+ end
84
+
85
+ regxs = /#{Regexp.escape(text.strip)}/i
86
+ rowCount.times do |r|
87
+ txt = item(r,0).text.gsub(/\.gem$/, '')
88
+ if regxs =~ txt then
89
+ showRow(r)
90
+ else
91
+ hideRow(r)
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+
98
+ #----------------------------------------------------------------------------
99
+ #
100
+ #
101
+ #
102
+ class DownloadedWin < Qt::Widget
103
+ def initialize(parent=nil)
104
+ super(parent)
105
+
106
+ createWidget
107
+ readSettings
108
+
109
+ Qt::Timer.singleShot(0, self, SLOT(:updateList))
110
+ end
111
+
112
+ GemDirs = %x{ gem environment gempath }.split(/:/).map! do |dir|
113
+ File.join(dir.strip, 'cache')
114
+ end
115
+
116
+ def createWidget
117
+ @gemFileList = DownloadedTable.new
118
+ @filterLine = KDE::LineEdit.new do |w|
119
+ connect(w,SIGNAL('textChanged(const QString &)'),
120
+ @gemFileList, SLOT('filterChanged(const QString &)'))
121
+ w.setClearButtonShown(true)
122
+ end
123
+
124
+ @installBtn = KDE::PushButton.new(KDE::Icon.new('run-build-install'), 'Install')
125
+ @deleteBtn = KDE::PushButton.new(KDE::Icon.new('edit-delete'), 'Delete')
126
+ @unpackBtn = KDE::PushButton.new('Unpack')
127
+
128
+ #
129
+ connect(@gemFileList, SIGNAL('itemClicked(QTableWidgetItem *)'), self, SLOT('itemClicked(QTableWidgetItem *)'))
130
+ connect(@installBtn, SIGNAL(:clicked), self, SLOT(:install))
131
+ connect(@deleteBtn, SIGNAL(:clicked), self, SLOT(:delete))
132
+ connect(@unpackBtn, SIGNAL(:clicked), self, SLOT(:unpack))
133
+
134
+ # layout
135
+ lo = Qt::VBoxLayout.new
136
+ lo.addWidgets('Filter:', @filterLine)
137
+ lo.addWidget(@gemFileList)
138
+ lo.addWidgets(nil, @installBtn, @unpackBtn, @deleteBtn)
139
+ setLayout(lo)
140
+ end
141
+
142
+ GroupName = "DownloadedGemWindow"
143
+ def writeSettings
144
+ config = $config.group(GroupName)
145
+ config.writeEntry('Header', @gemFileList.horizontalHeader.saveState)
146
+ end
147
+
148
+ def readSettings
149
+ config = $config.group(GroupName)
150
+ @gemFileList.horizontalHeader.restoreState(config.readEntry('Header', @gemFileList.horizontalHeader.saveState))
151
+ end
152
+
153
+
154
+ slots :updateList
155
+ def updateList
156
+ def allFilesInDir(dir)
157
+ exDir = File.expand_path(dir)
158
+ return [] unless File.directory?(exDir)
159
+ Dir.chdir(exDir)
160
+ files = Dir['*.gem']
161
+ gems = files.map do |f|
162
+ fGem = FetchedGem.new
163
+ fGem.fileName = f
164
+ fGem.directory = exDir
165
+ fGem.installed = InstalledGemList.checkVersionGemInstalled(f)
166
+ fGem
167
+ end
168
+ end
169
+
170
+ dirs = GemDirs + [ Settings.autoFetchDir.pathOrUrl ]
171
+ gems = dirs.uniq.inject([]) do |res, dir|
172
+ res + allFilesInDir(dir)
173
+ end
174
+
175
+ #
176
+ @gemFileList.updateGemList(gems)
177
+
178
+ @filterLine.text = ''
179
+ end
180
+
181
+ def notifyDownload
182
+ updateList
183
+ end
184
+
185
+ def notifyInstall
186
+ updateList
187
+ end
188
+
189
+ attr_accessor :gemViewer
190
+ slots 'itemClicked(QTableWidgetItem *)'
191
+ def itemClicked(item)
192
+ fetchedGem = @gemFileList.gem(item)
193
+ return unless fetchedGem
194
+ filePath = fetchedGem.filePath
195
+ return unless File.exist?(filePath)
196
+
197
+ @installBtn.enabled = @deleteBtn.enabled = ! fetchedGem.installed
198
+ files = %x{ tar xvf #{filePath} data.tar.gz -O | gunzip -c | tar t }.split(/\n/)
199
+ files.unshift
200
+ @gemViewer.setFiles(files)
201
+ gem = GemItem::getGemfromPath(filePath)
202
+ @gemViewer.setDetail(gem)
203
+
204
+ proc = lambda do |item|
205
+ file = item.text
206
+ @gemViewer.previewWin.setText( file, %x{ tar xvf #{filePath.shellescape} data.tar.gz -O | gunzip -c | tar x #{file.shellescape} -O } )
207
+ end
208
+ @gemViewer.setPreviewProc(proc)
209
+ end
210
+
211
+ slots :install
212
+ def install
213
+ fetchedGem = @gemFileList.currentGem
214
+ return unless fetchedGem and !fetchedGem.installed
215
+
216
+ filePath = fetchedGem.filePath
217
+ gem = GemItem::getGemfromPath(filePath)
218
+ gem.addLocalPath(filePath)
219
+ @gemViewer.install(gem, true) # localFlag = true
220
+ end
221
+
222
+ slots :delete
223
+ def delete
224
+ fetchedGem = @gemFileList.currentGem
225
+ return unless fetchedGem and !(GemDirs.include?(fetchedGem.directory) \
226
+ and fetchedGem.installed)
227
+
228
+ filePath = fetchedGem.filePath
229
+ if File.writable?(filePath) then
230
+ File.unlink(filePath)
231
+ passiveMessage(i18n('Deleted ') + filePath)
232
+ updateList
233
+ end
234
+ end
235
+
236
+ slots :unpack
237
+ def unpack
238
+ fetchedGem = @gemFileList.currentGem
239
+ fileName = fetchedGem.filePath
240
+ if Settings.autoUnpackFlag then
241
+ dir = Settings.autoUnpackDir.pathOrUrl
242
+ else
243
+ dir = KDE::FileDialog::getExistingDirectory(Settings.autoUnpackDir)
244
+ return unless dir
245
+ Settings.autoUnpackDir.setUrl(dir)
246
+ end
247
+ puts %Q{ execute: gem unpack #{fileName} --target=#{dir.shellescape} }
248
+ %x{ gem unpack #{fileName} --target=#{dir.shellescape} }
249
+ end
250
+
251
+ end