0
|
1 #!/usr/bin/env python3
|
|
2 #
|
|
3 # cover2music - appka do przypisywania obrazków płyt plikom ogg, oga, opus oraz mp3
|
|
4 # program: Przemysław R. Pietraszczyk
|
|
5 # rozpoczęto: 26-04-2021
|
|
6 # licencja: GPL
|
|
7 # napisano w edytorze: Atom
|
|
8
|
|
9 import gi, os
|
|
10 gi.require_version('Gtk', '3.0')
|
|
11 from gi.repository import Gtk, GdkPixbuf, GLib
|
|
12
|
|
13 import base64
|
|
14 from mutagen.mp3 import MP3
|
|
15 from mutagen.id3 import ID3, APIC, error
|
|
16 from mutagen.oggvorbis import OggVorbis
|
|
17 from mutagen.oggflac import OggFLAC
|
|
18 from mutagen.oggopus import OggOpus
|
|
19 from mutagen.flac import Picture
|
|
20 import mutagen
|
|
21
|
|
22 file_snd_selected=[]
|
|
23 file_img_selected=""
|
|
24
|
|
25 #snd_selected=[]
|
|
26 #COVER ="cover2music.png"
|
|
27 COVER ="/usr/share/pixmaps/cover2music.png"
|
|
28 snd_extension="ogg"
|
|
29 img_extension="png" # dla przykladu
|
|
30
|
|
31
|
|
32 UI_INFO = """
|
|
33 <ui>
|
|
34 <menubar name='MenuBar'>
|
|
35 <menu action='FileMenu'>
|
|
36 <menu action='FileLoad'>
|
|
37 <menuitem action='LoadImg' />
|
|
38 <menuitem action='LoadOgg' />
|
|
39 </menu>
|
|
40 <menu action='FileDelete'>
|
|
41 <menuitem action='RemoveCover' />
|
|
42 </menu>
|
|
43 <separator />
|
|
44 <menuitem action='FileQuit' />
|
|
45 </menu>
|
|
46
|
|
47 <menu action='ChoicesMenu'>
|
|
48 <menuitem action='ChoiceTree'/>
|
|
49 </menu>
|
|
50
|
|
51 <menu action='InfoMenu'>
|
|
52 <menuitem action='Help'/>
|
|
53 <menuitem action='About'/>
|
|
54 </menu>
|
|
55 </menubar>
|
|
56
|
|
57 </ui>
|
|
58 """
|
|
59
|
|
60
|
|
61 class FileChooserIMG(Gtk.Window):
|
|
62 def __init__(self):
|
|
63 Gtk.Window.__init__(self, title="Wybór plików graficznych")
|
|
64 global file_img_selected
|
|
65
|
|
66 dialog = Gtk.FileChooserDialog(title="Please choose a file", parent=self, action=Gtk.FileChooserAction.OPEN)
|
|
67 dialog.add_buttons(
|
|
68 Gtk.STOCK_CANCEL,
|
|
69 Gtk.ResponseType.CANCEL,
|
|
70 Gtk.STOCK_OPEN,
|
|
71 Gtk.ResponseType.OK,
|
|
72 )
|
|
73
|
|
74 self.add_filters(dialog)
|
|
75
|
|
76 response = dialog.run()
|
|
77 if response == Gtk.ResponseType.OK:
|
|
78 print("Open clicked")
|
|
79 print("File selected: " + dialog.get_filename())
|
|
80 file_img_selected=dialog.get_filename()
|
|
81 elif response == Gtk.ResponseType.CANCEL:
|
|
82 print("Cancel clicked")
|
|
83
|
|
84 dialog.destroy()
|
|
85
|
|
86 def add_filters(self, dialog):
|
|
87 filter_jpeg = Gtk.FileFilter()
|
|
88 filter_jpeg.set_name("Pliki JPEG")
|
|
89 filter_jpeg.add_mime_type("image/jpeg")
|
|
90 dialog.add_filter(filter_jpeg)
|
|
91
|
|
92 filter_png = Gtk.FileFilter()
|
|
93 filter_png.set_name("Pliki PNG")
|
|
94 filter_png.add_mime_type("image/png")
|
|
95 dialog.add_filter(filter_png)
|
|
96
|
|
97 class FileChooserOgg(Gtk.Window):
|
|
98 def __init__(self):
|
|
99 Gtk.Window.__init__(self, title="Wybór plików dzwiękowych")
|
|
100 global file_snd_selected
|
|
101 dialog = Gtk.FileChooserDialog(title="Please choose a file", parent=self, action=Gtk.FileChooserAction.OPEN)
|
|
102 dialog.add_buttons(
|
|
103 Gtk.STOCK_CANCEL,
|
|
104 Gtk.ResponseType.CANCEL,
|
|
105 Gtk.STOCK_OPEN,
|
|
106 Gtk.ResponseType.OK,
|
|
107 )
|
|
108
|
|
109 self.add_filters(dialog)
|
|
110 dialog.set_select_multiple(True)
|
|
111 response = dialog.run()
|
|
112 if response == Gtk.ResponseType.OK:
|
|
113 print("Open clicked")
|
|
114 file_snd_selected=dialog.get_filenames()
|
|
115
|
|
116 elif response == Gtk.ResponseType.CANCEL:
|
|
117 print("Cancel clicked")
|
|
118
|
|
119 dialog.destroy()
|
|
120
|
|
121 def add_filters(self, dialog):
|
|
122
|
|
123 filter_ogg = Gtk.FileFilter()
|
|
124 filter_ogg.set_name("Pliki OGG")
|
|
125 filter_ogg.add_mime_type("audio/ogg")
|
|
126 dialog.add_filter(filter_ogg)
|
|
127
|
|
128 filter_mp3 = Gtk.FileFilter()
|
|
129 filter_mp3.set_name("Pliki MP3")
|
|
130 filter_mp3.add_mime_type("audio/mp3")
|
|
131 dialog.add_filter(filter_mp3)
|
|
132
|
|
133
|
|
134 class DialogDeleteProgress(Gtk.Dialog):
|
|
135 def __init__(self,parent):
|
|
136
|
|
137 Gtk.Dialog.__init__(self, title="Postęp", transient_for=parent, flags=0)
|
|
138 self.current_snd=0
|
|
139 self.props.border_width = 20
|
|
140 #self.add_buttons(
|
|
141 # Gtk.STOCK_OK, Gtk.ResponseType.OK
|
|
142 #)
|
|
143 self.progressbar = Gtk.ProgressBar()
|
|
144 self.set_default_size(150, 100)
|
|
145 box = self.get_content_area()
|
|
146
|
|
147 label = Gtk.Label(label="Usuwam okladki z plików\n")
|
|
148
|
|
149 box.add(label)
|
|
150 box.add(self.progressbar)
|
|
151 self.divider_next=1/len(file_snd_selected)
|
|
152 self.timeout_id = GLib.timeout_add(300, self.on_timeout, len(file_snd_selected))
|
|
153 self.activity_mode = False
|
|
154 self.show_all()
|
|
155
|
|
156 def on_timeout(self, user_data):
|
|
157
|
|
158 #jesli przepytano wszyskie pliki wówczas koniec
|
|
159 if self.current_snd == user_data:
|
|
160 self.add_buttons(
|
|
161 Gtk.STOCK_OK, Gtk.ResponseType.OK
|
|
162 )
|
|
163 self.show_all()
|
|
164 return False
|
|
165
|
|
166 if self.activity_mode:
|
|
167 self.progressbar.pulse()
|
|
168 else:
|
|
169 new_value = self.progressbar.get_fraction() + self.divider_next
|
|
170
|
|
171 #if new_value > 1:
|
|
172 # new_value = 0
|
|
173
|
|
174 self.progressbar.set_fraction(new_value)
|
|
175 snd=file_snd_selected[self.current_snd]
|
|
176 self.current_snd = self.current_snd +1
|
|
177 print ("file selected: ",snd)
|
|
178 extension = os.path.splitext(snd)
|
|
179 snd_extension=extension[1].replace(".", "")
|
|
180 print ("Rozszerzenie pliku dzwiekowego: ", snd_extension)
|
|
181
|
|
182 type=self.check_file_type(snd)
|
|
183 if type == "mp3":
|
|
184 self.remove_cover_mp3_generic(snd)
|
|
185 elif type == "ogg":
|
|
186 self.remove_cover_ogg_generic(snd)
|
|
187 elif type == "oga":
|
|
188 self.remove_cover_oga_generic(snd)
|
|
189 elif type == "opus":
|
|
190 self.remove_cover_opus_generic(snd)
|
|
191
|
|
192 # As this is a timeout function, return True so that it
|
|
193 # continues to get called
|
|
194 return True
|
|
195
|
|
196
|
|
197 def check_file_type(self,snd):
|
|
198
|
|
199 magic_numbers = {'ID3v2': bytes([0x49, 0x44, 0x33]),
|
|
200 'ID3v1': bytes([0xFF, 0xF2]),
|
|
201 'ID3': bytes([0xFF, 0xF3]),
|
|
202 'withoutID': bytes([0xFF, 0xFB]),
|
|
203 'ogg': bytes([0x4F, 0x67, 0x67, 0x53])}
|
|
204 max_read_size = max(len(m) for m in magic_numbers.values())
|
|
205
|
|
206 with open(snd, 'rb') as fd:
|
|
207 file_head = fd.read()
|
|
208 #print(file_head)
|
|
209
|
|
210 if file_head.startswith(magic_numbers['ID3v2']):
|
|
211 print ("Plik MP3- z ID3v2")
|
|
212 return "mp3"
|
|
213 elif file_head.startswith(magic_numbers['ID3v1']):
|
|
214 print ("Plik MP3- z ID3v1")
|
|
215 return "mp3"
|
|
216 elif file_head.startswith(magic_numbers['ID3']):
|
|
217 print ("Plik MP3- z ID3")
|
|
218 return "mp3"
|
|
219 elif file_head.startswith(magic_numbers['withoutID']):
|
|
220 print ("Plik MP3 bez ID3")
|
|
221 return "mp3"
|
|
222 elif file_head.startswith(magic_numbers['ogg']):
|
|
223 print("Kontener OGG")
|
|
224 ogg_head=mutagen.File(snd).pprint()[0:20]
|
|
225
|
|
226 if 'opus' in ogg_head.lower():
|
|
227 return "opus"
|
|
228 elif 'flac' in ogg_head.lower():
|
|
229 return "oga"
|
|
230 elif 'vorbis'in ogg_head.lower():
|
|
231 return "ogg"
|
|
232
|
|
233
|
|
234
|
|
235
|
|
236 def remove_cover_mp3_generic(self,snd):
|
|
237
|
|
238 file = ID3(snd) # Load the file
|
|
239 file.delall("APIC") # Delete every APIC tag (Cover art)
|
|
240 file.save() # Save the file
|
|
241
|
|
242 def remove_cover_ogg_generic(self,snd):
|
|
243
|
|
244 file = OggVorbis(snd)
|
|
245 try:
|
|
246 artist=file["artist"]
|
|
247 except KeyError:
|
|
248 artist=""
|
|
249 try:
|
|
250 title=file["title"]
|
|
251 except KeyError:
|
|
252 title=""
|
|
253 try:
|
|
254 year=file["year_of_relase"]
|
|
255 except KeyError:
|
|
256 year=""
|
|
257 try:
|
|
258 album=file["album"]
|
|
259 except KeyError:
|
|
260 album=""
|
|
261 try:
|
|
262 genre=file["genre"]
|
|
263 except KeyError:
|
|
264 genre=""
|
|
265
|
|
266 file.delete()
|
|
267 file["year_of_relase"]=year
|
|
268 file["artist"]=artist
|
|
269 file["title"]=title
|
|
270 file["album"]=album
|
|
271 file["genre"]=genre
|
|
272 file.save()
|
|
273
|
|
274 def remove_cover_oga_generic(self,snd):
|
|
275
|
|
276 file = OggFLAC(snd)
|
|
277 try:
|
|
278 artist=file["artist"]
|
|
279 except KeyError:
|
|
280 artist=""
|
|
281 try:
|
|
282 title=file["title"]
|
|
283 except KeyError:
|
|
284 title=""
|
|
285 try:
|
|
286 year=file["year_of_relase"]
|
|
287 except KeyError:
|
|
288 year=""
|
|
289 try:
|
|
290 album=file["album"]
|
|
291 except KeyError:
|
|
292 album=""
|
|
293 try:
|
|
294 genre=file["genre"]
|
|
295 except KeyError:
|
|
296 genre=""
|
|
297
|
|
298 file.delete()
|
|
299 file["year_of_relase"]=year
|
|
300 file["artist"]=artist
|
|
301 file["title"]=title
|
|
302 file["album"]=album
|
|
303 file["genre"]=genre
|
|
304 file.save()
|
|
305
|
|
306 def remove_cover_opus_generic(self,snd):
|
|
307
|
|
308 file = OggOpus(snd)
|
|
309 #year=file["YEAR_OF_RELEASE"]
|
|
310 try:
|
|
311 artist=file["artist"]
|
|
312 except KeyError:
|
|
313 artist=""
|
|
314 try:
|
|
315 title=file["title"]
|
|
316 except KeyError:
|
|
317 title=""
|
|
318 try:
|
|
319 year=file["year_of_relase"]
|
|
320 except KeyError:
|
|
321 year=""
|
|
322 try:
|
|
323 album=file["album"]
|
|
324 except KeyError:
|
|
325 album=""
|
|
326 try:
|
|
327 genre=file["genre"]
|
|
328 except KeyError:
|
|
329 genre=""
|
|
330
|
|
331 file.delete()
|
|
332 file["year_of_relase"]=year
|
|
333 file["artist"]=artist
|
|
334 file["title"]=title
|
|
335 file["album"]=album
|
|
336 file["genre"]=genre
|
|
337 file.save()
|
|
338
|
|
339
|
|
340 class DialogAddCoverProgress(Gtk.Dialog):
|
|
341 def __init__(self,parent):
|
|
342
|
|
343 Gtk.Dialog.__init__(self, title="Postęp", transient_for=parent, flags=0)
|
|
344 self.current_snd=0
|
|
345 self.props.border_width = 20
|
|
346 #self.add_buttons(
|
|
347 # Gtk.STOCK_OK, Gtk.ResponseType.OK
|
|
348 #)
|
|
349 self.progressbar = Gtk.ProgressBar()
|
|
350 self.set_default_size(150, 100)
|
|
351 box = self.get_content_area()
|
|
352
|
|
353 label = Gtk.Label(label="Dodaję okladkę do plików\n")
|
|
354
|
|
355 box.add(label)
|
|
356 box.add(self.progressbar)
|
|
357
|
|
358 self.divider_next=1/len(file_snd_selected)
|
|
359 self.timeout_id = GLib.timeout_add(300, self.on_timeout, len(file_snd_selected))
|
|
360 self.activity_mode = False
|
|
361 self.show_all()
|
|
362
|
|
363 def on_timeout(self, user_data):
|
|
364 global img_extension
|
|
365 #jesli przepytano wszyskie pliki wówczas koniec
|
|
366 if self.current_snd == user_data:
|
|
367 self.add_buttons(
|
|
368 Gtk.STOCK_OK, Gtk.ResponseType.OK
|
|
369 )
|
|
370 self.show_all()
|
|
371 return False
|
|
372
|
|
373 if self.activity_mode:
|
|
374 self.progressbar.pulse()
|
|
375 else:
|
|
376 new_value = self.progressbar.get_fraction() + self.divider_next
|
|
377
|
|
378 #if new_value > 1:
|
|
379 # new_value = 0
|
|
380
|
|
381 self.progressbar.set_fraction(new_value)
|
|
382 snd=file_snd_selected[self.current_snd]
|
|
383 self.current_snd = self.current_snd +1
|
|
384 print ("file selected: ",snd)
|
|
385 extension = os.path.splitext(snd)
|
|
386 snd_extension=extension[1].replace(".", "")
|
|
387 print ("Rozszerzenie pliku dzwiekowego: ", snd_extension)
|
|
388
|
|
389
|
|
390 #print ("file selected: ",snd)
|
|
391 #extension = os.path.splitext(snd)
|
|
392 #snd_extension=extension[1].replace(".", "")
|
|
393 #print ("Rozszerzenie pliku dzwiekowego: ", snd_extension)
|
|
394
|
|
395 if snd_extension.lower() == "ogg":
|
|
396
|
|
397 file_ = OggVorbis(snd)
|
|
398 print("IMAGE FILE: ",file_img_selected)
|
|
399 with open(file_img_selected, "rb") as h:
|
|
400 data = h.read()
|
|
401
|
|
402 img_extension=img_extension.lower()
|
|
403 picture = Picture()
|
|
404 picture.data = data
|
|
405 picture.type = 17
|
|
406 picture.desc = u"Picture set by cover2music"
|
|
407 picture.mime = u"image/"+img_extension
|
|
408 picture.width = 100
|
|
409 picture.height = 100
|
|
410 picture.depth = 24
|
|
411
|
|
412 picture_data = picture.write()
|
|
413 encoded_data = base64.b64encode(picture_data)
|
|
414 vcomment_value = encoded_data.decode("ascii")
|
|
415
|
|
416 file_["metadata_block_picture"] = [vcomment_value]
|
|
417 file_.save()
|
|
418
|
|
419 elif snd_extension.lower() == "oga":
|
|
420
|
|
421 #for snd in file_snd_selected:
|
|
422 file_ = OggFLAC(snd)
|
|
423 print("IMAGE FILE: ",file_img_selected)
|
|
424 with open(file_img_selected, "rb") as h:
|
|
425 data = h.read()
|
|
426
|
|
427 img_extension=img_extension.lower()
|
|
428 picture = Picture()
|
|
429 picture.data = data
|
|
430 picture.type = 17 # 0x7f
|
|
431 picture.desc = u"Picture set by cover2music"
|
|
432 picture.mime = u"image/"+img_extension
|
|
433 picture.width = 100
|
|
434 picture.height = 100
|
|
435 picture.depth = 24
|
|
436
|
|
437 picture_data = picture.write()
|
|
438 encoded_data = base64.b64encode(picture_data)
|
|
439 vcomment_value = encoded_data.decode("ascii")
|
|
440
|
|
441 file_["metadata_block_picture"] = [vcomment_value]
|
|
442 file_.save()
|
|
443
|
|
444
|
|
445 elif snd_extension.lower() == "opus":
|
|
446
|
|
447 #for snd in file_snd_selected:
|
|
448 file_ = OggOpus(snd)
|
|
449 print("IMAGE FILE: ",file_img_selected)
|
|
450 with open(file_img_selected, "rb") as h:
|
|
451 data = h.read()
|
|
452
|
|
453 img_extension=img_extension.lower()
|
|
454 picture = Picture()
|
|
455 picture.data = data
|
|
456 picture.type = 17 # 0x7f
|
|
457 picture.desc = u"Picture set by cover2music"
|
|
458 picture.mime = u"image/"+img_extension
|
|
459 #picture.width = 100
|
|
460 #picture.height = 100
|
|
461 #picture.depth = 24
|
|
462
|
|
463 picture_data = picture.write()
|
|
464 encoded_data = base64.b64encode(picture_data)
|
|
465 vcomment_value = encoded_data.decode("ascii")
|
|
466
|
|
467 file_["metadata_block_picture"] = [vcomment_value]
|
|
468 file_.save()
|
|
469
|
|
470 elif snd_extension.lower() == "mp3":
|
|
471 #for snd in file_snd_selected:
|
|
472 print ("Dodaje do mp3: ",snd)
|
|
473 print ("file_img_selected: ", file_img_selected)
|
|
474 file = MP3(snd, ID3=ID3)
|
|
475
|
|
476 try:
|
|
477 file.add_tags()
|
|
478 except error:
|
|
479 pass
|
|
480
|
|
481 file.tags.add(APIC(mime="image/"+img_extension,type=3,desc=u'Cove by cover2music',data=open(file_img_selected,'rb').read()))
|
|
482 file.save() # save the current changes
|
|
483
|
|
484 else:
|
|
485 print ("źle")
|
|
486
|
|
487 # As this is a timeout function, return True so that it
|
|
488 # continues to get called
|
|
489 return True
|
|
490
|
|
491
|
|
492
|
|
493 class DialogHelp(Gtk.Dialog):
|
|
494 def __init__(self, parent):
|
|
495 Gtk.Dialog.__init__(self, title="Pomoc", transient_for=parent, flags=0)
|
|
496 self.props.border_width = 20
|
|
497 self.add_buttons(
|
|
498 Gtk.STOCK_OK, Gtk.ResponseType.OK
|
|
499 )
|
|
500
|
|
501 self.set_default_size(150, 100)
|
|
502 txt="-jednak samo załadownie obrazka do pliku nie gwarantuje, że zmieni się ikona w menedżerze plików.\n W tym względzie są przyjazne menedżery takie jak PCManFM, jak i nieprzyjazne jak Nemo.\n Jednak w graficznym odtwarzaczu, załadowany obrazek powinien pojawić się zawsze\n\n"
|
|
503 label1 = Gtk.Label(label="Aplikacja jest w stanie dodać okładkę do prawie wszystkich plików MP3, oraz do plików OGG (Vorbis),\n OGA (OGG FLAC) oraz OPUS. Możliwe jest również usuwanie okładek z pozostawieniem pozostałych tagów.\n Pliki można zmieniać pojedynczo jak i grupowo. Okładki odczytywane są w formatach JPEG oraz PNG.\n Należy zadbać wcześniej aby obrazy okładek nie były zbyt duże, optymalna wielkość to 384x384 px.\n\n")
|
|
504 label2 = Gtk.Label(label=" Uwagi:\n-format JPEG w plikach OPUS nie jest wspierany \n-mieszana kolekcja plików zakodowanych rożnymi kodekami w kontenerach OGG jest co prawda możliwa,\n jednak skrypt może zachowywać się niestabilnie\n"+txt)
|
|
505 box = self.get_content_area()
|
|
506 box.add(label1)
|
|
507 box.add(label2)
|
|
508 self.show_all()
|
|
509
|
|
510 class DialogAbout(Gtk.Dialog):
|
|
511 def __init__(self, parent):
|
|
512 Gtk.Dialog.__init__(self, title="O Programie", transient_for=parent, flags=0)
|
|
513 self.props.border_width = 20
|
|
514 self.add_buttons(
|
|
515 Gtk.STOCK_OK, Gtk.ResponseType.OK
|
|
516 )
|
|
517
|
|
518 self.set_default_size(150, 100)
|
|
519
|
|
520 label = Gtk.Label(label="\tAplikacja napisana na podstawie:\n\nhttps://python-gtk-3-tutorial.readthedocs.io/\n\n\t\t\tWersja: 0.1-3\n\n\t\tPrzemysław R. Pietraszczyk\n\n\t\t\tKwiecień/Maj 2021\n\t\t\tLicencja: GPL\n\n")
|
|
521 #label3 = Gtk.Label(label="-jednak samo załadownie obrazka do pliku nie gwarantuje, że zmieni się ikona w menedżerze plików.\n W tym względzie są przyjazne menedżery takie jak PCManFM, jak i nie przyjazne jak Nemo.\n Jednak w graficznym odtwarzaczu, załadowany obrazek powinien pojawić się zawsze.\n\n")
|
|
522
|
|
523 box = self.get_content_area()
|
|
524 box.add(label)
|
|
525
|
|
526 button = Gtk.LinkButton("http://www.prp.xlx.pl", label="Strona Domowa")
|
|
527 box.add(button)
|
|
528
|
|
529 self.show_all()
|
|
530
|
|
531 class DialogNoSelectIMG(Gtk.Dialog):
|
|
532 def __init__(self, parent):
|
|
533 Gtk.Dialog.__init__(self, title="Błąd", transient_for=parent, flags=0)
|
|
534 self.props.border_width = 20
|
|
535 self.add_buttons(
|
|
536 Gtk.STOCK_OK, Gtk.ResponseType.OK
|
|
537 )
|
|
538
|
|
539 self.set_default_size(150, 100)
|
|
540
|
|
541 label = Gtk.Label(label="Nie wybrano żadnego pliku z muzyką!\n")
|
|
542
|
|
543 box = self.get_content_area()
|
|
544 box.add(label)
|
|
545
|
|
546 self.show_all()
|
|
547
|
|
548 def get_resource_path(rel_path):
|
|
549 dir_of_py_file = os.path.dirname(__file__)
|
|
550 rel_path_to_resource = os.path.join(dir_of_py_file, rel_path)
|
|
551 abs_path_to_resource = os.path.abspath(rel_path_to_resource)
|
|
552 return abs_path_to_resource
|
|
553
|
|
554
|
|
555 grid = Gtk.Grid()
|
|
556
|
|
557
|
|
558 class MyWindow(Gtk.Window):
|
|
559
|
|
560 def __init__(self):
|
|
561 super().__init__()
|
|
562
|
|
563 self.init_ui()
|
|
564
|
|
565
|
|
566 def init_ui(self):
|
|
567 global grid, file_img_selected, snd_extension
|
|
568 self.image_new=None
|
|
569 #grid = Gtk.Grid()
|
|
570 self.props.border_width = 20
|
|
571 #self.img_extension="png" # dla przykladu
|
|
572 #snd_extension="ogg"
|
|
573
|
|
574 self.add(grid)
|
|
575
|
|
576 grid.set_row_spacing(10)
|
|
577 grid.set_column_spacing(10)
|
|
578 grid.set_column_homogeneous(True) # rozszerza kontrolke z utworami na resztę okna
|
|
579
|
|
580 action_group = Gtk.ActionGroup(name="my_actions")
|
|
581
|
|
582 self.add_file_menu_actions(action_group)
|
|
583 self.add_info_menu_actions(action_group)
|
|
584 self.add_choices_menu_actions(action_group)
|
|
585
|
|
586 uimanager = self.create_ui_manager()
|
|
587 uimanager.insert_action_group(action_group)
|
|
588
|
|
589 menubar = uimanager.get_widget("/MenuBar")
|
|
590
|
|
591 box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
592 box.pack_start(menubar, False, False, 0)
|
|
593
|
|
594 grid.attach(box, 0, 0, 2, 1)
|
|
595 file_img_selected=get_resource_path(COVER)
|
|
596 pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
|
|
597 filename=file_img_selected,
|
|
598 width=100,
|
|
599 height=100,
|
|
600 preserve_aspect_ratio=True)
|
|
601
|
|
602 self.image = Gtk.Image.new_from_pixbuf(pixbuf)
|
|
603 grid.attach(self.image,0,1,1,1)
|
|
604
|
|
605 quitBtn = Gtk.Button(label="Wykonaj !")
|
|
606 quitBtn.set_size_request(60, 30)
|
|
607
|
|
608 quitBtn.connect("clicked", self.on_button_clicked)
|
|
609
|
|
610 grid.attach(quitBtn, 0, 2, 1, 1) # lewo, top wielkosc, wysokosc
|
|
611
|
|
612 self.liststore = Gtk.ListStore(str, str)
|
|
613 self.treeview = Gtk.TreeView(model=self.liststore)
|
|
614
|
|
615 self.renderer_text = Gtk.CellRendererText()
|
|
616 self.column_text = Gtk.TreeViewColumn("Wybrane Utwory", self.renderer_text, text=0)
|
|
617 self.treeview.append_column(self.column_text)
|
|
618
|
|
619 self.scrolled_window = Gtk.ScrolledWindow ()
|
|
620 self.scrolled_window.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
|
|
621
|
|
622 self.scrolled_window.add (self.treeview)
|
|
623 grid.attach_next_to(self.scrolled_window, self.image ,Gtk.PositionType.RIGHT,6,2)
|
|
624
|
|
625 self.set_border_width(10)
|
|
626 self.set_title("Cover2Music")
|
|
627 self.set_default_size(650, 180)
|
|
628 self.connect("destroy", Gtk.main_quit)
|
|
629
|
|
630 self.set_icon_from_file(get_resource_path(COVER))
|
|
631
|
|
632 def on_button_clicked(self, widget):
|
|
633 global file_img_selected, snd_extension
|
|
634
|
|
635 if len(file_snd_selected)<1:
|
|
636 print("nie zaznaczyleś żadnego pliku z muzyką !")
|
|
637 dialog = DialogNoSelectIMG(self)
|
|
638 response = dialog.run()
|
|
639 dialog.destroy()
|
|
640 return
|
|
641
|
|
642
|
|
643 progress =DialogAddCoverProgress(self)
|
|
644 response = progress.run()
|
|
645 progress.destroy()
|
|
646
|
|
647
|
|
648 def add_info_menu_actions(self, action_group):
|
|
649 action_info_menu = Gtk.Action(name="InfoMenu", label="Info")
|
|
650 action_group.add_action(action_info_menu)
|
|
651
|
|
652 action_new = Gtk.Action(
|
|
653 name="Help",
|
|
654 label="Pomoc",
|
|
655 tooltip="Create a new file",
|
|
656 )
|
|
657 action_new.connect("activate", self.on_menu_help)
|
|
658 action_group.add_action_with_accel(action_new, None)
|
|
659
|
|
660 action_new = Gtk.Action(
|
|
661 name="About",
|
|
662 label="O Programie",
|
|
663 tooltip="Create a new file",
|
|
664 )
|
|
665 action_new.connect("activate", self.on_menu_about)
|
|
666 action_group.add_action_with_accel(action_new, None)
|
|
667
|
|
668 def add_file_menu_actions(self, action_group):
|
|
669 action_filemenu = Gtk.Action(name="FileMenu", label="Plik")
|
|
670 action_group.add_action(action_filemenu)
|
|
671
|
|
672 action_fileloadmenu = Gtk.Action(name="FileLoad", stock_id=Gtk.STOCK_NEW)
|
|
673 action_group.add_action(action_fileloadmenu)
|
|
674
|
|
675 action_new = Gtk.Action(
|
|
676 name="LoadImg",
|
|
677 label="Załaduj okladkę",
|
|
678 tooltip="Wybór okladki",
|
|
679 )
|
|
680 action_new.connect("activate", self.on_menu_file_load_img_generic)
|
|
681 action_group.add_action_with_accel(action_new, None)
|
|
682
|
|
683
|
|
684 action_new = Gtk.Action(
|
|
685 name="LoadOgg",
|
|
686 label="Załaduj muzykę",
|
|
687 tooltip="Wybór muzyki",
|
|
688 )
|
|
689 action_new.connect("activate", self.on_menu_file_load_ogg_generic)
|
|
690 action_group.add_action_with_accel(action_new, None)
|
|
691
|
|
692 action_fileloadmenu = Gtk.Action(name="FileDelete", label="Usuń", stock_id=None)
|
|
693 action_group.add_action(action_fileloadmenu)
|
|
694
|
|
695 action_new = Gtk.Action(
|
|
696 name="RemoveCover",
|
|
697 label="Usuwa okladkę",
|
|
698 tooltip="Usuwa okladkę z pliku",
|
|
699 )
|
|
700 action_new.connect("activate", self.on_menu_file_erase_cover_all)
|
|
701 action_group.add_action_with_accel(action_new, None)
|
|
702
|
|
703
|
|
704 action_filequit = Gtk.Action(name="FileQuit", stock_id=Gtk.STOCK_QUIT)
|
|
705 action_filequit.connect("activate", self.on_menu_file_quit)
|
|
706 action_group.add_action(action_filequit)
|
|
707
|
|
708 def add_choices_menu_actions(self, action_group):
|
|
709 action_group.add_action(Gtk.Action(name="ChoicesMenu", label="Opcje"))
|
|
710
|
|
711 three = Gtk.ToggleAction(name="ChoiceTree", label="Pozwolenie")
|
|
712 three.connect("toggled", self.on_menu_choices_toggled)
|
|
713 action_group.add_action(three)
|
|
714
|
|
715 # tworzy menu bar
|
|
716 def create_ui_manager(self):
|
|
717 uimanager = Gtk.UIManager()
|
|
718
|
|
719 # Throws exception if something went wrong
|
|
720 uimanager.add_ui_from_string(UI_INFO)
|
|
721
|
|
722 # Add the accelerator group to the toplevel window
|
|
723 accelgroup = uimanager.get_accel_group()
|
|
724 self.add_accel_group(accelgroup)
|
|
725 return uimanager
|
|
726
|
|
727 def on_menu_help(self, widget):
|
|
728 dialog = DialogHelp(self)
|
|
729 response = dialog.run()
|
|
730
|
|
731 dialog.destroy()
|
|
732
|
|
733 def on_menu_about(self, widget):
|
|
734 dialog = DialogAbout(self)
|
|
735 response = dialog.run()
|
|
736
|
|
737 dialog.destroy()
|
|
738
|
|
739
|
|
740 def on_menu_file_load_img_generic(self, widget):
|
|
741 global grid, file_img_selected, img_extension
|
|
742
|
|
743 print("A File|New menu item was selected.")
|
|
744 file=FileChooserIMG()
|
|
745 print ("file:"+str(file_img_selected))
|
|
746 pixbuf_new = GdkPixbuf.Pixbuf.new_from_file_at_scale(
|
|
747 filename=file_img_selected,
|
|
748 width=100,
|
|
749 height=100,
|
|
750 preserve_aspect_ratio=True)
|
|
751
|
|
752 if self.image != None:
|
|
753 grid.remove(self.image)
|
|
754 self.image=None
|
|
755 else:
|
|
756 grid.remove(self.image_new)
|
|
757
|
|
758
|
|
759 # TODO - pozbyć się self.image_new na rzecz self.image
|
|
760 self.image_new = Gtk.Image.new_from_pixbuf(pixbuf_new)
|
|
761 grid.attach_next_to(self.image_new, self.scrolled_window,Gtk.PositionType.LEFT,1,1)
|
|
762
|
|
763 self.show_all()
|
|
764
|
|
765 extension = os.path.splitext(file_img_selected)
|
|
766 #self.img_extension=extension[1].replace(".", "") # tupla (0) wskazuje na nazwe pliku !
|
|
767 img_extension=extension[1].replace(".", "") # tupla (0) wskazuje na nazwe pliku !
|
|
768
|
|
769
|
|
770 def on_menu_file_load_ogg_generic(self, widget):
|
|
771 global file_snd_selected
|
|
772 file=FileChooserOgg()
|
|
773 #grid.remove(self.treeview)
|
|
774 self.scrolled_window.remove(self.treeview)
|
|
775 grid.remove(self.scrolled_window)
|
|
776 self.liststore = Gtk.ListStore(str, str)
|
|
777 self.treeview.remove_column(self.column_text)
|
|
778
|
|
779 print ("file selected: ",file_snd_selected)
|
|
780
|
|
781 for o in file_snd_selected:
|
|
782 self.liststore.append([o,""])
|
|
783
|
|
784 self.scrolled_window = Gtk.ScrolledWindow ()
|
|
785 self.scrolled_window.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
|
|
786
|
|
787 self.treeview = Gtk.TreeView(model=self.liststore)
|
|
788 self.renderer_text = Gtk.CellRendererText()
|
|
789 self.column_text = Gtk.TreeViewColumn("Wybrane Utwory", self.renderer_text, text=0)
|
|
790 self.treeview.append_column(self.column_text)
|
|
791
|
|
792 if self.image != None:
|
|
793 self.scrolled_window.add (self.treeview)
|
|
794 grid.attach_next_to(self.scrolled_window, self.image ,Gtk.PositionType.RIGHT,6,2)
|
|
795 else:
|
|
796 self.scrolled_window.add (self.treeview)
|
|
797 grid.attach_next_to(self.scrolled_window, self.image_new ,Gtk.PositionType.RIGHT,6,2)
|
|
798
|
|
799 self.show_all()
|
|
800 """
|
|
801 def close_progress(self, gparmstring):
|
|
802 self.progress.destroy()
|
|
803 """
|
|
804 def on_menu_file_erase_cover_all(self, widget):
|
|
805
|
|
806 if len(file_snd_selected)<1:
|
|
807 dialog = DialogNoSelectIMG(self)
|
|
808 response = dialog.run()
|
|
809 dialog.destroy()
|
|
810 return
|
|
811
|
|
812 self.progress =DialogDeleteProgress(self)
|
|
813 response = self.progress.run()
|
|
814 self.progress.destroy()
|
|
815
|
|
816
|
|
817 def on_menu_file_quit(self, widget):
|
|
818 Gtk.main_quit()
|
|
819
|
|
820 def on_menu_choices_toggled(self, widget):
|
|
821 if widget.get_active():
|
|
822 print(widget.get_name() + " activated")
|
|
823 else:
|
|
824 print(widget.get_name() + " deactivated")
|
|
825
|
|
826 def on_button_press_event(self, widget, event):
|
|
827 # Check if right mouse button was preseed
|
|
828 if event.type == Gdk.EventType.BUTTON_PRESS and event.button == 3:
|
|
829 self.popup.popup(None, None, None, None, event.button, event.time)
|
|
830 return True # event has been handled
|
|
831
|
|
832
|
|
833 win = MyWindow()
|
|
834 win.show_all()
|
|
835 Gtk.main()
|