diff --git a/i18n/ar/cosmic_files.ftl b/i18n/ar/cosmic_files.ftl index 920647c..3e5e906 100644 --- a/i18n/ar/cosmic_files.ftl +++ b/i18n/ar/cosmic_files.ftl @@ -70,15 +70,6 @@ properties = الخصائص ## Settings settings = الإعدادات -settings-tab = لسان -settings-show-hidden = أظهر الملفّات والمجلدات المخفية -default-view = العرض المبدئي -icon-size-list = حجم الأيقونات (لائحة) -icon-size-grid = حجم الأيقونات (شبكة) -sorting-name = رتّب حسب -direction = الاتّجاه -ascending = تصاعديًا -descending = تنازليًا ### Appearance appearance = المظهر diff --git a/i18n/be/cosmic_files.ftl b/i18n/be/cosmic_files.ftl index ceb1267..646ba1d 100644 --- a/i18n/be/cosmic_files.ftl +++ b/i18n/be/cosmic_files.ftl @@ -170,15 +170,6 @@ show-details = Паказаць дэталі ## Settings settings = Налады -settings-tab = Укладка -settings-show-hidden = Паказаць схаваныя файлы -default-view = Выгляд па змаўчанні -icon-size-list = Памер значка (спіс) -icon-size-grid = Памер значка (сетка) -sorting-name = Сартаваць -direction = Напрамак -ascending = Па ўзрастанні -descending = Па ўбыванні ### Appearance appearance = Выгляд diff --git a/i18n/cs/cosmic_files.ftl b/i18n/cs/cosmic_files.ftl index 02a9563..6021795 100644 --- a/i18n/cs/cosmic_files.ftl +++ b/i18n/cs/cosmic_files.ftl @@ -70,15 +70,6 @@ properties = Vlastnosti ## Settings settings = Nastavení -settings-tab = Karta -settings-show-hidden = Zobrazit skryté soubory -default-view = Výchozí zobrazení -icon-size-list = Velikost ikon (seznam) -icon-size-grid = Velikost ikon (mřížka) -sorting-name = Třídit podle -direction = Směr -ascending = Vzestupně -descending = Sestupně ### Appearance appearance = Vzhled diff --git a/i18n/de/cosmic_files.ftl b/i18n/de/cosmic_files.ftl index beba282..6130dbf 100644 --- a/i18n/de/cosmic_files.ftl +++ b/i18n/de/cosmic_files.ftl @@ -169,15 +169,6 @@ properties = Eigenschaften ## Einstellungen settings = Einstellungen -settings-tab = Tab -settings-show-hidden = Versteckte Dateien anzeigen -default-view = Standardansicht -icon-size-list = Symbolgröße (Liste) -icon-size-grid = Symbolgröße (Raster) -sorting-name = Sortieren nach -direction = Richtung -ascending = Aufsteigend -descending = Absteigend ### Aussehen appearance = Aussehen diff --git a/i18n/en/cosmic_files.ftl b/i18n/en/cosmic_files.ftl index 5714dab..95bde15 100644 --- a/i18n/en/cosmic_files.ftl +++ b/i18n/en/cosmic_files.ftl @@ -169,15 +169,6 @@ show-details = Show details ## Settings settings = Settings -settings-tab = Tab -settings-show-hidden = Show hidden files -default-view = Default view -icon-size-list = Icon size (list) -icon-size-grid = Icon size (grid) -sorting-name = Sort by -direction = Direction -ascending = Ascending -descending = Descending ### Appearance appearance = Appearance diff --git a/i18n/es-419/cosmic_files.ftl b/i18n/es-419/cosmic_files.ftl index 07b5e7c..faf16ab 100644 --- a/i18n/es-419/cosmic_files.ftl +++ b/i18n/es-419/cosmic_files.ftl @@ -109,15 +109,6 @@ properties = Propiedades ## Settings settings = Configuración -settings-tab = Pestaña -settings-show-hidden = Mostrar archivos ocultos -default-view = Vista predeterminada -icon-size-list = Tamaño de icono (lista) -icon-size-grid = Tamaño de icono (cuadrícula) -sorting-name = Ordenar por -direction = Dirección -ascending = Ascendente -descending = Descendente ### Appearance appearance = Apariencia diff --git a/i18n/es/cosmic_files.ftl b/i18n/es/cosmic_files.ftl index 4cc352b..3b9a3ac 100644 --- a/i18n/es/cosmic_files.ftl +++ b/i18n/es/cosmic_files.ftl @@ -70,15 +70,6 @@ properties = Propiedades ## Settings settings = Configuración -settings-tab = Tab -default-view = Vista por defecto -settings-show-hidden = Mostrar archivos escondidos -icon-size-list = Tamaño de iconos (lista) -icon-size-grid = Tamaño de iconos (grilla) -sorting-name = Ordenar por -direction = Dirección -ascending = Ascendiente -descending = Descendiente ### Appearance appearance = Apariencia diff --git a/i18n/fi/cosmic_files.ftl b/i18n/fi/cosmic_files.ftl index 30c7285..0b234d3 100644 --- a/i18n/fi/cosmic_files.ftl +++ b/i18n/fi/cosmic_files.ftl @@ -60,14 +60,6 @@ properties = Ominaisuudet ## Settings settings = Asetukset -settings-tab = Välilehti -settings-show-hidden = Näytä piilotiedostot -icon-size-list = Kuvakkeen koko (luettelo) -icon-size-grid = Kuvakkeen koko (ruudukko) -sorting-name = Järjestä -direction = Suunta -ascending = Nouseva -descending = Laskeva ### Appearance appearance = Ulkoasu diff --git a/i18n/fr/cosmic_files.ftl b/i18n/fr/cosmic_files.ftl index 275eb04..bd6fded 100644 --- a/i18n/fr/cosmic_files.ftl +++ b/i18n/fr/cosmic_files.ftl @@ -169,15 +169,6 @@ show-details = Afficher les détails ## Settings settings = Paramètres -settings-tab = Onglet -settings-show-hidden = Afficher les fichiers cachés -default-view = Vue par défaut -icon-size-list = Taille des icônes (liste) -icon-size-grid = Taille des icônes (grille) -sorting-name = Trier par -direction = Direction -ascending = Ascendant -descending = Descendant ### Appearance appearance = Apparence diff --git a/i18n/hi/cosmic_files.ftl b/i18n/hi/cosmic_files.ftl index a4365f7..a32798f 100644 --- a/i18n/hi/cosmic_files.ftl +++ b/i18n/hi/cosmic_files.ftl @@ -169,15 +169,6 @@ show-details = विवरण दिखाएँ ## Settings settings = सेटिंग्स -settings-tab = टैब -settings-show-hidden = छिपी हुई फाइलें दिखाएँ -default-view = डिफ़ॉल्ट दृश्य -icon-size-list = आइकॉन आकार (सूची) -icon-size-grid = आइकॉन आकार (ग्रिड) -sorting-name = क्रमबद्ध द्वारा -direction = दिशा -ascending = आरोही -descending = अवरोही ### Appearance appearance = रूप diff --git a/i18n/hu/cosmic_files.ftl b/i18n/hu/cosmic_files.ftl index e8bcb27..c352cf8 100644 --- a/i18n/hu/cosmic_files.ftl +++ b/i18n/hu/cosmic_files.ftl @@ -110,15 +110,6 @@ properties = Tulajdonságok ## Settings settings = Beállítások -settings-tab = Lap -settings-show-hidden = Rejtett fájlok mutatása -default-view = Alapértelmezett nézet -icon-size-list = Ikon méret (lista) -icon-size-grid = Ikon méret (rács) -sorting-name = Rendezés -direction = Irány -ascending = Növekvő -descending = Csökkenő ### Appearance appearance = Kinézet diff --git a/i18n/it/cosmic_files.ftl b/i18n/it/cosmic_files.ftl index 9fe4621..5616158 100644 --- a/i18n/it/cosmic_files.ftl +++ b/i18n/it/cosmic_files.ftl @@ -170,15 +170,6 @@ show-details = Mostra dettagli ## Settings settings = Impostazioni -settings-tab = Schede -settings-show-hidden = Mostra file nascosti -default-view = Vista predefinita -icon-size-list = Dimensioni icone (lista) -icon-size-grid = Dimensioni icone (griglia) -sorting-name = Ordina per -direction = Direzione -ascending = Ascendente -descending = Discendente ### Appearance appearance = Aspetto diff --git a/i18n/ja/cosmic_files.ftl b/i18n/ja/cosmic_files.ftl index 2bc0656..c7e1e0c 100644 --- a/i18n/ja/cosmic_files.ftl +++ b/i18n/ja/cosmic_files.ftl @@ -136,15 +136,6 @@ properties = プロパティ ## Settings settings = 設定 -settings-tab = タブ -settings-show-hidden = 隠しファイルを表示 -default-view = デフォルトの表示 -icon-size-list = アイコンサイズ(リスト) -icon-size-grid = アイコンサイズ(グリッド) -sorting-name = 並べ替え -direction = 順 -ascending = 昇順 -descending = 降順 ### Appearance appearance = 外観 diff --git a/i18n/kn/cosmic_fiiles.ftl b/i18n/kn/cosmic_fiiles.ftl index 78ca417..e88ed69 100644 --- a/i18n/kn/cosmic_fiiles.ftl +++ b/i18n/kn/cosmic_fiiles.ftl @@ -169,15 +169,6 @@ show-details = ವಿವರಗಳನ್ನು ತೋರಿಸಿ ## Settings settings = ಸೆಟ್ಟಿಂಗ್‌ಗಳು -settings-tab = ಟ್ಯಾಬ್ -settings-show-hidden = ಮರೆಮಾಡಲಾದ ಫೈಲ್‌ಗಳನ್ನು ತೋರಿಸಿ -default-view = ಸ್ಥೂಲ ದೃಶ್ಯ -icon-size-list = ಐಕಾನ್ ಗಾತ್ರ (ಪಟ್ಟಿ) -icon-size-grid = ಐಕಾನ್ ಗಾತ್ರ (ಗ್ರೀಡ್) -sorting-name = ಇದರಿಂದ ಶ್ರೇಣೀಬದ್ಧಗೊಳಿಸಿ -direction = ದಿಕ್ಕು -ascending = ಆರೋಹಣ -descending = ಅವರೋಹಣ ### Appearance appearance = ನೋಟ diff --git a/i18n/ko/cosmic_files.ftl b/i18n/ko/cosmic_files.ftl index 2cf12c3..c41b8fb 100644 --- a/i18n/ko/cosmic_files.ftl +++ b/i18n/ko/cosmic_files.ftl @@ -60,14 +60,6 @@ properties = 정보 ## Settings settings = 설정 -settings-tab = 탭 -settings-show-hidden = 숨겨진 파일 표시 -icon-size-list = 아이콘 크기 (목록) -icon-size-grid = 아이콘 크기 (그리드) -sorting-name = 정렬 -direction = 경로 -ascending = 오름차순 -descending = 내림차순 ### Appearance appearance = 모양새 diff --git a/i18n/pl/cosmic_files.ftl b/i18n/pl/cosmic_files.ftl index 472c45e..ae648e1 100644 --- a/i18n/pl/cosmic_files.ftl +++ b/i18n/pl/cosmic_files.ftl @@ -174,15 +174,6 @@ show-details = Pokaż szczegóły ## Settings settings = Ustawienia -settings-tab = Karta -settings-show-hidden = Pokaż ukryte pliki -default-view = Domyślny widok -icon-size-list = Rozmiar ikon (lista) -icon-size-grid = Rozmiar ikon (siatka) -sorting-name = Uszereguj według -direction = Kierunek -ascending = Rosnąco -descending = Malejąco ### Appearance appearance = Wygląd diff --git a/i18n/pt-BR/cosmic_files.ftl b/i18n/pt-BR/cosmic_files.ftl index 1b4651c..589af82 100644 --- a/i18n/pt-BR/cosmic_files.ftl +++ b/i18n/pt-BR/cosmic_files.ftl @@ -169,15 +169,6 @@ show-details = Mostrar detalhes ## Settings settings = Configurações -settings-tab = Aba -settings-show-hidden = Mostrar arquivos ocultos -default-view = Visualização padrão -icon-size-list = Tamanho do ícone (lista) -icon-size-grid = Tamanho do ícone (grade) -sorting-name = Ordenar por -direction = Classificar -ascending = Crescente -descending = Decrescente ### Appearance appearance = Aparência diff --git a/i18n/pt/cosmic_files.ftl b/i18n/pt/cosmic_files.ftl index c584ced..e8d0f1d 100644 --- a/i18n/pt/cosmic_files.ftl +++ b/i18n/pt/cosmic_files.ftl @@ -130,15 +130,6 @@ show-details = Mostrar detalhes ## Settings settings = Definições -settings-tab = Separador -settings-show-hidden = Mostrar ficheiros ocultos -default-view = Vista predefinida -icon-size-list = Tamanho dos ícones (lista) -icon-size-grid = Tamanho dos ícones (grelha) -sorting-name = Ordenar por -direction = Direção -ascending = Ascendente -descending = Descendente ### Appearance appearance = Aparência diff --git a/i18n/ru/cosmic_files.ftl b/i18n/ru/cosmic_files.ftl index f83cbfe..169d1b1 100644 --- a/i18n/ru/cosmic_files.ftl +++ b/i18n/ru/cosmic_files.ftl @@ -69,15 +69,6 @@ properties = Свойства ## Settings settings = Параметры -settings-tab = Вкладка -settings-show-hidden = Показывать скрытые файлы -default-view = Вид по умолчанию -icon-size-list = Размер иконок (список) -icon-size-grid = Размер иконок (сетка) -sorting-name = Отсортировать -direction = Направление -ascending = По возрастанию -descending = По убыванию ### Appearance appearance = Оформление diff --git a/i18n/sk/cosmic_files.ftl b/i18n/sk/cosmic_files.ftl index 7b942b8..e7f33a0 100644 --- a/i18n/sk/cosmic_files.ftl +++ b/i18n/sk/cosmic_files.ftl @@ -116,15 +116,6 @@ properties = Podrobnosti ## Settings settings = Nastavenia -settings-tab = Karta -settings-show-hidden = Zobraziť skryté súbory -default-view = Predvolené zobrazenie -icon-size-list = Veľkosť ikon (zoznam) -icon-size-grid = Veľkosť ikon (mriežka) -sorting-name = Zoradiť podľa -direction = Smer -ascending = Vzostupný -descending = Zostupný ### Appearance appearance = Vzhľad diff --git a/i18n/sv/cosmic_files.ftl b/i18n/sv/cosmic_files.ftl index fac61b1..5a85b9c 100644 --- a/i18n/sv/cosmic_files.ftl +++ b/i18n/sv/cosmic_files.ftl @@ -31,15 +31,6 @@ properties = Egenskaper ## Settings settings = Inställningar -settings-tab = Flik -settings-show-hidden = Visa dolda filer -default-view = Standardvy -icon-size-list = Ikonstorlek (lista) -icon-size-grid = Ikonstorlek (rutnät) -sorting-name = Sortera efter -direction = Riktning -ascending = Stigande -descending = Fallande ### Appearance appearance = Utseende diff --git a/i18n/uk/cosmic_files.ftl b/i18n/uk/cosmic_files.ftl index 1f93011..3359e9e 100644 --- a/i18n/uk/cosmic_files.ftl +++ b/i18n/uk/cosmic_files.ftl @@ -114,15 +114,6 @@ properties = Властивості ## Settings settings = Налаштування -settings-tab = Вкладки -settings-show-hidden = Показувати приховані файли -default-view = Типовий режим перегляду -icon-size-list = Розмір піктограм (для списку) -icon-size-grid = Розмір піктограм (для ґратки) -sorting-name = Сортувати за -direction = Напрям -ascending = Зростання -descending = Спадання ### Appearance appearance = Зовнішній вигляд diff --git a/i18n/zh-CN/cosmic_files.ftl b/i18n/zh-CN/cosmic_files.ftl index 244f476..fedfff3 100644 --- a/i18n/zh-CN/cosmic_files.ftl +++ b/i18n/zh-CN/cosmic_files.ftl @@ -111,15 +111,6 @@ show-details = 显示详情 ## Settings settings = 设置 -settings-tab = 标签页 -settings-show-hidden = 显示隐藏文件 -default-view = 默认视图 -icon-size-list = 图标大小(列表) -icon-size-grid = 图标大小(网格) -sorting-name = 排序方式 -direction = 方向 -ascending = 升序 -descending = 降序 ### Appearance appearance = 外观 diff --git a/i18n/zh-TW/cosmic_files.ftl b/i18n/zh-TW/cosmic_files.ftl index 112503d..a87b9f7 100644 --- a/i18n/zh-TW/cosmic_files.ftl +++ b/i18n/zh-TW/cosmic_files.ftl @@ -167,15 +167,6 @@ show-details = 顯示詳細資料 ## Settings settings = 設定 -settings-tab = 分頁 -settings-show-hidden = 顯示隱藏檔案 -default-view = 預設檢視 -icon-size-list = 圖示大小(列表) -icon-size-grid = 圖示大小(網格) -sorting-name = 排序依據 -direction = 排序方向 -ascending = 升序 -descending = 降序 ### Appearance appearance = 外觀 diff --git a/src/app.rs b/src/app.rs index 84678f8..cfafbc5 100644 --- a/src/app.rs +++ b/src/app.rs @@ -181,15 +181,9 @@ impl Action { Action::TabNew => Message::TabNew, Action::TabNext => Message::TabNext, Action::TabPrev => Message::TabPrev, - Action::TabViewGrid => { - Message::TabMessage(entity_opt, tab::Message::View(tab::View::Grid)) - } - Action::TabViewList => { - Message::TabMessage(entity_opt, tab::Message::View(tab::View::List)) - } - Action::ToggleFoldersFirst => { - Message::TabMessage(entity_opt, tab::Message::ToggleFoldersFirst) - } + Action::TabViewGrid => Message::TabView(entity_opt, tab::View::Grid), + Action::TabViewList => Message::TabView(entity_opt, tab::View::List), + Action::ToggleFoldersFirst => Message::ToggleFoldersFirst, Action::ToggleShowHidden => { Message::TabMessage(entity_opt, tab::Message::ToggleShowHidden) } @@ -198,9 +192,9 @@ impl Action { } Action::WindowClose => Message::WindowClose, Action::WindowNew => Message::WindowNew, - Action::ZoomDefault => Message::TabMessage(entity_opt, tab::Message::ZoomDefault), - Action::ZoomIn => Message::TabMessage(entity_opt, tab::Message::ZoomIn), - Action::ZoomOut => Message::TabMessage(entity_opt, tab::Message::ZoomOut), + Action::ZoomDefault => Message::ZoomDefault(entity_opt), + Action::ZoomIn => Message::ZoomIn(entity_opt), + Action::ZoomOut => Message::ZoomOut(entity_opt), Action::Recents => Message::Recents, } } @@ -312,12 +306,17 @@ pub enum Message { TabMessage(Option, tab::Message), TabNew, TabRescan(Entity, Location, Vec, Option), + TabView(Option, tab::View), ToggleContextPage(ContextPage), + ToggleFoldersFirst, Undo(usize), UndoTrash(widget::ToastId, Arc<[PathBuf]>), UndoTrashStart(Vec), WindowClose, WindowNew, + ZoomDefault(Option), + ZoomIn(Option), + ZoomOut(Option), DndHoverLocTimeout(Location), DndHoverTabTimeout(Entity), DndEnterNav(Entity), @@ -459,9 +458,6 @@ pub struct App { config: Config, mode: Mode, app_themes: Vec, - default_view: Vec, - sort_by_names: Vec, - sort_direction: Vec, context_page: ContextPage, dialog_pages: VecDeque, dialog_text_input: widget::Id, @@ -622,7 +618,20 @@ impl App { fn update_config(&mut self) -> Command { self.update_nav_model(); - cosmic::app::command::set_theme(self.config.app_theme.theme()) + // Tabs are collected first to placate the borrowck + let tabs: Vec<_> = self.tab_model.iter().collect(); + // Update main conf and each tab with the new config + let commands: Vec<_> = std::iter::once(cosmic::app::command::set_theme( + self.config.app_theme.theme(), + )) + .chain(tabs.into_iter().map(|entity| { + self.update(Message::TabMessage( + Some(entity), + tab::Message::Config(self.config.tab), + )) + })) + .collect(); + Command::batch(commands) } fn activate_nav_model_location(&mut self, location: &Location) { @@ -924,7 +933,7 @@ impl App { let progress_bar_height = Length::Fixed(4.0); if !self.pending_operations.is_empty() { - let mut section = widget::settings::view_section(fl!("pending")); + let mut section = widget::settings::section().title(fl!("pending")); for (_id, (op, progress)) in self.pending_operations.iter().rev() { section = section.add(widget::column::with_children(vec![ widget::text(op.pending_text()).into(), @@ -937,7 +946,7 @@ impl App { } if !self.failed_operations.is_empty() { - let mut section = widget::settings::view_section(fl!("failed")); + let mut section = widget::settings::section().title(fl!("failed")); for (_id, (op, error)) in self.failed_operations.iter().rev() { section = section.add(widget::column::with_children(vec![ widget::text(op.pending_text()).into(), @@ -948,7 +957,7 @@ impl App { } if !self.complete_operations.is_empty() { - let mut section = widget::settings::view_section(fl!("complete")); + let mut section = widget::settings::section().title(fl!("complete")); for (_id, op) in self.complete_operations.iter().rev() { section = section.add(widget::text(op.completed_text())); } @@ -1003,133 +1012,27 @@ impl App { fn settings(&self) -> Element { // TODO: Should dialog be updated here too? - widget::settings::view_column(vec![ - widget::settings::view_section(fl!("appearance")) - .add({ - let app_theme_selected = match self.config.app_theme { - AppTheme::Dark => 1, - AppTheme::Light => 2, - AppTheme::System => 0, - }; - widget::settings::item::builder(fl!("theme")).control(widget::dropdown( - &self.app_themes, - Some(app_theme_selected), - move |index| { - Message::AppTheme(match index { - 1 => AppTheme::Dark, - 2 => AppTheme::Light, - _ => AppTheme::System, - }) - }, - )) - }) - .add({ - let tab_config = self.config.tab.clone(); - widget::settings::item::builder(fl!("default-view")).control(widget::dropdown( - &self.default_view, - match tab_config.view { - tab::View::Grid => Some(0), - tab::View::List => Some(1), - }, - move |index| { - Message::TabConfig(TabConfig { - view: match index { - 0 => tab::View::Grid, - _ => tab::View::List, - }, - ..tab_config - }) - }, - )) - }) - .add({ - let tab_config = self.config.tab.clone(); - let list: u16 = tab_config.icon_sizes.list.into(); - widget::settings::item::builder(fl!("icon-size-list")) - .description(format!("{}%", list)) - .control( - widget::slider(50..=500, list, move |list| { - Message::TabConfig(TabConfig { - icon_sizes: IconSizes { - list: NonZeroU16::new(list).unwrap(), - ..tab_config.icon_sizes - }, - ..tab_config - }) - }) - .step(25u16), - ) - }) - .add({ - let tab_config = self.config.tab.clone(); - let grid: u16 = tab_config.icon_sizes.grid.into(); - widget::settings::item::builder(fl!("icon-size-grid")) - .description(format!("{}%", grid)) - .control( - widget::slider(50..=500, grid, move |grid| { - Message::TabConfig(TabConfig { - icon_sizes: IconSizes { - grid: NonZeroU16::new(grid).unwrap(), - ..tab_config.icon_sizes - }, - ..tab_config - }) - }) - .step(25u16), - ) - }) - .add({ - let tab_config = self.config.tab; - let sort_by_selected = tab_config.sort_name as _; - - widget::settings::item::builder(fl!("sorting-name")).control(widget::dropdown( - &self.sort_by_names, - Some(sort_by_selected), - move |index| { - Message::TabConfig(TabConfig { - sort_name: match index { - 0 => HeadingOptions::Name, - 1 => HeadingOptions::Modified, - 2 => HeadingOptions::Size, - _ => HeadingOptions::Name, - }, - ..tab_config - }) - }, - )) - }) - .add({ - let tab_config = self.config.tab; - // Ascending is true. Descending is false - let direction = tab_config.sort_direction.into(); - - widget::settings::item::builder(fl!("direction")).control(widget::dropdown( - &self.sort_direction, - Some(direction), - move |index| { - Message::TabConfig(TabConfig { - sort_direction: index == 1, - ..tab_config - }) - }, - )) - }) - .into(), - widget::settings::view_section(fl!("settings-tab")) - .add({ - let tab_config = self.config.tab.clone(); - widget::settings::item::builder(fl!("settings-show-hidden")).toggler( - tab_config.show_hidden, - move |show_hidden| { - Message::TabConfig(TabConfig { - show_hidden, - ..tab_config - }) - }, - ) - }) - .into(), - ]) + widget::settings::view_column(vec![widget::settings::section() + .title(fl!("appearance")) + .add({ + let app_theme_selected = match self.config.app_theme { + AppTheme::Dark => 1, + AppTheme::Light => 2, + AppTheme::System => 0, + }; + widget::settings::item::builder(fl!("theme")).control(widget::dropdown( + &self.app_themes, + Some(app_theme_selected), + move |index| { + Message::AppTheme(match index { + 1 => AppTheme::Dark, + 2 => AppTheme::Light, + _ => AppTheme::System, + }) + }, + )) + }) + .into()]) .into() } } @@ -1183,9 +1086,6 @@ impl Application for App { config: flags.config, mode: flags.mode, app_themes, - default_view: vec![fl!("grid-view"), fl!("list-view")], - sort_by_names: HeadingOptions::names(), - sort_direction: vec![fl!("descending"), fl!("ascending")], context_page: ContextPage::Settings, dialog_pages: VecDeque::new(), dialog_text_input: widget::Id::unique(), @@ -1506,8 +1406,8 @@ impl Application for App { log::warn!("TODO: retry operation {}", id); } DialogPage::NetworkAuth { - mounter_key, - uri, + mounter_key: _, + uri: _, auth, auth_tx, } => { @@ -1520,9 +1420,9 @@ impl Application for App { ); } DialogPage::NetworkError { - mounter_key, + mounter_key: _, uri, - error, + error: _, } => { //TODO: re-use mounter_key? return Command::batch([ @@ -2248,23 +2148,15 @@ impl Application for App { } Message::TabConfig(config) => { if config != self.config.tab { - // Tabs are collected first to placate the borrowck - let tabs: Vec<_> = self.tab_model.iter().collect(); - // Update main conf and each tab with the new config - let commands: Vec<_> = std::iter::once(self.update_config()) - .chain(tabs.into_iter().map(|entity| { - let config = config.clone(); - self.update(Message::TabMessage( - Some(entity), - tab::Message::Config(config), - )) - })) - .collect(); - config_set!(tab, config); - return Command::batch(commands); + return self.update_config(); } } + Message::ToggleFoldersFirst => { + let mut config = self.config.tab; + config.folders_first = !config.folders_first; + return self.update(Message::TabConfig(config)); + } Message::TabMessage(entity_opt, tab_message) => { let entity = entity_opt.unwrap_or_else(|| self.tab_model.active()); @@ -2429,6 +2321,15 @@ impl Application for App { _ => (), } } + Message::TabView(entity_opt, view) => { + let entity = entity_opt.unwrap_or_else(|| self.tab_model.active()); + if let Some(tab) = self.tab_model.data_mut::(entity) { + tab.config.view = view; + } + let mut config = self.config.tab; + config.view = view; + return self.update(Message::TabConfig(config)); + } Message::ToggleContextPage(context_page) => { //TODO: ensure context menus are closed if self.context_page == context_page { @@ -2439,8 +2340,8 @@ impl Application for App { self.context_page = context_page; self.set_context_title(self.context_page.title()); } - Message::Undo(id) => { - // TODO; + Message::Undo(_id) => { + // TODO: undo } Message::UndoTrash(id, recently_trashed) => { self.toasts.remove(id); @@ -2497,6 +2398,65 @@ impl Application for App { log::error!("failed to get current executable path: {}", err); } }, + Message::ZoomDefault(entity_opt) => { + let entity = entity_opt.unwrap_or_else(|| self.tab_model.active()); + let mut config = self.config.tab; + if let Some(tab) = self.tab_model.data::(entity) { + match tab.config.view { + tab::View::List => config.icon_sizes.list = 100.try_into().unwrap(), + tab::View::Grid => config.icon_sizes.grid = 100.try_into().unwrap(), + } + } + return self.update(Message::TabConfig(config)); + } + Message::ZoomIn(entity_opt) => { + let entity = entity_opt.unwrap_or_else(|| self.tab_model.active()); + let zoom_in = |size: &mut NonZeroU16, min: u16, max: u16| { + let mut step = min; + while step <= max { + if size.get() < step { + *size = step.try_into().unwrap(); + break; + } + step += 25; + } + if size.get() > step { + *size = step.try_into().unwrap(); + } + }; + let mut config = self.config.tab; + if let Some(tab) = self.tab_model.data::(entity) { + match tab.config.view { + tab::View::List => zoom_in(&mut config.icon_sizes.list, 50, 500), + tab::View::Grid => zoom_in(&mut config.icon_sizes.grid, 50, 500), + } + } + return self.update(Message::TabConfig(config)); + } + Message::ZoomOut(entity_opt) => { + let entity = entity_opt.unwrap_or_else(|| self.tab_model.active()); + let zoom_out = |size: &mut NonZeroU16, min: u16, max: u16| { + let mut step = max; + while step >= min { + if size.get() > step { + *size = step.try_into().unwrap(); + break; + } + step -= 25; + } + if size.get() < step { + *size = step.try_into().unwrap(); + } + }; + let mut config = self.config.tab; + if let Some(tab) = self.tab_model.data::(entity) { + match tab.config.view { + tab::View::List => zoom_out(&mut config.icon_sizes.list, 50, 500), + tab::View::Grid => zoom_out(&mut config.icon_sizes.grid, 50, 500), + } + } + return self.update(Message::TabConfig(config)); + } Message::DndEnterNav(entity) => { if let Some(location) = self.nav_model.data::(entity) { self.nav_dnd_hover = Some((location.clone(), Instant::now())); @@ -3011,8 +2971,8 @@ impl Application for App { )) } DialogPage::NetworkError { - mounter_key, - uri, + mounter_key: _, + uri: _, error, } => widget::dialog(fl!("network-drive-error")) .body(error) @@ -3313,7 +3273,7 @@ impl Application for App { content } - fn view_window(&self, id: WindowId) -> Element { + fn view_window(&self, _id: WindowId) -> Element { //TODO: distinct views per window? self.view_main().map(|message| match message { app::Message::App(app) => app, diff --git a/src/config.rs b/src/config.rs index e75569b..f37414b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -158,9 +158,6 @@ pub struct TabConfig { pub folders_first: bool, /// Show hidden files and folders pub show_hidden: bool, - /// Sorter - pub sort_name: HeadingOptions, - pub sort_direction: bool, /// Icon zoom pub icon_sizes: IconSizes, } @@ -171,8 +168,6 @@ impl Default for TabConfig { view: View::List, folders_first: true, show_hidden: false, - sort_name: HeadingOptions::Name, - sort_direction: true, icon_sizes: IconSizes::default(), } } diff --git a/src/dialog.rs b/src/dialog.rs index 7564e4f..bcad9ce 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -698,12 +698,12 @@ impl Application for App { let tab_config = TabConfig { view: tab::View::List, folders_first: false, - sort_name: tab::HeadingOptions::Modified, - sort_direction: false, ..Default::default() }; let mut tab = Tab::new(location, tab_config); tab.mode = tab::Mode::Dialog(flags.kind.clone()); + tab.sort_name = tab::HeadingOptions::Modified; + tab.sort_direction = false; let mut app = App { core, diff --git a/src/lib.rs b/src/lib.rs index 37183ca..1e7309f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,10 +1,7 @@ // Copyright 2023 System76 // SPDX-License-Identifier: GPL-3.0-only -use cosmic::{ - app::{Application, Settings}, - iced::Limits, -}; +use cosmic::{app::Settings, iced::Limits}; use std::{env, fs, path::PathBuf, process}; use app::{App, Flags}; diff --git a/src/menu.rs b/src/menu.rs index cfe7939..b1bdb51 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -15,7 +15,6 @@ use std::collections::HashMap; use crate::{ app::{Action, Message}, - config::TabConfig, fl, tab::{self, HeadingOptions, Location, LocationMenuAction, Tab}, }; @@ -58,17 +57,12 @@ pub fn context_menu<'a>( .on_press(tab::Message::ContextAction(action)) }; - let TabConfig { - sort_name, - sort_direction, - .. - } = tab.config; let sort_item = |label, variant| { menu_item( format!( "{} {}", label, - match (sort_name == variant, sort_direction) { + match (tab.sort_name == variant, tab.sort_direction) { (true, true) => "\u{2B07}", (true, false) => "\u{2B06}", _ => "", @@ -273,7 +267,7 @@ pub fn dialog_menu<'a>( let sort_item = |label, sort, dir| { menu::Item::CheckBox( label, - tab.config.sort_name == sort && tab.config.sort_direction == dir, + tab.sort_name == sort && tab.sort_direction == dir, Action::SetSort(sort, dir), ) }; @@ -303,7 +297,7 @@ pub fn dialog_menu<'a>( ), ), menu::Tree::with_children( - widget::button::icon(widget::icon::from_name(if tab.config.sort_direction { + widget::button::icon(widget::icon::from_name(if tab.sort_direction { "view-sort-ascending-symbolic" } else { "view-sort-descending-symbolic" @@ -361,7 +355,7 @@ pub fn menu_bar<'a>( menu::Item::CheckBox( label, tab_opt.map_or(false, |tab| { - tab.config.sort_name == sort && tab.config.sort_direction == dir + tab.sort_name == sort && tab.sort_direction == dir }), Action::SetSort(sort, dir), ) diff --git a/src/mouse_area.rs b/src/mouse_area.rs index b9b86c1..3d2ecb8 100644 --- a/src/mouse_area.rs +++ b/src/mouse_area.rs @@ -13,7 +13,7 @@ use cosmic::{ Modifiers, }, layout, - mouse::{self, click, Event as MouseEvent}, + mouse::{self, click}, overlay, renderer::{self, Quad, Renderer as _}, touch, @@ -614,13 +614,11 @@ fn update( } } - if let Some(message) = widget.on_scroll.as_ref() { + if let Some(on_scroll) = widget.on_scroll.as_ref() { if let Event::Mouse(mouse::Event::WheelScrolled { delta }) = event { - if let Some(on_scroll) = widget.on_scroll.as_ref() { - if let Some(message) = on_scroll(delta.clone(), state.modifiers) { - shell.publish(message); - return event::Status::Captured; - } + if let Some(message) = on_scroll(delta.clone(), state.modifiers) { + shell.publish(message); + return event::Status::Captured; } } } diff --git a/src/operation.rs b/src/operation.rs index bb59e1a..1f0ad09 100644 --- a/src/operation.rs +++ b/src/operation.rs @@ -4,10 +4,7 @@ use std::{ fs, io::{self, Read, Write}, path::{Path, PathBuf}, - sync::{ - atomic::{self, AtomicU64}, - Arc, - }, + sync::Arc, }; use tokio::sync::{mpsc, Mutex}; use walkdir::WalkDir; diff --git a/src/tab.rs b/src/tab.rs index ac91e14..d911c0d 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -9,7 +9,7 @@ use cosmic::{ clipboard::dnd::DndAction, event, futures::SinkExt, - keyboard::{self, Modifiers}, + keyboard::Modifiers, subscription::{self, Subscription}, //TODO: export in cosmic::widget widget::{ @@ -39,7 +39,6 @@ use cosmic::{ use chrono::{DateTime, Utc}; use mime_guess::{mime, Mime}; use once_cell::sync::Lazy; -use recently_used_xbel::{Error, RecentlyUsed}; use serde::{Deserialize, Serialize}; use std::{ borrow::Cow, @@ -48,10 +47,8 @@ use std::{ collections::HashMap, fmt::{self, Display}, fs::{self, Metadata}, - num::NonZeroU16, os::unix::fs::MetadataExt, path::{Path, PathBuf}, - process, sync::{Arc, Mutex}, time::{Duration, Instant, SystemTime}, }; @@ -548,7 +545,7 @@ pub fn scan_search(tab_path: &PathBuf, term: &str, sizes: IconSizes) -> Vec Vec { } pub fn scan_network(uri: &str, mounters: Mounters, sizes: IconSizes) -> Vec { - for (key, mounter) in mounters.iter() { + for (_key, mounter) in mounters.iter() { match mounter.network_scan(uri, sizes) { Some(Ok(items)) => return items, Some(Err(err)) => { @@ -867,7 +864,6 @@ pub enum Message { SelectAll, SetSort(HeadingOptions, bool), Thumbnail(PathBuf, ItemThumbnail), - ToggleFoldersFirst, ToggleShowHidden, View(View), ToggleSort(HeadingOptions), @@ -877,9 +873,6 @@ pub enum Message { DndLeave(Location), WindowDrag, WindowToggleMaximize, - ZoomDefault, - ZoomIn, - ZoomOut, } #[derive(Copy, Clone, Debug, Eq, PartialEq)] @@ -1152,7 +1145,7 @@ impl Item { ); if self.mime.type_() == mime::IMAGE { - if let Some(path) = self.path_opt() { + if let Some(_path) = self.path_opt() { row = row.push( widget::button::icon(widget::icon::from_name("view-fullscreen-symbolic")) .on_press(app::Message::TabMessage(None, Message::Gallery(true))), @@ -1374,6 +1367,8 @@ pub struct Tab { pub history_i: usize, pub history: Vec, pub config: TabConfig, + pub sort_name: HeadingOptions, + pub sort_direction: bool, pub gallery: bool, pub(crate) items_opt: Option>, pub dnd_hovered: Option<(Location, Instant)>, @@ -1422,6 +1417,8 @@ impl Tab { history_i: 0, history, config, + sort_name: HeadingOptions::Name, + sort_direction: true, gallery: false, items_opt: None, scrollable_id: widget::Id::unique(), @@ -1827,9 +1824,7 @@ impl Tab { if let Some(range) = self.select_range { let min = range.0.min(range.1); let max = range.0.max(range.1); - if self.config.sort_name == HeadingOptions::Name - && self.config.sort_direction - { + if self.sort_name == HeadingOptions::Name && self.sort_direction { // A default/unsorted tab's view is consistent with how the // Items are laid out internally (items_opt), so Items can be // linearly selected @@ -1936,7 +1931,10 @@ impl Tab { } } Message::Config(config) => { + // View is preserved for existing tabs + let view = self.config.view; self.config = config; + self.config.view = view; } Message::ContextAction(action) => { // Close context menu @@ -2348,8 +2346,8 @@ impl Tab { } } Message::SetSort(heading_option, dir) => { - self.config.sort_name = heading_option; - self.config.sort_direction = dir; + self.sort_name = heading_option; + self.sort_direction = dir; } Message::Thumbnail(path, thumbnail) => { if let Some(ref mut items) = self.items_opt { @@ -2382,21 +2380,20 @@ impl Tab { } } } - Message::ToggleFoldersFirst => self.config.folders_first = !self.config.folders_first, Message::ToggleShowHidden => self.config.show_hidden = !self.config.show_hidden, Message::View(view) => { self.config.view = view; } Message::ToggleSort(heading_option) => { - let heading_sort = if self.config.sort_name == heading_option { - !self.config.sort_direction + let heading_sort = if self.sort_name == heading_option { + !self.sort_direction } else { // Default modified to descending, and others to ascending. heading_option != HeadingOptions::Modified }; - self.config.sort_direction = heading_sort; - self.config.sort_name = heading_option; + self.sort_direction = heading_sort; + self.sort_name = heading_option; } Message::Drop(Some((to, mut from))) => { self.dnd_hovered = None; @@ -2460,48 +2457,6 @@ impl Tab { Message::WindowToggleMaximize => { commands.push(Command::WindowToggleMaximize); } - Message::ZoomDefault => match self.config.view { - View::List => self.config.icon_sizes.list = 100.try_into().unwrap(), - View::Grid => self.config.icon_sizes.grid = 100.try_into().unwrap(), - }, - Message::ZoomIn => { - let zoom_in = |size: &mut NonZeroU16, min: u16, max: u16| { - let mut step = min; - while step <= max { - if size.get() < step { - *size = step.try_into().unwrap(); - break; - } - step += 25; - } - if size.get() > step { - *size = step.try_into().unwrap(); - } - }; - match self.config.view { - View::List => zoom_in(&mut self.config.icon_sizes.list, 50, 500), - View::Grid => zoom_in(&mut self.config.icon_sizes.grid, 50, 500), - } - } - Message::ZoomOut => { - let zoom_out = |size: &mut NonZeroU16, min: u16, max: u16| { - let mut step = max; - while step >= min { - if size.get() > step { - *size = step.try_into().unwrap(); - break; - } - step -= 25; - } - if size.get() < step { - *size = step.try_into().unwrap(); - } - }; - match self.config.view { - View::List => zoom_out(&mut self.config.icon_sizes.list, 50, 500), - View::Grid => zoom_out(&mut self.config.icon_sizes.grid, 50, 500), - } - } } // Update preview timer @@ -2572,8 +2527,8 @@ impl Tab { } }; let mut items: Vec<_> = self.items_opt.as_ref()?.iter().enumerate().collect(); - let heading_sort = self.config.sort_direction; - match self.config.sort_name { + let heading_sort = self.sort_direction; + match self.sort_name { HeadingOptions::Size => { items.sort_by(|a, b| { // entries take precedence over size @@ -2875,12 +2830,6 @@ impl Tab { .. } = theme::active().cosmic().spacing; - let TabConfig { - sort_name, - sort_direction, - .. - } = self.config; - let size = self.size_opt.get().unwrap_or(Size::new(0.0, 0.0)); let mut row = widget::row::with_capacity(5) @@ -2923,7 +2872,7 @@ impl Tab { .spacing(space_xxs) .width(width); row = row.push(widget::text::heading(name)); - match (sort_name == msg, sort_direction) { + match (self.sort_name == msg, self.sort_direction) { (true, true) => { row = row.push(widget::icon::from_name("pan-down-symbolic").size(16)); } @@ -3895,7 +3844,6 @@ impl Tab { mouse_area = mouse_area.on_right_press(Message::ContextMenu); } - let should_propogate_events = true; let mut popover = widget::popover(mouse_area); if let Some(point) = self.context_menu { @@ -3935,7 +3883,7 @@ impl Tab { } } } - Location::Network(uri, display_name) if uri == "network:///" => { + Location::Network(uri, _display_name) if uri == "network:///" => { tab_column = tab_column.push( widget::layer_container(widget::row::with_children(vec![ widget::horizontal_space(Length::Fill).into(), @@ -4090,6 +4038,7 @@ pub fn respond_to_scroll_direction(delta: ScrollDelta, modifiers: Modifiers) -> ScrollDelta::Pixels { y, .. } => y, }; + /*TODO if delta_y > 0.0 { return Some(Message::ZoomIn); } @@ -4097,6 +4046,7 @@ pub fn respond_to_scroll_direction(delta: ScrollDelta, modifiers: Modifiers) -> if delta_y < 0.0 { return Some(Message::ZoomOut); } + */ None } diff --git a/src/thumbnailer.rs b/src/thumbnailer.rs index 18a3bca..ac2df57 100644 --- a/src/thumbnailer.rs +++ b/src/thumbnailer.rs @@ -3,15 +3,7 @@ use mime_guess::Mime; use once_cell::sync::Lazy; -use std::{ - cmp::Ordering, - collections::HashMap, - env, fs, - path::{Path, PathBuf}, - process, - sync::Mutex, - time::Instant, -}; +use std::{collections::HashMap, fs, path::Path, process, sync::Mutex, time::Instant}; #[derive(Clone, Debug)] pub struct Thumbnailer { @@ -75,8 +67,6 @@ impl ThumbnailerCache { #[cfg(feature = "desktop")] pub fn reload(&mut self) { - use crate::localize::LANGUAGE_SORTER; - let start = Instant::now(); self.cache.clear();