def OnFileOpen(self, event): """ File Open Button Press """ # File Filter definition fileTypesString = _("Text files (*.txt)|*.txt") # If no config file is defined (ie using default colors) ... if self.configFile == '': # ... use the video path and no filename lastPath = TransanaGlobal.configData.videoPath filename = '' # if a config file is defined ... else: # ... split it into path and filename (lastPath, filename) = os.path.split(self.configFile) # Create a File Open dialog. fdlg = wx.FileDialog(self, _('Select Color Definition file'), lastPath, filename, fileTypesString, wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) # Show the dialog and get user response. If OK ... if fdlg.ShowModal() == wx.ID_OK: # Remember the file name locally (not globally yet) self.configFile = fdlg.GetPath() # Load the colors from the file self.colors = TransanaGlobal.getColorDefs(self.configFile) # If the File Load failed, the file name will have been cleared. Check this! if TransanaGlobal.configData.colorConfigFilename == '': self.configFile = '' # Update the file name label on screen self.lblFileName.SetLabel(self.configFile) # Populate the dialog's color list self.PopulateList() # Destroy the File Dialog fdlg.Destroy()
def OnOK(self, event): """ OK Button Press """ # Save the current values if OK is pressed self.OnFileSave(event) # If there was no SAVE because there is no file name, we still want to update the colors. (Normally, # this happens within FileSave.) if self.configFile == '': # Initialize the local internal color list self.colors = [] # Iterate through the color defs in the dialog's list item for item in range(self.colorList.GetItemCount()): # Get the color name from column 0 colorName = self.colorList.GetItem(item, 0).GetText() # Add the color definition to the local internal color list self.colors.append((colorName, (int(self.colorList.GetItem(item, 2).GetText()), int(self.colorList.GetItem(item, 3).GetText()), int(self.colorList.GetItem(item, 4).GetText())))) # Update the colors for all of Transana TransanaGlobal.transana_graphicsColorList = self.colors # Update all of the color-related data values needed to make use of the color scheme (TransanaGlobal.transana_colorNameList, TransanaGlobal.transana_colorLookup, TransanaGlobal.keywordMapColourSet) = \ TransanaGlobal.SetColorVariables() # Save the config filename in the configuration structure TransanaGlobal.configData.colorConfigFilename = self.configFile # indicate that we are closing the form self.closing = True # Allow the form's OK event to fire to close the form event.Skip()
def __init__(self, parent, default_text=""): """Initialize an NoteEditor object.""" # Determine the screen size rect = wx.Display(TransanaGlobal.configData.primaryScreen ).GetClientArea() # wx.ClientDisplayRect() # We'll make our default window 60% of the size of the screen self.width = rect[2] * .60 self.height = rect[3] * .60 # Initialize a Dialog object to form our basic window wx.Dialog.__init__( self, parent, -1, _("Note"), wx.DefaultPosition, wx.Size(self.width, self.height), wx.CAPTION | wx.CLOSE_BOX | wx.SYSTEM_MENU | wx.RESIZE_BORDER) # Specify the minimium size of this window. self.SetMinSize((400, 220)) # Add a Note Editor Panel to the dialog self.pnl = _NotePanel(self, default_text) # Create a Sizer for the Dialog dlgSizer = wx.BoxSizer(wx.HORIZONTAL) # Place the Panel on the Sizer, making it expandable in all directions dlgSizer.Add(self.pnl, 1, wx.EXPAND | wx.ALL, 2) # Set the Sizer to the Dialog self.SetSizer(dlgSizer) # Center the Dialog on the screen TransanaGlobal.CenterOnPrimary(self)
def __init__(self, parent, numRecords = 0): """ Create a Dialog Box to process the Database Conversion. Parameters: parent Parent Window numRecords The number of records that will be updated """ # Remember the total number of records passed in, or obtain that number if needed if numRecords == 0: self.numRecords = DBInterface.CountItemsWithoutPlainText() else: self.numRecords = numRecords # Create a Dialog Box wx.Dialog.__init__(self, parent, -1, _("Plain Text Conversion"), size=(600, 350)) # Add the Main Sizer mainSizer = wx.BoxSizer(wx.VERTICAL) # Add a gauge based on the number of records to be handled self.gauge = wx.Gauge(self, -1, numRecords) mainSizer.Add(self.gauge, 0, wx.EXPAND | wx.LEFT | wx.TOP | wx.RIGHT, 5) # Add a TextCtrl to provide user information self.txtCtrl = wx.TextCtrl(self, -1, "", style=wx.TE_LEFT | wx.TE_MULTILINE) mainSizer.Add(self.txtCtrl, 1, wx.EXPAND | wx.ALL, 5) # Add a hidden RichTextCrtl used for the conversion process self.richTextCtrl = TranscriptEditor_RTC.TranscriptEditor(self) self.richTextCtrl.SetReadOnly(True) self.richTextCtrl.Enable(False) # The user doesn't need to see this. self.richTextCtrl.Show(False) # Even though we add it to the sizer, it won't show up because of the Show(False). mainSizer.Add(self.richTextCtrl, 1, wx.EXPAND | wx.ALL, 5) # Finalize the Dialog layout self.SetSizer(mainSizer) self.SetAutoLayout(True) self.Layout() # Center the Dialog on the Screen TransanaGlobal.CenterOnPrimary(self)
def __init__(self, parent, title, msg): # Create a dialog wx.Dialog.__init__(self, parent, -1, title, size=(350, 150), style=wx.CAPTION | wx.STAY_ON_TOP) # Add sizers box = wx.BoxSizer(wx.VERTICAL) box2 = wx.BoxSizer(wx.HORIZONTAL) # Add an Info graphic bitmap = wx.EmptyBitmap(32, 32) bitmap = wx.ArtProvider_GetBitmap(wx.ART_INFORMATION, wx.ART_MESSAGE_BOX, (32, 32)) graphic = wx.StaticBitmap(self, -1, bitmap) box2.Add(graphic, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, 10) # Add the message message = wx.StaticText(self, -1, msg) box2.Add(message, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10) box.Add(box2, 0, wx.EXPAND) # Handle layout self.SetAutoLayout(True) self.SetSizer(box) self.Fit() self.Layout() # self.CentreOnScreen() TransanaGlobal.CenterOnPrimary(self) # Display the Dialog self.Show() # Make sure the screen gets fully drawn before continuing. (Needed for SAVE) try: wx.Yield() except: pass
def __init__(self, parent, msg, dlgTitle=_("Transana Information")): # This should be easy, right? Just use the OS MessageDialog like so: # wx.MessageDialog.__init__(self, parent, msg, _("Transana Information"), \ # wx.OK | wx.CENTRE | wx.ICON_INFORMATION) # That's all there is to it, right? # # Yeah, right. Unfortunately, on Windows, this dialog isn't TRULY modal. It's modal to the parent window # it's called from, but you can still select one of the other Transana Windows and do stuff. This message # can even get hidden behind other windows, and cause all kinds of problems. According to Robin Dunn, # writing my own class to do this is the only solution. Here goes. # Create a wxDialog wx.Dialog.__init__(self, parent, -1, dlgTitle, size=(350, 150), style=wx.CAPTION | wx.CLOSE_BOX | wx.STAY_ON_TOP) # Create Vertical and Horizontal Sizers box = wx.BoxSizer(wx.VERTICAL) box2 = wx.BoxSizer(wx.HORIZONTAL) # Display the Information graphic in the dialog box graphic = wx.StaticBitmap( self, -1, TransanaImages.ArtProv_INFORMATION.GetBitmap()) # Add the graphic to the Sizers box2.Add(graphic, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, 10) # Display the error message in the dialog box message = wx.StaticText(self, -1, msg) # Add the information message to the Sizers box2.Add( message, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10) box.Add(box2, 0, wx.EXPAND) # Add an OK button btnOK = wx.Button(self, wx.ID_OK, _("OK")) # Add the OK button to the Sizers box.Add(btnOK, 0, wx.ALIGN_CENTER | wx.BOTTOM, 10) # Make the OK button the default self.SetDefaultItem(btnOK) # Turn on Auto Layout self.SetAutoLayout(True) # Set the form sizer self.SetSizer(box) # Set the form size self.Fit() # Perform the Layout self.Layout() # Center the dialog on the screen # self.CentreOnScreen() # That's not working. Let's try this ... TransanaGlobal.CenterOnPrimary(self)
def __init__(self,parent,id,title): wx.SetDefaultPyEncoding('utf8') self.presLan_en = gettext.translation('Transana', 'locale', languages=['en']) self.presLan_en.install() lang = wx.LANGUAGE_ENGLISH self.locale = wx.Locale(lang) self.locale.AddCatalog("Transana") # Define the Configuration Data TransanaGlobal.configData = ConfigData.ConfigData() # Create the global transana graphics colors, once the ConfigData object exists. TransanaGlobal.transana_graphicsColorList = TransanaGlobal.getColorDefs(TransanaGlobal.configData.colorConfigFilename) # Set essential global color manipulation data structures once the ConfigData object exists. (TransanaGlobal.transana_colorNameList, TransanaGlobal.transana_colorLookup, TransanaGlobal.keywordMapColourSet) = TransanaGlobal.SetColorVariables() TransanaGlobal.configData.videoPath = 'C:\\Users\\DavidWoods\\Videos' TransanaGlobal.menuWindow = MenuWindow.MenuWindow(None, -1, title) self.ControlObject = ControlObjectClass.ControlObject() self.ControlObject.Register(Menu = TransanaGlobal.menuWindow) TransanaGlobal.menuWindow.Register(ControlObject = self.ControlObject) wx.Frame.__init__(self,parent,-1, title, size = (800,600), style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE) self.testsRun = 0 self.testsSuccessful = 0 self.testsFailed = 0 mainSizer = wx.BoxSizer(wx.VERTICAL) self.txtCtrl = wx.TextCtrl(self, -1, "Unit Test: SSL\n\n", style=wx.TE_LEFT | wx.TE_MULTILINE) self.txtCtrl.AppendText("Transana Version: %s\nsingleUserVersion: %s\n" % (TransanaConstants.versionNumber, TransanaConstants.singleUserVersion)) mainSizer.Add(self.txtCtrl, 1, wx.EXPAND | wx.ALL, 5) self.SetSizer(mainSizer) self.SetAutoLayout(True) self.Layout() self.CenterOnScreen() # Status Bar self.CreateStatusBar() self.SetStatusText("") self.Show(True) try: self.RunTests() except: print print print sys.exc_info()[0] print sys.exc_info()[1] traceback.print_exc(file=sys.stdout) if TransanaConstants.DBInstalled in ['MySQLdb-embedded']: DBInterface.EndSingleUserDatabase() TransanaGlobal.menuWindow.Destroy()
def CallDisplay(self): """ Call the parent method (passed in during initialization) that populates the report """ # Get the paper size from the TranscriptPrintoutClass (paperWidth, paperHeight) = TranscriptPrintoutClass.GetPaperSize() # Get the current height of the report window height = self.GetSize()[1] # Turn off the size hints, so we can resize the window self.SetSizeHints(-1, -1, -1, -1) # We need to adjust the size of the display slightly depending on platform. if '__WXMAC__' in wx.PlatformInfo: # GetPaperSize() is based on PRINTER, not SCREEN resolution. We need to adjust this on the mac, changing from 72 DPI to 96 DPI paperWidth = int(paperWidth * 4 / 3) # Adjust the page size for the right margin and scroll bar sizeAdjust = 48 # Set the size of the report so that it matches the width of the paper being used (plus the # line number area and the scroll bar) self.SetSize( (paperWidth + self.reportText.lineNumberWidth + sizeAdjust, height)) # Set Size Hints, so the report can't be resized. (This may not be practical for large paper on small monitors.) self.SetSizeHints(self.GetSize()[0], int(self.GetSize()[1] * 0.8), self.GetSize()[0], -1) # Center on the screen TransanaGlobal.CenterOnPrimary(self) # CallDisplay() ALWAYS makes the report Read Only, so change the EDIT button state to NO EDIT ... self.toolBar.ToggleTool(T_FILE_EDIT, False) # ... and make the report read-only. self.reportText.SetReadOnly(True) # Disable the Font items self.toolBar.EnableTool(T_FILE_FONT, False) # The Menu does not exist on the Mac ... if not '__WXMAC__' in wx.PlatformInfo: # ... but if we're not on the Mac, disable it! self.menuFile.Enable(M_FILE_FONT, False) # Clear the Report self.reportText.ClearDoc() # If a Display Method has been defined ... if self.displayMethod != None: # ... call it. self.displayMethod(self.reportText) # Move the cursor to the beginning of the report self.reportText.GotoPos(0) # Bring the Report to the top so it will definitely be visible self.Raise()
def __init__(self, parent, id, title, quote_object, mergeList=None): # If no Merge List is passed in ... if mergeList == None: # ... use the default Quote Properties Dialog size passed in from the config object. (This does NOT get saved.) size = TransanaGlobal.configData.quotePropertiesSize # ... we can enable Quote Change Propagation propagateEnabled = True HelpContext = 'Quote Properties' # If we DO have a merge list ... else: # ... increase the size of the dialog to allow for the list of mergeable quotes. size = (TransanaGlobal.configData.quotePropertiesSize[0], TransanaGlobal.configData.quotePropertiesSize[1] + 130) # ... and Quote Change Propagation should be disabled propagateEnabled = False HelpContext = 'Quote Merge' # Make the Keyword Edit List resizable by passing wx.RESIZE_BORDER style. Signal that Propogation is included. Dialogs.GenForm.__init__(self, parent, id, title, size=size, style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, propagateEnabled=propagateEnabled, useSizers=True, HelpContext=HelpContext) if mergeList == None: # Define the minimum size for this dialog as the initial size minWidth = 750 minHeight = 570 else: # Define the minimum size for this dialog as the initial size minWidth = 750 minHeight = 650 # Remember the Parent Window self.parent = parent # Remember the original Quote Object passed in self.obj = quote_object # Add a placeholder to the quote object for the merge quote number self.obj.mergeNumber = 0 # Remember the merge list, if one is passed in self.mergeList = mergeList # Initialize the merge item as unselected self.mergeItemIndex = -1 # if Keywords that server as Keyword Examples are removed, we will need to remember them. # Then, when OK is pressed, the Keyword Example references in the Database Tree can be removed. # We can't remove them immediately in case the whole Quote Properties Edit process is cancelled. self.keywordExamplesToDelete = [] # Initialize a variable to hold merged keyword examples. self.mergedKeywordExamples = [] # Create the form's main VERTICAL sizer mainSizer = wx.BoxSizer(wx.VERTICAL) # If we're merging Quotes ... if self.mergeList != None: # ... display a label for the Merge Quotes ... lblMergeQuote = wx.StaticText(self.panel, -1, _("Quote to Merge")) mainSizer.Add(lblMergeQuote, 0) # Add a vertical spacer to the main sizer mainSizer.Add((0, 3)) # Create a HORIZONTAL sizer for the merge information mergeSizer = wx.BoxSizer(wx.HORIZONTAL) # ... display a ListCtrl for the Merge Quotes ... self.mergeQuotes = wx.ListCtrl(self.panel, -1, size=(300, 100), style=wx.LC_REPORT | wx.LC_SINGLE_SEL) # Add the element to the sizer mergeSizer.Add(self.mergeQuotes, 1, wx.EXPAND) # ... bind the Item Selected event for the List Control ... self.mergeQuotes.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected) # ... define the columns for the Merge Quotes ... self.mergeQuotes.InsertColumn(0, _('Quote Name')) self.mergeQuotes.InsertColumn(1, _('Collection')) self.mergeQuotes.InsertColumn(2, _('Start Character')) self.mergeQuotes.InsertColumn(3, _('End Character')) self.mergeQuotes.SetColumnWidth(0, 244) self.mergeQuotes.SetColumnWidth(1, 244) # ... and populate the Merge Quotes list from the mergeList data for (QuoteNum, QuoteID, DocumentNum, CollectNum, CollectID, StartChar, EndChar) in self.mergeList: index = self.mergeQuotes.InsertStringItem(sys.maxint, QuoteID) self.mergeQuotes.SetStringItem(index, 1, CollectID) self.mergeQuotes.SetStringItem(index, 2, u"%s" % StartChar) self.mergeQuotes.SetStringItem(index, 3, u"%s" % EndChar) # Add the row sizer to the main vertical sizer mainSizer.Add(mergeSizer, 3, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the first row r1Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v1 = wx.BoxSizer(wx.VERTICAL) # Quote ID self.id_edit = self.new_edit_box(_("Quote ID"), v1, self.obj.id, maxLen=100) # Add the element to the sizer r1Sizer.Add(v1, 1, wx.EXPAND) # Add a horizontal spacer to the row sizer r1Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v2 = wx.BoxSizer(wx.VERTICAL) # Collection ID collection_edit = self.new_edit_box(_("Collection ID"), v2, self.obj.GetNodeString(False)) # Add the element to the sizer r1Sizer.Add(v2, 2, wx.EXPAND) collection_edit.Enable(False) # Add the row sizer to the main vertical sizer mainSizer.Add(r1Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r2Sizer = wx.BoxSizer(wx.HORIZONTAL) # If the source document is known ... if self.obj.source_document_num > 0: try: tmpSrcDoc = Document.Document(num=self.obj.source_document_num) srcDocID = tmpSrcDoc.id tmpLibrary = Library.Library(tmpSrcDoc.library_num) libraryID = tmpLibrary.id except TransanaExceptions.RecordNotFoundError: srcDocID = '' libraryID = '' self.obj.source_document_id = 0 except: print print sys.exc_info()[0] print sys.exc_info()[1] self.obj.source_document_id = 0 srcDocID = '' libraryID = '' else: srcDocID = '' libraryID = '' # Create a VERTICAL sizer for the next element v3 = wx.BoxSizer(wx.VERTICAL) # Library ID library_edit = self.new_edit_box(_("Library ID"), v3, libraryID) # Add the element to the sizer r2Sizer.Add(v3, 1, wx.EXPAND) library_edit.Enable(False) # Add a horizontal spacer to the row sizer r2Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v4 = wx.BoxSizer(wx.VERTICAL) # Document ID document_edit = self.new_edit_box(_("Document ID"), v4, srcDocID) # Add the element to the sizer r2Sizer.Add(v4, 1, wx.EXPAND) document_edit.Enable(False) # Add the row sizer to the main vertical sizer mainSizer.Add(r2Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r4Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v5 = wx.BoxSizer(wx.VERTICAL) # Quote Start Character self.quote_start_edit = self.new_edit_box(_("Quote Start Character"), v5, unicode(self.obj.start_char)) # Add the element to the sizer r4Sizer.Add(v5, 1, wx.EXPAND) # For merging, we need to remember the merged value of Quote Start Char self.start_char = self.obj.start_char self.quote_start_edit.Enable(False) # Add a horizontal spacer to the row sizer r4Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v6 = wx.BoxSizer(wx.VERTICAL) # Quote End Character self.quote_end_edit = self.new_edit_box(_("Quote End Character"), v6, unicode(self.obj.end_char)) # Add the element to the sizer r4Sizer.Add(v6, 1, wx.EXPAND) # For merging, we need to remember the merged value of Quote End Char self.end_char = self.obj.end_char self.quote_end_edit.Enable(False) # Add a horizontal spacer to the row sizer r4Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v7 = wx.BoxSizer(wx.VERTICAL) # Quote Length self.quote_length_edit = self.new_edit_box( _("Quote Length"), v7, unicode(self.obj.end_char - self.obj.start_char)) # Add the element to the sizer r4Sizer.Add(v7, 1, wx.EXPAND) self.quote_length_edit.Enable(False) # Add the row sizer to the main vertical sizer mainSizer.Add(r4Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r5Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v8 = wx.BoxSizer(wx.VERTICAL) # Comment comment_edit = self.new_edit_box(_("Comment"), v8, self.obj.comment, maxLen=255) # Add the element to the sizer r5Sizer.Add(v8, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r5Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) txt = wx.StaticText(self.panel, -1, _("Quote Text")) mainSizer.Add(txt, 0, wx.BOTTOM, 3) self.text_edit = TranscriptEditor_RTC.TranscriptEditor(self.panel) self.text_edit.load_transcript(self.obj) self.text_edit.SetReadOnly(False) self.text_edit.Enable(True) mainSizer.Add(self.text_edit, 6, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r7Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v9 = wx.BoxSizer(wx.VERTICAL) # Keyword Group [label] txt = wx.StaticText(self.panel, -1, _("Keyword Group")) v9.Add(txt, 0, wx.BOTTOM, 3) # Keyword Group [list box] # Create an empty Keyword Group List for now. We'll populate it later (for layout reasons) self.kw_groups = [] self.kw_group_lb = wx.ListBox(self.panel, -1, choices=self.kw_groups) v9.Add(self.kw_group_lb, 1, wx.EXPAND) # Add the element to the sizer r7Sizer.Add(v9, 1, wx.EXPAND) # Create an empty Keyword List for now. We'll populate it later (for layout reasons) self.kw_list = [] wx.EVT_LISTBOX(self, self.kw_group_lb.GetId(), self.OnGroupSelect) # Add a horizontal spacer r7Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v10 = wx.BoxSizer(wx.VERTICAL) # Keyword [label] txt = wx.StaticText(self.panel, -1, _("Keyword")) v10.Add(txt, 0, wx.BOTTOM, 3) # Keyword [list box] self.kw_lb = wx.ListBox(self.panel, -1, choices=self.kw_list, style=wx.LB_EXTENDED) v10.Add(self.kw_lb, 1, wx.EXPAND) wx.EVT_LISTBOX_DCLICK(self, self.kw_lb.GetId(), self.OnAddKW) # Add the element to the sizer r7Sizer.Add(v10, 1, wx.EXPAND) # Add a horizontal spacer r7Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v11 = wx.BoxSizer(wx.VERTICAL) # Keyword transfer buttons add_kw = wx.Button(self.panel, wx.ID_FILE2, ">>", wx.DefaultPosition) v11.Add(add_kw, 0, wx.EXPAND | wx.TOP, 20) wx.EVT_BUTTON(self, wx.ID_FILE2, self.OnAddKW) rm_kw = wx.Button(self.panel, wx.ID_FILE3, "<<", wx.DefaultPosition) v11.Add(rm_kw, 0, wx.EXPAND | wx.TOP, 10) wx.EVT_BUTTON(self, wx.ID_FILE3, self.OnRemoveKW) kwm = wx.BitmapButton(self.panel, wx.ID_FILE4, TransanaImages.KWManage.GetBitmap()) v11.Add(kwm, 0, wx.EXPAND | wx.TOP, 10) kwm.SetToolTipString(_("Keyword Management")) wx.EVT_BUTTON(self, wx.ID_FILE4, self.OnKWManage) # Add the element to the sizer r7Sizer.Add(v11, 0) # Add a horizontal spacer r7Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v12 = wx.BoxSizer(wx.VERTICAL) # Quote Keywords [label] txt = wx.StaticText(self.panel, -1, _("Quote Keywords")) v12.Add(txt, 0, wx.BOTTOM, 3) # Quote Keywords [list box] # Create an empty ListBox. We'll populate it later for layout reasons. self.ekw_lb = wx.ListBox(self.panel, -1, style=wx.LB_EXTENDED) v12.Add(self.ekw_lb, 1, wx.EXPAND) self.ekw_lb.Bind(wx.EVT_KEY_DOWN, self.OnKeywordKeyDown) # Add the element to the sizer r7Sizer.Add(v12, 2, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r7Sizer, 8, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a sizer for the buttons btnSizer = wx.BoxSizer(wx.HORIZONTAL) # Add the buttons self.create_buttons(sizer=btnSizer) # Add the button sizer to the main sizer mainSizer.Add(btnSizer, 0, wx.EXPAND) # Because of the way Quotes are created (with Drag&Drop / Cut&Paste functions), we have to trap the missing # ID error here. Therefore, we need to override the EVT_BUTTON for the OK Button. # Since we don't have an object for the OK Button, we use FindWindowById to find it based on its ID. self.Bind(wx.EVT_BUTTON, self.OnOK, self.FindWindowById(wx.ID_OK)) # We also need to intercept the Cancel button. self.Bind(wx.EVT_BUTTON, self.OnCancel, self.FindWindowById(wx.ID_CANCEL)) # Set the PANEL's main sizer self.panel.SetSizer(mainSizer) # Tell the PANEL to auto-layout self.panel.SetAutoLayout(True) # Lay out the Panel self.panel.Layout() # Lay out the panel on the form self.Layout() # Resize the form to fit the contents self.Fit() # Get the new size of the form (width, height) = self.GetSizeTuple() # Determine which monitor to use and get its size and position if TransanaGlobal.configData.primaryScreen < wx.Display.GetCount(): primaryScreen = TransanaGlobal.configData.primaryScreen else: primaryScreen = 0 rect = wx.Display(primaryScreen).GetClientArea() # Reset the form's size to be at least the specified minimum width self.SetSize( wx.Size(max(minWidth, width), min(max(minHeight, height), rect[3]))) # Define the minimum size for this dialog as the current size self.SetSizeHints(max(minWidth, width), min(max(minHeight, height), rect[3])) # Center the form on screen TransanaGlobal.CenterOnPrimary(self) # We need to set some minimum sizes so the sizers will work right self.kw_group_lb.SetSizeHints(minW=50, minH=20) self.kw_lb.SetSizeHints(minW=50, minH=20) self.ekw_lb.SetSizeHints(minW=50, minH=20) # We populate the Keyword Groups, Keywords, and Clip Keywords lists AFTER we determine the Form Size. # Long Keywords in the list were making the form too big! self.kw_groups = DBInterface.list_of_keyword_groups() for keywordGroup in self.kw_groups: self.kw_group_lb.Append(keywordGroup) # Populate the Keywords ListBox # Load the parent Collection in order to determine the default Keyword Group tempCollection = Collection.Collection(self.obj.collection_num) # Select the Collection Default Keyword Group in the Keyword Group list if (tempCollection.keyword_group != '') and (self.kw_group_lb.FindString( tempCollection.keyword_group) != wx.NOT_FOUND): self.kw_group_lb.SetStringSelection(tempCollection.keyword_group) # If no Default Keyword Group is defined, select the first item in the list else: # but only if there IS a first item. if len(self.kw_groups) > 0: self.kw_group_lb.SetSelection(0) # If there's a selected keyword group ... if self.kw_group_lb.GetSelection() != wx.NOT_FOUND: # populate the Keywords list self.kw_list = \ DBInterface.list_of_keywords_by_group(self.kw_group_lb.GetStringSelection()) else: # If not, create a blank one self.kw_list = [] for keyword in self.kw_list: self.kw_lb.Append(keyword) # Populate the Quote Keywords ListBox # If the quote object has keywords ... for quoteKeyword in self.obj.keyword_list: # ... add them to the keyword list self.ekw_lb.Append(quoteKeyword.keywordPair) # Set initial focus to the Quote ID self.id_edit.SetFocus()
def __init__(self, parent, id, title, ep_object): # Make the Keyword Edit List resizable by passing wx.RESIZE_BORDER style Dialogs.GenForm.__init__(self, parent, id, title, (550,435), style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, useSizers = True, HelpContext='Episode Properties') # Remember the Parent Window self.parent = parent self.obj = ep_object # Create the form's main VERTICAL sizer mainSizer = wx.BoxSizer(wx.VERTICAL) # Create a HORIZONTAL sizer for the first row r1Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v1 = wx.BoxSizer(wx.VERTICAL) # Episode ID self.id_edit = self.new_edit_box(_("Episode ID"), v1, self.obj.id, maxLen=100) # Add the element to the sizer r1Sizer.Add(v1, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r1Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r2Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v2 = wx.BoxSizer(wx.VERTICAL) # Library ID layout series_edit = self.new_edit_box(_("Library ID"), v2, self.obj.series_id) # Add the element to the sizer r2Sizer.Add(v2, 2, wx.EXPAND) series_edit.Enable(False) # Add a horizontal spacer to the row sizer r2Sizer.Add((10, 0)) # Dialogs.GenForm does not provide a Masked text control, so the Date # Field is handled differently than other fields. # Create a VERTICAL sizer for the next element v3 = wx.BoxSizer(wx.VERTICAL) # Date [label] date_lbl = wx.StaticText(self.panel, -1, _("Date (MM/DD/YYYY)")) v3.Add(date_lbl, 0, wx.BOTTOM, 3) # Date # Use the Masked Text Control (Requires wxPython 2.4.2.4 or later) # TODO: Make Date autoformat localizable self.dt_edit = wx.lib.masked.TextCtrl(self.panel, -1, '', autoformat='USDATEMMDDYYYY/') v3.Add(self.dt_edit, 0, wx.EXPAND) # If a Date is know, load it into the control if (self.obj.tape_date != None) and (self.obj.tape_date != '') and (self.obj.tape_date != '01/01/0'): self.dt_edit.SetValue(self.obj.tape_date) # Add the element to the sizer r2Sizer.Add(v3, 1, wx.EXPAND) # Add a horizontal spacer to the row sizer r2Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v4 = wx.BoxSizer(wx.VERTICAL) # Length self.len_edit = self.new_edit_box(_("Length"), v4, self.obj.tape_length_str()) # Add the element to the sizer r2Sizer.Add(v4, 1, wx.EXPAND) self.len_edit.Enable(False) # Add the row sizer to the main vertical sizer mainSizer.Add(r2Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Media Filename(s) [label] txt = wx.StaticText(self.panel, -1, _("Media Filename(s)")) mainSizer.Add(txt, 0, wx.BOTTOM, 3) # Create a HORIZONTAL sizer for the next row r3Sizer = wx.BoxSizer(wx.HORIZONTAL) # Media Filename(s) # If the media filename path is not empty, we should normalize the path specification if self.obj.media_filename == '': filePath = self.obj.media_filename else: filePath = os.path.normpath(self.obj.media_filename) # Initialize the list of media filenames with the first one. self.filenames = [filePath] # For each additional Media file ... for vid in self.obj.additional_media_files: # ... add it to the filename list self.filenames.append(vid['filename']) self.fname_lb = wx.ListBox(self.panel, -1, wx.DefaultPosition, wx.Size(180, 60), self.filenames) # Add the element to the sizer r3Sizer.Add(self.fname_lb, 5, wx.EXPAND) self.fname_lb.SetDropTarget(ListBoxFileDropTarget(self.fname_lb)) # Add a horizontal spacer to the row sizer r3Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v4 = wx.BoxSizer(wx.VERTICAL) # Add File button layout addFile = wx.Button(self.panel, wx.ID_FILE1, _("Add File"), wx.DefaultPosition) v4.Add(addFile, 0, wx.EXPAND | wx.BOTTOM, 3) wx.EVT_BUTTON(self, wx.ID_FILE1, self.OnBrowse) # Remove File button layout removeFile = wx.Button(self.panel, -1, _("Remove File"), wx.DefaultPosition) v4.Add(removeFile, 0, wx.EXPAND | wx.BOTTOM, 3) wx.EVT_BUTTON(self, removeFile.GetId(), self.OnRemoveFile) if TransanaConstants.proVersion: # SynchronizeFiles button layout synchronize = wx.Button(self.panel, -1, _("Synchronize"), wx.DefaultPosition) v4.Add(synchronize, 0, wx.EXPAND) synchronize.Bind(wx.EVT_BUTTON, self.OnSynchronize) # Add the element to the sizer r3Sizer.Add(v4, 1, wx.EXPAND) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping r3Sizer.Add((2, 0)) # Add the row sizer to the main vertical sizer mainSizer.Add(r3Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r4Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v5 = wx.BoxSizer(wx.VERTICAL) # Comment comment_edit = self.new_edit_box(_("Comment"), v5, self.obj.comment, maxLen=255) # Add the element to the sizer r4Sizer.Add(v5, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r4Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r5Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v6 = wx.BoxSizer(wx.VERTICAL) # Keyword Group [label] txt = wx.StaticText(self.panel, -1, _("Keyword Group")) v6.Add(txt, 0, wx.BOTTOM, 3) # Keyword Group [list box] kw_groups_id = wx.NewId() # Create an empty Keyword Group List for now. We'll populate it later (for layout reasons) self.kw_groups = [] self.kw_group_lb = wx.ListBox(self.panel, kw_groups_id, wx.DefaultPosition, wx.DefaultSize, self.kw_groups) v6.Add(self.kw_group_lb, 1, wx.EXPAND) # Add the element to the sizer r5Sizer.Add(v6, 1, wx.EXPAND) self.kw_list = [] wx.EVT_LISTBOX(self, kw_groups_id, self.OnGroupSelect) # Add a horizontal spacer r5Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v7 = wx.BoxSizer(wx.VERTICAL) # Keyword [label] txt = wx.StaticText(self.panel, -1, _("Keyword")) v7.Add(txt, 0, wx.BOTTOM, 3) # Keyword [list box] self.kw_lb = wx.ListBox(self.panel, -1, wx.DefaultPosition, wx.DefaultSize, self.kw_list, style=wx.LB_EXTENDED) v7.Add(self.kw_lb, 1, wx.EXPAND) wx.EVT_LISTBOX_DCLICK(self, self.kw_lb.GetId(), self.OnAddKW) # Add the element to the sizer r5Sizer.Add(v7, 1, wx.EXPAND) # Add a horizontal spacer r5Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v8 = wx.BoxSizer(wx.VERTICAL) # Keyword transfer buttons add_kw = wx.Button(self.panel, wx.ID_FILE2, ">>", wx.DefaultPosition) v8.Add(add_kw, 0, wx.EXPAND | wx.TOP, 20) wx.EVT_BUTTON(self.panel, wx.ID_FILE2, self.OnAddKW) rm_kw = wx.Button(self.panel, wx.ID_FILE3, "<<", wx.DefaultPosition) v8.Add(rm_kw, 0, wx.EXPAND | wx.TOP, 10) wx.EVT_BUTTON(self, wx.ID_FILE3, self.OnRemoveKW) kwm = wx.BitmapButton(self.panel, wx.ID_FILE4, TransanaImages.KWManage.GetBitmap()) v8.Add(kwm, 0, wx.EXPAND | wx.TOP, 10) # Add a spacer to increase the height of the Keywords section v8.Add((0, 60)) kwm.SetToolTipString(_("Keyword Management")) wx.EVT_BUTTON(self, wx.ID_FILE4, self.OnKWManage) # Add the element to the sizer r5Sizer.Add(v8, 0) # Add a horizontal spacer r5Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v9 = wx.BoxSizer(wx.VERTICAL) # Episode Keywords [label] txt = wx.StaticText(self.panel, -1, _("Episode Keywords")) v9.Add(txt, 0, wx.BOTTOM, 3) # Episode Keywords [list box] # Create an empty ListBox self.ekw_lb = wx.ListBox(self.panel, -1, wx.DefaultPosition, wx.DefaultSize, style=wx.LB_EXTENDED) v9.Add(self.ekw_lb, 1, wx.EXPAND) self.ekw_lb.Bind(wx.EVT_KEY_DOWN, self.OnKeywordKeyDown) # Add the element to the sizer r5Sizer.Add(v9, 2, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r5Sizer, 5, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a sizer for the buttons btnSizer = wx.BoxSizer(wx.HORIZONTAL) # Core Data button layout CoreData = wx.Button(self.panel, -1, _("Core Data")) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping btnSizer.Add((2, 0)) btnSizer.Add(CoreData, 0) wx.EVT_BUTTON(self, CoreData.GetId(), self.OnCoreDataClick) # Add the buttons self.create_buttons(sizer=btnSizer) # Add the button sizer to the main sizer mainSizer.Add(btnSizer, 0, wx.EXPAND) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping mainSizer.Add((0, 2)) # Set the PANEL's main sizer self.panel.SetSizer(mainSizer) # Tell the PANEL to auto-layout self.panel.SetAutoLayout(True) # Lay out the Panel self.panel.Layout() # Lay out the panel on the form self.Layout() # Resize the form to fit the contents self.Fit() # Get the new size of the form (width, height) = self.GetSizeTuple() # Reset the form's size to be at least the specified minimum width self.SetSize(wx.Size(max(550, width), max(435, height))) # Define the minimum size for this dialog as the current size self.SetSizeHints(max(550, width), max(435, height)) # Center the form on screen TransanaGlobal.CenterOnPrimary(self) # We need to set some minimum sizes so the sizers will work right self.kw_group_lb.SetSizeHints(minW = 50, minH = 20) self.kw_lb.SetSizeHints(minW = 50, minH = 20) self.ekw_lb.SetSizeHints(minW = 50, minH = 20) # We populate the Keyword Groups, Keywords, and Clip Keywords lists AFTER we determine the Form Size. # Long Keywords in the list were making the form too big! self.kw_groups = DBInterface.list_of_keyword_groups() for keywordGroup in self.kw_groups: self.kw_group_lb.Append(keywordGroup) # Load the parent Library in order to determine the default Keyword Group tempLibrary = Library.Library(self.obj.series_id) # Select the Library Default Keyword Group in the Keyword Group list if (tempLibrary.keyword_group != '') and (self.kw_group_lb.FindString(tempLibrary.keyword_group) != wx.NOT_FOUND): self.kw_group_lb.SetStringSelection(tempLibrary.keyword_group) # If no Default Keyword Group is defined, select the first item in the list else: # but only if there IS a first item in the list. if len(self.kw_groups) > 0: self.kw_group_lb.SetSelection(0) if self.kw_group_lb.GetSelection() != wx.NOT_FOUND: self.kw_list = \ DBInterface.list_of_keywords_by_group(self.kw_group_lb.GetStringSelection()) else: self.kw_list = [] for keyword in self.kw_list: self.kw_lb.Append(keyword) # Populate the ListBox for episodeKeyword in self.obj.keyword_list: self.ekw_lb.Append(episodeKeyword.keywordPair) self.id_edit.SetFocus()
def OnKeyUp(self, event): """ OnKeyUp event captures the release of keys so they can be processed """ # If ALT and SHIFT are pressed ... if event.AltDown() and event.ShiftDown(): # ... get the key that was pressed key = event.GetKeyCode() # If F11 is pressed, show COMPONENT VERSION information if (key == wx.WXK_F11) or (key in [ord('S'), ord('s')]): # Import Python's ctypes, Transana's DBInterface, Python's sys modules, and numpy import Crypto, ctypes, DBInterface, docx, numpy, paramiko, pyparsing, sys if sys.platform == 'win32': sysplat = 'Windows' sysver = platform.win32_ver()[0] elif sys.platform == 'darwin': sysplat = 'Mac OS X' sysver = platform.mac_ver()[0] else: sysplat = sys.platform sysver = platform.version() str = 'Platform: %s %s' % (sysplat, sysver) # Build a string that contains the version information for crucial programming components str += '\n\nTransana %s uses the following tools:\n\n' % ( TransanaConstants.versionNumber) if (platform.architecture()[0] == '32bit') or (sys.maxint == 2**31 - 1): arc = '32-bit' elif platform.architecture()[0] == '64bit': arc = '64-bit' else: arc = 'Unknown architecture' str = '%sPython: %s (%s)\n' % (str, sys.version[:6].strip(), arc) if 'unicode' in wx.PlatformInfo: str2 = 'unicode' else: str2 = 'ansi' str = '%swxPython: %s - %s\n' % (str, wx.VERSION_STRING, str2) if TransanaConstants.DBInstalled in [ 'MySQLdb-embedded', 'MySQLdb-server' ]: import MySQLdb str = '%sMySQL for Python: %s\n' % (str, MySQLdb.__version__) elif TransanaConstants.DBInstalled in ['PyMySQL']: import pymysql str = '%sPyMySQL: %s\n' % (str, pymysql.version_info) elif TransanaConstants.DBInstalled in ['sqlite3']: import sqlite3 str = '%ssqlite: %s\n' % (str, sqlite3.version) else: str = '%sUnknown Database: Unknown Version\n' % (str, ) if DBInterface._dbref != None: # Get a Database Cursor dbCursor = DBInterface._dbref.cursor() if TransanaConstants.DBInstalled in [ 'MySQLdb-embedded', 'MySQLdb-server', 'PyMySQL' ]: # Query the Database about what Database Names have been defined dbCursor.execute('SELECT VERSION()') vs = dbCursor.fetchall() for v in vs: str = "%sMySQL: %s\n" % (str, v[0]) str = "%sctypes: %s\n" % (str, ctypes.__version__) str = "%sCrypto: %s\n" % (str, Crypto.__version__) str = "%sparamiko: %s\n" % (str, paramiko.__version__) str = "%snumpy: %s\n" % (str, numpy.__version__) str = "%spython-docx: %s\n" % (str, docx.__version__) str = "%slxml: %s\n" % (str, '3.6.0') str = "%spyparsing: %s\n" % (str, pyparsing.__version__) str = "%swordcloud: %s\n" % (str, '1.2.1') str = "%sEncoding: %s\n" % (str, TransanaGlobal.encoding) str = "%sLanguage: %s\n" % ( str, TransanaGlobal.configData.language) # Replace the Description text with the version information text self.description.SetLabel(str) query = "SELECT COUNT(SeriesNum) FROM Series2" dbCursor.execute(query) seriesCount = dbCursor.fetchall()[0][0] query = "SELECT COUNT(DocumentNum) FROM Documents2" dbCursor.execute(query) documentCount = dbCursor.fetchall()[0][0] query = "SELECT COUNT(EpisodeNum) FROM Episodes2" dbCursor.execute(query) episodeCount = dbCursor.fetchall()[0][0] query = "SELECT COUNT(CoreDataNum) FROM CoreData2" dbCursor.execute(query) coreDataCount = dbCursor.fetchall()[0][0] query = "SELECT COUNT(TranscriptNum) FROM Transcripts2 WHERE ClipNum = 0" dbCursor.execute(query) transcriptCount = dbCursor.fetchall()[0][0] query = "SELECT COUNT(CollectNum) FROM Collections2" dbCursor.execute(query) collectionCount = dbCursor.fetchall()[0][0] query = "SELECT COUNT(quoteNum) FROM Quotes2" dbCursor.execute(query) quoteCount = dbCursor.fetchall()[0][0] query = "SELECT COUNT(clipNum) FROM Clips2" dbCursor.execute(query) clipCount = dbCursor.fetchall()[0][0] query = "SELECT COUNT(TranscriptNum) FROM Transcripts2 WHERE ClipNum <> 0" dbCursor.execute(query) clipTranscriptCount = dbCursor.fetchall()[0][0] query = "SELECT COUNT(SnapshotNum) FROM Snapshots2" dbCursor.execute(query) snapshotCount = dbCursor.fetchall()[0][0] query = "SELECT COUNT(NoteNum) FROM Notes2" dbCursor.execute(query) noteCount = dbCursor.fetchall()[0][0] query = "SELECT COUNT(Keyword) FROM Keywords2" dbCursor.execute(query) keywordCount = dbCursor.fetchall()[0][0] query = "SELECT COUNT(Keyword) FROM ClipKeywords2" dbCursor.execute(query) clipKeywordCount = dbCursor.fetchall()[0][0] query = "SELECT COUNT(Keyword) FROM SnapshotKeywords2" dbCursor.execute(query) snapshotKeywordCount = dbCursor.fetchall()[0][0] query = "SELECT COUNT(Keyword) FROM SnapshotKeywordStyles2" dbCursor.execute(query) snapshotKeywordStylesCount = dbCursor.fetchall()[0][0] query = "SELECT COUNT(AddVidNum) FROM AdditionalVids2" dbCursor.execute(query) addVidCount = dbCursor.fetchall()[0][0] query = "SELECT COUNT(ConfigName) FROM Filters2" dbCursor.execute(query) filterCount = dbCursor.fetchall()[0][0] tmpStr = """Data Records: Libraries: %s Documents: %s Episodes: %s Episode Transcripts: %s Collections: %s Quotes: %s Clips: %s Clip Transcripts: %s Snapshots: %s Notes: %s Keywords: %s Quote/Clip Keywords: %s Snapshot Keywords: %s Snapshot Keyword Styles: %s Additional Videos: %s Filters: %s Core Data: %s\n """ data = (seriesCount, documentCount, episodeCount, transcriptCount, collectionCount, quoteCount, clipCount, clipTranscriptCount, snapshotCount, noteCount, keywordCount, clipKeywordCount, snapshotKeywordCount, snapshotKeywordStylesCount, addVidCount, filterCount, coreDataCount) # Eliminate the Credits text self.credits.SetLabel(tmpStr % data) self.translations.SetLabel('') self.ffmpeg.SetLabel('') # If F12 is pressed ... elif (key == wx.WXK_F12) or (key in [ord('H'), ord('h')]): # Replace the Version information text with the original description text self.description.SetLabel(self.description_str) # Replace the blank credits text with the original credits text self.credits.SetLabel(self.credits_str) self.translations.SetLabel(self.translations_str) self.ffmpeg.SetLabel(self.ffmpeg_str) # Fit the window to the altered controls self.Fit() TransanaGlobal.CenterOnPrimary(self) # If ALT and SHIFT aren't both pressed ... else: # ... then we don't do anything pass
def __init__(self, parent, errmsg, dlgCaption=_("Transana Error"), includeSkipCheck=False): # This should be easy, right? Just use the OS MessageDialog like so: # wx.MessageDialog.__init__(self, parent, errmsg, _("Transana Error"), wx.OK | wx.CENTRE | wx.ICON_ERROR) # That's all there is to it, right? # # Yeah, right. Unfortunately, on Windows, this dialog isn't TRULY modal. It's modal to the parent window # it's called from, but you can still select one of the other Transana Windows and do stuff. This message # can even get hidden behind other windows, and cause all kinds of problems. According to Robin Dunn, # writing my own class to do this is the only solution. Here goes. # Remember if we're supposed to include the checkbox to skip additional messages self.includeSkipCheck = includeSkipCheck # Create a Dialog box wx.Dialog.__init__(self, parent, -1, dlgCaption, size=(350, 150), style=wx.CAPTION | wx.CLOSE_BOX | wx.STAY_ON_TOP) # Set "Window Variant" to small only for Mac to make fonts match better if "__WXMAC__" in wx.PlatformInfo: self.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) # Create Vertical and Horizontal Sizers box = wx.BoxSizer(wx.VERTICAL) box2 = wx.BoxSizer(wx.HORIZONTAL) # Display the Error graphic in the dialog box graphic = wx.StaticBitmap(self, -1, TransanaImages.ArtProv_ERROR.GetBitmap()) # Add the graphic to the Sizers box2.Add(graphic, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, 10) # Display the error message in the dialog box message = wx.StaticText(self, -1, errmsg) # Add the error message to the Sizers box2.Add( message, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10) box.Add(box2, 0, wx.EXPAND) # If we should add the "Skip Further messages" checkbox ... if self.includeSkipCheck: # ... then add the checkbox to the dialog self.skipCheck = wx.CheckBox(self, -1, _('Do not show this message again')) # ... and add the checkbox to the Sizers box.Add(self.skipCheck, 0, wx.ALIGN_CENTER | wx.ALL, 10) # Add an OK button btnOK = wx.Button(self, wx.ID_OK, _("OK")) # Add the OK button to the Sizers box.Add(btnOK, 0, wx.ALIGN_CENTER | wx.BOTTOM, 10) # Make the OK button the default self.SetDefaultItem(btnOK) # Turn on Auto Layout self.SetAutoLayout(True) # Set the form sizer self.SetSizer(box) # Set the form size self.Fit() # Perform the Layout self.Layout() # Center the dialog on the screen # self.CentreOnScreen() # That's not working. Let's try this ... TransanaGlobal.CenterOnPrimary(self)
def __init__(self, parent, id, title, note_object): # Make the Keyword Edit List resizable by passing wx.RESIZE_BORDER style Dialogs.GenForm.__init__(self, parent, id, title, size=(400, 260), style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, useSizers = True, HelpContext='Notes') # 'Notes' is the Help Context for Notes. There is no entry for Note Properties at this time self.obj = note_object seriesID = '' episodeID = '' transcriptID = '' collectionID = '' clipID = '' snapshotID = '' documentID = '' quoteID = '' if (self.obj.series_num != 0) and (self.obj.series_num != None): tempLibrary = Library.Library(self.obj.series_num) seriesID = tempLibrary.id elif (self.obj.episode_num != 0) and (self.obj.episode_num != None): tempEpisode = Episode.Episode(self.obj.episode_num) episodeID = tempEpisode.id tempLibrary = Library.Library(tempEpisode.series_num) seriesID = tempLibrary.id elif (self.obj.transcript_num != 0) and (self.obj.transcript_num != None): # To save time here, we can skip loading the actual transcript text, which can take time once we start dealing with images! tempTranscript = Transcript.Transcript(self.obj.transcript_num, skipText=True) transcriptID = tempTranscript.id tempEpisode = Episode.Episode(tempTranscript.episode_num) episodeID = tempEpisode.id tempLibrary = Library.Library(tempEpisode.series_num) seriesID = tempLibrary.id elif (self.obj.collection_num != 0) and (self.obj.collection_num != None): tempCollection = Collection.Collection(self.obj.collection_num) collectionID = tempCollection.GetNodeString() elif (self.obj.clip_num != 0) and (self.obj.clip_num != None): # We can skip loading the Clip Transcript to save load time tempClip = Clip.Clip(self.obj.clip_num, skipText=True) clipID = tempClip.id tempCollection = Collection.Collection(tempClip.collection_num) collectionID = tempCollection.GetNodeString() elif (self.obj.snapshot_num != 0) and (self.obj.snapshot_num != None): tempSnapshot = Snapshot.Snapshot(self.obj.snapshot_num) snapshotID = tempSnapshot.id tempCollection = Collection.Collection(tempSnapshot.collection_num) collectionID = tempCollection.GetNodeString() elif (self.obj.document_num != 0) and (self.obj.document_num != None): tempDocument = Document.Document(self.obj.document_num) documentID = tempDocument.id tempLibrary = Library.Library(tempDocument.library_num) seriesID = tempLibrary.id elif (self.obj.quote_num != 0) and (self.obj.quote_num != None): tempQuote = Quote.Quote(num=self.obj.quote_num, skipText=True) quoteID = tempQuote.id tempCollection = Collection.Collection(tempQuote.collection_num) collectionID = tempCollection.GetNodeString() # Create the form's main VERTICAL sizer mainSizer = wx.BoxSizer(wx.VERTICAL) # Create a HORIZONTAL sizer for the first row r1Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v1 = wx.BoxSizer(wx.VERTICAL) # Note ID id_edit = self.new_edit_box(_("Note ID"), v1, self.obj.id, maxLen=100) # Add the element to the sizer r1Sizer.Add(v1, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r1Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r2Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v2 = wx.BoxSizer(wx.VERTICAL) # Library ID seriesID_edit = self.new_edit_box(_("Library ID"), v2, seriesID) # Add the element to the row sizer r2Sizer.Add(v2, 1, wx.EXPAND) seriesID_edit.Enable(False) # Add the row sizer to the main vertical sizer mainSizer.Add(r2Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r3Sizer = wx.BoxSizer(wx.HORIZONTAL) if TransanaConstants.proVersion: # Create a VERTICAL sizer for the next element v9 = wx.BoxSizer(wx.VERTICAL) # Document ID documentID_edit = self.new_edit_box(_("Document ID"), v9, documentID) # Add the element to the row sizer r3Sizer.Add(v9, 1, wx.EXPAND) documentID_edit.Enable(False) # Add a horizontal spacer to the row sizer r3Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v3 = wx.BoxSizer(wx.VERTICAL) # Episode ID episodeID_edit = self.new_edit_box(_("Episode ID"), v3, episodeID) # Add the element to the row sizer r3Sizer.Add(v3, 1, wx.EXPAND) episodeID_edit.Enable(False) # Add a horizontal spacer to the row sizer r3Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v4 = wx.BoxSizer(wx.VERTICAL) # Transcript ID transcriptID_edit = self.new_edit_box(_("Transcript ID"), v4, transcriptID) # Add the element to the row sizer r3Sizer.Add(v4, 1, wx.EXPAND) transcriptID_edit.Enable(False) # Add the row sizer to the main vertical sizer mainSizer.Add(r3Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r5Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v5 = wx.BoxSizer(wx.VERTICAL) # Collection ID collectionID_edit = self.new_edit_box(_("Collection ID"), v5, collectionID) # Add the element to the row sizer r5Sizer.Add(v5, 2, wx.EXPAND) collectionID_edit.Enable(False) # Add the row sizer to the main vertical sizer mainSizer.Add(r5Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r6Sizer = wx.BoxSizer(wx.HORIZONTAL) if TransanaConstants.proVersion: # Create a VERTICAL sizer for the next element v7 = wx.BoxSizer(wx.VERTICAL) # Quote ID quoteID_edit = self.new_edit_box(_("Quote ID"), v7, quoteID) # Add the element to the row sizer r6Sizer.Add(v7, 1, wx.EXPAND) quoteID_edit.Enable(False) # Add a horizontal spacer to the row sizer r6Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v6 = wx.BoxSizer(wx.VERTICAL) # Clip ID clipID_edit = self.new_edit_box(_("Clip ID"), v6, clipID) # Add the element to the row sizer r6Sizer.Add(v6, 1, wx.EXPAND) clipID_edit.Enable(False) if TransanaConstants.proVersion: # Add a horizontal spacer to the row sizer r6Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v8 = wx.BoxSizer(wx.VERTICAL) # Snapshot ID snapshotID_edit = self.new_edit_box(_("Snapshot ID"), v8, snapshotID) # Add the element to the row sizer r6Sizer.Add(v8, 1, wx.EXPAND) snapshotID_edit.Enable(False) # Add the row sizer to the main vertical sizer mainSizer.Add(r6Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r8Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v8 = wx.BoxSizer(wx.VERTICAL) # Comment layout noteTaker_edit = self.new_edit_box(_("Note Taker"), v8, self.obj.author, maxLen=100) # Add the element to the row sizer r8Sizer.Add(v8, 2, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r8Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a sizer for the buttons btnSizer = wx.BoxSizer(wx.HORIZONTAL) # Add the buttons self.create_buttons(sizer=btnSizer) # Add the button sizer to the main sizer mainSizer.Add(btnSizer, 0, wx.EXPAND) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping mainSizer.Add((0, 2)) # Set the PANEL's main sizer self.panel.SetSizer(mainSizer) # Tell the PANEL to auto-layout self.panel.SetAutoLayout(True) # Lay out the Panel self.panel.Layout() # Lay out the panel on the form self.Layout() # Resize the form to fit the contents self.Fit() # Get the new size of the form (width, height) = self.GetSizeTuple() # Reset the form's size to be at least the specified minimum width self.SetSize(wx.Size(max(400, width), height)) # Define the minimum size for this dialog as the current size, and define height as unchangeable self.SetSizeHints(max(400, width), height, -1, height) # Center the form on screen TransanaGlobal.CenterOnPrimary(self) # Set focus to the Note ID id_edit.SetFocus()
def __init__(self, title, data, dataLabels, size=(800, 700)): """ Create a BarChart. title Title for the BarChart data List of data values for the BarChart dataLabels Matching list of data labels for the BarChart This module sizes the bitmap for a printed page by default. """ def barXPos(x): """ Calculate the horizontal center for each bar in pixels """ # numBars, barChartLeft, and barChartWidth are constants in the calling routine # Calculate the width of each bar barWidth = barChartWidth / numBars # Calculate the position of each bar barXPos = (float(x) / numBars) * barChartWidth + barWidth / 2 + barChartLeft # Return the bar center position return barXPos def barHeight(x): """ Calculate the height of each bar in pixels """ # data and barChartHeight are constants in the calling routine # Determine the size of the largest bar barMax = max(data) # Calculate the height of the bar value passed in barHeight = float(x) / barMax * barChartHeight # We return 95% of the height value to give the bar chart some white space at the top. return int(barHeight * 0.95) def verticalAxisValues(maxVal): """ Given the maximum value of the axis, determine what values should appear as axis labels. This method implements the 2-5-10 rule. """ # Initialize a list of values to return values = [] # Let's normalize the data as part of assigning axis labels # Initilaize the increment between axis label values increment = 1 # Initialize the conversion factor for axis labels, used in handling large values convertFactor = 1 # While our maxValue is over 100 ... while maxVal > 100: # ... reduce the maximum value by a factor of 10 ... maxVal /= 10 # ... and increase our conversion factor by a factor of 10. convertFactor *= 10 # If our normalized max value is over 50 ... if maxVal > 50: # ... increments of 10 will give us between 5 and 10 labels increment = 10 # If our normalized max value is between 20 and 50 ... elif maxVal > 20: # ... increments of 5 will give us between 4 and 10 labels increment = 5 # If our normalized max value is between 8 and 20 ... elif maxVal > 8: # ... increments of 2 will give us between 4 and 10 labels increment = 2 # If our normalized max value is 8 or less ... else: # ... increments of 1 will five us between 1 and 8 labels. increment = 1 # for values between 0 and our max value (plus 1 to include the mac value if a multiple of 10) space by increment ... for x in range(0, maxVal + 1, increment): # ... add the incremental value multiplied by the conversion factor to our list of axis labels values.append(x * convertFactor) # Return the list of axis labels return values # Get the Graphic Dimensions (imgWidth, imgHeight) = size # Create an empty bitmap self.bitmap = wx.EmptyBitmap(imgWidth, imgHeight) # Get the Device Context for that bitmap self.dc = wx.BufferedDC(None, self.bitmap) # The length of data is the number of bars we need numBars = len(data) # Determine the longest bar label # Define the label font size axisLabelFontSize = 11 # Define a Font for axis labels font = wx.Font(axisLabelFontSize, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.NORMAL, False) # Set the Font for the DC self.dc.SetFont(font) # Initize the max width variable maxWidth = 0 # For each bar label ... for x in range(numBars): # ... determine the size of the label (txtWidth, txtHeight) = self.dc.GetTextExtent(dataLabels[x]) # See if it's bigger than previous labels maxWidth = max(txtWidth, maxWidth) # Give a left margin of 70 pixels for the vertical axis labels barChartLeft = 70 # The width of the bar chart will be the image width less the left margin and 25 pixels for right margin barChartWidth = imgWidth - barChartLeft - 25 # Give a top margin of 50 pixels to have room for the chart title if title != '': barChartTop = 50 # or 20 pixels if there is no title else: barChartTop = 20 # Reserve almost HALF the image for bar labels. (Transana uses LONG labels!) barChartHeight = max(imgHeight / 2, imgHeight - maxWidth - barChartTop - 30) # Initialize a colorIndex to track what color to assign each bar colorIndx = 0 # Define the colors to be used in the BarChart # If we're running stand-alone ... if __name__ == '__main__': # ... use generic colors colors = [ '#FF0000', '#00FF00', '#0000FF', '#666600', '#FF00FF', '#00FFFF', '#440000', '#004400', '#000044' ] # There are no defined Colors for Keywords when running stand-alone colorsForKeywords = {} # If we're running inside Transana ... else: # ... import Transana's Global Values ... import TransanaGlobal # ... and use Transana's defined color scheme colorList = TransanaGlobal.getColorDefs( TransanaGlobal.configData.colorConfigFilename)[:-1] # Initialize the Colors list colors = [] # Populate the colors list from Transana's defined colors for colorName, colorDef in colorList: colors.append(colorDef) # Get the color definitions for all keywords in Transana with defined colors colorsForKeywords = DBInterface.dict_of_keyword_colors() # Define a white brush as the DC Background self.dc.SetBackground(wx.Brush((255, 255, 255))) # Clear the Image (uses the Brush) self.dc.Clear() # Draw a border around the whole bitmap # Set the DC Pen self.dc.SetPen(wx.Pen((0, 0, 0), 2, wx.SOLID)) # Draw an outline around the whole graphic self.dc.DrawRectangle(1, 1, imgWidth - 1, imgHeight - 1) # Place the Title on the DC # Define a Font font = wx.Font(18, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.NORMAL, False) # Set the Font for the DC self.dc.SetFont(font) # Set the Text Foreground Color to Black self.dc.SetTextForeground(wx.Colour(0, 0, 0)) # Determine the size of the title text (titleWidth, titleHeight) = self.dc.GetTextExtent(title) # Add the Title to the Memory DC (and therefore the bitmap) self.dc.DrawText(title, imgWidth / 2 - titleWidth / 2, 10) # Define a Font for axis labels font = wx.Font(axisLabelFontSize, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.NORMAL, False) # Set the Font for the DC self.dc.SetFont(font) # Draw Axes # Draw an outline around the Bar Chart area with just a little extra width so it looks better self.dc.DrawRectangle(barChartLeft - 3, barChartTop, barChartWidth + 6, barChartHeight) # Get the values that should be used for the vertical axis labels axisValues = verticalAxisValues(max(data)) # For each axis label ... for x in axisValues: # ... draw a pip at the value self.dc.DrawLine(barChartLeft - 8, barChartTop + barChartHeight - barHeight(x) - 1, barChartLeft - 3, barChartTop + barChartHeight - barHeight(x) - 1) # Convert the axis value to right-justified text axisLbl = "%10d" % x # Determine the size of the axis label (txtWidth, txtHeight) = self.dc.GetTextExtent(axisLbl) # Add the text to the drawing at just the right position self.dc.DrawText( axisLbl, barChartLeft - txtWidth - 13, barChartTop + barChartHeight - barHeight(x) - txtHeight / 2) # For each bar in the bar chart ... for x in range(numBars): # ... draw the pips for the bar labels self.dc.DrawLine(barXPos(x), barChartTop + barChartHeight, barXPos(x), barChartTop + barChartHeight + 3) # If there's a color defined for the Keyword ... if dataLabels[x] in colorsForKeywords.keys(): # ... use that color color = colorsForKeywords[dataLabels[x]]['colorDef'] # If there's no color defined ... else: # ... use the next color from the color list color = colors[colorIndx] # Increment or reset the color index if colorIndx >= len(colors) - 1: colorIndx = 0 else: colorIndx += 1 # Label the bars # Set the Text Foreground Color self.dc.SetTextForeground(color) # Get the size of the bar label (txtWidth, txtHeight) = self.dc.GetTextExtent(dataLabels[x]) # Add the bar label to the bar chart self.dc.DrawRotatedText(dataLabels[x], barXPos(x) + (txtHeight / 2), barChartTop + barChartHeight + 10, 270) # Calculate bar width as 80% of the width a bar would be with no whitespace between bars barWidth = float(barChartWidth) / numBars * 0.8 # Set the Brush color to the color to be used for the bar self.dc.SetBrush(wx.Brush(color)) # Draw the actual bar. 3 extra points compensates for the line thickness. self.dc.DrawRectangle( barXPos(x) - barWidth / 2 + 1, barChartTop + barChartHeight - barHeight(data[x]) - 3, barWidth, barHeight(data[x]) + 3)
def __init__(self, parent, id, title, coll_object): self.width = 400 self.height = 210 # Make the Keyword Edit List resizable by passing wx.RESIZE_BORDER style Dialogs.GenForm.__init__(self, parent, id, title, (self.width, self.height), style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, useSizers = True, HelpContext='Collection Properties') self.obj = coll_object # Create the form's main VERTICAL sizer mainSizer = wx.BoxSizer(wx.VERTICAL) # Create a HORIZONTAL sizer for the first row r1Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v1 = wx.BoxSizer(wx.VERTICAL) # Collection ID id_edit = self.new_edit_box(_("Collection ID"), v1, self.obj.id, maxLen=100) # Add the element to the row sizer r1Sizer.Add(v1, 1, wx.EXPAND) # Add a horizontal spacer to the row sizer r1Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v2 = wx.BoxSizer(wx.VERTICAL) # Owner owner_edit = self.new_edit_box(_("Owner"), v2, self.obj.owner, maxLen=100) # Add the element to the row sizer r1Sizer.Add(v2, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r1Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r2Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v3 = wx.BoxSizer(wx.VERTICAL) # Comment comment_edit = self.new_edit_box(_("Comment"), v3, self.obj.comment, maxLen=255) # Add the element to the row sizer r2Sizer.Add(v3, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r2Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r3Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v4 = wx.BoxSizer(wx.VERTICAL) # Default KW Group self.kw_groups = DBInterface.list_of_keyword_groups() self.kwg_choice = self.new_choice_box(_("Default Keyword Group"), v4, [""] + self.kw_groups, 0) # Add the element to the row sizer r3Sizer.Add(v4, 1, wx.EXPAND) if (self.obj.keyword_group) and (self.kwg_choice.FindString(self.obj.keyword_group) != wx.NOT_FOUND): self.kwg_choice.SetStringSelection(self.obj.keyword_group) else: self.kwg_choice.SetSelection(0) if self.obj.parent <> 0: # Add a horizontal spacer to the row sizer r3Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v5 = wx.BoxSizer(wx.VERTICAL) # Parent Collection Name coll_parent_edit = self.new_edit_box(_("Parent Collection"), v5, self.obj.parentName) # Add the element to the row sizer r3Sizer.Add(v5, 1, wx.EXPAND) coll_parent_edit.Enable(False) # Add the row sizer to the main vertical sizer mainSizer.Add(r3Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a sizer for the buttons btnSizer = wx.BoxSizer(wx.HORIZONTAL) # Add the buttons self.create_buttons(sizer=btnSizer) # Add the button sizer to the main sizer mainSizer.Add(btnSizer, 0, wx.EXPAND) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping mainSizer.Add((0, 2)) # Set the PANEL's main sizer self.panel.SetSizer(mainSizer) # Tell the PANEL to auto-layout self.panel.SetAutoLayout(True) # Lay out the Panel self.panel.Layout() # Lay out the panel on the form self.Layout() # Resize the form to fit the contents self.Fit() # Get the new size of the form (width, height) = self.GetSizeTuple() # Reset the form's size to be at least the specified minimum width self.SetSize(wx.Size(max(self.width, width), height)) # Define the minimum size for this dialog as the current size, and define height as unchangeable self.SetSizeHints(max(self.width, width), height, -1, height) # Center the form on screen TransanaGlobal.CenterOnPrimary(self) # Set focus to Series ID id_edit.SetFocus()
def OnInit(self): """ Initialize the application """ # If we have a Workshop Version, see if the version is still valid, report to the user and exit if not. # NOTE: This code just provides a user message and clean exit. Transana will still be disabled if this # code is removed. (This code is user-accessible on OS X!) if TransanaConstants.workshopVersion: import datetime t1 = TransanaConstants.startdate t2 = TransanaConstants.expirationdate t3 = time.localtime() t4 = datetime.datetime(t3[0], t3[1], t3[2], t3[3], t3[4]) if (t1 > t4) or (t2 < t4): dlg = Dialogs.ErrorDialog(None, "This copy of Transana is no longer valid.") dlg.ShowModal() dlg.Destroy return False # In wxPython, you used to be able to initialize the ConfigData object in the TransanaGlobal module, even though the # wx.App() hadn't been initialized yet. Moving from wxPython 2.8.1 to wxPython 2.8.9, this stopped being true # at least on the Mac. Therefore, we moved creation of the ConfigData object to here in the code. # However, there are MANY references to ConfigData being in the TransanaGlobal module, so that's where we'll keep it. TransanaGlobal.configData = ConfigData.ConfigData() # If we are running from a BUILD instead of source code ... if hasattr(sys, "frozen"): # or ('wxMac' in wx.PlatformInfo): # See if the Default Profile Path exists. If not ... if not os.path.exists(TransanaGlobal.configData.GetDefaultProfilePath()): # ... then create it (recursively). os.makedirs(TransanaGlobal.configData.GetDefaultProfilePath()) # Build the path for the error log path = os.path.join(TransanaGlobal.configData.GetDefaultProfilePath(), "Transana_Error.log") # redirect output to the error log self.RedirectStdio(filename=path) # Put a startup indicator in the Error Log print "Transana started:", time.asctime() # If no Language is defined ... if TransanaGlobal.configData.language == "": # ... then we know this is the first startup for this user profile. Remember that! firstStartup = True # If language is known ... else: # ... then it's NOT first time startup. firstStartup = False # Now that we've loaded the Configuration Data, we can see if we need to alter the default encoding # If we're on Windows, single-user, using Russian, use KOI8r encoding instead of Latin-1, # Chinese uses big5, Japanese uses cp932, and Korean uses cp949 ## if ('wxMSW' in wx.PlatformInfo) and (TransanaConstants.singleUserVersion): ## if (TransanaGlobal.configData.language == 'ru'): ## TransanaGlobal.encoding = 'koi8_r' ## elif (TransanaGlobal.configData.language == 'zh'): ## TransanaGlobal.encoding = TransanaConstants.chineseEncoding ## elif (TransanaGlobal.configData.language == 'el'): ## TransanaGlobal.encoding = 'iso8859_7' ## elif (TransanaGlobal.configData.language == 'ja'): ## TransanaGlobal.encoding = 'cp932' ## elif (TransanaGlobal.configData.language == 'ko'): ## TransanaGlobal.encoding = 'cp949' # Use UTF-8 Encoding throughout Transana to allow maximum internationalization if ("unicode" in wx.PlatformInfo) and (wx.VERSION_STRING >= "2.6"): wx.SetDefaultPyEncoding("utf_8") # On OS/X, change the working directory to the directory the script is # running from, this is necessary for running from a bundle. if "__WXMAC__" in wx.PlatformInfo: if TransanaGlobal.programDir != "": os.chdir(TransanaGlobal.programDir) import MenuWindow # import Menu Window Object sys.excepthook = transana_excepthook # Define the system exception handler # First, determine the program name that should be displayed, single or multi-user if TransanaConstants.singleUserVersion: if TransanaConstants.proVersion: programTitle = _("Transana - Professional") else: programTitle = _("Transana - Standard") else: programTitle = _("Transana - Multiuser") # Ammend the program title for the Demo version if appropriate if TransanaConstants.demoVersion: programTitle += _(" - Demonstration") # Create the Menu Window TransanaGlobal.menuWindow = MenuWindow.MenuWindow(None, -1, programTitle) # Create the global transana graphics colors, once the ConfigData object exists. TransanaGlobal.transana_graphicsColorList = TransanaGlobal.getColorDefs( TransanaGlobal.configData.colorConfigFilename ) # Set essential global color manipulation data structures once the ConfigData object exists. ( TransanaGlobal.transana_colorNameList, TransanaGlobal.transana_colorLookup, TransanaGlobal.keywordMapColourSet, ) = TransanaGlobal.SetColorVariables() # Add the RTF modules to the Python module search path. This allows # us to import from a directory other than the standard search paths # and the current directory/subdirectories. sys.path.append("rtf") # Load the Splash Screen graphic bitmap = TransanaImages.splash.GetBitmap() # We need to draw the Version Number onto the Splash Screen Graphic. # First, create a Memory DC memoryDC = wx.MemoryDC() # Select the bitmap into the Memory DC memoryDC.SelectObject(bitmap) # Build the Version label if TransanaConstants.singleUserVersion: if TransanaConstants.labVersion: versionLbl = _("Computer Lab Version") elif TransanaConstants.demoVersion: versionLbl = _("Demonstration Version") elif TransanaConstants.workshopVersion: versionLbl = _("Workshop Version") else: if TransanaConstants.proVersion: versionLbl = _("Professional Version") else: versionLbl = _("Standard Version") else: versionLbl = _("Multi-user Version") versionLbl += " %s" # Determine the size of the version text (verWidth, verHeight) = memoryDC.GetTextExtent(versionLbl % TransanaConstants.versionNumber) # Add the Version Number text to the Memory DC (and therefore the bitmap) memoryDC.DrawText(versionLbl % TransanaConstants.versionNumber, 370 - verWidth, 156) # Clear the bitmap from the Memory DC, thus freeing it to be displayed! memoryDC.SelectObject(wx.EmptyBitmap(10, 10)) # If the Splash Screen Graphic exists, display the Splash Screen for 4 seconds. # If not, raise an exception. if bitmap: # Mac requires a different style, as "STAY_ON_TOP" adds a header to the Splash Screen if "__WXMAC__" in wx.PlatformInfo: splashStyle = wx.SIMPLE_BORDER else: splashStyle = wx.SIMPLE_BORDER | wx.STAY_ON_TOP # If we have a Right-To-Left language ... if TransanaGlobal.configData.LayoutDirection == wx.Layout_RightToLeft: # ... we need to reverse the image direcion bitmap = bitmap.ConvertToImage().Mirror().ConvertToBitmap() splashPosition = wx.DefaultPosition ## This doesn't work. I have not been able to put the Splash Screen anywhere but on the Center of ## Monitor 0 (with wx.SPASH_CENTER_ON_SCREEN) or the upper left corner of Monitor 0 (without it). Bummer. ## # Get the Size and Position for the PRIMARY screen ## (x1, y1, w1, h1) = wx.Display(TransanaGlobal.configData.primaryScreen).GetClientArea() ## (x2, y2) = bitmap.GetSize() ## ## splashPosition = (int(float(w1) / 2.0) + x1 - int(float(x2) / 2.0), ## int(float(h1) / 2.0) + y1 - int(float(y2) / 2.0)) ## ## print "Splash Screen Position:" ## print TransanaGlobal.configData.primaryScreen ## print x1, y1, w1, h1 ## print x2, y2 ## print splashPosition ## print # Create the SplashScreen object splash = wx.SplashScreen( bitmap, wx.SPLASH_CENTER_ON_SCREEN | wx.SPLASH_TIMEOUT, 4000, None, -1, splashPosition, wx.DefaultSize, splashStyle, ) else: raise ImageLoadError, _("Unable to load Transana's splash screen image. Installation error?") wx.Yield() if DEBUG: print "Number of Monitors:", wx.Display.GetCount() for x in range(wx.Display.GetCount()): print " ", x, wx.Display(x).IsPrimary(), wx.Display(x).GetGeometry(), wx.Display(x).GetClientArea() print import DataWindow # import Data Window Object import VideoWindow # import Video Window Object # import Transcript Window Object if TransanaConstants.USESRTC: import TranscriptionUI_RTC as TranscriptionUI else: import TranscriptionUI import VisualizationWindow # import Visualization Window Object import exceptions # import exception handler (Python) # if we're running the multi-user version of Transana ... if not TransanaConstants.singleUserVersion: # ... import the Transana ChatWindow module import ChatWindow # Initialize all main application Window Objects # If we're running the Lab version OR we're on the Mac ... if TransanaConstants.labVersion or ("wxMac" in wx.PlatformInfo): # ... then pausing for 4 seconds delays the appearance of the Lab initial configuration dialog # or the Mac version login / database dialog until the Splash screen closes. time.sleep(4) # If we are running the Lab version ... if TransanaConstants.labVersion: # ... we want an initial configuration screen. Start by importing Transana's Option Settings dialog import OptionsSettings # Initialize all paths to BLANK for the lab version TransanaGlobal.configData.videoPath = "" TransanaGlobal.configData.visualizationPath = "" TransanaGlobal.configData.databaseDir = "" # Create the config dialog for the Lab initial configuration options = OptionsSettings.OptionsSettings(TransanaGlobal.menuWindow, lab=True) options.Destroy() wx.Yield() # If the databaseDir is blank, user pressed CANCEL ... if TransanaGlobal.configData.databaseDir == "": # ... and we should quit immediately, signalling failure return False # initialze a variable indicating database connection to False (assume the worst.) connectionEstablished = False # Let's trap the situation where the database folder is not available. try: # Start MySQL if using the embedded version if TransanaConstants.singleUserVersion: DBInterface.InitializeSingleUserDatabase() # If we get here, we've been successful! (NOTE that MU merely changes our default from False to True!) connectionEstablished = True except: if DEBUG: import traceback print sys.exc_info()[0], sys.exc_info()[1] traceback.print_exc(file=sys.stdout) msg = _( 'Transana is unable to access any Database at "%s".\nPlease check to see if this path is available.' ) if not TransanaConstants.labVersion: msg += "\n" + _("Would you like to restore the default Database path?") if ("unicode" in wx.PlatformInfo) and isinstance(msg, str): msg = unicode(msg, "utf8") msg = msg % TransanaGlobal.configData.databaseDir if TransanaConstants.labVersion: dlg = Dialogs.ErrorDialog(None, msg) dlg.ShowModal() dlg.Destroy() return False # If we're on the Single-user version for Windows ... if TransanaConstants.singleUserVersion: # ... determine the file name for the data conversion information pickle file fs = os.path.join(TransanaGlobal.configData.databaseDir, "260_300_Convert.pkl") # If there is data in mid-conversion ... if os.path.exists(fs): # ... get the conversion data from the Pickle File f = file(fs, "r") # exportedDBs is a dictionary containing the Transana-XML file name and the encoding of each DB to be imported self.exportedDBs = pickle.load(f) # Close the pickle file f.close() # Prompt the user about importing the converted data prompt = unicode( _( "Transana has detected one or more databases ready for conversion.\nDo you want to convert those databases now?" ), "utf8", ) tmpDlg = Dialogs.QuestionDialog(TransanaGlobal.menuWindow, prompt, _("Database Conversion")) result = tmpDlg.LocalShowModal() tmpDlg.Destroy() # If the user wants to do the conversion now ... if result == wx.ID_YES: # ... import Transana's XML Import code import XMLImport # Before we go further, let's make sure none of the conversion files have ALREADY been imported! # The 2.42 to 2.50 Data Conversion Utility shouldn't allow this, but it doesn't hurt to check. # Iterate through the conversion data for key in self.exportedDBs: # Determine the file path for the converted database newDBPath = os.path.join(TransanaGlobal.configData.databaseDir, key + ".db") # If the converted database ALREADY EXISTS ... if os.path.exists(newDBPath): # ... create an error message prompt = unicode( _('Database "%s" already exists.\nDatabase "%s" cannot be converted at this time.'), "utf8", ) # ... display an error message tmpDlg = Dialogs.ErrorDialog(None, prompt % (key, key)) tmpDlg.ShowModal() tmpDlg.Destroy() # If the converted database does NOT exist ... else: if "wxMac" in wx.PlatformInfo: prompt = _( 'Converting "%s"\nThis process may take a long time, depending on how much data this database contains.\nWe cannot provide progress feedback on OS X. Please be patient.' ) progWarn = Dialogs.PopupDialog(None, _("Converting Databases"), prompt % key) # Create the Import Database, passing the database name so the user won't be prompted for one. DBInterface.establish_db_exists(dbToOpen=key, usePrompt=False) # Import the database. # First, create an Import Database dialog, but don't SHOW it. temp = XMLImport.XMLImport( TransanaGlobal.menuWindow, -1, _("Transana XML Import"), importData=self.exportedDBs[key], ) # ... Import the requested data! temp.Import() # Close the Import Database dialog temp.Close() if "wxMac" in wx.PlatformInfo: progWarn.Destroy() progWarn = None # Close the database that was just imported DBInterface.close_db() # Clear the current database name from the Config data TransanaGlobal.configData.database = "" # If we do NOT have a localhost key (which Lab version does not!) ... if not TransanaGlobal.configData.databaseList.has_key("localhost"): # ... let's create one so we can pass the converted database name! TransanaGlobal.configData.databaseList["localhost"] = {} TransanaGlobal.configData.databaseList["localhost"]["dbList"] = [] # Update the database name TransanaGlobal.configData.database = key # Add the new (converted) database name to the database list TransanaGlobal.configData.databaseList["localhost"]["dbList"].append(key.encode("utf8")) # Start exception handling try: # If we're NOT in the lab version of Transana ... if not TransanaConstants.labVersion: # This is harder than it should be because of a combination of encoding and case-changing issues. # Let's iterate through the Version 2.5 "paths by database" config data for key2 in TransanaGlobal.configData.pathsByDB2.keys(): # If we have a LOCAL database with a matching key to the database being imported ... if ( (key2[0] == "") and (key2[1] == "localhost") and (key2[2].decode("utf8").lower() == key) ): # Add the unconverted database's PATH values to the CONVERTED database's configuration! TransanaGlobal.configData.pathsByDB[ ("", "localhost", key.encode("utf8")) ] = { "visualizationPath": TransanaGlobal.configData.pathsByDB2[key2][ "visualizationPath" ], "videoPath": TransanaGlobal.configData.pathsByDB2[key2]["videoPath"], } # ... and we can stop looking break # Save the altered configuration data TransanaGlobal.configData.SaveConfiguration() # The Computer Lab version sometimes throws a KeyError except exceptions.KeyError: # If this comes up, we can ignore it. pass # Delete the Import File Information os.remove(fs) if DEBUG: print "Done importing Files" # We can only continue if we initialized the database OR are running MU. if connectionEstablished: # If a new database login fails three times, we need to close the program. # Initialize a counter to track that. logonCount = 1 # Flag if Logon succeeds loggedOn = False # Keep trying for three tries or until successful while (logonCount <= 3) and (not loggedOn): logonCount += 1 # Confirm the existence of the DB Tables, creating them if needed. # This method also calls the Username and Password Dialog if needed. # NOTE: The Menu Window must be created first to server as a parent for the Username and Password Dialog # called up by DBInterface. if DBInterface.establish_db_exists(): if DEBUG: print "Creating Data Window", # Create the Data Window # Data Window creation causes Username and Password Dialog to be displayed, # so it should be created before the Video Window self.dataWindow = DataWindow.DataWindow(TransanaGlobal.menuWindow) if DEBUG: print self.dataWindow.GetSize() print "Creating Video Window", # Create the Video Window self.videoWindow = VideoWindow.VideoWindow(TransanaGlobal.menuWindow) # Create the Transcript Window. If on the Mac, include the Close button. if DEBUG: print self.videoWindow.GetSize() print "Creating Transcript Window", self.transcriptWindow = TranscriptionUI.TranscriptionUI( TransanaGlobal.menuWindow, includeClose=("wxMac" in wx.PlatformInfo) ) if DEBUG: print self.transcriptWindow.dlg.GetSize() print "Creating Visualization Window", # Create the Visualization Window self.visualizationWindow = VisualizationWindow.VisualizationWindow(TransanaGlobal.menuWindow) if DEBUG: print self.visualizationWindow.GetSize() print "Creating Control Object" # Create the Control Object and register all objects to be controlled with it self.ControlObject = ControlObject() self.ControlObject.Register( Menu=TransanaGlobal.menuWindow, Video=self.videoWindow, Transcript=self.transcriptWindow, Data=self.dataWindow, Visualization=self.visualizationWindow, ) # Set the active transcript self.ControlObject.activeTranscript = 0 # Register the ControlObject with all other objects to be controlled TransanaGlobal.menuWindow.Register(ControlObject=self.ControlObject) self.dataWindow.Register(ControlObject=self.ControlObject) self.videoWindow.Register(ControlObject=self.ControlObject) self.transcriptWindow.Register(ControlObject=self.ControlObject) self.visualizationWindow.Register(ControlObject=self.ControlObject) # Set the Application Top Window to the Menu Window (wxPython) self.SetTopWindow(TransanaGlobal.menuWindow) TransanaGlobal.resizingAll = True if DEBUG: print print "Before Showing Windows:" print " menu:\t\t", TransanaGlobal.menuWindow.GetRect() print " visual:\t", self.visualizationWindow.GetRect() print " video:\t", self.videoWindow.GetRect() print " trans:\t", self.transcriptWindow.dlg.GetRect() print " data:\t\t", self.dataWindow.GetRect() print print "Heights:", self.transcriptWindow.dlg.GetRect()[1] + self.transcriptWindow.dlg.GetRect()[ 3 ], self.dataWindow.GetRect()[1] + self.dataWindow.GetRect()[3] print if ( self.transcriptWindow.dlg.GetRect()[1] + self.transcriptWindow.dlg.GetRect()[3] > self.dataWindow.GetRect()[1] + self.dataWindow.GetRect()[3] ): self.dataWindow.SetRect( ( self.dataWindow.GetRect()[0], self.dataWindow.GetRect()[1], self.dataWindow.GetRect()[2], self.dataWindow.GetRect()[3] + ( self.transcriptWindow.dlg.GetRect()[1] + self.transcriptWindow.dlg.GetRect()[3] - (self.dataWindow.GetRect()[1] + self.dataWindow.GetRect()[3]) ), ) ) print "DataWindow Height Adjusted!" print " data:\t\t", self.dataWindow.GetRect() print # Show all Windows. TransanaGlobal.menuWindow.Show(True) if DEBUG: print "Showing Windows:" print " menu:", TransanaGlobal.menuWindow.GetRect() self.visualizationWindow.Show() if DEBUG: print " visualization:", self.visualizationWindow.GetRect() self.videoWindow.Show() if DEBUG: print " video:", self.videoWindow.GetRect(), self.transcriptWindow.dlg.GetRect() self.transcriptWindow.Show() if DEBUG: print " transcript:", self.transcriptWindow.dlg.GetRect(), self.dataWindow.GetRect() self.dataWindow.Show() if DEBUG: print " data:", self.dataWindow.GetRect(), self.visualizationWindow.GetRect() # Get the size and position of the Visualization Window (x, y, w, h) = self.visualizationWindow.GetRect() if DEBUG: print print "Call 3", "Visualization", w + x # Adjust the positions of all other windows to match the Visualization Window's initial position self.ControlObject.UpdateWindowPositions("Visualization", w + x, YUpper=h + y) TransanaGlobal.resizingAll = False loggedOn = True # If logon fails, inform user and offer to try again twice. elif logonCount <= 3: # Check to see if we have an SSL failure caused by insufficient data if ( (not TransanaConstants.singleUserVersion) and TransanaGlobal.configData.ssl and ( TransanaGlobal.configData.sslClientCert == "" or TransanaGlobal.configData.sslClientKey == "" ) ): # If so, inform the user prompt = _( "The information on the SSL tab is required to establish an SSL connection to the database.\nWould you like to try again?" ) # Otherwise ... else: # ... give a generic message about logon failure. prompt = _("Transana was unable to connect to the database.\nWould you like to try again?") dlg = Dialogs.QuestionDialog(TransanaGlobal.menuWindow, prompt, _("Transana Database Connection")) # If the user does not want to try again, set the counter to 4, which will cause the program to exit if dlg.LocalShowModal() == wx.ID_NO: logonCount = 4 # Clean up the Dialog Box dlg.Destroy() # If we successfully logged in ... if loggedOn: # ... save the configuration data that got us in TransanaGlobal.configData.SaveConfiguration() # if we're running the multi-user version of Transana and successfully connected to a database ... if not TransanaConstants.singleUserVersion and loggedOn: if DEBUG: print "Need to connect to MessageServer" # ... connect to the Message Server Here TransanaGlobal.socketConnection = ChatWindow.ConnectToMessageServer() # If the connections fails ... if TransanaGlobal.socketConnection == None: # ... signal that Transana should NOT start up! loggedOn = False else: # If Transana MU sits idle too long (30 - 60 minutes), people would sometimes get a # "Connection to Database Lost" error message even though MySQL was set to maintain the # connection for 8 hours. To try to address this, we will set up a Timer that will run # a simple query every 10 minutes to maintain the connection to the database. # Create the Connection Timer TransanaGlobal.connectionTimer = wx.Timer(self) # Bind the timer to its event self.Bind(wx.EVT_TIMER, self.OnTimer) # Tell the timer to fire every 10 minutes. # NOTE: If changing this value, it also needs to be changed in the ControlObjectClass.GetNewDatabase() method. TransanaGlobal.connectionTimer.Start(600000) if DEBUG: print "MessageServer connected!" # Check if the Database and Message Server are both using SSL and select the appropriate graphic self.dataWindow.UpdateSSLStatus(TransanaGlobal.configData.ssl and TransanaGlobal.chatIsSSL) # if this is the first time this user profile has used Transana ... if firstStartup and loggedOn: # ... create a prompt about looking at the Tutorial prompt = _( "If this is your first time using Transana, the Transana Tutorial can help you learn how to use the program." ) prompt += "\n\n" + _("Would you like to see the Transana Tutorial now?") # Display the Tutorial prompt in a Yes / No dialog tmpDlg = Dialogs.QuestionDialog(TransanaGlobal.menuWindow, prompt) # If the user says Yes ... if tmpDlg.LocalShowModal() == wx.ID_YES: # ... start the Tutorial self.ControlObject.Help("Welcome to the Transana Tutorial") if DEBUG: print print "Final Windows:" print " menu:\t\t", TransanaGlobal.menuWindow.GetRect() print " visual:\t", self.visualizationWindow.GetRect() print " video:\t", self.videoWindow.GetRect() print " trans:\t", self.transcriptWindow.dlg.GetRect() print " data:\t\t", self.dataWindow.GetRect() print else: loggedOn = False dlg = Dialogs.QuestionDialog(TransanaGlobal.menuWindow, msg, _("Transana Database Connection")) if dlg.LocalShowModal() == wx.ID_YES: TransanaGlobal.configData.databaseDir = os.path.join( TransanaGlobal.configData.GetDefaultProfilePath(), "databases" ) TransanaGlobal.configData.SaveConfiguration() # Clean up the Dialog Box dlg.Destroy() return loggedOn
def __init__(self, parent, msg, header=_("Transana Confirmation"), noDefault=False, useOkCancel=False, yesToAll=False, includeEncoding=False): """ QuestionDialog Parameters: parent Parent Window msg Message to display header Dialog box header, "Transana Confirmation" by default noDefault Set the No or Cancel button as the default, instead of Yes or OK useOkCancel Use OK / Cancel as the button labels rather than Yes / No yesToAll Include the "Yes to All" option includeEncoding Include Encoding selection for upgrading the single-user Windows database for 2.50 """ # This should be easy, right? Just use the OS MessageDialog like so: # wx.MessageDialog.__init__(self, parent, msg, _("Transana Information"), \ # wx.OK | wx.CENTRE | wx.ICON_INFORMATION) # That's all there is to it, right? # # Yeah, right. Unfortunately, on Windows, the MessageDialog isn't TRULY modal. It's modal to the parent window # it's called from, but you can still select one of the other Transana Windows and do stuff. This message # can even get hidden behind other windows, and cause all kinds of problems. According to Robin Dunn, # writing my own class to do this is the only solution. # Set the default result to indicate failure self.result = -1 # Remember the noDefault setting self.noDefault = noDefault # Remember if Encoding is included self.includeEncoding = includeEncoding # Define the default Window style dlgStyle = wx.CAPTION | wx.CLOSE_BOX | wx.STAY_ON_TOP # Create a small dialog box wx.Dialog.__init__(self, parent, -1, header, size=(350, 150), style=dlgStyle) # Create a main vertical sizer box = wx.BoxSizer(wx.VERTICAL) # Create a horizontal sizer for the first row box2 = wx.BoxSizer(wx.HORIZONTAL) # Create a horizontal sizer for the buttons boxButtons = wx.BoxSizer(wx.HORIZONTAL) # Create an empty bitmap for the question mark graphic bitmap = wx.EmptyBitmap(32, 32) # Create a bitmap screen object for the graphic graphic = wx.StaticBitmap(self, -1, TransanaImages.ArtProv_QUESTION.GetBitmap()) # Add the graphic to the first row horizontal sizer box2.Add(graphic, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, 10) # Create a text screen object for the dialog text message = wx.StaticText(self, -1, msg) # Add it to the first row sizer box2.Add( message, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10) # Add the first row to the main sizer box.Add(box2, 0, wx.EXPAND) # Determine the appropriate text and ID values for the buttons. # if useOkCancel is True ... if useOkCancel: # ... set the buttons to OK and Cancel btnYesText = _("OK") btnYesID = wx.ID_OK btnNoText = _("Cancel") btnNoID = wx.ID_CANCEL # If useOkCancel is False (the default) ... else: # ... set the buttons to Yes and No btnYesText = _("&Yes") btnYesID = wx.ID_YES btnNoText = _("&No") btnNoID = wx.ID_NO # Create the first button, which is Yes or OK btnYes = wx.Button(self, btnYesID, btnYesText) # Bind the button event to its method btnYes.Bind(wx.EVT_BUTTON, self.OnButton) # If the "Yes to All" option is enabled if yesToAll: # ... create a YesToAll ID self.YESTOALLID = wx.NewId() # Create a Yes To All button self.btnYesToAll = wx.Button(self, self.YESTOALLID, _("Yes to All")) # Bind the button handler for the Yes To All button self.btnYesToAll.Bind(wx.EVT_BUTTON, self.OnButton) # Create the second button, which is No or Cancel self.btnNo = wx.Button(self, btnNoID, btnNoText) # Bind the button event to its method self.btnNo.Bind(wx.EVT_BUTTON, self.OnButton) # Add an expandable spacer to the button sizer boxButtons.Add((20, 1), 1) # If we're on the Mac, we want No/Cancel then Yes/OK if "__WXMAC__" in wx.PlatformInfo: # Add No first boxButtons.Add(self.btnNo, 0, wx.ALIGN_CENTER | wx.BOTTOM, 10) # Add a spacer boxButtons.Add((20, 1)) # If the "Yes to All" option is enabled if yesToAll: # Add No first boxButtons.Add(self.btnYesToAll, 0, wx.ALIGN_CENTER | wx.BOTTOM, 10) # Add a spacer boxButtons.Add((20, 1)) # Then add Yes boxButtons.Add(btnYes, 0, wx.ALIGN_CENTER | wx.BOTTOM, 10) # If we're not on the Mac, we want Yes/OK then No/Cancel else: # Add Yes first boxButtons.Add(btnYes, 0, wx.ALIGN_CENTER | wx.BOTTOM, 10) # Add a spacer boxButtons.Add((20, 1)) # If the "Yes to All" option is enabled if yesToAll: # Add No first boxButtons.Add(self.btnYesToAll, 0, wx.ALIGN_CENTER | wx.BOTTOM, 10) # Add a spacer boxButtons.Add((20, 1)) # Then add No boxButtons.Add(self.btnNo, 0, wx.ALIGN_CENTER | wx.BOTTOM, 10) # Add a final expandable spacer boxButtons.Add((20, 1), 1) # Add the button bar to the main sizer box.Add(boxButtons, 0, wx.ALIGN_CENTER | wx.EXPAND) # If we're supposed to include the Encoding prompt ... if includeEncoding: # Create a horizontal sizer for the first row box3 = wx.BoxSizer(wx.HORIZONTAL) # Define the options for the Encoding choice box choices = [ '', _('Most languages from single-user Transana 2.1 - 2.42 on Windows' ), _('Chinese from single-user Transana 2.1 - 2.42 on Windows'), _('Russian from single-user Transana 2.1 - 2.42 on Windows'), _('Eastern European data from single-user Transana 2.1 - 2.42 on Windows' ), _('Greek data from single-user Transana 2.1 - 2.42 on Windows' ), _('Japanese data from single-user Transana 2.1 - 2.42 on Windows' ), _("All languages from OS X or MU database files") ] # Use a dictionary to define the encodings that go with each of the Encoding options self.encodingOptions = { '': None, _('Most languages from single-user Transana 2.1 - 2.42 on Windows'): 'latin1', _('Chinese from single-user Transana 2.1 - 2.42 on Windows'): 'gbk', _('Russian from single-user Transana 2.1 - 2.42 on Windows'): 'koi8_r', _('Eastern European data from single-user Transana 2.1 - 2.42 on Windows'): 'iso8859_2', _('Greek data from single-user Transana 2.1 - 2.42 on Windows'): 'iso8859_7', _('Japanese data from single-user Transana 2.1 - 2.42 on Windows'): 'cp932', _("All languages from OS X or MU database files"): 'utf8' } # Create a Choice Box where the user can select an import encoding, based on information about how the # Transana-XML file in question was created. This adds it to the Vertical Sizer created above. chLbl = wx.StaticText(self, -1, _('Language Option used:')) box3.Add(chLbl, 0, wx.LEFT | wx.TOP | wx.BOTTOM, 10) self.chImportEncoding = wx.Choice(self, -1, choices=choices) self.chImportEncoding.SetSelection(0) box3.Add( self.chImportEncoding, 1, wx.EXPAND | wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10) box.Add(box3, 0, wx.EXPAND) # Turn AutoLayout On self.SetAutoLayout(True) # Set the form's main sizer self.SetSizer(box) # Fit the form self.Fit() # Lay the form out self.Layout() # Center the form on screen # self.CentreOnScreen() # That's not working. Let's try this ... TransanaGlobal.CenterOnPrimary(self)
def __init__(self, parent, id, title, obj, keywords): # Make the Keyword Edit List resizable by passing wx.RESIZE_BORDER style Dialogs.GenForm.__init__( self, parent, id, title, size=TransanaGlobal.configData.keywordListEditSize, style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, useSizers=True, HelpContext='Edit Keywords') # Remember the parent Window self.parent = parent self.obj = obj # if Keywords that server as Keyword Examples are removed, we will need to remember them. # Then, when OK is pressed, the Keyword Example references in the Database Tree can be removed. # We can't remove them immediately in case the whole Clip Properties Edit process is cancelled. self.keywordExamplesToDelete = [] # COPY the keyword list, rather than just pointing to it, so that the list on this form will # be independent of the original list. That way, pressing CANCEL does not cause the list to # be changed anyway, though it means that if OK is pressed, you must copy the list to update # it in the calling routine. self.keywords = [] for kws in keywords: self.keywords.append(kws) # Create the form's main VERTICAL sizer mainSizer = wx.BoxSizer(wx.VERTICAL) # Create a HORIZONTAL sizer for the first row r1Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v1 = wx.BoxSizer(wx.VERTICAL) # Keyword Group [label] txt = wx.StaticText(self.panel, -1, _("Keyword Group")) v1.Add(txt, 0, wx.BOTTOM, 3) # Keyword Group layout [list box] # Create an empty Keyword Group List for now. We'll populate it later (for layout reasons) self.kw_groups = [] self.kw_group_lb = wx.ListBox(self.panel, 101, wx.DefaultPosition, wx.DefaultSize, self.kw_groups) v1.Add(self.kw_group_lb, 1, wx.EXPAND) # Add the element to the sizer r1Sizer.Add(v1, 1, wx.EXPAND) self.kw_list = [] wx.EVT_LISTBOX(self, 101, self.OnGroupSelect) # Add a horizontal spacer r1Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v2 = wx.BoxSizer(wx.VERTICAL) # Keyword [label] txt = wx.StaticText(self.panel, -1, _("Keyword")) v2.Add(txt, 0, wx.BOTTOM, 3) # Keyword [list box] self.kw_lb = wx.ListBox(self.panel, -1, wx.DefaultPosition, wx.DefaultSize, self.kw_list, style=wx.LB_EXTENDED) v2.Add(self.kw_lb, 1, wx.EXPAND) wx.EVT_LISTBOX_DCLICK(self, self.kw_lb.GetId(), self.OnAddKW) # Add the element to the sizer r1Sizer.Add(v2, 1, wx.EXPAND) # Add a horizontal spacer r1Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v3 = wx.BoxSizer(wx.VERTICAL) # Keyword transfer buttons add_kw = wx.Button(self.panel, wx.ID_FILE2, ">>", wx.DefaultPosition) v3.Add(add_kw, 0, wx.EXPAND | wx.TOP, 20) wx.EVT_BUTTON(self, wx.ID_FILE2, self.OnAddKW) rm_kw = wx.Button(self.panel, wx.ID_FILE3, "<<", wx.DefaultPosition) v3.Add(rm_kw, 0, wx.EXPAND | wx.TOP, 10) wx.EVT_BUTTON(self, wx.ID_FILE3, self.OnRemoveKW) kwm = wx.BitmapButton(self.panel, wx.ID_FILE4, TransanaImages.KWManage.GetBitmap()) v3.Add(kwm, 0, wx.EXPAND | wx.TOP, 10) # Add a spacer to increase the height of the Keywords section v3.Add((0, 60)) kwm.SetToolTipString(_("Keyword Management")) wx.EVT_BUTTON(self, wx.ID_FILE4, self.OnKWManage) # Add the element to the sizer r1Sizer.Add(v3, 0) # Add a horizontal spacer r1Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v4 = wx.BoxSizer(wx.VERTICAL) # Keywords [label] txt = wx.StaticText(self.panel, -1, _("Keywords")) v4.Add(txt, 0, wx.BOTTOM, 3) # Keywords [list box] # Create an empty ListBox self.ekw_lb = wx.ListBox(self.panel, -1, wx.DefaultPosition, wx.DefaultSize, style=wx.LB_EXTENDED) v4.Add(self.ekw_lb, 1, wx.EXPAND) self.ekw_lb.Bind(wx.EVT_KEY_DOWN, self.OnKeywordKeyDown) # Add the element to the sizer r1Sizer.Add(v4, 2, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r1Sizer, 1, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a sizer for the buttons btnSizer = wx.BoxSizer(wx.HORIZONTAL) # Add the buttons self.create_buttons(sizer=btnSizer) # Add the button sizer to the main sizer mainSizer.Add(btnSizer, 0, wx.EXPAND) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping mainSizer.Add((0, 2)) # Set the PANEL's main sizer self.panel.SetSizer(mainSizer) # Tell the PANEL to auto-layout self.panel.SetAutoLayout(True) # Lay out the Panel self.panel.Layout() # Lay out the panel on the form self.Layout() # Resize the form to fit the contents self.Fit() # Get the new size of the form (width, height) = self.GetSizeTuple() # Reset the form's size to be at least the specified minimum width self.SetSize(wx.Size(max(600, width), max(385, height))) # Define the minimum size for this dialog as the current size self.SetSizeHints(max(600, width), max(385, height)) # Center the form on screen TransanaGlobal.CenterOnPrimary(self) # We need to set some minimum sizes so the sizers will work right self.kw_group_lb.SetSizeHints(minW=50, minH=20) self.kw_lb.SetSizeHints(minW=50, minH=20) self.ekw_lb.SetSizeHints(minW=50, minH=20) # We need to capture the OK and Cancel button clicks locally. We'll use FindWindowByID to locate the correct widgets. self.Bind(wx.EVT_BUTTON, self.OnOK, self.FindWindowById(wx.ID_OK)) self.Bind(wx.EVT_BUTTON, self.OnCancel, self.FindWindowById(wx.ID_CANCEL)) # We populate the Keyword Groups, Keywords, and Clip Keywords lists AFTER we determine the Form Size. # Long Keywords in the list were making the form too big! # Obtain the list of Keyword Groups self.kw_groups = DBInterface.list_of_keyword_groups() for keywordGroup in self.kw_groups: self.kw_group_lb.Append(keywordGroup) if self.kw_group_lb.GetCount() > 0: self.kw_group_lb.EnsureVisible(0) # Get the Parent Object, so we can know the Default Keyword Group if isinstance(self.obj, Episode.Episode): objParent = Library.Library(self.obj.series_num) elif isinstance(self.obj, Document.Document): objParent = Library.Library(self.obj.library_num) elif isinstance(self.obj, Clip.Clip) or isinstance( self.obj, Snapshot.Snapshot) or isinstance( self.obj, Quote.Quote): objParent = Collection.Collection(self.obj.collection_num) if len(self.kw_groups) > 0: # Set the Keyword Group to the Default keyword Group if self.kw_group_lb.FindString( objParent.keyword_group) != wx.NOT_FOUND: self.kw_group_lb.SetStringSelection(objParent.keyword_group) else: self.kw_group_lb.SetSelection(0) # Obtain the list of Keywords for the intial Keyword Group self.kw_list = DBInterface.list_of_keywords_by_group( self.kw_group_lb.GetStringSelection()) else: self.kw_list = [] for keyword in self.kw_list: self.kw_lb.Append(keyword) if self.kw_lb.GetCount() > 0: self.kw_lb.EnsureVisible(0) # Populate the ListBox for clipKeyword in self.keywords: self.ekw_lb.Append(clipKeyword.keywordPair) if self.ekw_lb.GetCount() > 0: self.ekw_lb.EnsureVisible(0) self.kw_group_lb.SetFocus()
def __init__(self, parent, kw_groups): # ALSO SEE Keyword._set_keywordGroup(). The same errors are caught there. # Let's get a copy of kw_groups that's all upper case self.kw_groups_upper = [] for kwg in kw_groups: self.kw_groups_upper.append(kwg.upper()) # Define the default Window style dlgStyle = wx.CAPTION | wx.CLOSE_BOX | wx.STAY_ON_TOP | wx.DIALOG_NO_PARENT # Create a small dialog box wx.Dialog.__init__(self, parent, -1, _("Add Keyword Group"), size=(350, 145), style=dlgStyle) # Create a main vertical sizer box = wx.BoxSizer(wx.VERTICAL) # Create a horizontal sizer for the buttons boxButtons = wx.BoxSizer(wx.HORIZONTAL) # Create a text screen object for the dialog text message = wx.StaticText(self, -1, _("New Keyword Group:")) # Add the first row to the main sizer box.Add(message, 0, wx.EXPAND | wx.ALL, 10) # Create a TextCtrl for the Keyword Group name self.kwGroup = wx.TextCtrl(self, -1, "") box.Add(self.kwGroup, 1, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10) # Do error-checking in the EVT_TEXT event self.kwGroup.Bind(wx.EVT_TEXT, self.OnText) # Create the first button, which is OK btnOK = wx.Button(self, wx.ID_OK, _("OK")) # Set as the Default to handle ENTER keypress btnOK.SetDefault() # Bind the button event to its method btnOK.Bind(wx.EVT_BUTTON, self.OnButton) # Create the second button, which is Cancel btnCancel = wx.Button(self, wx.ID_CANCEL, _("Cancel")) # Add an expandable spacer to the button sizer boxButtons.Add((20, 1), 1) # If we're on the Mac, we want Cancel then OK if "__WXMAC__" in wx.PlatformInfo: # Add No first boxButtons.Add(btnCancel, 0, wx.ALIGN_CENTER | wx.BOTTOM, 10) # Add a spacer boxButtons.Add((20, 1)) # Then add Yes boxButtons.Add(btnOK, 0, wx.ALIGN_CENTER | wx.BOTTOM, 10) # If we're not on the Mac, we want OK then Cancel else: # Add Yes first boxButtons.Add(btnOK, 0, wx.ALIGN_CENTER | wx.BOTTOM, 10) # Add a spacer boxButtons.Add((20, 1)) # Then add No boxButtons.Add(btnCancel, 0, wx.ALIGN_CENTER | wx.BOTTOM, 10) # Add a final expandable spacer boxButtons.Add((20, 1), 1) # Add the button bar to the main sizer box.Add(boxButtons, 0, wx.ALIGN_RIGHT | wx.EXPAND) # Turn AutoLayout On self.SetAutoLayout(True) # Set the form's main sizer self.SetSizer(box) # Fit the form self.Fit() # Lay the form out self.Layout() # Center the form on screen # self.CentreOnScreen() # That's not working. Let's try this ... TransanaGlobal.CenterOnPrimary(self)
def __init__(self, parent, id, libraryNum=0, documentNum=0, episodeNum=0, collectionNum=0): # Remember the Library, Document, Episode or Collection that triggered creation of this report self.libraryNum = libraryNum self.documentNum = documentNum self.episodeNum = episodeNum self.collectionNum = collectionNum # Create a form to get the name of the file to receive the data # Define the form title title = _("Transana Analytic Data Export") # Create the form itself Dialogs.GenForm.__init__(self, parent, id, title, (550, 150), style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, useSizers=True, HelpContext='Analytic Data Export') # Create the form's main VERTICAL sizer mainSizer = wx.BoxSizer(wx.VERTICAL) # Create a HORIZONTAL sizer for the first row r1Sizer = wx.BoxSizer(wx.HORIZONTAL) # Header Message prompt = _('Please create a Transana Analytic Data File for export.') exportText = wx.StaticText(self.panel, -1, prompt) # Add the export message to the dialog box r1Sizer.Add(exportText, 0) # Add the row sizer to the main vertical sizer mainSizer.Add(r1Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r2Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v1 = wx.BoxSizer(wx.VERTICAL) # Export Filename self.exportFile = self.new_edit_box(_("Export Filename"), v1, '') self.exportFile.SetDropTarget(EditBoxFileDropTarget(self.exportFile)) # Add the element sizer to the row sizer r2Sizer.Add(v1, 1, wx.EXPAND) # Add a spacer to the row sizer r2Sizer.Add((10, 0)) # Browse button browse = wx.Button(self.panel, wx.ID_FILE1, _("Browse"), wx.DefaultPosition) wx.EVT_BUTTON(self, wx.ID_FILE1, self.OnBrowse) # Add the element to the row sizer r2Sizer.Add(browse, 0, wx.ALIGN_BOTTOM) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping r2Sizer.Add((2, 0)) # Add the row sizer to the main vertical sizer mainSizer.Add(r2Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a sizer for the buttons btnSizer = wx.BoxSizer(wx.HORIZONTAL) # Add the buttons self.create_buttons(sizer=btnSizer) # Add the button sizer to the main sizer mainSizer.Add(btnSizer, 0, wx.EXPAND) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping mainSizer.Add((0, 2)) # Set the PANEL's main sizer self.panel.SetSizer(mainSizer) # Tell the PANEL to auto-layout self.panel.SetAutoLayout(True) # Lay out the Panel self.panel.Layout() # Lay out the panel on the form self.Layout() # Resize the form to fit the contents self.Fit() # Get the new size of the form (width, height) = self.GetSizeTuple() # Reset the form's size to be at least the specified minimum width self.SetSize(wx.Size(max(550, width), max(100, height))) # Define the minimum size for this dialog as the current size, and define height as unchangeable self.SetSizeHints(max(550, width), max(100, height), -1, max(100, height)) # Center the form on screen TransanaGlobal.CenterOnPrimary(self) # Set focus to the Export File Name field self.exportFile.SetFocus()
def __init__(self, parent, id, title, coredata_object): """ Initialize the Core Data Properties form """ # Set the Size of the Form self.width = 550 self.height = 510 # Create the Base Form, based on GenForm in the Transana Dialogs module Dialogs.GenForm.__init__(self, parent, id, title, size=(self.width, self.height), style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, useSizers = True, HelpContext='Core Data Properties') # Preserve the initial Core Data Object sent in from the calling routine self.obj = coredata_object # Create the form's main VERTICAL sizer mainSizer = wx.BoxSizer(wx.VERTICAL) # Create a HORIZONTAL sizer for the first row r1Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v1 = wx.BoxSizer(wx.VERTICAL) # Media File Name # NOTE: The otherwise unused Comment Field is used to contain the full Media File Name. media_filename_edit = self.new_edit_box(_("Media File Name"), v1, self.obj.comment) # Add the element to the row sizer r1Sizer.Add(v1, 1, wx.EXPAND) # Media File Name Field is not editable media_filename_edit.Enable(False) # Add the row sizer to the main vertical sizer mainSizer.Add(r1Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the first row r2Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v2 = wx.BoxSizer(wx.VERTICAL) # Title title_edit = self.new_edit_box(_("Title"), v2, self.obj.title, maxLen=255) # Add the element to the row sizer r2Sizer.Add(v2, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r2Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the first row r3Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v3 = wx.BoxSizer(wx.VERTICAL) # Creator creator_edit = self.new_edit_box(_("Creator"), v3, self.obj.creator, maxLen=255) # Add the element to the row sizer r3Sizer.Add(v3, 1, wx.EXPAND) # Add a horizontal spacer to the row sizer r3Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v4 = wx.BoxSizer(wx.VERTICAL) # Subject subject_edit = self.new_edit_box(_("Subject"), v4, self.obj.subject, maxLen=255) # Add the element to the row sizer r3Sizer.Add(v4, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r3Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the first row r4Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v5 = wx.BoxSizer(wx.VERTICAL) # Description self.description_edit = self.new_edit_box(_("Description"), v5, self.obj.description, style=wx.TE_MULTILINE, maxLen=255) # Add the element to the row sizer r4Sizer.Add(v5, 1, wx.EXPAND) # Add a spacer to enforce the height of the Description item r4Sizer.Add((0, 80)) # Add the row sizer to the main vertical sizer mainSizer.Add(r4Sizer, 5, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the first row r5Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v6 = wx.BoxSizer(wx.VERTICAL) # Publisher publisher_edit = self.new_edit_box(_("Publisher"), v6, self.obj.publisher, maxLen=255) # Add the element to the row sizer r5Sizer.Add(v6, 1, wx.EXPAND) # Add a horizontal spacer to the row sizer r5Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v7 = wx.BoxSizer(wx.VERTICAL) # Contributor contributor_edit = self.new_edit_box(_("Contributor"), v7, self.obj.contributor, maxLen=255) # Add the element to the row sizer r5Sizer.Add(v7, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r5Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the first row r6Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v8 = wx.BoxSizer(wx.VERTICAL) # Dialogs.GenForm does not provide a Masked text control, so the Date # Field is handled differently than other fields. # Date [label] date_lbl = wx.StaticText(self.panel, -1, _("Date (MM/DD/YYYY)")) # Add the element to the vertical sizer v8.Add(date_lbl, 0, wx.BOTTOM, 3) # Date layout # Use the Masked Text Control (Requires wxPython 2.4.2.4 or later) # TODO: Make Date autoformat localizable self.date_edit = wx.lib.masked.TextCtrl(self.panel, -1, '', autoformat='USDATEMMDDYYYY/') # Add the element to the vertical sizer v8.Add(self.date_edit, 1, wx.EXPAND) # If a Date is know, load it into the control if (self.obj.dc_date != '') and (self.obj.dc_date != '01/01/0'): self.date_edit.SetValue(self.obj.dc_date) # Add the element to the row sizer r6Sizer.Add(v8, 1, wx.EXPAND) # Add a horizontal spacer to the row sizer r6Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v9 = wx.BoxSizer(wx.VERTICAL) # Type # Define legal options for the Combo Box options = ['', _('Image'), _('Sound')] self.type_combo = self.new_combo_box(_("Media Type"), v9, options, self.obj.dc_type) # Add the element to the row sizer r6Sizer.Add(v9, 1, wx.EXPAND) # Define a Combo Box Event. When different Types are selected, different Format options should be displayed. wx.EVT_COMBOBOX(self, self.type_combo.GetId(), self.OnTypeChoice) # Add a horizontal spacer to the row sizer r6Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v10 = wx.BoxSizer(wx.VERTICAL) # Format # The Format Combo Box has different options depending on the value of Type if self.obj.dc_type == unicode(_('Image'), 'utf8'): options = imageOptions elif self.obj.dc_type == unicode(_('Sound'), 'utf8'): options = soundOptions else: options = allOptions self.format_combo = self.new_combo_box(_("Format"), v10, options, self.obj.format) # Add the element to the row sizer r6Sizer.Add(v10, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r6Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the first row r7Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v11 = wx.BoxSizer(wx.VERTICAL) # Identifier identifier_edit = self.new_edit_box(_("Identifier"), v11, self.obj.id) # Add the element to the row sizer r7Sizer.Add(v11, 1, wx.EXPAND) # Identifier is not editable identifier_edit.Enable(False) # Add a horizontal spacer to the row sizer r7Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v12 = wx.BoxSizer(wx.VERTICAL) # Source source_edit = self.new_edit_box(_("Source"), v12, self.obj.source, maxLen=255) # Add the element to the row sizer r7Sizer.Add(v12, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r7Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the first row r8Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v13 = wx.BoxSizer(wx.VERTICAL) # Language language_edit = self.new_edit_box(_("Language"), v13, self.obj.language, maxLen=25) # Add the element to the row sizer r8Sizer.Add(v13, 1, wx.EXPAND) # Add a horizontal spacer to the row sizer r8Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v14 = wx.BoxSizer(wx.VERTICAL) # Relation relation_edit = self.new_edit_box(_("Relation"), v14, self.obj.relation, maxLen=255) # Add the element to the row sizer r8Sizer.Add(v14, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r8Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the first row r9Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v15 = wx.BoxSizer(wx.VERTICAL) # Coverage coverage_edit = self.new_edit_box(_("Coverage"), v15, self.obj.coverage, maxLen=255) # Add the element to the row sizer r9Sizer.Add(v15, 1, wx.EXPAND) # Add a horizontal spacer to the row sizer r9Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v16 = wx.BoxSizer(wx.VERTICAL) # Rights rights_edit = self.new_edit_box(_("Rights"), v16, self.obj.rights, maxLen=255) # Add the element to the row sizer r9Sizer.Add(v16, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r9Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a sizer for the buttons btnSizer = wx.BoxSizer(wx.HORIZONTAL) # Add the buttons self.create_buttons(sizer=btnSizer) # Add the button sizer to the main sizer mainSizer.Add(btnSizer, 0, wx.EXPAND) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping mainSizer.Add((0, 2)) # Set the PANEL's main sizer self.panel.SetSizer(mainSizer) # Tell the PANEL to auto-layout self.panel.SetAutoLayout(True) # Lay out the Panel self.panel.Layout() # Lay out the panel on the form self.Layout() # Resize the form to fit the contents self.Fit() # Get the new size of the form (width, height) = self.GetSizeTuple() # Reset the form's size to be at least the specified minimum width self.SetSize(wx.Size(max(self.width, width), height)) # Define the minimum size for this dialog as the current size self.SetSizeHints(max(self.width, width), height) # Center the form on screen TransanaGlobal.CenterOnPrimary(self) # Set focus to Title title_edit.SetFocus()
def OnInit(self): """ Initialize the application """ # If we have a Workshop Version, see if the version is still valid, report to the user and exit if not. # NOTE: This code just provides a user message and clean exit. Transana will still be disabled if this # code is removed. (This code is user-accessible on OS X!) if TransanaConstants.workshopVersion: import datetime t1 = TransanaConstants.startdate t2 = TransanaConstants.expirationdate t3 = time.localtime() t4 = datetime.datetime(t3[0], t3[1], t3[2], t3[3], t3[4]) if (t1 > t4) or (t2 < t4): dlg = Dialogs.ErrorDialog( None, "This copy of Transana is no longer valid.") dlg.ShowModal() dlg.Destroy return False # In wxPython, you used to be able to initialize the ConfigData object in the TransanaGlobal module, even though the # wx.App() hadn't been initialized yet. Moving from wxPython 2.8.1 to wxPython 2.8.9, this stopped being true # at least on the Mac. Therefore, we moved creation of the ConfigData object to here in the code. # However, there are MANY references to ConfigData being in the TransanaGlobal module, so that's where we'll keep it. TransanaGlobal.configData = ConfigData.ConfigData() # If we are running from a BUILD instead of source code ... if hasattr(sys, "frozen"): # or ('wxMac' in wx.PlatformInfo): # See if the Default Profile Path exists. If not ... if not os.path.exists( TransanaGlobal.configData.GetDefaultProfilePath()): # ... then create it (recursively). os.makedirs(TransanaGlobal.configData.GetDefaultProfilePath()) # Build the path for the error log path = os.path.join( TransanaGlobal.configData.GetDefaultProfilePath(), 'Transana_Error.log') # redirect output to the error log self.RedirectStdio(filename=path) # Put a startup indicator in the Error Log print "Transana started:", time.asctime() # If no Language is defined ... if TransanaGlobal.configData.language == '': # ... then we know this is the first startup for this user profile. Remember that! firstStartup = True # If language is known ... else: # ... then it's NOT first time startup. firstStartup = False # Now that we've loaded the Configuration Data, we can see if we need to alter the default encoding # If we're on Windows, single-user, using Russian, use KOI8r encoding instead of Latin-1, # Chinese uses big5, Japanese uses cp932, and Korean uses cp949 ## if ('wxMSW' in wx.PlatformInfo) and (TransanaConstants.singleUserVersion): ## if (TransanaGlobal.configData.language == 'ru'): ## TransanaGlobal.encoding = 'koi8_r' ## elif (TransanaGlobal.configData.language == 'zh'): ## TransanaGlobal.encoding = TransanaConstants.chineseEncoding ## elif (TransanaGlobal.configData.language == 'el'): ## TransanaGlobal.encoding = 'iso8859_7' ## elif (TransanaGlobal.configData.language == 'ja'): ## TransanaGlobal.encoding = 'cp932' ## elif (TransanaGlobal.configData.language == 'ko'): ## TransanaGlobal.encoding = 'cp949' # Use UTF-8 Encoding throughout Transana to allow maximum internationalization if ('unicode' in wx.PlatformInfo) and (wx.VERSION_STRING >= '2.6'): wx.SetDefaultPyEncoding('utf_8') # On OS/X, change the working directory to the directory the script is # running from, this is necessary for running from a bundle. if "__WXMAC__" in wx.PlatformInfo: if TransanaGlobal.programDir != '': os.chdir(TransanaGlobal.programDir) import MenuWindow # import Menu Window Object sys.excepthook = transana_excepthook # Define the system exception handler # First, determine the program name that should be displayed, single or multi-user if TransanaConstants.singleUserVersion: if TransanaConstants.proVersion: programTitle = _("Transana - Professional") else: programTitle = _("Transana - Standard") else: programTitle = _("Transana - Multiuser") # Ammend the program title for the Demo version if appropriate if TransanaConstants.demoVersion: programTitle += _(" - Demonstration") # Create the Menu Window TransanaGlobal.menuWindow = MenuWindow.MenuWindow( None, -1, programTitle) # Create the global transana graphics colors, once the ConfigData object exists. TransanaGlobal.transana_graphicsColorList = TransanaGlobal.getColorDefs( TransanaGlobal.configData.colorConfigFilename) # Set essential global color manipulation data structures once the ConfigData object exists. (TransanaGlobal.transana_colorNameList, TransanaGlobal.transana_colorLookup, TransanaGlobal.keywordMapColourSet ) = TransanaGlobal.SetColorVariables() # Add the RTF modules to the Python module search path. This allows # us to import from a directory other than the standard search paths # and the current directory/subdirectories. sys.path.append("rtf") # Load the Splash Screen graphic bitmap = TransanaImages.splash.GetBitmap() # We need to draw the Version Number onto the Splash Screen Graphic. # First, create a Memory DC memoryDC = wx.MemoryDC() # Select the bitmap into the Memory DC memoryDC.SelectObject(bitmap) # Build the Version label if TransanaConstants.singleUserVersion: if TransanaConstants.labVersion: versionLbl = _("Computer Lab Version") elif TransanaConstants.demoVersion: versionLbl = _("Demonstration Version") elif TransanaConstants.workshopVersion: versionLbl = _("Workshop Version") else: if TransanaConstants.proVersion: versionLbl = _("Professional Version") else: versionLbl = _("Standard Version") else: versionLbl = _("Multi-user Version") versionLbl += " %s" # Determine the size of the version text (verWidth, verHeight) = memoryDC.GetTextExtent( versionLbl % TransanaConstants.versionNumber) # Add the Version Number text to the Memory DC (and therefore the bitmap) memoryDC.DrawText(versionLbl % TransanaConstants.versionNumber, 370 - verWidth, 156) # Clear the bitmap from the Memory DC, thus freeing it to be displayed! memoryDC.SelectObject(wx.EmptyBitmap(10, 10)) # If the Splash Screen Graphic exists, display the Splash Screen for 4 seconds. # If not, raise an exception. if bitmap: # Mac requires a different style, as "STAY_ON_TOP" adds a header to the Splash Screen if "__WXMAC__" in wx.PlatformInfo: splashStyle = wx.SIMPLE_BORDER else: splashStyle = wx.SIMPLE_BORDER | wx.STAY_ON_TOP # If we have a Right-To-Left language ... if TransanaGlobal.configData.LayoutDirection == wx.Layout_RightToLeft: # ... we need to reverse the image direcion bitmap = bitmap.ConvertToImage().Mirror().ConvertToBitmap() splashPosition = wx.DefaultPosition ## This doesn't work. I have not been able to put the Splash Screen anywhere but on the Center of ## Monitor 0 (with wx.SPASH_CENTER_ON_SCREEN) or the upper left corner of Monitor 0 (without it). Bummer. ## # Get the Size and Position for the PRIMARY screen ## (x1, y1, w1, h1) = wx.Display(TransanaGlobal.configData.primaryScreen).GetClientArea() ## (x2, y2) = bitmap.GetSize() ## ## splashPosition = (int(float(w1) / 2.0) + x1 - int(float(x2) / 2.0), ## int(float(h1) / 2.0) + y1 - int(float(y2) / 2.0)) ## ## print "Splash Screen Position:" ## print TransanaGlobal.configData.primaryScreen ## print x1, y1, w1, h1 ## print x2, y2 ## print splashPosition ## print # Create the SplashScreen object splash = wx.SplashScreen( bitmap, wx.SPLASH_CENTER_ON_SCREEN | wx.SPLASH_TIMEOUT, 4000, None, -1, splashPosition, wx.DefaultSize, splashStyle) else: raise ImageLoadError, \ _("Unable to load Transana's splash screen image. Installation error?") wx.Yield() if DEBUG: print "Number of Monitors:", wx.Display.GetCount() for x in range(wx.Display.GetCount()): print " ", x, wx.Display(x).IsPrimary(), wx.Display( x).GetGeometry(), wx.Display(x).GetClientArea() print import DataWindow # import Data Window Object import VideoWindow # import Video Window Object # import Transcript Window Object if TransanaConstants.USESRTC: import TranscriptionUI_RTC as TranscriptionUI else: import TranscriptionUI import VisualizationWindow # import Visualization Window Object import exceptions # import exception handler (Python) # if we're running the multi-user version of Transana ... if not TransanaConstants.singleUserVersion: # ... import the Transana ChatWindow module import ChatWindow # Initialize all main application Window Objects # If we're running the Lab version OR we're on the Mac ... if TransanaConstants.labVersion or ('wxMac' in wx.PlatformInfo): # ... then pausing for 4 seconds delays the appearance of the Lab initial configuration dialog # or the Mac version login / database dialog until the Splash screen closes. time.sleep(4) # If we are running the Lab version ... if TransanaConstants.labVersion: # ... we want an initial configuration screen. Start by importing Transana's Option Settings dialog import OptionsSettings # Initialize all paths to BLANK for the lab version TransanaGlobal.configData.videoPath = '' TransanaGlobal.configData.visualizationPath = '' TransanaGlobal.configData.databaseDir = '' # Create the config dialog for the Lab initial configuration options = OptionsSettings.OptionsSettings( TransanaGlobal.menuWindow, lab=True) options.Destroy() wx.Yield() # If the databaseDir is blank, user pressed CANCEL ... if (TransanaGlobal.configData.databaseDir == ''): # ... and we should quit immediately, signalling failure return False # initialze a variable indicating database connection to False (assume the worst.) connectionEstablished = False # Let's trap the situation where the database folder is not available. try: # Start MySQL if using the embedded version if TransanaConstants.singleUserVersion: DBInterface.InitializeSingleUserDatabase() # If we get here, we've been successful! (NOTE that MU merely changes our default from False to True!) connectionEstablished = True except: if DEBUG: import traceback print sys.exc_info()[0], sys.exc_info()[1] traceback.print_exc(file=sys.stdout) msg = _( 'Transana is unable to access any Database at "%s".\nPlease check to see if this path is available.' ) if not TransanaConstants.labVersion: msg += '\n' + _( 'Would you like to restore the default Database path?') if ('unicode' in wx.PlatformInfo) and isinstance(msg, str): msg = unicode(msg, 'utf8') msg = msg % TransanaGlobal.configData.databaseDir if TransanaConstants.labVersion: dlg = Dialogs.ErrorDialog(None, msg) dlg.ShowModal() dlg.Destroy() return False # If we're on the Single-user version for Windows ... if TransanaConstants.singleUserVersion: # ... determine the file name for the data conversion information pickle file fs = os.path.join(TransanaGlobal.configData.databaseDir, '260_300_Convert.pkl') # If there is data in mid-conversion ... if os.path.exists(fs): # ... get the conversion data from the Pickle File f = file(fs, 'r') # exportedDBs is a dictionary containing the Transana-XML file name and the encoding of each DB to be imported self.exportedDBs = pickle.load(f) # Close the pickle file f.close() # Prompt the user about importing the converted data prompt = unicode( _("Transana has detected one or more databases ready for conversion.\nDo you want to convert those databases now?" ), 'utf8') tmpDlg = Dialogs.QuestionDialog(TransanaGlobal.menuWindow, prompt, _("Database Conversion")) result = tmpDlg.LocalShowModal() tmpDlg.Destroy() # If the user wants to do the conversion now ... if result == wx.ID_YES: # ... import Transana's XML Import code import XMLImport # Before we go further, let's make sure none of the conversion files have ALREADY been imported! # The 2.42 to 2.50 Data Conversion Utility shouldn't allow this, but it doesn't hurt to check. # Iterate through the conversion data for key in self.exportedDBs: # Determine the file path for the converted database newDBPath = os.path.join( TransanaGlobal.configData.databaseDir, key + '.db') # If the converted database ALREADY EXISTS ... if os.path.exists(newDBPath): # ... create an error message prompt = unicode( _('Database "%s" already exists.\nDatabase "%s" cannot be converted at this time.' ), 'utf8') # ... display an error message tmpDlg = Dialogs.ErrorDialog( None, prompt % (key, key)) tmpDlg.ShowModal() tmpDlg.Destroy() # If the converted database does NOT exist ... else: if 'wxMac' in wx.PlatformInfo: prompt = _( 'Converting "%s"\nThis process may take a long time, depending on how much data this database contains.\nWe cannot provide progress feedback on OS X. Please be patient.' ) progWarn = Dialogs.PopupDialog( None, _("Converting Databases"), prompt % key) # Create the Import Database, passing the database name so the user won't be prompted for one. DBInterface.establish_db_exists(dbToOpen=key, usePrompt=False) # Import the database. # First, create an Import Database dialog, but don't SHOW it. temp = XMLImport.XMLImport( TransanaGlobal.menuWindow, -1, _('Transana XML Import'), importData=self.exportedDBs[key]) # ... Import the requested data! temp.Import() # Close the Import Database dialog temp.Close() if 'wxMac' in wx.PlatformInfo: progWarn.Destroy() progWarn = None # Close the database that was just imported DBInterface.close_db() # Clear the current database name from the Config data TransanaGlobal.configData.database = '' # If we do NOT have a localhost key (which Lab version does not!) ... if not TransanaGlobal.configData.databaseList.has_key( 'localhost'): # ... let's create one so we can pass the converted database name! TransanaGlobal.configData.databaseList[ 'localhost'] = {} TransanaGlobal.configData.databaseList[ 'localhost']['dbList'] = [] # Update the database name TransanaGlobal.configData.database = key # Add the new (converted) database name to the database list TransanaGlobal.configData.databaseList[ 'localhost']['dbList'].append( key.encode('utf8')) # Start exception handling try: # If we're NOT in the lab version of Transana ... if not TransanaConstants.labVersion: # This is harder than it should be because of a combination of encoding and case-changing issues. # Let's iterate through the Version 2.5 "paths by database" config data for key2 in TransanaGlobal.configData.pathsByDB2.keys( ): # If we have a LOCAL database with a matching key to the database being imported ... if (key2[0] == '') and ( key2[1] == 'localhost' ) and (key2[2].decode('utf8').lower() == key): # Add the unconverted database's PATH values to the CONVERTED database's configuration! TransanaGlobal.configData.pathsByDB[('', 'localhost', key.encode('utf8'))] = \ {'visualizationPath' : TransanaGlobal.configData.pathsByDB2[key2]['visualizationPath'], 'videoPath' : TransanaGlobal.configData.pathsByDB2[key2]['videoPath']} # ... and we can stop looking break # Save the altered configuration data TransanaGlobal.configData.SaveConfiguration() # The Computer Lab version sometimes throws a KeyError except exceptions.KeyError: # If this comes up, we can ignore it. pass # Delete the Import File Information os.remove(fs) if DEBUG: print "Done importing Files" # We can only continue if we initialized the database OR are running MU. if connectionEstablished: # If a new database login fails three times, we need to close the program. # Initialize a counter to track that. logonCount = 1 # Flag if Logon succeeds loggedOn = False # Keep trying for three tries or until successful while (logonCount <= 3) and (not loggedOn): logonCount += 1 # Confirm the existence of the DB Tables, creating them if needed. # This method also calls the Username and Password Dialog if needed. # NOTE: The Menu Window must be created first to server as a parent for the Username and Password Dialog # called up by DBInterface. if DBInterface.establish_db_exists(): if DEBUG: print "Creating Data Window", # Create the Data Window # Data Window creation causes Username and Password Dialog to be displayed, # so it should be created before the Video Window self.dataWindow = DataWindow.DataWindow( TransanaGlobal.menuWindow) if DEBUG: print self.dataWindow.GetSize() print "Creating Video Window", # Create the Video Window self.videoWindow = VideoWindow.VideoWindow( TransanaGlobal.menuWindow) # Create the Transcript Window. If on the Mac, include the Close button. if DEBUG: print self.videoWindow.GetSize() print "Creating Transcript Window", self.transcriptWindow = TranscriptionUI.TranscriptionUI( TransanaGlobal.menuWindow, includeClose=('wxMac' in wx.PlatformInfo)) if DEBUG: print self.transcriptWindow.dlg.GetSize() print "Creating Visualization Window", # Create the Visualization Window self.visualizationWindow = VisualizationWindow.VisualizationWindow( TransanaGlobal.menuWindow) if DEBUG: print self.visualizationWindow.GetSize() print "Creating Control Object" # Create the Control Object and register all objects to be controlled with it self.ControlObject = ControlObject() self.ControlObject.Register( Menu=TransanaGlobal.menuWindow, Video=self.videoWindow, Transcript=self.transcriptWindow, Data=self.dataWindow, Visualization=self.visualizationWindow) # Set the active transcript self.ControlObject.activeTranscript = 0 # Register the ControlObject with all other objects to be controlled TransanaGlobal.menuWindow.Register( ControlObject=self.ControlObject) self.dataWindow.Register(ControlObject=self.ControlObject) self.videoWindow.Register(ControlObject=self.ControlObject) self.transcriptWindow.Register( ControlObject=self.ControlObject) self.visualizationWindow.Register( ControlObject=self.ControlObject) # Set the Application Top Window to the Menu Window (wxPython) self.SetTopWindow(TransanaGlobal.menuWindow) TransanaGlobal.resizingAll = True if DEBUG: print print "Before Showing Windows:" print " menu:\t\t", TransanaGlobal.menuWindow.GetRect( ) print " visual:\t", self.visualizationWindow.GetRect() print " video:\t", self.videoWindow.GetRect() print " trans:\t", self.transcriptWindow.dlg.GetRect() print " data:\t\t", self.dataWindow.GetRect() print print 'Heights:', self.transcriptWindow.dlg.GetRect( )[1] + self.transcriptWindow.dlg.GetRect( )[3], self.dataWindow.GetRect( )[1] + self.dataWindow.GetRect()[3] print if self.transcriptWindow.dlg.GetRect( )[1] + self.transcriptWindow.dlg.GetRect( )[3] > self.dataWindow.GetRect( )[1] + self.dataWindow.GetRect()[3]: self.dataWindow.SetRect((self.dataWindow.GetRect()[0], self.dataWindow.GetRect()[1], self.dataWindow.GetRect()[2], self.dataWindow.GetRect()[3] + \ (self.transcriptWindow.dlg.GetRect()[1] + self.transcriptWindow.dlg.GetRect()[3] - (self.dataWindow.GetRect()[1] + self.dataWindow.GetRect()[3])))) print "DataWindow Height Adjusted!" print " data:\t\t", self.dataWindow.GetRect() print # Show all Windows. TransanaGlobal.menuWindow.Show(True) if DEBUG: print "Showing Windows:" print " menu:", TransanaGlobal.menuWindow.GetRect() self.visualizationWindow.Show() if DEBUG: print " visualization:", self.visualizationWindow.GetRect( ) self.videoWindow.Show() if DEBUG: print " video:", self.videoWindow.GetRect( ), self.transcriptWindow.dlg.GetRect() self.transcriptWindow.Show() if DEBUG: print " transcript:", self.transcriptWindow.dlg.GetRect( ), self.dataWindow.GetRect() self.dataWindow.Show() if DEBUG: print " data:", self.dataWindow.GetRect( ), self.visualizationWindow.GetRect() # Get the size and position of the Visualization Window (x, y, w, h) = self.visualizationWindow.GetRect() if DEBUG: print print "Call 3", 'Visualization', w + x # Adjust the positions of all other windows to match the Visualization Window's initial position self.ControlObject.UpdateWindowPositions('Visualization', w + x + 1, YUpper=h + y + 1) TransanaGlobal.resizingAll = False loggedOn = True # If logon fails, inform user and offer to try again twice. elif logonCount <= 3: # Check to see if we have an SSL failure caused by insufficient data if (not TransanaConstants.singleUserVersion) and TransanaGlobal.configData.ssl and \ (TransanaGlobal.configData.sslClientCert == '' or TransanaGlobal.configData.sslClientKey == ''): # If so, inform the user prompt = _( "The information on the SSL tab is required to establish an SSL connection to the database.\nWould you like to try again?" ) # Otherwise ... else: # ... give a generic message about logon failure. prompt = _( 'Transana was unable to connect to the database.\nWould you like to try again?' ) dlg = Dialogs.QuestionDialog( TransanaGlobal.menuWindow, prompt, _('Transana Database Connection')) # If the user does not want to try again, set the counter to 4, which will cause the program to exit if dlg.LocalShowModal() == wx.ID_NO: logonCount = 4 # Clean up the Dialog Box dlg.Destroy() # If we successfully logged in ... if loggedOn: # ... save the configuration data that got us in TransanaGlobal.configData.SaveConfiguration() # if we're running the multi-user version of Transana and successfully connected to a database ... if not TransanaConstants.singleUserVersion and loggedOn: if DEBUG: print "Need to connect to MessageServer" # ... connect to the Message Server Here TransanaGlobal.socketConnection = ChatWindow.ConnectToMessageServer( ) # If the connections fails ... if TransanaGlobal.socketConnection == None: # ... signal that Transana should NOT start up! loggedOn = False else: # If Transana MU sits idle too long (30 - 60 minutes), people would sometimes get a # "Connection to Database Lost" error message even though MySQL was set to maintain the # connection for 8 hours. To try to address this, we will set up a Timer that will run # a simple query every 10 minutes to maintain the connection to the database. # Create the Connection Timer TransanaGlobal.connectionTimer = wx.Timer(self) # Bind the timer to its event self.Bind(wx.EVT_TIMER, self.OnTimer) # Tell the timer to fire every 10 minutes. # NOTE: If changing this value, it also needs to be changed in the ControlObjectClass.GetNewDatabase() method. TransanaGlobal.connectionTimer.Start(600000) if DEBUG: print "MessageServer connected!" # Check if the Database and Message Server are both using SSL and select the appropriate graphic self.dataWindow.UpdateSSLStatus(TransanaGlobal.configData.ssl and TransanaGlobal.chatIsSSL) # if this is the first time this user profile has used Transana ... if firstStartup and loggedOn: # ... create a prompt about looking at the Tutorial prompt = _( 'If this is your first time using Transana, the Transana Tutorial can help you learn how to use the program.' ) prompt += '\n\n' + _( 'Would you like to see the Transana Tutorial now?') # Display the Tutorial prompt in a Yes / No dialog tmpDlg = Dialogs.QuestionDialog(TransanaGlobal.menuWindow, prompt) # If the user says Yes ... if tmpDlg.LocalShowModal() == wx.ID_YES: # ... start the Tutorial self.ControlObject.Help('Welcome to the Transana Tutorial') if DEBUG: print print "Final Windows:" print " menu:\t\t", TransanaGlobal.menuWindow.GetRect() print " visual:\t", self.visualizationWindow.GetRect() print " video:\t", self.videoWindow.GetRect() print " trans:\t", self.transcriptWindow.dlg.GetRect() print " data:\t\t", self.dataWindow.GetRect() print else: loggedOn = False dlg = Dialogs.QuestionDialog(TransanaGlobal.menuWindow, msg, _('Transana Database Connection')) if dlg.LocalShowModal() == wx.ID_YES: TransanaGlobal.configData.databaseDir = os.path.join( TransanaGlobal.configData.GetDefaultProfilePath(), 'databases') TransanaGlobal.configData.SaveConfiguration() # Clean up the Dialog Box dlg.Destroy() return loggedOn
def __init__(self, parent, id, title, document_object): """ Create the Transcript Properties form """ self.parent = parent self.width = 500 self.height = 260 # Make the Keyword Edit List resizable by passing wx.RESIZE_BORDER style Dialogs.GenForm.__init__(self, parent, id, title, size=(self.width, self.height), style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, useSizers=True, HelpContext='Document Properties') # Define the form's main object self.obj = document_object # if a Library has been passed in ... if self.obj.library_num > 0: # ... get the Library's data library = Library.Library(self.obj.library_num) # If no Library has been passed in (ILLEGAL??) ... else: # ... create an empty Library library = Library.Library() # Create the form's main VERTICAL sizer mainSizer = wx.BoxSizer(wx.VERTICAL) # Create a VERTICAL sizer for the next element v1 = wx.BoxSizer(wx.VERTICAL) # Add the Transcript ID element self.id_edit = self.new_edit_box(_("Document ID"), v1, self.obj.id, maxLen=100) # Add the element to the sizer mainSizer.Add(v1, 1, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a VERTICAL sizer for the next element v2 = wx.BoxSizer(wx.VERTICAL) # Add the Library ID element library_id_edit = self.new_edit_box(_("Library ID"), v2, library.id) # Add the element to the main sizer mainSizer.Add(v2, 1, wx.EXPAND) # Disable Library ID library_id_edit.Enable(False) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # If the Document has already been defined, we can skip this! if self.obj.number == 0: # Create a HORIZONTAL sizer for the next row r1Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v3 = wx.BoxSizer(wx.VERTICAL) # Add the Import File element self.rtfname_edit = self.new_edit_box( _("DOCX/RTF/XML/TXT File to import (optional)"), v3, '') # Make this text box a File Drop Target self.rtfname_edit.SetDropTarget( EditBoxFileDropTarget(self.rtfname_edit)) # Add the element to the row sizer r1Sizer.Add(v3, 1, wx.EXPAND) # Add a horizontal spacer to the row sizer r1Sizer.Add((10, 0)) # Add the Browse Button browse = wx.Button(self.panel, -1, _("Browse")) # Add the Browse Method to the Browse Button wx.EVT_BUTTON(self, browse.GetId(), self.OnBrowseClick) # Add the element to the sizer r1Sizer.Add(browse, 0, wx.ALIGN_BOTTOM) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping r1Sizer.Add((2, 0)) # Add the row sizer to the main vertical sizer mainSizer.Add(r1Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) else: # Create a HORIZONTAL sizer for the next row r1Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v3 = wx.BoxSizer(wx.VERTICAL) # Add the Import File element self.rtfname_edit = self.new_edit_box(_("Imported File"), v3, self.obj.imported_file) # Disable this field self.rtfname_edit.Enable(False) # Add the element to the row sizer r1Sizer.Add(v3, 4, wx.EXPAND) # Add a horizontal spacer to the row sizer r1Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v35 = wx.BoxSizer(wx.VERTICAL) # If the import date is a datetime object ... if isinstance(self.obj.import_date, datetime.datetime): # ... get its YYYY-MM-DD representation dtStr = self.obj.import_date.strftime('%Y-%m-%d') # if the import date is None ... elif self.obj.import_date is None: # ... leave this field blank dtStr = '' # Otherwise ... else: # Use whatever the import date value is dtStr = self.obj.import_date # If no file was imported ... if self.obj.imported_file == '': # ... the date is the Document Creation Date prompt = _("Creation Date") # If a file was imported ... else: # ... the date is the Document Import Date prompt = _("Import Date") # Add the Import Date element self.import_date = self.new_edit_box(prompt, v35, dtStr) # Disable this field self.import_date.Enable(False) # Add the element to the row sizer r1Sizer.Add(v35, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r1Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a VERTICAL sizer for the next element v4 = wx.BoxSizer(wx.VERTICAL) # Add the Author element author_edit = self.new_edit_box(_("Author"), v4, self.obj.author, maxLen=100) # Add the element to the main sizer mainSizer.Add(v4, 1, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a VERTICAL sizer for the next element v5 = wx.BoxSizer(wx.VERTICAL) # Add the Comment element comment_edit = self.new_edit_box(_("Comment"), v5, self.obj.comment, maxLen=255) # Add the element to the main sizer mainSizer.Add(v5, 1, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r2Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v6 = wx.BoxSizer(wx.VERTICAL) # Keyword Group [label] txt = wx.StaticText(self.panel, -1, _("Keyword Group")) v6.Add(txt, 0, wx.BOTTOM, 3) # Keyword Group [list box] kw_groups_id = wx.NewId() # Create an empty Keyword Group List for now. We'll populate it later (for layout reasons) self.kw_groups = [] self.kw_group_lb = wx.ListBox(self.panel, kw_groups_id, wx.DefaultPosition, wx.DefaultSize, self.kw_groups) v6.Add(self.kw_group_lb, 1, wx.EXPAND) # Add the element to the sizer r2Sizer.Add(v6, 1, wx.EXPAND) self.kw_list = [] wx.EVT_LISTBOX(self, kw_groups_id, self.OnGroupSelect) # Add a horizontal spacer r2Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v7 = wx.BoxSizer(wx.VERTICAL) # Keyword [label] txt = wx.StaticText(self.panel, -1, _("Keyword")) v7.Add(txt, 0, wx.BOTTOM, 3) # Keyword [list box] self.kw_lb = wx.ListBox(self.panel, -1, wx.DefaultPosition, wx.DefaultSize, self.kw_list, style=wx.LB_EXTENDED) v7.Add(self.kw_lb, 1, wx.EXPAND) wx.EVT_LISTBOX_DCLICK(self, self.kw_lb.GetId(), self.OnAddKW) # Add the element to the sizer r2Sizer.Add(v7, 1, wx.EXPAND) # Add a horizontal spacer r2Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v8 = wx.BoxSizer(wx.VERTICAL) # Keyword transfer buttons add_kw = wx.Button(self.panel, wx.ID_FILE2, ">>", wx.DefaultPosition) v8.Add(add_kw, 0, wx.EXPAND | wx.TOP, 20) wx.EVT_BUTTON(self, wx.ID_FILE2, self.OnAddKW) rm_kw = wx.Button(self.panel, wx.ID_FILE3, "<<", wx.DefaultPosition) v8.Add(rm_kw, 0, wx.EXPAND | wx.TOP, 10) wx.EVT_BUTTON(self, wx.ID_FILE3, self.OnRemoveKW) kwm = wx.BitmapButton(self.panel, wx.ID_FILE4, TransanaImages.KWManage.GetBitmap()) v8.Add(kwm, 0, wx.EXPAND | wx.TOP, 10) # Add a spacer to increase the height of the Keywords section v8.Add((0, 60)) kwm.SetToolTipString(_("Keyword Management")) wx.EVT_BUTTON(self, wx.ID_FILE4, self.OnKWManage) # Add the element to the sizer r2Sizer.Add(v8, 0) # Add a horizontal spacer r2Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v9 = wx.BoxSizer(wx.VERTICAL) # Episode Keywords [label] txt = wx.StaticText(self.panel, -1, _("Document Keywords")) v9.Add(txt, 0, wx.BOTTOM, 3) # Episode Keywords [list box] # Create an empty ListBox self.ekw_lb = wx.ListBox(self.panel, -1, wx.DefaultPosition, wx.DefaultSize, style=wx.LB_EXTENDED) v9.Add(self.ekw_lb, 1, wx.EXPAND) self.ekw_lb.Bind(wx.EVT_KEY_DOWN, self.OnKeywordKeyDown) # Add the element to the sizer r2Sizer.Add(v9, 2, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r2Sizer, 5, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a sizer for the buttons btnSizer = wx.BoxSizer(wx.HORIZONTAL) # Add the buttons self.create_buttons(sizer=btnSizer) # Add the button sizer to the main sizer mainSizer.Add(btnSizer, 0, wx.EXPAND) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping mainSizer.Add((0, 2)) # Set the PANEL's main sizer self.panel.SetSizer(mainSizer) # Tell the PANEL to auto-layout self.panel.SetAutoLayout(True) # Lay out the Panel self.panel.Layout() # Lay out the Form self.Layout() # Resize the form to fit the contents self.Fit() # Get the new size of the form (width, height) = self.GetSizeTuple() # Reset the form's size to be at least the specified minimum width self.SetSize(wx.Size(max(self.width, width), height)) # Define the minimum size for this dialog as the current size, and define height as unchangeable self.SetSizeHints(max(self.width, width), height, -1, height) # Center the form on screen TransanaGlobal.CenterOnPrimary(self) # We need to set some minimum sizes so the sizers will work right self.kw_group_lb.SetSizeHints(minW=50, minH=20) self.kw_lb.SetSizeHints(minW=50, minH=20) self.ekw_lb.SetSizeHints(minW=50, minH=20) # We populate the Keyword Groups, Keywords, and Clip Keywords lists AFTER we determine the Form Size. # Long Keywords in the list were making the form too big! self.kw_groups = DBInterface.list_of_keyword_groups() for keywordGroup in self.kw_groups: self.kw_group_lb.Append(keywordGroup) # Select the Library Default Keyword Group in the Keyword Group list if (library.keyword_group != '') and (self.kw_group_lb.FindString( library.keyword_group) != wx.NOT_FOUND): self.kw_group_lb.SetStringSelection(library.keyword_group) # If no Default Keyword Group is defined, select the first item in the list else: # but only if there IS a first item in the list. if len(self.kw_groups) > 0: self.kw_group_lb.SetSelection(0) if self.kw_group_lb.GetSelection() != wx.NOT_FOUND: self.kw_list = \ DBInterface.list_of_keywords_by_group(self.kw_group_lb.GetStringSelection()) else: self.kw_list = [] for keyword in self.kw_list: self.kw_lb.Append(keyword) # Populate the ListBox for documentKeyword in self.obj.keyword_list: self.ekw_lb.Append(documentKeyword.keywordPair) # This is bad. Sorry. # Create a hidden RichTextEditCtrl to use for importing data self.hiddenRTC = RichTextEditCtrl_RTC.RichTextEditCtrl(self) # This control should NOT be visible self.hiddenRTC.Show(False) # Set focus to the Transcript ID self.id_edit.SetFocus()
def __init__(self, parent): wx.Dialog.__init__(self, parent, -1, _("sFTP Connection Parameters"), size=(250, 520), style=wx.CAPTION | wx.RESIZE_BORDER | wx.NO_FULL_REPAINT_ON_RESIZE) self.LoadConfiguration() # Create a Sizer box = wx.BoxSizer(wx.VERTICAL) lblUserName = wx.StaticText(self, -1, _("User Name:")) box.Add(lblUserName, 0, wx.LEFT, 10) self.editUserName = wx.TextCtrl(self, -1) box.Add(self.editUserName, 2, wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, 10) lblPassword = wx.StaticText(self, -1, _("Password:"******"sFTP Server:")) box.Add(lblsFTPServer, 0, wx.LEFT, 10) self.editsFTPServer = wx.TextCtrl(self, -1, self.sFTPServer) box.Add(self.editsFTPServer, 2, wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, 10) lblsFTPPort = wx.StaticText(self, -1, _("sFTP Port:")) box.Add(lblsFTPPort, 0, wx.LEFT, 10) self.editsFTPPort = wx.TextCtrl(self, -1, self.sFTPPort) box.Add(self.editsFTPPort, 2, wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, 10) lblsFTPPublicKeyType = wx.StaticText(self, -1, _("sFTP Server Public Key Type:")) box.Add(lblsFTPPublicKeyType, 0, wx.LEFT, 10) self.choicesFTPPublicKeyType = wx.Choice( self, -1, choices=[_('None'), 'ssh-rsa', 'ssh-dss']) self.choicesFTPPublicKeyType.SetStringSelection(self.sFTPPublicKeyType) self.choicesFTPPublicKeyType.Bind(wx.EVT_CHOICE, self.OnPublicKeyTypeSelect) box.Add(self.choicesFTPPublicKeyType, 2, wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, 10) lblsFTPPublicKey = wx.StaticText(self, -1, _("sFTP Server Public Key:")) box.Add(lblsFTPPublicKey, 0, wx.LEFT, 10) self.editsFTPPublicKey = wx.TextCtrl(self, -1, self.sFTPPublicKey) if self.sFTPPublicKeyType.encode('utf8') == _("None"): self.editsFTPPublicKey.Enable(False) box.Add(self.editsFTPPublicKey, 2, wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, 10) btnBox = wx.BoxSizer(wx.HORIZONTAL) btnBox.Add((20, 0)) btnConnect = wx.Button(self, wx.ID_OK, _("Connect")) btnBox.Add(btnConnect, 1, wx.ALIGN_CENTER_HORIZONTAL) # Make the Connect button the default self.SetDefaultItem(btnConnect) btnBox.Add((20, 0)) btnCancel = wx.Button(self, wx.ID_CANCEL, _("Cancel")) btnBox.Add(btnCancel, 1, wx.ALIGN_CENTER_HORIZONTAL) btnBox.Add((20, 0)) box.Add(btnBox, 0, wx.ALIGN_CENTER) box.Add((0, 10)) self.SetSizer(box) self.Fit() self.Layout() self.SetAutoLayout(True) # Center on the Screen TransanaGlobal.CenterOnPrimary(self) # Set Focus self.editUserName.SetFocus()
def __init__(self, parent, title, fileName, localDir, remoteDir, direction): """ Set up the Dialog Box and all GUI Widgets. """ # Initialize the last update time self.lastUpdate = time.time() # Set up local variables self.parent = parent size = (350,200) # Create the Dialog Box itself, with no minimize/maximize/close buttons wx.Dialog.__init__(self, parent, -1, title, size = size, style=wx.CAPTION) # Create a main VERTICAL sizer for the form mainSizer = wx.BoxSizer(wx.VERTICAL) # File label if 'unicode' in wx.PlatformInfo: # Encode with UTF-8 rather than TransanaGlobal.encoding because this is a prompt, not DB Data. prompt = unicode(_("File: %s"), 'utf8') else: prompt = _("File: %s") self.lblFile = wx.StaticText(self, -1, prompt % fileName, style=wx.ST_NO_AUTORESIZE) # Add the label to the Main Sizer mainSizer.Add(self.lblFile, 0, wx.ALL, 10) # Progress Bar self.progressBar = wx.Gauge(self, -1, 100, style=wx.GA_HORIZONTAL | wx.GA_SMOOTH) # Add the element to the Main Sizer mainSizer.Add(self.progressBar, 1, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10) # Create a Row Sizer r1Sizer = wx.BoxSizer(wx.HORIZONTAL) # Bytes Transferred label if 'unicode' in wx.PlatformInfo: # Encode with UTF-8 rather than TransanaGlobal.encoding because this is a prompt, not DB Data. prompt = unicode(_("%d bytes of %d transferred"), 'utf8') else: prompt = _("%d bytes of %d transferred") self.lblBytes = wx.StaticText(self, -1, prompt % (100000000, 100000000), style=wx.ST_NO_AUTORESIZE) # Add the label to the Row Sizer r1Sizer.Add(self.lblBytes, 5, wx.EXPAND) # Percent Transferred label self.lblPercent = wx.StaticText(self, -1, "%5.1d %%" % 1000.1, style=wx.ST_NO_AUTORESIZE | wx.ALIGN_RIGHT) # Add the Element to the Row Sizer r1Sizer.Add(self.lblPercent, 1, wx.ALIGN_RIGHT) # Add the Row Sizer to the Main Sizer mainSizer.Add(r1Sizer, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10) # Create a Row Sizer r2Sizer = wx.BoxSizer(wx.HORIZONTAL) # Elapsed Time label if 'unicode' in wx.PlatformInfo: # Encode with UTF-8 rather than TransanaGlobal.encoding because this is a prompt, not DB Data. prompt = unicode(_("Elapsed Time: %d:%02d:%02d"), 'utf8') else: prompt = _("Elapsed Time: %d:%02d:%02d") self.lblElapsedTime = wx.StaticText(self, -1, prompt % (0, 0, 0), style=wx.ST_NO_AUTORESIZE) # Add the element to the Row Sizer r2Sizer.Add(self.lblElapsedTime, 0) # Add a spacer r2Sizer.Add((1, 0), 1, wx.EXPAND) # Remaining Time label if 'unicode' in wx.PlatformInfo: # Encode with UTF-8 rather than TransanaGlobal.encoding because this is a prompt, not DB Data. prompt = unicode(_("Time Remaining: %d:%02d:%02d"), 'utf8') else: prompt = _("Time Remaining: %d:%02d:%02d") self.lblTimeRemaining = wx.StaticText(self, -1, prompt % (0, 0, 0), style=wx.ST_NO_AUTORESIZE | wx.ALIGN_RIGHT) # Add the element to the Row Sizer r2Sizer.Add(self.lblTimeRemaining, 0) # Add the Row Sizer to the Main Sizer mainSizer.Add(r2Sizer, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10) # Transfer Speed label if 'unicode' in wx.PlatformInfo: # Encode with UTF-8 rather than TransanaGlobal.encoding because this is a prompt, not DB Data. prompt = unicode(_("Transfer Speed: %d k/sec"), 'utf8') else: prompt = _("Transfer Speed: %d k/sec") self.lblTransferSpeed = wx.StaticText(self, -1, prompt % 0, style=wx.ST_NO_AUTORESIZE) # Add the element to the Main Sizer mainSizer.Add(self.lblTransferSpeed, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10) # Cancel Button self.btnCancel = wx.Button(self, wx.ID_CANCEL, _("Cancel Remaining Files")) # Add the element to the Main Sizer mainSizer.Add(self.btnCancel, 0, wx.ALIGN_CENTER | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10) wx.EVT_BUTTON(self, wx.ID_CANCEL, self.OnCancel) # Attach the main sizer to the form self.SetSizer(mainSizer) # Turn Auto Layout on self.SetAutoLayout(True) # Lay out the form self.Layout() # Center on the Screen TransanaGlobal.CenterOnPrimary(self) # Show the form self.Show() # make sure the loca directory ends with the proper path seperator character if localDir[-1] != os.sep: localDir = localDir + os.sep # Initialize variables used in file transfer BytesRead = 0 # "cancelled" is intialized to false. If the user cancels the file transfer, # this variable gets set to true to signal the need to interrupt the transfer. self.cancelled = False # Note the starting time of the transfer for progress reporting purposes self.StartTime = time.time() # If we are sending files from the sFTP Server to the local File System... if direction == sFTP_DOWNLOAD: self.SetTitle(_('Downloading . . .')) try: FileResult = parent.sFTPClient.get(string.join([remoteDir, fileName], '/'), os.path.join(localDir, fileName), callback = self.UpdateDisplay) except IOError: prompt = unicode(_("Input / Output Error"), 'utf8') + "\n%s\n" + unicode(_('Please press "Refresh".'), 'utf8') dlg = Dialogs.ErrorDialog(self, prompt % (sys.exc_info()[1])) dlg.ShowModal() dlg.Destroy() # If we are sending data from the local file system to the sFTP Server ... elif direction == sFTP_UPLOAD: self.SetTitle(_('Uploading . . .')) try: # Detect Strings (instead of Unicode objects) and decode them if needed. if isinstance(localDir, str): localDir = localDir.decode(TransanaGlobal.encoding) if isinstance(remoteDir, str): remoteDir = remoteDir.decode(TransanaGlobal.encoding) # Put the file and capture the result FileResult = parent.sFTPClient.put(os.path.join(localDir, fileName), string.join([remoteDir, fileName], '/'), callback = self.UpdateDisplay) except IOError: prompt = unicode(_("Input / Output Error"), 'utf8') + "\n%s\n" + unicode(_('Please press "Refresh".'), 'utf8') dlg = Dialogs.ErrorDialog(self, prompt % (sys.exc_info()[1])) dlg.ShowModal() dlg.Destroy()
def __init__(self, parent, id, title, snapshot_object): # ... use the default Clip Properties Dialog size passed in from the config object. (This does NOT get saved.) size = TransanaGlobal.configData.clipPropertiesSize # Define the Help Context HelpContext='Snapshot Properties' # Make the Keyword Edit List resizable by passing wx.RESIZE_BORDER style. Signal that Propogation is included. Dialogs.GenForm.__init__(self, parent, id, title, size=size, style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, useSizers = True, HelpContext=HelpContext) # Define the minimum size for this dialog as the initial size minWidth = 750 minHeight = 570 # Remember the Parent Window self.parent = parent # Remember the original Snapshot Object passed in self.obj = snapshot_object # Create the form's main VERTICAL sizer mainSizer = wx.BoxSizer(wx.VERTICAL) # Create a HORIZONTAL sizer for the first row r1Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v1 = wx.BoxSizer(wx.VERTICAL) # Snapshot ID self.id_edit = self.new_edit_box(_("Snapshot ID"), v1, self.obj.id, maxLen=100) # Add the element to the sizer r1Sizer.Add(v1, 1, wx.EXPAND) # Add a horizontal spacer to the row sizer r1Sizer.Add((10, 0)) # Update the Snapshot's Collection ID based on the Snapshot's Collection Number self.obj._sync_snapshot() # Create a VERTICAL sizer for the next element v2 = wx.BoxSizer(wx.VERTICAL) # Collection ID collection_edit = self.new_edit_box(_("Collection ID"), v2, self.obj.GetNodeString(False)) # Add the element to the sizer r1Sizer.Add(v2, 2, wx.EXPAND) collection_edit.Enable(False) # Add the row sizer to the main vertical sizer mainSizer.Add(r1Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r2Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v3 = wx.BoxSizer(wx.VERTICAL) # Image Filename # If the image filename path is not empty, we should normalize the path specification if self.obj.image_filename == '': filePath = self.obj.image_filename else: filePath = os.path.normpath(self.obj.image_filename) self.fname_edit = self.new_edit_box(_("Image Filename"), v3, filePath) r2Sizer.Add(v3, 5, wx.EXPAND) r2Sizer.Add((10, 0)) # Browse button layout btnBrowse = wx.Button(self.panel, wx.ID_FILE1, _("Browse"), wx.DefaultPosition) r2Sizer.Add(btnBrowse, 0, wx.EXPAND | wx.TOP, 20) wx.EVT_BUTTON(self, wx.ID_FILE1, self.OnBrowse) # Figure out if the Snapshot Button should be displayed if ((isinstance(self.parent.ControlObject.currentObj, Episode.Episode)) or \ (isinstance(self.parent.ControlObject.currentObj, Clip.Clip))) and \ (len(self.parent.ControlObject.VideoWindow.mediaPlayers) == 1): # Add a horizontal spacer r2Sizer.Add((10, 0)) # Snapshot button layout # Create the Snapshot button btnSnapshot = wx.BitmapButton(self.panel, -1, TransanaImages.Snapshot.GetBitmap(), size=(48, 24)) # Set the Help String btnSnapshot.SetToolTipString(_("Capture Snapshot for Coding")) r2Sizer.Add(btnSnapshot, 0, wx.EXPAND | wx.TOP, 20) # Bind the Snapshot button to its event handler btnSnapshot.Bind(wx.EVT_BUTTON, self.OnSnapshot) # Add the row sizer to the main vertical sizer mainSizer.Add(r2Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r4Sizer = wx.BoxSizer(wx.HORIZONTAL) self.seriesList = DBInterface.list_of_series() seriesRecs = [''] serDefault = 0 for (seriesNum, seriesName) in self.seriesList: seriesRecs.append(seriesName) if self.obj.series_num == seriesNum: serDefault = len(seriesRecs) - 1 # Create a VERTICAL sizer for the next element v4 = wx.BoxSizer(wx.VERTICAL) # Library ID self.series_cb = self.new_choice_box(_("Library ID"), v4, seriesRecs, default = serDefault) # Add the element to the sizer r4Sizer.Add(v4, 1, wx.EXPAND) self.series_cb.Bind(wx.EVT_CHOICE, self.OnSeriesChoice) # Add a horizontal spacer to the row sizer r4Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v5 = wx.BoxSizer(wx.VERTICAL) # Episode ID self.episode_cb = self.new_choice_box(_("Episode ID"), v5, ['']) # Add the element to the sizer r4Sizer.Add(v5, 1, wx.EXPAND) self.episode_cb.Bind(wx.EVT_CHOICE, self.OnEpisodeChoice) self.episodeList = [] if self.obj.series_id != '': self.PopulateEpisodeChoiceBasedOnSeries(self.obj.series_id) # Add the row sizer to the main vertical sizer mainSizer.Add(r4Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r5Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v6 = wx.BoxSizer(wx.VERTICAL) # Episode ID self.transcript_cb = self.new_choice_box(_("Transcript ID"), v6, ['']) # Add the element to the sizer r5Sizer.Add(v6, 2, wx.EXPAND) self.transcript_cb.Bind(wx.EVT_CHOICE, self.OnTranscriptChoice) self.transcriptList = [] if self.obj.episode_id != '': self.PopulateTranscriptChoiceBasedOnEpisode(self.obj.series_id, self.obj.episode_id) # Add a horizontal spacer to the row sizer r5Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v7 = wx.BoxSizer(wx.VERTICAL) # Episode Time Code. Convert to HH:MM:SS.mm self.episode_start_edit = self.new_edit_box(_("Episode Position"), v7, Misc.time_in_ms_to_str(self.obj.episode_start)) # Add the element to the sizer r5Sizer.Add(v7, 1, wx.EXPAND) if self.episode_cb.GetStringSelection() == '': self.episode_start_edit.Enable(False) # Add a horizontal spacer to the row sizer r5Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v8 = wx.BoxSizer(wx.VERTICAL) # Episode Duration. Convert to HH:MM:SS.mm self.episode_duration_edit = self.new_edit_box(_("Duration"), v8, Misc.time_in_ms_to_str(self.obj.episode_duration)) # Add the element to the sizer r5Sizer.Add(v8, 1, wx.EXPAND) if self.episode_cb.GetStringSelection() == '': self.episode_duration_edit.Enable(False) # Add the row sizer to the main vertical sizer mainSizer.Add(r5Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r6Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v9 = wx.BoxSizer(wx.VERTICAL) # Comment comment_edit = self.new_edit_box(_("Comment"), v9, self.obj.comment, maxLen=255) # Add the element to the sizer r6Sizer.Add(v9, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r6Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r7Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v10 = wx.BoxSizer(wx.VERTICAL) # Keyword Group [label] txt = wx.StaticText(self.panel, -1, _("Keyword Group")) v10.Add(txt, 0, wx.BOTTOM, 3) # Keyword Group [list box] # Create an empty Keyword Group List for now. We'll populate it later (for layout reasons) self.kw_groups = [] self.kw_group_lb = wx.ListBox(self.panel, -1, choices = self.kw_groups) v10.Add(self.kw_group_lb, 1, wx.EXPAND) # Add the element to the sizer r7Sizer.Add(v10, 1, wx.EXPAND) # Create an empty Keyword List for now. We'll populate it later (for layout reasons) self.kw_list = [] wx.EVT_LISTBOX(self, self.kw_group_lb.GetId(), self.OnGroupSelect) # Add a horizontal spacer r7Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v11 = wx.BoxSizer(wx.VERTICAL) # Keyword [label] txt = wx.StaticText(self.panel, -1, _("Keyword")) v11.Add(txt, 0, wx.BOTTOM, 3) # Keyword [list box] self.kw_lb = wx.ListBox(self.panel, -1, choices = self.kw_list, style=wx.LB_EXTENDED) v11.Add(self.kw_lb, 1, wx.EXPAND) wx.EVT_LISTBOX_DCLICK(self, self.kw_lb.GetId(), self.OnAddKW) # Add the element to the sizer r7Sizer.Add(v11, 1, wx.EXPAND) # Add a horizontal spacer r7Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v12 = wx.BoxSizer(wx.VERTICAL) # Keyword transfer buttons add_kw = wx.Button(self.panel, wx.ID_FILE2, ">>", wx.DefaultPosition) v12.Add(add_kw, 0, wx.EXPAND | wx.TOP, 20) wx.EVT_BUTTON(self, wx.ID_FILE2, self.OnAddKW) rm_kw = wx.Button(self.panel, wx.ID_FILE3, "<<", wx.DefaultPosition) v12.Add(rm_kw, 0, wx.EXPAND | wx.TOP, 10) wx.EVT_BUTTON(self, wx.ID_FILE3, self.OnRemoveKW) kwm = wx.BitmapButton(self.panel, wx.ID_FILE4, TransanaImages.KWManage.GetBitmap()) v12.Add(kwm, 0, wx.EXPAND | wx.TOP, 10) # Add a spacer to increase the height of the Keywords section v12.Add((0, 60)) kwm.SetToolTipString(_("Keyword Management")) wx.EVT_BUTTON(self, wx.ID_FILE4, self.OnKWManage) # Add the element to the sizer r7Sizer.Add(v12, 0) # Add a horizontal spacer r7Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v13 = wx.BoxSizer(wx.VERTICAL) # Whole Snapshot Keywords [label] txt = wx.StaticText(self.panel, -1, _("Whole Snapshot Keywords")) v13.Add(txt, 0, wx.BOTTOM, 3) # Clip Keywords [list box] # Create an empty ListBox. We'll populate it later for layout reasons. self.ekw_lb = wx.ListBox(self.panel, -1, style=wx.LB_EXTENDED) v13.Add(self.ekw_lb, 1, wx.EXPAND) self.ekw_lb.Bind(wx.EVT_KEY_DOWN, self.OnKeywordKeyDown) # Add the element to the sizer r7Sizer.Add(v13, 2, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r7Sizer, 5, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a sizer for the buttons btnSizer = wx.BoxSizer(wx.HORIZONTAL) # Add the buttons self.create_buttons(sizer=btnSizer) # Add the button sizer to the main sizer mainSizer.Add(btnSizer, 0, wx.EXPAND) ## # Because of the way Clips are created (with Drag&Drop / Cut&Paste functions), we have to trap the missing ## # ID error here. Therefore, we need to override the EVT_BUTTON for the OK Button. ## # Since we don't have an object for the OK Button, we use FindWindowById to find it based on its ID. ## self.Bind(wx.EVT_BUTTON, self.OnOK, self.FindWindowById(wx.ID_OK)) ## # We also need to intercept the Cancel button. ## self.Bind(wx.EVT_BUTTON, self.OnCancel, self.FindWindowById(wx.ID_CANCEL)) ## ## self.Bind(wx.EVT_SIZE, self.OnSize) ## # Set the main sizer self.panel.SetSizer(mainSizer) # Tell the panel to auto-layout self.panel.SetAutoLayout(True) # Lay out the Panel self.panel.Layout() # Lay out the form self.Layout() # Resize the form to fit the contents self.Fit() # Get the new size of the form (width, height) = self.GetSizeTuple() # Reset the form's size to be at least the specified minimum width self.SetSize(wx.Size(max(minWidth, width), max(minHeight, height))) # Define the minimum size for this dialog as the current size self.SetSizeHints(max(minWidth, width), max(minHeight, height)) # Center the form on screen TransanaGlobal.CenterOnPrimary(self) # We need to set some minimum sizes so the sizers will work right self.kw_group_lb.SetSizeHints(minW = 50, minH = 20) self.kw_lb.SetSizeHints(minW = 50, minH = 20) self.ekw_lb.SetSizeHints(minW = 50, minH = 20) # We populate the Keyword Groups, Keywords, and Clip Keywords lists AFTER we determine the Form Size. # Long Keywords in the list were making the form too big! self.kw_groups = DBInterface.list_of_keyword_groups() for keywordGroup in self.kw_groups: self.kw_group_lb.Append(keywordGroup) # Populate the Keywords ListBox # Load the parent Collection in order to determine the default Keyword Group tempCollection = Collection.Collection(self.obj.collection_num) # Select the Collection Default Keyword Group in the Keyword Group list if (tempCollection.keyword_group != '') and (self.kw_group_lb.FindString(tempCollection.keyword_group) != wx.NOT_FOUND): self.kw_group_lb.SetStringSelection(tempCollection.keyword_group) # If no Default Keyword Group is defined, select the first item in the list else: # but only if there IS a first item. if len(self.kw_groups) > 0: self.kw_group_lb.SetSelection(0) # If there's a selected keyword group ... if self.kw_group_lb.GetSelection() != wx.NOT_FOUND: # populate the Keywords list self.kw_list = \ DBInterface.list_of_keywords_by_group(self.kw_group_lb.GetStringSelection()) else: # If not, create a blank one self.kw_list = [] for keyword in self.kw_list: self.kw_lb.Append(keyword) # Populate the Snapshot Keywords ListBox # If the snapshot object has keywords ... for snapshotKeyword in self.obj.keyword_list: # ... add them to the keyword list self.ekw_lb.Append(snapshotKeyword.keywordPair) # Set initial focus to the Clip ID self.id_edit.SetFocus()
def __init__(self): """ Create and display the About Dialog Box """ # Define the initial size if '__WXMAC__' in wx.PlatformInfo: width = 400 else: width = 370 height = 425 # Create the form's main VERTICAL sizer mainSizer = wx.BoxSizer(wx.VERTICAL) # Create a Dialog Box wx.Dialog.__init__(self, None, -1, _("About Transana"), size=(width, height), style=wx.CAPTION | wx.WANTS_CHARS) # OS X requires the Small Window Variant to look right if "__WXMAC__" in wx.PlatformInfo: self.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) # Create a label for the Program Title title = wx.StaticText(self, -1, _("Transana"), style=wx.ALIGN_CENTRE) # Specify 16pt Bold font font = wx.Font(16, wx.SWISS, wx.NORMAL, wx.BOLD) # Apply this font to the Title title.SetFont(font) # Add the title to the main sizer mainSizer.Add( title, 0, wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM | wx.LEFT | wx.RIGHT, 12) # Create a label for the Program Version # Build the Version label if TransanaConstants.singleUserVersion: if TransanaConstants.labVersion: versionLbl = _("Computer Lab Version") elif TransanaConstants.demoVersion: versionLbl = _("Demonstration Version") elif TransanaConstants.workshopVersion: versionLbl = _("Workshop Version") else: if TransanaConstants.proVersion: versionLbl = _("Professional Version") else: versionLbl = _("Basic Version") else: versionLbl = _("Multi-user Version") versionLbl += " %s" version = wx.StaticText(self, -1, versionLbl % TransanaConstants.versionNumber, style=wx.ALIGN_CENTRE) # Specify 10pt Bold font font = wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD) # Apply the font to the Version Label version.SetFont(font) # Add the version to the main sizer mainSizer.Add(version, 0, wx.ALIGN_CENTER | wx.BOTTOM | wx.LEFT | wx.RIGHT, 12) # Create a label for the Program Copyright str = _("Copyright 2002 - 2017\nSpurgeon Woods LLC") copyright = wx.StaticText(self, -1, str, style=wx.ALIGN_CENTRE) # Apply the last specified font (from Program Version) to the copyright label font = self.GetFont() copyright.SetFont(font) # Add the copyright to the main sizer mainSizer.Add(copyright, 0, wx.ALIGN_CENTER | wx.BOTTOM | wx.LEFT | wx.RIGHT, 12) # Create a label for the Program Description, including GNU License information self.description_str = _( "Transana is written by David K. Woods, Ph.D.\nOther contributors include: Chris Fassnacht, Jonathan Beavers, \nNate Case, Mark Kim, Rajas Sambhare and David Mandelin" ) self.description = wx.StaticText(self, -1, self.description_str, style=wx.ALIGN_CENTRE) # Add the description to the main sizer mainSizer.Add(self.description, 0, wx.ALIGN_CENTER | wx.BOTTOM | wx.LEFT | wx.RIGHT, 12) # Create a label for the Program Authoring Credits self.credits_str = _( "Transana is a product of Spurgeon Woods LLC.\nIt is released with no warranty \nunder the GNU General Public License (GPL). \nFor more information, see http://www.gnu.org." ) self.credits_str += ".\n" + _( "Methodology consultants: Paul Dempster, Chris Thorn,\nand Nicolas Sheon." ) self.credits = wx.StaticText(self, -1, self.credits_str, style=wx.ALIGN_CENTRE) # Add the credits to the main sizer mainSizer.Add(self.credits, 0, wx.ALIGN_CENTER | wx.BOTTOM | wx.LEFT | wx.RIGHT, 12) # Create a label for the Translation Credits if TransanaGlobal.configData.language == 'en': str = 'Documentation written by David K. Woods\nwith assistance and editing by Becky Holmes.' elif TransanaGlobal.configData.language == 'ar': str = _("Arabic translation provided by\n.") elif TransanaGlobal.configData.language == 'da': str = _( "Danish translation provided by\nChris Kjeldsen, Aalborg University." ) elif TransanaGlobal.configData.language == 'de': str = _( "German translation provided by Tobias Reu, New York University.\n." ) elif TransanaGlobal.configData.language == 'el': str = _("Greek translation provided by\n.") elif TransanaGlobal.configData.language == 'es': str = _( "Spanish translation provided by\nNate Case, UW Madison, and Paco Molinero, Barcelone, Spain" ) elif TransanaGlobal.configData.language == 'fi': str = _( "Finnish translation provided by\nMiia Collanus, University of Helsinki, Finland" ) elif TransanaGlobal.configData.language == 'fr': str = _( "French translation provided by\nDr. Margot Kaszap, Ph. D., Universite Laval, Quebec, Canada." ) elif TransanaGlobal.configData.language == 'he': str = _("Hebrew translation provided by\n.") elif TransanaGlobal.configData.language == 'it': str = _( "Italian translation provided by\nFabio Malfatti, Centro Ricerche EtnoAntropologiche www.creasiena.it\nPeri Weingrad, University of Michigan & Terenziano Speranza, Rome, Italy\nDorian Soru, Ph. D. e ICLab, www.iclab.eu, Padova, Italia" ) elif TransanaGlobal.configData.language == 'nl': str = _("Dutch translation provided by\nFleur van der Houwen.") elif TransanaGlobal.configData.language in ['nb', 'nn']: str = _( "Norwegian translations provided by\nDr. Dan Yngve Jacobsen, Department of Psychology,\nNorwegian University of Science and Technology, Trondheim" ) elif TransanaGlobal.configData.language == 'pl': str = _("Polish translation provided by\n.") elif TransanaGlobal.configData.language == 'pt': str = _("Portuguese translation provided by\n.") elif TransanaGlobal.configData.language == 'ru': str = _("Russian translation provided by\nViktor Ignatjev.") elif TransanaGlobal.configData.language == 'sv': str = _( "Swedish translation provided by\nJohan Gille, Stockholm University, Sweden" ) elif TransanaGlobal.configData.language == 'zh': str = _( "Chinese translation provided by\nZhong Hongquan, Beijin Poweron Technology Co.Ltd.,\nmaintained by Bei Zhang, University of Wisconsin." ) self.translations_str = str self.translations = wx.StaticText(self, -1, self.translations_str, style=wx.ALIGN_CENTRE) # Add the transcription credit to the main sizer mainSizer.Add(self.translations, 0, wx.ALIGN_CENTER | wx.BOTTOM | wx.LEFT | wx.RIGHT, 12) # Create a label for the FFmpeg Credits self.ffmpeg_str = _( "This software uses libraries from the FFmpeg project\nunder the LGPLv2.1 or GNU-GPL. Transana's copyright\ndoes not extend to the FFmpeg libraries or code.\nPlease see http://www.ffmpeg.com." ) self.ffmpeg = wx.StaticText(self, -1, self.ffmpeg_str, style=wx.ALIGN_CENTRE) # Add the FFmpeg Credits to the main sizer mainSizer.Add(self.ffmpeg, 0, wx.ALIGN_CENTER | wx.BOTTOM | wx.LEFT | wx.RIGHT, 12) ## if ('wxMac' in wx.PlatformInfo): # and \ ## #(('alpha' in TransanaConstants.versionNumber.lower()) or ('beta' in TransanaConstants.versionNumber.lower())): ## self.tmpInput = wx.TextCtrl(self, -1, "DELETE ME!", pos=(0, 0), size=(1, 1)) ## self.tmpInput.Bind(wx.EVT_KEY_UP, self.OnKeyUp) ## self.tmpInput.SetFocus() # Create an OK button btnOK = wx.Button(self, wx.ID_OK, _("OK")) # Add the OK button to the main sizer mainSizer.Add(btnOK, 0, wx.ALIGN_CENTER | wx.BOTTOM | wx.LEFT | wx.RIGHT, 12) # Add the Keyboard Event for the Easter Egg screen self.Bind(wx.EVT_KEY_UP, self.OnKeyUp) btnOK.Bind(wx.EVT_KEY_UP, self.OnKeyUp) # Define the form's Sizer self.SetSizer(mainSizer) # Lay out the form self.SetAutoLayout(True) self.Layout() # Fit the form to the contained controls self.Fit() # Center on screen # self.CentreOnScreen() TransanaGlobal.CenterOnPrimary(self) # Show the About Dialog Box modally val = self.ShowModal() # Destroy the Dialog Box when done with it self.Destroy() # Dialog Box Initialization returns "None" as the result (see wxPython documentation) return None
def __init__(self, parent, defaultKWGroup=None, deleteEnabled=True): """Initialize a KWManager object.""" # Remember the value for deleteEnabled self.deleteEnabled = deleteEnabled wx.Dialog.__init__(self, parent, -1, _("Keyword Management"), wx.DefaultPosition, wx.Size(550, 420), style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER) # To look right, the Mac needs the Small Window Variant. if "__WXMAC__" in wx.PlatformInfo: self.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) # Define the minimum size for this dialog as the initial size self.SetSizeHints(550, 420) # Create the form's main VERTICAL sizer mainSizer = wx.BoxSizer(wx.VERTICAL) # Keyword Group txt = wx.StaticText(self, -1, _("Keyword Group")) mainSizer.Add(txt, 0, wx.LEFT | wx.RIGHT | wx.TOP, 10) mainSizer.Add((0, 3)) # Create a HORIZONTAL sizer for the first row r1Sizer = wx.BoxSizer(wx.HORIZONTAL) self.kw_group = wx.Choice(self, 101, wx.DefaultPosition, wx.DefaultSize, []) r1Sizer.Add(self.kw_group, 5, wx.EXPAND) wx.EVT_CHOICE(self, 101, self.OnGroupSelect) r1Sizer.Add((10, 0)) # Create a new Keyword Group button new_kwg = wx.Button(self, wx.ID_FILE1, _("Create a New Keyword Group")) r1Sizer.Add(new_kwg, 3, wx.EXPAND) wx.EVT_BUTTON(self, wx.ID_FILE1, self.OnNewKWG) mainSizer.Add(r1Sizer, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 10) mainSizer.Add((0, 10)) # Keywords label+listbox txt = wx.StaticText(self, -1, _("Keywords")) mainSizer.Add(txt, 0, wx.LEFT, 10) # Create a HORIZONTAL sizer for the first row r2Sizer = wx.BoxSizer(wx.HORIZONTAL) v1 = wx.BoxSizer(wx.VERTICAL) if 'wxMac' in wx.PlatformInfo: style = wx.LB_SINGLE else: style = wx.LB_SINGLE | wx.LB_SORT self.kw_lb = wx.ListBox(self, 100, wx.DefaultPosition, wx.DefaultSize, [], style=style) v1.Add(self.kw_lb, 1, wx.EXPAND) wx.EVT_LISTBOX(self, 100, self.OnKeywordSelect) wx.EVT_LISTBOX_DCLICK(self, 100, self.OnKeywordDoubleClick) r2Sizer.Add(v1, 5, wx.EXPAND) r2Sizer.Add((10, 0)) v2 = wx.BoxSizer(wx.VERTICAL) # Add Keyword to List button add_kw = wx.Button(self, wx.ID_FILE2, _("Add Keyword to List")) v2.Add(add_kw, 0, wx.EXPAND | wx.BOTTOM, 10) wx.EVT_BUTTON(self, wx.ID_FILE2, self.OnAddKW) # Edit Keyword button self.edit_kw = wx.Button(self, -1, _("Edit Keyword")) v2.Add(self.edit_kw, 0, wx.EXPAND | wx.BOTTOM, 10) wx.EVT_BUTTON(self, self.edit_kw.GetId(), self.OnEditKW) self.edit_kw.Enable(False) # Delete Keyword from List button self.del_kw = wx.Button(self, wx.ID_FILE3, _("Delete Keyword from List")) v2.Add(self.del_kw, 0, wx.EXPAND | wx.BOTTOM, 10) wx.EVT_BUTTON(self, wx.ID_FILE3, self.OnDelKW) self.del_kw.Enable(False) # Definition box def_txt = wx.StaticText(self, -1, _("Definition")) v2.Add(def_txt, 0, wx.BOTTOM, 3) self.definition = wx.TextCtrl(self, -1, '', style=wx.TE_MULTILINE) v2.Add(self.definition, 1, wx.EXPAND | wx.BOTTOM, 10) self.definition.Enable(False) btnSizer = wx.BoxSizer(wx.HORIZONTAL) # Dialog Close button close = wx.Button(self, wx.ID_CLOSE, _("Close")) btnSizer.Add(close, 1, wx.EXPAND | wx.RIGHT, 10) close.SetDefault() wx.EVT_BUTTON(self, wx.ID_CLOSE, self.OnClose) # We don't want to use wx.ID_HELP here, as that causes the Help buttons to be replaced with little question # mark buttons on the Mac, which don't look good. ID_HELP = wx.NewId() # Dialog Help button helpBtn = wx.Button(self, ID_HELP, _("Help")) btnSizer.Add(helpBtn, 1, wx.EXPAND) wx.EVT_BUTTON(self, ID_HELP, self.OnHelp) v2.Add(btnSizer, 0, wx.EXPAND) r2Sizer.Add(v2, 3, wx.EXPAND) mainSizer.Add(r2Sizer, 1, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10) self.SetSizer(mainSizer) self.SetAutoLayout(True) self.Layout() TransanaGlobal.CenterOnPrimary(self) self.kw_groups = DBInterface.list_of_keyword_groups() for kwg in self.kw_groups: self.kw_group.Append(kwg) if len(self.kw_groups) > 0: if defaultKWGroup != None: selPos = self.kw_group.FindString(defaultKWGroup) else: selPos = 0 self.kw_group.SetSelection(selPos) self.kw_list = DBInterface.list_of_keywords_by_group( self.kw_group.GetString(selPos)) else: self.kw_list = [] for kw in self.kw_list: self.kw_lb.Append(kw) if len(self.kw_list) > 0: self.kw_lb.SetSelection(0, False) self.ShowModal()
def __init__(self,parent,id,seriesNum=0, episodeNum=0, collectionNum=0): # Remember the Library, episode or collection that triggered creation of this export self.seriesNum = seriesNum self.episodeNum = episodeNum self.collectionNum = collectionNum # Set the encoding for export. # Use UTF-8 regardless of the current encoding for consistency in the Transana XML files EXPORT_ENCODING = 'utf8' # Create a form to get the name of the file to receive the data # Define the form title title = _("Transana Selective Data Export") Dialogs.GenForm.__init__(self, parent, id, title, (550,150), style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, useSizers = True, HelpContext='Selective Data Export') # Create an invisible instance of RichTextEditCtrl. This allows us to # get away with converting fastsaved documents to RTF behind the scenes. # Then we can simply pull the RTF data out of this object and write it # to the desired file. self.invisibleSTC = RichTextEditCtrl(self) self.invisibleSTC.Show(False) # Create the form's main VERTICAL sizer mainSizer = wx.BoxSizer(wx.VERTICAL) # Create a HORIZONTAL sizer for the first row r1Sizer = wx.BoxSizer(wx.HORIZONTAL) # Export Message # If the XML filename path is not empty, we need to tell the user. prompt = _('Please create an Transana XML File for export.') exportText = wx.StaticText(self.panel, -1, prompt) # Add the export message to the dialog box r1Sizer.Add(exportText, 0) # Add the row sizer to the main vertical sizer mainSizer.Add(r1Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r2Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v1 = wx.BoxSizer(wx.VERTICAL) # Export Filename Layout self.XMLFile = self.new_edit_box(_("Transana Export XML-Filename"), lay, '') self.XMLFile.SetDropTarget(EditBoxFileDropTarget(self.XMLFile)) # Add the element sizer to the row sizer r2Sizer.Add(v1, 1, wx.EXPAND) # Add a spacer to the row sizer r2Sizer.Add((10, 0)) # Browse button browse = wx.Button(self.panel, wx.ID_FILE1, _("Browse"), wx.DefaultPosition) wx.EVT_BUTTON(self, wx.ID_FILE1, self.OnBrowse) # Add the element to the row sizer r2Sizer.Add(browse, 0, wx.ALIGN_BOTTOM) # Add the row sizer to the main vertical sizer mainSizer.Add(r2Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a sizer for the buttons btnSizer = wx.BoxSizer(wx.HORIZONTAL) # Add the buttons self.create_buttons(sizer=btnSizer) # Add the button sizer to the main sizer mainSizer.Add(btnSizer, 0, wx.EXPAND) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping mainSizer.Add((0, 2)) # Set the PANEL's main sizer self.panel.SetSizer(mainSizer) # Tell the PANEL to auto-layout self.panel.SetAutoLayout(True) # Lay out the Panel self.panel.Layout() # Lay out the panel on the form self.Layout() # Resize the form to fit the contents self.Fit() # Get the new size of the form (width, height) = self.GetSizeTuple() # Reset the form's size to be at least the specified minimum width self.SetSize(wx.Size(max(550, width), height)) # Define the minimum size for this dialog as the current size, and define height as unchangeable self.SetSizeHints(max(550, width), height, -1, height) # Center the form on screen TransanaGlobal.CenterOnPrimary(self) # Set focus to the XML file field self.XMLFile.SetFocus()
def __init__(self, parent, id, title, transcript_object): """ Create the Transcript Properties form """ self.width = 500 self.height = 260 # Make the Keyword Edit List resizable by passing wx.RESIZE_BORDER style Dialogs.GenForm.__init__(self, parent, id, title, size=(self.width, self.height), style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, useSizers=True, HelpContext='Transcript Properties') # Define the form's main object self.obj = transcript_object # Create the form's main VERTICAL sizer mainSizer = wx.BoxSizer(wx.VERTICAL) # Create a HORIZONTAL sizer for the first row r1Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v1 = wx.BoxSizer(wx.VERTICAL) # Add the Transcript ID element self.id_edit = self.new_edit_box(_("Transcript ID"), v1, self.obj.id, maxLen=100) # Add the element to the sizer r1Sizer.Add(v1, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r1Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r2Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v2 = wx.BoxSizer(wx.VERTICAL) # Add the Library ID element series_id_edit = self.new_edit_box(_("Library ID"), v2, self.obj.series_id) # Add the element to the row sizer r2Sizer.Add(v2, 1, wx.EXPAND) # Disable Library ID series_id_edit.Enable(False) # Add a horizontal spacer to the row sizer r2Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v3 = wx.BoxSizer(wx.VERTICAL) # Add the Episode ID element episode_id_edit = self.new_edit_box(_("Episode ID"), v3, self.obj.episode_id) # Add the element to the row sizer r2Sizer.Add(v3, 1, wx.EXPAND) # Disable Episode ID episode_id_edit.Enable(False) # Add the row sizer to the main vertical sizer mainSizer.Add(r2Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r3Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v4 = wx.BoxSizer(wx.VERTICAL) # Add the Transcriber element transcriber_edit = self.new_edit_box(_("Transcriber"), v4, self.obj.transcriber, maxLen=100) # Add the element to the row sizer r3Sizer.Add(v4, 3, wx.EXPAND | wx.RIGHT, 10) # Create a VERTICAL sizer for the next element v7 = wx.BoxSizer(wx.VERTICAL) # Add the Min Transcript Width element mintranscriptwidth = self.new_edit_box( _("Min. Width"), v7, str(self.obj.minTranscriptWidth)) # Add the element to the row sizer r3Sizer.Add(v7, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r3Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r4Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v5 = wx.BoxSizer(wx.VERTICAL) # Add the Comment element comment_edit = self.new_edit_box(_("Comment"), v5, self.obj.comment, maxLen=255) # Add the element to the row sizer r4Sizer.Add(v5, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r4Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r5Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v6 = wx.BoxSizer(wx.VERTICAL) # Add the Import File element self.rtfname_edit = self.new_edit_box( _("DOCX/RTF/XML/TXT File to import (optional)"), v6, '') # Make this text box a File Drop Target self.rtfname_edit.SetDropTarget( EditBoxFileDropTarget(self.rtfname_edit)) # Add the element to the row sizer r5Sizer.Add(v6, 1, wx.EXPAND) # Add a horizontal spacer to the row sizer r5Sizer.Add((10, 0)) # Add the Browse Button browse = wx.Button(self.panel, -1, _("Browse")) # Add the Browse Method to the Browse Button wx.EVT_BUTTON(self, browse.GetId(), self.OnBrowseClick) # Add the element to the sizer r5Sizer.Add(browse, 0, wx.ALIGN_BOTTOM) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping r5Sizer.Add((2, 0)) # Add the row sizer to the main vertical sizer mainSizer.Add(r5Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a sizer for the buttons btnSizer = wx.BoxSizer(wx.HORIZONTAL) # Add the buttons self.create_buttons(sizer=btnSizer) # Add the button sizer to the main sizer mainSizer.Add(btnSizer, 0, wx.EXPAND) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping mainSizer.Add((0, 2)) # Set the PANEL's main sizer self.panel.SetSizer(mainSizer) # Tell the PANEL to auto-layout self.panel.SetAutoLayout(True) # Lay out the Panel self.panel.Layout() # Lay out the panel on the form self.Layout() # Resize the form to fit the contents self.Fit() # Get the new size of the form (width, height) = self.GetSizeTuple() # Reset the form's size to be at least the specified minimum width self.SetSize(wx.Size(max(self.width, width), height)) # Define the minimum size for this dialog as the current size, and define height as unchangeable self.SetSizeHints(max(self.width, width), height, -1, height) # Center the form on screen TransanaGlobal.CenterOnPrimary(self) # This is bad. Sorry. # Create a hidden RichTextEditCtrl to use for importing data self.hiddenRTC = RichTextEditCtrl_RTC.RichTextEditCtrl(self) # This control should NOT be visible self.hiddenRTC.Show(False) # Set focus to the Transcript ID self.id_edit.SetFocus()
def __init__(self, parent, title, copyFrom, copyTo): """ Set up the Dialog Box and all GUI Widgets. """ if (os.path.exists(copyFrom)): # Set up local variables self.parent = parent # Initialize Threaded File Copy object and the timer that updates the progress dialog self.threadedFileCopy = None self.timer = None size = (350, 200) # Create the Dialog Box itself, with no minimize/maximize/close buttons wx.Dialog.__init__(self, parent, -1, title, size=size, style=wx.CAPTION) # Create a main VERTICAL sizer for the form mainSizer = wx.BoxSizer(wx.VERTICAL) # File label if 'unicode' in wx.PlatformInfo: # Encode with UTF-8 rather than TransanaGlobal.encoding because this is a prompt, not DB Data. prompt = unicode(_("File: %s"), 'utf8') else: prompt = _("File: %s") # extract the file name... (dir, fileName) = os.path.split(copyFrom) self.destFileStr = os.path.join(copyTo, fileName) self.lblFile = wx.StaticText(self, -1, prompt % fileName, style=wx.ST_NO_AUTORESIZE) # Add the label to the Main Sizer mainSizer.Add(self.lblFile, 0, wx.ALL, 10) # Progress Bar self.progressBar = wx.Gauge(self, -1, 100, style=wx.GA_HORIZONTAL | wx.GA_SMOOTH) # Add the element to the Main Sizer mainSizer.Add(self.progressBar, 1, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10) # Create a Row Sizer r1Sizer = wx.BoxSizer(wx.HORIZONTAL) # Bytes Transferred label if 'unicode' in wx.PlatformInfo: # Encode with UTF-8 rather than TransanaGlobal.encoding because this is a prompt, not DB Data. prompt = unicode(_("%d bytes of %d transferred"), 'utf8') else: prompt = _("%d bytes of %d transferred") self.lblBytes = wx.StaticText(self, -1, prompt % (100000000, 100000000), style=wx.ST_NO_AUTORESIZE) # Add the label to the Row Sizer r1Sizer.Add(self.lblBytes, 5, wx.EXPAND) # Percent Transferred label self.lblPercent = wx.StaticText(self, -1, "%5.1d %%" % 1000.1, style=wx.ST_NO_AUTORESIZE | wx.ALIGN_RIGHT) # Add the Element to the Row Sizer r1Sizer.Add(self.lblPercent, 1, wx.ALIGN_RIGHT) # Add the Row Sizer to the Main Sizer mainSizer.Add(r1Sizer, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10) # Create a Row Sizer r2Sizer = wx.BoxSizer(wx.HORIZONTAL) # Elapsed Time label if 'unicode' in wx.PlatformInfo: # Encode with UTF-8 rather than TransanaGlobal.encoding because this is a prompt, not DB Data. prompt = unicode(_("Elapsed Time: %d:%02d:%02d"), 'utf8') else: prompt = _("Elapsed Time: %d:%02d:%02d") self.lblElapsedTime = wx.StaticText(self, -1, prompt % (0, 0, 0), style=wx.ST_NO_AUTORESIZE) # Add the element to the Row Sizer r2Sizer.Add(self.lblElapsedTime, 0) # Add a spacer r2Sizer.Add((1, 0), 1, wx.EXPAND) # Remaining Time label if 'unicode' in wx.PlatformInfo: # Encode with UTF-8 rather than TransanaGlobal.encoding because this is a prompt, not DB Data. prompt = unicode(_("Time Remaining: %d:%02d:%02d"), 'utf8') else: prompt = _("Time Remaining: %d:%02d:%02d") self.lblTimeRemaining = wx.StaticText(self, -1, prompt % (0, 0, 0), style=wx.ST_NO_AUTORESIZE | wx.ALIGN_RIGHT) # Add the element to the Row Sizer r2Sizer.Add(self.lblTimeRemaining, 0) # Add the Row Sizer to the Main Sizer mainSizer.Add(r2Sizer, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10) # Transfer Speed label if 'unicode' in wx.PlatformInfo: # Encode with UTF-8 rather than TransanaGlobal.encoding because this is a prompt, not DB Data. prompt = unicode(_("Transfer Speed: %d k/sec"), 'utf8') else: prompt = _("Transfer Speed: %d k/sec") self.lblTransferSpeed = wx.StaticText(self, -1, prompt % 0, style=wx.ST_NO_AUTORESIZE) # Add the element to the Main Sizer mainSizer.Add(self.lblTransferSpeed, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10) # Cancel Button self.btnCancel = wx.Button(self, wx.ID_CANCEL, _("Cancel Remaining Files")) # Add the element to the Main Sizer mainSizer.Add(self.btnCancel, 0, wx.ALIGN_CENTER | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10) wx.EVT_BUTTON(self, wx.ID_CANCEL, self.OnCancel) # Attach the main sizer to the form self.SetSizer(mainSizer) # Turn Auto Layout on self.SetAutoLayout(True) # Lay out the form self.Layout() # Center on the Screen TransanaGlobal.CenterOnPrimary(self) # Initialize variables used in file transfer BytesRead = 0 # "cancelled" is intialized to false. If the user cancels the file transfer, # this variable gets set to true to signal the need to interrupt the transfer. self.cancelled = False # Note the starting time of the transfer for progress reporting purposes self.StartTime = time.time() self.Bind(wx.EVT_TIMER, self.UpdateDisplay) EVT_THREAD_COMPLETE(self, self.OnFileCopyComplete) # Create a timer used to update the Progress Dialog self.timer = wx.Timer(self) # Start the timer, firing it every half second self.timer.Start(500) self.size1 = os.stat(copyFrom)[6] self.threadedFileCopy = ThreadedFileCopy(self, copyFrom, copyTo) # Show the form self.ShowModal()
def __init__(self, parent, id, title): wx.SetDefaultPyEncoding("utf8") self.presLan_en = gettext.translation("Transana", "locale", languages=["en"]) self.presLan_en.install() lang = wx.LANGUAGE_ENGLISH self.locale = wx.Locale(lang) self.locale.AddCatalog("Transana") # Define the Configuration Data TransanaGlobal.configData = ConfigData.ConfigData() # Create the global transana graphics colors, once the ConfigData object exists. TransanaGlobal.transana_graphicsColorList = TransanaGlobal.getColorDefs( TransanaGlobal.configData.colorConfigFilename ) # Set essential global color manipulation data structures once the ConfigData object exists. ( TransanaGlobal.transana_colorNameList, TransanaGlobal.transana_colorLookup, TransanaGlobal.keywordMapColourSet, ) = TransanaGlobal.SetColorVariables() TransanaGlobal.configData.videoPath = "C:\\Users\\DavidWoods\\Videos" TransanaGlobal.menuWindow = MenuWindow.MenuWindow(None, -1, title) self.ControlObject = ControlObjectClass.ControlObject() self.ControlObject.Register(Menu=TransanaGlobal.menuWindow) TransanaGlobal.menuWindow.Register(ControlObject=self.ControlObject) wx.Frame.__init__( self, parent, -1, title, size=(800, 600), style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE ) self.testsRun = 0 self.testsSuccessful = 0 self.testsFailed = 0 mainSizer = wx.BoxSizer(wx.VERTICAL) self.txtCtrl = wx.TextCtrl(self, -1, "Unit Test: SSL\n\n", style=wx.TE_LEFT | wx.TE_MULTILINE) self.txtCtrl.AppendText( "Transana Version: %s\nsingleUserVersion: %s\n" % (TransanaConstants.versionNumber, TransanaConstants.singleUserVersion) ) mainSizer.Add(self.txtCtrl, 1, wx.EXPAND | wx.ALL, 5) self.SetSizer(mainSizer) self.SetAutoLayout(True) self.Layout() self.CenterOnScreen() # Status Bar self.CreateStatusBar() self.SetStatusText("") self.Show(True) try: self.RunTests() except: print print print sys.exc_info()[0] print sys.exc_info()[1] traceback.print_exc(file=sys.stdout) if TransanaConstants.DBInstalled in ["MySQLdb-embedded"]: DBInterface.EndSingleUserDatabase() TransanaGlobal.menuWindow.Destroy()