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(sppasTheme()) 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(sppasTheme()) 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
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() else: try: bg = prefs.GetValue('M_BG_COLOUR') fg = prefs.GetValue('M_FG_COLOUR') font = prefs.GetValue('M_FONT') except Exception: self._prefsIO.SetTheme(sppasTheme()) try: mult = prefs.GetValue('F_CCB_MULTIPLE') except Exception: prefs.SetValue( 'F_CCB_MULTIPLE', t='bool', v=True, text= 'Allow to check/uncheck multiple files in the file manager.') try: space = prefs.GetValue('F_SPACING') except Exception: prefs.SetValue('F_SPACING', t='int', v=2, text='Space before each item of the file manager.') return prefs
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(sppasTheme()) 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(sppasTheme()) return prefs
class TrsList(wx.Panel): """ :author: Brigitte Bigi :organization: Laboratoire Parole et Langage, Aix-en-Provence, France :contact: [email protected] :license: GPL, v3 :copyright: Copyright (C) 2011-2018 Brigitte Bigi :summary: Show data about transcriptions, in a panel including a list of tiers. """ def __init__(self, parent, filename, trs=None, multiple=False): wx.Panel.__init__(self, parent, -1, size=wx.DefaultSize) # initialize the GUI self._prefs = Preferences() self._filename = filename self._dirty = False # the transcription was changed self._selected = False # the transcription is selected self._protected = [ ] # list of the tiers that are protected (can't be modified) if len(filename) == 0: self._filename = "Empty" boxtitle = self._create_title() self.tier_list = self._create_list(multiple) # load the Transcription if trs is None and len(filename) != 0: self.LoadFile(filename) else: self._transcription = trs # add Transcription information in the list for i in range(self._transcription.GetSize()): self.SetTierProperties(i) self._checksize() # events self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnListItemSelected, self.tier_list) self.Bind(wx.EVT_LIST_COL_CLICK, self.OnListItemSelected, self.tier_list) # layout sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(boxtitle, 0, wx.EXPAND | wx.ALL, border=4) sizer.Add(self.tier_list, 1, wx.EXPAND | wx.ALL, border=4) self.SetFont(self._prefs.GetValue('M_FONT')) self.SetForegroundColour(self._prefs.GetValue('M_FG_COLOUR')) self.SetBackgroundColour(self._prefs.GetValue('M_BG_COLOUR')) self._boxtitle.SetForegroundColour(FG_FILE_COLOUR) self.SetSizerAndFit(sizer) self.SetAutoLayout(True) self.Layout() # ---------------------------------------------------------------------- def _create_title(self): """ Create the title of the panel. """ _sizer = wx.BoxSizer(wx.HORIZONTAL) self._static_tx = wx.TextCtrl(self, -1, "File: ", style=wx.TE_READONLY | wx.NO_BORDER) self._boxtitle = wx.TextCtrl(self, -1, self._filename, style=wx.TE_READONLY | wx.NO_BORDER) _sizer.Add(self._static_tx, 0, wx.RIGHT, border=2) _sizer.Add(self._boxtitle, 1, wx.EXPAND) return _sizer # ---------------------------------------------------------------------- def _create_list(self, multiple=False): """ Create the list to show information of a each tier of a transcription. """ if multiple: tier_list = CheckListCtrl(self, -1, style=wx.LC_REPORT | wx.BORDER_NONE) else: tier_list = CheckListCtrl(self, -1, style=wx.LC_REPORT | wx.BORDER_NONE | wx.LC_SINGLE_SEL) # Add all columns col_names = [ " Nb ", " Name ", " Begin ", " End ", " Type ", " Size " ] for i, n in enumerate(col_names): tier_list.InsertColumn(i, n) # Fix column width for i in range(len(col_names)): tier_list.SetColumnWidth(i, wx.LIST_AUTOSIZE_USEHEADER) # Enlarge column with tier name tier_list.SetColumnWidth(1, 140) return tier_list # ------------------------------------------------------------------------- def SetTierProperties(self, tier_idx): """ Display tier properties. """ try: tier = self._transcription[tier_idx] if tier.IsPoint() is True: tier_type = "Point" elif tier.IsInterval(): tier_type = "Interval" elif tier.IsDisjoint(): tier_type = "Disjoint" else: tier_type = "Unknown" if tier.IsEmpty() is True: begin = " ... " end = " ... " else: begin = str(tier.GetBeginValue()) end = str(tier.GetEndValue()) self.tier_list.InsertStringItem(tier_idx, "Tier %d" % (tier_idx + 1)) self.tier_list.SetStringItem(tier_idx, 1, tier.GetName()) self.tier_list.SetStringItem(tier_idx, 2, begin) self.tier_list.SetStringItem(tier_idx, 3, end) self.tier_list.SetStringItem(tier_idx, 4, tier_type) self.tier_list.SetStringItem(tier_idx, 5, str(tier.GetSize())) except Exception as e: self.tier_list.InsertStringItem(1, "Error: " + str(e)) # ---------------------------------------------------------------------- # Callbacks... # ---------------------------------------------------------------------- def OnListItemSelected(self, event): """ An item of this panel was clicked. Inform the parent. """ evt = PanelSelectedEvent(panel=self) evt.SetEventObject(self) wx.PostEvent(self.GetParent(), evt) # ---------------------------------------------------------------------- # GUI # ---------------------------------------------------------------------- def SetPreferences(self, prefs): """ Set new preferences. """ self._prefs = prefs self.SetBackgroundColour(self._prefs.GetValue("M_BG_COLOUR")) self.SetForegroundColour(self._prefs.GetValue("M_FG_COLOUR")) self.SetFont(self._prefs.GetValue("M_FONT")) # ------------------------------------------------------------------------- def SetFont(self, font): """ Set a new font. """ wx.Window.SetFont(self, font) self.tier_list.SetFont(font) for i in range(self._transcription.GetSize()): self.tier_list.SetItemFont(i, font) self._static_tx.SetFont(font) self._boxtitle.SetFont(font) self.Layout() # bigger/smaller font can impact on the layout # ------------------------------------------------------------------------- def SetBackgroundColour(self, color): """ Set background. """ wx.Window.SetBackgroundColour(self, color) self.tier_list.SetBackgroundColour(color) for i in range(self._transcription.GetSize()): self.tier_list.SetItemBackgroundColour(i, color) self._static_tx.SetBackgroundColour(color) self._boxtitle.SetBackgroundColour(color) self.Refresh() # ------------------------------------------------------------------------- def SetForegroundColour(self, color): """ Set foreground and items text color. """ wx.Window.SetForegroundColour(self, color) self.tier_list.SetForegroundColour(color) for i in range(self._transcription.GetSize()): self.tier_list.SetItemTextColour(i, color) self._static_tx.SetForegroundColour(color) self.Refresh() # ---------------------------------------------------------------------- # Functions... # ---------------------------------------------------------------------- def Protect(self): """ Fix the current list of tiers as protected: they won't be changed. """ self._protected = [] for i, t in enumerate(self._transcription): self._protected.append(t) self.tier_list.SetItemTextColour(i, wx.Colour(140, 10, 10)) # ------------------------------------------------------------------------- def Unprotect(self): """ Erase the list of protected tiers. """ self._protected = [] # ---------------------------------------------------------------------- def IsSelected(self, tiername, case_sensitive=False): """ Return True if the tier is selected. """ i = self._transcription.GetIndex(tiername, case_sensitive) if i != -1: return self.tier_list.IsSelected(i) return False # ---------------------------------------------------------------------- def Select(self, tiername, case_sensitive=False): """ Select tiers which name is exactly matching. """ i = self._transcription.GetIndex(tiername, case_sensitive) if i != -1: self.tier_list.Select(i, on=True) return True return False # ---------------------------------------------------------------------- def Deselect(self): #for i in range(self.tier_list.GetItemCount()): # self.tier_list.Select(i, on=0) self.tier_list.DeSelectAll() # ---------------------------------------------------------------------- def Rename(self): """ Rename the selected tier. Dialog with the user to get the new name. """ if self._transcription.GetSize() == 0: return # Get the selected tier in the list sellist = self.tier_list.GetFirstSelected() # Nothing selected if sellist == -1: return # Too many selected items if self.tier_list.GetSelectedItemCount() > 1: ShowInformation(self, self._prefs, 'Only one tier has to be checked to be renamed...', style=wx.ICON_INFORMATION) return tier = self._transcription[sellist] if tier in self._protected: ShowInformation(self, self._prefs, "Attempt to rename a protected tier: forbidden!", style=wx.ICON_INFORMATION) return # Ask the user to enter a new name dlg = wx.TextEntryDialog(self, 'Indicate the new tier name', 'Data Roamer', 'Rename a tier.') dlg.SetValue(self._transcription[sellist].GetName()) if dlg.ShowModal() == wx.ID_OK: # Update tier name of the transcription tier.SetName(dlg.GetValue()) # Update tier name of the list self.tier_list.SetStringItem(sellist, 1, dlg.GetValue()) self._dirty = True self._boxtitle.SetForegroundColour(FG_FILE_DIRTY_COLOUR) self.Refresh() dlg.Destroy() # ---------------------------------------------------------------------- def Cut(self): """ Cut the selected tier. Return the clipboard. """ if self._transcription.GetSize() == 0: return # Get the selected tier in the list sellist = self.tier_list.GetFirstSelected() # No tier selected if sellist == -1: return # Too many selected items if self.tier_list.GetSelectedItemCount() > 1: ShowInformation(self, self._prefs, 'One tier must be checked.', style=wx.ICON_INFORMATION) return # Copy the tier to the clipboard tier = self._transcription[sellist] if tier in self._protected: ShowInformation(self, self._prefs, "Attempt to cut a protected tier: forbidden!", style=wx.ICON_INFORMATION) return clipboard = tier.Copy() # Delete tier of the transcription self._transcription.Remove(sellist) # Delete tier of the list self.tier_list.DeleteItem(sellist) # Update tier numbers of next items in the list. for i in range(sellist, self.tier_list.GetItemCount()): self.tier_list.SetStringItem(i, 0, "Tier " + str(i + 1)) self.Deselect() self._checksize() self._dirty = True self._boxtitle.SetForegroundColour(FG_FILE_DIRTY_COLOUR) self.Refresh() return clipboard # ---------------------------------------------------------------------- def Copy(self): """ Return the selected tier. """ if self._transcription.GetSize() == 0: return # Get the selected tier in the list sellist = self.tier_list.GetFirstSelected() if sellist == -1: return # Too many selected items if self.tier_list.GetSelectedItemCount() > 1: ShowInformation(self, self._prefs, "One tier must be checked", style=wx.ICON_INFORMATION) return # Copy the tier to the clipboard tier = self._transcription[sellist] return tier.Copy() # ---------------------------------------------------------------------- def Paste(self, clipboard): """ Paste the clipboard tier to the current page. """ # Get the clipboard tier if clipboard is None: return # Append clipboard to the transcription tier = clipboard #.Copy() self.Append(tier) # The tier comes from another Transcription... must update infos. if not (tier.GetTranscription() is self._transcription): # parent transcription tier.SetTranscription(self._transcription) # And if CtrlVocab... # TODO self._checksize() # ---------------------------------------------------------------------- def Delete(self): """ Delete the selected tier. Dialog with the user to confirm. """ if self._transcription.GetSize() == 0: return 0 # Get the selected tier in the list of this page sellist = self.tier_list.GetFirstSelected() if sellist == -1: return 0 # Get Indexes of tiers to remove indexes = [] while sellist != -1: indexes.append(sellist) sellist = self.tier_list.GetNextSelected(sellist) # Ask the user to confirm before deleting delete = 0 message = 'Are you sure you want to definitively delete:\n' \ '%d tiers in %s?' % (len(indexes), self._filename) dlg = ShowYesNoQuestion(self, self._prefs, message) if dlg == wx.ID_YES: for sellist in reversed(sorted(indexes)): item = self.tier_list.GetItem(sellist) tier = self._transcription[sellist] if tier in self._protected: pass else: # Delete tier of the transcription self._transcription.Remove(sellist) # Delete tier of the list self.tier_list.DeleteItem(sellist) delete = delete + 1 # Update tier numbers of next items in the list. for i in range(sellist, self.tier_list.GetItemCount()): self.tier_list.SetStringItem(i, 0, str(i + 1)) self._dirty = True self._boxtitle.SetForegroundColour(FG_FILE_DIRTY_COLOUR) self.Refresh self._checksize() return delete # ---------------------------------------------------------------------- def Duplicate(self): """ Duplicate the selected tier. """ if self._transcription.GetSize() == 0: return # Get the selected tier index in the list sellist = self.tier_list.GetFirstSelected() if sellist == -1: return # Too many selected items if self.tier_list.GetSelectedItemCount() > 1: ShowInformation(self, self._prefs, "One tier must be checked", style=wx.ICON_INFORMATION) return tier = self._transcription[sellist] self.Append(tier.Copy()) # ---------------------------------------------------------------------- def MoveUp(self): """ Move up the selected tier (except for the first one). """ if self._transcription.GetSize() == 0: return # Get the selected tier in the list sellist = self.tier_list.GetFirstSelected() if sellist == -1: return # Too many selected items if self.tier_list.GetSelectedItemCount() > 1: ShowInformation(self, self._prefs, "One tier must be checked", style=wx.ICON_INFORMATION) return # tier = self._transcription[sellist] if tier in self._protected: ShowInformation(self, self._prefs, "Attempt to move a protected tier: forbidden!", style=wx.ICON_INFORMATION) return #Impossible to move up the first tier. if sellist == 0: return # Pop selected tier from transcription. try: self._transcription._hierarchy.remove_tier( self._transcription[sellist] ) # waiting a better way to work with hierarchy... except Exception: pass self._transcription.Pop(sellist) # Delete old tier of the list self.tier_list.DeleteItem(sellist) # Add tier to the transcription tierindex = self._transcription.Add(tier, sellist - 1) # Add tier to the list self.SetTierProperties(tierindex) # Update tier number self.tier_list.SetStringItem(sellist, 0, str(sellist + 1)) # Let the item selected self.tier_list.Select(sellist - 1, on=True) self._dirty = True self._boxtitle.SetForegroundColour(FG_FILE_DIRTY_COLOUR) self.Refresh() # ---------------------------------------------------------------------- def MoveDown(self): """ Move down the selected tier (except for the last one). """ if self._transcription.GetSize() == 0: return # Get the selected tier in the list sellist = self.tier_list.GetFirstSelected() if sellist == -1: return # Too many selected items if self.tier_list.GetSelectedItemCount() > 1: ShowInformation(self, self._prefs, "One tier must be checked", style=wx.ICON_INFORMATION) return # tier = self._transcription[sellist] if tier in self._protected: ShowInformation(self, self._prefs, "Attempting to move a protected tier: forbidden!", style=wx.ICON_INFORMATION) return # Impossible to move down the last tier. if (sellist + 1) == self.tier_list.GetItemCount(): return # Pop selected tier from transcription. try: self._transcription._hierarchy.remove_tier( self._transcription[sellist] ) # waiting a better way to work with hierarchy... except Exception: pass self._transcription.Pop(sellist) # Delete old tier of the list self.tier_list.DeleteItem(sellist) # Add tier to the transcription if (sellist + 1) >= self.tier_list.GetItemCount(): tierindex = self._transcription.Add(tier) else: tierindex = self._transcription.Add(tier, sellist + 1) # Add tier to the list self.SetTierProperties(tierindex) # Update tier number self.tier_list.SetStringItem(sellist, 0, "Tier " + str(sellist + 1)) self.tier_list.SetStringItem(sellist + 1, 0, "Tier " + str(tierindex + 1)) # Let the item selected self.tier_list.Select(sellist + 1, on=True) self._dirty = True self._boxtitle.SetForegroundColour(FG_FILE_DIRTY_COLOUR) self.Refresh() # ---------------------------------------------------------------------- def Radius(self): """ Fix a new radius value to all TimePoint instances of the selected tier. """ if self._transcription.GetSize() == 0: return # Get the selected tier in the list sellist = self.tier_list.GetFirstSelected() if sellist == -1: return # tier = self._transcription[sellist] if tier in self._protected: ShowInformation(self, self._prefs, "Attempt to modify a protected tier: forbidden!", style=wx.ICON_INFORMATION) return # Open a dialog to ask the new radius value radius = tier.GetBegin().GetRadius() dlg = RadiusChooser(self, self._prefs, radius) if dlg.ShowModal() == wx.ID_OK: # Get the value r = dlg.GetValue() try: r = float(r) if r > 1.0: raise ValueError('Radius must range 0-1.') except: logging.info('Radius cancelled (can not be applied: %f).' % r) return # Set the value while sellist != -1: tier.SetRadius(r) logging.debug('Radius fixed to %f' % r) sellist = self.tier_list.GetNextSelected(sellist) dlg.Destroy() # ---------------------------------------------------------------------- def Preview(self): """ Open a grid frame with the selected tier content. """ if self._transcription.GetSize() == 0: return # Get the selected tier in the list sellist = self.tier_list.GetFirstSelected() if sellist == -1: return # Too many selected items if self.tier_list.GetSelectedItemCount() > 1: ShowInformation(self, self._prefs, "One tier only must be checked", style=wx.ICON_INFORMATION) return tier = self._transcription[sellist] dlg = PreviewTierDialog(self, self._prefs, tiers=[tier]) dlg.Show() # ---------------------------------------------------------------------- def Append(self, newtier): """ Append a tier in the transcription and in the list. """ # Append tier to the transcription tierindex = self._transcription.Append(newtier) # Append tier to the list self.SetTierProperties(tierindex) # Display information self._dirty = True self._boxtitle.SetForegroundColour(FG_FILE_DIRTY_COLOUR) self.Refresh() # ---------------------------------------------------------------------- def LoadFile(self, filename): """ Load a file in memory and show it. @param filename is an annotated file. """ self._filename = filename if os.path.exists(filename) is False: self._transcription = Transcription("Empty") return try: self._transcription = sppas.src.annotationdata.aio.read(filename) self._dirty = False self._boxtitle.SetForegroundColour(FG_FILE_COLOUR) self.Refresh() except Exception as e: logging.info('Error loading file %s: %s' % (filename, str(e))) self._transcription = Transcription("IO-Error") #raise # ---------------------------------------------------------------------- def Save(self): """ Save the current page content. """ if self._dirty is False: return try: sppas.src.annotationdata.aio.write(self._filename, self._transcription) self._dirty = False self._boxtitle.SetForegroundColour(FG_FILE_COLOUR) self.Refresh() except Exception as e: # give information ShowInformation(self, self._prefs, 'File not saved: %s' % str(e), style=wx.ICON_ERROR) # ---------------------------------------------------------------------- def SaveAs(self, filename): """ Save the current page content with another file name. Keep everything un-changed in self. """ try: sppas.src.annotationdata.aio.write(filename, self._transcription) except Exception as e: # give information ShowInformation(self, self._prefs, 'File not saved: %s' % str(e), style=wx.ICON_ERROR) # ---------------------------------------------------------------------- def GetTranscription(self): """ Return the Transcription. """ return self._transcription # ---------------------------------------------------------------------- def GetTranscriptionName(self): """ Return the name of the transcription. """ return self._transcription.GetName() # ---------------------------------------------------------------------- # Private # ---------------------------------------------------------------------- def _checksize(self): """ Check the transcription size. Append an "empty line" if transcription is empty. Remove this empty line if transcription is not empty. Return True if something has changed. """ # Append an "empty" line in the ListCtrl if self._transcription.GetSize() == 0 and self.tier_list.GetItemCount( ) == 0: self.tier_list.InsertStringItem(0, " ... ") if self._transcription.GetName() == "IO-Error": self.tier_list.SetStringItem( 0, 1, " Error while reading this file ") else: self.tier_list.SetStringItem(0, 1, " Empty file: no tiers ") for i in range(2, 5): self.tier_list.SetStringItem(0, i, " ") return True # Remove the "empty" line of the ListCtrl if self._transcription.GetSize() < self.tier_list.GetItemCount(): self.tier_list.DeleteItem(self.tier_list.GetItemCount() - 1) return True return False
class TrsList(wx.Panel): """Show data about transcriptions, in a panel including a list of tiers. :author: Brigitte Bigi :organization: Laboratoire Parole et Langage, Aix-en-Provence, France :contact: [email protected] :license: GPL, v3 :copyright: Copyright (C) 2011-2018 Brigitte Bigi """ def __init__(self, parent, filename, trs=None, multiple=False): wx.Panel.__init__(self, parent, -1, size=wx.DefaultSize) # initialize the GUI self._prefs = Preferences() self._filename = filename self._dirty = False # the transcription was changed self._selected = False # the transcription is selected self._protected = list( ) # list of the tiers that are protected (i.e. they can't be modified) if len(filename) == 0: self._filename = "Empty" box_title = self._create_title() self.tier_list = self._create_list(multiple) # load the Transcription if trs is None and len(filename) != 0: self.LoadFile(filename) else: self._transcription = trs # add Transcription information in the list for tier in self._transcription: self.AddTierProperties(tier) self._checksize() # events self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnListItemSelected, self.tier_list) self.Bind(wx.EVT_LIST_COL_CLICK, self.OnListItemSelected, self.tier_list) # layout sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(box_title, 0, wx.EXPAND | wx.ALL, border=4) sizer.Add(self.tier_list, 1, wx.EXPAND | wx.ALL, border=4) self.SetFont(self._prefs.GetValue('M_FONT')) self.SetForegroundColour(self._prefs.GetValue('M_FG_COLOUR')) self.SetBackgroundColour(self._prefs.GetValue('M_BG_COLOUR')) self._box_title.SetForegroundColour(FG_FILE_COLOUR) self.SetSizerAndFit(sizer) self.SetAutoLayout(True) self.Layout() # ---------------------------------------------------------------------- def _create_title(self): """Create the title of the panel.""" _sizer = wx.BoxSizer(wx.HORIZONTAL) self._static_tx = wx.TextCtrl(self, -1, "File: ", style=wx.TE_READONLY | wx.NO_BORDER) self._box_title = wx.TextCtrl(self, -1, self._filename, style=wx.TE_READONLY | wx.NO_BORDER) _sizer.Add(self._static_tx, 0, wx.RIGHT, border=2) _sizer.Add(self._box_title, 1, wx.EXPAND) return _sizer # ---------------------------------------------------------------------- def _create_list(self, multiple=False): """Create the list to show information of a each tier of a transcription.""" if multiple: tier_list = CheckListCtrl(self, -1, style=wx.LC_REPORT | wx.BORDER_NONE) else: tier_list = CheckListCtrl(self, -1, style=wx.LC_REPORT | wx.BORDER_NONE | wx.LC_SINGLE_SEL) # Add all columns col_names = [ " Number ", " Name ", " Begin ", " End ", " Type ", " Size " ] for i, n in enumerate(col_names): tier_list.InsertColumn(i, n) # Fix column width for i in range(len(col_names)): tier_list.SetColumnWidth(i, wx.LIST_AUTOSIZE_USEHEADER) # Enlarge column with tier name tier_list.SetColumnWidth(1, 140) return tier_list # ------------------------------------------------------------------------- def AddTierProperties(self, tier): """Display tier properties.""" if tier is None: ShowInformation(self, self._prefs, "Attempt to add a tier but tier is None!!!", style=wx.ICON_ERROR) return try: if tier.is_point() is True: tier_type = "Point" elif tier.is_interval(): tier_type = "Interval" elif tier.is_disjoint(): tier_type = "Disjoint" else: # probably an empty tier tier_type = "Unknown" if tier.is_empty() is True: begin = " ... " end = " ... " else: begin = tier.get_first_point().get_midpoint() end = tier.get_last_point().get_midpoint() tier_idx = self._transcription.get_tier_index(tier.get_name()) self.tier_list.InsertStringItem( tier_idx, " -- {:d} -- ".format(tier_idx + 1)) self.tier_list.SetStringItem(tier_idx, 1, tier.get_name()) self.tier_list.SetStringItem(tier_idx, 2, str(begin)) self.tier_list.SetStringItem(tier_idx, 3, str(end)) self.tier_list.SetStringItem(tier_idx, 4, tier_type) self.tier_list.SetStringItem(tier_idx, 5, str(len(tier))) except Exception as e: self.tier_list.InsertStringItem(1, "Error: {:s}".format(str(e))) # ---------------------------------------------------------------------- # Callbacks... # ---------------------------------------------------------------------- def OnListItemSelected(self, event): """An item of this panel was clicked. Inform the parent.""" evt = PanelSelectedEvent(panel=self) evt.SetEventObject(self) wx.PostEvent(self.GetParent(), evt) # ---------------------------------------------------------------------- # GUI # ---------------------------------------------------------------------- def SetPreferences(self, prefs): """Set new preferences.""" self._prefs = prefs self.SetBackgroundColour(self._prefs.GetValue("M_BG_COLOUR")) self.SetForegroundColour(self._prefs.GetValue("M_FG_COLOUR")) self.SetFont(self._prefs.GetValue("M_FONT")) # ------------------------------------------------------------------------- def SetFont(self, font): """Set a new font.""" wx.Window.SetFont(self, font) self.tier_list.SetFont(font) for i in range(len(self._transcription)): self.tier_list.SetItemFont(i, font) self._static_tx.SetFont(font) self._box_title.SetFont(font) self.Layout() # bigger/smaller font can impact on the layout # ------------------------------------------------------------------------- def SetBackgroundColour(self, color): """Set background.""" wx.Window.SetBackgroundColour(self, color) self.tier_list.SetBackgroundColour(color) for i in range(len(self._transcription)): self.tier_list.SetItemBackgroundColour(i, color) self._static_tx.SetBackgroundColour(color) self._box_title.SetBackgroundColour(color) self.Refresh() # ------------------------------------------------------------------------- def SetForegroundColour(self, color): """Set foreground and items text color.""" wx.Window.SetForegroundColour(self, color) self.tier_list.SetForegroundColour(color) for i in range(len(self._transcription)): self.tier_list.SetItemTextColour(i, color) self._static_tx.SetForegroundColour(color) self.Refresh() # ---------------------------------------------------------------------- # Functions... # ---------------------------------------------------------------------- def Protect(self): """Fix the current list of tiers as protected: they won't be changed.""" self._protected = list() for i, t in enumerate(self._transcription): self._protected.append(t) self.tier_list.SetItemTextColour(i, wx.Colour(140, 10, 10)) # ------------------------------------------------------------------------- def Unprotect(self): """Erase the list of protected tiers.""" self._protected = list() # ---------------------------------------------------------------------- def IsSelected(self, tier_name, case_sensitive=False): """Return True if the tier is selected.""" i = self._transcription.get_tier_index(tier_name, case_sensitive) if i != -1: return self.tier_list.IsSelected(i) return False # ---------------------------------------------------------------------- def Select(self, tier_name, case_sensitive=False): """Select tiers which name is exactly matching.""" i = self._transcription.get_tier_index(tier_name, case_sensitive) if i != -1: self.tier_list.Select(i, on=True) return True return False # ---------------------------------------------------------------------- def Deselect(self): #for i in range(self.tier_list.GetItemCount()): # self.tier_list.Select(i, on=0) self.tier_list.DeSelectAll() # ---------------------------------------------------------------------- def Rename(self): """Rename the selected tier. Dialog with the user to get the new name.""" sel_list = self._check_selected_tier() if sel_list == -1: return tier = self._transcription[sel_list] if tier in self._protected: ShowInformation(self, self._prefs, "Attempt to rename a protected tier: forbidden!", style=wx.ICON_INFORMATION) return # Ask the user to enter a new name (set current as default) dlg = wx.TextEntryDialog(self, 'Indicate the new tier name', 'Data Roamer', 'Rename a tier.') dlg.SetValue(tier.get_name()) if dlg.ShowModal() == wx.ID_OK: new_name = dlg.GetValue() else: new_name = tier.get_name() dlg.Destroy() if new_name != tier.get_name(): # Update tier name of the transcription tier.set_name(new_name) # Update tier name of the list self.tier_list.SetStringItem(sel_list, 1, dlg.GetValue()) self._dirty = True self._box_title.SetForegroundColour(FG_FILE_DIRTY_COLOUR) self.Refresh() # ---------------------------------------------------------------------- def Cut(self): """Cut the selected tier. Return the clipboard.""" sel_list = self._check_selected_tier() if sel_list == -1: return tier = self._transcription[sel_list] if tier in self._protected: ShowInformation(self, self._prefs, "Attempt to cut a protected tier: forbidden!", style=wx.ICON_INFORMATION) return # Copy the tier to the clipboard clipboard = tier.copy() clipboard.set_meta("tier_was_cut_from_id", tier.get_meta('id')) clipboard.set_meta("tier_was_cut_from_name", tier.get_name()) # Delete tier of the transcription self._transcription.pop(sel_list) # Delete tier of the list self.tier_list.DeleteItem(sel_list) # Update tier numbers of next items in the list. for i in range(sel_list, self.tier_list.GetItemCount()): self.tier_list.SetStringItem(i, 0, " -- {:d} -- ".format(i + 1)) self.Deselect() self._checksize() self._dirty = True self._box_title.SetForegroundColour(FG_FILE_DIRTY_COLOUR) self.Refresh() logging.debug('Cut: returned clipboard tier is {:s}'.format(clipboard)) logging.debug('Cut. returned clipboard tier name is {:s}'.format( clipboard.get_name())) return clipboard # ---------------------------------------------------------------------- def Copy(self): """Return the selected tier.""" sel_list = self._check_selected_tier() if sel_list == -1: return # Copy the tier to the clipboard tier = self._transcription[sel_list] new_tier = tier.copy() new_tier.set_meta("tier_was_copied_from_id", tier.get_meta('id')) new_tier.set_meta("tier_was_copied_from_name", tier.get_name()) new_tier.gen_id() return new_tier # ---------------------------------------------------------------------- def Paste(self, clipboard): """Paste the clipboard tier to the current page.""" # Get the clipboard tier if clipboard is None: return # Append clipboard to the transcription tier = clipboard.copy() tier.gen_id() self.AddTier(tier) # The tier comes from another Transcription... must update infos. if not (tier.get_parent() is self._transcription): # parent transcription (it also adds the related media and ctrl vocab) tier.set_parent(self._transcription) self._checksize() # ---------------------------------------------------------------------- def Delete(self): """Delete the selected tier. Dialog with the user to confirm. """ sel_list = self._check_selected_tier(multiple=True) # Get Indexes of tiers to remove indexes = list() while sel_list != -1: indexes.append(sel_list) sel_list = self.tier_list.GetNextSelected(sel_list) # how many tiers to delete??? d = 0 for sel_list in indexes: tier = self._transcription[sel_list] if tier not in self._protected: d += 1 if d == 0: message = 'None of the selected tiers can be deleted.' \ ''.format(d, self._filename) ShowInformation(self, self._prefs, message, style=wx.ICON_INFORMATION) return # Ask the user to confirm before deleting delete = 0 message = 'Are you sure you want to definitively delete:\n' \ '{:d} tiers in {:s}?'.format(d, self._filename) dlg = ShowYesNoQuestion(self, self._prefs, message) if dlg == wx.ID_YES: for sel_list in reversed(sorted(indexes)): tier = self._transcription[sel_list] if tier in self._protected: logging.info('Attempted to delete the protected tier {:s}' ''.format(tier.get_name())) else: # Delete tier of the transcription self._transcription.pop(sel_list) # Delete tier of the list self.tier_list.DeleteItem(sel_list) delete = delete + 1 # Update tier numbers of next items in the list. for i in range(sel_list, self.tier_list.GetItemCount()): self.tier_list.SetStringItem( i, 0, " -- {:d} --".format(i + 1)) self._dirty = True self._box_title.SetForegroundColour(FG_FILE_DIRTY_COLOUR) self.Refresh() self._checksize() return delete # ---------------------------------------------------------------------- def Duplicate(self): """Duplicate the selected tier.""" sel_list = self._check_selected_tier() if sel_list == -1: return tier = self._transcription[sel_list] new_tier = tier.copy() new_tier.gen_id() new_tier.set_meta("tier_was_duplicated_from_id", tier.get_meta('id')) new_tier.set_meta("tier_was_duplicated_from_name", tier.get_name()) self.AddTier(new_tier) # ---------------------------------------------------------------------- def MoveUp(self): """Move up the selected tier (except for the first one).""" sel_list = self._check_selected_tier() # Impossible to move up the first tier. if sel_list <= 0: return # tier = self._transcription[sel_list] if tier in self._protected: ShowInformation(self, self._prefs, "Attempt to move a protected tier: forbidden!", style=wx.ICON_INFORMATION) return # move up into the transcription self._transcription.set_tier_index(tier.get_name(), sel_list - 1) # Delete old tier of the list self.tier_list.DeleteItem(sel_list) # Add moved tier to the list self.AddTierProperties(tier) # Update tier number self.tier_list.SetStringItem(sel_list, 0, " -- {:d} --".format(sel_list + 1)) # Let the item selected self.tier_list.Select(sel_list - 1, on=True) self._dirty = True self._box_title.SetForegroundColour(FG_FILE_DIRTY_COLOUR) self.Refresh() # ---------------------------------------------------------------------- def MoveDown(self): """Move down the selected tier (except for the last one).""" sel_list = self._check_selected_tier() if sel_list == -1: return # tier = self._transcription[sel_list] if tier in self._protected: ShowInformation(self, self._prefs, "Attempting to move a protected tier: forbidden!", style=wx.ICON_INFORMATION) return # Impossible to move down the last tier. if (sel_list + 1) == self.tier_list.GetItemCount(): return # move down into the transcription self._transcription.set_tier_index(tier.get_name(), sel_list + 1) # Delete old tier of the list self.tier_list.DeleteItem(sel_list) # Add moved tier to the list self.AddTierProperties(tier) # Update tier number self.tier_list.SetStringItem(sel_list, 0, " -- {:d} --".format(sel_list + 1)) # Let the item selected self.tier_list.Select(sel_list + 1, on=True) self._dirty = True self._box_title.SetForegroundColour(FG_FILE_DIRTY_COLOUR) self.Refresh() # ---------------------------------------------------------------------- def Radius(self): """Fix a new radius value to all TimePoint instances of the selected tier.""" if len(self._transcription) == 0: return # Get the selected tier in the list sel_list = self.tier_list.GetFirstSelected() if sel_list == -1: return # tier = self._transcription[sel_list] if tier in self._protected: ShowInformation(self, self._prefs, "Attempt to modify a protected tier: forbidden!", style=wx.ICON_INFORMATION) return # Open a dialog to ask the new radius value radius = 0.005 dlg = RadiusChooser(self, self._prefs, radius) if dlg.ShowModal() == wx.ID_OK: # Get the value r = dlg.GetValue() try: r = float(r) if r > 1.0 or r < 0.: raise ValueError('Radius must range 0-1.') except Exception as e: ShowInformation(self, self._prefs, "Error: {:s}".format(str(e)), style=wx.ICON_ERROR) return # Set the value while sel_list != -1: tier.set_radius(r) sel_list = self.tier_list.GetNextSelected(sel_list) dlg.Destroy() # ---------------------------------------------------------------------- def Preview(self): """Open a grid frame with the selected tier content.""" sel_list = self._check_selected_tier() if sel_list == -1: return tier = self._transcription[sel_list] dlg = PreviewTierDialog(self, self._prefs, tiers=[tier]) dlg.Show() # ---------------------------------------------------------------------- def AddTier(self, new_tier): """Append a tier into the transcription and add in the list.""" # Append tier to the transcription self._transcription.append(new_tier) # Append tier into the list self.AddTierProperties(new_tier) # Display information self._dirty = True self._box_title.SetForegroundColour(FG_FILE_DIRTY_COLOUR) self.Refresh() # ---------------------------------------------------------------------- def LoadFile(self, filename): """Load a file in memory and show it. :param filename: an annotated file. """ self._filename = filename if os.path.exists(filename) is False: self._transcription = sppasTranscription("Empty") return try: parser = sppasRW(filename) self._transcription = parser.read() self._dirty = False self._box_title.SetForegroundColour(FG_FILE_COLOUR) self.Refresh() except Exception as e: logging.info('Error loading file {:s}: {:s}'.format( filename, str(e))) self._transcription = sppasTranscription("IO-Error") #raise # ---------------------------------------------------------------------- def Save(self): """Save the current page content.""" if self._dirty is False: return try: parser = sppasRW(self._filename) parser.write(self._transcription) self._dirty = False self._box_title.SetForegroundColour(FG_FILE_COLOUR) self.Refresh() except Exception as e: # give information ShowInformation( self, self._prefs, 'File not saved due to the following error: {:s}'.format(e), style=wx.ICON_ERROR) # ---------------------------------------------------------------------- def SaveAs(self, filename): """Save the current page content with another file name. Keep everything un-changed in self. """ try: parser = sppasRW(filename) parser.write(self._transcription) except Exception as e: # give information ShowInformation( self, self._prefs, 'File not saved due to the following error: {:s}'.format(e), style=wx.ICON_ERROR) # ---------------------------------------------------------------------- def GetTranscription(self): """Return the Transcription.""" return self._transcription # ---------------------------------------------------------------------- def GetTranscriptionName(self): """Return the name of the transcription.""" return self._transcription.get_name() # ---------------------------------------------------------------------- # Private # ---------------------------------------------------------------------- def _check_selected_tier(self, multiple=False): if len(self._transcription) == 0: return -1 # Too many selected items if multiple is False and self.tier_list.GetSelectedItemCount() > 1: ShowInformation(self, self._prefs, "Only one tier must be checked", style=wx.ICON_INFORMATION) return -1 # Get the selected tier in the list return self.tier_list.GetFirstSelected() # ---------------------------------------------------------------------- def _checksize(self): """Check the transcription size. Append an "empty line" if transcription is empty. Remove this empty line if transcription is not empty. Return True if something has changed. """ # Append an "empty" line in the ListCtrl if len(self._transcription) == 0 and self.tier_list.GetItemCount( ) == 0: self.tier_list.InsertStringItem(0, " ... ") if self._transcription.get_name() == "IO-Error": self.tier_list.SetStringItem( 0, 1, " Error while reading this file ") else: self.tier_list.SetStringItem(0, 1, " Empty file: no tiers ") for i in range(2, 5): self.tier_list.SetStringItem(0, i, " ") return True # Remove the "empty" line of the ListCtrl if len(self._transcription) < self.tier_list.GetItemCount(): self.tier_list.DeleteItem(self.tier_list.GetItemCount() - 1) return True return False