[fractal/fractal-next] session: Add dialog to view an Event's source
- From: Julian Sparber <jsparber src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal/fractal-next] session: Add dialog to view an Event's source
- Date: Mon, 31 May 2021 16:18:16 +0000 (UTC)
commit 3b538164ef5b504c7acc0b342ea5b2324428a0f0
Author: Kévin Commaille <zecakeh tedomum fr>
Date: Fri May 28 11:26:16 2021 +0200
session: Add dialog to view an Event's source
data/resources/resources.gresource.xml | 1 +
data/resources/style.css | 10 ++-
data/resources/ui/event-source-dialog.ui | 51 ++++++++++++++
po/POTFILES.in | 1 +
src/meson.build | 1 +
src/session/content/item_row.rs | 1 +
src/session/event_source_dialog.rs | 114 +++++++++++++++++++++++++++++++
src/session/mod.rs | 1 +
8 files changed, 178 insertions(+), 2 deletions(-)
---
diff --git a/data/resources/resources.gresource.xml b/data/resources/resources.gresource.xml
index 3355c92b..b38a6083 100644
--- a/data/resources/resources.gresource.xml
+++ b/data/resources/resources.gresource.xml
@@ -11,6 +11,7 @@
<file compressed="true" preprocess="xml-stripblanks"
alias="content-state-row.ui">ui/content-state-row.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="content-markdown-popover.ui">ui/content-markdown-popover.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="content-invite.ui">ui/content-invite.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks"
alias="event-source-dialog.ui">ui/event-source-dialog.ui</file>
<file compressed="true" preprocess="xml-stripblanks" alias="login.ui">ui/login.ui</file>
<file compressed="true" preprocess="xml-stripblanks" alias="session.ui">ui/session.ui</file>
<file compressed="true" preprocess="xml-stripblanks" alias="sidebar.ui">ui/sidebar.ui</file>
diff --git a/data/resources/style.css b/data/resources/style.css
index 8eedf99e..a92cde49 100644
--- a/data/resources/style.css
+++ b/data/resources/style.css
@@ -25,8 +25,8 @@
/* Session */
.session-loading-spinner {
- min-width: 32px;
- min-height: 32px;
+ min-width: 32px;
+ min-height: 32px;
}
headerbar.flat {
@@ -158,3 +158,9 @@ headerbar.flat {
border-radius: 9999px;
padding-left: 24px;
}
+
+/* Event Source Dialog */
+.event-source-dialog .sourceview {
+ background-color: @theme_base_color;
+ padding: 6px;
+}
diff --git a/data/resources/ui/event-source-dialog.ui b/data/resources/ui/event-source-dialog.ui
new file mode 100644
index 00000000..dcd304c4
--- /dev/null
+++ b/data/resources/ui/event-source-dialog.ui
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="EventSourceDialog" parent="AdwWindow">
+ <property name="modal">True</property>
+ <property name="title" translatable="yes">Event Source</property>
+ <property name="destroy-with-parent">True</property>
+ <property name="default-width">500</property>
+ <property name="default-height">300</property>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkHeaderBar">
+ <child type="start">
+ <object class="GtkButton">
+ <property name="icon-name">edit-copy-symbolic</property>
+ <property name="focus-on-click">False</property>
+ <property name="action-name">event-source-dialog.copy</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <style>
+ <class name="event-source-dialog"/>
+ </style>
+ <property name="child">
+ <object class="GtkSourceView" id="source_view">
+ <property name="can_focus">False</property>
+ <property name="editable">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="wrap_mode">word-char</property>
+ <property name="buffer">
+ <object class="GtkSourceBuffer">
+ <binding name="text">
+ <lookup name="source">
+ <lookup name="event">EventSourceDialog</lookup>
+ </lookup>
+ </binding>
+ </object>
+ </property>
+ </object>
+ </property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 93ff03cc..2d43d112 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -15,6 +15,7 @@ data/resources/ui/content-room-history.ui
data/resources/ui/content-state-row.ui
data/resources/ui/content.ui
data/resources/ui/context-menu-bin.ui
+data/resources/ui/event-source-dialog.ui
data/resources/ui/login.ui
data/resources/ui/in-app-notification.ui
data/resources/ui/session.ui
diff --git a/src/meson.build b/src/meson.build
index e149e2bc..bfd51e20 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -33,6 +33,7 @@ sources = files(
'login.rs',
'secret.rs',
'utils.rs',
+ 'session/event_source_dialog.rs',
'session/user.rs',
'session/mod.rs',
'session/categories/categories.rs',
diff --git a/src/session/content/item_row.rs b/src/session/content/item_row.rs
index b728d29c..030c5a27 100644
--- a/src/session/content/item_row.rs
+++ b/src/session/content/item_row.rs
@@ -4,6 +4,7 @@ use gtk::{gio, glib, prelude::*, subclass::prelude::*};
use crate::components::{ContextMenuBin, ContextMenuBinExt, ContextMenuBinImpl};
use crate::session::content::{DividerRow, MessageRow, StateRow};
+use crate::session::event_source_dialog::EventSourceDialog;
use crate::session::room::{Item, ItemType};
use matrix_sdk::events::AnyRoomEvent;
diff --git a/src/session/event_source_dialog.rs b/src/session/event_source_dialog.rs
new file mode 100644
index 00000000..fe7d5f1f
--- /dev/null
+++ b/src/session/event_source_dialog.rs
@@ -0,0 +1,114 @@
+use crate::session::room::Event;
+use adw::subclass::prelude::*;
+use gtk::{glib, prelude::*, subclass::prelude::*, CompositeTemplate};
+use sourceview::prelude::*;
+
+mod imp {
+ use super::*;
+ use glib::subclass::InitializingObject;
+ use once_cell::unsync::OnceCell;
+
+ #[derive(Debug, Default, CompositeTemplate)]
+ #[template(resource = "/org/gnome/FractalNext/event-source-dialog.ui")]
+ pub struct EventSourceDialog {
+ pub event: OnceCell<Event>,
+ #[template_child]
+ pub source_view: TemplateChild<sourceview::View>,
+ }
+
+ #[glib::object_subclass]
+ impl ObjectSubclass for EventSourceDialog {
+ const NAME: &'static str = "EventSourceDialog";
+ type Type = super::EventSourceDialog;
+ type ParentType = adw::Window;
+
+ fn class_init(klass: &mut Self::Class) {
+ Self::bind_template(klass);
+ klass.install_action("event-source-dialog.copy", None, move |widget, _, _| {
+ widget.copy_to_clipboard();
+ });
+ }
+
+ fn instance_init(obj: &InitializingObject<Self>) {
+ obj.init_template();
+ }
+ }
+
+ impl ObjectImpl for EventSourceDialog {
+ fn properties() -> &'static [glib::ParamSpec] {
+ use once_cell::sync::Lazy;
+ static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
+ vec![glib::ParamSpec::new_object(
+ "event",
+ "Event",
+ "The event that is displayed in the Dialog",
+ Event::static_type(),
+ glib::ParamFlags::READWRITE | glib::ParamFlags::CONSTRUCT_ONLY,
+ )]
+ });
+
+ PROPERTIES.as_ref()
+ }
+
+ fn set_property(
+ &self,
+ _obj: &Self::Type,
+ _id: usize,
+ value: &glib::Value,
+ pspec: &glib::ParamSpec,
+ ) {
+ match pspec.name() {
+ "event" => {
+ let event = value.get().unwrap();
+ let _ = self.event.set(event);
+ }
+ _ => unimplemented!(),
+ }
+ }
+
+ fn property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
+ match pspec.name() {
+ "event" => self.event.get().to_value(),
+ _ => unimplemented!(),
+ }
+ }
+
+ fn constructed(&self, obj: &Self::Type) {
+ let buffer = self
+ .source_view
+ .buffer()
+ .downcast::<sourceview::Buffer>()
+ .unwrap();
+
+ let md_lang = sourceview::LanguageManager::default().and_then(|lm| lm.language("json"));
+ buffer.set_language(md_lang.as_ref());
+
+ self.parent_constructed(obj);
+ }
+ }
+
+ impl WidgetImpl for EventSourceDialog {}
+ impl WindowImpl for EventSourceDialog {}
+ impl AdwWindowImpl for EventSourceDialog {}
+}
+
+glib::wrapper! {
+ pub struct EventSourceDialog(ObjectSubclass<imp::EventSourceDialog>)
+ @extends gtk::Widget, gtk::Window, adw::Window, @implements gtk::Accessible;
+}
+
+impl EventSourceDialog {
+ pub fn new(window: >k::Window, event: &Event) -> Self {
+ glib::Object::new(&[("transient-for", window), ("event", event)])
+ .expect("Failed to create EventSourceDialog")
+ }
+
+ pub fn copy_to_clipboard(&self) {
+ let priv_ = imp::EventSourceDialog::from_instance(self);
+
+ let clipboard = self.clipboard();
+ let buffer = priv_.source_view.buffer();
+ let (start_iter, end_iter) = buffer.bounds();
+ clipboard.set_text(buffer.text(&start_iter, &end_iter, true).as_ref());
+ }
+}
diff --git a/src/session/mod.rs b/src/session/mod.rs
index abf65411..4a183df4 100644
--- a/src/session/mod.rs
+++ b/src/session/mod.rs
@@ -1,5 +1,6 @@
mod categories;
mod content;
+mod event_source_dialog;
mod room;
mod room_list;
mod sidebar;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]