def retranslateUi(self, QTabWidget): _translate = QtCore.QCoreApplication.translate QTabWidget.setWindowTitle(_translate("QTabWidget", "QTabWidget")) self.label.setText(_translate("QTabWidget", "TextLabel")) self.pushButton_2.setText(_translate("QTabWidget", "View Resume")) self.pushButton.setText(_translate("QTabWidget", "View Addition Info")) self.label_2.setText(_translate("QTabWidget", "Email:")) self.label_3.setText(_translate("QTabWidget", "Adress:")) self.checkBox.setText(_translate("QTabWidget", "IOS")) self.checkBox_2.setText(_translate("QTabWidget", "Java")) self.checkBox_3.setText(_translate("QTabWidget", "Android")) self.checkBox_4.setText(_translate("QTabWidget", "Python")) self.checkBox_5.setText(_translate("QTabWidget", "DesktopApp")) self.checkBox_6.setText(_translate("QTabWidget", "CPP")) self.pushButton_3.setText(_translate("QTabWidget", "Submit Change")) QTabWidget.setTabText(QTabWidget.indexOf(self.PersonalInfo), _translate("QTabWidget", "Tab 1")) self.label_4.setText(_translate("QTabWidget", "Fill in below demand to quit from the system")) self.textBrowser.setHtml(_translate("QTabWidget", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" "p, li { white-space: pre-wrap; }\n" "</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal;\">\n" "<p align=\"justify\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Check belwo checkbox, means you fully understand your account will be deleted. Before doing this,You must <span style=\" font-weight:600; font-style:italic;\">Withdrawal all your money</span>.</p></body></html>")) self.checkBox_7.setText(_translate("QTabWidget", "I agreed")) self.pushButton_4.setText(_translate("QTabWidget", "Delete Acount")) QTabWidget.setTabText(QTabWidget.indexOf(self.tab), _translate("QTabWidget", "Tab 2")) # connect check box self.checkBox_7.stateChanged.connect(self.enable)
def retranslateUi(self, QTabWidget): _translate = QtCore.QCoreApplication.translate QTabWidget.setWindowTitle(_translate("QTabWidget", "QTabWidget")) item = self.tableWidget.horizontalHeaderItem(0) item.setText(_translate("QTabWidget", "Project Name")) item = self.tableWidget.horizontalHeaderItem(1) item.setText(_translate("QTabWidget", "Price")) item = self.tableWidget.horizontalHeaderItem(2) item.setText(_translate("QTabWidget", "Due Date")) item = self.tableWidget.horizontalHeaderItem(3) item.setText(_translate("QTabWidget", "Detail")) self.pushButton.setText(_translate("QTabWidget", "Submit Project")) item = self.tableWidget_2.horizontalHeaderItem(0) item.setText(_translate("QTabWidget", "Project Name")) item = self.tableWidget_2.horizontalHeaderItem(1) item.setText(_translate("QTabWidget", "Client ID")) self.pushButton_2.setText(_translate("QTabWidget", "Review")) QTabWidget.setTabText(QTabWidget.indexOf(self.tab_2), _translate("QTabWidget", "Current Projects")) item = self.tableWidget_3.horizontalHeaderItem(0) item.setText(_translate("QTabWidget", "Project Name")) item = self.tableWidget_3.horizontalHeaderItem(1) item.setText(_translate("QTabWidget", "Client ID")) item = self.tableWidget_3.horizontalHeaderItem(2) item.setText(_translate("QTabWidget", "Deadline")) item = self.tableWidget_3.horizontalHeaderItem(3) item.setText(_translate("QTabWidget", "Current Bid Price")) item = self.tableWidget_3.horizontalHeaderItem(4) item.setText(_translate("QTabWidget", "Detail")) self.label.setText(_translate("QTabWidget", "Bid Price")) self.pushButton_3.setText(_translate("QTabWidget", "Bid")) self.pushButton_5.setText(_translate("QTabWidget", "Team Bid")) self.pushButton_4.setText(_translate("QTabWidget", "Refresh")) QTabWidget.setTabText(QTabWidget.indexOf(self.tab), _translate("QTabWidget", "Bid Project"))
def retranslateUi(self, QTabWidget): _translate = QtCore.QCoreApplication.translate QTabWidget.setWindowTitle(_translate("QTabWidget", "QTabWidget")) item = self.tableWidget.horizontalHeaderItem(0) item.setText(_translate("QTabWidget", "Project Name")) item = self.tableWidget.horizontalHeaderItem(1) item.setText(_translate("QTabWidget", "Detail")) self.groupBox.setTitle( _translate("QTabWidget", "Select a team or developer for your project")) item = self.tableWidget_2.horizontalHeaderItem(0) item.setText(_translate("QTabWidget", "Developer ID")) item = self.tableWidget_2.horizontalHeaderItem(1) item.setText(_translate("QTabWidget", "Bid")) item = self.tableWidget_3.horizontalHeaderItem(0) item.setText(_translate("QTabWidget", "Team ID")) item = self.tableWidget_3.horizontalHeaderItem(1) item.setText(_translate("QTabWidget", "Bid")) self.pushButton_3.setText( _translate("QTabWidget", "Select this developer")) self.pushButton_4.setText(_translate("QTabWidget", "Select this team")) QTabWidget.setTabText(QTabWidget.indexOf(self.tab), _translate("QTabWidget", "Pending Project")) item = self.tableWidget_4.horizontalHeaderItem(0) item.setText(_translate("QTabWidget", "Project Name")) item = self.tableWidget_4.horizontalHeaderItem(1) item.setText(_translate("QTabWidget", "Developer")) item = self.tableWidget_4.horizontalHeaderItem(2) item.setText(_translate("QTabWidget", "Team")) item = self.tableWidget_4.horizontalHeaderItem(3) item.setText(_translate("QTabWidget", "Detail")) self.label_5.setText(_translate("QTabWidget", "Submited Project")) item = self.tableWidget_5.horizontalHeaderItem(0) item.setText(_translate("QTabWidget", "Project Name")) item = self.tableWidget_5.horizontalHeaderItem(1) item.setText(_translate("QTabWidget", "Developr")) item = self.tableWidget_5.horizontalHeaderItem(2) item.setText(_translate("QTabWidget", "Team")) item = self.tableWidget_5.horizontalHeaderItem(3) item.setText(_translate("QTabWidget", "Detail")) self.pushButton_5.setText(_translate("QTabWidget", "Download Project")) QTabWidget.setTabText(QTabWidget.indexOf(self.tab1), _translate("QTabWidget", "Current Project")) self.label.setText(_translate("QTabWidget", "Project Name")) self.label_2.setText(_translate("QTabWidget", "Detail")) self.label_3.setText(_translate("QTabWidget", "DeadLine")) self.label_4.setText(_translate("QTabWidget", "Biding Deadline")) self.pushButton_2.setText(_translate("QTabWidget", "Post")) QTabWidget.setTabText(QTabWidget.indexOf(self.tab_2), _translate("QTabWidget", "New Project"))
class MainWindow(QMainWindow): def __init__(self, tittle="Potato JS WebKit", width=1366, height=768): super().__init__() self.setWindowTitle(tittle) self.resize(width, height) self._tabs = QTabWidget() self.setCentralWidget(self._tabs) self.show() def addTab(self, tab, tittle="Tab"): self._tabs.addTab(tab, self.fixTabText(tittle)) # Connect to tittle change signal and call function to update tab tittle. tab.titleChanged.connect(self.setTabText) def setTabText(self, str): tab = self.sender() idx = self._tabs.indexOf(tab) self._tabs.setTabText(idx, self.fixTabText(str)) def fixTabText(self, text): if len(text) > 18: return text[:18] + "..." return text
def retranslateUi(self, QTabWidget): _translate = QtCore.QCoreApplication.translate QTabWidget.setWindowTitle(_translate("QTabWidget", "QTabWidget")) item = self.tableWidget.horizontalHeaderItem(0) item.setText(_translate("QTabWidget", "Team Name")) item = self.tableWidget.horizontalHeaderItem(1) item.setText(_translate("QTabWidget", "Member1")) item = self.tableWidget.horizontalHeaderItem(2) item.setText(_translate("QTabWidget", "Member2")) item = self.tableWidget.horizontalHeaderItem(3) item.setText(_translate("QTabWidget", "Member3")) item = self.tableWidget.horizontalHeaderItem(4) item.setText(_translate("QTabWidget", "Member4")) item = self.tableWidget.horizontalHeaderItem(5) item.setText(_translate("QTabWidget", "Member5")) self.pushButton_3.setText( _translate("QTabWidget", "Review this member")) item = self.tableWidget_2.horizontalHeaderItem(0) item.setText(_translate("QTabWidget", "Project id")) item = self.tableWidget_2.horizontalHeaderItem(1) item.setText(_translate("QTabWidget", "Client")) item = self.tableWidget_2.horizontalHeaderItem(2) item.setText(_translate("QTabWidget", "Price")) item = self.tableWidget_2.horizontalHeaderItem(3) item.setText(_translate("QTabWidget", "Due date")) item = self.tableWidget_2.horizontalHeaderItem(4) item.setText(_translate("QTabWidget", "Detail")) self.pushButton_4.setText(_translate("QTabWidget", "Submit Project")) QTabWidget.setTabText(QTabWidget.indexOf(self.tab), _translate("QTabWidget", "Team")) self.label_3.setText(_translate("QTabWidget", "Join a team")) self.pushButton.setText(_translate("QTabWidget", "Join")) self.label_4.setText(_translate("QTabWidget", "Create a team")) self.pushButton_5.setText(_translate("QTabWidget", "Create")) self.tableWidget_3.setSortingEnabled(True) item = self.tableWidget_3.horizontalHeaderItem(0) item.setText(_translate("QTabWidget", "Project Name")) item = self.tableWidget_3.horizontalHeaderItem(1) item.setText(_translate("QTabWidget", "Client")) item = self.tableWidget_3.horizontalHeaderItem(2) item.setText(_translate("QTabWidget", "Price")) item = self.tableWidget_3.horizontalHeaderItem(3) item.setText(_translate("QTabWidget", "Date")) item = self.tableWidget_3.horizontalHeaderItem(4) item.setText(_translate("QTabWidget", "Detail")) QTabWidget.setTabText(QTabWidget.indexOf(self.tab1), _translate("QTabWidget", "Team"))
def retranslateUi(self, QTabWidget): _translate = QtCore.QCoreApplication.translate QTabWidget.setWindowTitle(_translate("QTabWidget", "QTabWidget")) self.pushButton.setText(_translate("QTabWidget", "Search")) self.pushButton_2.setText(_translate("QTabWidget", "Refresh")) self.pushButton_4.setText(_translate("QTabWidget", "New Email")) item = self.tableWidget.horizontalHeaderItem(0) item.setText(_translate("QTabWidget", "Sender")) item = self.tableWidget.horizontalHeaderItem(1) item.setText(_translate("QTabWidget", "Time")) item = self.tableWidget.horizontalHeaderItem(2) item.setText(_translate("QTabWidget", "Content")) QTabWidget.setTabText(QTabWidget.indexOf(self.tab), _translate("QTabWidget", "Inbox")) item = self.tableWidget_2.horizontalHeaderItem(0) item.setText(_translate("QTabWidget", "Receiver")) item = self.tableWidget_2.horizontalHeaderItem(1) item.setText(_translate("QTabWidget", "Time")) item = self.tableWidget_2.horizontalHeaderItem(2) item.setText(_translate("QTabWidget", "Content")) QTabWidget.setTabText(QTabWidget.indexOf(self.tab1), _translate("QTabWidget", "Sent Items"))
def makeViewTabs(self) : """Create new tab with empty tables Tab is created, deta is pushed to the tab """ self.rowsCount = 1 self.table = QTableWidget(self.rowsCount, self.columnCount) self.table.updatesEnabled() self.table.setHorizontalHeaderLabels(self.viewHorHeaders) self.push() self.tabs.addTab(self.table, "New") self.tabs.setCurrentIndex(QTabWidget.indexOf(self.tabs, self.table)) self.tabs.currentChanged.connect(self.tabChanged)
def makeViewTabs(self): _lectures = self.database.getAllLectures() if _lectures == []: # If all data has deleted from db self.addLecture() return else: for lecture in _lectures: self.table = QTableWidget( len(self.database.getLectureIDs(lecture)), self.columnCount) self.table.setHorizontalHeaderLabels(self.viewHorHeaders) self.push(self.database.getRows(lecture)) self.tabs.addTab(self.table, "Lecture " + str(lecture)) _data = [self.tabs, self.table] self.__tabList.append(_data) self.tabs.setCurrentIndex(QTabWidget.indexOf(self.tabs, self.table)) self.tabs.currentChanged.connect(self.tabChanged)
class TassomaiUI(object): def __init__(self, main_window: QMainWindow): self.win = main_window def setupUi(self): self.win.setWindowTitle(f"Tassomai Automation v{__version__}") self.win.setWindowIcon(QIcon(path('images', 'logo.png'))) self.win.resize(665, 580) self.centralwidget = QWidget(self.win) self.formLayout = QFormLayout(self.centralwidget) self.formLayout.setContentsMargins(5, 0, 5, -1) self.topFrame = QFrame(self.centralwidget) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.topFrame.sizePolicy().hasHeightForWidth()) self.topFrame.setSizePolicy(sizePolicy) self.topFrame.setAutoFillBackground(True) self.topFrame.setFrameShape(QFrame.StyledPanel) self.topFrame.setFrameShadow(QFrame.Raised) self.gridLayout = QGridLayout(self.topFrame) self.tassomaiImage = QLabel(self.topFrame) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tassomaiImage.sizePolicy().hasHeightForWidth()) self.tassomaiImage.setSizePolicy(sizePolicy) self.tassomaiImage.setPixmap(QPixmap(path('images', 'banner.png'))) self.gridLayout.addWidget(self.tassomaiImage, 0, 0, 1, 1) self.formLayout.setWidget(0, QFormLayout.SpanningRole, self.topFrame) self.tab = QTabWidget(self.centralwidget) self.main_tab = QWidget() self.automation_tab = QWidget() self.gridLayout_4 = QGridLayout(self.main_tab) self.gridLayout_4.setContentsMargins(0, 0, 0, 0) self.main_frame = QFrame(self.main_tab) self.main_frame.setAutoFillBackground(True) self.main_frame.setFrameShape(QFrame.StyledPanel) self.main_frame.setFrameShadow(QFrame.Raised) self.gridLayout_2 = QGridLayout(self.main_frame) self.gridLayout_2.setContentsMargins(5, 6, 2, -1) self.gridLayout_2.setVerticalSpacing(10) self.gridLayout_5 = QGridLayout(self.automation_tab) self.gridLayout_5.setContentsMargins(0, 0, 0, 0) self.automation_frame = QFrame(self.automation_tab) self.automation_frame.setAutoFillBackground(True) self.automation_frame.setFrameShape(QFrame.StyledPanel) self.automation_frame.setFrameShadow(QFrame.Raised) self.delayLayout = QHBoxLayout() self.delayLayout.setContentsMargins(0, 0, 0, 0) self.delayLayout.setSpacing(3) self.delay = QCheckBox(self.main_frame) font = QFont() font.setPointSize(10) self.delay.setFont(font) self.delayLayout.addWidget(self.delay) self.amountOfDelay = QDoubleSpinBox(self.main_frame) self.amountOfDelay.setMinimumWidth(70) self.amountOfDelay.setMaximum(25.00) self.delayLayout.addWidget(self.amountOfDelay) self.label03 = QLabel(self.main_frame) self.label03.setSizePolicy(sizePolicy) self.label03.setFont(font) self.delayLayout.addWidget(self.label03) self.amountOfDelay2 = QDoubleSpinBox(self.main_frame) self.amountOfDelay2.setMinimumWidth(70) self.amountOfDelay2.setMaximum(25.00) self.delayLayout.addWidget(self.amountOfDelay2) self.label3 = QLabel(self.main_frame) self.label3.setSizePolicy(sizePolicy) self.label3.setFont(font) self.delayLayout.addWidget(self.label3) self.whenDelay = QComboBox(self.main_frame) self.whenDelay.addItem("question") self.whenDelay.addItem("quiz") self.whenDelay.setMaximumWidth(100) self.delayLayout.addWidget(self.whenDelay) self.verticalSpacer1 = QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Expanding) self.delayLayout.addItem(self.verticalSpacer1) self.gridLayout_2.addLayout(self.delayLayout, 2, 0, 1, 1) self.randomnessLayout = QHBoxLayout() self.randomnessLayout.setContentsMargins(0, 0, 0, 0) self.randomnessLayout.setSpacing(3) self.randomness = QCheckBox(self.main_frame) self.randomness.setFont(font) self.randomness.setMaximumWidth(338) self.randomnessLayout.addWidget(self.randomness) self.randomnessAmount = QSpinBox(self.main_frame) self.randomnessAmount.setMinimumWidth(70) self.randomnessAmount.setMaximum(600) self.randomnessLayout.addWidget(self.randomnessAmount) self.label4 = QLabel(self.main_frame) self.label4.setSizePolicy(sizePolicy) self.label4.setFont(font) self.randomnessLayout.addWidget(self.label4) self.gridLayout_2.addLayout(self.randomnessLayout, 3, 0, 1, 1) self.dailyGoal = QCheckBox(self.main_frame) font = QFont() font.setPointSize(10) self.dailyGoal.setFont(font) self.gridLayout_2.addWidget(self.dailyGoal, 4, 0, 1, 1) self.bonusGoal = QCheckBox(self.main_frame) self.bonusGoal.setFont(font) self.gridLayout_2.addWidget(self.bonusGoal, 5, 0, 1, 1) self.horizontalLayout = QHBoxLayout() self.label1 = QLabel(self.main_frame) sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.label1.sizePolicy().hasHeightForWidth()) self.label1.setSizePolicy(sizePolicy) font = QFont() font.setPointSize(10) self.label1.setFont(font) self.horizontalLayout.addWidget(self.label1) self.maxQuizes = QSpinBox(self.main_frame) self.maxQuizes.setMinimum(1) self.maxQuizes.setMaximum(1000000) self.maxQuizes.setProperty("value", 1000) self.horizontalLayout.addWidget(self.maxQuizes) self.label2 = QLabel(self.main_frame) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.label2.sizePolicy().hasHeightForWidth()) self.label2.setSizePolicy(sizePolicy) font = QFont() font.setPointSize(10) self.label2.setFont(font) self.horizontalLayout.addWidget(self.label2) self.gridLayout_2.addLayout(self.horizontalLayout, 1, 0, 1, 1) self.userBox = QGroupBox(self.main_frame) font = QFont() font.setPointSize(9) font.setBold(False) font.setWeight(50) self.userBox.setFont(font) self.gridLayout_3 = QGridLayout(self.userBox) self.emailTassomaiLabel = QLabel(self.userBox) self.gridLayout_3.addWidget(self.emailTassomaiLabel, 0, 0, 1, 1) self.emailTassomai = QLineEdit(self.userBox) self.gridLayout_3.addWidget(self.emailTassomai, 0, 1, 1, 1) self.passwordTassomaiLabel = QLabel(self.userBox) self.gridLayout_3.addWidget(self.passwordTassomaiLabel, 1, 0, 1, 1) self.passwordTassomai = QLineEdit(self.userBox) self.passwordTassomai.setEchoMode(QLineEdit.Password) self.gridLayout_3.addWidget(self.passwordTassomai, 1, 1, 1, 1) self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.gridLayout_3.addItem(self.verticalSpacer, 2, 0, 1, 1) self.gridLayout_4.addWidget(self.main_frame, 0, 0, 1, 1) self.gridLayout_5.addWidget(self.automation_frame, 0, 0, 1, 1) self.tab.addTab(self.main_tab, "") self.tab.addTab(self.automation_tab, "") self.formLayout.setWidget(1, QFormLayout.SpanningRole, self.tab) self.gridLayout_2.addWidget(self.userBox, 0, 0, 1, 1) self.buttonsLayout = QHBoxLayout() self.bottom_frame = QFrame(self.centralwidget) self.bottom_frame.setFrameShape(QFrame.StyledPanel) self.bottom_frame.setFrameShadow(QFrame.Raised) self.gridLayout_7 = QGridLayout(self.bottom_frame) self.gridLayout_7.setContentsMargins(0, 0, 0, 0) self.startButton = QPushButton(self.bottom_frame) self.buttonsLayout.addWidget(self.startButton) self.stopButton = QPushButton(self.bottom_frame) self.buttonsLayout.addWidget(self.stopButton) self.gridLayout_7.addLayout(self.buttonsLayout, 0, 0, 1, 1) self.output = QTextEdit(self.bottom_frame) self.gridLayout_7.addWidget(self.output, 1, 0, 1, 1) self.formLayout.setWidget(2, QFormLayout.SpanningRole, self.bottom_frame) self.win.setCentralWidget(self.centralwidget) self.menubar = QMenuBar(self.win) self.menubar.setGeometry(QRect(0, 0, 665, 21)) self.tools_menu = QMenu(self.menubar) self.uninstall_option = QAction() self.tools_menu.addAction(self.uninstall_option) self.menubar.addAction(self.tools_menu.menuAction()) self.win.setMenuBar(self.menubar) self.createTable() self.retranslateUi() self.tab.setCurrentIndex(0) self.tab.currentChanged['int'].connect(lambda k: self.bottom_frame.hide() if k != 0 else self.bottom_frame.show()) QMetaObject.connectSlotsByName(self.win) def retranslateUi(self): self.dailyGoal.setChecked(True) self.dailyGoal.setText("Finish when daily goal complete") self.bonusGoal.setText("Finish when bonus goal complete") self.delay.setText("Add a delay between") self.label03.setText("and") self.label3.setText("seconds between each") self.randomness.setText("Make it so that you answer a question incorrectly every") self.label4.setText("questions") self.label1.setText("Only do a maximum of ") self.label2.setText(" quiz(s)") self.userBox.setTitle("User Settings") self.passwordTassomaiLabel.setText("Password for Tassomai login") self.emailTassomaiLabel.setText("Email for Tassomai login") self.tab.setTabText(self.tab.indexOf(self.main_tab), "General") self.tab.setTabText(self.tab.indexOf(self.automation_tab), "Automation") self.startButton.setText("Start Automation") self.stopButton.setText("Stop Automation") self.tools_menu.setTitle("Tools") self.uninstall_option.setText("Uninstall (coming soon)") self.output.setReadOnly(True) self.startButton.setEnabled(True) self.stopButton.setEnabled(False) self.output.setHtml("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" "p, li { white-space: pre-wrap; }\n" "</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal;\">\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">-------------------------------------------</p>\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:8pt; font-weight:600; text-decoration: underline; color:#14860a;\">All output will go here<br /></span></p>\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">-------------------------------------------</p>\n" ) def createTable(self): self.table = QTableWidget(self.automation_tab) self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.table.setAlternatingRowColors(True) self.table.setSelectionMode(QAbstractItemView.SingleSelection) self.table.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) self.table.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel) self.table.setShowGrid(True) self.table.setGridStyle(Qt.DashLine) self.table.setRowCount(999999) self.table.setColumnCount(6) for i in range(6): self.table.setHorizontalHeaderItem(i, QTableWidgetItem()) self.table.horizontalHeaderItem(i).setTextAlignment(Qt.AlignLeft) for i in range(6): self.table.setItem(0, i, QTableWidgetItem()) self.table.setItem(1, i, QTableWidgetItem()) self.table.horizontalHeader().setVisible(True) self.table.horizontalHeader().setHighlightSections(True) self.table.verticalHeader().setVisible(False) self.table.verticalHeader().setHighlightSections(True) self.gridLayout_5.addWidget(self.table, 0, 0, 1, 1) headers = ["Quiz", "Num", "Question", "Correct", "Time", "Answer"] for header in headers: item = self.table.horizontalHeaderItem(headers.index(header)) item.setText(header) item.setSizeHint(QSize(25, 25)) self.table.setColumnWidth(0, 40) self.table.setColumnWidth(1, 40) self.table.setColumnWidth(2, 175) self.table.setColumnWidth(3, 80) self.table.setColumnWidth(4, 80) self.table.setColumnWidth(5, 230)
class Setting_Ui(QWidget): def __init__(self, persepolis_setting): super().__init__() icon = QtGui.QIcon() self.persepolis_setting = persepolis_setting # add support for other languages locale = str(self.persepolis_setting.value('settings/locale')) QLocale.setDefault(QLocale(locale)) self.translator = QTranslator() if self.translator.load(':/translations/locales/ui_' + locale, 'ts'): QCoreApplication.installTranslator(self.translator) self.setWindowIcon(QIcon.fromTheme('persepolis', QIcon(':/persepolis.svg'))) self.setWindowTitle(QCoreApplication.translate("setting_ui_tr", 'Preferences')) # set ui direction ui_direction = self.persepolis_setting.value('ui_direction') if ui_direction == 'rtl': self.setLayoutDirection(Qt.RightToLeft) elif ui_direction in 'ltr': self.setLayoutDirection(Qt.LeftToRight) global icons icons = ':/' + str(self.persepolis_setting.value('settings/icons')) + '/' # main layout window_verticalLayout = QVBoxLayout(self) # setting_tabWidget self.setting_tabWidget = QTabWidget(self) # download_options_tab self.download_options_tab = QWidget() download_options_tab_verticalLayout = QVBoxLayout(self.download_options_tab) download_options_tab_verticalLayout.setContentsMargins(21, 21, 0, 0) # tries tries_horizontalLayout = QHBoxLayout() self.tries_label = QLabel(self.download_options_tab) tries_horizontalLayout.addWidget(self.tries_label) self.tries_spinBox = QSpinBox(self.download_options_tab) self.tries_spinBox.setMinimum(1) tries_horizontalLayout.addWidget(self.tries_spinBox) download_options_tab_verticalLayout.addLayout(tries_horizontalLayout) #wait wait_horizontalLayout = QHBoxLayout() self.wait_label = QLabel(self.download_options_tab) wait_horizontalLayout.addWidget(self.wait_label) self.wait_spinBox = QSpinBox(self.download_options_tab) wait_horizontalLayout.addWidget(self.wait_spinBox) download_options_tab_verticalLayout.addLayout(wait_horizontalLayout) # time_out time_out_horizontalLayout = QHBoxLayout() self.time_out_label = QLabel(self.download_options_tab) time_out_horizontalLayout.addWidget(self.time_out_label) self.time_out_spinBox = QSpinBox(self.download_options_tab) time_out_horizontalLayout.addWidget(self.time_out_spinBox) download_options_tab_verticalLayout.addLayout(time_out_horizontalLayout) # connections connections_horizontalLayout = QHBoxLayout() self.connections_label = QLabel(self.download_options_tab) connections_horizontalLayout.addWidget(self.connections_label) self.connections_spinBox = QSpinBox(self.download_options_tab) self.connections_spinBox.setMinimum(1) self.connections_spinBox.setMaximum(16) connections_horizontalLayout.addWidget(self.connections_spinBox) download_options_tab_verticalLayout.addLayout(connections_horizontalLayout) # rpc_port self.rpc_port_label = QLabel(self.download_options_tab) self.rpc_horizontalLayout = QHBoxLayout() self.rpc_horizontalLayout.addWidget(self.rpc_port_label) self.rpc_port_spinbox = QSpinBox(self.download_options_tab) self.rpc_port_spinbox.setMinimum(1024) self.rpc_port_spinbox.setMaximum(65535) self.rpc_horizontalLayout.addWidget(self.rpc_port_spinbox) download_options_tab_verticalLayout.addLayout( self.rpc_horizontalLayout) # wait_queue wait_queue_horizontalLayout = QHBoxLayout() self.wait_queue_label = QLabel(self.download_options_tab) wait_queue_horizontalLayout.addWidget(self.wait_queue_label) self.wait_queue_time = QDateTimeEdit(self.download_options_tab) self.wait_queue_time.setDisplayFormat('H:mm') wait_queue_horizontalLayout.addWidget(self.wait_queue_time) download_options_tab_verticalLayout.addLayout( wait_queue_horizontalLayout) # change aria2 path aria2_path_verticalLayout = QVBoxLayout() self.aria2_path_checkBox = QCheckBox(self.download_options_tab) aria2_path_verticalLayout.addWidget(self.aria2_path_checkBox) aria2_path_horizontalLayout = QHBoxLayout() self.aria2_path_lineEdit = QLineEdit(self.download_options_tab) aria2_path_horizontalLayout.addWidget(self.aria2_path_lineEdit) self.aria2_path_pushButton = QPushButton(self.download_options_tab) aria2_path_horizontalLayout.addWidget(self.aria2_path_pushButton) aria2_path_verticalLayout.addLayout(aria2_path_horizontalLayout) download_options_tab_verticalLayout.addLayout(aria2_path_verticalLayout) download_options_tab_verticalLayout.addStretch(1) self.setting_tabWidget.addTab(self.download_options_tab, "") # save_as_tab self.save_as_tab = QWidget() save_as_tab_verticalLayout = QVBoxLayout(self.save_as_tab) save_as_tab_verticalLayout.setContentsMargins(20, 30, 0, 0) # download_folder self.download_folder_horizontalLayout = QHBoxLayout() self.download_folder_label = QLabel(self.save_as_tab) self.download_folder_horizontalLayout.addWidget( self.download_folder_label) self.download_folder_lineEdit = QLineEdit(self.save_as_tab) self.download_folder_horizontalLayout.addWidget(self.download_folder_lineEdit) self.download_folder_pushButton = QPushButton(self.save_as_tab) self.download_folder_horizontalLayout.addWidget(self.download_folder_pushButton) save_as_tab_verticalLayout.addLayout(self.download_folder_horizontalLayout) # temp_download_folder self.temp_horizontalLayout = QHBoxLayout() self.temp_download_label = QLabel(self.save_as_tab) self.temp_horizontalLayout.addWidget(self.temp_download_label) self.temp_download_lineEdit = QLineEdit(self.save_as_tab) self.temp_horizontalLayout.addWidget(self.temp_download_lineEdit) self.temp_download_pushButton = QPushButton(self.save_as_tab) self.temp_horizontalLayout.addWidget(self.temp_download_pushButton) save_as_tab_verticalLayout.addLayout(self.temp_horizontalLayout) # create subfolder self.subfolder_checkBox = QCheckBox(self.save_as_tab) save_as_tab_verticalLayout.addWidget(self.subfolder_checkBox) save_as_tab_verticalLayout.addStretch(1) self.setting_tabWidget.addTab(self.save_as_tab, "") # notifications_tab self.notifications_tab = QWidget() notification_tab_verticalLayout = QVBoxLayout(self.notifications_tab) notification_tab_verticalLayout.setContentsMargins(21, 21, 0, 0) self.enable_notifications_checkBox = QCheckBox(self.notifications_tab) notification_tab_verticalLayout.addWidget(self.enable_notifications_checkBox) self.sound_frame = QFrame(self.notifications_tab) self.sound_frame.setFrameShape(QFrame.StyledPanel) self.sound_frame.setFrameShadow(QFrame.Raised) verticalLayout = QVBoxLayout(self.sound_frame) self.volume_label = QLabel(self.sound_frame) verticalLayout.addWidget(self.volume_label) self.volume_dial = QDial(self.sound_frame) self.volume_dial.setProperty("value", 100) verticalLayout.addWidget(self.volume_dial) notification_tab_verticalLayout.addWidget(self.sound_frame) # message_notification message_notification_horizontalLayout = QHBoxLayout() self.notification_label = QLabel(self.notifications_tab) message_notification_horizontalLayout.addWidget(self.notification_label) self.notification_comboBox = QComboBox(self.notifications_tab) message_notification_horizontalLayout.addWidget(self.notification_comboBox) notification_tab_verticalLayout.addLayout(message_notification_horizontalLayout) notification_tab_verticalLayout.addStretch(1) self.setting_tabWidget.addTab(self.notifications_tab, "") # style_tab self.style_tab = QWidget() style_tab_verticalLayout = QVBoxLayout(self.style_tab) style_tab_verticalLayout.setContentsMargins(21, 21, 0, 0) # style style_horizontalLayout = QHBoxLayout() self.style_label = QLabel(self.style_tab) style_horizontalLayout.addWidget(self.style_label) self.style_comboBox = QComboBox(self.style_tab) style_horizontalLayout.addWidget(self.style_comboBox) style_tab_verticalLayout.addLayout(style_horizontalLayout) # language language_horizontalLayout = QHBoxLayout() self.lang_label = QLabel(self.style_tab) language_horizontalLayout.addWidget(self.lang_label) self.lang_comboBox = QComboBox(self.style_tab) language_horizontalLayout.addWidget(self.lang_comboBox) style_tab_verticalLayout.addLayout(language_horizontalLayout) language_horizontalLayout = QHBoxLayout() self.lang_label.setText(QCoreApplication.translate("setting_ui_tr", "Language:")) # color scheme self.color_label = QLabel(self.style_tab) language_horizontalLayout.addWidget(self.color_label) self.color_comboBox = QComboBox(self.style_tab) language_horizontalLayout.addWidget(self.color_comboBox) style_tab_verticalLayout.addLayout(language_horizontalLayout) # icons icons_horizontalLayout = QHBoxLayout() self.icon_label = QLabel(self.style_tab) icons_horizontalLayout.addWidget(self.icon_label) self.icon_comboBox = QComboBox(self.style_tab) icons_horizontalLayout.addWidget(self.icon_comboBox) style_tab_verticalLayout.addLayout(icons_horizontalLayout) self.icons_size_horizontalLayout = QHBoxLayout() self.icons_size_label = QLabel(self.style_tab) self.icons_size_horizontalLayout.addWidget(self.icons_size_label) self.icons_size_comboBox = QComboBox(self.style_tab) self.icons_size_horizontalLayout.addWidget(self.icons_size_comboBox) style_tab_verticalLayout.addLayout(self.icons_size_horizontalLayout) # font font_horizontalLayout = QHBoxLayout() self.font_checkBox = QCheckBox(self.style_tab) font_horizontalLayout.addWidget(self.font_checkBox) self.fontComboBox = QFontComboBox(self.style_tab) font_horizontalLayout.addWidget(self.fontComboBox) self.font_size_label = QLabel(self.style_tab) font_horizontalLayout.addWidget(self.font_size_label) self.font_size_spinBox = QSpinBox(self.style_tab) self.font_size_spinBox.setMinimum(1) font_horizontalLayout.addWidget(self.font_size_spinBox) style_tab_verticalLayout.addLayout(font_horizontalLayout) self.setting_tabWidget.addTab(self.style_tab, "") window_verticalLayout.addWidget(self.setting_tabWidget) # Enable system tray icon self.enable_system_tray_checkBox = QCheckBox(self.style_tab) style_tab_verticalLayout.addWidget(self.enable_system_tray_checkBox) # after_download dialog self.after_download_checkBox = QCheckBox() style_tab_verticalLayout.addWidget(self.after_download_checkBox) # show_menubar_checkbox self.show_menubar_checkbox = QCheckBox() style_tab_verticalLayout.addWidget(self.show_menubar_checkbox) # show_sidepanel_checkbox self.show_sidepanel_checkbox = QCheckBox() style_tab_verticalLayout.addWidget(self.show_sidepanel_checkbox) # hide progress window self.show_progress_window_checkbox = QCheckBox() style_tab_verticalLayout.addWidget(self.show_progress_window_checkbox) # add persepolis to startup self.startup_checkbox = QCheckBox() style_tab_verticalLayout.addWidget(self.startup_checkbox) # keep system awake self.keep_awake_checkBox = QCheckBox() style_tab_verticalLayout.addWidget(self.keep_awake_checkBox) style_tab_verticalLayout.addStretch(1) # columns_tab self.columns_tab = QWidget() columns_tab_verticalLayout = QVBoxLayout(self.columns_tab) columns_tab_verticalLayout.setContentsMargins(21, 21, 0, 0) # creating checkBox for columns self.show_column_label = QLabel() self.column0_checkBox = QCheckBox() self.column1_checkBox = QCheckBox() self.column2_checkBox = QCheckBox() self.column3_checkBox = QCheckBox() self.column4_checkBox = QCheckBox() self.column5_checkBox = QCheckBox() self.column6_checkBox = QCheckBox() self.column7_checkBox = QCheckBox() self.column10_checkBox = QCheckBox() self.column11_checkBox = QCheckBox() self.column12_checkBox = QCheckBox() columns_tab_verticalLayout.addWidget(self.show_column_label) columns_tab_verticalLayout.addWidget(self.column0_checkBox) columns_tab_verticalLayout.addWidget(self.column1_checkBox) columns_tab_verticalLayout.addWidget(self.column2_checkBox) columns_tab_verticalLayout.addWidget(self.column3_checkBox) columns_tab_verticalLayout.addWidget(self.column4_checkBox) columns_tab_verticalLayout.addWidget(self.column5_checkBox) columns_tab_verticalLayout.addWidget(self.column6_checkBox) columns_tab_verticalLayout.addWidget(self.column7_checkBox) columns_tab_verticalLayout.addWidget(self.column10_checkBox) columns_tab_verticalLayout.addWidget(self.column11_checkBox) columns_tab_verticalLayout.addWidget(self.column12_checkBox) columns_tab_verticalLayout.addStretch(1) self.setting_tabWidget.addTab(self.columns_tab, '') # video_finder_tab self.video_finder_tab = QWidget() video_finder_layout = QVBoxLayout(self.video_finder_tab) video_finder_layout.setContentsMargins(21, 21, 0, 0) video_finder_tab_verticalLayout = QVBoxLayout() # Whether to enable video link capturing. self.enable_video_finder_checkbox = QCheckBox(self.video_finder_tab) video_finder_layout.addWidget(self.enable_video_finder_checkbox) # If we should hide videos with no audio self.hide_no_audio_checkbox = QCheckBox(self.video_finder_tab) video_finder_tab_verticalLayout.addWidget(self.hide_no_audio_checkbox) # If we should hide audios without video self.hide_no_video_checkbox = QCheckBox(self.video_finder_tab) video_finder_tab_verticalLayout.addWidget(self.hide_no_video_checkbox) max_links_horizontalLayout = QHBoxLayout() # max_links_label self.max_links_label = QLabel(self.video_finder_tab) max_links_horizontalLayout.addWidget(self.max_links_label) # max_links_spinBox self.max_links_spinBox = QSpinBox(self.video_finder_tab) self.max_links_spinBox.setMinimum(1) self.max_links_spinBox.setMaximum(16) max_links_horizontalLayout.addWidget(self.max_links_spinBox) video_finder_tab_verticalLayout.addLayout(max_links_horizontalLayout) self.video_finder_dl_path_horizontalLayout = QHBoxLayout() self.video_finder_frame = QFrame(self.video_finder_tab) self.video_finder_frame.setLayout(video_finder_tab_verticalLayout) video_finder_tab_verticalLayout.addStretch(1) video_finder_layout.addWidget(self.video_finder_frame) self.setting_tabWidget.addTab(self.video_finder_tab, "") # window buttons buttons_horizontalLayout = QHBoxLayout() buttons_horizontalLayout.addStretch(1) self.defaults_pushButton = QPushButton(self) buttons_horizontalLayout.addWidget(self.defaults_pushButton) self.cancel_pushButton = QPushButton(self) self.cancel_pushButton.setIcon(QIcon(icons + 'remove')) buttons_horizontalLayout.addWidget(self.cancel_pushButton) self.ok_pushButton = QPushButton(self) self.ok_pushButton.setIcon(QIcon(icons + 'ok')) buttons_horizontalLayout.addWidget(self.ok_pushButton) window_verticalLayout.addLayout(buttons_horizontalLayout) # set style_tab for default self.setting_tabWidget.setCurrentIndex(3) # labels and translations self.setWindowTitle(QCoreApplication.translate("setting_ui_tr", "Preferences")) self.tries_label.setToolTip( QCoreApplication.translate("setting_ui_tr", "<html><head/><body><p>Set number of tries if download failed.</p></body></html>")) self.tries_label.setText(QCoreApplication.translate("setting_ui_tr", "Number of tries: ")) self.tries_spinBox.setToolTip( QCoreApplication.translate("setting_ui_tr", "<html><head/><body><p>Set number of tries if download failed.</p></body></html>")) self.wait_label.setToolTip( QCoreApplication.translate("setting_ui_tr", "<html><head/><body><p>Set the seconds to wait between retries. Download manager will retry downloads when the HTTP server returns a 503 response.</p></body></html>")) self.wait_label.setText(QCoreApplication.translate("setting_ui_tr", "Wait between retries (seconds): ")) self.wait_spinBox.setToolTip( QCoreApplication.translate("setting_ui_tr", "<html><head/><body><p>Set the seconds to wait between retries. Download manager will retry downloads when the HTTP server returns a 503 response.</p></body></html>")) self.time_out_label.setToolTip( QCoreApplication.translate("setting_ui_tr", "<html><head/><body><p>Set timeout in seconds. </p></body></html>")) self.time_out_label.setText(QCoreApplication.translate("setting_ui_tr", "Timeout (seconds): ")) self.time_out_spinBox.setToolTip( QCoreApplication.translate("setting_ui_tr", "<html><head/><body><p>Set timeout in seconds. </p></body></html>")) self.connections_label.setToolTip( QCoreApplication.translate("setting_ui_tr", "<html><head/><body><p>Using multiple connections can help speed up your download.</p></body></html>")) self.connections_label.setText(QCoreApplication.translate("setting_ui_tr", "Number of connections: ")) self.connections_spinBox.setToolTip( QCoreApplication.translate("setting_ui_tr", "<html><head/><body><p>Using multiple connections can help speed up your download.</p></body></html>")) self.rpc_port_label.setText(QCoreApplication.translate("setting_ui_tr", "RPC port number: ")) self.rpc_port_spinbox.setToolTip( QCoreApplication.translate("setting_ui_tr", "<html><head/><body><p> Specify a port number for JSON-RPC/XML-RPC server to listen to. Possible Values: 1024 - 65535 Default: 6801 </p></body></html>")) self.wait_queue_label.setText(QCoreApplication.translate("setting_ui_tr", 'Wait between every downloads in queue:')) self.aria2_path_checkBox.setText(QCoreApplication.translate("setting_ui_tr", 'Change Aria2 default path')) self.aria2_path_pushButton.setText(QCoreApplication.translate("setting_ui_tr", 'Change')) aria2_path_tooltip =QCoreApplication.translate("setting_ui_tr", "<html><head/><body><p>Attention: Wrong path may have caused problem! Do it carefully or don't change default setting!</p></body></html>" ) self.aria2_path_checkBox.setToolTip(aria2_path_tooltip) self.aria2_path_lineEdit.setToolTip(aria2_path_tooltip) self.aria2_path_pushButton.setToolTip(aria2_path_tooltip) self.setting_tabWidget.setTabText(self.setting_tabWidget.indexOf( self.download_options_tab), QCoreApplication.translate("setting_ui_tr", "Download Options")) self.download_folder_label.setText(QCoreApplication.translate("setting_ui_tr", "Download Folder: ")) self.download_folder_pushButton.setText(QCoreApplication.translate("setting_ui_tr", "Change")) self.temp_download_label.setText(QCoreApplication.translate("setting_ui_tr", "Temporary Download Folder: ")) self.temp_download_pushButton.setText(QCoreApplication.translate("setting_ui_tr", "Change")) self.subfolder_checkBox.setText(QCoreApplication.translate("setting_ui_tr", "Create subfolders for Music,Videos,... in default download folder")) self.setting_tabWidget.setTabText( self.setting_tabWidget.indexOf(self.save_as_tab), QCoreApplication.translate("setting_ui_tr", "Save as")) self.enable_notifications_checkBox.setText( QCoreApplication.translate("setting_ui_tr", "Enable notification sounds")) self.volume_label.setText(QCoreApplication.translate("setting_ui_tr", "Volume: ")) self.setting_tabWidget.setTabText(self.setting_tabWidget.indexOf( self.notifications_tab), QCoreApplication.translate("setting_ui_tr", "Notifications")) self.style_label.setText(QCoreApplication.translate("setting_ui_tr", "Style: ")) self.color_label.setText(QCoreApplication.translate("setting_ui_tr", "Color scheme: ")) self.icon_label.setText(QCoreApplication.translate("setting_ui_tr", "Icons: ")) self.icons_size_label.setText(QCoreApplication.translate("setting_ui_tr", "Toolbar's icons size: ")) self.notification_label.setText(QCoreApplication.translate("setting_ui_tr", "Notification type: ")) self.font_checkBox.setText(QCoreApplication.translate("setting_ui_tr", "Font: ")) self.font_size_label.setText(QCoreApplication.translate("setting_ui_tr", "Size: ")) self.enable_system_tray_checkBox.setText(QCoreApplication.translate("setting_ui_tr", "Enable system tray icon.")) self.after_download_checkBox.setText( QCoreApplication.translate("setting_ui_tr", "Show download complete dialog when download has finished.")) self.show_menubar_checkbox.setText(QCoreApplication.translate("setting_ui_tr", "Show menubar.")) self.show_sidepanel_checkbox.setText(QCoreApplication.translate("setting_ui_tr", "Show side panel.")) self.show_progress_window_checkbox.setText( QCoreApplication.translate("setting_ui_tr", "Show download's progress window")) self.startup_checkbox.setText(QCoreApplication.translate("setting_ui_tr", "Run Persepolis at startup")) self.keep_awake_checkBox.setText(QCoreApplication.translate("setting_ui_tr", "Keep system awake!")) self.keep_awake_checkBox.setToolTip( QCoreApplication.translate("setting_ui_tr", "<html><head/><body><p>This option is preventing system from going to sleep.\ This is necessary if your power manager is suspending system automatically. </p></body></html>")) self.wait_queue_time.setToolTip( QCoreApplication.translate("setting_ui_tr", "<html><head/><body><p>Format HH:MM</p></body></html>")) self.setting_tabWidget.setTabText( self.setting_tabWidget.indexOf(self.style_tab), QCoreApplication.translate("setting_ui_tr", "Preferences")) # columns_tab self.show_column_label.setText(QCoreApplication.translate("setting_ui_tr", 'Show this columns:')) self.column0_checkBox.setText(QCoreApplication.translate("setting_ui_tr", 'File Name')) self.column1_checkBox.setText(QCoreApplication.translate("setting_ui_tr", 'Status')) self.column2_checkBox.setText(QCoreApplication.translate("setting_ui_tr", 'Size')) self.column3_checkBox.setText(QCoreApplication.translate("setting_ui_tr", 'Downloaded')) self.column4_checkBox.setText(QCoreApplication.translate("setting_ui_tr", 'Percentage')) self.column5_checkBox.setText(QCoreApplication.translate("setting_ui_tr", 'Connections')) self.column6_checkBox.setText(QCoreApplication.translate("setting_ui_tr", 'Transfer rate')) self.column7_checkBox.setText(QCoreApplication.translate("setting_ui_tr", 'Estimated time left')) self.column10_checkBox.setText(QCoreApplication.translate("setting_ui_tr", 'First try date')) self.column11_checkBox.setText(QCoreApplication.translate("setting_ui_tr", 'Last try date')) self.column12_checkBox.setText(QCoreApplication.translate("setting_ui_tr", 'Category')) self.setting_tabWidget.setTabText( self.setting_tabWidget.indexOf(self.columns_tab), QCoreApplication.translate("setting_ui_tr", "Columns customization")) # Video Finder options tab self.setting_tabWidget.setTabText(self.setting_tabWidget.indexOf( self.video_finder_tab), QCoreApplication.translate("setting_ui_tr", "Video Finder Options")) self.enable_video_finder_checkbox.setText(QCoreApplication.translate("setting_ui_tr", 'Enable Video Finder')) self.hide_no_audio_checkbox.setText(QCoreApplication.translate("setting_ui_tr", 'Hide videos with no audio')) self.hide_no_video_checkbox.setText(QCoreApplication.translate("setting_ui_tr", 'Hide audios with no video')) self.max_links_label.setText(QCoreApplication.translate("setting_ui_tr", 'Maximum number of links to capture:<br/>' '<small>(If browser sends multiple video links at a time)</small>')) # window buttons self.defaults_pushButton.setText(QCoreApplication.translate("setting_ui_tr", "Defaults")) self.cancel_pushButton.setText(QCoreApplication.translate("setting_ui_tr", "Cancel")) self.ok_pushButton.setText(QCoreApplication.translate("setting_ui_tr", "OK"))
class Gui(QWidget): def __init__(self, config, core, language='de'): super(Gui, self).__init__() # setup the translation object self.language = language self.tran = cc_texts.Texts(self.language) self.helper = cc_help.Help(self.language) self.configparser = config self.config = config.read_config() self.core_ref = core self.messages = set() self.thread = None self.mainLayout = None self.mainsplitter = None self.maintabwidget = None self.status_line = None self.settab = None self.advtab = None self.keytab = None self.ugtab = None self_selected_tab = None # set the main window name and icon self.setWindowTitle(self.tran.get_text("title")) self.setWindowIcon( QIcon(join(dirname(__file__), "resources/Logo_v2.png"))) # configure the main window self.setObjectName('main_window') self.resize(800, 700) self.center() self.status_line = QTextBrowser(self.mainsplitter) self.status_line.setObjectName('status_line') # setup the main layout self.mainLayout = QGridLayout(self) self.mainLayout.setObjectName('main_layout') # setup the main splitter self.mainsplitter = QSplitter(self) self.mainsplitter.setOrientation(Qt.Vertical) self.mainsplitter.setObjectName('main_splitter') # setup the tab widget self.maintabwidget = QTabWidget(self.mainsplitter) self.maintabwidget.setObjectName('main_tab_widget') # make sure, the tab are is bigger than the message area self.maintabwidget_sizepolicy = QSizePolicy() self.maintabwidget_sizepolicy.setVerticalStretch(2) self.maintabwidget.setSizePolicy(self.maintabwidget_sizepolicy) self.maintabwidget.currentChanged.connect(self._sync) # setup the settings tab self.settab = NorSetTab(self) self._selected_tab = self.settab self.advtab = AdvSetTab(self) self.maintabwidget.addTab(self.settab, self.tran.get_text('settings_title')) self.settab.init() # setup the status line self.status_line = QTextBrowser(self.mainsplitter) self.status_line.setObjectName('status_line') # add the elements to the main layout self.mainLayout.addWidget(self.mainsplitter, 0, 0, 1, 1) self.menubar = QMenuBar() self.help_menu = QMenu(self.tran.get_text('help_menu_title'), self) self.help_action = self.help_menu.addAction( self.tran.get_text('help_menu_action')) self.help_action.triggered.connect(self.open_help_page) self.menubar.addMenu(self.help_menu) self.mainLayout.setMenuBar(self.menubar) self.set_style_sheet() def set_style_sheet(self): if cc_con.THEME in self.config: try: with open( cc_con.THEME_PREFIX + self.config[cc_con.THEME] + cc_con.THEME_POSTFIX, "r") as theme: self.setStyleSheet(theme.read()) except EnvironmentError: print("ERROR: Theme not found, using default theme") with open( cc_con.THEME_PREFIX + self.config[cc_con.THEME_DEFAULT] + cc_con.THEME_POSTFIX, "r") as theme: self.setStyleSheet(theme.read()) def show_adv_tab(self, onoff): """ Show or hide the advanced settings tab :param onoff: True to show the advanced settings tab and false to hide it :return: None """ # check if the advanced tab is already in the tablist tab_in_tablist = True if self.maintabwidget.indexOf( self.advtab) != -1 else False if onoff and not tab_in_tablist: self.maintabwidget.addTab(self.advtab, self.tran.get_text('advanced_title')) elif tab_in_tablist: self.maintabwidget.removeTab( self.maintabwidget.indexOf(self.advtab)) def browse_config(self): """ Opens a file browser to select the config file and sets the QEditLine according to the selection. :return: None """ filename, _ = QFileDialog.getOpenFileName( self, self.tran.get_text('adv_tab_button_config_desc'), self.advtab_input_config.text(), "XML (*.xml)") if filename: self.advtab_input_config.setText(str(filename)) def get_config_path(self): if self.advtab_input_config == "": return None else: return self.advtab_input_config.text() def get_plain_path(self): if self.settab_input_clear == "": return None else: return self.settab_input_clear.text() def get_cipher_path(self): if self.settab_input_enc == "": return None else: return self.settab_input_enc.text() def open_help_page(self): self.helper.open_help("index.html", "") def write_config(self): self.messages.add(str(self.config)) self.messages.add(self.tran.get_text('writing_config')) self._renew_message_area() self.configparser.write_config(self.config) def _renew_message_area(self): self.status_line.setText("") for message in self.messages: self.status_line.append(message) def center(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) def add_message(self, message): self.messages.add(message) self._renew_message_area() def del_message(self, message): """ Remove a message from the message area :param message: the message to remove :return: True if the message was removed sucessfully and False if the message was not there to begin with """ try: self.messages.remove(message) self._renew_message_area() return True except KeyError: return False def str_to_bool(self, text): if text in 'True': return True else: return False def _sync(self): self.config = self._selected_tab.config() self.configparser.write_config(self._selected_tab.config()) if self.maintabwidget.count() > 0: self.maintabwidget.currentWidget().init() if self.settab.is_running(): self.maintabwidget.currentWidget().lock() else: self.maintabwidget.currentWidget().unlock() if self.settab.tooltip_state(): self.maintabwidget.currentWidget().toggle_tooltips("True") else: self.maintabwidget.currentWidget().toggle_tooltips("False") self._selected_tab = self.maintabwidget.currentWidget() def closeEvent(self, event): reply = QMessageBox.question(None, '', self.tran.get_text('exit_cloudcrypt'), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) self.write_config() if reply == QMessageBox.Yes: self.settab.slider_moved("off") event.accept() else: event.ignore()
class Ui_MainWindow(object): def setupUi(self, MainWindow): """ :param MainWindow: :type MainWindow: """ MainWindow.setObjectName("MainWindow") MainWindow.resize(779, 434) font = QFont() font.setFamily(u"Segoe UI") font.setPointSize(14) MainWindow.setFont(font) MainWindow.setStyleSheet(u"background-color: rgb(36, 36, 36);") self.centralwidget = QWidget(MainWindow) self.centralwidget.setObjectName(u"centralwidget") self.tabWidget = QTabWidget(self.centralwidget) self.tabWidget.setObjectName(u"tabWidget") self.tabWidget.setGeometry(QRect(10, 10, 511, 421)) self.tabWidget.setStyleSheet(u"font: 12pt \"Lucida Calligraphy\";\n" "border-radius: 10px;\n" "color: rgb(17, 167, 157);\n" "") self.profileTab = QWidget() self.profileTab.setObjectName(u"profileTab") self.helloLabel = QLabel(self.profileTab) self.helloLabel.setObjectName(u"helloLabel") self.helloLabel.setGeometry(QRect(10, 10, 491, 31)) self.infoLabel = QLabel(self.profileTab) self.infoLabel.setObjectName(u"infoLabel") self.infoLabel.setGeometry(QRect(10, 50, 491, 31)) self.messagesList = QListWidget(self.profileTab) self.messagesList.setObjectName(u"messagesList") self.messagesList.setGeometry(QRect(10, 90, 491, 281)) self.messagesList.setStyleSheet(u"background: rgba(10,100,120,100);") self.tabWidget.addTab(self.profileTab, "") self.feedNewsTab = QWidget() self.feedNewsTab.setObjectName(u"feedNewsTab") self.horizontalLayout = QHBoxLayout(self.feedNewsTab) self.horizontalLayout.setObjectName(u"horizontalLayout") self.feedsArea = QScrollArea(self.feedNewsTab) self.feedsArea.setObjectName(u"feedsArea") self.feedsArea.setWidgetResizable(True) self.scrollAreaWidgetContents = QWidget() self.scrollAreaWidgetContents.setObjectName( u"scrollAreaWidgetContents") self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 481, 353)) self.verticalLayout = QVBoxLayout(self.scrollAreaWidgetContents) self.verticalLayout.setObjectName(u"verticalLayout") self.feedsArea.setWidget(self.scrollAreaWidgetContents) self.horizontalLayout.addWidget(self.feedsArea) self.tabWidget.addTab(self.feedNewsTab, "") self.myNewsFeedTab = QWidget() self.myNewsFeedTab.setObjectName(u"myNewsFeedTab") self.myFeedsArea = QScrollArea(self.myNewsFeedTab) self.myFeedsArea.setObjectName(u"myFeedsArea") self.myFeedsArea.setGeometry(QRect(10, 10, 487, 365)) self.myFeedsArea.setWidgetResizable(True) self.scrollAreaWidgetContents_2 = QWidget() self.scrollAreaWidgetContents_2.setObjectName( u"scrollAreaWidgetContents_2") self.scrollAreaWidgetContents_2.setGeometry(QRect(0, 0, 485, 363)) self.verticalLayout_2 = QVBoxLayout(self.scrollAreaWidgetContents_2) self.verticalLayout_2.setObjectName(u"verticalLayout_2") self.myFeedsArea.setWidget(self.scrollAreaWidgetContents_2) self.tabWidget.addTab(self.myNewsFeedTab, "") self.friendsTab = QWidget() self.friendsTab.setObjectName(u"friendsTab") self.friendsList = QListWidget(self.friendsTab) self.friendsList.setObjectName(u"friendsList") self.friendsList.setGeometry(QRect(10, 10, 491, 321)) font1 = QFont() font1.setFamily(u"Lucida Calligraphy") font1.setPointSize(12) font1.setBold(False) font1.setItalic(False) font1.setWeight(50) self.friendsList.setFont(font1) self.friendsList.setStyleSheet(u"") self.tabWidget.addTab(self.friendsTab, "") self.exitButton = QPushButton(self.centralwidget) self.exitButton.setObjectName(u"exitButton") self.exitButton.setGeometry(QRect(530, 300, 211, 31)) self.exitButton.setStyleSheet(u"font: 12pt \"Lucida Calligraphy\";\n" "border-radius: 10px;\n" "background-color: rgb(17, 167, 157);\n" "") self.sendMessageButton = QPushButton(self.centralwidget) self.sendMessageButton.setObjectName(u"sendMessageButton") self.sendMessageButton.setGeometry(QRect(530, 140, 211, 31)) self.sendMessageButton.setStyleSheet( u"font: 12pt \"Lucida Calligraphy\";\n" "border-radius: 10px;\n" "background-color: rgb(17, 167, 157);\n" "") self.createPostButton = QPushButton(self.centralwidget) self.createPostButton.setObjectName(u"createPostButton") self.createPostButton.setGeometry(QRect(530, 180, 211, 31)) self.createPostButton.setStyleSheet( u"font: 12pt \"Lucida Calligraphy\";\n" "border-radius: 10px;\n" "background-color: rgb(17, 167, 157);\n" "") self.deleteFriend = QPushButton(self.centralwidget) self.deleteFriend.setObjectName(u"deleteFriend") self.deleteFriend.setGeometry(QRect(530, 260, 211, 31)) self.deleteFriend.setStyleSheet( u"font: 12pt \"Lucida Calligraphy\";\n" "border-radius: 10px;\n" "background-color: rgb(17, 167, 157);\n" "") self.addFriend = QPushButton(self.centralwidget) self.addFriend.setObjectName(u"addFriend") self.addFriend.setGeometry(QRect(530, 220, 211, 31)) self.addFriend.setStyleSheet(u"font: 12pt \"Lucida Calligraphy\";\n" "border-radius: 10px;\n" "background-color: rgb(17, 167, 157);\n" "") self.aboutMeButton = QPushButton(self.centralwidget) self.aboutMeButton.setObjectName(u"aboutMeButton") self.aboutMeButton.setGeometry(QRect(530, 100, 211, 31)) self.aboutMeButton.setStyleSheet( u"font: 12pt \"Lucida Calligraphy\";\n" "border-radius: 10px;\n" "background-color: rgb(17, 167, 157);\n" "") MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) self.tabWidget.setCurrentIndex(2) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): """ :param MainWindow: :type MainWindow: """ _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.helloLabel.setText(_translate("MainWindow", "Здравствуйте , Олег")) self.infoLabel.setText( _translate("MainWindow", "У вас 6 непрочитанных сообщений")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.profileTab), _translate("MainWindow", "Профиль")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.feedNewsTab), _translate("MainWindow", "Лента")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.myNewsFeedTab), _translate("MainWindow", "Моя лента")) self.addFriend.setText(_translate("MainWindow", "Добавить друга")) self.deleteFriend.setText(_translate("MainWindow", "Удалить")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.friendsTab), _translate("MainWindow", "Друзья")) self.exitButton.setText(_translate("MainWindow", "Выход")) self.sendMessageButton.setText( _translate("MainWindow", "Отправить сообщение")) self.createPostButton.setText(_translate("MainWindow", "Создать пост")) self.aboutMeButton.setText(_translate("MainWindow", "Обо мне"))
class AddLinkWindow_Ui(QWidget): def __init__(self, persepolis_setting): super().__init__() self.persepolis_setting = persepolis_setting # add support for other languages locale = str(self.persepolis_setting.value('settings/locale')) QLocale.setDefault(QLocale(locale)) self.translator = QTranslator() if self.translator.load(':/translations/locales/ui_' + locale, 'ts'): QCoreApplication.installTranslator(self.translator) # set ui direction ui_direction = self.persepolis_setting.value('ui_direction') if ui_direction == 'rtl': self.setLayoutDirection(Qt.RightToLeft) elif ui_direction in 'ltr': self.setLayoutDirection(Qt.LeftToRight) # get icons name icons = ':/' + \ str(self.persepolis_setting.value('settings/icons')) + '/' self.setMinimumSize(QtCore.QSize(520, 425)) self.setWindowIcon(QIcon.fromTheme('persepolis', QIcon(':/persepolis.svg'))) # main layout window_verticalLayout = QVBoxLayout() # add link tab widget self.add_link_tabWidget = QTabWidget(self) window_verticalLayout.addWidget(self.add_link_tabWidget) # link tab self.link_tab = QWidget() link_tab_verticalLayout = QVBoxLayout(self.link_tab) link_tab_verticalLayout.setContentsMargins(21, 21, 21, 81) self.link_frame = QFrame(self.link_tab) self.link_frame.setFrameShape(QFrame.StyledPanel) self.link_frame.setFrameShadow(QFrame.Raised) horizontalLayout_2 = QHBoxLayout(self.link_frame) self.link_verticalLayout = QVBoxLayout() # link -> self.link_horizontalLayout = QHBoxLayout() self.link_label = QLabel(self.link_frame) self.link_horizontalLayout.addWidget(self.link_label) self.link_lineEdit = QLineEdit(self.link_frame) self.link_horizontalLayout.addWidget(self.link_lineEdit) self.link_verticalLayout.addLayout(self.link_horizontalLayout) horizontalLayout_2.addLayout(self.link_verticalLayout) link_tab_verticalLayout.addWidget(self.link_frame) # add change_name field -> self.change_name_horizontalLayout = QHBoxLayout() self.change_name_checkBox = QCheckBox(self.link_frame) self.change_name_horizontalLayout.addWidget(self.change_name_checkBox) self.change_name_lineEdit = QLineEdit(self.link_frame) self.change_name_horizontalLayout.addWidget(self.change_name_lineEdit) self.link_verticalLayout.addLayout(self.change_name_horizontalLayout) # add_category -> queue_horizontalLayout = QHBoxLayout() self.queue_frame = QFrame(self) self.queue_frame.setFrameShape(QFrame.StyledPanel) self.queue_frame.setFrameShadow(QFrame.Raised) add_queue_horizontalLayout = QHBoxLayout(self.queue_frame) self.add_queue_label = QLabel(self.queue_frame) add_queue_horizontalLayout.addWidget(self.add_queue_label) self.add_queue_comboBox = QComboBox(self.queue_frame) add_queue_horizontalLayout.addWidget(self.add_queue_comboBox) queue_horizontalLayout.addWidget(self.queue_frame) queue_horizontalLayout.addStretch(1) self.size_label = QLabel(self) queue_horizontalLayout.addWidget(self.size_label) link_tab_verticalLayout.addLayout(queue_horizontalLayout) link_tab_verticalLayout.addStretch(1) self.add_link_tabWidget.addTab(self.link_tab, '') # proxy tab self.proxy_tab = QWidget(self) proxy_verticalLayout = QVBoxLayout(self.proxy_tab) proxy_verticalLayout.setContentsMargins(21, 21, 21, 171) proxy_horizontalLayout = QHBoxLayout() self.proxy_checkBox = QCheckBox(self.proxy_tab) self.detect_proxy_pushButton = QPushButton(self.proxy_tab) self.detect_proxy_label = QLabel(self.proxy_tab) proxy_horizontalLayout.addWidget(self.proxy_checkBox) proxy_horizontalLayout.addWidget(self.detect_proxy_label) proxy_horizontalLayout.addWidget(self.detect_proxy_pushButton) proxy_verticalLayout.addLayout(proxy_horizontalLayout) self.proxy_frame = QFrame(self.proxy_tab) self.proxy_frame.setFrameShape(QFrame.StyledPanel) self.proxy_frame.setFrameShadow(QFrame.Raised) gridLayout = QGridLayout(self.proxy_frame) self.ip_label = QLabel(self.proxy_frame) gridLayout.addWidget(self.ip_label, 0, 0, 1, 1) self.ip_lineEdit = QLineEdit(self.proxy_frame) self.ip_lineEdit.setInputMethodHints(QtCore.Qt.ImhNone) gridLayout.addWidget(self.ip_lineEdit, 0, 1, 1, 1) self.port_label = QLabel(self.proxy_frame) gridLayout.addWidget(self.port_label, 0, 2, 1, 1) self.port_spinBox = QSpinBox(self.proxy_frame) self.port_spinBox.setMaximum(65535) self.port_spinBox.setSingleStep(1) gridLayout.addWidget(self.port_spinBox, 0, 3, 1, 1) self.proxy_user_label = QLabel(self.proxy_frame) gridLayout.addWidget(self.proxy_user_label, 2, 0, 1, 1) self.proxy_user_lineEdit = QLineEdit(self.proxy_frame) gridLayout.addWidget(self.proxy_user_lineEdit, 2, 1, 1, 1) self.proxy_pass_label = QLabel(self.proxy_frame) gridLayout.addWidget(self.proxy_pass_label, 2, 2, 1, 1) self.proxy_pass_lineEdit = QLineEdit(self.proxy_frame) self.proxy_pass_lineEdit.setEchoMode(QLineEdit.Password) gridLayout.addWidget(self.proxy_pass_lineEdit, 2, 3, 1, 1) proxy_verticalLayout.addWidget(self.proxy_frame) proxy_verticalLayout.addStretch(1) self.add_link_tabWidget.addTab(self.proxy_tab, '') # more options tab self.more_options_tab = QWidget(self) more_options_tab_verticalLayout = QVBoxLayout(self.more_options_tab) # download UserName & Password -> download_horizontalLayout = QHBoxLayout() download_horizontalLayout.setContentsMargins(-1, 10, -1, -1) download_verticalLayout = QVBoxLayout() self.download_checkBox = QCheckBox(self.more_options_tab) download_verticalLayout.addWidget(self.download_checkBox) self.download_frame = QFrame(self.more_options_tab) self.download_frame.setFrameShape(QFrame.StyledPanel) self.download_frame.setFrameShadow(QFrame.Raised) gridLayout_2 = QGridLayout(self.download_frame) self.download_user_lineEdit = QLineEdit(self.download_frame) gridLayout_2.addWidget(self.download_user_lineEdit, 0, 1, 1, 1) self.download_user_label = QLabel(self.download_frame) gridLayout_2.addWidget(self.download_user_label, 0, 0, 1, 1) self.download_pass_label = QLabel(self.download_frame) gridLayout_2.addWidget(self.download_pass_label, 1, 0, 1, 1) self.download_pass_lineEdit = QLineEdit(self.download_frame) self.download_pass_lineEdit.setEchoMode(QLineEdit.Password) gridLayout_2.addWidget(self.download_pass_lineEdit, 1, 1, 1, 1) download_verticalLayout.addWidget(self.download_frame) download_horizontalLayout.addLayout(download_verticalLayout) # select folder -> self.folder_frame = QFrame(self.more_options_tab) self.folder_frame.setFrameShape(QFrame.StyledPanel) self.folder_frame.setFrameShadow(QFrame.Raised) gridLayout_3 = QGridLayout(self.folder_frame) self.download_folder_lineEdit = QLineEdit(self.folder_frame) gridLayout_3.addWidget(self.download_folder_lineEdit, 2, 0, 1, 1) self.folder_pushButton = QPushButton(self.folder_frame) gridLayout_3.addWidget(self.folder_pushButton, 3, 0, 1, 1) self.folder_pushButton.setIcon(QIcon(icons + 'folder')) self.folder_label = QLabel(self.folder_frame) self.folder_label.setAlignment(QtCore.Qt.AlignCenter) gridLayout_3.addWidget(self.folder_label, 1, 0, 1, 1) download_horizontalLayout.addWidget(self.folder_frame) more_options_tab_verticalLayout.addLayout(download_horizontalLayout) # start time -> time_limit_horizontalLayout = QHBoxLayout() time_limit_horizontalLayout.setContentsMargins(-1, 10, -1, -1) start_verticalLayout = QVBoxLayout() self.start_checkBox = QCheckBox(self.more_options_tab) start_verticalLayout.addWidget(self.start_checkBox) self.start_frame = QFrame(self.more_options_tab) self.start_frame.setFrameShape(QFrame.StyledPanel) self.start_frame.setFrameShadow(QFrame.Raised) horizontalLayout_5 = QHBoxLayout(self.start_frame) self.start_time_qDataTimeEdit = QDateTimeEdit(self.start_frame) self.start_time_qDataTimeEdit.setDisplayFormat('H:mm') horizontalLayout_5.addWidget(self.start_time_qDataTimeEdit) start_verticalLayout.addWidget(self.start_frame) time_limit_horizontalLayout.addLayout(start_verticalLayout) # end time -> end_verticalLayout = QVBoxLayout() self.end_checkBox = QCheckBox(self.more_options_tab) end_verticalLayout.addWidget(self.end_checkBox) self.end_frame = QFrame(self.more_options_tab) self.end_frame.setFrameShape(QFrame.StyledPanel) self.end_frame.setFrameShadow(QFrame.Raised) horizontalLayout_6 = QHBoxLayout(self.end_frame) self.end_time_qDateTimeEdit = QDateTimeEdit(self.end_frame) self.end_time_qDateTimeEdit.setDisplayFormat('H:mm') horizontalLayout_6.addWidget(self.end_time_qDateTimeEdit) end_verticalLayout.addWidget(self.end_frame) time_limit_horizontalLayout.addLayout(end_verticalLayout) # limit Speed -> limit_verticalLayout = QVBoxLayout() self.limit_checkBox = QCheckBox(self.more_options_tab) limit_verticalLayout.addWidget(self.limit_checkBox) self.limit_frame = QFrame(self.more_options_tab) self.limit_frame.setFrameShape(QFrame.StyledPanel) self.limit_frame.setFrameShadow(QFrame.Raised) horizontalLayout_4 = QHBoxLayout(self.limit_frame) self.limit_spinBox = QDoubleSpinBox(self.limit_frame) self.limit_spinBox.setMinimum(1) self.limit_spinBox.setMaximum(1023) horizontalLayout_4.addWidget(self.limit_spinBox) self.limit_comboBox = QComboBox(self.limit_frame) self.limit_comboBox.addItem("") self.limit_comboBox.addItem("") horizontalLayout_4.addWidget(self.limit_comboBox) limit_verticalLayout.addWidget(self.limit_frame) time_limit_horizontalLayout.addLayout(limit_verticalLayout) more_options_tab_verticalLayout.addLayout(time_limit_horizontalLayout) # number of connections -> connections_horizontalLayout = QHBoxLayout() connections_horizontalLayout.setContentsMargins(-1, 10, -1, -1) self.connections_frame = QFrame(self.more_options_tab) self.connections_frame.setFrameShape(QFrame.StyledPanel) self.connections_frame.setFrameShadow(QFrame.Raised) horizontalLayout_3 = QHBoxLayout(self.connections_frame) self.connections_label = QLabel(self.connections_frame) horizontalLayout_3.addWidget(self.connections_label) self.connections_spinBox = QSpinBox(self.connections_frame) self.connections_spinBox.setMinimum(1) self.connections_spinBox.setMaximum(16) self.connections_spinBox.setProperty("value", 16) horizontalLayout_3.addWidget(self.connections_spinBox) connections_horizontalLayout.addWidget(self.connections_frame) connections_horizontalLayout.addStretch(1) more_options_tab_verticalLayout.addLayout(connections_horizontalLayout) more_options_tab_verticalLayout.addStretch(1) self.add_link_tabWidget.addTab(self.more_options_tab, '') # advance options self.advance_options_tab = QWidget(self) advance_options_tab_verticalLayout = QVBoxLayout(self.advance_options_tab) # referer referer_horizontalLayout = QHBoxLayout() self.referer_label = QLabel(self.advance_options_tab) referer_horizontalLayout.addWidget(self.referer_label) self.referer_lineEdit = QLineEdit(self.advance_options_tab) referer_horizontalLayout.addWidget(self.referer_lineEdit) advance_options_tab_verticalLayout.addLayout(referer_horizontalLayout) # header header_horizontalLayout = QHBoxLayout() self.header_label = QLabel(self.advance_options_tab) header_horizontalLayout.addWidget(self.header_label) self.header_lineEdit = QLineEdit(self.advance_options_tab) header_horizontalLayout.addWidget(self.header_lineEdit) advance_options_tab_verticalLayout.addLayout(header_horizontalLayout) # user_agent user_agent_horizontalLayout = QHBoxLayout() self.user_agent_label = QLabel(self.advance_options_tab) user_agent_horizontalLayout.addWidget(self.user_agent_label) self.user_agent_lineEdit = QLineEdit(self.advance_options_tab) user_agent_horizontalLayout.addWidget(self.user_agent_lineEdit) advance_options_tab_verticalLayout.addLayout(user_agent_horizontalLayout) # load_cookies load_cookies_horizontalLayout = QHBoxLayout() self.load_cookies_label = QLabel(self.advance_options_tab) load_cookies_horizontalLayout.addWidget(self.load_cookies_label) self.load_cookies_lineEdit = QLineEdit(self.advance_options_tab) load_cookies_horizontalLayout.addWidget(self.load_cookies_lineEdit) advance_options_tab_verticalLayout.addLayout(load_cookies_horizontalLayout) advance_options_tab_verticalLayout.addStretch(1) self.add_link_tabWidget.addTab(self.advance_options_tab, '') # ok cancel download_later buttons -> buttons_horizontalLayout = QHBoxLayout() buttons_horizontalLayout.addStretch(1) self.download_later_pushButton = QPushButton(self) self.download_later_pushButton.setIcon(QIcon(icons + 'stop')) self.cancel_pushButton = QPushButton(self) self.cancel_pushButton.setIcon(QIcon(icons + 'remove')) self.ok_pushButton = QPushButton(self) self.ok_pushButton.setIcon(QIcon(icons + 'ok')) buttons_horizontalLayout.addWidget(self.download_later_pushButton) buttons_horizontalLayout.addWidget(self.cancel_pushButton) buttons_horizontalLayout.addWidget(self.ok_pushButton) window_verticalLayout.addLayout(buttons_horizontalLayout) self.setLayout(window_verticalLayout) # labels -> self.setWindowTitle(QCoreApplication.translate("addlink_ui_tr", "Enter Your Link")) self.link_label.setText(QCoreApplication.translate("addlink_ui_tr", "Download Link: ")) self.add_queue_label.setText(QCoreApplication.translate("addlink_ui_tr", "Add to category: ")) self.change_name_checkBox.setText(QCoreApplication.translate("addlink_ui_tr", "Change File Name: ")) self.detect_proxy_pushButton.setText(QCoreApplication.translate("addlink_ui_tr", "Detect system proxy setting")) self.proxy_checkBox.setText(QCoreApplication.translate("addlink_ui_tr", "Proxy")) self.proxy_pass_label.setText(QCoreApplication.translate("addlink_ui_tr", "Proxy PassWord: "******"addlink_ui_tr", "IP: ")) self.proxy_user_label.setText(QCoreApplication.translate("addlink_ui_tr", "Proxy UserName: "******"addlink_ui_tr", "Port:")) self.download_checkBox.setText(QCoreApplication.translate("addlink_ui_tr", "Download UserName and PassWord")) self.download_user_label.setText(QCoreApplication.translate("addlink_ui_tr", "Download UserName: "******"addlink_ui_tr", "Download PassWord: "******"addlink_ui_tr", "Change Download Folder")) self.folder_label.setText(QCoreApplication.translate("addlink_ui_tr", "Download Folder: ")) self.start_checkBox.setText(QCoreApplication.translate("addlink_ui_tr", "Start Time")) self.end_checkBox.setText(QCoreApplication.translate("addlink_ui_tr", "End Time")) self.limit_checkBox.setText(QCoreApplication.translate("addlink_ui_tr", "Limit Speed")) self.limit_comboBox.setItemText(0, "KiB/s") self.limit_comboBox.setItemText(1, "MiB/s") self.connections_label.setText(QCoreApplication.translate("addlink_ui_tr", "Number Of Connections:")) self.cancel_pushButton.setText(QCoreApplication.translate("addlink_ui_tr", "Cancel")) self.ok_pushButton.setText(QCoreApplication.translate("addlink_ui_tr", "OK")) self.download_later_pushButton.setText(QCoreApplication.translate("addlink_ui_tr", "Download later")) self.add_link_tabWidget.setTabText(self.add_link_tabWidget.indexOf( self.link_tab), QCoreApplication.translate("addlink_ui_tr", "Link")) self.add_link_tabWidget.setTabText(self.add_link_tabWidget.indexOf( self.proxy_tab), QCoreApplication.translate("addlink_ui_tr", "Proxy")) self.add_link_tabWidget.setTabText(self.add_link_tabWidget.indexOf( self.more_options_tab), QCoreApplication.translate("addlink_ui_tr", "More Options")) self.add_link_tabWidget.setTabText(self.add_link_tabWidget.indexOf( self.advance_options_tab), QCoreApplication.translate("addlink_ui_tr", "Advanced Options")) self.referer_label.setText(QCoreApplication.translate("addlink_ui_tr", 'Referrer: ')) self.header_label.setText(QCoreApplication.translate("addlink_ui_tr", 'Header: ')) self.load_cookies_label.setText(QCoreApplication.translate("addlink_ui_tr", 'Load cookies: ')) self.user_agent_label.setText(QCoreApplication.translate("addlink_ui_tr", 'User agent: '))
class Setting_Ui(QWidget): def __init__(self, persepolis_setting): super().__init__() icon = QIcon() self.persepolis_setting = persepolis_setting # add support for other languages locale = str(self.persepolis_setting.value('settings/locale')) QLocale.setDefault(QLocale(locale)) self.translator = QTranslator() if self.translator.load(':/translations/locales/ui_' + locale, 'ts'): QCoreApplication.installTranslator(self.translator) self.setWindowIcon( QIcon.fromTheme('persepolis', QIcon(':/persepolis.svg'))) self.setWindowTitle( QCoreApplication.translate("setting_ui_tr", 'Preferences')) # set ui direction ui_direction = self.persepolis_setting.value('ui_direction') if ui_direction == 'rtl': self.setLayoutDirection(Qt.RightToLeft) elif ui_direction in 'ltr': self.setLayoutDirection(Qt.LeftToRight) global icons icons = ':/' + str( self.persepolis_setting.value('settings/icons')) + '/' # main layout window_verticalLayout = QVBoxLayout(self) # setting_tabWidget self.setting_tabWidget = QTabWidget(self) # download_options_tab self.download_options_tab = QWidget() download_options_tab_verticalLayout = QVBoxLayout( self.download_options_tab) download_options_tab_verticalLayout.setContentsMargins(21, 21, 0, 0) # tries tries_horizontalLayout = QHBoxLayout() self.tries_label = QLabel(self.download_options_tab) tries_horizontalLayout.addWidget(self.tries_label) self.tries_spinBox = QSpinBox(self.download_options_tab) self.tries_spinBox.setMinimum(1) tries_horizontalLayout.addWidget(self.tries_spinBox) download_options_tab_verticalLayout.addLayout(tries_horizontalLayout) #wait wait_horizontalLayout = QHBoxLayout() self.wait_label = QLabel(self.download_options_tab) wait_horizontalLayout.addWidget(self.wait_label) self.wait_spinBox = QSpinBox(self.download_options_tab) wait_horizontalLayout.addWidget(self.wait_spinBox) download_options_tab_verticalLayout.addLayout(wait_horizontalLayout) # time_out time_out_horizontalLayout = QHBoxLayout() self.time_out_label = QLabel(self.download_options_tab) time_out_horizontalLayout.addWidget(self.time_out_label) self.time_out_spinBox = QSpinBox(self.download_options_tab) time_out_horizontalLayout.addWidget(self.time_out_spinBox) download_options_tab_verticalLayout.addLayout( time_out_horizontalLayout) # connections connections_horizontalLayout = QHBoxLayout() self.connections_label = QLabel(self.download_options_tab) connections_horizontalLayout.addWidget(self.connections_label) self.connections_spinBox = QSpinBox(self.download_options_tab) self.connections_spinBox.setMinimum(1) self.connections_spinBox.setMaximum(16) connections_horizontalLayout.addWidget(self.connections_spinBox) download_options_tab_verticalLayout.addLayout( connections_horizontalLayout) # rpc_port self.rpc_port_label = QLabel(self.download_options_tab) self.rpc_horizontalLayout = QHBoxLayout() self.rpc_horizontalLayout.addWidget(self.rpc_port_label) self.rpc_port_spinbox = QSpinBox(self.download_options_tab) self.rpc_port_spinbox.setMinimum(1024) self.rpc_port_spinbox.setMaximum(65535) self.rpc_horizontalLayout.addWidget(self.rpc_port_spinbox) download_options_tab_verticalLayout.addLayout( self.rpc_horizontalLayout) # wait_queue wait_queue_horizontalLayout = QHBoxLayout() self.wait_queue_label = QLabel(self.download_options_tab) wait_queue_horizontalLayout.addWidget(self.wait_queue_label) self.wait_queue_time = QDateTimeEdit(self.download_options_tab) self.wait_queue_time.setDisplayFormat('H:mm') wait_queue_horizontalLayout.addWidget(self.wait_queue_time) download_options_tab_verticalLayout.addLayout( wait_queue_horizontalLayout) # change aria2 path aria2_path_verticalLayout = QVBoxLayout() self.aria2_path_checkBox = QCheckBox(self.download_options_tab) aria2_path_verticalLayout.addWidget(self.aria2_path_checkBox) aria2_path_horizontalLayout = QHBoxLayout() self.aria2_path_lineEdit = QLineEdit(self.download_options_tab) aria2_path_horizontalLayout.addWidget(self.aria2_path_lineEdit) self.aria2_path_pushButton = QPushButton(self.download_options_tab) aria2_path_horizontalLayout.addWidget(self.aria2_path_pushButton) aria2_path_verticalLayout.addLayout(aria2_path_horizontalLayout) download_options_tab_verticalLayout.addLayout( aria2_path_verticalLayout) download_options_tab_verticalLayout.addStretch(1) self.setting_tabWidget.addTab(self.download_options_tab, "") # save_as_tab self.save_as_tab = QWidget() save_as_tab_verticalLayout = QVBoxLayout(self.save_as_tab) save_as_tab_verticalLayout.setContentsMargins(20, 30, 0, 0) # download_folder self.download_folder_horizontalLayout = QHBoxLayout() self.download_folder_label = QLabel(self.save_as_tab) self.download_folder_horizontalLayout.addWidget( self.download_folder_label) self.download_folder_lineEdit = QLineEdit(self.save_as_tab) self.download_folder_horizontalLayout.addWidget( self.download_folder_lineEdit) self.download_folder_pushButton = QPushButton(self.save_as_tab) self.download_folder_horizontalLayout.addWidget( self.download_folder_pushButton) save_as_tab_verticalLayout.addLayout( self.download_folder_horizontalLayout) # temp_download_folder self.temp_horizontalLayout = QHBoxLayout() self.temp_download_label = QLabel(self.save_as_tab) self.temp_horizontalLayout.addWidget(self.temp_download_label) self.temp_download_lineEdit = QLineEdit(self.save_as_tab) self.temp_horizontalLayout.addWidget(self.temp_download_lineEdit) self.temp_download_pushButton = QPushButton(self.save_as_tab) self.temp_horizontalLayout.addWidget(self.temp_download_pushButton) save_as_tab_verticalLayout.addLayout(self.temp_horizontalLayout) # create subfolder self.subfolder_checkBox = QCheckBox(self.save_as_tab) save_as_tab_verticalLayout.addWidget(self.subfolder_checkBox) save_as_tab_verticalLayout.addStretch(1) self.setting_tabWidget.addTab(self.save_as_tab, "") # notifications_tab self.notifications_tab = QWidget() notification_tab_verticalLayout = QVBoxLayout(self.notifications_tab) notification_tab_verticalLayout.setContentsMargins(21, 21, 0, 0) self.enable_notifications_checkBox = QCheckBox(self.notifications_tab) notification_tab_verticalLayout.addWidget( self.enable_notifications_checkBox) self.sound_frame = QFrame(self.notifications_tab) self.sound_frame.setFrameShape(QFrame.StyledPanel) self.sound_frame.setFrameShadow(QFrame.Raised) verticalLayout = QVBoxLayout(self.sound_frame) self.volume_label = QLabel(self.sound_frame) verticalLayout.addWidget(self.volume_label) self.volume_dial = QDial(self.sound_frame) self.volume_dial.setProperty("value", 100) verticalLayout.addWidget(self.volume_dial) notification_tab_verticalLayout.addWidget(self.sound_frame) # message_notification message_notification_horizontalLayout = QHBoxLayout() self.notification_label = QLabel(self.notifications_tab) message_notification_horizontalLayout.addWidget( self.notification_label) self.notification_comboBox = QComboBox(self.notifications_tab) message_notification_horizontalLayout.addWidget( self.notification_comboBox) notification_tab_verticalLayout.addLayout( message_notification_horizontalLayout) notification_tab_verticalLayout.addStretch(1) self.setting_tabWidget.addTab(self.notifications_tab, "") # style_tab self.style_tab = QWidget() style_tab_verticalLayout = QVBoxLayout(self.style_tab) style_tab_verticalLayout.setContentsMargins(21, 21, 0, 0) # style style_horizontalLayout = QHBoxLayout() self.style_label = QLabel(self.style_tab) style_horizontalLayout.addWidget(self.style_label) self.style_comboBox = QComboBox(self.style_tab) style_horizontalLayout.addWidget(self.style_comboBox) style_tab_verticalLayout.addLayout(style_horizontalLayout) # language language_horizontalLayout = QHBoxLayout() self.lang_label = QLabel(self.style_tab) language_horizontalLayout.addWidget(self.lang_label) self.lang_comboBox = QComboBox(self.style_tab) language_horizontalLayout.addWidget(self.lang_comboBox) style_tab_verticalLayout.addLayout(language_horizontalLayout) language_horizontalLayout = QHBoxLayout() self.lang_label.setText( QCoreApplication.translate("setting_ui_tr", "Language:")) # color scheme self.color_label = QLabel(self.style_tab) language_horizontalLayout.addWidget(self.color_label) self.color_comboBox = QComboBox(self.style_tab) language_horizontalLayout.addWidget(self.color_comboBox) style_tab_verticalLayout.addLayout(language_horizontalLayout) # icons icons_horizontalLayout = QHBoxLayout() self.icon_label = QLabel(self.style_tab) icons_horizontalLayout.addWidget(self.icon_label) self.icon_comboBox = QComboBox(self.style_tab) icons_horizontalLayout.addWidget(self.icon_comboBox) style_tab_verticalLayout.addLayout(icons_horizontalLayout) self.icons_size_horizontalLayout = QHBoxLayout() self.icons_size_label = QLabel(self.style_tab) self.icons_size_horizontalLayout.addWidget(self.icons_size_label) self.icons_size_comboBox = QComboBox(self.style_tab) self.icons_size_horizontalLayout.addWidget(self.icons_size_comboBox) style_tab_verticalLayout.addLayout(self.icons_size_horizontalLayout) # font font_horizontalLayout = QHBoxLayout() self.font_checkBox = QCheckBox(self.style_tab) font_horizontalLayout.addWidget(self.font_checkBox) self.fontComboBox = QFontComboBox(self.style_tab) font_horizontalLayout.addWidget(self.fontComboBox) self.font_size_label = QLabel(self.style_tab) font_horizontalLayout.addWidget(self.font_size_label) self.font_size_spinBox = QSpinBox(self.style_tab) self.font_size_spinBox.setMinimum(1) font_horizontalLayout.addWidget(self.font_size_spinBox) style_tab_verticalLayout.addLayout(font_horizontalLayout) self.setting_tabWidget.addTab(self.style_tab, "") window_verticalLayout.addWidget(self.setting_tabWidget) # start persepolis in system tray if browser executed self.start_persepolis_if_browser_executed_checkBox = QCheckBox( self.style_tab) style_tab_verticalLayout.addWidget( self.start_persepolis_if_browser_executed_checkBox) # hide window if close button clicked self.hide_window_checkBox = QCheckBox(self.style_tab) style_tab_verticalLayout.addWidget(self.hide_window_checkBox) # Enable system tray icon self.enable_system_tray_checkBox = QCheckBox(self.style_tab) style_tab_verticalLayout.addWidget(self.enable_system_tray_checkBox) # after_download dialog self.after_download_checkBox = QCheckBox() style_tab_verticalLayout.addWidget(self.after_download_checkBox) # show_menubar_checkbox self.show_menubar_checkbox = QCheckBox() style_tab_verticalLayout.addWidget(self.show_menubar_checkbox) # show_sidepanel_checkbox self.show_sidepanel_checkbox = QCheckBox() style_tab_verticalLayout.addWidget(self.show_sidepanel_checkbox) # hide progress window self.show_progress_window_checkbox = QCheckBox() style_tab_verticalLayout.addWidget(self.show_progress_window_checkbox) # add persepolis to startup self.startup_checkbox = QCheckBox() style_tab_verticalLayout.addWidget(self.startup_checkbox) # keep system awake self.keep_awake_checkBox = QCheckBox() style_tab_verticalLayout.addWidget(self.keep_awake_checkBox) style_tab_verticalLayout.addStretch(1) # columns_tab self.columns_tab = QWidget() columns_tab_verticalLayout = QVBoxLayout(self.columns_tab) columns_tab_verticalLayout.setContentsMargins(21, 21, 0, 0) # creating checkBox for columns self.show_column_label = QLabel() self.column0_checkBox = QCheckBox() self.column1_checkBox = QCheckBox() self.column2_checkBox = QCheckBox() self.column3_checkBox = QCheckBox() self.column4_checkBox = QCheckBox() self.column5_checkBox = QCheckBox() self.column6_checkBox = QCheckBox() self.column7_checkBox = QCheckBox() self.column10_checkBox = QCheckBox() self.column11_checkBox = QCheckBox() self.column12_checkBox = QCheckBox() columns_tab_verticalLayout.addWidget(self.show_column_label) columns_tab_verticalLayout.addWidget(self.column0_checkBox) columns_tab_verticalLayout.addWidget(self.column1_checkBox) columns_tab_verticalLayout.addWidget(self.column2_checkBox) columns_tab_verticalLayout.addWidget(self.column3_checkBox) columns_tab_verticalLayout.addWidget(self.column4_checkBox) columns_tab_verticalLayout.addWidget(self.column5_checkBox) columns_tab_verticalLayout.addWidget(self.column6_checkBox) columns_tab_verticalLayout.addWidget(self.column7_checkBox) columns_tab_verticalLayout.addWidget(self.column10_checkBox) columns_tab_verticalLayout.addWidget(self.column11_checkBox) columns_tab_verticalLayout.addWidget(self.column12_checkBox) columns_tab_verticalLayout.addStretch(1) self.setting_tabWidget.addTab(self.columns_tab, '') # video_finder_tab self.video_finder_tab = QWidget() video_finder_layout = QVBoxLayout(self.video_finder_tab) video_finder_layout.setContentsMargins(21, 21, 0, 0) video_finder_tab_verticalLayout = QVBoxLayout() max_links_horizontalLayout = QHBoxLayout() # max_links_label self.max_links_label = QLabel(self.video_finder_tab) max_links_horizontalLayout.addWidget(self.max_links_label) # max_links_spinBox self.max_links_spinBox = QSpinBox(self.video_finder_tab) self.max_links_spinBox.setMinimum(1) self.max_links_spinBox.setMaximum(16) max_links_horizontalLayout.addWidget(self.max_links_spinBox) video_finder_tab_verticalLayout.addLayout(max_links_horizontalLayout) self.video_finder_dl_path_horizontalLayout = QHBoxLayout() self.video_finder_frame = QFrame(self.video_finder_tab) self.video_finder_frame.setLayout(video_finder_tab_verticalLayout) video_finder_tab_verticalLayout.addStretch(1) video_finder_layout.addWidget(self.video_finder_frame) self.setting_tabWidget.addTab(self.video_finder_tab, "") # shortcut tab self.shortcut_tab = QWidget() shortcut_tab_verticalLayout = QVBoxLayout(self.shortcut_tab) shortcut_tab_verticalLayout.setContentsMargins(21, 21, 0, 0) # shortcut_table self.shortcut_table = QTableWidget(self) self.shortcut_table.setColumnCount(2) self.shortcut_table.setSelectionBehavior(QAbstractItemView.SelectRows) self.shortcut_table.setSelectionMode(QAbstractItemView.SingleSelection) self.shortcut_table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.shortcut_table.verticalHeader().hide() shortcut_table_header = [ QCoreApplication.translate("setting_ui_tr", 'Action'), QCoreApplication.translate("setting_ui_tr", 'Shortcut') ] self.shortcut_table.setHorizontalHeaderLabels(shortcut_table_header) shortcut_tab_verticalLayout.addWidget(self.shortcut_table) self.setting_tabWidget.addTab( self.shortcut_tab, QCoreApplication.translate("setting_ui_tr", "Shortcuts")) # Actions actions_list = [ QCoreApplication.translate('setting_ui_tr', 'Quit'), QCoreApplication.translate( 'setting_ui_tr', 'Minimize main window to the tray icon'), QCoreApplication.translate('setting_ui_tr', 'Remove download items'), QCoreApplication.translate('setting_ui_tr', 'Delete download items'), QCoreApplication.translate('setting_ui_tr', 'Move up selected items'), QCoreApplication.translate('setting_ui_tr', 'Move down selected items'), QCoreApplication.translate('setting_ui_tr', 'Add new download link'), QCoreApplication.translate('setting_ui_tr', 'Add new Video link'), QCoreApplication.translate('setting_ui_tr', 'Import links from text file') ] # add actions to the shortcut_table j = 0 for action in actions_list: item = QTableWidgetItem(str(action)) # align center item.setTextAlignment(0x0004 | 0x0080) # insert item in shortcut_table self.shortcut_table.insertRow(j) self.shortcut_table.setItem(j, 0, item) j = j + 1 self.shortcut_table.resizeColumnsToContents() # window buttons buttons_horizontalLayout = QHBoxLayout() buttons_horizontalLayout.addStretch(1) self.defaults_pushButton = QPushButton(self) buttons_horizontalLayout.addWidget(self.defaults_pushButton) self.cancel_pushButton = QPushButton(self) self.cancel_pushButton.setIcon(QIcon(icons + 'remove')) buttons_horizontalLayout.addWidget(self.cancel_pushButton) self.ok_pushButton = QPushButton(self) self.ok_pushButton.setIcon(QIcon(icons + 'ok')) buttons_horizontalLayout.addWidget(self.ok_pushButton) window_verticalLayout.addLayout(buttons_horizontalLayout) # set style_tab for default self.setting_tabWidget.setCurrentIndex(3) # labels and translations self.setWindowTitle( QCoreApplication.translate("setting_ui_tr", "Preferences")) self.tries_label.setToolTip( QCoreApplication.translate( "setting_ui_tr", "<html><head/><body><p>Set number of tries if download failed.</p></body></html>" )) self.tries_label.setText( QCoreApplication.translate("setting_ui_tr", "Number of tries: ")) self.tries_spinBox.setToolTip( QCoreApplication.translate( "setting_ui_tr", "<html><head/><body><p>Set number of tries if download failed.</p></body></html>" )) self.wait_label.setToolTip( QCoreApplication.translate( "setting_ui_tr", "<html><head/><body><p>Set the seconds to wait between retries. Download manager will retry downloads when the HTTP server returns a 503 response.</p></body></html>" )) self.wait_label.setText( QCoreApplication.translate("setting_ui_tr", "Wait between retries (seconds): ")) self.wait_spinBox.setToolTip( QCoreApplication.translate( "setting_ui_tr", "<html><head/><body><p>Set the seconds to wait between retries. Download manager will retry downloads when the HTTP server returns a 503 response.</p></body></html>" )) self.time_out_label.setToolTip( QCoreApplication.translate( "setting_ui_tr", "<html><head/><body><p>Set timeout in seconds. </p></body></html>" )) self.time_out_label.setText( QCoreApplication.translate("setting_ui_tr", "Timeout (seconds): ")) self.time_out_spinBox.setToolTip( QCoreApplication.translate( "setting_ui_tr", "<html><head/><body><p>Set timeout in seconds. </p></body></html>" )) self.connections_label.setToolTip( QCoreApplication.translate( "setting_ui_tr", "<html><head/><body><p>Using multiple connections can help speed up your download.</p></body></html>" )) self.connections_label.setText( QCoreApplication.translate("setting_ui_tr", "Number of connections: ")) self.connections_spinBox.setToolTip( QCoreApplication.translate( "setting_ui_tr", "<html><head/><body><p>Using multiple connections can help speed up your download.</p></body></html>" )) self.rpc_port_label.setText( QCoreApplication.translate("setting_ui_tr", "RPC port number: ")) self.rpc_port_spinbox.setToolTip( QCoreApplication.translate( "setting_ui_tr", "<html><head/><body><p> Specify a port number for JSON-RPC/XML-RPC server to listen to. Possible Values: 1024 - 65535 Default: 6801 </p></body></html>" )) self.wait_queue_label.setText( QCoreApplication.translate( "setting_ui_tr", 'Wait between every downloads in queue:')) self.aria2_path_checkBox.setText( QCoreApplication.translate("setting_ui_tr", 'Change Aria2 default path')) self.aria2_path_pushButton.setText( QCoreApplication.translate("setting_ui_tr", 'Change')) aria2_path_tooltip = QCoreApplication.translate( "setting_ui_tr", "<html><head/><body><p>Attention: Wrong path may have caused problem! Do it carefully or don't change default setting!</p></body></html>" ) self.aria2_path_checkBox.setToolTip(aria2_path_tooltip) self.aria2_path_lineEdit.setToolTip(aria2_path_tooltip) self.aria2_path_pushButton.setToolTip(aria2_path_tooltip) self.setting_tabWidget.setTabText( self.setting_tabWidget.indexOf(self.download_options_tab), QCoreApplication.translate("setting_ui_tr", "Download Options")) self.download_folder_label.setText( QCoreApplication.translate("setting_ui_tr", "Download Folder: ")) self.download_folder_pushButton.setText( QCoreApplication.translate("setting_ui_tr", "Change")) self.temp_download_label.setText( QCoreApplication.translate("setting_ui_tr", "Temporary Download Folder: ")) self.temp_download_pushButton.setText( QCoreApplication.translate("setting_ui_tr", "Change")) self.subfolder_checkBox.setText( QCoreApplication.translate( "setting_ui_tr", "Create subfolders for Music,Videos,... in default download folder" )) self.setting_tabWidget.setTabText( self.setting_tabWidget.indexOf(self.save_as_tab), QCoreApplication.translate("setting_ui_tr", "Save as")) self.enable_notifications_checkBox.setText( QCoreApplication.translate("setting_ui_tr", "Enable notification sounds")) self.volume_label.setText( QCoreApplication.translate("setting_ui_tr", "Volume: ")) self.setting_tabWidget.setTabText( self.setting_tabWidget.indexOf(self.notifications_tab), QCoreApplication.translate("setting_ui_tr", "Notifications")) self.style_label.setText( QCoreApplication.translate("setting_ui_tr", "Style: ")) self.color_label.setText( QCoreApplication.translate("setting_ui_tr", "Color scheme: ")) self.icon_label.setText( QCoreApplication.translate("setting_ui_tr", "Icons: ")) self.icons_size_label.setText( QCoreApplication.translate("setting_ui_tr", "Toolbar's icons size: ")) self.notification_label.setText( QCoreApplication.translate("setting_ui_tr", "Notification type: ")) self.font_checkBox.setText( QCoreApplication.translate("setting_ui_tr", "Font: ")) self.font_size_label.setText( QCoreApplication.translate("setting_ui_tr", "Size: ")) self.hide_window_checkBox.setText( QCoreApplication.translate( "setting_ui_tr", "Hide main window if close button clicked.")) self.hide_window_checkBox.setToolTip( QCoreApplication.translate( "setting_ui_tr", "<html><head/><body><p>This feature may not work in your operating system.</p></body></html>" )) self.start_persepolis_if_browser_executed_checkBox.setText( QCoreApplication.translate( 'setting_ui_tr', 'Start Persepolis in system tray, If browser is executed.')) self.enable_system_tray_checkBox.setText( QCoreApplication.translate("setting_ui_tr", "Enable system tray icon.")) self.after_download_checkBox.setText( QCoreApplication.translate( "setting_ui_tr", "Show download complete dialog when download has finished.")) self.show_menubar_checkbox.setText( QCoreApplication.translate("setting_ui_tr", "Show menubar.")) self.show_sidepanel_checkbox.setText( QCoreApplication.translate("setting_ui_tr", "Show side panel.")) self.show_progress_window_checkbox.setText( QCoreApplication.translate("setting_ui_tr", "Show download's progress window")) self.startup_checkbox.setText( QCoreApplication.translate("setting_ui_tr", "Run Persepolis at startup")) self.keep_awake_checkBox.setText( QCoreApplication.translate("setting_ui_tr", "Keep system awake!")) self.keep_awake_checkBox.setToolTip( QCoreApplication.translate( "setting_ui_tr", "<html><head/><body><p>This option is preventing system from going to sleep.\ This is necessary if your power manager is suspending system automatically. </p></body></html>" )) self.wait_queue_time.setToolTip( QCoreApplication.translate( "setting_ui_tr", "<html><head/><body><p>Format HH:MM</p></body></html>")) self.setting_tabWidget.setTabText( self.setting_tabWidget.indexOf(self.style_tab), QCoreApplication.translate("setting_ui_tr", "Preferences")) # columns_tab self.show_column_label.setText( QCoreApplication.translate("setting_ui_tr", 'Show this columns:')) self.column0_checkBox.setText( QCoreApplication.translate("setting_ui_tr", 'File Name')) self.column1_checkBox.setText( QCoreApplication.translate("setting_ui_tr", 'Status')) self.column2_checkBox.setText( QCoreApplication.translate("setting_ui_tr", 'Size')) self.column3_checkBox.setText( QCoreApplication.translate("setting_ui_tr", 'Downloaded')) self.column4_checkBox.setText( QCoreApplication.translate("setting_ui_tr", 'Percentage')) self.column5_checkBox.setText( QCoreApplication.translate("setting_ui_tr", 'Connections')) self.column6_checkBox.setText( QCoreApplication.translate("setting_ui_tr", 'Transfer rate')) self.column7_checkBox.setText( QCoreApplication.translate("setting_ui_tr", 'Estimated time left')) self.column10_checkBox.setText( QCoreApplication.translate("setting_ui_tr", 'First try date')) self.column11_checkBox.setText( QCoreApplication.translate("setting_ui_tr", 'Last try date')) self.column12_checkBox.setText( QCoreApplication.translate("setting_ui_tr", 'Category')) self.setting_tabWidget.setTabText( self.setting_tabWidget.indexOf(self.columns_tab), QCoreApplication.translate("setting_ui_tr", "Columns customization")) # Video Finder options tab self.setting_tabWidget.setTabText( self.setting_tabWidget.indexOf(self.video_finder_tab), QCoreApplication.translate("setting_ui_tr", "Video Finder Options")) self.max_links_label.setText( QCoreApplication.translate( "setting_ui_tr", 'Maximum number of links to capture:<br/>' '<small>(If browser sends multiple video links at a time)</small>' )) # window buttons self.defaults_pushButton.setText( QCoreApplication.translate("setting_ui_tr", "Defaults")) self.cancel_pushButton.setText( QCoreApplication.translate("setting_ui_tr", "Cancel")) self.ok_pushButton.setText( QCoreApplication.translate("setting_ui_tr", "OK"))
class EditorMainWindow(QMainWindow): def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.ui = Ui_ScriptEditor() self.ui.setupUi(self) #self.ui.actionExit.triggered.connect(self.exit) self.splitter = QSplitter(Qt.Vertical, self) self.setCentralWidget(self.splitter) self.edit_tab = QTabWidget(self.splitter) self.console_tab = QTabWidget(self.splitter) self.py_console = PythonConsole(self.console_tab) self.console_tab.addTab(self.py_console, "&Python console") self.js_console = QtQmlConsole(self.console_tab) self.console_tab.addTab(self.js_console, "&QtQml console") self.editors = [] self.on_actionNewPython_triggered() @pyqtSlot() def closeEvent(self, event): while(self.editors.__len__()): edit = self.edit_tab.currentWidget() if edit: if(edit.isModified()): saveBox = SaveDialog("You have unsaved script. Save it now?") prompt = saveBox.exec_() if(prompt == QMessageBox.Save): event.ignore() self.save(True) elif(prompt == QMessageBox.Cancel): event.ignore() return elif(prompt == QMessageBox.Discard): event.accept() i = self.edit_tab.indexOf(edit) self.edit_tab.removeTab(i) self.editors.remove(edit) event.accept() @pyqtSlot() def on_actionExit_triggered(self): while(self.editors.__len__()): edit = self.edit_tab.currentWidget() if edit: if(edit.isModified()): saveBox = SaveDialog("You have unsaved script. Save it now?") prompt = saveBox.exec_() if(prompt == QMessageBox.Save): self.save(True) elif(prompt == QMessageBox.Cancel): return elif(prompt == QMessageBox.Discard): pass i = self.edit_tab.indexOf(edit) self.edit_tab.removeTab(i) self.editors.remove(edit) self.close() @pyqtSlot() def on_actionNewPython_triggered(self): pyedit = PythonEditorWidget(self.edit_tab) pyedit.setPlainText(template_py) self.edit_tab.addTab(pyedit, "Python") self.edit_tab.setCurrentWidget(pyedit) self.editors.append(pyedit) self.py_console.attach() self.console_tab.setCurrentIndex(0) pyedit.setFocus() pyedit.view.setFocus() @pyqtSlot() def on_actionNewQtQml_triggered(self): jsedit = QtQmlEditorWidget(self.edit_tab) self.edit_tab.addTab(jsedit, "QtQml") self.edit_tab.setCurrentWidget(jsedit) self.editors.append(jsedit) self.js_console.attach() self.console_tab.setCurrentIndex(1) @pyqtSlot() def on_actionClose_triggered(self): edit = self.edit_tab.currentWidget() if edit: if(edit.isModified()): saveBox = SaveDialog("Do you want to save this Script?") prompt = saveBox.exec_() if(prompt == QMessageBox.Save): self.save(True) elif(prompt == QMessageBox.Cancel): return elif(prompt == QMessageBox.Discard): pass i = self.edit_tab.indexOf(edit) self.edit_tab.removeTab(i) self.editors.remove(edit) @pyqtSlot() def on_actionClear_triggered(self): #edit = self.edit_tab.currentWidget() #edit.setPlainText(template_py) self.py_console.clear() @pyqtSlot() def on_actionSave_As_triggered(self): self.save() @pyqtSlot() def on_actionSave_triggered(self): self.save(True) #Path of the script file in each tab will be stored in tabToolTip def save(self, Update = False): edit = self.edit_tab.currentWidget() contents = str(edit.toPlainText()) if((Update == False) or (self.edit_tab.tabText(self.edit_tab.currentIndex()) == "Python") ): #Save in its first invocation and Save As will enter filename = QFileDialog.getSaveFileName(self, "Save File", "", "*.spy") fil = open(filename , 'w') if(filename and self.edit_tab.tabText(self.edit_tab.currentIndex()) == "Python"): #Script hasn't been saved before and user specifies a valid filename self.edit_tab.setTabToolTip(self.edit_tab.currentIndex(), filename+'.spy') self.edit_tab.setTabText(self.edit_tab.currentIndex(), os.path.basename(str(filename+'.spy'))) else: #filename = self.edit_tab.tabText(self.edit_tab.currentIndex()) filename = self.edit_tab.tabToolTip(self.edit_tab.currentIndex()) fil = open( filename , 'w') fil.write(contents) fil.close() edit.setModified(False) @pyqtSlot() def on_actionOpen_triggered(self): filename = QFileDialog.getOpenFileName(self,"Open File","","*.spy") try: fil = open(filename , 'r') except IOError: return code = fil.read() edit = self.edit_tab.currentWidget() self.edit_tab.setTabText(self.edit_tab.currentIndex(), os.path.basename(str(filename))) self.edit_tab.setTabToolTip(self.edit_tab.currentIndex(), filename) edit.setPlainText(code) fil.close() @pyqtSlot() def on_actionRun_triggered(self): self.run() @pyqtSlot() def on_actionRunConsole_triggered(self): self.run(True) def run(self, console=False): edit = self.edit_tab.currentWidget() code = str(edit.toPlainText()) if isinstance(edit, PythonEditorWidget): self.py_console.attach() self.console_tab.setCurrentIndex(0) if console: namespace = self.py_console.namespace else: namespace = {} try: exec code in namespace except Exception as e: traceback.print_exc() try: Scripter.activeWindow.redraw = True Scripter.activeWindow.update() except: pass else: self.js_console.attach() self.console_tab.setCurrentIndex(1) if console: self.js_console.inter.execute(code) else: self.js_console.inter.execute_code(code)
class Window(QMainWindow): def __init__(self): super(Window, self).__init__() screenShape = QDesktopWidget().screenGeometry() SCREEN_WIDTH = screenShape.width() SCREEN_HIGHT = screenShape.height() self.setWindowTitle(APPNAME) self.setWindowIcon(QIcon(ICON)) self.setMinimumWidth(SCREEN_WIDTH // 3) self.setMinimumHeight(SCREEN_HIGHT // 3) self.statusBar = self.statusBar() self.mainMenu = self.menuBar() QApplication.setStyle(QStyleFactory.create(STYLE)) self.iraChache = {} self.mainTab = None self.stringView = None self.asmLinear = None self.hexView = None self.initMenu() self.initToolBar() self.showMaximized() def initMenu(self): names = ['File', 'View', 'Tool'] items = { 'File': [ ('Open', 'Ctrl+O', 'Open file', self.openFile), ('Save', 'Ctrl+S', 'Save file', self.saveFile), ('Save As', 'Ctrl+Shift+S', 'Save file as', self.saveFileAs), ('Quit', 'Ctrl+Q', 'Quit the program', self.closeApp), ], 'View': [ ('Linear Diassembly', 'Ctrl+L', 'Linear Dissembly View', self.openAsmLinearView), ('Asm Graph', 'Ctrl+G', 'Graph View', self.openAsmCFGView), ('IR Linear', 'Ctrl+G', 'IR Linear View', self.openIRLinearView), ('IR Graph', 'Ctrl+G', 'IR Graph View', self.openIRCFGView), ('Hex', 'Ctrl+H', 'Hex View', self.openHexView), ('String', 'Ctrl+L', 'String View', self.openStringView), ], 'Tool': [('Basic Deobfuscate', 'Ctrl+R', "Basic Deobfuscate", self.recoverAlgorithm)] } for name in names: menu = self.mainMenu.addMenu('&' + name) for item, shortcut, status, func in items[name]: menu.addAction( self.createActionWithShortcut(item, shortcut, status, func)) def initToolBar(self): names = ['File Utils', 'View'] items = { 'File Utils': [ ('imgs/open.png', 'Open', 'Open file', self.openFile), ('imgs/save.png', 'Save', 'Save file', self.saveFile), ('imgs/saveas.png', 'Save as', 'Save file as', self.saveFileAs), ], 'View': [ ('imgs/hex.png', 'Hex', 'Hex View', self.openHexView), ('imgs/graph.png', 'Graph', 'Graph View', self.openAsmCFGView), ('imgs/linear.png', 'Linear Disassembly', 'Linear Disassembly View', self.openAsmLinearView), ], } for name in names: toolBar = self.addToolBar(name) for img, desc, status, func in items[name]: toolBar.addAction( self.createActionWithIcon(img, desc, status, func)) def createActionWithShortcut(self, name, shortcut, status, func): """ Tao action gan voi shortcut key. VD: createActionWithShortcut('Quit', 'Ctrl+Q', closeApp) :param name: ten action :param shortcut: phim shortcut gan voi action :param func: ham se chay khi bi click :return: QAction """ action = QAction(name, self) action.setShortcut(shortcut) action.setStatusTip(status) action.triggered.connect(func) return action def createActionWithIcon(self, icon, description, status, func): """ Tao action bieu tuong icon. VD: createActionWithIcon('ifa.png', 'Quit', closeApp) :param icon: ten file icon :param description: text hien thi khi de chuot vao :param func: ham se chay neu icon duoc click :return: QAction """ action = QAction(QIcon(icon), description, self) action.setStatusTip(status) action.triggered.connect(func) return action # ============================================================== def closeApp(self): """ Quit App :return: """ sys.exit() def openFile(self): """" Open File, Load Function to ListFunction and Info :return: """ try: f = open('cache', 'r') dir = f.read() except FileNotFoundError: dir = '' file, _ = QFileDialog.getOpenFileName( self, "Open File", dir, "All File (*);;Python File (*.elf);;PE File (*.exe", options=QFileDialog.DontUseNativeDialog) if file: dir = os.path.dirname(file) open('cache', 'w').write(dir) self.centralWidget = QWidget(self) self.setCentralWidget(self.centralWidget) QVBoxLayout(self.centralWidget) allLayout = self.centralWidget.layout() BinaryAnalysis.init(file) self.outputLog = QTextEdit() self.binInfo = QTextEdit() self.binInfo.setReadOnly(True) self.binInfo.setText(BinaryAnalysis.binaryInfo.info()) self.listFunctions = ListFuncs(BinaryAnalysis.funcs) self.listFunctions.gotoFunc.connect(self.gotoAddress) leftTopBottomSplitter = QSplitter(Qt.Vertical) leftTopBottomSplitter.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) leftTopBottomSplitter.addWidget(self.binInfo) leftTopBottomSplitter.addWidget(self.listFunctions) leftTopBottomSplitter.setStretchFactor(0, 1) leftTopBottomSplitter.setStretchFactor(1, 9) leftRightSplitter = QSplitter() self.mainTab = QTabWidget() self.mainTab.setTabsClosable(True) self.mainTab.tabCloseRequested.connect(self.closeTab) self.mainTab.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.asmLinear = AsmLinear() self.mainTab.addTab(self.asmLinear, "Disassembly") self.asmLinear.focusAddress(BinaryAnalysis.binaryInfo.entryPoint) self.bindAsmLinear() self.hexView = HexView(BinaryAnalysis.rawData) self.mainTab.addTab(self.hexView, "Hex View") self.stringView = StringView(BinaryAnalysis.binaryInfo.strings) self.stringView.clicked.connect(self.gotoAddress) self.mainTab.addTab(self.stringView, "String List") self.importView = ImportView(BinaryAnalysis.binaryInfo.imports) self.importView.clicked.connect(self.gotoLibFunc) self.mainTab.addTab(self.importView, "Imports") self.exportView = ExportView(BinaryAnalysis.binaryInfo.exports) self.exportView.clicked.connect(self.gotoLibFunc) self.mainTab.addTab(self.exportView, "Exports") leftRightSplitter.addWidget(leftTopBottomSplitter) leftRightSplitter.addWidget(self.mainTab) leftRightSplitter.setStretchFactor(0, 2) leftRightSplitter.setStretchFactor(1, 8) topBottomSplitter = QSplitter(Qt.Vertical) topBottomSplitter.addWidget(leftRightSplitter) topBottomSplitter.addWidget(self.outputLog) topBottomSplitter.setStretchFactor(0, 8) topBottomSplitter.setStretchFactor(1, 2) allLayout.addWidget(topBottomSplitter) self.asmLinear.setFocus() def gotoLibFunc(self, name): for func in BinaryAnalysis.funcs: if func.name.endswith(name): self.gotoAsmLinear(func.address) break def bindAsmLinear(self): self.asmLinear.addCFG.connect(self.addAsmCFGView) self.asmLinear.gotoHexView.connect(self.gotoHexView) self.asmLinear.log.connect(self.outputLog.append) self.asmLinear.changedData.connect(self.changeData) self.asmLinear.addIRLinear.connect(self.addIRLinearView) def changeData(self, offset, data): index = self.mainTab.indexOf(self.hexView) if index == -1: self.hexView = HexView(BinaryAnalysis.rawData) self.addNewTab(self.hexView, "Hex View") self.hexView.changeData(offset, data) def addIRLinearView(self, func): from IRAnalysis import IRAnalysis from IRView import IRWidget if func in self.iraChache: if not func.changed: ira = self.iraChache[func] else: func.changed = False ira = IRAnalysis(func.address, func.cfg) self.iraChache[func] = ira else: ira = IRAnalysis(func.address, func.cfg) self.iraChache[func] = ira irLinearView = IRWidget(ira, 0) self.addNewTab(irLinearView, "IR Linear %s" % func.name) def addIRCFGView(self, func): from IRAnalysis import IRAnalysis from IRView import IRWidget if func in self.iraChache: if not func.changed: ira = self.iraChache[func] else: func.changed = False func.ircfg = None func.defUse = None func.ira = None ira = IRAnalysis(func.address, func.cfg) self.iraChache[func] = ira else: ira = IRAnalysis(func.address, func.cfg) self.iraChache[func] = ira irLinearView = IRWidget(ira, 2) self.addNewTab(irLinearView, "IR CFG %s" % func.name) def addAsmCFGView(self, line): for i in range(self.mainTab.count()): widget = self.mainTab.widget(i) if isinstance(widget, AsmCFGView): if line.func == widget.func: if not line.func.changed: self.mainTab.setCurrentIndex(i) return else: self.mainTab.removeTab(i) line.func.changed = False line.func.ircfg = None line.func.ira = None line.func.defUse = None if line.func in self.iraChache: del self.iraChache[line.func] break asmCFGView = AsmCFGView(line.func) asmCFGView.gotoAsmLinear.connect(self.gotoAsmLinear) asmCFGView.changeCFG.connect(self.replaceAsmCFG) asmCFGView.gotoHexView.connect(self.gotoHexView) asmCFGView.gotoIRCFG.connect(self.addIRCFGView) asmCFGView.gotoAddress.connect(self.gotoAsmLinear) asmCFGView.log.connect(self.outputLog.append) indexes = self.asmLinear.selectedIndexes() for index in indexes: item = self.asmLinear.getItemFormIndex(index) if hasattr(item, 'instr'): asmCFGView.selectAddress(item.instr.offset, False, False) asmCFGView.selectAddress(line.address, True, False) self.addNewTab(asmCFGView, "AsmCFG") def gotoAsmLinear(self, address): index = self.mainTab.indexOf(self.asmLinear) if index == -1: self.asmLinear = AsmLinear() self.bindAsmLinear() self.addNewTab(self.asmLinear, "Disassmbly") if address in self.asmLinear.addressMap: self.focusWidgetInTab(self.asmLinear) self.asmLinear.focusAddress(address) self.asmLinear.setFocus() def gotoHexView(self, offset, lenData): index = self.mainTab.indexOf(self.hexView) if index == -1: self.hexView = HexView(BinaryAnalysis.rawData) self.addNewTab(self.hexView, "Hex View") self.hexView.toOffset(offset, lenData) self.focusWidgetInTab(self.hexView) def addNewTab(self, widget, name): index = self.mainTab.currentIndex() self.mainTab.insertTab(index + 1, widget, name) self.mainTab.setCurrentIndex(index + 1) widget.setFocus() def gotoAddress(self, address): from IRView import IRWidget widget = self.getCurrentWidget() if isinstance(widget, AsmCFGView): self.replaceAsmCFG(address) elif isinstance(widget, IRWidget): for func in BinaryAnalysis.funcs: if func.address == address: if widget.viewType == 0: self.addIRLinearView(func) else: self.addIRCFGView(func) self.mainTab.removeTab(self.mainTab.currentIndex() - 1) break elif address in self.asmLinear.addressMap: linearIndex = self.mainTab.indexOf(self.asmLinear) self.mainTab.setCurrentIndex(linearIndex) self.asmLinear.focusAddress(address) self.asmLinear.setFocus() else: hexIndex = self.mainTab.indexOf(self.hexView) self.mainTab.setCurrentIndex(hexIndex) offset = BinaryAnalysis.binaryInfo.getOffsetAtAddress(address) self.hexView.toOffset(offset) self.hexView.setFocus() def replaceAsmCFG(self, address): newFunc = None index = self.mainTab.currentIndex() for func in BinaryAnalysis.funcs: if address == func.address: newFunc = func break if newFunc is not None: asmCFGView = AsmCFGView(newFunc) self.addNewTab(asmCFGView, "AsmCFG") asmCFGView.changeCFG.connect(self.replaceAsmCFG) self.mainTab.removeTab(index) asmCFGView.setFocus() def getCurrentWidget(self): return self.mainTab.currentWidget() def closeTab(self, index): self.mainTab.removeTab(index) self.mainTab.setCurrentIndex(index - 1) self.mainTab.widget(index - 1).setFocus() def focusWidgetInTab(self, widget): index = self.mainTab.indexOf(widget) self.mainTab.setCurrentIndex(index) widget.setFocus() def saveFile(self): if BinaryAnalysis.path is not None: button_pressed = QMessageBox.question( self, 'Save File', "Do you want to save?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if button_pressed == QMessageBox.Yes: f = open(BinaryAnalysis.path, 'wb') f.write(bytearray(BinaryAnalysis.rawData)) f.close() def saveFileAs(self): if BinaryAnalysis.path is not None: name, _ = QFileDialog.getSaveFileName(self, "Save File as") if name: f = open(name, 'wb') f.write(bytearray(BinaryAnalysis.rawData)) f.close() def openAsmLinearView(self): if BinaryAnalysis.path is not None: self.gotoAsmLinear(BinaryAnalysis.binaryInfo.entryPoint) def openAsmCFGView(self): if BinaryAnalysis.path is not None: if self.mainTab.currentWidget() == self.asmLinear: indexes = self.asmLinear.selectedIndexes() if len(indexes) > 0: line = self.asmLinear.getItemFormIndex(indexes[0]) self.addAsmCFGView(line) def openIRLinearView(self): if BinaryAnalysis.path is not None: if self.mainTab.currentWidget() == self.asmLinear: indexes = self.asmLinear.selectedIndexes() if len(indexes) > 0: line = self.asmLinear.getItemFormIndex(indexes[0]) self.addIRLinearView(line.func) elif isinstance(self.mainTab.currentWidget(), AsmCFGView): self.addIRLinearView(self.mainTab.currentWidget().func) def openIRCFGView(self): if BinaryAnalysis.path is not None: if self.mainTab.currentWidget() == self.asmLinear: indexes = self.asmLinear.selectedIndexes() if len(indexes) > 0: line = self.asmLinear.getItemFormIndex(indexes[0]) self.addIRCFGView(line.func) elif isinstance(self.mainTab.currentWidget(), AsmCFGView): self.addIRCFGView(self.mainTab.currentWidget().func) def openHexView(self): if self.hexView is not None: self.focusWidgetInTab(self.hexView) else: self.hexView = HexView(BinaryAnalysis.rawData) self.addNewTab(self.hexView, "Hex View") def openStringView(self): if self.stringView is not None: self.focusWidgetInTab(self.stringView) else: self.stringView = StringView(BinaryAnalysis.binaryInfo.strings) self.addNewTab(self.stringView, "Strings") def recoverAlgorithm(self): from IRAnalysis import IRAnalysis from IRView import IRCFGRecover, IRWidget widget = self.mainTab.currentWidget() func = None if isinstance(widget, AsmLinear): indexes = widget.selectedIndexes() if len(indexes) > 0: line = widget.getItemFormIndex(indexes[0]) func = line.func elif isinstance(widget, AsmCFGView): func = widget.func elif isinstance(widget, IRWidget): address = widget.ira.address for f in BinaryAnalysis.funcs: if f.address == address: func = f break if func is not None: if func in self.iraChache: ira = self.iraChache[func] else: ira = IRAnalysis(func.address, func.cfg) newLocDB, newIRCFG = ira.recoverAlgorithm() recoverIRCFG = IRCFGRecover(newIRCFG) for block in recoverIRCFG.mapItems: line = block.model.item(0, 0) line.setText(newLocDB.pretty_str(line.lockey)) self.addNewTab(recoverIRCFG, "Recovered IRCFG")
class TextQueue_Ui(QWidget): def __init__(self, persepolis_setting): super().__init__() self.persepolis_setting = persepolis_setting icons = ':/' + \ str(self.persepolis_setting.value('settings/icons')) + '/' self.setWindowIcon(QIcon.fromTheme('persepolis', QIcon(':/persepolis.svg'))) window_verticalLayout = QVBoxLayout() self.setLayout(window_verticalLayout) # queue_tabWidget self.queue_tabWidget = QTabWidget(self) window_verticalLayout.addWidget(self.queue_tabWidget) # links_tab self.links_tab = QWidget() links_tab_verticalLayout = QVBoxLayout(self.links_tab) # link table self.links_table = QTableWidget(self.links_tab) links_tab_verticalLayout.addWidget(self.links_table) self.links_table.setSelectionBehavior(QAbstractItemView.SelectRows) self.links_table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.links_table.verticalHeader().hide() self.links_table.setColumnCount(3) links_table_header_labels = [ 'File Name', 'Download Link', 'dictionary'] self.links_table.setHorizontalHeaderLabels(links_table_header_labels) self.links_table.setColumnHidden(2, True) self.links_table.horizontalHeader().setSectionResizeMode(0) self.links_table.horizontalHeader().setStretchLastSection(True) # add_queue add_queue_horizontalLayout = QHBoxLayout() self.select_all_pushButton = QPushButton(self.links_tab) add_queue_horizontalLayout.addWidget(self.select_all_pushButton) self.deselect_all_pushButton = QPushButton(self.links_tab) add_queue_horizontalLayout.addWidget(self.deselect_all_pushButton) add_queue_horizontalLayout.addStretch(1) self.add_queue_label = QLabel(self.links_tab) add_queue_horizontalLayout.addWidget(self.add_queue_label) self.add_queue_comboBox = QComboBox(self.links_tab) add_queue_horizontalLayout.addWidget(self.add_queue_comboBox) links_tab_verticalLayout.addLayout(add_queue_horizontalLayout) self.queue_tabWidget.addTab(self.links_tab, "") # options_tab self.options_tab = QWidget() options_tab_verticalLayout = QVBoxLayout(self.options_tab) # proxy proxy_verticalLayout = QVBoxLayout() self.proxy_checkBox = QCheckBox(self.options_tab) proxy_verticalLayout.addWidget(self.proxy_checkBox) self.proxy_frame = QFrame(self.options_tab) self.proxy_frame.setFrameShape(QFrame.StyledPanel) self.proxy_frame.setFrameShadow(QFrame.Raised) proxy_gridLayout = QGridLayout(self.proxy_frame) self.ip_lineEdit = QLineEdit(self.proxy_frame) self.ip_lineEdit.setInputMethodHints(QtCore.Qt.ImhNone) proxy_gridLayout.addWidget(self.ip_lineEdit, 0, 1, 1, 1) self.proxy_pass_label = QLabel(self.proxy_frame) proxy_gridLayout.addWidget(self.proxy_pass_label, 2, 2, 1, 1) self.proxy_pass_lineEdit = QLineEdit(self.proxy_frame) self.proxy_pass_lineEdit.setEchoMode(QLineEdit.Password) proxy_gridLayout.addWidget(self.proxy_pass_lineEdit, 2, 3, 1, 1) self.ip_label = QLabel(self.proxy_frame) proxy_gridLayout.addWidget(self.ip_label, 0, 0, 1, 1) self.proxy_user_lineEdit = QLineEdit(self.proxy_frame) proxy_gridLayout.addWidget(self.proxy_user_lineEdit, 0, 3, 1, 1) self.proxy_user_label = QLabel(self.proxy_frame) proxy_gridLayout.addWidget(self.proxy_user_label, 0, 2, 1, 1) self.port_label = QLabel(self.proxy_frame) proxy_gridLayout.addWidget(self.port_label, 2, 0, 1, 1) self.port_spinBox = QSpinBox(self.proxy_frame) self.port_spinBox.setMaximum(9999) self.port_spinBox.setSingleStep(1) proxy_gridLayout.addWidget(self.port_spinBox, 2, 1, 1, 1) proxy_verticalLayout.addWidget(self.proxy_frame) options_tab_verticalLayout.addLayout(proxy_verticalLayout) # download UserName & Password download_horizontalLayout = QHBoxLayout() download_horizontalLayout.setContentsMargins(-1, 10, -1, -1) download_verticalLayout = QVBoxLayout() self.download_checkBox = QCheckBox(self.options_tab) download_verticalLayout.addWidget(self.download_checkBox) self.download_frame = QFrame(self.options_tab) self.download_frame.setFrameShape(QFrame.StyledPanel) self.download_frame.setFrameShadow(QFrame.Raised) download_gridLayout = QGridLayout(self.download_frame) self.download_user_lineEdit = QLineEdit(self.download_frame) download_gridLayout.addWidget(self.download_user_lineEdit, 0, 1, 1, 1) self.download_user_label = QLabel(self.download_frame) download_gridLayout.addWidget(self.download_user_label, 0, 0, 1, 1) self.download_pass_label = QLabel(self.download_frame) download_gridLayout.addWidget(self.download_pass_label, 1, 0, 1, 1) self.download_pass_lineEdit = QLineEdit(self.download_frame) self.download_pass_lineEdit.setEchoMode(QLineEdit.Password) download_gridLayout.addWidget(self.download_pass_lineEdit, 1, 1, 1, 1) download_verticalLayout.addWidget(self.download_frame) download_horizontalLayout.addLayout(download_verticalLayout) # select folder self.folder_frame = QFrame(self.options_tab) self.folder_frame.setFrameShape(QFrame.StyledPanel) self.folder_frame.setFrameShadow(QFrame.Raised) folder_gridLayout = QGridLayout(self.folder_frame) self.download_folder_lineEdit = QLineEdit(self.folder_frame) folder_gridLayout.addWidget(self.download_folder_lineEdit, 2, 0, 1, 1) self.folder_pushButton = QPushButton(self.folder_frame) folder_gridLayout.addWidget(self.folder_pushButton, 3, 0, 1, 1) self.folder_pushButton.setIcon(QIcon(icons + 'folder')) self.folder_label = QLabel(self.folder_frame) self.folder_label.setAlignment(QtCore.Qt.AlignCenter) folder_gridLayout.addWidget(self.folder_label, 1, 0, 1, 1) download_horizontalLayout.addWidget(self.folder_frame) options_tab_verticalLayout.addLayout(download_horizontalLayout) self.queue_tabWidget.addTab(self.options_tab, '') # limit Speed limit_verticalLayout = QVBoxLayout() self.limit_checkBox = QCheckBox(self.options_tab) limit_verticalLayout.addWidget(self.limit_checkBox) self.limit_frame = QFrame(self.options_tab) self.limit_frame.setFrameShape(QFrame.StyledPanel) self.limit_frame.setFrameShadow(QFrame.Raised) limit_horizontalLayout = QHBoxLayout(self.limit_frame) self.limit_spinBox = QSpinBox(self.limit_frame) self.limit_spinBox.setMinimum(1) self.limit_spinBox.setMaximum(1023) limit_horizontalLayout.addWidget(self.limit_spinBox) self.limit_comboBox = QComboBox(self.limit_frame) self.limit_comboBox.addItem("KB/S") self.limit_comboBox.addItem("MB/S") limit_horizontalLayout.addWidget(self.limit_comboBox) limit_verticalLayout.addWidget(self.limit_frame) limit_connections_horizontalLayout = QHBoxLayout() limit_connections_horizontalLayout.addLayout(limit_verticalLayout) # number of connections connections_horizontalLayout = QHBoxLayout() connections_horizontalLayout.setContentsMargins(-1, 10, -1, -1) self.connections_frame = QFrame(self.options_tab) self.connections_frame.setFrameShape(QFrame.StyledPanel) self.connections_frame.setFrameShadow(QFrame.Raised) horizontalLayout_3 = QHBoxLayout(self.connections_frame) self.connections_label = QLabel(self.connections_frame) horizontalLayout_3.addWidget(self.connections_label) self.connections_spinBox = QSpinBox(self.connections_frame) self.connections_spinBox.setMinimum(1) self.connections_spinBox.setMaximum(16) self.connections_spinBox.setProperty("value", 16) horizontalLayout_3.addWidget(self.connections_spinBox) connections_horizontalLayout.addWidget(self.connections_frame) limit_connections_horizontalLayout.addLayout( connections_horizontalLayout) options_tab_verticalLayout.addLayout( limit_connections_horizontalLayout) # buttons buttons_horizontalLayout = QHBoxLayout() buttons_horizontalLayout.addStretch(1) # ok_pushButton self.ok_pushButton = QPushButton(self) self.ok_pushButton.setIcon(QIcon(icons + 'ok')) buttons_horizontalLayout.addWidget(self.ok_pushButton) # cancel_pushButton self.cancel_pushButton = QPushButton(self) self.cancel_pushButton.setIcon(QIcon(icons + 'remove')) buttons_horizontalLayout.addWidget(self.cancel_pushButton) window_verticalLayout.addLayout(buttons_horizontalLayout) # labels self.setWindowTitle("Persepolis Download Manager") self.queue_tabWidget.setTabText( self.queue_tabWidget.indexOf(self.links_tab), 'Links') self.queue_tabWidget.setTabText( self.queue_tabWidget.indexOf(self.options_tab), 'Download options') self.select_all_pushButton.setText('Select All') self.deselect_all_pushButton.setText('Deselect All') self.add_queue_label.setText('Add to queue : ') self.proxy_checkBox.setText('Proxy') self.proxy_pass_label.setText("Proxy PassWord : "******"IP :") self.proxy_user_label.setText("Proxy UserName : "******"Port:") self.download_checkBox.setText("Download UserName and PassWord") self.download_user_label.setText("Download UserName : "******"Download PassWord : "******"Change Download Folder") self.folder_label.setText("Download Folder : ") self.limit_checkBox.setText("Limit Speed") self.connections_label.setText("Number Of Connections :") self.ok_pushButton.setText('OK') self.cancel_pushButton.setText('Cancel') def changeIcon(self, icons): icons = ':/' + str(icons) + '/' self.ok_pushButton.setIcon(QIcon(icons + 'ok')) self.cancel_pushButton.setIcon(QIcon(icons + 'remove')) self.folder_pushButton.setIcon(QIcon(icons + 'folder'))
class Ui_Ucics(object): def setupUi(self, Ucics): size_280_650 = QSize(280, 650) size_20_20 = QSize(20, 20) size_25_25 = QSize(25, 25) Ucics.setObjectName("Ucics") Ucics.resize(size_280_650) # 窗口大小 Ucics.setMinimumSize(size_280_650) # 设置最小大小 Ucics.setMaximumSize(size_280_650) # 设置最大大小 Ucics.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) # 无边框 Ucics.setMouseTracking(True) # 可拖动 Ucics.setContextMenuPolicy(Qt.NoContextMenu) # 禁止上下文菜单 # 由于父QWidget无法通过样式设置背景 # 所以这里把所有控件放到子QWidget中 self.bgWidget = QWidget(Ucics) self.bgWidget.setObjectName("bgWidget") # 顶部标题图标 最小化 关闭 self.topWidget = QWidget(self.bgWidget) self.topWidget.setMaximumHeight(25) self.topWidget.setObjectName("topWidget") # --布局 topLayout = QHBoxLayout(self.topWidget) topLayout.setSpacing(1) topLayout.setContentsMargins(0, 0, 0, 0) topLayout.setObjectName("topLayout") # ----icon self.iconLabel = QLabel(self.bgWidget) self.iconLabel.setMinimumSize(size_25_25) self.iconLabel.setMaximumSize(size_25_25) self.iconLabel.setObjectName("iconLabel") # ----最小化按钮 self.minButton = QPushButton(self.bgWidget) self.minButton.setMinimumSize(size_25_25) self.minButton.setMaximumSize(size_25_25) self.minButton.setObjectName("minButton") # ----关闭按钮 self.closeButton = QPushButton(self.bgWidget) self.closeButton.setMinimumSize(size_25_25) self.closeButton.setMaximumSize(size_25_25) self.closeButton.setObjectName("closeButton") # ----添加到布局中 topLayout.addWidget(self.iconLabel, 0, Qt.AlignLeft) topLayout.addWidget(self.minButton, 1, Qt.AlignRight) topLayout.addWidget(self.closeButton, 0, Qt.AlignRight) # 头像 昵称 心情 天气等 self.headWidget = QWidget(self.bgWidget) self.headWidget.setMinimumHeight(90) self.headWidget.setMaximumHeight(90) self.headWidget.setObjectName("headWidget") # --布局 headLayout = QHBoxLayout(self.headWidget) headLayout.setSpacing(6) headLayout.setContentsMargins(9, 20, 9, 6) headLayout.setObjectName("headLayout") # ----头像 self.headLabel = QLabel(self.headWidget) self.headLabel.setMinimumWidth(60) self.headLabel.setMaximumWidth(60) self.headLabel.setToolTip("") self.headLabel.setCursor(QCursor(Qt.PointingHandCursor)) self.headLabel.setObjectName("headLabel") # ----中间部分(昵称和签名等) self.headInfoWidget = QWidget(self.headWidget) self.headInfoWidget.setObjectName("headInfoWidget") # ------中间部分布局 headInfoLayout = QVBoxLayout(self.headInfoWidget) headInfoLayout.setSpacing(1) headInfoLayout.setContentsMargins(0, 0, 0, 0) headInfoLayout.setObjectName("headInfoLayout") # --------昵称 self.nameLabel = QLabel(self.headInfoWidget) self.nameLabel.setMinimumHeight(20) self.nameLabel.setMaximumHeight(20) self.nameLabel.setObjectName("nameLabel") # --------签名 self.moodEdit = LineEdit(self.headInfoWidget) self.moodEdit.setMinimumHeight(20) self.moodEdit.setMaximumHeight(20) self.moodEdit.setFrame(False) # 去掉边框 # self.moodEdit.setClearButtonEnabled(True) # 添加清除按钮 self.moodEdit.setObjectName("moodEdit") # --------工具 self.toolWidget = QWidget(self.headInfoWidget) self.toolWidget.setMinimumHeight(20) self.toolWidget.setMaximumHeight(20) self.toolWidget.setObjectName("toolWidget") # ----------工具布局 toolLayout = QHBoxLayout(self.toolWidget) toolLayout.setSpacing(1) toolLayout.setContentsMargins(0, 0, 0, 0) toolLayout.setObjectName("toolLayout") # ------------空间 self.qzoneButton = QPushButton(self.toolWidget) self.qzoneButton.setMinimumSize(size_20_20) self.qzoneButton.setMaximumSize(size_20_20) self.qzoneButton.setObjectName("qzoneButton") # ------------皮肤 self.skinButton = QPushButton(self.toolWidget) self.skinButton.setMinimumSize(size_20_20) self.skinButton.setMaximumSize(size_20_20) self.skinButton.setObjectName("skinButton") # ------------添加到布局 toolLayout.addWidget(self.qzoneButton, 0, Qt.AlignLeft) toolLayout.addWidget(self.skinButton, 1, Qt.AlignLeft) # --------添加到布局 headInfoLayout.addWidget(self.nameLabel) headInfoLayout.addWidget(self.moodEdit) headInfoLayout.addWidget(self.toolWidget) # ----天气 self.weatherLabel = QLabel(self.headWidget) self.weatherLabel.setMinimumWidth(60) self.weatherLabel.setMaximumWidth(60) self.weatherLabel.setCursor(QCursor(Qt.PointingHandCursor)) self.weatherLabel.setObjectName("weatherLabel") # ----添加到布局中 headLayout.addWidget(self.headLabel, 0, Qt.AlignLeft) headLayout.addWidget(self.headInfoWidget, 0, Qt.AlignCenter) headLayout.addWidget(self.weatherLabel, 0, Qt.AlignRight) # 搜索输入框 self.searchEdit = LineEdit(self.bgWidget) self.searchEdit.setFrame(False) # self.searchEdit.setClearButtonEnabled(True) self.searchEdit.setObjectName("searchEdit") # tab self.tabWidget = QTabWidget(self.bgWidget) self.tabWidget.setUsesScrollButtons(False) # 取消两个切换按钮 self.tabWidget.setDocumentMode(True) # 取消边框 self.tabWidget.setObjectName("tabWidget") # --分组 self.tabGroup = QWidget(self.tabWidget) self.tabGroup.setObjectName("tabGroup") # ----分组布局 groupVerticalLayout = QVBoxLayout(self.tabGroup) groupVerticalLayout.setSpacing(0) groupVerticalLayout.setContentsMargins(0, 0, 0, 0) groupVerticalLayout.setObjectName("groupVerticalLayout") # ------分组list控件 self.groupTreeWidget = QTreeWidget(self.tabGroup) self.groupTreeWidget.setFrameShape(QFrame.NoFrame) self.groupTreeWidget.setFrameStyle(QFrame.NoFrame) self.groupTreeWidget.setLineWidth(0) self.groupTreeWidget.setIndentation(0) self.groupTreeWidget.setRootIsDecorated(False) self.groupTreeWidget.setExpandsOnDoubleClick(False) self.groupTreeWidget.header().setVisible(False) self.groupTreeWidget.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.groupTreeWidget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.groupTreeWidget.setObjectName("groupTreeWidget") # ----添加到布局 groupVerticalLayout.addWidget(self.groupTreeWidget) # --历史 self.tabHistory = QWidget(self.tabWidget) self.tabHistory.setObjectName("tabHistory") # ----历史布局 historyVerticalLayout = QVBoxLayout(self.tabHistory) historyVerticalLayout.setSpacing(0) historyVerticalLayout.setContentsMargins(0, 0, 0, 0) historyVerticalLayout.setObjectName("historyVerticalLayout") # ------历史list控件 self.historyTreeWidget = QTreeWidget(self.tabHistory) self.historyTreeWidget.setFrameShape(QFrame.NoFrame) self.historyTreeWidget.setFrameStyle(QFrame.NoFrame) self.historyTreeWidget.setLineWidth(0) self.historyTreeWidget.setIndentation(0) self.historyTreeWidget.setRootIsDecorated(False) self.historyTreeWidget.setExpandsOnDoubleClick(False) self.historyTreeWidget.header().setVisible(False) self.historyTreeWidget.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.historyTreeWidget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.historyTreeWidget.setObjectName("historyTreeWidget") # ----添加到布局 historyVerticalLayout.addWidget(self.historyTreeWidget) # 添加到tab中 self.tabWidget.addTab(self.tabGroup, "") self.tabWidget.addTab(self.tabHistory, "") # 整体布局 verticalLayout = QVBoxLayout(self.bgWidget) verticalLayout.setSpacing(0) verticalLayout.setContentsMargins(0, 0, 0, 0) verticalLayout.setObjectName("verticalLayout") verticalLayout.addWidget(self.topWidget) verticalLayout.addWidget(self.headWidget) verticalLayout.addWidget(self.searchEdit) verticalLayout.addWidget(self.tabWidget) # bg layout = QVBoxLayout(Ucics) layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.bgWidget) # 初始化一些设置 _translate = QCoreApplication.translate Ucics.setWindowTitle(_translate("Ucics", "UCICS")) self.tabWidget.setCurrentIndex(0) self.tabWidget.setTabToolTip(self.tabWidget.indexOf(self.tabGroup), _translate("tabGroup", "分组")) self.tabWidget.setTabToolTip(self.tabWidget.indexOf(self.tabHistory), _translate("tabHistory", "历史")) QMetaObject.connectSlotsByName(Ucics)
class AboutVM(QDialog): def __init__(self, parent=None): """Class initializer.""" super(AboutVM, self).__init__(parent) self.setWindowTitle(self.tr('About VideoMorph')) self.resize(374, 404) self.horizontalLayout_3 = QHBoxLayout(self) self.verticalLayout_4 = QVBoxLayout() self.horizontalLayout_2 = QHBoxLayout() self.label = QLabel(self) self.label.setMinimumSize(QSize(64, 64)) self.label.setMaximumSize(QSize(64, 64)) self.label.setText("") self.label.setPixmap(QPixmap(':/logo/images/videomorph.png')) self.label.setScaledContents(True) self.horizontalLayout_2.addWidget(self.label) self.label_2 = QLabel( "<p align=\"center\"><span style=\" font-size:20pt; font-weight:600;\">VideoMorph</span></p><p align=\"center\"><span style=\" font-size:9pt; font-weight:600;\">version {v}</span></p>".format( v=VERSION)) self.label_2.setMinimumSize(QSize(0, 64)) self.label_2.setMaximumSize(QSize(16777215, 64)) self.horizontalLayout_2.addWidget(self.label_2) self.verticalLayout_4.addLayout(self.horizontalLayout_2) self.tabWidget = QTabWidget(self) self.tab = QWidget() self.verticalLayout_2 = QVBoxLayout(self.tab) self.textEdit_3 = QTextEdit(self.tab) self.textEdit_3.setReadOnly(True) self.verticalLayout_2.addWidget(self.textEdit_3) self.tabWidget.addTab(self.tab, "") self.tab_2 = QWidget() self.verticalLayout_3 = QVBoxLayout(self.tab_2) self.textEdit_2 = QTextEdit(self.tab_2) self.textEdit_2.setReadOnly(True) self.verticalLayout_3.addWidget(self.textEdit_2) self.tabWidget.addTab(self.tab_2, "") self.tab_3 = QWidget() self.verticalLayout = QVBoxLayout(self.tab_3) self.plainTextEdit = QPlainTextEdit(self.tab_3) self.plainTextEdit.setReadOnly(True) self.verticalLayout.addWidget(self.plainTextEdit) self.tabWidget.addTab(self.tab_3, "") self.verticalLayout_4.addWidget(self.tabWidget) self.horizontalLayout = QHBoxLayout() spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Ok) self.buttonBox.accepted.connect(self.accept) self.horizontalLayout.addWidget(self.buttonBox) self.verticalLayout_4.addLayout(self.horizontalLayout) self.horizontalLayout_3.addLayout(self.verticalLayout_4) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), self.tr("Info")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), self.tr("Credits")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), self.tr("License")) self.textEdit_2.setHtml(self.tr( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" "p, li { white-space: pre-wrap; }\n" "</style></head><body style=\" font-family:\'Sans Serif\'; font-size:10pt; font-weight:400; font-style:normal;\">\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:11pt; font-weight:600;\">Developers:</span></p>\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Ozkar L. Garcell - project leader</p>\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><[email protected]></p>\n" "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p>\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Leodanis Pozo Ramos - main developer</p>\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><[email protected]></p>\n" "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt; font-weight:600;\"><br /></p>\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:11pt; font-weight:600;\">Translators:</span></p>\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Ozkar L. Garcell - en_US, es_ES</p>\n" "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt; font-weight:600;\"><br /></p>\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:11pt; font-weight:600;\">Contributors:</span></p>\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Carlos Parra Zaldivar - Artwork.</p>\n" "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt; font-weight:600;\"><br /></p></body></html>" )) self.textEdit_3.setHtml(self.tr( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" "p, li { white-space: pre-wrap; }\n" "</style></head><body style=\" font-family:\'Sans Serif\'; font-size:10pt; font-weight:400; font-style:normal;\">\n" "<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:12pt; font-weight:600;\">A simple and lightweight video transcoder.</span></p>\n" "<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt; font-weight:600;\"><br /></p>\n" "<p align=\"justify\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:11pt; font-weight:600;\">VideoMorph</span><span style=\" font-size:11pt;\"> is a small GUI front-end for </span><a href=\"http://ffmpeg.org/\"><span style=\" font-size:11pt; text-decoration: underline; color:#2980b9;\">ffmpeg</span></a><span style=\" font-size:11pt;\"> and avconv, based on code from </span><a href=\"https://github.com/senko/python-video-converter\"><span style=\" font-size:11pt; text-decoration: underline; color:#2980b9;\">python-video-converter</span></a><span style=\" font-size:11pt;\"> and presets idea from </span><a href=\"http://qwinff.github.io/\"><span style=\" font-size:11pt; text-decoration: underline; color:#2980b9;\">QWinFF</span></a><span style=\" font-size:11pt;\">.</span></p>\n" "<p align=\"justify\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;\"><br /></p>\n" "<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><a href=\"https://github.com/codeshard/videomorph\"><span style=\" text-decoration: underline; color:#2980b9;\">https://github.com/codeshard/videomorph</span></a></p></body></html>" )) self.plainTextEdit.setPlainText(self.tr( " Apache License\n" " Version 2.0, January 2004\n" " http://www.apache.org/licenses/\n" "\n" " TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n" "\n" " 1. Definitions.\n" "\n" " \"License\" shall mean the terms and conditions for use, reproduction,\n" " and distribution as defined by Sections 1 through 9 of this document.\n" "\n" " \"Licensor\" shall mean the copyright owner or entity authorized by\n" " the copyright owner that is granting the License.\n" "\n" " \"Legal Entity\" shall mean the union of the acting entity and all\n" " other entities that control, are controlled by, or are under common\n" " control with that entity. For the purposes of this definition,\n" " \"control\" means (i) the power, direct or indirect, to cause the\n" " direction or management of such entity, whether by contract or\n" " otherwise, or (ii) ownership of fifty percent (50%) or more of the\n" " outstanding shares, or (iii) beneficial ownership of such entity.\n" "\n" " \"You\" (or \"Your\") shall mean an individual or Legal Entity\n" " exercising permissions granted by this License.\n" "\n" " \"Source\" form shall mean the preferred form for making modifications,\n" " including but not limited to software source code, documentation\n" " source, and configuration files.\n" "\n" " \"Object\" form shall mean any form resulting from mechanical\n" " transformation or translation of a Source form, including but\n" " not limited to compiled object code, generated documentation,\n" " and conversions to other media types.\n" "\n" " \"Work\" shall mean the work of authorship, whether in Source or\n" " Object form, made available under the License, as indicated by a\n" " copyright notice that is included in or attached to the work\n" " (an example is provided in the Appendix below).\n" "\n" " \"Derivative Works\" shall mean any work, whether in Source or Object\n" " form, that is based on (or derived from) the Work and for which the\n" " editorial revisions, annotations, elaborations, or other modifications\n" " represent, as a whole, an original work of authorship. For the purposes\n" " of this License, Derivative Works shall not include works that remain\n" " separable from, or merely link (or bind by name) to the interfaces of,\n" " the Work and Derivative Works thereof.\n" "\n" " \"Contribution\" shall mean any work of authorship, including\n" " the original version of the Work and any modifications or additions\n" " to that Work or Derivative Works thereof, that is intentionally\n" " submitted to Licensor for inclusion in the Work by the copyright owner\n" " or by an individual or Legal Entity authorized to submit on behalf of\n" " the copyright owner. For the purposes of this definition, \"submitted\"\n" " means any form of electronic, verbal, or written communication sent\n" " to the Licensor or its representatives, including but not limited to\n" " communication on electronic mailing lists, source code control systems,\n" " and issue tracking systems that are managed by, or on behalf of, the\n" " Licensor for the purpose of discussing and improving the Work, but\n" " excluding communication that is conspicuously marked or otherwise\n" " designated in writing by the copyright owner as \"Not a Contribution.\"\n" "\n" " \"Contributor\" shall mean Licensor and any individual or Legal Entity\n" " on behalf of whom a Contribution has been received by Licensor and\n" " subsequently incorporated within the Work.\n" "\n" " 2. Grant of Copyright License. Subject to the terms and conditions of\n" " this License, each Contributor hereby grants to You a perpetual,\n" " worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n" " copyright license to reproduce, prepare Derivative Works of,\n" " publicly display, publicly perform, sublicense, and distribute the\n" " Work and such Derivative Works in Source or Object form.\n" "\n" " 3. Grant of Patent License. Subject to the terms and conditions of\n" " this License, each Contributor hereby grants to You a perpetual,\n" " worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n" " (except as stated in this section) patent license to make, have made,\n" " use, offer to sell, sell, import, and otherwise transfer the Work,\n" " where such license applies only to those patent claims licensable\n" " by such Contributor that are necessarily infringed by their\n" " Contribution(s) alone or by combination of their Contribution(s)\n" " with the Work to which such Contribution(s) was submitted. If You\n" " institute patent litigation against any entity (including a\n" " cross-claim or counterclaim in a lawsuit) alleging that the Work\n" " or a Contribution incorporated within the Work constitutes direct\n" " or contributory patent infringement, then any patent licenses\n" " granted to You under this License for that Work shall terminate\n" " as of the date such litigation is filed.\n" "\n" " 4. Redistribution. You may reproduce and distribute copies of the\n" " Work or Derivative Works thereof in any medium, with or without\n" " modifications, and in Source or Object form, provided that You\n" " meet the following conditions:\n" "\n" " (a) You must give any other recipients of the Work or\n" " Derivative Works a copy of this License; and\n" "\n" " (b) You must cause any modified files to carry prominent notices\n" " stating that You changed the files; and\n" "\n" " (c) You must retain, in the Source form of any Derivative Works\n" " that You distribute, all copyright, patent, trademark, and\n" " attribution notices from the Source form of the Work,\n" " excluding those notices that do not pertain to any part of\n" " the Derivative Works; and\n" "\n" " (d) If the Work includes a \"NOTICE\" text file as part of its\n" " distribution, then any Derivative Works that You distribute must\n" " include a readable copy of the attribution notices contained\n" " within such NOTICE file, excluding those notices that do not\n" " pertain to any part of the Derivative Works, in at least one\n" " of the following places: within a NOTICE text file distributed\n" " as part of the Derivative Works; within the Source form or\n" " documentation, if provided along with the Derivative Works; or,\n" " within a display generated by the Derivative Works, if and\n" " wherever such third-party notices normally appear. The contents\n" " of the NOTICE file are for informational purposes only and\n" " do not modify the License. You may add_file Your own attribution\n" " notices within Derivative Works that You distribute, alongside\n" " or as an addendum to the NOTICE text from the Work, provided\n" " that such additional attribution notices cannot be construed\n" " as modifying the License.\n" "\n" " You may add_file Your own copyright statement to Your modifications and\n" " may provide additional or different license terms and conditions\n" " for use, reproduction, or distribution of Your modifications, or\n" " for any such Derivative Works as a whole, provided Your use,\n" " reproduction, and distribution of the Work otherwise complies with\n" " the conditions stated in this License.\n" "\n" " 5. Submission of Contributions. Unless You explicitly state otherwise,\n" " any Contribution intentionally submitted for inclusion in the Work\n" " by You to the Licensor shall be under the terms and conditions of\n" " this License, without any additional terms or conditions.\n" " Notwithstanding the above, nothing herein shall supersede or modify\n" " the terms of any separate license agreement you may have executed\n" " with Licensor regarding such Contributions.\n" "\n" " 6. Trademarks. This License does not grant permission to use the trade\n" " names, trademarks, service marks, or product names of the Licensor,\n" " except as required for reasonable and customary use in describing the\n" " origin of the Work and reproducing the content of the NOTICE file.\n" "\n" " 7. Disclaimer of Warranty. Unless required by applicable law or\n" " agreed to in writing, Licensor provides the Work (and each\n" " Contributor provides its Contributions) on an \"AS IS\" BASIS,\n" " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n" " implied, including, without limitation, any warranties or conditions\n" " of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n" " PARTICULAR PURPOSE. You are solely responsible for determining the\n" " appropriateness of using or redistributing the Work and assume any\n" " risks associated with Your exercise of permissions under this License.\n" "\n" " 8. Limitation of Liability. In no event and under no legal theory,\n" " whether in tort (including negligence), contract, or otherwise,\n" " unless required by applicable law (such as deliberate and grossly\n" " negligent acts) or agreed to in writing, shall any Contributor be\n" " liable to You for damages, including any direct, indirect, special,\n" " incidental, or consequential damages of any character arising as a\n" " result of this License or out of the use or inability to use the\n" " Work (including but not limited to damages for loss of goodwill,\n" " work stoppage, computer failure or malfunction, or any and all\n" " other commercial damages or losses), even if such Contributor\n" " has been advised of the possibility of such damages.\n" "\n" " 9. Accepting Warranty or Additional Liability. While redistributing\n" " the Work or Derivative Works thereof, You may choose to offer,\n" " and charge a fee for, acceptance of support, warranty, indemnity,\n" " or other liability obligations and/or rights consistent with this\n" " License. However, in accepting such obligations, You may act only\n" " on Your own behalf and on Your sole responsibility, not on behalf\n" " of any other Contributor, and only if You agree to indemnify,\n" " defend, and hold each Contributor harmless for any liability\n" " incurred by, or claims asserted against, such Contributor by reason\n" " of your accepting any such warranty or additional liability.\n" "\n" " END OF TERMS AND CONDITIONS" ))
class MainWindow(QMainWindow): def __init__(self, data): super().__init__() self.resize(400, 600) self.setWindowTitle('Logger Skeleton') self.statusBar().showMessage("Ready", 2000) # Make widgets #################################### self.tabs = QTabWidget(self) self.setCentralWidget(self.tabs) # Add tabs self.table_tab = QWidget(self) self.stats_tab = QWidget(self) self.tabs.addTab(self.table_tab, "Table") self.tabs.addTab(self.stats_tab, "Stats") # Table tab ########################################################### self.table_view = QTableView(self.table_tab) self.text_edit = QPlainTextEdit() self.btn_add_row = QPushButton("Add a row") #self.btn_remove_row = QPushButton("Remove selected rows") table_tab_vbox = QVBoxLayout() table_tab_vbox.addWidget(self.table_view) table_tab_vbox.addWidget(self.text_edit) table_tab_vbox.addWidget(self.btn_add_row) #table_tab_vbox.addWidget(self.btn_remove_row) self.table_tab.setLayout(table_tab_vbox) # Set model ####################################### my_model = DataQtModel(data, parent=self) # TODO: right use of "parent" ? # Proxy model ##################################### proxy_model = QSortFilterProxyModel(parent=self) # TODO: right use of "parent" ? proxy_model.setSourceModel(my_model) self.table_view.setModel(proxy_model) #self.table_view.setModel(my_model) # Set the view #################################### self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows) # Select the full row when a cell is selected (See http://doc.qt.io/qt-5/qabstractitemview.html#selectionBehavior-prop ) #self.table_view.setSelectionMode(QAbstractItemView.SingleSelection) # Set selection mode. See http://doc.qt.io/qt-5/qabstractitemview.html#selectionMode-prop self.table_view.setAlternatingRowColors(True) self.table_view.setSortingEnabled(True) self.table_view.setColumnWidth(0, 200) # TODO: automatically get the best width self.table_view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # https://stackoverflow.com/q/17535563 self.table_view.setColumnHidden(COMMENT_COLUMN_INDEX, True) delegate = Delegate() self.table_view.setItemDelegate(delegate) # Set key shortcut ################################ # see https://stackoverflow.com/a/17631703 and http://doc.qt.io/qt-5/qaction.html#details # Add row action add_action = QAction(self.table_view) add_action.setShortcut(Qt.CTRL | Qt.Key_N) add_action.triggered.connect(self.add_row_btn_callback) self.table_view.addAction(add_action) # Delete action del_action = QAction(self.table_view) del_action.setShortcut(Qt.Key_Delete) del_action.triggered.connect(self.remove_row_callback) self.table_view.addAction(del_action) # Set QDataWidgetMapper ########################### self.mapper = QDataWidgetMapper() self.mapper.setModel(proxy_model) # WARNING: do not use `my_model` here otherwise the index mapping will be wrong! self.mapper.addMapping(self.text_edit, COMMENT_COLUMN_INDEX) self.mapper.toFirst() # TODO: is it a good idea ? self.table_view.selectionModel().selectionChanged.connect(self.update_selection) # Set slots ####################################### self.btn_add_row.clicked.connect(self.add_row_btn_callback) #self.btn_remove_row.clicked.connect(self.remove_row_callback) #self.table_view.setColumnHidden(1, True) # Stats tab ########################################################### # See https://matplotlib.org/examples/user_interfaces/embedding_in_qt5.html stats_tab_layout = QVBoxLayout(self.stats_tab) self.plot_canvas = PlotCanvas(data, self.stats_tab, width=5, height=4, dpi=100) stats_tab_layout.addWidget(self.plot_canvas) ################################################### #proxy_model.dataChanged.connect(plot_canvas.update_figure) #proxy_model.rowsInserted.connect(plot_canvas.update_figure) # TODO #proxy_model.rowsRemoved.connect(plot_canvas.update_figure) # TODO self.tabs.currentChanged.connect(self.updatePlot) # Update the stats plot when the tabs switch to the stats tab # Show ############################################ self.show() def update_selection(self, selected, deselected): index = self.table_view.selectionModel().currentIndex() self.mapper.setCurrentIndex(index.row()) print("Index: ", index.row()) def updatePlot(self, index): """ Parameters ---------- index Returns ------- """ if index == self.tabs.indexOf(self.stats_tab): self.plot_canvas.update_figure() def add_row_btn_callback(self): parent = QModelIndex() # More useful with e.g. tree structures #row_index = 0 # Insert new rows to the begining row_index = self.table_view.model().rowCount(parent) # Insert new rows to the end self.table_view.model().insertRows(row_index, 1, parent) def remove_row_callback(self): parent = QModelIndex() # More useful with e.g. tree structures # See http://doc.qt.io/qt-5/model-view-programming.html#handling-selections-in-item-views #current_index = self.table_view.selectionModel().currentIndex() #print("Current index:", current_index.row(), current_index.column()) selection_index_list = self.table_view.selectionModel().selectedRows() selected_row_list = [selection_index.row() for selection_index in selection_index_list] print("Current selection:", selected_row_list) #row_index = 0 # Remove the first row #row_index = self.table_view.model().rowCount(parent) - 1 # Remove the last row # WARNING: the list of rows to remove MUST be sorted in reverse order # otherwise the index of rows to remove may change at each iteration of the for loop! # TODO: there should be a lock mechanism to avoid model modifications from external sources while iterating this loop... # Or as a much simpler alternative, modify the ItemSelectionMode to forbid the non contiguous selection of rows and remove the following for loop for row_index in sorted(selected_row_list, reverse=True): # Remove rows one by one to allow the removql of non-contiguously selected rows (e.g. "rows 0, 2 and 3") success = self.table_view.model().removeRows(row_index, 1, parent) if not success: raise Exception("Unknown error...") # TODO
class AppWindow(QMainWindow): onRestart = pyqtSignal(name='onRestart') def __init__(self, dwarf_args, flags=None): super(AppWindow, self).__init__(flags) self.dwarf_args = dwarf_args self.session_manager = SessionManager(self) self.session_manager.sessionCreated.connect(self.session_created) self.session_manager.sessionStopped.connect(self.session_stopped) self.session_manager.sessionClosed.connect(self.session_closed) self._tab_order = [ 'memory', 'modules', 'ranges', 'jvm-inspector', 'jvm-debugger' ] self.menu = self.menuBar() self._is_newer_dwarf = False self.view_menu = None #dockwidgets self.watchers_dwidget = None self.hooks_dwiget = None self.bookmarks_dwiget = None self.registers_dock = None self.console_dock = None self.backtrace_dock = None self.threads_dock = None #panels self.asm_panel = None self.console_panel = None self.context_panel = None self.backtrace_panel = None self.contexts_list_panel = None self.data_panel = None self.emulator_panel = None self.ftrace_panel = None self.hooks_panel = None self.bookmarks_panel = None self.smali_panel = None self.java_inspector_panel = None self.java_explorer_panel = None self.java_trace_panel = None self.memory_panel = None self.modules_panel = None self.ranges_panel = None self.search_panel = None self.trace_panel = None self.watchers_panel = None self.welcome_window = None self._ui_elems = [] self.setWindowTitle( 'Dwarf - A debugger for reverse engineers, crackers and security analyst' ) # load external assets _app = QApplication.instance() self.remove_tmp_dir() # themes self.prefs = Prefs() self.set_theme(self.prefs.get('dwarf_ui_theme', 'black')) # load font if os.path.exists(utils.resource_path('assets/Anton.ttf')): QFontDatabase.addApplicationFont( utils.resource_path('assets/Anton.ttf')) if os.path.exists(utils.resource_path('assets/OpenSans-Regular.ttf')): QFontDatabase.addApplicationFont( utils.resource_path('assets/OpenSans-Regular.ttf')) _app.setFont(QFont("OpenSans", 9, QFont.Normal)) if os.path.exists(utils.resource_path('assets/OpenSans-Bold.ttf')): QFontDatabase.addApplicationFont( utils.resource_path('assets/OpenSans-Bold.ttf')) # mainwindow statusbar self.progressbar = QProgressBar() self.progressbar.setRange(0, 0) self.progressbar.setVisible(False) self.progressbar.setFixedHeight(15) self.progressbar.setFixedWidth(100) self.progressbar.setTextVisible(False) self.progressbar.setValue(30) self.statusbar = QStatusBar(self) self.statusbar.setAutoFillBackground(False) self.statusbar.addPermanentWidget(self.progressbar) self.statusbar.setObjectName("statusbar") self.setStatusBar(self.statusbar) self.main_tabs = QTabWidget(self) self.main_tabs.setMovable(False) self.main_tabs.setTabsClosable(True) self.main_tabs.setAutoFillBackground(True) self.main_tabs.tabCloseRequested.connect(self._on_close_tab) self.setCentralWidget(self.main_tabs) if self.dwarf_args.package is None: self.welcome_window = WelcomeDialog(self) self.welcome_window.setModal(True) self.welcome_window.onIsNewerVersion.connect( self._enable_update_menu) self.welcome_window.onUpdateComplete.connect( self._on_dwarf_updated) self.welcome_window.setWindowTitle( 'Welcome to Dwarf - A debugger for reverse engineers, crackers and security analyst' ) self.welcome_window.onSessionSelected.connect(self._start_session) self.welcome_window.onSessionRestore.connect(self._restore_session) # wait for welcome screen self.hide() self.welcome_window.show() else: if dwarf_args.package is not None: if dwarf_args.type is None: # no device given check if package is local path if os.path.exists(dwarf_args.package): print('* Starting new LocalSession') self._start_session('local') else: print('use -t to set sessiontype') exit(0) else: print('* Starting new Session') self._start_session(dwarf_args.type) def _setup_main_menu(self): self.menu = self.menuBar() dwarf_menu = QMenu('Dwarf', self) theme = QMenu('Theme', dwarf_menu) theme.addAction('Black') theme.addAction('Dark') theme.addAction('Light') theme.triggered.connect(self._set_theme) dwarf_menu.addMenu(theme) dwarf_menu.addSeparator() if self._is_newer_dwarf: dwarf_menu.addAction('Update', self._update_dwarf) dwarf_menu.addAction('Close', self.session_manager.session.stop) self.menu.addMenu(dwarf_menu) session = self.session_manager.session if session is not None: session_menu = session.main_menu if isinstance(session_menu, list): for menu in session_menu: self.menu.addMenu(menu) else: self.menu.addMenu(session_menu) self.view_menu = QMenu('View', self) subview_menu = QMenu('Subview', self.view_menu) subview_menu.addAction('Search', lambda: self.show_main_tab('search'), shortcut=QKeySequence(Qt.CTRL + Qt.Key_F3)) subview_menu.addAction('Emulator', lambda: self.show_main_tab('emulator'), shortcut=QKeySequence(Qt.CTRL + Qt.Key_F2)) subview_menu.addAction('Disassembly', lambda: self.show_main_tab('disassembly'), shortcut=QKeySequence(Qt.CTRL + Qt.Key_F5)) self.view_menu.addMenu(subview_menu) self.view_menu.addSeparator() self.menu.addMenu(self.view_menu) if self.dwarf_args.debug_script: debug_menu = QMenu('Debug', self) debug_menu.addAction('Reload core', self._menu_reload_core) debug_menu.addAction('Debug dwarf js core', self._menu_debug_dwarf_js) self.menu.addMenu(debug_menu) about_menu = QMenu('About', self) about_menu.addAction('Dwarf on GitHub', self._menu_github) about_menu.addAction('Documention', self._menu_documentation) about_menu.addAction('Api', self._menu_api) about_menu.addAction('Slack', self._menu_slack) about_menu.addSeparator() about_menu.addAction('Info', self._show_about_dlg) self.menu.addMenu(about_menu) def _enable_update_menu(self): self._is_newer_dwarf = True def _update_dwarf(self): if self.welcome_window: self.welcome_window._update_dwarf() def _on_close_tab(self, index): tab_text = self.main_tabs.tabText(index) if tab_text: if tab_text.lower() in self.session_manager.session.non_closable: return try: self._ui_elems.remove(tab_text.lower()) except ValueError: # recheck ValueError: list.remove(x): x not in list pass self.main_tabs.removeTab(index) def _handle_tab_change(self): for index in range(self.main_tabs.count()): tab_name = self.main_tabs.tabText(index).lower().replace(' ', '-') if tab_name in self.session_manager.session.non_closable: self.main_tabs.tabBar().setTabButton(index, QTabBar.RightSide, None) if tab_name in self._tab_order: should_index = self._tab_order.index(tab_name) if index != should_index: self.main_tabs.tabBar().moveTab(index, should_index) def _on_dwarf_updated(self): self.onRestart.emit() def remove_tmp_dir(self): if os.path.exists('.tmp'): shutil.rmtree('.tmp', ignore_errors=True) def _set_theme(self, qaction): if qaction: self.set_theme(qaction.text()) def _menu_reload_core(self): self.dwarf.load_script() def _menu_debug_dwarf_js(self): you_know_what_to_do = json.loads( self.dwarf._script.exports.debugdwarfjs()) return you_know_what_to_do def show_main_tab(self, name): # elem doesnt exists? create it if name not in self._ui_elems: self._create_ui_elem(name) index = 0 name = name.join(name.split()).lower() if name == 'memory': index = self.main_tabs.indexOf(self.memory_panel) elif name == 'ranges': index = self.main_tabs.indexOf(self.ranges_panel) elif name == 'search': index = self.main_tabs.indexOf(self.search_panel) elif name == 'modules': index = self.main_tabs.indexOf(self.modules_panel) elif name == 'disassembly': index = self.main_tabs.indexOf(self.asm_panel) elif name == 'trace': index = self.main_tabs.indexOf(self.trace_panel) elif name == 'data': index = self.main_tabs.indexOf(self.data_panel) elif name == 'emulator': index = self.main_tabs.indexOf(self.emulator_panel) elif name == 'java-trace': index = self.main_tabs.indexOf(self.java_trace_panel) elif name == 'jvm-inspector': index = self.main_tabs.indexOf(self.java_inspector_panel) elif name == 'jvm-debugger': index = self.main_tabs.indexOf(self.java_explorer_panel) elif name == 'smali': index = self.main_tabs.indexOf(self.smali_panel) self.main_tabs.setCurrentIndex(index) def jump_to_address(self, ptr, show_panel=True): if self.memory_panel is not None: if show_panel: self.show_main_tab('memory') self.memory_panel.read_memory(ptr) @pyqtSlot(name='mainMenuGitHub') def _menu_github(self): QDesktopServices.openUrl(QUrl('https://github.com/iGio90/Dwarf')) @pyqtSlot(name='mainMenuDocumentation') def _menu_api(self): QDesktopServices.openUrl(QUrl('https://igio90.github.io/Dwarf/')) @pyqtSlot(name='mainMenuApi') def _menu_documentation(self): QDesktopServices.openUrl(QUrl('https://igio90.github.io/Dwarf/api')) @pyqtSlot(name='mainMenuSlack') def _menu_slack(self): QDesktopServices.openUrl( QUrl('https://join.slack.com/t/resecret/shared_invite' '/enQtMzc1NTg4MzE3NjA1LTlkNzYxNTIwYTc2ZTYyOWY1MT' 'Q1NzBiN2ZhYjQwYmY0ZmRhODQ0NDE3NmRmZjFiMmE1MDYwN' 'WJlNDVjZDcwNGE')) def _show_about_dlg(self): about_dlg = AboutDialog(self) about_dlg.show() def _create_ui_elem(self, elem): if not isinstance(elem, str): return if elem not in self._ui_elems: self._ui_elems.append(elem) if elem == 'watchers': from ui.panel_watchers import WatchersPanel self.watchers_dwidget = QDockWidget('Watchers', self) self.watchers_panel = WatchersPanel(self) # dont respond to dblclick mem cant be shown # self.watchers_panel.onItemDoubleClicked.connect( # self._on_watcher_clicked) self.watchers_panel.onItemRemoved.connect( self._on_watcher_removeditem) self.watchers_panel.onItemAdded.connect(self._on_watcher_added) self.watchers_dwidget.setWidget(self.watchers_panel) self.watchers_dwidget.setObjectName('WatchersPanel') self.addDockWidget(Qt.LeftDockWidgetArea, self.watchers_dwidget) self.view_menu.addAction(self.watchers_dwidget.toggleViewAction()) elif elem == 'hooks': from ui.panel_hooks import HooksPanel self.hooks_dwiget = QDockWidget('Breakpoints', self) self.hooks_panel = HooksPanel(self) self.hooks_panel.onShowMemoryRequest.connect( self._on_watcher_clicked) self.hooks_panel.onHookRemoved.connect(self._on_hook_removed) self.hooks_dwiget.setWidget(self.hooks_panel) self.hooks_dwiget.setObjectName('HooksPanel') self.addDockWidget(Qt.LeftDockWidgetArea, self.hooks_dwiget) self.view_menu.addAction(self.hooks_dwiget.toggleViewAction()) elif elem == 'bookmarks': from ui.panel_bookmarks import BookmarksPanel self.bookmarks_dwiget = QDockWidget('Boomarks', self) self.bookmarks_panel = BookmarksPanel(self) self.bookmarks_panel.onShowMemoryRequest.connect( self._on_watcher_clicked) self.bookmarks_dwiget.setWidget(self.bookmarks_panel) self.bookmarks_dwiget.setObjectName('BookmarksPanel') self.addDockWidget(Qt.LeftDockWidgetArea, self.bookmarks_dwiget) self.view_menu.addAction(self.bookmarks_dwiget.toggleViewAction()) elif elem == 'registers': from ui.panel_context import ContextPanel self.registers_dock = QDockWidget('Context', self) self.context_panel = ContextPanel(self) self.registers_dock.setWidget(self.context_panel) self.registers_dock.setObjectName('ContextsPanel') self.addDockWidget(Qt.RightDockWidgetArea, self.registers_dock) self.view_menu.addAction(self.registers_dock.toggleViewAction()) elif elem == 'memory': from ui.panel_memory import MemoryPanel self.memory_panel = MemoryPanel(self) self.memory_panel.onShowDisassembly.connect( self._disassemble_range) self.memory_panel.dataChanged.connect(self._on_memory_modified) self.memory_panel.statusChanged.connect(self.set_status_text) self.main_tabs.addTab(self.memory_panel, 'Memory') elif elem == 'jvm-debugger': from ui.panel_java_explorer import JavaExplorerPanel self.java_explorer_panel = JavaExplorerPanel(self) self.main_tabs.addTab(self.java_explorer_panel, 'JVM debugger') self.main_tabs.tabBar().moveTab( self.main_tabs.indexOf(self.java_explorer_panel), 1) elif elem == 'jvm-inspector': from ui.panel_java_inspector import JavaInspector self.java_inspector_panel = JavaInspector(self) self.main_tabs.addTab(self.java_inspector_panel, 'JVM inspector') elif elem == 'console': from ui.panel_console import ConsolePanel self.console_dock = QDockWidget('Console', self) self.console_panel = ConsolePanel(self) self.dwarf.onLogToConsole.connect(self._log_js_output) self.console_dock.setWidget(self.console_panel) self.console_dock.setObjectName('ConsolePanel') self.addDockWidget(Qt.BottomDockWidgetArea, self.console_dock) self.view_menu.addAction(self.console_dock.toggleViewAction()) elif elem == 'backtrace': from ui.panel_backtrace import BacktracePanel self.backtrace_dock = QDockWidget('Backtrace', self) self.backtrace_panel = BacktracePanel(self) self.backtrace_dock.setWidget(self.backtrace_panel) self.backtrace_dock.setObjectName('BacktracePanel') self.backtrace_panel.onShowMemoryRequest.connect( self._on_watcher_clicked) self.addDockWidget(Qt.RightDockWidgetArea, self.backtrace_dock) self.view_menu.addAction(self.backtrace_dock.toggleViewAction()) elif elem == 'threads': from ui.panel_contexts_list import ContextsListPanel self.threads_dock = QDockWidget('Threads', self) self.contexts_list_panel = ContextsListPanel(self) self.dwarf.onThreadResumed.connect( self.contexts_list_panel.resume_tid) self.contexts_list_panel.onItemDoubleClicked.connect( self._manually_apply_context) self.threads_dock.setWidget(self.contexts_list_panel) self.threads_dock.setObjectName('ThreadPanel') self.addDockWidget(Qt.RightDockWidgetArea, self.threads_dock) self.view_menu.addAction(self.threads_dock.toggleViewAction()) elif elem == 'modules': from ui.panel_modules import ModulesPanel self.modules_panel = ModulesPanel(self) self.modules_panel.onModuleSelected.connect( self._on_module_dblclicked) self.modules_panel.onModuleFuncSelected.connect( self._on_modulefunc_dblclicked) self.modules_panel.onAddHook.connect(self._on_addmodule_hook) self.modules_panel.onDumpBinary.connect(self._on_dumpmodule) self.main_tabs.addTab(self.modules_panel, 'Modules') elif elem == 'ranges': from ui.panel_ranges import RangesPanel self.ranges_panel = RangesPanel(self) self.ranges_panel.onItemDoubleClicked.connect( self._range_dblclicked) self.ranges_panel.onDumpBinary.connect(self._on_dumpmodule) # connect to watcherpanel func self.ranges_panel.onAddWatcher.connect( self.watchers_panel.do_addwatcher_dlg) self.main_tabs.addTab(self.ranges_panel, 'Ranges') elif elem == 'search': from ui.panel_search import SearchPanel self.search_panel = SearchPanel(self) self.search_panel.onShowMemoryRequest.connect( self._on_watcher_clicked) self.main_tabs.addTab(self.search_panel, 'Search') elif elem == 'data': from ui.panel_data import DataPanel self.data_panel = DataPanel(self) self.main_tabs.addTab(self.data_panel, 'Data') elif elem == 'trace': from ui.panel_trace import TracePanel self.trace_panel = TracePanel(self) self.main_tabs.addTab(self.trace_panel, 'Trace') elif elem == 'disassembly': from ui.widgets.disasm_view import DisassemblyView self.asm_panel = DisassemblyView(self) self.asm_panel.onShowMemoryRequest.connect(self._on_disasm_showmem) self.main_tabs.addTab(self.asm_panel, 'Disassembly') elif elem == 'emulator': from ui.panel_emulator import EmulatorPanel self.emulator_panel = EmulatorPanel(self) self.main_tabs.addTab(self.emulator_panel, 'Emulator') elif elem == 'java-trace': from ui.panel_java_trace import JavaTracePanel self.java_trace_panel = JavaTracePanel(self) self.main_tabs.addTab(self.java_trace_panel, 'JVM tracer') elif elem == 'smali': from ui.panel_smali import SmaliPanel self.smali_panel = SmaliPanel() self.main_tabs.addTab(self.smali_panel, 'Smali') else: print('no handler for elem: ' + elem) # make tabs unclosable and sort self._handle_tab_change() # TODO: remove add @2x for item in self.findChildren(QDockWidget): if item: if 'darwin' in sys.platform: item.setStyleSheet( 'QDockWidget::title { padding-left:-30px; } QDockWidget::close-button, QDockWidget::float-button { width: 10px; height:10px }' ) def set_theme(self, theme): if theme: theme = theme.replace(os.pardir, '').replace('.', '') theme = theme.join(theme.split()).lower() theme_style = 'assets/' + theme + '_style.qss' if not os.path.exists(utils.resource_path(theme_style)): return self.prefs.put('dwarf_ui_theme', theme) try: _app = QApplication.instance() with open(theme_style) as stylesheet: _app.setStyleSheet(_app.styleSheet() + '\n' + stylesheet.read()) except Exception as e: pass # err = self.dwarf.spawn(dwarf_args.package, dwarf_args.script) def set_status_text(self, txt): self.statusbar.showMessage(txt) # ************************************************************************ # **************************** Properties ******************************** # ************************************************************************ @property def disassembly(self): return self.asm_panel @property def backtrace(self): return self.backtrace_panel @property def console(self): return self.console_panel @property def context(self): return self.context_panel @property def threads(self): return self.contexts_list_panel @property def emulator(self): return self.emulator_panel @property def ftrace(self): return self.ftrace_panel @property def hooks(self): return self.hooks_panel @property def java_inspector(self): return self.java_inspector_panel @property def java_explorer(self): return self.java_explorer_panel @property def memory(self): return self.memory_panel @property def modules(self): return self.memory_panel @property def ranges(self): return self.ranges_panel @property def trace(self): return self.trace_panel @property def watchers(self): return self.watchers_panel @property def dwarf(self): if self.session_manager.session is not None: return self.session_manager.session.dwarf else: return None # ************************************************************************ # **************************** Handlers ********************************** # ************************************************************************ # session handlers def _start_session(self, session_type, session_data=None): if self.welcome_window is not None: self.welcome_window.close() self.session_manager.create_session(session_type, session_data=session_data) def _restore_session(self, session_data): if 'session' in session_data: session_type = session_data['session'] self._start_session(session_type, session_data=session_data) def session_created(self): # session init done create ui for it session = self.session_manager.session self._setup_main_menu() for ui_elem in session.session_ui_sections: ui_elem = ui_elem.join(ui_elem.split()).lower() self._create_ui_elem(ui_elem) self.dwarf.onAttached.connect(self._on_attached) self.dwarf.onScriptLoaded.connect(self._on_script_loaded) # hookup self.dwarf.onSetRanges.connect(self._on_setranges) self.dwarf.onSetModules.connect(self._on_setmodules) self.dwarf.onAddNativeHook.connect(self._on_add_hook) self.dwarf.onApplyContext.connect(self._apply_context) self.dwarf.onThreadResumed.connect(self.on_tid_resumed) self.dwarf.onTraceData.connect(self._on_tracer_data) self.dwarf.onSetData.connect(self._on_set_data) self.session_manager.start_session(self.dwarf_args) q_settings = QSettings("dwarf_window_pos.ini", QSettings.IniFormat) ui_state = q_settings.value('dwarf_ui_state') if ui_state: self.restoreGeometry(ui_state) window_state = q_settings.value('dwarf_ui_window', self.saveState()) if window_state: self.restoreState(window_state) self.showMaximized() def session_stopped(self): self.remove_tmp_dir() self.menu.clear() self.main_tabs.clear() # actually we need to kill this. needs a refactor if self.java_trace_panel is not None: self.java_trace_panel = None for elem in self._ui_elems: if elem == 'watchers': self.watchers_panel.clear_list() self.watchers_panel.close() self.watchers_panel = None self.removeDockWidget(self.watchers_dwidget) self.watchers_dwidget = None elif elem == 'hooks': self.hooks_panel.close() self.hooks_panel = None self.removeDockWidget(self.hooks_dwiget) self.hooks_dwiget = None elif elem == 'registers': self.context_panel.close() self.context_panel = None self.removeDockWidget(self.registers_dock) self.registers_dock = None elif elem == 'memory': self.memory_panel.close() self.memory_panel = None self.main_tabs.removeTab(0) # self.main_tabs elif elem == 'jvm-debugger': self.java_explorer_panel.close() self.java_explorer_panel = None self.removeDockWidget(self.watchers_dwidget) elif elem == 'console': self.console_panel.close() self.console_panel = None self.removeDockWidget(self.console_dock) self.console_dock = None elif elem == 'backtrace': self.backtrace_panel.close() self.backtrace_panel = None self.removeDockWidget(self.backtrace_dock) elif elem == 'threads': self.contexts_list_panel.close() self.contexts_list_panel = None self.removeDockWidget(self.threads_dock) self.threads_dock = None elif elem == 'bookmarks': self.bookmarks_panel.close() self.bookmarks_panel = None self.removeDockWidget(self.bookmarks_dwiget) self.bookmarks_dwiget = None def session_closed(self): self._ui_elems = [] self.hide() if self.welcome_window is not None: self.welcome_window.exec() # close if it was a commandline session if self.welcome_window is None: if self.dwarf_args.package: self.close() # ui handler def closeEvent(self, event): """ Window closed save stuff or whatever at exit detaches dwarf """ # save windowstuff q_settings = QSettings("dwarf_window_pos.ini", QSettings.IniFormat) q_settings.setValue('dwarf_ui_state', self.saveGeometry()) q_settings.setValue('dwarf_ui_window', self.saveState()) if self.dwarf: self.dwarf.detach() super().closeEvent(event) def _on_watcher_clicked(self, ptr): """ Address in Watcher/Hookpanel was clicked show Memory """ if '.' in ptr: # java_hook file_path = ptr.replace('.', os.path.sep) if os.path.exists('.tmp/smali/' + file_path + '.smali'): if self.smali_panel is None: self._create_ui_elem('smali') self.smali_panel.set_file('.tmp/smali/' + file_path + '.smali') self.show_main_tab('smali') else: self.memory_panel.read_memory(ptr=ptr) self.show_main_tab('memory') def _on_disasm_showmem(self, ptr, length): """ Address in Disasm was clicked adds temphighlight for bytes from current instruction """ self.memory_panel.read_memory(ptr) self.memory_panel.add_highlight( HighLight('attention', utils.parse_ptr(ptr), length)) self.show_main_tab('memory') def _on_watcher_added(self, ptr): """ Watcher Entry was added """ try: # set highlight self.memory_panel.add_highlight( HighLight('watcher', ptr, self.dwarf.pointer_size)) except HighlightExistsError: pass def _on_watcher_removeditem(self, ptr): """ Watcher Entry was removed remove highlight too """ self.memory_panel.remove_highlight(ptr) def _on_module_dblclicked(self, data): """ Module in ModulePanel was doubleclicked """ addr, size = data addr = utils.parse_ptr(addr) size = int(size, 10) self.memory_panel.read_memory(ptr=addr, length=size) self.show_main_tab('Memory') def _on_modulefunc_dblclicked(self, ptr): """ Function in ModulePanel was doubleclicked """ ptr = utils.parse_ptr(ptr) self.memory_panel.read_memory(ptr=ptr) self.show_main_tab('Memory') def _on_dumpmodule(self, data): """ DumpBinary MenuItem in ModulePanel was selected """ ptr, size = data ptr = utils.parse_ptr(ptr) size = int(size, 10) self.dwarf.dump_memory(ptr=ptr, length=size) def _disassemble_range(self, mem_range): """ Disassemble MenuItem in Hexview was selected """ if mem_range: if self.asm_panel is None: self._create_ui_elem('disassembly') if mem_range: self.asm_panel.disassemble(mem_range) self.show_main_tab('disassembly') def _range_dblclicked(self, ptr): """ Range in RangesPanel was doubleclicked """ ptr = utils.parse_ptr(ptr) self.memory_panel.read_memory(ptr=ptr) self.show_main_tab('Memory') # dwarf handlers def _log_js_output(self, output): if self.console_panel is not None: self.console_panel.get_js_console().log(output) def _on_setranges(self, ranges): """ Dwarf wants to set Ranges only hooked up to switch tab or create ui its connected in panel after creation """ if self.ranges_panel is None: self.show_main_tab('ranges') # forward only now to panel it connects after creation self.ranges_panel.set_ranges(ranges) def _on_setmodules(self, modules): """ Dwarf wants to set Modules only hooked up to switch tab or create ui its connected in panel after creation """ if self.modules_panel is None: self._create_ui_elem('modules') self.modules_panel.set_modules(modules) if self.modules_panel is not None: self.show_main_tab('modules') def _manually_apply_context(self, context): """ perform additional operation if the context has been manually applied from the context list """ self._apply_context(context, manual=True) def _apply_context(self, context, manual=False): # update current context tid # this should be on top as any further api from js needs to be executed on that thread is_initial_hook = context['reason'] >= 0 if manual or (self.dwarf.context_tid and not is_initial_hook): self.dwarf.context_tid = context['tid'] if 'context' in context: if not manual: self.threads.add_context(context) is_java = context['is_java'] if is_java: if self.java_explorer_panel is None: self._create_ui_elem('jvm-debugger') self.context_panel.set_context(context['ptr'], 1, context['context']) self.java_explorer_panel.set_handle_arg(-1) self.show_main_tab('jvm-debugger') else: self.context_panel.set_context(context['ptr'], 0, context['context']) if 'pc' in context['context']: if not 'disassembly' in self._ui_elems: from lib.range import Range _range = Range(Range.SOURCE_TARGET, self.dwarf) _range.init_with_address( int(context['context']['pc']['value'], 16)) self._disassemble_range(_range) if 'backtrace' in context: self.backtrace_panel.set_backtrace(context['backtrace']) def _on_add_hook(self, hook): try: # set highlight ptr = hook.get_ptr() ptr = utils.parse_ptr(ptr) self.memory_panel.add_highlight( HighLight('hook', ptr, self.dwarf.pointer_size)) except HighlightExistsError: pass def _on_hook_removed(self, ptr): ptr = utils.parse_ptr(ptr) self.memory_panel.remove_highlight(ptr) def _on_addmodule_hook(self, data): ptr, name = data self.dwarf.hook_native(ptr, own_input=name) def on_tid_resumed(self, tid): if self.dwarf: if self.dwarf.context_tid == tid: # clear backtrace if 'backtrace' in self._ui_elems: if self.backtrace_panel is not None: self.backtrace_panel.clear() # remove thread if 'threads' in self._ui_elems: if self.contexts_list_panel is not None: self.contexts_list_panel.resume_tid(tid) # clear registers if 'registers' in self._ui_elems: if self.context_panel is not None: self.context_panel.clear() # clear jvm explorer if 'jvm-debugger' in self._ui_elems: if self.java_explorer_panel is not None: self.java_explorer_panel.clear_panel() # invalidate dwarf context tid self.dwarf.context_tid = 0 def _on_tracer_data(self, data): if not data: return if self.trace_panel is None: self._create_ui_elem('trace') if self.trace_panel is not None: self.show_main_tab('Trace') self.trace_panel.start() trace_events_parts = data[1].split(',') while trace_events_parts: trace_event = TraceEvent(trace_events_parts.pop(0), trace_events_parts.pop(0), trace_events_parts.pop(0), trace_events_parts.pop(0)) self.trace_panel.event_queue.append(trace_event) def _on_set_data(self, data): if not isinstance(data, list): return if self.data_panel is None: self._create_ui_elem('data') if self.data_panel is not None: self.show_main_tab('Data') self.data_panel.append_data(data[0], data[1], data[2]) def show_progress(self, text): self.progressbar.setVisible(True) self.set_status_text(text) def hide_progress(self): self.progressbar.setVisible(False) self.set_status_text('') def _on_attached(self, data): self.setWindowTitle('Dwarf - Attached to %s (%s)' % (data[1], data[0])) def _on_script_loaded(self): # restore the loaded session if any self.session_manager.restore_session() def _on_memory_modified(self, pos, length): data_pos = self.memory_panel.base + pos data = self.memory_panel.data[pos:pos + length] data = [data[0]] # todo: strange js part if self.dwarf.dwarf_api('writeBytes', [data_pos, data]): pass else: utils.show_message_box('Failed to write Memory') def on_add_bookmark(self, ptr): """ provide ptr as int """ if self.bookmarks_panel is not None: self.bookmarks_panel._create_bookmark(ptr=hex(ptr))
class ProgressWindow_Ui(QWidget): def __init__(self, persepolis_setting): super().__init__() self.persepolis_setting = persepolis_setting icons = ':/' + str(persepolis_setting.value('settings/icons')) + '/' # add support for other languages self.translator = QTranslator() # detect current value of locale in persepolis config file if str(self.persepolis_setting.value('settings/locale')) in (-1, 'en_US'): self.translator.load('') else: self.translator.load( 'locales/' + str(self.persepolis_setting.value('settings/locale')), ':/ui.qm') QCoreApplication.installTranslator(self.translator) # set ui direction ui_direction = self.persepolis_setting.value('ui_direction') if ui_direction == 'rtl': self.setLayoutDirection(Qt.RightToLeft) elif ui_direction in 'ltr': self.setLayoutDirection(Qt.LeftToRight) # window self.setMinimumSize(QtCore.QSize(595, 284)) self.setWindowIcon( QIcon.fromTheme('persepolis', QIcon(':/persepolis.svg'))) self.setWindowTitle( QCoreApplication.translate("progress_ui_tr", "Persepolis Download Manager")) verticalLayout = QVBoxLayout(self) # progress_tabWidget self.progress_tabWidget = QTabWidget(self) # information_tab self.information_tab = QWidget() information_verticalLayout = QVBoxLayout(self.information_tab) # link_label self.link_label = QLabel(self.information_tab) information_verticalLayout.addWidget(self.link_label) # status_label self.status_label = QLabel(self.information_tab) information_verticalLayout.addWidget(self.status_label) # downloaded_label self.downloaded_label = QLabel(self.information_tab) information_verticalLayout.addWidget(self.downloaded_label) # rate_label self.rate_label = QLabel(self.information_tab) information_verticalLayout.addWidget(self.rate_label) # time_label self.time_label = QLabel(self.information_tab) information_verticalLayout.addWidget(self.time_label) # connections_label self.connections_label = QLabel(self.information_tab) information_verticalLayout.addWidget(self.connections_label) # add information_tab to progress_tabWidget self.progress_tabWidget.addTab(self.information_tab, "") # options_tab self.options_tab = QWidget() options_tab_horizontalLayout = QHBoxLayout(self.options_tab) options_tab_horizontalLayout.setContentsMargins(11, 11, 11, 11) # limit_checkBox self.limit_checkBox = QCheckBox(self.options_tab) limit_verticalLayout = QVBoxLayout() limit_verticalLayout.addWidget(self.limit_checkBox) # limit_frame self.limit_frame = QFrame(self.options_tab) self.limit_frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.limit_frame.setFrameShadow(QtWidgets.QFrame.Raised) limit_frame_verticalLayout = QVBoxLayout(self.limit_frame) limit_frame_horizontalLayout = QHBoxLayout() # limit_spinBox self.limit_spinBox = QDoubleSpinBox(self.options_tab) self.limit_spinBox.setMinimum(1) self.limit_spinBox.setMaximum(1023) limit_frame_horizontalLayout.addWidget(self.limit_spinBox) # limit_comboBox self.limit_comboBox = QComboBox(self.options_tab) self.limit_comboBox.addItem("") self.limit_comboBox.addItem("") limit_frame_horizontalLayout.addWidget(self.limit_comboBox) # limit_pushButton self.limit_pushButton = QPushButton(self.options_tab) limit_frame_verticalLayout.addLayout(limit_frame_horizontalLayout) limit_frame_verticalLayout.addWidget(self.limit_pushButton) limit_verticalLayout.addWidget(self.limit_frame) limit_verticalLayout.setContentsMargins(11, 11, 11, 11) options_tab_horizontalLayout.addLayout(limit_verticalLayout) # after_checkBox self.after_checkBox = QCheckBox(self.options_tab) after_verticalLayout = QVBoxLayout() after_verticalLayout.addWidget(self.after_checkBox) # after_frame self.after_frame = QFrame(self.options_tab) self.after_frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.after_frame.setFrameShadow(QtWidgets.QFrame.Raised) after_frame_verticalLayout = QVBoxLayout(self.after_frame) # after_comboBox self.after_comboBox = QComboBox(self.options_tab) self.after_comboBox.addItem("") after_frame_verticalLayout.addWidget(self.after_comboBox) # after_pushButton self.after_pushButton = QPushButton(self.options_tab) after_frame_verticalLayout.addWidget(self.after_pushButton) after_verticalLayout.addWidget(self.after_frame) after_verticalLayout.setContentsMargins(11, 11, 11, 11) options_tab_horizontalLayout.addLayout(after_verticalLayout) self.progress_tabWidget.addTab(self.options_tab, "") verticalLayout.addWidget(self.progress_tabWidget) # download_progressBar self.download_progressBar = QProgressBar(self) verticalLayout.addWidget(self.download_progressBar) # buttons button_horizontalLayout = QHBoxLayout() button_horizontalLayout.addStretch(1) # resume_pushButton self.resume_pushButton = QPushButton(self) self.resume_pushButton.setIcon(QIcon(icons + 'play')) button_horizontalLayout.addWidget(self.resume_pushButton) # pause_pushButton self.pause_pushButton = QtWidgets.QPushButton(self) self.pause_pushButton.setIcon(QIcon(icons + 'pause')) button_horizontalLayout.addWidget(self.pause_pushButton) # stop_pushButton self.stop_pushButton = QtWidgets.QPushButton(self) self.stop_pushButton.setIcon(QIcon(icons + 'stop')) button_horizontalLayout.addWidget(self.stop_pushButton) verticalLayout.addLayout(button_horizontalLayout) self.progress_tabWidget.setCurrentIndex(0) # labels self.link_label.setText( QCoreApplication.translate("progress_ui_tr", "Link :")) self.status_label.setText( QCoreApplication.translate("progress_ui_tr", "Status : ")) self.downloaded_label.setText( QCoreApplication.translate("progress_ui_tr", "Downloaded :")) self.rate_label.setText( QCoreApplication.translate("progress_ui_tr", "Transfer rate : ")) self.time_label.setText( QCoreApplication.translate("progress_ui_tr", "Estimated time left :")) self.connections_label.setText( QCoreApplication.translate("progress_ui_tr", "Number of connections : ")) self.progress_tabWidget.setTabText( self.progress_tabWidget.indexOf(self.information_tab), QCoreApplication.translate("progress_ui_tr", "Download information")) self.limit_checkBox.setText( QCoreApplication.translate("progress_ui_tr", "Limit Speed")) self.after_checkBox.setText( QCoreApplication.translate("progress_ui_tr", "After download")) self.limit_comboBox.setItemText( 0, QCoreApplication.translate("progress_ui_tr", "KB/S")) self.limit_comboBox.setItemText( 1, QCoreApplication.translate("progress_ui_tr", "MB/S")) self.limit_pushButton.setText( QCoreApplication.translate("progress_ui_tr", "Apply")) self.after_comboBox.setItemText( 0, QCoreApplication.translate("progress_ui_tr", "Shut Down")) self.progress_tabWidget.setTabText( self.progress_tabWidget.indexOf(self.options_tab), QCoreApplication.translate("progress_ui_tr", "Download Options")) self.resume_pushButton.setText( QCoreApplication.translate("progress_ui_tr", "Resume")) self.pause_pushButton.setText( QCoreApplication.translate("progress_ui_tr", "Pause")) self.stop_pushButton.setText( QCoreApplication.translate("progress_ui_tr", "Stop")) self.after_pushButton.setText( QCoreApplication.translate("progress_ui_tr", "Apply")) def changeIcon(self, icons): icons = ':/' + str(icons) + '/' self.resume_pushButton.setIcon(QIcon(icons + 'play')) self.pause_pushButton.setIcon(QIcon(icons + 'pause')) self.stop_pushButton.setIcon(QIcon(icons + 'stop'))
class HelpUI(ToolInstance): # do not close when opening session (especially if web page asked to open session) SESSION_ENDURING = True help = "help:user/tools/helpviewer.html" def __init__(self, session): tool_name = "Help Viewer" ToolInstance.__init__(self, session, tool_name) self._pending_downloads = [] from chimerax.ui import MainToolWindow self.tool_window = MainToolWindow(self) parent = self.tool_window.ui_area # UI content code from PyQt5.QtWidgets import QToolBar, QVBoxLayout, QAction, QLineEdit, QTabWidget, QShortcut, QStatusBar from PyQt5.QtGui import QIcon from PyQt5.QtCore import Qt shortcuts = ( (Qt.CTRL + Qt.Key_0, self.page_reset_zoom), (Qt.CTRL + Qt.Key_T, lambda: self.create_tab(empty=True)), (Qt.CTRL + Qt.Key_W, self.close_current_tab), (Qt.CTRL + Qt.Key_Tab, lambda: self.cycle_tab(1)), (Qt.CTRL + Qt.SHIFT + Qt.Key_Tab, lambda: self.cycle_tab(-1)), (Qt.CTRL + Qt.Key_1, lambda: self.tab_n(0)), (Qt.CTRL + Qt.Key_2, lambda: self.tab_n(1)), (Qt.CTRL + Qt.Key_3, lambda: self.tab_n(2)), (Qt.CTRL + Qt.Key_4, lambda: self.tab_n(3)), (Qt.CTRL + Qt.Key_5, lambda: self.tab_n(4)), (Qt.CTRL + Qt.Key_6, lambda: self.tab_n(5)), (Qt.CTRL + Qt.Key_7, lambda: self.tab_n(6)), (Qt.CTRL + Qt.Key_8, lambda: self.tab_n(7)), (Qt.CTRL + Qt.Key_9, lambda: self.tab_n(-1)), ) for shortcut, callback in shortcuts: sc = QShortcut(shortcut, parent) sc.activated.connect(callback) self.toolbar = tb = QToolBar() # tb.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) layout = QVBoxLayout() layout.setContentsMargins(0, 1, 0, 0) layout.addWidget(tb) parent.setLayout(layout) import os.path icon_dir = os.path.dirname(__file__) # attribute, text, tool tip, callback, shortcut(s), enabled buttons = ( ("back", "Back", "Back to previous page", self.page_back, Qt.Key_Back, False), ("forward", "Forward", "Next page", self.page_forward, Qt.Key_Forward, False), ("reload", "Reload", "Reload page", self.page_reload, Qt.Key_Reload, True), ("new_tab", "New Tab", "New Tab", lambda: self.create_tab(empty=True), Qt.Key_Reload, True), ("zoom_in", "Zoom in", "Zoom in", self.page_zoom_in, [Qt.CTRL + Qt.Key_Plus, Qt.Key_ZoomIn, Qt.CTRL + Qt.Key_Equal], True), ("zoom_out", "Zoom out", "Zoom out", self.page_zoom_out, [Qt.CTRL + Qt.Key_Minus, Qt.Key_ZoomOut], True), ("home", "Home", "Home page", self.page_home, Qt.Key_HomePage, True), (None, None, None, None, None, None), ("search", "Search", "Search in page", self.page_search, Qt.Key_Search, True), ) for attribute, text, tooltip, callback, shortcut, enabled in buttons: if attribute is None: tb.addSeparator() continue icon_path = os.path.join(icon_dir, "%s.svg" % attribute) setattr(self, attribute, QAction(QIcon(icon_path), text, tb)) a = getattr(self, attribute) a.setToolTip(tooltip) a.triggered.connect(callback) if shortcut: if isinstance(shortcut, list): a.setShortcuts(shortcut) else: a.setShortcut(shortcut) a.setEnabled(enabled) tb.addAction(a) self.url = QLineEdit() self.url.setPlaceholderText("url") self.url.setClearButtonEnabled(True) self.url.returnPressed.connect(self.go_to) tb.insertWidget(self.reload, self.url) self.search_terms = QLineEdit() self.search_terms.setClearButtonEnabled(True) self.search_terms.setPlaceholderText("search in page") self.search_terms.setMaximumWidth(200) self.search_terms.returnPressed.connect(self.page_search) tb.addWidget(self.search_terms) self.tabs = QTabWidget(parent) self.tabs.setTabsClosable(True) self.tabs.setUsesScrollButtons(True) self.tabs.setTabBarAutoHide(True) self.tabs.setDocumentMode(False) self.tabs.currentChanged.connect(self.tab_changed) self.tabs.tabCloseRequested.connect(self.close_tab) layout.addWidget(self.tabs) self.status_bar = QStatusBar() layout.addWidget(self.status_bar) self.tool_window.manage(placement=None) self.profile = create_chimerax_profile( self.tabs, interceptor=self.intercept, download=self.download_requested) def status(self, message): self.status_bar.showMessage(message, 2000) def create_tab(self, *, empty=False, background=False): w = _HelpWebView(self.session, self, profile=self.profile) self.tabs.addTab(w, "New Tab") if empty: from chimerax import app_dirs self.tool_window.title = app_dirs.appname from PyQt5.QtCore import Qt self.url.setFocus(Qt.ShortcutFocusReason) if not background: self.tabs.setCurrentWidget(w) p = w.page() p.loadFinished.connect(lambda okay, w=w: self.page_loaded(w, okay)) p.urlChanged.connect(lambda url, w=w: self.url_changed(w, url)) p.titleChanged.connect(lambda title, w=w: self.title_changed(w, title)) p.linkHovered.connect(self.link_hovered) p.authenticationRequired.connect(self.authorize) # TODO? p.iconChanged.connect(....) # TODO? p.iconUrlChanged.connect(....) # TODO? p.loadProgress.connect(....) # TODO? p.loadStarted.connect(....) # TODO? p.renderProcessTerminated.connect(....) # TODO? p.selectionChanged.connect(....) # TODO? p.windowCloseRequested.connect(....) return w def authorize(self, requestUrl, auth): from PyQt5.QtWidgets import QDialog, QGridLayout, QLineEdit, QLabel, QPushButton from PyQt5.QtCore import Qt class PasswordDialog(QDialog): def __init__(self, requestUrl, auth, parent=None): super().__init__(parent) self.setWindowTitle("ChimeraX: Authentication Required") self.setModal(True) self.auth = auth url = requestUrl.url() key = QLabel("\N{KEY}") font = key.font() font.setPointSize(2 * font.pointSize()) key.setFont(font) self.info = QLabel( f'{url} is requesting your username and password. The site says: "{auth.realm()}"' ) self.info.setWordWrap(True) user_name = QLabel("User name:") self.user_name = QLineEdit(self) password = QLabel("Password:"******"item" is an instance of QWebEngineDownloadItem # print("HelpUI.download_requested", item) import os url_file = item.url().fileName() base, extension = os.path.splitext(url_file) # print("HelpUI.download_requested connect", item.mimeType(), extension) # Normally, we would look at the download type or MIME type, # but since neither one is set by the server, we look at the # download extension instead if extension == ".whl": if not base.endswith("x86_64"): # Since the file name encodes the package name and version # number, we make sure that we are using the right name # instead of whatever QWebEngine may want to use. # Remove _# which may be present if bundle author submitted # the same version of the bundle multiple times. parts = base.rsplit('_', 1) if len(parts) == 2 and parts[1].isdigit(): url_file = parts[0] + extension file_path = os.path.join(os.path.dirname(item.path()), url_file) import pkg_resources py_env = pkg_resources.Environment() dist = pkg_resources.Distribution.from_filename(file_path) if not py_env.can_add(dist): raise ValueError("unsupported wheel platform") item.setPath(file_path) # print("HelpUI.download_requested clean", file_path) try: # Guarantee that file name is available os.remove(file_path) except OSError: pass self._pending_downloads.append(item) self.session.logger.info("Downloading bundle %s" % url_file) item.finished.connect(self.download_finished) else: from PyQt5.QtWidgets import QFileDialog path, filt = QFileDialog.getSaveFileName(directory=item.path()) if not path: return self.session.logger.info("Downloading file %s" % url_file) item.setPath(path) # print("HelpUI.download_requested accept", file_path) item.accept() def download_finished(self, *args, **kw): # print("HelpUI.download_finished", args, kw) finished = [] pending = [] for item in self._pending_downloads: if not item.isFinished(): pending.append(item) else: finished.append(item) self._pending_downloads = pending import pkginfo from chimerax.ui.ask import ask for item in finished: item.finished.disconnect() filename = item.path() try: w = pkginfo.Wheel(filename) except Exception as e: self.session.logger.info("Error parsing %s: %s" % (filename, str(e))) self.session.logger.info("File saved as %s" % filename) continue if not _installable(w, self.session.logger): self.session.logger.info("Bundle saved as %s" % filename) continue how = ask(self.session, "Install %s %s (file %s)?" % (w.name, w.version, filename), ["install", "cancel"], title="Toolshed") if how == "cancel": self.session.logger.info("Bundle installation canceled") continue self.session.toolshed.install_bundle(filename, self.session.logger, per_user=True, session=self.session) def show(self, url, *, new_tab=False, html=None): from urllib.parse import urlparse, urlunparse parts = urlparse(url) if not parts.scheme: parts = list(parts) parts[0] = "http" url = urlunparse(parts) # canonicalize if new_tab or self.tabs.count() == 0: w = self.create_tab() else: w = self.tabs.currentWidget() from PyQt5.QtCore import QUrl if html: w.setHtml(html, QUrl(url)) else: w.setUrl(QUrl(url)) self.display(True) def go_to(self): self.show(self.url.text()) def page_back(self, checked): w = self.tabs.currentWidget() if w is None: return w.history().back() def page_forward(self, checked): w = self.tabs.currentWidget() if w is None: return w.history().forward() def page_home(self, checked): w = self.tabs.currentWidget() if w is None: return history = w.history() hi = history.itemAt(0) self.show(_qurl2text(hi.url())) def page_zoom_in(self): w = self.tabs.currentWidget() if w is None: return w.setZoomFactor(1.25 * w.zoomFactor()) def page_zoom_out(self): w = self.tabs.currentWidget() if w is None: return w.setZoomFactor(0.8 * w.zoomFactor()) def page_reset_zoom(self): w = self.tabs.currentWidget() if w is None: return w.setZoomFactor(1) def page_reload(self, checked): w = self.tabs.currentWidget() if w is None: return w.reload() def page_search(self): w = self.tabs.currentWidget() if w is None: return w.findText(self.search_terms.text()) def delete(self): global _singleton _singleton = None ToolInstance.delete(self) def page_loaded(self, w, okay): if self.tabs.currentWidget() != w: return self.update_back_forward(w) def url_changed(self, w, url): if self.tabs.currentWidget() != w: return self.url.setText(_qurl2text(url)) self.update_back_forward(w) def title_changed(self, w, title): if self.tabs.currentWidget() == w: self.tool_window.title = title i = self.tabs.indexOf(w) self.tabs.setTabText(i, title) def link_hovered(self, url): from PyQt5.QtCore import QUrl try: self.status(_qurl2text(QUrl(url))) except Exception: self.status(url) def tab_changed(self, i): if i >= 0: tab_text = self.tabs.tabText(i) if tab_text != "New Tab": self.tool_window.title = tab_text self.url.setText(_qurl2text(self.tabs.currentWidget().url())) else: # no more tabs self.display(False) self.update_back_forward() def close_tab(self, i): w = self.tabs.widget(i) self.tabs.removeTab(i) w.deleteLater() self.update_back_forward() def close_current_tab(self): i = self.tabs.currentIndex() if i != -1: self.close_tab(i) def cycle_tab(self, incr): i = self.tabs.currentIndex() if i == -1: return count = self.tabs.count() i = (i + incr) % count self.tabs.setCurrentIndex(i) def tab_n(self, n): count = self.tabs.count() if count == 0: return if n == -1: self.tabs.setCurrentIndex(count - 1) elif n < count: self.tabs.setCurrentIndex(n) def update_back_forward(self, w=None): if w is None: w = self.tabs.currentWidget() history = w.history() self.back.setEnabled(history.canGoBack()) self.forward.setEnabled(history.canGoForward()) @classmethod def get_viewer(cls, session, target=None): global _singleton if _singleton is None: _singleton = HelpUI(session) return _singleton
class SimulatorWindow(QMainWindow): def __init__(self, argv): QMainWindow.__init__(self) self.setWindowTitle("SimSo: Real-Time Scheduling Simulator") # Possible actions: style = QApplication.style() # New self._newAction = QAction( style.standardIcon(QStyle.SP_FileDialogNewFolder), '&New', None) self._newAction.setShortcut(Qt.CTRL + Qt.Key_N) self._newAction.triggered.connect(self.fileNew) # Open self._openAction = QAction( style.standardIcon(QStyle.SP_DialogOpenButton), '&Open', None) self._openAction.setShortcut(Qt.CTRL + Qt.Key_O) self._openAction.triggered.connect(self.fileOpen) # Save self._saveAction = QAction( style.standardIcon(QStyle.SP_DialogSaveButton), '&Save', None) self._saveAction.setShortcut(Qt.CTRL + Qt.Key_S) self._saveAction.triggered.connect(self.fileSave) # Save As self._saveAsAction = QAction( style.standardIcon(QStyle.SP_DialogSaveButton), 'Save &As', None) self._saveAsAction.setShortcut(Qt.CTRL + Qt.SHIFT + Qt.Key_S) self._saveAsAction.triggered.connect(self.fileSaveAs) # Run self._runAction = QAction( style.standardIcon(QStyle.SP_MediaPlay), '&Run', None) self._runAction.setShortcut(Qt.CTRL + Qt.Key_R) self._runAction.triggered.connect(self.fileRun) # Show Model data self._modelAction = QAction('&Model data', None) self._modelAction.setShortcut(Qt.CTRL + Qt.Key_M) #self._ganttAction.setCheckable(True) self._modelAction.triggered.connect(self.showModelWindow) # Show Gantt self._ganttAction = QAction('&Gantt', None) self._ganttAction.setShortcut(Qt.CTRL + Qt.Key_G) self._ganttAction.setEnabled(False) #self._ganttAction.setCheckable(True) self._ganttAction.triggered.connect(self.showGantt) # Show Results self._metricsAction = QAction('&Results', None) self._metricsAction.setShortcut(Qt.CTRL + Qt.Key_I) self._metricsAction.setEnabled(False) #self._metricsAction.setCheckable(True) self._metricsAction.triggered.connect(self.showResults) # Show Doc self._docAction = QAction('&Documentation', None) self._docAction.triggered.connect(self.showDocumentation) self._aboutAction = QAction('&About SimSo', None) self._aboutAction.triggered.connect(self.showAbout) # Recent files self._recentFileActions = [] for i in range(5): act = QAction(self) act.setVisible(False) act.triggered.connect(self.openRecentFile) self._recentFileActions.append(act) # File Menu: file_menu = QMenu('&File', self) file_menu.addAction(self._newAction) file_menu.addAction(self._openAction) file_menu.addAction(self._saveAction) file_menu.addAction(self._saveAsAction) file_menu.addAction(self._runAction) file_menu.addSeparator() for act in self._recentFileActions: file_menu.addAction(act) file_menu.addSeparator() file_menu.addAction('&Quit', self.fileQuit, Qt.CTRL + Qt.Key_Q) self.updateRecentFileActions() # View Menu: view_menu = QMenu('&View', self) view_menu.addAction(self._modelAction) view_menu.addAction(self._ganttAction) view_menu.addAction(self._metricsAction) # Help Menu: help_menu = QMenu('&Help', self) help_menu.addAction(self._docAction) help_menu.addAction(self._aboutAction) # Add menus to menuBar: self.menuBar().addMenu(file_menu) self.menuBar().addMenu(view_menu) self.menuBar().addMenu(help_menu) # ToolBar: self.toolBar = QToolBar("Main ToolBar") self.addToolBar(self.toolBar) self.toolBar.addAction(self._newAction) self.toolBar.addAction(self._openAction) self.toolBar.addAction(self._saveAction) self.toolBar.addAction(self._runAction) self.toolBar.addAction(self._ganttAction) self.toolBar.addAction(self._metricsAction) # Tab: self.main_tab = QTabWidget() self.main_tab.setTabsClosable(True) self.main_tab.setMovable(True) self.main_tab.tabCloseRequested.connect(self.tabCloseRequested) self.main_tab.currentChanged.connect(self.tabChanged) self.setCentralWidget(self.main_tab) # Init statusBar: self.statusBar().showMessage("", 2000) self._documentation = None if argv: for arg in argv: try: self.open_file(arg) except Exception as e: print(e) else: self.fileNew() def openRecentFile(self): try: self.open_file(self.sender().data().toString()) except AttributeError: self.open_file(self.sender().data()) def updateRecentFileActions(self): settings = QSettings() files = settings.value("recentFileList", defaultValue=[], type='QString') for i in range(5): if i < len(files): text = "&{} {}".format(i + 1, QFileInfo(files[i]).fileName()) self._recentFileActions[i].setText(text) self._recentFileActions[i].setData(files[i]) self._recentFileActions[i].setVisible(True) else: self._recentFileActions[i].setVisible(False) def setCurrentFile(self, filename): filename = QFileInfo(filename).absoluteFilePath() settings = QSettings() files = settings.value("recentFileList", defaultValue=[], type='QString') if filename in files: files.remove(filename) files.insert(0, filename) while len(files) > 5: del files[-1] settings.setValue("recentFileList", files) self.updateRecentFileActions() def showAbout(self): QMessageBox.about( self, "About SimSo", "<b>SimSo - Simulation of Multiprocessor Scheduling with Overheads</b><br/><br/>" "Version: SimSo {}, Graphical User Interface {}<br/><br/>" "SimSo is a free software developed by Maxime Cheramy (LAAS-CNRS).<br/>" "This software is distributed under the <a href='http://www.cecill.info'>CECILL license</a>, " "compatible with the GNU GPL.<br/><br/>" "Contact: <a href='mailto:[email protected]'>[email protected]</a>".format(simso.__version__, simsogui.__version__) ) def showDocumentation(self): if self._documentation is None: doc = QWebView(self) doc.load(QUrl("doc/html/index.html")) self._documentation = QDockWidget("Documentation", self) self._documentation.setWidget(doc) self._documentation.closeEvent = lambda _: self.hide_documentation() self.addDockWidget(Qt.LeftDockWidgetArea, self._documentation) def showGantt(self): self.main_tab.currentWidget().showGantt() def showModelWindow(self): self.main_tab.currentWidget().showModelWindow() def showResults(self): self.main_tab.currentWidget().showResults() def hide_documentation(self): self._documentation = None def fileNew(self): self.main_tab.addTab(SimulationTab(self), 'Unsaved') def fileOpen(self): simulation_file = QFileDialog.getOpenFileName( filter="*.xml", caption="Open XML simulation file.")[0] if simulation_file: self.open_file(simulation_file) def open_file(self, simulation_file): try: simulation_file = unicode(simulation_file) except NameError: pass try: self.setCurrentFile(simulation_file) sim = SimulationTab(self, simulation_file) if (self.main_tab.currentWidget() and not self.main_tab.currentWidget().simulation_file and self.main_tab.currentWidget().configuration.is_saved() and self.main_tab.count() == 1): self.main_tab.removeTab(0) self.main_tab.addTab(sim, os.path.split(simulation_file)[1]) self.main_tab.setCurrentWidget(sim) self.updateMenus() except Exception: QMessageBox.critical( self, "Could not open file", "The file {} could not be opened.".format(simulation_file)) print(traceback.format_exc()) def fileSave(self): try: self.main_tab.currentWidget().save() except: self.fileSaveAs() def fileSaveAs(self): simulation_file = QFileDialog.getSaveFileName( filter="*.xml", caption="Save XML simulation file.")[0] try: simulation_file = unicode(simulation_file) except NameError: pass if simulation_file: if simulation_file[-4:] != '.xml': simulation_file += '.xml' self.main_tab.currentWidget().save_as(simulation_file) self.setCurrentFile(simulation_file) def fileRun(self): self._runAction.setEnabled(False) self.main_tab.currentWidget().run() def fileQuit(self): self.close() def setTabText(self, tab, text): self.main_tab.setTabText(self.main_tab.indexOf(tab), text) def tabChanged(self, index): self.updateMenus() def tabCloseRequested(self, index): if self.main_tab.widget(index).close(): self.main_tab.removeTab(index) self.updateMenus() def closeEvent(self, event): while self.main_tab.count() > 0: if self.main_tab.widget(0).close(): self.main_tab.removeTab(0) else: event.ignore() return def updateMenus(self): if self.main_tab.count() > 0: widget = self.main_tab.currentWidget() self._runAction.setEnabled(True) self._modelAction.setEnabled(True) self._ganttAction.setEnabled(widget._model is not None) self._metricsAction.setEnabled(widget._model is not None) else: self._runAction.setEnabled(False) self._modelAction.setEnabled(False) self._ganttAction.setEnabled(False) self._metricsAction.setEnabled(False)
class TextQueue_Ui(QWidget): def __init__(self, persepolis_setting): super().__init__() self.persepolis_setting = persepolis_setting icons = ':/' + \ str(self.persepolis_setting.value('settings/icons')) + '/' # add support for other languages locale = str(self.persepolis_setting.value('settings/locale')) QLocale.setDefault(QLocale(locale)) self.translator = QTranslator() if self.translator.load(':/translations/locales/ui_' + locale, 'ts'): QCoreApplication.installTranslator(self.translator) # set ui direction ui_direction = self.persepolis_setting.value('ui_direction') if ui_direction == 'rtl': self.setLayoutDirection(Qt.RightToLeft) elif ui_direction in 'ltr': self.setLayoutDirection(Qt.LeftToRight) self.setWindowIcon( QIcon.fromTheme('persepolis', QIcon(':/persepolis.svg'))) window_verticalLayout = QVBoxLayout() self.setLayout(window_verticalLayout) # queue_tabWidget self.queue_tabWidget = QTabWidget(self) window_verticalLayout.addWidget(self.queue_tabWidget) # links_tab self.links_tab = QWidget() links_tab_verticalLayout = QVBoxLayout(self.links_tab) # link table self.links_table = QTableWidget(self.links_tab) links_tab_verticalLayout.addWidget(self.links_table) self.links_table.setSelectionBehavior(QAbstractItemView.SelectRows) self.links_table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.links_table.verticalHeader().hide() self.links_table.setColumnCount(3) links_table_header_labels = [ 'File Name', 'Download Link', 'dictionary' ] self.links_table.setHorizontalHeaderLabels(links_table_header_labels) self.links_table.setColumnHidden(2, True) self.links_table.horizontalHeader().setSectionResizeMode(0) self.links_table.horizontalHeader().setStretchLastSection(True) # add_queue add_queue_horizontalLayout = QHBoxLayout() self.select_all_pushButton = QPushButton(self.links_tab) add_queue_horizontalLayout.addWidget(self.select_all_pushButton) self.deselect_all_pushButton = QPushButton(self.links_tab) add_queue_horizontalLayout.addWidget(self.deselect_all_pushButton) add_queue_horizontalLayout.addStretch(1) self.add_queue_label = QLabel(self.links_tab) add_queue_horizontalLayout.addWidget(self.add_queue_label) self.add_queue_comboBox = QComboBox(self.links_tab) add_queue_horizontalLayout.addWidget(self.add_queue_comboBox) links_tab_verticalLayout.addLayout(add_queue_horizontalLayout) self.queue_tabWidget.addTab(self.links_tab, "") # options_tab self.options_tab = QWidget() options_tab_verticalLayout = QVBoxLayout(self.options_tab) # proxy proxy_verticalLayout = QVBoxLayout() self.proxy_checkBox = QCheckBox(self.options_tab) proxy_verticalLayout.addWidget(self.proxy_checkBox) self.proxy_frame = QFrame(self.options_tab) self.proxy_frame.setFrameShape(QFrame.StyledPanel) self.proxy_frame.setFrameShadow(QFrame.Raised) proxy_gridLayout = QGridLayout(self.proxy_frame) self.ip_lineEdit = QLineEdit(self.proxy_frame) self.ip_lineEdit.setInputMethodHints(QtCore.Qt.ImhNone) proxy_gridLayout.addWidget(self.ip_lineEdit, 0, 1, 1, 1) self.proxy_pass_label = QLabel(self.proxy_frame) proxy_gridLayout.addWidget(self.proxy_pass_label, 2, 2, 1, 1) self.proxy_pass_lineEdit = QLineEdit(self.proxy_frame) self.proxy_pass_lineEdit.setEchoMode(QLineEdit.Password) proxy_gridLayout.addWidget(self.proxy_pass_lineEdit, 2, 3, 1, 1) self.ip_label = QLabel(self.proxy_frame) proxy_gridLayout.addWidget(self.ip_label, 0, 0, 1, 1) self.proxy_user_lineEdit = QLineEdit(self.proxy_frame) proxy_gridLayout.addWidget(self.proxy_user_lineEdit, 0, 3, 1, 1) self.proxy_user_label = QLabel(self.proxy_frame) proxy_gridLayout.addWidget(self.proxy_user_label, 0, 2, 1, 1) self.port_label = QLabel(self.proxy_frame) proxy_gridLayout.addWidget(self.port_label, 2, 0, 1, 1) self.port_spinBox = QSpinBox(self.proxy_frame) self.port_spinBox.setMaximum(9999) self.port_spinBox.setSingleStep(1) proxy_gridLayout.addWidget(self.port_spinBox, 2, 1, 1, 1) proxy_verticalLayout.addWidget(self.proxy_frame) options_tab_verticalLayout.addLayout(proxy_verticalLayout) # download UserName & Password download_horizontalLayout = QHBoxLayout() download_horizontalLayout.setContentsMargins(-1, 10, -1, -1) download_verticalLayout = QVBoxLayout() self.download_checkBox = QCheckBox(self.options_tab) download_verticalLayout.addWidget(self.download_checkBox) self.download_frame = QFrame(self.options_tab) self.download_frame.setFrameShape(QFrame.StyledPanel) self.download_frame.setFrameShadow(QFrame.Raised) download_gridLayout = QGridLayout(self.download_frame) self.download_user_lineEdit = QLineEdit(self.download_frame) download_gridLayout.addWidget(self.download_user_lineEdit, 0, 1, 1, 1) self.download_user_label = QLabel(self.download_frame) download_gridLayout.addWidget(self.download_user_label, 0, 0, 1, 1) self.download_pass_label = QLabel(self.download_frame) download_gridLayout.addWidget(self.download_pass_label, 1, 0, 1, 1) self.download_pass_lineEdit = QLineEdit(self.download_frame) self.download_pass_lineEdit.setEchoMode(QLineEdit.Password) download_gridLayout.addWidget(self.download_pass_lineEdit, 1, 1, 1, 1) download_verticalLayout.addWidget(self.download_frame) download_horizontalLayout.addLayout(download_verticalLayout) # select folder self.folder_frame = QFrame(self.options_tab) self.folder_frame.setFrameShape(QFrame.StyledPanel) self.folder_frame.setFrameShadow(QFrame.Raised) folder_gridLayout = QGridLayout(self.folder_frame) self.download_folder_lineEdit = QLineEdit(self.folder_frame) folder_gridLayout.addWidget(self.download_folder_lineEdit, 2, 0, 1, 1) self.folder_pushButton = QPushButton(self.folder_frame) folder_gridLayout.addWidget(self.folder_pushButton, 3, 0, 1, 1) self.folder_pushButton.setIcon(QIcon(icons + 'folder')) self.folder_label = QLabel(self.folder_frame) self.folder_label.setAlignment(QtCore.Qt.AlignCenter) folder_gridLayout.addWidget(self.folder_label, 1, 0, 1, 1) download_horizontalLayout.addWidget(self.folder_frame) options_tab_verticalLayout.addLayout(download_horizontalLayout) self.queue_tabWidget.addTab(self.options_tab, '') # limit Speed limit_verticalLayout = QVBoxLayout() self.limit_checkBox = QCheckBox(self.options_tab) limit_verticalLayout.addWidget(self.limit_checkBox) self.limit_frame = QFrame(self.options_tab) self.limit_frame.setFrameShape(QFrame.StyledPanel) self.limit_frame.setFrameShadow(QFrame.Raised) limit_horizontalLayout = QHBoxLayout(self.limit_frame) self.limit_spinBox = QSpinBox(self.limit_frame) self.limit_spinBox.setMinimum(1) self.limit_spinBox.setMaximum(1023) limit_horizontalLayout.addWidget(self.limit_spinBox) self.limit_comboBox = QComboBox(self.limit_frame) self.limit_comboBox.addItem("KiB/S") self.limit_comboBox.addItem("MiB/S") limit_horizontalLayout.addWidget(self.limit_comboBox) limit_verticalLayout.addWidget(self.limit_frame) limit_connections_horizontalLayout = QHBoxLayout() limit_connections_horizontalLayout.addLayout(limit_verticalLayout) # number of connections connections_horizontalLayout = QHBoxLayout() connections_horizontalLayout.setContentsMargins(-1, 10, -1, -1) self.connections_frame = QFrame(self.options_tab) self.connections_frame.setFrameShape(QFrame.StyledPanel) self.connections_frame.setFrameShadow(QFrame.Raised) horizontalLayout_3 = QHBoxLayout(self.connections_frame) self.connections_label = QLabel(self.connections_frame) horizontalLayout_3.addWidget(self.connections_label) self.connections_spinBox = QSpinBox(self.connections_frame) self.connections_spinBox.setMinimum(1) self.connections_spinBox.setMaximum(16) self.connections_spinBox.setProperty("value", 16) horizontalLayout_3.addWidget(self.connections_spinBox) connections_horizontalLayout.addWidget(self.connections_frame) limit_connections_horizontalLayout.addLayout( connections_horizontalLayout) options_tab_verticalLayout.addLayout( limit_connections_horizontalLayout) # buttons buttons_horizontalLayout = QHBoxLayout() buttons_horizontalLayout.addStretch(1) # ok_pushButton self.ok_pushButton = QPushButton(self) self.ok_pushButton.setIcon(QIcon(icons + 'ok')) buttons_horizontalLayout.addWidget(self.ok_pushButton) # cancel_pushButton self.cancel_pushButton = QPushButton(self) self.cancel_pushButton.setIcon(QIcon(icons + 'remove')) buttons_horizontalLayout.addWidget(self.cancel_pushButton) window_verticalLayout.addLayout(buttons_horizontalLayout) # labels self.setWindowTitle( QCoreApplication.translate("text_ui_tr", "Persepolis Download Manager")) self.queue_tabWidget.setTabText( self.queue_tabWidget.indexOf(self.links_tab), QCoreApplication.translate("text_ui_tr", 'Links')) self.queue_tabWidget.setTabText( self.queue_tabWidget.indexOf(self.options_tab), QCoreApplication.translate("text_ui_tr", 'Download options')) self.select_all_pushButton.setText( QCoreApplication.translate("text_ui_tr", 'Select All')) self.deselect_all_pushButton.setText( QCoreApplication.translate("text_ui_tr", 'Deselect All')) self.add_queue_label.setText( QCoreApplication.translate("text_ui_tr", 'Add to queue: ')) self.proxy_checkBox.setText( QCoreApplication.translate("text_ui_tr", 'Proxy')) self.proxy_pass_label.setText( QCoreApplication.translate("text_ui_tr", "Proxy PassWord: "******"text_ui_tr", "IP:")) self.proxy_user_label.setText( QCoreApplication.translate("text_ui_tr", "Proxy UserName: "******"text_ui_tr", "Port:")) self.download_checkBox.setText( QCoreApplication.translate("text_ui_tr", "Download UserName and PassWord")) self.download_user_label.setText( QCoreApplication.translate("text_ui_tr", "Download UserName: "******"text_ui_tr", "Download PassWord: "******"text_ui_tr", "Change Download Folder")) self.folder_label.setText( QCoreApplication.translate("text_ui_tr", "Download Folder: ")) self.limit_checkBox.setText( QCoreApplication.translate("text_ui_tr", "Limit Speed")) self.connections_label.setText( QCoreApplication.translate("text_ui_tr", "Number Of Connections:")) self.ok_pushButton.setText( QCoreApplication.translate("text_ui_tr", 'OK')) self.cancel_pushButton.setText( QCoreApplication.translate("text_ui_tr", 'Cancel')) def changeIcon(self, icons): icons = ':/' + str(icons) + '/' self.ok_pushButton.setIcon(QIcon(icons + 'ok')) self.cancel_pushButton.setIcon(QIcon(icons + 'remove')) self.folder_pushButton.setIcon(QIcon(icons + 'folder'))
class TabWindow(QMainWindow): def __init__(self, app, **kwargs): super().__init__(None, **kwargs) self.app = app self.pages = {} self.menubar = None self.menuList = set() self.last_index = -1 self.previous_widget_actions = set() self._setupUi() self.app.willSavePrefs.connect(self.appWillSavePrefs) def _setupActions(self): # (name, shortcut, icon, desc, func) ACTIONS = [ ( "actionToggleTabs", "", "", tr("Show tab bar"), self.toggleTabBar, ), ] createActions(ACTIONS, self) self.actionToggleTabs.setCheckable(True) self.actionToggleTabs.setChecked(True) def _setupUi(self): self.setWindowTitle(self.app.NAME) self.resize(640, 480) self.tabWidget = QTabWidget() # self.tabWidget.setTabPosition(QTabWidget.South) self.tabWidget.setContentsMargins(0, 0, 0, 0) # self.tabWidget.setTabBarAutoHide(True) # This gets rid of the annoying margin around the TabWidget: self.tabWidget.setDocumentMode(True) self._setupActions() self._setupMenu() # This should be the same as self.centralWidget.setLayout(self.verticalLayout) self.verticalLayout = QVBoxLayout(self.tabWidget) # self.verticalLayout.addWidget(self.tabWidget) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.tabWidget.setTabsClosable(True) self.setCentralWidget(self.tabWidget) # only for QMainWindow self.tabWidget.currentChanged.connect(self.updateMenuBar) self.tabWidget.tabCloseRequested.connect(self.onTabCloseRequested) self.updateMenuBar(self.tabWidget.currentIndex()) self.restoreGeometry() def restoreGeometry(self): if self.app.prefs.mainWindowRect is not None: self.setGeometry(self.app.prefs.mainWindowRect) else: moveToScreenCenter(self) def _setupMenu(self): """Setup the menubar boiler plates which will be filled by the underlying tab's widgets whenever they are instantiated.""" self.menubar = self.menuBar( ) # QMainWindow, similar to just QMenuBar() here # self.setMenuBar(self.menubar) # already set if QMainWindow class self.menubar.setGeometry(QRect(0, 0, 100, 22)) self.menuFile = QMenu(self.menubar) self.menuFile.setTitle(tr("File")) self.menuMark = QMenu(self.menubar) self.menuMark.setTitle(tr("Mark")) self.menuActions = QMenu(self.menubar) self.menuActions.setTitle(tr("Actions")) self.menuColumns = QMenu(self.menubar) self.menuColumns.setTitle(tr("Columns")) self.menuView = QMenu(self.menubar) self.menuView.setTitle(tr("View")) self.menuHelp = QMenu(self.menubar) self.menuHelp.setTitle(tr("Help")) self.menuView.addAction(self.actionToggleTabs) self.menuView.addSeparator() self.menuList.add(self.menuFile) self.menuList.add(self.menuMark) self.menuList.add(self.menuActions) self.menuList.add(self.menuColumns) self.menuList.add(self.menuView) self.menuList.add(self.menuHelp) @pyqtSlot(int) def updateMenuBar(self, page_index=None): if page_index < 0: return current_index = self.getCurrentIndex() active_widget = self.getWidgetAtIndex(current_index) if self.last_index < 0: self.last_index = current_index self.previous_widget_actions = active_widget.specific_actions return page_type = type(active_widget).__name__ for menu in self.menuList: if menu is self.menuColumns or menu is self.menuActions or menu is self.menuMark: if not isinstance(active_widget, ResultWindow): menu.setEnabled(False) continue else: menu.setEnabled(True) for action in menu.actions(): if action not in active_widget.specific_actions: if action in self.previous_widget_actions: action.setEnabled(False) continue action.setEnabled(True) self.app.directories_dialog.actionShowResultsWindow.setEnabled( False if page_type == "ResultWindow" else self.app.resultWindow is not None) self.app.actionIgnoreList.setEnabled( True if self.app.ignoreListDialog is not None and not page_type == "IgnoreListDialog" else False) self.app.actionDirectoriesWindow.setEnabled( False if page_type == "DirectoriesDialog" else True) self.previous_widget_actions = active_widget.specific_actions self.last_index = current_index def createPage(self, cls, **kwargs): app = kwargs.get("app", self.app) page = None if cls == "DirectoriesDialog": page = DirectoriesDialog(app) elif cls == "ResultWindow": parent = kwargs.get("parent", self) page = ResultWindow(parent, app) elif cls == "IgnoreListDialog": parent = kwargs.get("parent", self) model = kwargs.get("model") page = IgnoreListDialog(parent, model) self.pages[cls] = page return page def addTab(self, page, title, switch=False): # Warning: this supposedly takes ownership of the page index = self.tabWidget.addTab(page, title) # index = self.tabWidget.insertTab(-1, page, title) if isinstance(page, DirectoriesDialog): self.tabWidget.tabBar().setTabButton(index, QTabBar.RightSide, None) if switch: self.setCurrentIndex(index) return index def showTab(self, page): index = self.indexOfWidget(page) self.setTabVisible(index, True) self.setCurrentIndex(index) def indexOfWidget(self, widget): return self.tabWidget.indexOf(widget) def setCurrentIndex(self, index): return self.tabWidget.setCurrentIndex(index) def setTabVisible(self, index, value): return self.tabWidget.setTabVisible(index, value) def removeTab(self, index): return self.tabWidget.removeTab(index) def isTabVisible(self, index): return self.tabWidget.isTabVisible(index) def getCurrentIndex(self): return self.tabWidget.currentIndex() def getWidgetAtIndex(self, index): return self.tabWidget.widget(index) def getCount(self): return self.tabWidget.count() # --- Events def appWillSavePrefs(self): # Right now this is useless since the first spawn dialog inside the # QTabWidget will assign its geometry after restoring it prefs = self.app.prefs prefs.mainWindowIsMaximized = self.isMaximized() prefs.mainWindowRect = self.geometry() def closeEvent(self, close_event): # Force closing of our tabbed widgets in reverse order so that the # directories dialog (which usually is at index 0) will be called last for index in range(self.getCount() - 1, -1, -1): self.getWidgetAtIndex(index).closeEvent(close_event) self.appWillSavePrefs() @pyqtSlot(int) def onTabCloseRequested(self, index): current_widget = self.getWidgetAtIndex(index) if isinstance(current_widget, DirectoriesDialog): # if we close this one, the application quits. Force user to use the # menu or shortcut. But this is useless if we don't have a button # set up to make a close request anyway. This check could be removed. return current_widget.close() self.setTabVisible(index, False) # self.tabWidget.widget(index).hide() self.removeTab(index) @pyqtSlot() def onDialogAccepted(self): """Remove tabbed dialog when Accepted/Done.""" widget = self.sender() index = self.indexOfWidget(widget) if index > -1: self.removeTab(index) @pyqtSlot() def toggleTabBar(self): value = self.sender().isChecked() self.actionToggleTabs.setChecked(value) self.tabWidget.tabBar().setVisible(value)
class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName(_fromUtf8("MainWindow")) MainWindow.resize(1010, 754) self.centralwidget = QWidget(MainWindow) self.centralwidget.setObjectName( _fromUtf8("centralwidget")) # do not change this name self.gridLayout = QGridLayout(self.centralwidget) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.splitter_2 = QSplitter(self.centralwidget) self.splitter_2.setOrientation(Qt.Vertical) self.splitter_2.setObjectName(_fromUtf8("splitter_2")) self.MainTabWidget = QTabWidget(self.splitter_2) self.MainTabWidget.setObjectName(_fromUtf8("MainTabWidget")) self.ScanTab = QWidget() self.ScanTab.setObjectName(_fromUtf8("ScanTab")) self.gridLayout_2 = QGridLayout(self.ScanTab) self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) self.splitter = QSplitter(self.ScanTab) self.splitter.setOrientation(Qt.Horizontal) self.splitter.setObjectName(_fromUtf8("splitter")) # size policies self.sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.sizePolicy.setHorizontalStretch( 0 ) # this specifies that the widget will keep its width when the window is resized self.sizePolicy.setVerticalStretch(0) self.sizePolicy2 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.sizePolicy2.setHorizontalStretch( 1 ) # this specifies that the widget will expand its width when the window is resized self.sizePolicy2.setVerticalStretch(0) self.setupLeftPanel() self.setupRightPanel() self.setupMainTabs() self.setupBottomPanel() self.gridLayout.addWidget(self.splitter_2, 0, 0, 1, 1) MainWindow.setCentralWidget(self.centralwidget) self.setupMenuBar(MainWindow) self.retranslateUi(MainWindow) self.setDefaultIndexes() QMetaObject.connectSlotsByName(MainWindow) def setupLeftPanel(self): self.HostsTabWidget = QTabWidget(self.splitter) self.sizePolicy.setHeightForWidth( self.HostsTabWidget.sizePolicy().hasHeightForWidth()) self.HostsTabWidget.setSizePolicy(self.sizePolicy) self.HostsTabWidget.setObjectName(_fromUtf8("HostsTabWidget")) self.HostsTab = QWidget() self.HostsTab.setObjectName(_fromUtf8("HostsTab")) self.keywordTextInput = QLineEdit() self.FilterApplyButton = QToolButton() self.searchIcon = QIcon() self.searchIcon.addPixmap(QPixmap(_fromUtf8("./images/search.png")), QIcon.Normal, QIcon.Off) self.FilterApplyButton.setIconSize(QSize(29, 21)) self.FilterApplyButton.setIcon(self.searchIcon) self.FilterAdvancedButton = QToolButton() self.advancedIcon = QIcon() self.advancedIcon.addPixmap( QPixmap(_fromUtf8("./images/advanced.png")), QIcon.Normal, QIcon.Off) self.FilterAdvancedButton.setIconSize(QSize(19, 19)) self.FilterAdvancedButton.setIcon(self.advancedIcon) self.vlayout = QVBoxLayout(self.HostsTab) self.vlayout.setObjectName(_fromUtf8("vlayout")) self.HostsTableView = QTableView(self.HostsTab) self.HostsTableView.setObjectName(_fromUtf8("HostsTableView")) self.vlayout.addWidget(self.HostsTableView) self.addHostsOverlay = QTextEdit( self.HostsTab ) # the overlay widget that appears over the hosttableview self.addHostsOverlay.setObjectName(_fromUtf8("addHostsOverlay")) self.addHostsOverlay.setText('Click here to add host(s) to scope') self.addHostsOverlay.setReadOnly(True) self.addHostsOverlay.setContextMenuPolicy(Qt.NoContextMenu) ### self.addHostsOverlay.setFont(QFont('', 12)) self.addHostsOverlay.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) ### self.vlayout.addWidget(self.addHostsOverlay) self.hlayout = QHBoxLayout() self.hlayout.addWidget(self.keywordTextInput) self.hlayout.addWidget(self.FilterApplyButton) self.hlayout.addWidget(self.FilterAdvancedButton) self.vlayout.addLayout(self.hlayout) self.HostsTabWidget.addTab(self.HostsTab, _fromUtf8("")) self.ServicesLeftTab = QWidget() self.ServicesLeftTab.setObjectName(_fromUtf8("ServicesLeftTab")) self.horizontalLayout_2 = QHBoxLayout(self.ServicesLeftTab) self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) self.ServiceNamesTableView = QTableView(self.ServicesLeftTab) self.ServiceNamesTableView.setObjectName( _fromUtf8("ServiceNamesTableView")) self.horizontalLayout_2.addWidget(self.ServiceNamesTableView) self.HostsTabWidget.addTab(self.ServicesLeftTab, _fromUtf8("")) self.ToolsTab = QWidget() self.ToolsTab.setObjectName(_fromUtf8("ToolsTab")) self.horizontalLayout_3 = QHBoxLayout(self.ToolsTab) self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3")) self.ToolsTableView = QTableView(self.ToolsTab) self.ToolsTableView.setObjectName(_fromUtf8("ToolsTableView")) self.horizontalLayout_3.addWidget(self.ToolsTableView) self.HostsTabWidget.addTab(self.ToolsTab, _fromUtf8("")) def setupRightPanel(self): self.ServicesTabWidget = QTabWidget() self.ServicesTabWidget.setEnabled(True) self.sizePolicy2.setHeightForWidth( self.ServicesTabWidget.sizePolicy().hasHeightForWidth()) self.ServicesTabWidget.setSizePolicy(self.sizePolicy2) self.ServicesTabWidget.setObjectName(_fromUtf8("ServicesTabWidget")) self.splitter.addWidget(self.ServicesTabWidget) ### self.splitter_3 = QSplitter() self.splitter_3.setOrientation(Qt.Horizontal) self.splitter_3.setObjectName(_fromUtf8("splitter_3")) self.splitter_3.setSizePolicy( self.sizePolicy2 ) # this makes the tools tab stay the same width when resizing the window ### self.ToolHostsWidget = QWidget() self.ToolHostsWidget.setObjectName(_fromUtf8("ToolHostsTab")) self.ToolHostsLayout = QVBoxLayout(self.ToolHostsWidget) self.ToolHostsLayout.setObjectName(_fromUtf8("verticalLayout")) self.ToolHostsTableView = QTableView(self.ToolHostsWidget) self.ToolHostsTableView.setObjectName(_fromUtf8("ServicesTableView")) self.ToolHostsLayout.addWidget(self.ToolHostsTableView) self.splitter_3.addWidget(self.ToolHostsWidget) self.DisplayWidget = QWidget() self.DisplayWidget.setObjectName('ToolOutput') self.DisplayWidget.setSizePolicy(self.sizePolicy2) #self.toolOutputTextView = QTextEdit(self.DisplayWidget) self.toolOutputTextView = QPlainTextEdit(self.DisplayWidget) self.toolOutputTextView.setReadOnly(True) self.DisplayWidgetLayout = QHBoxLayout(self.DisplayWidget) self.DisplayWidgetLayout.addWidget(self.toolOutputTextView) self.splitter_3.addWidget(self.DisplayWidget) self.ScreenshotWidget = ImageViewer() self.ScreenshotWidget.setObjectName('Screenshot') self.ScreenshotWidget.scrollArea.setSizePolicy(self.sizePolicy2) self.ScreenshotWidget.scrollArea.setContextMenuPolicy( Qt.CustomContextMenu) self.splitter_3.addWidget(self.ScreenshotWidget.scrollArea) self.splitter.addWidget(self.splitter_3) ### self.ServicesRightTab = QWidget() self.ServicesRightTab.setObjectName(_fromUtf8("ServicesRightTab")) self.verticalLayout = QVBoxLayout(self.ServicesRightTab) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.ServicesTableView = QTableView(self.ServicesRightTab) self.ServicesTableView.setObjectName(_fromUtf8("ServicesTableView")) self.verticalLayout.addWidget(self.ServicesTableView) self.ServicesTabWidget.addTab(self.ServicesRightTab, _fromUtf8("")) self.ScriptsTab = QWidget() self.ScriptsTab.setObjectName(_fromUtf8("ScriptsTab")) self.horizontalLayout_6 = QHBoxLayout(self.ScriptsTab) self.horizontalLayout_6.setObjectName(_fromUtf8("horizontalLayout_6")) self.splitter_4 = QSplitter(self.ScriptsTab) self.splitter_4.setOrientation(Qt.Horizontal) self.splitter_4.setObjectName(_fromUtf8("splitter_4")) self.ScriptsTableView = QTableView() self.ScriptsTableView.setObjectName(_fromUtf8("ScriptsTableView")) self.splitter_4.addWidget(self.ScriptsTableView) self.ScriptsOutputTextEdit = QPlainTextEdit() self.ScriptsOutputTextEdit.setObjectName( _fromUtf8("ScriptsOutputTextEdit")) self.ScriptsOutputTextEdit.setReadOnly(True) self.splitter_4.addWidget(self.ScriptsOutputTextEdit) self.horizontalLayout_6.addWidget(self.splitter_4) self.ServicesTabWidget.addTab(self.ScriptsTab, _fromUtf8("")) self.InformationTab = QWidget() self.InformationTab.setObjectName(_fromUtf8("InformationTab")) self.ServicesTabWidget.addTab(self.InformationTab, _fromUtf8("")) self.NotesTab = QWidget() self.NotesTab.setObjectName(_fromUtf8("NotesTab")) self.horizontalLayout_4 = QHBoxLayout(self.NotesTab) self.horizontalLayout_4.setObjectName(_fromUtf8("horizontalLayout_4")) #self.NotesTextEdit = QTextEdit(self.NotesTab) self.NotesTextEdit = QPlainTextEdit(self.NotesTab) self.NotesTextEdit.setObjectName(_fromUtf8("NotesTextEdit")) self.horizontalLayout_4.addWidget(self.NotesTextEdit) self.ServicesTabWidget.addTab(self.NotesTab, _fromUtf8("")) def setupMainTabs(self): self.gridLayout_2.addWidget(self.splitter, 0, 0, 1, 1) self.gridLayout_3 = QGridLayout() self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3")) self.gridLayout_2.addLayout(self.gridLayout_3, 0, 0, 1, 1) self.MainTabWidget.addTab(self.ScanTab, _fromUtf8("")) self.BruteTab = QWidget() self.BruteTab.setObjectName(_fromUtf8("BruteTab")) self.horizontalLayout_7 = QHBoxLayout(self.BruteTab) self.horizontalLayout_7.setObjectName(_fromUtf8("horizontalLayout_7")) self.BruteTabWidget = QTabWidget(self.BruteTab) self.BruteTabWidget.setObjectName(_fromUtf8("BruteTabWidget")) self.horizontalLayout_7.addWidget(self.BruteTabWidget) self.MainTabWidget.addTab(self.BruteTab, _fromUtf8("")) def setupBottomPanel(self): self.BottomTabWidget = QTabWidget(self.splitter_2) self.BottomTabWidget.setSizeIncrement(QSize(0, 0)) self.BottomTabWidget.setBaseSize(QSize(0, 0)) self.BottomTabWidget.setObjectName(_fromUtf8("BottomTabWidget")) self.LogTab = QWidget() self.LogTab.setObjectName(_fromUtf8("LogTab")) self.horizontalLayout_5 = QHBoxLayout(self.LogTab) self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5")) self.ProcessesTableView = QTableView(self.LogTab) self.ProcessesTableView.setObjectName(_fromUtf8("ProcessesTableView")) self.horizontalLayout_5.addWidget(self.ProcessesTableView) self.BottomTabWidget.addTab(self.LogTab, _fromUtf8("")) # self.TerminalTab = QWidget() # self.TerminalTab.setObjectName(_fromUtf8("TerminalTab")) # self.BottomTabWidget.addTab(self.TerminalTab, _fromUtf8("")) # self.PythonTab = QWidget() # self.PythonTab.setObjectName(_fromUtf8("PythonTab")) # self.BottomTabWidget.addTab(self.PythonTab, _fromUtf8("")) def setupMenuBar(self, MainWindow): self.menubar = QMenuBar(MainWindow) self.menubar.setGeometry(QRect(0, 0, 1010, 25)) self.menubar.setObjectName(_fromUtf8("menubar")) self.menuFile = QMenu(self.menubar) self.menuFile.setObjectName(_fromUtf8("menuFile")) # self.menuEdit = QMenu(self.menubar) # self.menuEdit.setObjectName(_fromUtf8("menuEdit")) # self.menuSettings = QMenu(self.menubar) # self.menuSettings.setObjectName(_fromUtf8("menuSettings")) self.menuHelp = QMenu(self.menubar) self.menuHelp.setObjectName(_fromUtf8("menuHelp")) MainWindow.setMenuBar(self.menubar) self.statusbar = QStatusBar(MainWindow) self.statusbar.setObjectName(_fromUtf8("statusbar")) MainWindow.setStatusBar(self.statusbar) self.actionExit = QAction(MainWindow) self.actionExit.setObjectName(_fromUtf8("actionExit")) self.actionOpen = QAction(MainWindow) self.actionOpen.setObjectName(_fromUtf8("actionOpen")) self.actionSave = QAction(MainWindow) self.actionSave.setObjectName(_fromUtf8("actionSave")) self.actionImportNmap = QAction(MainWindow) self.actionImportNmap.setObjectName(_fromUtf8("actionImportNmap")) self.actionSaveAs = QAction(MainWindow) self.actionSaveAs.setObjectName(_fromUtf8("actionSaveAs")) self.actionNew = QAction(MainWindow) self.actionNew.setObjectName(_fromUtf8("actionNew")) self.actionAddHosts = QAction(MainWindow) self.actionAddHosts.setObjectName(_fromUtf8("actionAddHosts")) self.menuFile.addAction(self.actionNew) self.menuFile.addAction(self.actionOpen) self.menuFile.addAction(self.actionSave) self.menuFile.addAction(self.actionSaveAs) self.menuFile.addSeparator() self.menuFile.addAction(self.actionAddHosts) self.menuFile.addAction(self.actionImportNmap) self.menuFile.addSeparator() self.menuFile.addAction(self.actionExit) self.menubar.addAction(self.menuFile.menuAction()) # self.menubar.addAction(self.menuEdit.menuAction()) # self.menubar.addAction(self.menuSettings.menuAction()) # self.menubar.addAction(self.menuSettings.menuAction()) # self.actionSettings = QAction(MainWindow) # self.actionSettings.setObjectName(_fromUtf8("getSettingsMenu")) # self.menuSettings.addAction(self.actionSettings) self.actionHelp = QAction(MainWindow) self.actionHelp.setObjectName(_fromUtf8("getHelp")) self.menuHelp.addAction(self.actionHelp) self.menubar.addAction(self.menuHelp.menuAction()) def setDefaultIndexes(self): self.MainTabWidget.setCurrentIndex(1) self.HostsTabWidget.setCurrentIndex(1) self.ServicesTabWidget.setCurrentIndex(1) self.BruteTabWidget.setCurrentIndex(1) self.BottomTabWidget.setCurrentIndex(0) def retranslateUi(self, MainWindow): MainWindow.setWindowTitle( QApplication.translate("MainWindow", "SPARTA 2.0", None)) self.HostsTabWidget.setTabText( self.HostsTabWidget.indexOf(self.HostsTab), QApplication.translate("MainWindow", "Hosts", None)) self.HostsTabWidget.setTabText( self.HostsTabWidget.indexOf(self.ServicesLeftTab), QApplication.translate("MainWindow", "Services", None)) self.HostsTabWidget.setTabText( self.HostsTabWidget.indexOf(self.ToolsTab), QApplication.translate("MainWindow", "Tools", None)) self.ServicesTabWidget.setTabText( self.ServicesTabWidget.indexOf(self.ServicesRightTab), QApplication.translate("MainWindow", "Services", None)) self.ServicesTabWidget.setTabText( self.ServicesTabWidget.indexOf(self.ScriptsTab), QApplication.translate("MainWindow", "Scripts", None)) self.ServicesTabWidget.setTabText( self.ServicesTabWidget.indexOf(self.InformationTab), QApplication.translate("MainWindow", "Information", None)) self.ServicesTabWidget.setTabText( self.ServicesTabWidget.indexOf(self.NotesTab), QApplication.translate("MainWindow", "Notes", None)) # self.ServicesTabWidget.setTabText(self.ServicesTabWidget.indexOf(self.ScreenshotsTab), QApplication.translate("MainWindow", "Screenshots", None)) self.MainTabWidget.setTabText( self.MainTabWidget.indexOf(self.ScanTab), QApplication.translate("MainWindow", "Scan", None)) #self.BruteTabWidget.setTabText(self.BruteTabWidget.indexOf(self.tab), QApplication.translate("MainWindow", "Tab 1", None)) #self.BruteTabWidget.setTabText(self.BruteTabWidget.indexOf(self.tab_2), QApplication.translate("MainWindow", "Tab 2", None)) self.MainTabWidget.setTabText( self.MainTabWidget.indexOf(self.BruteTab), QApplication.translate("MainWindow", "Brute", None)) self.BottomTabWidget.setTabText( self.BottomTabWidget.indexOf(self.LogTab), QApplication.translate("MainWindow", "Log", None)) # self.BottomTabWidget.setTabText(self.BottomTabWidget.indexOf(self.TerminalTab), QApplication.translate("MainWindow", "Terminal", None)) # self.BottomTabWidget.setTabText(self.BottomTabWidget.indexOf(self.PythonTab), QApplication.translate("MainWindow", "Python", None)) self.menuFile.setTitle( QApplication.translate("MainWindow", "File", None)) # self.menuEdit.setTitle(QApplication.translate("MainWindow", "Edit", None)) # self.menuSettings.setTitle(QApplication.translate("MainWindow", "Settings", None)) self.menuHelp.setTitle( QApplication.translate("MainWindow", "Help", None)) self.actionExit.setText( QApplication.translate("MainWindow", "Exit", None)) self.actionExit.setToolTip( QApplication.translate("MainWindow", "Exit the application", None)) self.actionExit.setShortcut( QApplication.translate("MainWindow", "Ctrl+Q", None)) self.actionOpen.setText( QApplication.translate("MainWindow", "Open", None)) self.actionOpen.setToolTip( QApplication.translate("MainWindow", "Open an existing project file", None)) self.actionOpen.setShortcut( QApplication.translate("MainWindow", "Ctrl+O", None)) self.actionSave.setText( QApplication.translate("MainWindow", "Save", None)) self.actionSave.setToolTip( QApplication.translate("MainWindow", "Save the current project", None)) self.actionSave.setShortcut( QApplication.translate("MainWindow", "Ctrl+S", None)) self.actionImportNmap.setText( QApplication.translate("MainWindow", "Import nmap", None)) self.actionImportNmap.setToolTip( QApplication.translate("MainWindow", "Import an nmap xml file", None)) self.actionImportNmap.setShortcut( QApplication.translate("MainWindow", "Ctrl+I", None)) self.actionSaveAs.setText( QApplication.translate("MainWindow", "Save As", None)) self.actionNew.setText( QApplication.translate("MainWindow", "New", None)) self.actionNew.setShortcut( QApplication.translate("MainWindow", "Ctrl+N", None)) self.actionAddHosts.setText( QApplication.translate("MainWindow", "Add host(s) to scope", None)) self.actionAddHosts.setShortcut( QApplication.translate("MainWindow", "Ctrl+H", None)) #self.actionSettings.setText(QApplication.translate("MainWindow", "Preferences", None)) self.actionHelp.setText( QApplication.translate("MainWindow", "Help", None)) self.actionHelp.setShortcut( QApplication.translate("MainWindow", "F1", None))
class Ui_Form(object): # Setup def setupUi(self, Form): # Links array self.links = [] Form.setObjectName("Form") # Window icon Form.setWindowIcon(QIcon("img/icon.ico")) # Unresizable Form.resize(397, 296) Form.setMaximumSize(397, 296) # Tab self.tabWidget = QTabWidget(Form) self.tabWidget.setGeometry(QRect(0, 0, 401, 301)) self.tabWidget.setStyleSheet("background-color: rgb(133, 181, 191);") self.tabWidget.setObjectName("tabWidget") self.tab_3 = QWidget() self.tab_3.setObjectName("tab_3") # Button to open github page self.githubButton = QPushButton(self.tab_3) self.githubButton.setGeometry(QRect(100, 0, 180, 120)) self.githubButton.setCursor(QCursor(Qt.OpenHandCursor)) self.githubButton.setIconSize(QSize(200, 120)) self.githubButton.setIcon(QIcon("img/GitHub.jpg")) self.githubButton.setObjectName("label") # Button to open telegram page self.telegramButton = QPushButton(self.tab_3) self.telegramButton.setGeometry(QRect(100, 140, 180, 120)) self.telegramButton.setCursor(QCursor(Qt.OpenHandCursor)) self.telegramButton.setText("") self.telegramButton.setIcon(QIcon("img/Telegram.jpg")) self.telegramButton.setIconSize(QSize(210, 120)) self.telegramButton.setObjectName("label_2") self.tabWidget.addTab(self.tab_3, "") self.tab_2 = QWidget() self.tab_2.setObjectName("tab_2") self.tab_1 = QWidget() self.tab_1.setObjectName("tab_1") # Text next to url entry self.urlText = QLabel(self.tab_2) self.urlText.setGeometry(QRect(10, 10, 111, 31)) font = QFont() font.setFamily("Berlin Sans FB") font.setPointSize(15) font.setBold(True) font.setWeight(75) self.urlText.setFont(font) self.urlText.setObjectName("urlText") # Text entry to get url self.url = QPlainTextEdit(self.tab_2) self.url.setGeometry(QRect(150, 10, 181, 41)) font = QFont() font.setFamily("Berlin Sans FB") font.setPointSize(15) font.setBold(False) font.setWeight(50) self.url.setFont(font) self.url.viewport().setProperty("cursor", QCursor(Qt.IBeamCursor)) self.url.setObjectName("url") # Text next to filter key text entry self.filterText = QLabel(self.tab_2) self.filterText.setGeometry(QRect(10, 50, 121, 61)) font = QFont() font.setFamily("Berlin Sans FB") font.setPointSize(15) font.setBold(True) font.setWeight(75) self.filterText.setFont(font) self.filterText.setWordWrap(True) self.filterText.setObjectName("filterText") # Filter key entry self.contain = QPlainTextEdit(self.tab_2) self.contain.setGeometry(QRect(150, 50, 181, 61)) font = QFont() font.setFamily("Berlin Sans FB") font.setPointSize(15) self.contain.setFont(font) self.contain.viewport().setProperty("cursor", QCursor(Qt.IBeamCursor)) self.contain.setObjectName("contain") # Button to submit url self.urlButton = QPushButton(self.tab_2) self.urlButton.setGeometry(QRect(340, 10, 41, 41)) font = QFont() font.setFamily("Berlin Sans FB") font.setPointSize(10) font.setBold(True) font.setWeight(75) self.urlButton.setFont(font) self.urlButton.setCursor(QCursor(Qt.OpenHandCursor)) self.urlButton.setText("OK") self.urlButton.setObjectName("urlButton") # Button to submit filter key self.filterButton = QPushButton(self.tab_2) self.filterButton.setEnabled(False) self.filterButton.setGeometry(QRect(340, 60, 41, 41)) font = QFont() font.setFamily("Berlin Sans FB") font.setPointSize(10) font.setBold(True) font.setWeight(75) self.filterButton.setFont(font) self.filterButton.setCursor(QCursor(Qt.OpenHandCursor)) self.filterButton.setText("OK") self.filterButton.setObjectName("filterButton") # "RESULTS" label self.resultText = QLabel(self.tab_2) self.resultText.setGeometry(QRect(10, 120, 50, 50)) font.setBold(True) font.setPointSize(15) self.resultText.setFont(font) self.resultText.setText("RESULTS") self.resultText.adjustSize() self.resultText.setObjectName("resultText") font = QFont() font.setFamily("Berlin Sans FB") font.setPointSize(15) font.setBold(True) font.setWeight(75) # Creating scroll label self.label = ScrollLabel(self.tab_2) self.label.setGeometry(10, 150, 300, 100) # Button to open url self.pushButton = QPushButton(self.tab_2) self.pushButton.setEnabled(False) self.pushButton.setGeometry(QRect(100, 125, 70, 20)) font = QFont() font.setFamily("Berlin Sans FB") font.setPointSize(10) font.setBold(True) font.setWeight(75) self.pushButton.setFont(font) self.pushButton.setCursor(QCursor(Qt.OpenHandCursor)) self.pushButton.setObjectName("pushButton") # Title of help text self.help_title_label = QLabel(self.tab_1) self.help_title_label.setText("HOW TO USE ?") self.help_title_label.move(10, 10) self.help_title_label.setFont(font) self.help_label = QLabel(self.tab_1) font.setBold(False) font.setPointSize(12) # Help text helpText = "OPEN LINK COLLECTOR TAB AND WRITE THE URL \nTHAT YOU WANT FIND LINKS. THEN CLICK OK BUTTON.\n\nTO FILTER LINKS, WRITE WHICH SHOULD LINK \nCONTAIN TO THE TEXT ENTRY.\n\nTO OPEN A URL WRITE WRITE INDEX OF URL TO \nPOP UP DIALOG AND CLICK OK." # Help text label self.help_label.setFont(font) self.help_label.move(10, 30) self.help_label.setText(helpText) self.help_label.setWordWrap(True) # Add tabs self.tabWidget.addTab(self.tab_1, "") self.tabWidget.addTab(self.tab_2, "") self.tabWidget.addTab(self.tab_3, "") self.retranslateUi(Form) #Set current tab self.tabWidget.setCurrentIndex(0) QMetaObject.connectSlotsByName(Form) # Method to open github page def github(self): open("https://github.com/SukruGokk") # Method to open telegram page def telegram(self): open("https://t.me/SukruGokk") # Method for get urls def connect(self): # Get link from user with input url = self.url.document().toPlainText() # Try to connect try: # Connect r = get(url) # Parse page's codes soup = BS(r.content, "lxml") # Get links from site content for link in soup.findAll('a'): # If it doesnt contains http, dont but if it contains append if str(link.get('href')).find("http") == -1: pass else: self.links.append(link.get('href')) # Enable button to submit filter key self.filterButton.setEnabled(True) # String of links self.strLinks = "" # Add list's elements to string num = 1 for i in self.links: self.strLinks += str(num) self.strLinks += " " self.strLinks += i self.strLinks += '\n' num += 1 # Display urls self.label.setText(self.strLinks) self.filteredLinks = self.links # Enable open link button self.pushButton.setEnabled(True) # If url if invalid except: # Show error message msg = QMessageBox() msg.setIcon(QMessageBox.Critical) msg.setText("INVALID URL") msg.setWindowTitle("ERROR") msg.setFont(QFont("Berlin Sans FB", 20, 17)) msg.exec_() # Filter the links according to filter key def filterLinks(self): self.filterKey = self.contain.document().toPlainText() self.filteredLinks = [] for i in self.links: if i.find(self.filterKey) != -1: self.filteredLinks.append(i) num = 1 self.strLinks = "" for i in self.filteredLinks: self.strLinks += str(num) self.strLinks += " " self.strLinks += i self.strLinks += '\n' num += 1 self.label.setText(self.strLinks) # Open selected link def openLink(self): text, okPressed = QInputDialog.getText(self.tab_2, "NUMBER OF URL", "NUMBER: ", QLineEdit.Normal, "") # Open url try: if okPressed: open(self.filteredLinks[int(text)-1]) # If index is invalid except: msg = QMessageBox() msg.setIcon(QMessageBox.Critical) msg.setText("INVALID") msg.setFont(QFont("Berlin Sans FB", 20, 17)) msg.setWindowTitle("INVALID") msg.exec_() # Retranslate method def retranslateUi(self, Form): _translate = QCoreApplication.translate # Set title Form.setWindowTitle("LINK COLLECTOR") # Set tab text self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_1), _translate("Form", "HELP")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("Form", "LINK COLLECTOR")) self.urlText.setText(_translate("Form", "WRITE URL")) self.filterText.setText(_translate("Form", "What should link contain")) self.pushButton.setText(_translate("Form", "OPEN LINK")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("Form", "DEVELOPER")) self.url.document().setPlainText("https://") # Onlick events self.urlButton.clicked.connect(self.connect) self.filterButton.clicked.connect(self.filterLinks) self.pushButton.clicked.connect(self.openLink) self.githubButton.clicked.connect(self.github) self.telegramButton.clicked.connect(self.telegram)
class Ui_MainWindow(object): def setupUi(self, MainWindow): if not MainWindow.objectName(): MainWindow.setObjectName(u"MainWindow") MainWindow.resize(1000, 800) self.centralwidget = QWidget(MainWindow) self.centralwidget.setObjectName(u"centralwidget") self.gridLayout = QGridLayout(self.centralwidget) self.gridLayout.setSpacing(5) self.gridLayout.setObjectName(u"gridLayout") self.gridLayout.setContentsMargins(10, 10, 10, 10) self.lineEdit = QLineEdit(self.centralwidget) self.lineEdit.setObjectName(u"lineEdit") regex = QtCore.QRegExp("^[0-9A-Za-z]{4}( [0-9A-Za-z]{4})*") validator = QtGui.QRegExpValidator(regex) self.lineEdit.setValidator(validator) self.gridLayout.addWidget(self.lineEdit, 0, 0, 1, 1) self.getMETAR = QPushButton(self.centralwidget) self.getMETAR.setObjectName(u"getMETAR") self.gridLayout.addWidget(self.getMETAR, 0, 1, 1, 1) self.clearButton = QPushButton(self.centralwidget) self.clearButton.setObjectName(u"clearButton") self.gridLayout.addWidget(self.clearButton, 0, 2, 1, 1) # Maintab self.tabWidget = QTabWidget(self.centralwidget) self.tabWidget.setObjectName(u"tabWidget") #Tab METAR self.tab_1 = QWidget() self.tab_1.setObjectName(u"tab_1") self.gridLayout_2 = QGridLayout(self.tab_1) self.gridLayout_2.setObjectName(u"gridLayout_2") self.tableWidget = QTableWidget(self.tab_1) self.tableWidget.setObjectName(u"tableWidget") self.tableWidget.setColumnCount(3) self.tableWidget.setRowCount(0) self.tableWidget.horizontalHeader().setCascadingSectionResizes(True) self.tableWidget.horizontalHeader().setVisible(True) self.tableWidget.verticalHeader().setVisible(False) self.tableWidget.setHorizontalHeaderLabels( [u"ICAO", u"TIME", u"METAR CODE"]) self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) self.gridLayout_2.addWidget(self.tableWidget, 0, 0, 1, 1) self.tabWidget.addTab(self.tab_1, "") self.textBrowser = QtWidgets.QTextBrowser(self.tab_1) self.textBrowser.setObjectName("textBrowser") self.gridLayout_2.addWidget(self.textBrowser, 1, 0, 1, 1) self.tabWidget.addTab(self.tab_1, "") #Tab_METAR_END #Tab_TAF self.tab_2 = QWidget() self.tab_2.setObjectName(u"tab_2") self.gridLayout_3 = QGridLayout(self.tab_2) self.gridLayout_3.setObjectName(u"gridLayout_3") self.textBrowser_3 = QtWidgets.QTextBrowser(self.tab_2) self.textBrowser_3.setObjectName("textBrowser_3") self.gridLayout_3.addWidget(self.textBrowser_3, 1, 0, 1, 1) self.tabWidget.addTab(self.tab_2, "") #Tab_TAF_END self.tab_3 = QWidget() self.tab_3.setObjectName(u"tab_3") self.gridLayout_4 = QGridLayout(self.tab_3) self.gridLayout_4.setObjectName(u"gridLayout_4") self.tableWidget_3 = QTableWidget(self.tab_3) self.tableWidget_3.setObjectName(u"tableWidget_3") self.gridLayout_4.addWidget(self.tableWidget_3, 0, 0, 1, 1) self.tabWidget.addTab(self.tab_3, "") self.gridLayout.addWidget(self.tabWidget, 2, 0, 1, 1) #Maintab_END self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout.setObjectName("verticalLayout") self.checkBox = QtWidgets.QCheckBox(self.centralwidget) self.checkBox.setEnabled(True) self.checkBox.setStatusTip("") self.checkBox.setChecked(True) self.checkBox.setTristate(False) self.checkBox.setObjectName("checkBox") self.verticalLayout.addWidget(self.checkBox) self.checkBox_2 = QtWidgets.QCheckBox(self.centralwidget) self.checkBox_2.setObjectName("checkBox_2") self.verticalLayout.addWidget(self.checkBox_2) self.checkBox_3 = QtWidgets.QCheckBox(self.centralwidget) self.checkBox_3.setObjectName("checkBox_3") self.verticalLayout.addWidget(self.checkBox_3) self.gridLayout.addLayout(self.verticalLayout, 2, 1, 1, 2) #WIP self.checkBox.setChecked(True) self.checkBox.setDisabled(True) self.checkBox_2.setChecked(True) self.checkBox_2.setDisabled(True) self.checkBox_3.setDisabled(True) #END_WIP MainWindow.setCentralWidget(self.centralwidget) self.menubar = QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 294, 29)) self.menubar.setObjectName("menubar") self.menuFile = QMenu(self.menubar) self.menuFile.setObjectName("menuFile") MainWindow.setMenuBar(self.menubar) self.statusbar = QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.actionQuit = QAction(MainWindow) self.actionQuit.setObjectName("actionQuit") self.menuFile.addAction(self.actionQuit) self.menubar.addAction(self.menuFile.menuAction()) self.retranslateUi(MainWindow) self.actionQuit.triggered.connect(MainWindow.close) self.tabWidget.setCurrentIndex(0) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "METAR")) self.menuFile.setTitle(_translate("MainWindow", "Fi&le")) self.actionQuit.setText(_translate("MainWindow", "&Quit")) self.getMETAR.setText( QCoreApplication.translate("MainWindow", u"GET", None)) self.clearButton.setText( QCoreApplication.translate("MainWindow", u"CLEAR", None)) self.tabWidget.setTabText( self.tabWidget.indexOf(self.tab_1), QCoreApplication.translate("MainWindow", u"METAR", None)) self.tabWidget.setTabText( self.tabWidget.indexOf(self.tab_2), QCoreApplication.translate("MainWindow", u"TAF", None)) self.tabWidget.setTabText( self.tabWidget.indexOf(self.tab_3), QCoreApplication.translate("MainWindow", u"NOTAM", None)) self.checkBox_2.setText( QCoreApplication.translate("MainWindow", u"TAF", None)) self.checkBox_3.setText( QCoreApplication.translate("MainWindow", u"NOTAM", None)) self.checkBox.setText( QCoreApplication.translate("MainWindow", u"METAR", None))
class Ui_MainWindow(QMainWindow): def __init__(self): super().__init__() self.initUI() def initUI(self): self.transprot_mass =[] self.netprot_mass =[] self.filtering_is_on = 0 grid = QGridLayout() self.setLayout(grid) self.IP_list = IP_list(self) self.TransProt_list = TransProt_list(self) self.NetProt_list = NetProt_list(self) self.setWindowTitle('Гамма') self.setWindowIcon(QIcon('допочки\Gamma_200x200.png')) self.resize(740, 830) self.to_center() self.centralwidget = QWidget(self) self.tabWidget = QTabWidget(self.centralwidget) self.tabWidget.setGeometry(QRect(20, 20, 700, 750)) self.tab = QWidget() grid.addWidget(self.tab) self.cb_time = QCheckBox(self.tab) self.cb_time.setGeometry(QRect(360, 130, 120, 20)) self.cb_time.setText("Фильтр по времени") self.cb_prot = QCheckBox(self.tab) self.cb_prot.setGeometry(QRect(20, 130, 140, 20)) self.cb_prot.setText("Фильтр по протоколам") self.cb_addr = QCheckBox(self.tab) self.cb_addr.setGeometry(QRect(360, 290, 130, 20)) self.cb_addr.setText("Фильтр по IP-адресам") self.dt_beg = QDateTimeEdit(self.tab) self.dt_beg.setGeometry(QRect(360, 210, 150, 20)) self.dt_beg.setDateTime(QDateTime.currentDateTime()) self.dt_beg.setDisplayFormat("dd.MM.yyyy H:mm:ss.zzz") self.dt_beg.setCalendarPopup(True) self.dt_beg.setToolTip('Выбрать начальное время (>=)') self.dt_beg.setEnabled(False) self.dt_end = QDateTimeEdit(self.tab) self.dt_end.setGeometry(QRect(520, 210, 150, 20)) self.dt_end.setDateTime(QDateTime.currentDateTime()) self.dt_end.setDisplayFormat("dd.MM.yyyy H:mm:ss.zzz") self.dt_end.setCalendarPopup(True) self.dt_end.setToolTip('Выбрать конечное время (<)') self.dt_end.setEnabled(False) self.dt_beg.dateChanged.connect(lambda dc: self.date_changed(1)) self.dt_end.dateChanged.connect(lambda dc: self.date_changed(2)) #self.l_input_dir = QLabel(self.tab) #self.l_input_dir.setGeometry(QRect(102, 50, 180, 15)) #self.l_input_dir.setText("Выберите директорию с файлами") #self.l_or = QLabel(self.tab) #self.l_or.setGeometry(QRect(340, 50, 21, 16)) #self.l_or.setText("ИЛИ") self.l_input_file = QLabel(self.tab) self.l_input_file.setGeometry(QRect(300, 50, 90, 15)) self.l_input_file.setText("Выберите файлы") self.l_transpr = QLabel(self.tab) self.l_transpr.setGeometry(QRect(50, 190, 180, 16)) self.l_transpr.setEnabled(False) self.l_transpr.setText("Протоколы Транспортного уровня") self.l_netpr = QLabel(self.tab) self.l_netpr.setGeometry(QRect(50, 290, 180, 16)) self.l_netpr.setEnabled(False) self.l_netpr.setText("Протоколы Сетевого уровня") self.l_beg = QLabel(self.tab) self.l_beg.setGeometry(QRect(390, 190, 60, 16)) self.l_beg.setEnabled(False) self.l_beg.setText("Начиная с..") self.l_end = QLabel(self.tab) self.l_end.setGeometry(QRect(560, 190, 80, 16)) self.l_end.setEnabled(False) self.l_end.setText("Оканчивая до..") self.l_name = QLabel(self.tab) self.l_name.setGeometry(QRect(300, 450, 96, 16)) self.l_name.setText("Как назвать файл?") self.l_filt = QLabel(self.tab) self.l_filt.setGeometry(QRect(300, 10, 91, 16)) self.l_filt.setText("Выборка пакетов") self.line = QFrame(self.tab) self.line.setGeometry(QRect(0, 110, 690, 15)) self.line.setFrameShape(QFrame.HLine) self.line.setFrameShadow(QFrame.Sunken) self.line_2 = QFrame(self.tab) self.line_2.setGeometry(QRect(340, 120, 15, 300)) self.line_2.setFrameShape(QFrame.VLine) self.line_2.setFrameShadow(QFrame.Sunken) self.line_3 = QFrame(self.tab) self.line_3.setGeometry(QRect(0, 420, 690, 15)) self.line_3.setFrameShape(QFrame.HLine) self.line_3.setFrameShadow(QFrame.Sunken) #self.le_dir = QLineEdit(self.tab) #self.le_dir.setGeometry(QRect(110, 80, 211, 20)) #self.le_dir.setEnabled(False) #self.le_dir.setReadOnly(True) self.le_file = QLineEdit(self.tab) self.le_file.setGeometry(QRect(250, 80, 211, 20)) #self.le_file.setEnabled(False) self.le_file.setReadOnly(True) self.le_name = QLineEdit(self.tab) self.le_name.setGeometry(QRect(250, 480, 231, 20)) self.pt_transpr = QPlainTextEdit(self.tab) self.pt_transpr.setGeometry(QRect(50, 210, 271, 71)) self.pt_transpr.setEnabled(False) self.pt_transpr.setReadOnly(True) self.pt_netpr = QPlainTextEdit(self.tab) self.pt_netpr.setGeometry(QRect(50, 320, 271, 71)) self.pt_netpr.setEnabled(False) self.pt_netpr.setReadOnly(True) self.pt_addr = QPlainTextEdit(self.tab) self.pt_addr.setGeometry(QRect(390, 320, 271, 71)) self.pt_addr.setEnabled(False) self.pt_log = QPlainTextEdit(self.tab) self.pt_log.setGeometry(QRect(20, 610, 651, 101)) self.pt_log.setReadOnly(True) self.progressBar = QProgressBar(self.tab) self.progressBar.setGeometry(QRect(20, 580, 651, 20)) self.progressBar.setFormat("%v" + "%") self.progressBar.setMaximum(100) self.progressBar.setValue(0) #self.pb_dir = QPushButton(self.tab) #self.pb_dir.setGeometry(QRect(80, 80, 21, 20)) #self.pb_dir.setIcon(QIcon('допочки\_folder.png')) #self.pb_dir.clicked.connect(lambda gd: self.get_directory(1)) self.pb_file = QPushButton(self.tab) self.pb_file.setGeometry(QRect(220, 80, 21, 20)) self.pb_file.setIcon(QIcon('допочки\_folder.png')) self.pb_file.clicked.connect(lambda gf: self.get_files(1)) self.pb_time = QPushButton(self.tab) self.pb_time.setGeometry(QRect(480, 240, 71, 20)) self.pb_time.setToolTip('Добавить ещё временной отрезок') self.pb_time.setEnabled(False) self.pb_time.setText("Ещё!") self.pb_transpr = QPushButton(self.tab) self.pb_transpr.setGeometry(QRect(20, 210, 21, 20)) self.pb_transpr.setToolTip('Выбрать протоколы Транспортного уровня') self.pb_transpr.setIcon(QIcon('допочки\_blank.png')) self.pb_transpr.setEnabled(False) self.pb_transpr.clicked.connect(self.TransProt_list.exec) self.pb_netpr = QPushButton(self.tab) self.pb_netpr.setGeometry(QRect(20, 320, 21, 20)) self.pb_netpr.setToolTip('Выбрать протоколы Сетевого уровня') self.pb_netpr.setIcon(QIcon('допочки\_blank.png')) self.pb_netpr.setEnabled(False) self.pb_netpr.clicked.connect(self.NetProt_list.exec) self.pb_addr = QPushButton(self.tab) self.pb_addr.setGeometry(QRect(530, 290, 132, 20)) self.pb_addr.setText('Редактировать список') self.pb_addr.setEnabled(False) self.pb_addr.clicked.connect(self.IP_list.exec) self.pb_name = QPushButton(self.tab) self.pb_name.setGeometry(QRect(220, 480, 21, 20)) self.pb_name.setIcon(QIcon('допочки\_folder.png')) self.pb_name.clicked.connect(lambda ed: self.extract_to_directory(1)) self.pb_start = QPushButton(self.tab) self.pb_start.setGeometry(QRect(220, 510, 261, 41)) self.pb_start.setText("Начать выборку") self.pb_start.clicked.connect(self.do_it_motherFucker) #self.radiobutton = QRadioButton(self.tab) #self.radiobutton.setGeometry(QRect(84, 48, 20, 20)) #self.radiobutton_2 = QRadioButton(self.tab) #self.radiobutton_2.setGeometry(QRect(424, 48, 20, 20)) #self.radiobutton.raise_() #self.radiobutton_2.raise_() self.cb_time.raise_() self.cb_prot.raise_() self.cb_addr.raise_() self.dt_beg.raise_() self.dt_end.raise_() #self.l_input_dir.raise_() #self.l_or.raise_() self.l_input_file.raise_() self.l_transpr.raise_() self.l_netpr.raise_() self.l_beg.raise_() self.l_end.raise_() self.l_name.raise_() self.l_filt.raise_() self.line.raise_() self.line_2.raise_() self.line_3.raise_() #self.le_dir.raise_() self.le_file.raise_() self.le_name.raise_() self.pt_transpr.raise_() self.pt_netpr.raise_() self.pt_addr.raise_() self.pt_log.raise_() self.progressBar.raise_() #self.pb_dir.raise_() self.pb_file.raise_() self.pb_time.raise_() self.pb_transpr.raise_() self.pb_netpr.raise_() self.pb_addr.raise_() self.pb_name.raise_() self.pb_start.raise_() self.setCentralWidget(self.centralwidget) self.statusbar = QStatusBar(self) self.setStatusBar(self.statusbar) self.tabWidget.addTab(self.tab, "") self.cb_time.clicked['bool'].connect(self.dt_beg.setEnabled) self.cb_time.clicked['bool'].connect(self.dt_end.setEnabled) self.cb_time.clicked['bool'].connect(self.l_beg.setEnabled) self.cb_time.clicked['bool'].connect(self.l_end.setEnabled) self.cb_prot.clicked['bool'].connect(self.l_transpr.setEnabled) self.cb_prot.clicked['bool'].connect(self.l_netpr.setEnabled) self.cb_prot.clicked['bool'].connect(self.pt_transpr.setEnabled) self.cb_prot.clicked['bool'].connect(self.pt_netpr.setEnabled) self.cb_prot.clicked['bool'].connect(self.pb_transpr.setEnabled) self.cb_prot.clicked['bool'].connect(self.pb_netpr.setEnabled) self.cb_addr.clicked['bool'].connect(self.pt_addr.setEnabled) self.cb_addr.clicked['bool'].connect(self.pb_addr.setEnabled) #####------------------------------2_TAB self.tab_2 = QWidget() self.tabWidget.addTab(self.tab_2, "") self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), ("II работа с файлами")) self.l_merge = QLabel(self.tab_2) self.l_merge.setGeometry(QRect(300, 10, 180, 16)) self.l_merge.setText("Объединение файлов") self.l_arch = QLabel(self.tab_2) self.l_arch.setGeometry(QRect(300, 250, 180, 16)) self.l_arch.setText("Архивирование файлов") #self.radiobutton_3 = QRadioButton(self.tab_2) #self.radiobutton_3.setGeometry(QRect(84, 48, 20, 20)) #self.radiobutton_4 = QRadioButton(self.tab_2) #self.radiobutton_4.setGeometry(QRect(424, 48, 20, 20)) #self.l_input_dir2 = QLabel(self.tab_2) #self.l_input_dir2.setGeometry(QRect(102, 50, 180, 15)) #self.l_input_dir2.setText("Выберите директорию с файлами") #self.l_or2 = QLabel(self.tab_2) #self.l_or2.setGeometry(QRect(340, 50, 21, 16)) #self.l_or2.setText("ИЛИ") self.l_input_file2 = QLabel(self.tab_2) self.l_input_file2.setGeometry(QRect(102, 50, 180, 15))#442, 50, 90, 15)) self.l_input_file2.setText("Выберите файлы") self.l_name2 = QLabel(self.tab_2) self.l_name2.setGeometry(QRect(442, 50, 180, 15))#280, 140, 180, 16)) self.l_name2.setText("Куда сохранить результат?") self.l_ciph2 = QLabel(self.tab_2) self.l_ciph2.setGeometry(QRect(84, 298, 180, 15)) self.l_ciph2.setText("Убрать шифрованный трафик") self.l_arch2 = QLabel(self.tab_2) self.l_arch2.setGeometry(QRect(424, 298, 180, 15)) self.l_arch2.setText("Заархивировать файлы") #self.le_dir2 = QLineEdit(self.tab_2) #self.le_dir2.setGeometry(QRect(110, 80, 211, 20)) #self.le_dir2.setEnabled(False) self.le_file2 = QLineEdit(self.tab_2) self.le_file2.setGeometry(QRect(110, 80, 211, 20))#450, 80, 211, 20)) self.le_file2.setReadOnly(True) self.le_name2 = QLineEdit(self.tab_2) self.le_name2.setGeometry(QRect(450, 80, 211, 20))#260, 170, 180, 20)) #self.pb_dir2 = QPushButton(self.tab_2) #self.pb_dir2.setGeometry(QRect(80, 80, 21, 20)) #self.pb_dir2.setIcon(QIcon('допочки\_folder.png')) #self.pb_dir2.clicked.connect(lambda gd: self.get_directory(2)) self.pb_file2 = QPushButton(self.tab_2) self.pb_file2.setGeometry(QRect(80, 80, 21, 20))#420, 80, 21, 20)) self.pb_file2.setIcon(QIcon('допочки\_folder.png')) self.pb_file2.clicked.connect(lambda gf: self.get_files(2)) self.pb_name2 = QPushButton(self.tab_2) self.pb_name2.setGeometry(QRect(420, 80, 21, 20))#230, 170, 21, 20)) self.pb_name2.setIcon(QIcon('допочки\_folder.png')) self.pb_name2.clicked.connect(lambda ed: self.extract_to_directory(2)) self.pb_merge = QPushButton(self.tab_2) self.pb_merge.setGeometry(QRect(270, 170, 160, 20)) self.pb_merge.setText("Объединить") self.pb_merge.clicked.connect(self.merge_it_motherFucker) self.line_4 = QFrame(self.tab_2) self.line_4.setGeometry(QRect(0, 280, 690, 15)) self.line_4.setFrameShape(QFrame.HLine) self.line_4.setFrameShadow(QFrame.Sunken) self.line_5 = QFrame(self.tab_2) self.line_5.setGeometry(QRect(0, 580, 690, 15)) self.line_5.setFrameShape(QFrame.HLine) self.line_5.setFrameShadow(QFrame.Sunken) self.pt_log2 = QPlainTextEdit(self.tab_2) self.pt_log2.setGeometry(QRect(20, 610, 651, 101)) self.pt_log2.setReadOnly(True) self.graphicsView = QGraphicsView(self.tab_2) self.graphicsView.setGeometry(QRect(0, 330, 714, 277)) self.scene = QGraphicsScene() self.graphicsView.setScene(self.scene) self.scene.addPixmap(QPixmap('допочки\_in_working_3.png')) self.l_merge.raise_() self.l_arch.raise_() #self.l_input_dir2.raise_() #self.l_or2.raise_() self.l_input_file2.raise_() self.l_name2.raise_() #self.radiobutton_3.raise_() #self.radiobutton_4.raise_() #self.pb_dir2.raise_() self.pb_file2.raise_() self.pb_name2.raise_() #self.le_dir2.raise_() self.le_file2.raise_() self.le_name2.raise_() self.line_4.raise_() self.line_5.raise_() self.pt_log2.raise_() #####------------------------------2_TAB #####------------------------------3_TAB self.tab_3 = QWidget() self.tabWidget.addTab(self.tab_3, "") self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), ("III Проверка на аномальную активность")) self.tab_3.setEnabled(False) self.l_filt3 = QLabel(self.tab_3) self.l_filt3.setGeometry(QRect(300, 10, 91, 16)) self.l_filt3.setText("Выборка пакетов") self.l_input_file3 = QLabel(self.tab_3) self.l_input_file3.setGeometry(QRect(300, 50, 90, 15)) self.l_input_file3.setText("Выберите файлы") self.pb_file3 = QPushButton(self.tab_3) self.pb_file3.setGeometry(QRect(220, 80, 21, 20)) self.pb_file3.setIcon(QIcon('допочки\_folder.png')) self.pb_file3.clicked.connect(lambda gf: self.get_files(3)) self.le_file3 = QLineEdit(self.tab_3) self.le_file3.setGeometry(QRect(250, 80, 211, 20)) self.le_file3.setReadOnly(True) self.pb_graphy = QPushButton(self.tab_3) self.pb_graphy.setGeometry(QRect(270, 170, 160, 20)) self.pb_graphy.setText("Построить граф") #self.pb_graphy.clicked.connect(self.graph_it) #self.label_6 = QLabel(self.tab_3) #self.pixmap = QPixmap('допочки\_in_working_1.png') #self.label_6.setPixmap(self.pixmap) self.l_filt3.raise_() self.l_input_file3.raise_() self.pb_file3.raise_() self.le_file3.raise_() #####------------------------------3_TAB #####----------------------------IN_WORK self.tab_4 = QWidget() self.tabWidget.addTab(self.tab_4, "") self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), ("...IV visualization...")) self.tab_4.setEnabled(False) self.label_7 = QLabel(self.tab_4) self.pixmap_2 = QPixmap('допочки\_in_working_2.png') self.label_7.setPixmap(self.pixmap_2) #####----------------------------IN_WORK self.tabWidget.setCurrentIndex(0) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), ("I выборка пакетов")) QMetaObject.connectSlotsByName(self) self.show() def closeEvent(self, event): reply = QMessageBox.question(self, 'Ща закроется всё', "Ты чо, реально хочешь выйти?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: event.accept() else: event.ignore() def to_center(self): qr = self.frameGeometry() qr.moveCenter(QDesktopWidget().availableGeometry().center()) self.move(qr.topLeft()) def get_directory(self, gd): if gd == 1: result = QFileDialog.getExistingDirectory() #self.le_dir.setText(result) self.le_file.setDisabled(True) #self.le_dir.setEnabled(True) #self.radiobutton_2.setChecked(False) #self.radiobutton.setChecked(True) else: result = QFileDialog.getExistingDirectory() #self.le_dir2.setText(result) self.le_file2.setDisabled(True) #self.le_dir2.setEnabled(True) #self.radiobutton_4.setChecked(False) #self.radiobutton_3.setChecked(True) def get_files(self, gf): if gf == 1: result, bullshit = QFileDialog.getOpenFileNames(self, "Выберите pcap-файлы", getcwd(), "files (*.pcap *.pcapng)") #self.le_dir.setDisabled(True) self.le_file.setEnabled(True) #self.radiobutton.setChecked(False) #self.radiobutton_2.setChecked(True) if len(result): self.le_file.setText(", ".join(result)) elif gf == 3: result, bullshit = QFileDialog.getOpenFileNames(self, "Выберите pcap-файлы", getcwd(), "files (*.pcap *.pcapng)") #self.le_dir.setDisabled(True) self.le_file3.setEnabled(True) #self.radiobutton.setChecked(False) #self.radiobutton_2.setChecked(True) if len(result): self.le_file3.setText(", ".join(result)) else: result, bullshit = QFileDialog.getOpenFileNames(self, "Выберите pcap-файлы", getcwd(), "files (*.pcap *.pcapng)") #self.le_dir2.setDisabled(True) self.le_file2.setEnabled(True) #self.radiobutton_3.setChecked(False) #self.radiobutton_4.setChecked(True) if len(result): self.le_file2.setText(", ".join(result)) def date_changed(self, dc): if dc == 1: self.dt_end.setMinimumDateTime(QDateTime(self.dt_beg.dateTime())) else: self.dt_beg.setMaximumDateTime(QDateTime(self.dt_end.dateTime())) def extract_to_directory(self, ed): if ed == 1: result, bullshit =QFileDialog.getSaveFileName(self, "Сохранить файл", getcwd(), "files (*.pcap *.pcapng)") self.le_name.setText(result) else: result, bullshit =QFileDialog.getSaveFileName(self, "Сохранить файл", getcwd(), "files (*.pcap *.pcapng)") self.le_name2.setText(result) def do_it_motherFucker(self): if self.filtering_is_on == 0: #if ((not self.radiobutton.isChecked() and not self.radiobutton_2.isChecked())\ # or (self.radiobutton.isChecked() and self.le_dir.text() == '')\ # or (self.radiobutton_2.isChecked() and self.le_file.text() == ''))\ # and self.le_name.text() == '': if self.le_file.text() == '' and self.le_name.text() == '': self.pt_log.appendPlainText(" " + "Какие файлы обработать? Куда сохранить? Такая неопределённость..") #elif (not self.radiobutton.isChecked() and not self.radiobutton_2.isChecked()) or (self.radiobutton.isChecked() and self.le_dir.text() == '') or (self.radiobutton_2.isChecked() and self.le_file.text() == ''): elif self.le_file.text() == '': self.pt_log.appendPlainText(" " + "Какие файлы обработать?") elif self.le_name.text() == '': self.pt_log.appendPlainText(" " + "Куда сохранить?") else: self.filtering_is_on = 1 # эти пиздецы в идеале нужно заменить на что-нибудь адекватное self.count_for_pr_b = 0 # эти пиздецы в идеале нужно заменить на что-нибудь адекватное self.progressBar.setValue(0) self.pb_start.setText("Остановить выборку") #my_directory = self.le_dir.text() pcap_files_in = self.le_file.text() pcap_file_out = self.le_name.text() per_quest = 0 per_beg = '' per_end = '' prot_quest = 0 net_prot = 0 trans_prot = 0 appl_prot = 0 ## ip_quest = 0 netprot_mass = [] transprot_mass = [] addr_mass = [] if (pcap_file_out.endswith(".pcap") or pcap_file_out.endswith(".pcapng")) == False: pcap_file_out = pcap_file_out + ".pcap" self.pt_log.appendPlainText("Сохранить в:") self.pt_log.appendPlainText(" " + pcap_file_out) #if self.radiobutton.isChecked(): # onlyfiles = [my_directory + '/' + f for f in listdir(my_directory) if # f.endswith(".pcap") or f.endswith(".pcapng") and isfile(join(my_directory, f))] # self.for_pr_b = len(onlyfiles) # # self.pt_log.appendPlainText("Выбрана директория:") # self.pt_log.appendPlainText(" " + self.le_dir.text()) # self.pt_log.appendPlainText("С pcap-файлами:") # for file in onlyfiles: # bullshit, fname = file.rsplit('/', 1) # self.pt_log.appendPlainText(" " + fname) #elif self.radiobutton_2.isChecked(): onlyfiles = pcap_files_in.split(', ') self.for_pr_b = len(onlyfiles) self.pt_log.appendPlainText("Выбраны pcap-файлы:") for file in onlyfiles: self.pt_log.appendPlainText(" " + (file)) if self.cb_addr.isChecked() and self.pt_addr.toPlainText() != '': ip_quest = 1 addr_mass = self.pt_addr.toPlainText().splitlines() if self.cb_time.isChecked(): per_quest = 1 per_beg = self.dt_beg.dateTime() per_end = self.dt_end.dateTime() if self.cb_prot.isChecked(): prot_quest = 1 transprot_mass = self.transprot_mass netprot_mass = self.netprot_mass if self.pt_transpr.toPlainText() != '': trans_prot = 1 if self.pt_netpr.toPlainText() != '': net_prot = 1 #self.radiobutton.setDisabled(True) #self.radiobutton_2.setDisabled(True) #self.l_input_dir.setDisabled(True) #self.l_or.setDisabled(True) self.l_input_file.setDisabled(True) #self.pb_dir.setDisabled(True) self.pb_file.setDisabled(True) #self.le_dir.setDisabled(True) self.le_file.setDisabled(True) self.cb_time.setDisabled(True) self.cb_prot.setDisabled(True) self.cb_addr.setDisabled(True) self.l_transpr.setDisabled(True) self.l_netpr.setDisabled(True) self.l_beg.setDisabled(True) self.l_end.setDisabled(True) self.l_name.setDisabled(True) self.l_filt.setDisabled(True) self.le_name.setDisabled(True) self.dt_beg.setDisabled(True) self.dt_end.setDisabled(True) self.pt_transpr.setDisabled(True) self.pt_netpr.setDisabled(True) self.pt_addr.setDisabled(True) self.pb_time.setDisabled(True) self.pb_transpr.setDisabled(True) self.pb_netpr.setDisabled(True) self.pb_addr.setDisabled(True) self.pb_name.setDisabled(True) self.worker = WorkerThread(onlyfiles, pcap_file_out, per_quest, per_beg, per_end, prot_quest, net_prot, netprot_mass, trans_prot, transprot_mass, appl_prot, ip_quest, addr_mass) self.worker.callback_received.connect(self.append_to_log) self.worker.start() self.pt_log.appendPlainText("") self.pt_log.appendPlainText("В работе:") elif self.filtering_is_on == 1: self.worker.terminate() self.pt_log.appendPlainText("") self.pt_log.appendPlainText("Работа прервана") self.pt_log.appendPlainText("") self.pt_log.appendPlainText("") self.go_to_starting_set() def append_to_log(self, x): self.count_for_pr_b += 1 self.pt_log.appendPlainText("") self.pt_log.appendPlainText(x) self.progressBar.setValue(self.count_for_pr_b * 100 / (self.for_pr_b + 1)) if self.progressBar.value() == 100: self.pt_log.appendPlainText("") self.pt_log.appendPlainText("") self.go_to_starting_set() def go_to_starting_set(self): self.filtering_is_on = 0 self.pb_start.setText("Начать выборку") #self.radiobutton.setDisabled(False) #self.radiobutton_2.setDisabled(False) #self.l_input_dir.setDisabled(False) #self.l_or.setDisabled(False) self.l_input_file.setDisabled(False) #self.pb_dir.setDisabled(False) self.pb_file.setDisabled(False) #self.le_dir.setDisabled(False) self.le_file.setDisabled(False) self.cb_time.setDisabled(False) self.cb_prot.setDisabled(False) self.cb_addr.setDisabled(False) self.l_name.setDisabled(False) self.l_filt.setDisabled(False) self.le_name.setDisabled(False) self.pb_name.setDisabled(False) if self.cb_time.isChecked(): self.dt_beg.setEnabled(True) self.dt_end.setEnabled(True) self.l_beg.setEnabled(True) self.l_end.setEnabled(True) if self.cb_prot.isChecked(): self.l_transpr.setEnabled(True) self.l_netpr.setEnabled(True) self.pt_transpr.setEnabled(True) self.pt_netpr.setEnabled(True) self.pb_transpr.setEnabled(True) self.pb_netpr.setEnabled(True) if self.cb_addr.isChecked(): self.pt_addr.setEnabled(True) self.pb_addr.setEnabled(True) def merge_it_motherFucker(self): #if self.radiobutton_3.isChecked(): # self.pt_log2.appendPlainText("Выбрана директория с pcap-файлами:") # self.pt_log2.appendPlainText(" " + self.le_dir2.text()) # self.pt_log2.appendPlainText('Просматриваем "{}"...'.format(self.le_dir2.text())) # onlyfiles = [self.le_dir2.text() + '/' + f for f in listdir(self.le_dir2.text()) if # f.endswith(".pcap") or f.endswith(".pcapng") and isfile(join(self.le_dir2.text(), f))] # self.pt_log2.appendPlainText(str(onlyfiles)) #elif self.radiobutton_4.isChecked(): self.pt_log2.appendPlainText("Выбраны pcap-файлы:") self.pt_log2.appendPlainText(" " + self.le_file2.text()) onlyfiles = self.le_file2.text().split(', ') self.pt_log2.appendPlainText('Работаем с "{}"...'.format(onlyfiles)) merge_file_out = self.le_name2.text() if (merge_file_out.endswith(".pcap") or merge_file_out.endswith(".pcapng")) == False: merge_file_out = merge_file_out + ".pcap" self.pt_log2.appendPlainText("Сохранить в:") self.pt_log2.appendPlainText(" " + merge_file_out) self.pt_log2.appendPlainText("") merge.mergecap(onlyfiles, merge_file_out)
class Assembler(QMainWindow): def __init__(self, parent=None): super(Assembler, self).__init__(parent) self.resize(800, 600) self.filename = None self.filetuple = None self.dirty = False # Refers to Data Page only. self.nb = None centralwidget = QWidget(self) gridLayout = QGridLayout(centralwidget) self.tabWidget = QTabWidget(centralwidget) # textbox self.tab = QWidget() font = QFont() font.setFamily("Inconsolata") font.setPointSize(14) self.tab.setFont(font) gridLayout_3 = QGridLayout(self.tab) self.plainTextEdit = QPlainTextEdit(self.tab) self.plainTextEdit.installEventFilter(self) self.plainTextEdit.setAcceptDrops(True) gridLayout_3.addWidget(self.plainTextEdit, 0, 0, 1, 1) self.tabWidget.addTab(self.tab, "") self.tab_2 = QWidget() self.tab_2.setFont(font) gridLayout_2 = QGridLayout(self.tab_2) self.plainTextEdit_2 = QPlainTextEdit(self.tab_2) gridLayout_2.addWidget(self.plainTextEdit_2, 0, 0, 1, 1) self.tabWidget.addTab(self.tab_2, "") self.tab_3 = QWidget() self.tab_3.setFont(font) gridLayout_3 = QGridLayout(self.tab_3) self.checkbox = QCheckBox("Cloning genes by tailed primers (no pYPKa_A vectors constructed)") self.checkbox.setChecked(True) gridLayout_3.addWidget(self.checkbox, 0, 0, 0, 0) self.tabWidget.addTab(self.tab_3, "") gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) self.setCentralWidget(centralwidget) menubar = QMenuBar(self) menubar.setGeometry(QRect(0, 0, 800, 29)) menu_File = QMenu(menubar) self.menu_Solve = QMenu(menubar) self.menu_Help = QMenu(menubar) self.setMenuBar(menubar) self.statusbar = QStatusBar(self) self.setStatusBar(self.statusbar) self.action_New = QAction(self) self.actionSave_As = QAction(self) self.action_Save = QAction(self) self.action_Open = QAction(self) self.action_Quit = QAction(self) self.action_About = QAction(self) self.actionShow_CCPL = QAction(self) self.action_Solve = QAction(self) self.action_OpenNB = QAction(self) self.action_CCPL = QAction(self) self.action_Help = QAction(self) menu_File.addAction(self.action_New) menu_File.addAction(self.action_Open) menu_File.addAction(self.actionSave_As) menu_File.addAction(self.action_Save) menu_File.addSeparator() menu_File.addAction(self.action_Quit) self.menu_Solve.addAction(self.action_Solve) self.menu_Solve.addAction(self.action_OpenNB) self.menu_Help.addAction(self.action_About) #self.menu_Help.addAction(self.action_CCPL) #self.menu_Help.addAction(self.action_Help) menubar.addAction(menu_File.menuAction()) menubar.addAction(self.menu_Solve.menuAction()) menubar.addAction(self.menu_Help.menuAction()) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab),\ "Data Page") self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2),\ "Assembly log") self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3),\ "Settings") menu_File.setTitle("&File") self.menu_Solve.setTitle("&Assemble") self.menu_Help.setTitle("&About") self.tabWidget.setCurrentIndex(0) self.action_New.setText("&New") self.action_Open.setText("&Open") self.actionSave_As.setText("Save &As") self.action_Save.setText("&Save") self.action_Quit.setText("&Quit") self.action_Solve.setText("&Assemble") self.action_OpenNB.setText("&Open &pathway") self.action_About.setText("&About") #self.action_CCPL.setText("&CCPL") #self.action_Help.setText("&Help") self.action_Quit.triggered.connect(self.close) allToolBar = self.addToolBar("AllToolBar") allToolBar.setObjectName("AllToolBar") self.addActions(allToolBar, (self.action_Open, self.actionSave_As, self.action_Save, self.action_Solve, self.action_OpenNB, self.action_Quit )) self.action_New.triggered.connect(self.fileNew) self.action_Open.triggered.connect(self.fileOpen) self.actionSave_As.triggered.connect(self.fileSaveAs) self.action_Save.triggered.connect(self.fileSave) self.action_Solve.triggered.connect(self.solveAssembly) self.action_OpenNB.triggered.connect(self.openNB) self.action_About.triggered.connect(self.aboutBox) #self.action_CCPL.triggered.connect(self.displayCCPL) #self.action_Help.triggered.connect(self.help) self.plainTextEdit.textChanged.connect(self.setDirty) self.action_New = self.editAction(self.action_New, None,\ 'ctrl+N', 'filenew', 'New File.') self.action_Open = self.editAction(self.action_Open, None, 'ctrl+O', 'fileopen', 'Open File.') self.actionSave_As = self.editAction(self.actionSave_As,\ None, 'ctrl+A', 'filesaveas',\ 'Save and Name File.') self.action_Save = self.editAction(self.action_Save, None, 'ctrl+S', 'filesave', 'Save File.') self.action_Solve = self.editAction(self.action_Solve, None, '', 'solve', 'Assemble.') self.action_OpenNB = self.editAction(self.action_OpenNB, None, '', 'ipynb', 'Open pathway.') self.action_About = self.editAction(self.action_About, None, 'ctrl+B', 'about','Pop About Box.') self.action_CCPL = self.editAction(self.action_CCPL, None, 'ctrl+G', 'licence', 'Show Licence') self.action_Help = self.editAction(self.action_Help, None, 'ctrl+H', 'help', 'Show Help Page.') self.action_Quit = self.editAction(self.action_Quit, None, 'ctrl+Q', 'quit', 'Quit the program.') self.plainTextEdit_2.setReadOnly(True) self.setWindowTitle("ypkpathway") self.setWindowIcon(QIcon( resource_filename("ypkpathway","icons/ypkpathway.png"))) self.plainTextEdit.setFocus() def eventFilter(self, object, event): #print(event.type(), QEvent.DragEnter, object, self.plainTextEdit) if (object is self.plainTextEdit): if (event.type() == QEvent.DragEnter): if event.mimeData().hasUrls(): event.accept() # must accept the dragEnterEvent or else the dropEvent can't occur !!! print("accept") else: event.ignore() print("ignore") if (event.type() == QEvent.Drop): if event.mimeData().hasUrls(): # if file or link is dropped urlcount = len(event.mimeData().urls()) # count number of drops url = event.mimeData().urls()[0] # get first url object.setPlainText('abc') # assign first url to editline event.accept() # doesnt appear to be needed print(456) return True return False # lets the event continue to the edit return False def setDirty(self): '''On change of text in textEdit window, set the flag "dirty" to True''' index = self.tabWidget.currentIndex() if index is not 0: return if self.dirty: return True self.dirty = True self.updateStatus('self.dirty set to True') def clearDirty(self): 'Clear dirty flag' self.dirty = False def fileNew(self): '''Clear both Data Page and Solution Page.''' self.plainTextEdit.setPlainText(' ') self.plainTextEdit_2.setPlainText(' ') self.clearDirty() self.filename = None def okToContinue(self): if self.dirty: reply = QMessageBox.question(self, "Data Loader - Unsaved Changes", "Save unsaved changes?", QMessageBox.Yes|QMessageBox.No|QMessageBox.Cancel) if reply == QMessageBox.Cancel: return False elif reply == QMessageBox.Yes: self.clearDirty() return self.fileSave() return True def okRead(self): 'Pop-up a warning message.' reply = QMessageBox.warning(self, "Warning", '''\nFile Open and Save only in Data Page \n\(Use SaveAs for the Assembly log)''', QMessageBox.Ok) return True def fileOpen(self): '''Open a file in Data Page (with index == 0)''' if self.tabWidget.currentIndex(): self.okRead() return if not self.okToContinue(): return dir_ = (os.path.dirname(str(self.filename)) if self.filename is not None else ".") filetuple = QFileDialog.getOpenFileName(self,"Open File", dir_,) self.filename = filetuple[0] # QFileDialog returns a tuple x with x[0] = file name and # x[1] = type of filter. if self.filename: self.loadFile(self.filename) self.updateStatus('New file opened.') def loadFile(self, fname=None): fl = open(fname, "r") text = fl.read() self.plainTextEdit.setPlainText(text) self.dirty = False def fileSave(self): '''Save file with current file name.''' if self.tabWidget.currentIndex(): self.okRead() return if self.filename is None: return self.fileSaveAs() else: flname = self.filename if flname: tempText = self.plainTextEdit.toPlainText() with open(flname, 'w') as fl: fl.write(tempText) self.dirty = False self.updateStatus('File saved.') return True else: self.updateStatus('Failed to save... ') return False self.filename = None self.dirty = False def fileSaveAs(self): '''Save file with a new name.''' qpr = self.qprintline fname = self.filename or "NoName.txt" self.filename = str(QFileDialog.getSaveFileName(self,"ypkpathway - Save File", fname)) flname = self.filename or "NoName.txt" self.filename = flname fl = open(flname, 'w') tempText = str(self.plainTextEdit.toPlainText()) fl.write(tempText) fl.close() self.dirty = False self.updateStatus('File saved.') def solveAssembly(self): printline = self.qprintline self.plainTextEdit_2.clear() self.tabWidget.setCurrentIndex(1) flbase = os.path.basename(str(self.filename)) title = 'Assembly log for ' + flbase printline('='*len(title)) printline(title) printline('='*len(title)) #print(type(self.plainTextEdit.toPlainText())) #qstringobj = self.plainTextEdit.toPlainText().encode('utf-8') #print(type(qstringobj)) #<class 'PyQt4.QtCore.QString'> #print(qstringobj.toUtf8()[3268:3279]) #print(str(qstringobj.toUtf8()[3268:3279])) #print(type(rawtext), "rawtext") #codec0 = .QTextCodec.codecForName("UTF-16"); #rawtext = unicode(codec0.fromUnicode(tmp), 'UTF-16') #unicode(qstringobj.toUtf8(), encoding="UTF-8").decode() qstringobj = self.plainTextEdit.toPlainText() #import sys;sys.exit(42) pth = parse( qstringobj ) #import sys;sys.exit(42) if len(pth)==0: printline("No of sequences found in Data window") return if self.filename is None: self.fileSaveAs() dir_, ext = os.path.splitext( str(self.filename)) fl, log = ypkpathway.pathway( pth, dir_, pYPKa_A = not self.checkbox.isChecked(), print = printline) if not fl: return with open(os.path.join(dir_, "log.txt"),"w") as f: f.write(log) shutil.copy2( str(self.filename), os.path.join(dir_, "INDATA_"+os.path.basename(str(self.filename)))) printline('') printline('\n\nAssembly finished.') printline('click on the Open pathway button above to open the pathway in the default web browser') self.nb = fl.path def qprintline(self, line): '''Append one line to Solution Page.''' self.plainTextEdit_2.appendPlainText(line.rstrip()) #.decode("utf8")) QApplication.processEvents() def openNB(self): if self.nb: subprocess.Popen(["ipython", "notebook", self.nb]) def aboutBox(self): from PyQt5.QtCore import QT_VERSION_STR from PyQt5.Qt import PYQT_VERSION_STR from sip import SIP_VERSION_STR from ._version import get_versions __version__ = get_versions()["version"][:5] del get_versions from IPython import __version__ as IPython_version QMessageBox.about(self, "About ypkpathway", """<b>Planning of yeast pathway kit constructions.</b> <p>version: {}<br> Copyright 2015-2017 Björn Johansson. This software is released under a BSD style license. This software comes with no warranties expressed or implied.<br><br> Python version: {}<br><br> IPython version: {}<br> Qt version: {}<br> SIP version: {}<br> PyQt version: {}<br> pydna version: {}<br></p> """.format(__version__, sys.version, IPython_version, QT_VERSION_STR, SIP_VERSION_STR, PYQT_VERSION_STR, pydna.__version__[:5])) def displayCCPL(self): '''Read and display CCPL licence.''' self.plainTextEdit.setPlainText(open('CCPL.txt').read()) self.dirty = False self.filename = 'COPYING.txt' self.updateStatus('CCPL displayed.') def help(self): '''Read and display a help file- currently the README.txt.''' self.plainTextEdit.setPlainText(open('README.md').read()) self.dirty = False self.filename = 'README.txt' self.updateStatus('README displayed.') def addActions(self, target, actions): '''Actions are added to Tool Bar.''' for action in actions: if action is None: target.addSeparator() else: target.addAction(action) def editAction(self, action, slot=None, shortcut=None, icon=None, tip=None): '''This method adds to action: icon, shortcut, ToolTip,\ StatusTip and can connect triggered action to slot ''' if icon is not None: action.setIcon(QIcon(":/%s.png" % (icon))) if shortcut is not None: action.setShortcut(shortcut) if tip is not None: action.setToolTip(tip) action.setStatusTip(tip) if slot is not None: action.triggered.connect(slot) return action def qreadline(self, lineNo): '''Read one line from Data Page (lineNo starts with 0)''' return str(self.plainTextEdit.document().\ findBlockByLineNumber(lineNo).text()).rstrip() def updateStatus(self, message): '''Keep status current.''' if self.filename is not None: flbase = os.path.basename(str(self.filename)) self.setWindowTitle(str("ypkpathway - " +\ flbase + "[*]") ) self.statusBar().showMessage(message, 5000) self.setWindowModified(self.dirty)
class Setting_Ui(QWidget): def __init__(self, persepolis_setting): super().__init__() icon = QtGui.QIcon() self.setWindowIcon(QIcon.fromTheme('persepolis', QIcon(':/icon.svg'))) self.setWindowTitle('Preferences') global icons icons = ':/' + str(persepolis_setting.value('settings/icons')) + '/' self.verticalLayout_2 = QVBoxLayout(self) self.setting_tabWidget = QTabWidget(self) # download_options_tab self.download_options_tab = QWidget() self.layoutWidget = QWidget(self.download_options_tab) self.download_options_verticalLayout = QVBoxLayout(self.layoutWidget) self.download_options_verticalLayout.setContentsMargins(21, 21, 0, 0) self.download_options_verticalLayout.setObjectName( "download_options_verticalLayout") self.horizontalLayout_5 = QHBoxLayout() # tries_label self.tries_label = QLabel(self.layoutWidget) self.horizontalLayout_5.addWidget(self.tries_label) # tries_spinBox self.tries_spinBox = QSpinBox(self.layoutWidget) self.tries_spinBox.setMinimum(1) self.horizontalLayout_5.addWidget(self.tries_spinBox) self.download_options_verticalLayout.addLayout(self.horizontalLayout_5) self.horizontalLayout_4 = QHBoxLayout() # wait_label self.wait_label = QLabel(self.layoutWidget) self.horizontalLayout_4.addWidget(self.wait_label) # wait_spinBox self.wait_spinBox = QSpinBox(self.layoutWidget) self.horizontalLayout_4.addWidget(self.wait_spinBox) self.download_options_verticalLayout.addLayout(self.horizontalLayout_4) self.horizontalLayout_3 = QHBoxLayout() # time_out_label self.time_out_label = QLabel(self.layoutWidget) self.horizontalLayout_3.addWidget(self.time_out_label) # time_out_spinBox self.time_out_spinBox = QSpinBox(self.layoutWidget) self.horizontalLayout_3.addWidget(self.time_out_spinBox) self.download_options_verticalLayout.addLayout(self.horizontalLayout_3) self.horizontalLayout_2 = QHBoxLayout() # connections_label self.connections_label = QLabel(self.layoutWidget) self.horizontalLayout_2.addWidget(self.connections_label) # connections_spinBox self.connections_spinBox = QSpinBox(self.layoutWidget) self.connections_spinBox.setMinimum(1) self.connections_spinBox.setMaximum(16) self.horizontalLayout_2.addWidget(self.connections_spinBox) self.download_options_verticalLayout.addLayout(self.horizontalLayout_2) # rpc_port_label self.rpc_port_label = QLabel(self.layoutWidget) self.rpc_horizontalLayout = QHBoxLayout() self.rpc_horizontalLayout.addWidget(self.rpc_port_label) # rpc_port_spinbox self.rpc_port_spinbox = QSpinBox(self.layoutWidget) self.rpc_port_spinbox.setMinimum(1024) self.rpc_port_spinbox.setMaximum(65535) self.rpc_horizontalLayout.addWidget(self.rpc_port_spinbox) self.download_options_verticalLayout.addLayout( self.rpc_horizontalLayout) self.setting_tabWidget.addTab(self.download_options_tab, "") # save_as_tab self.save_as_tab = QWidget() self.layoutWidget1 = QWidget(self.save_as_tab) self.save_as_verticalLayout = QVBoxLayout(self.layoutWidget1) self.save_as_verticalLayout.setContentsMargins(20, 30, 0, 0) self.download_folder_horizontalLayout = QHBoxLayout() # download_folder_label self.download_folder_label = QLabel(self.layoutWidget1) self.download_folder_horizontalLayout.addWidget( self.download_folder_label) # download_folder_lineEdit self.download_folder_lineEdit = QLineEdit(self.layoutWidget1) self.download_folder_horizontalLayout.addWidget( self.download_folder_lineEdit) # download_folder_pushButton self.download_folder_pushButton = QPushButton(self.layoutWidget1) self.download_folder_horizontalLayout.addWidget( self.download_folder_pushButton) self.save_as_verticalLayout.addLayout( self.download_folder_horizontalLayout) self.temp_horizontalLayout = QHBoxLayout() # temp_download_label self.temp_download_label = QLabel(self.layoutWidget1) self.temp_horizontalLayout.addWidget(self.temp_download_label) # temp_download_lineEdit self.temp_download_lineEdit = QLineEdit(self.layoutWidget1) self.temp_horizontalLayout.addWidget(self.temp_download_lineEdit) # temp_download_pushButton self.temp_download_pushButton = QPushButton(self.layoutWidget1) self.temp_horizontalLayout.addWidget(self.temp_download_pushButton) self.save_as_verticalLayout.addLayout(self.temp_horizontalLayout) self.setting_tabWidget.addTab(self.save_as_tab, "") # notifications_tab self.notifications_tab = QWidget() self.layoutWidget2 = QWidget(self.notifications_tab) self.verticalLayout_4 = QVBoxLayout(self.layoutWidget2) self.verticalLayout_4.setContentsMargins(21, 21, 0, 0) # enable_notifications_checkBox self.enable_notifications_checkBox = QCheckBox(self.layoutWidget2) self.verticalLayout_4.addWidget(self.enable_notifications_checkBox) # sound_frame self.sound_frame = QFrame(self.layoutWidget2) self.sound_frame.setFrameShape(QFrame.StyledPanel) self.sound_frame.setFrameShadow(QFrame.Raised) self.verticalLayout = QVBoxLayout(self.sound_frame) # volume_label self.volume_label = QLabel(self.sound_frame) self.verticalLayout.addWidget(self.volume_label) # volume_dial self.volume_dial = QDial(self.sound_frame) self.volume_dial.setProperty("value", 100) self.verticalLayout.addWidget(self.volume_dial) self.verticalLayout_4.addWidget(self.sound_frame) self.setting_tabWidget.addTab(self.notifications_tab, "") # style_tab self.style_tab = QWidget() self.layoutWidget3 = QWidget(self.style_tab) self.verticalLayout_3 = QVBoxLayout(self.layoutWidget3) self.verticalLayout_3.setContentsMargins(21, 21, 0, 0) self.horizontalLayout_8 = QHBoxLayout() # style_label self.style_label = QLabel(self.layoutWidget3) self.horizontalLayout_8.addWidget(self.style_label) # style_comboBox self.style_comboBox = QComboBox(self.layoutWidget3) self.horizontalLayout_8.addWidget(self.style_comboBox) self.verticalLayout_3.addLayout(self.horizontalLayout_8) self.horizontalLayout_7 = QHBoxLayout() # color_label self.color_label = QLabel(self.layoutWidget3) self.horizontalLayout_7.addWidget(self.color_label) # color_comboBox self.color_comboBox = QComboBox(self.layoutWidget3) self.horizontalLayout_7.addWidget(self.color_comboBox) self.verticalLayout_3.addLayout(self.horizontalLayout_7) # icon_label self.horizontalLayout_12 = QHBoxLayout() self.icon_label = QLabel(self.layoutWidget3) self.horizontalLayout_12.addWidget(self.icon_label) # icon_comboBox self.icon_comboBox = QComboBox(self.layoutWidget3) self.horizontalLayout_12.addWidget(self.icon_comboBox) self.verticalLayout_3.addLayout(self.horizontalLayout_12) self.horizontalLayout_6 = QHBoxLayout() # notification_label self.horizontalLayout_13 = QHBoxLayout() self.notification_label = QLabel(self.layoutWidget3) self.horizontalLayout_13.addWidget(self.notification_label) # notification_comboBox self.notification_comboBox = QComboBox(self.layoutWidget3) self.horizontalLayout_13.addWidget(self.notification_comboBox) self.verticalLayout_3.addLayout(self.horizontalLayout_13) # font_label self.font_label = QLabel(self.layoutWidget3) self.horizontalLayout_6.addWidget(self.font_label) # fontComboBox self.fontComboBox = QFontComboBox(self.layoutWidget3) self.horizontalLayout_6.addWidget(self.fontComboBox) # font_size_label self.font_size_label = QLabel(self.layoutWidget3) self.horizontalLayout_6.addWidget(self.font_size_label) # font_size_spinBox self.font_size_spinBox = QSpinBox(self.layoutWidget3) self.font_size_spinBox.setMinimum(1) self.horizontalLayout_6.addWidget(self.font_size_spinBox) self.verticalLayout_3.addLayout(self.horizontalLayout_6) self.setting_tabWidget.addTab(self.style_tab, "") self.verticalLayout_2.addWidget(self.setting_tabWidget) self.horizontalLayout = QHBoxLayout() spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) # Enable system tray icon self.enable_system_tray_checkBox = QCheckBox(self.layoutWidget3) self.verticalLayout_3.addWidget(self.enable_system_tray_checkBox) # after_download dialog self.after_download_checkBox = QCheckBox() self.verticalLayout_3.addWidget(self.after_download_checkBox) # show_menubar_checkbox self.show_menubar_checkbox = QCheckBox() self.verticalLayout_3.addWidget(self.show_menubar_checkbox) # show_sidepanel_checkbox self.show_sidepanel_checkbox = QCheckBox() self.verticalLayout_3.addWidget(self.show_sidepanel_checkbox) # hide progress window self.show_progress_window_checkbox = QCheckBox() self.verticalLayout_3.addWidget(self.show_progress_window_checkbox) # add persepolis to startup self.startup_checkbox = QCheckBox() self.verticalLayout_3.addWidget(self.startup_checkbox) # defaults_pushButton self.defaults_pushButton = QPushButton(self) self.horizontalLayout.addWidget(self.defaults_pushButton) # cancel_pushButton self.cancel_pushButton = QPushButton(self) self.cancel_pushButton.setIcon(QIcon(icons + 'remove')) self.horizontalLayout.addWidget(self.cancel_pushButton) # ok_pushButton self.ok_pushButton = QPushButton(self) self.ok_pushButton.setIcon(QIcon(icons + 'ok')) self.horizontalLayout.addWidget(self.ok_pushButton) self.verticalLayout_2.addLayout(self.horizontalLayout) self.setting_tabWidget.setCurrentIndex(3) self.setWindowTitle("Preferences") self.tries_label.setToolTip( "<html><head/><body><p>Set number of tries if download failed.</p></body></html>" ) self.tries_label.setText("Number of tries : ") self.tries_spinBox.setToolTip( "<html><head/><body><p>Set number of tries if download failed.</p></body></html>" ) self.wait_label.setToolTip( "<html><head/><body><p>Set the seconds to wait between retries. Download manager will retry downloads when the HTTP server returns a 503 response.</p></body></html>" ) self.wait_label.setText("Wait between retries (seconds) : ") self.wait_spinBox.setToolTip( "<html><head/><body><p>Set the seconds to wait between retries. Download manager will retry downloads when the HTTP server returns a 503 response.</p></body></html>" ) self.time_out_label.setToolTip( "<html><head/><body><p>Set timeout in seconds. </p></body></html>") self.time_out_label.setText("Time out (seconds) : ") self.time_out_spinBox.setToolTip( "<html><head/><body><p>Set timeout in seconds. </p></body></html>") self.connections_label.setToolTip( "<html><head/><body><p>Using multiple connections can help speed up your download.</p></body></html>" ) self.connections_label.setText("Number of connections : ") self.connections_spinBox.setToolTip( "<html><head/><body><p>Using multiple connections can help speed up your download.</p></body></html>" ) self.rpc_port_label.setText("RPC port number : ") self.rpc_port_spinbox.setToolTip( "<html><head/><body><p> Specify a port number for JSON-RPC/XML-RPC server to listen to. Possible Values: 1024 - 65535 Default: 6801 </p></body></html>" ) self.setting_tabWidget.setTabText( self.setting_tabWidget.indexOf(self.download_options_tab), "Download Options") self.download_folder_label.setText("Download Folder : ") self.download_folder_pushButton.setText("Change") self.temp_download_label.setText("Temporary Download Folder : ") self.temp_download_pushButton.setText("Change") self.setting_tabWidget.setTabText( self.setting_tabWidget.indexOf(self.save_as_tab), "Save as") self.enable_notifications_checkBox.setText( "Enable notification sounds") self.volume_label.setText("Volume : ") self.setting_tabWidget.setTabText( self.setting_tabWidget.indexOf(self.notifications_tab), "Notifications") self.style_label.setText("Style : ") self.color_label.setText("Color scheme : ") self.icon_label.setText("Icons : ") self.notification_label.setText("Notification type : ") self.font_label.setText("Font : ") self.font_size_label.setText("Size : ") self.enable_system_tray_checkBox.setText("Enable system tray icon.") self.after_download_checkBox.setText( "Show download complete dialog,when download has finished.") self.show_menubar_checkbox.setText("Show menubar.") self.show_sidepanel_checkbox.setText("Show side panel.") self.show_progress_window_checkbox.setText( "Show download's progress window") self.startup_checkbox.setText("Run Persepolis at startup") self.setting_tabWidget.setTabText( self.setting_tabWidget.indexOf(self.style_tab), "Preferences") self.defaults_pushButton.setText("Defaults") self.cancel_pushButton.setText("Cancel") self.ok_pushButton.setText("OK")
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.lastyear = int(time.strftime('%Y', time.localtime(time.time()))) - 1 self.in_parameters = {u'datetime': str(self.lastyear) + u'年', u'target_area': u'绍兴市', u'density_cell': u'10', u'density_class': 10, u'day_cell': u'15', u'day_class': 10, u'out_type': u'tiff'} self.setupUi() def setupUi(self): self.setObjectName("MainWindow") self.setFixedSize(1040, 915) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(sizePolicy) icon = QIcon() icon.addPixmap(QPixmap('./resource/weather-thunder.png'),QIcon.Normal, QIcon.Off) self.setWindowIcon(icon) self.centralwidget = QWidget(self) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth()) self.centralwidget.setSizePolicy(sizePolicy) self.centralwidget.setObjectName("centralwidget") self.layoutWidget = QWidget(self.centralwidget) self.layoutWidget.setGeometry(QRect(32, 10, 979, 851)) self.layoutWidget.setObjectName("layoutWidget") self.verticalLayout_5 =QVBoxLayout(self.layoutWidget) self.verticalLayout_5.setContentsMargins(0, 0, 0, 0) self.verticalLayout_5.setObjectName("verticalLayout_5") self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") spacerItem = QSpacerItem(300, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.datetime_label = QLabel(self.layoutWidget) self.datetime_label.setObjectName("datetime_label") self.horizontalLayout.addWidget(self.datetime_label) self.datetime = QDateEdit(self.layoutWidget) self.datetime.setDateTime(QDateTime(QDate(self.lastyear, 1, 1), QTime(0, 0, 0))) self.datetime.setObjectName("datetime") self.horizontalLayout.addWidget(self.datetime) spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem1) self.target_area_label = QLabel(self.layoutWidget) self.target_area_label.setObjectName("target_area_label") self.horizontalLayout.addWidget(self.target_area_label) self.target_area = QComboBox(self.layoutWidget) self.target_area.setObjectName("target_area") self.target_area.addItem("") self.target_area.addItem("") self.target_area.addItem("") self.target_area.addItem("") self.target_area.addItem("") self.target_area.addItem("") self.horizontalLayout.addWidget(self.target_area) spacerItem2 = QSpacerItem(300, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem2) self.verticalLayout_5.addLayout(self.horizontalLayout) self.tabWidget = QTabWidget(self.layoutWidget) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth()) self.tabWidget.setSizePolicy(sizePolicy) self.tabWidget.setObjectName("tabWidget") self.density_tab = QWidget() self.density_tab.setObjectName("density_tab") self.verticalLayout_3 =QVBoxLayout(self.density_tab) self.verticalLayout_3.setObjectName("verticalLayout_3") self.verticalLayout_2 =QVBoxLayout() self.verticalLayout_2.setObjectName("verticalLayout_2") self.horizontalLayout_2 = QHBoxLayout() self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.density_cell_label = QLabel(self.density_tab) self.density_cell_label.setObjectName("density_cell_label") self.horizontalLayout_2.addWidget(self.density_cell_label) self.density_cell = QSpinBox(self.density_tab) self.density_cell.setProperty("value", 10) self.density_cell.setObjectName("density_cell") self.horizontalLayout_2.addWidget(self.density_cell) spacerItem3 = QSpacerItem(40, 0, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_2.addItem(spacerItem3) self.density_class_label = QLabel(self.density_tab) self.density_class_label.setObjectName("density_class_label") self.horizontalLayout_2.addWidget(self.density_class_label) self.density_class = QSpinBox(self.density_tab) self.density_class.setProperty("value", 10) self.density_class.setObjectName("density_class") self.horizontalLayout_2.addWidget(self.density_class) spacerItem4 = QSpacerItem(478, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_2.addItem(spacerItem4) self.density_mxd = QPushButton(self.density_tab) self.density_mxd.setObjectName("density_mxd") self.horizontalLayout_2.addWidget(self.density_mxd) self.verticalLayout_2.addLayout(self.horizontalLayout_2) self.density_view = QGraphicsView(self.density_tab) self.density_view.setObjectName("density_view") self.verticalLayout_2.addWidget(self.density_view) self.verticalLayout_3.addLayout(self.verticalLayout_2) self.tabWidget.addTab(self.density_tab, "") self.day_tab = QWidget() self.day_tab.setObjectName("day_tab") self.verticalLayout_4 =QVBoxLayout(self.day_tab) self.verticalLayout_4.setObjectName("verticalLayout_4") self.verticalLayout =QVBoxLayout() self.verticalLayout.setObjectName("verticalLayout") self.horizontalLayout_3 =QHBoxLayout() self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.day_cell_label = QLabel(self.day_tab) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.day_cell_label.sizePolicy().hasHeightForWidth()) self.day_cell_label.setSizePolicy(sizePolicy) self.day_cell_label.setObjectName("day_cell_label") self.horizontalLayout_3.addWidget(self.day_cell_label) self.day_cell = QSpinBox(self.day_tab) self.day_cell.setProperty("value", 15) self.day_cell.setObjectName("day_cell") self.horizontalLayout_3.addWidget(self.day_cell) spacerItem5 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem5) self.day_class_label = QLabel(self.day_tab) self.day_class_label.setObjectName("day_class_label") self.horizontalLayout_3.addWidget(self.day_class_label) self.day_class = QSpinBox(self.day_tab) self.day_class.setProperty("value", 10) self.day_class.setObjectName("day_class") self.horizontalLayout_3.addWidget(self.day_class) spacerItem6 = QSpacerItem(478, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem6) self.day_mxd = QPushButton(self.day_tab) self.day_mxd.setObjectName("day_mxd") self.horizontalLayout_3.addWidget(self.day_mxd) self.verticalLayout.addLayout(self.horizontalLayout_3) self.day_view = QGraphicsView(self.day_tab) self.day_view.setObjectName("day_view") self.verticalLayout.addWidget(self.day_view) self.verticalLayout_4.addLayout(self.verticalLayout) self.tabWidget.addTab(self.day_tab, "") self.verticalLayout_5.addWidget(self.tabWidget) self.horizontalLayout_4 =QHBoxLayout() self.horizontalLayout_4.setObjectName("horizontalLayout_4") self.progressBar = QProgressBar(self.layoutWidget) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.progressBar.sizePolicy().hasHeightForWidth()) self.progressBar.setSizePolicy(sizePolicy) self.progressBar.setProperty("value", 0) self.progressBar.setObjectName("progressBar") self.horizontalLayout_4.addWidget(self.progressBar) self.execute_button = QPushButton(self.layoutWidget) sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.execute_button.sizePolicy().hasHeightForWidth()) self.execute_button.setSizePolicy(sizePolicy) self.execute_button.setObjectName("execute_button") self.horizontalLayout_4.addWidget(self.execute_button) self.verticalLayout_5.addLayout(self.horizontalLayout_4) self.setCentralWidget(self.centralwidget) self.menubar = QMenuBar(self) self.menubar.setGeometry(QRect(0, 0, 1040, 26)) self.menubar.setObjectName("menubar") self.file_menu = QMenu(self.menubar) self.file_menu.setObjectName("file_menu") self.help_menu = QMenu(self.menubar) self.help_menu.setObjectName("help_menu") self.setMenuBar(self.menubar) self.statusbar = QStatusBar(self) self.statusbar.setObjectName("statusbar") self.setStatusBar(self.statusbar) self.action_add_data = QAction(self) self.action_add_data.setObjectName("action_add_data") self.action_help = QAction(self) self.action_help.setObjectName("action_help") self.action_about = QAction(self) self.action_about.setObjectName("action_about") self.action_save_pic = QAction(self) self.action_save_pic.setObjectName("action_save_pic") self.file_menu.addAction(self.action_add_data) self.file_menu.addAction(self.action_save_pic) self.help_menu.addAction(self.action_help) self.help_menu.addAction(self.action_about) self.menubar.addAction(self.file_menu.menuAction()) self.menubar.addAction(self.help_menu.menuAction()) self.retranslateUi() self.tabWidget.setCurrentIndex(0) QMetaObject.connectSlotsByName(self) self.center() self.show() self.target_area.activated[str].connect(self.updateTargetArea) self.datetime.dateChanged.connect(self.updateDatetime) self.density_cell.valueChanged.connect(self.updateDensityCell) self.density_class.valueChanged.connect(self.updateDensityClass) self.day_cell.valueChanged.connect(self.updateDayCell) self.day_class.valueChanged.connect(self.updateDayClass) self.action_add_data.triggered.connect(self.addData) self.action_save_pic.triggered.connect(self.savePic) self.action_about.triggered.connect(self.showAbout) self.action_help.triggered.connect(self.showHelp) self.execute_button.clicked.connect(self.execute) self.density_mxd.clicked.connect(self.openMxdDensity) self.day_mxd.clicked.connect(self.openMxdDay) self.density_mxd.setDisabled(True) self.day_mxd.setDisabled(True) self.action_save_pic.setDisabled(True) def execute(self): dir = u"E:/Documents/工作/雷电公报/闪电定位原始文本数据/" + self.in_parameters[u'datetime'] if os.path.exists(dir): datafiles = os.listdir(dir) datafiles = map(lambda x:os.path.join(dir,x),datafiles) self.in_parameters[u'origin_data_path'] = datafiles if not self.in_parameters.has_key(u'origin_data_path'): message = u"请加载%s的数据" % self.in_parameters[u'datetime'] msgBox = QMessageBox() msgBox.setText(message) msgBox.setIcon(QMessageBox.Information) icon = QIcon() icon.addPixmap(QPixmap('./resource/weather-thunder.png'), QIcon.Normal, QIcon.Off) msgBox.setWindowIcon(icon) msgBox.setWindowTitle(" ") msgBox.exec_() return self.execute_button.setDisabled(True) self.execute_button.setText(u'正在制图中……') self.progressBar.setMaximum(0) self.progressBar.setMinimum(0) self.action_add_data.setDisabled(True) self.target_area.setDisabled(True) self.datetime.setDisabled(True) self.density_cell.setDisabled(True) self.density_class.setDisabled(True) self.day_cell.setDisabled(True) self.day_class.setDisabled(True) # for outfile in self.in_parameters[u'origin_data_path']: # infile = # try: # with open(infile, 'w+') as in_f: # for line in in_f: # line = line.replace(u":",":") # in_f.write(line) # except Exception,inst: # print infile self.process_thread = WorkThread() self.process_thread.trigger.connect(self.finished) self.process_thread.beginRun(self.in_parameters) def finished(self): #绘制闪电密度图 ##清除上一次的QGraphicsView对象,防止其记录上一次图片结果,影响显示效果 self.density_view.setAttribute(Qt.WA_DeleteOnClose) self.verticalLayout_2.removeWidget(self.density_view) size = self.density_view.size() self.density_view.close() self.density_view = QGraphicsView(self.density_tab) self.density_view.setObjectName("density_view") self.density_view.resize(size) self.verticalLayout_2.addWidget(self.density_view) densityPic = ''.join([cwd,u'/bulletinTemp/', self.in_parameters[u'datetime'],u'/',self.in_parameters[u'datetime'], self.in_parameters[u'target_area'],u'闪电密度空间分布.tif']) scene = QGraphicsScene() pixmap_density = QPixmap(densityPic) scene.addPixmap(pixmap_density) self.density_view.setScene(scene) scale = float(self.density_view.width()) / pixmap_density.width() self.density_view.scale(scale, scale) #绘制雷暴日图 self.day_view.setAttribute(Qt.WA_DeleteOnClose) self.verticalLayout.removeWidget(self.day_view) size = self.day_view.size() self.day_view.close() self.day_view = QGraphicsView(self.day_tab) self.day_view.setObjectName("day_view") self.day_view.resize(size) self.verticalLayout.addWidget(self.day_view) dayPic = ''.join([cwd,u'/bulletinTemp/', self.in_parameters[u'datetime'],u'/',self.in_parameters[u'datetime'], self.in_parameters[u'target_area'],u'地闪雷暴日空间分布.tif']) pixmap_day = QPixmap(dayPic) scene = QGraphicsScene() scene.addPixmap(pixmap_day) self.day_view.resize(self.density_view.width(),self.density_view.height()) self.day_view.setScene(scene) scale = float(self.day_view.width()) / pixmap_day.width() self.day_view.scale(scale, scale) #处理进度条和执行按钮状态 self.progressBar.setMinimum(0) self.progressBar.setMaximum(100) self.progressBar.setValue(100) self.progressBar.setFormat(u'完成!') self.execute_button.setDisabled(False) self.execute_button.setText(u'执行') #改变一些控件的状态 self.action_add_data.setDisabled(False) self.target_area.setDisabled(False) self.datetime.setDisabled(False) self.density_cell.setDisabled(False) self.density_class.setDisabled(False) self.day_cell.setDisabled(False) self.day_class.setDisabled(False) self.density_mxd.setDisabled(False) self.day_mxd.setDisabled(False) self.action_save_pic.setDisabled(False) def addData(self): fnames = QFileDialog.getOpenFileNames(self, u'请选择原始的电闪数据', u'E:/Documents/工作/雷电公报/闪电定位原始文本数据', 'Text files (*.txt);;All(*.*)') self.in_parameters[u'origin_data_path'] = fnames[0] def savePic(self): densityPic = ''.join([cwd,u'/bulletinTemp/',self.in_parameters[u'datetime'],u'/', self.in_parameters[u'target_area'],'.gdb',u'/',self.in_parameters[u'datetime'], self.in_parameters[u'target_area'],u'闪电密度空间分布.tif']) dayPic = ''.join([cwd,u'/bulletinTemp/',self.in_parameters[u'datetime'],u'/', self.in_parameters[u'target_area'],'.gdb',u'/',self.in_parameters[u'datetime'], self.in_parameters[u'target_area'],u'地闪雷暴日空间分布.tif']) directory = QFileDialog.getExistingDirectory(self,u'请选择图片保存位置', u'E:/Documents/工作/雷电公报', QFileDialog.ShowDirsOnly|QFileDialog.DontResolveSymlinks) dest_density = os.path.join(directory,os.path.basename(densityPic)) dest_day = os.path.join(directory,os.path.basename(dayPic)) if os.path.isfile(dest_day) or os.path.isfile(dest_density): message = u"文件已经存在!" msgBox = QMessageBox() msgBox.setText(message) msgBox.setIcon(QMessageBox.Information) icon = QIcon() icon.addPixmap(QPixmap("./resource/weather-thunder.png"), QIcon.Normal, QIcon.Off) msgBox.setWindowIcon(icon) msgBox.setWindowTitle(" ") msgBox.exec_() return move(dayPic,directory) move(densityPic,directory) def openMxdDay(self): program = u'C:/Program Files (x86)/ArcGIS/Desktop10.3/bin/ArcMap.exe' src_dir = ''.join([cwd,u'/data/LightningBulletin.gdb']) dest_dir = ''.join([cwd,u"/bulletinTemp/",self.in_parameters[u'datetime'], u"/" , self.in_parameters[u'target_area']]) src_file = ''.join([self.in_parameters[u'target_area'] , u"地闪雷暴日空间分布模板.mxd"]) copy(os.path.join(src_dir,src_file),dest_dir) arguments = [os.path.join(dest_dir,src_file)] self.process = QProcess(self) self.process.start(program,arguments) def openMxdDensity(self): program = u'C:/Program Files (x86)/ArcGIS/Desktop10.3/bin/ArcMap.exe' src_dir = ''.join([cwd,u'/data/LightningBulletin.gdb']) dest_dir = ''.join([cwd,u"/bulletinTemp/",self.in_parameters[u'datetime'], u"/" , self.in_parameters[u'target_area']]) src_file = ''.join([self.in_parameters[u'target_area'] ,u"闪电密度空间分布模板.mxd"]) copy(os.path.join(src_dir,src_file),dest_dir) arguments = [os.path.join(dest_dir,src_file)] self.process = QProcess(self) self.process.start(program,arguments) def showAbout(self): self.about = About_Dialog() def showHelp(self): program = u'C:/Windows/hh.exe' arguments = [''.join([cwd,'/help/help.CHM'])] self.process = QProcess(self) self.process.start(program,arguments) def updateTargetArea(self, area): self.in_parameters[u'target_area'] = area def updateDatetime(self, date): self.in_parameters[u'datetime'] = str(date.year()) + u'年' if self.in_parameters.has_key(u'origin_data_path'): self.in_parameters.__delitem__(u'origin_data_path') def updateDensityCell(self, cell): self.in_parameters[u'density_cell'] = str(cell) def updateDensityClass(self, nclass): self.in_parameters[u'density_class'] = nclass def updateDayCell(self, cell): self.in_parameters[u'day_cell'] = str(cell) def updateDayClass(self, nclass): self.in_parameters[u'day_class'] = nclass def center(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) def retranslateUi(self): _translate = QCoreApplication.translate self.setWindowTitle(_translate("MainWindow", "绍兴防雷中心 雷电公报制图")) self.datetime_label.setText(_translate("MainWindow", "年份")) self.datetime.setDisplayFormat(_translate("MainWindow", "yyyy")) self.target_area_label.setText(_translate("MainWindow", "地区")) self.target_area.setItemText(0, _translate("MainWindow", "绍兴市")) self.target_area.setItemText(1, _translate("MainWindow", "柯桥区")) self.target_area.setItemText(2, _translate("MainWindow", "上虞区")) self.target_area.setItemText(3, _translate("MainWindow", "诸暨市")) self.target_area.setItemText(4, _translate("MainWindow", "嵊州市")) self.target_area.setItemText(5, _translate("MainWindow", "新昌县")) self.density_cell_label.setText(_translate("MainWindow", "插值网格大小")) self.density_class_label.setText(_translate("MainWindow", "制图分类数目")) self.density_mxd.setText(_translate("MainWindow", "ArcGIS文档")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.density_tab), _translate("MainWindow", "电闪密度")) self.day_cell_label.setText(_translate("MainWindow", "插值网格大小")) self.day_class_label.setText(_translate("MainWindow", "制图分类数目")) self.day_mxd.setText(_translate("MainWindow", "ArcGIS文档")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.day_tab), _translate("MainWindow", "雷暴日")) self.execute_button.setText(_translate("MainWindow", "执行")) self.file_menu.setTitle(_translate("MainWindow", "文件")) self.help_menu.setTitle(_translate("MainWindow", "帮助")) self.action_add_data.setText(_translate("MainWindow", "加载数据")) self.action_help.setText(_translate("MainWindow", "使用说明")) self.action_about.setText(_translate("MainWindow", "关于")) self.action_save_pic.setText(_translate("MainWindow", "图片另存为"))
class Editor(QMainWindow): def __init__(self, taxfile=None, parent=None): super().__init__(parent) # Python => 3.0 method # super(Editor, self).__init__(parent) # Python < 3.0 method # load and set stylesheet look qtstyle_file = "modules/darkorange.stylesheet" with open(qtstyle_file, "r") as fh: self.mystyle = fh.read() self.setStyleSheet(self.mystyle) # Move whole window to the right self.move(710, 0) if (taxfile != None): self.taxyear = taxfile else: self.taxyear = "BCtax2018" self.initUI(self.taxyear) def openFile(self): fname, _filter = QFileDialog.getOpenFileName(self, 'Open json file', DATA_DIR, "Json file (*.json)") if (fname != ''): json_tax_file = fname.split("/")[-1:][0] self.updateTax(json_tax_file.split(".")[0]) def saveFile(self): data = self.readData() fname = "{}tax{}.json".format(data['info']['prov'], data['info']['year']) sname = DATA_DIR + "/{}".format(fname) if os.path.isfile(sname): msg_box = QMessageBox() msg_box.setStyleSheet(self.mystyle) button_reply = msg_box.question( self, 'File Exists', "Do you want overwrite {}?".format(fname), QMessageBox.Yes | QMessageBox.Cancel, QMessageBox.Cancel) if button_reply == QMessageBox.Yes: JsonFile(sname).save(data) if button_reply == QMessageBox.Cancel: print('Cancel') else: JsonFile(sname).save(data) def saveFileAs(self): data = self.readData() sname, _filter = QFileDialog.getSaveFileName(self, 'Save json File', DATA_DIR, "Json file (*.json)") if sname != '': JsonFile(sname).save(data) def updateTax(self, taxyear): self.taxyear = taxyear self.setWindowTitle("Editing {}".format(taxyear)) self.fillData(taxyear) def loadData(self, taxyear): taxdata = JsonFile("data/{}.json".format(taxyear)) return taxdata.load() def initMenu(self): self.menubar = QMenuBar() self.menubar.setGeometry(QtCore.QRect(0, 0, 916, 28)) self.menubar.setObjectName("menubar") self.menuFile = QMenu(self.menubar) self.menuFile.setObjectName("menuFile") self.menuFile.setTitle("File") self.setMenuBar(self.menubar) self.statusbar = QStatusBar() self.statusbar.setObjectName("statusbar") self.setStatusBar(self.statusbar) self.actionOpen = QAction() self.actionOpen.setObjectName("actionOpen") self.actionOpen.triggered.connect(self.openFile) self.actionOpen.setText("Open") self.actionSave = QAction() self.actionSave.setObjectName("actionSave") self.actionSave.triggered.connect(self.saveFile) self.actionSave.setText("Save") self.actionSaveAs = QAction() self.actionSaveAs.setObjectName("actionSaveAs") self.actionSaveAs.triggered.connect(self.saveFileAs) self.actionSaveAs.setText("Save As..") self.actionExit = QAction(QtGui.QIcon('images/exit.png'), '&Exit', self) self.actionExit.setShortcut('Ctrl+Q') self.actionExit.setStatusTip('Exit application') self.actionExit.setObjectName("actionExit") self.actionExit.triggered.connect(qApp.quit) self.actionExit.setText("Exit") self.menuFile.addAction(self.actionOpen) self.menuFile.addAction(self.actionSave) self.menuFile.addAction(self.actionSaveAs) self.menuFile.addAction(self.actionExit) self.menubar.addAction(self.menuFile.menuAction()) def initUI(self, taxyear): self.setObjectName("MainWindow") self.setEnabled(True) self.resize(400, 800) self.centralwidget = QWidget() self.verticalLayout_3 = QVBoxLayout(self.centralwidget) self.splitter = QSplitter(self.centralwidget) # --------------------- TOP MENU ------------------------- self.initMenu() # ------------- Province ---------------- self.ProvinceLabel = QLabel(self.splitter) self.provinceBox = QComboBox(self.splitter) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) self.provinceBox.addItem("Alberta") self.provinceBox.setItemText(0, "AB") self.provinceBox.addItem("British Columbia") self.provinceBox.setItemText(1, "BC") self.provinceBox.addItem("Manitoba") self.provinceBox.setItemText(2, "MB") self.provinceBox.addItem("New Brunswick") self.provinceBox.setItemText(3, "NB") self.provinceBox.addItem("Newfoundland and Labrador") self.provinceBox.setItemText(4, "NL") self.provinceBox.addItem("Nova Scotia") self.provinceBox.setItemText(5, "NS") self.provinceBox.addItem("Nunavut") self.provinceBox.setItemText(6, "BC") self.provinceBox.addItem("Ontario") self.provinceBox.setItemText(7, "ON") self.provinceBox.addItem("Prince Edward Island") self.provinceBox.setItemText(8, "PE") self.provinceBox.addItem("Quebec") self.provinceBox.setItemText(9, "QC") self.provinceBox.addItem("Saskatchewan") self.provinceBox.setItemText(10, "SK") self.taxYearLabel = QLabel(self.splitter) self.taxYearBox = QSpinBox(self.splitter) self.taxYearBox.setMinimum(1990) self.taxYearBox.setMaximum(2050) self.taxYearBox.setValue(2018) self.verticalLayout_3.addWidget(self.splitter) self.tabWidget = QTabWidget(self.centralwidget) self.ProvincialTab = QWidget() self.verticalLayout = QVBoxLayout(self.ProvincialTab) self.provLabel = QLabel(self.ProvincialTab) self.verticalLayout.addWidget(self.provLabel) # ---------- PROVINCIAL TABLE --------------- self.provTable = QTableWidget(self.ProvincialTab) self.provTable.setColumnCount(3) self.provTable.setRowCount(6) font = QtGui.QFont() font.setPointSize(9) item = QTableWidgetItem() self.provTable.setHorizontalHeaderItem(0, item) self.provTable.horizontalHeaderItem(0).setText("Bracket From") self.provTable.horizontalHeaderItem(0).setFont(font) item = QTableWidgetItem() self.provTable.setHorizontalHeaderItem(1, item) self.provTable.horizontalHeaderItem(1).setText("Bracket To") self.provTable.horizontalHeaderItem(1).setFont(font) item = QTableWidgetItem() self.provTable.setHorizontalHeaderItem(2, item) self.provTable.horizontalHeaderItem(2).setText("tax Rate") self.provTable.horizontalHeaderItem(2).setFont(font) self.provTable.horizontalHeader().setDefaultSectionSize(110) self.provTable.horizontalHeader().setStretchLastSection(True) self.provTable.verticalHeader().setVisible(False) self.verticalLayout.addWidget(self.provTable) self.provPerLabel = QLabel(self.ProvincialTab) self.verticalLayout.addWidget(self.provPerLabel) # ----------- PROVINCE PERSONAL ------------------- self.provPerTable = QTableWidget(self.ProvincialTab) self.provPerTable.setMaximumSize(QtCore.QSize(16777215, 60)) self.provPerTable.setRowCount(1) self.provPerTable.setColumnCount(2) self.provPerTable.setObjectName("provPerTable") item = QTableWidgetItem() self.provPerTable.setVerticalHeaderItem(0, item) item = QTableWidgetItem() self.provPerTable.setHorizontalHeaderItem(0, item) item = QTableWidgetItem() self.provPerTable.setHorizontalHeaderItem(1, item) self.provPerTable.horizontalHeader().setDefaultSectionSize(180) self.provPerTable.horizontalHeader().setStretchLastSection(True) self.provPerTable.verticalHeader().setVisible(False) self.provPerTable.verticalHeader().setStretchLastSection(True) self.verticalLayout.addWidget(self.provPerTable) self.tabWidget.addTab(self.ProvincialTab, "") self.FederalTab = QWidget() self.FederalTab.setObjectName("FederalTab") self.verticalLayout_2 = QVBoxLayout(self.FederalTab) self.verticalLayout_2.setObjectName("verticalLayout_2") self.fedLabel = QLabel(self.FederalTab) sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.fedLabel.sizePolicy().hasHeightForWidth()) self.fedLabel.setSizePolicy(sizePolicy) self.fedLabel.setAlignment(QtCore.Qt.AlignCenter) self.fedLabel.setObjectName("fedLabel") self.verticalLayout_2.addWidget(self.fedLabel) # ----------- FEDERAL TABLE ----------------- self.fedTable = QTableWidget(self.FederalTab) self.fedTable.setColumnCount(3) self.fedTable.setRowCount(5) font = QtGui.QFont() font.setPointSize(9) item = QTableWidgetItem() self.fedTable.setHorizontalHeaderItem(0, item) self.fedTable.horizontalHeaderItem(0).setText("Bracket From") self.fedTable.horizontalHeaderItem(0).setFont(font) item = QTableWidgetItem() self.fedTable.setHorizontalHeaderItem(1, item) self.fedTable.horizontalHeaderItem(1).setText("Bracket To") self.fedTable.horizontalHeaderItem(1).setFont(font) item = QTableWidgetItem() self.fedTable.setHorizontalHeaderItem(2, item) self.fedTable.horizontalHeaderItem(2).setText("tax Rate") self.fedTable.horizontalHeaderItem(2).setFont(font) self.fedTable.horizontalHeader().setDefaultSectionSize(100) self.fedTable.horizontalHeader().setStretchLastSection(True) self.fedTable.verticalHeader().setVisible(False) self.verticalLayout_2.addWidget(self.fedTable) self.fedPerLabel = QLabel(self.FederalTab) sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.fedPerLabel.sizePolicy().hasHeightForWidth()) self.fedPerLabel.setSizePolicy(sizePolicy) self.fedPerLabel.setAlignment(QtCore.Qt.AlignCenter) self.fedPerLabel.setObjectName("fedPerLabel") self.verticalLayout_2.addWidget(self.fedPerLabel) # ----------- FEDERAL PERSONAL TABLE ----------------- self.fedPerTable = QTableWidget(self.FederalTab) sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.fedPerTable.sizePolicy().hasHeightForWidth()) self.fedPerTable.setSizePolicy(sizePolicy) self.fedPerTable.setMaximumSize(QtCore.QSize(16777215, 60)) self.fedPerTable.setRowCount(1) self.fedPerTable.setColumnCount(2) self.fedPerTable.setObjectName("fedPerTable") item = QTableWidgetItem() self.fedPerTable.setVerticalHeaderItem(0, item) item = QTableWidgetItem() self.fedPerTable.setHorizontalHeaderItem(0, item) item = QTableWidgetItem() self.fedPerTable.setHorizontalHeaderItem(1, item) self.fedPerTable.horizontalHeader().setDefaultSectionSize(180) self.fedPerTable.horizontalHeader().setStretchLastSection(True) self.fedPerTable.verticalHeader().setVisible(False) self.fedPerTable.verticalHeader().setStretchLastSection(True) self.verticalLayout_2.addWidget(self.fedPerTable) self.tabWidget.addTab(self.FederalTab, "") self.verticalLayout_3.addWidget(self.tabWidget) self.eiLabel = QLabel(self.centralwidget) self.eiLabel.setAlignment(QtCore.Qt.AlignCenter) self.eiLabel.setObjectName("eiLabel") self.verticalLayout_3.addWidget(self.eiLabel) self.eiTable = QTableWidget(self.centralwidget) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.eiTable.sizePolicy().hasHeightForWidth()) self.eiTable.setSizePolicy(sizePolicy) self.eiTable.setMaximumSize(QtCore.QSize(16777215, 60)) self.eiTable.setObjectName("eiTable") self.eiTable.setColumnCount(2) self.eiTable.setRowCount(1) item = QTableWidgetItem() self.eiTable.setVerticalHeaderItem(0, item) item = QTableWidgetItem() self.eiTable.setHorizontalHeaderItem(0, item) item = QTableWidgetItem() self.eiTable.setHorizontalHeaderItem(1, item) self.eiTable.horizontalHeader().setDefaultSectionSize(180) self.eiTable.horizontalHeader().setStretchLastSection(True) self.eiTable.verticalHeader().setVisible(False) self.eiTable.verticalHeader().setStretchLastSection(True) self.verticalLayout_3.addWidget(self.eiTable) self.cppLabel = QLabel(self.centralwidget) self.cppLabel.setAlignment(QtCore.Qt.AlignCenter) self.cppLabel.setObjectName("cppLabel") self.cppLabel.setText("Canada Pension Plan") self.verticalLayout_3.addWidget(self.cppLabel) self.cppTable = QTableWidget(self.centralwidget) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.cppTable.sizePolicy().hasHeightForWidth()) self.cppTable.setSizePolicy(sizePolicy) self.cppTable.setMaximumSize(QtCore.QSize(16777215, 60)) self.cppTable.setObjectName("cppTable") self.cppTable.setColumnCount(3) self.cppTable.setRowCount(1) item = QTableWidgetItem() self.cppTable.setVerticalHeaderItem(0, item) item = QTableWidgetItem() self.cppTable.setHorizontalHeaderItem(0, item) item = QTableWidgetItem() self.cppTable.setHorizontalHeaderItem(1, item) item = QTableWidgetItem() self.cppTable.setHorizontalHeaderItem(2, item) self.cppTable.horizontalHeader().setDefaultSectionSize(120) self.cppTable.horizontalHeader().setStretchLastSection(True) self.cppTable.verticalHeader().setVisible(False) self.cppTable.verticalHeader().setStretchLastSection(True) self.verticalLayout_3.addWidget(self.cppTable) self.setCentralWidget(self.centralwidget) item = self.cppTable.horizontalHeaderItem(0) item.setText("max contrib") item = self.cppTable.horizontalHeaderItem(1) item.setText("tax") item = self.cppTable.horizontalHeaderItem(2) item.setText("excempt") self.retranslateUi() self.tabWidget.setCurrentIndex(0) # QtCore.QMetaObject.connectSlotsByName() self.setWindowTitle("Editing {}".format(taxyear)) self.fillData(taxyear) def retranslateUi(self): _translate = QtCore.QCoreApplication.translate self.ProvinceLabel.setText(_translate("MainWindow", "Province")) self.taxYearLabel.setText(_translate("MainWindow", "Tax Year")) self.provLabel.setText( _translate("MainWindow", "Provincial Tax Rates, Personal income")) self.provPerLabel.setText(_translate("MainWindow", "Personal Amount")) item = self.provPerTable.verticalHeaderItem(0) item.setText(_translate("MainWindow", "1")) item = self.provPerTable.horizontalHeaderItem(0) item.setText(_translate("MainWindow", "amount")) item = self.provPerTable.horizontalHeaderItem(1) item.setText(_translate("MainWindow", "tax rate")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.ProvincialTab), _translate("MainWindow", "Provincial Tax")) self.fedLabel.setText(_translate("MainWindow", "Federal Tax Rates")) self.fedPerLabel.setText(_translate("MainWindow", "Personal Amount")) item = self.fedPerTable.verticalHeaderItem(0) item.setText(_translate("MainWindow", "1")) item = self.fedPerTable.horizontalHeaderItem(0) item.setText(_translate("MainWindow", "amount")) item = self.fedPerTable.horizontalHeaderItem(1) item.setText(_translate("MainWindow", "tax rate")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.FederalTab), _translate("MainWindow", "Federal Tax")) self.eiLabel.setText(_translate("MainWindow", "Employee Insurance")) item = self.eiTable.verticalHeaderItem(0) item.setText(_translate("MainWindow", "Employee Insurance")) item = self.eiTable.horizontalHeaderItem(0) item.setText(_translate("MainWindow", "maxei")) item = self.eiTable.horizontalHeaderItem(1) item.setText(_translate("MainWindow", "tax")) def readData(self): taxdata = {} taxdata['info'] = {} taxdata['info']['year'] = self.taxYearBox.value() taxdata['info']['prov'] = self.provinceBox.currentText() taxdata['province'] = {} for i in range(0, 6): taxdata['province']['brk{}'.format(i + 1)] = [ float(self.provTable.item(i, c).text()) for c in range(3) ] taxdata['province']['PersonalAmount'] = [ float(self.provPerTable.item(0, c).text()) for c in range(2) ] taxdata['federal'] = {} for i in range(0, 5): taxdata['federal']['brk{}'.format(i + 1)] = [ float(self.fedTable.item(i, c).text()) for c in range(3) ] taxdata['federal']['PersonalAmount'] = [ float(self.fedPerTable.item(0, c).text()) for c in range(2) ] taxdata['employeeInsurance'] = {} taxdata['employeeInsurance']['maxei'] = [ float(self.eiTable.item(0, c).text()) for c in range(2) ] taxdata['cpp'] = {} taxdata['cpp']['maxcppContrib'] = [ float(self.cppTable.item(0, c).text()) for c in range(2) ] taxdata['cpp']['cppExempt'] = float(self.cppTable.item(0, 2).text()) return taxdata def fillData(self, taxyear): taxdata = self.loadData(taxyear) year = taxdata['info']['year'] print(year) self.taxYearBox.setValue(year) prov = taxdata['info']['prov'] index = self.provinceBox.findText(prov, QtCore.Qt.MatchFixedString) if index >= 0: self.provinceBox.setCurrentIndex(index) self.prov_brk = [ taxdata['province']['brk{}'.format(x)] for x in range(1, 7) ] self.prov_PersonalAmount = taxdata['province']['PersonalAmount'] self.federal_brk = [ taxdata['federal']['brk{}'.format(x)] for x in range(1, 6) ] self.federal_PersonalAmount = taxdata['federal']['PersonalAmount'] self.maxei = taxdata['employeeInsurance']['maxei'] self.maxcppContrib = taxdata['cpp']['maxcppContrib'] self.cppExempt = taxdata['cpp']['cppExempt'] for c in range(0, self.provTable.columnCount()): for r in range(0, self.provTable.rowCount()): item = QTableWidgetItem() item.setData(QtCore.Qt.EditRole, self.prov_brk[r][c]) self.provTable.setItem(r, c, item) for i in range(0, self.provPerTable.columnCount()): item = QTableWidgetItem() item.setData(QtCore.Qt.EditRole, self.prov_PersonalAmount[i]) self.provPerTable.setItem(0, i, item) for c in range(0, self.fedTable.columnCount()): for r in range(0, self.fedTable.rowCount()): item = QTableWidgetItem() item.setData(QtCore.Qt.EditRole, self.federal_brk[r][c]) self.fedTable.setItem(r, c, item) for i in range(0, self.fedPerTable.columnCount()): item = QTableWidgetItem() item.setData(QtCore.Qt.EditRole, self.federal_PersonalAmount[i]) self.fedPerTable.setItem(0, i, item) for i in range(0, self.eiTable.columnCount()): item = QTableWidgetItem() item.setData(QtCore.Qt.EditRole, self.maxei[i]) self.eiTable.setItem(0, i, item) item = QTableWidgetItem() item.setData(QtCore.Qt.EditRole, self.maxcppContrib[0]) self.cppTable.setItem(0, 0, item) item = QTableWidgetItem() item.setData(QtCore.Qt.EditRole, self.maxcppContrib[1]) self.cppTable.setItem(0, 1, item) item = QTableWidgetItem() item.setData(QtCore.Qt.EditRole, self.cppExempt) self.cppTable.setItem(0, 2, item)
class MainApp(QMainWindow, Ui_MainWindow): _translate = QCoreApplication.translate tab_list = [] # TODO - add dutch translation files def __init__(self, isolated, *args): super(MainApp, self).__init__(*args) Lumberjack.info('spawning the <<< MainApp >>> hey says: I am the Main man here see!') self.load_settings() self.setup_tray(isolated) self.dbhelper = DbHelper() self.setupUi(self) self.iconize_controls() self.load_styling() self.tabWidget = QTabWidget(self.centralwidget) self.tabWidget.setTabsClosable(True) self.tabWidget.setMovable(True) self.tabWidget.setTabBarAutoHide(True) self.tabWidget.setObjectName("tabWidget") self.verticalLayout.addWidget(self.tabWidget) builderLabel = QLabel('made by: MazeFX Solutions') self.statusbar.addPermanentWidget(builderLabel) self.menuPAT.triggered.connect(self.handle_menu_event) self.menuLists.triggered.connect(self.handle_menu_event) self.menuHelp.triggered.connect(self.handle_menu_event) self.tabWidget.tabCloseRequested.connect(self.close_tab) self.actionHome.trigger() self._retranslateUi(self) def iconize_controls(self): Lumberjack.info('< MainApp > - -> (iconize_controls)') homeIcon = qta.icon('fa.home', color='white') self.actionHome.setIcon(homeIcon) wrenchIcon = qta.icon('fa.wrench', color='white') self.actionSettings.setIcon(wrenchIcon) bankIcon = qta.icon('fa.bank', color='white') self.actionListBankAccounts.setIcon(bankIcon) contractIcon = QIcon(':/app_icons/rc/handshake_icon.svg') self.actionListContracts.setIcon(contractIcon) atIcon = qta.icon('fa.at', color='white') self.actionListEmailAddresses.setIcon(atIcon) envelopeIcon = qta.icon('fa.envelope', color='white') self.actionListLetters.setIcon(envelopeIcon) relationIcon = qta.icon('fa.group', color='white') self.actionListRelations.setIcon(relationIcon) transactionIcon = qta.icon('fa.money', color='white') self.actionListTransactions.setIcon(transactionIcon) userIcon = qta.icon('fa.user', color='white') self.actionListUsers.setIcon(userIcon) helpIcon = qta.icon('fa.question', color='white') self.actionHelp.setIcon(helpIcon) aboutIcon = qta.icon('fa.info', color='white') self.actionAbout.setIcon(aboutIcon) def setup_tray(self, isolated): Lumberjack.info('< MainApp > - -> (setup_tray)') self.trayIcon = QSystemTrayIcon(QIcon(':/app_icons/rc/PAT_icon.png'), self) self.trayMenu = QMenu(self) showAction = self.trayMenu.addAction("Open PAT") self.trayMenu.addSeparator() exitAction = self.trayMenu.addAction("Exit") self.trayIcon.setContextMenu(self.trayMenu) self.trayMenu.triggered.connect(self.handle_tray_event) self.trayIcon.activated.connect(self.handle_tray_event) self.trayIcon.show() if isolated: self.trayIcon.showMessage('PAT Service', 'PAT service is now running..') def handle_tray_event(self, *args): Lumberjack.info('< MainApp > - -> (handle_tray_event)') print(Fore.MAGENTA + '$! Received a tray action with args: ', args) if args[0] == 3: self.show() return elif hasattr(args[0], 'text'): print(Fore.MAGENTA + '$! Tray event has text!!') if args[0].text() == 'Open PAT': self.show() elif args[0].text() == 'Exit': self.close() def _retranslateUi(self, MainWindow): pass def handle_menu_event(self, *args): Lumberjack.info('< MainApp > - -> (handle_menu_event)') Lumberjack.debug('(handle_menu_event) - args = {}'.format(args)) action_text = args[0].text() icon = args[0].icon() Lumberjack.debug('(handle_menu_event) - Action text selector = {}'.format(action_text)) print(Fore.MAGENTA + '$! Action text received: ', action_text) if action_text == 'Home': Lumberjack.info('(handle_menu_event) >User action> : Adding Home tab to self') self.add_tab(HomeTab, 'Home', icon) if action_text == 'Settings': Lumberjack.info('(handle_menu_event) >User action> : Showing settings dialog') self.show_settings() elif action_text == 'Bank accounts': Lumberjack.info('(handle_menu_event) >User action> : Adding Bank account List tab to self') self.add_tab(BankAccountListTab, 'Bank accounts', icon) elif action_text == 'Contracts': Lumberjack.info('(handle_menu_event) >User action> : Adding Contracts List tab to self') self.add_tab(ContractListTab, 'Contracts', icon) elif action_text == 'Email addresses': Lumberjack.info('(handle_menu_event) >User action> : Adding EmailAddress List tab to self') self.add_tab(EmailAddressListTab, 'Email addresses', icon) elif action_text == 'Letters': Lumberjack.info('(handle_menu_event) >User action> : Adding Letter List tab to self') self.add_tab(LetterListTab, 'Letters', icon) elif action_text == 'Users': Lumberjack.info('(handle_menu_event) >User action> : Adding User List tab to self') self.add_tab(UserListTab, 'Users', icon) elif action_text == 'Relations': Lumberjack.info('(handle_menu_event) >User action> : Adding Relation List tab to self') self.add_tab(RelationListTab, 'Relations', icon) elif action_text == 'Transactions': Lumberjack.info('(handle_menu_event) >User action> : Adding Transaction List tab to self') self.add_tab(TransactionListTab, 'Transactions', icon) elif action_text == 'Help': Lumberjack.info('(handle_menu_event) >User action> : Showing help dialog') # TODO - build help dialog and help files elif action_text == 'About': Lumberjack.info('(handle_menu_event) >User action> : Showing about dialog') # TODO build About dialog. def show_settings(self): Lumberjack.info('< MainApp > - -> (show_settings)') settings_dialog = SettingsDialog() settings_dialog.exec_() def add_tab(self, tab_cls, tab_name, icon): Lumberjack.info('< MainApp > - -> (add_tab)') new_tab = tab_cls(self.dbhelper) print(Fore.MAGENTA + 'Adding a tab with class: ', str(tab_cls)) new_tab.setObjectName(str(tab_cls)) self.tabWidget.addTab(new_tab, icon, self._translate("MainWindow", tab_name)) print(Fore.MAGENTA + 'New tab added to tab list.') self.tabWidget.setCurrentIndex(self.tabWidget.indexOf(new_tab)) self.tab_list.append(new_tab) def close_tab(self, index): # TODO - Check if index stays correct when moving tabs around requesting_tab = self.tab_list[index] print(Fore.MAGENTA + 'requesting tab is: ', requesting_tab) if hasattr(requesting_tab, 'form'): if requesting_tab.form.edit_mode: print(Fore.MAGENTA + 'Tab is in edit mode.') requesting_tab.form.toggle_edit_mode(False, None, None) if requesting_tab.form.edit_mode is None: print(Fore.MAGENTA + 'Tab is now in equil.') self.tabWidget.removeTab(index) del self.tab_list[index] else: self.tabWidget.removeTab(index) del self.tab_list[index] def load_settings(self): self.settings = QSettings() db_path = self.settings.value('db_base_path') db_name = self.settings.value('db_name') if db_path is not None and db_name is not None: db_file = os.path.join(db_path, db_name) Lumberjack.debug('__init__ - db_file = {}'.format(db_file)) if os.path.exists(db_file): return Lumberjack.warning('(load_settings) - database not found') settings_dialog = SettingsDialog() settings_dialog.exec_() int_value = self.settings.value('db_type', type=int) print(Fore.MAGENTA + "load choosen database setting: %s" % repr(int_value)) def load_styling(self): style.set_window_style(self) def closeEvent(self, event): print(Fore.MAGENTA + "User has clicked the red x on the main window") for tab in self.tab_list: if hasattr(tab, 'form'): if tab.form.edit_mode: print(Fore.MAGENTA + 'Tab is in edit mode.') tab.form.toggle_edit_mode(False, None, None) close_dialog = CloseDialog() result = close_dialog.exec_() if result == close_dialog.Minimize: self.hide() event.ignore() elif result == close_dialog.Rejected: event.ignore() elif result == close_dialog.Exit: print(Fore.MAGENTA + "Exiting via save dialog, result = ", result) self.trayIcon.hide() event.accept()
class Main(QMainWindow): def __init__(self): global downloads_list_file QMainWindow.__init__(self) self.setWindowIcon(QIcon(":/quartz.png")) self.setWindowTitle("Quartz Browser - "+__version__) # Window Properties self.history = [] self.downloads = [] self.confirm_before_quit = True # Create required directories for folder in [configdir, icon_dir, thumbnails_dir]: if not os.path.exists(folder): os.mkdir(folder) # Import and Apply Settings self.setAttribute(Qt.WA_DeleteOnClose) self.settings = QSettings(1, 0, "quartz-browser","Quartz", self) self.opensettings() self.websettings = QWebSettings.globalSettings() self.websettings.setAttribute(QWebSettings.DnsPrefetchEnabled, True) self.websettings.setMaximumPagesInCache(10) self.websettings.setIconDatabasePath(icon_dir) self.websettings.setAttribute(QWebSettings.JavascriptCanOpenWindows, True) self.websettings.setAttribute(QWebSettings.JavascriptCanCloseWindows, True) if webkit.enable_adblock: self.websettings.setUserStyleSheetUrl(QUrl.fromLocalFile(program_dir + 'userContent.css')) # Import Downloads and Bookmarks self.dwnldsmodel = DownloadsModel(self.downloads, QApplication.instance()) self.dwnldsmodel.deleteDownloadsRequested.connect(self.deleteDownloads) imported_downloads = importDownloads(downloads_list_file) for [filepath, url, totalsize, timestamp] in imported_downloads: try : # Check if downloads.txt is valid tymstamp = float(timestamp) except : self.downloads = [] exportDownloads(downloads_list_file, []) print("Error in importing Downloads.") break old_download = Download(networkmanager) old_download.loadDownload(filepath, url, totalsize, timestamp) old_download.datachanged.connect(self.dwnldsmodel.datachanged) self.downloads.append(old_download) self.bookmarks = importBookmarks(configdir+"bookmarks.txt") self.favourites = importFavourites(configdir + 'favourites.txt') # Find and set icon theme name for theme_name in ['Adwaita', 'Gnome', 'Tango']: if os.path.exists('/usr/share/icons/' + theme_name): QIcon.setThemeName(theme_name) break self.initUI() self.resize(1024,714) def initUI(self): ############################### Create Actions ############################## self.loadimagesaction = QAction("Load Images",self) self.loadimagesaction.setCheckable(True) self.loadimagesaction.triggered.connect(self.loadimages) self.javascriptmode = QAction("Enable Javascript",self) self.javascriptmode.setCheckable(True) self.javascriptmode.triggered.connect(self.setjavascript) self.useragent_mode_desktop = QAction("Desktop",self) self.useragent_mode_desktop.setCheckable(True) self.useragent_mode_desktop.triggered.connect(self.setUserAgentDesktop) self.useragent_mode_mobile = QAction("Mobile",self) self.useragent_mode_mobile.setCheckable(True) self.useragent_mode_mobile.triggered.connect(self.setUserAgentMobile) self.useragent_mode_custom = QAction("Custom",self) self.useragent_mode_custom.setCheckable(True) self.useragent_mode_custom.triggered.connect(self.setUserAgentCustom) ################ Add Actions to Menu #################### # This sub-menu sets useragent mode to desktop/mobile/custom self.useragentMenu = QMenu('UserAgent', self) self.useragentMenu.setIcon(QIcon(":/computer.png")) self.useragentMenu.addAction(self.useragent_mode_desktop) self.useragentMenu.addAction(self.useragent_mode_mobile) self.useragentMenu.addAction(self.useragent_mode_custom) # This is main menu self.menu = QMenu(self) self.menu.addAction(QIcon(":/edit-find.png"), "Find Text", self.findmode, "Ctrl+F") self.menu.addAction(QIcon(":/list-add.png"), "Zoom In", self.zoomin, "Ctrl++") self.menu.addAction(QIcon(":/list-remove.png"), "Zoom Out", self.zoomout, "Ctrl+-") self.menu.addAction(QIcon(":/view-fullscreen.png"), "Toggle Fullscreen", self.fullscreenmode, "F11") self.menu.addSeparator() self.menu.addAction(self.loadimagesaction) self.menu.addAction(self.javascriptmode) self.menu.addMenu(self.useragentMenu) self.menu.addAction(QIcon(":/applications-system.png"), "Settings", self.settingseditor, "Ctrl+,") self.menu.addSeparator() self.menu.addAction(QIcon(":/image-x-generic.png"), "Save as Image", self.saveAsImage, "Shift+Ctrl+S") self.menu.addAction(QIcon(":/text-html.png"), "Save as HTML", self.saveashtml, "Ctrl+S") self.menu.addAction(QIcon(":/document-print.png"), "Print to PDF", self.printpage, "Ctrl+P") self.menu.addSeparator() self.menu.addAction(QIcon(":/process-stop.png"), "Quit", self.forceClose, "Ctrl+Q") self.bmk_menu = QMenu(self) self.bmk_menu.addAction(QIcon(':/add-bookmark.png'), 'Add Bookmark', self.addbookmark) self.bmk_menu.addAction(QIcon(':/favourites.png'), 'Add to Home', self.addToFavourites) ############################### Create Gui Parts ############################## self.centralwidget = QWidget(self) self.setCentralWidget(self.centralwidget) grid = QGridLayout(self.centralwidget) grid.setSpacing(1) grid.setContentsMargins(0,2,0,0) self.toolBar = QWidget(self) horLayout = QHBoxLayout(self.toolBar) horLayout.setSpacing(1) horLayout.setContentsMargins(0,2,0,0) self.addtabBtn = QPushButton(QIcon(":/add-tab.png"), "",self) self.addtabBtn.setToolTip("New Tab\n[Ctrl+Tab]") self.addtabBtn.setShortcut("Ctrl+Tab") self.addtabBtn.clicked.connect(self.addTab) self.reload = QPushButton(QIcon(":/refresh.png"), "",self) self.reload.setMinimumSize(35,26) self.reload.setToolTip("Reload/Stop\n [Space]") self.reload.setShortcut("Space") self.reload.clicked.connect(self.Reload) self.back = QPushButton(QIcon(":/prev.png"), "", self) self.back.setToolTip("Previous Page") self.back.setMinimumSize(35,26) self.back.clicked.connect(self.Back) self.forw = QPushButton(QIcon(":/next.png"), "",self) self.forw.setToolTip("Next Page") self.forw.setMinimumSize(35,26) self.forw.clicked.connect(self.Forward) self.homeBtn = QPushButton(QIcon(":/home.png"), "",self) self.homeBtn.setToolTip("Go Home") self.homeBtn.clicked.connect(self.goToHome) self.videoDownloadButton = QPushButton(QIcon(":/video-dwnld.png"), "", self) self.videoDownloadButton.setToolTip("Download this Video") self.videoDownloadButton.clicked.connect(self.downloadVideo) self.videoDownloadButton.hide() self.addbookmarkBtn = QToolButton(self) self.addbookmarkBtn.setIcon(QIcon(":/add-bookmark.png")) self.addbookmarkBtn.setToolTip("Add Bookmark") self.addbookmarkBtn.setMenu(self.bmk_menu) self.addbookmarkBtn.setPopupMode(QToolButton.InstantPopup) self.menuBtn = QToolButton(self) self.menuBtn.setIcon(QIcon(":/menu.png")) self.menuBtn.setMenu(self.menu) self.menuBtn.setPopupMode(QToolButton.InstantPopup) self.bookmarkBtn = QPushButton(QIcon(":/bookmarks.png"), "", self) self.bookmarkBtn.setToolTip("Manage Bookmarks\n [Alt+B]") self.bookmarkBtn.setShortcut("Alt+B") self.bookmarkBtn.clicked.connect(self.managebookmarks) self.historyBtn = QPushButton(QIcon(":/history.png"), "", self) self.historyBtn.setShortcut("Alt+H") self.historyBtn.setToolTip("View History\n [Alt+H]") self.historyBtn.clicked.connect(self.viewhistory) self.downloadsBtn = QPushButton(QIcon(":/download.png"), "", self) self.downloadsBtn.setToolTip("Download Manager") self.downloadsBtn.clicked.connect(self.download_manager) self.find = QPushButton(self) self.find.setText("Find/Next") self.find.clicked.connect(self.findnext) self.find.hide() self.findprev = QPushButton(self) self.findprev.setText("Backward") self.findprev.clicked.connect(self.findback) self.findprev.hide() self.cancelfind = QPushButton(self) self.cancelfind.setText("Cancel") self.cancelfind.clicked.connect(self.cancelfindmode) self.cancelfind.hide() self.pbar = QProgressBar(self) self.pbar.setTextVisible(False) self.pbar.setStyleSheet("QProgressBar::chunk { background-color: #bad8ff; }") pbarLayout = QGridLayout(self.pbar) pbarLayout.setContentsMargins(0,0,0,0) self.line = webkit.UrlEdit(self.pbar) self.line.openUrlRequested.connect(self.Enter) self.line.textEdited.connect(self.urlsuggestions) self.line.downloadRequested.connect(self.download_requested_file) pbarLayout.addWidget(self.line) self.listmodel = QStringListModel(self) self.completer = QCompleter(self.listmodel, self.line) self.completer.setCompletionMode(1) self.completer.setMaxVisibleItems(10) self.line.setCompleter(self.completer) self.statusbar = QLabel(self) self.statusbar.setStyleSheet("QLabel { font-size: 12px; border-radius: 2px; padding: 2px; background: palette(highlight); color: palette(highlighted-text); }") self.statusbar.setMaximumHeight(16) self.statusbar.hide() self.tabWidget = QTabWidget(self) self.tabWidget.setTabsClosable(True) self.tabWidget.setDocumentMode(True) self.tabWidget.tabBar().setExpanding(True) self.tabWidget.tabBar().setElideMode(Qt.ElideMiddle) self.tabWidget.currentChanged.connect(self.onTabSwitch) self.tabWidget.tabCloseRequested.connect(self.closeTab) self.addTab() self.applysettings() # grid.addWidget(self.toolBar, 0,0, 1,1) for widget in [self.addtabBtn, self.back, self.forw, self.reload, self.homeBtn, self.videoDownloadButton, self.pbar, self.find, self.findprev, self.cancelfind, self.addbookmarkBtn, self.menuBtn, self.bookmarkBtn, self.historyBtn, self.downloadsBtn]: horLayout.addWidget(widget) grid.addWidget(self.tabWidget, 1, 0, 1, 1) #------------------------------------------------------------------------------------------ # Must be at the end, otherwise cause segmentation fault # self.status = self.statusBar() def addTab(self, webview_tab=None): """ Creates a new tab and add to QTabWidget applysettings() must be called after adding each tab""" if not webview_tab: webview_tab = webkit.MyWebView(self.tabWidget, networkmanager) webview_tab.windowCreated.connect(self.addTab) webview_tab.loadStarted.connect(self.onLoadStart) webview_tab.loadFinished.connect(self.onLoadFinish) webview_tab.loadProgress.connect(self.onProgress) webview_tab.urlChanged.connect(self.onUrlChange) webview_tab.titleChanged.connect(self.onTitleChange) webview_tab.iconChanged.connect(self.onIconChange) webview_tab.videoListRequested.connect(self.getVideos) webview_tab.page().printRequested.connect(self.printpage) webview_tab.page().downloadRequested.connect(self.download_requested_file) webview_tab.page().unsupportedContent.connect(self.handleUnsupportedContent) webview_tab.page().linkHovered.connect(self.onLinkHover) webview_tab.page().windowCloseRequested.connect(self.closeRequestedTab) self.tabWidget.addTab(webview_tab, "( Untitled )") if self.tabWidget.count()==1: self.tabWidget.tabBar().hide() else: self.tabWidget.tabBar().show() self.tabWidget.setCurrentIndex(self.tabWidget.count()-1) def closeTab(self, index=None): """ Closes tab, hides tabbar if only one tab remains""" if index==None: index = self.tabWidget.currentIndex() widget = self.tabWidget.widget(index) self.tabWidget.removeTab(index) widget.deleteLater() # Auto hide tab bar, when no. of tab widget is one if self.tabWidget.count()==1: self.tabWidget.tabBar().hide() def closeRequestedTab(self): """ Close tab requested by the page """ webview = self.sender().view() index = self.tabWidget.indexOf(webview) self.closeTab(index) def Enter(self): url = self.line.text() if url == 'about:home': self.goToHome() else: self.GoTo(url) def GoTo(self, url): URL = QUrl.fromUserInput(url) self.tabWidget.currentWidget().openLink(URL) self.line.setText(url) self.tabWidget.currentWidget().setFocus() def goToHome(self): self.GoTo(homepage) loop = QEventLoop() QTimer.singleShot(10, loop.quit) loop.exec_() document = self.tabWidget.currentWidget().page().mainFrame().documentElement() gallery = document.findFirst('div') for i, fav in enumerate(self.favourites): title, url, img = fav[0], fav[1], thumbnails_dir+fav[2] child = '<div class="photo"> <a href="{}"><img src="{}"></a><div class="desc">{}</div></div>'.format(url, img, title) gallery.appendInside(child) def onLoadStart(self): webview = self.sender() if webview is self.tabWidget.currentWidget(): self.reload.setIcon(QIcon(":/stop.png")) def onProgress(self, progress): webview = self.sender() if webview is self.tabWidget.currentWidget() and webview.loading: self.pbar.setValue(progress) def onLoadFinish(self, ok): webview = self.sender() if webview is self.tabWidget.currentWidget(): self.reload.setIcon(QIcon(":/refresh.png")) self.pbar.reset() url = self.line.text() self.handleVideoButton(url) def onTabSwitch(self, index): """ Updates urlbox, refresh icon, progress bar on switching tab""" webview = self.tabWidget.currentWidget() if webview.loading == True: self.reload.setIcon(QIcon(":/stop.png")) self.pbar.setValue(webview.progressVal) else: self.reload.setIcon(QIcon(":/refresh.png")) self.pbar.reset() url = webview.url().toString() if url == homepage : url = 'about:home' self.line.setText(url) self.statusbar.hide() self.onIconChange(webview) self.handleVideoButton(url) def onUrlChange(self,url): url = url.toString() if url == homepage : url = 'about:home' webview = self.sender() if webview is self.tabWidget.currentWidget(): self.line.setText(url) self.onIconChange(webview) self.handleVideoButton(url) def onTitleChange(self, title): webview = self.sender() index = self.tabWidget.indexOf(webview) if not title == '': self.tabWidget.tabBar().setTabText(index, title) url = webview.url().toString() for item in self.history: # Removes the old item, inserts new same item on the top if url == item[1]: self.history.remove(item) self.history.insert(0, [title, url]) def onIconChange(self, webview=None): if not webview: webview = self.sender() icon = webview.icon() if icon.isNull(): icon = QIcon(':/quartz.png') if webview is self.tabWidget.currentWidget(): self.line.setIcon(icon) index = self.tabWidget.indexOf(webview) self.tabWidget.setTabIcon(index, icon) def onLinkHover(self, url): if url=="": self.statusbar.hide() return self.statusbar.setText(url) self.statusbar.adjustSize() self.statusbar.show() self.statusbar.move(QPoint(0, self.height()-self.statusbar.height())) def Back(self): self.tabWidget.currentWidget().back() def Forward(self): self.tabWidget.currentWidget().forward() def Reload(self): if self.tabWidget.currentWidget().loading: self.tabWidget.currentWidget().stop() else: if self.line.text() == 'about:home': self.goToHome() else: self.tabWidget.currentWidget().reload() def urlsuggestions(self, text): """ Creates the list of url suggestions for URL box """ suggestions = [] if not webkit.find_mode_on: for [title, url] in self.history: if text in url: suggestions.insert(0, url) for [title, address] in self.bookmarks: if text in address: suggestions.insert(0, address) self.listmodel.setStringList( suggestions ) def handleVideoButton(self, url): if youtube.validYoutubeUrl(url): self.videoDownloadButton.show() return frames = [self.tabWidget.currentWidget().page().mainFrame()] frames += frames[0].childFrames() for frame in frames: video = frame.findFirstElement('video') if not video.isNull(): self.videoDownloadButton.show() return self.videoDownloadButton.hide() ##################### Downloading and Printing ######################## def download_requested_file(self, networkrequest): """ Gets called when the page requests a file to be downloaded """ reply = networkmanager.get(networkrequest) self.handleUnsupportedContent(reply) def handleUnsupportedContent(self, reply, preset_filename=None, page_url=None): """ This is called when url content is a downloadable file. e.g- pdf,mp3,mp4 """ if reply.rawHeaderList() == []: loop = QEventLoop() reply.metaDataChanged.connect(loop.quit) QTimer.singleShot(5000, loop.quit) loop.exec_() if reply.hasRawHeader(b'Location'): URL = QUrl.fromUserInput(str_(reply.rawHeader(b'Location'))) reply.abort() reply = networkmanager.get(QNetworkRequest(URL)) self.handleUnsupportedContent(reply, preset_filename) return for (title, header) in reply.rawHeaderPairs(): print( str_(title) + "-> " + str_(header) ) # copy url to clipboard QApplication.clipboard().setText(reply.url().toString()) # Get filename and mimetype mimetype = None if reply.hasRawHeader(b'Content-Type'): mimetype = str_(reply.rawHeader(b'Content-Type')).split(';')[0] # eg - audio/mpeg; name="" content_name = str_(reply.rawHeader(b'Content-Disposition')) if preset_filename: filename = preset_filename else: filename = filenameFromHeader(content_name) if filename == '': filename = filenameFromUrl(reply.url().toString()) filename = validateFileName(filename, mimetype) # Create downld Confirmation dialog dlDialog = DownloadDialog(self) dlDialog.filenameEdit.setText(filename) # Get filesize if reply.hasRawHeader(b'Content-Length'): filesize = reply.header(1) if filesize >= 1048576 : file_size = "{} M".format(round(float(filesize)/1048576, 2)) elif 1023 < filesize < 1048576 : file_size = "{} k".format(round(float(filesize)/1024, 1)) else: file_size = "{} B".format(filesize) dlDialog.labelFileSize.setText(file_size) # Get filetype and resume support info if mimetype: dlDialog.labelFileType.setText(mimetype) if reply.hasRawHeader(b'Accept-Ranges') or reply.hasRawHeader(b'Content-Range'): dlDialog.labelResume.setText("True") # Execute dialog and show confirmation if dlDialog.exec_()== QDialog.Accepted: filepath = dlDialog.folder + dlDialog.filenameEdit.text() url = reply.url().toString() if self.useexternaldownloader: download_externally(url, self.externaldownloader) reply.abort() reply.deleteLater() return global downloads_list_file newdownload = Download(networkmanager, page_url) newdownload.startDownload(reply, filepath) newdownload.datachanged.connect(self.dwnldsmodel.datachanged) self.downloads.insert(0, newdownload) imported_downloads = importDownloads(downloads_list_file) imported_downloads.insert(0, [filepath, url, str(newdownload.totalsize), newdownload.timestamp]) exportDownloads(downloads_list_file, imported_downloads) else: reply.abort() reply.deleteLater() def download_manager(self): """ Opens download manager dialog """ dialog = QDialog(self) downloads_dialog = Downloads_Dialog() downloads_dialog.setupUi(dialog, self.dwnldsmodel) dialog.exec_() def deleteDownloads(self, timestamps): global downloads_list_file imported_downloads = importDownloads(downloads_list_file) exported_downloads = [] for download in imported_downloads: if download[-1] not in timestamps: exported_downloads.append(download) exportDownloads(downloads_list_file, exported_downloads) def downloadVideo(self): url = self.tabWidget.currentWidget().url().toString() # For youtube videos, parse youtube links in separate thread if youtube.validYoutubeUrl(url): vid_id = parse_qs(urlparse(url).query)['v'][0] ytThread = youtube.YoutubeThread(self) ytThread.ytParseFailed.connect(self.onYtParseFail) ytThread.ytVideoParsed.connect(self.onYtVideoParse) ytThread.finished.connect(ytThread.deleteLater) ytThread.vid_id = vid_id ytThread.start() return # For embeded HTML5 videos self.getVideos() def onYtVideoParse(self, videos): dialog = youtube.YoutubeDialog(videos, self) if dialog.exec_() == 1 : index = abs(dialog.buttonGroup.checkedId())-2 vid = videos[index] reply = networkmanager.get( QNetworkRequest(QUrl.fromUserInput(vid.url)) ) self.handleUnsupportedContent(reply, vid.filename + '.' + vid.extension) def onYtParseFail(self): # Show error on fail to parse youtube QMessageBox.warning(self, "Download Failed !","This Video can not be downloaded") def getVideos(self): dialog = youtube.Media_Dialog(self, self.tabWidget.currentWidget().page(), networkmanager) dialog.downloadRequested.connect(self.handleUnsupportedContent) dialog.exec_() def saveAsImage(self): """ Saves the whole page as PNG/JPG image""" title = self.tabWidget.currentWidget().page().mainFrame().title() title == validateFileName(title) filename = QFileDialog.getSaveFileName(self, "Select Image to Save", downloaddir + title +".jpg", "JPEG Image (*.jpg);;PNG Image (*.png)" )[0] if filename == '': return viewportsize = self.tabWidget.currentWidget().page().viewportSize() contentsize = self.tabWidget.currentWidget().page().mainFrame().contentsSize() self.tabWidget.currentWidget().page().setViewportSize(contentsize) img = QPixmap(contentsize) painter = QPainter(img) self.tabWidget.currentWidget().page().mainFrame().render(painter) painter.end() if img.save(filename): QMessageBox.information(self, "Successful !","Page has been successfully saved as\n"+filename) else: QMessageBox.warning(self, "Saving Failed !","Exporting page to Image hasbeen failed") self.tabWidget.currentWidget().page().setViewportSize(viewportsize) def saveashtml(self): """ Saves current page as HTML , bt does not saves any content (e.g images)""" title = self.tabWidget.currentWidget().page().mainFrame().title() title = validateFileName(title) filename = QFileDialog.getSaveFileName(self, "Enter HTML File Name", downloaddir + title +".html", "HTML Document (*.html)" )[0] if filename == '': return #html = self.tabWidget.currentWidget().page().mainFrame().toHtml() page_URL = self.tabWidget.currentWidget().url() useragent = self.tabWidget.currentWidget().page().userAgentForUrl(page_URL) doc = self.tabWidget.currentWidget().page().mainFrame().documentElement().clone() #doc.setInnerXml(html) SaveAsHtml(networkmanager, doc, filename, page_URL, useragent) def printpage(self, page=None): """ Prints current/requested page """ if not page: page = self.tabWidget.currentWidget().page().currentFrame() printer = QPrinter(QPrinter.HighResolution) printer.setPaperSize(QPrinter.A4) printer.setPageSize(QPrinter.A4) printer.setColorMode(QPrinter.Color) printer.setCreator("Quartz Browser") title = self.tabWidget.currentWidget().page().mainFrame().title() title = validateFileName(title) printer.setDocName(title) printer.setOutputFileName(docdir + title + ".pdf") #printer.setOutputFormat(QPrinter.PdfFormat) print_dialog = QPrintPreviewDialog(printer, self) print_dialog.paintRequested.connect(page.print_) print_dialog.exec_() ################################################################################################## def addToFavourites(self): dialog = QDialog(self) addbmkdialog = Add_Bookmark_Dialog() addbmkdialog.setupUi(dialog) dialog.setWindowTitle('Add to HomePage') addbmkdialog.titleEdit.setMaxLength(31) addbmkdialog.titleEdit.setText(self.tabWidget.currentWidget().page().mainFrame().title()) addbmkdialog.addressEdit.setText(self.line.text()) if (dialog.exec_() == QDialog.Accepted): title = addbmkdialog.titleEdit.text() addr = addbmkdialog.addressEdit.text() imgfile = str(time.time()) + '.jpg' viewportsize = self.tabWidget.currentWidget().page().viewportSize() contentsize = QSize(640, 640) self.tabWidget.currentWidget().page().setViewportSize(contentsize) img = QPixmap(contentsize) painter = QPainter(img) self.tabWidget.currentWidget().page().mainFrame().render(painter, QWebFrame.AllLayers) painter.end() self.tabWidget.currentWidget().page().setViewportSize(viewportsize) icon = img.scaledToWidth(184, 1).copy(0,0, 180, 120) icon.save(thumbnails_dir + imgfile) self.favourites = importFavourites(configdir + 'favourites.txt') self.favourites.append([title, addr, imgfile]) exportFavourites(configdir + 'favourites.txt', self.favourites) def addbookmark(self): """ Opens add bookmark dialog and gets url from url box""" dialog = QDialog(self) addbmkdialog = Add_Bookmark_Dialog() addbmkdialog.setupUi(dialog) addbmkdialog.titleEdit.setText(self.tabWidget.currentWidget().page().mainFrame().title()) addbmkdialog.addressEdit.setText(self.line.text()) if (dialog.exec_() == QDialog.Accepted): url = addbmkdialog.addressEdit.text() bmk = [addbmkdialog.titleEdit.text(), url] self.bookmarks = importBookmarks(configdir+"bookmarks.txt") self.bookmarks.insert(0, bmk) exportBookmarks(configdir+"bookmarks.txt", self.bookmarks) icon = self.tabWidget.currentWidget().icon() if not icon.isNull(): icon.pixmap(16, 16).save(icon_dir + url.split('/')[2] + '.png') def managebookmarks(self): """ Opens Bookmarks dialog """ dialog = QDialog(self) bmk_dialog = Bookmarks_Dialog() bmk_dialog.setupUi(dialog, self.bookmarks, self.favourites) bmk_dialog.bookmarks_table.doubleclicked.connect(self.GoTo) bmk_dialog.favs_table.doubleclicked.connect(self.GoTo) dialog.exec_() if bmk_dialog.bookmarks_table.data_changed: self.bookmarks = bmk_dialog.bookmarks_table.data exportBookmarks(configdir+"bookmarks.txt", self.bookmarks) if bmk_dialog.favs_table.data_changed: self.favourites = bmk_dialog.favs_table.data exportFavourites(configdir+"favourites.txt", self.favourites) def viewhistory(self): """ Open history dialog """ dialog = QDialog(self) history_dialog = History_Dialog() history_dialog.setupUi(dialog, self.history) history_dialog.tableView.doubleclicked.connect(self.GoTo) dialog.exec_() def findmode(self): """ Starts find mode and unhides find buttons""" webkit.find_mode_on = True self.line.clear() self.find.show() self.findprev.show() self.cancelfind.show() self.line.setFocus() def cancelfindmode(self): """ Hides the find buttons, updates urlbox""" webkit.find_mode_on = False self.tabWidget.currentWidget().findText("") self.find.hide() self.findprev.hide() self.cancelfind.hide() self.line.setText(self.tabWidget.currentWidget().url().toString()) def findnext(self): text = self.line.text() self.tabWidget.currentWidget().findText(text) def findback(self): text = self.line.text() self.tabWidget.currentWidget().findText(text, QWebPage.FindBackward) ##################### View Settings ################### def zoomin(self): zoomlevel = self.tabWidget.currentWidget().zoomFactor() self.tabWidget.currentWidget().setZoomFactor(zoomlevel+0.1) # Use setZoomFactor() to zoom text and images def zoomout(self): zoomlevel = self.tabWidget.currentWidget().zoomFactor() self.tabWidget.currentWidget().setZoomFactor(zoomlevel-0.1) def fullscreenmode(self): if self.isFullScreen(): self.showNormal() else: self.showFullScreen() def loadimages(self, state): """ TOggles image loading on/off""" self.websettings.setAttribute(QWebSettings.AutoLoadImages, state) self.loadimagesval = bool(state) def setjavascript(self, state): """ Toggles js on/off """ self.websettings.setAttribute(QWebSettings.JavascriptEnabled, state) self.javascriptenabledval = bool(state) def setUserAgentDesktop(self, checked): if bool(checked): webkit.useragent_mode = 'Desktop' self.useragent_mode_mobile.setChecked(False) self.useragent_mode_custom.setChecked(False) def setUserAgentMobile(self, checked): if bool(checked): webkit.useragent_mode = 'Mobile' self.useragent_mode_desktop.setChecked(False) self.useragent_mode_custom.setChecked(False) def setUserAgentCustom(self, checked): if bool(checked): webkit.useragent_mode = 'Custom' self.useragent_mode_mobile.setChecked(False) self.useragent_mode_desktop.setChecked(False) ########################## Settings Portion ######################### def settingseditor(self): """ Opens the settings manager dialog, then applies the change""" dialog = QDialog(self) websettingsdialog = Ui_SettingsDialog() websettingsdialog.setupUi(dialog) # Enable AdBlock websettingsdialog.checkAdBlock.setChecked(webkit.enable_adblock) # Fonts blocking websettingsdialog.checkFontLoad.setChecked(webkit.block_fonts) # Popups blocking websettingsdialog.checkBlockPopups.setChecked(webkit.block_popups) # Custom user agent websettingsdialog.useragentEdit.setText(webkit.useragent_custom) # External download manager websettingsdialog.checkDownMan.setChecked(self.useexternaldownloader) websettingsdialog.downManEdit.setText(self.externaldownloader) # RTSP media player command websettingsdialog.mediaPlayerEdit.setText(webkit.video_player_command) websettingsdialog.mediaPlayerEdit.setCursorPosition(0) # Font settings websettingsdialog.spinFontSize.setValue(self.minfontsizeval) websettingsdialog.standardfontCombo.setCurrentFont(QFont(self.standardfontval)) websettingsdialog.sansfontCombo.setCurrentFont(QFont(self.sansfontval)) websettingsdialog.seriffontCombo.setCurrentFont(QFont(self.seriffontval)) websettingsdialog.fixedfontCombo.setCurrentFont(QFont(self.fixedfontval)) # Clear Data buttons websettingsdialog.clearCacheButton.clicked.connect(self.websettings.clearMemoryCaches) websettingsdialog.cookiesButton.clicked.connect(cookiejar.clearCookies) websettingsdialog.iconDBButton.clicked.connect(self.websettings.clearIconDatabase) if dialog.exec_() == QDialog.Accepted: # Enable AdBlock webkit.enable_adblock = websettingsdialog.checkAdBlock.isChecked() # Block Fonts webkit.block_fonts = websettingsdialog.checkFontLoad.isChecked() # Block Popups webkit.block_popups = websettingsdialog.checkBlockPopups.isChecked() # User Agent webkit.useragent_custom = websettingsdialog.useragentEdit.text() # Download Manager self.useexternaldownloader = websettingsdialog.checkDownMan.isChecked() self.externaldownloader = websettingsdialog.downManEdit.text() # Media Player Command webkit.video_player_command = websettingsdialog.mediaPlayerEdit.text() self.minfontsizeval = websettingsdialog.spinFontSize.value() self.standardfontval = websettingsdialog.standardfontCombo.currentText() self.sansfontval = websettingsdialog.sansfontCombo.currentText() self.seriffontval = websettingsdialog.seriffontCombo.currentText() self.fixedfontval = websettingsdialog.fixedfontCombo.currentText() self.applysettings() self.savesettings() def opensettings(self): """ Reads settings file in ~/.config/quartz-browser/ directory and saves values in settings variables""" webkit.enable_adblock = _bool(self.settings.value('EnableAdblock', True)) self.loadimagesval = _bool(self.settings.value('LoadImages', True)) self.javascriptenabledval = _bool(self.settings.value('JavaScriptEnabled', True)) webkit.block_fonts = _bool(self.settings.value('BlockFontLoading', False)) webkit.block_popups = _bool(self.settings.value('BlockPopups', False)) webkit.useragent_mode = self.settings.value('UserAgentMode', webkit.useragent_mode) webkit.useragent_custom = self.settings.value('UserAgent', webkit.useragent_custom) self.useexternaldownloader = _bool(self.settings.value('UseExternalDownloader', False)) self.externaldownloader = self.settings.value('ExternalDownloader', "x-terminal-emulator wget -c %u") webkit.video_player_command = self.settings.value('MediaPlayerCommand', webkit.video_player_command) self.maximize_window = _bool(self.settings.value('MaximizeWindow', False)) self.minfontsizeval = int(self.settings.value('MinFontSize', 11)) self.standardfontval = self.settings.value('StandardFont', 'Sans') self.sansfontval = self.settings.value('SansFont', 'Sans') self.seriffontval = self.settings.value('SerifFont', 'Serif') self.fixedfontval = self.settings.value('FixedFont', 'Monospace') def savesettings(self): """ Writes setings to disk in ~/.config/quartz-browser/ directory""" self.settings.setValue('EnableAdblock', webkit.enable_adblock) self.settings.setValue('LoadImages', self.loadimagesval) self.settings.setValue('JavaScriptEnabled', self.javascriptenabledval) self.settings.setValue('BlockFontLoading', webkit.block_fonts) self.settings.setValue('BlockPopups', webkit.block_popups) self.settings.setValue('UserAgent', webkit.useragent_custom) self.settings.setValue('UserAgentMode', webkit.useragent_mode) self.settings.setValue('UseExternalDownloader', self.useexternaldownloader) self.settings.setValue('ExternalDownloader', self.externaldownloader) self.settings.setValue('MediaPlayerCommand', webkit.video_player_command) self.settings.setValue('MaximizeWindow', self.isMaximized()) self.settings.setValue('MinFontSize', self.minfontsizeval) self.settings.setValue('StandardFont', self.standardfontval) self.settings.setValue('SansFont', self.sansfontval) self.settings.setValue('SerifFont', self.seriffontval) self.settings.setValue('FixedFont', self.fixedfontval) def applysettings(self): """ Reads settings variables, and changes browser settings.This is run after changing settings by Settings Dialog""" if webkit.enable_adblock: self.websettings.setUserStyleSheetUrl(QUrl.fromLocalFile(program_dir + 'userContent.css')) else: self.websettings.setUserStyleSheetUrl(QUrl('')) self.websettings.setAttribute(QWebSettings.AutoLoadImages, self.loadimagesval) self.loadimagesaction.setChecked(self.loadimagesval) self.websettings.setAttribute(QWebSettings.JavascriptEnabled, self.javascriptenabledval) self.javascriptmode.setChecked(self.javascriptenabledval) if webkit.useragent_mode == 'Mobile': self.useragent_mode_mobile.setChecked(True) elif webkit.useragent_mode == 'Custom': self.useragent_mode_custom.setChecked(True) else: self.useragent_mode_desktop.setChecked(True) self.websettings.setFontSize(QWebSettings.MinimumFontSize, self.minfontsizeval) self.websettings.setFontFamily(QWebSettings.StandardFont, self.standardfontval) self.websettings.setFontFamily(QWebSettings.SansSerifFont, self.sansfontval) self.websettings.setFontFamily(QWebSettings.SerifFont, self.seriffontval) self.websettings.setFontFamily(QWebSettings.FixedFont, self.fixedfontval) # self.websettings.setFontSize(QWebSettings.DefaultFontSize, 14) def enableKiosk(self): webkit.KIOSK_MODE = True self.menu.clear() self.toolBar.hide() self.showFullScreen() def forceClose(self): self.confirm_before_quit = False self.close() def closeEvent(self, event): """This saves all settings, bookmarks, cookies etc. during window close""" if self.confirm_before_quit: confirm = QMessageBox.warning(self, 'Quit Browser ?', 'Are you sure to close the Browser', QMessageBox.Yes|QMessageBox.No, QMessageBox.Yes) if confirm == QMessageBox.No : event.ignore() return self.savesettings() cookiejar.exportCookies() # Delete excess thumbnails thumbnails = [ x for x in os.listdir(thumbnails_dir) ] for fav in self.favourites: if fav[2] in thumbnails: thumbnails.remove(fav[2]) for f in thumbnails: os.remove(thumbnails_dir + f) # Delete excess icons icons = [ x for x in os.listdir(icon_dir) if x.endswith('.png') ] for bmk in self.bookmarks: host = QUrl(bmk[1]).host() if host + '.png' in icons: icons.remove(host + '.png') for f in icons: os.remove( icon_dir + f ) super(Main, self).closeEvent(event)
class Library(QMainWindow): ''' ''' def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.centralWidget = QWidget() self.setWindowTitle('Library') self.addActions() self.addMenubar() self.addToolbars() self.path = os.getcwd() self.libConfig = [] self.readLib() self.closeFlag = False self.mainWins = [] self.tabs = QTabWidget() tabS = '' index = 0 for el in self.libConfig: if el['lib'] != tabS: if tabS != '': tab = QWidget() layout = QVBoxLayout() layout.addWidget(view) tab.setLayout(layout) self.tabs.addTab(tab, tabS) if tabS == 'common': index = self.tabs.indexOf(tab) tabS = el['lib'] diagram = CompViewer(self) view = QGraphicsView(diagram) diagram.compLock = True i = 1 try: w = el['width'] except: w = BWmin stbin = (el['stin'] == 1) stbout = (el['stout'] == 1) b = Block(None, diagram, el['name'], el['ip'], el['op'], stbin, stbout, el['icon'], el['params'], w, False) px = (i - 1) % 2 py = (i - 1) / 2 b.setPos(px * 150, py * 200) i += 1 tab = QWidget() layout = QVBoxLayout() layout.addWidget(view) tab.setLayout(layout) self.tabs.addTab(tab, tabS) layout = QHBoxLayout() layout.addWidget(self.tabs) self.widget = QWidget() self.widget.setLayout(layout) self.setCentralWidget(self.widget) self.tabs.setTabPosition(QTabWidget.West) self.tabs.setCurrentIndex(index) def addActions(self): mypath = respath + '/icons/' self.newFileAction = QAction(QIcon(mypath + 'filenew.png'), '&New', self, shortcut='Ctrl+N', statusTip='New File', triggered=self.newFile) self.openFileAction = QAction(QIcon(mypath + 'fileopen.png'), '&Open', self, shortcut='Ctrl+O', statusTip='Open File', triggered=self.openFile) self.exitAction = QAction(QIcon(mypath + 'exit.png'), '&Exit', self, shortcut='Ctrl+X', statusTip='Exit Application', triggered=self.close) def newFile(self): main = NewEditorMainWindow('untitled', self.path, self) self.mainWins.append(main) main.show() def openFile(self): filename = QFileDialog.getOpenFileName(self, 'Open', '.', filter='*.dgm') filename = filename[0] if filename != '': self.fopen(filename) def fopen(self, filename): fname = QFileInfo(filename) self.path = str(fname.absolutePath()) fn = str(fname.baseName()) main = NewEditorMainWindow(fn, self.path, self) self.mainWins.append(main) main.show() def addToolbars(self): toolbarF = self.addToolBar('File') toolbarF.addAction(self.newFileAction) toolbarF.addAction(self.openFileAction) toolbarF.addAction(self.exitAction) def addMenubar(self): menubar = self.menuBar() fileMenu = menubar.addMenu('&File') fileMenu.addAction(self.newFileAction) fileMenu.addAction(self.openFileAction) fileMenu.addAction(self.exitAction) def getBlock(self, fn): f = open(fn, 'r') d = f.read() f.close() d = json.loads(d) return d def readLib(self): commonDir = respath + 'blocks/blocks' blkList = [] try: fn = open(commonDir + '/common.blks') for f in fn: f = f.rstrip() try: d = self.getBlock(respath + 'blocks/blocks/' + f) d['lib'] = 'common' blkList.append(d) except: try: d = self.getBlock(myDir + '/' + f) d['lib'] = 'common' blkList.append(d) except: pass fn.close() except: pass files = os.listdir(commonDir) for f in sorted(files): if f.endswith('.xblk'): d = self.getBlock(respath + 'blocks/blocks/' + f) blkList.append(d) self.libConfig = sorted(blkList, key=lambda k: (k['lib'].lower())) def closeWindow(self, mainW): self.mainWins.remove(mainW) def closeEvent(self, event): for el in self.mainWins: el.close() event.accept()
class AppWindow(QMainWindow): onRestart = pyqtSignal(name='onRestart') onSystemUIElementCreated = pyqtSignal(str, QWidget, name='onSystemUIElementCreated') onSystemUIElementRemoved = pyqtSignal(str, name='onSystemUIElementRemoved') def __init__(self, dwarf_args, flags=None): super(AppWindow, self).__init__(flags) self.dwarf_args = dwarf_args self.session_manager = SessionManager(self) self.session_manager.sessionCreated.connect(self.session_created) self.session_manager.sessionStopped.connect(self.session_stopped) self.session_manager.sessionClosed.connect(self.session_closed) self._tab_order = [ 'debug', 'modules', 'ranges', 'jvm-inspector', 'jvm-debugger' ] self._is_newer_dwarf = False self.q_settings = QSettings("dwarf_window_pos.ini", QSettings.IniFormat) self.menu = self.menuBar() self.view_menu = None self._initialize_ui_elements() self.setWindowTitle( 'Dwarf - A debugger for reverse engineers, crackers and security analyst' ) # load external assets _app = QApplication.instance() self.remove_tmp_dir() # themes self.prefs = Prefs() utils.set_theme(self.prefs.get('dwarf_ui_theme', 'black'), self.prefs) # load font if os.path.exists(utils.resource_path('assets/Anton.ttf')): QFontDatabase.addApplicationFont( utils.resource_path('assets/Anton.ttf')) if os.path.exists(utils.resource_path('assets/OpenSans-Regular.ttf')): QFontDatabase.addApplicationFont( utils.resource_path('assets/OpenSans-Regular.ttf')) font = QFont("OpenSans", 9, QFont.Normal) # TODO: add settingsdlg font_size = self.prefs.get('dwarf_ui_font_size', 12) font.setPixelSize(font_size) _app.setFont(font) if os.path.exists(utils.resource_path('assets/OpenSans-Bold.ttf')): QFontDatabase.addApplicationFont( utils.resource_path('assets/OpenSans-Bold.ttf')) # mainwindow statusbar self.progressbar = QProgressBar() self.progressbar.setRange(0, 0) self.progressbar.setVisible(False) self.progressbar.setFixedHeight(15) self.progressbar.setFixedWidth(100) self.progressbar.setTextVisible(False) self.progressbar.setValue(30) self.statusbar = QStatusBar(self) self.statusbar.setAutoFillBackground(False) self.statusbar.addPermanentWidget(self.progressbar) self.statusbar.setObjectName("statusbar") self.setStatusBar(self.statusbar) self.main_tabs = QTabWidget(self) self.main_tabs.setMovable(False) self.main_tabs.setTabsClosable(True) self.main_tabs.setAutoFillBackground(True) self.main_tabs.tabCloseRequested.connect(self._on_close_tab) self.setCentralWidget(self.main_tabs) # pluginmanager self.plugin_manager = PluginManager(self) self.plugin_manager.reload_plugins() if dwarf_args.any == '': self.welcome_window = WelcomeDialog(self) self.welcome_window.setModal(True) self.welcome_window.onIsNewerVersion.connect( self._enable_update_menu) self.welcome_window.onUpdateComplete.connect( self._on_dwarf_updated) self.welcome_window.setWindowTitle( 'Welcome to Dwarf - A debugger for reverse engineers, crackers and security analyst' ) self.welcome_window.onSessionSelected.connect(self._start_session) # wait for welcome screen self.hide() self.welcome_window.show() else: print('* Starting new Session') self._start_session(dwarf_args.target) def _initialize_ui_elements(self): # dockwidgets self.watchers_dwidget = None self.hooks_dwiget = None self.bookmarks_dwiget = None self.registers_dock = None self.console_dock = None self.backtrace_dock = None self.threads_dock = None # panels self.asm_panel = None self.backtrace_panel = None self.bookmarks_panel = None self.console_panel = None self.context_panel = None self.debug_panel = None self.contexts_list_panel = None self.data_panel = None self.ftrace_panel = None self.hooks_panel = None self.java_inspector_panel = None self.java_explorer_panel = None self.java_trace_panel = None self.modules_panel = None self.ranges_panel = None self.search_panel = None self.smali_panel = None self.watchers_panel = None self.welcome_window = None self._ui_elems = [] def _setup_main_menu(self): self.menu = self.menuBar() dwarf_menu = QMenu('Dwarf', self) theme = QMenu('Theme', dwarf_menu) theme.addAction('Black') theme.addAction('Dark') theme.addAction('Light') theme.triggered.connect(self._set_theme) dwarf_menu.addMenu(theme) dwarf_menu.addSeparator() if sys.platform == 'linux' or sys.platform == 'darwin': dwarf_bin_path = os.path.join( '/'.join(os.path.realpath(__file__).split('/')[:-2]), 'bin/dwarf') if not os.path.exists(dwarf_bin_path): dwarf_menu.addAction('Create launcher', utils.create_launcher) dwarf_menu.addSeparator() if self._is_newer_dwarf: dwarf_menu.addAction('Update', self._update_dwarf) dwarf_menu.addAction('Close', self.session_manager.session.stop) self.menu.addMenu(dwarf_menu) session = self.session_manager.session if session is not None: session_menu = session.main_menu if isinstance(session_menu, list): for menu in session_menu: self.menu.addMenu(menu) else: self.menu.addMenu(session_menu) # plugins if self.plugin_manager.plugins: self.plugin_menu = QMenu('Plugins', self) for plugin in self.plugin_manager.plugins: plugin_instance = self.plugin_manager.plugins[plugin] plugin_sub_menu = self.plugin_menu.addMenu( plugin_instance.name) try: actions = plugin_instance.__get_top_menu_actions__() for action in actions: plugin_sub_menu.addAction(action) except: pass if not plugin_sub_menu.isEmpty(): plugin_sub_menu.addSeparator() about = plugin_sub_menu.addAction('About') about.triggered.connect( lambda x, item=plugin: self._show_plugin_about(item)) if not self.plugin_menu.isEmpty(): self.menu.addMenu(self.plugin_menu) self.view_menu = QMenu('View', self) self.panels_menu = QMenu('Panels', self.view_menu) self.panels_menu.addAction('Search', lambda: self.show_main_tab('search'), shortcut=QKeySequence(Qt.CTRL + Qt.Key_F3)) self.view_menu.addMenu(self.panels_menu) self.debug_view_menu = self.view_menu.addMenu('Debug') self.view_menu.addSeparator() self.view_menu.addAction('Hide all', self._hide_all_widgets, shortcut=QKeySequence(Qt.CTRL + Qt.Key_F1)) self.view_menu.addAction('Show all', self._show_all_widgets, shortcut=QKeySequence(Qt.CTRL + Qt.Key_F2)) self.view_menu.addSeparator() self.menu.addMenu(self.view_menu) if self.dwarf_args.debug_script: debug_menu = QMenu('Debug', self) debug_menu.addAction('Reload core', self._menu_reload_core) debug_menu.addAction('Debug dwarf js core', self._menu_debug_dwarf_js) self.menu.addMenu(debug_menu) # tools _tools = self.prefs.get('tools') if _tools: tools_menu = QMenu('Tools', self) for _tool in _tools: if _tool and _tool['name']: if _tool['name'] == 'sep': tools_menu.addSeparator() continue _cmd = _tool['cmd'] tools_menu.addAction(_tool['name']) if not tools_menu.isEmpty(): tools_menu.triggered.connect(self._execute_tool) self.menu.addMenu(tools_menu) about_menu = QMenu('About', self) about_menu.addAction('Dwarf on GitHub', self._menu_github) about_menu.addAction('Documention', self._menu_documentation) about_menu.addAction('Api', self._menu_api) about_menu.addAction('Slack', self._menu_slack) about_menu.addSeparator() about_menu.addAction('Info', self._show_about_dlg) self.menu.addMenu(about_menu) def _show_plugin_about(self, plugin): plugin = self.plugin_manager.plugins[plugin] if plugin: info = plugin.__get_plugin_info__() version = utils.safe_read_map(info, 'version', '') description = utils.safe_read_map(info, 'description', '') author = utils.safe_read_map(info, 'author', '') homepage = utils.safe_read_map(info, 'homepage', '') license_ = utils.safe_read_map(info, 'license', '') utils.show_message_box( 'Name: {0}\nVersion: {1}\nDescription: {2}\nAuthor: {3}\nHomepage: {4}\nLicense: {5}' .format(plugin.name, version, description, author, homepage, license_)) def _enable_update_menu(self): self._is_newer_dwarf = True def _update_dwarf(self): if self.welcome_window: self.welcome_window._update_dwarf() def _on_close_tab(self, index): tab_text = self.main_tabs.tabText(index) if tab_text: tab_text = tab_text.lower().replace(' ', '-') if tab_text in self.session_manager.session.non_closable: return try: self._ui_elems.remove(tab_text) except ValueError: # recheck ValueError: list.remove(x): x not in list pass self.main_tabs.removeTab(index) self.onSystemUIElementRemoved.emit(tab_text) def _handle_tab_change(self): for index in range(self.main_tabs.count()): tab_name = self.main_tabs.tabText(index).lower().replace(' ', '-') if tab_name in self.session_manager.session.non_closable: self.main_tabs.tabBar().setTabButton(index, QTabBar.RightSide, None) if tab_name in self._tab_order: should_index = self._tab_order.index(tab_name) if index != should_index: self.main_tabs.tabBar().moveTab(index, should_index) def _on_dwarf_updated(self): self.onRestart.emit() def remove_tmp_dir(self): if os.path.exists('.tmp'): shutil.rmtree('.tmp', ignore_errors=True) def _execute_tool(self, qaction): if qaction: _tools = self.prefs.get('tools') if _tools: for _tool in _tools: if _tool and _tool['name'] and _tool['name'] != 'sep': if qaction.text() == _tool['name']: try: import subprocess subprocess.Popen(_tool['cmd'], creationflags=subprocess. CREATE_NEW_CONSOLE) except: pass break def _set_theme(self, qaction): if qaction: utils.set_theme(qaction.text(), self.prefs) def _hide_all_widgets(self): self.watchers_dwidget.hide() self.hooks_dwiget.hide() self.bookmarks_dwiget.hide() self.registers_dock.hide() self.console_dock.hide() self.backtrace_dock.hide() self.threads_dock.hide() def _show_all_widgets(self): self.watchers_dwidget.show() self.hooks_dwiget.show() self.bookmarks_dwiget.show() self.registers_dock.show() self.console_dock.show() self.backtrace_dock.show() self.threads_dock.show() def _menu_reload_core(self): self.dwarf.script.exports.reload() def _menu_debug_dwarf_js(self): you_know_what_to_do = json.loads( self.dwarf.script.exports.debugdwarfjs()) return you_know_what_to_do def show_main_tab(self, name): name = name.lower() # elem doesnt exists? create it if name not in self._ui_elems: self._create_ui_elem(name) index = 0 name = name.join(name.split()).lower() if name == 'ranges': index = self.main_tabs.indexOf(self.ranges_panel) elif name == 'search': index = self.main_tabs.indexOf(self.search_panel) elif name == 'modules': index = self.main_tabs.indexOf(self.modules_panel) elif name == 'data': index = self.main_tabs.indexOf(self.data_panel) elif name == 'jvm-tracer': index = self.main_tabs.indexOf(self.java_trace_panel) elif name == 'jvm-inspector': index = self.main_tabs.indexOf(self.java_inspector_panel) elif name == 'jvm-debugger': index = self.main_tabs.indexOf(self.java_explorer_panel) elif name == 'smali': index = self.main_tabs.indexOf(self.smali_panel) self.main_tabs.setCurrentIndex(index) def jump_to_address(self, ptr, view=0, show_panel=True): if show_panel: self.show_main_tab('debug') self.debug_panel.jump_to_address(ptr, view=view) @pyqtSlot(name='mainMenuGitHub') def _menu_github(self): QDesktopServices.openUrl(QUrl('https://github.com/iGio90/Dwarf')) @pyqtSlot(name='mainMenuApi') def _menu_api(self): QDesktopServices.openUrl( QUrl('http://www.giovanni-rocca.com/dwarf/javascript/')) @pyqtSlot(name='mainMenuDocumentation') def _menu_documentation(self): QDesktopServices.openUrl(QUrl('http://www.giovanni-rocca.com/dwarf/')) @pyqtSlot(name='mainMenuSlack') def _menu_slack(self): QDesktopServices.openUrl( QUrl('https://join.slack.com/t/resecret/shared_invite' '/enQtMzc1NTg4MzE3NjA1LTlkNzYxNTIwYTc2ZTYyOWY1MT' 'Q1NzBiN2ZhYjQwYmY0ZmRhODQ0NDE3NmRmZjFiMmE1MDYwN' 'WJlNDVjZDcwNGE')) def _show_about_dlg(self): about_dlg = AboutDialog(self) about_dlg.show() def _create_ui_elem(self, elem): elem = elem.lower() if not isinstance(elem, str): return if elem not in self._ui_elems: self._ui_elems.append(elem) elem_wiget = None if elem == 'watchers': from ui.session_widgets.watchers import WatchersWidget self.watchers_dwidget = QDockWidget('Watchers', self) self.watchers_panel = WatchersWidget(self) # dont respond to dblclick mem cant be shown # self.watchers_panel.onItemDoubleClicked.connect( # self._on_watcher_clicked) self.watchers_panel.onItemRemoved.connect( self._on_watcher_removeditem) self.watchers_panel.onItemAdded.connect(self._on_watcher_added) self.watchers_dwidget.setWidget(self.watchers_panel) self.watchers_dwidget.setObjectName('WatchersWidget') self.addDockWidget(Qt.LeftDockWidgetArea, self.watchers_dwidget) self.view_menu.addAction(self.watchers_dwidget.toggleViewAction()) elem_wiget = self.watchers_panel elif elem == 'hooks': from ui.session_widgets.hooks import HooksWidget self.hooks_dwiget = QDockWidget('Breakpoints', self) self.hooks_panel = HooksWidget(self) self.hooks_panel.onHookRemoved.connect(self._on_hook_removed) self.hooks_dwiget.setWidget(self.hooks_panel) self.hooks_dwiget.setObjectName('HooksWidget') self.addDockWidget(Qt.LeftDockWidgetArea, self.hooks_dwiget) self.view_menu.addAction(self.hooks_dwiget.toggleViewAction()) elem_wiget = self.hooks_panel elif elem == 'bookmarks': from ui.session_widgets.bookmarks import BookmarksWidget self.bookmarks_dwiget = QDockWidget('Boomarks', self) self.bookmarks_panel = BookmarksWidget(self) self.bookmarks_dwiget.setWidget(self.bookmarks_panel) self.bookmarks_dwiget.setObjectName('BookmarksWidget') self.addDockWidget(Qt.LeftDockWidgetArea, self.bookmarks_dwiget) self.view_menu.addAction(self.bookmarks_dwiget.toggleViewAction()) elem_wiget = self.bookmarks_panel elif elem == 'registers': from ui.session_widgets.context import ContextWidget self.registers_dock = QDockWidget('Context', self) self.context_panel = ContextWidget(self) self.registers_dock.setWidget(self.context_panel) self.registers_dock.setObjectName('ContextWidget') self.addDockWidget(Qt.RightDockWidgetArea, self.registers_dock) self.view_menu.addAction(self.registers_dock.toggleViewAction()) elem_wiget = self.context_panel elif elem == 'debug': from ui.panels.panel_debug import QDebugPanel self.debug_panel = QDebugPanel(self) self.main_tabs.addTab(self.debug_panel, 'Debug') elem_wiget = self.debug_panel elif elem == 'jvm-debugger': from ui.panels.panel_java_explorer import JavaExplorerPanel self.java_explorer_panel = JavaExplorerPanel(self) self.main_tabs.addTab(self.java_explorer_panel, 'JVM debugger') self.main_tabs.tabBar().moveTab( self.main_tabs.indexOf(self.java_explorer_panel), 1) elem_wiget = self.java_explorer_panel elif elem == 'jvm-inspector': from ui.panels.panel_java_inspector import JavaInspector self.java_inspector_panel = JavaInspector(self) self.main_tabs.addTab(self.java_inspector_panel, 'JVM inspector') elem_wiget = self.java_inspector_panel elif elem == 'console': from ui.session_widgets.console import ConsoleWidget self.console_dock = QDockWidget('Console', self) self.console_panel = ConsoleWidget(self) if self.dwarf_args.script and len( self.dwarf_args.script) > 0 and os.path.exists( self.dwarf_args.script): with open(self.dwarf_args.script, 'r') as f: self.console_panel.get_js_console( ).script_file = self.dwarf_args.script self.console_panel.get_js_console( ).function_content = f.read() self.dwarf.onLogToConsole.connect(self._log_js_output) self.dwarf.onLogEvent.connect(self._log_event) self.console_dock.setWidget(self.console_panel) self.console_dock.setObjectName('ConsoleWidget') self.addDockWidget(Qt.BottomDockWidgetArea, self.console_dock) self.view_menu.addAction(self.console_dock.toggleViewAction()) elem_wiget = self.console_panel elif elem == 'backtrace': from ui.session_widgets.backtrace import BacktraceWidget self.backtrace_dock = QDockWidget('Backtrace', self) self.backtrace_panel = BacktraceWidget(self) self.backtrace_dock.setWidget(self.backtrace_panel) self.backtrace_dock.setObjectName('BacktraceWidget') self.backtrace_panel.onShowMemoryRequest.connect( self._on_showmemory_request) self.addDockWidget(Qt.RightDockWidgetArea, self.backtrace_dock) self.view_menu.addAction(self.backtrace_dock.toggleViewAction()) elem_wiget = self.backtrace_panel elif elem == 'threads': from ui.session_widgets.threads import ThreadsWidget self.threads_dock = QDockWidget('Threads', self) self.contexts_list_panel = ThreadsWidget(self) self.dwarf.onThreadResumed.connect( self.contexts_list_panel.resume_tid) self.contexts_list_panel.onItemDoubleClicked.connect( self._manually_apply_context) self.threads_dock.setWidget(self.contexts_list_panel) self.threads_dock.setObjectName('ThreadPanel') self.addDockWidget(Qt.RightDockWidgetArea, self.threads_dock) self.view_menu.addAction(self.threads_dock.toggleViewAction()) elem_wiget = self.contexts_list_panel elif elem == 'modules': from ui.panels.panel_modules import ModulesPanel self.modules_panel = ModulesPanel(self) self.modules_panel.onModuleSelected.connect( self._on_module_dblclicked) self.modules_panel.onModuleFuncSelected.connect( self._on_modulefunc_dblclicked) self.modules_panel.onAddHook.connect(self._on_addmodule_hook) self.modules_panel.onDumpBinary.connect(self._on_dumpmodule) self.main_tabs.addTab(self.modules_panel, 'Modules') elem_wiget = self.modules_panel elif elem == 'ranges': from ui.panels.panel_ranges import RangesPanel self.ranges_panel = RangesPanel(self) self.ranges_panel.onItemDoubleClicked.connect( self._range_dblclicked) self.ranges_panel.onDumpBinary.connect(self._on_dumpmodule) # connect to watcherpanel func self.ranges_panel.onAddWatcher.connect( self.watchers_panel.do_addwatcher_dlg) self.main_tabs.addTab(self.ranges_panel, 'Ranges') elem_wiget = self.ranges_panel elif elem == 'search': from ui.panels.panel_search import SearchPanel self.search_panel = SearchPanel(self) self.main_tabs.addTab(self.search_panel, 'Search') elem_wiget = self.search_panel elif elem == 'data': from ui.panels.panel_data import DataPanel self.data_panel = DataPanel(self) self.main_tabs.addTab(self.data_panel, 'Data') elem_wiget = self.data_panel elif elem == 'jvm-tracer': from ui.panels.panel_java_trace import JavaTracePanel self.java_trace_panel = JavaTracePanel(self) self.main_tabs.addTab(self.java_trace_panel, 'JVM tracer') elem_wiget = self.java_trace_panel elif elem == 'smali': from ui.panels.panel_smali import SmaliPanel self.smali_panel = SmaliPanel() self.main_tabs.addTab(self.smali_panel, 'Smali') elem_wiget = self.smali_panel else: print('no handler for elem: ' + elem) # make tabs unclosable and sort self._handle_tab_change() if elem_wiget is not None: self.onSystemUIElementCreated.emit(elem, elem_wiget) # TODO: remove add @2x for item in self.findChildren(QDockWidget): if item: if 'darwin' in sys.platform: item.setStyleSheet( 'QDockWidget::title { padding-left:-30px; }') def set_status_text(self, txt): self.statusbar.showMessage(txt) # ************************************************************************ # **************************** Properties ******************************** # ************************************************************************ @property def disassembly(self): return self.asm_panel @property def backtrace(self): return self.backtrace_panel @property def console(self): return self.console_panel @property def context(self): return self.context_panel @property def threads(self): return self.contexts_list_panel @property def ftrace(self): return self.ftrace_panel @property def hooks(self): return self.hooks_panel @property def java_inspector(self): return self.java_inspector_panel @property def java_explorer(self): return self.java_explorer_panel @property def modules(self): return self.modules_panel @property def ranges(self): return self.ranges_panel @property def watchers(self): return self.watchers_panel @property def dwarf(self): if self.session_manager.session is not None: return self.session_manager.session.dwarf else: return None @property def ui_elements(self): return self._ui_elems # ************************************************************************ # **************************** Handlers ********************************** # ************************************************************************ # session handlers def _start_session(self, session_type, session_data=None): if self.welcome_window is not None: self.welcome_window.close() self.session_manager.create_session(session_type, session_data=session_data) def _restore_session(self, session_data): if 'session' in session_data: session_type = session_data['session'] self.dwarf_args.any = session_data['package'] self._start_session(session_type, session_data=session_data) def session_created(self): # session init done create ui for it session = self.session_manager.session self._setup_main_menu() for ui_elem in session.session_ui_sections: ui_elem = ui_elem.join(ui_elem.split()).lower() self._create_ui_elem(ui_elem) self.dwarf.onProcessAttached.connect(self._on_attached) self.dwarf.onProcessDetached.connect(self._on_detached) self.dwarf.onScriptLoaded.connect(self._on_script_loaded) # hookup self.dwarf.onSetRanges.connect(self._on_setranges) self.dwarf.onSetModules.connect(self._on_setmodules) self.dwarf.onAddNativeHook.connect(self._on_add_hook) self.dwarf.onApplyContext.connect(self._apply_context) self.dwarf.onThreadResumed.connect(self.on_tid_resumed) self.dwarf.onSetData.connect(self._on_set_data) self.session_manager.start_session(self.dwarf_args) ui_state = self.q_settings.value('dwarf_ui_state') if ui_state: self.restoreGeometry(ui_state) window_state = self.q_settings.value('dwarf_ui_window', self.saveState()) if window_state: self.restoreState(window_state) self.showMaximized() def session_stopped(self): self.remove_tmp_dir() self.menu.clear() self.main_tabs.clear() # actually we need to kill this. needs a refactor if self.java_trace_panel is not None: self.java_trace_panel = None for elem in self._ui_elems: if elem == 'watchers': self.watchers_panel.clear_list() self.watchers_panel.close() self.watchers_panel = None self.removeDockWidget(self.watchers_dwidget) self.watchers_dwidget = None elif elem == 'hooks': self.hooks_panel.close() self.hooks_panel = None self.removeDockWidget(self.hooks_dwiget) self.hooks_dwiget = None elif elem == 'registers': self.context_panel.close() self.context_panel = None self.removeDockWidget(self.registers_dock) self.registers_dock = None elif elem == 'debug': self.debug_panel.close() self.debug_panel = None self.main_tabs.removeTab(0) # self.main_tabs elif elem == 'jvm-debugger': self.java_explorer_panel.close() self.java_explorer_panel = None self.removeDockWidget(self.watchers_dwidget) elif elem == 'console': self.console_panel.close() self.console_panel = None self.removeDockWidget(self.console_dock) self.console_dock = None elif elem == 'backtrace': self.backtrace_panel.close() self.backtrace_panel = None self.removeDockWidget(self.backtrace_dock) elif elem == 'threads': self.contexts_list_panel.close() self.contexts_list_panel = None self.removeDockWidget(self.threads_dock) self.threads_dock = None elif elem == 'bookmarks': self.bookmarks_panel.close() self.bookmarks_panel = None self.removeDockWidget(self.bookmarks_dwiget) self.bookmarks_dwiget = None self._initialize_ui_elements() def session_closed(self): self._initialize_ui_elements() self.hide() if self.welcome_window is not None: self.welcome_window.exec() # close if it was a commandline session if self.welcome_window is None: if self.dwarf_args.any != '': self.close() # ui handler def closeEvent(self, event): """ Window closed save stuff or whatever at exit detaches dwarf """ # save windowstuff self.q_settings.setValue('dwarf_ui_state', self.saveGeometry()) self.q_settings.setValue('dwarf_ui_window', self.saveState()) if self.dwarf: try: self.dwarf.detach() except: pass super().closeEvent(event) def _on_watcher_clicked(self, ptr): """ Address in Watcher/Hookpanel was clicked show Memory """ if '.' in ptr: # java_hook file_path = ptr.replace('.', os.path.sep) if os.path.exists('.tmp/smali/' + file_path + '.smali'): if self.smali_panel is None: self._create_ui_elem('smali') self.smali_panel.set_file('.tmp/smali/' + file_path + '.smali') self.show_main_tab('smali') else: self.jump_to_address(ptr) def _on_watcher_added(self, ptr): """ Watcher Entry was added """ try: # set highlight self.debug_panel.memory_panel.add_highlight( HighLight('watcher', ptr, self.dwarf.pointer_size)) except HighlightExistsError: pass def _on_watcher_removeditem(self, ptr): """ Watcher Entry was removed remove highlight too """ self.debug_panel.memory_panel.remove_highlight(ptr) def _on_module_dblclicked(self, data): """ Module in ModulePanel was doubleclicked """ addr, size = data addr = utils.parse_ptr(addr) self.jump_to_address(addr) def _on_modulefunc_dblclicked(self, ptr): """ Function in ModulePanel was doubleclicked """ ptr = utils.parse_ptr(ptr) self.jump_to_address(ptr) def _on_dumpmodule(self, data): """ DumpBinary MenuItem in ModulePanel was selected """ ptr, size = data ptr = utils.parse_ptr(ptr) size = int(size, 10) self.dwarf.dump_memory(ptr=ptr, length=size) def _disassemble_range(self, dwarf_range): """ Disassemble MenuItem in Hexview was selected """ if dwarf_range: if self.asm_panel is None: self._create_ui_elem('disassembly') self.asm_panel.disassemble(dwarf_range) self.show_main_tab('disassembly') def _range_dblclicked(self, ptr): """ Range in RangesPanel was doubleclicked """ ptr = utils.parse_ptr(ptr) self.jump_to_address(ptr) # dwarf handlers def _log_js_output(self, output): if self.console_panel is not None: time_prefix = True if len(output.split('\n')) > 1 or len(output.split('<br />')) > 1: time_prefix = False self.console_panel.get_js_console().log(output, time_prefix=time_prefix) def _log_event(self, output): if self.console_panel is not None: self.console_panel.get_events_console().log(output) def _on_setranges(self, ranges): """ Dwarf wants to set Ranges only hooked up to switch tab or create ui its connected in panel after creation """ if self.ranges_panel is None: self.show_main_tab('ranges') # forward only now to panel it connects after creation self.ranges_panel.set_ranges(ranges) def _on_setmodules(self, modules): """ Dwarf wants to set Modules only hooked up to switch tab or create ui its connected in panel after creation """ if self.modules_panel is None: self._create_ui_elem('modules') self.modules_panel.set_modules(modules) if self.modules_panel is not None: self.show_main_tab('modules') def _manually_apply_context(self, context): """ perform additional operation if the context has been manually applied from the context list """ self._apply_context(context, manual=True) def _apply_context(self, context, manual=False): # update current context tid # this should be on top as any further api from js needs to be executed on that thread reason = context['reason'] is_initial_setup = reason == -1 if manual or (self.dwarf.context_tid and not is_initial_setup): self.dwarf.context_tid = context['tid'] if is_initial_setup: self.debug_panel.on_context_setup() if 'context' in context: if not manual: self.threads.add_context(context) is_java = context['is_java'] if is_java: if self.java_explorer_panel is None: self._create_ui_elem('jvm-debugger') self.context_panel.set_context(context['ptr'], 1, context['context']) self.java_explorer_panel._set_handle_arg(-1) self.show_main_tab('jvm-debugger') else: self.context_panel.set_context(context['ptr'], 0, context['context']) if reason == 2: # native on load if self.debug_panel.memory_panel_range is None: base = context['moduleBase'] self.jump_to_address(base) else: if 'pc' in context['context']: if self.debug_panel.disassembly_panel_range is None or manual: self.jump_to_address( context['context']['pc']['value'], view=1) if 'backtrace' in context: self.backtrace_panel.set_backtrace(context['backtrace']) def _on_add_hook(self, hook): try: # set highlight ptr = hook.get_ptr() ptr = utils.parse_ptr(ptr) self.debug_panel.memory_panel.add_highlight( HighLight('hook', ptr, self.dwarf.pointer_size)) except HighlightExistsError: pass def _on_hook_removed(self, ptr): ptr = utils.parse_ptr(ptr) self.debug_panel.memory_panel.remove_highlight(ptr) def _on_addmodule_hook(self, data): ptr, name = data self.dwarf.hook_native(ptr, own_input=name) def on_tid_resumed(self, tid): if self.dwarf: if self.dwarf.context_tid == tid: # clear backtrace if 'backtrace' in self._ui_elems: if self.backtrace_panel is not None: self.backtrace_panel.clear() # remove thread if 'threads' in self._ui_elems: if self.contexts_list_panel is not None: self.contexts_list_panel.resume_tid(tid) # clear registers if 'registers' in self._ui_elems: if self.context_panel is not None: self.context_panel.clear() # clear jvm explorer if 'jvm-debugger' in self._ui_elems: if self.java_explorer_panel is not None: self.java_explorer_panel.clear_panel() # invalidate dwarf context tid self.dwarf.context_tid = 0 def _on_set_data(self, data): if not isinstance(data, list): return if self.data_panel is None: self.show_main_tab('data') if self.data_panel is not None: self.data_panel.append_data(data[0], data[1], data[2]) def show_progress(self, text): self.progressbar.setVisible(True) self.set_status_text(text) def hide_progress(self): self.progressbar.setVisible(False) self.set_status_text('') def _on_attached(self, data): self.setWindowTitle('Dwarf - Attached to %s (%s)' % (data[1], data[0])) def _on_detached(self, data): reason = data[1] if reason == 'application-requested': self.session_manager.session.stop() return 0 if self.dwarf is not None: ret = QDialogDetached.show_dialog(self.dwarf, data[0], data[1], data[2]) if ret == 0: self.dwarf.restart_proc() elif ret == 1: self.session_manager.session.stop() return 0 def _on_script_loaded(self): # restore the loaded session if any self.session_manager.restore_session() def on_add_bookmark(self, ptr): """ provide ptr as int """ if self.bookmarks_panel is not None: self.bookmarks_panel._create_bookmark(ptr=hex(ptr)) def _on_showmemory_request(self, ptr): # its simple ptr show in memorypanel if isinstance(ptr, str): ptr = utils.parse_ptr(ptr) self.jump_to_address(ptr, 0) elif isinstance(ptr, list): # TODO: extend caller, ptr = ptr ptr = utils.parse_ptr(ptr) if caller == 'backtrace' or caller == 'bt': # jumpto in disasm self.jump_to_address(ptr, 1)
class EditThParametersDialog(QDialog): """Create the form that is used to modify the theorys parameters""" def __init__(self, parent, p_name): super().__init__(parent) self.parent_theory = parent self.tabs = QTabWidget() self.all_pattr = {} for pname in self.parent_theory.parameters: tab = self.create_param_tab(pname) self.tabs.addTab(tab, pname) if pname == p_name: index = self.tabs.indexOf(tab) self.tabs.setCurrentIndex(index) buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) mainLayout = QVBoxLayout() mainLayout.addWidget(self.tabs) mainLayout.addWidget(buttonBox) self.setLayout(mainLayout) self.setWindowTitle("Theory Parameters") def create_param_tab(self, p_name): """Create a form to set the new values of the file parameters""" tab = QWidget() layout = QFormLayout() p = self.parent_theory.parameters[p_name] p_attributes = p.__dict__ attr_dict = {} a_new = [] i = 0 for attr_name in p_attributes: #loop over the Parameters attributes if attr_name == 'type': cb = QComboBox() cb.addItem('real') cb.addItem('integer') cb.addItem('discrete_real') cb.addItem('discrete_integer') cb.addItem('boolean') # cb.setCurrentText('%s'.split(".")[-1] % p_attributes[attr_name]) s = '%s' % p_attributes[attr_name] cb.setCurrentText(s.split(".")[-1]) a_new.append(cb) elif attr_name == 'opt_type': cb = QComboBox() cb.addItem('opt') cb.addItem('nopt') cb.addItem('const') # cb.setCurrentText('%s'.split(".")[-1] % p_attributes[attr_name]) s = '%s' % p_attributes[attr_name] cb.setCurrentText(s.split(".")[-1]) a_new.append(cb) elif attr_name == 'display_flag': cb = QComboBox() cb.addItem('True') cb.addItem('False') cb.setCurrentText('%s' % p_attributes[attr_name]) a_new.append(cb) elif attr_name in ['value', 'error']: continue else: qline = QLineEdit() if attr_name in ['name', 'description']: qline.setReadOnly(True) a_new.append(qline) a_new[i].setText("%s" % p_attributes[attr_name]) layout.addRow("%s:" % attr_name, a_new[i]) attr_dict[attr_name] = a_new[i] i += 1 tab.setLayout(layout) self.all_pattr[p_name] = attr_dict return tab