def __init__(self, mainwindow): """Creates the about dialog. You can simply exec_() it.""" super(AboutDialog, self).__init__(mainwindow) self.setWindowTitle(_("About {appname}").format(appname = appinfo.appname)) layout = QVBoxLayout() self.setLayout(layout) tabw = QTabWidget() layout.addWidget(tabw) tabw.addTab(About(self), _("About")) tabw.addTab(Credits(self), _("Credits")) tabw.addTab(Version(self), _("Version")) button = QDialogButtonBox(QDialogButtonBox.Ok) button.setCenterButtons(True) button.accepted.connect(self.accept) layout.addWidget(button) layout.setSizeConstraint(QLayout.SetFixedSize)
def __init__(self): ' make a diff method with GUI ' self.dialog = QDialog() self.diff_path = None # directory auto completer self.completer = QCompleter(self.dialog) self.dirs = QDirModel(self.dialog) self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot) self.completer.setModel(self.dirs) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setCompletionMode(QCompleter.PopupCompletion) #self.completer.setCompletionMode(QCompleter.InlineCompletion) self.group1 = QGroupBox() self.group1.setTitle('Diff') self.frmt = QComboBox(self.group1) self.frmt.addItems(['Unified', 'Normal', 'Context']) self.file1 = QLineEdit() self.file1.setPlaceholderText('/full/path/to/one_file.py') self.file1.setCompleter(self.completer) self.file2 = QLineEdit() self.file2.setPlaceholderText('/full/path/to/another_file.py') self.file2.setCompleter(self.completer) self.fout = QLineEdit() self.fout.setText(''.join((path.join(gettempdir(), datetime.now().strftime('%d-%b-%Y_%H:%M:%S.diff'))))) self.fout.setPlaceholderText('/full/path/to/output_file.diff') self.fout.setCompleter(self.completer) self.regex = QLineEdit() self.regex.setPlaceholderText('DONT use unless you know what are doing') self.regex.setToolTip('Do NOT use unless you know what you are doing !') self.borig = QPushButton(QIcon.fromTheme("folder-open"), 'Open') self.borig.clicked.connect(lambda: self.file1.setText(str( QFileDialog.getOpenFileName(self.dialog, 'Open file to compare', path.expanduser("~"), ';;(*.*)')))) self.bmodi = QPushButton(QIcon.fromTheme("folder-open"), 'Open') self.bmodi.clicked.connect(lambda: self.file2.setText(str( QFileDialog.getOpenFileName(self.dialog, 'Open file to compare', path.expanduser("~"), ';;(*.*)')))) self.bout = QPushButton(QIcon.fromTheme("folder-open"), 'Open') self.bout.clicked.connect(lambda: self.fout.setText(str( QFileDialog.getSaveFileName(self.dialog, 'Save a Diff file', path.expanduser("~"), ';;(*.diff)')))) vboxg1 = QVBoxLayout(self.group1) for each_widget in (QLabel('Original file full path'), self.file1, self.borig, QLabel('Modified file full path'), self.file2, self.bmodi, QLabel('Output file full Path'), self.fout, self.bout, QLabel('Diff Output Format'), self.frmt, QLabel('Diff REGEX to Ignore (ADVANCED)'), self.regex): vboxg1.addWidget(each_widget) self.group2 = QGroupBox() self.group2.setTitle('Options') self.nwfl = QCheckBox('Treat new files as Empty') self.smll = QCheckBox('Look for smaller changes') self.lrgf = QCheckBox('Optimize for large files') self.case = QCheckBox('Ignore case changes on content') self.cnvt = QCheckBox('Convert Tabs to Spaces') self.blnk = QCheckBox('Ignore added or removed Blank lines') self.spac = QCheckBox('Ignore changes in amount of Spaces') self.whit = QCheckBox('Ignore ALL white Spaces') self.tabz = QCheckBox('Ignore changes by Tab expansions') self.sprs = QCheckBox('Remove Space or Tab before empty lines') self.filn = QCheckBox('Ignore case when comparing file names') self.tbs = QComboBox(self.group2) self.tbs.addItems(['4', '6', '8', '10', '2']) self.nice = QComboBox(self.group2) self.nice.addItems(['20', '15', '10', '5', '0']) vboxg2 = QVBoxLayout(self.group2) for each_widget in (self.nwfl, self.smll, self.lrgf, self.case, self.cnvt, self.blnk, self.spac, self.whit, self.tabz, self.sprs, self.filn, QLabel('Diff Tabs-to-Spaces Size'), self.tbs, QLabel('Diff Backend CPU Priority'), self.nice): vboxg2.addWidget(each_widget) try: each_widget.setToolTip(each_widget.text()) except: each_widget.setToolTip(each_widget.currentText()) each_widget.setCursor(QCursor(Qt.PointingHandCursor)) group3 = QGroupBox() group3.setTitle('Even More Options') self.plai = QCheckBox('Force treat all files as plain text') self.nocr = QCheckBox('Force strip trailing carriage return') self.ridt = QCheckBox('Report when two files are identical') self.nocm = QCheckBox('Do not output common lines') self.rdif = QCheckBox('Report only when files differ') self.clip = QCheckBox('Copy Diff to Clipboard when done') self.noti = QCheckBox('Use system Notification when done') self.pret = QCheckBox('Align all Tabs by prepending a Tab') self.lolz = QCheckBox('Output Diff in two equal columns') self.odif = QCheckBox('Open Diff with Ninja-IDE when done') self.plac = QCheckBox('Make an Awesome Diff view when done') self.wdth = QComboBox(group3) self.wdth.addItems(['80', '100', '120', '130', '250', '500', '999999']) self.bcknd = QComboBox(group3) self.bcknd.addItems(['diff', 'diff.py']) self.bcknd.setDisabled(True) #TODO this feature needs work vboxg3 = QVBoxLayout(group3) for each_widget in (self.plai, self.nocr, self.ridt, self.nocm, self.rdif, self.pret, self.clip, self.noti, self.lolz, self.odif, self.plac, QLabel('Diff Maximum Total Width'), self.wdth, QLabel('Diff Backend (EXPERIMENTAL)'), self.bcknd): vboxg3.addWidget(each_widget) try: each_widget.setToolTip(each_widget.text()) except: each_widget.setToolTip(each_widget.currentText()) each_widget.setCursor(QCursor(Qt.PointingHandCursor)) for widget_should_be_checked in (self.nwfl, self.smll, self.lrgf, self.clip, self.cnvt, self.plai, self.noti): widget_should_be_checked.setChecked(True) container = QWidget() hbox = QHBoxLayout(container) for each_widget in (self.group2, self.group1, group3): hbox.addWidget(each_widget) buttons = QDialogButtonBox() buttons.resize(self.dialog.size().width(), buttons.size().height() * 2) buttons.setOrientation(Qt.Horizontal) buttons.setStandardButtons( QDialogButtonBox.Ok | QDialogButtonBox.Cancel | QDialogButtonBox.Close | QDialogButtonBox.Help) buttons.setCenterButtons(False) buttons.helpRequested.connect(lambda: QMessageBox.about( self.dialog, __doc__, ''.join((__doc__, ' GUI and Visualizer Plugin,', linesep, 'version ', __version__, ', (', __license__, '), by ', linesep, __author__, ', ( ', __email__, ' ).', linesep)))) buttons.rejected.connect(self.dialog.close) buttons.accepted.connect(self.make_diff) info = QLabel(''.join(('<b> Current Backend Diff Engine: </b>', getoutput('diff --version').split(linesep)[0]))) vbox = QVBoxLayout(self.dialog) for each_widget in ( QLabel('<center><h2> Ninja IDE Diff and Patch </h2></center>'), container, info, buttons): vbox.addWidget(each_widget) self.dialog.resize(1024, self.dialog.size().height()) self.dialog.exec_()
class MainWindow(QDialog, SetupTabStopsMixin, CenterOnScreenMixin): WINDOW_TITLE_TEXT = 'BAON' OPTIONS_BOX_TEXT = 'Options' SCAN_RECURSIVE_CHECKBOX_TEXT = 'Recursively scan subfolders' USE_PATH_CHECKBOX_TEXT = 'Use path' USE_EXTENSION_CHECKBOX_TEXT = 'Use extension' RULES_BOX_TEXT = 'Rename Rules' FILES_BOX_TEXT = 'Renamed Files' RENAME_WARNINGS_DIALOG_CAPTION = 'Please Confirm' RENAME_WARNINGS_DIALOG_TEXT = 'There are warnings for some of the files. Proceed with the rename operation anyway?' RENAME_COMPLETE_DIALOG_CAPTION = 'Rename Complete' RENAME_COMPLETE_DIALOG_TEXT =\ 'The files have been renamed successfully. Do you wish to perform another rename operation?' DEFAULT_WINDOW_WIDTH = 800 DEFAULT_WINDOW_HEIGHT = 600 RULES_BOX_HEIGHT = 112 base_path_edited = pyqtSignal(str) scan_recursive_changed = pyqtSignal(bool) rules_text_changed = pyqtSignal(str) use_path_changed = pyqtSignal(bool) use_extension_changed = pyqtSignal(bool) request_add_override = pyqtSignal(BAONPath, BAONPath) request_remove_override = pyqtSignal(BAONPath) request_do_rename = pyqtSignal() request_rescan = pyqtSignal() _base_path_panel = None _scan_recursive_checkbox = None _use_path_checkbox = None _use_extension_checkbox = None _rules_editor = None _files_display = None _files_display_summary_panel = None _status_box = None _dialog_button_box = None def __init__(self, args): super().__init__() self._init_ui() self._fill_in_controls(args) self._center_on_screen() def _init_ui(self): self.setWindowTitle(self.WINDOW_TITLE_TEXT) self.resize(self.DEFAULT_WINDOW_WIDTH, self.DEFAULT_WINDOW_HEIGHT) main_layout = QVBoxLayout(self) main_layout.addWidget(self._create_base_path_panel()) main_layout.addWidget(self._create_options_box()) main_layout.addWidget(self._create_rules_box()) main_layout.addWidget(self._create_files_box()) main_layout.addWidget(self._create_status_box()) main_layout.addWidget(self._create_dialog_buttons()) self._setup_tab_stops( self._base_path_panel, self._scan_recursive_checkbox, self._use_path_checkbox, self._use_extension_checkbox, self._rules_editor, self._files_display, self._files_display_summary, self._dialog_button_box, ) def _create_base_path_panel(self): self._base_path_panel = BasePathPanel(self) self._base_path_panel.path_edited.connect(self.base_path_edited) return self._base_path_panel def _create_options_box(self): box = QGroupBox(self.OPTIONS_BOX_TEXT, self) self._scan_recursive_checkbox = QCheckBox(self.SCAN_RECURSIVE_CHECKBOX_TEXT, box) self._scan_recursive_checkbox.toggled.connect(self.scan_recursive_changed) self._use_path_checkbox = QCheckBox(self.USE_PATH_CHECKBOX_TEXT, box) self._use_path_checkbox.toggled.connect(self.use_path_changed) self._use_extension_checkbox = QCheckBox(self.USE_EXTENSION_CHECKBOX_TEXT, box) self._use_extension_checkbox.toggled.connect(self.use_extension_changed) layout = QHBoxLayout(box) layout.addWidget(self._scan_recursive_checkbox) layout.addWidget(self._use_path_checkbox) layout.addWidget(self._use_extension_checkbox) layout.addStretch() return box def _create_rules_box(self): box = QGroupBox(self.RULES_BOX_TEXT, self) box.setMaximumHeight(self.RULES_BOX_HEIGHT) self._rules_editor = RulesEditor(box) self._rules_editor.rules_edited.connect(self.rules_text_changed) layout = QHBoxLayout(box) layout.addWidget(self._rules_editor) return box def _create_files_box(self): box = QGroupBox(self.FILES_BOX_TEXT, self) box.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)) self._files_display = FilesDisplay(box) self._files_display_summary = FilesDisplaySummaryPanel(box) self._files_display.request_add_override.connect(self.request_add_override) self._files_display.request_remove_override.connect(self.request_remove_override) self._files_display.counts_changed.connect(self._files_display_summary.set_counts) self._files_display.is_browsing_category_changed.connect(self._files_display_summary.set_is_browsing_category) self._files_display.has_next_in_category_changed.connect(self._files_display_summary.set_has_next_in_category) self._files_display.has_prev_in_category_changed.connect(self._files_display_summary.set_has_prev_in_category) self._files_display_summary.start_browsing_category.connect(self._files_display.start_browsing_category) self._files_display_summary.next_in_category.connect(self._files_display.next_in_category) self._files_display_summary.prev_in_category.connect(self._files_display.prev_in_category) layout = QVBoxLayout(box) layout.addWidget(self._files_display) layout.addWidget(self._files_display_summary) return box def _create_status_box(self): self._status_box = StatusBox(self) return self._status_box def _create_dialog_buttons(self): self._dialog_button_box = QDialogButtonBox(self) self._dialog_button_box.setOrientation(Qt.Horizontal) self._dialog_button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self._dialog_button_box.setCenterButtons(True) self._dialog_button_box.accepted.connect(self._confirm_rename) self._dialog_button_box.rejected.connect(self.reject) return self._dialog_button_box def _fill_in_controls(self, args): if args.base_path is not None: self._base_path_panel.set_base_path(args.base_path) if args.scan_recursive is not None: self._scan_recursive_checkbox.setChecked(args.scan_recursive) if args.use_extension is not None: self._use_extension_checkbox.setChecked(args.use_extension) if args.use_path is not None: self._use_path_checkbox.setChecked(args.use_path) if args.rules_text is not None: self._rules_editor.set_rules(args.rules_text) @pyqtSlot() def show_first_time(self): self.show() self.raise_() # We need to do this here as otherwise the operation may fail on some platforms self.setWindowIcon(QIcon(':/app_icon.png')) @pyqtSlot(str) def set_base_path(self, base_path): self._base_path_panel.set_base_path(base_path) @pyqtSlot(BAONStatus) def report_status(self, status): files_busy = \ status.scan_status in [BAONStatus.IN_PROGRESS, BAONStatus.PENDING] or \ status.rename_status in [BAONStatus.IN_PROGRESS, BAONStatus.PENDING] self._files_display.setEnabled(not files_busy) if status.rules_status == BAONStatus.ERROR: self._rules_editor.show_error(status.rules_status_extra.source_span) else: self._rules_editor.clear_error() self._status_box.show_status(status) self._dialog_button_box.button(QDialogButtonBox.Ok).setEnabled( status.execute_status in [BAONStatus.WAITING_FOR_USER, BAONStatus.ERROR] ) if status.execute_status == BAONStatus.AVAILABLE: self._on_rename_completed() @pyqtSlot(list) def update_scanned_files(self, files): self._files_display.set_original_files(files) @pyqtSlot(list) def update_renamed_files(self, files): self._files_display.set_renamed_files(files) @pyqtSlot() def _confirm_rename(self): if self._files_display.has_rename_warnings(): if not self._ask_user(self.RENAME_WARNINGS_DIALOG_CAPTION, self.RENAME_WARNINGS_DIALOG_TEXT): return self.request_do_rename.emit() def _on_rename_completed(self): self._rules_editor.clear() self.request_rescan.emit() if self._ask_user(self.RENAME_COMPLETE_DIALOG_CAPTION, self.RENAME_COMPLETE_DIALOG_TEXT): pass else: self.reject() def _ask_user(self, caption, text): on_mac = platform.system() == 'Darwin' dialog = QMessageBox( QMessageBox.Question, caption, text, QMessageBox.Yes | QMessageBox.No, self, Qt.Sheet if on_mac else Qt.Dialog | Qt.MSWindowsFixedSizeDialogHint, ) dialog.setDefaultButton(QMessageBox.No) dialog.setWindowModality(Qt.WindowModal) return dialog.exec_() == QMessageBox.Yes
class MyMainWindow(QMainWindow): ' Main Window ' def __init__(self, parent=None): super(MyMainWindow, self).__init__(parent) self.statusBar().showMessage(__doc__) self.setWindowTitle(__doc__) self.setMinimumSize(250, 280) self.setMaximumSize(300, 300) self.resize(250, 290) self.setWindowIcon(QIcon.fromTheme("face-monkey")) self.setStyleSheet('''QWidget { color: rgba( 0, 255, 255, 255 ); background-color: #323232; font-family: 'Ubuntu Light'; font-size: 14px; } QToolTip { border: 1px solid black; background-color: #ffa02f; background-image: None; padding: 1px; border-radius: 3px; opacity: 100; } QWidget:item:hover { background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #ca0619 ); color: #000000; } QWidget:item:selected { background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a ); } QWidget:disabled { color: #404040; background-color: #323232; } QWidget:focus { background-image: None; border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a ); } QPushButton { background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #565656, stop: 0.1 #525252, stop: 0.5 #4e4e4e, stop: 0.9 #4a4a4a, stop: 1 #464646 ); border-width: 1px; border-color: #1e1e1e; border-style: solid; border-radius: 6; padding: 3px; font-size: 12px; padding-left: 5px; padding-right: 5px; background-image: None; } QPushButton:pressed { background-image: None; background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d2d2d, stop: 0.1 #2b2b2b, stop: 0.5 #292929, stop: 0.9 #282828, stop: 1 #252525 ); } QComboBox { background-image: None; selection-background-color: #ffaa00; background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #565656, stop: 0.1 #525252, stop: 0.5 #4e4e4e, stop: 0.9 #4a4a4a, stop: 1 #464646 ); border-style: solid; border: 1px solid #1e1e1e; border-radius: 5; } QComboBox:hover, QPushButton:hover { background-image: url(.bg.png); border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a ); } QComboBox:on { padding-top: 3px; padding-left: 4px; background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d2d2d, stop: 0.1 #2b2b2b, stop: 0.5 #292929, stop: 0.9 #282828, stop: 1 #252525 ); selection-background-color: #ffaa00; background-image: None; } QComboBox QAbstractItemView { background-image: None; border: 2px solid darkgray; selection-background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a ); } QComboBox::drop-down { subcontrol-origin: padding; subcontrol-position: top right; width: 15px; border-left-width: 0px; border-left-color: darkgray; border-left-style: solid; border-top-right-radius: 3px; border-bottom-right-radius: 3px; background-image: None; } QComboBox::down-arrow { background-image: None; } QSlider { border-width: 2px; border-color: #1e1e1e; border-style: solid; padding: 3px; font-size: 8px; padding-left: 5px; padding-right: 5px; width: 25px; border-radius: 5px; } QSlider::sub-page:vertical { background: red; border: none; width: 25px; } QSlider::add-page:vertical { background: green; border: none; width: 25px; } QSlider::handle:vertical { background-color: QLinearGradient(spread:pad, x1:0, y1:0, x2:1, y2:0.273, stop:0 rgba(0, 0, 0, 255), stop:1 rgba(150, 255, 255, 255) ); width: 10px; height: 25px; border: 1px solid grey; text-align: center; border-top-left-radius: 2px; border-bottom-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius 2px; margin-left: 2px; margin-right: 2px; } QSlider::handle:vertical:hover { border: 2px solid #ffaa00; margin-left: 2px; margin-right: 2px; } QSlider::sub-page:vertical:disabled { background: #bbb; border-color: #999; } QSlider::add-page:vertical:disabled { background: #eee; border-color: #999; } QSlider::handle:vertical:disabled { background: #eee; border: 1px solid #aaa; border-radius: 4px; } ''') self.label1 = QLabel(self) self.label1.setText('Use Debug') self.label1.setGeometry(QtCore.QRect(25, 25, 125, 25)) self.slider1 = QSlider(self) self.slider1.setGeometry(QtCore.QRect(150, 25, 25, 25)) self.slider1.setTickInterval(1) self.slider1.setCursor(QCursor(QtCore.Qt.OpenHandCursor)) self.slider1.TickPosition(QSlider.TicksBothSides) self.slider1.setRange(0, 1) self.slider1.setValue(1) self.sli1lbl = QLabel(str(self.slider1.value()), self.slider1) self.sli1lbl.move(9, 5) self.sli1lbl.setAutoFillBackground(False) self.slider1.valueChanged.connect( lambda: self.sli1lbl.setText(str(self.slider1.value()))) self.slider1.sliderPressed.connect( lambda: self.slider1.setCursor(QCursor(QtCore.Qt.ClosedHandCursor))) self.slider1.sliderReleased.connect( lambda: self.slider1.setCursor(QCursor(QtCore.Qt.OpenHandCursor))) self.label2 = QLabel(self) self.label2.setText('Make Executable') self.label2.setGeometry(QtCore.QRect(25, 75, 125, 25)) self.slider2 = QSlider(self) self.slider2.setGeometry(QtCore.QRect(150, 75, 25, 25)) self.slider2.setTickInterval(1) self.slider2.setCursor(QCursor(QtCore.Qt.OpenHandCursor)) self.slider2.TickPosition(QSlider.TicksBothSides) self.slider2.setRange(0, 1) self.slider2.setValue(1) self.sli2lbl = QLabel(str(self.slider2.value()), self.slider2) self.sli2lbl.move(9, 5) self.sli2lbl.setAutoFillBackground(False) self.slider2.valueChanged.connect( lambda: self.sli2lbl.setText(str(self.slider2.value()))) self.slider2.sliderPressed.connect( lambda: self.slider2.setCursor(QCursor(QtCore.Qt.ClosedHandCursor))) self.slider2.sliderReleased.connect( lambda: self.slider2.setCursor(QCursor(QtCore.Qt.OpenHandCursor))) self.label3 = QLabel(self) self.label3.setText('Relative Imports') self.label3.setGeometry(QtCore.QRect(25, 125, 125, 25)) self.slider3 = QSlider(self) self.slider3.setGeometry(QtCore.QRect(150, 125, 25, 25)) self.slider3.setTickInterval(1) self.slider3.setCursor(QCursor(QtCore.Qt.OpenHandCursor)) self.slider3.TickPosition(QSlider.TicksBothSides) self.slider3.setRange(0, 1) self.slider3.setValue(0) self.sli3lbl = QLabel(str(self.slider3.value()), self.slider3) self.sli3lbl.move(9, 5) self.sli3lbl.setAutoFillBackground(False) self.slider3.valueChanged.connect( lambda: self.sli3lbl.setText(str(self.slider3.value()))) self.slider3.sliderPressed.connect( lambda: self.slider3.setCursor(QCursor(QtCore.Qt.ClosedHandCursor))) self.slider3.sliderReleased.connect( lambda: self.slider3.setCursor(QCursor(QtCore.Qt.OpenHandCursor))) self.label4 = QLabel(self) self.label4.setText('Indent Spaces') self.label4.setGeometry(QtCore.QRect(25, 175, 125, 25)) self.combo1 = QComboBox(self) self.combo1.setCursor(QCursor(QtCore.Qt.PointingHandCursor)) self.combo1.addItems(['4', '0', '2', '6', '8']) self.combo1.setGeometry(QtCore.QRect(150, 175, 50, 25)) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setGeometry(QtCore.QRect(25, 225, 200, 32)) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons( QDialogButtonBox.Ok | QDialogButtonBox.Cancel | QDialogButtonBox.Close | QDialogButtonBox.Help) self.buttonBox.setCenterButtons(False) self.buttonBox.helpRequested.connect(lambda: QMessageBox.about( self, __doc__, str(__doc__ + ', ' + ',\nversion ' + __version__ + '(' + __license__ + '),\nby ' + __author__ + ', ' + __email__))) self.buttonBox.accepted.connect(self.run) self.buttonBox.rejected.connect(self.close) palette = self.palette() palette.setBrush(QPalette.Base, Qt.transparent) self.setPalette(palette) self.setAttribute(Qt.WA_OpaquePaintEvent, False) def run(self): 'Run the actual conversion.' # Ask the User for the source .ui file as input filein = str(QFileDialog.getOpenFileName( self, __doc__, path.expanduser("~"), 'UI(*.ui)')).strip() # Parse Value of Slider1 as the Debug flag parameter if self.slider1.value() == 0: arg1 = '' else: arg1 = '--debug ' # Parse Value of Slider2 as the Execute flag parameter if self.slider2.value() == 0: arg2 = '' else: arg2 = '--execute ' # Parse Value of Slider3 as the relative imports flag parameter if self.slider3.value() == 0: arg3 = '' else: arg3 = '--from-imports ' # debug #print(arg1, arg2, arg3, str(self.combo1.currentText())) # run the subprocesses subprocess.Popen( 'nice --adjustment=19 pyuic4 ' + arg1 + arg2 + arg3 + '--indent=' + str(self.combo1.currentText()) + ' --output=' + str(filein).lower().replace('.ui', '.py') + ' ' + filein + ' && chmod -v +x ' + str(filein).lower().replace('.ui', '.py'), shell=True) def paintEvent(self, event): ' Paint semi-transparent background ' painter = QPainter(self) painter.fillRect(event.rect(), Qt.transparent) painter.setPen(Qt.NoPen) painter.setBrush(QColor(0, 0, 0)) painter.setOpacity(0.75) painter.drawRoundedRect(self.rect(), 75, 50) painter.end()
def __init__(self): ' make a diff method with GUI ' self.dialog = QDialog() self.diff_path = None # directory auto completer self.completer = QCompleter(self.dialog) self.dirs = QDirModel(self.dialog) self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot) self.completer.setModel(self.dirs) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setCompletionMode(QCompleter.PopupCompletion) self.group1 = QGroupBox() self.group1.setTitle('Diff') self.frmt = QComboBox(self.group1) self.frmt.addItems(['Unified', 'Normal', 'Context']) self.file1 = QLineEdit() self.file1.setPlaceholderText('/full/path/to/one_file.py') self.file1.setCompleter(self.completer) self.file2 = QLineEdit() self.file2.setPlaceholderText('/full/path/to/another_file.py') self.file2.setCompleter(self.completer) self.fout = QLineEdit() self.fout.setText(''.join((path.join(gettempdir(), datetime.now().strftime('%d-%b-%Y_%H:%M:%S.diff'))))) self.fout.setPlaceholderText('/full/path/to/output_file.diff') self.fout.setCompleter(self.completer) self.regex = QLineEdit() self.regex.setPlaceholderText('DONT use unless you know what are doing') self.regex.setToolTip('Do NOT use unless you know what you are doing !') self.borig = QPushButton(QIcon.fromTheme("folder-open"), 'Open') self.borig.clicked.connect(lambda: self.file1.setText(str( QFileDialog.getOpenFileName(self.dialog, 'Open file to compare', path.expanduser("~"), ';;(*.*)')))) self.bmodi = QPushButton(QIcon.fromTheme("folder-open"), 'Open') self.bmodi.clicked.connect(lambda: self.file2.setText(str( QFileDialog.getOpenFileName(self.dialog, 'Open file to compare', path.expanduser("~"), ';;(*.*)')))) self.bout = QPushButton(QIcon.fromTheme("folder-open"), 'Open') self.bout.clicked.connect(lambda: self.fout.setText(str( QFileDialog.getSaveFileName(self.dialog, 'Save a Diff file', path.expanduser("~"), ';;(*.diff)')))) vboxg1 = QVBoxLayout(self.group1) for each_widget in (QLabel('Original file full path'), self.file1, self.borig, QLabel('Modified file full path'), self.file2, self.bmodi, QLabel('Output file full Path'), self.fout, self.bout, QLabel('Diff Output Format'), self.frmt, QLabel('Diff REGEX to Ignore (ADVANCED)'), self.regex): vboxg1.addWidget(each_widget) self.group2 = QGroupBox() self.group2.setTitle('Options') self.nwfl = QCheckBox('Treat new files as Empty') self.smll = QCheckBox('Look for smaller changes') self.lrgf = QCheckBox('Optimize for large files') self.case = QCheckBox('Ignore case changes on content') self.cnvt = QCheckBox('Convert Tabs to Spaces') self.blnk = QCheckBox('Ignore added or removed Blank lines') self.spac = QCheckBox('Ignore changes in amount of Spaces') self.whit = QCheckBox('Ignore ALL white Spaces') self.tabz = QCheckBox('Ignore changes by Tab expansions') self.sprs = QCheckBox('Remove Space or Tab before empty lines') self.filn = QCheckBox('Ignore case when comparing file names') self.tbs = QComboBox(self.group2) self.tbs.addItems(['4', '6', '8', '10', '2']) self.nice = QComboBox(self.group2) self.nice.addItems(['20', '15', '10', '5', '0']) vboxg2 = QVBoxLayout(self.group2) for each_widget in (self.nwfl, self.smll, self.lrgf, self.case, self.cnvt, self.blnk, self.spac, self.whit, self.tabz, self.sprs, self.filn, QLabel('Diff Tabs-to-Spaces Size'), self.tbs, QLabel('Diff Backend CPU Priority'), self.nice): vboxg2.addWidget(each_widget) try: each_widget.setToolTip(each_widget.text()) except: each_widget.setToolTip(each_widget.currentText()) each_widget.setCursor(QCursor(Qt.PointingHandCursor)) group3 = QGroupBox() group3.setTitle('Even More Options') self.plai = QCheckBox('Force treat all files as plain text') self.nocr = QCheckBox('Force strip trailing carriage return') self.ridt = QCheckBox('Report when two files are identical') self.nocm = QCheckBox('Do not output common lines') self.rdif = QCheckBox('Report only when files differ') self.clip = QCheckBox('Copy Diff to Clipboard when done') self.noti = QCheckBox('Use system Notification when done') self.pret = QCheckBox('Align all Tabs by prepending a Tab') self.lolz = QCheckBox('Output Diff in two equal columns') self.odif = QCheckBox('Open Diff with Ninja-IDE when done') self.plac = QCheckBox('Make an Awesome Diff view when done') self.wdth = QComboBox(group3) self.wdth.addItems(['80', '100', '120', '130', '250', '500', '9999999']) self.bcknd = QComboBox(group3) self.bcknd.addItems(['diff', 'diff.py']) self.bcknd.setDisabled(True) # TODO this feature needs work vboxg3 = QVBoxLayout(group3) for each_widget in (self.plai, self.nocr, self.ridt, self.nocm, self.rdif, self.pret, self.clip, self.noti, self.lolz, self.odif, self.plac, QLabel('Diff Maximum Total Width'), self.wdth, QLabel('Diff Backend (EXPERIMENTAL)'), self.bcknd): vboxg3.addWidget(each_widget) try: each_widget.setToolTip(each_widget.text()) except: each_widget.setToolTip(each_widget.currentText()) each_widget.setCursor(QCursor(Qt.PointingHandCursor)) for widget_should_be_checked in (self.nwfl, self.smll, self.lrgf, self.clip, self.cnvt, self.plai, self.noti): widget_should_be_checked.setChecked(True) container = QWidget() hbox = QHBoxLayout(container) for each_widget in (self.group2, self.group1, group3): hbox.addWidget(each_widget) buttons = QDialogButtonBox() buttons.resize(self.dialog.size().width(), buttons.size().height() * 2) buttons.setOrientation(Qt.Horizontal) buttons.setStandardButtons( QDialogButtonBox.Ok | QDialogButtonBox.Cancel | QDialogButtonBox.Close | QDialogButtonBox.Help) buttons.setCenterButtons(False) buttons.helpRequested.connect(lambda: QMessageBox.about( self.dialog, __doc__, ''.join((__doc__, ' GUI and Visualizer Plugin,', linesep, 'version ', __version__, ', (', __license__, '), by ', linesep, __author__, ', ( ', __email__, ' ).', linesep)))) buttons.rejected.connect(self.dialog.close) buttons.accepted.connect(self.make_diff) info = QLabel(''.join(('<b> Current Backend Diff Engine: </b>', getoutput('diff --version').split(linesep)[0]))) vbox = QVBoxLayout(self.dialog) for each_widget in ( QLabel('<center><h2> Ninja IDE Diff and Patch </h2></center>'), container, info, buttons): vbox.addWidget(each_widget) self.dialog.resize(1024, self.dialog.size().height()) self.dialog.exec_()
class FilterGroupDialog(QDialog): """ A dialog for editing filters """ def __init__(self, type=None, name=None, exclusive=False, parent=None): QDialog.__init__(self, parent) self.setupUi() if type: index = self.filterTypeComboBox.findText(type) if index >= 0: self.filterTypeComboBox.setCurrentIndex(index) if name: self.nameLineEdit.setText(name) self.filterTypeComboBox.setEnabled(False) self.exclusiveCheckBox.setChecked(exclusive) def setupUi(self): self.setWindowTitle('Edit filter group') self.filterTypeComboBox = QComboBox(self) self.filterTypeComboBox.addItem('Block') self.filterTypeComboBox.addItem('Segment') self.filterTypeComboBox.addItem('Recording Channel Group') self.filterTypeComboBox.addItem('Recording Channel') self.filterTypeComboBox.addItem('Unit') self.nameLineEdit = QLineEdit() self.dialogButtonBox = QDialogButtonBox(self) self.dialogButtonBox.setAutoFillBackground(False) self.dialogButtonBox.setOrientation(Qt.Horizontal) self.dialogButtonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok) self.dialogButtonBox.setCenterButtons(True) self.exclusiveCheckBox = QCheckBox(self) self.exclusiveCheckBox.setText('Only one filter can be active') self.exclusiveCheckBox.setToolTip('Determines if exactly one or an arbitrary number of filters in this group can be active at once') gridLayout = QGridLayout(self) gridLayout.addWidget(QLabel('Type:', self), 0, 0) gridLayout.addWidget(self.filterTypeComboBox, 0, 1) gridLayout.addWidget(QLabel('Name:', self), 1, 0) gridLayout.addWidget(self.nameLineEdit, 1, 1) gridLayout.addWidget(self.exclusiveCheckBox, 2, 0, 1, 2) gridLayout.addWidget(self.dialogButtonBox, 3, 0, 1, 2) self.connect(self.dialogButtonBox, SIGNAL('accepted()'), self.accept) self.connect(self.dialogButtonBox, SIGNAL('rejected()'), self.reject) def name(self): return self.nameLineEdit.text() def type(self): return self.filterTypeComboBox.currentText() def exclusive(self): return self.exclusiveCheckBox.isChecked() #noinspection PyCallByClass,PyTypeChecker,PyArgumentList def accept(self): if len(self.nameLineEdit.text()) < 1: QMessageBox.critical(self, 'Error saving filter group', 'Please provide a name for the group.') return QDialog.accept(self)
class FilterDialog(QDialog): """ A dialog for editing filters """ solo_signatures = [ 'def filter(block):', 'def filter(segment):', 'def filter(rcg):', 'def filter(rc):', 'def filter(unit):' ] combi_signatures = [ 'def filter(blocks):', 'def filter(segments):', 'def filter(rcgs):', 'def filter(rcs):', 'def filter(units):' ] def __init__(self, groups, type=None, group=None, name=None, code=None, combined=False, on_exception=False, parent=None): QDialog.__init__(self, parent) self.setupUi() self.groups = groups if type: index = self.filterTypeComboBox.findText(type) if index >= 0: self.filterTypeComboBox.setCurrentIndex(index) self.populate_groups() if group: index = self.filterGroupComboBox.findText(group) if index >= 0: self.filterGroupComboBox.setCurrentIndex(index) if name: self.nameLineEdit.setText(name) if code: self.editor.set_text('\n'.join(code)) if name and code and type: self.filterTypeComboBox.setEnabled(False) self.combinedCheckBox.setChecked(combined) self.onExceptionCheckBox.setChecked(on_exception) def populate_groups(self): self.filterGroupComboBox.clear() self.filterGroupComboBox.addItem('') for g in sorted(self.groups[self.filterTypeComboBox.currentText()]): self.filterGroupComboBox.addItem(g) def setupUi(self): self.setWindowTitle('Edit filter') #self.resize(400, 300) self.signatureLabel = QLabel(self) self.signatureLabel.setText('def filter(block):') font = QFont('Some font that does not exist') font.setStyleHint(font.TypeWriter, font.PreferDefault) self.editor = CodeEditor(self) self.editor.setup_editor(linenumbers=False, language='py', scrollflagarea=False, codecompletion_enter=True, font=font, highlight_current_line=False, occurence_highlighting=False) self.editor.setCursor(Qt.IBeamCursor) self.editor.horizontalScrollBar().setCursor(Qt.ArrowCursor) self.editor.verticalScrollBar().setCursor(Qt.ArrowCursor) self.editor.set_text('return True') self.onExceptionCheckBox = QCheckBox(self) self.onExceptionCheckBox.setText('True on exception') self.onExceptionCheckBox.setToolTip('Determines if the filter will ' 'admit items if there is an ' 'exception during its execution') self.combinedCheckBox = QCheckBox(self) self.combinedCheckBox.setText('Combined filter') self.combinedCheckBox.setToolTip('Determines if the filter operates ' 'on single items (return True or ' 'False) or lists of items (return a ' 'list of items to be admitted)') self.filterTypeComboBox = QComboBox(self) self.filterTypeComboBox.addItem('Block') self.filterTypeComboBox.addItem('Segment') self.filterTypeComboBox.addItem('Recording Channel Group') self.filterTypeComboBox.addItem('Recording Channel') self.filterTypeComboBox.addItem('Unit') self.filterGroupComboBox = QComboBox(self) self.nameLineEdit = QLineEdit() self.dialogButtonBox = QDialogButtonBox(self) self.dialogButtonBox.setAutoFillBackground(False) self.dialogButtonBox.setOrientation(Qt.Horizontal) self.dialogButtonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self.dialogButtonBox.setCenterButtons(True) gridLayout = QGridLayout(self) gridLayout.addWidget(self.signatureLabel, 0, 0, 1, 4) gridLayout.addWidget(self.editor, 1, 0, 1, 4) gridLayout.addWidget(self.onExceptionCheckBox, 2, 2, 1, 1) gridLayout.addWidget(self.combinedCheckBox, 2, 3, 1, 1) gridLayout.addWidget(QLabel('Type:', self), 2, 0) gridLayout.addWidget(self.filterTypeComboBox, 2, 1) gridLayout.addWidget(QLabel('Group:', self), 3, 0) gridLayout.addWidget(self.filterGroupComboBox, 3, 1, 1, 3) gridLayout.addWidget(QLabel('Name:', self), 4, 0) gridLayout.addWidget(self.nameLineEdit, 4, 1, 1, 3) gridLayout.addWidget(self.dialogButtonBox, 5, 0, 1, 4) self.connect(self.dialogButtonBox, SIGNAL('accepted()'), self.accept) self.connect(self.dialogButtonBox, SIGNAL('rejected()'), self.reject) self.combinedCheckBox.stateChanged.connect(self.combined_state_changed) self.connect(self.filterTypeComboBox, SIGNAL('currentIndexChanged(int)'), self.on_filterTypeComboBox_currentIndexChanged) def name(self): return self.nameLineEdit.text() def code(self): return [ self.editor.get_text_line(l) for l in xrange(self.editor.get_line_count()) ] def type(self): return self.filterTypeComboBox.currentText() def combined(self): return self.combinedCheckBox.isChecked() def group(self): if self.filterGroupComboBox.currentText() == '': return None return self.filterGroupComboBox.currentText() def on_exception(self): return self.onExceptionCheckBox.isChecked() def combined_state_changed(self): self.set_signature() def code_errors(self): code = self.signatureLabel.text() + '\n\t' code += '\n\t'.join(self.code()) try: compile(code, '<filter>', 'exec') except SyntaxError as e: return e.msg + ' (Line %d)' % (e.lineno - 1) return None def set_signature(self): if self.combinedCheckBox.isChecked(): self.signatureLabel.setText( self.combi_signatures[self.filterTypeComboBox.currentIndex()]) else: self.signatureLabel.setText( self.solo_signatures[self.filterTypeComboBox.currentIndex()]) def on_filterTypeComboBox_currentIndexChanged(self, index): self.set_signature() self.populate_groups() #noinspection PyCallByClass,PyTypeChecker,PyArgumentList def accept(self): if len(self.nameLineEdit.text()) < 1: QMessageBox.critical(self, 'Error saving filter', 'Please provide a name for the filter.') return if '"' in self.nameLineEdit.text(): QMessageBox.critical(self, 'Error saving filter', 'You cannot use " in the name of a filter.') return err = self.code_errors() if err: QMessageBox.critical(self, 'Error saving filter', 'Compile error:\n' + err) return QDialog.accept(self)
class FilterGroupDialog(QDialog): """ A dialog for editing filters """ def __init__(self, type=None, name=None, exclusive=False, parent=None): QDialog.__init__(self, parent) self.setupUi() if type: index = self.filterTypeComboBox.findText(type) if index >= 0: self.filterTypeComboBox.setCurrentIndex(index) if name: self.nameLineEdit.setText(name) self.filterTypeComboBox.setEnabled(False) self.exclusiveCheckBox.setChecked(exclusive) def setupUi(self): self.setWindowTitle('Edit filter group') self.filterTypeComboBox = QComboBox(self) self.filterTypeComboBox.addItem('Block') self.filterTypeComboBox.addItem('Segment') self.filterTypeComboBox.addItem('Recording Channel Group') self.filterTypeComboBox.addItem('Recording Channel') self.filterTypeComboBox.addItem('Unit') self.nameLineEdit = QLineEdit() self.dialogButtonBox = QDialogButtonBox(self) self.dialogButtonBox.setAutoFillBackground(False) self.dialogButtonBox.setOrientation(Qt.Horizontal) self.dialogButtonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self.dialogButtonBox.setCenterButtons(True) self.exclusiveCheckBox = QCheckBox(self) self.exclusiveCheckBox.setText('Only one filter can be active') self.exclusiveCheckBox.setToolTip( 'Determines if exactly one or an arbitrary number of filters in this group can be active at once' ) gridLayout = QGridLayout(self) gridLayout.addWidget(QLabel('Type:', self), 0, 0) gridLayout.addWidget(self.filterTypeComboBox, 0, 1) gridLayout.addWidget(QLabel('Name:', self), 1, 0) gridLayout.addWidget(self.nameLineEdit, 1, 1) gridLayout.addWidget(self.exclusiveCheckBox, 2, 0, 1, 2) gridLayout.addWidget(self.dialogButtonBox, 3, 0, 1, 2) self.connect(self.dialogButtonBox, SIGNAL('accepted()'), self.accept) self.connect(self.dialogButtonBox, SIGNAL('rejected()'), self.reject) def name(self): return self.nameLineEdit.text() def type(self): return self.filterTypeComboBox.currentText() def exclusive(self): return self.exclusiveCheckBox.isChecked() #noinspection PyCallByClass,PyTypeChecker,PyArgumentList def accept(self): if len(self.nameLineEdit.text()) < 1: QMessageBox.critical(self, 'Error saving filter group', 'Please provide a name for the group.') return QDialog.accept(self)
class FilterDialog(QDialog): """ A dialog for editing filters """ def __init__(self, groups, type=None, group=None, name=None, code=None, on_exception=False, parent=None): QDialog.__init__(self, parent) self.setupUi() self.groups = groups if type: index = self.filterTypeComboBox.findText(type) if index >= 0: self.filterTypeComboBox.setCurrentIndex(index) self.populate_groups() if group: index = self.filterGroupComboBox.findText(group) if index >= 0: self.filterGroupComboBox.setCurrentIndex(index) if name: self.nameLineEdit.setText(name) if code: self.editor.set_text('\n'.join(code)) if name and code and type: self.filterTypeComboBox.setEnabled(False) self.onExceptionCheckBox.setChecked(on_exception) def populate_groups(self): self.filterGroupComboBox.clear() self.filterGroupComboBox.addItem('') for g in sorted(self.groups[self.filterTypeComboBox.currentText()]): self.filterGroupComboBox.addItem(g) def setupUi(self): self.setWindowTitle('Edit filter') #self.resize(400, 300) self.signatureLabel = QLabel(self) self.signatureLabel.setText('def filter(block):') font = QFont('Some font that does not exist') font.setStyleHint(font.TypeWriter, font.PreferDefault) self.editor = CodeEditor() self.editor.setup_editor(linenumbers=False, language='py', scrollflagarea=False, codecompletion_enter=True, font=font, highlight_current_line=False, occurence_highlighting=False) self.editor.set_text('return True') self.editor.setCursor(Qt.IBeamCursor) self.onExceptionCheckBox = QCheckBox(self) self.onExceptionCheckBox.setText('True on exception') self.onExceptionCheckBox.setToolTip('Determines if the filter will be admit items if there is an exception during its execution') self.filterTypeComboBox = QComboBox(self) self.filterTypeComboBox.addItem('Block') self.filterTypeComboBox.addItem('Segment') self.filterTypeComboBox.addItem('Recording Channel Group') self.filterTypeComboBox.addItem('Recording Channel') self.filterTypeComboBox.addItem('Unit') self.filterGroupComboBox = QComboBox(self) self.nameLineEdit = QLineEdit() self.dialogButtonBox = QDialogButtonBox(self) self.dialogButtonBox.setAutoFillBackground(False) self.dialogButtonBox.setOrientation(Qt.Horizontal) self.dialogButtonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok) self.dialogButtonBox.setCenterButtons(True) gridLayout = QGridLayout(self) gridLayout.addWidget(self.signatureLabel, 0, 0, 1, 2) gridLayout.addWidget(self.editor, 1, 0, 1, 2) gridLayout.addWidget(self.onExceptionCheckBox, 2,0, 1, 2) gridLayout.addWidget(QLabel('Type:', self), 3, 0) gridLayout.addWidget(self.filterTypeComboBox, 3, 1) gridLayout.addWidget(QLabel('Group:', self), 4, 0) gridLayout.addWidget(self.filterGroupComboBox, 4, 1) gridLayout.addWidget(QLabel('Name:', self), 5, 0) gridLayout.addWidget(self.nameLineEdit, 5, 1) gridLayout.addWidget(self.dialogButtonBox, 6, 0, 1, 2) self.connect(self.dialogButtonBox, SIGNAL('accepted()'), self.accept) self.connect(self.dialogButtonBox, SIGNAL('rejected()'), self.reject) self.connect(self.filterTypeComboBox, SIGNAL('currentIndexChanged(int)'), self.on_filterTypeComboBox_currentIndexChanged) def name(self): return self.nameLineEdit.text() def code(self): return [self.editor.get_text_line(l) for l in xrange(self.editor.get_line_count())] def type(self): return self.filterTypeComboBox.currentText() def group(self): if self.filterGroupComboBox.currentText() == '': return None return self.filterGroupComboBox.currentText() def on_exception(self): return self.onExceptionCheckBox.isChecked() def code_errors(self): code = self.signatureLabel.text() + '\n\t' code += '\n\t'.join(self.code()) try: compile(code, '<filter>', 'exec') except SyntaxError as e: return e.msg + ' (Line %d)' % (e.lineno - 1) return None def on_filterTypeComboBox_currentIndexChanged(self, index): if index == 0: self.signatureLabel.setText('def filter(block):') elif index == 1: self.signatureLabel.setText('def filter(segment):') elif index == 2: self.signatureLabel.setText('def filter(rcg):') elif index == 3: self.signatureLabel.setText('def filter(rc):') elif index == 4: self.signatureLabel.setText('def filter(unit):') self.populate_groups() #noinspection PyCallByClass,PyTypeChecker,PyArgumentList def accept(self): if len(self.nameLineEdit.text()) < 1: QMessageBox.critical(self, 'Error saving filter', 'Please provide a name for the filter.') return if '"' in self.nameLineEdit.text(): QMessageBox.critical(self, 'Error saving filter', 'You cannot use " in the name of a filter.') return err = self.code_errors() if err: QMessageBox.critical(self, 'Error saving filter', 'Compile error:\n' + err) return QDialog.accept(self)