kgem 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,286 @@
1
+ #
2
+ #
3
+ #
4
+
5
+ class StaleGemItem
6
+ attr_reader :name, :version, :atime
7
+ def initialize(name, ver, atime)
8
+ @name = name
9
+ @version = ver
10
+ @atime = atime
11
+ end
12
+ end
13
+
14
+
15
+ #-----------------------------------------------
16
+ #
17
+ #
18
+ class GemListTable < Qt::TableWidget
19
+ #
20
+ #
21
+ class Item < Qt::TableWidgetItem
22
+ def initialize(text)
23
+ super(text)
24
+ self.flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled
25
+ end
26
+
27
+ def gem
28
+ tableWidget.gem(self)
29
+ end
30
+ end
31
+
32
+
33
+ # column no
34
+ PACKAGE_NAME = 0
35
+ PACKAGE_VERSION = 1
36
+ PACKAGE_SUMMARY = 2
37
+ PACKAGE_ATIME = 3
38
+
39
+ def initialize(title)
40
+ super(0,4)
41
+
42
+ self.windowTitle = title
43
+ setHorizontalHeaderLabels(['package', 'version', 'summary', 'last access'])
44
+ self.horizontalHeader.stretchLastSection = true
45
+ self.selectionBehavior = Qt::AbstractItemView::SelectRows
46
+ self.selectionMode = Qt::AbstractItemView::SingleSelection
47
+ self.alternatingRowColors = true
48
+ self.sortingEnabled = true
49
+ sortByColumn(PACKAGE_NAME, Qt::AscendingOrder )
50
+ @gems = {}
51
+ end
52
+
53
+ # caution ! : befor call, sortingEnabled must be set false.
54
+ # if sortingEnabled is on while updating table, it is very sluggish.
55
+ def addPackage(row, gem)
56
+ # self.sortingEnabled = false
57
+ nameItem = Item.new(gem.package)
58
+ @gems[nameItem] = gem # 0 column item is hash key.
59
+ setItem( row, PACKAGE_NAME, nameItem )
60
+ setItem( row, PACKAGE_VERSION, Item.new(gem.version) )
61
+ setItem( row, PACKAGE_SUMMARY, Item.new(gem.summary) )
62
+ setItem( row, PACKAGE_ATIME, Item.new('') )
63
+ end
64
+
65
+
66
+ def updateGemList(gemList)
67
+ sortFlag = self.sortingEnabled
68
+ self.sortingEnabled = false
69
+
70
+ clearContents
71
+ self.rowCount = gemList.length
72
+ gemList.each_with_index do |g, r|
73
+ addPackage(r, g)
74
+ end
75
+
76
+ self.sortingEnabled = sortFlag
77
+ end
78
+
79
+
80
+ def gem(item)
81
+ gemAtRow(item.row)
82
+ end
83
+
84
+ def gemAtRow(row)
85
+ @gems[item(row,0)] # use 0 column item as hash key.
86
+ end
87
+
88
+ def currentGem
89
+ gemAtRow(currentRow)
90
+ end
91
+
92
+ def showall
93
+ rowCount.times do |r|
94
+ showRow(r)
95
+ end
96
+ end
97
+
98
+
99
+ slots 'filterChanged(const QString &)'
100
+ def filterChanged(text)
101
+ unless text && !text.empty?
102
+ showall
103
+ return
104
+ end
105
+
106
+ regxs = /#{Regexp.escape(text.strip)}/i
107
+ rowCount.times do |r|
108
+ gem = gemAtRow(r)
109
+ txt = [ gem.package, gem.summary, gem.author, gem.platform ].inject("") do |s, t|
110
+ t.nil? ? s : s + t.to_s
111
+ end
112
+ if regxs =~ txt then
113
+ showRow(r)
114
+ else
115
+ hideRow(r)
116
+ end
117
+ end
118
+ end
119
+
120
+ # @return : number : row of found item.
121
+ def find
122
+ rowCount.times do |r|
123
+ i = gemAtRow(r)
124
+ return r if yield i
125
+ end
126
+ false
127
+ end
128
+ end
129
+
130
+
131
+
132
+ #--------------------------------------------------------------------
133
+ #
134
+ #
135
+ class InstalledGemWin < Qt::Widget
136
+ def initialize(parent=nil)
137
+ super(parent)
138
+
139
+ createWidget
140
+ readSettings
141
+
142
+ Qt::Timer.singleShot(0, self, SLOT(:updateInstalledGemList))
143
+ end
144
+
145
+ def createWidget
146
+ @installedGemsTable = GemListTable.new('installed')
147
+
148
+ @viewDirBtn = KDE::PushButton.new(KDE::Icon.new('folder'), 'View Directory')
149
+ @viewRdocBtn = KDE::PushButton.new(KDE::Icon.new('help-contents'), 'View RDoc')
150
+ @generateRdocBtn = KDE::PushButton.new(KDE::Icon.new('document-new'), 'Generate RDoc/ri')
151
+ @updateGemBtn = KDE::PushButton.new(KDE::Icon.new('view-refresh'), 'Update')
152
+
153
+ @uninstallBtn = KDE::PushButton.new(KDE::Icon.new('list-remove'), 'Uninstall')
154
+
155
+ @filterInstalledLineEdit = KDE::LineEdit.new do |w|
156
+ connect(w,SIGNAL('textChanged(const QString &)'),
157
+ @installedGemsTable, SLOT('filterChanged(const QString &)'))
158
+ w.setClearButtonShown(true)
159
+ end
160
+ @checkTestBtn = KDE::PushButton.new(KDE::Icon.new('checkbox'), 'Test')
161
+
162
+
163
+ # connect
164
+ connect(@viewDirBtn, SIGNAL(:clicked), self, SLOT(:viewDir))
165
+ connect(@viewRdocBtn, SIGNAL(:clicked), self, SLOT(:viewRdoc))
166
+ connect(@uninstallBtn, SIGNAL(:clicked), self, SLOT(:uninstallGem))
167
+ connect(@installedGemsTable, SIGNAL('itemClicked(QTableWidgetItem *)'),
168
+ self, SLOT('itemClicked(QTableWidgetItem *)'))
169
+ connect(@generateRdocBtn, SIGNAL(:clicked), self, SLOT(:generateRdoc))
170
+ connect(@updateGemBtn, SIGNAL(:clicked), self, SLOT(:updateGem))
171
+ connect(@checkTestBtn, SIGNAL(:clicked), self, SLOT(:testGem))
172
+
173
+ # layout
174
+ lo = Qt::VBoxLayout.new do |w|
175
+ w.addWidgets('Filter:', @filterInstalledLineEdit)
176
+ w.addWidget(@installedGemsTable)
177
+ w.addWidgets(nil, @viewDirBtn, @viewRdocBtn, @generateRdocBtn, @checkTestBtn, @updateGemBtn, @uninstallBtn)
178
+ end
179
+ setLayout(lo)
180
+ end
181
+
182
+
183
+ GroupName = "InstalledGemWindow"
184
+ def writeSettings
185
+ config = $config.group(GroupName)
186
+ config.writeEntry('Header', @installedGemsTable.horizontalHeader.saveState)
187
+ end
188
+
189
+ def readSettings
190
+ config = $config.group(GroupName)
191
+ @installedGemsTable.horizontalHeader.restoreState(config.readEntry('Header', @installedGemsTable.horizontalHeader.saveState))
192
+ end
193
+
194
+
195
+ #------------------------------------
196
+ #
197
+ #
198
+ def notifyInstall
199
+ updateInstalledGemList
200
+ end
201
+
202
+ slots :testGem
203
+ def testGem
204
+ gem = @installedGemsTable.currentGem
205
+ return unless gem
206
+
207
+ @gemViewer.testGem(gem)
208
+ end
209
+
210
+ slots :updateGem
211
+ def updateGem
212
+ gem = @installedGemsTable.currentGem
213
+ return unless gem
214
+
215
+ @gemViewer.updateGem(gem)
216
+ end
217
+
218
+ slots :generateRdoc
219
+ def generateRdoc
220
+ gem = @installedGemsTable.currentGem
221
+ return unless gem
222
+
223
+ @gemViewer.generateRdoc(gem)
224
+ end
225
+
226
+ slots :updateInstalledGemList
227
+ def updateInstalledGemList
228
+ gemList = InstalledGemList.get
229
+ @installedGemsTable.updateGemList(gemList)
230
+ end
231
+
232
+ def setStaleTime(stales)
233
+ stales.each do |i|
234
+ r = @installedGemsTable.find do |g|
235
+ g.name == i.name && g.version == i.version
236
+ end
237
+ if r then
238
+ @installedGemsTable.item(r, GemListTable::PACKAGE_ATIME).text = i.atime.to_s
239
+ end
240
+ end
241
+ @installedGemsTable.sortItems(GemListTable::PACKAGE_ATIME)
242
+ @installedGemsTable.clearSelection
243
+ parent.parent.currentIndex = parent.indexOf(self)
244
+ end
245
+
246
+ attr_accessor :gemViewer
247
+ slots 'itemClicked(QTableWidgetItem *)'
248
+ def itemClicked(item)
249
+ unless item.gem.spec then
250
+ specStr = %x{gem specification #{item.gem.package} -l --marshal}
251
+ begin
252
+ spec = Marshal.load(specStr)
253
+ rescue NoMethodError, ArgumentError => e
254
+ # rescue from some error gems.
255
+ @gemViewer.setError(item.gem, e)
256
+ return
257
+ end
258
+ item.gem.spec = spec
259
+ end
260
+ @gemViewer.setDetail( item.gem )
261
+ files = %x{gem contents --prefix #{item.gem.package} -v #{item.gem.version}}.split(/[\r\n]+/)
262
+ @gemViewer.setFiles( files )
263
+
264
+ proc = lambda do |item|
265
+ file = item.text
266
+ @gemViewer.previewWin.setFile( file )
267
+ end
268
+ @gemViewer.setPreviewProc(proc)
269
+ end
270
+
271
+ slots :viewRdoc
272
+ def viewRdoc
273
+ @gemViewer.viewGemRdoc(@installedGemsTable.currentGem)
274
+ end
275
+
276
+
277
+ slots :viewDir
278
+ def viewDir
279
+ @gemViewer.viewGemDir(@installedGemsTable.currentGem)
280
+ end
281
+
282
+ slots :uninstallGem
283
+ def uninstallGem
284
+ @gemViewer.uninstall(@installedGemsTable.currentGem)
285
+ end
286
+ end
data/lib/mylibs.rb ADDED
@@ -0,0 +1,407 @@
1
+ #
2
+ # My library
3
+ #
4
+ # Qt & other miscs
5
+
6
+ require 'singleton'
7
+ require 'korundum4'
8
+
9
+ #
10
+ class Qt::HBoxLayout
11
+ def addWidgets(*w)
12
+ w.each do |i|
13
+ if i then
14
+ e = i.kind_of?(String) ? Qt::Label.new(i) : i
15
+ addWidget(e)
16
+ else
17
+ addStretch
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ class Qt::VBoxLayout
24
+ def addWidgetWithNilStretch(*w)
25
+ addLayout(
26
+ Qt::HBoxLayout.new do |l|
27
+ l.addWidgets(*w)
28
+ end
29
+ )
30
+ end
31
+ alias :addWidgets :addWidgetWithNilStretch
32
+
33
+ def addWidgetAtCenter(*w)
34
+ w.unshift(nil)
35
+ addWidgetWithNilStretch(*w)
36
+ end
37
+
38
+ def addWidgetAtRight(*w)
39
+ w.unshift(nil)
40
+ addWidgetWithNilStretch(*w)
41
+ end
42
+
43
+ def addWidgetAtLeft(*w)
44
+ w.push(nil)
45
+ addWidgetWithNilStretch(*w)
46
+ end
47
+ end
48
+
49
+
50
+ #
51
+ class VBoxLayoutWidget < Qt::Widget
52
+ def initialize(parent=nil)
53
+ @layout = Qt::VBoxLayout.new
54
+ super(parent)
55
+ setLayout(@layout)
56
+ end
57
+
58
+ def addLayout(l)
59
+ @layout.addLayout(l)
60
+ end
61
+
62
+ def addWidget(w)
63
+ @layout.addWidget(w)
64
+ end
65
+
66
+ def addWidgetWithNilStretch(*w)
67
+ @layout.addWidgetWithNilStretch(*w)
68
+ end
69
+ alias :addWidgets :addWidgetWithNilStretch
70
+
71
+ def addWidgetAtRight(*w)
72
+ @layout.addWidgetAtRight(*w)
73
+ end
74
+
75
+ def addWidgetAtCenter(*w)
76
+ @layout.addWidgetAtCenter(*w)
77
+ end
78
+
79
+ def layout
80
+ @layout
81
+ end
82
+ end
83
+
84
+ class HBoxLayoutWidget < Qt::Widget
85
+ def initialize(parent=nil)
86
+ @layout = Qt::HBoxLayout.new
87
+ super(parent)
88
+ setLayout(@layout)
89
+ end
90
+
91
+ def addLayout(l)
92
+ @layout.addLayout(l)
93
+ end
94
+
95
+ def addWidget(w)
96
+ @layout.addWidget(w)
97
+ end
98
+
99
+ def addWidgets(*w)
100
+ @layout.addWidgets(*w)
101
+ end
102
+
103
+ def layout
104
+ @layout
105
+ end
106
+ end
107
+
108
+
109
+ #--------------------------------------------------------------------------
110
+ #
111
+ #
112
+ def passiveMessage(text)
113
+ %x{ kdialog --passivepopup #{text.shellescape} }
114
+ end
115
+
116
+
117
+
118
+ #--------------------------------------------------------------------------
119
+ #
120
+ #
121
+
122
+ class Qt::Action
123
+ def setVData(data)
124
+ setData(Qt::Variant.new(data))
125
+ end
126
+
127
+ def vData
128
+ self.data.toString
129
+ end
130
+ end
131
+
132
+ module Mime
133
+ def self.services(url)
134
+ mimeType = KDE::MimeType.findByUrl(KDE::Url.new(url))
135
+ mime = mimeType.name
136
+ services = KDE::MimeTypeTrader.self.query(mime)
137
+ end
138
+ end
139
+
140
+ class KDE::ActionCollection
141
+ # @return : KDE::Action
142
+ # @parameter name :
143
+ # @parameter parent : parent Qt::Object
144
+ # @parameter options { :text=>name, :icon=>iconName, :shortCut=>key, :triggered=>SLOT or [object, SLOT] }
145
+ def addNew(name, parent=self.parent, options = {})
146
+ text = options[:text] || name
147
+ icon = options[:icon]
148
+ if icon then
149
+ action = KDE::Action.new(KDE::Icon.new(icon), text, parent)
150
+ else
151
+ action = KDE::Action.new(text, parent)
152
+ end
153
+ shortCut = options[:shortCut]
154
+ if shortCut then
155
+ action.setShortcut(KDE::Shortcut.new(shortCut))
156
+ end
157
+ self.addAction(action.text, action)
158
+ slot = options[:triggered]
159
+ if slot then
160
+ if slot.kind_of? Array then
161
+ self.connect(action, SIGNAL(:triggered), slot[0], \
162
+ SLOT(slot[1]))
163
+ else
164
+ self.connect(action, SIGNAL(:triggered), parent, \
165
+ SLOT(slot))
166
+ end
167
+ end
168
+ action
169
+ end
170
+ end
171
+
172
+
173
+
174
+
175
+
176
+
177
+
178
+ #--------------------------------------------------------------------------
179
+ #
180
+ #
181
+ class SettingsBase < KDE::ConfigSkeleton
182
+ include Singleton
183
+
184
+ public
185
+ # @sym : instance symbol to be added.
186
+ def addBoolItem(sym, default=true)
187
+ name = sym.to_s
188
+ defineItem(sym, 'value', ItemBool, default)
189
+ end
190
+
191
+ def addStringItem(sym, default="")
192
+ defineItem(sym, 'toString', ItemString, default)
193
+ end
194
+
195
+ def addIntItem(sym, default="")
196
+ defineItem(sym, 'value', ItemInt, default)
197
+ end
198
+
199
+ def addUrlItem(sym, default=KDE::Url.new)
200
+ if default.kind_of? String then
201
+ default = KDE::Url.new(default)
202
+ end
203
+ defineItem(sym, 'value', ItemUrl, default)
204
+ end
205
+
206
+ def addStringListItem(sym, default="")
207
+ defineItem(sym, 'value', ItemStringList, default)
208
+ end
209
+
210
+ def addChoiceItem(name, list, default=0)
211
+ choices = makeChoices(list)
212
+ defineItemProperty(name, 'value')
213
+ item = ItemEnum.new(currentGroup, name.to_s, default, choices, default)
214
+ addItem(item)
215
+ end
216
+
217
+ def [](name)
218
+ findItem(name)
219
+ end
220
+
221
+ protected
222
+ def makeChoices(list)
223
+ choices = []
224
+ list.each do |i|
225
+ c = ItemEnum::Choice.new
226
+ c.name = i
227
+ choices << c
228
+ end
229
+ choices
230
+ end
231
+
232
+ def defineItem(name, valueMethod, itemClass, default)
233
+ defineItemProperty(name, valueMethod)
234
+ item = itemClass.new(currentGroup, name.to_s, default, default)
235
+ addItem(item)
236
+ end
237
+
238
+ def defineItemProperty(name, valueMethod)
239
+ self.class.class_eval %Q{
240
+ def #{name}
241
+ findItem('#{name}').property.#{valueMethod}
242
+ end
243
+
244
+ def self.#{name}
245
+ s = self.instance
246
+ s.#{name}
247
+ end
248
+
249
+ def set#{name}(v)
250
+ item = findItem('#{name}')
251
+ # unless item.immutable?
252
+ item.property = Qt::Variant.fromValue(v)
253
+ # end
254
+ end
255
+
256
+ def self.set#{name}(v)
257
+ s = self.instance
258
+ s.set#{name}(v)
259
+ end
260
+
261
+ def #{name}=(v)
262
+ set#{name}(v)
263
+ end
264
+
265
+ def self.#{name}=(v)
266
+ self.set#{name}(v)
267
+ end
268
+ }
269
+ end
270
+
271
+ def self.allChildren(obj)
272
+ all = children = obj.children
273
+ children.each do |o|
274
+ all += allChildren(o)
275
+ end
276
+ all
277
+ end
278
+
279
+ def self.printAllProperties(obj)
280
+ puts "============= settings properties =============="
281
+ options = self.instance
282
+ allChildren(obj).each do |o|
283
+ if o.objectName =~ /^kcfg_/ then
284
+ name = o.objectName.sub(/^kcfg_/, '')
285
+ if o.kind_of? Qt::CheckBox
286
+ prop = o.checked.to_s
287
+ elsif o.kind_of? Qt::ComboBox
288
+ prop = o.currentIndex.to_s
289
+ elsif o.kind_of? KDE::UrlRequester
290
+ prop = o.text
291
+ else
292
+ prop = '?'
293
+ end
294
+ if options.respond_to? name then
295
+ val = options.send(name).inspect
296
+ else
297
+ val = ''
298
+ end
299
+ err = prop == val ? '' : ' !! Error !!'
300
+ puts " name:#{name}, property:#{prop}, settings value:#{val} #{err}"
301
+ end
302
+ end
303
+ end
304
+
305
+ def self.updateWidgets(obj)
306
+ options = self.instance
307
+ allChildren(obj).each do |o|
308
+ if o.objectName =~ /^kcfg_/ then
309
+ name = o.objectName.sub(/^kcfg_/, '')
310
+ if options.respond_to? name then
311
+ val = options.send(name)
312
+ if o.kind_of? Qt::CheckBox
313
+ o.checked = val
314
+ elsif o.kind_of? Qt::ComboBox
315
+ o.currentIndex = val
316
+ elsif o.kind_of? KDE::UrlRequester
317
+ o.setUrl(val)
318
+ end
319
+ end
320
+ end
321
+ end
322
+ end
323
+
324
+ def self.updateSettings(obj)
325
+ options = self.instance
326
+ allChildren(obj).each do |o|
327
+ if o.objectName =~ /^kcfg_/ then
328
+ name = o.objectName.sub(/^kcfg_/, '') + '='
329
+ if options.respond_to? name then
330
+ if o.kind_of? Qt::CheckBox
331
+ options.send(name, o.checked)
332
+ if options.send(name[0..-2]) != o.checked then
333
+ puts "Error !! : #{name[0..-2]}(#{options.send(name[0..-2])} != #{o.checked}"
334
+ end
335
+ elsif o.kind_of? Qt::ComboBox
336
+ options.send(name, o.currentIndex)
337
+ elsif o.kind_of? KDE::UrlRequester
338
+ options.send(name, o.url)
339
+ else
340
+ puts "not know type class:#{o.class.name}"
341
+ end
342
+ end
343
+ end
344
+ end
345
+ end
346
+ end
347
+
348
+
349
+ #--------------------------------------------------------------------------
350
+ #
351
+ #
352
+ def openDirectory(dir)
353
+ cmd = KDE::MimeTypeTrader.self.query('inode/directory').first.exec[/\w+/]
354
+ cmd += " " + dir
355
+ fork do exec(cmd) end
356
+ end
357
+
358
+ #--------------------------------------------------------------------------
359
+ #
360
+ # stdlib
361
+ #
362
+ module Enumerable
363
+ class Proxy
364
+ instance_methods.each { |m| undef_method(m) unless m.match(/^__/) }
365
+ def initialize(enum, method=:map)
366
+ @enum, @method = enum, method
367
+ end
368
+ def method_missing(method, *args, &block)
369
+ @enum.__send__(@method) {|o| o.__send__(method, *args, &block) }
370
+ end
371
+ end
372
+
373
+ def every
374
+ Proxy.new(self)
375
+ end
376
+ end
377
+
378
+ #
379
+ #
380
+ #
381
+ class String
382
+ def double_quote
383
+ '"' + self + '"'
384
+ end
385
+ alias :dquote :double_quote
386
+
387
+ def single_quote
388
+ "'" + self + "'"
389
+ end
390
+ alias :squote :single_quote
391
+
392
+ def _chomp_null
393
+ gsub(/\0.*/, '')
394
+ end
395
+
396
+ def sql_quote
397
+ str = _chomp_null
398
+ return 'NULL' if str.empty?
399
+ "'#{str.sql_escape}'"
400
+ end
401
+
402
+ def sql_escape
403
+ str = _chomp_null
404
+ str.gsub(/\\/, '\&\&').gsub(/'/, "''") #'
405
+ end
406
+ end
407
+