class MainWindow(QMainWindow): """ Our main window class """ def __init__(self): QMainWindow.__init__(self) self.setWindowTitle("Main Window") self.setGeometry(300, 250, 400, 300) self.statusLabel = QLabel('Showing Progress') self.progressBar = QProgressBar() self.progressBar.setMinimum(0) self.progressBar.setMaximum(100) def CreateStatusBar(self): self.myStatusBar = QStatusBar() self.progressBar.setValue(10) self.myStatusBar.addWidget(self.statusLabel, 1) self.myStatusBar.addWidget(self.progressBar, 2) #self.myStatusBar.showMessage('Ready', 2000) self.setStatusBar(self.myStatusBar) def showProgress(self): while(self.progressBar.value() < self.progressBar.maximum()): self.progressBar.setValue(self.progressBar.value() + 10) time.sleep(1) self.statusLabel.setText('Ready')
class MainWindow(QMainWindow): """ Our Main Window """ def __init__(self): """ Constructor Fucntion """ QMainWindow.__init__(self) self.setWindowTitle("Main Window") self.setGeometry(300, 250, 400, 300) self.statusLabel = QLabel('Showing Progress') self.progressBar = QProgressBar() self.progressBar.setMinimum(0) self.progressBar.setMaximum(100) def createStatusBar(self): """ Function to create the status bar """ self.myStatusBar = QStatusBar() self.progressBar.setValue(10) self.myStatusBar.addWidget(self.statusLabel, 1) self.myStatusBar.addWidget(self.progressBar, 2) self.setStatusBar(self.myStatusBar) def showProgress(self): """ Function to show progress """ while(self.progressBar.value() < self.progressBar.maximum()): self.progressBar.setValue(self.progressBar.value() + 10) time.sleep(1) self.statusLabel.setText('Ready')
class MainWindow(QMainWindow): """ Create the Application Main Window CLass """ def __init__(self): """ Constructo FUnction """ QMainWindow.__init__(self) self.setWindowTitle("Application Title Here") self.setGeometry(300, 250, 400, 300) self.statusLabel = QLabel('Showing Progress') self.progressBar = QProgressBar() self.progressBar.setMinimum(0) self.progressBar.setMaximum(1000000) def CreateStatusBar(self): """ Funtion to Create Status Bar """ self.myStatusBar = QStatusBar() self.progressBar.setValue(10) self.myStatusBar.addWidget(self.statusLabel, 1) self.myStatusBar.addWidget(self.progressBar, 2) self.setStatusBar(self.myStatusBar) def ShowProgress(self): """ Function to Show Progress """ while self.progressBar.value() < self.progressBar.maximum(): self.progressBar.setValue(self.progressBar.value() + 1) self.statusLabel.setText('Ready')
class StatusArea(QWidget): def __init__(self, parent=None): super(StatusArea, self).__init__(parent) self.setStyleSheet('StatusArea {background: yellow}') self.msg = QLabel(self) self.file = QLabel(self) self.progress = QProgressBar(self) self.msg.setFont(View.labelsFont()) self.file.setFont(View.editsFont()) self.progress.setMaximum(100) self.progress.setMinimum(0) self.progress.setTextVisible(False) self.progress.setStyleSheet(""" QProgressBar { border: 2px solid grey; border-radius: 5px; width: 60px; height: 10px; } QProgressBar::chunk { background-color: #05B8CC; width: 5px; }""") layout = QHBoxLayout() layout.addWidget(self.msg, 0, Qt.AlignLeft) layout.addWidget(self.file, 0, Qt.AlignLeft) layout.addWidget(self.progress, 0, Qt.AlignRight) self.setLayout(layout) @Slot(str) @Slot(str, str, str) def setMessage(self, msg, file='', progress=None): if not progress: self.progress.hide() self.progress.setValue(0) else: self.progress.setValue(progress) self.progress.show() self.msg.setText(msg) self.file.setText(file) def paintEvent(self, event): p = QPainter() p.begin(self) p.fillRect(self.rect(), QBrush(QColor(240, 200, 0))) p.end()
def __init__(self, parent, message): super(ExportProgressDialog, self).__init__(parent) self.setModal(True) self.setWindowTitle(message) indicator = QProgressBar() indicator.setMinimum(0) indicator.setMaximum(0) messageLabel = QLabel(message) layout = QGridLayout() layout.addWidget(messageLabel) layout.addWidget(indicator) self.setLayout(layout)
class STMainWindow(QMainWindow): def __init__(self): super(STMainWindow, self).__init__() self.createActions() self.createMenus() layout = QVBoxLayout() self.tabs = QTabWidget() self.tabs.setTabPosition(QTabWidget.West) self.tabs.currentChanged[int].connect(self.tabChanged) self.sessiontab = sweattrails.qt.sessiontab.SessionTab(self) self.tabs.addTab(self.sessiontab, "Sessions") self.tabs.addTab(sweattrails.qt.fitnesstab.FitnessTab(self), "Fitness") self.tabs.addTab(sweattrails.qt.profiletab.ProfileTab(self), "Profile") self.usertab = sweattrails.qt.usertab.UserTab(self) self.tabs.addTab(self.usertab, "Users") self.usertab.hide() layout.addWidget(self.tabs) w = QWidget(self) w.setLayout(layout) self.setCentralWidget(w) self.statusmessage = QLabel() self.statusmessage.setMinimumWidth(200) self.statusBar().addPermanentWidget(self.statusmessage) self.progressbar = QProgressBar() self.progressbar.setMinimumWidth(100) self.progressbar.setMinimum(0) self.progressbar.setMaximum(100) self.statusBar().addPermanentWidget(self.progressbar) self.setWindowTitle("SweatTrails") self.setWindowIconText("SweatTrails") icon = QPixmap("image/sweatdrops.png") self.setWindowIcon(QIcon(icon)) QCoreApplication.instance().refresh.connect(self.userSet) def createActions(self): self.switchUserAct = QAction("&Switch User", self, shortcut = "Ctrl+U", statusTip = "Switch User", triggered = self.switch_user) self.importFileAct = QAction("&Import", self, shortcut = "Ctrl+I", statusTip = "Import Session", triggered = self.file_import) self.downloadAct = QAction("&Download", self, shortcut = "Ctrl+D", statusTip = "Download activities from device", triggered = QCoreApplication.instance().download) self.downloadAct = QAction("&Withings", self, statusTip = "Download Withings data", triggered = QCoreApplication.instance().withings) self.exitAct = QAction("E&xit", self, shortcut = "Ctrl+Q", statusTip = "Exit SweatTrails", triggered = self.close) self.aboutAct = QAction("&About", self, triggered = self.about) self.aboutQtAct = QAction("About &Qt", self, triggered = QApplication.aboutQt) def createMenus(self): self.fileMenu = self.menuBar().addMenu(self.tr("&File")) self.fileMenu.addAction(self.switchUserAct) self.fileMenu.addSeparator() self.fileMenu.addAction(self.importFileAct) self.fileMenu.addAction(self.downloadAct) self.fileMenu.addSeparator() self.fileMenu.addAction(self.exitAct) self.menuBar().addSeparator() self.helpMenu = self.menuBar().addMenu("&Help") self.helpMenu.addAction(self.aboutAct) self.helpMenu.addAction(self.aboutQtAct) def show(self): super(QMainWindow, self).show() if self.select_user(): t = sweattrails.qt.imports.BackgroundThread.get_thread() t.jobStarted.connect(self.status_message) t.jobFinished.connect(self.status_message) t.jobError.connect(self.status_message) else: self.close() def switch_user(self): pass def select_user(self): ret = False if QCoreApplication.instance().user: return True elif QCoreApplication.instance().has_users(): dialog = SelectUser(self) dialog.select() ret = QCoreApplication.instance().is_authenticated() if ret: self.refresh() else: dialog = CreateUser(self) dialog.exec_() ret = QCoreApplication.instance().is_authenticated() if ret: self.refresh() return ret # # FILE IMPORT # def file_import(self): (fileNames, _) = QFileDialog.getOpenFileNames(self, "Open Activity File", "", "Activity Files (*.tcx *.fit *.csv)") if fileNames: QCoreApplication.instance().import_files(*fileNames) def file_import_started(self, filename): self.switchUserAct.setEnabled(False) def file_imported(self, filename): self.switchUserAct.setEnabled(True) self.refresh() def file_import_error(self, filename, msg): self.switchUserAct.setEnabled(True) self.refresh() # # END FILE IMPORT # # ===================================================================== # S I G N A L H A N D L E R S # ===================================================================== def refresh(self): QCoreApplication.instance().refresh.emit() self.status_message("") def tabChanged(self, tabix): w = self.tabs.currentWidget() if hasattr(w, "activate"): w.activate(0) if hasattr(w, "setValues"): w.setValues() def setSession(self, session): self.tabs.setCurrentIndex(0) self.sessiontab.setSession(session) def setTab(self, tab): t = self.tabs.currentWidget() if t and hasattr(t, "setTab"): t.setTab(tab) def userSet(self): user = QCoreApplication.instance().user if user.is_admin(): self.usertab.show() def status_message(self, msg, *args): self.statusmessage.setText(msg.format(*args)) def progress_init(self, msg, *args): self.progressbar.setValue(0) self.status_message(msg, *args) def progress(self, percentage): self.progressbar.setValue(percentage) def progress_done(self): self.progressbar.reset() def about(self): QMessageBox.about(self, "About SweatTrails", "SweatTrails is a training log application")
class SafeLock(QWidget): def __init__(self): super(SafeLock, self).__init__() main_layout = QVBoxLayout(self) self.Version = '0.5 beta' self.s_error = "QStatusBar{color:red;font-weight:1000;}" self.s_loop = "QStatusBar{color:black;font-weight:1000;}" self.s_norm = "QStatusBar{color:blue;font-style:italic;" self.s_norm += "font-weight:500;}" self.Processing = None self.CP = None self.PPbar = None self.key = None self.DFiles = [] self.picon = r_path("images/favicon.png") self.plogo = r_path("images/logo.png") if name == 'nt': self.picon = r_path("images\\favicon.png") self.plogo = r_path("images\\logo.png") self.icon = QIcon(self.picon) self.logo = QIcon(self.plogo) self.center() self.setStyle() self.setMW(main_layout) self.setSB(main_layout) self.show() def db(self, password="******", dbname="untitled.sld", dc=True): eng = create_engine("sqlite:///%s" % dbname, connect_args={'check_same_thread': False}) Base = declarative_base(bind=eng) Session = sessionmaker(bind=eng) session = Session() class Identifier(Base): __tablename__ = "identifier" id = Column(Integer, primary_key=True) version = Column(Binary) kvd = Column(Binary) def __init__(self, version, kvd): self.id = 0 self.version = version self.kvd = kvd class Folder(Base): __tablename__ = 'folders' id = Column(Integer, primary_key=True) path = Column(Unicode) def __init__(self, path="Empty"): self.path = path class File(Base): __tablename__ = 'files' id = Column(Integer, primary_key=True) name = Column(String) f_id = Column(Integer, ForeignKey('folders.id'), nullable=True) bb = Column(Binary) def __init__(self, name="empty", f_id=0, bb=1010): self.name = name self.f_id = f_id self.bb = bb if dc: Base.metadata.create_all() enc = encryptit(sha256(self.Version).digest(), sha256(password).digest()) session.add(Identifier(enc[0], enc[1])) session.commit() return [eng, Base, session, File, Folder, Identifier, password] def checkP(self, db): try: d = db[2].query(db[5]).filter_by(id=0).first() if d is not None: if isenct(self.Version, d.version, db[6], d.kvd): return True except: pass return False def setStyle(self): self.setMaximumWidth(410) self.setMinimumWidth(410) self.setMaximumHeight(370) self.setMinimumHeight(370) self.setWindowIcon(self.icon) self.activateWindow() self.setWindowTitle("safelock " + self.Version) self.setToolTip( u"단순히 끌어다 놓는 것으로 파일이나 폴더를 암호화하거나" + u" .sld 파일을 복호화할 수 있습니다.") self.setAcceptDrops(True) self.show() def center(self): qrect = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qrect.moveCenter(cp) self.move(qrect.topLeft()) def setMW(self, ml): ll = QVBoxLayout() self.mIcon = QLabel() self.mIcon.setAlignment(Qt.AlignCenter) mmicon = self.logo.pixmap(250, 230, QIcon.Active, QIcon.On) self.mIcon.setPixmap(mmicon) self.mInst = QLabel( # u"<center>(Drag and drop files or folders to encrypt them)<br>" + u"<center>(마우스로 끌어다 놓으십시오)<br>" + u"<u>최대 2GB 파일 또는 디렉토리만 가능</u></center>") font = QFont() font.setPointSize(13) font.setBold(True) font.setWeight(75) self.fInst = QLabel('<center></center>') self.mInst.setFont(font) ll.addWidget(self.mIcon) ll.addWidget(self.mInst) ll.addWidget(self.fInst) ml.addLayout(ll) def setSB(self, ml): self.statusb = QStatusBar() ml.addWidget(self.statusb) def modSB(self): if self.PPbar is None: self.PPbar = True self.statusb.clear() self.pbar = QProgressBar() self.pbar.setMaximum(100) self.pbar.setMinimum(0) self.plabel = QLabel() self.statusb.addWidget(self.plabel, 0.5) self.statusb.addWidget(self.pbar, 3) else: self.PPbar = None self.statusb.removeWidget(self.plabel) self.statusb.removeWidget(self.pbar) self.statusb.clear() # def searchF(self, dirname): # filelist = [] # try: # filenames = listdir(dirname) # for filename in filenames: # full_filename = path.join(dirname, filename) # if path.isdir(full_filename): # tmplist = self.searchF(full_filename) # for tmpfile in tmplist: # filelist.append(tmpfile) # else: # tmp = full_filename.replace('\\','/') # filelist.append(tmp) # except PermissionError: # pass # return filelist def saveFile(self, fl): fname, _ = QFileDialog.getSaveFileName(self, u"암호화 경로 설정", fl, "Safelock file (*.sld)") if '.' in fname: tm = fname.split('.') tm = tm[len(tm) - 1] if tm == "sld": try: if path.isfile(fname): remove(fname) except: pass return fname if len(fname) <= 0: return None fname += ".sld" try: if path.isfile(fname): remove(fname) except: pass return fname def extTo(self, fl): fname = QFileDialog.getExistingDirectory(self, u"복호화 경로 설정", fl) if len(fname) <= 0: return None return fname def getPass(self): passwd, re = QInputDialog.getText(self, u"비밀번호", u"입력하신 비밀번호 :", QLineEdit.Password) if len(passwd) > 0 : passwd2, re = QInputDialog.getText(self, u"비밀번호", u"다시한번 입력하세요 :", QLineEdit.Password) if passwd != passwd2: self.errorMsg(u"비밀번호가 맞지 않습니다") return False else: if not re: return False if len(passwd) <= 0: return None return passwd else: if not re: return False else: return None def getPass2(self): passwd, re = QInputDialog.getText(self, u"비밀번호", u"입력하신 비밀번호 :", QLineEdit.Password) if not re: return False if len(passwd) <= 0: return None return passwd def errorMsg(self, msg=u"에러 발생 !"): QMessageBox.critical(self, "Error", msg) return True def aboutMsgg(self): Amsg = u"<center>SafeLock %s " % self.Version Amsg += u"은 Mozilla Public License 버전 2.0에 " Amsg += u"따라 허가된 무료 오픈소스 프로젝트 입니다.<br><br>" Amsg += u" 본 프로그램에 대한 더 많은 정보를 원하시면:<br> " Amsg += u"<b><a href='https://github.com/mjuc4/safelock'> " Amsg += u"https://github.com/mjuc4/safelock/ </a> </b></center>" QMessageBox.about(self, "About", Amsg) return True def getSession(self): self.eng = eng(self.password, self.dbname) Session = sessionmaker(bind=self.eng) self.Base = declarative_base(bind=self.eng) self.Base.metadata.create_all() self.session = Session() return self.session def dragEnterEvent(self, e): if e.mimeData().hasUrls: e.accept() else: e.ignore() def dragMoveEvent(self, e): if e.mimeData().hasUrls: e.accept() else: e.ignore() def dropEvent(self, e): if e.mimeData().hasUrls: e.setDropAction(Qt.CopyAction) e.accept() self.DFiles = [] for url in e.mimeData().urls(): try: if sysname == 'darwin': from Foundation import NSURL fname = NSURL.URLWithString_( url.toString()).filePathURL().path() else: fname = url.toLocalFile() self.DFiles.append(fname) except: pass self.dealD(self.DFiles) else: event.ignore() def in_loop(self): if self.Processing is None: self.Processing = True self.setAcceptDrops(False) self.mIcon.setEnabled(False) self.mInst.setEnabled(False) self.fInst.setText(u"<center>| 취소는 더블 클릭 |</center>") self.setToolTip("Double-Click anywhere to cancel") else: self.Processing = None self.setAcceptDrops(True) self.mIcon.setEnabled(True) self.mInst.setEnabled(True) self.fInst.setText(u"<center>| 취소는 더블 클릭 |</center>") self.setToolTip( u"단순히 끌어다 놓는 것으로 파일이나 폴더를 암호화하거나" + u" .sld 파일을 복호화할 수 있습니다.") def dealD(self, files): def tpp(inp): a = path.basename(inp) return inp.replace(a, '') if len(files) < 1: return False elif len(files) >= 1: if len(files) == 1: tf = files[0].split('.') tf = tf[len(tf) - 1] if tf == 'sld': pw = self.getPass2() if pw is None: self.errorMsg(u"비밀번호 입력하십쇼!") return False elif not pw: return False if not self.checkP(self.db(sha256(pw).digest(), files[0], dc=False)): self.errorMsg( u"비밀번호가 맞지 않습니다. 다시 시도하세요") return False else: fold = self.extTo(tpp(files[0])) if fold is not None: self.CP = fold self.in_loop() self.P = DecryptTH(fold, self.db(pw, files[0], dc=False), sha256(pw).digest()) self.P.start() self.P.somesignal.connect(self.handleStatusMessage) self.P.setTerminationEnabled(True) return True pw = self.getPass() if pw is None: self.errorMsg(u"비밀번호 입력하십시오 !") elif not pw: pass else: fil = self.saveFile(tpp(files[0])) if fil is not None: if path.isfile(fil): try: remove(fil) except: pass self.CP = fil self.in_loop() self.P = EncryptTH(files, self.db(pw, fil), sha256(pw).digest()) self.P.start() self.P.somesignal.connect(self.handleStatusMessage) self.P.setTerminationEnabled(True) return True @Slot(object) def handleStatusMessage(self, message): self.statusb.setStyleSheet(self.s_loop) def getIT(f, o): return int((f / o) * 100) mm = message.split('/') if mm[len(mm) - 1] == '%': if self.PPbar is None: self.modSB() self.pbar.setValue(getIT(int(mm[0]), int(mm[1]))) self.setWindowTitle("Processing : " + str(getIT(int(mm[0]), int(mm[1]))) + "%") self.plabel.setText(mm[0] + '/' + mm[1]) else: self.unsetCursor() if self.PPbar is not None: self.modSB() if message[:7] == '# Error': if self.Processing: self.in_loop() self.statusb.setStyleSheet(self.s_error) self.cleanup() elif message[:6] == '# Stop': self.statusb.setStyleSheet(self.s_error) elif message[:6] == '# Done': if self.Processing: self.in_loop() self.statusb.setStyleSheet(self.s_norm) if message.find('encrypted')>=0 : QMessageBox.question(None,'success',"Encrypted succes") else: QMessageBox.question(None,'success',"Decrypted succes") elif message == "# Loading": self.setCursor(Qt.BusyCursor) self.statusb.setStyleSheet(self.s_norm) self.setWindowTitle('safelock ' + self.Version) self.statusb.showMessage(message) def mousePressEvent(self, event): if event.type() == QEvent.Type.MouseButtonDblClick: if self.Processing is None: self.aboutMsgg() else: self.closeEvent() def closeEvent(self, event=None): if self.Processing is not None: if event is not None: r = QMessageBox.question( self, "Making sure", "Are you sure you want to exit, during an active" + " process ?", QMessageBox.Yes | QMessageBox.No) else: r = QMessageBox.question( self, "Making sure", "Are you sure, you to cancel ?", QMessageBox.Yes | QMessageBox.No) if r == QMessageBox.Yes: self.P.stop() self.cleanup() if event is not None: self.in_loop() event.accept() else: self.in_loop() else: if event is not None: event.ignore() else: if self.CP is not None: try: if path.isfile(self.CP + '-journal'): remove(self.CP + '-journal') except: pass if event is not None: event.accept() def cleanup(self): if self.CP is not None: try: if path.isfile(self.CP + '-journal'): remove(self.CP + '-journal') if path.isfile(self.CP): remove(self.CP) except: pass
class MainWindow(QMainWindow): """ Starting point of the GUI based application """ isMyProgressTimer = False def __init__(self): """ MainWindow Constructor Function""" super(MainWindow, self).__init__() wdgt = QWidget() wdgt.setWindowTitle = "ManageHD" self.setCentralWidget(wdgt) self.InitUI() self.GetParameterFileInfo() def InitUI(self): """ Initialize user created UI elements """ self.qlVidsDone = QLabel('0', self) self.qlVidsInProgress = QLabel('0', self) self.qlStartTime = QLabel(datetime.now().strftime("%a, %d %b %Y %H:%M:%S"), self) self.qlEndTime = QLabel('', self) self.qlTimeLeft = QLabel('', self) self.qlDestinationSpace = QLabel('', self) self.qlArcSpace = QLabel('', self) self.qlProcessingSpeed = QLabel('', self) self.qleSourceDir = QLineEditDirectoriesOnly() self.qleArchiveDir = QLineEditDirectoriesOnly() self.qleDestinationDir = QLineEditDirectoriesOnly() self.qleMaxVidsCap = QLineEditIntsOnly() self.qleVideoTypes = QLineEditNoPeriodsOrCommas() self.qleVideoTypes.installEventFilter(self) self.qpbSourceDir = self.__CreateButton('folder.png',"", 50, self.SelectSingleFileForSourceDirectory) self.qpbArchiveDir = self.__CreateButton('folder.png',"", 50, self.SelectSingleFileForArchiveDirectory) self.qpbTargetDir = self.__CreateButton('folder.png',"", 50, self.SelectSingleFileForTargetDirectory) self.qpbRun = self.__CreateButton(None,"Run", 75, self.Process) self.setWindowTitle("Manage HD Video") self.videoExtensionFileFilter = "Video (*.mkv *.mp4 *.avi)" self.qleVideoTypes.setText("mkv mp4 avi") self.statusLabel = QLabel('Showing Progress') self.progressBar = QProgressBar() self.progressBar.setMinimum(0) self.progressBar.setMaximum(100) self.__CreateActions() self.__CreateMenus() self.fileMenu.addAction(self.stdAction) self.fileMenu.addAction(self.altAction) if Progress.runPlatform == 'win': self.stdAction.setIcon(QIcon('checked.jpg')) self.stdAction.setChecked(True) self.fileMenu.addSeparator() self.fileMenu.addAction(self.exitAction) self.fileMenu.addSeparator() self.helpMenu.addAction(self.aboutAction) self.__SetIcon() self.__CenterWindow() self.__CreateGrid() def eventFilter(self, source, event): #Override """ Override the QMainWindow eventFilter method to add File Mask Validation. """ if (event.type() == QEvent.FocusOut and source is self.qleVideoTypes): self.ValidateFileMask() return QMainWindow.eventFilter(self, source, event) def DisableGuiElements(self): """ Change the setEnabled property of the main GUI elements to False. """ self.qleArchiveDir.setEnabled(False) self.qleDestinationDir.setEnabled(False) self.qleMaxVidsCap.setEnabled(False) self.qleSourceDir.setEnabled(False) self.qleVideoTypes.setEnabled(False) self.qpbArchiveDir.setEnabled(False) self.qpbSourceDir.setEnabled(False) self.qpbTargetDir.setEnabled(False) self.qpbRun.setEnabled(False) def EnableGuiElements(self): """ Change the setEnabled property of the main GUI elements to True. """ self.qleArchiveDir.setEnabled(True) self.qleDestinationDir.setEnabled(True) self.qleMaxVidsCap.setEnabled(True) self.qleSourceDir.setEnabled(True) self.qleVideoTypes.setEnabled(True) self.qpbArchiveDir.setEnabled(True) self.qpbSourceDir.setEnabled(True) self.qpbTargetDir.setEnabled(True) self.qpbRun.setEnabled(True) def __AddGridLabel(self, grid, lblText, custFont, row, column, justification): sd = QLabel(lblText, self) sd.setFont(custFont) grid.addWidget(sd, row, column, alignment = justification) def SelectSingleFileForSourceDirectory(self): self.qleSourceDir.setText( self.InvokeSingleSelectionDirectoryDialog() ) self.ValidateFileMask() def SelectSingleFileForArchiveDirectory(self): self.qleArchiveDir.setText( self.InvokeSingleSelectionDirectoryDialog() ) def SelectSingleFileForTargetDirectory(self): self.qleDestinationDir.setText( self.InvokeSingleSelectionDirectoryDialog() ) def InvokeSingleSelectionFileDialog(self): """ Prompts the user to select a single file from a file dialog window. """ dialog = QFileDialog() dialog.setFileMode(QFileDialog.ExistingFile) dialog.setFilter(self.videoExtensionFileFilter) ret = dialog.exec_() FileNames = dialog.selectedFiles() if len(FileNames) == 0: FileNames.append(None) return FileNames[0] def InvokeSingleSelectionDirectoryDialog(self): """ Prompts the user to select a single directory from a directory dialog window. """ dialog = QFileDialog() dialog.setFileMode(QFileDialog.DirectoryOnly) DirectoryName = dialog.getExistingDirectory() if len(DirectoryName) == 0: DirectoryName = None return DirectoryName def ValidateFileMask(self): """ Function to validate that the entered file mask is valid. """ extensionList = "" if len(self.qleVideoTypes.text().split(" ")) > 0: for videoExtension in self.qleVideoTypes.text().split(" "): extensionList += ("*." + videoExtension + " ") extensionList = extensionList[:-1] self.videoExtensionFileFilter = "Video ({})".format(extensionList) def __CreateGrid(self): g1 = QGridLayout() self.centralWidget().setLayout(g1) g1.setSpacing(5) bold = QFont() bold.setBold(True) self.__AddGridLabel(g1, 'Source Directory:', QFont(), 0, 0, -1) self.__AddGridLabel(g1, 'Archive Directory:', QFont(), 1, 0, -1) self.__AddGridLabel(g1, 'Target Directory:', QFont(), 2, 0, -1) self.__AddGridLabel(g1, 'Max Number of Videos:', QFont(), 3, 0, -1) self.__AddGridLabel(g1, 'Video File Types:', QFont(), 3, 2, -1) #self.__AddGridLabel(g1, 'Max Run Time in Hours:', QFont(), 4, 2, -1) g1.addWidget(self.qleSourceDir, 0, 1, 1, 3) g1.addWidget(self.qleArchiveDir, 1, 1, 1, 3) g1.addWidget(self.qleDestinationDir, 2, 1, 1, 3) g1.addWidget(self.qleMaxVidsCap, 3, 1) g1.addWidget(self.qleVideoTypes, 3, 3) #g1.addWidget(self.qleRunTimeMax, 4, 3) g1.addWidget(self.qpbRun, 10, 3, alignment = -1) g1.addWidget(QLabel('', self), 4, 0,) # Empty Column As Separator g1.addWidget(QLabel('', self), 5, 0,) # Empty Column As Separator self.__AddGridLabel(g1, 'Videos Completed:', bold, 5, 0, -1) self.__AddGridLabel(g1, 'Start Time:', bold, 5, 2, -1) self.__AddGridLabel(g1, 'Videos In Progress:', bold, 6, 0, -1) self.__AddGridLabel(g1, 'Time Remaining:', bold, 7, 2, -1) self.__AddGridLabel(g1, 'Target Space Left:', bold, 7, 0, -1) self.__AddGridLabel(g1, 'Archive Space Left:', bold, 8, 0, -1) self.__AddGridLabel(g1, 'End Time:', bold, 6, 2, -1) self.__AddGridLabel(g1, 'Processing Speed:', bold, 8, 2, -1) g1.addWidget(self.qlVidsDone, 5, 1,) g1.addWidget(self.qlVidsInProgress, 6, 1) g1.addWidget(self.qlStartTime, 5, 3,) g1.addWidget(self.qlEndTime, 6, 3,) g1.addWidget(self.qlTimeLeft, 7, 3,) g1.addWidget(self.qlDestinationSpace, 7, 1,) g1.addWidget(self.qlArcSpace, 8, 1,) g1.addWidget(self.qlProcessingSpeed, 8, 3,) g1.addWidget(self.qpbSourceDir, 0, 4,) g1.addWidget(self.qpbArchiveDir, 1, 4,) g1.addWidget(self.qpbTargetDir, 2, 4,) self.show def GetParameterFileInfo(self): Progress.DeterminePlatform() fm = FileManip() #params = Progress.cliParams.copy() params = fm.ReadSettingsFile() self.qlProcessingSpeed.setText(str(Progress.cliParams['ProcessingSpeedInGBperHour'])) self.qleSourceDir.setText(params['sourceDir']) self.qleArchiveDir.setText(params['archiveDir']) self.qleDestinationDir.setText(params['destinationDir']) def GetDriveSpace(self, path): """ Call the GetDriveSpace() method using an instance of the FileManip class. """ fm = FileManip() return fm.GetDriveSpace(path) def ResetStats(self): """ Change statistical data displays back to their original initialized values. """ Progress.ResetStatuses() self.qlVidsDone.setText( '0') self.qlVidsInProgress.setText('0') self.qlStartTime.setText(datetime.now().strftime("%a, %d %b %Y %H:%M:%S")) self.qlTimeLeft.setText("") if self.qleDestinationDir.text() != "": self.qlDestinationSpace.setText(str(self.GetDriveSpace(self.qleDestinationDir.text()))) if self.qleArchiveDir.text() != "": self.qlArcSpace.setText(str(self.GetDriveSpace(self.qleArchiveDir.text()))) self.qlEndTime.setText("") self.qlProcessingSpeed.setText("") def VerifyRequiredFieldsFilled(self): """ Cancels the RUN functionality and informs the user via Message Box if the required fields are not all completed. """ if self.qleSourceDir.text() == "" or \ self.qleVideoTypes.text() == "" or \ self.qleDestinationDir.text() == "": QMessageBox.critical(self, "Required Field Error", "You have not filled out the three required fields. " "'Source Directory', " "'Target Directory' and " "'Video File Types' " "are all required Fields.", QMessageBox.Ok) return 0 return True def Process(self): """ Batch processing of the source video files begins here. """ result = self.VerifyRequiredFieldsFilled() if result != True: return self.ResetStats() Progress.statuses['ProcessingComplete'] = False self.DisableGuiElements() Params = Progress.cliParams.copy() Params['sourceDir'] = self.qleSourceDir.text() Params['archiveDir'] = self.qleArchiveDir.text() Params['destinationDir'] = self.qleDestinationDir.text() maximumNumVids = "" for idx in range(0, len(self.qleMaxVidsCap.text())): if self.qleMaxVidsCap.text()[idx] != '.': maximumNumVids = maximumNumVids + self.qleMaxVidsCap.text()[idx] if maximumNumVids.isnumeric(): Params['maxNumberOfVideosToProcess'] = '%1.f' % float(self.qleMaxVidsCap.text()) if len(self.qleVideoTypes.text().split(" ")) > 0: extensionList = "" for videoExtension in self.qleVideoTypes.text().split(" "): extensionList += (videoExtension + ",") else: extensionList = None Params['videoTypes'] = extensionList #Create and instance of the processing class pm = ProcessMovies() #Disable applicable GUI elements self.DisableGuiElements #Spawn a thread to run this Thread(target=pm.StartWithGUI, args=(Params,)).start() sleep(1) self.qlTimeLeft.setText(Progress.CalculateTimeRemaining()) Progress.statuses['StatusesHaveChanged'] = True return def __CreateButton(self, folderIcon, txt, pxSize, actionFunction): """ Function to add a button """ if folderIcon != None: folderIcon = QIcon('folder.png') myButton = QPushButton(folderIcon, "") else: myButton = QPushButton(txt) myButton.setMaximumWidth(pxSize) myButton.clicked.connect(actionFunction) return myButton def aboutHelp(self): """ Displays the ABOUT box and sets its content. """ QMessageBox.about(self, "About ManageHD", "Program written in Python v3.4 \n\n" "ManageHD allows you to select an entire " "directory of HD video files and lower their " "resolution from 1080 HD to 720 HD, in batch. " "It calls the HandBrake Command Line Interface " "(CLI) in order to re-encode each video. \n\nYou must " "have the Handbrake CLI installed to use this " "software. " "The CLI (command line interface) can be downloaded at:\n\n " " http://handbrake.fr/downloads2.php \n\n" "The average video file at 720 HD " "is generally one fourth to one sixth the size " "of its 1080 HD source file. \n\n" "Coding was done by InfanteLabz. \n\n" "This sofware is released under GPL v3 " "licensing. \n\n Developed on Wing IDE") def exitFile(self): """ Exits the Main Window, ending the program. """ self.close() def __CreateActions(self): """ Function to create actions for menus """ self.stdAction = QAction(QIcon('convert.png'), 'Create MKV files', self, shortcut = "Ctrl+K", statusTip = "File format set to MKV container", triggered = self.stdConversion, checkable = True) self.altAction = QAction(QIcon('convert.png'), 'Create MP4 files', self, shortcut = "Ctrl+P", statusTip = "File format set to MP4 file", triggered = self.altConversion, checkable = True) self.exitAction = QAction(QIcon('exit.png'), '&Quit', self, shortcut="Ctrl+Q", statusTip = "Exit the Application", triggered=self.exitFile) #self.copyAction = QAction(QIcon('copy.png'), 'C&opy', #self, shortcut="Ctrl+C", #statusTip="Copy", #triggered=self.CopyFunction) self.aboutAction = QAction(QIcon('about.png'), 'A&bout', self, statusTip="Displays info about ManageHD", triggered=self.aboutHelp) def __CreateMenus(self): """ Function to create actual menu bar """ self.fileMenu = self.menuBar().addMenu("&File") self.helpMenu = self.menuBar().addMenu("&Help") def __CenterWindow(self): """ Function to center the window """ qRect = self.frameGeometry() centerPoint = QDesktopWidget().availableGeometry().center() qRect.moveCenter(centerPoint) self.move(qRect.topLeft()) def __SetAboutBox(self): """ Function to position and wire the ABOUT box """ self.aboutButton = QPushButton("About", self) self.aboutButton.move(200, 100) self.aboutButton.clicked.connect(self.ShowAbout) def __SetIcon(self): """ Function to set Icon """ appIcon = QIcon('ManageHD_Icon.png') self.setWindowIcon(appIcon) def DisplayAbnormalTerminationStatus(self, status): # Not Implemented pass def GetArchiveDirectory(self): # Not Implemented pass def stdConversion(self): """ Called by the STANDARD menu item under FILE. Sets ManageHD to perform the standard Handbrake conversion. """ Progress.statuses['HandbrakeOptionsString'] = str(" -i {0} -o {1} -f mkv --width 1280 --crop 0:0:0:0 --decomb -s 1 -N eng -m --large-file --encoder x264 -q 19 -E ffac3") Progress.statuses['OutputExtension'] = 'mkv' self.altAction.setChecked(False) if Progress.runPlatform == "win": self.altAction.setIcon(QIcon('convert.png')) self.stdAction.setIcon(QIcon('checked.jpg')) self.stdAction.setChecked(True) def altConversion(self): """ Called by the ALTERNATE menu item under FILE. Sets ManageHD to perform Handbrake conversions using an alternate series of settings. """ Progress.statuses['HandbrakeOptionsString'] = str(" -i {0} -o {1} -f mp4 --width 1280 --crop 0:0:0:0 --decomb -s 1 -N eng -m --large-file --encoder x264 -q 19 -E ffac3") Progress.statuses['OutputExtension'] = 'mp4' self.stdAction.setChecked(False) if Progress.runPlatform == "win": self.altAction.setIcon(QIcon('checked.jpg')) self.stdAction.setIcon(QIcon('convert.png')) self.altAction.setChecked(True) def CopyFunction(): # Not Implemented pass def ValidateAndRun(self): # Not Implemented pass
class MainWindow(QMainWindow): """ The main window of angr management. """ def __init__(self, file_to_open=None, parent=None): super(MainWindow, self).__init__(parent) icon_location = os.path.join(IMG_LOCATION, 'angr.png') self.setWindowIcon(QIcon(icon_location)) GlobalInfo.main_window = self # initialization self.caption = "angr Management" self.setMinimumSize(QSize(400, 400)) self.setDockNestingEnabled(True) self.workspace = None self.central_widget = None self._file_toolbar = None # type: FileToolbar self._states_toolbar = None # type: StatesToolbar self._analysis_toolbar = None # type: AnalysisToolbar self._progressbar = None # type: QProgressBar self._status = "" self._progress = None self._init_menus() self._init_toolbars() self._init_statusbar() self._init_workspace() self.showMaximized() # I'm ready to show off! self.show() self.status = "Ready." if file_to_open is not None: # load a binary self._open_loadbinary_dialog(file_to_open) # # Properties # @property def caption(self): return self.getWindowTitle() @caption.setter def caption(self, v): self.setWindowTitle(v) @property def status(self): return self._status @status.setter def status(self, v): self._status = v self.statusBar().showMessage(v) @property def progress(self): return self._progress @progress.setter def progress(self, v): self._progress = v self._progressbar.show() self._progressbar.setValue(v) # # Dialogs # def _open_loadbinary_dialog(self, file_to_open): load_binary_dialog = LoadBinary(file_to_open) load_binary_dialog.exec_() if load_binary_dialog.cfg_args is not None: # load the binary self._load_binary(file_to_open, load_options=load_binary_dialog.load_options, cfg_args=load_binary_dialog.cfg_args ) def open_newstate_dialog(self): new_state_dialog = NewState(self.workspace, parent=self) new_state_dialog.exec_() # # Widgets # def _init_statusbar(self): self._progressbar = QProgressBar() self._progressbar.setMinimum(0) self._progressbar.setMaximum(100) self._progressbar.hide() self.statusBar().addPermanentWidget(self._progressbar) def _init_toolbars(self): self._file_toolbar = FileToolbar(self) self._states_toolbar = StatesToolbar(self) self._analysis_toolbar = AnalysisToolbar(self) self.addToolBar(Qt.TopToolBarArea, self._file_toolbar.qtoolbar()) self.addToolBar(Qt.TopToolBarArea, self._states_toolbar.qtoolbar()) self.addToolBar(Qt.TopToolBarArea, self._analysis_toolbar.qtoolbar()) # # Menus # def _init_menus(self): fileMenu = FileMenu(self) self.menuBar().addMenu(fileMenu.qmenu()) # # Workspace # def _init_workspace(self): self.central_widget = QMainWindow() self.setCentralWidget(self.central_widget) wk = Workspace(self) self.workspace = wk right_dockable_views = [ dock for dock in self.workspace.dockable_views if dock.widget().default_docking_position == 'right' ] for d0, d1 in zip(right_dockable_views, right_dockable_views[1:]): self.central_widget.tabifyDockWidget(d0, d1) right_dockable_views[0].raise_() self.central_widget.setTabPosition(Qt.RightDockWidgetArea, QTabWidget.North) # # Event # def resizeEvent(self, event): """ :param QResizeEvent event: :return: """ pass # self._recalculate_view_sizes(event.oldSize()) def event(self, event): if event.type() == QEvent.User: # our event callback try: event.result = event.execute() except Exception: event.exception = sys.exc_info() event.event.set() return True return super(MainWindow, self).event(event) # # Actions # def reload(self): self.workspace.reload() def load_binary(self): # Open File window file_path, _ = QFileDialog.getOpenFileName(self, "Open a binary", ".", "All executables (*);;Windows PE files (*.exe);;Core Dumps (*.core)", ) if os.path.isfile(file_path): self._open_loadbinary_dialog(file_path) def quit(self): self.close() def run_variable_recovery(self): self.workspace.views_by_category['disassembly'][0].variable_recovery_flavor = 'accurate' def run_induction_variable_analysis(self): self.workspace.views_by_category['disassembly'][0].run_induction_variable_analysis() # # Other public methods # def progress_done(self): self._progress = None self._progressbar.hide() # # Private methods # def _load_binary(self, file_path, load_options=None, cfg_args=None): if load_options is None: load_options = { } if cfg_args is None: cfg_args = { } inst = Instance(project=angr.Project(file_path, load_options=load_options)) self.workspace.set_instance(inst) inst.initialize(cfg_args=cfg_args) def _recalculate_view_sizes(self, old_size): adjustable_dockable_views = [dock for dock in self.workspace.dockable_views if dock.widget().default_docking_position in ('left', 'bottom', 'right')] if not adjustable_dockable_views: return for dock in adjustable_dockable_views: widget = dock.widget() if old_size.width() < 0: dock.old_size = widget.sizeHint() continue if old_size != self.size(): # calculate the width ratio if widget.default_docking_position == 'left': # we want to adjust the width ratio = dock.old_size.width() * 1.0 / old_size.width() new_width = int(self.width() * ratio) self._resize_dock_widget(dock, new_width, widget.height()) elif widget.default_docking_position == 'bottom': # we want to adjust the height ratio = dock.old_size.height() * 1.0 / old_size.height() new_height = int(self.height() * ratio) self._resize_dock_widget(dock, widget.width(), new_height) dock.old_size = widget.size() def _resize_dock_widget(self, dock_widget, new_width, new_height): original_size = dock_widget.size() original_min = dock_widget.minimumSize() original_max = dock_widget.maximumSize() dock_widget.resize(new_width, new_height) if new_width != original_size.width(): if original_size.width() > new_width: dock_widget.setMaximumWidth(new_width) else: dock_widget.setMinimumWidth(new_width) if new_height != original_size.height(): if original_size.height() > new_height: dock_widget.setMaximumHeight(new_height) else: dock_widget.setMinimumHeight(new_height) dock_widget.original_min = original_min dock_widget.original_max = original_max QTimer.singleShot(1, dock_widget.restore_original_size)
class ProgressBarService(QObject): """ This service is initialized with a status bar upon which it sets a progress bar. Consumers of the service can then show/hide the progress bar and set values. The __new__ method is overridden to make this class a singleton. Every time it is instantiated somewhere in code, the same instance will be returned. In this way, it can serve like a static class. @param statusbar: The status bar on which to display progress. @type statusbar: QStatusBar (I think) @since: 2010-03-02 """ __author__ = "Moritz Wade" __contact__ = "*****@*****.**" __copyright__ = "Zuse Institute Berlin 2010" _instance = None def __new__(cls, *args, **kwargs ): # making this a Singleton, always returns the same instance if not cls._instance: cls._instance = super(ProgressBarService, cls).__new__(cls, *args, **kwargs) return cls._instance def __init__(self, parent=None, statusBarService=None): """ Creates a QProgressBar and adds it to the given status bar (for threads that can provide accurate progress information). Note: The status bar can either be a QStatusBar or the StatusBarService. In the default BioPARKIN use, it is the StatusBarService instance. @todo: A throbber is created and also added to the status bar (for threads that can only provide start/stop information). """ # super(ProgressBarService, self).__init__(parent) # done in __new__ if statusBarService is not None: self.statusBarService = statusBarService self.progressBar = QProgressBar(None) # used for showing progress self.progressBarMutex = QMutex() self.progressBar.hide() self.statusBarService.addPermanentWidget(self.progressBar) self.progressRunning = False self.throbber = QLabel() self.throbberRunning = False self.throbberMutex = QMutex() self.statusBarService.addPermanentWidget(self.throbber) self.throbber.show() self.throbber.hide() throbberImage = QMovie(":/images/Spinning_wheel_throbber.gif", parent=self.throbber) throbberImage.setScaledSize(QSize(24, 24)) throbberImage.setCacheMode(QMovie.CacheAll) throbberImage.start() self.throbber.setMovie(throbberImage) self.throbber.setFixedSize(24, 24) def getStatusBar(self): """ Gets the internal status bar (or StatusBarService) """ return self.statusBarService def connect_to_thread(self, thread): """ Connects standard BioParkinThreadBase SIGNALs to update methods. @param thread: Thread whose Signals to handle @type thread: BioParkinThreadBase """ if thread is not None: self.thread = thread self.thread.startWithoutProgressSignal.connect(self.start_throbber) self.thread.startWithProgressSignal.connect(self.start_progress) self.thread.finishedSignal.connect(self.finish) self.thread.progressMinimumSignal.connect( self.setProgressBarMinimum) self.thread.progressMaximumSignal.connect( self.setProgressBarMaximum) self.thread.progressValueSignal.connect(self.setProgressBarValue) self.thread.progressTextSignal.connect(self.showMessage) def setProgressBarMinimum(self, min): """ Uses a QMutexLocker to set the minimum value for the progress bar. """ with QMutexLocker(self.progressBarMutex): self.progressBar.setMinimum(min) def setProgressBarMaximum(self, max): """ Uses a QMutexLocker to set the maximum value for the progress bar. """ with QMutexLocker(self.progressBarMutex): self.progressBar.setMaximum(max) def setProgressBarValue(self, value): """ Uses a QMutexLocker to set the minimum value for the progress bar. This also implicitely "starts" the progress, e.g. show the ProgressBar. """ self.progressRunning = True with QMutexLocker(self.progressBarMutex): self.progressBar.setValue(value) self.progressBar.show() def update(self, value, min=None, max=None, text=None): """ Updates the progress bar with the given information. @param value: current value @type value: int @param min: Value that represents 0% @type min: int @param max: Value that represents 100% @type max: int @param text: Text to display on status bar @type text: str """ # self.progressRunning = True with QMutexLocker(self.progressBarMutex): if min and max: self.progressBar.setRange(min, max) self.progressBar.setValue(value) self.progressBar.show() if text is not None: self.statusBarService.showMessage(text) # @Slot("QString") def finish(self, text=None): """ This is a slot. It's called when a thread emits its "finished" Signal. The given text is posted to the status bar. @param text: Text for status bar @type text: str """ if self.progressRunning: with QMutexLocker(self.progressBarMutex): self.progressBar.hide() if self.throbberRunning: with QMutexLocker(self.throbberMutex): self.throbber.hide() if text is None: self.statusBarService.showMessage("Finished", 1000) else: self.statusBarService.showMessage( text, 3000) # show finish message for 3 seconds self.thread = None # release reference to thread def start_throbber(self, text=None): """ This is a slot. It starts (the progress-state-less) throbber animation. The given text is posted to the status bar. @param text: Text for status bar @type text: str """ with QMutexLocker(self.throbberMutex): self.throbber.show() self.throbberRunning = True if text is None: self.statusBarService.showMessage("Computing...") else: self.statusBarService.showMessage(text) # @Slot("QString") def start_progress(self, text=None): """ This is a slot. It starts the progress animation. The given text is posted to the status bar. @param text: Text for status bar @type text: str """ self.progressRunning = True with QMutexLocker(self.progressBarMutex): self.progressBar.show() if text is None: self.statusBarService.showMessage("Computing...", 1000) else: self.statusBarService.showMessage(text) def showMessage(self, text): if self.statusBarService: self.statusBarService.showMessage(text)
class SafeLock(QWidget): def __init__(self): super(SafeLock, self).__init__() main_layout = QVBoxLayout(self) self.Version = '0.5 beta' self.s_error = "QStatusBar{color:red;font-weight:1000;}" self.s_loop = "QStatusBar{color:black;font-weight:1000;}" self.s_norm = "QStatusBar{color:blue;font-style:italic;" self.s_norm += "font-weight:500;}" self.Processing = None self.CP = None self.PPbar = None self.key = None self.DFiles = [] self.picon = r_path("images/favicon.png") self.plogo = r_path("images/logo.png") if name == 'nt': self.picon = r_path("images\\favicon.png") self.plogo = r_path("images\\logo.png") self.icon = QIcon(self.picon) self.logo = QIcon(self.plogo) self.center() self.setStyle() self.setMW(main_layout) self.setSB(main_layout) self.show() def db(self, password="******", dbname="untitled.sld", dc=True): eng = create_engine("sqlite:///%s" % dbname, connect_args={'check_same_thread': False}) Base = declarative_base(bind=eng) Session = sessionmaker(bind=eng) session = Session() class Identifier(Base): __tablename__ = "identifier" id = Column(Integer, primary_key=True) version = Column(Binary) kvd = Column(Binary) def __init__(self, version, kvd): self.id = 0 self.version = version self.kvd = kvd class Folder(Base): __tablename__ = 'folders' id = Column(Integer, primary_key=True) path = Column(String) def __init__(self, path="Empty"): self.path = path class File(Base): __tablename__ = 'files' id = Column(Integer, primary_key=True) name = Column(String) f_id = Column(Integer, ForeignKey('folders.id'), nullable=True) bb = Column(Binary) def __init__(self, name="empty", f_id=0, bb=1010): self.name = name self.f_id = f_id self.bb = bb if dc: Base.metadata.create_all() enc = encryptit( sha256(self.Version).digest(), sha256(password).digest()) session.add(Identifier(enc[0], enc[1])) session.commit() return [eng, Base, session, File, Folder, Identifier, password] def checkP(self, db): try: d = db[2].query(db[5]).filter_by(id=0).first() if d is not None: if isenct(self.Version, d.version, db[6], d.kvd): return True except: pass return False def setStyle(self): self.setMaximumWidth(410) self.setMinimumWidth(410) self.setMaximumHeight(370) self.setMinimumHeight(370) self.setWindowIcon(self.icon) self.activateWindow() self.setWindowTitle("safelock " + self.Version) self.setToolTip("Just drag and drop any files or folders" + " to ecrypt or a .sld file to decrypt") self.setAcceptDrops(True) self.show() def center(self): qrect = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qrect.moveCenter(cp) self.move(qrect.topLeft()) def setMW(self, ml): ll = QVBoxLayout() self.mIcon = QLabel() self.mIcon.setAlignment(Qt.AlignCenter) mmicon = self.logo.pixmap(250, 230, QIcon.Active, QIcon.On) self.mIcon.setPixmap(mmicon) self.mInst = QLabel( "<center>(Drag and drop files or folders to encrypt them)<br>" + "(Drap and drop .sld file to decrypt it)<br>" + "<u>2GB max single file size to encrypt</u></center>") font = QFont() font.setPointSize(13) font.setBold(True) font.setWeight(75) self.fInst = QLabel('<center>| Double-Click for about |</center>') self.mInst.setFont(font) ll.addWidget(self.mIcon) ll.addWidget(self.mInst) ll.addWidget(self.fInst) ml.addLayout(ll) def setSB(self, ml): self.statusb = QStatusBar() ml.addWidget(self.statusb) def modSB(self): if self.PPbar is None: self.PPbar = True self.statusb.clear() self.pbar = QProgressBar() self.pbar.setMaximum(100) self.pbar.setMinimum(0) self.plabel = QLabel() self.statusb.addWidget(self.plabel, 0.5) self.statusb.addWidget(self.pbar, 3) else: self.PPbar = None self.statusb.removeWidget(self.plabel) self.statusb.removeWidget(self.pbar) self.statusb.clear() def saveFile(self, fl): fname, _ = QFileDialog.getSaveFileName(self, "Save encrypted file", fl, "Safelock file (*.sld)") if '.' in fname: tm = fname.split('.') tm = tm[len(tm) - 1] if tm == "sld": try: if path.isfile(fname): remove(fname) except: pass return fname if len(fname) <= 0: return None fname += ".sld" try: if path.isfile(fname): remove(fname) except: pass return fname def extTo(self, fl): fname = QFileDialog.getExistingDirectory(self, "Extract files to", fl) if len(fname) <= 0: return None return fname def getPass(self): passwd, re = QInputDialog.getText(self, "Password", "Enter password :"******"Something went wrong !"): QMessageBox.critical(self, "Error", msg) return True def aboutMsgg(self): Amsg = "<center>All credit reserved to the author of " Amsg += "safelock %s " % self.Version Amsg += ", This work is a free, open-source project licensed " Amsg += " under Mozilla Public License version 2.0 . <br><br>" Amsg += " visit for more info or report:<br> " Amsg += "<b><a href='https://safe-lock.github.io'> " Amsg += "https://safe-lock.github.io/ </a> </b></center>" QMessageBox.about(self, "About", Amsg) return True def getSession(self): self.eng = eng(self.password, self.dbname) Session = sessionmaker(bind=self.eng) self.Base = declarative_base(bind=self.eng) self.Base.metadata.create_all() self.session = Session() return self.session def dragEnterEvent(self, e): if e.mimeData().hasUrls: e.accept() else: e.ignore() def dragMoveEvent(self, e): if e.mimeData().hasUrls: e.accept() else: e.ignore() def dropEvent(self, e): if e.mimeData().hasUrls: e.setDropAction(Qt.CopyAction) e.accept() self.DFiles = [] for url in e.mimeData().urls(): try: if sysname == 'darwin': from Foundation import NSURL fname = NSURL.URLWithString_( url.toString()).filePathURL().path() else: fname = url.toLocalFile() self.DFiles.append(fname) except: pass self.dealD(self.DFiles) else: event.ignore() def in_loop(self): if self.Processing is None: self.Processing = True self.setAcceptDrops(False) self.mIcon.setEnabled(False) self.mInst.setEnabled(False) self.fInst.setText("<center>| Double-Click to cancel |</center>") self.setToolTip("Double-Click anywhere to cancel") else: self.Processing = None self.setAcceptDrops(True) self.mIcon.setEnabled(True) self.mInst.setEnabled(True) self.fInst.setText("<center>| Double-Click for about |</center>") self.setToolTip("Just drag and drop any files or folders" + " to ecrypt or a .sld file to decrypt") def dealD(self, files): def tpp(inp): a = path.basename(inp) return inp.replace(a, '') if len(files) < 1: return False elif len(files) >= 1: if len(files) == 1: tf = files[0].split('.') tf = tf[len(tf) - 1] if tf == 'sld': pw = self.getPass() if pw is None: self.errorMsg("You can't set an empty password !") return False elif not pw: return False if not self.checkP( self.db(sha256(pw).digest(), files[0], dc=False)): self.errorMsg("Wrong password entered, try again.") return False else: fold = self.extTo(tpp(files[0])) if fold is not None: self.CP = fold self.in_loop() self.P = DecryptTH(fold, self.db(pw, files[0], dc=False), sha256(pw).digest()) self.P.start() self.P.somesignal.connect(self.handleStatusMessage) self.P.setTerminationEnabled(True) return True pw = self.getPass() if pw is None: self.errorMsg("You can't set an empty password !") elif not pw: pass else: fil = self.saveFile(tpp(files[0])) if fil is not None: if path.isfile(fil): try: remove(fil) except: pass self.CP = fil self.in_loop() self.P = EncryptTH(files, self.db(pw, fil), sha256(pw).digest()) self.P.start() self.P.somesignal.connect(self.handleStatusMessage) self.P.setTerminationEnabled(True) return True @Slot(object) def handleStatusMessage(self, message): self.statusb.setStyleSheet(self.s_loop) def getIT(f, o): return int((f / o) * 100) mm = message.split('/') if mm[len(mm) - 1] == '%': if self.PPbar is None: self.modSB() self.pbar.setValue(getIT(int(mm[0]), int(mm[1]))) self.setWindowTitle("Processing : " + str(getIT(int(mm[0]), int(mm[1]))) + "%") self.plabel.setText(mm[0] + '/' + mm[1]) else: self.unsetCursor() if self.PPbar is not None: self.modSB() if message[:7] == '# Error': if self.Processing: self.in_loop() self.statusb.setStyleSheet(self.s_error) self.cleanup() elif message[:6] == '# Stop': self.statusb.setStyleSheet(self.s_error) elif message[:6] == '# Done': if self.Processing: self.in_loop() self.statusb.setStyleSheet(self.s_norm) elif message == "# Loading": self.setCursor(Qt.BusyCursor) self.statusb.setStyleSheet(self.s_norm) self.setWindowTitle('safelock ' + self.Version) self.statusb.showMessage(message) def mousePressEvent(self, event): if event.type() == QEvent.Type.MouseButtonDblClick: if self.Processing is None: self.aboutMsgg() else: self.closeEvent() def closeEvent(self, event=None): if self.Processing is not None: if event is not None: r = QMessageBox.question( self, "Making sure", "Are you sure you want to exit, during an active" + " process ?", QMessageBox.Yes | QMessageBox.No) else: r = QMessageBox.question(self, "Making sure", "Are you sure, you to cancel ?", QMessageBox.Yes | QMessageBox.No) if r == QMessageBox.Yes: self.P.stop() self.cleanup() if event is not None: self.in_loop() event.accept() else: self.in_loop() else: if event is not None: event.ignore() else: if self.CP is not None: try: if path.isfile(self.CP + '-journal'): remove(self.CP + '-journal') except: pass if event is not None: event.accept() def cleanup(self): if self.CP is not None: try: if path.isfile(self.CP + '-journal'): remove(self.CP + '-journal') if path.isfile(self.CP): remove(self.CP) except: pass
class Dialog(QWidget): def __init__(self, parent=None): super(Dialog, self).__init__(parent) self.setupUI() self.setupConnection() self.threadPool = [] self.totalUids = 0 self.finishedThreadNum = 0 self.realThreadNum = 0 self.excel = Excel() #self.initSearchDb() def setupUI(self): self.pushButton = QPushButton(u"Search", self) #self.testButton = QPushButton(u"Test", self) self.lineEdit = QLineEdit(self) self.textEdit = QTextEdit(self) self.comboBox = QComboBox(self) self.label = QLabel(u"DB:", self) self.progressBar = QProgressBar(self) self.progressBar.setRange(0,1) self.textEdit.setReadOnly(True) self.layout = QVBoxLayout() self.topLayout = QHBoxLayout() self.topLayout.addWidget(self.label) self.topLayout.addWidget(self.comboBox) self.topLayout.addWidget(self.lineEdit) self.topLayout.addWidget(self.pushButton) #self.topLayout.addWidget(self.testButton) #self.testButton.clicked.connect(self.onTestButtonClicked) self.layout.addLayout(self.topLayout) self.layout.addWidget(self.textEdit) self.layout.addWidget(self.progressBar) self.setLayout(self.layout) self.resize(600, 700) self.setWindowTitle(u"Search Data for NCBI") def setupConnection(self): self.pushButton.clicked.connect(self.onButtonClicked) def onButtonClicked(self): if not self.lineEdit.text() or not self.comboBox.count(): QtGui.QMessageBox.information(self, u"Warning", u"Please Set the Search Field") return # disable button self.pushButton.setDisabled(True) dbName = self.comboBox.currentText() fieldName = self.lineEdit.text() self.log("Start searching db: %s and field: %s" % (dbName, fieldName)) # add use history to add all uids to the history server handle = self.entrez.esearch(db=dbName, term=fieldName, usehistory='y') record = self.entrez.read(handle) self.log("All result count %s" % record['Count']) self.totalUids = int(record['Count']) # to get onnly data less than the MAX_COUNT if self.totalUids > MAX_COUNT: ret = QtGui.QMessageBox.question( self, u'Warning', u'result count %s is too large, will only get the %s result \ continue?' % (self.totalUids, MAX_COUNT), QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel ) if ret == QtGui.QMessageBox.Ok: self.totalUids = MAX_COUNT else: return #handle = self.entrez.efetch(db=dbName, id=record['IdList'], rettype='gb') self.finishedThreadNum = 0 WebEnv = record['WebEnv'] QueryKey = record['QueryKey'] global FINISHED_COUNT FINISHED_COUNT = 0 self.progressBar.setValue(0) self.progressBar.setMaximum(self.totalUids) if self.totalUids / RET_MAX_SUMMARY >= MAX_THREAD: self.realThreadNum = MAX_THREAD each_count = self.totalUids/MAX_THREAD startIndex = 0 for i in range(MAX_THREAD - 1): thread = MyThread(startIndex, each_count, dbName, fieldName, WebEnv, QueryKey) thread.finished.connect(self.onThreadFinished) thread.finishedCountChanged.connect(self.onFinishedCountChange) thread.start() self.threadPool.append(thread) startIndex = startIndex + each_count thread = MyThread(startIndex, (self.totalUids-startIndex+1), dbName, fieldName, WebEnv, QueryKey) thread.finished.connect(self.onThreadFinished) thread.finishedCountChanged.connect(self.onFinishedCountChange) self.threadPool.append(thread) thread.start() else: if self.totalUids == RET_MAX_SUMMARY: self.realThreadNum = 1 else: self.realThreadNum = self.totalUids/RET_MAX_SUMMARY + 1 startIndex = 0 for i in range(self.realThreadNum): thread = MyThread(startIndex, RET_MAX_SUMMARY, dbName, fieldName, WebEnv, QueryKey) thread.finished.connect(self.onThreadFinished) thread.finishedCountChanged.connect(self.onFinishedCountChange) self.threadPool.append(thread) thread.start() startIndex = startIndex + RET_MAX_SUMMARY self.log("thread num: %s" % self.realThreadNum) self.log('reading data') self.filename = '%s_%s_output.xls' % (dbName, fieldName) self.excel.setFilename(self.filename) def log(self, context): self.textEdit.append(context) def initSearchDb(self): self.entrez = Entrez self.entrez.email = email self.log("Connect to NCBI") try: handle = self.entrez.einfo() except: QtGui.QMessageBox.warning(self, u"Error", u"Error Connect the WebSite") self.close() record = self.entrez.read(handle) self.log("Get NCBI DataBases:") for name in record['DbList']: self.log('DBName:\t%s' % name) self.comboBox.addItems(record['DbList']) def onThreadFinished(self): self.finishedThreadNum = self.finishedThreadNum + 1 self.log('finished thread %s ' % self.finishedThreadNum) if(self.finishedThreadNum == self.realThreadNum): global all_output heads = all_output[0][0].keys() self.excel.setHead(heads) for values in all_output: for value in values: self.excel.addValues(value) self.excel.save() self.progressBar.setValue(int(self.totalUids)) # clear all thread self.threadPool = [] all_output = [] self.excel.clearValues() self.pushButton.setDisabled(False) self.log("output to file: %s" % self.filename) def onFinishedCountChange(self, num): self.progressBar.setValue(num) def onTestButtonClicked(self): self.finishedThreadNum = 0 self.realThreadNum = 1 self.thread = MyThread(0, 10,"abd","123") self.thread.finished.connect(self.onThreadFinished) self.thread.startIndex()
class MainWindow(QMainWindow): """Fenêtre principale du programme""" def __init__(self): QMainWindow.__init__(self) self.setWindowTitle("Main Window") self.setGeometry(300, 250, 400, 300) self.setWindowIcon(QIcon('Stock/appicon.png')) def setupComponent(self): """Initialise l'ensemble des éléments de l'application""" self.setupStatusBar() self.setupZoneText() self.setupMenu() self.setupToolBar() def setupStatusBar(self): """Ajoute une barre de status""" self.progressBar = QProgressBar() self.statusLabel = QLabel('Progression ...') self.progressBar.setMaximum(100) self.progressBar.setMinimum(0) self.statusBar = QStatusBar() # # Affiche un message durant 2 sec après ouverture de l'application # self.statusBar.showMessage('Please Wait ...', 2000) self.progressBar.setValue(10) self.statusBar.addWidget(self.statusLabel, 1) self.statusBar.addWidget(self.progressBar, 2) self.setStatusBar(self.statusBar) def setupZoneText(self): """Ajout du widget central (zone de texte)""" self.textEdit = QTextEdit() self.setCentralWidget(self.textEdit) def setupMenu(self): """Ajout de menus contextuels""" self.createActions() self.createMenu() self.fileMenu.addAction(self.newAction) self.fileMenu.addSeparator() self.fileMenu.addAction(self.exitAction) self.editMenu.addAction(self.copyAction) self.editMenu.addSeparator() self.editMenu.addAction(self.pasteAction) self.helpMenu.addAction(self.aboutAction) def setupToolBar(self): """Ajout de la barre d'outils""" self.mainToolBar = self.addToolBar('Main') self.mainToolBar.addAction(self.newAction) self.mainToolBar.addSeparator() self.mainToolBar.addAction(self.copyAction) self.mainToolBar.addAction(self.pasteAction) def showProgress(self): """Avancement de la barre de progression""" while self.progressBar.value() < self.progressBar.maximum(): self.progressBar.setValue(self.progressBar.value() + 10) time.sleep(1/10) # self.statusBar.showMessage('Ready', 2000) self.statusLabel.setText('Ready !!') def createMenu(self): """Création de la barre de menu avec 3 menus""" self.fileMenu = self.menuBar().addMenu('&Fichier') self.editMenu = self.menuBar().addMenu('&Edition') self.helpMenu = self.menuBar().addMenu('&About') def createActions(self): """Création des différentes actions du menu '&' permet de surligner une lettre pour acès rapide Alt+lettre 'shortcut' permet de définir le raccourci de l'action du menu 'statusTip' permet de modifier l'affichage dans la barre de status 'triggered' permet de définir l'action à réaliser""" self.newAction = QAction('&New', self, shortcut=QKeySequence.New, statusTip="Créer un nouveau fichier", triggered=self.newFile) self.exitAction = QAction('&Exit', self, shortcut="Ctrl+Q", statusTip="Quitter l'application", triggered=self.exitFile) self.copyAction = QAction('&Copy', self, shortcut="Ctrl+C", statusTip="Copier", triggered=self.textEdit.copy) self.pasteAction = QAction('&Paste', self, shortcut="Ctrl+V", statusTip="Coller", triggered=self.textEdit.paste) self.aboutAction = QAction('&About', self, statusTip="Infos à propos de l'éditeur", triggered=self.aboutHelp) def newFile(self): """Efface le contenu du widget de text""" self.textEdit.setText('') def exitFile(self): """Ferme le programme""" self.close() def aboutHelp(self): """Affiche des renseignements sur le logiciel""" QMessageBox.about(self, "About this application", "Just a simple text editor using Menu Bar")
class TransferPanel(QWidget): ''' Transfer Panel This Panel is the main dialog box for the Dive Computer Transfer GUI ''' def __init__(self, parent=None): super(TransferPanel, self).__init__(parent) self._logbook = None self._logbookName = 'None' self._logbookPath = None self._createLayout() self._readSettings() self.setWindowTitle(self.tr('DC Transfer - %s') % self._logbookName) def _createLayout(self): 'Create the Widget Layout' self._txtLogbook = QLineEdit() self._txtLogbook.setReadOnly(True) self._lblLogbook = QLabel(self.tr('&Logbook File:')) self._lblLogbook.setBuddy(self._txtLogbook) self._btnBrowse = QPushButton('...') self._btnBrowse.clicked.connect(self._btnBrowseClicked) self._btnBrowse.setStyleSheet('QPushButton { min-width: 24px; max-width: 24px; }') self._btnBrowse.setToolTip(self.tr('Browse for a Logbook')) self._cbxComputer = QComboBox() self._lblComputer = QLabel(self.tr('Dive &Computer:')) self._lblComputer.setBuddy(self._cbxComputer) self._btnAddComputer = QPushButton(QPixmap(':/icons/list-add.png'), self.tr('')) self._btnAddComputer.setStyleSheet('QPushButton { min-width: 24px; min-height: 24; max-width: 24px; max-height: 24; }') self._btnAddComputer.clicked.connect(self._btnAddComputerClicked) self._btnRemoveComputer = QPushButton(QPixmap(':/icons/list-remove.png'), self.tr('')) self._btnRemoveComputer.setStyleSheet('QPushButton { min-width: 24px; min-height: 24; max-width: 24px; max-height: 24; }') self._btnRemoveComputer.clicked.connect(self._btnRemoveComputerClicked) hbox = QHBoxLayout() hbox.addWidget(self._btnAddComputer) hbox.addWidget(self._btnRemoveComputer) gbox = QGridLayout() gbox.addWidget(self._lblLogbook, 0, 0) gbox.addWidget(self._txtLogbook, 0, 1) gbox.addWidget(self._btnBrowse, 0, 2) gbox.addWidget(self._lblComputer, 1, 0) gbox.addWidget(self._cbxComputer, 1, 1) gbox.addLayout(hbox, 1, 2) gbox.setColumnStretch(1, 1) self._pbTransfer = QProgressBar() self._pbTransfer.reset() self._txtStatus = QTextEdit() self._txtStatus.setReadOnly(True) self._btnTransfer = QPushButton(self.tr('&Transfer Dives')) self._btnTransfer.clicked.connect(self._btnTransferClicked) self._btnExit = QPushButton(self.tr('E&xit')) self._btnExit.clicked.connect(self.close) hbox = QHBoxLayout() hbox.addWidget(self._btnTransfer) hbox.addStretch() hbox.addWidget(self._btnExit) vbox = QVBoxLayout() vbox.addLayout(gbox) vbox.addWidget(self._pbTransfer) vbox.addWidget(self._txtStatus) vbox.addLayout(hbox) self.setLayout(vbox) def _closeLogbook(self): 'Close the current Logbook' if self._logbook is None: return self._logbook = None self._logbookName = 'None' self._logbookPath = None self._txtLogbook.clear() self._cbxComputer.setModel(None) self._writeSettings() self.setWindowTitle(self.tr('DC Transfer - %s') % self._logbookName) def _openLogbook(self, path): 'Open an existing Logbook' if self._logbook is not None: self._closeLogbook() if not os.path.exists(path): QMessageBox.critical(self, self.tr('Missing Logbook'), self.tr('Logbook File "%s" does not exist.') % path) return #TODO: Handle a Schema Upgrade in a user-friendly manner self._logbook = Logbook(path, auto_update=False) self._logbookName = os.path.basename(path) self._logbookPath = path self._txtLogbook.setText(self._logbookPath) self._cbxComputer.setModel(DiveComputersModel(self._logbook)) self._writeSettings() self.setWindowTitle(self.tr('DC Transfer - %s') % self._logbookName) def _readSettings(self): 'Read main window settings from the configuration' settings = QSettings() settings.beginGroup('MainWindow') max = settings.value('max') size = settings.value('size') pos = settings.value('pos') file = settings.value('file') settings.endGroup() # Size and Position the Main Window if size is not None: self.resize(size) if pos is not None: self.move(pos) # HAX because QVariant is not exposed in PySide and the default # coercion to string is just stupid if max is not None and (max == 'true'): self.showMaximized() # Open the Logbook if file is not None: self._openLogbook(file) def _writeSettings(self): 'Write settings to the configuration' settings = QSettings() settings.beginGroup('MainWindow') settings.setValue('pos', self.pos()) settings.setValue('size', self.size()) settings.setValue('max', self.isMaximized()) settings.setValue('file', self._logbookPath) settings.endGroup() def closeEvent(self, e): 'Intercept an OnClose event' self._writeSettings() e.accept() #-------------------------------------------------------------------------- # Slots @QtCore.Slot() def _btnAddComputerClicked(self): 'Add a Dive Computer' dc = AddDiveComputerWizard.RunWizard(self) if dc is not None: self._logbook.session.add(dc) self._logbook.session.commit() self._cbxComputer.model().reload() self._cbxComputer.setCurrentIndex(self._cbxComputer.findText(dc.name)) @QtCore.Slot() def _btnRemoveComputerClicked(self): 'Remove a Dive Computer' idx = self._cbxComputer.currentIndex() dc = self._cbxComputer.itemData(idx, Qt.UserRole+0) if QMessageBox.question(self, self.tr('Delete Dive Computer?'), self.tr('Are you sure you want to delete "%s"?') % dc.name, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) == QMessageBox.Yes: self._logbook.session.delete(dc) self._logbook.session.commit() self._cbxComputer.model().reload() @QtCore.Slot() def _btnBrowseClicked(self): 'Browse for a Logbook File' if self._logbook is not None: dir = os.path.dirname(self._logbookPath) else: dir = os.path.expanduser('~') fn = QFileDialog.getOpenFileName(self, caption=self.tr('Select a Logbook file'), dir=dir, filter='Logbook Files (*.lbk);;All Files(*.*)')[0] if fn == '': return if not os.path.exists(fn): if QMessageBox.question(self, self.tr('Create new Logbook?'), self.tr('Logbook "%s" does not exist. Would you like to create it?') % os.path.basename(fn), QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) != QMessageBox.Yes: return Logbook.Create(fn) self._openLogbook(fn) @QtCore.Slot() def _btnTransferClicked(self): 'Transfer Dives' idx = self._cbxComputer.currentIndex() dc = self._cbxComputer.itemData(idx, Qt.UserRole+0) if self._logbook.session.dirty: print "Flushing dirty session" self._logbook.rollback() self._txtLogbook.setEnabled(False) self._btnBrowse.setEnabled(False) self._cbxComputer.setEnabled(False) self._btnAddComputer.setEnabled(False) self._btnRemoveComputer.setEnabled(False) self._btnTransfer.setEnabled(False) self._btnExit.setEnabled(False) self._txtStatus.clear() thread = QThread(self) #FIXME: ZOMG HAX: Garbage Collector will eat TransferWorker when moveToThread is called #NOTE: Qt.QueuedConnection is important... self.worker = None self.worker = TransferWorker(dc) thread.started.connect(self.worker.start, Qt.QueuedConnection) self.worker.moveToThread(thread) self.worker.finished.connect(self._transferFinished, Qt.QueuedConnection) self.worker.finished.connect(self.worker.deleteLater, Qt.QueuedConnection) self.worker.finished.connect(thread.deleteLater, Qt.QueuedConnection) self.worker.progress.connect(self._transferProgress, Qt.QueuedConnection) self.worker.started.connect(self._transferStart, Qt.QueuedConnection) self.worker.status.connect(self._transferStatus, Qt.QueuedConnection) thread.start() @QtCore.Slot(str) def _transferStatus(self, msg): 'Transfer Status Message' self._txtStatus.append(msg) @QtCore.Slot(int) def _transferStart(self, nBytes): 'Transfer Thread Stated' if nBytes > 0: self._pbTransfer.setMaximum(nBytes) else: self._pbTransfer.setMaximum(100) self._pbTransfer.reset() @QtCore.Slot(int) def _transferProgress(self, nTransferred): 'Transfer Thread Progress Event' self._pbTransfer.setValue(nTransferred) @QtCore.Slot(models.Dive) def _transferParsed(self, dive): 'Transfer Thread Parsed Dive' self._logbook.session.add(dive) @QtCore.Slot() def _transferFinished(self): 'Transfer Thread Finished' self._logbook.session.commit() self._txtLogbook.setEnabled(True) self._btnBrowse.setEnabled(True) self._cbxComputer.setEnabled(True) self._btnAddComputer.setEnabled(True) self._btnRemoveComputer.setEnabled(True) self._btnTransfer.setEnabled(True) self._btnExit.setEnabled(True)
class MainWindow(QMainWindow): """Fenêtre principale du programme""" def __init__(self): QMainWindow.__init__(self) self.setWindowTitle("Main Window") self.setGeometry(300, 250, 400, 300) self.setWindowIcon(QIcon('Stock/appicon.png')) def setupComponent(self): """Initialise l'ensemble des éléments de l'application""" self.setupStatusBar() self.setupZoneText() self.setupMenu() self.setupToolBar() def setupStatusBar(self): """Ajoute une barre de status""" self.progressBar = QProgressBar() self.statusLabel = QLabel('Progression ...') self.progressBar.setMaximum(100) self.progressBar.setMinimum(0) self.statusBar = QStatusBar() # # Affiche un message durant 2 sec après ouverture de l'application # self.statusBar.showMessage('Please Wait ...', 2000) self.progressBar.setValue(10) self.statusBar.addWidget(self.statusLabel, 1) self.statusBar.addWidget(self.progressBar, 2) self.setStatusBar(self.statusBar) def setupZoneText(self): """Ajout du widget central (zone de texte)""" self.textEdit = QTextEdit() self.setCentralWidget(self.textEdit) def setupMenu(self): """Ajout de menus contextuels""" self.createActions() self.createMenu() self.fileMenu.addAction(self.newAction) self.fileMenu.addSeparator() self.fileMenu.addAction(self.exitAction) self.editMenu.addAction(self.copyAction) self.editMenu.addSeparator() self.editMenu.addAction(self.pasteAction) self.helpMenu.addAction(self.aboutAction) def setupToolBar(self): """Ajout de la barre d'outils""" self.mainToolBar = self.addToolBar('Main') self.mainToolBar.addAction(self.newAction) self.mainToolBar.addSeparator() self.mainToolBar.addAction(self.copyAction) self.mainToolBar.addAction(self.pasteAction) def showProgress(self): """Avancement de la barre de progression""" while self.progressBar.value() < self.progressBar.maximum(): self.progressBar.setValue(self.progressBar.value() + 10) time.sleep(1 / 10) # self.statusBar.showMessage('Ready', 2000) self.statusLabel.setText('Ready !!') def createMenu(self): """Création de la barre de menu avec 3 menus""" self.fileMenu = self.menuBar().addMenu('&Fichier') self.editMenu = self.menuBar().addMenu('&Edition') self.helpMenu = self.menuBar().addMenu('&About') def createActions(self): """Création des différentes actions du menu '&' permet de surligner une lettre pour acès rapide Alt+lettre 'shortcut' permet de définir le raccourci de l'action du menu 'statusTip' permet de modifier l'affichage dans la barre de status 'triggered' permet de définir l'action à réaliser""" self.newAction = QAction('&New', self, shortcut=QKeySequence.New, statusTip="Créer un nouveau fichier", triggered=self.newFile) self.exitAction = QAction('&Exit', self, shortcut="Ctrl+Q", statusTip="Quitter l'application", triggered=self.exitFile) self.copyAction = QAction('&Copy', self, shortcut="Ctrl+C", statusTip="Copier", triggered=self.textEdit.copy) self.pasteAction = QAction('&Paste', self, shortcut="Ctrl+V", statusTip="Coller", triggered=self.textEdit.paste) self.aboutAction = QAction('&About', self, statusTip="Infos à propos de l'éditeur", triggered=self.aboutHelp) def newFile(self): """Efface le contenu du widget de text""" self.textEdit.setText('') def exitFile(self): """Ferme le programme""" self.close() def aboutHelp(self): """Affiche des renseignements sur le logiciel""" QMessageBox.about(self, "About this application", "Just a simple text editor using Menu Bar")
class SpiderTab(QWidget): """Has handlers for spider data and events. It houses the results table of the spider, controls for the spider and progress indication It implicitly conforms to IEventHandler interface""" TIMER_CHECK_INTERVAL = 3000 favicon_received = Signal(str) # send the url or path to the handler, which should be the tab widget stop_spider_signal = Signal(int) became_current = Signal(bool) # tell the table it has become active. it's an interesting property for producers! def __init__(self, parent=None, **kwargs): super(SpiderTab, self).__init__(parent) self._event_queue = None self._data_queue = None self._engine = None self._favicon_received = False self._spider_id = None self._item_count = 0 self.setContextMenuPolicy(Qt.ContextMenuPolicy.DefaultContextMenu) self.initInterface(kwargs) self._context_menu = None self._setupContextMenu() self.became_current.connect(self._set_table_activity) self._queue_check_timer = QTimer() self._queue_check_timer.setInterval(self.TIMER_CHECK_INTERVAL) self._queue_check_timer.timeout.connect(self._checkQueues) self._queue_check_timer.start() def initInterface(self, kwargs): layout = QGridLayout() self._data_table = SearchTable(name=kwargs.get("name")) self._progress_spider = QProgressBar() self._label_count = QLabel(self.tr("0 items scraped")) # make it a busy indicator. you don't know when it'll finish self._progress_spider.setMinimum(0); self._progress_spider.setMaximum(0) self._progress_spider.setTextVisible(False) self._btn_stop_spider = QPushButton(self.tr("Stop Spider")) self._btn_stop_spider.clicked.connect(self.stop_spider) row = 0; col = 0; layout.addWidget(self._data_table, row, col, 1, 4) row += 1; layout.addWidget(self._progress_spider, row, col, 1, 1) col += 1 layout.addWidget(self._label_count, row, col, 1, 2) col += 2 layout.addWidget(self._btn_stop_spider, row, col, 1, 1) self.setLayout(layout) def _setupContextMenu(self): from visualscrape.lib.data import ActionStore self._context_menu = QMenu(self) # get the export action from the action store action_store = ActionStore.get_instance() for action in action_store: if action.get_name() == "export": export_action = action break self._context_menu.addAction(export_action) def export_table(self): export_dialog = ExportDialog() export_dialog.exec_() export_info = export_dialog.data() if export_info: data = self._data_table.get_visible_data() FileExporter.export(data, self._data_table.name.lower(), export_info.location, export_info.format) def set_event_queue(self, eq): self._event_queue = eq def set_data_queue(self, dq): self._data_queue = dq def stop_spider(self): if self._spider_id is None: # do not stop the the spider before receiving data pass else: if self._queue_check_timer.isActive(): confirm_stop = QMessageBox(self) confirm_stop.setIcon(QMessageBox.Warning) confirm_stop.setStandardButtons(QMessageBox.Yes | QMessageBox.No) confirm_stop.setText(self.tr("Scraping process still running")) confirm_stop.setDetailedText(self.tr("Are you sure you want to stop it?")) confirm_stop.setWindowTitle(self.tr("Spider still running")) ret = confirm_stop.exec_() if ret == QMessageBox.Yes: self.stop_spider_signal.emit(self._spider_id) return True else: return False # I won't whip you if you stop it accidentally else: return True # already over def configure_searchlineedit(self, lineEdit): self._data_table.configure_search_lineedit(lineEdit) def _checkQueues(self): while not self._event_queue.empty(): event = self._event_queue.get(block=False, timeout=0) if isinstance(event, SpiderClosed): self._queue_check_timer.stop() self._progress_spider.setMinimum(0) self._progress_spider.setMaximum(100) self._progress_spider.setValue(100) self._btn_stop_spider.setEnabled(False) while not self._data_queue.empty(): item = self._data_queue.get(block=False, timeout=0) if not self._favicon_received: # the first item on the data queue should be the favicon favicon_data = item["images"][0] self.favicon_received.emit(favicon_data["path"]) # note that icons are not guaranteed to have a path. Not everybody wants to save images self._favicon_received = True self._spider_id = item["_id"] else: item.pop("_id") # the table has nothing to do with spider ids self._data_table.addItem(item) self._item_count += 1 self._label_count.setText(self.tr("{0:n} items scraped".format(self._item_count))) def _set_table_activity(self, state): self._data_table.set_active(state)
class ProgressBarService(QObject): """ This service is initialized with a status bar upon which it sets a progress bar. Consumers of the service can then show/hide the progress bar and set values. The __new__ method is overridden to make this class a singleton. Every time it is instantiated somewhere in code, the same instance will be returned. In this way, it can serve like a static class. @param statusbar: The status bar on which to display progress. @type statusbar: QStatusBar (I think) @since: 2010-03-02 """ __author__ = "Moritz Wade" __contact__ = "*****@*****.**" __copyright__ = "Zuse Institute Berlin 2010" _instance = None def __new__(cls, *args, **kwargs): # making this a Singleton, always returns the same instance if not cls._instance: cls._instance = super(ProgressBarService, cls).__new__(cls, *args, **kwargs) return cls._instance def __init__(self, parent=None, statusBarService = None): """ Creates a QProgressBar and adds it to the given status bar (for threads that can provide accurate progress information). Note: The status bar can either be a QStatusBar or the StatusBarService. In the default BioPARKIN use, it is the StatusBarService instance. @todo: A throbber is created and also added to the status bar (for threads that can only provide start/stop information). """ # super(ProgressBarService, self).__init__(parent) # done in __new__ if statusBarService is not None: self.statusBarService = statusBarService #self.progressBar = QProgressBar(self.statusBarService) # used for showing progress self.progressBar = QProgressBar(None) # used for showing progress self.progressBarMutex = QMutex() self.progressBar.hide() self.statusBarService.addPermanentWidget(self.progressBar) self.progressRunning = False self.throbber = QLabel() self.throbberRunning = False self.throbberMutex = QMutex() self.statusBarService.addPermanentWidget(self.throbber) self.throbber.show() self.throbber.hide() throbberImage = QMovie(":/images/Spinning_wheel_throbber.gif", parent=self.throbber) throbberImage.setScaledSize(QSize(24, 24)) throbberImage.setCacheMode(QMovie.CacheAll) throbberImage.start() self.throbber.setMovie(throbberImage) self.throbber.setFixedSize(24,24) # def __call__(self): # """ # Quick'n'dirty way to make a Singleton out of this class. # """ # return self # def setStatusBar(self, statusbar): # """ # Sets the internal status bar (or StatusBarService) # """ # self.statusbar = statusbar def getStatusBar(self): """ Gets the internal status bar (or StatusBarService) """ return self.statusBarService def connect_to_thread(self, thread): """ Connects standard BioParkinThreadBase SIGNALs to update methods. @param thread: Thread whose Signals to handle @type thread: BioParkinThreadBase """ if thread is not None: self.thread = thread #thread.finished.connect(self.threadFinished) #print "in connect_to_thread" self.thread.startWithoutProgressSignal.connect(self.start_throbber) self.thread.startWithProgressSignal.connect(self.start_progress) self.thread.finishedSignal.connect(self.finish) self.thread.progressMinimumSignal.connect(self.setProgressBarMinimum) self.thread.progressMaximumSignal.connect(self.setProgressBarMaximum) self.thread.progressValueSignal.connect(self.setProgressBarValue) self.thread.progressTextSignal.connect(self.showMessage) # def threadFinished(self, bool): # self.hide("Action finished.") def setProgressBarMinimum(self, min): """ Uses a QMutexLocker to set the minimum value for the progress bar. """ with QMutexLocker(self.progressBarMutex): self.progressBar.setMinimum(min) def setProgressBarMaximum(self, max): """ Uses a QMutexLocker to set the maximum value for the progress bar. """ with QMutexLocker(self.progressBarMutex): self.progressBar.setMaximum(max) def setProgressBarValue(self, value): """ Uses a QMutexLocker to set the minimum value for the progress bar. This also implicitely "starts" the progress, e.g. show the ProgressBar. """ self.progressRunning = True with QMutexLocker(self.progressBarMutex): self.progressBar.setValue(value) self.progressBar.show() def update(self, value, min=None, max=None, text = None): """ Updates the progress bar with the given information. @param value: current value @type value: int @param min: Value that represents 0% @type min: int @param max: Value that represents 100% @type max: int @param text: Text to display on status bar @type text: str """ # self.progressRunning = True #QApplication.processEvents() with QMutexLocker(self.progressBarMutex): if min and max: self.progressBar.setRange(min, max) self.progressBar.setValue(value) self.progressBar.show() if text is not None: self.statusBarService.showMessage(text) # @Slot("QString") def finish(self, text = None): """ This is a slot. It's called when a thread emits its "finished" Signal. The given text is posted to the status bar. @param text: Text for status bar @type text: str """ #print "in finish()" #logging.info("Finishing Progress Service") if self.progressRunning: with QMutexLocker(self.progressBarMutex): self.progressBar.hide() if self.throbberRunning: with QMutexLocker(self.throbberMutex): self.throbber.hide() if text is None: self.statusBarService.showMessage("Finished", 1000) else: self.statusBarService.showMessage(text, 3000) # show finish message for 3 seconds self.thread = None # release reference to thread # @Slot("QString") def start_throbber(self, text = None): """ This is a slot. It starts (the progress-state-less) throbber animation. The given text is posted to the status bar. @param text: Text for status bar @type text: str """ #print "Starting progress throbber...." #logging.info("Starting progress throbber....") with QMutexLocker(self.throbberMutex): self.throbber.show() self.throbberRunning = True if text is None: self.statusBarService.showMessage("Computing...") else: self.statusBarService.showMessage(text) # @Slot("QString") def start_progress(self, text = None): """ This is a slot. It starts the progress animation. The given text is posted to the status bar. @param text: Text for status bar @type text: str """ self.progressRunning = True with QMutexLocker(self.progressBarMutex): self.progressBar.show() if text is None: self.statusBarService.showMessage("Computing...", 1000) else: self.statusBarService.showMessage(text) def showMessage(self, text): if self.statusBarService: self.statusBarService.showMessage(text)
class OtpOperations(object): def __init__(self): self.verbose = True self.address_increment_disable_reg = REGISTERS_BY_OFFSET_DICT[ADDRESS_AUTO_INCREMENT_ADDR] self.supervisor_disable_reg = REGISTERS_BY_OFFSET_DICT[SUPERVISOR_DISABLE_ADDR] self.supervisor_state_reg = REGISTERS_BY_OFFSET_DICT[SUPERVISOR_STATE_ADDR] self.regulator_poc_reg = REGISTERS_BY_OFFSET_DICT[REGULATOR_POC_ADDR] self.otp_addr_reg = REGISTERS_BY_OFFSET_DICT[OTP_A_ADDR] self.otp_d_reg = REGISTERS_BY_OFFSET_DICT[OTP_D_ADDR] self.otp_q_reg = REGISTERS_BY_OFFSET_DICT[OTP_Q_ADDR] self.otp_ctl_reg = REGISTERS_BY_OFFSET_DICT[OTP_CTL_ADDR] self.vg_ctl_reg = REGISTERS_BY_OFFSET_DICT[VG_CTL_ADDR] self.vg_mpp_reg = REGISTERS_BY_OFFSET_DICT[VG_MPP_ADDR] self.vg_mrr_h_reg = REGISTERS_BY_OFFSET_DICT[VG_MRR_H_ADDR] self.vg_mrr_l_reg = REGISTERS_BY_OFFSET_DICT[VG_MRR_L_ADDR] self.OTP_bytes=[] self.regulator_trim_reg = REGISTERS_BY_OFFSET_DICT[BYTE003] def loadWindow(self,wind): self.window=QMainWindow() self.window=wind self.progressBar=QProgressBar(self.window) self.progressBar.setGeometry(600, 660, 150, 15) def otp_disable(self): self.vg_ctl_reg.set_and_upload(0x00) self.otp_ctl_reg.set_and_upload(0x00) return def otp_operations_preps_are_complete(self, forcing=False): # first, check that the supervisor is disabled success, readback, log_string, log_color = self.supervisor_disable_reg.download_and_overwrite() if (readback & SUPERVISOR_DISABLE) == 0x00: UI.log('supervisor is not disabled', Qt.red) if not forcing: UI.log('....aborting!', Qt.red) return False else: UI.log('....override is ON', Qt.red) UI.log('....continuing!', Qt.red) # then, get the supervisor state, REG1 POC, and REG3 POC success, readback, log_string, log_color = self.supervisor_state_reg.download_and_overwrite() if (readback & SUPERVISOR_STATE) != 0x00: UI.log('supervisor is ACTIVE!', Qt.red) if not forcing: UI.log('....aborting!', Qt.red) return False else: UI.log('....override is ON', Qt.red) UI.log('....continuing!', Qt.red) # then, get the regulator POC bits success, readback, log_string, log_color = self.regulator_poc_reg.download_and_overwrite() if (readback & REGULATOR_POC) != 0x00: UI.log('at least one regulator is POWERED-DOWN', Qt.red) if not forcing: UI.log('....aborting!', Qt.red) return False else: UI.log('....override is ON', Qt.red) UI.log('....continuing!', Qt.red) # finally, set the regulator voltage if required self.regulator_trim_reg.set_and_upload(VREG_SETUP) return True def otp_read_setup(self, vg_mrr): self.vg_mrr_h_reg.set_and_upload(0x00) self.vg_mrr_l_reg.set_and_upload(vg_mrr & 0xFF) self.vg_ctl_reg.set_and_upload(VG_DBEN | VG_VRREN) self.otp_ctl_reg.set_and_upload(CK_ONESHOT_EN | OTP_TEST_EN | OTP_SEL) return def otp_write_setup(self): self.vg_mpp_reg.set_and_upload(0x00) self.vg_mrr_h_reg.set_and_upload(0x00) self.vg_mrr_l_reg.set_and_upload(VRR0 & 0xFF) self.vg_ctl_reg.set_and_upload(VG_VRREN | VG_VPPEN) # note read voltage must be enabled even for write self.otp_ctl_reg.set_and_upload(OTP_VCC_EXT_EN | OTP_TEST_EN | OTP_SEL) self.otp_ctl_reg.set_and_upload(OTP_VCC_EXT_EN | OTP_TEST_EN | OTP_WE | OTP_SEL) return def otp_write_clk_180(self): # print "write_180" data_otp_ck_high = (OTP_VCC_EXT_EN | OTP_TEST_EN | OTP_WE | OTP_SEL | OTP_CK) data_otp_ck_low = (OTP_VCC_EXT_EN | OTP_TEST_EN | OTP_WE | OTP_SEL) databytes = [data_otp_ck_high, data_otp_ck_low, ] UI.process_events() # time.sleep(2) SERIAL_CHANNELS.current_channel.smbus_block_write(OTP_CTL_ADDR, databytes) return def otp_write_clk_2000(self): # print "write_2000" data_otp_ck_high = (OTP_VCC_EXT_EN | OTP_TEST_EN | OTP_WE | OTP_SEL | OTP_CK) data_otp_ck_low = (OTP_VCC_EXT_EN | OTP_TEST_EN | OTP_WE | OTP_SEL) databytes = [] for i in range(10): databytes.append(data_otp_ck_high) databytes.append(data_otp_ck_low) UI.process_events() # time.sleep(2) SERIAL_CHANNELS.current_channel.smbus_block_write(OTP_CTL_ADDR, databytes) return def otp_read_atom(self, offset): """ otp_setup_for_read must be first called with the correct VG_MRR voltage """ self.otp_addr_reg.set_and_upload(offset & 0x7F) self.otp_ctl_reg.set_and_upload(CK_ONESHOT_EN | OTP_TEST_EN | OTP_SEL | OTP_CK) self.otp_ctl_reg.set_and_upload(CK_ONESHOT_EN | OTP_TEST_EN | OTP_SEL) success, readback, log_strng, log_color = self.otp_q_reg.download_and_overwrite() return success, readback, log_strng, log_color def otp_read_range(self, read_range=None, forcing=False, overwrite_queue=False): """ check the supervisor and regulator states, then if they are OK, iterate on a read of all OTP registers of the device """ UI.process_events() self.OTP_bytes[:]=[] if not self.otp_operations_preps_are_complete(forcing=forcing): return # setup the OTP for reading UI.log('enabling OTP for read') self.otp_read_setup(VRR0) # use "normal" read voltage UI.progressBar.setVisible(True) UI.progressBar.setMinimum(0) UI.progressBar.setMaximum(len(OTPBYTES_BY_OFFSET_DICT)) count = 0 UI.progressBar.setValue(count) self.progressBar.setVisible(True) self.progressBar.setMinimum(0) self.progressBar.setMaximum(len(OTPBYTES_BY_OFFSET_DICT)) count = 0 self.progressBar.setValue(count) UI.process_events() # loop over the range of registers, reading both "banks" or versions UI.log('reading device OTP') if read_range is None: working_read_range = range(0x00, 0x80) else: working_read_range = read_range for offset in working_read_range: otp_reg = OTPBYTES_BY_OFFSET_DICT[offset] count += 1 if (count % 5) == 0: UI.progressBar.setValue(count) self.progressBar.setValue(count) UI.process_events() success, readback, log_strng, log_color = self.otp_read_atom(offset) if success: otp_reg.current_active_val = readback readback_string = number_to_hex_string(readback, 2) otp_reg.active_hex_item.setText(readback_string) if overwrite_queue: otp_reg.update_bits_from_readback(readback) string = "offset=" + number_to_hex_string(offset, 2) + " / data=" + number_to_hex_string(readback, 2) self.OTP_bytes.append(number_to_hex_string(readback, 2)) UI.log(string) else: UI.log(log_strng, log_color) self.otp_disable() UI.log('OTP read finished') UI.progressBar.setVisible(False) self.progressBar.setVisible(False) return def otp_write_one_byte_from_queue_atom(self, offset, bit_position_list): bits_programmed = [] # offset should already be in this register, but just to be sure self.otp_addr_reg.set_and_upload(offset) for bit_pos in bit_position_list: # set the data bit at the correct position (all others 0) # and program the bit for 180 us self.otp_d_reg.set_and_upload(2**bit_pos & 0xFF) # DATA = 8-bit one hot value self.otp_write_setup() self.otp_write_clk_180() count = 1 bit_programmed = False while count < 10: # read the byte using VRR1, and check the bit which was just programmed self.otp_read_setup(VRR1) success, readback, log_strng, log_color = self.otp_read_atom(offset) if readback & 2**bit_pos != 0: read_passed = True else: read_passed = False if read_passed and count > 1: bit_programmed = True break # program the bit for 2000 us self.otp_write_setup() self.otp_write_clk_2000() count += 1 # read the byte using VRR2, and check the bit which was just programmed self.otp_read_setup(VRR2) success, readback, log_strng, log_color = self.otp_read_atom(offset) if readback & 2**bit_pos != 0: bit_programmed = True break bits_programmed.append(bit_programmed) UI.log("count="+str(count)) self.otp_disable() return bits_programmed def otp_write_range(self, write_rng, forcing=False): """ check the supervisor and regulator states, then if they are OK, iterate on a write of all OTP registers in the bank chosen """ errorFlag=False if not self.otp_operations_preps_are_complete(forcing=forcing): return # for OTP write, we need to make sure that the auto-increment bit is DISABLED success, readback, log_string, log_color = self.address_increment_disable_reg.download_and_overwrite() if (readback & ADDRESS_AUTO_INCREMENT_DISABLE) == 0x00: UI.log("address auto-increment bit is not set....setting it") self.address_increment_disable_reg.set_and_upload(readback | ADDRESS_AUTO_INCREMENT_DISABLE) if (readback & ADDRESS_AUTO_INCREMENT_DISABLE) == 0x00: UI.log('address auto-increment bit is not disabled', Qt.red) UI.log('....aborting!', Qt.red) return UI.progressBar.setVisible(True) UI.progressBar.setMinimum(0) UI.progressBar.setMaximum(len(OTPBYTES_BY_OFFSET_DICT)) count = 0 UI.progressBar.setValue(count) UI.process_events() progress_count = 0 self.progressBar.setVisible(True) self.progressBar.setMinimum(0) self.progressBar.setMaximum(len(OTPBYTES_BY_OFFSET_DICT)) count = 0 self.progressBar.setValue(count) for offset in write_rng: # get the data to be written # get the write data otp_reg = OTPBYTES_BY_OFFSET_DICT[offset] write_data = otp_reg.current_queue_val # get the current OTP contents, reading the OTP with vrr0 (normal) self.otp_read_setup(VRR0) success, readback, log_strng, log_color = self.otp_read_atom(offset) # put that readback into the OTP register table (or not) if success: otp_reg.current_active_val = readback readback_string = number_to_hex_string(readback, 2) otp_reg.active_hex_item.setText(readback_string) else: UI.log(log_strng, log_color) break # make a list of the bits that have to be written # OTP starts out as a zero, so we don't have to program 0's, # and we write only 1's where the OTP is not already a 1 failed = False bit_position_list = [] for i in range(8): if (write_data & 2**i) != 0 and (readback & 2**i) == 0: bit_position_list.append(i) if (write_data & 2**i) == 0 and (readback & 2**i) != 0: UI.log("OTP bit #"+str(i)+"cannot be UNset", Qt.red) failed = True break if failed: string = "OTP write halted" UI.log(string, Qt.red) errorFlag=True break string = "writing offset=" + str(offset) + ", bits=[" for bit_position in bit_position_list: string += str(bit_position) + "," string += "]" UI.log(string) bits_programmed = self.otp_write_one_byte_from_queue_atom(offset, bit_position_list) if not all(bits_programmed): string = "OTP write failed" errorFlag=True UI.log(string, Qt.red) break progress_count += 1 if (progress_count % 5) == 0: UI.progressBar.setValue(progress_count) self.progressBar.setValue(progress_count) UI.process_events() UI.log('disabling OTP write mode') self.otp_disable() UI.log('OTP write finished') UI.progressBar.setVisible(False) self.progressBar.setVisible(False) if errorFlag==True: return 0 return 1