def createEditor(self, parent): """ Creates a QLineEdit instance for GUI editing of integer values :param parent: the parent of the widget :return: a QLineEdit instance """ res = QLineEdit(parent) v = QDoubleValidator() # QDoubleValidator seems to have a very strange behaviour when bottom and/or top values are set. # Therefore, we don't use this feature and rely on our own implementation. res.setValidator(v) res.setFrame(False) return res
class PropertyTreeDelegateEditor(QFrame): """A special editor that handles renaming blocks and groups.""" sizeHintChanged = Signal(object) """Emitted when the widget changes sizeHint. Delegate should update it's geometry.""" def __init__(self, parent=None): super().__init__(parent) layout = QVBoxLayout() self.setLayout(layout) self.setContentsMargins(0, 0, 0, 0) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) self.setAutoFillBackground(True) self.setFocusPolicy(Qt.StrongFocus) self.setFrameStyle(QFrame.Panel | QFrame.Plain) self._fallback_text = None self._experiment = None self.line_edit = QLineEdit() self.line_edit.setFrame(False) self.message_label = QLabel() self.message_label.hide() # Divider line self.divider_line = QFrame() self.divider_line.setFrameShape(QFrame.HLine) self.divider_line.setFrameShadow(QFrame.Plain) self.divider_line.setLineWidth(1) layout.addWidget(self.line_edit) layout.addWidget(self.divider_line) layout.addWidget(self.message_label) self.line_edit.textChanged.connect(self._updateMessage) def experiment(self): return self._experiment def setExperiment(self, ex): self._experiment = ex def fallbackText(self): return self._fallback_text def text(self): """Get the current text value of the editor widget. If editing has not been finished succesfully, returns fallbackText(). """ (text_ok, _) = self.experiment().checkName(self.line_edit.text()) if text_ok: return self.line_edit.text() else: return self.fallbackText() def setFallbackText(self, text): """Set the fallback text value to be used if the editing was not succesfully finished. The text() method returns this value or the line_edit text. """ self._fallback_text = text def setText(self, text): """Set currently editable text. Equivalent to self.line_edit.setText.""" self.line_edit.setText(text) def _updateMessage(self): """Update the displayed message in response to changed text.""" if self.line_edit.text() == self.fallbackText(): # Perform no check text_ok = True else: (text_ok, reason) = self.experiment().checkName(self.line_edit.text()) if text_ok: self.message_label.hide() self.divider_line.hide() else: self.message_label.setText(reason) self.message_label.show() self.divider_line.show() self.sizeHintChanged.emit(self) def focusInEvent(self, event): super().focusInEvent(event) self.line_edit.setFocus()
class PageAllegroOptions(QWidget): def __init__(self, parent=None): QWidget.__init__(self) self.parent = parent self.parent.addWidget(self) self.auto_login, self.auto_pwd, self.auto_email, self.auto_time = data.get_autofill() self.gridLayout = QGridLayout(self) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setSpacing(0) self.gridLayout.setColumnStretch(0, 3) self.gridLayout.setColumnStretch(1, 7) self.pushButton_auto = QPushButton(self) self.pushButton_auto.setText("Autofill") self.pushButton_auto.setStyleSheet(styles.btn_allegro_ops_auto) self.pushButton_auto.setCheckable(True) self.pushButton_auto.setChecked(True) self.pushButton_auto.clicked.connect(lambda: self.on_auto()) self.gridLayout.addWidget(self.pushButton_auto, 0, 0, 1, 1) self.pushButton_help = QPushButton(self) self.pushButton_help.setText("Help") self.pushButton_help.setStyleSheet(styles.btn_allegro_ops_auto) self.pushButton_help.setCheckable(True) self.pushButton_help.setChecked(False) self.pushButton_help.clicked.connect(lambda: self.on_help()) self.gridLayout.addWidget(self.pushButton_help, 1, 0, 1, 1) self.spacer_btn_d = QSpacerItem(40, 20, QSizePolicy.Expanding) self.gridLayout.addItem(self.spacer_btn_d, 2, 0, 1, 1) self.stackedWidget = QStackedWidget(self) self.stackedWidget.setStyleSheet("""QStackedWidget{background-color: #fff;}""") self.gridLayout.addWidget(self.stackedWidget, 0, 1, 3, 1) self.widget_auto = QWidget(self.stackedWidget) self.widget_auto.setStyleSheet("""QWidget{background-color: #fff;}""") self.stackedWidget.addWidget(self.widget_auto) self.widget_help = QWidget(self.stackedWidget) self.widget_help.setStyleSheet("""QWidget{background-color: #fff;}""") self.stackedWidget.addWidget(self.widget_help) self.gridLayout_help = QVBoxLayout(self.widget_help) self.gridLayout_help.setContentsMargins(50, 50, 50, 50) self.gridLayout_help.setSpacing(50) self.label_help = QLabel(self.widget_help) self.label_help.setStyleSheet(styles.label_lineEdit) self.label_help.setWordWrap(True) self.label_help.setText(styles.help_text) self.gridLayout_help.addWidget(self.label_help) self.spacer_help = QSpacerItem(40, 20, QSizePolicy.Expanding) self.gridLayout_help.addItem(self.spacer_help) self.gridLayout_auto = QGridLayout(self.widget_auto) self.gridLayout_auto.setContentsMargins(0, 0, 0, 0) self.gridLayout_auto.setSpacing(20) self.gridLayout_auto.setColumnStretch(0, 1) self.gridLayout_auto.setColumnStretch(1, 1) self.gridLayout_auto.setColumnStretch(2, 1) self.gridLayout_auto.setColumnStretch(3, 1) self.gridLayout_auto.setRowStretch(0, 3) self.gridLayout_auto.setRowStretch(1, 1) self.gridLayout_auto.setRowStretch(2, 1) self.gridLayout_auto.setRowStretch(3, 1) self.gridLayout_auto.setRowStretch(4, 1) self.gridLayout_auto.setRowStretch(5, 1) self.gridLayout_auto.setRowStretch(6, 3) self.lineEdit_login = QLineEdit(self.widget_auto) self.lineEdit_login.setMinimumSize(QSize(0, 60)) self.lineEdit_login.setSizeIncrement(QSize(40, 40)) self.lineEdit_login.setStyleSheet(styles.lineEdit_opt) self.gridLayout_auto.addWidget(self.lineEdit_login, 1, 2, 1, 1) self.lineEdit_login.setPlaceholderText("login or email of your account") self.lineEdit_login.setText(self.auto_login) self.lineEdit_password = QLineEdit(self.widget_auto) self.lineEdit_password.setMinimumSize(QSize(20, 60)) self.lineEdit_password.setStyleSheet(styles.lineEdit_opt) self.lineEdit_password.setEchoMode(QLineEdit.Password) self.lineEdit_password.setReadOnly(False) self.gridLayout_auto.addWidget(self.lineEdit_password, 2, 2, 1, 1) self.lineEdit_password.setPlaceholderText("password of your account") self.lineEdit_password.setText(self.auto_pwd) self.lineEdit_email = QLineEdit(self.widget_auto) self.lineEdit_email.setMinimumSize(QSize(0, 60)) self.lineEdit_email.setStyleSheet(styles.lineEdit_opt) self.lineEdit_email.setFrame(True) self.lineEdit_email.setEchoMode(QLineEdit.Normal) self.gridLayout_auto.addWidget(self.lineEdit_email, 3, 2, 1, 1) self.lineEdit_email.setPlaceholderText("email to which the notification will be sent") self.lineEdit_email.setText(self.auto_email) self.lineEdit_time = QLineEdit(self.widget_auto) self.lineEdit_time.setMinimumSize(QSize(0, 60)) self.lineEdit_time.setStyleSheet(styles.lineEdit) self.gridLayout_auto.addWidget(self.lineEdit_time, 4, 2, 1, 1) self.lineEdit_time.setPlaceholderText("interval between refreshes") self.lineEdit_time.setText(str(self.auto_time)) self.label_login = QLabel("Allegro login", self) self.label_login.setStyleSheet(styles.label_lineEdit) self.gridLayout_auto.addWidget(self.label_login, 1, 1, 1, 1) self.label_password = QLabel("Allegro password", self) self.label_password.setStyleSheet(styles.label_lineEdit) self.gridLayout_auto.addWidget(self.label_password, 2, 1, 1, 1) self.label_email = QLabel("Email to notificate", self) self.label_email.setStyleSheet(styles.label_lineEdit) self.gridLayout_auto.addWidget(self.label_email, 3, 1, 1, 1) self.label_time = QLabel("Refresh time[s]", self) self.label_time.setStyleSheet(styles.label_lineEdit) self.gridLayout_auto.addWidget(self.label_time, 4, 1, 1, 1) self.pushButton_set = QPushButton("Set", self.widget_auto) self.pushButton_set.clicked.connect(lambda: self.on_set()) self.pushButton_set.setMinimumSize(QSize(0, 40)) self.pushButton_set.setStyleSheet(styles.btn_dark) self.gridLayout_auto.addWidget(self.pushButton_set, 5, 2, 1, 1) self.spacer_auto_l = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.gridLayout_auto.addItem(self.spacer_auto_l, 1, 1, 1, 1) self.spacer_auto_r = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.gridLayout_auto.addItem(self.spacer_auto_r, 1, 3, 1, 1) self.spacer_auto_t = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.gridLayout_auto.addItem(self.spacer_auto_t, 0, 0, 1, 1) self.spacer_auto_b = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.gridLayout_auto.addItem(self.spacer_auto_b, 6, 0, 1, 1) def on_set(self): data.add_autofill(self.lineEdit_login.text(), self.lineEdit_password.text(), self.lineEdit_email.text(), int(self.lineEdit_time.text())) auto_login, auto_pwd, auto_email, auto_time = data.get_autofill() self.parent.pageAllegroAdd.lineEdit_login.setText(auto_login) self.parent.pageAllegroAdd.lineEdit_password.setText(auto_pwd) self.parent.pageAllegroAdd.lineEdit_email.setText(auto_email) self.parent.pageAllegroAdd.lineEdit_time.setText(str(auto_time)) def on_auto(self): self.pushButton_auto.setChecked(True) self.pushButton_help.setChecked(False) self.stackedWidget.setCurrentIndex(0) def on_help(self): self.pushButton_auto.setChecked(False) self.pushButton_help.setChecked(True) self.stackedWidget.setCurrentIndex(1)
class PageAllegroAdd(QWidget): def __init__(self, parent=None, shared_dict=None): QWidget.__init__(self, parent) parent.addWidget(self) self.shared_dict = shared_dict self.gridLayout = QGridLayout(self) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setRowStretch(0, 1) self.gridLayout.setRowStretch(1, 1) self.gridLayout.setRowStretch(2, 1) self.gridLayout.setRowStretch(3, 1) self.gridLayout.setRowStretch(4, 1) self.gridLayout.setRowStretch(5, 1) self.gridLayout.setRowStretch(6, 1) self.gridLayout.setRowStretch(7, 1) self.gridLayout.setRowStretch(8, 1) self.gridLayout.setRowStretch(9, 1) self.gridLayout.setRowStretch(10, 1) self.gridLayout.setRowStretch(11, 1) self.gridLayout.setRowStretch(12, 1) self.gridLayout.setRowStretch(13, 1) self.gridLayout.setRowStretch(14, 2) self.gridLayout.setRowStretch(15, 1) self.gridLayout.setColumnStretch(0, 5) self.gridLayout.setColumnStretch(1, 5) self.gridLayout.setColumnStretch(2, 1) self.gridLayout.setColumnStretch(3, 2) self.gridLayout.setColumnStretch(4, 1) self.gridLayout.setColumnStretch(5, 2) self.gridLayout.setColumnStretch(6, 1) self.gridLayout.setColumnStretch(7, 2) self.gridLayout.setColumnStretch(8, 3) self.gridLayout.setColumnStretch(9, 5) # create lineEdits self.lineEdit_login = QLineEdit(self) self.lineEdit_login.setMinimumSize(QSize(0, 60)) self.lineEdit_login.setSizeIncrement(QSize(40, 40)) self.lineEdit_login.setStyleSheet(styles.lineEdit) self.lineEdit_login.setMaxLength(32767) self.gridLayout.addWidget(self.lineEdit_login, 4, 1, 1, 3) self.lineEdit_login.setPlaceholderText("login or email of your account") self.lineEdit_password = QLineEdit(self) self.lineEdit_password.setMinimumSize(QSize(20, 60)) self.lineEdit_password.setStyleSheet(styles.lineEdit) self.lineEdit_password.setEchoMode(QLineEdit.Password) self.lineEdit_password.setReadOnly(False) self.gridLayout.addWidget(self.lineEdit_password, 7, 1, 1, 3) self.lineEdit_password.setPlaceholderText("password of your account") self.lineEdit_email = QLineEdit(self) self.lineEdit_email.setMinimumSize(QSize(0, 60)) self.lineEdit_email.setStyleSheet(styles.lineEdit) self.lineEdit_email.setFrame(True) self.lineEdit_email.setEchoMode(QLineEdit.Normal) self.gridLayout.addWidget(self.lineEdit_email, 7, 5, 1, 4) self.lineEdit_email.setPlaceholderText("email to which the notification will be sent") self.lineEdit_link = QLineEdit(self) self.lineEdit_link.setMinimumSize(QSize(0, 60)) self.lineEdit_link.setStyleSheet(styles.lineEdit) self.gridLayout.addWidget(self.lineEdit_link, 10, 1, 1, 8) self.lineEdit_link.setPlaceholderText("link to the page that you want to monitor") self.lineEdit_price = QLineEdit(self) self.lineEdit_price.setMinimumSize(QSize(0, 60)) self.lineEdit_price.setStyleSheet(styles.lineEdit) self.gridLayout.addWidget(self.lineEdit_price, 13, 1, 1, 1) self.lineEdit_price.setPlaceholderText("Price below which to notificate") self.lineEdit_xpath = QLineEdit(self) self.lineEdit_xpath.setMinimumSize(QSize(0, 60)) self.lineEdit_xpath.setStyleSheet(styles.lineEdit) self.gridLayout.addWidget(self.lineEdit_xpath, 13, 3, 1, 3) self.lineEdit_xpath.setPlaceholderText("XPATH of element with the price") self.lineEdit_time = QLineEdit(self) self.lineEdit_time.setMinimumSize(QSize(0, 60)) self.lineEdit_time.setStyleSheet(styles.lineEdit) self.gridLayout.addWidget(self.lineEdit_time, 13, 7, 1, 2) self.lineEdit_time.setPlaceholderText("interval between refreshes") # Create Labels self.label_title = QLabel("Add new monitoring object", self) self.label_title.setStyleSheet(styles.label_title) self.label_title.setAlignment(Qt.AlignCenter) self.gridLayout.addWidget(self.label_title, 0, 1, 1, 8) self.label_info = QLabel("", self) self.label_info.setStyleSheet(styles.label_info_wrong) self.label_info.setAlignment(Qt.AlignCenter) self.gridLayout.addWidget(self.label_info, 1, 1, 1, 8) self.label_login = QLabel("Allegro login", self) self.label_login.setStyleSheet(styles.label_lineEdit) self.gridLayout.addWidget(self.label_login, 3, 1, 1, 3) self.label_password = QLabel("Allegro password", self) self.label_password.setStyleSheet(styles.label_lineEdit) self.gridLayout.addWidget(self.label_password, 6, 1, 1, 3) self.label_email = QLabel("Email to notificate", self) self.label_email.setStyleSheet(styles.label_lineEdit) self.gridLayout.addWidget(self.label_email, 6, 5, 1, 4) self.label_link = QLabel("Product link", self) self.label_link.setStyleSheet(styles.label_lineEdit) self.gridLayout.addWidget(self.label_link, 9, 1, 1, 8) self.label_price = QLabel("Price", self) self.label_price.setStyleSheet(styles.label_lineEdit) self.gridLayout.addWidget(self.label_price, 12, 1, 1, 1) self.label_xpath = QLabel("Monitored element", self) self.label_xpath.setStyleSheet(styles.label_lineEdit) self.gridLayout.addWidget(self.label_xpath, 12, 3, 1, 3) self.label_time = QLabel("Refresh time[s]", self) self.label_time.setStyleSheet(styles.label_lineEdit) self.gridLayout.addWidget(self.label_time, 12, 7, 1, 2) self.pushButton_search = QPushButton(self) self.pushButton_search.clicked.connect(lambda: webbrowser.open('https://allegro.pl/')) icon = QIcon() icon.addFile(os.path.join(path, "img/search.png"), QSize(), QIcon.Selected, QIcon.Off) self.pushButton_search.setIcon(icon) self.pushButton_search.setIconSize(QSize(100, 100)) self.pushButton_search.setStyleSheet("""QPushButton{border:none;}""") self.pushButton_search.setCursor(QCursor(Qt.PointingHandCursor)) self.gridLayout.addWidget(self.pushButton_search, 3, 7, 3, 1) # Create spacers self.spacer_search_l = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.gridLayout.addItem(self.spacer_search_l, 5, 5, 1, 2) self.spacer_search_r = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.gridLayout.addItem(self.spacer_search_r, 5, 8, 1, 1) self.spacer_search_t = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.gridLayout.addItem(self.spacer_search_t, 2, 1, 1, 8) self.spacer_search_b = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.gridLayout.addItem(self.spacer_search_b, 5, 1, 1, 8) self.spacer_email_l = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.gridLayout.addItem(self.spacer_email_l, 7, 4, 1, 1) self.spacer_link_l = QSpacerItem(40, 20, QSizePolicy.MinimumExpanding, QSizePolicy.Minimum) self.gridLayout.addItem(self.spacer_link_l, 13, 0, 1, 1) self.spacer_link_r = QSpacerItem(40, 20, QSizePolicy.MinimumExpanding, QSizePolicy.Minimum) self.gridLayout.addItem(self.spacer_link_r, 13, 9, 1, 1) self.spacer_link_t = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.gridLayout.addItem(self.spacer_link_t, 8, 1, 1, 8) self.spacer_link_b = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.gridLayout.addItem(self.spacer_link_b, 11, 1, 1, 8) self.spacer_price_b = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.gridLayout.addItem(self.spacer_price_b, 14, 1, 1, 7) # create frame bottom self.frame_bottom = QFrame(self) self.frame_bottom.setStyleSheet("""QFrame{background-color: #fff; padding: 10px;}""") self.frame_bottom.setFrameShape(QFrame.StyledPanel) self.frame_bottom.setFrameShadow(QFrame.Raised) self.gridLayout.addWidget(self.frame_bottom, 15, 0, 1, 10) self.horizontalLayout_frame_bottom = QHBoxLayout(self.frame_bottom) self.spacer_frame_bottom_l = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_frame_bottom.addItem(self.spacer_frame_bottom_l) self.pushButton_bn = QPushButton("Buy when price drops", self.frame_bottom) self.pushButton_bn.setMinimumSize(QSize(0, 40)) self.pushButton_bn.setStyleSheet(styles.btn_light) self.horizontalLayout_frame_bottom.addWidget(self.pushButton_bn) self.pushButton_bn.setShortcut("Return") self.spacer_frame_bottom_c = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_frame_bottom.addItem(self.spacer_frame_bottom_c) self.pushButton_monitor = QPushButton("Monitor", self.frame_bottom) self.pushButton_monitor.clicked.connect(lambda: self.new_link_handler(True)) self.pushButton_monitor.setMinimumSize(QSize(0, 40)) self.pushButton_monitor.setStyleSheet(styles.btn_dark) self.horizontalLayout_frame_bottom.addWidget(self.pushButton_monitor) self.spacer_frame_bottom_r = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_frame_bottom.addItem(self.spacer_frame_bottom_r) self.horizontalLayout_frame_bottom.setStretch(0, 1) self.horizontalLayout_frame_bottom.setStretch(1, 1) self.horizontalLayout_frame_bottom.setStretch(2, 2) self.horizontalLayout_frame_bottom.setStretch(3, 1) self.horizontalLayout_frame_bottom.setStretch(4, 1) self.timer = QTimer(self) auto_login, auto_pwd, auto_email, auto_time = data.get_autofill() self.lineEdit_login.setText(auto_login) self.lineEdit_password.setText(auto_pwd) self.lineEdit_email.setText(auto_email) self.lineEdit_time.setText(str(auto_time)) def new_link_handler(self, is_monitoring): # check if fields were filled properly no_warnings = True is_email = False link = "" login = "" email = "" password = "" xpath = "" price = 0 time = 60 if self.lineEdit_email.text() == "": self.lineEdit_email.setStyleSheet(styles.lineEdit_warning) no_warnings = False else: self.lineEdit_email.setStyleSheet(styles.lineEdit) email = self.lineEdit_email.text() for symbol in email: if symbol == '@': is_email = True if not is_email: self.lineEdit_email.setStyleSheet(styles.lineEdit_warning) no_warnings = False if self.lineEdit_login.text() == "": self.lineEdit_login.setStyleSheet(styles.lineEdit_warning) no_warnings = False else: self.lineEdit_login.setStyleSheet(styles.lineEdit) login = self.lineEdit_login.text() if self.lineEdit_link.text() == "": self.lineEdit_link.setStyleSheet(styles.lineEdit_warning) no_warnings = False else: self.lineEdit_link.setStyleSheet(styles.lineEdit) link = self.lineEdit_link.text() if self.lineEdit_password.text() == "": self.lineEdit_password.setStyleSheet(styles.lineEdit_warning) no_warnings = False else: self.lineEdit_password.setStyleSheet(styles.lineEdit) password = self.lineEdit_password.text() if self.lineEdit_price.text() == "": self.lineEdit_price.setStyleSheet(styles.lineEdit_warning) no_warnings = False else: self.lineEdit_price.setStyleSheet(styles.lineEdit) price = float(self.lineEdit_price.text()) if self.lineEdit_xpath.text() == "": self.lineEdit_xpath.setStyleSheet(styles.lineEdit_warning) no_warnings = False else: self.lineEdit_xpath.setStyleSheet(styles.lineEdit) xpath = self.lineEdit_xpath.text() if self.lineEdit_time.text() == "": self.lineEdit_time.setStyleSheet(styles.lineEdit_warning) no_warnings = False else: self.lineEdit_time.setStyleSheet(styles.lineEdit) time = int(self.lineEdit_time.text()) if no_warnings: self.lineEdit_login.clear() self.lineEdit_password.clear() self.lineEdit_email.clear() self.lineEdit_link.clear() self.lineEdit_price.clear() self.lineEdit_xpath.clear() self.lineEdit_time.clear() try: data.add_monitored_elements(login, email, password, link, price, xpath, time, is_monitoring) self.shared_dict['isTerminatedP2'] = True except InvalidArgumentException: self.set_info_text("Warning. Wrong link submitted", True) except KeyError: self.set_info_text("Error. This page has already monitored", True) else: self.set_info_text("Info. Object was successfully added", False) self.lineEdit_login.setText(self.auto_login) self.lineEdit_password.setText(self.auto_pwd) self.lineEdit_email.setText(self.auto_email) self.lineEdit_time.setText(self.auto_time) self.lineEdit_link.clear() self.lineEdit_price.clear() self.lineEdit_xpath.clear() else: self.set_info_text("Warning. Fill all field properly", True) return data.get_element(link) # def on_monitor(self): # new_price = monitoring.check_if_price_lower(self.label_link, self.label_xpath, self.label_price, self.label_time) # email_send.send_email(self.label_email, self.label_link, new_price) def set_info_text(self, text, is_warning): self.label_info.setText(text) if is_warning: self.label_info.setStyleSheet(styles.label_info_wrong) else: self.label_info.setStyleSheet(styles.label_info_right) self.timer.setInterval(5000) self.timer.timeout.connect(lambda: self.label_info.setText("")) self.timer.start()
class SearchReplaceDialog(QDialog): """Search & Replace window """ def __init__(self, parent, initial_query=None): """Initialize the search window """ super(SearchReplaceDialog, self).__init__(parent) self.parent = parent self.prefs = parent.prefs self.items_checked = 0 self.search_button = QPushButton('Search') self.search_text = MySearchField(self.search_button) self.search_text.setPlaceholderText("Enter search query here") self.search_button.clicked.connect(self.submit_search) input_layout = QHBoxLayout() input_layout.addWidget(self.search_text) input_layout.addWidget(self.search_button) self.results_tree = QTreeView() self.results_tree.setRootIsDecorated(False) self.results_tree.setAlternatingRowColors(True) self.results_tree.setAllColumnsShowFocus(True) self.results_tree.setSelectionBehavior(QAbstractItemView.SelectRows) self.results_tree.setSelectionMode(QAbstractItemView.SingleSelection) self.results_tree.doubleClicked.connect(self.go_to_object) self.whole_field_checkbox = QCheckBox("Whole Field Only", self) self.advanced_search_checkbox = QCheckBox("Advanced Search", self) self.advanced_search_checkbox.stateChanged.connect( self.advanced_search_checked) self.ignore_geometry_checkbox = QCheckBox("Ignore Geometry", self) self.go_button = QPushButton('Go') self.go_button.clicked.connect(self.go_to_object) checks_layout = QHBoxLayout() checks_layout.addWidget(self.whole_field_checkbox) checks_layout.addWidget(self.advanced_search_checkbox) checks_layout.addWidget(self.ignore_geometry_checkbox) checks_layout.addStretch() checks_layout.addWidget(self.go_button) self.query_label = QLabel("Query:") self.query_label.setEnabled(False) self.query_text = QLineEdit() self.query_text.setEnabled(True) self.query_text.setReadOnly(True) self.query_text.setFrame(False) self.query_text.setStyleSheet("""QLineEdit { background-color: LightGray; color: white; } """) query_layout = QHBoxLayout() query_layout.addWidget(self.query_label) query_layout.addWidget(self.query_text) self.select_label = QLabel("Select:") self.select_all_button = QPushButton("All") self.select_none_button = QPushButton("None") self.select_invert_button = QPushButton("Invert") self.delete_button = QPushButton("Delete Objects") self.select_all_button.clicked.connect(self.select_all_clicked) self.select_none_button.clicked.connect(self.select_none_clicked) self.select_invert_button.clicked.connect(self.select_invert_clicked) self.delete_button.clicked.connect(self.delete_button_clicked) self.delete_button.setEnabled(False) selection_layout = QHBoxLayout() selection_layout.addWidget(self.select_label) selection_layout.addWidget(self.select_all_button) selection_layout.addWidget(self.select_none_button) selection_layout.addWidget(self.select_invert_button) selection_layout.addStretch() selection_layout.addWidget(self.delete_button) self.replace_with_text = QLineEdit() self.replace_with_label = QLabel("Replace With:") self.replace_button = QPushButton("Replace") self.replace_button.clicked.connect(self.replace_button_clicked) self.replace_button.setEnabled(False) replace_layout = QHBoxLayout() replace_layout.addWidget(self.replace_with_label) replace_layout.addWidget(self.replace_with_text) replace_layout.addWidget(self.replace_button) layout = QVBoxLayout() layout.addLayout(input_layout) layout.addLayout(checks_layout) layout.addLayout(query_layout) layout.addWidget(self.results_tree) layout.addLayout(selection_layout) layout.addLayout(replace_layout) self.resize(650, 450) self.setLayout(layout) self.setWindowTitle("IDF+ Search & Replace") self.search_text.setFocus() self.setTabOrder(self.search_text, self.search_button) self.setTabOrder(self.search_button, self.whole_field_checkbox) self.setTabOrder(self.whole_field_checkbox, self.advanced_search_checkbox) self.setTabOrder(self.advanced_search_checkbox, self.select_all_button) self.setTabOrder(self.select_all_button, self.select_none_button) self.setTabOrder(self.select_none_button, self.select_invert_button) self.setTabOrder(self.select_invert_button, self.replace_with_text) self.setTabOrder(self.replace_with_text, self.replace_button) self.setTabOrder(self.replace_button, self.search_text) self.results_tree.setModel(self.create_results_model([])) self.results_tree.setColumnHidden(2, True) if initial_query is not None: self.search_text.setText(initial_query) self.search_button.click() def create_results_model(self, results): def add_result_row(row_model, value, obj_class, uuid): row_model.insertRow(0) row_model.setData(model.index(0, 0), value) row_model.setData(model.index(0, 1), obj_class) row_model.setData(model.index(0, 2), uuid) item_0 = model.itemFromIndex(model.index(0, 0)) item_0.setCheckState(Qt.Unchecked) item_0.setFlags(item_0.flags() | Qt.ItemIsUserCheckable) item_0.setEditable(False) item_1 = model.itemFromIndex(model.index(0, 1)) item_1.setEditable(False) model = QStandardItemModel(0, 3, self) model.setHeaderData(0, Qt.Horizontal, "Value") model.setHeaderData(1, Qt.Horizontal, "Class") model.setHeaderData(2, Qt.Horizontal, "UUID") for hit in results: add_result_row(model, hit['value'], hit['obj_class_display'], hit['uuid']) return model def submit_search(self): """Submits a search based on the current query """ user_query = self.search_text.text() idf = self.parent.idf if not user_query or len(user_query) < 2 or not idf: return [], "" results, my_query = idf.search( user_query, self.whole_field_checkbox.isChecked(), self.advanced_search_checkbox.isChecked(), self.ignore_geometry_checkbox.isChecked()) self.query_text.setText(str(my_query)) self.results_tree.setModel(self.create_results_model(results)) self.results_tree.model().itemChanged.connect(self.item_checked) # self.results_tree.setColumnHidden(2, True) self.results_tree.resizeColumnToContents(0) self.results_tree.resizeColumnToContents(1) self.results_tree.setSortingEnabled(True) def item_checked(self, item): if item.checkState() == Qt.Checked: self.items_checked += 1 else: self.items_checked -= 1 if self.items_checked > 0: self.delete_button.setEnabled(True) self.replace_button.setEnabled(True) else: self.delete_button.setEnabled(False) self.replace_button.setEnabled(False) def select_all_clicked(self): model = self.results_tree.model() result_count = model.rowCount() for i in range(result_count): model.itemFromIndex(model.index(i, 0)).setCheckState(Qt.Checked) def select_none_clicked(self): model = self.results_tree.model() result_count = model.rowCount() for i in range(result_count): model.itemFromIndex(model.index(i, 0)).setCheckState(Qt.Unchecked) def select_invert_clicked(self): model = self.results_tree.model() result_count = model.rowCount() for i in range(result_count): item = model.itemFromIndex(model.index(i, 0)) if item.checkState() == Qt.Checked: new_state = Qt.Unchecked else: new_state = Qt.Checked item.setCheckState(new_state) def delete_button_clicked(self): model = self.results_tree.model() result_count = model.rowCount() if result_count <= 0 or self.items_checked <= 0: return question = "Are you sure you want to perform this deletion?\n" \ "Undo is currently NOT supported for this operation." response = self.confirm_action(question) if response is not True: return for i in range(result_count): item_0 = model.itemFromIndex(model.index(i, 0)) item_2 = model.itemFromIndex(model.index(i, 2)) if item_0.checkState() != Qt.Checked: continue field = self.parent.idf.field_by_uuid(item_2.text()) obj = field._outer obj_class = self.parent.idf.idf_objects(obj.obj_class) try: index = obj_class.index(obj) self.parent.idf.remove_objects(obj.obj_class, index, index + 1) except ValueError: pass # already deleted self.parent.set_dirty(True) self.submit_search() self.parent.load_table_view(self.parent.current_obj_class) QMessageBox.information(self, "Delete Action", "Deletion Complete!") def advanced_search_checked(self): if self.advanced_search_checkbox.isChecked(): self.whole_field_checkbox.setEnabled(False) self.whole_field_checkbox.setChecked(True) self.ignore_geometry_checkbox.setEnabled(False) self.ignore_geometry_checkbox.setChecked(False) else: self.whole_field_checkbox.setEnabled(True) self.whole_field_checkbox.setChecked(False) self.ignore_geometry_checkbox.setEnabled(True) self.ignore_geometry_checkbox.setChecked(False) def replace_button_clicked(self): search_text = self.search_text.text() replace_with_text = self.replace_with_text.text() if not search_text: return model = self.results_tree.model() result_count = model.rowCount() if result_count <= 0 or self.items_checked <= 0: return question = "Are you sure you want to perform this replacement?\n" \ "Undo is currently NOT supported for this operation." response = self.confirm_action(question) if response is not True: return for i in range(result_count): item_0 = model.itemFromIndex(model.index(i, 0)) item_2 = model.itemFromIndex(model.index(i, 2)) if item_0.checkState() != Qt.Checked: continue field = self.parent.idf.field_by_uuid(item_2.text()) if self.whole_field_checkbox.isChecked( ) or self.advanced_search_checkbox.isChecked(): field.value = replace_with_text else: regex = re.compile(re.escape(search_text), re.IGNORECASE) field.value = regex.sub(replace_with_text, field.value) self.parent.set_dirty(True) self.submit_search() self.parent.load_table_view(self.parent.current_obj_class) QMessageBox.information(self, "Replacement", "Replacement Complete!") def confirm_action(self, question): """Confirm user wants to perform action """ flags = QMessageBox.StandardButton.Yes flags |= QMessageBox.StandardButton.No response = QMessageBox.question(self, "Are you sure?", question, flags) if response == QMessageBox.Yes: return True elif QMessageBox.No: return False else: return False def go_to_object(self, index=None): if index is None: selected = self.results_tree.selectedIndexes() if not selected: return index = selected[0] model = self.results_tree.model() item = model.itemFromIndex(model.index(index.row(), 2)) field = self.parent.idf.field_by_uuid(item.text()) self.parent.activateWindow() self.parent.jump_to_field(field)