irecorder 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,185 @@
1
+
2
+ #---------------------------------------------------------------------------------------------
3
+ #
4
+ #
5
+ class ProgrammeTableWidget < Qt::TableWidget
6
+ #
7
+ #
8
+ class Programme
9
+ attr_reader :titleItem, :categoriesItem, :updatedItem
10
+ attr_reader :content, :link
11
+
12
+ def initialize(title, categories, updated, content, link)
13
+ @titleItem = Item.new(title)
14
+ @categoriesItem = Item.new(categories)
15
+ @updatedItem = Item.new(updated)
16
+ @content = content
17
+ @link = link
18
+ end
19
+
20
+ def title
21
+ @titleItem.text
22
+ end
23
+
24
+ def categories
25
+ @categoriesItem.text
26
+ end
27
+
28
+ def updated
29
+ @updatedItem.text
30
+ end
31
+ end
32
+
33
+ #
34
+ #
35
+ class Item < Qt::TableWidgetItem
36
+ def initialize(text)
37
+ super(text)
38
+ self.flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled
39
+ self.toolTip = text
40
+ end
41
+ end
42
+
43
+
44
+ #------------------------------------------------------------------------
45
+ #
46
+ #
47
+
48
+ def initialize()
49
+ super(0, 3)
50
+
51
+ setHorizontalHeaderLabels(['Title', 'Category', 'Updated'])
52
+ self.horizontalHeader.stretchLastSection = true
53
+ self.selectionBehavior = Qt::AbstractItemView::SelectRows
54
+ self.alternatingRowColors = true
55
+ self.sortingEnabled = true
56
+ sortByColumn(2, Qt::DescendingOrder )
57
+
58
+
59
+ # Hash table : key column_0_item => Programme entry.
60
+ @table = Hash.new
61
+ end
62
+
63
+ def addEntry( row, title, categories, updated, content, link )
64
+ entry = Programme.new(title, categories, updated, content, link)
65
+ setItem( row, 0, entry.titleItem )
66
+ setItem( row, 1, entry.categoriesItem )
67
+ setItem( row, 2, entry.updatedItem )
68
+ @table[entry.titleItem] = entry
69
+ end
70
+
71
+ # return Programme object.
72
+ def [](row)
73
+ @table[item(row,0)]
74
+ end
75
+
76
+
77
+ #
78
+ # slot : called when filterLineEdit text is changed.
79
+ #
80
+ public
81
+ slots 'filterChanged(const QString &)'
82
+ def filterChanged(text)
83
+ return unless text
84
+
85
+ regxs = text.split(/[,\s]+/).map do |w|
86
+ /#{Regexp.escape(w.strip)}/i
87
+ end
88
+ rowCount.times do |r|
89
+ i0 = item(r,0)
90
+ i1 = item(r,1)
91
+ i2 = item(r,2)
92
+ txt = ((i0 && i0.text) || '') + ((i1 && i1.text) || '') + ((i2 && i2.text) || '')
93
+ if regxs.all? do |rx| rx =~ txt end then
94
+ showRow(r)
95
+ else
96
+ hideRow(r)
97
+ end
98
+ end
99
+ end
100
+
101
+ GroupName = "ProgrammeTable"
102
+ def writeSettings
103
+ config = $config.group(GroupName)
104
+ config.writeEntry('Header', horizontalHeader.saveState)
105
+ end
106
+
107
+ def readSettings
108
+ config = $config.group(GroupName)
109
+ horizontalHeader.restoreState(config.readEntry('Header', horizontalHeader.saveState))
110
+ end
111
+
112
+ protected
113
+ def contextMenuEvent(e)
114
+ prog = self[itemAt(e.pos).row]
115
+ menu = createPopup
116
+ action = menu.exec(e.globalPos)
117
+ action and execPopup(action, prog)
118
+ menu.deleteLater
119
+ end
120
+
121
+ def createPopup()
122
+ menu = Qt::Menu.new
123
+ a = menu.addAction(KDE::Icon.new('search'), i18n('Search Same Programme'))
124
+ a.setVData('searchSame@')
125
+ a = menu.addAction(KDE::Icon.new('search'), i18n('Search Same Category tags'))
126
+ a.setVData('searchSameTags@')
127
+ menu.addSeparator
128
+ insertPlayerActions(menu)
129
+ menu
130
+ end
131
+
132
+ def execPopup(action, item)
133
+ $log.code { "execute : '#{action.vData}'" }
134
+ cmd, exe = action.vData.split(/@/, 2)
135
+ $log.code { "cmd(#{cmd}), exe(#{exe})" }
136
+ if cmd == 'play'
137
+ playMedia(exe, item)
138
+ elsif self.respond_to?(cmd)
139
+ self.method(cmd).call(item)
140
+ else
141
+ $log.warn { "No method #{cmd} in contextmenu." }
142
+ end
143
+ end
144
+
145
+ def insertPlayerActions(menu)
146
+ Mime::services('.wma').each do |s|
147
+ exeName = s.exec[/\w+/]
148
+ a = menu.addAction(KDE::Icon.new(exeName), 'Play with ' + exeName)
149
+ a.setVData('play@' + s.exec)
150
+ end
151
+ end
152
+
153
+ def playMedia(exe, prog)
154
+ begin
155
+ url = prog.content[UrlRegexp] # String[] method extract only 1st one.
156
+
157
+ $log.info { "episode Url : #{url}" }
158
+ minfo = BBCNet::MetaInfo.get(url).update
159
+ url = minfo.wma.url
160
+
161
+ cmd, args = exe.split(/\s+/, 2)
162
+ args = args.split(/\s+/).map do |a|
163
+ a.gsub(/%\w/, url)
164
+ end
165
+ $log.debug { "execute cmd '#{cmd}', args '#{args.inspect}'" }
166
+ proc = Qt::Process.new(self)
167
+ proc.start(cmd, args)
168
+
169
+ rescue => e
170
+ $log.error { e }
171
+ KDE::MessageBox::information(self, i18n("There is not direct stream for this programme."))
172
+ end
173
+ end
174
+
175
+ signals 'filterRequest(const QString &)'
176
+ def searchSame(prog)
177
+ emit filterRequest( prog.title.sub(/:.*/, '') )
178
+ end
179
+
180
+ def searchSameTags(prog)
181
+ emit filterRequest( prog.categories )
182
+ end
183
+ end
184
+
185
+
@@ -0,0 +1,376 @@
1
+ #
2
+ # 2007 by ruby.twiddler@gmail.com
3
+ #
4
+ require "mylibs.rb"
5
+
6
+
7
+ #--------------------------------------------------------------------------
8
+ #
9
+ # select from traders, system menu, arbitarary file.
10
+ #
11
+ class SelectServiceDlg < KDE::Dialog
12
+ def initialize(parent, defaultName=nil)
13
+ super(parent)
14
+ @message = i18n('Select Application')
15
+ userInitialize
16
+ self.windowTitle = @message
17
+ @selectedName = @services[0].name
18
+ createWidget
19
+ setSelected(defaultName)
20
+ end
21
+
22
+ def userInitialize
23
+ @message = i18n('Select Application for .html file.')
24
+ @services = Mime.services('.html')
25
+ end
26
+
27
+ def name
28
+ @selectedName
29
+ end
30
+
31
+ def iconName
32
+ SelectServiceDlg.exeName2IconName(serviceFromName(name).exec)
33
+ end
34
+
35
+ def accept
36
+ @selectedName = @serviceList.selectedItems.first.text
37
+ super
38
+ end
39
+
40
+ def commandFromName(name)
41
+ i = serviceFromName(name)
42
+ i && i.exec
43
+ end
44
+
45
+ def serviceFromName(name)
46
+ name.gsub!(/&/, '')
47
+ return nil if @services.size == 0
48
+ service = @services.find(@services[0]) do |s| s.name == name end
49
+ end
50
+
51
+ def setSelected(name)
52
+ return unless name
53
+ name.gsub!(/&/, '')
54
+ return if @services.size == 0
55
+ unless name then
56
+ @serviceList.takeItem(0).setSelected(true)
57
+ else
58
+ items = @serviceList.findItems(name, Qt::MatchExactly)
59
+ if items.size > 0 then
60
+ items[0].setSelected(true)
61
+ end
62
+ end
63
+ end
64
+
65
+ def self.exeName2IconName(exeName)
66
+ iconName = exeName.gsub(%r{[^ ]*/}, '')[/([-_\w\d])+/] .
67
+ gsub(/(dragon)/, '\1player').gsub(/kfmclient/, 'konqueror')
68
+ end
69
+
70
+ protected
71
+ def createWidget
72
+ mainWidget = VBoxLayoutWidget.new
73
+ mainWidget.addWidget(Qt::Label.new(@message))
74
+ @serviceList = KDE::ListWidget.new
75
+ @services.each do |s|
76
+ iconName = SelectServiceDlg.exeName2IconName(s.exec)
77
+ @serviceList.addItem( Qt::ListWidgetItem.new(KDE::Icon.new(iconName), s.name) )
78
+ end
79
+ @selectFromMenu = KDE::PushButton.new(i18n('Select Other from Menu'))
80
+ mainWidget.addWidget(@serviceList)
81
+ # mainWidget.addWidget(@selectFromMenu)
82
+
83
+ setMainWidget(mainWidget)
84
+ end
85
+ end
86
+
87
+
88
+ class SelectWebPlayerDlg < SelectServiceDlg
89
+ def userInitialize
90
+ @message = i18n('Select Web Player for iPlayer page.')
91
+ @services = Mime.services('.html').select do |s|
92
+ s.name !~ /office/i and
93
+ s.serviceTypes.find do |st|
94
+ st =~ /application\//
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ class SelectDirectPlayerDlg < SelectServiceDlg
101
+ def userInitialize
102
+ @message = i18n('Select Direct Stream Player.')
103
+ @services = Mime.services('.wma')
104
+ end
105
+ end
106
+
107
+
108
+
109
+
110
+ #--------------------------------------------------------------------------
111
+ #
112
+ # IRecorder Settings
113
+ #
114
+ class IRecSettings < SettingsBase
115
+ def initialize
116
+ super()
117
+
118
+ setCurrentGroup("Preferences")
119
+
120
+ # meta programed version.
121
+ addStringItem(:rawDownloadDir, Qt::Dir::tempPath + '/RadioRaw')
122
+ addStringItem(:downloadDir, KDE::GlobalSettings.musicPath)
123
+ addBoolItem(:dirAddMediaName, true)
124
+ addBoolItem(:dirAddChannelName, false)
125
+ addBoolItem(:dirAddGenreName, true)
126
+ addStringItem(:fileAddHeadStr, 'BBC ')
127
+ addBoolItem(:fileAddMediaName, true)
128
+ addBoolItem(:fileAddChannelName, false)
129
+ addBoolItem(:fileAddGenreName, true)
130
+ addBoolItem(:leaveRawFile, false)
131
+
132
+ addBoolItem(:playerTypeSmall, false)
133
+ addBoolItem(:playerTypeBeta, true)
134
+
135
+ addBoolItem(:useInnerPlayer, true)
136
+ addBoolItem(:useWebPlayer, false)
137
+ addStringItem(:webPlayerName, 'Konqueror')
138
+ addBoolItem(:useDirectPlayer, false)
139
+ addStringItem(:directPlayerName, 'KMPlayer')
140
+ end
141
+
142
+ def webPlayerCommand
143
+ @webPlayerCnv.commandFromName(self.webPlayerName)
144
+ end
145
+
146
+ def self.webPlayerCommand
147
+ self.instance.webPlayerCommand
148
+ end
149
+
150
+ def directPlayerCommand
151
+ @directPlayerCnv.commandFromName(self.directPlayerName)
152
+ end
153
+
154
+ def self.directPlayerCommand
155
+ self.instance.directPlayerCommand
156
+ end
157
+
158
+ def regConverter(webPlayerCnv, directPlayerCnv)
159
+ @webPlayerCnv = webPlayerCnv
160
+ @directPlayerCnv = directPlayerCnv
161
+ end
162
+ end
163
+
164
+
165
+ #--------------------------------------------------------------------------
166
+ #
167
+ #
168
+ class SettingsDlg < KDE::ConfigDialog
169
+ def initialize(parent)
170
+ super(parent, "Settings", IRecSettings.instance)
171
+ addPage(FolderSettingsPage.new, i18n("Folder"), 'folder', i18n('Folder and File Name'))
172
+ addPage(PlayerSettingsPage.new, i18n("Player"), 'internet-web-browser', i18n('Player and web Browser'))
173
+ end
174
+ end
175
+
176
+
177
+ #--------------------------------------------------------------------------
178
+ #
179
+ #
180
+ class FolderSettingsPage < Qt::Widget
181
+ def initialize(parent=nil)
182
+ super(parent)
183
+ createWidget
184
+ end
185
+
186
+ protected
187
+
188
+ def createWidget
189
+ @rawFileDirLine = FolderSelectorLineEdit.new(KDE::GlobalSettings.downloadPath)
190
+ @downloadDirLine = FolderSelectorLineEdit.new(KDE::GlobalSettings.downloadPath)
191
+
192
+ @dirSampleLabel = Qt::Label.new('Example) ')
193
+ @dirAddMediaName = Qt::CheckBox.new(i18n('Add media directory'))
194
+ @dirAddChannelName = Qt::CheckBox.new(i18n('Add channel directory'))
195
+ @dirAddGenreName = Qt::CheckBox.new(i18n('Add genre directory'))
196
+ [ @dirAddMediaName, @dirAddChannelName, @dirAddGenreName ].each do |w|
197
+ w.connect(SIGNAL('stateChanged(int)')) do |s| updateSampleDirName end
198
+ end
199
+
200
+ @fileSampleLabel = Qt::Label.new('Example) ')
201
+ @fileAddHeadStr = KDE::LineEdit.new do |w|
202
+ w.connect(SIGNAL('textChanged(const QString&)')) do |t| updateSampleFileName end
203
+ end
204
+ @fileAddMediaName = Qt::CheckBox.new(i18n('Add media name'))
205
+ @fileAddChannelName = Qt::CheckBox.new(i18n('Add channel name'))
206
+ @fileAddGenreName = Qt::CheckBox.new(i18n('Add genre name'))
207
+
208
+ [ @fileAddMediaName, @fileAddChannelName, @fileAddGenreName ].each do |w|
209
+ w.connect(SIGNAL('stateChanged(int)')) do |s| updateSampleFileName end
210
+ end
211
+ @leaveRawFile = Qt::CheckBox.new(i18n('Leave raw file.(don\'t delete it)'))
212
+
213
+ # set objectNames
214
+ # 'kcfg_' + class Settings's instance name.
215
+ @rawFileDirLine.objectName = 'kcfg_rawDownloadDir'
216
+ @downloadDirLine.objectName = 'kcfg_downloadDir'
217
+ @dirAddMediaName.objectName = 'kcfg_dirAddMediaName'
218
+ @dirAddChannelName.objectName = 'kcfg_dirAddChannelName'
219
+ @dirAddGenreName.objectName = 'kcfg_dirAddGenreName'
220
+ @fileAddHeadStr.objectName = 'kcfg_fileAddHeadStr'
221
+ @fileAddMediaName.objectName = 'kcfg_fileAddMediaName'
222
+ @fileAddChannelName.objectName = 'kcfg_fileAddChannelName'
223
+ @fileAddGenreName.objectName = 'kcfg_fileAddGenreName'
224
+ @leaveRawFile.objectName = 'kcfg_leaveRawFile'
225
+
226
+
227
+ # layout
228
+ lo = Qt::VBoxLayout.new do |l|
229
+ l.addWidget(Qt::Label.new(i18n('Download Directory')))
230
+ l.addWidgets(' ', @downloadDirLine)
231
+ l.addWidget(Qt::Label.new(i18n('Temporary Raw File Download Directory')))
232
+ l.addWidgets(' ', @rawFileDirLine)
233
+ l.addWidget(Qt::GroupBox.new(i18n('Generating directory')) do |g|
234
+ vbx = Qt::VBoxLayout.new do |vb|
235
+ vb.addWidget(@dirSampleLabel)
236
+ vb.addWidget(@dirAddMediaName)
237
+ # vb.addWidget(@dirAddChannelName)
238
+ vb.addWidget(@dirAddGenreName)
239
+ end
240
+ g.setLayout(vbx)
241
+ end
242
+ )
243
+ l.addWidget(Qt::GroupBox.new(i18n('Generating file name')) do |g|
244
+ vbx = Qt::VBoxLayout.new do |vb|
245
+ vb.addWidget(@fileSampleLabel)
246
+ vb.addWidgets(i18n('Head Text'), @fileAddHeadStr)
247
+ vb.addWidget(@fileAddMediaName)
248
+ # vb.addWidget(@fileAddChannelName)
249
+ vb.addWidget(@fileAddGenreName)
250
+ end
251
+ g.setLayout(vbx)
252
+ end
253
+ )
254
+ l.addWidget(@leaveRawFile)
255
+ l.addStretch
256
+ end
257
+
258
+ setLayout(lo)
259
+ end
260
+
261
+ def updateSampleFileName
262
+ @fileSampleLabel.text = 'Example) ' + getSampleFileName
263
+ end
264
+
265
+ def checkState(checkBox)
266
+ checkBox.checkState== Qt::Checked
267
+ end
268
+
269
+ def getSampleFileName
270
+ head = @fileAddHeadStr.text
271
+ head += 'Radio ' if checkState(@fileAddMediaName)
272
+ head += 'Radio 7 ' if checkState(@fileAddChannelName)
273
+ head += 'Drama ' if checkState(@fileAddGenreName)
274
+ head += "- " unless head.empty?
275
+ baseName = head + 'Space Hacks Lost in Space Ship.mp3'
276
+ baseName.gsub(%r{[\/]}, '-')
277
+ end
278
+
279
+
280
+ def updateSampleDirName
281
+ @dirSampleLabel.text = 'Example) ... /' + getSampleDirName
282
+ end
283
+
284
+ def getSampleDirName
285
+ dir = []
286
+ dir << 'Radio' if checkState(@dirAddMediaName)
287
+ dir << 'Radio 7' if checkState(@dirAddChannelName)
288
+ dir << 'Drama' if checkState(@dirAddGenreName)
289
+ File.join(dir.compact)
290
+ end
291
+
292
+ end
293
+
294
+ #--------------------------------------------------------------------------
295
+ #
296
+ #
297
+ class PlayerSettingsPage < Qt::Widget
298
+ def initialize(parent=nil)
299
+ super(parent)
300
+ createWidget
301
+ end
302
+
303
+ protected
304
+
305
+ def createWidget
306
+ @SelectWebPlayerDlg = SelectWebPlayerDlg.new(self, IRecSettings.webPlayerName)
307
+ @SelectDirectPlayerDlg = SelectDirectPlayerDlg.new(self, IRecSettings.directPlayerName)
308
+ IRecSettings.instance.regConverter(@SelectWebPlayerDlg, @SelectDirectPlayerDlg)
309
+
310
+ @playerTypeSmall = Qt::RadioButton.new(i18n('small iplayer'))
311
+ @playerTypeBeta = Qt::RadioButton.new(i18n('beta iplayer'))
312
+
313
+ @innerPlayer = Qt::RadioButton.new(i18n('inner Player'))
314
+ @webPlayer = Qt::RadioButton.new(i18n('Web Player'))
315
+ @directPlayer = Qt::RadioButton.new(i18n('Direnct Stream Player'))
316
+
317
+ @webPlayerName = KDE::PushButton.new('Konqueror')
318
+ @webPlayerName.connect(SIGNAL(:pressed)) do
319
+ @SelectWebPlayerDlg.setSelected(@webPlayerName.text)
320
+ if @SelectWebPlayerDlg.exec == Qt::Dialog::Accepted then
321
+ @webPlayerName.text = @SelectWebPlayerDlg.name
322
+ # @webPlayerName.setIcon(KDE::Icon.new(@SelectWebPlayerDlg.iconName))
323
+ @webPlayer.checked = true
324
+ end
325
+ end
326
+ @webPlayerName.setProperty("kcfg_property", Qt::Variant.new("text"))
327
+
328
+ @directPlayerName = KDE::PushButton.new('KMPlayer')
329
+ @directPlayerName.connect(SIGNAL(:pressed)) do
330
+ @SelectDirectPlayerDlg.setSelected(@directPlayerName.text)
331
+ if @SelectDirectPlayerDlg.exec == Qt::Dialog::Accepted then
332
+ @directPlayerName.text = @SelectDirectPlayerDlg.name
333
+ # @directPlayerName.setIcon(KDE::Icon.new(@SelectDirectPlayerDlg.iconName))
334
+ @directPlayer.checked = true
335
+ end
336
+ end
337
+ @directPlayerName.setProperty("kcfg_property", Qt::Variant.new("text"))
338
+
339
+ # set objectNames
340
+ # 'kcfg_' + class Settings's instance name.
341
+ @playerTypeSmall.objectName = 'kcfg_playerTypeSmall'
342
+ @playerTypeBeta.objectName = 'kcfg_playerTypeBeta'
343
+ @innerPlayer.objectName = 'kcfg_useInnerPlayer'
344
+ @webPlayer.objectName = 'kcfg_useWebPlayer'
345
+ @directPlayer.objectName = 'kcfg_useDirectPlayer'
346
+ @webPlayerName.objectName = 'kcfg_webPlayerName'
347
+ @directPlayerName.objectName = 'kcfg_directPlayerName'
348
+
349
+
350
+ # layout
351
+ lo = Qt::VBoxLayout.new do |l|
352
+ l.addWidget(Qt::GroupBox.new(i18n('iPlayer Type')) do |g|
353
+ vbx = Qt::VBoxLayout.new do |vb|
354
+ vb.addWidget(@playerTypeSmall)
355
+ vb.addWidget(@playerTypeBeta)
356
+ end
357
+ g.setLayout(vbx)
358
+ end
359
+ )
360
+ l.addWidget(Qt::GroupBox.new(i18n('Player')) do |g|
361
+ vbx = Qt::VBoxLayout.new do |vb|
362
+ vb.addWidget(@innerPlayer)
363
+ vb.addWidget(@webPlayer)
364
+ vb.addWidgets(' ', @webPlayerName, nil)
365
+ vb.addWidget(@directPlayer)
366
+ vb.addWidgets(' ', @directPlayerName, nil)
367
+ end
368
+ g.setLayout(vbx)
369
+ end
370
+ )
371
+ l.addStretch
372
+ end
373
+
374
+ setLayout(lo)
375
+ end
376
+ end