def confirm_unlink(self, folders): humanized_folders = humanized_list(folders, "folders") title = "Permanently remove {}?".format(humanized_folders) if len(folders) == 1: text = ("Are you sure you wish to <b>permanently</b> remove the " "'{}' folder? If you do, it will be unlinked from your " "rootcap and cannot be restored with your Recovery Key.". format(folders[0])) else: text = ("Are you sure you wish to <b>permanently</b> remove {}? " "If you do, they will be unlinked from your rootcap and " "cannot be restored with your Recovery Key.".format( humanized_folders)) reply = QMessageBox.question(self, title, text, QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: tasks = [] for folder in folders: d = self.gateway.unlink_magic_folder_from_rootcap(folder) d.addErrback(self.show_failure) tasks.append(d) self.model().removeRow(self.model().findItems(folder)[0].row()) d = DeferredList(tasks) d.addCallback(lambda _: self.model().monitor.scan_rootcap()) d.addCallback(self.show_drop_label)
def confirm_remove(self, folders): humanized_folders = humanized_list(folders, "folders") title = "Remove {}?".format(humanized_folders) if len(folders) == 1: text = ("Are you sure you wish to remove the '{}' folder? If " "you do, it will remain on your computer, however, {} " "will no longer synchronize its contents with {}".format( folders[0], APP_NAME, self.gateway.name)) else: text = ("Are you sure you wish to remove {}? If you do, they " "will remain on your computer, however, {} will no " "longer synchronize their contents with {}.".format( humanized_folders, APP_NAME, self.gateway.name)) reply = QMessageBox.question(self, title, text, QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: tasks = [] for folder in folders: d = self.gateway.remove_magic_folder(folder) d.addErrback(self.show_failure) tasks.append(d) self.model().removeRow(self.model().findItems(folder)[0].row()) d = DeferredList(tasks) d.addCallback(lambda _: self.model().monitor.scan_rootcap()) d.addCallback(self.show_drop_label)
def confirm_unlink(self, folders): msgbox = QMessageBox(self) msgbox.setIcon(QMessageBox.Question) humanized_folders = humanized_list(folders, "folders") msgbox.setWindowTitle( "Permanently remove {}?".format(humanized_folders)) if len(folders) == 1: msgbox.setText( 'Are you sure you wish to <b>permanently</b> remove the "{}" ' 'folder?'.format(folders[0])) else: msgbox.setText( "Are you sure you wish to <b>permanently</b> remove {}?" .format(humanized_folders)) msgbox.setInformativeText( "Permanently removed folders cannot be restored with your " "Recovery Key.") msgbox.setStandardButtons(QMessageBox.Yes | QMessageBox.No) msgbox.setDefaultButton(QMessageBox.No) if msgbox.exec_() == QMessageBox.Yes: tasks = [] for folder in folders: d = self.gateway.unlink_magic_folder_from_rootcap(folder) d.addErrback(self.show_failure) tasks.append(d) self.model().removeRow(self.model().findItems(folder)[0].row()) d = DeferredList(tasks) d.addCallback(lambda _: self.model().monitor.scan_rootcap()) d.addCallback(self.show_drop_label)
def confirm_unlink(self, folders): msgbox = QMessageBox(self) msgbox.setIcon(QMessageBox.Question) humanized_folders = humanized_list(folders, "folders") msgbox.setWindowTitle( "Permanently remove {}?".format(humanized_folders)) if len(folders) == 1: msgbox.setText( 'Are you sure you wish to <b>permanently</b> remove the "{}" ' "folder?".format(folders[0])) else: msgbox.setText( "Are you sure you wish to <b>permanently</b> remove {}?". format(humanized_folders)) msgbox.setInformativeText( "Permanently removed folders cannot be restored with your " "Recovery Key.") msgbox.setStandardButtons(QMessageBox.Yes | QMessageBox.No) msgbox.setDefaultButton(QMessageBox.No) if msgbox.exec_() == QMessageBox.Yes: tasks = [] for folder in folders: tasks.append(self.unlink_folder(folder)) d = DeferredList(tasks) d.addCallback(self.maybe_rescan_rootcap)
def on_updated_files(self, folder_name, files_list, action, author): if get_preference('notifications', 'folder') != 'false': self.gui.show_message( folder_name + " folder updated", "{} {}".format( author + " " + action if author else action.capitalize(), humanized_list(files_list) ) )
def on_done(self, _): self.progressbar.setValue(self.progressbar.maximum()) self.close_button.show() self.done.emit(self) self.label.setPixmap( QPixmap(resource('green_checkmark.png')).scaled(32, 32)) if self.joined_folders and len(self.joined_folders) == 1: target = self.joined_folders[0] self.message_label.setText( 'Successfully joined folder "{0}"!\n"{0}" is now available ' 'for download'.format(target)) elif self.joined_folders: target = humanized_list(self.joined_folders, 'folders') self.message_label.setText( 'Successfully joined {0}!\n{0} are now available for ' 'download'.format(target))
def on_done(self, gateway): self.progressbar.setValue(self.progressbar.maximum()) self.close_button.show() self.checkmark.show() self.done.emit(gateway) if self.joined_folders and len(self.joined_folders) == 1: target = self.joined_folders[0] self.message_label.setText( 'Successfully joined folder "{0}"!\n"{0}" is now available ' 'for download'.format(target)) elif self.joined_folders: target = humanized_list(self.joined_folders, 'folders') self.message_label.setText( 'Successfully joined {0}!\n{0} are now available for ' 'download'.format(target)) self.close() # TODO: Cleanup
def confirm_stop_syncing(self, folders): msgbox = QMessageBox(self) msgbox.setIcon(QMessageBox.Question) humanized_folders = humanized_list(folders, "folders") msgbox.setWindowTitle("Stop syncing {}?".format(humanized_folders)) if len(folders) == 1: msgbox.setText( 'Are you sure you wish to stop syncing the "{}" folder?'. format(folders[0])) msgbox.setInformativeText( "This folder will remain on your computer but it will no " "longer synchronize automatically with {}.".format( self.gateway.name)) checkbox = QCheckBox( "Keep a backup copy of this folder on {}".format( self.gateway.name)) else: msgbox.setText("Are you sure you wish to stop syncing {}?".format( humanized_folders)) msgbox.setInformativeText( "These folders will remain on your computer but they will no " "longer synchronize automatically with {}.".format( self.gateway.name)) checkbox = QCheckBox( "Keep backup copies of these folders on {}".format( self.gateway.name)) checkbox.setCheckState(Qt.Unchecked) msgbox.setCheckBox(checkbox) msgbox.setStandardButtons(QMessageBox.Yes | QMessageBox.No) msgbox.setDefaultButton(QMessageBox.Yes) if msgbox.exec_() == QMessageBox.Yes: tasks = [] if checkbox.checkState() == Qt.Checked: for folder in folders: tasks.append(self.remove_folder(folder, unlink=False)) else: for folder in folders: tasks.append(self.remove_folder(folder, unlink=True)) d = DeferredList(tasks) d.addCallback(self.maybe_rescan_rootcap) d.addCallback(self.maybe_restart_gateway)
def confirm_remove(self, folders): msgbox = QMessageBox(self) msgbox.setIcon(QMessageBox.Question) humanized_folders = humanized_list(folders, "folders") msgbox.setWindowTitle("Remove {}?".format(humanized_folders)) if len(folders) == 1: msgbox.setText( 'Are you sure you wish to remove the "{}" folder?'.format( folders[0])) checkbox = QCheckBox( "Allow this folder to be restored later with my Recovery Key") else: msgbox.setText( "Are you sure you wish to remove {}?".format(humanized_folders) ) checkbox = QCheckBox( "Allow these folders to be restored later with my Recovery Key" ) msgbox.setInformativeText( "Removed folders will remain on your computer but {} will no " "longer synchronize their contents with {}.".format( APP_NAME, self.gateway.name)) checkbox.setCheckState(Qt.Checked) msgbox.setCheckBox(checkbox) msgbox.setStandardButtons(QMessageBox.Yes | QMessageBox.No) msgbox.setDefaultButton(QMessageBox.Yes) if msgbox.exec_() == QMessageBox.Yes: tasks = [] for folder in folders: d = self.gateway.remove_magic_folder(folder) d.addErrback(self.show_failure) tasks.append(d) if checkbox.checkState() == Qt.Unchecked: d2 = self.gateway.unlink_magic_folder_from_rootcap(folder) d2.addErrback(self.show_failure) tasks.append(d2) self.model().removeRow(self.model().findItems(folder)[0].row()) d = DeferredList(tasks) d.addCallback(lambda _: self.model().monitor.scan_rootcap()) d.addCallback(self.show_drop_label)
def confirm_remove(self, folders): msgbox = QMessageBox(self) msgbox.setIcon(QMessageBox.Question) humanized_folders = humanized_list(folders, "folders") msgbox.setWindowTitle("Remove {}?".format(humanized_folders)) if len(folders) == 1: msgbox.setText( 'Are you sure you wish to remove the "{}" folder?'.format( folders[0])) checkbox = QCheckBox( "Allow this folder to be restored later with my Recovery Key") else: msgbox.setText( "Are you sure you wish to remove {}?".format(humanized_folders) ) checkbox = QCheckBox( "Allow these folders to be restored later with my Recovery Key" ) msgbox.setInformativeText( "Removed folders will remain on your computer but {} will no " "longer synchronize their contents with {}.".format( APP_NAME, self.gateway.name)) checkbox.setCheckState(Qt.Checked) msgbox.setCheckBox(checkbox) msgbox.setStandardButtons(QMessageBox.Yes | QMessageBox.No) msgbox.setDefaultButton(QMessageBox.Yes) if msgbox.exec_() == QMessageBox.Yes: tasks = [] if checkbox.checkState() == Qt.Unchecked: for folder in folders: tasks.append(self.remove_folder(folder, unlink=True)) else: for folder in folders: tasks.append(self.remove_folder(folder, unlink=False)) d = DeferredList(tasks) d.addCallback(self.maybe_rescan_rootcap) d.addCallback(self.maybe_restart_gateway)
def __init__(self, gateway, gui, folder_names=None): # noqa: max-complexity=11 XXX super(ShareWidget, self).__init__() self.gateway = gateway self.gui = gui self.folder_names = folder_names self.folder_names_humanized = humanized_list(folder_names, 'folders') self.settings = {} self.wormhole = None self.pending_invites = [] self.use_tor = self.gateway.use_tor # XXX Temporary(?) workaround for font-scaling inconsistencies observed # during user-testing (wherein fonts on Windows on one laptop were # rendering especially large for some reason but were fine elsewhere) if sys.platform == 'win32': self.setMinimumSize(600, 400) else: self.setMinimumSize(500, 300) header_icon = QLabel(self) if self.folder_names: icon = QFileIconProvider().icon( QFileInfo( self.gateway.get_magic_folder_directory( self.folder_names[0]))) else: icon = QIcon(os.path.join(gateway.nodedir, 'icon')) if not icon.availableSizes(): icon = QIcon(resource('tahoe-lafs.png')) header_icon.setPixmap(icon.pixmap(50, 50)) header_text = QLabel(self) if self.folder_names: header_text.setText(self.folder_names_humanized) else: header_text.setText(self.gateway.name) font = QFont() if sys.platform == 'darwin': font.setPointSize(22) else: font.setPointSize(18) header_text.setFont(font) header_text.setAlignment(Qt.AlignCenter) header_layout = QGridLayout() header_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 1) header_layout.addWidget(header_icon, 1, 2) header_layout.addWidget(header_text, 1, 3) header_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 4) self.subtext_label = QLabel(self) font = QFont() if sys.platform == 'darwin': font.setPointSize(13) else: font.setPointSize(10) self.subtext_label.setFont(font) self.subtext_label.setStyleSheet("color: grey") self.subtext_label.setWordWrap(True) self.subtext_label.setAlignment(Qt.AlignCenter) self.noise_label = QLabel() font = QFont() if sys.platform == 'darwin': font.setPointSize(20) else: font.setPointSize(16) font.setFamily("Courier") font.setStyleHint(QFont.Monospace) self.noise_label.setFont(font) self.noise_label.setStyleSheet("color: grey") self.noise_timer = QTimer() self.noise_timer.timeout.connect( lambda: self.noise_label.setText(b58encode(os.urandom(16)))) self.noise_timer.start(75) self.code_label = QLabel() font = QFont() if sys.platform == 'darwin': font.setPointSize(22) else: font.setPointSize(18) self.code_label.setFont(font) self.code_label.setTextInteractionFlags(Qt.TextSelectableByMouse) self.code_label.hide() self.box_title = QLabel(self) self.box_title.setAlignment(Qt.AlignCenter) font = QFont() if sys.platform == 'darwin': font.setPointSize(20) else: font.setPointSize(16) self.box_title.setFont(font) self.box = QGroupBox() self.box.setAlignment(Qt.AlignCenter) self.box.setStyleSheet('QGroupBox {font-size: 16px}') self.copy_button = QToolButton() self.copy_button.setIcon(QIcon(resource('copy.png'))) self.copy_button.setToolTip("Copy to clipboard") self.copy_button.setStyleSheet('border: 0px; padding: 0px;') self.copy_button.hide() box_layout = QGridLayout(self.box) box_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 1) box_layout.addWidget(self.noise_label, 1, 2) box_layout.addWidget(self.code_label, 1, 3) box_layout.addWidget(self.copy_button, 1, 4) box_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 5) self.close_button = QPushButton("Close and cancel invite") self.close_button.setAutoDefault(False) self.checkmark = QLabel() self.checkmark.setPixmap( QPixmap(resource('green_checkmark.png')).scaled(32, 32)) self.checkmark.setAlignment(Qt.AlignCenter) self.checkmark.hide() self.tor_label = QLabel() self.tor_label.setToolTip( "This connection is being routed through the Tor network.") self.tor_label.setPixmap( QPixmap(resource('tor-onion.png')).scaled(32, 32)) self.tor_label.hide() self.progress_bar = QProgressBar() self.progress_bar.setMaximum(2) self.progress_bar.setTextVisible(False) self.progress_bar.hide() layout = QGridLayout(self) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 0, 0) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 1) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 2) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 3) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 4) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 5) layout.addLayout(header_layout, 1, 3) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 2, 1) layout.addWidget(self.box_title, 3, 2, 1, 3) layout.addWidget(self.checkmark, 3, 3) layout.addWidget(self.tor_label, 4, 1, 1, 1, Qt.AlignRight | Qt.AlignVCenter) layout.addWidget(self.box, 4, 2, 1, 3) layout.addWidget(self.progress_bar, 4, 2, 1, 3) layout.addWidget(self.subtext_label, 5, 2, 1, 3) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 6, 1) layout.addWidget(self.close_button, 7, 3) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 8, 1) self.copy_button.clicked.connect(self.on_copy_button_clicked) self.close_button.clicked.connect(self.close) self.set_box_title("Generating invite code...") if self.use_tor: self.tor_label.show() self.progress_bar.setStyleSheet( 'QProgressBar::chunk {{ background-color: {}; }}'.format( TOR_PURPLE)) self.go() # XXX
def on_updated_files(self, folder_name, files_list): if get_preference('notifications', 'folder') != 'false': self.gui.show_message(folder_name + " updated and encrypted", "Updated " + humanized_list(files_list))
def __init__(self, gateway, gui, folder_names=None): super(InviteSenderDialog, self).__init__() self.gateway = gateway self.gui = gui self.folder_names = folder_names self.folder_names_humanized = humanized_list(folder_names, 'folders') self.settings = {} self.pending_invites = [] self.use_tor = self.gateway.use_tor self.setMinimumSize(500, 300) header_icon = QLabel(self) if self.folder_names: icon = QFileIconProvider().icon( QFileInfo( self.gateway.get_magic_folder_directory( self.folder_names[0]))) else: icon = QIcon(os.path.join(gateway.nodedir, 'icon')) if not icon.availableSizes(): icon = QIcon(resource('tahoe-lafs.png')) header_icon.setPixmap(icon.pixmap(50, 50)) header_text = QLabel(self) if self.folder_names: header_text.setText(self.folder_names_humanized) else: header_text.setText(self.gateway.name) header_text.setFont(Font(18)) header_text.setAlignment(Qt.AlignCenter) header_layout = QGridLayout() header_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 1) header_layout.addWidget(header_icon, 1, 2) header_layout.addWidget(header_text, 1, 3) header_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 4) self.subtext_label = QLabel(self) self.subtext_label.setFont(Font(10)) self.subtext_label.setStyleSheet("color: grey") self.subtext_label.setWordWrap(True) self.subtext_label.setAlignment(Qt.AlignCenter) self.noise_label = QLabel() font = Font(16) font.setFamily("Courier") font.setStyleHint(QFont.Monospace) self.noise_label.setFont(font) self.noise_label.setStyleSheet("color: grey") self.noise_timer = QTimer() self.noise_timer.timeout.connect( lambda: self.noise_label.setText(b58encode(os.urandom(16)))) self.noise_timer.start(75) self.code_label = QLabel() self.code_label.setFont(Font(18)) self.code_label.setTextInteractionFlags(Qt.TextSelectableByMouse) self.code_label.hide() self.box_title = QLabel(self) self.box_title.setAlignment(Qt.AlignCenter) self.box_title.setFont(Font(16)) self.box = QGroupBox() self.box.setAlignment(Qt.AlignCenter) self.box.setStyleSheet('QGroupBox {font-size: 16px}') self.copy_button = QToolButton() self.copy_button.setIcon(QIcon(resource('copy.png'))) self.copy_button.setToolTip("Copy to clipboard") self.copy_button.setStyleSheet('border: 0px; padding: 0px;') self.copy_button.hide() box_layout = QGridLayout(self.box) box_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 1) box_layout.addWidget(self.noise_label, 1, 2) box_layout.addWidget(self.code_label, 1, 3) box_layout.addWidget(self.copy_button, 1, 4) box_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 5) self.close_button = QPushButton("Close and cancel invite") self.close_button.setAutoDefault(False) self.checkmark = QLabel() self.checkmark.setPixmap(Pixmap('green_checkmark.png', 32)) self.checkmark.setAlignment(Qt.AlignCenter) self.checkmark.hide() self.tor_label = QLabel() self.tor_label.setToolTip( "This connection is being routed through the Tor network.") self.tor_label.setPixmap(Pixmap('tor-onion.png', 24)) self.tor_label.hide() self.progress_bar = QProgressBar() self.progress_bar.setMaximum(2) self.progress_bar.setTextVisible(False) self.progress_bar.hide() layout = QGridLayout(self) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 0, 0) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 1) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 2) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 3) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 4) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 5) layout.addLayout(header_layout, 1, 3) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 2, 1) layout.addWidget(self.box_title, 3, 2, 1, 3) layout.addWidget(self.checkmark, 3, 3) layout.addWidget(self.tor_label, 4, 1, 1, 1, Qt.AlignRight | Qt.AlignVCenter) layout.addWidget(self.box, 4, 2, 1, 3) layout.addWidget(self.progress_bar, 4, 2, 1, 3) layout.addWidget(self.subtext_label, 5, 2, 1, 3) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 6, 1) layout.addWidget(self.close_button, 7, 3) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 8, 1) self.copy_button.clicked.connect(self.on_copy_button_clicked) self.close_button.clicked.connect(self.close) self.set_box_title("Generating invite code...") self.subtext_label.setText("Creating folder invite(s)...\n\n") if self.use_tor: self.tor_label.show() self.progress_bar.setStyleSheet( 'QProgressBar::chunk {{ background-color: {}; }}'.format( TOR_PURPLE)) self.go() # XXX
def test_humanized_list(items, kind, humanized): assert humanized_list(items, kind) == humanized
def __init__(self, gateway, gui, folder_names=None): # pylint:disable=too-many-statements super(ShareWidget, self).__init__() self.gateway = gateway self.gui = gui self.folder_names = folder_names self.folder_names_humanized = humanized_list(folder_names, 'folders') self.settings = {} self.wormhole = None self.pending_invites = [] self.setMinimumSize(500, 300) header_icon = QLabel(self) if self.folder_names: icon = QFileIconProvider().icon( QFileInfo( self.gateway.get_magic_folder_directory( self.folder_names[0]))) else: icon = QIcon(os.path.join(gateway.nodedir, 'icon')) if not icon.availableSizes(): icon = QIcon(resource('tahoe-lafs.png')) header_icon.setPixmap(icon.pixmap(50, 50)) header_text = QLabel(self) if self.folder_names: header_text.setText(self.folder_names_humanized) else: header_text.setText(self.gateway.name) font = QFont() font.setPointSize(18) header_text.setFont(font) header_text.setAlignment(Qt.AlignCenter) header_layout = QGridLayout() header_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 1) header_layout.addWidget(header_icon, 1, 2) header_layout.addWidget(header_text, 1, 3) header_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 4) self.subtext_label = QLabel(self) font = QFont() font.setPointSize(10) self.subtext_label.setFont(font) self.subtext_label.setStyleSheet("color: grey") self.subtext_label.setWordWrap(True) self.subtext_label.setAlignment(Qt.AlignCenter) self.noise_label = QLabel() font = QFont() font.setPointSize(16) font.setFamily("Courier") font.setStyleHint(QFont.Monospace) self.noise_label.setFont(font) self.noise_label.setStyleSheet("color: grey") self.noise_timer = QTimer() self.noise_timer.timeout.connect( lambda: self.noise_label.setText(b58encode(os.urandom(16)))) self.noise_timer.start(75) self.code_label = QLabel() font = QFont() font.setPointSize(18) self.code_label.setFont(font) self.code_label.setTextInteractionFlags(Qt.TextSelectableByMouse) self.code_label.hide() self.box_title = QLabel(self) self.box_title.setAlignment(Qt.AlignCenter) font = QFont() font.setPointSize(16) self.box_title.setFont(font) self.box = QGroupBox() self.box.setAlignment(Qt.AlignCenter) self.box.setStyleSheet('QGroupBox {font-size: 16px}') self.copy_button = QToolButton() self.copy_button.setIcon(QIcon(resource('copy.png'))) self.copy_button.setToolTip("Copy to clipboard") self.copy_button.setStyleSheet('border: 0px; padding: 0px;') self.copy_button.hide() box_layout = QGridLayout(self.box) box_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 1) box_layout.addWidget(self.noise_label, 1, 2) box_layout.addWidget(self.code_label, 1, 3) box_layout.addWidget(self.copy_button, 1, 4) box_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 5) self.close_button = QPushButton("Close and cancel invite") self.close_button.setAutoDefault(False) self.checkmark = QLabel() self.checkmark.setPixmap( QPixmap(resource('green_checkmark.png')).scaled(32, 32)) self.checkmark.setAlignment(Qt.AlignCenter) self.checkmark.hide() self.progress_bar = QProgressBar() self.progress_bar.setMaximum(2) self.progress_bar.setTextVisible(False) self.progress_bar.hide() layout = QGridLayout(self) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 0, 0) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 1) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 2) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 3) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 4) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 5) layout.addLayout(header_layout, 1, 3) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 2, 1) layout.addWidget(self.box_title, 3, 2, 1, 3) layout.addWidget(self.checkmark, 3, 3) layout.addWidget(self.box, 4, 2, 1, 3) layout.addWidget(self.progress_bar, 4, 2, 1, 3) layout.addWidget(self.subtext_label, 5, 2, 1, 3) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 6, 1) layout.addWidget(self.close_button, 7, 3) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 8, 1) self.copy_button.clicked.connect(self.on_copy_button_clicked) self.close_button.clicked.connect(self.close) self.set_box_title("Generating invite code...") self.go() # XXX