class IPUscribe( wx.Panel ): """ Create the whole IPUscribe panel. """ def __init__(self, parent, prefsIO): """ Create a new instance. """ wx.Panel.__init__(self, parent, -1, style=wx.NO_BORDER) sizer = wx.BoxSizer( wx.VERTICAL ) # members self._prefsIO = self._check_prefs(prefsIO) self._current_page = 0 self._sndname = None # a set of panels: self._txtinfo = wx.StaticText(self, -1, "", style=wx.ALIGN_LEFT) self._trsPanel = IPUscribeData(self, prefsIO) self._create_media() self._create_nav() sizer.Add(self._txtinfo, proportion=0, flag=wx.ALL|wx.EXPAND, border=8 ) sizer.Add(self._trsPanel, proportion=1, flag=wx.ALL|wx.EXPAND, border=2 ) sizer.Add(self._mediaPanel, proportion=0, flag=wx.ALL|wx.EXPAND, border=2 ) sizer.Add(self._navPanel, proportion=0, flag=wx.ALL|wx.EXPAND, border=2) # Bind events self.Bind(spEVT_FILE_WANDER, self.OnFileWander) self.Bind(wx.EVT_SET_FOCUS, self.OnFocus) self.GetTopLevelParent().Bind(wx.EVT_CHAR_HOOK, self.OnKeyPress) self.SetSizer(sizer) self.SetAutoLayout( True ) self.Layout() self.SetBackgroundColour( self._prefsIO.GetValue('M_BG_COLOUR') ) self.SetForegroundColour( self._prefsIO.GetValue('M_FG_COLOUR') ) self.SetFont( self._prefsIO.GetValue('M_FONT') ) # ---------------------------------------------------------------------- def __create_button(self, bmp): """ Create a button and add it to the sizer. - bmp is a picture file name """ btn = platebtn.PlateButton(self._navPanel, -1, bmp=spBitmap(bmp, 24, theme=self._prefsIO.GetValue('M_ICON_THEME'))) btn.SetInitialSize() btn.SetPressColor(wx.LIGHT_GREY) btn.Enable( True ) return btn #---------------------------------------------------------------------- def _create_media(self): """ Create the media panel. """ self._mediaPanel = SndPlayer(self, orient=wx.HORIZONTAL, refreshtimer=10, prefsIO=self._prefsIO) self._mediaPanel.SetPreferences(self._prefsIO) self._mediaPanel.ActivateButtons(False) #---------------------------------------------------------------------- def _create_nav(self): """ Create the page-navigation panel. """ self._navPanel = wx.Panel(self) s = wx.BoxSizer( wx.HORIZONTAL ) # Number of IPUs by page self._infoipus = wx.StaticText(self._navPanel, -1, label="IPUs by page: ") self._textpage = wx.TextCtrl(self._navPanel, -1, value=str(IPU_BY_PAGE)) self._spinpage = wx.SpinButton(self._navPanel, style=wx.SP_VERTICAL) self._spinpage.SetRange(20, 300) self._spinpage.SetValue(IPU_BY_PAGE) # Buttons to change the page self._buttons = {} self._buttons['apply'] = self.__create_button(APPLY_ICON) self._buttons['first'] = self.__create_button(PAGE_FIRST_ICON) self._buttons['prev'] = self.__create_button(PAGE_PREV_ICON) self._buttons['next'] = self.__create_button(PAGE_NEXT_ICON) self._buttons['last'] = self.__create_button(PAGE_LAST_ICON) # Text to indicate the current page self._footer = wx.StaticText(self._navPanel, -1, "") self.__set_footer() s.Add(self._infoipus, 0, wx.ALL|wx.CENTER) s.Add(self._textpage, 0, wx.ALL|wx.CENTER) s.Add(self._spinpage, 0, wx.ALL|wx.CENTER) s.Add(self._buttons['apply'], proportion=0, flag=wx.ALL, border=2) s.AddStretchSpacer() s.Add(self._buttons['first'], proportion=0, flag=wx.ALL, border=2) s.Add(self._buttons['prev'], proportion=0, flag=wx.ALL, border=2) s.Add(self._buttons['next'], proportion=0, flag=wx.ALL, border=2) s.Add(self._buttons['last'], proportion=0, flag=wx.ALL, border=2) s.AddStretchSpacer() s.Add(self._footer, 0, wx.ALL, 6) self.Bind(wx.EVT_SPIN, self.OnSpinPage, self._spinpage) self._buttons['apply'].Bind(wx.EVT_BUTTON, self.OnChangeIPUbyPage) self._buttons['first'].Bind(wx.EVT_BUTTON, self.OnFirstPage) self._buttons['prev'].Bind(wx.EVT_BUTTON, self.OnPrevPage) self._buttons['next'].Bind(wx.EVT_BUTTON, self.OnNextPage) self._buttons['last'].Bind(wx.EVT_BUTTON, self.OnLastPage) self._navPanel.SetSizer(s) # ---------------------------------------------------------------------- def __set_footer(self): """ Set the label of the footer. """ pagenb = "---" if self._current_page: pagenb = str(self._current_page) pagetotal = "---" if self._trsPanel.GetPageCount(): pagetotal = str(self._trsPanel.GetPageCount()) self._footer.SetLabel(" Page %s / %s " % (pagenb, pagetotal)) # ---------------------------------------------------------------------- def _check_prefs(self, prefs): """ Check if preferences are set properly. Set new ones if required. Return the new version. """ if prefs is None: prefs = Preferences( BaseTheme() ) else: try: a = prefs.GetValue( 'M_BG_COLOUR' ) a = prefs.GetValue( 'M_FG_COLOUR' ) a = prefs.GetValue( 'M_FONT' ) a = prefs.GetValue( 'M_ICON_THEME' ) except Exception: self._prefsIO.SetTheme( BaseTheme() ) prefs = self._prefsIO prefs.SetValue('SND_AUTOREPLAY', 'bool', True) prefs.SetValue('SND_INFO', 'bool', True) prefs.SetValue('SND_PLAY', 'bool', True) prefs.SetValue('SND_PAUSE', 'bool', True) prefs.SetValue('SND_STOP', 'bool', True) prefs.SetValue('SND_NEXT', 'bool', False) prefs.SetValue('SND_REWIND', 'bool', False) return prefs # ---------------------------------------------------------------------- # Callbacks... Page navigation # ---------------------------------------------------------------------- def OnFirstPage(self, evt=None): """ Load the first page, except if the current page is already the first one! """ if self._current_page > 1: self._current_page = self._trsPanel.LoadPage(1) self.__set_footer() self._trsPanel.KillFocus() self._mediaPanel.SetOffsetPeriod(0,0) # ---------------------------------------------------------------------- def OnLastPage(self, evt=None): """ Load the last page, except if the current page is already the last one! """ if self._current_page < self._trsPanel.GetPageCount(): self._current_page = self._trsPanel.LoadPage(self._trsPanel.GetPageCount()) self.__set_footer() self._trsPanel.KillFocus() self._mediaPanel.SetOffsetPeriod(0,0) # ---------------------------------------------------------------------- def OnPrevPage(self, evt=None): """ Load the previous page, except if the current page is the first one!. """ if self._current_page > 1: self._current_page = self._trsPanel.LoadPage(self._current_page-1) self.__set_footer() self._trsPanel.KillFocus() self._mediaPanel.SetOffsetPeriod(0,0) # ---------------------------------------------------------------------- def OnNextPage(self, evt=None): """ Load the next page, except if the current page is the last one. """ if self._current_page < self._trsPanel.GetPageCount(): self._current_page = self._trsPanel.LoadPage(self._current_page+1) self.__set_footer() self._trsPanel.KillFocus() self._mediaPanel.SetOffsetPeriod(0,0) # ---------------------------------------------------------------------- def OnSpinPage(self, evt): """ Update the text about the number of IPUs by page. """ self._textpage.SetValue(str(evt.GetPosition())) # ---------------------------------------------------------------------- def OnChangeIPUbyPage(self, evt): """ Change the IPU_BY_PAGE value. """ try: v = int(self._textpage.GetValue()) except Exception: v = -1 if v <= 0: self._textpage.SetValue(str(IPU_BY_PAGE)) self._spinpage.SetValue(IPU_BY_PAGE) v = IPU_BY_PAGE self._current_page = self._trsPanel.SetState(ipu_by_page=v) self.__set_footer() # ------------------------------------------------------------------------ def OnFocus(self, event): """ An IPU received the focus. """ obj = event.GetEventObject() if obj != self._trsPanel: return self._mediaPanel.FileSelected( self._sndname ) (s,e) = self._trsPanel.GetSelectionStartEnd() self._mediaPanel.SetOffsetPeriod( int(s),int(e) ) # ---------------------------------------------------------------------- # Functions... # ---------------------------------------------------------------------- def Save(self): """ Save the transcription. """ self._trsPanel.Save() # ---------------------------------------------------------------------- def SetFont(self, font): """ Change font of all texts. """ wx.Window.SetFont( self,font ) # Apply on all panels self._trsPanel.SetFont( font ) self._mediaPanel.SetFont( font ) self._navPanel.SetFont( font ) self._infoipus.SetFont( font ) self._textpage.SetFont( font ) self._footer.SetFont( font ) self._txtinfo.SetFont( font ) # ---------------------------------------------------------------------- def SetBackgroundColour(self, color): """ Change background of all panels. """ wx.Window.SetBackgroundColour( self,color ) # Apply as background on all panels self._trsPanel.SetBackgroundColour( color ) self._mediaPanel.SetBackgroundColour( color ) self._navPanel.SetBackgroundColour( color ) self._infoipus.SetBackgroundColour( color ) self._textpage.SetBackgroundColour( color ) self._spinpage.SetBackgroundColour( color ) self._footer.SetBackgroundColour( color ) self._txtinfo.SetBackgroundColour( color ) # ---------------------------------------------------------------------- def SetForegroundColour(self, color): """ Change foreground of all panels. """ wx.Window.SetForegroundColour( self,color ) # Apply as foreground on all panels self._trsPanel.SetForegroundColour( color ) self._mediaPanel.SetForegroundColour( color ) self._navPanel.SetForegroundColour( color ) self._infoipus.SetForegroundColour( color ) self._textpage.SetForegroundColour( color ) self._spinpage.SetForegroundColour( color ) self._footer.SetForegroundColour( color ) self._txtinfo.SetForegroundColour( color ) # ---------------------------------------------------------------------- # Callbacks # ---------------------------------------------------------------------- def OnFileWander(self, event): """ A file was selected/unselected. """ f = event.filename s = event.status if s is True: self.FileSelected( f ) else: self.FileDeSelected() # ---------------------------------------------------------------------- # Data Management # ---------------------------------------------------------------------- def exists(self, filename): for x in os.listdir( os.path.dirname(filename)): try: if os.path.basename(filename.lower()) == x.lower(): return os.path.join(os.path.dirname(filename),x) except Exception: pass return None # ---------------------------------------------------------------------- def FileSelected(self, filename): """ Add files. """ got = False name = os.path.splitext(filename)[0] for ext in annotationdata.io.extensions: if ext in [ '.pitchtier', '.hz', '.txt']: continue f = self.exists( name+ext ) if got is False and f is not None: # create the object r = self._trsPanel.SetData(filename, f) if r is True: self._txtinfo.SetLabel("Transcription file: "+f) self._current_page = self._trsPanel.LoadPage(1) # show the current page and the total amount of pages at the bottom of the window self.__set_footer() self.Layout() got = True else: self._trsPanel.UnsetData() self._sndname = filename if got is False: ShowInformation(self, self._prefsIO, "Missing IPUs: A file with an IPUs segmentation is required.", wx.ICON_ERROR) self.FileDeSelected() return # ------------------------------------------------------------------------ def FileDeSelected(self): """ Remove the file. """ if self._trsPanel._dirty is True: # dlg to ask to save or not userChoice = ShowYesNoQuestion( None, self._prefsIO, "Do you want to save changes on the transcription of audio file %s?"%self._sndname) if userChoice == wx.ID_YES: self._trsPanel.Save() try: self._trsPanel.UnsetData() self._current_page = 0 self._txtinfo.SetLabel("") self._mediaPanel.FileDeSelected() self._mediaPanel.onClose(None) except Exception as e: logging.debug('ERROR for file %s: %s'%(self._sndname,str(e))) evt = FileWanderEvent(filename=self._sndname, status=False) evt.SetEventObject(self) wx.PostEvent( self.GetParent().GetParent().GetParent(), evt ) self._sndname = None # ------------------------------------------------------------------------ def OnKeyPress(self, event): """ Respond to a keypress event. """ keycode = event.GetKeyCode() # Media player # TAB -> PLay # F7 -> Pause # ESC -> Stop if keycode == wx.WXK_TAB: self._mediaPanel.onPlay( event ) elif keycode == wx.WXK_F6: self._mediaPanel.onRewind( event ) elif keycode == wx.WXK_F7: self._mediaPanel.onPause( event ) elif keycode == wx.WXK_F8: self._mediaPanel.onNext( event ) elif keycode == wx.WXK_ESCAPE: self._mediaPanel.onStop( event ) else: event.Skip()
def onPause(self, event): """ Pauses the music. """ SndPlayer.onPause(self,event) self.UpdateRuler()
class SndRoamer( scrolled.ScrolledPanel ): """ @author: Brigitte Bigi @organization: Laboratoire Parole et Langage, Aix-en-Provence, France @contact: [email protected] @license: GPL, v3 @copyright: Copyright (C) 2011-2016 Brigitte Bigi @summary: Manage audio files. Panel to manage audio files: - show information, - manage the content of the audio, - play. """ def __init__(self, parent, prefsIO): """ SndRoamer Component ScrolledPanel. """ scrolled.ScrolledPanel.__init__(self, parent, -1) # members self._prefsIO = self._check_prefs(prefsIO) self._filename = None # GUI sizer = self._create_content() # Bind events self.Bind(spEVT_FILE_WANDER, self.OnFileWander) self.Bind(spEVT_SETTINGS, self.OnSettings) self.GetTopLevelParent().Bind(wx.EVT_CHAR_HOOK, self.OnKeyPress) self.SetBackgroundColour( self._prefsIO.GetValue('M_BG_COLOUR')) self.SetSizer(sizer) self.SetAutoLayout( True ) self.Layout() self.SetupScrolling() # ---------------------------------------------------------------------- def _create_content(self): """ GUI design. """ sizer = wx.BoxSizer( wx.VERTICAL ) # create the panels self._propertyPanel = AudioInfo(self, self._prefsIO) self._managerPanel = AudioRoamer(self, self._prefsIO) self._playerPanel = SndPlayer(self, prefsIO=self._prefsIO) sizer.Add(self._managerPanel, proportion=0, flag=wx.CENTRE|wx.ALL, border=2 ) sizer.Add(self._propertyPanel, proportion=0, flag=wx.LEFT|wx.EXPAND|wx.ALL, border=2 ) sizer.Add(self._playerPanel, proportion=1, flag=wx.CENTRE|wx.ALL, border=2 ) return sizer # ---------------------------------------------------------------------- def _check_prefs(self, prefs): """ Check if preferences are set properly. Set new ones if required. Return the new version. """ if prefs is None: prefs = Preferences( BaseTheme() ) else: try: prefs.GetValue( 'M_BG_COLOUR' ) prefs.GetValue( 'M_FG_COLOUR' ) prefs.GetValue( 'M_FONT' ) prefs.GetValue( 'M_ICON_THEME' ) except Exception: self._prefsIO.SetTheme( BaseTheme() ) prefs = self._prefsIO prefs.SetValue('SND_INFO', 'bool', False) prefs.SetValue('SND_PLAY', 'bool', True) prefs.SetValue('SND_AUTOREPLAY', 'bool', False) prefs.SetValue('SND_PAUSE', 'bool', True) prefs.SetValue('SND_STOP', 'bool', True) prefs.SetValue('SND_NEXT', 'bool', True) prefs.SetValue('SND_REWIND', 'bool', True) prefs.SetValue('SND_EJECT', 'bool', True) return prefs # ---------------------------------------------------------------------- # GUI # ---------------------------------------------------------------------- def OnSettings(self, event): """ Set new preferences, then apply them. """ self._prefsIO = self._check_prefs( event.prefsIO ) # Apply the changes on self self.SetBackgroundColour( self._prefsIO.GetValue( 'M_BG_COLOUR' ) ) self.SetForegroundColour( self._prefsIO.GetValue( 'M_FG_COLOUR' ) ) self.SetFont( self._prefsIO.GetValue( 'M_FONT' ) ) self._managerPanel.SetPreferences( self._prefsIO ) self.Layout() self.Refresh() # ---------------------------------------------------------------------- def SetFont(self, font): """ Change font of all wx texts. """ wx.Window.SetFont( self, font ) self._propertyPanel.SetFont( font ) self._playerPanel.SetFont( font ) # ---------------------------------------------------------------------- def SetBackgroundColour(self, color): """ Change background of all texts. """ wx.Window.SetBackgroundColour( self, color ) self._propertyPanel.SetBackgroundColour( color ) self._playerPanel.SetBackgroundColour( color ) # ---------------------------------------------------------------------- def SetForegroundColour(self, color): """ Change foreground of all texts. """ wx.Window.SetForegroundColour( self, color ) self._propertyPanel.SetForegroundColour( color ) self._playerPanel.SetForegroundColour( color ) # ---------------------------------------------------------------------- # Callbacks # ---------------------------------------------------------------------- def OnFileWander(self, event): """ A file was checked/unchecked/ejected somewhere else. """ o = event.GetEventObject() if o == self._playerPanel: evt = NotebookClosePageEvent() evt.SetEventObject(self) wx.PostEvent( self.GetParent().GetParent().GetParent(),evt ) self._propertyPanel.FileDeSelected() return f = event.filename s = event.status if s is True: self._propertyPanel.FileSelected( f ) self._playerPanel.FileSelected( f ) self._managerPanel.FileSelected( f ) self._filename = f else: self._propertyPanel.FileDeSelected() self._playerPanel.FileDeSelected() self._managerPanel.FileDeSelected( f ) evt = FileWanderEvent(filename=self._filename, status=False) evt.SetEventObject(self) wx.PostEvent( self.GetParent().GetParent().GetParent(), evt ) self._filename = None # ---------------------------------------------------------------------- def OnKeyPress(self, event): """ Respond to a keypress event. """ keycode = event.GetKeyCode() # Media player # TAB -> PLay # F6 -> Rewind # F7 -> Pause/Play # F8 -> Next # F12 -> Eject # ESC -> Stop if keycode == wx.WXK_TAB: self._playerPanel.onPlay( event ) elif keycode == wx.WXK_F6: self._playerPanel.onRewind( event ) elif keycode == wx.WXK_F7: self._playerPanel.onPause( event ) elif keycode == wx.WXK_F8: self._playerPanel.onNext( event ) elif keycode == wx.WXK_F12: self._playerPanel.onEject( event ) elif keycode == wx.WXK_ESCAPE: self._playerPanel.onStop( event ) else: event.Skip()