def main(): app = QCoreApplication([]) settings4 = QSettings(QSettings.IniFormat, QSettings.UserScope, "nimbus", "config", QCoreApplication.instance()) data4 = QSettings(QSettings.IniFormat, QSettings.UserScope, "nimbus", "data", QCoreApplication.instance()) settings5 = qsettings.QSettings(QSettings.IniFormat, QSettings.UserScope, "nimbus", "config", QCoreApplication.instance()) data5 = qsettings.QSettings(QSettings.IniFormat, QSettings.UserScope, "nimbus", "data", QCoreApplication.instance()) keys = settings4.allKeys() for key in keys: settings5.setValue(key, settings4.value(key)) if key.startswith("general/"): settings5.setValue(chop(key, "general/"), settings4.value(key)) elif key.startswith("General/"): settings5.setValue(chop(key, "General/"), settings4.value(key)) settings5.sync() keys = data4.allKeys() for key in keys: data5.setValue(key, data4.value(key)) if key.startswith("general/"): data5.setValue(chop(key, "general/"), data4.value(key)) elif key.startswith("General/"): data5.setValue(chop(key, "General/"), data4.value(key)) data5.sync()
def getTagGroupsConfiguration(filename): """ Configure in an external file the attributes that belong together to a taggroup. This configuration file is also used to decide which attributes are considered. The file needs to be in the ini format in the following form: [taggroup1] attribute1_name=key1 attribute2_name=key2 [taggroup2] attribute3_name=key1 attribute4_name=key2 etc. The ini format has been chosen because Qt has the in-built class QSettings to read that format (unlike e.g. YAML) """ settings = QSettings("%s/%s" % (os.path.dirname(__file__), filename), QSettings.IniFormat) # Two-dimensional array with taggroups groups = [] # Dictionary that maps the attribute names to LO keys transformMap = {} # The attribute column in the GIS layer that holds the Uuid identifierColumn = None # Loop all groups for i in settings.childGroups(): settings.beginGroup(i) keys = [] # Check if the current group defines a taggroup if QString(i).contains(QRegExp('taggroup[0-9+]')): for j in settings.allKeys(): keys.append(str(j)) transformMap[str(j)] = str(settings.value(j).toString()) # Append the keys to the taggroup groups.append(keys) # Check if the current group defines general settings elif QString(i).contains(QRegExp('settings')): for j in settings.allKeys(): if settings.value(j) == QString('activity_identifier'): identifierColumn = str(j) # End this group settings.endGroup() return identifierColumn, transformMap, groups
def run(self): """Run method that performs all the real work""" # get all available Databases and their connections. db_default = ['PostgreSQL', 'SpatialLite'] db_con_dict = {} qs = QSettings() for k in qs.allKeys(): qsk = k.split('/') if qsk[0] in db_default and qsk[0] not in db_con_dict.keys(): db_con_dict.update({qsk[0]: qsk[2]}) self.dlg.cmb_db.clear() self.dlg.cmb_db.addItems(db_con_dict.keys()) self.get_connections() self.get_db_tables() # list tables to select geonames tables = self.iface.legendInterface().layers() layers_list = [] for layer in tables: layers_list.append(layer.name()) self.dlg.cmb_lay.clear() self.dlg.cmb_lay.addItems(layers_list) # list field names of initial table self.get_field_names() # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. pass
class SettingsINI(object): """ Settings INI file implemented for Wifi-Pumpkin""" def __init__(self,filename): if path.isfile(filename) and filename.endswith('.ini'): self.psettings = QSettings(filename,QSettings.IniFormat) def get_setting(self,name_group,key,format=str): """ Get the value for setting key """ self.psettings.beginGroup(name_group) value = self.psettings.value(key,type=format) self.closeGroup() return value def set_setting(self,name_group,key, value): """ Sets the value of setting key to value """ self.psettings.beginGroup(name_group) self.psettings.setValue(key, value) self.closeGroup() def get_all_childname(self,key): """ get list all childskeys on file config.ini """ return [x.split('/')[1] for x in self.get_all_keys() if x.split('/')[0] == key] def get_all_keys(self): """ get all keys on settings""" return str(self.psettings.allKeys().join("<join>")).split("<join>") def closeGroup(self): """ close group settings""" self.psettings.endGroup()
def __getOption(self, option): if option == 'knownHosts': settings = QSettings() hosts = {} settings.beginGroup('Servers') knownHosts = settings.allKeys() if not knownHosts: return self.defaults[option] for name in knownHosts: host = settings.value(name) hosts[unicode(name)] = [ unicode(col.toString()) for col in host.toList() ] settings.endGroup() return hosts valueType = type(self.defaults[option]) QtType = self.types[valueType] value = QtType(QSettings().value(option, self.defaults[option])) if not value and value == None: return None if option == 'tabOrder': return [unicode(x.toString()) for x in value] if option == 'server': return [unicode(col.toString()) for col in value] if valueType == list: return [int(x.toInt()[0]) for x in value] if valueType == int: return int(value[0]) return valueType(value)
class QNewScoreDialog(QDialog, Ui_newScoreDialog): ''' classdocs ''' def __init__(self, parent = None, counter = None, registry = None): ''' Constructor ''' super(QNewScoreDialog, self).__init__(parent) self.setupUi(self) self.measureTabs.setup(counter, registry, Data.MeasureCount, QComplexCountDialog) for name in DefaultKits.DEFAULT_KIT_NAMES: self.kitCombobox.addItem(name, userData = QVariant(False)) self._settings = QSettings() self._settings.beginGroup("UserDefaultKits") for kitName in self._settings.allKeys(): self.kitCombobox.addItem(kitName, userData = QVariant(True)) def getValues(self): mc = self.measureTabs.getCounter() kitName = unicode(self.kitCombobox.currentText()) kitIndex = self.kitCombobox.currentIndex() isUserKit = self.kitCombobox.itemData(kitIndex).toBool() if isUserKit: kitString = str(self._settings.value(kitName).toString()) handle = StringIO(kitString) dbfile = fileUtils.dbFileIterator(handle) kit = DrumKit.DrumKit() kit.read(dbfile) else: kit = DrumKit.getNamedDefaultKit(kitName) return (self.numMeasuresSpinBox.value(), mc, kit)
def __getOption(self, option): if option == 'knownHosts': settings = QSettings() hosts = {} settings.beginGroup('Servers') knownHosts = settings.allKeys() if not knownHosts: return self.defaults[option] for name in knownHosts: host = settings.value(name) hosts[unicode(name)] = [unicode(col.toString()) for col in host.toList()] settings.endGroup() return hosts valueType = type(self.defaults[option]) QtType = self.types[valueType] value = QtType(QSettings().value(option,self.defaults[option])) if not value and value == None: return None if option == 'tabOrder': return [unicode(x.toString()) for x in value] if option == 'server': return [unicode(col.toString()) for col in value] if valueType == list: return [int(x.toInt()[0]) for x in value] if valueType == int: return int(value[0]) return valueType(value)
class QNewScoreDialog(QDialog, Ui_newScoreDialog): ''' classdocs ''' def __init__(self, parent=None, counter=None, registry=None): ''' Constructor ''' super(QNewScoreDialog, self).__init__(parent) self.setupUi(self) self.measureTabs.setup(counter, registry, Data.MeasureCount, QComplexCountDialog) for name in DefaultKits.DEFAULT_KIT_NAMES: self.kitCombobox.addItem(name, userData=QVariant(False)) self._settings = QSettings() self._settings.beginGroup("UserDefaultKits") for kitName in self._settings.allKeys(): self.kitCombobox.addItem(kitName, userData=QVariant(True)) def getValues(self): mc = self.measureTabs.getCounter() kitName = unicode(self.kitCombobox.currentText()) kitIndex = self.kitCombobox.currentIndex() isUserKit = self.kitCombobox.itemData(kitIndex).toBool() if isUserKit: kitString = str(self._settings.value(kitName).toString()) handle = StringIO(kitString) dbfile = fileUtils.dbFileIterator(handle) kit = DrumKit.DrumKit() kit.read(dbfile) else: kit = DrumKit.getNamedDefaultKit(kitName) return (self.numMeasuresSpinBox.value(), mc, kit)
def addCon(self, d): s = QSettings() s.beginGroup("PostgreSQL/connections") try: connects = [] for x in s.allKeys(): if x[-9:] == "/username": connects.append(x[:-9]) d.listConCombo.addItems(connects) except: QMessageBox.warning(self.iface.mainWindow(), "ERRO", u"Erro ao ler 'Conexões'")
def listConnection(self): try: conf = QSettings() conf.beginGroup("PostgreSQL/connections") connections = [] for x in conf.allKeys(): if x[-9:] == "/username": connections.append(x[:-9]) self.listConnCombo.addItems(connections) except: QtGui.QMessageBox.warning(self.iface.mainWindow(), "ERRO", u"Erro ao ler 'Conexões'")
def checkAllWSDirectories(self, dirPath): """ @summary: given a path, does it exist as a workspace for an existing user """ user = QGISProject.NOUSER s = QSettings() for key in s.allKeys(): if "_ws" in key: value = str(s.value(key)) if value == dirPath: user = key.split('_')[0] return user
def get_connections(self): """Get the db connections, based on the selection in the database field""" qs = QSettings() con_list = [] selected_db_name = self.dlg.cmb_db.currentText() if not selected_db_name == '': for k in qs.allKeys(): qsk = k.split('/') if qsk[0] == selected_db_name and qsk[2] not in con_list and qsk[2] is not 'selected': con_list.append(qsk[2]) if len(con_list) > 0: con_list.remove('selected') self.dlg.cmb_con.clear() self.dlg.cmb_con.addItems(con_list)
def load_from_string(self, string): ''' Hacky as f**k. Writes to temp file on disk, then loads into QSettings. ''' cfg = collections.OrderedDict() tmpfilename = '' with NamedTemporaryFile(suffix='.ini', delete=False) as f: tmpfilename = f.name f.write(string) qset = QSettings(tmpfilename, QSettings.IniFormat) for key in qset.allKeys(): #print('key: {}'.format(key)) delimset(cfg, str(key), self._toPyType(qset.value(key)), delim='/') del qset os.remove(tmpfilename) return cfg
def get_connections(self): """Get the db connections, based on the selection in the database field""" qs = QSettings() con_list = [] selected_db_name = self.dlg.cmb_db.currentText() if not selected_db_name == '': for k in qs.allKeys(): qsk = k.split('/') if qsk[0] == selected_db_name and qsk[ 2] not in con_list and qsk[2] is not 'selected': con_list.append(qsk[2]) if len(con_list) > 0: con_list.remove('selected') self.dlg.cmb_con.clear() self.dlg.cmb_con.addItems(con_list)
def moveSettingsToNewRoot(): """Move all settings to one application file.""" movelist = [[info.name, info.url, False], "metainfo", "snippets", "sessions", "sessiondata"] for moveitem in movelist: if isinstance(moveitem, basestring): moveitem = [moveitem, info.name, True] o = QSettings(moveitem[1], moveitem[0]) o.setFallbacksEnabled(False) keys = o.allKeys() if len(keys) > 0: s = QSettings() if moveitem[2]: s.beginGroup(moveitem[0]) for k in keys: s.setValue(k, o.value(k)) o.clear()
def get_postgis_connections(): qs = QSettings() postgresql_connections = {} for k in sorted(qs.allKeys()): k = utils.returnunicode(k) if k.startswith(u'PostgreSQL'): cols = k.split(u'/') conn_name = cols[2] try: setting = cols[3] except IndexError: #utils.MessagebarAndLog.info(log_msg=u'Postgresql connection info: Setting ' + str(k) + u" couldn't be read") continue value = qs.value(k) postgresql_connections.setdefault(conn_name, {})[setting] = value postgresql_connections = utils.returnunicode(postgresql_connections, keep_containers=True) return postgresql_connections
def readThemeIndex(self, themeName): dirList = [] parents = [] themeIndex = QFile() # Read theme index files for i in range(len(self.iconDirs)): themeIndex.setFileName(path.join(unicode(self.iconDirs[i]), unicode(themeName), "index.theme")) if themeIndex.exists(): indexReader = QSettings(themeIndex.fileName(), QSettings.IniFormat) for key in indexReader.allKeys(): if key.endsWith("/Size"): size = indexReader.value(key).toInt() dirList.append((size[0], unicode(key.left(key.size() - 5)))) parents = indexReader.value('Icon Theme/Inherits') parents = parents.toStringList() break return QIconTheme(dirList, parents)
def readThemeIndex(self, themeName): dirList = [] parents = [] themeIndex = QFile() # Read theme index files for i in range(len(self.iconDirs)): themeIndex.setFileName( path.join(unicode(self.iconDirs[i]), unicode(themeName), "index.theme")) if themeIndex.exists(): indexReader = QSettings(themeIndex.fileName(), QSettings.IniFormat) for key in indexReader.allKeys(): if key.endsWith("/Size"): size = indexReader.value(key).toInt() dirList.append( (size[0], unicode(key.left(key.size() - 5)))) parents = indexReader.value('Icon Theme/Inherits') parents = parents.toStringList() break return QIconTheme(dirList, parents)
def export_setting(file_path, qsettings=None): """Export InaSAFE's setting to a file. :param file_path: The file to write the exported setting. :type file_path: basestring :param qsettings: A custom QSettings to use. If it's not defined, it will use the default one. :type qsettings: qgis.PyQt.QtCore.QSettings :returns: A dictionary of the exported settings. :rtype: dict """ inasafe_settings = {} if not qsettings: qsettings = QSettings() qsettings.beginGroup('inasafe') all_keys = qsettings.allKeys() qsettings.endGroup() for key in all_keys: inasafe_settings[key] = setting(key, qsettings=qsettings) def custom_default(obj): if isinstance(obj, QPyNullVariant): return '' raise TypeError with open(file_path, 'w') as json_file: json.dump(inasafe_settings, json_file, indent=2, default=custom_default) return inasafe_settings
class SempyConfig(QDialog): def __init__(self): """ Config window. Extremely messy atm, need to make this more functional. :return: A config window object """ super(SempyConfig, self).__init__() self.info = {} self.settings = QSettings(QSettings.IniFormat, QSettings.UserScope, "Sempy", "config") self.reload_button = QPushButton("Reload") self.save_button = QPushButton("Save") self.verify_button = QPushButton("Verify") self.box_layout = QGridLayout() self.main_layout = QGridLayout() self.box_group = QButtonGroup() self.btn_layout = QHBoxLayout() self.settings_layout = QGridLayout() self.interval_spinner = QSpinBox() self.interval_label = QLabel("Interval: ") self.token_box = QLineEdit() self.token_label = QLabel("API token: ") self.init_ui() def init_ui(self): """ Create all the UI elements """ self.box_group.setExclusive(False) self.interval_spinner.setSuffix(" seconds") self.interval_spinner.setValue(int(self.settings.value("interval"))) self.token_box.setText(self.settings.value("token")) self.setWindowTitle('Sempy Configuration') self.setWindowIcon(QIcon('res/semaphore.png')) self.interval_label.setBuddy(self.interval_spinner) self.box_layout.addWidget(QLabel("<b>Enable/disable repositories below:</b>"), 0, 0) row = 1 self.settings.beginGroup("Repositories") for key in self.settings.allKeys(): self.info[key] = self.settings.value(key) for key, val in self.info.items(): checkbox = QCheckBox(key) if val == "True": checkbox.setCheckState(Qt.Checked) self.box_layout.addWidget(checkbox, row, 0) self.box_group.addButton(checkbox) row += 1 self.settings.endGroup() self.save_button.clicked.connect(self.save) self.reload_button.clicked.connect(self.reload) self.verify_button.clicked.connect(self.verify) self.btn_layout.addWidget(self.save_button) self.btn_layout.addWidget(self.reload_button) self.settings_layout.addWidget(self.interval_label, 0, 0) self.settings_layout.addWidget(self.interval_spinner, 0, 1) self.settings_layout.addWidget(self.token_label, 1, 0) self.settings_layout.addWidget(self.token_box, 1, 1) self.settings_layout.addWidget(self.verify_button, 1, 3) self.main_layout.addItem(self.settings_layout, 0, 0) self.main_layout.addItem(self.box_layout, 2, 0) self.main_layout.addItem(self.btn_layout, 4, 0) self.setLayout(self.main_layout) @pyqtSlot() def save(self): self.settings.setValue("interval", self.interval_spinner.value()) self.settings.setValue("token", self.token_box.text()) self.settings.beginGroup("Repositories") for i in self.box_group.buttons(): self.settings.setValue(i.text(), str(i.isChecked()).capitalize()) self.settings.endGroup() @pyqtSlot() def reload(self): self.settings.sync() self.interval_spinner.setValue(int(self.settings.value("interval"))) self.token_box.setText(self.settings.value("token")) self.settings.beginGroup("Repositories") for i in self.box_group.buttons(): if self.settings.value(i.text()) == "True": i.setCheckState(Qt.Checked) else: i.setCheckState(Qt.Unchecked) self.settings.endGroup() @pyqtSlot() def verify(self): token = self.token_box.text() try: self.info = json_to_dict(json.loads(get_json(token))) except (TypeError, ValueError): QMessageBox.critical(QMessageBox(), "Token invalid", "Enter a valid token", QMessageBox.Ok) finally: self.settings.beginGroup("Repositories") for key, val in self.info.items(): self.settings.setValue(key, "True") self.settings.endGroup() self.reload() def closeEvent(self, event): event.ignore() self.hide()
class Settings(): def __init__(self, parent=None): self.parent = parent self.app_path = self.getPathToSelf() self.values = {} self.reg = QSettings('seeebek', 'eliteOCR') if self.reg.contains('settings_version'): # in future if version < X.X then... self.values = self.loadSettings() else: self.cleanReg() self.setAllDefaults() self.reg.sync() self.values = self.loadSettings() self.runCalibration() self.values = self.loadSettings() def __getitem__(self, key): if key in self.values: return self.values[key] else: raise KeyError("Key "+str(key)+" not found in settings.") def setValue(self, key, value): self.reg.setValue(key, value) def sync(self): """Save changes and reload settings""" self.reg.sync() self.values = self.loadSettings() def cleanReg(self): """Clean all registry entries (for old version or version not set)""" keys = self.reg.allKeys() for key in keys: self.reg.remove(key) def runCalibration(self): """Run Calibration process""" QMessageBox.information(self.parent, "Calibration neccessary", "The OCR areas need to be set."+\ " Callibration dialog will open now. Please choose a screenshot file."+\ " You can recalibrate at any time by clicking on Calibrate in Settings menu.") image = QFileDialog.getOpenFileName(None, "Open", self.values['screenshot_dir']) if image != "": calibrateDialog = CalibrateDialog(self, image) calibrateDialog.exec_() self.sync() def loadSettings(self): """Load all settings to a dict""" set = {'screenshot_dir': self.reg.value('screenshot_dir', type=QString), 'export_dir': self.reg.value('export_dir', type=QString), 'log_dir': self.reg.value('log_dir', type=QString), 'auto_fill': self.reg.value('auto_fill', type=bool), 'remove_dupli': self.reg.value('remove_dupli', type=bool), 'cal_points': self.reg.value('cal_points', type=float), 'img_res': self.reg.value('img_res', type=int), 'create_nn_images': self.reg.value('create_nn_images', type=bool)} return set def setAllDefaults(self): """Set all settings to default values""" self.setDefaultAutoFill() self.setDefaultRemoveDupli() self.setDefaultCreateNNImg() self.setDefaultScreenshotDir() self.setDefaultLogDir() self.setDefaultExportDir() self.setSettingsVersion() def setSettingsVersion(self): self.reg.setValue('settings_version', "1.0") def setDefaultAutoFill(self): self.reg.setValue('auto_fill', False) def setDefaultRemoveDupli(self): self.reg.setValue('remove_dupli', True) def setDefaultCreateNNImg(self): self.reg.setValue('create_nn_images', False) # opt-in def setDefaultScreenshotDir(self): if isdir(environ['USERPROFILE']+'\\Pictures\\Frontier Developments\\Elite Dangerous'): dir = environ['USERPROFILE']+'\\Pictures\\Frontier Developments\\Elite Dangerous' else: dir = self.app_path self.reg.setValue('screenshot_dir', dir) def setDefaultLogDir(self): if isdir(environ['USERPROFILE']+'\\AppData\\Local\\Frontier_Developments\\Products\\FORC-FDEV-D-1002\\Logs'): logdir = environ['USERPROFILE']+'\\AppData\\Local\\Frontier_Developments\\Products\\FORC-FDEV-D-1002\\Logs' self.reg.setValue('log_dir', logdir) else: QMessageBox.warning(None, "Warning", "The Game was not installed in the default "+\ "location. Log directory could not be found. Please choose the directory in which "+\ "you installed the game. Otherwise system names will not be added to the results.") logdir = QFileDialog.getExistingDirectory(None, "Choose", self.app_path) if logdir != "": if isdir(logdir + "\\Products\\FORC-FDEV-D-1002\\Logs"): self.reg.setValue('log_dir', logdir+"\\Products\\FORC-FDEV-D-1002\\Logs") elif split(str(logdir))[1] == "Logs": self.reg.setValue('log_dir', logdir) else: QMessageBox.warning(None, "Warning", "Log directory not found.\n"+\ "You can add this directory later in settings menu. Until then your "+\ "results will not contain system names.") self.reg.setValue('log_dir', self.app_path) else: self.reg.setValue('log_dir', self.app_path) def setDefaultExportDir(self): self.reg.setValue('export_dir', self.app_path) def getPathToSelf(self): """Return the path to EliteOCR.py or EliteOCR.exe""" if getattr(sys, 'frozen', False): application_path = dirname(sys.executable) elif __file__: application_path = dirname(__file__) return application_path
class MainWindow(QMainWindow): """The main window class. This class auto setup the ui and initialize all the needed objects, for the windows logic. """ def __init__(self): QMainWindow.__init__(self) # Window ui setup self.ui = Ui_MainWindow() self.ui.setupUi(self) self.setWindowTitle(_app_name) self.editor = self.ui.pythonEdit # File menu signals and slots connections self.ui.actionNew_File.triggered.connect(self.newFile) self.ui.actionOpen_File.triggered.connect(self.openFiles) self.ui.actionClear_All.triggered.connect(self._clearRecents) self.ui.actionSave.triggered.connect(self.saveFile) self.ui.actionSave_as.triggered.connect(self.saveFileAs) self.ui.actionPrint.triggered.connect(self.editor.print_on_paper) self.ui.actionExit.triggered.connect(self.close) # Edit menu signals and slots connections self.ui.actionUndo.triggered.connect(self.editor.undo) self.ui.actionRedo.triggered.connect(self.editor.redo) self.ui.actionCut.triggered.connect(self.editor.cut) self.ui.actionCopy.triggered.connect(self.editor.copy) self.ui.actionPaste.triggered.connect(self.editor.paste) self.ui.actionDelete.triggered.connect( self.editor.removeSelectedText) self.ui.actionSelect_All.triggered.connect(self.editor.selectAll) # Run menu signals and slots connections self.ui.actionRun_From_Start.triggered.connect(self.runFromStart) self.ui.actionRun_From_Last_Statement.triggered.connect( self.runFromLast) # Find/Replace menu signals and slots connections self.ui.actionFind_Replace.triggered.connect(self._toggleFindAndReplace) self.ui.actionFind_Next.triggered.connect(self._findNext) self.ui.actionFind_Previous.triggered.connect(self._findPrevious) self.ui.actionReplace.triggered.connect(self._replace) self.ui.actionReplace_All.triggered.connect(self._replaceAll) # Window menu signals and slots connections self.ui.actionFull_Screen.triggered.connect(self._toggleFullScreen) self.ui.actionPreferences.triggered.connect(self._showPreferences) # 3D View menu signals and slots connections self.ui.actionPerspective.triggered.connect( self.ui.glPreviewWidget.togglePerspective) self.ui.actionReset_Camera.triggered.connect( self.ui.glPreviewWidget.resetCamera) # Help menu signals and slots connections self.ui.actionAbout.triggered.connect(self.showAbout) # Find and Replace widget signals and slots connections self.ui.findButton.pressed.connect(self._findNext) self.ui.replaceButton.pressed.connect(self._replace) self.ui.replaceAllButton.pressed.connect(self._replaceAll) # Other signals and slots self.editor.modificationChanged.connect(self._updateWindowTitle) # Recents file management self.recent_file_names = [] self.recent_files_limit = 5 # Dynamic code execution self._auto_execution = True self.code_check_delay = 1.0 self.code_executor = CodeExecutor() self.code_checker = CodeChecker(self.code_executor) self.editor.textChanged.connect(self._resetCheckTimer) self._code_check_timer = Timer(0, None) # Dynamic code execution signals self.code_checker.parseStart.connect(self.editor.cleanSyntaxErrors) self.code_checker.parseEnd.connect(self.editor.addSyntaxErrors) self.code_executor.csgDataChanged.connect( self.ui.glPreviewWidget.setRenderObjects) self.code_executor.executionEnd.connect(self.updateConsole) # Application settings self.settings = QSettings(_app_name, _app_name + " " + _app_version_str) self.restoreSettings() # Open file if provided self._file_name = None if len(sys.argv) > 1: with open(sys.argv[1], "r") as f: self.file_name = sys.argv[1] self.editor.setText(f.read()) self.editor.setModified(False) else: self._file_name = "Untitled" self._updateWindowTitle(False) @property def file_name(self): """The current file name, if changed, the title of the window \ and the current working directory are chenged accordigly""" return self._file_name @file_name.setter def file_name(self, value): self._file_name = value os.chdir(os.path.dirname(value)) self._updateWindowTitle(self.editor.isModified()) @property def auto_execution(self): """Whether auto execution is enabled or not.""" return self._auto_execution @auto_execution.setter def auto_execution(self, value): if value and not self._auto_execution: self._auto_execution = value self._requestCheck() else: self._auto_execution = value def updateConsole(self, exec_stdout, exec_stderr, exec_globals, exec_locals): """Updates the console with the execution output.""" self.ui.consoleTextEdit.setText("") self.ui.consoleTextEdit.append(exec_stdout.getvalue()) def closeEvent(self,event): """Overwrites the QMainWindow closeEvent. Check for file modfications and ask to save.""" if self.editor.isModified(): if not self._askForAndSave(): event.ignore() return self.code_checker.send_request(CodeChecker.TermRequest()) self.code_executor.send_request(CodeExecutor.TermRequest()) self.saveSettings() event.accept() def newFile(self): """Creates a new file, actually launches a new instance of \ the program.""" subprocess.call(["python", "./pyCSGScriptLive.py"]) def openFiles(self): """Opens existing files. The user is asked for the file target, if here is specified the first file will replace the current, otherwise a new instance is fired. For each file from the second there on, a new instance is fired. """ dialog_caption = self.tr("Open Files") file_names = QFileDialog.getOpenFileNames(caption=dialog_caption, filter="python script (*py)") if len(file_names) == 0: return else: selection = self._askForOpenTarget() if selection == 2: return elif selection == 0: self.openFileByName(file_names[0], True) file_names = file_names[1:] for file_name in file_names: self.openFileByName(str(file_name)) def openFileByName(self, file_name, here = False): """Opens the file with the provided name. If here is specified the opened file will replace the current, else a new instance is fired. """ self._addToRecents(file_name) if here: if self.editor.isModified(): if not self._askForAndSave(): return False with open(file_name, "r") as f: self.editor.setText(f.read()) self.editor.setModified(False) self.file_name = str(file_name) else: subprocess.call(["python", "./pyCSGScriptLive.py", file_name]) return True return False def saveFile(self): """Save the file with its current file name.""" with open(self.file_name, "w") as f: f.write(self.editor.text()) self.editor.setModified(False) self._addToRecents(self.file_name) def saveFileAs(self): """Asks the user for a new file name and save the file with \ that name.""" file_name = QFileDialog.getSaveFileName(caption="Save File As", filter="python script (*.py)") if file_name: self.file_name = str(file_name) self.saveFile() def saveSettings(self): """Saves settigns such as the window state and geometry, \ and user preferences.""" # Widgets state and geometry self.settings.beginGroup("widgets") self.settings.setValue("geometry", self.saveGeometry()) self.settings.setValue("splitter1_state", self.ui.splitter.saveState()) self.settings.setValue("splitter2_state", self.ui.splitter_2.saveState()) self.settings.setValue("window_state", self.saveState(_app_version)) self.settings.endGroup() # User preferences self.settings.beginGroup("preferences") self.settings.setValue("annotations", self.editor.annotations_active) self.settings.setValue("autoindent", self.editor.autoIndent()) self.settings.setValue("autocomp_thresh", self.editor.autoCompletionThreshold()) self.settings.setValue("indent_width", self.editor.indentationWidth()) self.settings.setValue("indent_use_tabs", self.editor.indentationsUseTabs()) self.settings.setValue("autoexecution", self._auto_execution) self.settings.setValue("code_check_delay", self.code_check_delay) self.settings.endGroup() # 3D View state self.settings.beginGroup("view_state") self.settings.setValue("perspective", self.ui.glPreviewWidget.perspective) self.settings.endGroup() def restoreSettings(self): """Restore the previous saved settings such as window state/geometry and recent files.""" # Check for exsisting settings if len(self.settings.allKeys()) == 0: return # Widgets state and geometry self.settings.beginGroup("widgets") geometry = self.settings.value("geometry").toByteArray() splitter1_state = self.settings.value("splitter1_state").toByteArray() splitter2_state = self.settings.value("splitter2_state").toByteArray() window_state = self.settings.value("window_state").toByteArray() self.restoreGeometry(geometry) self.restoreState(window_state, _app_version) self.ui.splitter.restoreState(splitter1_state) self.ui.splitter_2.restoreState(splitter2_state) self.settings.endGroup() # Recent files recents_data = self.settings.value("recent_file_names") recents_file_names = recents_data.toStringList() for recent_file_name in recents_file_names: self.recent_file_names.append(str(recent_file_name)) self._updateRecentsMenu() # User preferences self.settings.beginGroup("preferences") annotations_active = self.settings.value("annotations").toBool() autoindent = self.settings.value("autoindent").toBool() autocomp_thresh = self.settings.value("autocomp_thresh").toInt()[0] indent_width = self.settings.value("indent_width").toInt()[0] indent_use_tabs = self.settings.value("indent_use_tabs").toBool() self._auto_execution = self.settings.value("autoexecution").toBool() self.code_check_delay = \ self.settings.value("code_check_delay").toFloat()[0] self.settings.endGroup() self.editor.annotations_active = annotations_active self.editor.setAutoIndent(autoindent) self.editor.setAutoCompletionThreshold(autocomp_thresh) self.editor.setIndentationWidth(indent_width) self.editor.setIndentationsUseTabs(indent_use_tabs) # 3D View state self.settings.beginGroup("view_state") persp = self.settings.value("perspective").toBool() self.ui.glPreviewWidget.perspective = persp self.settings.endGroup() def showAbout(self): """Shows the about dialog.""" with open("about") as f: text = f.read().format(_app_version_str) QMessageBox.about(self, "About PyCSGScriptLive", text) def runFromStart(self): self.code_executor.send_request(CodeExecutor.StopRequest()) request = CodeChecker.CheckRequest(unicode(self.editor.text()), unicode(self.file_name), True) self.code_checker.send_request(request) def runFromLast(self): request = CodeChecker.CheckRequest(unicode(self.editor.text()), unicode(self.file_name), True) self.code_checker.send_request(request) def _askForAndSave(self): # Asks the user for save the current file, and if the user # confirms, save the file. # Returns False if the Cancel button is pressed, True otherwise. file_name = QFileInfo(self.file_name).fileName() selection = QMessageBox.warning(self, self.tr("Save File"), file_name + \ self.tr(" has been modified."), self.tr("Save"), self.tr("Ignore"), self.tr("Cancel")) if selection == 0: self.saveFile() return selection != 2 def _askForOpenTarget(self): # Asks the user for the open target of a file, and return # the index of the button pressed. return QMessageBox.information(self, self.tr("Open Target"), self.tr("Open In:"), self.tr("Here"), self.tr("New Window"), self.tr("Cancel")) def _updateWindowTitle(self, modified): # Updates the window title according to the current file name # and state. if modified: modified_note = QCoreApplication.translate("MainWindow", "[modified]") else: modified_note = "" file_name = QFileInfo(self.file_name).fileName() title = _app_name + " - " + file_name + " " + modified_note self.setWindowTitle(title) def _genRecentOpenSlot(self, file_name): # Generates a function that calls the openFileByName with # binded with the provided file_name. # Used to generate slots for the recents files. def open_slot(): selection = self._askForOpenTarget() if selection == 2: return self.openFileByName(file_name, selection == 0) return open_slot def _updateRecentsMenu(self): # Ensures the recent files menu matches the recent file names # into the recent_file_names attribute. # This shoud be called each time the recent_file_names is modified. self.ui.menuRecent_Files.clear() for recent_file_name in self.recent_file_names: recent_file_info = QFileInfo(recent_file_name) action_text = recent_file_info.baseName() + " [" action_text += recent_file_info.canonicalFilePath() + "]" file_action = self.ui.menuRecent_Files.addAction(action_text) file_name = recent_file_info.canonicalFilePath() file_action.triggered.connect(self._genRecentOpenSlot(file_name)) self.ui.menuRecent_Files.addSeparator() self.ui.menuRecent_Files.addAction(self.ui.actionClear_All) def _clearRecents(self): # Remove all the recent file names and update the menu self.recent_file_names = [] self._updateRecentsMenu() def _addToRecents(self, file_name): # Add a file tot he recents and update the menu # Removes the file if already into the list of recent file names try: self.recent_file_names.remove(file_name) except ValueError: pass # Insert the element on top of the recent file names self.recent_file_names.insert(0, file_name) # Drops any exeeding entry of the recent file names if len(self.recent_file_names) > self.recent_files_limit: self.recent_file_names.pop() # Save the recent file names in settings qrecent_file_names = QStringList() for recent_file_name in self.recent_file_names: qrecent_file_names.append(recent_file_name) self.settings.setValue("recent_file_names", qrecent_file_names) # Update the Ui self._updateRecentsMenu() def _toggleFullScreen(self): if self.isFullScreen(): self.showNormal() else: self.showFullScreen() def _toggleFindAndReplace(self): if self.ui.findAndReplacedockWidget.isVisible(): self.ui.findAndReplacedockWidget.hide() else: self.ui.findAndReplacedockWidget.show() def _findNext(self): expr = self.ui.findTextEdit.toPlainText() case_sensitive = self.ui.findCaseSensitiveCheckBox.isChecked() is_regex = self.ui.findRegexCheckBox.isChecked() whole_word = self.ui.findWholeWordCheckBox.isChecked() return self.editor.findFirst(expr, is_regex, case_sensitive, whole_word, True) def _findPrevious(self): expr = self.ui.findTextEdit.toPlainText() case_sensitive = self.ui.findCaseSensitiveCheckBox.isChecked() is_regex = self.ui.findRegexCheckBox.isChecked() whole_word = self.ui.findWholeWordCheckBox.isChecked() cursor_pos = self.editor.getCursorPosition() # We need to search by a positione before the acutal cursor # position otherwise the search will find the same item again and # again in the item is located immediately on le left of the cursor. pos = cursor_pos[0], max(cursor_pos[1] - 1, 0) return self.editor.findFirst(expr, is_regex, case_sensitive, whole_word, True, False, pos[0], pos[1]) def _replace(self): if self.editor.selectedText() == self.ui.findTextEdit.toPlainText(): self.editor.replace(self.ui.replaceTextEdit.toPlainText()) elif self._findNext(): self.editor.replace(self.ui.replaceTextEdit.toPlainText()) return True else: return False def _replaceAll(self): self.editor.beginUndoAction() while self._replace(): pass self.editor.endUndoAction() def _showPreferences(self): pref_dialog = PreferencesDialog(self) pref_dialog.show() def _requestCheck(self): request = CodeChecker.CheckRequest(unicode(self.editor.text()), unicode(self.file_name), self._auto_execution) self.code_checker.send_request(request) def _resetCheckTimer(self): self._code_check_timer.cancel() self._code_check_timer = Timer(self.code_check_delay, self._requestCheck) self._code_check_timer.start()
class USBSettings(QObject): valueChanged = pyqtSignal() def __init__(self, parent=None): QObject.__init__(self, parent) self.buffer = array.array("B") self.buffer.fromlist([0] * 64) self.file = QSettings("settings.ini", QSettings.IniFormat) #HACK for name in self.file.allKeys(): name = str(name) method = getattr(self, "set" + name) if name in ["PC4", "PC5"]: method(self.file.value(name).toBool()) else: method(self.file.value(name).toInt()[0]) def setPROM_hv(self, arg1): self.buffer[0]=arg1>>8; self.buffer[1]=arg1&255; self.file.setValue("PROM_hv", arg1) self.valueChanged.emit() def setFOL2_I(self, arg1): self.buffer[2]=arg1>>8 self.buffer[3]=arg1&255 self.file.setValue("FOL2_I", arg1) self.valueChanged.emit() def setFOL2_T(self, arg1): self.buffer[4]=arg1>>8 self.buffer[5]=arg1&255 self.file.setValue("FOL2_T", arg1) self.valueChanged.emit() def setFOL1_I(self, arg1): self.buffer[6]=arg1>>8 self.buffer[7]=arg1&255 self.file.setValue("FOL1_I", arg1) self.valueChanged.emit() def setDIL_I(self, arg1): self.buffer[8]=arg1>>8 self.buffer[9]=arg1&255 self.file.setValue("DIL_I", arg1) self.valueChanged.emit() def setDIL_T(self, arg1): self.buffer[10]=arg1>>8 self.buffer[11]=arg1&255 self.file.setValue("DIL_T", arg1) self.valueChanged.emit() def setFOL1_T(self, arg1): self.buffer[12]=arg1>>8 self.buffer[13]=arg1&255 self.file.setValue("FOL1_T", arg1) self.valueChanged.emit() def setPROM_shift(self, arg1): self.buffer[14]=arg1>>8 self.buffer[15]=arg1&255 self.file.setValue("PROM_shift", arg1) self.valueChanged.emit() def setPC4(self, checked): self.buffer[16]=int(checked) self.file.setValue("PC4", checked) self.valueChanged.emit() def setPC5(self, checked): self.buffer[17]=int(checked) self.file.setValue("PC5", checked) self.valueChanged.emit() def setPFGI_amplitude(self, arg1): self.buffer[18]=arg1>>8 self.buffer[19]=arg1&255 self.file.setValue("PFGI_amplitude", arg1) self.valueChanged.emit() def setPFGI_pedestal(self, arg1): self.buffer[20]=arg1>>8 self.buffer[21]=arg1&255 self.file.setValue("PFGI_pedestal", arg1) self.valueChanged.emit() def setPFGI_Tset(self, arg1): self.buffer[22]=arg1>>8 self.buffer[23]=arg1&255 self.file.setValue("PFGI_Tset", arg1) self.valueChanged.emit() def setPFGI_TscanAmp(self, arg1): self.buffer[24]=arg1>>8 self.buffer[25]=arg1&255 self.file.setValue("PFGI_TscanAmp", arg1) self.valueChanged.emit() def setA1(self, arg1): self.file.setValue("A1", arg1) arg1+=32768 self.buffer[26]=arg1>>8 self.buffer[27]=arg1&255 self.valueChanged.emit() def setA2(self, arg1): self.file.setValue("A2", arg1) arg1+=32768 self.buffer[28]=arg1>>8 self.buffer[29]=arg1&255 self.valueChanged.emit() def setA3(self, arg1): self.file.setValue("A3", arg1) arg1+=32768 self.buffer[30]=arg1>>8 self.buffer[31]=arg1&255 self.valueChanged.emit() def setB1(self, arg1): self.file.setValue("B1", arg1) arg1+=32768 self.buffer[32]=arg1>>8 self.buffer[33]=arg1&255 self.valueChanged.emit() def setB2(self, arg1): self.file.setValue("B2", arg1) arg1+=32768 self.buffer[34]=arg1>>8 self.buffer[35]=arg1&255 self.valueChanged.emit() def setB3(self, arg1): self.file.setValue("B3", arg1) arg1+=32768 self.buffer[36]=arg1>>8 self.buffer[37]=arg1&255 self.valueChanged.emit() def setC1(self, arg1): self.file.setValue("C1", arg1) arg1+=32768 self.buffer[38]=arg1>>8 self.buffer[39]=arg1&255 self.valueChanged.emit() def setC2(self, arg1): self.file.setValue("C2", arg1) arg1+=32768 self.buffer[40]=arg1>>8 self.buffer[41]=arg1&255 self.valueChanged.emit() def setC3(self, arg1): self.file.setValue("C3", arg1) arg1+=32768 self.buffer[42]=arg1>>8 self.buffer[43]=arg1&255 self.valueChanged.emit() def setT1set(self, arg1): self.buffer[44]=arg1>>8 self.buffer[45]=arg1&255 self.file.setValue("T1set", arg1) self.valueChanged.emit() def setT2set(self, arg1): self.buffer[46]=arg1>>8 self.buffer[47]=arg1&255 self.file.setValue("T2set", arg1) self.valueChanged.emit() def setT3set(self, arg1): self.buffer[48]=arg1>>8 self.buffer[49]=arg1&255 self.file.setValue("T3set", arg1) self.valueChanged.emit() def setPID(self, checked): self.buffer[50]=int(checked) self.valueChanged.emit() def setPFGI_TscanPeriod(self, arg1): self.buffer[51]=arg1>>8 self.buffer[52]=arg1&255 self.file.setValue("PFGI_TscanPeriod", arg1) self.valueChanged.emit() def setDiode(self, checked): self.buffer[53]=int(checked) self.valueChanged.emit() def setDIL_T_scan_time(self, sec): self.buffer[60] = sec >> 8 self.buffer[61] = sec & 255 self.file.setValue("DIL_T_scan_time", sec) self.valueChanged.emit() def setDIL_T_scan_bottom(self, val): self.buffer[55] = val >> 8 self.buffer[56] = val & 255 self.file.setValue("DIL_T_scan_bottom", val) self.valueChanged.emit() def setDIL_T_scan_top(self, val): self.buffer[57] = val >> 8 self.buffer[58] = val & 255 self.file.setValue("DIL_T_scan_top", val) self.valueChanged.emit() def setDIL_T_scan_state(self, val): self.buffer[59] = val self.valueChanged.emit()
class ini_setting: """ class for managing .ini file and project defaults """ release_mode = False def __init__(self, file_name): """ constructor: read setting values into a QSetting object Args: file_name: ini file name """ self.file_name = file_name self.error_msg = "" self.groups_with_values = {} # all values read self.groups = {} # group names and key names self.config = None if self.config is None and os.path.isfile(self.file_name): try: self.config = QSettings(self.file_name, QSettings.IniFormat) self.build_setting_map() print("Read project settings from " + self.file_name) except Exception as exINI: self.config = None self.error_msg = "Reading Error" + ":\n" + str(exINI) else: if file_name: self.create_ini_file(file_name) def create_ini_file(self, file_name): """ Specify .ini file path after instantiation if setting is not yet instantiated: a new setting is instantiated if the new setting has no key: a new ini file is created Args: file_name: the full path to an ini file Returns: True if successful; False if failed """ if os.path.isfile(self.file_name): return False if self.config is None: try: self.config = QSettings(file_name, QSettings.IniFormat) if len(self.config.allKeys()) == 0: # this is a brand new ini file self.config.setValue("Model/Name", "") self.config.sync() print("created ini file: " + file_name) else: print("Read settings from ini file: " + file_name) self.file_name = file_name return True except Exception as exINI: self.config = None self.error_msg = "Reading Error" + ":\n" + str(exINI) return False def get_setting_value(self, group, key): """ Get the value of a ini setting, assuming all settings are grouped Args: group: the string name of a group or section key: the string name of a key Returns: a list of two elements, first being the value, second being the value type """ rval = [None, None] if len(self.groups) == 0: return rval if not self.groups.has_key(group): return rval self.config.beginGroup(group) qvar = self.config.value(key) if qvar is None: self.config.endGroup() return rval str_val = unicode(qvar) if len(str_val) > 0: tval, tval_is_good = ParseData.intTryParse(str_val) if tval_is_good: rval[0] = tval rval[1] = "integer" self.config.endGroup() return rval tval, tval_is_good = ParseData.floatTryParse(str_val) if tval_is_good: rval[0] = tval rval[1] = "float" self.config.endGroup() return rval rval[0] = str_val rval[1] = "string" self.config.endGroup() return rval elif str_val == "": rval[0] = "" rval[1] = "string" else: str_list = qvar.toStringList().join(",") if len(str_list) > 0: rval[0] = str_list.strip(",").split(",") rval[1] = "stringlist" self.config.endGroup() return rval self.config.endGroup() return rval def build_setting_map(self): """ Build a setting group-key-value mapping dictionary as below: self.groups_with_values [group_name] -> [key_name] -> [value, value_type] Also create group dictionary keyed on group name, pointing to its list of keys so we can get setting values on a as needed basis self.groups [group_name] -> [key names] """ self.groups.clear() self.groups_with_values.clear() for group in self.config.childGroups(): self.config.beginGroup(group) self.groups_with_values[group] = {} self.groups[group] = [] for key in self.config.childKeys(): self.groups[group].append(key) val, vtype = self.get_setting_value(group, key) self.groups_with_values[group][key] = val # print group + "::" + key + "::" + self.config.value(key).toString() self.config.endGroup() def read_ini_file_cp(self): self.config.read(self.file_name) for section in self.config.sections(): dict1 = self.config_section_map(section) pass pass def config_section_map(self, section): dict1 = {} for option in self.config.options(section): try: dict1[option] = self.config.get(section, option) if dict1[option] == -1: print "skip: %s" % option pass except: print "exception on %s!" % option dict1[option] = None return dict1
class Settings(): def __init__(self, parent=None): self.parent = parent self.app_path = self.getPathToSelf() self.storage_path = self.getPathToStorage() self.values = {} self.reg = QSettings() # uses QCoreApplication.organizationName and applicationName self.userprofile = self.getUserProfile() if self.reg.contains('settings_version'): if float(self.reg.value('settings_version', type=QString)) < 1.6: self.cleanReg() self.setAllDefaults() self.reg.sync() self.values = self.loadSettings() else: self.values = self.loadSettings() self.values['create_nn_images'] = False else: self.cleanReg() self.setAllDefaults() self.reg.sync() self.values = self.loadSettings() def __getitem__(self, key): if key in self.values: return self.values[key] else: raise KeyError("Key "+unicode(key)+" not found in settings.") def setValue(self, key, value): self.reg.setValue(key, value) def sync(self): """Save changes and reload settings""" self.reg.sync() self.values = self.loadSettings() def cleanReg(self): """Clean all registry entries (for old version or version not set)""" keys = self.reg.allKeys() for key in keys: self.reg.remove(key) def loadSettings(self): """Load all settings to a dict""" set = {'first_run': self.reg.value('first_run', True, type=bool), 'screenshot_dir': self.reg.value('screenshot_dir', type=QString), 'export_dir': self.reg.value('export_dir', type=QString), 'horizontal_exp': self.reg.value('horizontal_exp', False, type=bool), 'gray_preview': self.reg.value('gray_preview', False, type=bool), 'last_export_format': self.reg.value('last_export_format', "csv", type=QString), 'log_dir': self.reg.value('log_dir', type=QString), 'auto_fill': self.reg.value('auto_fill', type=bool), 'remove_dupli': self.reg.value('remove_dupli', type=bool), 'userID': self.reg.value('userID', type=QString), 'ui_language': self.reg.value('ui_language', type=QString), 'ocr_language': self.reg.value('ocr_language', type=QString), 'delete_files': self.reg.value('delete_files', type=bool), 'translate_results': self.reg.value('translate_results', type=bool), 'pause_at_end': self.reg.value('pause_at_end', type=bool), 'public_mode': self.reg.value('public_mode', type=bool), 'native_dialog': self.reg.value('native_dialog', type=bool), 'create_nn_images': self.reg.value('create_nn_images', type=bool), 'zoom_factor': self.reg.value('zoom_factor', 1.0, type=float), 'info_accepted': self.reg.value('info_accepted', False, type=bool), 'theme': self.reg.value('theme', 'default', type=QString), 'input_size': self.reg.value('input_size', 30, type=int), 'snippet_size': self.reg.value('snippet_size', 30, type=int), 'label_color': self.reg.value('label_color', '#ff7f0f', type=QString), 'input_color': self.reg.value('input_color', '#ffffff', type=QString), 'button_color': self.reg.value('button_color', '#ff7f0f', type=QString), 'button_border_color': self.reg.value('button_border_color', '#af4f0f', type=QString), 'border_color': self.reg.value('border_color', '#af4f0f', type=QString), 'background_color': self.reg.value('background_color', '#000000', type=QString), 'color1': self.reg.value('color1', '#ffffff', type=QString), 'color2': self.reg.value('color2', '#ffffff', type=QString), 'color3': self.reg.value('color3', '#ffffff', type=QString), 'color4': self.reg.value('color4', '#ffffff', type=QString), 'color5': self.reg.value('color5', '#ffffff', type=QString), 'contrast': self.reg.value('contrast', 85.0, type=float)} return set def setAllDefaults(self): """Set all settings to default values""" self.setDefaultAutoFill() self.setDefaultRemoveDupli() self.setDefaultCreateNNImg() self.setDefaultDelete() self.setDefaultTranslateResults() self.setDefaultPause() self.setDefaultPublicMode() self.setDefaultNativeDialog() self.setDefaultScreenshotDir() self.setDefaultLogDir() self.setDefaultExportDir() self.setDefaultLanguage() self.setUserID() self.setSettingsVersion() def setSettingsVersion(self): self.reg.setValue('settings_version', "1.6") def setUserID(self): self.reg.setValue('userID', "EO"+''.join(random.choice('0123456789abcdef') for i in range(8))) def setDefaultExportOptions(self): self.setValue('horizontal_exp', False) self.setValue('last_export_format', 'xlsx') def setDefaultAutoFill(self): self.reg.setValue('auto_fill', False) def setDefaultRemoveDupli(self): self.reg.setValue('remove_dupli', True) def setDefaultLanguage(self): self.reg.setValue('ui_language', "en") self.reg.setValue('ocr_language', "eng") def setDefaultCreateNNImg(self): self.reg.setValue('create_nn_images', False) def setDefaultDelete(self): self.reg.setValue('delete_files', False) def setDefaultTranslateResults(self): self.reg.setValue('translate_results', False) def setDefaultPause(self): self.reg.setValue('pause_at_end', True) def setDefaultPublicMode(self): self.reg.setValue('public_mode', True) def setDefaultNativeDialog(self): # Native save dialogs bugged on 4.8.6 on OSX - https://codereview.qt-project.org/#/c/94980/ self.reg.setValue('native_dialog', platform=="darwin" and QT_VERSION>=0x40807) def setDefaultScreenshotDir(self): path = join(unicode(QDesktopServices.storageLocation(QDesktopServices.PicturesLocation)), "Frontier Developments", "Elite Dangerous") self.reg.setValue('screenshot_dir', isdir(path) and path or self.userprofile) def setDefaultLogDir(self): self.reg.setValue('log_dir', self.getLogDir() or self.userprofile) def getLogDir(self): if platform == 'win32': # https://support.elitedangerous.com/kb/faq.php?id=108 candidates = [] # Steam and Steam libraries key = HKEY() if not RegOpenKeyEx(HKEY_CURRENT_USER, r'Software\Valve\Steam', 0, KEY_READ, ctypes.byref(key)): valtype = DWORD() valsize = DWORD() if not RegQueryValueEx(key, 'SteamPath', 0, ctypes.byref(valtype), None, ctypes.byref(valsize)) and valtype.value == REG_SZ: buf = ctypes.create_unicode_buffer(valsize.value / 2) if not RegQueryValueEx(key, 'SteamPath', 0, ctypes.byref(valtype), buf, ctypes.byref(valsize)): steampath = buf.value.replace('/', '\\') # For some reason uses POSIX seperators steamlibs = [steampath] try: # Simple-minded Valve VDF parser with open(join(steampath, 'config', 'config.vdf'), 'rU') as h: for line in h: vals = line.split() if vals and vals[0].startswith('"BaseInstallFolder_'): steamlibs.append(vals[1].strip('"').replace('\\\\', '\\')) except: pass for lib in steamlibs: candidates.append(join(lib, 'steamapps', 'common', 'Elite Dangerous Horizons', 'Products')) candidates.append(join(lib, 'steamapps', 'common', 'Elite Dangerous', 'Products')) RegCloseKey(key) # Next try custom installation under the Launcher candidates.append(self.getCustomLogDir() or '') # Standard non-Steam locations programs = ctypes.create_unicode_buffer(MAX_PATH) ctypes.windll.shell32.SHGetSpecialFolderPathW(0, programs, CSIDL_PROGRAM_FILESX86, 0) candidates.append(join(programs.value, 'Frontier', 'Products')), applocal = ctypes.create_unicode_buffer(MAX_PATH) ctypes.windll.shell32.SHGetSpecialFolderPathW(0, applocal, CSIDL_LOCAL_APPDATA, 0) candidates.append(join(applocal.value, 'Frontier_Developments', 'Products')) for game in ['elite-dangerous-64', 'FORC-FDEV-D-1']: # Look for Horizons in all candidate places first for base in candidates: if isdir(base): for d in listdir(base): if d.startswith(game) and isfile(join(base, d, 'AppConfig.xml')) and isdir(join(base, d, 'Logs')): return join(base, d, 'Logs') elif platform == 'darwin': # https://support.frontier.co.uk/kb/faq.php?id=97 suffix = join("Frontier Developments", "Elite Dangerous", "Logs") paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, True) if len(paths) and isdir(join(paths[0], suffix)): return join(paths[0], suffix) return None # not found in standard places def getCustomLogDir(self): if platform == 'win32': key = HKEY() if not RegOpenKeyEx(HKEY_LOCAL_MACHINE, machine().endswith('64') and r'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall' or # Assumes that the launcher is a 32bit process r'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', 0, KEY_READ, ctypes.byref(key)): buf = ctypes.create_unicode_buffer(MAX_PATH) i = 0 while True: size = DWORD(MAX_PATH) if RegEnumKeyEx(key, i, buf, ctypes.byref(size), None, None, None, None): break subkey = HKEY() if not RegOpenKeyEx(key, buf, 0, KEY_READ, ctypes.byref(subkey)): valtype = DWORD() valsize = DWORD((len('Frontier Developments')+1)*2) valbuf = ctypes.create_unicode_buffer(valsize.value / 2) if not RegQueryValueEx(subkey, 'Publisher', 0, ctypes.byref(valtype), valbuf, ctypes.byref(valsize)) and valtype.value == REG_SZ and valbuf.value == 'Frontier Developments': if not RegQueryValueEx(subkey, 'InstallLocation', 0, ctypes.byref(valtype), None, ctypes.byref(valsize)) and valtype.value == REG_SZ: valbuf = ctypes.create_unicode_buffer(valsize.value / 2) if not RegQueryValueEx(subkey, 'InstallLocation', 0, ctypes.byref(valtype), valbuf, ctypes.byref(valsize)): return(join(valbuf.value, 'Products')) RegCloseKey(subkey) i += 1 RegCloseKey(key) return None def setDefaultExportDir(self): path = unicode(QDesktopServices.storageLocation(QDesktopServices.DocumentsLocation)) self.reg.setValue('export_dir', isdir(path) and path or self.userprofile) def getUserProfile(self): path = unicode(QDesktopServices.storageLocation(QDesktopServices.HomeLocation)) return isdir(path) and path or u"." def getPathToSelf(self): """Return the path to our supporting files""" if getattr(sys, 'frozen', False): if platform=='darwin': application_path = normpath(join(dirname(sys.executable), os.pardir, 'Resources')) else: application_path = dirname(sys.executable).decode(sys.getfilesystemencoding()) elif __file__: application_path = dirname(__file__).decode(sys.getfilesystemencoding()) else: application_path = u"." return application_path def getPathToStorage(self): """Return the path to a place for writing supporting files""" path = unicode(QDesktopServices.storageLocation(QDesktopServices.DataLocation)) if not isdir(path): makedirs(path) return path
class Settings(): def __init__(self, parent=None): self.parent = parent self.app_path = self.getPathToSelf() self.storage_path = self.getPathToStorage() self.values = {} self.reg = QSettings( ) # uses QCoreApplication.organizationName and applicationName self.userprofile = self.getUserProfile() if self.reg.contains('settings_version'): if float(self.reg.value('settings_version', type=QString)) < 1.6: self.cleanReg() self.setAllDefaults() self.reg.sync() self.values = self.loadSettings() else: self.values = self.loadSettings() self.values['create_nn_images'] = False else: self.cleanReg() self.setAllDefaults() self.reg.sync() self.values = self.loadSettings() def __getitem__(self, key): if key in self.values: return self.values[key] else: raise KeyError("Key " + unicode(key) + " not found in settings.") def setValue(self, key, value): self.reg.setValue(key, value) def sync(self): """Save changes and reload settings""" self.reg.sync() self.values = self.loadSettings() def cleanReg(self): """Clean all registry entries (for old version or version not set)""" keys = self.reg.allKeys() for key in keys: self.reg.remove(key) def loadSettings(self): """Load all settings to a dict""" set = { 'first_run': self.reg.value('first_run', True, type=bool), 'screenshot_dir': self.reg.value('screenshot_dir', type=QString), 'export_dir': self.reg.value('export_dir', type=QString), 'horizontal_exp': self.reg.value('horizontal_exp', False, type=bool), 'gray_preview': self.reg.value('gray_preview', False, type=bool), 'last_export_format': self.reg.value('last_export_format', "csv", type=QString), 'log_dir': self.reg.value('log_dir', type=QString), 'auto_fill': self.reg.value('auto_fill', type=bool), 'remove_dupli': self.reg.value('remove_dupli', type=bool), 'userID': self.reg.value('userID', type=QString), 'ui_language': self.reg.value('ui_language', type=QString), 'ocr_language': self.reg.value('ocr_language', type=QString), 'delete_files': self.reg.value('delete_files', type=bool), 'translate_results': self.reg.value('translate_results', type=bool), 'pause_at_end': self.reg.value('pause_at_end', type=bool), 'public_mode': self.reg.value('public_mode', type=bool), 'native_dialog': self.reg.value('native_dialog', type=bool), 'create_nn_images': self.reg.value('create_nn_images', type=bool), 'zoom_factor': self.reg.value('zoom_factor', 1.0, type=float), 'info_accepted': self.reg.value('info_accepted', False, type=bool), 'theme': self.reg.value('theme', 'default', type=QString), 'input_size': self.reg.value('input_size', 30, type=int), 'snippet_size': self.reg.value('snippet_size', 30, type=int), 'label_color': self.reg.value('label_color', '#ff7f0f', type=QString), 'input_color': self.reg.value('input_color', '#ffffff', type=QString), 'button_color': self.reg.value('button_color', '#ff7f0f', type=QString), 'button_border_color': self.reg.value('button_border_color', '#af4f0f', type=QString), 'border_color': self.reg.value('border_color', '#af4f0f', type=QString), 'background_color': self.reg.value('background_color', '#000000', type=QString), 'color1': self.reg.value('color1', '#ffffff', type=QString), 'color2': self.reg.value('color2', '#ffffff', type=QString), 'color3': self.reg.value('color3', '#ffffff', type=QString), 'color4': self.reg.value('color4', '#ffffff', type=QString), 'color5': self.reg.value('color5', '#ffffff', type=QString), 'contrast': self.reg.value('contrast', 85.0, type=float) } return set def setAllDefaults(self): """Set all settings to default values""" self.setDefaultAutoFill() self.setDefaultRemoveDupli() self.setDefaultCreateNNImg() self.setDefaultDelete() self.setDefaultTranslateResults() self.setDefaultPause() self.setDefaultPublicMode() self.setDefaultNativeDialog() self.setDefaultScreenshotDir() self.setDefaultLogDir() self.setDefaultExportDir() self.setDefaultLanguage() self.setUserID() self.setSettingsVersion() def setSettingsVersion(self): self.reg.setValue('settings_version', "1.6") def setUserID(self): self.reg.setValue( 'userID', "EO" + ''.join(random.choice('0123456789abcdef') for i in range(8))) def setDefaultExportOptions(self): self.setValue('horizontal_exp', False) self.setValue('last_export_format', 'xlsx') def setDefaultAutoFill(self): self.reg.setValue('auto_fill', False) def setDefaultRemoveDupli(self): self.reg.setValue('remove_dupli', True) def setDefaultLanguage(self): self.reg.setValue('ui_language', "en") self.reg.setValue('ocr_language', "eng") def setDefaultCreateNNImg(self): self.reg.setValue('create_nn_images', False) def setDefaultDelete(self): self.reg.setValue('delete_files', False) def setDefaultTranslateResults(self): self.reg.setValue('translate_results', False) def setDefaultPause(self): self.reg.setValue('pause_at_end', True) def setDefaultPublicMode(self): self.reg.setValue('public_mode', True) def setDefaultNativeDialog(self): # Native save dialogs bugged on 4.8.6 on OSX - https://codereview.qt-project.org/#/c/94980/ self.reg.setValue('native_dialog', platform == "darwin" and QT_VERSION >= 0x40807) def setDefaultScreenshotDir(self): path = join( unicode( QDesktopServices.storageLocation( QDesktopServices.PicturesLocation)), "Frontier Developments", "Elite Dangerous") self.reg.setValue('screenshot_dir', isdir(path) and path or self.userprofile) def setDefaultLogDir(self): self.reg.setValue( 'log_dir', self.getCustomLogDir() or self.getStandardLogDir() or self.userprofile) def getStandardLogDir(self): if platform == 'win32': # https://support.elitedangerous.com/kb/faq.php?id=108 programs = ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH) ctypes.windll.shell32.SHGetSpecialFolderPathW( 0, programs, CSIDL_PROGRAM_FILESX86, 0) applocal = ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH) ctypes.windll.shell32.SHGetSpecialFolderPathW( 0, applocal, CSIDL_LOCAL_APPDATA, 0) for base in [ join(programs.value, "Steam", "steamapps", "common", "Elite Dangerous", "Products"), join(programs.value, "Frontier", "Products"), join(applocal.value, "Frontier_Developments", "Products") ]: if isdir(base): for d in listdir(base): if d.startswith("FORC-FDEV-D-1") and isdir( join(base, d, "Logs")): return join(base, d, "Logs") elif platform == 'darwin': # TODO: Steam on Mac suffix = join("Frontier Developments", "Elite Dangerous", "Logs") paths = NSSearchPathForDirectoriesInDomains( NSApplicationSupportDirectory, NSUserDomainMask, True) if len(paths) and isdir(join(paths[0], suffix)): return join(paths[0], suffix) return None # not found in standard places def getCustomLogDir(self): if platform == 'win32': from _winreg import OpenKey, EnumKey, QueryValueEx, HKEY_LOCAL_MACHINE aKey = OpenKey( HKEY_LOCAL_MACHINE, r"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" ) try: i = 0 while True: asubkey = OpenKey(aKey, EnumKey(aKey, i)) try: if QueryValueEx( asubkey, "Publisher")[0] == "Frontier Developments": custpath = join( QueryValueEx(asubkey, "InstallLocation")[0], "Products") if isdir(custpath): for d in listdir(custpath): if d.startswith("FORC-FDEV-D-1") and isdir( join(custpath, d, "Logs")): asubkey.Close() aKey.Close() return join(custpath, d, "Logs") except: pass asubkey.Close() i += 1 except: aKey.Close() return None def setDefaultExportDir(self): path = unicode( QDesktopServices.storageLocation( QDesktopServices.DocumentsLocation)) self.reg.setValue('export_dir', isdir(path) and path or self.userprofile) def getUserProfile(self): path = unicode( QDesktopServices.storageLocation(QDesktopServices.HomeLocation)) return isdir(path) and path or u"." def getPathToSelf(self): """Return the path to our supporting files""" if getattr(sys, 'frozen', False): if platform == 'darwin': application_path = normpath( join(dirname(sys.executable), os.pardir, 'Resources')) else: application_path = dirname(sys.executable).decode( sys.getfilesystemencoding()) elif __file__: application_path = dirname(__file__).decode( sys.getfilesystemencoding()) else: application_path = u"." return application_path def getPathToStorage(self): """Return the path to a place for writing supporting files""" if platform == 'win32': path = join( self.getPathToSelf(), "trainingdata") # Store writable data alongside executable else: path = unicode( QDesktopServices.storageLocation( QDesktopServices.DataLocation)) if not isdir(path): makedirs(path) return path
class Settings(): def __init__(self, parent=None): self.parent = parent self.app_path = self.getPathToSelf() self.values = {} self.reg = QSettings('seeebek', 'eliteOCR') if self.reg.contains('settings_version'): if float(self.reg.value('settings_version', type=QString)) < 1.1: self.setDefaultExportOptions() self.setSettingsVersion() self.reg.sync() self.values = self.loadSettings() else: self.values = self.loadSettings() else: self.cleanReg() self.setAllDefaults() self.reg.sync() self.values = self.loadSettings() def __getitem__(self, key): if key in self.values: return self.values[key] else: raise KeyError("Key "+unicode(key)+" not found in settings.") def setValue(self, key, value): self.reg.setValue(key, value) def sync(self): """Save changes and reload settings""" self.reg.sync() self.values = self.loadSettings() def cleanReg(self): """Clean all registry entries (for old version or version not set)""" keys = self.reg.allKeys() for key in keys: self.reg.remove(key) def loadSettings(self): """Load all settings to a dict""" set = {'screenshot_dir': self.reg.value('screenshot_dir', type=QString), 'export_dir': self.reg.value('export_dir', type=QString), 'horizontal_exp': self.reg.value('horizontal_exp', type=bool), 'last_export_format': self.reg.value('last_export_format', type=QString), 'log_dir': self.reg.value('log_dir', type=QString), 'auto_fill': self.reg.value('auto_fill', type=bool), 'remove_dupli': self.reg.value('remove_dupli', type=bool), 'create_nn_images': self.reg.value('create_nn_images', type=bool)} return set def setAllDefaults(self): """Set all settings to default values""" self.setDefaultAutoFill() self.setDefaultRemoveDupli() self.setDefaultCreateNNImg() self.setDefaultScreenshotDir() self.setDefaultLogDir() self.setDefaultExportDir() self.setSettingsVersion() def setSettingsVersion(self): self.reg.setValue('settings_version', "1.1") def setDefaultExportOptions(self): self.setValue('horizontal_exp', False) self.setValue('last_export_format', 'xlsx') def setDefaultAutoFill(self): self.reg.setValue('auto_fill', False) def setDefaultRemoveDupli(self): self.reg.setValue('remove_dupli', True) def setDefaultCreateNNImg(self): self.reg.setValue('create_nn_images', False) # opt-in def setDefaultScreenshotDir(self): if isdir(environ['USERPROFILE']+'\\Pictures\\Frontier Developments\\Elite Dangerous'): dir = environ['USERPROFILE']+'\\Pictures\\Frontier Developments\\Elite Dangerous' else: dir = self.app_path self.reg.setValue('screenshot_dir', dir) def setDefaultLogDir(self): if isdir(environ['USERPROFILE']+'\\AppData\\Local\\Frontier_Developments\\Products\\FORC-FDEV-D-1002\\Logs'): logdir = environ['USERPROFILE']+'\\AppData\\Local\\Frontier_Developments\\Products\\FORC-FDEV-D-1002\\Logs' self.reg.setValue('log_dir', logdir) else: self.reg.setValue('log_dir', self.app_path) def setDefaultExportDir(self): self.reg.setValue('export_dir', self.app_path) def getPathToSelf(self): """Return the path to EliteOCR.py or EliteOCR.exe""" if getattr(sys, 'frozen', False): application_path = dirname(sys.executable) elif __file__: application_path = dirname(__file__) return application_path
class Settings(): def __init__(self, parent=None): self.parent = parent self.app_path = self.getPathToSelf() self.storage_path = self.getPathToStorage() self.values = {} self.reg = QSettings( ) # uses QCoreApplication.organizationName and applicationName self.userprofile = self.getUserProfile() if self.reg.contains('settings_version'): if float(self.reg.value('settings_version', type=QString)) < 1.6: self.cleanReg() self.setAllDefaults() self.reg.sync() self.values = self.loadSettings() else: self.values = self.loadSettings() self.values['create_nn_images'] = False else: self.cleanReg() self.setAllDefaults() self.reg.sync() self.values = self.loadSettings() def __getitem__(self, key): if key in self.values: return self.values[key] else: raise KeyError("Key " + unicode(key) + " not found in settings.") def setValue(self, key, value): self.reg.setValue(key, value) def sync(self): """Save changes and reload settings""" self.reg.sync() self.values = self.loadSettings() def cleanReg(self): """Clean all registry entries (for old version or version not set)""" keys = self.reg.allKeys() for key in keys: self.reg.remove(key) def loadSettings(self): """Load all settings to a dict""" set = { 'first_run': self.reg.value('first_run', True, type=bool), 'screenshot_dir': self.reg.value('screenshot_dir', type=QString), 'export_dir': self.reg.value('export_dir', type=QString), 'horizontal_exp': self.reg.value('horizontal_exp', False, type=bool), 'gray_preview': self.reg.value('gray_preview', False, type=bool), 'last_export_format': self.reg.value('last_export_format', "csv", type=QString), 'log_dir': self.reg.value('log_dir', type=QString), 'auto_fill': self.reg.value('auto_fill', type=bool), 'remove_dupli': self.reg.value('remove_dupli', type=bool), 'userID': self.reg.value('userID', type=QString), 'ui_language': self.reg.value('ui_language', type=QString), 'ocr_language': self.reg.value('ocr_language', type=QString), 'delete_files': self.reg.value('delete_files', type=bool), 'translate_results': self.reg.value('translate_results', type=bool), 'pause_at_end': self.reg.value('pause_at_end', type=bool), 'public_mode': self.reg.value('public_mode', type=bool), 'native_dialog': self.reg.value('native_dialog', type=bool), 'create_nn_images': self.reg.value('create_nn_images', type=bool), 'zoom_factor': self.reg.value('zoom_factor', 1.0, type=float), 'info_accepted': self.reg.value('info_accepted', False, type=bool), 'theme': self.reg.value('theme', 'default', type=QString), 'input_size': self.reg.value('input_size', 30, type=int), 'snippet_size': self.reg.value('snippet_size', 30, type=int), 'label_color': self.reg.value('label_color', '#ff7f0f', type=QString), 'input_color': self.reg.value('input_color', '#ffffff', type=QString), 'button_color': self.reg.value('button_color', '#ff7f0f', type=QString), 'button_border_color': self.reg.value('button_border_color', '#af4f0f', type=QString), 'border_color': self.reg.value('border_color', '#af4f0f', type=QString), 'background_color': self.reg.value('background_color', '#000000', type=QString), 'color1': self.reg.value('color1', '#ffffff', type=QString), 'color2': self.reg.value('color2', '#ffffff', type=QString), 'color3': self.reg.value('color3', '#ffffff', type=QString), 'color4': self.reg.value('color4', '#ffffff', type=QString), 'color5': self.reg.value('color5', '#ffffff', type=QString), 'contrast': self.reg.value('contrast', 85.0, type=float) } return set def setAllDefaults(self): """Set all settings to default values""" self.setDefaultAutoFill() self.setDefaultRemoveDupli() self.setDefaultCreateNNImg() self.setDefaultDelete() self.setDefaultTranslateResults() self.setDefaultPause() self.setDefaultPublicMode() self.setDefaultNativeDialog() self.setDefaultScreenshotDir() self.setDefaultLogDir() self.setDefaultExportDir() self.setDefaultLanguage() self.setUserID() self.setSettingsVersion() def setSettingsVersion(self): self.reg.setValue('settings_version', "1.6") def setUserID(self): self.reg.setValue( 'userID', "EO" + ''.join(random.choice('0123456789abcdef') for i in range(8))) def setDefaultExportOptions(self): self.setValue('horizontal_exp', False) self.setValue('last_export_format', 'xlsx') def setDefaultAutoFill(self): self.reg.setValue('auto_fill', False) def setDefaultRemoveDupli(self): self.reg.setValue('remove_dupli', True) def setDefaultLanguage(self): self.reg.setValue('ui_language', "en") self.reg.setValue('ocr_language', "eng") def setDefaultCreateNNImg(self): self.reg.setValue('create_nn_images', False) def setDefaultDelete(self): self.reg.setValue('delete_files', False) def setDefaultTranslateResults(self): self.reg.setValue('translate_results', False) def setDefaultPause(self): self.reg.setValue('pause_at_end', True) def setDefaultPublicMode(self): self.reg.setValue('public_mode', True) def setDefaultNativeDialog(self): # Native save dialogs bugged on 4.8.6 on OSX - https://codereview.qt-project.org/#/c/94980/ self.reg.setValue('native_dialog', platform == "darwin" and QT_VERSION >= 0x40807) def setDefaultScreenshotDir(self): path = join( unicode( QDesktopServices.storageLocation( QDesktopServices.PicturesLocation)), "Frontier Developments", "Elite Dangerous") self.reg.setValue('screenshot_dir', isdir(path) and path or self.userprofile) def setDefaultLogDir(self): self.reg.setValue('log_dir', self.getLogDir() or self.userprofile) def getLogDir(self): if platform == 'win32': # https://support.elitedangerous.com/kb/faq.php?id=108 candidates = [] # Steam and Steam libraries key = HKEY() if not RegOpenKeyEx(HKEY_CURRENT_USER, r'Software\Valve\Steam', 0, KEY_READ, ctypes.byref(key)): valtype = DWORD() valsize = DWORD() if not RegQueryValueEx( key, 'SteamPath', 0, ctypes.byref(valtype), None, ctypes.byref(valsize)) and valtype.value == REG_SZ: buf = ctypes.create_unicode_buffer(valsize.value / 2) if not RegQueryValueEx(key, 'SteamPath', 0, ctypes.byref(valtype), buf, ctypes.byref(valsize)): steampath = buf.value.replace( '/', '\\') # For some reason uses POSIX seperators steamlibs = [steampath] try: # Simple-minded Valve VDF parser with open(join(steampath, 'config', 'config.vdf'), 'rU') as h: for line in h: vals = line.split() if vals and vals[0].startswith( '"BaseInstallFolder_'): steamlibs.append( vals[1].strip('"').replace( '\\\\', '\\')) except: pass for lib in steamlibs: candidates.append( join(lib, 'steamapps', 'common', 'Elite Dangerous Horizons', 'Products')) candidates.append( join(lib, 'steamapps', 'common', 'Elite Dangerous', 'Products')) RegCloseKey(key) # Next try custom installation under the Launcher candidates.append(self.getCustomLogDir() or '') # Standard non-Steam locations programs = ctypes.create_unicode_buffer(MAX_PATH) ctypes.windll.shell32.SHGetSpecialFolderPathW( 0, programs, CSIDL_PROGRAM_FILESX86, 0) candidates.append(join(programs.value, 'Frontier', 'Products')), applocal = ctypes.create_unicode_buffer(MAX_PATH) ctypes.windll.shell32.SHGetSpecialFolderPathW( 0, applocal, CSIDL_LOCAL_APPDATA, 0) candidates.append( join(applocal.value, 'Frontier_Developments', 'Products')) for game in ['elite-dangerous-64', 'FORC-FDEV-D-1' ]: # Look for Horizons in all candidate places first for base in candidates: if isdir(base): for d in listdir(base): if d.startswith(game) and isfile( join(base, d, 'AppConfig.xml')) and isdir( join(base, d, 'Logs')): return join(base, d, 'Logs') elif platform == 'darwin': # https://support.frontier.co.uk/kb/faq.php?id=97 suffix = join("Frontier Developments", "Elite Dangerous", "Logs") paths = NSSearchPathForDirectoriesInDomains( NSApplicationSupportDirectory, NSUserDomainMask, True) if len(paths) and isdir(join(paths[0], suffix)): return join(paths[0], suffix) return None # not found in standard places def getCustomLogDir(self): if platform == 'win32': key = HKEY() if not RegOpenKeyEx( HKEY_LOCAL_MACHINE, machine().endswith('64') and r'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall' or # Assumes that the launcher is a 32bit process r'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', 0, KEY_READ, ctypes.byref(key)): buf = ctypes.create_unicode_buffer(MAX_PATH) i = 0 while True: size = DWORD(MAX_PATH) if RegEnumKeyEx(key, i, buf, ctypes.byref(size), None, None, None, None): break subkey = HKEY() if not RegOpenKeyEx(key, buf, 0, KEY_READ, ctypes.byref(subkey)): valtype = DWORD() valsize = DWORD((len('Frontier Developments') + 1) * 2) valbuf = ctypes.create_unicode_buffer(valsize.value / 2) if not RegQueryValueEx( subkey, 'Publisher', 0, ctypes.byref(valtype), valbuf, ctypes.byref(valsize) ) and valtype.value == REG_SZ and valbuf.value == 'Frontier Developments': if not RegQueryValueEx( subkey, 'InstallLocation', 0, ctypes.byref(valtype), None, ctypes.byref( valsize)) and valtype.value == REG_SZ: valbuf = ctypes.create_unicode_buffer( valsize.value / 2) if not RegQueryValueEx( subkey, 'InstallLocation', 0, ctypes.byref(valtype), valbuf, ctypes.byref(valsize)): return (join(valbuf.value, 'Products')) RegCloseKey(subkey) i += 1 RegCloseKey(key) return None def setDefaultExportDir(self): path = unicode( QDesktopServices.storageLocation( QDesktopServices.DocumentsLocation)) self.reg.setValue('export_dir', isdir(path) and path or self.userprofile) def getUserProfile(self): path = unicode( QDesktopServices.storageLocation(QDesktopServices.HomeLocation)) return isdir(path) and path or u"." def getPathToSelf(self): """Return the path to our supporting files""" if getattr(sys, 'frozen', False): if platform == 'darwin': application_path = normpath( join(dirname(sys.executable), os.pardir, 'Resources')) else: application_path = dirname(sys.executable).decode( sys.getfilesystemencoding()) elif __file__: application_path = dirname(__file__).decode( sys.getfilesystemencoding()) else: application_path = u"." return application_path def getPathToStorage(self): """Return the path to a place for writing supporting files""" path = unicode( QDesktopServices.storageLocation(QDesktopServices.DataLocation)) if not isdir(path): makedirs(path) return path
class Settings(): def __init__(self, parent=None): self.parent = parent self.app_path = self.getPathToSelf() self.values = {} self.reg = QSettings('seeebek', 'eliteOCR') self.userprofile = self.getUserProfile() if self.reg.contains('settings_version'): if float(self.reg.value('settings_version', type=QString)) < 1.6: self.cleanReg() self.setAllDefaults() self.reg.sync() self.values = self.loadSettings() else: self.values = self.loadSettings() self.values['create_nn_images'] = False else: self.cleanReg() self.setAllDefaults() self.reg.sync() self.values = self.loadSettings() def __getitem__(self, key): if key in self.values: return self.values[key] else: raise KeyError("Key "+unicode(key)+" not found in settings.") def setValue(self, key, value): self.reg.setValue(key, value) def sync(self): """Save changes and reload settings""" self.reg.sync() self.values = self.loadSettings() def cleanReg(self): """Clean all registry entries (for old version or version not set)""" keys = self.reg.allKeys() for key in keys: self.reg.remove(key) def loadSettings(self): """Load all settings to a dict""" set = {'first_run': self.reg.value('first_run', True, type=bool), 'screenshot_dir': self.reg.value('screenshot_dir', type=QString), 'export_dir': self.reg.value('export_dir', type=QString), 'horizontal_exp': self.reg.value('horizontal_exp', type=bool), 'last_export_format': self.reg.value('last_export_format', type=QString), 'log_dir': self.reg.value('log_dir', type=QString), 'auto_fill': self.reg.value('auto_fill', type=bool), 'remove_dupli': self.reg.value('remove_dupli', type=bool), 'userID': self.reg.value('userID', type=QString), 'ui_language': self.reg.value('ui_language', type=QString), 'ocr_language': self.reg.value('ocr_language', type=QString), 'delete_files': self.reg.value('delete_files', type=bool), 'translate_results': self.reg.value('translate_results', type=bool), 'pause_at_end': self.reg.value('pause_at_end', type=bool), 'public_mode': self.reg.value('public_mode', type=bool), 'native_dialog': self.reg.value('native_dialog', type=bool), 'create_nn_images': self.reg.value('create_nn_images', type=bool), 'zoom_factor': self.reg.value('zoom_factor', 1.0, type=float), 'info_accepted': self.reg.value('info_accepted', False, type=bool), 'theme': self.reg.value('theme', 'default', type=QString), 'input_size': self.reg.value('input_size', 30, type=int), 'snippet_size': self.reg.value('snippet_size', 30, type=int), 'label_color': self.reg.value('label_color', '#ffffff', type=QString), 'input_color': self.reg.value('input_color', '#ffffff', type=QString), 'button_color': self.reg.value('button_color', '#ffffff', type=QString), 'button_border_color': self.reg.value('button_border_color', '#ffffff', type=QString), 'border_color': self.reg.value('border_color', '#ffffff', type=QString), 'background_color': self.reg.value('background_color', '#000000', type=QString), 'color1': self.reg.value('color1', '#ffffff', type=QString), 'color2': self.reg.value('color2', '#ffffff', type=QString), 'color3': self.reg.value('color3', '#ffffff', type=QString), 'color4': self.reg.value('color4', '#ffffff', type=QString), 'color5': self.reg.value('color5', '#ffffff', type=QString), 'contrast': self.reg.value('contrast', 85.0, type=float)} return set def setAllDefaults(self): """Set all settings to default values""" self.setDefaultAutoFill() self.setDefaultRemoveDupli() self.setDefaultCreateNNImg() self.setDefaultDelete() self.setDefaultTranslateResults() self.setDefaultPause() self.setDefaultPublicMode() self.setDefaultNativeDialog() self.setDefaultScreenshotDir() self.setDefaultLogDir() self.setDefaultExportDir() self.setDefaultLanguage() self.setUserID() self.setSettingsVersion() def setSettingsVersion(self): self.reg.setValue('settings_version', "1.6") def setUserID(self): self.reg.setValue('userID', "EO"+''.join(random.choice('0123456789abcdef') for i in range(8))) def setDefaultExportOptions(self): self.setValue('horizontal_exp', False) self.setValue('last_export_format', 'xlsx') def setDefaultAutoFill(self): self.reg.setValue('auto_fill', False) def setDefaultRemoveDupli(self): self.reg.setValue('remove_dupli', True) def setDefaultLanguage(self): self.reg.setValue('ui_language', "en") self.reg.setValue('ocr_language', "eng") def setDefaultCreateNNImg(self): self.reg.setValue('create_nn_images', False) def setDefaultDelete(self): self.reg.setValue('delete_files', False) def setDefaultTranslateResults(self): self.reg.setValue('translate_results', False) def setDefaultPause(self): self.reg.setValue('pause_at_end', True) def setDefaultPublicMode(self): self.reg.setValue('public_mode', True) def setDefaultNativeDialog(self): self.reg.setValue('native_dialog', False) def setDefaultScreenshotDir(self): if isdir(self.userprofile+ os.sep +"Pictures"+ os.sep +"Frontier Developments"+ os.sep +"Elite Dangerous"): dir = self.userprofile+ os.sep +"Pictures"+ os.sep +"Frontier Developments"+ os.sep +"Elite Dangerous" else: dir = self.app_path self.reg.setValue('screenshot_dir', dir) def setDefaultLogDir(self): if isdir(self.userprofile+ os.sep +"AppData"+ os.sep +"Local"+ os.sep +"Frontier_Developments"+ os.sep +"Products"+ os.sep +"FORC-FDEV-D-1002"+ os.sep +"Logs"): logdir = self.userprofile+ os.sep +"AppData"+ os.sep +"Local"+ os.sep +"Frontier_Developments"+ os.sep +"Products"+ os.sep +"FORC-FDEV-D-1002"+ os.sep +"Logs" self.reg.setValue('log_dir', logdir) else: self.reg.setValue('log_dir', self.app_path) def setDefaultExportDir(self): self.reg.setValue('export_dir', self.app_path) def getUserProfile(self): if 'USERPROFILE' in environ: return environ['USERPROFILE'].decode(sys.getfilesystemencoding()) else: return u"." def getPathToSelf(self): """Return the path to EliteOCR.py or EliteOCR.exe""" if getattr(sys, 'frozen', False): application_path = dirname(sys.executable).decode(sys.getfilesystemencoding()) elif __file__: application_path = dirname(__file__).decode(sys.getfilesystemencoding()) else: application_path = u"." return application_path
class Settings(): def __init__(self, parent=None): self.parent = parent self.app_path = self.getPathToSelf() self.values = {} self.reg = QSettings('seeebek', 'eliteOCR') if self.reg.contains('settings_version'): if float(self.reg.value('settings_version', type=QString)) < 1.2: self.cleanReg() self.setAllDefaults() self.reg.sync() self.values = self.loadSettings() if float(self.reg.value('settings_version', type=QString)) < 1.4: self.setDefaultLanguage() self.setDefaultDelete() self.setDefaultTranslateResults() self.setDefaultPause() self.setDefaultUpdatesCheck() self.setDefaultPublicMode() self.setDefaultNativeDialog() self.reg.setValue('settings_version', "1.4") self.reg.sync() else: self.values = self.loadSettings() else: self.cleanReg() self.setAllDefaults() self.reg.sync() self.values = self.loadSettings() def __getitem__(self, key): if key in self.values: return self.values[key] else: raise KeyError("Key " + unicode(key) + " not found in settings.") def setValue(self, key, value): self.reg.setValue(key, value) def sync(self): """Save changes and reload settings""" self.reg.sync() self.values = self.loadSettings() def cleanReg(self): """Clean all registry entries (for old version or version not set)""" keys = self.reg.allKeys() for key in keys: self.reg.remove(key) def loadSettings(self): """Load all settings to a dict""" set = { 'screenshot_dir': self.reg.value('screenshot_dir', type=QString), 'export_dir': self.reg.value('export_dir', type=QString), 'horizontal_exp': self.reg.value('horizontal_exp', type=bool), 'last_export_format': self.reg.value('last_export_format', type=QString), 'log_dir': self.reg.value('log_dir', type=QString), 'auto_fill': self.reg.value('auto_fill', type=bool), 'remove_dupli': self.reg.value('remove_dupli', type=bool), 'userID': self.reg.value('userID', type=QString), 'ui_language': self.reg.value('ui_language', type=QString), 'ocr_language': self.reg.value('ocr_language', type=QString), 'delete_files': self.reg.value('delete_files', type=bool), 'translate_results': self.reg.value('translate_results', type=bool), 'pause_at_end': self.reg.value('pause_at_end', type=bool), 'updates_check': self.reg.value('updates_check', type=bool), 'public_mode': self.reg.value('public_mode', type=bool), 'native_dialog': self.reg.value('native_dialog', type=bool), 'create_nn_images': self.reg.value('create_nn_images', type=bool), 'zoom_factor': self.reg.value('zoom_factor', 1.0, type=float), 'info_accepted': self.reg.value('info_accepted', False, type=bool), } return set def setAllDefaults(self): """Set all settings to default values""" self.setDefaultAutoFill() self.setDefaultRemoveDupli() self.setDefaultCreateNNImg() self.setDefaultDelete() self.setDefaultTranslateResults() self.setDefaultPause() self.setDefaultUpdatesCheck() self.setDefaultPublicMode() self.setDefaultNativeDialog() self.setDefaultScreenshotDir() self.setDefaultLogDir() self.setDefaultExportDir() self.setDefaultLanguage() self.setUserID() self.setSettingsVersion() def setSettingsVersion(self): self.reg.setValue('settings_version', "1.2") def setUserID(self): self.reg.setValue( 'userID', "EO" + ''.join(random.choice('0123456789abcdef') for i in range(8))) def setDefaultExportOptions(self): self.setValue('horizontal_exp', False) self.setValue('last_export_format', 'xlsx') def setDefaultAutoFill(self): self.reg.setValue('auto_fill', False) def setDefaultRemoveDupli(self): self.reg.setValue('remove_dupli', True) def setDefaultLanguage(self): self.reg.setValue('ui_language', "en") self.reg.setValue('ocr_language', "eng") def setDefaultCreateNNImg(self): self.reg.setValue('create_nn_images', False) def setDefaultDelete(self): self.reg.setValue('delete_files', False) def setDefaultUpdatesCheck(self): self.reg.setValue('updates_check', True) def setDefaultTranslateResults(self): self.reg.setValue('translate_results', False) def setDefaultPause(self): self.reg.setValue('pause_at_end', True) def setDefaultPublicMode(self): self.reg.setValue('public_mode', True) def setDefaultNativeDialog(self): self.reg.setValue('native_dialog', False) def setDefaultScreenshotDir(self): if isdir(environ['USERPROFILE'] + '\\Pictures\\Frontier Developments\\Elite Dangerous'): dir = environ[ 'USERPROFILE'] + '\\Pictures\\Frontier Developments\\Elite Dangerous' else: dir = self.app_path self.reg.setValue('screenshot_dir', dir) def setDefaultLogDir(self): if isdir( environ['USERPROFILE'] + '\\AppData\\Local\\Frontier_Developments\\Products\\FORC-FDEV-D-1002\\Logs' ): logdir = environ[ 'USERPROFILE'] + '\\AppData\\Local\\Frontier_Developments\\Products\\FORC-FDEV-D-1002\\Logs' self.reg.setValue('log_dir', logdir) else: self.reg.setValue('log_dir', self.app_path) def setDefaultExportDir(self): self.reg.setValue('export_dir', self.app_path) def getPathToSelf(self): """Return the path to EliteOCR.py or EliteOCR.exe""" if getattr(sys, 'frozen', False): application_path = dirname(sys.executable) elif __file__: application_path = dirname(__file__) return application_path
class SIREN: def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Edit part for the plugin (Init the classes members) self.database_connection = None # Database list (will be initialized in @SIREN::init_database_selector() self.core = None # Main class to manipulate Layers and Notifications # End of Edit part self.iface = iface self.plugin_dir = os.path.dirname(__file__) locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'SIREN_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) self.actions = [] self.menu = self.tr(u'&SIREN') self.toolbar = self.iface.addToolBar(u'SIREN') self.toolbar.setObjectName(u'SIREN') self.pluginIsActive = False self.dockwidget = None # Automatically Display the Widget self.run() # Automatically Generated # noinspection PyMethodMayBeStatic def tr(self, message): # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('SIREN', message) # Automatically Generated def add_action( self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToMenu( self.menu, action) self.actions.append(action) return action # Automatically Generated def initGui(self): icon_path = ':/plugins/SIREN/icon.png' self.add_action( icon_path, text=self.tr(u''), callback=self.run, parent=self.iface.mainWindow()) def onClosePlugin(self): self.dockwidget.closingPlugin.disconnect(self.onClosePlugin) self.pluginIsActive = False # Stop the Multi-threading (managed by the Main Class @Core if self.core is not None: self.core.reset() def unload(self): for action in self.actions: self.iface.removePluginMenu( self.tr(u'&SIREN'), action) self.iface.removeToolBarIcon(action) # remove the toolbar del self.toolbar # -------------------------------------------------------------------------- def run(self): if not self.pluginIsActive: # Read the param list stored in QGIS. # Only entries starting with #PostgreSQL/connections# self.database_connection = QSettings() self.pluginIsActive = True if self.dockwidget is None: self.dockwidget = SIRENDockWidget() self.dockwidget.closingPlugin.connect(self.onClosePlugin) # Initialize the Database list in the UI self.init_database_selector() # Associate method @SIREN.live_button to the button click (UI - Live) self.dockwidget.liveButton.clicked.connect(self.live_button) # Associate method @SIREN.reset_button to the button click (UI - Live) self.dockwidget.resetButton.clicked.connect(self.reset_button) self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dockwidget) self.dockwidget.show() def init_database_selector(self): """ Method to initialize the Database selector. This method load all information and display it into the UI selector. """ # Restrict the list to Postgres connections self.database_connection.beginGroup('PostgreSQL/connections') # Create a set for the connection list connector_name = set() for entry in sorted(self.database_connection.allKeys()): # Take only the information before the "/". It is the connector name connector_name.add(entry.split('/')[0]) # There is a 'selected' Key. It is not entered by the user, so delete it (if exist) connector_name.discard('selected') # Clear the list in the UI selector self.dockwidget.databaseSelector.clear() # Populate the UI selector with new entries for entry in sorted(list(connector_name)): self.dockwidget.databaseSelector.addItem(entry) def live_button(self): """ Action triggered when the 'live' button is pressed """ self.dockwidget.liveButton.setEnabled(False) # if no layer do nothing if not self.dockwidget.checkBoxCorrected.isChecked(): if not self.dockwidget.checkBoxDifference.isChecked(): if not self.dockwidget.checkBoxBrut.isChecked(): ErrorWindow("Erreur selection couche", "Veillez selectionner une couche avant de continuer", "critical") #enable live_button self.dockwidget.liveButton.setEnabled(True) return # init core if self.core is None: # Get the current database selection (in the UI selector) selected = self.dockwidget.databaseSelector.currentText() if selected == "": ErrorWindow("Erreur selection base de donnees", "Veillez selectionner une base de donnees avant de valider", "information") # enable live_button self.dockwidget.liveButton.setEnabled(True) return # Construct the @Core class (Main Class) # The Class need the global information of the database # The Class need to manipulate layers so a reference to the interface (iface) is required self.core = Core( self.database_connection.value(selected + '/host'), self.database_connection.value(selected + '/port'), self.database_connection.value(selected + '/username'), self.database_connection.value(selected + '/password'), self.database_connection.value(selected + '/database'), self.iface ) self.core.connect_init() self.update_layer_list() print("live -> stop") # unbind live event self.dockwidget.liveButton.clicked.disconnect(self.live_button) # change text self.dockwidget.liveButton.setText("Stop") # bind stop event self.dockwidget.liveButton.clicked.connect(self.stop_button) # enable liveButton self.dockwidget.liveButton.setEnabled(True) # disable resetButton self.dockwidget.resetButton.setEnabled(False) def stop_button(self): """ Stop listening :return: """ # set inactive self.dockwidget.liveButton.setEnabled(False) print("stop -> live") self.core.stop() # change text self.dockwidget.liveButton.setText("Live") # unbind stop event self.dockwidget.liveButton.clicked.disconnect(self.stop_button) # bind live event self.dockwidget.liveButton.clicked.connect(self.live_button) # setactive self.dockwidget.liveButton.setEnabled(True) # enable resetButton self.dockwidget.resetButton.setEnabled(True) def reset_button(self): """ Reset stuff """ self.dockwidget.liveButton.setEnabled(False) print("reset") # remove all the layers we added self.core.reset() self.uncheck_checkboxes() # destroys core self.core = None #enable liveButton self.dockwidget.liveButton.setEnabled(True) # disable resetButton self.dockwidget.resetButton.setEnabled(False) def update_layer_list(self): """ TODO :return: """ # If the 'Brut Position' checkbox is checked add the associated layer to the current project if self.dockwidget.checkBoxBrut.isChecked(): self.core.brut_layer() else: self.core.remove_brut_layer() # If the 'Corrected Position' checkbox is checked add the associated layer to the current project if self.dockwidget.checkBoxCorrected.isChecked(): self.core.corrected_layer() else: self.core.remove_corrected_layer() # If the 'Difference Area' checkbox is checked add the associated layer to the current project if self.dockwidget.checkBoxDifference.isChecked(): self.core.difference_layer() else: self.core.remove_difference_layer() def uncheck_checkboxes(self): """ TODO :return: """ self.dockwidget.checkBoxBrut.setChecked(False) self.dockwidget.checkBoxCorrected.setChecked(False) self.dockwidget.checkBoxDifference.setChecked(False)