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 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 __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 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, 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 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 plot(self, title, data, dataLabels): """ 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 limits the BarChart to 15 bars max. """ # Clear the Figure (in case we use the same BarChartGraphic to create multiple BarCharts) self.figure.clf() # The length of data is the number of bars we need numBars = len(data) # 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' ] # colors = [(1, 0, 0), (0, 1, 0), (0, 0, 1), (0.5, 0.5, 0), (1, 0, 1), (0, 1, 1)] # There are no 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. for colorName, colorDef in colorList: # MatPlotLib uses a 0 .. 1 scale rather than a 0 .. 255 scale for RGB colors! colors.append((colorDef[0] / 255.0, colorDef[1] / 255.0, colorDef[2] / 255.0)) # Get the color definitions for all keywords in Transana colorsForKeywords = DBInterface.dict_of_keyword_colors() # If we have more data points that will fit, we should truncate the number of bars maxBars = 30 if numBars > maxBars: # Reduce data to the first 15 points data = data[:maxBars] # Reduce the data labels to the first 15 labels dataLabels = dataLabels[:maxBars] # Reduce the number of bars to be displayed to maxBars numBars = maxBars # X values for the bars are simple integers for bar number xValues = range(numBars) # Set the bar width to allow space between bars width = .85 # Create a MatPlotLib SubPlot ax = self.figure.add_subplot(111) # Define the BarChart Bars in the figure rects1 = ax.bar(xValues, data, width) # Add the Chart Title ax.set_title(title) # If we're running stand-alone ... if __name__ == '__main__': # Add the Y axis label ax.set_ylabel('Frequency') else: # Add the Y axis label ax.set_ylabel(_('Frequency')) # Set X axis tick marks for each bar ax.set_xticks(xValues) # Add the bar labels lbls = ax.set_xticklabels(dataLabels, rotation=90) # 35 65 # Initialize the color list position indicator colorIndx = 0 # For each bar ... for x in range(numBars): # 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 # ... define the bar color rects1[x].set_color(color) # ... make the label color match the bar color lbls[x].set_color(color) # Give the graph small inside margins plt.margins(0.05) # Adjust the bottom margin to make room for bar labels plt.subplots_adjust(bottom=0.5) # 0.2 0.4 # Draw the BarChart self.canvas.draw() # Copy the BarChart to the Clipboard self.canvas.Copy_to_Clipboard()
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()