Something went wrong. Try again.
fork of gpui
Something went wrong. Try again.
4.8 kB · 144 lines
Rust
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145use crate::{EncodingSelector, Toggle};
use editor::Editor;use encoding_rs::{Encoding, UTF_8};use gpui::{ App, Context, Entity, IntoElement, ParentElement, Render, Styled, Subscription, WeakEntity, Window, div,};use project::Project;use ui::{Button, ButtonCommon, Clickable, LabelSize, Tooltip};use workspace::{ EncodingDisplayOptions, HideStatusItem, StatusBarSettings, StatusItemView, Workspace, item::{ItemHandle, Settings},};
pub struct ActiveBufferEncoding { active_encoding: Option<&'static Encoding>, workspace: WeakEntity<Workspace>, project: Entity<Project>, _observe_active_editor: Option<Subscription>, has_bom: bool, is_dirty: bool, is_shared: bool, is_via_remote_server: bool,}
impl ActiveBufferEncoding { pub fn new(workspace: &Workspace) -> Self { Self { active_encoding: None, workspace: workspace.weak_handle(), project: workspace.project().clone(), _observe_active_editor: None, has_bom: false, is_dirty: false, is_shared: false, is_via_remote_server: false, } }
fn update_encoding(&mut self, editor: Entity<Editor>, _: &mut Window, cx: &mut Context<Self>) { self.active_encoding = None; self.has_bom = false; self.is_dirty = false;
let project = self.project.read(cx); self.is_shared = project.is_shared(); self.is_via_remote_server = project.is_via_remote_server();
if let Some(buffer) = editor.read(cx).active_buffer(cx) { let buffer = buffer.read(cx); self.active_encoding = Some(buffer.encoding()); self.has_bom = buffer.has_bom(); self.is_dirty = buffer.is_dirty(); }
cx.notify(); }}
impl Render for ActiveBufferEncoding { fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement { let Some(active_encoding) = self.active_encoding else { return div().hidden(); };
let display_option = StatusBarSettings::get_global(cx).active_encoding_button; let is_utf8 = active_encoding == UTF_8; if !display_option.should_show(is_utf8, self.has_bom) { return div().hidden(); }
let mut text = active_encoding.name().to_string(); if self.has_bom { text.push_str(" (BOM)"); }
let (disabled, tooltip_text) = if self.is_dirty { (true, "Save file to change encoding") } else if self.is_shared { (true, "Cannot change encoding during collaboration") } else if self.is_via_remote_server { (true, "Cannot change encoding of remote server file") } else { (false, "Reopen with Encoding") };
div().child( Button::new("change-encoding", text) .label_size(LabelSize::Small) .tab_index(0isize) .on_click(cx.listener(move |this, _, window, cx| { if disabled { return; } if let Some(workspace) = this.workspace.upgrade() { workspace.update(cx, |workspace, cx| { EncodingSelector::toggle(workspace, window, cx) }); } })) .tooltip(move |_window, cx| { if disabled { Tooltip::text(tooltip_text)(_window, cx) } else { Tooltip::for_action(tooltip_text, &Toggle, cx) } }), ) }}
impl StatusItemView for ActiveBufferEncoding { fn set_active_pane_item( &mut self, active_pane_item: Option<&dyn ItemHandle>, window: &mut Window, cx: &mut Context<Self>, ) { if let Some(editor) = active_pane_item.and_then(|item| item.downcast::<Editor>()) { self._observe_active_editor = Some(cx.observe_in(&editor, window, Self::update_encoding)); self.update_encoding(editor, window, cx); } else { self.active_encoding = None; self.has_bom = false; self.is_dirty = false; self.is_shared = false; self.is_via_remote_server = false; self._observe_active_editor = None; }
cx.notify(); }
fn hide_setting(&self, _: &App) -> Option<HideStatusItem> { Some(HideStatusItem::new(|settings| { settings .status_bar .get_or_insert_default() .active_encoding_button = Some(EncodingDisplayOptions::Disabled); })) }}