def flush_events(self): # docstring inherited wx.Yield()
def syncProject(parent, project=None, closeFrameWhenDone=False): """A function to sync the current project (if there is one) Returns ----------- 1 for success 0 for fail -1 for cancel at some point in the process """ if not pavlovia.haveGit: noGitWarning(parent) return 0 isCoder = hasattr(parent, 'currentDoc') if not project and "BuilderFrame" in repr(parent): # try getting one from the frame project = parent.project # type: pavlovia.PavloviaProject if not project: # ask the user to create one # if we're going to create a project we need user to be logged in pavSession = pavlovia.getCurrentSession() try: username = pavSession.user.username except: username = logInPavlovia(parent) if not username: return -1 # never logged in # create project dialog msg = _translate("This file doesn't belong to any existing project.") style = wx.OK | wx.CANCEL | wx.CENTER dlg = wx.MessageDialog(parent=parent, message=msg, style=style) dlg.SetOKLabel(_translate("Create a project")) if dlg.ShowModal() == wx.ID_OK: if isCoder: if parent.currentDoc: localRoot = os.path.dirname(parent.currentDoc.filename) else: localRoot = '' else: localRoot = os.path.dirname(parent.filename) # open the project editor (with no project to create one) editor = ProjectEditor(parent=parent, localRoot=localRoot) if editor.ShowModal() == wx.ID_OK: project = editor.project else: project = None else: return -1 # user pressed cancel if not project: # we did our best for them. Give up! return 0 # if project.localRoot doesn't exist, or is empty if 'localRoot' not in project or not project.localRoot: # we first need to choose a location for the repository setLocalPath(parent, project) parent.Raise() # make sure that frame is still visible #check that the project does exist remotely if not project.pavlovia: # project didn't exist at Pavlovia (deleted?) recreatorDlg = ProjectRecreator(parent=parent, project=project) ok = recreatorDlg.ShowModal() if ok > 0: project = recreatorDlg.project else: logging.error("Failed to recreate project to sync with") return # a sync will be necessary so can create syncFrame syncFrame = sync.SyncFrame(parent=parent, id=wx.ID_ANY, project=project) if project._newRemote: # new remote so this will be a first push if project.getRepo(forceRefresh=True) is None: # no local repo yet so create one project.newRepo(syncFrame) # add the local files and commit them ok = showCommitDialog(parent=parent, project=project, initMsg="First commit", infoStream=syncFrame.syncPanel.infoStream) if ok == -1: # cancelled syncFrame.Destroy() return -1 syncFrame.syncPanel.setStatus("Pushing files to Pavlovia") wx.Yield() time.sleep(0.001) # git push -u origin master try: project.firstPush(infoStream=syncFrame.syncPanel.infoStream) project._newRemote = False except Exception as e: closeFrameWhenDone = False syncFrame.syncPanel.statusAppend(traceback.format_exc()) else: # existing remote which we should sync (or clone) try: ok = project.getRepo(syncFrame.syncPanel.infoStream) if not ok: closeFrameWhenDone = False except Exception as e: closeFrameWhenDone = False syncFrame.syncPanel.statusAppend(traceback.format_exc()) # check for anything to commit before pull/push outcome = showCommitDialog(parent, project, infoStream=syncFrame.syncPanel.infoStream) # 0=nothing to do, 1=OK, -1=cancelled if outcome == -1: # user cancelled syncFrame.Destroy() return -1 try: status = project.sync(syncFrame.syncPanel.infoStream) if status == -1: syncFrame.syncPanel.statusAppend("Couldn't sync") except Exception: # not yet sure what errors might occur # send the closeFrameWhenDone = False syncFrame.syncPanel.statusAppend(traceback.format_exc()) wx.Yield() project._lastKnownSync = time.time() if closeFrameWhenDone: syncFrame.Destroy() return 1
def setStatus(self, status): self.statusMsg.SetValue(status) self.Refresh() self.Layout() wx.Yield()
def onInit(self, showSplash=True, testMode=False): """This is launched immediately *after* the app initialises with wx :Parameters: testMode: bool """ self.SetAppName('PsychoPy3') if False: # show splash screen splashFile = os.path.join(self.prefs.paths['resources'], 'psychopySplash.png') splashImage = wx.Image(name=splashFile) splashImage.ConvertAlphaToMask() splash = AS.AdvancedSplash( None, bitmap=splashImage.ConvertToBitmap(), timeout=3000, agwStyle=AS.AS_TIMEOUT | AS.AS_CENTER_ON_SCREEN, ) # transparency? w, h = splashImage.GetSize() splash.SetTextPosition((int(w - 130), h - 20)) splash.SetText(_translate("Loading libraries...")) wx.Yield() else: splash = None # SLOW IMPORTS - these need to be imported after splash screen starts # but then that they end up being local so keep track in self if splash: splash.SetText(_translate("Loading PsychoPy3...")) wx.Yield() from psychopy.compatibility import checkCompatibility # import coder and builder here but only use them later from psychopy.app import coder, builder, dialogs if '--firstrun' in sys.argv: del sys.argv[sys.argv.index('--firstrun')] self.firstRun = True if 'lastVersion' not in self.prefs.appData: # must be before 1.74.00 last = self.prefs.appData['lastVersion'] = '1.73.04' self.firstRun = True else: last = self.prefs.appData['lastVersion'] if self.firstRun and not self.testMode: pass # setup links for URLs # on a mac, don't exit when the last frame is deleted, just show menu if sys.platform == 'darwin': self.menuFrame = MenuFrame(parent=None, app=self) # get preferred view(s) from prefs and previous view if self.prefs.app['defaultView'] == 'last': mainFrame = self.prefs.appData['lastFrame'] else: # configobjValidate should take care of this situation allowed = ['last', 'coder', 'builder', 'both'] if self.prefs.app['defaultView'] in allowed: mainFrame = self.prefs.app['defaultView'] else: self.prefs.app['defaultView'] = 'both' mainFrame = 'both' # fetch prev files if that's the preference if self.prefs.coder['reloadPrevFiles']: scripts = self.prefs.appData['coder']['prevFiles'] else: scripts = [] appKeys = list(self.prefs.appData['builder'].keys()) if self.prefs.builder['reloadPrevExp'] and ('prevFiles' in appKeys): exps = self.prefs.appData['builder']['prevFiles'] else: exps = [] # then override the prev files by command options and passed files if len(sys.argv) > 1: if sys.argv[1] == __name__: # program was executed as "python.exe psychopyApp.py %1' args = sys.argv[2:] else: # program was executed as "psychopyApp.py %1' args = sys.argv[1:] # choose which frame to start with if args[0] in ['builder', '--builder', '-b']: mainFrame = 'builder' args = args[1:] # can remove that argument elif args[0] in ['coder', '--coder', '-c']: mainFrame = 'coder' args = args[1:] # can remove that argument # did we get .py or .psyexp files? elif args[0][-7:] == '.psyexp': mainFrame = 'builder' exps = [args[0]] elif args[0][-3:] == '.py': mainFrame = 'coder' scripts = [args[0]] else: args = [] self.dpi = int(wx.GetDisplaySize()[0] / float(wx.GetDisplaySizeMM()[0]) * 25.4) if not (50 < self.dpi < 120): self.dpi = 80 # dpi was unreasonable, make one up if sys.platform == 'win32': # wx.SYS_DEFAULT_GUI_FONT is default GUI font in Win32 self._mainFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) else: self._mainFont = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT) try: self._codeFont = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT) except wx._core.wxAssertionError: # if no SYS_ANSI_FIXED_FONT then try generic FONTFAMILY_MODERN self._codeFont = wx.Font(self._mainFont.GetPointSize(), wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) self._codeFont.SetFaceName(self.prefs.coder['codeFont']) # removed Aug 2017: on newer versions of wx (at least on mac) # this looks too big # if hasattr(self._mainFont, 'Larger'): # # Font.Larger is available since wyPython version 2.9.1 # # PsychoPy still supports 2.8 (see ensureMinimal above) # self._mainFont = self._mainFont.Larger() # self._codeFont.SetPointSize( # self._mainFont.GetPointSize()) # unify font size # create both frame for coder/builder as necess if splash: splash.SetText(_translate(" Creating frames...")) if mainFrame in ['both', 'coder']: self.showCoder(fileList=scripts) if mainFrame in ['both', 'builder']: self.showBuilder(fileList=exps) # send anonymous info to www.psychopy.org/usage.php # please don't disable this, it's important for PsychoPy's development self._latestAvailableVersion = None self.updater = None self.news = None self.tasks = None prefsConn = self.prefs.connections ok, msg = checkCompatibility(last, self.version, self.prefs, fix=True) # tell the user what has changed if not ok and not self.firstRun and not self.testMode: title = _translate("Compatibility information") dlg = dialogs.MessageDialog(parent=None, message=msg, type='Info', title=title) dlg.ShowModal() if (self.prefs.app['showStartupTips'] and not self.testMode and not blockTips): tipFile = os.path.join(self.prefs.paths['resources'], _translate("tips.txt")) tipIndex = self.prefs.appData['tipIndex'] if parse_version(wx.__version__) >= parse_version('4.0.0a1'): tp = wx.adv.CreateFileTipProvider(tipFile, tipIndex) showTip = wx.adv.ShowTip(None, tp) else: tp = wx.CreateFileTipProvider(tipFile, tipIndex) showTip = wx.ShowTip(None, tp) self.prefs.appData['tipIndex'] = tp.GetCurrentTip() self.prefs.saveAppData() self.prefs.app['showStartupTips'] = showTip self.prefs.saveUserPrefs() self.Bind(wx.EVT_IDLE, self.onIdle) # doing this once subsequently enables the app to open & switch among # wx-windows on some platforms (Mac 10.9.4) with wx-3.0: v = parse_version if sys.platform == 'darwin': if v('3.0') <= v(wx.version()) < v('4.0'): _Showgui_Hack() # returns ~immediately, no display # focus stays in never-land, so bring back to the app: if mainFrame in ['both', 'builder']: self.showBuilder() else: self.showCoder() # after all windows are created (so errors flushed) create output self._appLoaded = True if self.coder: self.coder.setOutputWindow() # takes control of sys.stdout return True
def OnNew(self, event): """New grid event handler""" # If changes have taken place save of old grid if self.main_window.changed_since_save: save_choice = self.interfaces.get_save_request_from_user() if save_choice is None: # Cancelled close operation return elif save_choice: # User wants to save content post_command_event(self.main_window, self.main_window.SaveMsg) # Get grid dimensions shape = self.interfaces.get_dimensions_from_user(no_dim=3) if shape is None: return # Set new filepath and post it to the title bar self.main_window.filepath = None post_command_event(self.main_window, self.main_window.TitleMsg, text="pyspread") # Clear globals self.main_window.grid.actions.clear_globals_reload_modules() # Create new grid post_command_event(self.main_window, self.main_window.GridActionNewMsg, shape=shape) # Update TableChoiceIntCtrl post_command_event(self.main_window, self.main_window.ResizeGridMsg, shape=shape) if is_gtk(): wx.Yield() self.main_window.grid.actions.change_grid_shape(shape) self.main_window.grid.GetTable().ResetView() self.main_window.grid.ForceRefresh() # Display grid creation in status bar msg = _("New grid with dimensions {dim} created.").format(dim=shape) post_command_event(self.main_window, self.main_window.StatusBarMsg, text=msg) self.main_window.grid.ForceRefresh() if is_gtk(): wx.Yield() # Mark content as unchanged try: post_command_event(self.main_window, self.ContentChangedMsg, changed=False) except TypeError: # The main window does not exist any more pass
def parseBlueTermFile(self, infoDict): """ a BlueTerm log file can contain captured data from a series of daily GL text files, possibly even from different loggers """ dataRecItemCt = 0 dataRecsAdded = 0 dataRecsDupSkipped = 0 self.putTextLinesIntoTmpTable(infoDict) # find the different data dump segments # within each one, data will be from only one logger, and so we # can use the same metadata header # make a list of 2-tuples; tuple item 0 = the starting ID of the # dump segment and tuple item 1 = the ending ID lDmpSegs = [] stSQL = """SELECT ID, Line FROM tmpLines WHERE Line = '{"datadump":"begin"}' OR Line = '{"datadump":"end"}' ORDER BY ID;""" dmSegs = scidb.curT.execute(stSQL).fetchall() # begin or end may be missing, due to log interruption idSegStart = None idSegEnd = None # only use segments that have valid begin/end for dmSegItm in dmSegs: if dmSegItm['Line'] == '{"datadump":"begin"}': idSegStart = dmSegItm['ID'] elif dmSegItm['Line'] == '{"datadump":"end"}': if idSegStart != None: # make the tuple tSeg = (idSegStart, dmSegItm['ID']) # append to list lDmpSegs.append(tSeg) # null the vars idSegStart = None idSegEnd = None else: # this should not happen, but tie up if it does idSegStart = None idSegEnd = None print "dump segments:", lDmpSegs # being worked on >>>> iNumSegs = len(lDmpSegs) if iNumSegs == 0: infoDict['stParseMsg'] = " No valid data segments in file." # will skip following loop iCtSeg = 0 for tSeg in lDmpSegs: iCtSeg += 1 idSegStart, idSegEnd = tSeg # get the metadata header; if multiple will all be the same for one dump segment stSQL = """SELECT Line FROM tmpLines WHERE ID > ? AND ID < ? AND Line LIKE '{"Instrument identifier":%' GROUP BY Line;""" mtDat = scidb.curT.execute(stSQL, tSeg).fetchone() dictHd = ast.literal_eval(mtDat['Line']) # somewhat redundant to do 'LoggerSerialNumber' here (fn 'assureChannelIsInDB' would fill in # later), but allows putting Model into the DB iInstSpecID = scidb.assureItemIsInTableField( dictHd['Model'], "InstrumentSpecs", "InstrumentSpec") iLoggerID = scidb.assureItemIsInTableField( dictHd['Instrument identifier'], "Loggers", "LoggerSerialNumber") scidb.curD.execute( "UPDATE Loggers SET InstrumentSpecID = ? WHERE ID = ?;", (iInstSpecID, iLoggerID)) # get the hour offset(s); most files will have only one stSQL = "SELECT substr(Line, 21, 3) as TZ FROM tmpLines " \ "WHERE ID > ? AND ID < ? " \ "AND Line LIKE '____-__-__ __:__:__ ___%' GROUP BY TZ;" hrOffsets = scidb.curT.execute(stSQL, tSeg).fetchall() for hrOffset in hrOffsets: iTimeZoneOffset = int(hrOffset['TZ']) # make a dictionary of channel IDs for data lines that have this hour offset # would be slightly different for different hour offsets lCols = dictHd[ 'Columns'] # get col metadata; this is a list of dictionaries # # it is indexed by the columns list, and is zero-based # lCh = [0 for i in range(len(lCols))] # initially, fill with all zeroes dictChannels = {} # this is the dictionary we will build for dictCol in lCols: # somewhat redundant to fill these in before calling function 'assureChannelIsInDB', but # allows assigning sensor device types iDeviceTypeID = scidb.assureItemIsInTableField( dictCol['Device'], "DeviceSpecs", "DeviceSpec") iSensorID = scidb.assureItemIsInTableField( dictCol['Identifier'], "Sensors", "SensorSerialNumber") scidb.curD.execute( "UPDATE Sensors SET DeviceSpecID = ? WHERE ID = ?;", (iDeviceTypeID, iSensorID)) # iDataTypeID = scidb.assureItemIsInTableField(dictCol['DataType'], "DataTypes", "TypeText") # iDataUnitsID = scidb.assureItemIsInTableField(dictCol['DataUnits'], "DataUnits", "UnitsText") # build list to create the channel # list items are: ChannelID, originalCol, Logger, Sensor, dataType, dataUnits, hrOffset, new lChannel = [ 0, dictCol['Order'], dictHd['Instrument identifier'], dictCol['Identifier'], dictCol['DataType'], dictCol['DataUnits'], iTimeZoneOffset, '' ] dictChannels[dictCol['Order']] = ( lChannel[:]) # the key is the column number scidb.assureChannelIsInDB(dictChannels[ dictCol['Order']]) # get or create the channel iChannelID = dictChannels[dictCol['Order']][0] # store the column name as a Series iSeriesID = scidb.assureItemIsInTableField( dictCol['Name'], "DataSeries", "DataSeriesDescription") # tie it to this Channel, to offer later stSQLcs = 'INSERT INTO tmpChanSegSeries(ChannelID, SeriesID) VALUES (?, ?);' try: scidb.curD.execute(stSQLcs, (iChannelID, iSeriesID)) except sqlite3.IntegrityError: pass # silently ignore duplicates # print 'Before Channel function' # for ky in dictChannels.keys(): # print ky, dictChannels[ky][:] # for ky in dictChannels.keys(): # scidb.assureChannelIsInDB(dictChannels[ky]) # print 'After Channel function' # for ky in dictChannels.keys(): # print ky, dictChannels[ky][:] # make a list of channel IDs for the set of lines with this HrOffset, for quick lookup # it is indexed by the columns list, and is zero-based lCh = [] for iCol in range(len(lCols)): iNomCol = iCol + 1 if iNomCol in dictChannels: lChanSet = dictChannels[iNomCol][:] lCh.append(lChanSet[0]) else: # does not correspond to a data colum lCh.append( 0) # placeholder, to make list indexes work right # done setting up channels, get data lines stSQL = "SELECT ID, Line FROM tmpLines " \ "WHERE ID > ? AND ID < ? " \ "AND substr(Line, 21, 3) = ? " \ "AND Line LIKE '____-__-__ __:__:__ ___%' ORDER BY ID;" recs = scidb.curT.execute(stSQL, ( idSegStart, idSegEnd, hrOffset['TZ'], )).fetchall() iNumSegLines = len(recs) iCtSegLines = 0 for rec in recs: iCtSegLines += 1 lData = rec['Line'].split('\t') # item zero is the timestamp followed by the timezone offset sTimeStamp = lData[ 0][:-4] # drop timezone offset, we already have it tsAsTime = datetime.datetime.strptime( sTimeStamp, "%Y-%m-%d %H:%M:%S") tsAsTime.replace( tzinfo=None ) # make sure it does not get local timezone info tsAsTime = tsAsTime + datetime.timedelta( hours=-iTimeZoneOffset) tsAsDate = tsAsTime.date() stSQL = "INSERT INTO Data (UTTimestamp, ChannelID, Value) VALUES (?, ?, ?)" for iCol in range(len(lData)): if iCol > 0: # an item of data # give some progress diagnostics dataRecItemCt += 1 if dataRecItemCt % 100 == 0: self.msgArea.ChangeValue( "Segment " + str(iCtSeg) + " of " + str(iNumSegs) + ", HrOffset " + str(iTimeZoneOffset) + ", Line " + str(iCtSegLines) + " of " + str(iNumSegLines) + "; " + str(dataRecsAdded) + " records added, " + str(dataRecsDupSkipped) + " duplicates skipped.") wx.Yield() try: # much faster to try and fail than to test first scidb.curD.execute( stSQL, (tsAsTime, lCh[iCol], lData[iCol])) dataRecsAdded += 1 # count it except sqlite3.IntegrityError: # item is already in Data table dataRecsDupSkipped += 1 # count but otherwise ignore finally: wx.Yield() # <<<<< being worked on # finished parsing lines infoDict['numNewDataRecsAdded'] = dataRecsAdded infoDict['numDupDataRecsSkipped'] = dataRecsDupSkipped infoDict['stParseMsg'] = str(infoDict['lineCt']) + " lines processed; " + \ str(dataRecsAdded) + " data records added to database, " + \ str(dataRecsDupSkipped) + " duplicates skipped." self.msgArea.ChangeValue(infoDict['stParseMsg'])
def parseHoboWareTextFile(self, infoDict): """ parse a data file exported as text by HoboWare """ sStrip = '" \x0a\x0d' # characters to strip from parsed items # regular expression pattern to find logger number pLogger = re.compile(r'LGR S/N: (?P<nLogger>\d+)') # regular expression pattern to find sensor number pSensor = re.compile(r'SEN S/N: (?P<nSensor>\d+)') # regular expression pattern to find hour offset pHrOffset = re.compile(r'Time, GMT(?P<sHrOffset>.+)') dataRecItemCt = 0 dataRecsAdded = 0 dataRecsDupSkipped = 0 print "About to put lines into temp table" self.putTextLinesIntoTmpTable(infoDict) print "Finished putting lines into temp table" #parse file, start with header line; 1st line in this file format scidb.curT.execute("SELECT * FROM tmpLines ORDER BY ID;") for rec in scidb.curT: if rec['ID'] == 1: """ Build a dictionary of the channels. The indexes will be the column numbers because all data files have at least that. The value will be a 7-membered list The first item in each list will be the primary key in the Channels table. The list is first created with this = 0. The rest of the list is built up, then the list is sent to a function that looks in the database. The function fills in the primary key, either existing or newly created. List item 7 will be "new" if the record is new, otherwise "existing" The list contains the text values of logger serial number, sensor serial number, data type, and data units. The function takes care of filling in all these in their respective tables. When the dictionary is complete, the calling procedure can quickly insert data values into the data table by just pulling list item [0] for the dictionary key, which key is the column number in the source file. This loose structure allows some kludgy workarounds for bugs that were in some versions of the data files. """ lHdrs = rec['Line'].split('\t') # ignore item zero, just a pound sign and possibly three junk characters # item 1 is the hour offset, and clue to export bugs we need to workaround sHd = lHdrs[1].strip(sStrip) m = pHrOffset.search(sHd) if m: sTimeOffset = m.group('sHrOffset') lTimeOffsetComponents = sTimeOffset.split(':') sTimeOffsetHrs = lTimeOffsetComponents[0] iHrOffset = int(sTimeOffsetHrs) else: iHrOffset = 0 dictChannels = {} # list items are: ChannelID, originalCol, Logger, Sensor, dataType, dataUnits, hrOffset, new lChannel = [0, 0, '', '', '', '', iHrOffset, ''] for iCol in range(len(lHdrs)): # skip items 0 & 1 if iCol > 1: # a header for a data column lChannel[1] = iCol + 1 # stored columns are 1-based sHd = lHdrs[iCol].strip(sStrip) # get the type and units lTypeUnits = sHd.split('(', 2) sTypeUnits = lTypeUnits[0].strip(' ') lTypeUnits = sTypeUnits.split(',') ## TNP_MOD print("TNP debug1") print(lTypeUnits) ## If units specified, make units 'NA' if (len(lTypeUnits) == 1): lTypeUnits.append('NA') if lTypeUnits[0]: sType = lTypeUnits[0].strip(' ') else: sType = '(na)' lChannel[4] = sType if lTypeUnits[1]: sUnits = lTypeUnits[1].strip(' ') else: sUnits = '(na)' lChannel[5] = sUnits # get the logger ID and sensor ID m = pLogger.search(sHd) if m: sLoggerID = m.group('nLogger') else: sLoggerID = '(na)' lChannel[2] = sLoggerID m = pSensor.search(sHd) if m: sSensorID = m.group('nSensor') else: sSensorID = "(na)" lChannel[3] = sSensorID dictChannels[iCol + 1] = (lChannel[:]) # gone through all the headers, apply bug workarounds here print 'Before Channel function' for ky in dictChannels.keys(): print ky, dictChannels[ky][:] for ky in dictChannels.keys(): scidb.assureChannelIsInDB(dictChannels[ky]) print 'After Channel function' for ky in dictChannels.keys(): print ky, dictChannels[ky][:] # make a list of channel IDs for the rest of this file, for quick lookup # it is indexed by the columns list, and is zero-based lCh = [] for iCol in range(len(lHdrs)): iNomCol = iCol + 1 if iNomCol in dictChannels: lChanSet = dictChannels[iNomCol][:] lCh.append(lChanSet[0]) else: # does not correspond to a data colum lCh.append( 0) # placeholder, to make list indexes work right else: # not the 1st (header) line, but a line of data lData = rec['Line'].split('\t') # ignore item zero, a line number, not used sTimeStamp = lData[1] tsAsTime = datetime.datetime.strptime(sTimeStamp, "%Y-%m-%d %H:%M:%S") tsAsTime.replace( tzinfo=None ) # make sure it does not get local timezone info tsAsTime = tsAsTime + datetime.timedelta(hours=-iHrOffset) tsAsDate = tsAsTime.date() stSQL = "INSERT INTO Data (UTTimestamp, ChannelID, Value) VALUES (?, ?, ?)" for iCol in range(len(lData)): if iCol > 1: # an item of data # give some progress diagnostics dataRecItemCt += 1 if dataRecItemCt % 100 == 0: self.msgArea.ChangeValue("Line " + str(rec['ID']) + " of " + str(infoDict['lineCt']) + "; " + str(dataRecsAdded) + " records added, " + str(dataRecsDupSkipped) + " duplicates skipped.") wx.Yield() try: # much faster to try and fail than to test first scidb.curD.execute( stSQL, (tsAsTime, lCh[iCol], lData[iCol])) dataRecsAdded += 1 # count it except sqlite3.IntegrityError: # item is already in Data table dataRecsDupSkipped += 1 # count but otherwise ignore finally: wx.Yield() # finished parsing lines infoDict['numNewDataRecsAdded'] = dataRecsAdded infoDict['numDupDataRecsSkipped'] = dataRecsDupSkipped infoDict['stParseMsg'] = str(infoDict['lineCt']) + " lines processed; " + \ str(dataRecsAdded) + " data records added to database, " + \ str(dataRecsDupSkipped) + " duplicates skipped." self.msgArea.ChangeValue(infoDict['stParseMsg'])
def __call__(self, text): self.progress_dialog.Update(self.cur_num, text) self.cur_num += 1 wx.Yield()
def OnYValidated(self,evt): self.arena_center_y = float(self.y_text.GetValue()) self.set_edgepoint() wx.Yield() self.display_parameters(self.y_text) self.ShowImage()
def OnAuth(self, Event=None): """Check the password is correct, then either warn the user or call self.StartWxFixBoot()""" #Remove any cached credentials, so we don't create a security problem, or say the password is right when it isn't. subprocess.Popen("sudo -k", shell=True).wait() #Check the password is right. Password = self.PasswordField.GetLineText(0) Cmd = subprocess.Popen( "LC_ALL=C sudo -S echo 'Authentication Succeeded'", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) #Send the password to sudo through stdin, to avoid showing the user's password in the system/activity monitor. Cmd.stdin.write(Password + "\n") Cmd.stdin.close() self.Throbber.SetAnimation(self.Busy) self.Throbber.Play() while Cmd.poll() == None: wx.Yield() time.sleep(0.04) Output = Cmd.stdout.read() if "Authentication Succeeded" in Output: #Set the password field colour to green and disable the auth button. self.PasswordField.SetBackgroundColour((192, 255, 192)) self.AuthButton.Disable() #Play the green pulse for one second. self.Throbber.SetAnimation(self.GreenPulse) self.Throbber.Play() wx.CallLater(1000, self.Throbber.Stop) wx.CallLater(1100, self.StartWxFixBoot, Password) else: #Shake the window XPos, YPos = self.GetPosition() Count = 0 while Count <= 6: if Count in (0, 2, 4, 6): XPos -= 10 else: XPos += 10 time.sleep(0.02) self.SetPosition((XPos, YPos)) wx.Yield() Count += 1 #Set the password field colour to pink, and select its text. self.PasswordField.SetBackgroundColour((255, 192, 192)) self.PasswordField.SetSelection(0, -1) self.PasswordField.SetFocus() #Play the red pulse for one second. self.Throbber.SetAnimation(self.RedPulse) self.Throbber.Play() wx.CallLater(1000, self.Throbber.Stop)
def on_start_scan(self, e): print "start scan" self.scanning = True # get scan parameters: self.x0 = float(self.frame.m_textCtrl_x0.GetValue()) self.x1 = float(self.frame.m_textCtrl_x1.GetValue()) self.y0 = float(self.frame.m_textCtrl_y0.GetValue()) self.y1 = float(self.frame.m_textCtrl_y1.GetValue()) self.dx = float(self.frame.m_textCtrl_dx.GetValue()) / 1000. self.dy = float(self.frame.m_textCtrl_dy.GetValue()) / 1000. self.x_array = np.arange(self.x0, self.x1, self.dx, dtype=float) self.y_array = np.arange(self.y0, self.y1, self.dy, dtype=float) self.Nx = len(self.x_array) self.Ny = len(self.y_array) print "Nx, Ny", self.Nx, self.Ny self.tacq = int(float(self.frame.m_textCtrl_tacq.GetValue()) * 1000) self.phrange = int(self.frame.m_textCtrl_phrange.GetValue()) self.phoffset = int(self.frame.m_textCtrl_phoffset.GetValue()) self.syncdiv = int( self.frame.m_choice_syncdivider.GetString( self.frame.m_choice_syncdivider.GetSelection())) self.zerocross0 = int(self.frame.m_spinCtrl_zerocross0.GetValue()) self.zerocross1 = int(self.frame.m_spinCtrl_zerocross0.GetValue()) self.level0 = int(self.frame.m_textCtrl_level0.GetValue()) self.level1 = int(self.frame.m_textCtrl_level1.GetValue()) # create data arrays #self.integrated_count_map_c0 = np.zeros((self.Nx, self.Ny), dtype=int) self.integrated_count_map_c1 = np.zeros((self.Ny, self.Nx), dtype=int) self.time_trace_map = np.zeros( (self.Ny, self.Nx, self.STORED_HISTCHAN), dtype=int) print "shape:", self.integrated_count_map_c1.shape, self.time_trace_map.shape #update figure self.aximg = self.ax.imshow( self.integrated_count_map_c1, origin='lower', vmin=1e4, vmax=1e5, interpolation='nearest', extent=[self.x0, self.x1, self.y0, self.y1]) self.wxfig.redraw() # set up experiment self.picoharp.setup_experiment(Range=self.phrange, Offset=self.phoffset, Tacq=self.tacq, SyncDivider=self.syncdiv, CFDZeroCross0=self.zerocross0, CFDLevel0=self.level0, CFDZeroCross1=self.zerocross1, CFDLevel1=self.level1) line_time0 = time.time() for jj in range(self.Ny): #self.nanodrive.SetY(self.y_array[j]) if not self.scanning: break y = self.y_array[jj] #self.lockinstage.sety(y) #self.read_from_hardware() self.nanodrive.set_pos_ax(y, 1) self.read_from_hardware() y = self.ypos print "line time:", time.time() - line_time0 print "pixel time:", float(time.time() - line_time0) / len( self.x_array) line_time0 = time.time() """xdelta = self.x_array[0] - self.xpos if abs(xdelta) > 2.0: if xdelta > 0: step = +1.0 elif xdelta < 0: step = -1.0 for x in np.arange(self.xpos, self.x_array[0], step): self.nanodrive.set_pos_ax(x, 2) wx_yielded_sleep(0.1) """ if jj % 2: #odd lines x_line_indicies = range(self.Nx) else: #even lines -- traverse in opposite direction x_line_indicies = range(self.Nx)[::-1] for ii in x_line_indicies: if not self.scanning: break x = self.xpos = self.x_array[ii] #print ii,x wx.Yield() #self.nanodrive.SetX(self.x_array[i]) #self.nanodrive.set_pos(x, y) #print "nanodrive set_pos: ", x, y #self.lockinstage.setx(x) self.nanodrive.set_pos_ax(x, 2) #if self.HARDWARE_DEBUG: print "lockin stage moved to ", x, y ph = self.picoharp ph.start_histogram(Tacq=self.tacq) while not ph.check_done_scanning(): wx.Yield() ph.stop_histogram() hist_data = ph.read_histogram_data() self.time_trace_map[jj, ii, :] = hist_data[0:self.STORED_HISTCHAN] self.integrated_count_map_c1[jj, ii] = sum(hist_data) #x1, y1 = self.nanodrive.get_pos() #print "get pos: ", x1,y1 # update display try: self.update_display() except Exception, err: print "Failed to update_display", err if not (ii % 5): #self.update_figure() try: #print "updating figure" #self.read_from_hardware() self.aximg.set_data(self.integrated_count_map_c1) try: count_min = np.min( self.integrated_count_map_c1[np.nonzero( self.integrated_count_map_c1)]) except Exception as err: count_min = 0 count_max = np.max(self.integrated_count_map_c1) self.aximg.set_clim(count_min, count_max + 1) self.wxfig.redraw() except Exception, err: print "Failed to update figure:", err
def spin(p): while not p.finished: wx.Yield() time.sleep(0.01)
def Show(self): # show the dialog then start search wx.Dialog.Show(self) wx.Yield() self.onSearch() # trigger the search update
def OnOpen(self, event): """File open event handler""" # If changes have taken place save of old grid if self.main_window.changed_since_save: save_choice = self.interfaces.get_save_request_from_user() if save_choice is None: # Cancelled close operation return elif save_choice: # User wants to save content post_command_event(self.main_window, self.main_window.SaveMsg) # Get filepath from user f2w = get_filetypes2wildcards( ["pys", "pysu", "xls", "xlsx", "ods", "all"]) filetypes = f2w.keys() wildcards = f2w.values() wildcard = "|".join(wildcards) message = _("Choose file to open.") style = wx.OPEN default_filetype = config["default_open_filetype"] try: default_filterindex = filetypes.index(default_filetype) except ValueError: # Be graceful if the user has entered an unkown filetype default_filterindex = 0 get_fp_fidx = self.interfaces.get_filepath_findex_from_user filepath, filterindex = get_fp_fidx(wildcard, message, style, filterindex=default_filterindex) if filepath is None: return filetype = filetypes[filterindex] # Change the main window filepath state self.main_window.filepath = filepath # Load file into grid post_command_event(self.main_window, self.main_window.GridActionOpenMsg, attr={ "filepath": filepath, "filetype": filetype }) # Set Window title to new filepath title_text = filepath.split("/")[-1] + " - pyspread" post_command_event(self.main_window, self.main_window.TitleMsg, text=title_text) self.main_window.grid.ForceRefresh() if is_gtk(): try: wx.Yield() except: pass # Mark content as unchanged try: post_command_event(self.main_window, self.ContentChangedMsg, changed=False) except TypeError: # The main window does not exist any more pass
except: print "We are detecting an error with unpacking molfile2params" print "Check the scripts directory and make sure there is a folder called \"rosetta_py\" in it" print "If not, run molfile.bat as the Administrator" p = input("Press any key to exit: ") exit() else: exit() # Display splash screen if (platform.system() == "Windows"): splashImage = wx.Bitmap("images\\splash.png", wx.BITMAP_TYPE_PNG) else: splashImage = wx.Bitmap("images/splash.png", wx.BITMAP_TYPE_PNG) splash = wx.SplashScreen(splashImage, wx.SPLASH_CENTRE_ON_SCREEN | wx.SPLASH_NO_TIMEOUT, 10000, None, style=wx.FRAME_NO_TASKBAR) wx.Yield() # Start PyMOL # Depending on the computer, the windows may have sizes and positions that are slightly off, so when # the user resizes/repositions them, their settings get saved and loaded by default the next time # this program is run # Import PyMOL with the saved window settings screenW = wx.GetDisplaySize()[0] screenH = wx.GetDisplaySize()[1] # These defaults get the sizes mostly right pymolw = screenW - 370 pymolh = screenH - 340 pymolx = 370 pymoly = 0 try: # Read the saved offsets and modify the coordinates/sizes as needed
def CreateEdgeImage(self): self.edgemag_zero = self.edgemag.copy() self.edgemag_zero[self.edgemag < params.arena_edgethresh] = 0 wx.Yield() self.image_shown,clim = colormapk.colormap_image(self.edgemag_zero)
def Sauvegarder(self): """ Sauvegarde des attestations """ # Demande la confirmation de sauvegarde dlg = wx.MessageDialog(self, _(u"Souhaitez-vous mémoriser les attestations ?\n\n(Cliquez NON si c'était juste un test sinon cliquez OUI)"), _(u"Sauvegarde"), wx.YES_NO|wx.YES_DEFAULT|wx.CANCEL|wx.ICON_INFORMATION) reponse = dlg.ShowModal() dlg.Destroy() if reponse != wx.ID_YES : return dlgAttente = PBI.PyBusyInfo(_(u"Sauvegarde des attestations en cours..."), parent=None, title=_(u"Veuillez patienter..."), icon=wx.Bitmap(Chemins.GetStaticPath("Images/16x16/Logo.png"), wx.BITMAP_TYPE_ANY)) wx.Yield() DB = GestionDB.DB() try : for IDcompte_payeur, dictCompte in self.donnees.iteritems() : if dictCompte["select"] == True : numero = dictCompte["num_attestation"] IDfamille = dictCompte["IDfamille"] listePrestations = dictCompte["listePrestations"] total = dictCompte["total"] regle = dictCompte["ventilation"] solde = total - regle # Liste des activités texteActivites = "" for IDactivite in self.listeActivites : texteActivites += "%d;" % IDactivite if len(self.listeActivites) > 0 : texteActivites = texteActivites[:-1] # Liste des individus texteIndividus = "" for IDindividu in dictCompte["individus"].keys() : texteIndividus += "%d;" % IDindividu if len(dictCompte["individus"].keys()) > 0 : texteIndividus = texteIndividus[:-1] IDutilisateur = UTILS_Identification.GetIDutilisateur() # Sauvegarde de la facture listeDonnees = [ ("numero", numero), ("IDfamille", IDfamille), ("date_edition", str(datetime.date.today())), ("activites", texteActivites), ("individus", texteIndividus), ("IDutilisateur", IDutilisateur), ("date_debut", str(self.date_debut)), ("date_fin", str(self.date_fin)), ("total", float(total)), ("regle", float(regle)), ("solde", float(solde)), ] IDattestation = DB.ReqInsert("attestations", listeDonnees) # Mémorisation de l'action dans l'historique UTILS_Historique.InsertActions([{ "IDfamille" : IDfamille, "IDcategorie" : 27, "action" : _(u"Edition d'une attestation de présence pour la période du %s au %s pour un total de %.02f ¤ et un solde de %.02f ¤") % (DateEngFr(str(self.date_debut)), DateEngFr(str(self.date_fin)), total, solde), },]) DB.Close() del dlgAttente except Exception, err: DB.Close() del dlgAttente traceback.print_exc(file=sys.stdout) dlg = wx.MessageDialog(self, _(u"Désolé, le problème suivant a été rencontré dans la sauvegarde des attestations : \n\n%s") % err, _(u"Erreur"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return False
def InitializeValues(self): wx.BeginBusyCursor() wx.Yield() # resize the image for speed (self.im,self.nr_resize_ratio,self.nc_resize_ratio) = resize_image_for_speed(self.im) imblank = num.zeros(self.im.shape+(3,),dtype=num.uint8) self.img_wind.update_image_and_drawings('setarena',imblank, format='RGB8') self.img_wind_child = self.img_wind.get_child_canvas('setarena') # compute the edge magnitude image self.edgemag = edge(self.im) # initialize value for edge threshold if params.arena_edgethresh is None: params.arena_edgethresh = choose_edge_threshold(self.edgemag) # initialize arena parameters if not set yet (nr,nc) = self.im.shape if params.arena_center_x is None: self.arena_center_x = .5*nc else: self.arena_center_x = params.arena_center_x * self.nc_resize_ratio if params.arena_center_y is None: self.arena_center_y = .5*nr else: self.arena_center_y = params.arena_center_y * self.nr_resize_ratio if params.arena_radius is None: self.arena_radius = .375*min(nc,nr) else: self.arena_radius = params.arena_radius * .5 * (self.nr_resize_ratio + self.nc_resize_ratio) # set bounds on the threshold self.minedgemag = num.min(self.edgemag) self.maxedgemag = num.max(self.edgemag) self.edge_threshold_button.SetRange(0,NTHRESHSTEPS-1) params.arena_edgethresh = min(params.arena_edgethresh,self.maxedgemag) params.arena_edgethresh = max(params.arena_edgethresh,self.minedgemag) # set value of threshold displayed v = int(num.round((params.arena_edgethresh-self.minedgemag)/(self.maxedgemag-self.minedgemag)*NTHRESHSTEPS)) self.edge_threshold_button.SetValue(v) # create the threshold image self.CreateEdgeImage() self.edgepoint = [self.arena_center_x + self.arena_radius, self.arena_center_y] # set click mode self.selected_point = 'none' # set text self.radius_text.SetValue("%.1f"%self.arena_radius) self.x_text.SetValue("%.1f"%self.arena_center_x) self.y_text.SetValue("%.1f"%self.arena_center_y) # set min, max text self.minradius_text.SetValue("%.3f"%params.min_arena_radius) self.maxradius_text.SetValue("%.3f"%params.max_arena_radius) self.minx_text.SetValue("%.3f"%params.min_arena_center_x) self.maxx_text.SetValue("%.3f"%params.max_arena_center_x) self.miny_text.SetValue("%.3f"%params.min_arena_center_y) self.maxy_text.SetValue("%.3f"%params.max_arena_center_y) # set-up spinners self.maxradius = max(params.movie.get_width()*self.nc_resize_ratio, params.movie.get_height()*self.nr_resize_ratio)/2. self.maxx = (params.movie.get_width()-1.)*self.nc_resize_ratio self.maxy = (params.movie.get_height()-1.)*self.nr_resize_ratio self.radius_spinner_scale = float(NRADIUSSTEPS)/self.maxradius self.x_spinner_scale = float(NXSTEPS)/self.maxx self.y_spinner_scale = float(NYSTEPS)/self.maxy self.radius_spin.SetRange(0,NRADIUSSTEPS-1) self.x_spin.SetRange(0,NXSTEPS-1) self.y_spin.SetRange(0,NYSTEPS-1) self.set_radius_spinner_value() self.set_x_spinner_value() self.set_y_spinner_value() wx.EndBusyCursor()
def parseGLTextFile(self, infoDict): """ parse a GreenLogger text file """ dataRecItemCt = 0 dataRecsAdded = 0 dataRecsDupSkipped = 0 # print "About to put lines into temp table" self.putTextLinesIntoTmpTable(infoDict) # print "Finished putting lines into temp table" # get the metadata header stSQL = """SELECT Line FROM tmpLines WHERE Line LIKE '{"Instrument identifier":%' GROUP BY Line;""" mtDat = scidb.curT.execute(stSQL).fetchone() dictHd = ast.literal_eval(mtDat['Line']) # somewhat redundant to do 'LoggerSerialNumber' here (fn 'assureChannelIsInDB' would fill in # later), but allows putting Model into the DB iInstSpecID = scidb.assureItemIsInTableField(dictHd['Model'], "InstrumentSpecs", "InstrumentSpec") iLoggerID = scidb.assureItemIsInTableField( dictHd['Instrument identifier'], "Loggers", "LoggerSerialNumber") scidb.curD.execute( "UPDATE Loggers SET InstrumentSpecID = ? WHERE ID = ?;", (iInstSpecID, iLoggerID)) # get the hour offset(s); most files will have only one stSQL = "SELECT substr(Line, 21, 3) as TZ FROM tmpLines " \ "WHERE Line LIKE '____-__-__ __:__:__ ___%' GROUP BY TZ;" hrOffsets = scidb.curT.execute(stSQL).fetchall() for hrOffset in hrOffsets: iTimeZoneOffset = int(hrOffset['TZ']) # make a dictionary of channel IDs for data lines that have this hour offset # would be slightly different for different hour offsets lCols = dictHd[ 'Columns'] # get col metadata; this is a list of dictionaries # # it is indexed by the columns list, and is zero-based # lCh = [0 for i in range(len(lCols))] # initially, fill with all zeroes dictChannels = {} # this is the dictionary we will build for dictCol in lCols: # somewhat redundant to fill these in before calling function 'assureChannelIsInDB', but # allows assigning sensor device types iDeviceTypeID = scidb.assureItemIsInTableField( dictCol['Device'], "DeviceSpecs", "DeviceSpec") iSensorID = scidb.assureItemIsInTableField( dictCol['Identifier'], "Sensors", "SensorSerialNumber") scidb.curD.execute( "UPDATE Sensors SET DeviceSpecID = ? WHERE ID = ?;", (iDeviceTypeID, iSensorID)) # iDataTypeID = scidb.assureItemIsInTableField(dictCol['DataType'], "DataTypes", "TypeText") # iDataUnitsID = scidb.assureItemIsInTableField(dictCol['DataUnits'], "DataUnits", "UnitsText") # build list to create the channel # list items are: ChannelID, originalCol, Logger, Sensor, dataType, dataUnits, hrOffset, new lChannel = [ 0, dictCol['Order'], dictHd['Instrument identifier'], dictCol['Identifier'], dictCol['DataType'], dictCol['DataUnits'], iTimeZoneOffset, '' ] dictChannels[dictCol['Order']] = ( lChannel[:]) # the key is the column number scidb.assureChannelIsInDB(dictChannels[ dictCol['Order']]) # get or create the channel iChannelID = dictChannels[dictCol['Order']][0] # store the column name as a Series iSeriesID = scidb.assureItemIsInTableField( dictCol['Name'], "DataSeries", "DataSeriesDescription") # tie it to this Channel, to offer later stSQLcs = 'INSERT INTO tmpChanSegSeries(ChannelID, SeriesID) VALUES (?, ?);' try: scidb.curD.execute(stSQLcs, (iChannelID, iSeriesID)) except sqlite3.IntegrityError: pass # silently ignore duplicates # print 'Before Channel function' # for ky in dictChannels.keys(): # print ky, dictChannels[ky][:] # for ky in dictChannels.keys(): # scidb.assureChannelIsInDB(dictChannels[ky]) # print 'After Channel function' # for ky in dictChannels.keys(): # print ky, dictChannels[ky][:] # make a list of channel IDs for the set of lines with this HrOffset, for quick lookup # it is indexed by the columns list, and is zero-based lCh = [] for iCol in range(len(lCols)): iNomCol = iCol + 1 if iNomCol in dictChannels: lChanSet = dictChannels[iNomCol][:] lCh.append(lChanSet[0]) else: # does not correspond to a data colum lCh.append( 0) # placeholder, to make list indexes work right # done setting up channels, get data lines stSQL = "SELECT ID, Line FROM tmpLines WHERE substr(Line, 21, 3) = ? " \ "AND Line LIKE '____-__-__ __:__:__ ___%' ORDER BY ID;" recs = scidb.curT.execute(stSQL, (hrOffset['TZ'], )).fetchall() for rec in recs: lData = rec['Line'].split('\t') # item zero is the timestamp followed by the timezone offset sTimeStamp = lData[ 0][:-4] # drop timezone offset, we already have it tsAsTime = datetime.datetime.strptime(sTimeStamp, "%Y-%m-%d %H:%M:%S") tsAsTime.replace( tzinfo=None ) # make sure it does not get local timezone info tsAsTime = tsAsTime + datetime.timedelta( hours=-iTimeZoneOffset) tsAsDate = tsAsTime.date() stSQL = "INSERT INTO Data (UTTimestamp, ChannelID, Value) VALUES (?, ?, ?)" for iCol in range(len(lData)): if iCol > 0: # an item of data # give some progress diagnostics dataRecItemCt += 1 if dataRecItemCt % 100 == 0: self.msgArea.ChangeValue("Line " + str(rec['ID']) + " of " + str(infoDict['lineCt']) + "; " + str(dataRecsAdded) + " records added, " + str(dataRecsDupSkipped) + " duplicates skipped.") wx.Yield() try: # much faster to try and fail than to test first scidb.curD.execute( stSQL, (tsAsTime, lCh[iCol], lData[iCol])) dataRecsAdded += 1 # count it except sqlite3.IntegrityError: # item is already in Data table dataRecsDupSkipped += 1 # count but otherwise ignore finally: wx.Yield() # finished parsing lines infoDict['numNewDataRecsAdded'] = dataRecsAdded infoDict['numDupDataRecsSkipped'] = dataRecsDupSkipped infoDict['stParseMsg'] = str(infoDict['lineCt']) + " lines processed; " + \ str(dataRecsAdded) + " data records added to database, " + \ str(dataRecsDupSkipped) + " duplicates skipped." self.msgArea.ChangeValue(infoDict['stParseMsg'])
def BeginBusy(self): """ set a busy cursor """ wx.Yield() wx.BeginBusyCursor()
def putTextLinesIntoTmpTable(self, infoDict): """ Usable for data files that are in text format: This function puts the lines as separate records into the temporary table "tmpLines", which it creates new each time. Adds the member infoDict['lineCt'] """ scidb.curT.executescript(""" DROP TABLE IF EXISTS "tmpLines"; """) scidb.tmpConn.execute("VACUUM") scidb.curT.executescript(""" CREATE TABLE "tmpLines" ("ID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE , "Line" VARCHAR(200)); """) stSQL = 'INSERT INTO tmpLines(Line) VALUES (?);' ct = 0 numToInsertAtOnce = 1000 # arbitrary number, guessing to optimize lstLines = [] with open(infoDict['fullPath'], 'rb') as f: for sLine in f: ct += 1 # much faster to insert a batch at once wx.Yield() st = sLine.strip( ) # removes ambiguous x0A, x0D, etc, chars from ends if st != '': # ignore empty lines m = re.search(r"\{.*\}", st) # if the line has a JSON string in it if m: # take it out into a separate line sJ = m.group(0) lstLines.append((sJ, )) stx = st.replace(sJ, '') if len(stx) > 0: lstLines.append((stx, )) else: lstLines.append((st, )) wx.Yield() if len(lstLines) >= numToInsertAtOnce: self.msgArea.ChangeValue("counting lines in file: " + str(ct)) scidb.tmpConn.execute("BEGIN DEFERRED TRANSACTION") scidb.curT.executemany(stSQL, lstLines) scidb.tmpConn.execute("COMMIT TRANSACTION") lstLines = [] wx.Yield() scidb.tmpConn.commit() wx.Yield() # file should be closed by here, avoid possible corruption if left open # put last batch of lines into DB if len(lstLines) > 0: wx.Yield() scidb.tmpConn.execute("BEGIN DEFERRED TRANSACTION") scidb.curT.executemany(stSQL, lstLines) scidb.tmpConn.execute("COMMIT TRANSACTION") lstLines = [] wx.Yield() # get count scidb.curT.execute("SELECT count(*) AS 'lineCt' FROM tmpLines;") t = scidb.curT.fetchone() # a tuple with one value infoDict['lineCt'] = t[0] self.msgArea.ChangeValue(str(infoDict['lineCt']) + " lines in file") wx.Yield() return
def AddNewActor(self, slice_, mask, surface_parameters): """ Create surface actor, save into project and send it to viewer. """ t_init = time.time() matrix = slice_.matrix filename_img = slice_.matrix_filename spacing = slice_.spacing algorithm = surface_parameters['method']['algorithm'] options = surface_parameters['method']['options'] surface_name = surface_parameters['options']['name'] quality = surface_parameters['options']['quality'] fill_holes = surface_parameters['options']['fill'] keep_largest = surface_parameters['options']['keep_largest'] fill_border_holes = surface_parameters['options'].get( 'fill_border_holes', True) mode = 'CONTOUR' # 'GRAYSCALE' min_value, max_value = mask.threshold_range colour = mask.colour[:3] try: overwrite = surface_parameters['options']['overwrite'] except KeyError: overwrite = False mask.matrix.flush() if quality in const.SURFACE_QUALITY.keys(): imagedata_resolution = const.SURFACE_QUALITY[quality][0] smooth_iterations = const.SURFACE_QUALITY[quality][1] smooth_relaxation_factor = const.SURFACE_QUALITY[quality][2] decimate_reduction = const.SURFACE_QUALITY[quality][3] pipeline_size = 4 if decimate_reduction: pipeline_size += 1 if (smooth_iterations and smooth_relaxation_factor): pipeline_size += 1 if fill_holes: pipeline_size += 1 if keep_largest: pipeline_size += 1 language = ses.Session().language if (prj.Project().original_orientation == const.CORONAL): flip_image = False else: flip_image = True n_processors = multiprocessing.cpu_count() o_piece = 1 piece_size = 20 n_pieces = int(round(matrix.shape[0] / piece_size + 0.5, 0)) filenames = [] pool = multiprocessing.Pool(processes=min(n_pieces, n_processors)) manager = multiprocessing.Manager() msg_queue = manager.Queue(1) # If InVesalius is running without GUI if wx.GetApp() is None: for i in range(n_pieces): init = i * piece_size end = init + piece_size + o_piece roi = slice(init, end) print("new_piece", roi) f = pool.apply_async( surface_process.create_surface_piece, args=(filename_img, matrix.shape, matrix.dtype, mask.temp_file, mask.matrix.shape, mask.matrix.dtype, roi, spacing, mode, min_value, max_value, decimate_reduction, smooth_relaxation_factor, smooth_iterations, language, flip_image, algorithm != 'Default', algorithm, imagedata_resolution, fill_border_holes), callback=lambda x: filenames.append(x)) while len(filenames) != n_pieces: time.sleep(0.25) f = pool.apply_async(surface_process.join_process_surface, args=(filenames, algorithm, smooth_iterations, smooth_relaxation_factor, decimate_reduction, keep_largest, fill_holes, options, msg_queue)) while not f.ready(): time.sleep(0.25) try: surface_filename, surface_measures = f.get() except Exception as e: print(_("InVesalius was not able to create the surface")) print(traceback.print_exc()) return reader = vtk.vtkXMLPolyDataReader() reader.SetFileName(surface_filename) reader.Update() polydata = reader.GetOutput() proj = prj.Project() #Create Surface instance if overwrite: surface = Surface(index=self.last_surface_index) proj.ChangeSurface(surface) else: surface = Surface(name=surface_name) index = proj.AddSurface(surface) surface.index = index self.last_surface_index = index surface.colour = colour surface.polydata = polydata surface.volume = surface_measures['volume'] surface.area = surface_measures['area'] # With GUI else: sp = dialogs.SurfaceProgressWindow() for i in range(n_pieces): init = i * piece_size end = init + piece_size + o_piece roi = slice(init, end) print("new_piece", roi) try: f = pool.apply_async( surface_process.create_surface_piece, args=(filename_img, matrix.shape, matrix.dtype, mask.temp_file, mask.matrix.shape, mask.matrix.dtype, roi, spacing, mode, min_value, max_value, decimate_reduction, smooth_relaxation_factor, smooth_iterations, language, flip_image, algorithm != 'Default', algorithm, imagedata_resolution, fill_border_holes), callback=lambda x: filenames.append(x), error_callback=functools.partial( self._on_callback_error, dialog=sp)) # python2 except TypeError: f = pool.apply_async( surface_process.create_surface_piece, args=(filename_img, matrix.shape, matrix.dtype, mask.temp_file, mask.matrix.shape, mask.matrix.dtype, roi, spacing, mode, min_value, max_value, decimate_reduction, smooth_relaxation_factor, smooth_iterations, language, flip_image, algorithm != 'Default', algorithm, imagedata_resolution, fill_border_holes), callback=lambda x: filenames.append(x)) while len(filenames) != n_pieces: if sp.WasCancelled() or not sp.running: break time.sleep(0.25) sp.Update(_("Creating 3D surface...")) wx.Yield() if not sp.WasCancelled() or sp.running: f = pool.apply_async( surface_process.join_process_surface, args=(filenames, algorithm, smooth_iterations, smooth_relaxation_factor, decimate_reduction, keep_largest, fill_holes, options, msg_queue), callback=functools.partial( self._on_complete_surface_creation, overwrite=overwrite, surface_name=surface_name, colour=colour, dialog=sp), error_callback=functools.partial(self._on_callback_error, dialog=sp)) while sp.running: if sp.WasCancelled(): break time.sleep(0.25) try: msg = msg_queue.get_nowait() sp.Update(msg) except: sp.Update(None) wx.Yield() t_end = time.time() print("Elapsed time - {}".format(t_end - t_init)) sp.Close() if sp.error: dlg = GMD.GenericMessageDialog(None, sp.error, "Exception!", wx.OK | wx.ICON_ERROR) dlg.ShowModal() del sp pool.close() try: pool.terminate() except AssertionError: pass del pool del manager del msg_queue import gc gc.collect()
def ShowSplash(self): self.splash = wx.SplashScreen(self.GetSplash(), wx.SPLASH_CENTRE_ON_SCREEN|wx.SPLASH_NO_TIMEOUT, 3000, None, -1, style = wx.BORDER_NONE) self.splash.Show() wx.Yield()
def flush(self): if self.text: self.text.SetInsertionPointEnd() wx.Yield()
def OnOpen(self, event): """File open event handler""" # If changes have taken place save of old grid if self.main_window.changed_since_save: save_choice = self.interfaces.get_save_request_from_user() if save_choice is None: # Cancelled close operation return elif save_choice: # User wants to save content post_command_event(self.main_window, self.main_window.SaveMsg) # Get filepath from user try: import xlrd wildcard = \ _("Pyspread file") + " (*.pys)|*.pys|" + \ _("Excel file") + " (*.xls)|*.xls|" + \ _("All files") + " (*.*)|*.*" except ImportError: wildcard = \ _("Pyspread file") + " (*.pys)|*.pys|" + \ _("All files") + " (*.*)|*.*" xlrd = None message = _("Choose file to open.") style = wx.OPEN filepath, filterindex = \ self.interfaces.get_filepath_findex_from_user(wildcard, message, style) if filepath is None: return filetype = "pys" if xlrd is None or filterindex != 1 else "xls" # Change the main window filepath state self.main_window.filepath = filepath # Load file into grid post_command_event(self.main_window, self.main_window.GridActionOpenMsg, attr={"filepath": filepath, "filetype": filetype}) # Set Window title to new filepath title_text = filepath.split("/")[-1] + " - pyspread" post_command_event(self.main_window, self.main_window.TitleMsg, text=title_text) self.main_window.grid.ForceRefresh() if is_gtk(): wx.Yield() # Mark content as unchanged try: post_command_event(self.main_window, self.ContentChangedMsg, changed=False) except TypeError: # The main window does not exist any more pass
def _export(self, exportInfo, decorations): size = self.frame.animationPanel.GetSize() if self.temporalMode == TemporalMode.TEMPORAL: timeLabels, mapNamesDict = self.temporalManager.GetLabelsAndMaps() frameCount = len(timeLabels) else: frameCount = self.animationData[ 0].mapCount # should be the same for all animWinSize = [] animWinPos = [] animWinIndex = [] legends = [anim.legendCmd for anim in self.animationData] # determine position and sizes of bitmaps for i, (win, anim) in enumerate(zip(self.mapwindows, self.animations)): if anim.IsActive(): pos = win.GetPosition() animWinPos.append(pos) animWinSize.append(win.GetSize()) animWinIndex.append(i) images = [] busy = wx.BusyInfo(_("Preparing export, please wait..."), parent=self.frame) wx.Yield() lastBitmaps = {} fgcolor = UserSettings.Get(group='animation', key='font', subkey='fgcolor') bgcolor = UserSettings.Get(group='animation', key='font', subkey='bgcolor') for frameIndex in range(frameCount): image = EmptyImage(*size) image.Replace(0, 0, 0, 255, 255, 255) # collect bitmaps of all windows and paste them into the one for i in animWinIndex: frameId = self.animations[i].GetFrame(frameIndex) if not UserSettings.Get(group='animation', key='temporal', subkey=['nodata', 'enable']): if frameId is not None: bitmap = self.bitmapProvider.GetBitmap(frameId) lastBitmaps[i] = bitmap else: if i not in lastBitmaps: lastBitmaps[i] = wx.NullBitmap() else: bitmap = self.bitmapProvider.GetBitmap(frameId) lastBitmaps[i] = bitmap im = ImageFromBitmap(lastBitmaps[i]) # add legend if used legend = legends[i] if legend: legendBitmap = self.bitmapProvider.LoadOverlay(legend) x, y = self.mapwindows[i].GetOverlayPos() legImage = ImageFromBitmap(legendBitmap) # not so nice result, can we handle the transparency # otherwise? legImage.ConvertAlphaToMask() im.Paste(legImage, x, y) if im.GetSize() != animWinSize[i]: im.Rescale(*animWinSize[i]) image.Paste(im, *animWinPos[i]) # paste decorations for decoration in decorations: # add image x = decoration['pos'][0] / 100. * size[0] y = decoration['pos'][1] / 100. * size[1] if decoration['name'] == 'image': decImage = wx.Image(decoration['file']) elif decoration['name'] == 'time': timeLabel = timeLabels[frameIndex] if timeLabel[1]: # interval text = _("%(from)s %(dash)s %(to)s") % { 'from': timeLabel[0], 'dash': u"\u2013", 'to': timeLabel[1] } else: if self.temporalManager.GetTemporalType( ) == TemporalType.ABSOLUTE: text = timeLabel[0] else: text = _("%(start)s %(unit)s") % \ {'start': timeLabel[0], 'unit': timeLabel[2]} decImage = RenderText(text, decoration['font'], bgcolor, fgcolor).ConvertToImage() elif decoration['name'] == 'text': text = decoration['text'] decImage = RenderText(text, decoration['font'], bgcolor, fgcolor).ConvertToImage() image.Paste(decImage, x, y) images.append(image) del busy # export pilImages = [WxImageToPil(image) for image in images] busy = wx.BusyInfo(_("Exporting animation, please wait..."), parent=self.frame) wx.Yield() try: if exportInfo['method'] == 'sequence': filename = os.path.join( exportInfo['directory'], exportInfo['prefix'] + '.' + exportInfo['format'].lower()) writeIms(filename=filename, images=pilImages) elif exportInfo['method'] == 'gif': writeGif(filename=exportInfo['file'], images=pilImages, duration=self.timeTick / float(1000), repeat=True) elif exportInfo['method'] == 'swf': writeSwf(filename=exportInfo['file'], images=pilImages, duration=self.timeTick / float(1000), repeat=True) elif exportInfo['method'] == 'avi': writeAvi(filename=exportInfo['file'], images=pilImages, duration=self.timeTick / float(1000), encoding=exportInfo['encoding'], inputOptions=exportInfo['options']) except Exception as e: del busy GError(parent=self.frame, message=str(e)) return del busy
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 append_hits(self, tag_id): ''' ''' mysql = self.top.main_frame.mysql if not mysql: self.top.err("No available connection to MySQL server.") return busy = wx.BusyInfo("Loading... please wait.") wx.Yield() # step through the hits for this tag id. hits = mysql.cursor(MySQLdb.cursors.DictCursor) hits.execute( "SELECT hits.*, tags.tag FROM cc_hits AS hits, cc_tags AS tags WHERE hits.tag_id = '%d' AND tags.id = '%d' ORDER BY num ASC" % (tag_id, tag_id)) idx = len(self.hits_by_index) hitlist = hits.fetchall() # XXX - need to fix this logic, it craps out some times try: min_time = min( [h["timestamp"] for h in hitlist if h["timestamp"] != 0]) except: min_time = 0 for hit in hitlist: self.hits_by_index[idx] = hit if self.eips.count(hit["eip"]) == 0: if hit["is_function"]: self.top.hit_function_count += 1 self.top.hit_basic_block_count += 1 if hit["is_function"]: is_function = "Y" else: is_function = "" timestamp = int(hit["timestamp"]) - min_time self.InsertStringItem(idx, "") self.SetStringItem(idx, 0, "%d" % hit["num"]) self.SetStringItem(idx, 1, "+%ds" % timestamp) self.SetStringItem(idx, 2, "%08x" % hit["eip"]) self.SetStringItem(idx, 3, "%d" % hit["tid"]) self.SetStringItem(idx, 4, hit["module"]) self.SetStringItem(idx, 5, "%s" % is_function) self.SetStringItem(idx, 6, hit["tag"]) self.items_sort_map[idx] = ( \ int(hit["num"]), "+%ds" % timestamp, "%08x" % hit["eip"], int(hit["tid"]), hit["module"], "%s" % is_function, hit["tag"]) self.SetItemData(idx, idx) self.eips.append(hit["eip"]) idx += 1 self.top.update_gauges()
def __init__(self, parent, id, title): global shell wx.Frame.__init__( self, parent, id, title, (100, 100), # Win32 change [600, 550], style=wx.DEFAULT_FRAME_STYLE | wx.CLIP_CHILDREN | wx.NO_FULL_REPAINT_ON_RESIZE) self.Bind(wx.EVT_CLOSE, self._OnCloseWindow) self.known_modules = {} self.menu = self.make_menu() self.SetMenuBar(self.menu) if aui: self._aui = aui.AuiManager(self) nb_style = (aui.AUI_NB_TAB_SPLIT | aui.AUI_NB_TAB_MOVE | aui.AUI_NB_TAB_EXTERNAL_MOVE | aui.AUI_NB_SCROLL_BUTTONS) nb = aui.AuiNotebook(self, style=nb_style) control_parent = self else: splitter = wx.SplitterWindow(self, -1, style=wx.SP_3DSASH | wx.CLIP_CHILDREN | wx.NO_FULL_REPAINT_ON_RESIZE | wx.SP_LIVE_UPDATE) control_parent = splitter self.icon_display = icon_display.IconDisplay(control_parent, self) if aui: self.shell = PyShellGameraShell(parent=self) rootObject = self.shell.interp.locals self.filling = wx.py.filling.Filling(parent=nb, rootObject=rootObject, rootIsNamespace=True) # Add 'filling' to the interpreter's locals. self.calltip = Calltip(parent=nb) self.sessionlisting = wx.py.crust.SessionListing(parent=nb) else: crust = PyCrustGameraShell(control_parent, -1) self.shell = crust.shell self.shell.main_win = self self.shell.update = self.Update image_menu.set_shell(self.shell) image_menu.set_shell_frame(self) self.shell.push("from gamera.gui import gui") self.shell.push("from gamera.gui.matplotlib_support import *") self.shell.push("from gamera.core import *") self.shell.push("init_gamera()") self.shell.update = self.Update self.icon_display.shell = self.shell self.icon_display.main = self self.Update() self.shell.SetFocus() if aui: self._aui.AddPane( self.icon_display, aui.AuiPaneInfo().Name("icon_display").CenterPane().MinSize( wx.Size(96, 96)).CloseButton(False).CaptionVisible( True).Caption("Objects").Dockable(True)) self._aui.AddPane( self.shell, aui.AuiPaneInfo().Name("shell").CenterPane().MinSize( wx.Size(200, 200)).CloseButton(False).CaptionVisible( True).MaximizeButton(True).Caption( "Interactive Python Shell").Dockable(True)) nb.AddPage(self.calltip, "Documentation") nb.AddPage(self.filling, "Namespace") nb.AddPage(self.sessionlisting, "History") self._aui.AddPane( nb, aui.AuiPaneInfo().Name("notebook").CenterPane().MinSize( wx.Size(200, 100)).MaximizeButton(True)) self._aui.GetPane("notebook").Show().Bottom() self._aui.GetPane("icon_display").Show().Left() self._aui.Update() else: splitter.SetMinimumPaneSize(20) splitter.SplitVertically(self.icon_display, crust, 120) splitter.SetSashPosition(120) self.status = StatusBar(self) self.SetStatusBar(self.status) from gamera.gui import gamera_icons icon = compat_wx.create_icon_from_bitmap(gamera_icons.getIconBitmap()) self.SetIcon(icon) self.Move(wx.Point(int(30), int(30))) wx.Yield()
def Impression(self, tracks=[], nomDoc=None, afficherDoc=True, dictOptions=None, repertoire=None, repertoireTemp=False): """ Impression des factures """ # Récupération des données à partir des IDrappel resultat = self.GetDonneesImpression(tracks, dictOptions) if resultat == False: return False dictDonnees, dictChampsFusion = resultat # Récupération des paramètres d'affichage if dictOptions == None: if afficherDoc == False: dlg = DLG_Apercu_attestation_fiscale.Dialog( None, titre=_( u"Sélection des paramètres de l'attestation fiscale" ), intro= _(u"Sélectionnez ici les paramètres d'affichage de l'attestation fiscale" )) dlg.bouton_ok.SetImageEtTexte("Images/32x32/Valider.png", _("Ok")) else: dlg = DLG_Apercu_attestation_fiscale.Dialog(None) if dlg.ShowModal() == wx.ID_OK: dictOptions = dlg.GetParametres() dlg.Destroy() else: dlg.Destroy() return False # Création des PDF à l'unité def CreationPDFunique(repertoireCible=""): dictPieces = {} dlgAttente = wx.BusyInfo( _(u"Génération des attestations fiscales à l'unité au format PDF..." ), None) if 'phoenix' not in wx.PlatformInfo: wx.Yield() try: index = 0 for IDcompte_payeur, dictAttestation in dictDonnees.items(): nomTitulaires = self.Supprime_accent( dictAttestation["{FAMILLE_NOM}"]) nomFichier = u"%s" % nomTitulaires cheminFichier = u"%s/%s.pdf" % (repertoireCible, nomFichier) dictComptesTemp = {IDcompte_payeur: dictAttestation} self.EcritStatusbar( _(u"Edition de l'attestation fiscale %d/%d : %s") % (index, len(dictAttestation), nomFichier)) UTILS_Impression_attestation_fiscale.Impression( dictComptesTemp, dictOptions, IDmodele=dictOptions["IDmodele"], ouverture=False, nomFichier=cheminFichier) dictPieces[IDcompte_payeur] = cheminFichier index += 1 self.EcritStatusbar("") del dlgAttente return dictPieces except Exception as err: del dlgAttente traceback.print_exc(file=sys.stdout) dlg = wx.MessageDialog( None, _(u"Désolé, le problème suivant a été rencontré dans l'édition des attestations fiscales : \n\n%s" ) % err, _(u"Erreur"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return False # Répertoire souhaité par l'utilisateur if repertoire != None: resultat = CreationPDFunique(repertoire) if resultat == False: return False # Répertoire TEMP (pour Emails) dictPieces = {} if repertoireTemp == True: dictPieces = CreationPDFunique(UTILS_Fichiers.GetRepTemp()) if dictPieces == False: return False # Fabrication du PDF global if repertoireTemp == False: dlgAttente = wx.BusyInfo( _(u"Création du PDF des attestations fiscales..."), None) try: if 'phoenix' not in wx.PlatformInfo: wx.Yield() except: pass self.EcritStatusbar( _(u"Création du PDF des attestations fiscales en cours... veuillez patienter..." )) try: UTILS_Impression_attestation_fiscale.Impression( dictDonnees, dictOptions, IDmodele=dictOptions["IDmodele"], ouverture=afficherDoc, nomFichier=nomDoc) self.EcritStatusbar("") del dlgAttente except Exception as err: del dlgAttente traceback.print_exc(file=sys.stdout) dlg = wx.MessageDialog( None, _(u"Désolé, le problème suivant a été rencontré dans l'édition des attestations fiscales : \n\n%s" ) % err, _(u"Erreur"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return False return dictChampsFusion, dictPieces