diff --git a/securedrop_client/gui/main.py b/securedrop_client/gui/main.py index de7299af9c..c41eb253ba 100644 --- a/securedrop_client/gui/main.py +++ b/securedrop_client/gui/main.py @@ -23,7 +23,8 @@ from PyQt5.QtCore import Qt from securedrop_client import __version__ from securedrop_client.gui.widgets import (ToolBar, MainView, LoginDialog, - ConversationView) + ConversationView, + SourceProfileShortWidget) from securedrop_client.resources import load_icon @@ -205,7 +206,15 @@ def show_conversation_for(self, source): "identity details released. She feels " "horrible. She wants the children who survived " "to find peace. Thanks.") - self.main_view.update_view(conversation) + + container = QWidget() + layout = QVBoxLayout() + container.setLayout(layout) + source_profile = SourceProfileShortWidget(source) + + layout.addWidget(source_profile) + layout.addWidget(conversation) + self.main_view.update_view(container) def set_status(self, message, duration=5000): """ diff --git a/securedrop_client/gui/widgets.py b/securedrop_client/gui/widgets.py index 89a17965b2..2ad2abc061 100644 --- a/securedrop_client/gui/widgets.py +++ b/securedrop_client/gui/widgets.py @@ -19,11 +19,12 @@ import logging import arrow from PyQt5.QtCore import Qt -from PyQt5.QtGui import QPainter +from PyQt5.QtGui import QPainter, QIcon from PyQt5.QtWidgets import (QListWidget, QTextEdit, QLabel, QToolBar, QAction, QWidget, QListWidgetItem, QHBoxLayout, QPushButton, QVBoxLayout, QLineEdit, QScrollArea, - QPlainTextEdit, QSpacerItem, QSizePolicy, QDialog) + QPlainTextEdit, QSpacerItem, QSizePolicy, QDialog, + QMenu, QToolButton) from securedrop_client.resources import load_svg, load_image @@ -487,3 +488,81 @@ def add_reply(self, reply, files=None): if files: for f in files: self.conversation_layout.addWidget(FileWidget(f, 'right')) + + +class DeleteSourceAction(QAction): + """ + Use this action to Delete the source record + """ + + def __init__(self, source, parent): + self.source = source + self.text = _("Delete") + super().__init__(self.text, parent) + self.triggered.connect(self._delete_source) + + def _delete_source(self): + self.source.delete() + + +class SourceMenu(QMenu): + """ + Renders Menu for performing various operations to Source. + + Note: It only supports "delete" operation at the moment. + """ + + def __init__(self, source): + super().__init__() + self.source = source + actions = ( + DeleteSourceAction(self.source, self), + ) + for action in actions: + self.addAction(action) + + +class HamburgerMenuButton(QToolButton): + """ + A menu button for displaying source menu + """ + + def __init__(self, source): + super().__init__() + self.source = source + hamburger_icon = load_image("hamburger_icon.png") + self.setIcon(QIcon(hamburger_icon)) + self.setMenu(SourceMenu(self.source)) + self.setPopupMode(QToolButton.InstantPopup) + + +class TitleLabel(QLabel): + """ + Centered aligned, Heading level 3 label + """ + + def __init__(self, text): + html_text = "