def _draw_pixmap(self, source, selected, synced, confined): color = QColor(0x99, 0x99, 0x99) if confined: color = QColor(0xDD, 0xDD, 0xDD) if selected: color = QColor(0xAA, 0xAA, 0xAA) elif selected: color = QColor(0x33, 0x33, 0x33) p = Pixmap(source) if p.isNull(): return p = Pixmap(p.scaled(120, 120, Qt.KeepAspectRatio)) p.replace_color(QColor(0, 0, 0), color) painter = QPainter(p) if confined: painter.drawPixmap(p.width() - 90, 0, 100, 100, IconTableItem.CONFINED_ICON) elif synced: painter.drawPixmap(p.width() - 90, 0, 100, 100, IconTableItem.SYNCED_ICON) else: painter.drawPixmap(p.width() - 90, 0, 100, 100, IconTableItem.UNSYNCED_ICON) painter.end() return p
def __init__(self, pending): super().__init__() self.setupUi(self) self.pending = pending accept_pix = Pixmap(":/icons/images/material/done.svg") accept_pix.replace_color(QColor(0x00, 0x00, 0x00), QColor(0xFF, 0xFF, 0xFF)) reject_pix = Pixmap(":/icons/images/material/clear.svg") reject_pix.replace_color(QColor(0x00, 0x00, 0x00), QColor(0xFF, 0xFF, 0xFF)) self.button_accept.setIcon(QIcon(accept_pix)) self.button_reject.setIcon(QIcon(reject_pix)) self.label_date.setText(format_datetime(pending.submitted_on)) if isinstance(self.pending, PkiEnrollementAccepterInvalidSubmittedCtx): if self.pending.submitter_x509_certificate: self.widget_cert_infos.setVisible(True) self.widget_cert_error.setVisible(False) self.label_name.setText( self.pending.submitter_x509_certificate.subject_common_name ) self.label_email.setText( self.pending.submitter_x509_certificate. subject_email_address) self.label_issuer.setText( self.pending.submitter_x509_certificate.issuer_common_name) else: self.widget_cert_infos.setVisible(False) self.widget_cert_error.setVisible(True) self.label_error.setText( translate("TEXT_ENROLLMENT_ERROR_WITH_CERTIFICATE")) self.button_accept.setVisible(False) self.label_cert_validity.setStyleSheet( "#label_cert_validity { color: #F44336; }") self.label_cert_validity.setText( "✘ " + translate("TEXT_ENROLLMENT_CERTIFICATE_IS_INVALID")) self.label_cert_validity.setToolTip( textwrap.fill(str(self.pending.error), 80)) else: assert isinstance(self.pending, PkiEnrollementAccepterValidSubmittedCtx) self.widget_cert_infos.setVisible(True) self.widget_cert_error.setVisible(False) self.button_accept.setVisible(True) self.label_name.setText( self.pending.submitter_x509_certificate.subject_common_name) self.label_email.setText( self.pending.submitter_x509_certificate.subject_email_address) self.label_issuer.setText( self.pending.submitter_x509_certificate.issuer_common_name) self.label_cert_validity.setStyleSheet( "#label_cert_validity { color: #8BC34A; }") self.label_cert_validity.setText( "✔ " + translate("TEXT_ENROLLMENT_CERTIFICATE_IS_VALID")) self.button_accept.clicked.connect( lambda: self.accept_clicked.emit(self)) self.button_reject.clicked.connect( lambda: self.reject_clicked.emit(self))
def __init__(self, is_synced, pixmap, *args, **kwargs): super().__init__(*args, **kwargs) self.source = pixmap if not IconTableItem.SYNCED_ICON: IconTableItem.SYNCED_ICON = Pixmap(":/icons/images/material/check.svg") IconTableItem.SYNCED_ICON.replace_color(QColor(0, 0, 0), QColor(50, 168, 82)) if not IconTableItem.UNSYNCED_ICON: IconTableItem.UNSYNCED_ICON = Pixmap(":/icons/images/material/cached.svg") IconTableItem.UNSYNCED_ICON.replace_color(QColor(0, 0, 0), QColor(219, 20, 20)) self._is_synced = is_synced self.switch_icon()
def warn(cls, msg, timeout=3000, action_text=None, action=None, animate=True): pix = Pixmap(":/icons/images/material/report_problem.svg") pix.replace_color(QColor(0, 0, 0), QColor(208, 102, 73)) snackbar = SnackbarWidget( msg, icon=pix, timeout=timeout, action_text=action_text, action=action, animate=animate ) cls.get_manager().add_snackbar(snackbar)
def congratulate(cls, msg, timeout=3000, action_text=None, action=None, animate=True): pix = Pixmap(":/icons/images/material/check_circle.svg") pix.replace_color(QColor(0, 0, 0), QColor(73, 208, 86)) snackbar = SnackbarWidget( msg, icon=pix, timeout=timeout, action_text=action_text, action=action, animate=animate ) cls.get_manager().add_snackbar(snackbar)
def inform(cls, msg, timeout=3000, action_text=None, action=None, animate=True): pix = Pixmap(":/icons/images/material/info.svg") pix.replace_color(QColor(0, 0, 0), QColor(73, 153, 208)) snackbar = SnackbarWidget( msg, icon=pix, timeout=timeout, action_text=action_text, action=action, animate=animate ) cls.get_manager().add_snackbar(snackbar)
def user_info(self, val): profiles_txt = { UserProfile.OUTSIDER: _("TEXT_USER_PROFILE_OUTSIDER"), UserProfile.STANDARD: _("TEXT_USER_PROFILE_STANDARD"), UserProfile.ADMIN: _("TEXT_USER_PROFILE_ADMIN"), } profiles_icons = { UserProfile.OUTSIDER: ":/icons/images/material/person_outline.svg", UserProfile.STANDARD: ":/icons/images/material/person.svg", UserProfile.ADMIN: ":/icons/images/material/manage_accounts.svg", } self._user_info = val if self.user_info.is_revoked: self.setToolTip(_("TEXT_USER_IS_REVOKED")) self.widget.setStyleSheet("background-color: #DDDDDD;") self.label_revoked.setText(_("TEXT_USER_IS_REVOKED")) else: self.label_revoked.setText("") self.setToolTip("") self.widget.setStyleSheet("background-color: #FFFFFF;") if self.user_info.human_handle: self.label_email.setText( ensure_string_size(self.user_info.human_handle.email, 160, self.label_email.font())) self.label_email.setToolTip(self.user_info.human_handle.email) self.label_username.setText( ensure_string_size(self.user_info.short_user_display, 160, self.label_username.font())) self.label_username.setToolTip(self.user_info.short_user_display) self.label_role.setText(profiles_txt[self.user_info.profile]) pix = Pixmap(profiles_icons[self.user_info.profile]) pix.replace_color(QColor(0, 0, 0), QColor(153, 153, 153)) self.label_icon.setPixmap(pix)
def _draw_pixmap(self, source, selected, synced): color = QColor(0x33, 0x33, 0x33) if selected else QColor(0x99, 0x99, 0x99) p = Pixmap(source) p.replace_color(QColor(0, 0, 0), color) painter = QPainter(p) if synced: painter.drawPixmap(p.width() - 90, 0, 100, 100, IconTableItem.SYNCED_ICON) else: painter.drawPixmap(p.width() - 90, 0, 100, 100, IconTableItem.UNSYNCED_ICON) painter.end() return p
def change_selection(self): selected = self.selectedItems() for item in self.previous_selection: if item.column() == Column.ICON: file_type = item.data(TYPE_DATA_INDEX) if file_type == FileType.ParentWorkspace or file_type == FileType.ParentFolder: p = Pixmap(":/icons/images/material/arrow_upward.svg") p.replace_color(QColor(0, 0, 0), QColor(0x99, 0x99, 0x99)) item.setIcon(QIcon(p)) elif file_type == FileType.File or file_type == FileType.Folder: item.switch_icon() for item in selected: if item.column() == Column.ICON: file_type = item.data(TYPE_DATA_INDEX) if file_type == FileType.ParentWorkspace or file_type == FileType.ParentFolder: p = Pixmap(":/icons/images/material/arrow_upward.svg") p.replace_color(QColor(0, 0, 0), QColor(255, 255, 255)) item.setIcon(QIcon(p)) elif file_type == FileType.File or file_type == FileType.Folder: item.switch_icon() self.previous_selection = selected
def add_parent_workspace(self): row_idx = self.rowCount() self.insertRow(row_idx) items = [] p = Pixmap(":/icons/images/material/arrow_upward.svg") p.replace_color(QColor(0, 0, 0), QColor(0x99, 0x99, 0x99)) items.append(CustomTableItem(QIcon(p), "")) items.append(CustomTableItem(_("TEXT_FILE_TREE_PARENT_WORKSPACE"))) items.append(CustomTableItem()) items.append(CustomTableItem()) items.append(CustomTableItem()) for col, item in zip(Column, items): item.setData(NAME_DATA_INDEX, "") item.setData(TYPE_DATA_INDEX, FileType.ParentWorkspace) item.setData(UUID_DATA_INDEX, None) item.setFlags(Qt.ItemIsEnabled) self.setItem(row_idx, col, item)
def set_status_update_failed(self): p = Pixmap(":/icons/images/material/sync_problem.svg") p.replace_color(QColor(0, 0, 0), QColor(0xF1, 0x96, 0x2B)) self.label_status.setPixmap(p) self.status_timer.start()
def set_status_updated(self): p = Pixmap(":/icons/images/material/done.svg") p.replace_color(QColor(0, 0, 0), QColor(0x8B, 0xC3, 0x4A)) self.label_status.setPixmap(p) self.status_timer.start()
def set_status_updating(self): p = Pixmap(":/icons/images/material/update.svg") p.replace_color(QColor(0, 0, 0), QColor(0x99, 0x99, 0x99)) self.label_status.setPixmap(p)
def __init__( self, core: LoggedCore, jobs_ctx: QtToTrioJobScheduler, event_bus: EventBus, systray_notification: pyqtBoundSignal, file_link_addr: Optional[BackendOrganizationFileLinkAddr] = None, parent: Optional[QWidget] = None, ): super().__init__(parent=parent) self.setupUi(self) self.jobs_ctx = jobs_ctx self.core = core self.event_bus = event_bus self.systray_notification = systray_notification self.last_notification = 0.0 self.desync_notified = False self.menu = MenuWidget(parent=self) self.widget_menu.layout().addWidget(self.menu) for e in self.NOTIFICATION_EVENTS: self.event_bus.connect(e, cast(EventCallback, self.handle_event)) self.event_bus.connect(CoreEvent.FS_ENTRY_SYNCED, self._on_vlobs_updated) self.event_bus.connect(CoreEvent.BACKEND_REALM_VLOBS_UPDATED, self._on_vlobs_updated) self.set_user_info() menu = QMenu() if self.core.device.is_admin and is_saas_addr(self.core.device.organization_addr): update_sub_act = menu.addAction(_("ACTION_UPDATE_SUBSCRIPTION")) update_sub_act.triggered.connect(self._on_update_subscription_clicked) copy_backend_addr_act = menu.addAction(_("ACTION_COPY_BACKEND_ADDR")) copy_backend_addr_act.triggered.connect(self._on_copy_backend_addr) menu.addSeparator() change_auth_act = menu.addAction(_("ACTION_DEVICE_MENU_CHANGE_AUTHENTICATION")) change_auth_act.triggered.connect(self.change_authentication) menu.addSeparator() log_out_act = menu.addAction(_("ACTION_LOG_OUT")) log_out_act.triggered.connect(self.logout_requested.emit) self.button_user.setMenu(menu) pix = Pixmap(":/icons/images/material/person.svg") pix.replace_color(QColor(0, 0, 0), QColor(0x00, 0x92, 0xFF)) self.button_user.setIcon(QIcon(pix)) self.button_user.clicked.connect(self._show_user_menu) self.new_notification.connect(self.on_new_notification) self.menu.button_enrollment.setVisible( self.core.device.is_admin and is_pki_enrollment_available() ) if self.core.device.is_outsider: self.menu.button_users.hide() self.menu.files_clicked.connect(self.show_mount_widget) self.menu.users_clicked.connect(self.show_users_widget) self.menu.devices_clicked.connect(self.show_devices_widget) self.menu.enrollment_clicked.connect(self.show_enrollment_widget) self.connection_state_changed.connect(self._on_connection_state_changed) self.navigation_bar_widget.clear() self.navigation_bar_widget.route_clicked.connect(self._on_route_clicked) effect = QGraphicsDropShadowEffect(self) effect.setColor(QColor(100, 100, 100)) effect.setBlurRadius(4) effect.setXOffset(-2) effect.setYOffset(2) self.widget_notif.setGraphicsEffect(effect) self.mount_widget = MountWidget(self.core, self.jobs_ctx, self.event_bus, parent=self) self.widget_central.layout().insertWidget(0, self.mount_widget) self.mount_widget.folder_changed.connect(self._on_folder_changed) self.organization_stats_success.connect(self._on_organization_stats_success) self.organization_stats_error.connect(self._on_organization_stats_error) self.users_widget = UsersWidget(self.core, self.jobs_ctx, self.event_bus, parent=self) self.users_widget.filter_shared_workspaces_request.connect(self.show_mount_widget) self.widget_central.layout().insertWidget(0, self.users_widget) self.devices_widget = DevicesWidget(self.core, self.jobs_ctx, self.event_bus, parent=self) self.widget_central.layout().insertWidget(0, self.devices_widget) self.enrollment_widget = EnrollmentWidget( self.core, self.jobs_ctx, self.event_bus, parent=self ) self.widget_central.layout().insertWidget(0, self.enrollment_widget) self._on_connection_state_changed( self.core.backend_status, self.core.backend_status_exc, allow_systray=False ) if file_link_addr is not None: try: self.go_to_file_link(file_link_addr) except GoToFileLinkBadWorkspaceIDError: show_error( self, _("TEXT_FILE_LINK_WORKSPACE_NOT_FOUND_organization").format( organization=file_link_addr.organization_id ), ) self.show_mount_widget() except GoToFileLinkPathDecryptionError: show_error(self, _("TEXT_INVALID_URL")) self.show_mount_widget() except GoToFileLinkBadOrganizationIDError: show_error( self, _("TEXT_FILE_LINK_NOT_IN_ORG_organization").format( organization=file_link_addr.organization_id ), ) self.show_mount_widget() else: self.show_mount_widget()
def __init__(self, core, jobs_ctx, event_bus, systray_notification, action_addr=None, **kwargs): super().__init__(**kwargs) self.setupUi(self) self.jobs_ctx = jobs_ctx self.core = core self.event_bus = event_bus self.systray_notification = systray_notification self.menu = MenuWidget(parent=self) self.widget_menu.layout().addWidget(self.menu) for e in self.NOTIFICATION_EVENTS: self.event_bus.connect(e, self.handle_event) self.event_bus.connect(CoreEvent.FS_ENTRY_SYNCED, self._on_vlobs_updated_trio) self.event_bus.connect(CoreEvent.BACKEND_REALM_VLOBS_UPDATED, self._on_vlobs_updated_trio) self.vlobs_updated_qt.connect(self._on_vlobs_updated_qt) self.organization_stats_timer = QTimer() self.organization_stats_timer.setInterval(self.RESET_TIMER_STATS) self.organization_stats_timer.setSingleShot(True) self.organization_stats_timer.timeout.connect( self._get_organization_stats) self.set_user_info() menu = QMenu() log_out_act = menu.addAction(_("ACTION_LOG_OUT")) log_out_act.triggered.connect(self.logout_requested.emit) self.button_user.setMenu(menu) pix = Pixmap(":/icons/images/material/person.svg") pix.replace_color(QColor(0, 0, 0), QColor(0x00, 0x92, 0xFF)) self.button_user.setIcon(QIcon(pix)) self.button_user.clicked.connect(self._show_user_menu) self.new_notification.connect(self.on_new_notification) self.menu.files_clicked.connect(self.show_mount_widget) self.menu.users_clicked.connect(self.show_users_widget) self.menu.devices_clicked.connect(self.show_devices_widget) self.connection_state_changed.connect( self._on_connection_state_changed) self.widget_title2.hide() self.icon_title3.hide() self.label_title3.setText("") self.icon_title3.apply_style() self.icon_title3.apply_style() effect = QGraphicsDropShadowEffect(self) effect.setColor(QColor(100, 100, 100)) effect.setBlurRadius(4) effect.setXOffset(-2) effect.setYOffset(2) self.widget_notif.setGraphicsEffect(effect) self.mount_widget = MountWidget(self.core, self.jobs_ctx, self.event_bus, parent=self) self.widget_central.layout().insertWidget(0, self.mount_widget) self.mount_widget.folder_changed.connect(self._on_folder_changed) self.organization_stats_success.connect( self._on_organization_stats_success) self.organization_stats_error.connect( self._on_organization_stats_error) self.users_widget = UsersWidget(self.core, self.jobs_ctx, self.event_bus, parent=self) self.users_widget.filter_shared_workspaces_request.connect( self.show_mount_widget) self.widget_central.layout().insertWidget(0, self.users_widget) self.devices_widget = DevicesWidget(self.core, self.jobs_ctx, self.event_bus, parent=self) self.widget_central.layout().insertWidget(0, self.devices_widget) self._on_connection_state_changed(self.core.backend_status, self.core.backend_status_exc, allow_systray=False) if action_addr is not None: try: self.go_to_file_link(action_addr.workspace_id, action_addr.path) except FSWorkspaceNotFoundError: show_error( self, _("TEXT_FILE_LINK_WORKSPACE_NOT_FOUND_organization"). format(organization=action_addr.organization_id), ) self.show_mount_widget() else: self.show_mount_widget()