def __init__(self, gateway, folder_name, data, parent): super().__init__() self.gateway = gateway self.data = data self.parent = parent self.path = data["path"] self.size = data["size"] self.action = data["action"] self.mtime = data["mtime"] self._thumbnail_loaded = False self.setAutoFillBackground(True) directory = self.gateway.get_magic_folder_directory(folder_name) if directory: self.path = os.path.join(directory, self.path) self.basename = os.path.basename(os.path.normpath(self.path)) self.setToolTip( "{}\n\nSize: {}\nModified: {}".format( self.path, naturalsize(self.size), time.ctime(self.mtime) ) ) self.icon = QLabel() self.icon.setPixmap( QFileIconProvider().icon(QFileInfo(self.path)).pixmap(48, 48) ) self.basename_label = QLabel(self.basename) self.basename_label.setFont(Font(11)) self.details_label = QLabel() self.details_label.setFont(Font(10)) palette = self.palette() dimmer_grey = BlendedColor( palette.text().color(), palette.base().color(), 0.6 ).name() self.details_label.setStyleSheet("color: {}".format(dimmer_grey)) self.button = QPushButton() self.button.setIcon(QIcon(resource("dots-horizontal-triple.png"))) self.button.setStyleSheet("border: none;") self.button.clicked.connect(self.parent.on_right_click) self.button.hide() self.layout = QGridLayout(self) self.layout.addWidget(self.icon, 1, 1, 2, 2) self.layout.addWidget(self.basename_label, 1, 3) self.layout.addWidget(self.details_label, 2, 3) self.layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 4, 4) self.layout.addWidget(self.button, 1, 5, 2, 2) self.update_text() QTimer.singleShot(50, self.load_thumbnail)
def __init__(self, parent=None, help_text="", show_stats=True): super().__init__(parent) self.setMinimumWidth(400) self.label = QLabel("Password:"******"color: gray") self.lineedit = QLineEdit(self) self.lineedit.setFont(Font(14)) self.lineedit.setEchoMode(QLineEdit.Password) self.action = QAction(QIcon(resource("eye.png")), "Toggle visibility") self.action.triggered.connect(self.toggle_visibility) self.lineedit.addAction(self.action, QLineEdit.TrailingPosition) self.lineedit.returnPressed.connect(self.accept) layout = QGridLayout(self) layout.addWidget(self.label, 1, 1) layout.addWidget(self.lineedit, 2, 1) if show_stats: self.progressbar = QProgressBar() self.progressbar.setMaximum(4) self.progressbar.setTextVisible(False) self.progressbar.setFixedHeight(5) self.progressbar.setStyleSheet( "QProgressBar { background-color: transparent }" "QProgressBar::chunk { background-color: gray }" ) self.rating_label = QLabel() self.rating_label.setAlignment(Qt.AlignRight) self.time_label = QLabel() self.time_label.setStyleSheet("color: gray") layout.addWidget(self.progressbar, 3, 1) layout.addWidget(self.time_label, 4, 1) layout.addWidget(self.rating_label, 4, 1) self.lineedit.textChanged.connect(self.update_stats) self.update_color("transparent") if help_text: gbox = QGroupBox() gbox_layout = QGridLayout() gbox_label = QLabel(help_text) gbox_label.setWordWrap(True) gbox_label.setAlignment(Qt.AlignCenter) gbox_label.setStyleSheet("color: gray") gbox_layout.addWidget(gbox_label) gbox.setLayout(gbox_layout) layout.addWidget(gbox, 5, 1) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 6, 1)
def __init__(self, parent=None): super(InviteCodeLineEdit, self).__init__() self.parent = parent model = QStringListModel() model.setStringList(wordlist) completer = InviteCodeCompleter() completer.setModel(model) self.setFont(Font(16)) self.setCompleter(completer) self.setAlignment(Qt.AlignCenter) # self.setPlaceholderText("Enter invite code") self.blank_icon = QIcon() self.paste_icon = QIcon(resource("paste.png")) self.clear_icon = QIcon(resource("close.png")) self.go_icon = QIcon(resource("arrow-right.png")) self.tor_icon = QIcon(resource("tor-onion.png")) self.status_action = QAction(self.blank_icon, "", self) self.addAction(self.status_action, 0) self.action_button = QAction(self.blank_icon, "", self) self.addAction(self.action_button, 1) completer.highlighted.connect(self.update_action_button) self.textChanged.connect(self.update_action_button) self.returnPressed.connect(self.return_pressed) self.action_button.triggered.connect(self.button_clicked) self.update_action_button()
def __init__(self): super().__init__() self.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.setFont(Font(10)) self.current_index = 0 self.insertSeparator(0) self.addItem(" Add new...") self.activated.connect(self.on_activated)
def __init__(self, parent=None, tor_available=False): super(InviteCodeWidget, self).__init__() self.parent = parent self.label = QLabel("Enter invite code:") self.label.setFont(Font(14)) p = self.palette() dimmer_grey = BlendedColor( p.windowText().color(), p.window().color() ).name() self.label.setStyleSheet("color: {}".format(dimmer_grey)) self.label.setAlignment(Qt.AlignCenter) self.code_info_text = ( "An <i>invite code</i> is a short combination of numbers and " 'words (like "7-guitarist-revenge" or "9-potato-gremlin") that ' "allows two parties with the same code to establish a one-time " "secure communication channel with each other. In {}, " "invite codes are used to safely share the credentials needed " "to access resources -- for example, allowing another person or " "device to store files on a grid or granting them the ability to " "view and modify a folder.<p>" "Invite codes can only be used once and expire immediately when " "used or cancelled.".format(APP_NAME) ) self.code_info_button = QPushButton() self.code_info_button.setFlat(True) self.code_info_button.setIcon(QIcon(resource("question"))) self.code_info_button.setIconSize(QSize(13, 13)) if sys.platform == "darwin": self.code_info_button.setFixedSize(16, 16) else: self.code_info_button.setFixedSize(13, 13) self.code_info_button.setToolTip(self.code_info_text) self.code_info_button.clicked.connect(self.on_code_info_button_clicked) self.code_info_button.setFocusPolicy(Qt.NoFocus) label_layout = QGridLayout() label_layout.setHorizontalSpacing(6) label_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 1) label_layout.addWidget(self.label, 1, 2, Qt.AlignCenter) label_layout.addWidget(self.code_info_button, 1, 3, Qt.AlignLeft) label_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 5) self.lineedit = InviteCodeLineEdit(self) self.tor_checkbox = QCheckBox("Connect over the Tor network") if sys.platform == "darwin": # For some reason, the checkbox and pushbutton overlap slightly on # macOS. A space here adds just enough padding to separate them. self.tor_checkbox.setText(self.tor_checkbox.text() + " ") self.tor_checkbox.setStyleSheet("QCheckBox { color: dimgrey }") self.tor_checkbox.setFocusPolicy(Qt.NoFocus) self.tor_checkbox_effect = QGraphicsOpacityEffect() self.tor_checkbox.setGraphicsEffect(self.tor_checkbox_effect) self.tor_checkbox.setAutoFillBackground(True) self.tor_checkbox_animation_in = QPropertyAnimation( self.tor_checkbox_effect, b"opacity" ) self.tor_checkbox_animation_in.setDuration(500) self.tor_checkbox_animation_in.setStartValue(0) self.tor_checkbox_animation_in.setEndValue(1) self.tor_checkbox_animation_out = QPropertyAnimation( self.tor_checkbox_effect, b"opacity" ) self.tor_checkbox_animation_out.setDuration(500) self.tor_checkbox_animation_out.setStartValue(1) self.tor_checkbox_animation_out.setEndValue(0) self.tor_info_text = ( "<i>Tor</i> is an anonymizing network that helps defend against " "network surveillance and traffic analysis. With this checkbox " "enabled, {} will route all traffic corresponding to this " "connection through the Tor network, concealing your geographical " "location from your storage provider and other parties (such as " "any persons with whom you might share folders).<p>" "Using this option requires that Tor already be installed and " "running on your computer and may be slower or less reliable than " "your normal internet connection.<p>" "For more information or to download Tor, please visit " "<a href=https://torproject.org>https://torproject.org</a>".format( APP_NAME ) ) self.tor_info_button = QPushButton() self.tor_info_button.setFlat(True) self.tor_info_button.setIcon(QIcon(resource("question"))) self.tor_info_button.setIconSize(QSize(13, 13)) if sys.platform == "darwin": self.tor_info_button.setFixedSize(16, 16) else: self.tor_info_button.setFixedSize(13, 13) self.tor_info_button.setToolTip(self.tor_info_text) self.tor_info_button.clicked.connect(self.on_tor_info_button_clicked) self.tor_info_button.setFocusPolicy(Qt.NoFocus) self.tor_info_button_effect = QGraphicsOpacityEffect() self.tor_info_button.setGraphicsEffect(self.tor_info_button_effect) self.tor_info_button.setAutoFillBackground(True) self.tor_info_button_animation_in = QPropertyAnimation( self.tor_info_button_effect, b"opacity" ) self.tor_info_button_animation_in.setDuration(500) self.tor_info_button_animation_in.setStartValue(0) self.tor_info_button_animation_in.setEndValue(1) self.tor_info_button_animation_out = QPropertyAnimation( self.tor_info_button_effect, b"opacity" ) self.tor_info_button_animation_out.setDuration(500) self.tor_info_button_animation_out.setStartValue(1) self.tor_info_button_animation_out.setEndValue(0) if tor_available: self.tor_checkbox_effect.setOpacity(1.0) self.tor_info_button_effect.setOpacity(1.0) else: self.tor_checkbox.setEnabled(False) self.tor_checkbox_effect.setOpacity(0.0) self.tor_info_button_effect.setOpacity(0.0) tor_layout = QGridLayout() tor_layout.setHorizontalSpacing(0) tor_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 1) tor_layout.addWidget(self.tor_checkbox, 1, 2, Qt.AlignCenter) tor_layout.addWidget(self.tor_info_button, 1, 3, Qt.AlignLeft) tor_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 4) layout = QGridLayout(self) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 1, 1) layout.addLayout(label_layout, 2, 1) layout.addWidget(self.lineedit, 3, 1) layout.addLayout(tor_layout, 4, 1) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 5, 1) self.tor_checkbox.toggled.connect(self.toggle_tor_status) self.maybe_enable_tor_checkbox()
def __init__(self, gateway, gui): super().__init__() self.gateway = gateway self.gui = gui self.state = 0 self.num_connected = 0 self.num_known = 0 self.available_space = 0 self.checkmark_icon = QLabel() self.checkmark_icon.setPixmap(Pixmap("checkmark.png", 20)) self.syncing_icon = QLabel() self.sync_movie = QMovie(resource("sync.gif")) self.sync_movie.setCacheMode(True) self.sync_movie.updated.connect( lambda: self.syncing_icon.setPixmap(self.sync_movie.currentPixmap( ).scaled(20, 20, Qt.KeepAspectRatio, Qt.SmoothTransformation))) self.status_label = QLabel() p = self.palette() dimmer_grey = BlendedColor(p.windowText().color(), p.window().color(), 0.6).name() self.status_label.setStyleSheet(f"QLabel {{ color: {dimmer_grey} }}") self.status_label.setFont(Font(10)) self.setStyleSheet("QToolButton { border: none }") # self.setStyleSheet(""" # QToolButton { color: dimgrey; border: none; } # QToolButton:hover { # background-color: #FAFAFA; # border: 1px solid grey; # border-radius: 2px; # } # """) self.tor_button = QToolButton() self.tor_button.setIconSize(QSize(20, 20)) self.tor_action = QAction( QIcon(resource("tor-onion.png")), "This connection is being routed through the Tor network", ) self.tor_button.setDefaultAction(self.tor_action) if not self.gateway.use_tor: self.tor_button.hide() preferences_button = QToolButton(self) preferences_button.setIcon(QIcon(resource("preferences.png"))) preferences_button.setIconSize(QSize(20, 20)) preferences_button.setMenu(Menu(self.gui, show_open_action=False)) preferences_button.setPopupMode(2) preferences_button.setStyleSheet( "QToolButton::menu-indicator { image: none }") layout = QGridLayout(self) left, _, right, bottom = layout.getContentsMargins() layout.setContentsMargins(left, 0, right, bottom - 2) layout.addWidget(self.checkmark_icon, 1, 1) layout.addWidget(self.syncing_icon, 1, 1) layout.addWidget(self.status_label, 1, 2) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 3) layout.addWidget(self.tor_button, 1, 4) layout.addWidget(preferences_button, 1, 6) self.gateway.monitor.total_sync_state_updated.connect( self.on_sync_state_updated) self.gateway.monitor.space_updated.connect(self.on_space_updated) self.gateway.monitor.nodes_updated.connect(self.on_nodes_updated) self.on_sync_state_updated(0)
def __init__(self, gui, gateway): # pylint: disable=too-many-statements super().__init__() self.gui = gui self.gateway = gateway self.invite_sender_dialogs = [] self._rescan_required = False self._restart_required = False self.setModel(Model(self)) self.setItemDelegate(Delegate(self)) self.setAcceptDrops(True) # self.setColumnWidth(0, 150) # self.setColumnWidth(1, 100) self.setColumnWidth(2, 115) self.setColumnWidth(3, 70) self.setColumnWidth(4, 10) self.setContextMenuPolicy(Qt.CustomContextMenu) self.setHeaderHidden(True) # self.setRootIsDecorated(False) self.setSortingEnabled(True) self.setEditTriggers(QAbstractItemView.NoEditTriggers) self.setSelectionMode(QAbstractItemView.ExtendedSelection) self.setFocusPolicy(Qt.NoFocus) # font = QFont() # font.setPointSize(12) # self.header().setFont(font) # self.header().setDefaultAlignment(Qt.AlignCenter) self.header().setStretchLastSection(False) self.header().setSectionResizeMode(0, QHeaderView.Stretch) self.header().setSectionResizeMode(1, QHeaderView.Stretch) # self.header().setSectionResizeMode(2, QHeaderView.Stretch) # self.header().setSectionResizeMode(3, QHeaderView.Stretch) self.setIconSize(QSize(24, 24)) # XXX Should match the result of subtracting top from left margin from # CentralWidget's folders_views[gateway].layout().getContentsMargins() # but since this object's enclosing widget/layout won't appear in the # folders_views dict until after this __init__() call completes, set # the value "manually" instead. self.dropzone_top_margin = 0 if sys.platform == "darwin" else 11 self.drop_icon = QLabel(self) self.drop_icon.setPixmap(QPixmap(resource("upload.png"))) self.drop_icon.setAlignment(Qt.AlignCenter) self.drop_icon.setAcceptDrops(True) self.drop_icon.installEventFilter(self) self.drop_text = QLabel(self) self.drop_text.setText("Drag and drop folders here") self.drop_text.setFont(Font(14)) self.drop_text.setStyleSheet("color: grey") self.drop_text.setAlignment(Qt.AlignCenter) self.drop_text.setAcceptDrops(True) self.drop_text.installEventFilter(self) self.drop_text.setSizePolicy(QSizePolicy.Expanding, 0) self.drop_subtext = QLabel(self) self.drop_subtext.setText("Added folders will sync with {}".format( self.gateway.name)) self.drop_subtext.setFont(Font(10)) self.drop_subtext.setStyleSheet("color: grey") self.drop_subtext.setAlignment(Qt.AlignCenter) self.drop_subtext.setAcceptDrops(True) self.drop_subtext.installEventFilter(self) self.drop_subtext.setSizePolicy(QSizePolicy.Expanding, 0) self.select_folder_button = QPushButton("Select...", self) self.select_folder_button.setAcceptDrops(True) self.select_folder_button.installEventFilter(self) self.select_folder_button.clicked.connect(self.select_folder) layout = QGridLayout(self) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 1, 1) layout.addWidget(self.drop_icon, 2, 2, 3, 1) layout.addWidget(self.drop_text, 6, 1, 1, 3) layout.addWidget(self.drop_subtext, 7, 1, 1, 3) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 8, 1) layout.addWidget(self.select_folder_button, 8, 2) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 8, 3) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 9, 1) self.doubleClicked.connect(self.on_double_click) self.customContextMenuRequested.connect(self.on_right_click) self.model().populate()
def __init__(self, gui): # noqa: max-complexity super().__init__() self.gui = gui self.gateways = [] self.welcome_dialog = None self.recovery_key_exporter = None self.setWindowTitle(APP_NAME) self.setMinimumSize(QSize(600, 400)) self.setUnifiedTitleAndToolBarOnMac(True) self.setContextMenuPolicy(Qt.NoContextMenu) if sys.platform == "darwin": # To disable the broken/buggy "full screen" mode on macOS. # See https://github.com/gridsync/gridsync/issues/241 self.setWindowFlags(Qt.Dialog) grid_invites_enabled = True invites_enabled = True multiple_grids_enabled = True features_settings = settings.get("features") if features_settings: grid_invites = features_settings.get("grid_invites") if grid_invites and grid_invites.lower() == "false": grid_invites_enabled = False invites = features_settings.get("invites") if invites and invites.lower() == "false": invites_enabled = False multiple_grids = features_settings.get("multiple_grids") if multiple_grids and multiple_grids.lower() == "false": multiple_grids_enabled = False if multiple_grids_enabled: self.shortcut_new = QShortcut(QKeySequence.New, self) self.shortcut_new.activated.connect(self.show_welcome_dialog) self.shortcut_open = QShortcut(QKeySequence.Open, self) self.shortcut_open.activated.connect(self.select_folder) self.shortcut_preferences = QShortcut(QKeySequence.Preferences, self) self.shortcut_preferences.activated.connect( self.gui.show_preferences_window) self.shortcut_close = QShortcut(QKeySequence.Close, self) self.shortcut_close.activated.connect(self.close) self.shortcut_quit = QShortcut(QKeySequence.Quit, self) self.shortcut_quit.activated.connect(self.confirm_quit) self.central_widget = CentralWidget(self.gui) self.setCentralWidget(self.central_widget) font = Font(8) folder_icon_default = QFileIconProvider().icon(QFileInfo(config_dir)) folder_icon_composite = CompositePixmap( folder_icon_default.pixmap(256, 256), resource("green-plus.png")) folder_icon = QIcon(folder_icon_composite) folder_action = QAction(folder_icon, "Add Folder", self) folder_action.setToolTip("Add a Folder...") folder_action.setFont(font) folder_action.triggered.connect(self.select_folder) if grid_invites_enabled: invites_action = QAction(QIcon(resource("invite.png")), "Invites", self) invites_action.setToolTip("Enter or Create an Invite Code") invites_action.setFont(font) enter_invite_action = QAction(QIcon(), "Enter Invite Code...", self) enter_invite_action.setToolTip("Enter an Invite Code...") enter_invite_action.triggered.connect(self.open_invite_receiver) create_invite_action = QAction(QIcon(), "Create Invite Code...", self) create_invite_action.setToolTip("Create on Invite Code...") create_invite_action.triggered.connect( self.open_invite_sender_dialog) invites_menu = QMenu(self) invites_menu.addAction(enter_invite_action) invites_menu.addAction(create_invite_action) invites_button = QToolButton(self) invites_button.setDefaultAction(invites_action) invites_button.setMenu(invites_menu) invites_button.setPopupMode(2) invites_button.setStyleSheet( "QToolButton::menu-indicator { image: none }") invites_button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) elif invites_enabled: invite_action = QAction(QIcon(resource("invite.png")), "Enter Code", self) invite_action.setToolTip("Enter an Invite Code...") invite_action.setFont(font) invite_action.triggered.connect(self.open_invite_receiver) spacer_left = QWidget() spacer_left.setSizePolicy(QSizePolicy.Expanding, 0) self.combo_box = ComboBox() self.combo_box.currentIndexChanged.connect(self.on_grid_selected) if not multiple_grids_enabled: self.combo_box.hide() spacer_right = QWidget() spacer_right.setSizePolicy(QSizePolicy.Expanding, 0) history_action = QAction(QIcon(resource("time.png")), "History", self) history_action.setToolTip("Show/Hide History") history_action.setFont(font) history_action.triggered.connect(self.on_history_button_clicked) self.history_button = QToolButton(self) self.history_button.setDefaultAction(history_action) self.history_button.setCheckable(True) self.history_button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) recovery_action = QAction(QIcon(resource("key.png")), "Recovery", self) recovery_action.setToolTip("Import or Export a Recovery Key") recovery_action.setFont(font) import_action = QAction(QIcon(), "Import Recovery Key...", self) import_action.setToolTip("Import Recovery Key...") import_action.triggered.connect(self.import_recovery_key) export_action = QAction(QIcon(), "Export Recovery Key...", self) export_action.setToolTip("Export Recovery Key...") export_action.setShortcut(QKeySequence.Save) export_action.triggered.connect(self.export_recovery_key) recovery_menu = QMenu(self) recovery_menu.addAction(import_action) recovery_menu.addAction(export_action) recovery_button = QToolButton(self) recovery_button.setDefaultAction(recovery_action) recovery_button.setMenu(recovery_menu) recovery_button.setPopupMode(2) recovery_button.setStyleSheet( "QToolButton::menu-indicator { image: none }") recovery_button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.toolbar = self.addToolBar("") p = self.palette() dimmer_grey = BlendedColor(p.windowText().color(), p.window().color(), 0.7).name() if sys.platform != "darwin": self.toolbar.setStyleSheet(""" QToolBar {{ border: 0px }} QToolButton {{ color: {} }} """.format(dimmer_grey)) else: self.toolbar.setStyleSheet( "QToolButton {{ color: {} }}".format(dimmer_grey)) self.toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.toolbar.setIconSize(QSize(24, 24)) self.toolbar.setMovable(False) self.toolbar.addAction(folder_action) if grid_invites_enabled: self.toolbar.addWidget(invites_button) elif invites_enabled: self.toolbar.addAction(invite_action) self.toolbar.addWidget(spacer_left) self.toolbar.addWidget(self.combo_box) self.toolbar.addWidget(spacer_right) self.toolbar.addWidget(self.history_button) self.toolbar.addWidget(recovery_button) if sys.platform != "win32": # Text is getting clipped on Windows 10 for action in self.toolbar.actions(): widget = self.toolbar.widgetForAction(action) if isinstance(widget, QToolButton): widget.setMaximumWidth(68) self.active_invite_sender_dialogs = [] self.active_invite_receiver_dialogs = [] self.pending_news_message = ()
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 __init__(self, parent=None): super(WelcomeWidget, self).__init__() self.parent = parent application_settings = global_settings["application"] logo_icon = application_settings.get("logo_icon") if logo_icon: icon_file = logo_icon icon_size = 288 else: icon_file = application_settings.get("tray_icon") icon_size = 220 self.icon = QLabel() self.icon.setPixmap(Pixmap(icon_file, icon_size)) self.icon.setAlignment(Qt.AlignCenter) self.slogan = QLabel("<i>{}</i>".format( application_settings.get("description", ""))) self.slogan.setFont(Font(12)) p = self.palette() dimmer_grey = BlendedColor(p.windowText().color(), p.window().color()).name() self.slogan.setStyleSheet("color: {}".format(dimmer_grey)) self.slogan.setAlignment(Qt.AlignCenter) if logo_icon: self.slogan.hide() self.invite_code_widget = InviteCodeWidget(self) self.lineedit = self.invite_code_widget.lineedit self.connect_button = QPushButton("Connect") try: default_code = global_settings["connection"]["default"] except KeyError: default_code = "" grid_settings = load_settings_from_cheatcode(default_code) if grid_settings: self.invite_code_widget.hide() nickname = grid_settings.get("nickname") if nickname: font = Font(11) self.connect_button.setFont(font) self.connect_button.setFixedHeight(32) self.connect_button.setText(f"Connect to {nickname}") self.connect_button.clicked.connect( lambda: self.parent.go(default_code, grid_settings)) primary_color = grid_settings.get("color-1") if primary_color: self.connect_button.setStyleSheet( f"background: {primary_color}; color: white") else: self.connect_button.setStyleSheet( "background: green; color: white") else: self.connect_button.hide() self.message = QLabel() self.message.setStyleSheet("color: red") self.message.setAlignment(Qt.AlignCenter) self.message.hide() self.restore_link = QLabel() self.restore_link.setText("<a href>Restore from Recovery Key...</a>") self.restore_link.setFont(Font(9)) self.restore_link.setAlignment(Qt.AlignCenter) self.configure_link = QLabel() self.configure_link.setText("<a href>Manual configuration...</a>") self.configure_link.setFont(Font(9)) self.configure_link.setAlignment(Qt.AlignCenter) self.preferences_button = QPushButton() self.preferences_button.setIcon(QIcon(resource("preferences.png"))) self.preferences_button.setStyleSheet("border: 0px; padding: 0px;") self.preferences_button.setToolTip("Preferences...") self.preferences_button.setFocusPolicy(Qt.NoFocus) links_grid = QGridLayout() links_grid.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 1, 1) links_grid.addWidget(self.restore_link, 2, 1) links_grid.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 3, 1) links_grid.addWidget(self.configure_link, 4, 1) links_grid.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 5, 1) prefs_layout = QGridLayout() prefs_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 1) prefs_layout.addWidget(self.preferences_button, 1, 2) 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.addWidget(self.icon, 1, 3) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 4) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 5) layout.addWidget(self.slogan, 2, 3) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 3, 1) layout.addWidget(self.invite_code_widget, 4, 2, 1, 3) layout.addWidget(self.connect_button, 4, 2, 1, 3) layout.addWidget(self.message, 5, 3) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Minimum), 6, 1) layout.addLayout(links_grid, 7, 3) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Minimum), 8, 1) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 9, 1) layout.addLayout(prefs_layout, 10, 1, 1, 5)
def __init__(self, parent=None): super(WelcomeWidget, self).__init__() self.parent = parent application_settings = global_settings['application'] logo_icon = application_settings.get('logo_icon') if logo_icon: icon_file = logo_icon icon_size = 288 else: icon_file = application_settings.get('tray_icon') icon_size = 220 self.icon = QLabel() self.icon.setPixmap(Pixmap(icon_file, icon_size)) self.icon.setAlignment(Qt.AlignCenter) self.slogan = QLabel("<i>{}</i>".format( application_settings.get('description', ''))) self.slogan.setFont(Font(12)) p = self.palette() dimmer_grey = BlendedColor(p.windowText().color(), p.window().color()).name() self.slogan.setStyleSheet("color: {}".format(dimmer_grey)) self.slogan.setAlignment(Qt.AlignCenter) if logo_icon: self.slogan.hide() self.invite_code_widget = InviteCodeWidget(self) self.lineedit = self.invite_code_widget.lineedit self.message = QLabel() self.message.setStyleSheet("color: red") self.message.setAlignment(Qt.AlignCenter) self.message.hide() self.restore_link = QLabel() self.restore_link.setText("<a href>Restore from Recovery Key...</a>") self.restore_link.setFont(Font(9)) self.restore_link.setAlignment(Qt.AlignCenter) self.configure_link = QLabel() self.configure_link.setText("<a href>Manual configuration...</a>") self.configure_link.setFont(Font(9)) self.configure_link.setAlignment(Qt.AlignCenter) self.preferences_button = QPushButton() self.preferences_button.setIcon(QIcon(resource('preferences.png'))) self.preferences_button.setStyleSheet('border: 0px; padding: 0px;') self.preferences_button.setToolTip("Preferences...") self.preferences_button.setFocusPolicy(Qt.NoFocus) links_grid = QGridLayout() links_grid.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 1, 1) links_grid.addWidget(self.restore_link, 2, 1) links_grid.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 3, 1) links_grid.addWidget(self.configure_link, 4, 1) links_grid.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 5, 1) prefs_layout = QGridLayout() prefs_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 1) prefs_layout.addWidget(self.preferences_button, 1, 2) 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.addWidget(self.icon, 1, 3) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 4) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 5) layout.addWidget(self.slogan, 2, 3) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 3, 1) layout.addWidget(self.invite_code_widget, 4, 2, 1, 3) layout.addWidget(self.message, 5, 3) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Minimum), 6, 1) layout.addLayout(links_grid, 7, 3) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Minimum), 8, 1) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 9, 1) layout.addLayout(prefs_layout, 10, 1, 1, 5)
def test_font_upscale_on_macos(point_size, point_size_mac, monkeypatch): monkeypatch.setattr("sys.platform", "darwin") font = Font(point_size) assert font.pointSize() == point_size_mac
def test_font_default(platform, expected, monkeypatch): monkeypatch.setattr("sys.platform", platform) font = Font() assert font.pointSize() == expected