def _load_settings(self): """ Load the user specific settings. """ settings = QSettings() self.resize(settings.value('size', QSize(860, 400))) self.move(settings.value('pos', QPoint(200, 200)))
def readSettings(self): """read the settings""" settings = QSettings('Pixel Stereo', 'lekture') pos = settings.value('pos', QPoint(200, 200)) size = settings.value('size', QSize(1000, 650)) self.move(pos) self.resize(size)
def dropEvent(self, event): if event.mimeData().hasFormat('text/uri-list'): paths = [url for url in event.mimeData().urls()] # If we drop many files, only the first one will be take into # acount fileName = paths[0] index = self.indexAt(event.pos()) row, col = index.row(), index.column() settings = QSettings() if col == UploadListView.COL_VIDEO: if(VideoTools.isVideofile(fileName)): settings.setValue("mainwindow/workingDirectory", fileName) video = VideoFile(fileName) self.model().layoutAboutToBeChanged.emit() self.model().addVideos(row, [video]) subtitle = Subtitle.AutoDetectSubtitle(video.getFilePath()) if subtitle: sub = SubtitleFile(False, subtitle) self.model().addSubs(row, [sub]) thread.start_new_thread( self.uploadModel.ObtainUploadInfo, ()) self.resizeRowsToContents() self.model().layoutChanged.emit() else: # if it's the column in SUBTITLES print(fileName) if(Subtitle.isSubtitle(fileName)): settings.setValue("mainwindow/workingDirectory", fileName) sub = SubtitleFile(False, fileName) self.model().layoutAboutToBeChanged.emit() self.model().addSubs(row, [sub]) self.resizeRowsToContents() self.model().layoutChanged.emit() thread.start_new_thread( self.uploadModel.ObtainUploadInfo, ())
def _save_settings(self): """ Save the user specific settings. """ settings = QSettings() settings.setValue('size', self.size()) settings.setValue('pos', self.pos())
def _clearSettings(self): """ Just clears all peacock settings. """ settings = QSettings() settings.clear() settings.sync()
def rock_and_roll(): qsettings = QSettings(paths.SETTINGS, QSettings.IniFormat) qapp = QApplication(sys.argv) # Load components after qapp #lint:disable import amaru.ui.main_container import amaru.ui.status_bar import amaru.ui.lateral.tree_project import amaru.ui.lateral.lateral #lint:enable # StyleSheet log.debug("Aply style sheet...") with open(style, mode='r') as f: qapp.setStyleSheet(f.read()) # Show GUI log.debug("Showing GUI...") gui = Amaru() gui.setMinimumSize(700, 500) gui.show() # Load tabs from last session tabs = qsettings.value("opened-tabs") if tabs is None: tabs = [] gui.load_files(tabs) sys.exit(qapp.exec_())
def setUp(self): self.tempFile = tempfile.NamedTemporaryFile(prefix='retext-', suffix='.ini') baseName = splitext(basename(self.tempFile.name))[0] QSettings.setPath(QSettings.IniFormat, QSettings.UserScope, dirname(self.tempFile.name)) self.settings = QSettings(QSettings.IniFormat, QSettings.UserScope, baseName)
def main(): if len(sys.argv) > 1: font = TFont(os.path.abspath(sys.argv[1])) else: font = None representationFactories.registerAllFactories() app = Application(sys.argv) # TODO: http://stackoverflow.com/a/21330349/2037879 app.setOrganizationName("TruFont") app.setOrganizationDomain("trufont.github.io") app.setApplicationName("TruFont") app.setWindowIcon(QIcon(":/resources/app.png")) settings = QSettings() glyphListPath = settings.value("settings/glyphListPath", "", type=str) if glyphListPath and os.path.exists(glyphListPath): from defconQt.util import glyphList try: glyphList = glyphList.parseGlyphList(glyphListPath) except Exception as e: print(e) else: app.GL2UV = glyphList window = MainWindow(font) window.show() sys.exit(app.exec_())
def updateReport(self, data): if data == self.data: return settings = QSettings('Floppy', 'Floppy') self.fileBase = settings.value('WorkDir', type=str) self.data = data self._update()
def langs(): """Returns a list of language codes wished for documentation. If the list is empty, english (untranslated) is assumed. If a language code also has a country suffix, a hyphen will be used as separator (as required per RFC2616, Accept-Language header). """ s = QSettings() langs = [] lang = s.value("documentation/language", "default", str) if lang == "default": lang = s.value("language", "", str) if lang and lang != "C": langs.append(lang) langs.extend(po.setup.preferred()) # now fixup the list, remove dups and # language/country codes in Accept-Language headers must have '-' and not '_' result = [] def add(item): if item not in result: result.append(item) for l in langs: # if there is a language/country code, insert also the generic language code if '_' in l: add(l.replace('_', '-')) add(l.split('_')[0]) else: add(l) return result
def showEvent(self, event): #Show Event QWidget.showEvent(self, event) #Avoid recalculate the panel sizes if they are already loaded if self._splitterArea.count() == 2: return #Rearrange widgets on Window self._splitterArea.insertWidget(0, self._splitterMain) if not event.spontaneous(): self.change_misc_visibility() if bin(settings.UI_LAYOUT)[-1] == '1': self.splitter_central_rotate() if bin(settings.UI_LAYOUT >> 1)[-1] == '1': self.splitter_misc_rotate() if bin(settings.UI_LAYOUT >> 2)[-1] == '1': self.splitter_central_orientation() qsettings = QSettings(resources.SETTINGS_PATH, QSettings.IniFormat) #Lists of sizes as list of QVariant- heightList = [QVariant, QVariant] heightList = list(qsettings.value("window/central/mainSize", [(self.height() / 3) * 2, self.height() / 3])) widthList = list(qsettings.value("window/central/areaSize", [(self.width() / 6) * 5, self.width() / 6])) self._splitterMainSizes = [int(heightList[0]), int(heightList[1])] self._splitterAreaSizes = [int(widthList[0]), int(widthList[1])] #Set the sizes to splitters #self._splitterMain.setSizes(self._splitterMainSizes) self._splitterMain.setSizes(self._splitterMainSizes) self._splitterArea.setSizes(self._splitterAreaSizes) self.misc.setVisible( qsettings.value("window/show_misc", False, type=bool))
def requireScripts(self, urlList): """ Public method to get the sources of all required scripts. @param urlList list of URLs (list of string) @return sources of all required scripts (string) """ requiresDir = QDir(self.requireScriptsDirectory()) if not requiresDir.exists() or len(urlList) == 0: return "" script = "" settings = QSettings( os.path.join(self.requireScriptsDirectory(), "requires.ini"), QSettings.IniFormat) settings.beginGroup("Files") for url in urlList: if settings.contains(url): fileName = settings.value(url) try: f = open(fileName, "r", encoding="utf-8") source = f.read() f.close() except (IOError, OSError): source = "" script += source.strip() + "\n" return script
def loadSettings(self, firstTime): qsettings = QSettings() websettings = self.ui.webview.settings() self.fSavedSettings = { # WebView MOD_KEY_WEBVIEW_INSPECTOR: qsettings.value(MOD_KEY_WEBVIEW_INSPECTOR, MOD_DEFAULT_WEBVIEW_INSPECTOR, type=bool), MOD_KEY_WEBVIEW_SHOW_INSPECTOR: qsettings.value(MOD_KEY_WEBVIEW_SHOW_INSPECTOR, MOD_DEFAULT_WEBVIEW_SHOW_INSPECTOR, type=bool) } inspectorEnabled = self.fSavedSettings[MOD_KEY_WEBVIEW_INSPECTOR] and not USING_LIVE_ISO websettings.setAttribute(QWebSettings.DeveloperExtrasEnabled, inspectorEnabled) if firstTime: self.restoreGeometry(qsettings.value("Geometry", "")) if inspectorEnabled and self.fSavedSettings[MOD_KEY_WEBVIEW_SHOW_INSPECTOR]: QTimer.singleShot(1000, self.ui.webinspector.show) self.ui.act_file_inspect.setVisible(inspectorEnabled) if self.fIdleTimerId != 0: self.killTimer(self.fIdleTimerId) self.fIdleTimerId = self.startTimer(MOD_DEFAULT_MAIN_REFRESH_INTERVAL)
def loadSettings(self): settings = QSettings("falkTX", "Carla2") audioDevice = settings.value("%s%s/Device" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), "", type=str) audioNumPeriods = settings.value("%s%s/NumPeriods" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), CARLA_DEFAULT_AUDIO_NUM_PERIODS, type=int) audioBufferSize = settings.value("%s%s/BufferSize" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), CARLA_DEFAULT_AUDIO_BUFFER_SIZE, type=int) audioSampleRate = settings.value("%s%s/SampleRate" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), CARLA_DEFAULT_AUDIO_SAMPLE_RATE, type=int) if audioDevice and audioDevice in self.fDeviceNames: self.ui.cb_device.setCurrentIndex(self.fDeviceNames.index(audioDevice)) else: self.ui.cb_device.setCurrentIndex(-1) # fill combo-boxes first self.slot_updateDeviceInfo() if audioNumPeriods in (2, 3): self.ui.sb_numperiods.setValue(audioNumPeriods) else: self.ui.sb_numperiods.setValue(CARLA_DEFAULT_AUDIO_NUM_PERIODS) if audioBufferSize and audioBufferSize in self.fBufferSizes: self.ui.cb_buffersize.setCurrentIndex(self.fBufferSizes.index(audioBufferSize)) elif self.fBufferSizes == BUFFER_SIZE_LIST: self.ui.cb_buffersize.setCurrentIndex(BUFFER_SIZE_LIST.index(CARLA_DEFAULT_AUDIO_BUFFER_SIZE)) else: self.ui.cb_buffersize.setCurrentIndex(len(self.fBufferSizes)/2) if audioSampleRate and audioSampleRate in self.fSampleRates: self.ui.cb_samplerate.setCurrentIndex(self.fSampleRates.index(audioSampleRate)) elif self.fSampleRates == SAMPLE_RATE_LIST: self.ui.cb_samplerate.setCurrentIndex(SAMPLE_RATE_LIST.index(CARLA_DEFAULT_AUDIO_SAMPLE_RATE)) else: self.ui.cb_samplerate.setCurrentIndex(len(self.fSampleRates)/2)
def loadSettings(self): settings = QSettings(QSettings.UserScope, 'Georgia Tech', 'RamanGui', self) if settings.contains('alpha'): self.alphaBox.setText(settings.value('alpha')) if settings.contains('l1Ratio'): self.l1RatioBox.setText(settings.value('l1Ratio'))
def _init_misc(): """Initialize misc. config-related files.""" save_manager = objreg.get('save-manager') state_config = ini.ReadWriteConfigParser(standarddir.data(), 'state') for sect in ['general', 'geometry']: try: state_config.add_section(sect) except configparser.DuplicateSectionError: pass # See commit a98060e020a4ba83b663813a4b9404edb47f28ad. state_config['general'].pop('fooled', None) objreg.register('state-config', state_config) save_manager.add_saveable('state-config', state_config.save) # We need to import this here because lineparser needs config. from qutebrowser.misc import lineparser command_history = lineparser.LimitLineParser( standarddir.data(), 'cmd-history', limit=('completion', 'cmd-history-max-items'), parent=objreg.get('config')) objreg.register('command-history', command_history) save_manager.add_saveable('command-history', command_history.save, command_history.changed) # Set the QSettings path to something like # ~/.config/qutebrowser/qsettings/qutebrowser/qutebrowser.conf so it # doesn't overwrite our config. # # This fixes one of the corruption issues here: # https://github.com/qutebrowser/qutebrowser/issues/515 path = os.path.join(standarddir.config(), 'qsettings') for fmt in [QSettings.NativeFormat, QSettings.IniFormat]: QSettings.setPath(fmt, QSettings.UserScope, path)
def removeConfigurationData(): """ Remove the eric configuration directory. """ try: from PyQt5.QtCore import QSettings except ImportError: try: from PyQt4.QtCore import QSettings except ImportError: print("No PyQt variant installed. The configuration directory") print("cannot be determined. You have to remove it manually.\n") return settings = QSettings(QSettings.IniFormat, QSettings.UserScope, settingsNameOrganization, settingsNameGlobal) settingsDir = os.path.dirname(settings.fileName()) if os.path.exists(settingsDir): print("Found the eric configuration directory") print(" - {0}".format(settingsDir)) answer = "c" while answer not in ["y", "Y", "n", "N", ""]: if sys.version_info[0] == 2: answer = raw_input( "Shall this directory be removed (y/N)? ") else: answer = input( "Shall this directory be removed (y/N)? ") if answer in ["y", "Y"]: shutil.rmtree(settings)
def _on_click_on_favorite(self, path, value): settings = QSettings(resources.SETTINGS_PATH, QSettings.IniFormat) recent_projects = settings.value("recentProjects") properties = recent_projects[path] properties["isFavorite"] = value recent_projects[path] = properties settings.setValue("recentProjects", recent_projects)
def load_items(self): settings = QSettings(resources.SETTINGS_PATH, QSettings.IniFormat) listByFavorites = [] listNoneFavorites = [] recent_projects_dict = dict(settings.value('recentProjects', {})) #Filter for favorites for recent_project_path, content in list(recent_projects_dict.items()): if bool(dict(content)["isFavorite"]): listByFavorites.append((recent_project_path, content["lastopen"])) else: listNoneFavorites.append((recent_project_path, content["lastopen"])) if len(listByFavorites) > 1: # sort by date favorites listByFavorites = sorted(listByFavorites, key=lambda date: listByFavorites[1]) if len(listNoneFavorites) > 1: #sort by date last used listNoneFavorites = sorted(listNoneFavorites, key=lambda date: listNoneFavorites[1]) for recent_project_path in listByFavorites: path = recent_project_path[0] name = recent_projects_dict[path]['name'] self.root.add_project(name, path, True) for recent_project_path in listNoneFavorites: path = recent_project_path[0] name = recent_projects_dict[path]['name'] self.root.add_project(name, path, False)
def sGetCGVersion(): s = QSettings( "EZUSoft", fncProgKennung() ) try: if int(s.value( "cgversion"))==0: return "V11" if int(s.value( "cgversion"))==1: return "V20xx" except: return None
def _run_git_command(self, cmd, args = []): """ run a git command and return its output as a string list. Raise an exception if it returns an error. - cmd is the git command (without 'git') - args is a string or a list of strings """ from PyQt5.QtCore import QSettings s = QSettings() s.beginGroup("helper_applications") git_cmd = s.value("git", "git", str) git_cmd = git_cmd if git_cmd else "git" cmd = [git_cmd, cmd] cmd.extend(args) pr = subprocess.Popen(cmd, cwd = self.rootDir, stdout = subprocess.PIPE, stderr = subprocess.PIPE, universal_newlines = True) (out, error) = pr.communicate() if error: raise GitError(error) result = out.split('\n') if result[-1] == '': result.pop() return result
def loadSettings(self): output_port = midihub.default_output() input_port = midihub.default_input() s = QSettings() s.beginGroup("midi") self._playerPort.setEditText(s.value("player/output_port", output_port, str)) self._inputPort.setEditText(s.value("midi/input_port", input_port, str))
def main(): app = QApplication(sys.argv) QCoreApplication.setOrganizationName('Hardcoded Software') QCoreApplication.setApplicationName(__appname__) QCoreApplication.setApplicationVersion(__version__) setupQtLogging() settings = QSettings() lang = settings.value('Language') locale_folder = op.join(BASE_PATH, 'locale') install_gettext_trans_under_qt(locale_folder, lang) # Handle OS signals setUpSignals() # Let the Python interpreter runs every 500ms to handle signals. This is # required because Python cannot handle signals while the Qt event loop is # running. from PyQt5.QtCore import QTimer timer = QTimer() timer.start(500) timer.timeout.connect(lambda: None) # Many strings are translated at import time, so this is why we only import after the translator # has been installed from qt.app import DupeGuru app.setWindowIcon(QIcon(QPixmap(":/{0}".format(DupeGuru.LOGO_NAME)))) global dgapp dgapp = DupeGuru() install_excepthook('https://github.com/hsoft/dupeguru/issues') result = app.exec() # I was getting weird crashes when quitting under Windows, and manually deleting main app # references with gc.collect() in between seems to fix the problem. del dgapp gc.collect() del app gc.collect() return result
def getThemeName(theme): settings = QSettings(theme, QSettings.IniFormat) if settings.contains("Name"): return settings.value("Name") else: return os.path.splitext(os.path.split(theme)[1])[0]
def getLastAccessedDirectory(self): sttgs = QSettings() lastDirectory = sttgs.value("lastAccessedDirectory", defaultValue=".", type=str) if lastDirectory != '.': print(qApp.translate("lastAccessedDirectoryInfo", "Last accessed directory \"{}\" loaded.").format( lastDirectory)) return lastDirectory
def playNotification(file): # getting user setting from persepolis_setting persepolis_setting = QSettings('persepolis_download_manager', 'persepolis') # enbling or disabling notification sound in persepolis_setting enable_notification = str(persepolis_setting.value('settings/sound')) # volume of notification in persepolis_setting(an integer between 0 to 100) volume_percent = int(persepolis_setting.value('settings/sound-volume')) # Paplay volume value must be between 0 (silent) and 65536 (100% volume) volume = int((65536 * volume_percent)/100) if enable_notification == 'yes': if os_type == 'Linux' or os_type == 'FreeBSD' or os_type == 'OpenBSD': answer = os.system("paplay --volume='" + str(volume) + "' '" + file + "' &") if answer != 0: print("paplay not installed!Install it for playing sound notification") logger.sendToLog( "paplay not installed!Install it for playing sound notification", "WARNING") elif os_type == 'Darwin': os.system("osascript -e 'set volume alert volume " + str(volume) + "'") os.system("osascript -e 'beep 3' &") elif os_type == 'Windows': CREATE_NO_WINDOW = 0x08000000 subprocess.Popen(['rundll32', 'user32.dll,MessageBeep'], shell=False, creationflags=CREATE_NO_WINDOW)
def start(self): file = self.destination.text().strip() if not file: QMessageBox.warning(self, self.tr("Create mobile collection"), self.tr("Destination file not specified")) return density = self.densitySelector.currentText() settings = QSettings() settings.setValue('density', density) self.params['filter'] = self.filterSelector.itemData(self.filterSelector.currentIndex()) self.params['density'] = density self.params['file'] = file if self.obverseRadio.isChecked(): self.params['image'] = self.IMAGE_OBVERSE elif self.reverseRadio.isChecked(): self.params['image'] = self.IMAGE_REVERSE elif self.noneRadio.isChecked(): self.params['image'] = self.IMAGE_NONE else: self.params['image'] = self.IMAGE_BOTH self.accept()
def run_command(cls, cmd, args=[], dir=None): """ run a git command and return its output as a string list. Raise an exception if it returns an error. - cmd is the git command (without 'git') - args is a string or a list of strings If no dir is passed the running dir of Frescobaldi is used as default """ dir = os.path.normpath(os.path.join(sys.path[0], '..')) if dir is None else dir from PyQt5.QtCore import QSettings s = QSettings() s.beginGroup("helper_applications") git_cmd = s.value("git", "git", str) git_cmd = git_cmd if git_cmd else "git" cmd = [git_cmd, cmd] cmd.extend(args) pr = subprocess.Popen(cmd, cwd=dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) (out, error) = pr.communicate() if error: raise GitError(error) result = out.split('\n') if result[-1] == '': result.pop() return result
def update_cmp_list(self, cd): keys = list( cd.keys() ) keys.sort( key=split_alphanumeric ) self.setRowCount(len(cd)) Settings = QSettings('kicad-tools', 'Schematic Component Manager') if Settings.contains('component-view'): CmpViewDict = Settings.value('component-view') else: CmpViewDict = {} for idx, k in enumerate( keys ): Ref = QTableWidgetItem(k) res = re.match('([a-zA-Z]+)\d+', k) Pattern = '$LibRef' if res: RefBase = res.groups()[0] if RefBase in CmpViewDict.keys(): Pattern = CmpViewDict[RefBase] cmp = cd[k][0] info_str = cmp.get_str_from_pattern(Pattern) Name = QTableWidgetItem(info_str) self.setItem(idx, 0, Ref) self.setItem(idx, 1, Name)
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 str(key).endswith("/Size"): size = str(indexReader.value(key)) dirList.append((size, unicode(key[:-5]))) parents = indexReader.value('Icon Theme/Inherits') dump=parents parents = list() parents.append(dump) break return QIconTheme(dirList, parents)
class MyMainWindow(QMainWindow, Ui_MainWindow): def __init__(self, parent=None): super(MyMainWindow, self).__init__(parent) self.setupUi(self) # 设置ini文件 self.settings = QSettings("./QtPad.ini", QSettings.IniFormat) self.lineEdit_dirSaveImage.setText(self.settings.value('dirSaveImage')) self.lineEdit_dirSaveAnnotation.setText( self.settings.value('dirSaveAnnotation')) self.lineEdit_RGBdirSaveImage.setText( self.settings.value('RGBdirSaveImage')) self.listWidget_image_list.clear() self.listWidget_image_list.addItems( self.getFileList(self.settings.value('dirSaveImage'))) self.cap_depth = None self.jump_frame = 1 self.last_choice = None self.dir_depth_video = None self.initUI() self.action_last_page.triggered.connect(self.last_page) self.action_next_page.triggered.connect(self.next_page) self.pushButton_delete_files.clicked.connect(self.delete_files) self.pushButton_dirSaveAnnotation.clicked.connect( self.change_dir_annotation) self.pushButton_dirSaveImage.clicked.connect(self.change_dir_image) self.pushButton_RGBdirSaveImage.clicked.connect( self.change_dir_RGBimage) self.pushButton_Head.clicked.connect(self.change_body_part) self.pushButton_LShouder.clicked.connect(self.change_body_part) self.pushButton_LAncon.clicked.connect(self.change_body_part) self.pushButton_LHand.clicked.connect(self.change_body_part) self.pushButton_RShouder.clicked.connect(self.change_body_part) self.pushButton_RAncon.clicked.connect(self.change_body_part) self.pushButton_RHand.clicked.connect(self.change_body_part) self.action_openImageFolder.triggered.connect(self.openImageFolder) self.action_openDepthVideo.triggered.connect(self.openDepthVideo) self.listWidget_image_list.itemClicked.connect(self.listChange) self.listWidget_image_list.setCurrentRow(0) self.listWidget_image_list.itemClicked.emit( self.listWidget_image_list.item(0)) self.update() def initUI(self): self.frame1 = MyShowWidget() self.frame1.setMinimumSize(QtCore.QSize(500, 500)) self.frame1.setObjectName("frame1") self.horizontalLayout.addWidget(self.frame1) self.frame1.myclicked.connect(self.update_frame2_annotation) self.frame2 = MyShowWidget() self.frame2.setMinimumSize(QtCore.QSize(500, 500)) self.frame2.setObjectName("frame2") self.horizontalLayout.addWidget(self.frame2) self.frame2.myclicked.connect(self.update_frame1_annotation) def last_page(self): if (self.listWidget_image_list.currentRow() > 0): self.listWidget_image_list.itemClicked.emit( self.listWidget_image_list.item( self.listWidget_image_list.currentRow() - 1)) self.listWidget_image_list.setCurrentRow( self.listWidget_image_list.currentRow() - 1) def next_page(self): self.listWidget_image_list.itemClicked.emit( self.listWidget_image_list.item( self.listWidget_image_list.currentRow() + 1)) self.listWidget_image_list.setCurrentRow( self.listWidget_image_list.currentRow() + 1) def delete_files(self): file = self.listWidget_image_list.currentItem().text() self.listWidget_image_list.takeItem( self.listWidget_image_list.currentRow()) self.listWidget_image_list.removeItemWidget( self.listWidget_image_list.currentItem()) self.listWidget_image_list.itemClicked.emit( self.listWidget_image_list.currentItem()) os.remove(self.lineEdit_RGBdirSaveImage.text() + '/' + file.split('/')[-1]) os.remove(file) def update_frame1_annotation(self, ann, x, y): self.frame1.dict_body[ann] = x, y self.frame1.update() def update_frame2_annotation(self, ann, x, y): self.frame2.dict_body[ann] = x, y self.frame2.update() def change_dir_annotation(self): dir = QFileDialog.getExistingDirectory( self, "选择标注保存路径", '/home/learn/PycharmProjects/test/') self.lineEdit_dirSaveAnnotation.setText(dir) def change_dir_image(self): dir = QFileDialog.getExistingDirectory( self, "选择图片保存路径", '/home/learn/PycharmProjects/test/') self.lineEdit_dirSaveImage.setText(dir) def change_dir_RGBimage(self): dir = QFileDialog.getExistingDirectory( self, "选择RGB图片保存路径", '/home/learn/PycharmProjects/test/') self.lineEdit_RGBdirSaveImage.setText(dir) def change_body_part(self): sender = self.sender() if not self.last_choice: self.last_choice = sender self.frame1.str_body = sender.objectName()[11:] self.frame2.str_body = sender.objectName()[11:] elif self.last_choice == sender: self.last_choice = None self.frame1.str_body = None self.frame2.str_body = None else: self.last_choice.setChecked(False) self.last_choice = sender self.frame1.str_body = sender.objectName()[11:] self.frame2.str_body = sender.objectName()[11:] self.frame1.update() self.frame2.update() def openImageFolder(self): dir = QFileDialog.getExistingDirectory(self, "打开", '/') def openDepthVideo(self): self.dir_depth_video, ok = QFileDialog.getOpenFileName( self, "打开", '/home/learn/PycharmProjects/test/', "All Files (*);;Video Files(*.avi)") if not self.cap_depth: self.cap_depth = cv2.VideoCapture(self.dir_depth_video) def closeEvent(self, event): self.settings.setValue("dirSaveImage", self.lineEdit_dirSaveImage.text()) self.settings.setValue("dirSaveAnnotation", self.lineEdit_dirSaveAnnotation.text()) self.settings.setValue("RGBdirSaveImage", self.lineEdit_RGBdirSaveImage.text()) del self.settings def getFileList(self, fileDir): _list = os.listdir(fileDir) # 列出文件夹下所有的目录与文件 dirlist = [] for i in range(0, len(_list)): path = os.path.join(fileDir, _list[i]) if os.path.isfile(path): dirlist.append(path) dirlist.sort() return dirlist def listChange(self, imageChoice): self.frame2.showImageFromDir( imageChoice.text(), self.lineEdit_RGBdirSaveImage.text() + '/' + imageChoice.text().split('/')[-1], self.lineEdit_dirSaveAnnotation.text() + '/' + imageChoice.text().split('/')[-1][:-4] + '.xml', 'depth') self.frame1.showImageFromDir( imageChoice.text(), self.lineEdit_RGBdirSaveImage.text() + '/' + imageChoice.text().split('/')[-1], self.lineEdit_dirSaveAnnotation.text() + '/' + imageChoice.text().split('/')[-1][:-4] + '.xml', 'color')
def writeSettings(self): s = QSettings() s.beginGroup('copy_image') s.setValue("dpi", self.dpiCombo.currentText()) s.setValue("papercolor", self.colorButton.color()) s.setValue("autocrop", self.crop.isChecked()) s.setValue("antialias", self.antialias.isChecked()) s.setValue("scaleup", self.scaleup.isChecked())
def remember_checked_handler(self): """ 记住密码状态改变 """ client_config_path = os.path.join(BASE_DIR, "dawn/client.ini") app_configs = QSettings(client_config_path, QSettings.IniFormat) state = self.login_widget.remember_psd.checkState() if state == Qt.Checked: phone = self.login_widget.phone_edit.text().strip() password = self.login_widget.password_edit.text().strip() encrypt_phone = base64.b64encode( phone.encode('utf-8')).decode('utf-8') encrypt_password = base64.b64encode( password.encode('utf-8')).decode('utf-8') app_configs.setValue("USER/USER", encrypt_phone) app_configs.setValue("USER/USERP", encrypt_password) else: app_configs.remove("USER/USER") app_configs.remove("USER/USERP") app_configs.remove("USER/AUTOLOGIN")
def save_account_settings(self): settings = QSettings() settings.setValue(SETTINGS_ACCOUNT, self.accountLineEdit.text()) settings.sync()
def closeApp(self): settings = QSettings() settings.setValue(SETTINGS_SIZE, self.size()) settings.setValue(SETTINGS_POS, self.pos()) settings.sync() sys.exit()
def __init__(self): super(QMainWindow, self).__init__() # Set up the user interface from Designer. self.setupUi(self) self.setAccessibleName("Hive Desktop") self.redrawLock = Lock() self.updateLock = Lock() self.optionsDialog = dialogs.Options(self) self.aboutDialog = dialogs.About(self, copyright='holger80', programName='Hive Desktop', version=VERSION, website='https://github.com/holgern/hivedesktop', websiteLabel='Github', comments='"Welcome to Hive desktop!\n This is the first release for testing qt5.\n Please vote for holger80 as witness, if you like this :).', licenseName='GPL-3.0', # licenseUrl=helpers.joinpath_to_cwd('LICENSE').as_uri(), authors=('holger80',), # dependencies=[l.strip() for l in requirements.readlines()], ) self.mdrenderer = MDRenderer(str(helpers.joinpath_to_cwd('themes'))) # tmpfile = helpers.mktemp(prefix='hivedesktop', suffix='.html') self.post = {"body": "##test", "authorperm": "@test/test"} self.thread = threads.MDThread(self) # self.webview.url = tmpfile.as_uri() self.feedListWidget.currentRowChanged.connect(self.change_displayed_post, Qt.QueuedConnection) self.timer = QTimer() self.timer.timeout.connect(self.refresh_account_thread) self.timer2 = QTimer() self.timer2.timeout.connect(self.update_account_hist_thread) self.timer3 = QTimer() self.timer3.timeout.connect(self.update_account_feed_thread) self.cache_path = QStandardPaths.writableLocation(QStandardPaths.CacheLocation) self.db_type = "shelve" self.db_type = "sqlite" self.feed = [] self.post = None # Get settings settings = QSettings() # Get checkbox state with speciying type of checkbox: # type=bool is a replacement of toBool() in PyQt5 check_state = settings.value(SETTINGS_TRAY, True, type=bool) hist_info_check_state = settings.value(SETTINGS_HIST_INFO, True, type=bool) account_state = settings.value(SETTINGS_ACCOUNT, "", type=str) self.resize(settings.value(SETTINGS_SIZE, QSize(1053, 800))) self.move(settings.value(SETTINGS_POS, QPoint(50, 50))) #self.accountHistTableWidget.setColumnCount(5) #self.accountHistTableWidget.setHorizontalHeaderLabels(["type", "1", "2", "3", "timestamp"]) self.update_account_refreshtime = 5000 # Set state self.accountHistNotificationCheckBox.setChecked(hist_info_check_state) self.autoRefreshCheckBox.setChecked(check_state) if check_state: self.timer.start(self.update_account_refreshtime) self.timer2.start(15000) self.timer3.start(60000) self.accountLineEdit.setText(account_state) # connect the slot to the signal by clicking the checkbox to save the state settings self.autoRefreshCheckBox.clicked.connect(self.save_check_box_settings) self.accountHistNotificationCheckBox.clicked.connect(self.save_check_box_settings) self.accountLineEdit.editingFinished.connect(self.save_account_settings) self.actionAbout.triggered.connect(self.about) self.actionOptions.triggered.connect(self.options) self.threadpool = QThreadPool() self.minimizeAction = QAction("Mi&nimize", self, triggered=self.hide) self.maximizeAction = QAction("Ma&ximize", self, triggered=self.showMaximized) self.restoreAction = QAction("&Restore", self, triggered=self.showNormal) menu = QMenu() menu.addAction(self.minimizeAction) menu.addAction(self.maximizeAction) menu.addAction(self.restoreAction) menu.addSeparator() # aboutAction = menu.addAction("about") # aboutAction.triggered.connect(self.about) exitAction = menu.addAction("Exit") exitAction.triggered.connect(self.closeApp) self.tray = QSystemTrayIcon(QIcon(':/icons/icon.ico')) self.tray.setContextMenu(menu) self.tray.activated.connect(self.trayAction) self.tray.setToolTip("Hive Desktop!") self.tray.setObjectName("Hive Desktop") self.setWindowTitle("Hive Desktop") self.tray.show() splash_pix = QPixmap(':/icons/splash.png') splash = QSplashScreen(splash_pix, Qt.WindowStaysOnTopHint) splash.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint) splash.setEnabled(False) #splash.show() #splash.showMessage("<h1><font color='green'>starting...</font></h1>", Qt.AlignTop | Qt.AlignCenter, Qt.black) account = account_state nodelist = NodeList() nodelist.update_nodes() self.stm = Steem(node=nodelist.get_nodes(hive=True)) set_shared_blockchain_instance(self.stm) if account != "": try: self.hist_account = Account(account, steem_instance=self.stm) except: self.hist_account = None else: self.hist_account = None self.refreshPushButton.clicked.connect(self.refresh_account) self.refreshPushButton.clicked.connect(self.update_account_hist_thread) self.accountLineEdit.editingFinished.connect(self.update_account_info) if self.hasFocus is not None: self.init_new_account() self.init_new_blocks() splash.deleteLater()
def chunks(l, n): for i in range(0, len(l), n): yield l[i:i + n] QCoreApplication.setOrganizationName("QGIS") QCoreApplication.setOrganizationDomain("qgis.org") QCoreApplication.setApplicationName("QGIS3") if len(sys.argv) == 1: print("Usage: ./scripts/mkuidefaults.py \"location_to_ini\"") sys.exit(1) s = QSettings(sys.argv[1], QSettings.IniFormat) ba = bytes(s.value("/UI/geometry")) print with open("src/app/ui_defaults.h", "w") as f: f.write("#ifndef UI_DEFAULTS_H\n#define UI_DEFAULTS_H\n" + "\nstatic const unsigned char defaultUIgeometry[] =\n{\n") for chunk in chunks(ba, 16): f.write(' {},\n'.format( ', '.join(map(hex, struct.unpack('B' * len(chunk), chunk))))) f.write("};\n\nstatic const unsigned char defaultUIstate[] =\n{\n")
def update(): # APPLICATION ------------------------------------------------------------------------------------------ appSettings = QSettings(COMPANY, APPLICATION) # Saving preferences appSettings.setValue('auto_connect_output', auto_connect_output) appSettings.setValue('auto_connect_input', auto_connect_input) # save mixer settings appSettings.setValue('save_mixerstrip_gain', save_mixerstrip_gain) appSettings.setValue('save_mixerstrip_send1', save_mixerstrip_send1) appSettings.setValue('save_mixerstrip_send2', save_mixerstrip_send2) appSettings.setValue('save_mixerstrip_volume', save_mixerstrip_volume) appSettings.setValue('save_mixerstrip_mute', save_mixerstrip_mute) appSettings.setValue('save_mixerstrip_to_master', save_mixerstrip_to_master) # customreset appSettings.setValue('customreset_mixerstrip_gain', customreset_mixerstrip_gain) appSettings.setValue('customreset_mixerstrip_send1', customreset_mixerstrip_send1) appSettings.setValue('customreset_mixerstrip_send2', customreset_mixerstrip_send2) appSettings.setValue('customreset_mixerstrip_volume', customreset_mixerstrip_volume) appSettings.setValue('customreset_mixerstrip_mute', customreset_mixerstrip_mute) # Performance appSettings.setValue('disable_shift_after_processing', disable_shift_after_processing) appSettings.setValue('show_clip_details_on_trigger', show_clip_details_on_trigger) appSettings.setValue('use_big_fonts_playlist', use_big_fonts_playlist) appSettings.setValue('use_big_fonts_scenes', use_big_fonts_scenes) appSettings.setValue('allow_record_empty_clip', allow_record_empty_clip) appSettings.setValue('auto_assign_new_clip_column', auto_assign_new_clip_column) appSettings.setValue('play_clip_after_record', play_clip_after_record) appSettings.setValue('show_scenes_on_start', show_scenes_on_start) appSettings.setValue('show_playlist_on_start', show_playlist_on_start) appSettings.setValue('show_song_annotation_on_load', show_song_annotation_on_load) appSettings.setValue('slower_processing', slower_processing) appSettings.setValue('system_monitoring', system_monitoring) appSettings.setValue('rec_color', rec_color) appSettings.setValue('grid_rows', str(grid_rows)) appSettings.setValue('grid_columns', str(grid_columns)) appSettings.setValue('bigFontSize', str(bigFontSize)) appSettings.setValue('new_song_master_volume', str(new_song_master_volume)) appSettings.setValue('new_song_bpm', str(new_song_bpm)) appSettings.setValue('new_song_beats', str(new_song_beats)) appSettings.setValue('prevent_song_save', prevent_song_save) # and windows position and geometry appSettings.setValue("gui_geometry", gui_geometry) appSettings.setValue("scenes_geometry", scenes_geometry) appSettings.setValue("playlist_geometry", playlist_geometry) appSettings.setValue("song_annotation_geometry", song_annotation_geometry) appSettings.setValue("mixer_geometry", mixer_geometry) # session appSettings.setValue('paths_used', paths_used) appSettings.value('playlist', playlist) appSettings.sync() # DEVICE --------------------------------------------------------------------------------------------- devSettings = QSettings(COMPANY, DEVICES) devSettings.setValue('devices', devices) devSettings.sync() # PORTS --------------------------------------------------------------------------------------------- portSettings = QSettings(COMPANY, PORTS) portSettings.setValue('output_ports', output_ports) portSettings.setValue('master_port_final_volume', str(master_port_final_volume)) portSettings.setValue('master_port_mute', master_port_mute) portSettings.sync()
class TriblerWindow(QMainWindow): resize_event = pyqtSignal() escape_pressed = pyqtSignal() received_search_completions = pyqtSignal(object) def on_exception(self, *exc_info): if self.exception_handler_called: # We only show one feedback dialog, even when there are two consecutive exceptions. return self.exception_handler_called = True self.delete_tray_icon() # Stop the download loop self.downloads_page.stop_loading_downloads() # Add info about whether we are stopping Tribler or not os.environ['TRIBLER_SHUTTING_DOWN'] = str( self.core_manager.shutting_down) if not self.core_manager.shutting_down: self.core_manager.stop(stop_app_on_shutdown=False) self.setHidden(True) if self.debug_window: self.debug_window.setHidden(True) exception_text = "".join(traceback.format_exception(*exc_info)) logging.error(exception_text) dialog = FeedbackDialog( self, exception_text, self.core_manager.events_manager.tribler_version, self.start_time) dialog.show() def __init__(self, core_args=None, core_env=None, api_port=None): QMainWindow.__init__(self) QCoreApplication.setOrganizationDomain("nl") QCoreApplication.setOrganizationName("TUDelft") QCoreApplication.setApplicationName("Tribler") QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) self.gui_settings = QSettings() api_port = api_port or int( get_gui_setting(self.gui_settings, "api_port", DEFAULT_API_PORT)) dispatcher.update_worker_settings(port=api_port) self.navigation_stack = [] self.tribler_started = False self.tribler_settings = None self.debug_window = None self.core_manager = CoreManager(api_port) self.pending_requests = {} self.pending_uri_requests = [] self.download_uri = None self.dialog = None self.new_version_dialog = None self.start_download_dialog_active = False self.request_mgr = None self.search_request_mgr = None self.search_suggestion_mgr = None self.selected_torrent_files = [] self.vlc_available = True self.has_search_results = False self.last_search_query = None self.last_search_time = None self.start_time = time.time() self.exception_handler_called = False self.token_refresh_timer = None sys.excepthook = self.on_exception uic.loadUi(get_ui_file_path('mainwindow.ui'), self) TriblerRequestManager.window = self self.tribler_status_bar.hide() # Load dynamic widgets uic.loadUi(get_ui_file_path('torrent_channel_list_container.ui'), self.channel_page_container) self.channel_torrents_list = self.channel_page_container.items_list self.channel_torrents_detail_widget = self.channel_page_container.details_tab_widget self.channel_torrents_detail_widget.initialize_details_widget() self.channel_torrents_list.itemSelectionChanged.connect( self.channel_page.clicked_item) uic.loadUi(get_ui_file_path('torrent_channel_list_container.ui'), self.search_page_container) self.search_results_list = self.search_page_container.items_list self.search_torrents_detail_widget = self.search_page_container.details_tab_widget self.search_torrents_detail_widget.initialize_details_widget() self.search_results_list.itemClicked.connect( self.on_channel_item_click) self.search_results_list.itemSelectionChanged.connect( self.search_results_page.clicked_item) self.token_balance_widget.mouseReleaseEvent = self.on_token_balance_click def on_state_update(new_state): self.loading_text_label.setText(new_state) self.core_manager.core_state_update.connect(on_state_update) self.magnet_handler = MagnetHandler(self.window) QDesktopServices.setUrlHandler("magnet", self.magnet_handler, "on_open_magnet_link") self.debug_pane_shortcut = QShortcut(QKeySequence("Ctrl+d"), self) self.debug_pane_shortcut.activated.connect( self.clicked_menu_button_debug) # Remove the focus rect on OS X for widget in self.findChildren(QLineEdit) + self.findChildren( QListWidget) + self.findChildren(QTreeWidget): widget.setAttribute(Qt.WA_MacShowFocusRect, 0) self.menu_buttons = [ self.left_menu_button_home, self.left_menu_button_search, self.left_menu_button_my_channel, self.left_menu_button_subscriptions, self.left_menu_button_video_player, self.left_menu_button_downloads, self.left_menu_button_discovered ] self.video_player_page.initialize_player() self.search_results_page.initialize_search_results_page() self.settings_page.initialize_settings_page() self.subscribed_channels_page.initialize() self.edit_channel_page.initialize_edit_channel_page() self.downloads_page.initialize_downloads_page() self.home_page.initialize_home_page() self.loading_page.initialize_loading_page() self.discovering_page.initialize_discovering_page() self.discovered_page.initialize_discovered_page() self.trust_page.initialize_trust_page() self.stackedWidget.setCurrentIndex(PAGE_LOADING) # Create the system tray icon if QSystemTrayIcon.isSystemTrayAvailable(): self.tray_icon = QSystemTrayIcon() use_monochrome_icon = get_gui_setting(self.gui_settings, "use_monochrome_icon", False, is_bool=True) self.update_tray_icon(use_monochrome_icon) # Create the tray icon menu menu = self.create_add_torrent_menu() show_downloads_action = QAction('Show downloads', self) show_downloads_action.triggered.connect( self.clicked_menu_button_downloads) token_balance_action = QAction('Show token balance', self) token_balance_action.triggered.connect( lambda: self.on_token_balance_click(None)) quit_action = QAction('Quit Tribler', self) quit_action.triggered.connect(self.close_tribler) menu.addSeparator() menu.addAction(show_downloads_action) menu.addAction(token_balance_action) menu.addSeparator() menu.addAction(quit_action) self.tray_icon.setContextMenu(menu) else: self.tray_icon = None self.hide_left_menu_playlist() self.left_menu_button_debug.setHidden(True) self.top_menu_button.setHidden(True) self.left_menu.setHidden(True) self.token_balance_widget.setHidden(True) self.settings_button.setHidden(True) self.add_torrent_button.setHidden(True) self.top_search_bar.setHidden(True) # Set various icons self.top_menu_button.setIcon(QIcon(get_image_path('menu.png'))) self.search_completion_model = QStringListModel() completer = QCompleter() completer.setModel(self.search_completion_model) completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) self.item_delegate = QStyledItemDelegate() completer.popup().setItemDelegate(self.item_delegate) completer.popup().setStyleSheet(""" QListView { background-color: #404040; } QListView::item { color: #D0D0D0; padding-top: 5px; padding-bottom: 5px; } QListView::item:hover { background-color: #707070; } """) self.top_search_bar.setCompleter(completer) # Toggle debug if developer mode is enabled self.window().left_menu_button_debug.setHidden(not get_gui_setting( self.gui_settings, "debug", False, is_bool=True)) # Start Tribler self.core_manager.start(core_args=core_args, core_env=core_env) self.core_manager.events_manager.received_search_result_channel.connect( self.search_results_page.received_search_result_channel) self.core_manager.events_manager.received_search_result_torrent.connect( self.search_results_page.received_search_result_torrent) self.core_manager.events_manager.torrent_finished.connect( self.on_torrent_finished) self.core_manager.events_manager.new_version_available.connect( self.on_new_version_available) self.core_manager.events_manager.tribler_started.connect( self.on_tribler_started) self.core_manager.events_manager.events_started.connect( self.on_events_started) self.core_manager.events_manager.low_storage_signal.connect( self.on_low_storage) self.core_manager.events_manager.credit_mining_signal.connect( self.on_credit_mining_error) # Install signal handler for ctrl+c events def sigint_handler(*_): self.close_tribler() signal.signal(signal.SIGINT, sigint_handler) self.installEventFilter(self.video_player_page) # Resize the window according to the settings center = QApplication.desktop().availableGeometry(self).center() pos = self.gui_settings.value( "pos", QPoint(center.x() - self.width() * 0.5, center.y() - self.height() * 0.5)) size = self.gui_settings.value("size", self.size()) self.move(pos) self.resize(size) self.show() def update_tray_icon(self, use_monochrome_icon): if not QSystemTrayIcon.isSystemTrayAvailable(): return if use_monochrome_icon: self.tray_icon.setIcon( QIcon(QPixmap(get_image_path('monochrome_tribler.png')))) else: self.tray_icon.setIcon( QIcon(QPixmap(get_image_path('tribler.png')))) self.tray_icon.show() def delete_tray_icon(self): if self.tray_icon: try: self.tray_icon.deleteLater() except RuntimeError: # The tray icon might have already been removed when unloading Qt. # This is due to the C code actually being asynchronous. logging.debug( "Tray icon already removed, no further deletion necessary." ) self.tray_icon = None def on_low_storage(self): """ Dealing with low storage space available. First stop the downloads and the core manager and ask user to user to make free space. :return: """ self.downloads_page.stop_loading_downloads() self.core_manager.stop(False) close_dialog = ConfirmationDialog( self.window(), "<b>CRITICAL ERROR</b>", "You are running low on disk space (<100MB). Please make sure to have " "sufficient free space available and restart Tribler again.", [("Close Tribler", BUTTON_TYPE_NORMAL)]) close_dialog.button_clicked.connect(lambda _: self.close_tribler()) close_dialog.show() def on_torrent_finished(self, torrent_info): self.tray_show_message( "Download finished", "Download of %s has finished." % torrent_info["name"]) def show_loading_screen(self): self.top_menu_button.setHidden(True) self.left_menu.setHidden(True) self.token_balance_widget.setHidden(True) self.settings_button.setHidden(True) self.add_torrent_button.setHidden(True) self.top_search_bar.setHidden(True) self.stackedWidget.setCurrentIndex(PAGE_LOADING) def tray_set_tooltip(self, message): """ Set a tooltip message for the tray icon, if possible. :param message: the message to display on hover """ if self.tray_icon: try: self.tray_icon.setToolTip(message) except RuntimeError as e: logging.error("Failed to set tray tooltip: %s", str(e)) def tray_show_message(self, title, message): """ Show a message at the tray icon, if possible. :param title: the title of the message :param message: the message to display """ if self.tray_icon: try: self.tray_icon.showMessage(title, message) except RuntimeError as e: logging.error("Failed to set tray message: %s", str(e)) def on_tribler_started(self): self.tribler_started = True self.top_menu_button.setHidden(False) self.left_menu.setHidden(False) self.token_balance_widget.setHidden(False) self.settings_button.setHidden(False) self.add_torrent_button.setHidden(False) self.top_search_bar.setHidden(False) # fetch the settings, needed for the video player port self.request_mgr = TriblerRequestManager() self.fetch_settings() self.downloads_page.start_loading_downloads() self.home_page.load_popular_torrents() if not self.gui_settings.value( "first_discover", False) and not self.core_manager.use_existing_core: self.window().gui_settings.setValue("first_discover", True) self.discovering_page.is_discovering = True self.stackedWidget.setCurrentIndex(PAGE_DISCOVERING) else: self.clicked_menu_button_home() self.setAcceptDrops(True) def on_events_started(self, json_dict): self.setWindowTitle("Tribler %s" % json_dict["version"]) def show_status_bar(self, message): self.tribler_status_bar_label.setText(message) self.tribler_status_bar.show() def hide_status_bar(self): self.tribler_status_bar.hide() def process_uri_request(self): """ Process a URI request if we have one in the queue. """ if len(self.pending_uri_requests) == 0: return uri = self.pending_uri_requests.pop() if uri.startswith('file') or uri.startswith('magnet'): self.start_download_from_uri(uri) def perform_start_download_request(self, uri, anon_download, safe_seeding, destination, selected_files, total_files=0, callback=None): # Check if destination directory is writable is_writable, error = is_dir_writable(destination) if not is_writable: gui_error_message = "Insufficient write permissions to <i>%s</i> directory. Please add proper " \ "write permissions on the directory and add the torrent again. %s" \ % (destination, error) ConfirmationDialog.show_message(self.window(), "Download error <i>%s</i>" % uri, gui_error_message, "OK") return selected_files_uri = "" if len(selected_files) != total_files: # Not all files included selected_files_uri = u'&' + u''.join( u"selected_files[]=%s&" % quote_plus_unicode(filename) for filename in selected_files)[:-1] anon_hops = int(self.tribler_settings['download_defaults'] ['number_hops']) if anon_download else 0 safe_seeding = 1 if safe_seeding else 0 post_data = "uri=%s&anon_hops=%d&safe_seeding=%d&destination=%s%s" % ( quote_plus_unicode(uri), anon_hops, safe_seeding, destination, selected_files_uri) post_data = post_data.encode( 'utf-8') # We need to send bytes in the request, not unicode request_mgr = TriblerRequestManager() request_mgr.perform_request( "downloads", callback if callback else self.on_download_added, method='PUT', data=post_data) # Save the download location to the GUI settings current_settings = get_gui_setting(self.gui_settings, "recent_download_locations", "") recent_locations = current_settings.split( ",") if len(current_settings) > 0 else [] if isinstance(destination, unicode): destination = destination.encode('utf-8') encoded_destination = destination.encode('hex') if encoded_destination in recent_locations: recent_locations.remove(encoded_destination) recent_locations.insert(0, encoded_destination) if len(recent_locations) > 5: recent_locations = recent_locations[:5] self.gui_settings.setValue("recent_download_locations", ','.join(recent_locations)) def on_new_version_available(self, version): if version == str(self.gui_settings.value('last_reported_version')): return self.new_version_dialog = ConfirmationDialog( self, "New version available", "Version %s of Tribler is available.Do you want to visit the " "website to download the newest version?" % version, [('IGNORE', BUTTON_TYPE_NORMAL), ('LATER', BUTTON_TYPE_NORMAL), ('OK', BUTTON_TYPE_NORMAL)]) self.new_version_dialog.button_clicked.connect( lambda action: self.on_new_version_dialog_done(version, action)) self.new_version_dialog.show() def on_new_version_dialog_done(self, version, action): if action == 0: # ignore self.gui_settings.setValue("last_reported_version", version) elif action == 2: # ok import webbrowser webbrowser.open("https://tribler.org") if self.new_version_dialog: self.new_version_dialog.close_dialog() self.new_version_dialog = None def on_search_text_change(self, text): self.search_suggestion_mgr = TriblerRequestManager() self.search_suggestion_mgr.perform_request( "search/completions?q=%s" % text, self.on_received_search_completions) def on_received_search_completions(self, completions): if completions is None: return self.received_search_completions.emit(completions) self.search_completion_model.setStringList(completions["completions"]) def fetch_settings(self): self.request_mgr = TriblerRequestManager() self.request_mgr.perform_request("settings", self.received_settings, capture_errors=False) def received_settings(self, settings): if not settings: return # If we cannot receive the settings, stop Tribler with an option to send the crash report. if 'error' in settings: raise RuntimeError( TriblerRequestManager.get_message_from_error(settings)) self.tribler_settings = settings['settings'] # Set the video server port self.video_player_page.video_player_port = settings["ports"][ "video_server~port"] # Disable various components based on the settings if not self.tribler_settings['search_community']['enabled']: self.window().top_search_bar.setHidden(True) if not self.tribler_settings['video_server']['enabled']: self.left_menu_button_video_player.setHidden(True) self.downloads_creditmining_button.setHidden( not self.tribler_settings["credit_mining"]["enabled"]) self.downloads_all_button.click() # process pending file requests (i.e. someone clicked a torrent file when Tribler was closed) # We do this after receiving the settings so we have the default download location. self.process_uri_request() # Set token balance refresh timer and load the token balance self.token_refresh_timer = QTimer() self.token_refresh_timer.timeout.connect(self.load_token_balance) self.token_refresh_timer.start(60000) self.load_token_balance() def on_top_search_button_click(self): current_ts = time.time() current_search_query = self.top_search_bar.text() if self.last_search_query and self.last_search_time \ and self.last_search_query == self.top_search_bar.text() \ and current_ts - self.last_search_time < 1: logging.info( "Same search query already sent within 500ms so dropping this one" ) return self.left_menu_button_search.setChecked(True) self.has_search_results = True self.clicked_menu_button_search() self.search_results_page.perform_search(current_search_query) self.search_request_mgr = TriblerRequestManager() self.search_request_mgr.perform_request( "search?q=%s" % current_search_query, None) self.last_search_query = current_search_query self.last_search_time = current_ts def on_settings_button_click(self): self.deselect_all_menu_buttons() self.stackedWidget.setCurrentIndex(PAGE_SETTINGS) self.settings_page.load_settings() self.navigation_stack = [] self.hide_left_menu_playlist() def on_token_balance_click(self, _): self.raise_window() self.deselect_all_menu_buttons() self.stackedWidget.setCurrentIndex(PAGE_TRUST) self.load_token_balance() self.trust_page.load_blocks() self.navigation_stack = [] self.hide_left_menu_playlist() def load_token_balance(self): self.request_mgr = TriblerRequestManager() self.request_mgr.perform_request("trustchain/statistics", self.received_trustchain_statistics, capture_errors=False) def received_trustchain_statistics(self, statistics): if not statistics or "statistics" not in statistics: return self.trust_page.received_trustchain_statistics(statistics) statistics = statistics["statistics"] if 'latest_block' in statistics: balance = (statistics["latest_block"]["transaction"]["total_up"] - statistics["latest_block"]["transaction"]["total_down"]) self.set_token_balance(balance) else: self.token_balance_label.setText("0 MB") # If trust page is currently visible, then load the graph as well if self.stackedWidget.currentIndex() == PAGE_TRUST: self.trust_page.load_blocks() def set_token_balance(self, balance): if abs(balance) > 1024**4: # Balance is over a TB balance /= 1024.0**4 self.token_balance_label.setText("%.1f TB" % balance) elif abs(balance) > 1024**3: # Balance is over a GB balance /= 1024.0**3 self.token_balance_label.setText("%.1f GB" % balance) else: balance /= 1024.0**2 self.token_balance_label.setText("%d MB" % balance) def raise_window(self): self.setWindowState(self.windowState() & ~Qt.WindowMinimized | Qt.WindowActive) self.raise_() self.activateWindow() def create_add_torrent_menu(self): """ Create a menu to add new torrents. Shows when users click on the tray icon or the big plus button. """ menu = TriblerActionMenu(self) browse_files_action = QAction('Import torrent from file', self) browse_directory_action = QAction('Import torrent(s) from directory', self) add_url_action = QAction('Import torrent from magnet/URL', self) browse_files_action.triggered.connect(self.on_add_torrent_browse_file) browse_directory_action.triggered.connect( self.on_add_torrent_browse_dir) add_url_action.triggered.connect(self.on_add_torrent_from_url) menu.addAction(browse_files_action) menu.addAction(browse_directory_action) menu.addAction(add_url_action) return menu def on_add_torrent_button_click(self, pos): self.create_add_torrent_menu().exec_( self.mapToGlobal(self.add_torrent_button.pos())) def on_add_torrent_browse_file(self): filenames = QFileDialog.getOpenFileNames( self, "Please select the .torrent file", QDir.homePath(), "Torrent files (*.torrent)") if len(filenames[0]) > 0: [ self.pending_uri_requests.append(u"file:%s" % filename) for filename in filenames[0] ] self.process_uri_request() def start_download_from_uri(self, uri): self.download_uri = uri if get_gui_setting(self.gui_settings, "ask_download_settings", True, is_bool=True): # If tribler settings is not available, fetch the settings and inform the user to try again. if not self.tribler_settings: self.fetch_settings() ConfirmationDialog.show_error( self, "Download Error", "Tribler settings is not available yet. " "Fetching it now. Please try again later.") return # Clear any previous dialog if exists if self.dialog: self.dialog.close_dialog() self.dialog = None self.dialog = StartDownloadDialog(self, self.download_uri) self.dialog.button_clicked.connect(self.on_start_download_action) self.dialog.show() self.start_download_dialog_active = True else: # In the unlikely scenario that tribler settings are not available yet, try to fetch settings again and # add the download uri back to self.pending_uri_requests to process again. if not self.tribler_settings: self.fetch_settings() if self.download_uri not in self.pending_uri_requests: self.pending_uri_requests.append(self.download_uri) return self.window().perform_start_download_request( self.download_uri, self.window().tribler_settings['download_defaults'] ['anonymity_enabled'], self.window().tribler_settings['download_defaults'] ['safeseeding_enabled'], self.tribler_settings['download_defaults']['saveas'], [], 0) self.process_uri_request() def on_start_download_action(self, action): if action == 1: if self.dialog and self.dialog.dialog_widget: self.window().perform_start_download_request( self.download_uri, self.dialog.dialog_widget.anon_download_checkbox.isChecked( ), self.dialog.dialog_widget.safe_seed_checkbox.isChecked(), self.dialog.dialog_widget.destination_input.currentText(), self.dialog.get_selected_files(), self.dialog.dialog_widget.files_list_view. topLevelItemCount()) else: ConfirmationDialog.show_error( self, "Tribler UI Error", "Something went wrong. Please try again.") logging.exception( "Error while trying to download. Either dialog or dialog.dialog_widget is None" ) self.dialog.request_mgr.cancel_request( ) # To abort the torrent info request self.dialog.close_dialog() self.dialog = None self.start_download_dialog_active = False if action == 0: # We do this after removing the dialog since process_uri_request is blocking self.process_uri_request() def on_add_torrent_browse_dir(self): chosen_dir = QFileDialog.getExistingDirectory( self, "Please select the directory containing the .torrent files", QDir.homePath(), QFileDialog.ShowDirsOnly) if len(chosen_dir) != 0: self.selected_torrent_files = [ torrent_file for torrent_file in glob.glob(chosen_dir + "/*.torrent") ] self.dialog = ConfirmationDialog( self, "Add torrents from directory", "Are you sure you want to add %d torrents to Tribler?" % len(self.selected_torrent_files), [('ADD', BUTTON_TYPE_NORMAL), ('CANCEL', BUTTON_TYPE_CONFIRM)]) self.dialog.button_clicked.connect( self.on_confirm_add_directory_dialog) self.dialog.show() def on_confirm_add_directory_dialog(self, action): if action == 0: for torrent_file in self.selected_torrent_files: escaped_uri = u"file:%s" % pathname2url(torrent_file) self.perform_start_download_request( escaped_uri, self.window().tribler_settings['download_defaults'] ['anonymity_enabled'], self.window().tribler_settings['download_defaults'] ['safeseeding_enabled'], self.tribler_settings['download_defaults']['saveas'], [], 0) if self.dialog: self.dialog.close_dialog() self.dialog = None def on_add_torrent_from_url(self): # Make sure that the window is visible (this action might be triggered from the tray icon) self.raise_window() if self.video_player_page.isVisible(): # If we're adding a torrent from the video player page, go to the home page. # This is necessary since VLC takes the screen and the popup becomes invisible. self.clicked_menu_button_home() self.dialog = ConfirmationDialog( self, "Add torrent from URL/magnet link", "Please enter the URL/magnet link in the field below:", [('ADD', BUTTON_TYPE_NORMAL), ('CANCEL', BUTTON_TYPE_CONFIRM)], show_input=True) self.dialog.dialog_widget.dialog_input.setPlaceholderText( 'URL/magnet link') self.dialog.dialog_widget.dialog_input.setFocus() self.dialog.button_clicked.connect( self.on_torrent_from_url_dialog_done) self.dialog.show() def on_torrent_from_url_dialog_done(self, action): if self.dialog and self.dialog.dialog_widget: uri = self.dialog.dialog_widget.dialog_input.text() # Remove first dialog self.dialog.close_dialog() self.dialog = None if action == 0: self.start_download_from_uri(uri) def on_download_added(self, result): if not result: return if len(self.pending_uri_requests ) == 0: # Otherwise, we first process the remaining requests. self.window().left_menu_button_downloads.click() else: self.process_uri_request() def on_top_menu_button_click(self): if self.left_menu.isHidden(): self.left_menu.show() else: self.left_menu.hide() def deselect_all_menu_buttons(self, except_select=None): for button in self.menu_buttons: if button == except_select: button.setEnabled(False) continue button.setEnabled(True) if button == self.left_menu_button_search and not self.has_search_results: button.setEnabled(False) button.setChecked(False) def clicked_menu_button_home(self): self.deselect_all_menu_buttons(self.left_menu_button_home) self.stackedWidget.setCurrentIndex(PAGE_HOME) self.navigation_stack = [] self.hide_left_menu_playlist() def clicked_menu_button_search(self): self.deselect_all_menu_buttons(self.left_menu_button_search) self.stackedWidget.setCurrentIndex(PAGE_SEARCH_RESULTS) self.navigation_stack = [] self.hide_left_menu_playlist() def clicked_menu_button_discovered(self): self.deselect_all_menu_buttons(self.left_menu_button_discovered) self.stackedWidget.setCurrentIndex(PAGE_DISCOVERED) self.discovered_page.load_discovered_channels() self.navigation_stack = [] self.hide_left_menu_playlist() def clicked_menu_button_my_channel(self): self.deselect_all_menu_buttons(self.left_menu_button_my_channel) self.stackedWidget.setCurrentIndex(PAGE_EDIT_CHANNEL) self.edit_channel_page.load_my_channel_overview() self.navigation_stack = [] self.hide_left_menu_playlist() def clicked_menu_button_video_player(self): self.deselect_all_menu_buttons(self.left_menu_button_video_player) self.stackedWidget.setCurrentIndex(PAGE_VIDEO_PLAYER) self.navigation_stack = [] self.show_left_menu_playlist() def clicked_menu_button_downloads(self): self.raise_window() self.left_menu_button_downloads.setChecked(True) self.deselect_all_menu_buttons(self.left_menu_button_downloads) self.stackedWidget.setCurrentIndex(PAGE_DOWNLOADS) self.navigation_stack = [] self.hide_left_menu_playlist() def clicked_menu_button_debug(self): if not self.debug_window: self.debug_window = DebugWindow( self.tribler_settings, self.core_manager.events_manager.tribler_version) self.debug_window.show() def clicked_menu_button_subscriptions(self): self.deselect_all_menu_buttons(self.left_menu_button_subscriptions) self.subscribed_channels_page.load_subscribed_channels() self.stackedWidget.setCurrentIndex(PAGE_SUBSCRIBED_CHANNELS) self.navigation_stack = [] self.hide_left_menu_playlist() def hide_left_menu_playlist(self): self.left_menu_seperator.setHidden(True) self.left_menu_playlist_label.setHidden(True) self.left_menu_playlist.setHidden(True) def show_left_menu_playlist(self): self.left_menu_seperator.setHidden(False) self.left_menu_playlist_label.setHidden(False) self.left_menu_playlist.setHidden(False) def on_channel_item_click(self, channel_list_item): list_widget = channel_list_item.listWidget() from TriblerGUI.widgets.channel_list_item import ChannelListItem if isinstance(list_widget.itemWidget(channel_list_item), ChannelListItem): channel_info = channel_list_item.data(Qt.UserRole) self.channel_page.initialize_with_channel(channel_info) self.navigation_stack.append(self.stackedWidget.currentIndex()) self.stackedWidget.setCurrentIndex(PAGE_CHANNEL_DETAILS) def on_playlist_item_click(self, playlist_list_item): list_widget = playlist_list_item.listWidget() from TriblerGUI.widgets.playlist_list_item import PlaylistListItem if isinstance(list_widget.itemWidget(playlist_list_item), PlaylistListItem): playlist_info = playlist_list_item.data(Qt.UserRole) self.playlist_page.initialize_with_playlist(playlist_info) self.navigation_stack.append(self.stackedWidget.currentIndex()) self.stackedWidget.setCurrentIndex(PAGE_PLAYLIST_DETAILS) def on_page_back_clicked(self): try: prev_page = self.navigation_stack.pop() self.stackedWidget.setCurrentIndex(prev_page) if prev_page == PAGE_SEARCH_RESULTS: self.stackedWidget.widget( prev_page).load_search_results_in_list() if prev_page == PAGE_SUBSCRIBED_CHANNELS: self.stackedWidget.widget(prev_page).load_subscribed_channels() if prev_page == PAGE_DISCOVERED: self.stackedWidget.widget(prev_page).load_discovered_channels() except IndexError: logging.exception("Unknown page found in stack") def on_credit_mining_error(self, error): ConfirmationDialog.show_error(self, "Credit Mining Error", error[u'message']) def on_edit_channel_clicked(self): self.stackedWidget.setCurrentIndex(PAGE_EDIT_CHANNEL) self.navigation_stack = [] self.channel_page.on_edit_channel_clicked() def resizeEvent(self, _): # Resize home page cells cell_width = self.home_page_table_view.width( ) / 3 - 3 # We have some padding to the right cell_height = cell_width / 2 + 60 for i in range(0, 3): self.home_page_table_view.setColumnWidth(i, cell_width) self.home_page_table_view.setRowHeight(i, cell_height) self.resize_event.emit() def exit_full_screen(self): self.top_bar.show() self.left_menu.show() self.video_player_page.is_full_screen = False self.showNormal() def close_tribler(self): if not self.core_manager.shutting_down: def show_force_shutdown(): self.loading_text_label.setText( "Tribler is taking longer than expected to shut down. You can force " "Tribler to shutdown by pressing the button below. This might lead " "to data loss.") self.window().force_shutdown_btn.show() self.delete_tray_icon() self.show_loading_screen() self.hide_status_bar() self.loading_text_label.setText("Shutting down...") self.shutdown_timer = QTimer() self.shutdown_timer.timeout.connect(show_force_shutdown) self.shutdown_timer.start(SHUTDOWN_WAITING_PERIOD) self.gui_settings.setValue("pos", self.pos()) self.gui_settings.setValue("size", self.size()) if self.core_manager.use_existing_core: # Don't close the core that we are using QApplication.quit() self.core_manager.stop() self.core_manager.shutting_down = True self.downloads_page.stop_loading_downloads() request_queue.clear() # Stop the token balance timer if self.token_refresh_timer: self.token_refresh_timer.stop() def closeEvent(self, close_event): self.close_tribler() close_event.ignore() def keyReleaseEvent(self, event): if event.key() == Qt.Key_Escape: self.escape_pressed.emit() if self.isFullScreen(): self.exit_full_screen() def dragEnterEvent(self, e): file_urls = [_qurl_to_path(url) for url in e.mimeData().urls() ] if e.mimeData().hasUrls() else [] if any(os.path.isfile(filename) for filename in file_urls): e.accept() else: e.ignore() def dropEvent(self, e): file_urls = ([(_qurl_to_path(url), url.toString()) for url in e.mimeData().urls()] if e.mimeData().hasUrls() else []) for filename, fileurl in file_urls: if os.path.isfile(filename): self.start_download_from_uri(fileurl) e.accept() def clicked_force_shutdown(self): process_checker = ProcessChecker() if process_checker.already_running: core_pid = process_checker.get_pid_from_lock_file() os.kill(int(core_pid), 9) # Stop the Qt application QApplication.quit()
def init(): global COMPANY COMPANY = "MeltinPop" # SECTIONS ------------------------------- global APPLICATION APPLICATION = "SpinTool" global DEVICES DEVICES = "Devices" global PORTS PORTS = "Ports" # Enums ---------------------------------- global COLOR_RED COLOR_RED = "RED" global COLOR_AMBER COLOR_AMBER = "AMBER" # APPLICATION ------------------------------------------------------------------------------------------ appSettings = QSettings(COMPANY, APPLICATION) # Load preferences global use_big_fonts_playlist use_big_fonts_playlist = appSettings.value('use_big_fonts_playlist', 'false') == 'true' global use_big_fonts_scenes use_big_fonts_scenes = appSettings.value('use_big_fonts_scenes', 'false') == 'true' global auto_connect_output auto_connect_output = appSettings.value('auto_connect_output', 'true') == 'true' global auto_connect_input auto_connect_input = appSettings.value('auto_connect_input', 'true') == 'true' # save mixer settings global save_mixerstrip_gain save_mixerstrip_gain = appSettings.value('save_mixerstrip_gain', 'false') == 'true' global save_mixerstrip_send1 save_mixerstrip_send1 = appSettings.value('save_mixerstrip_send1', 'false') == 'true' global save_mixerstrip_send2 save_mixerstrip_send2 = appSettings.value('save_mixerstrip_send2', 'false') == 'true' global save_mixerstrip_volume save_mixerstrip_volume = appSettings.value('save_mixerstrip_volume', 'false') == 'true' global save_mixerstrip_mute save_mixerstrip_mute = appSettings.value('save_mixerstrip_mute', 'false') == 'true' global save_mixerstrip_to_master save_mixerstrip_to_master = appSettings.value('save_mixerstrip_to_master', 'false') == 'true' # reset all global customreset_mixerstrip_gain customreset_mixerstrip_gain = appSettings.value( 'customreset_mixerstrip_gain', 'false') == 'true' global customreset_mixerstrip_send1 customreset_mixerstrip_send1 = appSettings.value( 'customreset_mixerstrip_send1', 'false') == 'true' global customreset_mixerstrip_send2 customreset_mixerstrip_send2 = appSettings.value( 'customreset_mixerstrip_send2', 'false') == 'true' global customreset_mixerstrip_volume customreset_mixerstrip_volume = appSettings.value( 'customreset_mixerstrip_volume', 'false') == 'true' global customreset_mixerstrip_mute customreset_mixerstrip_mute = appSettings.value( 'customreset_mixerstrip_mute', 'false') == 'true' # Performance global disable_shift_after_processing disable_shift_after_processing = appSettings.value( 'disable_shift_after_processing', 'true') == 'true' global show_clip_details_on_trigger show_clip_details_on_trigger = appSettings.value( 'show_clip_details_on_trigger', 'false') == 'true' global play_clip_after_record play_clip_after_record = appSettings.value('play_clip_after_record', 'false') == 'true' global show_scenes_on_start show_scenes_on_start = appSettings.value('show_scenes_on_start', 'false') == 'true' global allow_record_empty_clip allow_record_empty_clip = appSettings.value('allow_record_empty_clip', 'false') == 'true' global auto_assign_new_clip_column auto_assign_new_clip_column = appSettings.value( 'auto_assign_new_clip_column', 'false') == 'true' global show_playlist_on_start show_playlist_on_start = appSettings.value('show_playlist_on_start', 'false') == 'true' global show_song_annotation_on_load show_song_annotation_on_load = appSettings.value( 'show_song_annotation_on_load', 'false') == 'true' global slower_processing slower_processing = appSettings.value('slower_processing', 'false') == 'true' global system_monitoring system_monitoring = appSettings.value('system_monitoring', 'false') == 'true' global rec_color rec_color = appSettings.value('rec_color', COLOR_AMBER) global grid_rows grid_rows = int(appSettings.value('grid_rows', 8)) global grid_columns grid_columns = int(appSettings.value('grid_columns', 8)) global new_song_master_volume new_song_master_volume = int( appSettings.value('new_song_master_volume', 50)) global new_song_bpm new_song_bpm = int(appSettings.value('new_song_bpm', 120)) global new_song_beats new_song_beats = int(appSettings.value('new_song_beats', 4)) global bigFontSize bigFontSize = int(appSettings.value('bigFontSize', 14)) global prevent_song_save prevent_song_save = appSettings.value('prevent_song_save', 'false') == 'true' # and windows positions global playlist_geometry playlist_geometry = appSettings.value('playlist_geometry', None) global scenes_geometry scenes_geometry = appSettings.value('scenes_geometry', None) global gui_geometry gui_geometry = appSettings.value('gui_geometry', None) global song_annotation_geometry song_annotation_geometry = appSettings.value('song_annotation_geometry', None) global mixer_geometry mixer_geometry = appSettings.value('mixer_geometry', None) # session global paths_used paths_used = appSettings.value('paths_used', {}) global playlist playlist = appSettings.value('playlist', []) or [] # DEVICE --------------------------------------------------------------------------------------------- devSettings = QSettings(COMPANY, DEVICES) global devices devices = devSettings.value('devices', None) global hasDevices hasDevices = devSettings.contains('devices') # PORTS AND MIXER VALUES ------------------------------------------------------------------------------ portSettings = QSettings(COMPANY, PORTS) # A dict maintaining the output ports. Every item of the list is a dict # which defines elements like: name:{"vol", "mute", "gain"} # e.g. output_ports = {"vol":1, "mute":False, "gain":0.5, "send1":0, "send2":0} # the default dict can be found in common.py global output_ports output_ports = portSettings.value('output_ports', None) # master port final volume global master_port_final_volume master_port_final_volume = float( portSettings.value('master_port_final_volume', 1)) # master port mute global master_port_mute master_port_mute = portSettings.value('master_port_mute', 'false') == 'true'
class UpdateRegistryWorker(QObject): '''Background worker for updating Image Registry''' finished = pyqtSignal(object) error = pyqtSignal(Exception, str) def __init__(self): QObject.__init__(self) self.killed = False self.settings = QSettings(QSettings().value("APIS/config_ini"), QSettings.IniFormat) # self.registryFile = pluginDir + "\\" + "apis_image_registry.json" #self.settings.value("APIS/image_registry_file", None) self.imageDirName = self.settings.value("APIS/image_dir") self.orthoDirName = self.settings.value("APIS/ortho_image_dir") self.imageDir = QDir(self.imageDirName) self.orthoDir = QDir(self.orthoDirName) self.imageFormats = self.settings.value("APIS/image_formats", ['jpg']) self.hiResFormats = self.settings.value("APIS/hires_formats", ['jpg', 'tif', 'sid', 'nef', 'raf', 'cr2', 'dng']) self.orthoFormats = self.settings.value("APIS/ortho_formats", ['jpg', 'tif', 'sid']) self.imageFormatsStr = "|".join(self.imageFormats) self.hiResFormatsStr = "|".join(self.hiResFormats) self.orthoFormatsStr = "|".join(self.orthoFormats) def run(self): try: self.updateImageRegistries() self.updateOrthoRegistries() if self.killed is False: ret = True ret = { "imageRegistryNE": self.imageRegistryNE, "hiResRegistryNE": self.hiResRegistryNE, "i2cRegistryNE": self.i2cRegistryNE, "orthoRegistryNE": self.orthoRegistryNE, "mosaicRegistryNE": self.mosaicRegistryNE, "imageRegistry": self.imageRegistry, "hiResRegistry": self.hiResRegistry, "i2cRegistry": self.i2cRegistry, "orthoRegistry": self.orthoRegistry, "mosaicRegistry": self.mosaicRegistry } else: ret = False except Exception as e: # forward the exception upstream self.error.emit(e, traceback.format_exc()) self.finished.emit(ret) def kill(self): self.killed = True def updateImageRegistries(self): self.imageRegistry = [] self.hiResRegistry = [] self.i2cRegistry = [] imageEntryList = self.imageDir.entryList(['??????????'], QDir.Dirs) for i in imageEntryList: if self.killed is True: # kill request received, exit loop early break iDir = QDir(self.imageDir.path() + '\\' + i) # FIXME implement solution for not just jpg but values from ini iEntryList = iDir.entryList([i + '_???.jpg'], QDir.Files) self.imageRegistry = self.imageRegistry + iEntryList hiResDirsEntryList = iDir.entryList(["highres*", "mrsid", "raw"], QDir.Dirs) hiResFilters = [i + '_???.' + ext for ext in self.hiResFormats] for hr in hiResDirsEntryList: if self.killed is True: # kill request received, exit loop early break hrDir = QDir(iDir.path() + '\\' + hr) hrEntryList = hrDir.entryList(hiResFilters, QDir.Files) self.hiResRegistry = self.hiResRegistry + hrEntryList i2cDirEntryList = iDir.entryList(["ins2cam"], QDir.Dirs) i2cFilters = [i + '_???.' + ext for ext in ['jpg', 'tif', 'tiff']] for i2c in i2cDirEntryList: if self.killed is True: # kill request received, exit loop early break i2cDir = QDir(iDir.path() + '\\' + i2c) i2cEntryList = i2cDir.entryList(i2cFilters, QDir.Files) self.i2cRegistry = self.i2cRegistry + i2cEntryList if self.killed is False: self.imageRegistryNE = [img[:14].replace('_', '.') for img in self.imageRegistry] self.hiResRegistryNE = [img[:14].replace('_', '.') for img in self.hiResRegistry] self.i2cRegistryNE = [img[:14].replace('_', '.') for img in self.i2cRegistry] def updateOrthoRegistries(self): self.orthoRegistryNE = [] self.orthoRegistry = [] self.mosaicRegistryNE = [] self.mosaicRegistry = [] orthoEntryList = self.orthoDir.entryList(['??????????'], QDir.Dirs) for o in orthoEntryList: if self.killed is True: # kill request received, exit loop early break orthoFilters = [o + '_???_op*.' + ext for ext in self.orthoFormats] mosaicFilters = [o + '_???_???_op*.' + ext for ext in self.orthoFormats] oDir = QDir(self.orthoDir.path() + '\\' + o) oEntryList = oDir.entryList(orthoFilters, QDir.Files) mEntryList = oDir.entryList(mosaicFilters, QDir.Files) #chekc oEntryList if _INT_op oEntryList = [img for img in oEntryList if img[11:14].isdigit()] #check mEntryList if _INT_INT_op mEntryList = [img for img in mEntryList if img[11:14].isdigit() and img[15:18].isdigit()] self.orthoRegistry = self.orthoRegistry + oEntryList self.mosaicRegistry = self.mosaicRegistry + mEntryList if self.killed is False: self.orthoRegistryNE = [img[:14].replace('_', '.') for img in self.orthoRegistry] self.mosaicRegistryNE = [f"{img[:10]}.{img[11:14]}-{img[15:18]}" for img in self.mosaicRegistry]
def __init__(self, core_args=None, core_env=None, api_port=None): QMainWindow.__init__(self) QCoreApplication.setOrganizationDomain("nl") QCoreApplication.setOrganizationName("TUDelft") QCoreApplication.setApplicationName("Tribler") QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) self.gui_settings = QSettings() api_port = api_port or int( get_gui_setting(self.gui_settings, "api_port", DEFAULT_API_PORT)) dispatcher.update_worker_settings(port=api_port) self.navigation_stack = [] self.tribler_started = False self.tribler_settings = None self.debug_window = None self.core_manager = CoreManager(api_port) self.pending_requests = {} self.pending_uri_requests = [] self.download_uri = None self.dialog = None self.new_version_dialog = None self.start_download_dialog_active = False self.request_mgr = None self.search_request_mgr = None self.search_suggestion_mgr = None self.selected_torrent_files = [] self.vlc_available = True self.has_search_results = False self.last_search_query = None self.last_search_time = None self.start_time = time.time() self.exception_handler_called = False self.token_refresh_timer = None sys.excepthook = self.on_exception uic.loadUi(get_ui_file_path('mainwindow.ui'), self) TriblerRequestManager.window = self self.tribler_status_bar.hide() # Load dynamic widgets uic.loadUi(get_ui_file_path('torrent_channel_list_container.ui'), self.channel_page_container) self.channel_torrents_list = self.channel_page_container.items_list self.channel_torrents_detail_widget = self.channel_page_container.details_tab_widget self.channel_torrents_detail_widget.initialize_details_widget() self.channel_torrents_list.itemSelectionChanged.connect( self.channel_page.clicked_item) uic.loadUi(get_ui_file_path('torrent_channel_list_container.ui'), self.search_page_container) self.search_results_list = self.search_page_container.items_list self.search_torrents_detail_widget = self.search_page_container.details_tab_widget self.search_torrents_detail_widget.initialize_details_widget() self.search_results_list.itemClicked.connect( self.on_channel_item_click) self.search_results_list.itemSelectionChanged.connect( self.search_results_page.clicked_item) self.token_balance_widget.mouseReleaseEvent = self.on_token_balance_click def on_state_update(new_state): self.loading_text_label.setText(new_state) self.core_manager.core_state_update.connect(on_state_update) self.magnet_handler = MagnetHandler(self.window) QDesktopServices.setUrlHandler("magnet", self.magnet_handler, "on_open_magnet_link") self.debug_pane_shortcut = QShortcut(QKeySequence("Ctrl+d"), self) self.debug_pane_shortcut.activated.connect( self.clicked_menu_button_debug) # Remove the focus rect on OS X for widget in self.findChildren(QLineEdit) + self.findChildren( QListWidget) + self.findChildren(QTreeWidget): widget.setAttribute(Qt.WA_MacShowFocusRect, 0) self.menu_buttons = [ self.left_menu_button_home, self.left_menu_button_search, self.left_menu_button_my_channel, self.left_menu_button_subscriptions, self.left_menu_button_video_player, self.left_menu_button_downloads, self.left_menu_button_discovered ] self.video_player_page.initialize_player() self.search_results_page.initialize_search_results_page() self.settings_page.initialize_settings_page() self.subscribed_channels_page.initialize() self.edit_channel_page.initialize_edit_channel_page() self.downloads_page.initialize_downloads_page() self.home_page.initialize_home_page() self.loading_page.initialize_loading_page() self.discovering_page.initialize_discovering_page() self.discovered_page.initialize_discovered_page() self.trust_page.initialize_trust_page() self.stackedWidget.setCurrentIndex(PAGE_LOADING) # Create the system tray icon if QSystemTrayIcon.isSystemTrayAvailable(): self.tray_icon = QSystemTrayIcon() use_monochrome_icon = get_gui_setting(self.gui_settings, "use_monochrome_icon", False, is_bool=True) self.update_tray_icon(use_monochrome_icon) # Create the tray icon menu menu = self.create_add_torrent_menu() show_downloads_action = QAction('Show downloads', self) show_downloads_action.triggered.connect( self.clicked_menu_button_downloads) token_balance_action = QAction('Show token balance', self) token_balance_action.triggered.connect( lambda: self.on_token_balance_click(None)) quit_action = QAction('Quit Tribler', self) quit_action.triggered.connect(self.close_tribler) menu.addSeparator() menu.addAction(show_downloads_action) menu.addAction(token_balance_action) menu.addSeparator() menu.addAction(quit_action) self.tray_icon.setContextMenu(menu) else: self.tray_icon = None self.hide_left_menu_playlist() self.left_menu_button_debug.setHidden(True) self.top_menu_button.setHidden(True) self.left_menu.setHidden(True) self.token_balance_widget.setHidden(True) self.settings_button.setHidden(True) self.add_torrent_button.setHidden(True) self.top_search_bar.setHidden(True) # Set various icons self.top_menu_button.setIcon(QIcon(get_image_path('menu.png'))) self.search_completion_model = QStringListModel() completer = QCompleter() completer.setModel(self.search_completion_model) completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) self.item_delegate = QStyledItemDelegate() completer.popup().setItemDelegate(self.item_delegate) completer.popup().setStyleSheet(""" QListView { background-color: #404040; } QListView::item { color: #D0D0D0; padding-top: 5px; padding-bottom: 5px; } QListView::item:hover { background-color: #707070; } """) self.top_search_bar.setCompleter(completer) # Toggle debug if developer mode is enabled self.window().left_menu_button_debug.setHidden(not get_gui_setting( self.gui_settings, "debug", False, is_bool=True)) # Start Tribler self.core_manager.start(core_args=core_args, core_env=core_env) self.core_manager.events_manager.received_search_result_channel.connect( self.search_results_page.received_search_result_channel) self.core_manager.events_manager.received_search_result_torrent.connect( self.search_results_page.received_search_result_torrent) self.core_manager.events_manager.torrent_finished.connect( self.on_torrent_finished) self.core_manager.events_manager.new_version_available.connect( self.on_new_version_available) self.core_manager.events_manager.tribler_started.connect( self.on_tribler_started) self.core_manager.events_manager.events_started.connect( self.on_events_started) self.core_manager.events_manager.low_storage_signal.connect( self.on_low_storage) self.core_manager.events_manager.credit_mining_signal.connect( self.on_credit_mining_error) # Install signal handler for ctrl+c events def sigint_handler(*_): self.close_tribler() signal.signal(signal.SIGINT, sigint_handler) self.installEventFilter(self.video_player_page) # Resize the window according to the settings center = QApplication.desktop().availableGeometry(self).center() pos = self.gui_settings.value( "pos", QPoint(center.x() - self.width() * 0.5, center.y() - self.height() * 0.5)) size = self.gui_settings.value("size", self.size()) self.move(pos) self.resize(size) self.show()
class MainWindow(QMainWindow): APP_NAME = 'Tagit' APP_VERSION = '0.5' KEY_GROUP = 'groups' KEY_TAG = 'tags' KEY_ITEM = 'items' KEY_SETTING = 'settings' def __init__(self): super(MainWindow, self).__init__() # whole views self.setupViews() # menu and toolbox self.createMainMenu() # init data: last saved database self.setting = QSettings('dothinking', 'tagit') filename = self.setting.value('database') self.initData(filename) # status bar self.createStatusBar() # window self.setTitle() self.resize(1000, 800) # self.showMaximized() # ---------------------------------------------- # --------------- properties --------------- # ---------------------------------------------- def groupsView(self): return self.groupsTreeView def tagsView(self): return self.tagsTableView def itemsView(self): return self.itemsTableView def propertyView(self): return self.dockProperty def tabViews(self): return self.tabWidget def database(self): return self._database # ---------------------------------------------- # --------------- data operation --------------- # ---------------------------------------------- def initData(self, database=None): '''load data from specified database, init default if failed. two failing situations: - database is not specified -> init by default and return true - specified but is invalid -> init by default but return false ''' ok = True if database and os.path.exists(database): # load database try: with open(database, 'rb') as f: data = pickle.load(f) except Exception as e: ok = False else: if self.APP_NAME in data: # valid database self._database = database self._initData(data) return ok else: ok = False # init by default if load data from database failed self._database = None self._initData() return ok def _initData(self, data={}): '''load data from database''' # set window title self.setTitle() self.groupsTreeView.setFocus() # get data if self.KEY_GROUP in data: groups = data.get(self.KEY_GROUP)[GroupModel.CHILDREN] else: groups = [] tags = data.get(self.KEY_TAG, []) items = data.get(self.KEY_ITEM, []) # settings settings = data.get(self.KEY_SETTING, {}) selected_group = settings.get('selected_group', GroupModel.ALLGROUPS) selected_tag = settings.get('selected_tag', TagModel.NOTAG) selected_style = settings.get('selected_style', None) dock_area = settings.get('dock_area', Qt.BottomDockWidgetArea) # init groups tree view self.groupsTreeView.setup(groups, selected_group) self.groupsTreeView.model().updateItems(items) self.groupsTreeView.setColumnHidden(GroupModel.KEY, True) # init tags table view self.tagsTableView.setup(tags, selected_tag) self.tagsTableView.model().updateItems(items) self.tagsTableView.setColumnHidden(TagModel.KEY, True) # hide first column -> key # init items table view self.itemsTableView.setup(items) self.itemsTableView.setColumnHidden(ItemModel.GROUP, True) self.itemsTableView.setColumnHidden(ItemModel.TAGS, True) self.itemsTableView.setColumnHidden(ItemModel.PATH, True) self.itemsTableView.setColumnHidden(ItemModel.NOTES, True) # add dock widget self.addDockWidget(dock_area, self.dockProperty) # set style sheet self.main_menu.setStyleSheet(selected_style) def closeEvent(self, event): '''default method called when trying to close the app''' if self.main_menu.maybeSave(): event.accept() else: event.ignore() def saveRequired(self): '''saving is required if anything is changed''' return (self.groupsTreeView.model().saveRequired() or self.tagsTableView.model().saveRequired() or self.itemsTableView.model().sourceModel().saveRequired()) def serialize(self, filename): '''save project data to database''' # current group for index in self.groupsTreeView.selectedIndexes(): selected_group = index.siblingAtColumn(GroupModel.KEY).data() break else: selected_group = self.groupsTreeView.model().ALLGROUPS # current tag for index in self.tagsTableView.selectedIndexes(): selected_tag = index.siblingAtColumn(TagModel.KEY).data() break else: selected_tag = TagModel.NOTAG # collect all data data = { self.APP_NAME: self.APP_VERSION, self.KEY_GROUP: self.groupsTreeView.model().serialize(), self.KEY_TAG: self.tagsTableView.model().serialize(), self.KEY_ITEM: self.itemsTableView.model().sourceModel().serialize(), self.KEY_SETTING: { 'selected_group': selected_group, 'selected_tag': selected_tag, 'selected_style': self.main_menu.getCurrentSheetStyle(), 'dock_area': self.dockWidgetArea(self.dockProperty) }, } # dump pickle file try: with open(filename, 'wb') as f: pickle.dump(data, f) except Exception as e: QMessageBox.critical( None, "Error", "Could not save current project to\n {0}.".format(filename)) else: self._database = filename self.setting.setValue('database', filename) self.setTitle() self.statusBar().showMessage('File saved.') return True return False # ---------------------------------------------- # --------------- user interface --------------- # ---------------------------------------------- def setupViews(self): '''create main views''' # left widgets self.tabWidget = QTabWidget() self.groupsTreeView = GroupTreeView(['Group', 'Key']) # groups tree view self.tagsTableView = TagTableView(['KEY', 'TAG', 'COLOR']) # tags table view self.tabWidget.addTab(self.groupsTreeView, "Groups") self.tabWidget.addTab(self.tagsTableView, "Tags") # central widgets: reference item table widget headers = [ 'Item Title', 'Group', 'Tags', 'Path', 'Create Date', 'Notes' ] self.itemsTableView = ItemTableView(headers, self.tabWidget) # arranged views splitter = QSplitter() splitter.addWidget(self.tabWidget) splitter.addWidget(self.itemsTableView) splitter.setStretchFactor(0, 0) splitter.setStretchFactor(1, 1) self.setCentralWidget(splitter) # dock widgets # it has not been added to main window util called by addDockWidget() explicitly propWidget = PropertyWidget(self.itemsTableView) self.dockProperty = QDockWidget(self.tr("Properties"), self) self.dockProperty.setWidget(propWidget) def createMainMenu(self): '''main menu''' self.main_menu = MainMenu(self) # create menu items self.main_menu.createMenus() # set menu enable status self.main_menu.refreshMenus() # toolbar self.main_menu.createToolBars() def setTitle(self): '''set window title''' title = self._database if self._database else 'untitled.dat' self.setWindowTitle("Tagit - {0}".format(title)) def createStatusBar(self): if self._database: msg = 'loading database successfully - {0}'.format(self._database) else: msg = 'New database' self.statusBar().showMessage(msg)
def run(self): settings = QSettings() pref_target_path = settings.value(Settings.SETTINGS_SAVE_PATH, Settings.DEFAULT_TARGET_PATH, type=str) pref_max_pool_cnt = settings.value(Settings.SETTINGS_MAX_POOL_CNT, Settings.DEFAULT_MAX_POOL, type=int) gallery_save_path = pref_target_path + '/' + self.gallery.path if not os.path.exists(gallery_save_path): os.makedirs(gallery_save_path) # Cloudflare Authorization self.state.emit('Authorize..') Logger.LOGGER.info("Wait for Cloudflare Authorization..") self.driver.get(URL_HITOMI) while "Just a moment..." in self.driver.page_source: pass user_agent = self.driver.execute_script("return navigator.userAgent;") try: cookie_value = '__cfduid=' + self.driver.get_cookie('__cfduid')['value'] + \ '; cf_clearance=' + self.driver.get_cookie('cf_clearance')['value'] headers = {'User-Agent': user_agent} cookies = {'session_id': cookie_value} except TypeError: Logger.LOGGER.warning("Not apply cookies to requests") headers = None cookies = None # Make Download Session session = FuturesSession(max_workers=pref_max_pool_cnt) if headers is not None: session.headers = headers if cookies is not None: session.cookies = cookies responses = {} # Fetch image data from gallery page download_list = [] self.state.emit('Fetch..') Logger.LOGGER.info("Connect to Gallery page..") self.driver.get(self.gallery.url.replace('galleries', 'reader')) source = self.driver.page_source soup = BeautifulSoup(source, 'html.parser') ref_url = soup.find('img')['src'] ref_key = ref_url[:ref_url.index('.')] img_urls = soup.find_all('div', class_='img-url') self.total_cnt = len(img_urls) for img_url in img_urls: download_url = 'https:' + img_url.get_text().replace( '//g', ref_key) download_name = download_url.split('/')[-1] responses[download_name] = session.get(download_url) download_list.append(download_url) for filename in responses: self.response_to_file(response=responses[filename].result(), name=filename, path=gallery_save_path) session.close() # Compress Zip Files self.state.emit('Compressing..') if self.gallery.original != "": zip_path = pref_target_path + '/' + self.gallery.type + '/' + self.gallery.original + '/' + self.gallery.path + '.zip' else: zip_path = pref_target_path + '/' + self.gallery.type + '/' + self.gallery.path + '.zip' try: if not os.path.exists(zip_path[:zip_path.rfind('/')]): os.makedirs(zip_path[:zip_path.rfind('/')]) FileUtil.make_zip(gallery_save_path, zip_path) shutil.rmtree(gallery_save_path) except: print(traceback.format_exc()) Logger.LOGGER.error("Compressing Process Error... pass") # Save to Firebase # TODO Enable next line on Build FirebaseClient.fbclient.insert_data(self.gallery)
def __init__(self, parent=None): super(Proxy, self).__init__(parent) self.settings = QSettings() self.layout = QVBoxLayout() self.buttonLayout = QHBoxLayout() self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonBox.rejected.connect(self.reject) self.buttonBox.accepted.connect(self.accept) self.buttonLayout.addWidget(self.buttonBox) self.proxy_url_label = QLabel(QCoreApplication.translate( 'Entry label for the proxy url', 'Proxy URL:', 'Proxy settings dialogue')) self.proxy_url_line = QLineEdit() url = self.settings.value('Proxy_url') or '' self.proxy_url_line = QLineEdit(url) self.proxy_url_line.setMinimumWidth(300) self.proxy_port_label = QLabel(QCoreApplication.translate( 'Entry label for the proxy port', 'Port:', 'Proxy settings dialogue')) port = self.settings.value('Proxy_port') or '' self.proxy_port_line = QLineEdit(port) self.proxy_auth_label = QLabel(QCoreApplication.translate( 'Checkbox', 'Use proxy authentification', 'Proxy settings dialogue')) self.proxy_auth_checkbox = QCheckBox() self.proxy_auth_bool = eval(self.settings.value( 'Use_proxy_authentification') or 'False') self.proxy_auth_checkbox.setChecked(self.proxy_auth_bool) self.proxy_auth_checkbox.stateChanged.connect(self.proxy_auth) self.proxy_user_label = QLabel(QCoreApplication.translate( 'Proxy username authentification', 'User ID:', 'Proxy configuration dialogue')) self.proxy_user_label.setEnabled(self.proxy_auth_bool) self.proxy_pass_label = QLabel(QCoreApplication.translate( 'Proxy password authentification', 'Password:'******'Proxy configuration dialogue')) self.proxy_pass_label.setEnabled(self.proxy_auth_bool) user = self.settings.value('Proxy_user') or '' self.proxy_user_line = QLineEdit(user) self.proxy_user_line.setEnabled(self.proxy_auth_bool) password = self.settings.value('Proxy_password') or '' self.proxy_pass_line = QLineEdit(password) self.proxy_pass_line.setEnabled(self.proxy_auth_bool) self.proxy_pass_line.setEchoMode(QLineEdit.Password) self.status_layout = QHBoxLayout() self.status_label = QLabel() self.status_layout.addWidget(self.status_label) self.panel = QGridLayout() self.panel.addWidget(self.proxy_url_label, 0, 0) self.panel.addWidget(self.proxy_url_line, 0, 1) self.panel.addWidget(self.proxy_port_label, 0, 2) self.panel.addWidget(self.proxy_port_line, 0, 3) self.panel.addWidget(self.proxy_auth_label, 1, 0) self.panel.addWidget(self.proxy_auth_checkbox, 1, 1) self.panel.addWidget(self.proxy_user_label, 2, 0) self.panel.addWidget(self.proxy_user_line, 2, 1) self.panel.addWidget(self.proxy_pass_label, 3, 0) self.panel.addWidget(self.proxy_pass_line, 3, 1) self.layout.addLayout(self.panel) self.layout.addLayout(self.status_layout) self.layout.addLayout(self.buttonLayout) self.setLayout(self.layout)
class ApisImageRegistry(QObject): loaded = pyqtSignal(object) def __init__(self, pluginDir, iface): QObject.__init__(self) self.iface = iface self.registryFile = pluginDir + "\\" + "apis_image_registry.json" # self.settings.value("APIS/image_registry_file", None) # NE ... NoExtension self.__imageRegistryNE = None self.__hiResRegistryNE = None self.__i2cRegistryNE = None self.__orthoRegistryNE = None self.__mosaicRegistryNE = None self.__imageRegistry = None self.__hiResRegistry = None self.__i2cRegistry = None self.__orthoRegistry = None self.__mosaicRegistry = None self.isLoaded = False self.isSetup = False self.worker = None def setupSettings(self): self.settings = QSettings(QSettings().value("APIS/config_ini"), QSettings.IniFormat) self.imageDirName = self.settings.value("APIS/image_dir") self.orthoDirName = self.settings.value("APIS/ortho_image_dir") self.imageDir = QDir(self.imageDirName) self.orthoDir = QDir(self.orthoDirName) self.imageFormats = self.settings.value("APIS/image_formats", [u'jpg']) self.hiResFormats = self.settings.value("APIS/hires_formats", [u'jpg', u'tif', u'sid', u'nef', u'raf', u'cr2', u'dng']) self.orthoFormats = self.settings.value("APIS/ortho_formats", [u'jpg', u'tif', u'sid']) self.imageFormatsStr = u"|".join(self.imageFormats) self.hiResFormatsStr = u"|".join(self.hiResFormats) self.orthoFormatsStr = u"|".join(self.orthoFormats) self.isSetup = True def registryIsSetup(self): return self.isSetup def setupRegistry(self): if self.registryFile and os.path.isfile(self.registryFile): if self.isOutdated(): # If isOutdated > PopUp > Info: Local Image Registry is outdated > Please Update Image Registry # ask if update ImageRegistry msgBox = QMessageBox() msgBox.setWindowTitle(u'Image Registry') msgBox.setText(u'Die APIS Image Registry ist älter als ein Monat. Bitte führen Sie ein Update durch!') msgBox.addButton(QPushButton(u'Update'), QMessageBox.YesRole) msgBox.addButton(QPushButton(u'Abbrechen'), QMessageBox.NoRole) ret = msgBox.exec_() if ret == 0: self.updateRegistries() else: self.loadRegistryFromFile() else: self.loadRegistryFromFile() else: # ask if generate ImageRegistry msgBox = QMessageBox() msgBox.setWindowTitle(u'Image Registry') msgBox.setText(u'Für die Verwendung von APIS muss eine Image Registry erstellt werden!') msgBox.addButton(QPushButton(u'Jetzt erstellen'), QMessageBox.YesRole) msgBox.addButton(QPushButton(u'Abbrechen'), QMessageBox.NoRole) ret = msgBox.exec_() if ret == 0: self.updateRegistries() else: self.isLoaded = False def registryIsLoaded(self): return self.isLoaded def loadRegistryFromFile(self): #load self.__imageRegistry, self.__hiResRegistry, self.__orthoRegistry from JSON File if os.path.isfile(self.registryFile): with open(self.registryFile, 'rU') as registry: registryDict = json.load(registry) self.__imageRegistryNE = registryDict["imageRegistryNE"] self.__hiResRegistryNE = registryDict["hiResRegistryNE"] self.__i2cRegistryNE = registryDict["i2cRegistryNE"] self.__orthoRegistryNE = registryDict["orthoRegistryNE"] self.__mosaicRegistryNE = registryDict["mosaicRegistryNE"] self.__imageRegistry = registryDict["imageRegistry"] self.__hiResRegistry = registryDict["hiResRegistry"] self.__i2cRegistry = registryDict["i2cRegistry"] self.__orthoRegistry = registryDict["orthoRegistry"] self.__mosaicRegistry = registryDict["mosaicRegistry"] self.isLoaded = True self.loaded.emit(True) else: self.isLoaded = False def writeRegistryToFile(self): # write self.__imageRegistry, self.__hiResRegistry, self.__orthoRegistry to JSON File # does registry file exist if os.path.isfile(self.registryFile): os.remove(self.registryFile) with open(self.registryFile, 'w') as f: registryDict = { "imageRegistryNE": self.__imageRegistryNE, "hiResRegistryNE": self.__hiResRegistryNE, "i2cRegistryNE": self.__i2cRegistryNE, "orthoRegistryNE": self.__orthoRegistryNE, "mosaicRegistryNE": self.__mosaicRegistryNE, "imageRegistry": self.__imageRegistry, "hiResRegistry": self.__hiResRegistry, "i2cRegistry": self.__i2cRegistry, "orthoRegistry": self.__orthoRegistry, "mosaicRegistry": self.__mosaicRegistry } json.dump(registryDict, f) def isOutdated(self): if os.path.isfile(self.registryFile): today = datetime.datetime.today() creationDate = datetime.datetime.fromtimestamp(os.path.getctime(self.registryFile)) modificationDate = datetime.datetime.fromtimestamp(os.path.getmtime(self.registryFile)) if modificationDate > creationDate: fileAge = today - modificationDate else: fileAge = today - creationDate #QMessageBox.warning(None, "Zeit", "{0}".format(fileAge.days)) if fileAge.days > 30: return True else: return False # Registry is Outdated > if local File is older than one month! def updateRegistries(self): self.startWorker() def hasImage(self, imageNumber): return True if imageNumber in self.__imageRegistryNE else False def hasHiRes(self, imageNumber): return True if imageNumber in self.__hiResRegistryNE else False def hasIns2Cam(self, imageNumber): return True if imageNumber in self.__i2cRegistryNE else False def hasOrtho(self, imageNumber): return True if imageNumber in self.__orthoRegistryNE else False def hasMosaic(self, imageNumber): filmNumber = imageNumber[:10] image = int(imageNumber[11:14]) r = re.compile(r"^{0}*".format(filmNumber), re.IGNORECASE) mosaicCandidates = list(filter(r.match, self.__mosaicRegistryNE)) mosaicsValid = [] for mC in mosaicCandidates: fromTo = range(int(mC[11:14]), int(mC[15:18]) + 1) if image in fromTo: mosaicsValid.append(mC) return mosaicsValid # QMessageBox.information(None, "MosaicInfo", "{0}: {1}".format(imageNumber, ", ".join(mosaicsValid))) def hasOrthoOrMosaic(self, imageNumber): return self.hasOrtho(imageNumber) or bool(self.hasMosaic(imageNumber)) def hasImageRE(self, imageNumber): r = re.compile(r"^{0}\.({1})$".format(imageNumber, self.imageFormatsStr), re.IGNORECASE) r = list(filter(r.match, self.__imageRegistry)) return len(r) def hasHiResRE(self, imageNumber): r = re.compile(r"^{0}\.({1})$".format(imageNumber, self.hiResFormatsStr), re.IGNORECASE) r = list(filter(r.match, self.__hiResRegistry)) return len(r) def hasIns2CamRE(self, imageNumber): pass def hasOrthoRE(self, imageNumber): r = re.compile(r"^{0}_op.+\.({1})$".format(imageNumber, self.orthoFormatsStr), re.IGNORECASE) r = list(filter(r.match, self.__orthoRegistry)) return len(r) def hasMosaicRE(self, imageNumber): pass #filmNumber = OLD Film Number def getImageRegistryForFilm(self, filmNumber): imagesForFilm = [] for imageNumber in self.__imageRegistryNE: if filmNumber in imageNumber: imagesForFilm.append(imageNumber) return imagesForFilm def startWorker(self): # create a new worker instance if self.worker is None: worker = UpdateRegistryWorker() # configure the QgsMessageBar messageBar = self.iface.messageBar().createMessage(u"Update Image Registry", u"Dieser Vorgang kann einige Minute dauern, bitte haben Sie Geduld!") progressBar = QProgressBar() progressBar.setMinimum(0) progressBar.setMaximum(0) progressBar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) cancelButton = QPushButton() cancelButton.setText('Cancel') cancelButton.clicked.connect(self.killWorker) messageBar.layout().addWidget(progressBar) self.progressBar = progressBar messageBar.layout().addWidget(cancelButton) self.iface.messageBar().pushWidget(messageBar, Qgis.Info) #self.iface.messageBar().widgetRemoved # messageBar self.messageBar = messageBar # start the worker in a new thread thread = QThread() worker.moveToThread(thread) worker.finished.connect(self.workerFinished) worker.error.connect(self.workerError) #worker.progress.connect(progressBar.setValue) thread.started.connect(worker.run) thread.start() self.thread = thread self.worker = worker def killWorker(self): self.worker.kill() #self.progressBar.setMaximum(100) #self.progressBar.setValue(100) def workerFinished(self, ret): # clean up the worker and thread self.worker.deleteLater() self.thread.quit() self.thread.wait() self.thread.deleteLater() # remove widget from message bar self.iface.messageBar().popWidget(self.messageBar) if ret is not None: #report the result if not self.worker.killed: self.__imageRegistryNE = ret["imageRegistryNE"] self.__hiResRegistryNE = ret["hiResRegistryNE"] self.__i2cRegistryNE = ret["i2cRegistryNE"] self.__orthoRegistryNE = ret["orthoRegistryNE"] self.__mosaicRegistryNE = ret["mosaicRegistryNE"] self.__imageRegistry = ret["imageRegistry"] self.__hiResRegistry = ret["hiResRegistry"] self.__i2cRegistry = ret["i2cRegistry"] self.__orthoRegistry = ret["orthoRegistry"] self.__mosaicRegistry = ret["mosaicRegistry"] self.writeRegistryToFile() self.iface.messageBar().pushMessage(u"Update Image Registry", u"Das Update wurde erfolgreich abgeschloßen!", level=Qgis.Success, duration=5) self.isLoaded = True self.loaded.emit(True) else: self.iface.messageBar().pushMessage(u"Update Image Registry", u"Das Update wurde abgebrochen!", level=Qgis.Warning, duration=5) if os.path.isfile(self.registryFile): os.remove(self.registryFile) self.isLoaded = False self.loaded.emit(False) #self.iface.messageBar().pushMessage('Result') else: # notify the user that something went wrong self.iface.messageBar().pushMessage('Something went wrong! See the message log for more information.', level=Qgis.Critical, duration=3) self.isLoaded = False self.worker = None def workerError(self, e, exception_string): QgsMessageLog.logMessage('APIS UpdateRegistryWorker thread raised an exception:\n'.format(exception_string), tag='APIS', level=Qgis.Critical)
class qwProgressBox(QtWidgets.QWidget): ''' Widget personalise construisant la boite de progression lors du streaming d'un fichier GCode ''' def __init__(self, parent=None): super().__init__() self.__settings = QSettings(QSettings.NativeFormat, QSettings.UserScope, ORG_NAME, APP_NAME) self.pBox = QtWidgets.QFrame(parent) self.pBox.setStyleSheet( ".QFrame{background-color: rgba(192, 192, 192, 192); border: 2px solid #000060;}" ) self.pBoxBtnHeader = btnHeader(self.pBox) self.pBoxBtnHeader.setStyleSheet( ".btnHeader{background-color: rgba(48, 48, 80, 192); border-radius: 0px}" ) self.pBoxLblStart = QtWidgets.QLabel(self.pBoxBtnHeader) debut = datetime.now() self.pBoxLblStart.setText( self.tr("GCode started at: {}").format( debut.strftime("%A %x %H:%M:%S"))) self.pBoxLblStart.setStyleSheet("color: white;") self.pBoxLblStart.adjustSize() self.pBoxBtnHeader.setGeometry(2, 2, self.pBoxLblStart.width() + 36, self.pBoxBtnHeader.height()) self.pBoxLblStart.setGeometry( 20, (self.pBoxBtnHeader.height() - self.pBoxLblStart.height()) / 2, self.pBoxLblStart.width(), self.pBoxLblStart.height()) self.pBoxProgress = QtWidgets.QProgressBar(self.pBox) self.pBoxProgress.setAlignment(Qt.AlignHCenter) self.pBoxProgress.setGeometry( 20, self.pBoxBtnHeader.geometry().y() + self.pBoxBtnHeader.height() + 9, self.pBoxLblStart.width(), 20) self.pBoxProgress.setRange(0, 100) self.pBoxProgress.setValue(37) self.pBoxLblComment = QtWidgets.QLabel(self.pBox) self.pBoxLblComment.setText("()") self.pBoxLblComment.setGeometry( 20, self.pBoxProgress.geometry().y() + self.pBoxProgress.height() + 3, self.pBoxLblStart.width(), 20) self.pBoxLblElapse = QtWidgets.QLabel(self.pBox) total_seconds = int((datetime.now() - debut).total_seconds()) hours, remainder = divmod(total_seconds, 60 * 60) minutes, seconds = divmod(remainder, 60) self.pBoxLblElapse.setText(self.tr("Elapsed time:")) self.pBoxLblElapse.setGeometry( 20, self.pBoxLblComment.geometry().y() + self.pBoxLblComment.height() + 3, self.pBoxLblStart.width(), 20) pBoxLargeur = self.pBoxLblStart.width() + 40 pBoxHauteur = self.pBoxLblElapse.geometry().y( ) + self.pBoxLblElapse.height() + 6 defaultX = int((parent.width() - pBoxLargeur) / 2) defaultY = int((parent.height() - pBoxHauteur) / 5 * 3) pBoxX = self.__settings.value("ProgressBox/posX", defaultX, type=int) pBoxY = self.__settings.value("ProgressBox/posY", defaultY, type=int) self.pBox.setGeometry(pBoxX, pBoxY, pBoxLargeur, pBoxHauteur) self.pBox.setVisible(False) def start(self): debut = datetime.now() self.pBoxLblStart.setText( self.tr("GCode started at: {}").format( debut.strftime("%A %x %H:%M:%S"))) self.pBox.setVisible(True) # Démarre la mise à jour régulière du temps elapsed self.__elapseThread = elapseThread(self.pBoxLblElapse) self.__elapseThread.start() def stop(self): # Masque la boite self.pBox.setVisible(False) # Arrete la mise à jour régulière du temps elapsed self.__elapseThread.stop() def setRange(self, mini: int, maxi: int): self.pBoxProgress.setRange(mini, maxi) def setValue(self, val: int): self.pBoxProgress.setValue(val) self.pBoxProgress.setToolTip( self.tr("Line {} of {}").format(val, self.pBoxProgress.maximum())) def setComment(self, comment: str): self.pBoxLblComment.setText(comment) def isVisible(self): return self.pBox.isVisible()
class Proxy(QDialog): id_signal = pyqtSignal([tuple]) city_signal = pyqtSignal([tuple]) country_signal = pyqtSignal([tuple]) def __init__(self, parent=None): super(Proxy, self).__init__(parent) self.settings = QSettings() self.layout = QVBoxLayout() self.buttonLayout = QHBoxLayout() self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonBox.rejected.connect(self.reject) self.buttonBox.accepted.connect(self.accept) self.buttonLayout.addWidget(self.buttonBox) self.proxy_url_label = QLabel(QCoreApplication.translate( 'Entry label for the proxy url', 'Proxy URL:', 'Proxy settings dialogue')) self.proxy_url_line = QLineEdit() url = self.settings.value('Proxy_url') or '' self.proxy_url_line = QLineEdit(url) self.proxy_url_line.setMinimumWidth(300) self.proxy_port_label = QLabel(QCoreApplication.translate( 'Entry label for the proxy port', 'Port:', 'Proxy settings dialogue')) port = self.settings.value('Proxy_port') or '' self.proxy_port_line = QLineEdit(port) self.proxy_auth_label = QLabel(QCoreApplication.translate( 'Checkbox', 'Use proxy authentification', 'Proxy settings dialogue')) self.proxy_auth_checkbox = QCheckBox() self.proxy_auth_bool = eval(self.settings.value( 'Use_proxy_authentification') or 'False') self.proxy_auth_checkbox.setChecked(self.proxy_auth_bool) self.proxy_auth_checkbox.stateChanged.connect(self.proxy_auth) self.proxy_user_label = QLabel(QCoreApplication.translate( 'Proxy username authentification', 'User ID:', 'Proxy configuration dialogue')) self.proxy_user_label.setEnabled(self.proxy_auth_bool) self.proxy_pass_label = QLabel(QCoreApplication.translate( 'Proxy password authentification', 'Password:'******'Proxy configuration dialogue')) self.proxy_pass_label.setEnabled(self.proxy_auth_bool) user = self.settings.value('Proxy_user') or '' self.proxy_user_line = QLineEdit(user) self.proxy_user_line.setEnabled(self.proxy_auth_bool) password = self.settings.value('Proxy_password') or '' self.proxy_pass_line = QLineEdit(password) self.proxy_pass_line.setEnabled(self.proxy_auth_bool) self.proxy_pass_line.setEchoMode(QLineEdit.Password) self.status_layout = QHBoxLayout() self.status_label = QLabel() self.status_layout.addWidget(self.status_label) self.panel = QGridLayout() self.panel.addWidget(self.proxy_url_label, 0, 0) self.panel.addWidget(self.proxy_url_line, 0, 1) self.panel.addWidget(self.proxy_port_label, 0, 2) self.panel.addWidget(self.proxy_port_line, 0, 3) self.panel.addWidget(self.proxy_auth_label, 1, 0) self.panel.addWidget(self.proxy_auth_checkbox, 1, 1) self.panel.addWidget(self.proxy_user_label, 2, 0) self.panel.addWidget(self.proxy_user_line, 2, 1) self.panel.addWidget(self.proxy_pass_label, 3, 0) self.panel.addWidget(self.proxy_pass_line, 3, 1) self.layout.addLayout(self.panel) self.layout.addLayout(self.status_layout) self.layout.addLayout(self.buttonLayout) self.setLayout(self.layout) def proxy_auth(self, state): if state == 2: self.proxy_auth_bool = True self.proxy_user_label.setEnabled(True) self.proxy_pass_label.setEnabled(True) self.proxy_user_line.setEnabled(True) self.proxy_pass_line.setEnabled(True) else: self.proxy_auth_bool = False self.proxy_user_label.setEnabled(False) self.proxy_pass_label.setEnabled(False) self.proxy_user_line.setEnabled(False) self.proxy_pass_line.setEnabled(False) def accept(self): port = self.proxy_port_line.text() if port.isdigit() or port == '': self.settings.setValue('Proxy_url', self.proxy_url_line.text()) self.settings.setValue('Proxy_port', port) self.settings.setValue('Use_proxy_authentification', str(self.proxy_auth_bool)) if self.proxy_auth_bool: self.settings.setValue('Proxy_user', self.proxy_user_line.text()) self.settings.setValue('Proxy_password', self.proxy_pass_line.text()) else: self.status_label.setText('Port number must contain only digits') return QDialog.accept(self)
def save(self): """Stores the settings.""" s = QSettings() s.beginGroup("musicview/magnifier") s.setValue("size", self.size) s.setValue("scale", self.scale)
def __init__(self, parent=None): super().__init__() self.__settings = QSettings(QSettings.NativeFormat, QSettings.UserScope, ORG_NAME, APP_NAME) self.pBox = QtWidgets.QFrame(parent) self.pBox.setStyleSheet( ".QFrame{background-color: rgba(192, 192, 192, 192); border: 2px solid #000060;}" ) self.pBoxBtnHeader = btnHeader(self.pBox) self.pBoxBtnHeader.setStyleSheet( ".btnHeader{background-color: rgba(48, 48, 80, 192); border-radius: 0px}" ) self.pBoxLblStart = QtWidgets.QLabel(self.pBoxBtnHeader) debut = datetime.now() self.pBoxLblStart.setText( self.tr("GCode started at: {}").format( debut.strftime("%A %x %H:%M:%S"))) self.pBoxLblStart.setStyleSheet("color: white;") self.pBoxLblStart.adjustSize() self.pBoxBtnHeader.setGeometry(2, 2, self.pBoxLblStart.width() + 36, self.pBoxBtnHeader.height()) self.pBoxLblStart.setGeometry( 20, (self.pBoxBtnHeader.height() - self.pBoxLblStart.height()) / 2, self.pBoxLblStart.width(), self.pBoxLblStart.height()) self.pBoxProgress = QtWidgets.QProgressBar(self.pBox) self.pBoxProgress.setAlignment(Qt.AlignHCenter) self.pBoxProgress.setGeometry( 20, self.pBoxBtnHeader.geometry().y() + self.pBoxBtnHeader.height() + 9, self.pBoxLblStart.width(), 20) self.pBoxProgress.setRange(0, 100) self.pBoxProgress.setValue(37) self.pBoxLblComment = QtWidgets.QLabel(self.pBox) self.pBoxLblComment.setText("()") self.pBoxLblComment.setGeometry( 20, self.pBoxProgress.geometry().y() + self.pBoxProgress.height() + 3, self.pBoxLblStart.width(), 20) self.pBoxLblElapse = QtWidgets.QLabel(self.pBox) total_seconds = int((datetime.now() - debut).total_seconds()) hours, remainder = divmod(total_seconds, 60 * 60) minutes, seconds = divmod(remainder, 60) self.pBoxLblElapse.setText(self.tr("Elapsed time:")) self.pBoxLblElapse.setGeometry( 20, self.pBoxLblComment.geometry().y() + self.pBoxLblComment.height() + 3, self.pBoxLblStart.width(), 20) pBoxLargeur = self.pBoxLblStart.width() + 40 pBoxHauteur = self.pBoxLblElapse.geometry().y( ) + self.pBoxLblElapse.height() + 6 defaultX = int((parent.width() - pBoxLargeur) / 2) defaultY = int((parent.height() - pBoxHauteur) / 5 * 3) pBoxX = self.__settings.value("ProgressBox/posX", defaultX, type=int) pBoxY = self.__settings.value("ProgressBox/posY", defaultY, type=int) self.pBox.setGeometry(pBoxX, pBoxY, pBoxLargeur, pBoxHauteur) self.pBox.setVisible(False)
class MainWindow(QMainWindow): """The main window, containing the search bar and results table.""" def __init__(self, db, keybinds): super(MainWindow, self).__init__() self.settings = QSettings("xapers-qt", "xapers-qt") self.shortcuts = [] self.db = db self.ui = Ui_MainWindow() self.ui.setupUi(self) self.results = self.ui.resultsWidget self.searchBar = self.ui.searchBar self.results.setDb(self.db) self.results.setSettings(self.settings) self.setupKeybinds(keybinds) self.restore_size() self.show() def restore_size(self): """Resize to size stored in settings. """ try: width = int(self.settings.value("main/width", 800)) except ValueError: width = 800 try: height = int(self.settings.value("main/height", 300)) except ValueError: height = 300 self.resize(width, height) def startSearch(self): """Launches a search.""" self.results.doSearch(self.searchBar.text()) def setupKeybinds(self, binds): """Setup the keyboard shortcuts. """ for shortcut in self.shortcuts: pass # TODO Delete shortcut? for keys, action in binds: if action == "Search": func = self.focusSearchBar elif action == "Next": func = self.results.selectNext elif action == "Prev": func = self.results.selectPrev elif action == "OpenPDF": func = self.results.openPDF elif action == "OpenDoc": func = self.results.openDoc elif action == "Exit": func = self.close else: action = None if action: shortcut = QShortcut(QKeySequence(keys), self) shortcut.activated.connect(func) self.shortcuts.append(shortcut) def focusSearchBar(self): """Set focus to the search bar.""" self.searchBar.searchLine.setFocus(Qt.ShortcutFocusReason) def saveSettings(self): """Save any settings we may have changed.""" self.settings.setValue("main/width", self.width()) self.settings.setValue("main/height", self.height()) self.results.saveSettings() def closeEvent(self, event): """Things to do when closing the window. """ self.saveSettings() def resizeEvent(self, resizeEvent): """Things to do when resizing the window. """ self.results.refresh()
def saveApplicationSettings(self): settings = QSettings() settings.setValue("MainWindow/Size", self.size()) settings.setValue("MainWindow/Position", self.pos()) settings.setValue("MainWindow/State", self.saveState()) settings.setValue("MainWindow/ViewsLocked", self.ui.actionLocked.isChecked()) if self.labeltool.getCurrentFilename() is not None: filename = self.labeltool.getCurrentFilename() else: filename = None settings.setValue("LastFile", filename)
# SEPARATION COLORS ONES_AREA_COLOR = QColor.fromRgb(0, 128, 128) ZEROS_AREA_COLOR = QColor.fromRgb(90, 9, 148) SEPARATION_OPACITY = 0.2 SEPARATION_PADDING = .05 # Prozent # PROTOCOL TABLE COLORS SELECTED_ROW_COLOR = QColor.fromRgb(0, 0, 255) DIFFERENCE_CELL_COLOR = QColor.fromRgb(255, 0, 0) PROPERTY_FOUND_COLOR = QColor.fromRgb(0, 124, 0, 100) PROPERTY_NOT_FOUND_COLOR = QColor.fromRgb(124, 0, 0, 100) SEPARATION_ROW_HEIGHT = 30 SETTINGS = QSettings(QSettings.IniFormat, QSettings.UserScope, 'urh', 'urh') PROJECT_FILE = "URHProject.xml" DECODINGS_FILE = "decodings.txt" FIELD_TYPE_SETTINGS = os.path.realpath(os.path.join(SETTINGS.fileName(), "..", "fieldtypes.xml")) # DECODING NAMES DECODING_INVERT = "Invert" DECODING_DIFFERENTIAL = "Differential Encoding" DECODING_REDUNDANCY = "Remove Redundancy" DECODING_DATAWHITENING = "Remove Data Whitening (CC1101)" DECODING_CARRIER = "Remove Carrier" DECODING_BITORDER = "Change Bitorder" DECODING_EDGE = "Edge Trigger" DECODING_SUBSTITUTION = "Substitution" DECODING_EXTERNAL = "External Program"
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.chunk_directory = Directory( "CHUNK", QIcon(Assets.get_asset_path("document_a4_locked.png")), None) self.mod_directory = Directory( "MOD", QIcon(Assets.get_asset_path("document_a4.png")), None) self.workspace = Workspace([self.mod_directory, self.chunk_directory], parent=self) self.workspace.fileOpened.connect(self.handle_workspace_file_opened) self.workspace.fileClosed.connect(self.handle_workspace_file_closed) self.workspace.fileActivated.connect(self.handle_workspace_file_activated) self.workspace.fileLoadError.connect(self.handle_workspace_file_load_error) self.init_actions() self.init_menu_bar() self.init_toolbar() self.setStatusBar(QStatusBar()) self.setWindowTitle("MHW-Editor-Suite") self.init_file_tree( self.chunk_directory, "Chunk directory", self.open_chunk_directory_action, filtered=True) self.init_file_tree( self.mod_directory, "Mod directory", self.open_mod_directory_action) self.setCentralWidget(self.init_editor_tabs()) self.load_settings() def closeEvent(self, event): self.write_settings() def load_settings(self): self.settings = QSettings(QSettings.IniFormat, QSettings.UserScope, "fre-sch.github.com", "MHW-Editor-Suite") self.settings.beginGroup("MainWindow") size = self.settings.value("size", QSize(1000, 800)) position = self.settings.value("position", QPoint(300, 300)) self.settings.endGroup() self.settings.beginGroup("Application") chunk_directory = self.settings.value("chunk_directory", None) mod_directory = self.settings.value("mod_directory", None) lang = self.settings.value("lang", None) self.settings.endGroup() self.resize(size) self.move(position) if chunk_directory: self.chunk_directory.set_path(chunk_directory) if mod_directory: self.mod_directory.set_path(mod_directory) if lang: self.handle_set_lang_action(lang) def write_settings(self): self.settings.beginGroup("MainWindow") self.settings.setValue("size", self.size()) self.settings.setValue("position", self.pos()) self.settings.endGroup() self.settings.beginGroup("Application") self.settings.setValue("chunk_directory", self.chunk_directory.path) self.settings.setValue("mod_directory", self.mod_directory.path) self.settings.setValue("lang", FilePluginRegistry.lang) self.settings.endGroup() def get_icon(self, name): return self.style().standardIcon(name) def init_actions(self): self.open_chunk_directory_action = create_action( self.get_icon(QStyle.SP_DirOpenIcon), "Open chunk_directory ...", self.handle_open_chunk_directory, None) self.open_mod_directory_action = create_action( self.get_icon(QStyle.SP_DirOpenIcon), "Open mod directory ...", self.handle_open_mod_directory, QKeySequence.Open) self.save_file_action = create_action( self.get_icon(QStyle.SP_DriveHDIcon), "Save file", self.handle_save_file_action, QKeySequence.Save) self.save_file_action.setDisabled(True) self.export_csv_action = create_action( self.get_icon(QStyle.SP_FileIcon), "Export file to CSV...", self.handle_export_file_action) self.export_csv_action.setDisabled(True) self.about_action = create_action( None, "About", self.handle_about_action) self.lang_actions = { lang: create_action( None, name, partial(self.handle_set_lang_action, lang), checkable=True) for lang, name in LANG } def init_menu_bar(self): menubar = self.menuBar() file_menu = menubar.addMenu("File") file_menu.insertAction(None, self.open_chunk_directory_action) file_menu.insertAction(None, self.open_mod_directory_action) file_menu.insertAction(None, self.export_csv_action) file_menu.insertAction(None, self.save_file_action) lang_menu = menubar.addMenu("Language") for action in self.lang_actions.values(): lang_menu.insertAction(None, action) help_menu = menubar.addMenu("Help") help_menu.insertAction(None, self.about_action) def init_toolbar(self): toolbar = self.addToolBar("Main") toolbar.setIconSize(QSize(16, 16)) toolbar.setFloatable(False) toolbar.setMovable(False) toolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) toolbar.insertAction(None, self.open_mod_directory_action) toolbar.insertAction(None, self.save_file_action) def init_file_tree(self, directory, title, action, filtered=False): widget = DirectoryDockWidget(directory, filtered=filtered, parent=self) widget.path_label.addAction(action, QLineEdit.LeadingPosition) widget.tree_view.activated.connect( partial(self.handle_directory_tree_view_activated, directory)) dock = QDockWidget(title, self) dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) dock.setFeatures(QDockWidget.DockWidgetMovable) dock.setWidget(widget) self.addDockWidget(Qt.LeftDockWidgetArea, dock) def handle_directory_tree_view_activated(self, directory, qindex: QModelIndex): if qindex.model().isDir(qindex): return file_path = qindex.model().filePath(qindex) self.workspace.open_file(directory, file_path) def init_editor_tabs(self): self.editor_tabs = QTabWidget() self.editor_tabs.setDocumentMode(True) self.editor_tabs.setTabsClosable(True) self.editor_tabs.tabCloseRequested.connect( self.handle_editor_tab_close_requested) return self.editor_tabs def handle_workspace_file_opened(self, path, rel_path): ws_file = self.workspace.files[path] editor_view = EditorView.factory(self.editor_tabs, ws_file) editor_view.setObjectName(path) self.editor_tabs.addTab(editor_view, ws_file.directory.file_icon, f"{ws_file.directory.name}: {rel_path}") self.editor_tabs.setCurrentWidget(editor_view) self.save_file_action.setDisabled(False) self.export_csv_action.setDisabled(False) def handle_workspace_file_activated(self, path, rel_path): widget = self.editor_tabs.findChild(QWidget, path) self.editor_tabs.setCurrentWidget(widget) def handle_workspace_file_closed(self, path, rel_path): widget = self.editor_tabs.findChild(QWidget, path) widget.deleteLater() self.save_file_action.setDisabled(not self.workspace.files) self.export_csv_action.setDisabled(not self.workspace.files) def handle_workspace_file_load_error(self, path, rel_path, error): QMessageBox.warning(self, f"Error loading file `{rel_path}`", f"Error while loading\n{path}:\n\n{error}", QMessageBox.Ok, QMessageBox.Ok) def handle_editor_tab_close_requested(self, tab_index): editor_view = self.editor_tabs.widget(tab_index) self.workspace.close_file(editor_view.workspace_file) def handle_open_chunk_directory(self): path = QFileDialog.getExistingDirectory(parent=self, caption="Open chunk directory") if path: self.chunk_directory.set_path(os.path.normpath(path)) def handle_open_mod_directory(self): path = QFileDialog.getExistingDirectory(parent=self, caption="Open mod directory") if path: self.mod_directory.set_path(os.path.normpath(path)) def handle_save_file_action(self): editor = self.editor_tabs.currentWidget() main_ws_file = editor.workspace_file for ws_file in main_ws_file.get_files_modified(): if ws_file.directory is self.chunk_directory: if self.mod_directory.is_valid: self.transfer_file_to_mod_workspace( ws_file, ws_file is main_ws_file) else: self.save_base_content_file(ws_file) else: with show_error_dialog(self, "Error writing file"): self.save_workspace_file(ws_file) def handle_export_file_action(self): editor = self.editor_tabs.currentWidget() ws_file = editor.workspace_file file_name, file_type = QFileDialog.getSaveFileName(self, "Export file as CSV") if file_name: if not file_name.endswith(".csv"): file_name += ".csv" with show_error_dialog(self, "Error exporting file"): self.write_csv(ws_file, file_name) self.statusBar().showMessage( f"Export '{file_name}' finished.", STATUSBAR_MESSAGE_TIMEOUT) def handle_set_lang_action(self, lang): FilePluginRegistry.lang = lang for act in self.lang_actions.values(): act.setChecked(False) self.lang_actions[lang].setChecked(True) def write_csv(self, ws_file, file_name): with open(file_name, "w") as fp: csv_writer = csv.writer( fp, delimiter=",", doublequote=False, escapechar='\\', lineterminator="\n") cls = type(ws_file.data) fields = cls.EntryFactory.fields() csv_writer.writerow(fields) for entry in ws_file.data.entries: csv_writer.writerow(entry.values()) def save_base_content_file(self, ws_file): result = QMessageBox.question( self, "Save base content file?", "Do you really want to update this chunk file?", QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Cancel) if result == QMessageBox.Ok: with show_error_dialog(self, "Error writing file"): self.save_workspace_file(ws_file) def transfer_file_to_mod_workspace(self, ws_file, reopen=False): mod_abs_path, exists = self.mod_directory.get_child_path(ws_file.rel_path) if not exists: return self.transfer_file(ws_file, self.mod_directory, reopen) result = QMessageBox.question( self, "File exists, overwrite?", f"File '{ws_file.rel_path}' already found in mod directory, overwrite?", QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok) if result == QMessageBox.Ok: self.transfer_file(ws_file, self.mod_directory, reopen) def transfer_file(self, ws_file, target_directory, reopen=False): if target_directory is ws_file.directory: return self.workspace.close_file(ws_file) ws_file.set_directory(target_directory) self.save_workspace_file(ws_file) if reopen: self.workspace.open_file(target_directory, ws_file.abs_path) def save_workspace_file(self, ws_file): ws_file.save() self.statusBar().showMessage( f"File '{ws_file.abs_path}' saved.", STATUSBAR_MESSAGE_TIMEOUT) def handle_about_action(self): dialog = QDialog(self) dialog.setWindowTitle("About MHW Editor Suite") layout = QVBoxLayout() dialog.setLayout(layout) about_text = QLabel(ABOUT_TEXT) about_text.setTextFormat(Qt.RichText) about_text.setTextInteractionFlags(Qt.TextBrowserInteraction) about_text.setOpenExternalLinks(True) layout.addWidget(about_text) dialog.exec()
def __init__(self): super().__init__() self.setupUi(self) self.setWindowTitle('Settings') self.settings = QSettings('settings.ini', QSettings.IniFormat) self.load_settings()
def run_gui(api_port, api_key, root_state_dir, parsed_args): logger.info('Running GUI' + ' in gui_test_mode' if parsed_args.gui_test_mode else '') # Workaround for macOS Big Sur, see https://github.com/Tribler/tribler/issues/5728 if sys.platform == "darwin": logger.info('Enabling a workaround for macOS Big Sur') os.environ["QT_MAC_WANTS_LAYER"] = "1" # Workaround for Ubuntu 21.04+, see https://github.com/Tribler/tribler/issues/6701 elif sys.platform == "linux": logger.info( 'Enabling a workaround for Ubuntu 21.04+ wayland environment') os.environ["GDK_BACKEND"] = "x11" # Set up logging load_logger_config('tribler-gui', root_state_dir) # Enable tracer using commandline args: --trace-debug or --trace-exceptions trace_logger = check_and_enable_code_tracing('gui', root_state_dir) try: enable_fault_handler(root_state_dir) # Exit if we cant read/write files, etc. check_environment() check_free_space() app_name = os.environ.get('TRIBLER_APP_NAME', 'triblerapp') app = TriblerApplication(app_name, sys.argv) # Note (@ichorid): translator MUST BE created and assigned to a separate variable # before calling installTranslator on app. Otherwise, it won't work for some reason settings = QSettings('nl.tudelft.tribler') translator = get_translator(settings.value('translation', None)) app.installTranslator(translator) if app.is_running(): # if an application is already running, then send the command line # argument to it and close the current instance logger.info( 'GUI Application is already running. Passing a torrent file path to it.' ) for arg in sys.argv[1:]: if os.path.exists(arg) and arg.endswith(".torrent"): app.send_message(path_to_uri(arg)) elif arg.startswith('magnet'): app.send_message(arg) logger.info('Close the current application.') sys.exit(1) logger.info('Start Tribler Window') window = TriblerWindow(settings, root_state_dir, api_port=api_port, api_key=api_key) window.setWindowTitle("Tribler") app.set_activation_window(window) app.parse_sys_args(sys.argv) sys.exit(app.exec_()) except ImportError as ie: logger.exception(ie) error_and_exit("Import Error", f"Import error: {ie}") except TriblerException as te: logger.exception(te) error_and_exit("Tribler Exception", f"{te}") except SystemExit: logger.info("Shutting down Tribler") if trace_logger: trace_logger.close() # Flush all the logs to make sure it is written to file before it exits for handler in logging.getLogger().handlers: handler.flush() gui_sentry_reporter.global_strategy = SentryStrategy.SEND_SUPPRESSED raise
class NewNodeBaseDialog(QDialog): def __init__(self, parent, title, server): QDialog.__init__(self, parent) self.setWindowTitle(title) self.settings = QSettings() self.server = server self.vlayout = QVBoxLayout(self) self.layout = QHBoxLayout() self.vlayout.addLayout(self.layout) self.layout.addWidget(QLabel("ns:", self)) self.nsComboBox = QComboBox(self) uries = server.get_namespace_array() for uri in uries: self.nsComboBox.addItem(uri) nsidx = int(self.settings.value("last_namespace", len(uries) - 1)) if nsidx > len(uries) - 1: nsidx = len(uries) - 1 self.nsComboBox.setCurrentIndex(nsidx) self.layout.addWidget(self.nsComboBox) self.layout.addWidget(QLabel("Name:", self)) self.nameLabel = QLineEdit(self) self.nameLabel.setText("NoName") self.layout.addWidget(self.nameLabel) self.nodeidCheckBox = QCheckBox("Auto NodeId", self) self.nodeidCheckBox.setChecked(True) self.nodeidCheckBox.stateChanged.connect(self._show_nodeid) self.layout.addWidget(self.nodeidCheckBox) self.nodeidLineEdit = QLineEdit(self) self.nodeidLineEdit.setText("ns={};i=20000".format(nsidx)) self.layout.addWidget(self.nodeidLineEdit) self.nodeidLineEdit.hide() self.buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) self.vlayout.addWidget(self.buttons) self.buttons.accepted.connect(self.accept) self.buttons.accepted.connect(self._store_state) self.buttons.rejected.connect(self.reject) def _store_state(self): self.settings.setValue("last_namespace", self.nsComboBox.currentIndex()) def _show_nodeid(self, val): if val: self.nodeidLineEdit.hide() else: self.nodeidLineEdit.show() self.adjustSize() def get_ns_and_name(self): args = [] ns = self.nsComboBox.currentIndex() name = self.nameLabel.text() if self.nodeidCheckBox.isChecked(): args.append(ns) args.append(name) else: nodeid = ua.NodeId.from_string(self.nodeidLineEdit.text()) args.append(nodeid) args.append(ua.QualifiedName(name, ns)) return args def get_args(self): args = self.get_ns_and_name() print("NewNodeBaseDialog returns:", args) return args @classmethod def getArgs(cls, parent, title, server, *args, **kwargs): dialog = cls(parent, title, server, *args, **kwargs) result = dialog.exec_() if result == QDialog.Accepted: return dialog.get_args(), True else: return [], False
# create tables plugins_db.createTables() # delete old links plugins_db.deleteOldLinks() # close connections plugins_db.closeConnections() # import persepolis_setting # persepolis is using QSettings for saving windows size and windows # position and program settings. persepolis_setting = QSettings('persepolis_download_manager', 'persepolis') persepolis_setting.beginGroup('settings') # download files is downloading in temporary folder(download_path_temp) and then they will be moved to user download folder(download_path) after completion. # persepolis temporary download folder if os_type != 'Windows': download_path_temp = str(home_address) + '/.persepolis' else: download_path_temp = os.path.join( str(home_address), 'AppData', 'Local', 'persepolis') # user download folder path download_path = os.path.join(str(home_address), 'Downloads', 'Persepolis') # Persepolis default setting
class RTG: def __init__(self, settings=None, db=None, overnight=0): ''' :params overnight:Percentage of trades to include overnight transaction. ''' self.overnight = overnight if settings: self.settings = settings else: self.settings = QSettings("zero_substance", "structjour") if db is not None: self.db = db else: self.db = self.settings.value('tradeDb') self.testfiles = [] def makeRandomDASImport(self, numTrades, start, outfile=None, strict=False, overwrite=True): start = pd.Timestamp(start) df = self.getRandomTradeDF(numTrades=numTrades, start=start, strict=strict) if outfile: outfile, ext = os.path.splitext(outfile) outfile = f'''{outfile}_{start.strftime('%Y%m%d')}{ext}''' d = os.path.dirname(outfile) if not overwrite and os.path.exists(outfile): return outfile, df if os.path.exists(d): df.to_csv(outfile, index=False) else: logging.error(f'Failed to save file. Directory {d} does not exist') return outfile, df def makeOvernight(self, df): if len(df) > 2 and random.randint(0, 99) < self.overnight: r = random.random() delrow = df.index[0] if r < .5 else df.index[-1] df.drop(delrow, inplace=True) return df def saveSomeTestFiles(self, dates, outdir, outfile='DASrandomTrades.csv', strict=False, overwrite=False): ''' Create DAS export like random trades.csv files for testing purposes :params dates: Create one file for each date. Date will be appended to the name :parmas outdir: The directory to place the files :params outfile: The name for the file. Date will be appended to each file :params outfile: The base name for the files. Final name will be {outfile}_yyyymmdd{ext} :params strict: If False, files will include Balance and Date fields :params overwrite: If False files already exist will be overwritten. Otherwise writing the file is quietly skipped. ''' savedfiles = [] for date in dates: date = pd.Timestamp(date) filename = os.path.join(outdir, outfile) filename, df = self.makeRandomDASImport(random.randint(3, 5), date, outfile=filename, strict=strict, overwrite=overwrite) savedfiles.append(filename) return savedfiles def getRandomTradeDF(self, numTrades=None, start='2018-06-06 09:30:00', strict=False): ''' Creates a day of trades in the same form with the required columns from a DAS export plus a Balance and Date column. Use strict=True to remove them :numTrades: The number of trades in the statemnt :start: The earliest possible trade start time. ''' if numTrades is None: numTrades = random.randint(1, 10) start = pd.Timestamp(start) df = pd.DataFrame() exclude = [] for i in range(numTrades): tdf, start = self.randomTradeGenerator2(earliest=start, pdbool=True, exclude=exclude) if strict is True: tdf = tdf.drop(['Balance', 'Date'], axis=1) df = df.append(tdf) exclude.append(tdf.Symb.unique()[0]) df.reset_index(drop=True, inplace=True) return df def randomTradeGenerator2(self, earliest=pd.Timestamp('2019-01-01 09:30:00'), pdbool=True, exclude=None): ''' Create a passable DAS import :params earliest: Transaction progress in time with earliest as the easliest possible trade except for before HOLDs. :params pdbool: Setting to True will cause the return to be a DataFrame instead of an array. Deprecated. Changed to allways return a dataframe :params exclude: A list of symbols to exclude as candidates for this trade :return pd.DataFrame: DataFrame or list of transactions making up a single trade. ''' earliest = pd.Timestamp(earliest) latest = earliest start = earliest nowtime = start numTrades = self.getNumTrades(maxt=10) trade = list() prevBal = 0 price = 0 long = True # duration = '' sumtotal = 0 account = self.getAccount() # account = 'U000000' ticker = self.getTicker(exclude=exclude) daDate = pd.Timestamp(start.year, start.month, start.day) cloid = -1 average = 0 oc = '' for i in range(numTrades): firsttrade = True if i == 0 else False nexttime = self.getRandomFuture(nowtime) latest = nexttime pl = 0 side = self.getSide(firsttrade=firsttrade) if firsttrade: # Note: not using these yet. If we start, may need to add a test identifier and convert to string cloid = random.randint(-999999999999, -100000000000) if side == 'S' or side.find('-') >= 0: long = False price = self.getPrice() average = price oc = 'O' else: price = self.getPrice(price, long) time = nowtime.strftime("%H:%M:%S") daDate = pd.Timestamp(daDate.year, daDate.month, daDate.day, nowtime.hour, nowtime.minute, nowtime.second) cloid += 1 if i == numTrades - 1: side = 'S' if prevBal >= 0 else 'B' # pl = self.getPL() pl = (average - price) * -prevBal trade.append([time, ticker, side, price, -prevBal, 0, account, pl, daDate, cloid, average, 'C']) sumtotal = sumtotal + pl prevBal = 0 break else: qty = random.randint(1, 500) qty = -qty if (side == 'S' or side == 'HOLD-B') else qty # Check for flippers if long and (prevBal + qty) < 0: long = False elif not long and (prevBal + qty) > 0: long = True if (long is True and side == 'B') or (long is not True and side != 'B'): # An opener -- adjust the average # Average = ((PrevAvg * PrevBal) + (Qty * Price))/ Balance average = ((average * prevBal) + (qty * price)) / (prevBal + qty) oc = 'O' else: # a closer-- figure the pl # pl = (average - price) * qty pl = (average - price) * qty oc = 'C' trade.append([time, ticker, side, price, qty, prevBal + qty, account, pl, daDate, cloid, average, oc]) sumtotal = sumtotal + pl prevBal = prevBal + qty if prevBal == 0: # We are coincidentally at 0 balance. Trade is over. Must be a hotkey mistake ;-) break nowtime = nexttime # duration = nowtime - start tradedf = pd.DataFrame(data=trade, columns=['Time', 'Symb', 'Side', 'Price', 'Qty', 'Balance', 'Account', 'P / L', 'Date', 'Cloid', 'Average', 'OC']) tradedf['Commission'] = float('nan') tradedf = self.makeOvernight(tradedf) return tradedf, latest def getPrice(self, price=None, long=True): if price is None: price = random.randint(3, 300) + random.randint(0, 99) / 100 return price change = (random.random() / 70) upordown = random.random() if long and upordown > .62: change *= -1 elif not long and upordown > .38: change *= -1 return price + (price * change) def getNumTrades(self, maxt=8): ''' Return a number between 2 and 8 by default ''' t = random.randint(2, maxt) return t def getAccount(self): ''' Get a randoms account real or sim ''' real = 'U000000' sim = 'TRIB0000' percentReal = .75 r = random.random() acct = real if r < percentReal else sim return acct def getTicker(self, exclude=None): ''' Get a random ticker symbol :exclude: A list of tickers to exclude from consideration. ''' tickers = ['SQ', 'AAPL', 'TSLA', 'ROKU', 'NVDA', 'NUGT', 'MSFT', 'CAG', 'ACRS', 'FRED', 'PCG', 'AMD', 'GE', 'NIO', 'AMRN', 'FIVE', 'BABA', 'BPTH', 'Z', ] tick = tickers[random.randint(0, len(tickers) - 1)] if exclude and tick in exclude: if not set(tickers).difference(set(exclude)): # We could make up some random letters here if this ever ....-- or include more raise ValueError("You have excluded every stock in the method") return self.getTicker(exclude=exclude) return tick def getRandomFuture(self, earliest=pd.Timestamp('2019-01-01 09:30:00')): ''' Get a time that is in the future a random amount of seconds from earliset ''' rsec = random.randint(45, 1500) nextt = earliest + pd.Timedelta(seconds=rsec) return nextt def getSide(self, firsttrade=False): ''' Get a random distribution of 'B', 'S', 'HOLD+', 'HOLD-'. Set the probabilities here. HOLDs provide the weirdest exceptions. They should be relatively likely for tests. ''' s = random.random() side = 'B'if s < .55 else 'S' return side def getPL(self): ''' Get a random dollar amount ''' amnt = random.random() upordown = random.random() upordown = 1 if upordown > .4 else -1 multiplier = random.randint(2, 200) return amnt * upordown * multiplier
class ProjectHTMLDlg(QDialog, Ui_ProjectHTMLDlg): """ Class documentation goes here. """ def __init__(self, parent=None, schemaModel = None, model = None): """ Constructor @param parent reference to the parent widget @type QWidget """ super(ProjectHTMLDlg, self).__init__(parent) self.setupUi(self) self.settings = QSettings() self.schemaModel = schemaModel self.model = model self.projectData = model.modelData self.helper = Helper() # initialize the header area dir = self.projectData["GenToDir"] self.lblOutputDir.setText(dir) self.lblOutputDir.setToolTip(dir) # initialize the report generation fields self.txtTitle.setText(self.projectData["HeaderTitle"]) self.txtHomeTitle.setText(self.projectData["HomePageTitle"]) self.txtAuthor.setText(self.projectData["Author"]) self.txtFooter.setText(self.projectData["FooterTitle"]) self.txtImageFile.setText(self.projectData["IconFile"]) if len(self.projectData.get("IconFile", "")) > 0: self.loadImage() def outputPath(self): return self.lblOutputDir.text() def fileFormat(self): '''only one file format for now ''' return QByteArray(b'HTML') def fileExtension(self): '''Only one file extension for now ''' return "HTML" def loadImage(self, ): '''load the image file into the frame ''' try: fileName = self.txtImageFile.text() pixmap = QPixmap(fileName) self.frmImage.setPixmap(pixmap.scaled(self.frmImage.width(), self.frmImage.height(), aspectRatioMode = Qt.KeepAspectRatio)) except Exception as e: self.helper.displayErrMsg("Load Image", "Error loading {} image file. Error: {}".format(fileName, str(e))) return def getImage(self, ): '''return a QImage if valid image file is present ''' try: fileName = self.txtImageFile.text() if len(fileName) > 0: if os.path.isfile(fileName) == True: pixmap = QPixmap(fileName) anImage = pixmap.toImage() return fileName, anImage else: self.helper.displayErrMsg("Load Image", "Image File: {} not a valid file.".format(fileName)) return fileName, None else: return fileName, None except Exception as e: self.helper.displayErrMsg("Load Image", "Error loading {} image file. Error: {}".format(fileName, str(e))) return fileName, None # should never happen return None, None def saveSetupData(self): # save the report generation fields self.projectData["GenToDir"]= self.lblOutputDir.text() self.projectData["HeaderTitle"]= self.txtTitle.text() self.projectData["HomePageTitle"] = self.txtHomeTitle.text() self.projectData["Author"] = self.txtAuthor.text() self.projectData["FooterTitle"] = self.txtFooter.text() self.projectData["IconFile"] = self.txtImageFile.text() @pyqtSlot() def on_btnSelectDir_clicked(self): """ User selects Path button to select an output path """ curDir = self.lblOutputDir.text() dlg = QFileDialog() dlg.setFileMode(QFileDialog.Directory) dlg.setDirectory(curDir) file = str(dlg.getExistingDirectory(self, "Select Directory")) if file: self.lblOutputDir.setText(str(file)) self.lblOutputDir.setToolTip(str(file)) @pyqtSlot() def on_btnLoadImage_clicked(self): """ User clicks on image file button. They select an image file from disk. """ dlg = QFileDialog() dlg.setFileMode(QFileDialog.ExistingFile) dlg.setAcceptMode(QFileDialog.AcceptOpen) dlg.setNameFilters(["Image Files (*.bmp *.gif *.jpg *.jpeg *.png)","all files (*.*)"]) dlg.setDirectory(self.settings.value("Default/ProjPath")) if dlg.exec_(): fileNames = dlg.selectedFiles() if fileNames: fileName = fileNames[0] self.txtImageFile.setText(fileName) if len(self.txtImageFile.text()) > 0: self.loadImage() @pyqtSlot() def on_btnGenerate_clicked(self): """ User clicks button to generate html using Mako """ try: # setup folder structure, cancel html generation if error if self.createFolders(): QApplication.setOverrideCursor(Qt.WaitCursor) # generate home page self.genIndexPage2() # generate object pages for objectType in self.projectData["TopLevel"]: if objectType in ["Label","Property","Relationship","Node Template", "Relationship Template", "Template Diagram", "Instance Diagram" ]: objectList = self.model.instanceList(objectType) objectPath = self.outputPath() + "/PAGES/{}".format(''.join(objectType.upper().split()) ) if len(objectList) > 0: if os.path.exists(objectPath) == False: os.mkdir(objectPath) for objectName in objectList: self.genObjectPage2(objectType=objectType, objectName=objectName) # completed message QApplication.restoreOverrideCursor() self.helper.displayErrMsg("Generate HTML", 'HTML generation complete! Click "View In Browser" button.') except Exception as e: self.helper.displayErrMsg("Generate HTML", "Error clearing html folders. Error: {}".format(str(e))) finally: QApplication.restoreOverrideCursor() @pyqtSlot() def on_btnViewBrowser_clicked(self): """ user clicks on the view in browser button """ genPath = self.outputPath() indexFileName = genPath + "/index.html" if os.path.isfile(indexFileName) == True: webbrowser.open(indexFileName) else: self.helper.displayErrMsg("Open Browser", "Error - index.html file {} not found.") @pyqtSlot() def on_btnClose_clicked(self): """ User clicks the Close button """ # save the report generation fields self.saveSetupData() QDialog.accept(self) ############################################################ ## diagram render methods ############################################################ def renderDiagram(self, diagramType=None, diagramName=None, fileName=None): # the parent of the scene needs to maintain these dictionaries self.itemDict = {} # dictionary of graphic items rendered on the scene self.relIRPair = {} self.relTRPair = {} # create the scene self.scene = DiagramScene(self) # render the diagram self.scene.renderDiagram(diagramType=diagramType, diagramName=diagramName) # save the image self.scene.saveImage(fileName=fileName) # these functions need to be in the parent of the scene. This needs to be refactored so the scene handles this def addRelationship(self, relItem): '''Track how many relationship instances exist between any pair of node instances. ''' key=relItem.startNZID + relItem.endNZID x = self.relIRPair.setdefault(key, 0) self.relIRPair[key] = x + 1 def numRels(self, startNZID, endNZID): return self.relIRPair.setdefault(startNZID + endNZID, 0) def anyRels(self, startNZID, endNZID): ''' return True if there are any instance relationships between these two nodes''' for key, value in self.itemDict.items(): if value.diagramType == "Instance Relationship": if value.startNZID in [startNZID, endNZID] and value.endNZID in [startNZID, endNZID]: return True return False def addTRelationship(self, relItem): '''Track how many relationship templates exist between any pair of node templates. ''' key=relItem.startNZID + relItem.endNZID # add the from/to key to the dictionary if it's not there, then return the current total which is initialized to zero (see next step) x = self.relTRPair.setdefault(key, 0) # increment the count and save it as the new total self.relTRPair[key] = x + 1 return self.relTRPair[key] ############################################################ def createFolders(self, ): # create directories indexFileName = self.outputPath() + "/index.html" pagePath = self.outputPath() + "/PAGES" imagePath = self.outputPath() + "/IMAGES" try: # first delete existing content if the user says ok if (os.path.isfile(indexFileName) == True or os.path.exists(pagePath) == True or os.path.exists(imagePath) == True): if self.helper.delObjectPrompt("Generated HTML files in {}".format(self.outputPath())): # delete existing content and re-add the needed folders if os.path.isfile(indexFileName) == True: os.remove(indexFileName) if os.path.exists(pagePath) == True: shutil.rmtree(pagePath) if os.path.exists(imagePath) == True: shutil.rmtree(imagePath) else: return False # now create the two needed folders if they don't exist if os.path.exists(pagePath) == False: os.mkdir(pagePath) if os.path.exists(imagePath) == False: os.mkdir(imagePath) except Exception as e: self.helper.displayErrMsg("Generate HTML", "Error checking {} for existing html folders, html generation cancelled. Error: {}".format(self.outputPath(), str(e))) return False # create the icon image file in the /images directory try: self.logoImage = None self.logoFile = None fileName, anImage = self.getImage() if not anImage is None: self.logoImage = anImage self.logoFile = imagePath + "/" + os.path.basename(fileName) anImage.save (self.logoFile) except Exception as e: self.helper.displayErrMsg("Generate HTML", "Error saving {} to {}. Error: {}".format(fileName, self.logoFile, str(e))) return False return True def genIndexPage2(self, ): try: genPath = self.outputPath() indexFileName = genPath + "/index.html" # make sur current generation settings are in the project model so template can see them self.saveSetupData() # get the template for the index page mytemplate = self.indexPageTemplate() # validate the file to write to file = QFile(indexFileName) if not file.open(QFile.WriteOnly | QFile.Text): self.helper.displayErrMsg("Generate HTML", "Cannot write file %s:\n%s." % (self.indexFileName, file.errorString())) return # generate the html page outstr = QTextStream(file) outstr << mytemplate.render(model=self.model, outputPath= self.outputPath()) except Exception as e: self.helper.displayErrMsg("Generate HTML", "Error saving {}. Error: {}".format(indexFileName, str(e))) def genObjectPage2(self, objectType=None, objectName=None ): try: # get the object dictionary index, objectDict = self.model.getDictByName(objectType, objectName) objectPath = self.outputPath() + "/PAGES/{}".format(''.join(objectType.upper().split()) ) objName = objectDict.get("name", "NoName") # goodObjName = self.helper.slugify(objName) goodObjName = "".join(x for x in objName if x.isalpha() or x.isnumeric() ) + "_file" objFileName = objectPath + "/{}.html".format(goodObjName) # get the template for the page mytemplate = self.objectPageTemplate(objectDict = objectDict) # validate the file to write to file = QFile(objFileName) if not file.open(QFile.WriteOnly | QFile.Text): self.helper.displayErrMsg("Generate HTML", "Cannot write file %s:\n%s." % (self.indexFileName, file.errorString())) return # generate the html page outstr = QTextStream(file) outstr << mytemplate.render(objectDict=objectDict, model=self.model, outputPath= self.outputPath(), genObjectType=objectType, genObjectName=objectName) except Exception as e: self.helper.displayErrMsg("Generate HTML", "Error saving {}. Error: {}".format(objFileName, str(e))) try: # for diagrams, also generate the PNG file and save it if objectType in ("Template Diagram", "Instance Diagram"): goodImgName = "".join(x for x in objName if x.isalpha() or x.isnumeric() ) + "_image" imgFileName = objectPath + "/{}.png".format(goodImgName) self.renderDiagram(diagramType=objectType, diagramName=objectName) # save the image self.scene.saveImage(fileName=imgFileName) except Exception as e: self.helper.displayErrMsg("Generate HTML", "Error saving {}. Error: {}".format(imgFileName, str(e))) def indexPageTemplate(self): aTemplate = Template(self.htmlHead() + self.htmlHeader() + self.htmlAside() + self.htmlIndexArticle() + self.htmlFooter() + self.htmlEnd()) return aTemplate def objectPageTemplate(self, objectDict = None): aTemplate = Template(self.htmlHead() + self.htmlHeader() + self.htmlAside() + self.htmlObjectArticle(objectDict = objectDict) + self.htmlFooter() + self.htmlEnd()) return aTemplate def htmlHead(self, ): html = ''' <!DOCTYPE html> <html> <head> <title>NodeEra Generated Web Page</title> <meta charset="UTF-8"> <style type="text/css">''' + self.htmlCSS() + ''' </style> </head> <body> <div class="wrapper">''' return html def htmlHeader(self, ): html = ''' <header class="header"> <table> <tbody> <tr> <h1><p> <img src="${model.modelData["IconFile"]}" /> <span>${model.modelData["HeaderTitle"]}</span> </p></h1> </tr> </tbody> </table> </header>''' return html def htmlAside(self, ): ''' this is the object list of links on the left hand side of the screen ''' html = ''' <aside class="aside"> <% homeURL = outputPath + "/index.html" %> <a href="${homeURL}"> <span>Home</span> </a> <h2><p>Model Objects</p></h2> % for objectType in ["Label","Property","Relationship","Node Template", "Relationship Template", "Template Diagram", "Instance Diagram" ]: <% objectPath = outputPath + "/PAGES/{}".format(''.join(objectType.upper().split()) ) %> <h3><p>${objectType}</p></h3> <ul> % for objectName in model.instanceList(objectType): <li> <% goodObjName = "".join(x for x in objectName if x.isalpha() or x.isnumeric() ) + "_file" objFile = "/{}.html".format(goodObjName) %> <a href="${objectPath}${objFile}"> <span>${objectName}</span> </a> </li> % endfor </ul> % endfor </aside> ''' return html def htmlIndexArticle(self, ): html = ''' <article class="content"> <table> <tbody> <tr> <h2><p>${model.modelData["HomePageTitle"]}</p></h2> <p>Project File: ${model.modelFileName}</p> <p>Author: ${model.modelData["Author"]}</p> <p>Description: ${model.modelData["Description"]}</p> </tr> </tbody> </table> </article>''' return html def htmlObjectArticle(self, objectDict = None): html = ''' <article class="content"> ## generic header for all object types <h1>${genObjectType}: ${genObjectName}</h1> <p>Description: ${objectDict.get("desc","No Description")}</p> ## generate object specific stuff % if genObjectType == "Instance Diagram": <% diagramImgFile = "".join(x for x in objectDict.get("name", "") if x.isalpha() or x.isnumeric() ) + "_image" diagramImgURL = "{}/PAGES/INSTANCEDIAGRAM/{}.png".format(outputPath, diagramImgFile) %> <p>Diagram Image:</p> <p> <img src="${diagramImgURL}" /> </p> % endif % if genObjectType == "Template Diagram": <% diagramImgFile = "".join(x for x in objectDict.get("name", "") if x.isalpha() or x.isnumeric() ) + "_image" diagramImgURL = "{}/PAGES/TEMPLATEDIAGRAM/{}.png".format(outputPath, diagramImgFile) %> <p>Diagram Image:</p> <p> <img src="${diagramImgURL}" /> </p> % endif % if genObjectType == "Node Template": ## label grid <p>Labels:</p> ''' + self.htmlTable(listName="labels", dict=objectDict) + ''' <p></p> ## property grid <p>Properties:</p> ''' + self.htmlTable(listName="properties", dict=objectDict) + ''' <p></p> ## constraint grid <p>Constraints:</p> ''' + self.htmlTable(listName="constraints", dict=objectDict) + ''' <p></p> ## index grid <p>Indexes:</p> ''' + self.htmlTable(listName="indexes", dict=objectDict) + ''' <p></p> % endif % if genObjectType == "Relationship Template": <% relNameFile = "".join(x for x in objectDict.get("relname", "") if x.isalpha() or x.isnumeric() ) + "_file" relNameURL = "{}/PAGES/RELATIONSHIP/{}.html".format(outputPath, relNameFile) toNodeFile = "".join(x for x in objectDict.get("toTemplate", "") if x.isalpha() or x.isnumeric() ) + "_file" toNodeURL = "{}/PAGES/NODETEMPLATE/{}.html".format(outputPath, toNodeFile) fromNodeFile = "".join(x for x in objectDict.get("fromTemplate", "") if x.isalpha() or x.isnumeric() ) + "_file" fromNodeURL = "{}/PAGES/NODETEMPLATE/{}.html".format(outputPath, fromNodeFile) %> <p>Relationship Type: <a href="${relNameURL}"> <span>${objectDict.get("relname", "")}</span> </a> </p> <p>From node template: <a href="${fromNodeURL}"> <span>${objectDict.get("fromTemplate", "")}</span> </a> has ${objectDict.get("fromCardinality", "")} node template: ${objectDict.get("toTemplate", "")} </p> <p>To node template: <a href="${toNodeURL}"> <span>${objectDict.get("toTemplate", "")}</span> </a> has ${objectDict.get("toCardinality", "")} node template: ${objectDict.get("fromTemplate", "")} </p> <p>Properties:</p> ''' + self.htmlTable(listName="properties", dict=objectDict) + ''' <p></p> <p>Constraints:</p> ''' + self.htmlTable(listName="constraints", dict=objectDict) + ''' <p></p> % endif % if genObjectType == "Property": <p>Data Type: ${objectDict.get("dataType", "")} </p> % endif ## generate the where used section <p>Where Used:</p> <% hitList = model.scanForObjectUse(genObjectType, genObjectName) %> % if not hitList is None: % if len(hitList) > 0: <ul> % for hit in hitList: % if hit[0] in ["Label","Property","Node Template", "Relationship Template", "Template Diagram", "Instance Diagram"]: <% goodObjName = "".join(x for x in hit[1] if x.isalpha() or x.isnumeric() ) + "_file" objURL = "../{}/{}.html".format(''.join(hit[0].upper().split()), goodObjName) ##text = "{} - {} ({})".format(hit[0], hit[1], hit[2]) %> <li> <p>${hit[0]} - <a href="${objURL}"> <span>${hit[1]}</span> </a> (${hit[2]}) </p> </li> % endif % endfor </ul> % endif % endif </article>''' return html def htmlTable(self, listName=None, dict=None ): '''generate a table from the list in the dictionary ''' # print(objectType, objectName, listName, dict) html = ''' <% aList = objectDict.get("{}", []) ## labels %> % if not aList is None: % if (len(aList) > 0 ): <% rows = len(aList)+1 columns = len(aList[0]) colMetaDataList = model.getHeaderList(objectType=genObjectType, listName="{}") ## labels %> <table id=object-section> % if not colMetaDataList is None: <% colHeaderList = colMetaDataList[0] colLinkList = colMetaDataList[1] %> <thead> <tr> % for header in colHeaderList: <th>${{header}}</td> % endfor </tr> </thead> % endif <tbody> % for indexObject, listObject in enumerate(aList): <tr> % for indexItem, listItem in enumerate(listObject): % if isinstance(listItem, int): % if listItem == 0: <% displayText = "False" %> % else: <% displayText = "True" %> % endif % else: <% displayText = str(listItem) %> % endif ##<td>${{displayText}}</td> % if len(colLinkList[indexItem]) > 0: <% linkItemList = displayText.split(",") %> <td> % for linkItem in linkItemList: <% goodObjName = "".join(x for x in linkItem if x.isalpha() or x.isnumeric() ) + "_file" objURL = "../{{}}/{{}}.html".format(''.join(colLinkList[indexItem].upper().split()), goodObjName) %> <a href="${{objURL}}"> <span>${{linkItem}} </span> </a> % endfor </td> % else: <td>${{displayText}}</td> % endif % endfor </tr> % endfor </tbody> % endif </table> % endif '''.format(listName, listName) return html def htmlFooter(self, ): html = ''' <footer class="footer"> <table> <tbody> <tr> <p>${model.modelData["FooterTitle"]}</p> </tr> </tbody> </table> </footer>''' return html def htmlEnd(self, ): html = ''' </div> </body> </html>''' return html def htmlCSS(self, ): html = ''' *, *:before, *:after { box-sizing: border-box; } body { margin: 40px; font-family: 'Open Sans', 'sans-serif'; background-color: #fff; color: #444; } h1, p { margin: 0 0 1em 0; } .wrapper { max-width: 1100px; margin: 0 20px; display: grid; grid-gap: 10px; } @media screen and (min-width: 500px) { /* no grid support? */ .sidebar { float: left; width: 19.1489%; } .content { float: right; width: 79.7872%; } .wrapper { margin: 0 auto; grid-template-columns: 1fr 3fr; } .header, .footer { grid-column: 1 / -1; /* needed for the floated layout */ clear: both; } } .wrapper > * { background-color: AliceBlue; color: Black; border-radius: 5px; padding: 10px; font-size: 100%; /* needed for the floated layout*/ margin-bottom: 10px; } /* We need to set the widths used on floated items back to auto, and remove the bottom margin as when we have grid we have gaps. */ @supports (display: grid) { .wrapper > * { width: auto; margin: 0; } } #object-section {font-family:lucida sans unicode,lucida grande,Sans-Serif;font-size:12px;width:480px;text-align:left;border-collapse:collapse;margin:20px} #object-section th{font-size:13px;font-weight:400;background:#b9c9fe;border-top:4px solid #aabcfe;border-bottom:1px solid #fff;color:#039;padding:8px} #object-section td{background:#e8edff;border-bottom:1px solid #fff;color:#669;border-top:1px solid transparent;padding:8px} #object-section tr:hover td{background:#d0dafd;color:#339}''' return html