-
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #53 from luleyleo/31-add-content-preview-for-text-…
…files Add content preview for text files
- Loading branch information
Showing
12 changed files
with
434 additions
and
114 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
.cg-banner { | ||
background-color: var(--accent-bg-color); | ||
color: var(--accent-fg-color); | ||
.view { | ||
background-color: #00000000; | ||
} | ||
|
||
.view gutter { | ||
background-color: #00000000; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,5 @@ pub use error_window::ErrorWindow; | |
|
||
mod search_window; | ||
pub use search_window::SearchWindow; | ||
|
||
mod preview; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
mod plain_preview; | ||
pub use plain_preview::PlainPreview; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
using Gtk 4.0; | ||
using Adw 1; | ||
using GtkSource 5; | ||
|
||
template $ClapgrepPlainPreview: Widget { | ||
layout-manager: Gtk.BinLayout {}; | ||
|
||
Adw.ToolbarView { | ||
top-bar-style: flat; | ||
|
||
[top] | ||
Adw.HeaderBar { | ||
title-widget: Adw.WindowTitle title { | ||
title: _("Content Preview"); | ||
}; | ||
} | ||
|
||
Stack views { | ||
StackPage no_preview { | ||
child: Adw.StatusPage { | ||
title: _("No Preview Available"); | ||
description: _("Try clicking on on of the result lines."); | ||
icon-name: "x-office-document-symbolic"; | ||
}; | ||
} | ||
|
||
StackPage some_preview { | ||
child: ScrolledWindow { | ||
child: GtkSource.View text_view { | ||
vexpand: true; | ||
editable: false; | ||
show-line-numbers: true; | ||
highlight-current-line: true; | ||
}; | ||
}; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
use gtk::glib::{self, Object}; | ||
|
||
use crate::search::SearchResult; | ||
|
||
glib::wrapper! { | ||
pub struct PlainPreview(ObjectSubclass<imp::PlainPreview>) | ||
@extends gtk::Widget; | ||
} | ||
|
||
impl PlainPreview { | ||
pub fn new(result: &SearchResult) -> Self { | ||
Object::builder().property("result", result).build() | ||
} | ||
} | ||
|
||
mod imp { | ||
use crate::search::SearchResult; | ||
use adw::subclass::prelude::*; | ||
use gettextrs::gettext; | ||
use glib::subclass::InitializingObject; | ||
use gtk::{glib, prelude::*, CompositeTemplate}; | ||
use sourceview5::prelude::*; | ||
use std::{cell::RefCell, fs, time::Duration}; | ||
|
||
#[derive(CompositeTemplate, glib::Properties, Default)] | ||
#[template(file = "src/ui/preview/plain_preview.blp")] | ||
#[properties(wrapper_type = super::PlainPreview)] | ||
pub struct PlainPreview { | ||
#[property(get, set)] | ||
pub result: RefCell<SearchResult>, | ||
|
||
#[template_child] | ||
pub title: TemplateChild<adw::WindowTitle>, | ||
#[template_child] | ||
pub text_view: TemplateChild<sourceview5::View>, | ||
|
||
#[template_child] | ||
pub views: TemplateChild<gtk::Stack>, | ||
#[template_child] | ||
pub no_preview: TemplateChild<gtk::StackPage>, | ||
#[template_child] | ||
pub some_preview: TemplateChild<gtk::StackPage>, | ||
} | ||
|
||
#[glib::object_subclass] | ||
impl ObjectSubclass for PlainPreview { | ||
const NAME: &'static str = "ClapgrepPlainPreview"; | ||
type Type = super::PlainPreview; | ||
type ParentType = gtk::Widget; | ||
|
||
fn class_init(klass: &mut Self::Class) { | ||
klass.bind_template(); | ||
klass.bind_template_callbacks(); | ||
} | ||
|
||
fn instance_init(obj: &InitializingObject<Self>) { | ||
obj.init_template(); | ||
} | ||
} | ||
|
||
#[gtk::template_callbacks] | ||
impl PlainPreview { | ||
fn buffer(&self) -> sourceview5::Buffer { | ||
self.text_view | ||
.buffer() | ||
.downcast::<sourceview5::Buffer>() | ||
.unwrap() | ||
} | ||
|
||
fn update_preview(&self) { | ||
let result = self.result.borrow(); | ||
let file = result.absolute_path(); | ||
|
||
if !file.exists() { | ||
return; | ||
} | ||
|
||
if let Ok(full_text) = fs::read_to_string(&file) { | ||
let buffer = self.buffer(); | ||
buffer.set_text(&full_text); | ||
|
||
// Setup syntax highlighting | ||
let lm = sourceview5::LanguageManager::default(); | ||
let language = lm.guess_language(Some(&file), None); | ||
buffer.set_language(language.as_ref()); | ||
self.text_view.set_monospace(language.is_some()); | ||
|
||
// Place cursor on result line. | ||
let mut cursor_position = buffer.start_iter(); | ||
cursor_position.forward_lines((result.line() - 1) as i32); | ||
buffer.place_cursor(&cursor_position); | ||
|
||
// Set title to file name. | ||
let file_name = file.file_name().unwrap().to_string_lossy(); | ||
self.title.set_title(file_name.as_ref()); | ||
|
||
// Scroll to result line after 100ms. | ||
// | ||
// The delay is needed because scroll_to_iter only works | ||
// once the line hights have been calculated in an idle handler. | ||
let text_view = self.text_view.clone(); | ||
glib::timeout_add_local_once(Duration::from_millis(100), move || { | ||
text_view.scroll_to_iter(&mut cursor_position, 0.0, true, 0.0, 0.3); | ||
}); | ||
|
||
self.views.set_visible_child(&self.some_preview.child()); | ||
} else { | ||
self.title.set_title(&gettext("Content Preview")); | ||
self.views.set_visible_child(&self.no_preview.child()); | ||
} | ||
} | ||
|
||
fn setup_style(&self) { | ||
let text_view_buffer = self.buffer(); | ||
|
||
let asm = adw::StyleManager::default(); | ||
let sm = sourceview5::StyleSchemeManager::default(); | ||
|
||
let light_style = sm.scheme("Adwaita").unwrap(); | ||
let dark_style = sm.scheme("Adwaita-dark").unwrap(); | ||
|
||
let setter = move |asm: &adw::StyleManager| { | ||
let current_style = if asm.is_dark() { | ||
&dark_style | ||
} else { | ||
&light_style | ||
}; | ||
|
||
text_view_buffer.set_style_scheme(Some(current_style)); | ||
}; | ||
|
||
setter(&asm); | ||
asm.connect_dark_notify(setter); | ||
} | ||
} | ||
|
||
#[glib::derived_properties] | ||
impl ObjectImpl for PlainPreview { | ||
fn constructed(&self) { | ||
self.parent_constructed(); | ||
let obj = self.obj(); | ||
|
||
self.setup_style(); | ||
|
||
obj.connect_result_notify(|obj| { | ||
obj.imp().update_preview(); | ||
}); | ||
} | ||
} | ||
|
||
impl WidgetImpl for PlainPreview {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.