Settings overhaul, part of #321
This commit is contained in:
parent
9a02c0f9f4
commit
60743ed251
33 changed files with 170 additions and 503 deletions
|
|
@ -70,15 +70,6 @@ properties = الخصائص
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = الإعدادات
|
settings = الإعدادات
|
||||||
settings-tab = لسان
|
|
||||||
settings-show-hidden = أظهر الملفّات والمجلدات المخفية
|
|
||||||
default-view = العرض المبدئي
|
|
||||||
icon-size-list = حجم الأيقونات (لائحة)
|
|
||||||
icon-size-grid = حجم الأيقونات (شبكة)
|
|
||||||
sorting-name = رتّب حسب
|
|
||||||
direction = الاتّجاه
|
|
||||||
ascending = تصاعديًا
|
|
||||||
descending = تنازليًا
|
|
||||||
|
|
||||||
### Appearance
|
### Appearance
|
||||||
appearance = المظهر
|
appearance = المظهر
|
||||||
|
|
|
||||||
|
|
@ -170,15 +170,6 @@ show-details = Паказаць дэталі
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = Налады
|
settings = Налады
|
||||||
settings-tab = Укладка
|
|
||||||
settings-show-hidden = Паказаць схаваныя файлы
|
|
||||||
default-view = Выгляд па змаўчанні
|
|
||||||
icon-size-list = Памер значка (спіс)
|
|
||||||
icon-size-grid = Памер значка (сетка)
|
|
||||||
sorting-name = Сартаваць
|
|
||||||
direction = Напрамак
|
|
||||||
ascending = Па ўзрастанні
|
|
||||||
descending = Па ўбыванні
|
|
||||||
|
|
||||||
### Appearance
|
### Appearance
|
||||||
appearance = Выгляд
|
appearance = Выгляд
|
||||||
|
|
|
||||||
|
|
@ -70,15 +70,6 @@ properties = Vlastnosti
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = Nastavení
|
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
|
||||||
appearance = Vzhled
|
appearance = Vzhled
|
||||||
|
|
|
||||||
|
|
@ -169,15 +169,6 @@ properties = Eigenschaften
|
||||||
|
|
||||||
## Einstellungen
|
## Einstellungen
|
||||||
settings = 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
|
### Aussehen
|
||||||
appearance = Aussehen
|
appearance = Aussehen
|
||||||
|
|
|
||||||
|
|
@ -169,15 +169,6 @@ show-details = Show details
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = 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 = Appearance
|
appearance = Appearance
|
||||||
|
|
|
||||||
|
|
@ -109,15 +109,6 @@ properties = Propiedades
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = Configuración
|
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
|
||||||
appearance = Apariencia
|
appearance = Apariencia
|
||||||
|
|
|
||||||
|
|
@ -70,15 +70,6 @@ properties = Propiedades
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = Configuración
|
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
|
||||||
appearance = Apariencia
|
appearance = Apariencia
|
||||||
|
|
|
||||||
|
|
@ -60,14 +60,6 @@ properties = Ominaisuudet
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = Asetukset
|
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
|
||||||
appearance = Ulkoasu
|
appearance = Ulkoasu
|
||||||
|
|
|
||||||
|
|
@ -169,15 +169,6 @@ show-details = Afficher les détails
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = Paramètres
|
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
|
||||||
appearance = Apparence
|
appearance = Apparence
|
||||||
|
|
|
||||||
|
|
@ -169,15 +169,6 @@ show-details = विवरण दिखाएँ
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = सेटिंग्स
|
settings = सेटिंग्स
|
||||||
settings-tab = टैब
|
|
||||||
settings-show-hidden = छिपी हुई फाइलें दिखाएँ
|
|
||||||
default-view = डिफ़ॉल्ट दृश्य
|
|
||||||
icon-size-list = आइकॉन आकार (सूची)
|
|
||||||
icon-size-grid = आइकॉन आकार (ग्रिड)
|
|
||||||
sorting-name = क्रमबद्ध द्वारा
|
|
||||||
direction = दिशा
|
|
||||||
ascending = आरोही
|
|
||||||
descending = अवरोही
|
|
||||||
|
|
||||||
### Appearance
|
### Appearance
|
||||||
appearance = रूप
|
appearance = रूप
|
||||||
|
|
|
||||||
|
|
@ -110,15 +110,6 @@ properties = Tulajdonságok
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = Beállítások
|
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
|
||||||
appearance = Kinézet
|
appearance = Kinézet
|
||||||
|
|
|
||||||
|
|
@ -170,15 +170,6 @@ show-details = Mostra dettagli
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = Impostazioni
|
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
|
||||||
appearance = Aspetto
|
appearance = Aspetto
|
||||||
|
|
|
||||||
|
|
@ -136,15 +136,6 @@ properties = プロパティ
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = 設定
|
settings = 設定
|
||||||
settings-tab = タブ
|
|
||||||
settings-show-hidden = 隠しファイルを表示
|
|
||||||
default-view = デフォルトの表示
|
|
||||||
icon-size-list = アイコンサイズ(リスト)
|
|
||||||
icon-size-grid = アイコンサイズ(グリッド)
|
|
||||||
sorting-name = 並べ替え
|
|
||||||
direction = 順
|
|
||||||
ascending = 昇順
|
|
||||||
descending = 降順
|
|
||||||
|
|
||||||
### Appearance
|
### Appearance
|
||||||
appearance = 外観
|
appearance = 外観
|
||||||
|
|
|
||||||
|
|
@ -169,15 +169,6 @@ show-details = ವಿವರಗಳನ್ನು ತೋರಿಸಿ
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = ಸೆಟ್ಟಿಂಗ್ಗಳು
|
settings = ಸೆಟ್ಟಿಂಗ್ಗಳು
|
||||||
settings-tab = ಟ್ಯಾಬ್
|
|
||||||
settings-show-hidden = ಮರೆಮಾಡಲಾದ ಫೈಲ್ಗಳನ್ನು ತೋರಿಸಿ
|
|
||||||
default-view = ಸ್ಥೂಲ ದೃಶ್ಯ
|
|
||||||
icon-size-list = ಐಕಾನ್ ಗಾತ್ರ (ಪಟ್ಟಿ)
|
|
||||||
icon-size-grid = ಐಕಾನ್ ಗಾತ್ರ (ಗ್ರೀಡ್)
|
|
||||||
sorting-name = ಇದರಿಂದ ಶ್ರೇಣೀಬದ್ಧಗೊಳಿಸಿ
|
|
||||||
direction = ದಿಕ್ಕು
|
|
||||||
ascending = ಆರೋಹಣ
|
|
||||||
descending = ಅವರೋಹಣ
|
|
||||||
|
|
||||||
### Appearance
|
### Appearance
|
||||||
appearance = ನೋಟ
|
appearance = ನೋಟ
|
||||||
|
|
|
||||||
|
|
@ -60,14 +60,6 @@ properties = 정보
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = 설정
|
settings = 설정
|
||||||
settings-tab = 탭
|
|
||||||
settings-show-hidden = 숨겨진 파일 표시
|
|
||||||
icon-size-list = 아이콘 크기 (목록)
|
|
||||||
icon-size-grid = 아이콘 크기 (그리드)
|
|
||||||
sorting-name = 정렬
|
|
||||||
direction = 경로
|
|
||||||
ascending = 오름차순
|
|
||||||
descending = 내림차순
|
|
||||||
|
|
||||||
### Appearance
|
### Appearance
|
||||||
appearance = 모양새
|
appearance = 모양새
|
||||||
|
|
|
||||||
|
|
@ -174,15 +174,6 @@ show-details = Pokaż szczegóły
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = Ustawienia
|
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
|
||||||
appearance = Wygląd
|
appearance = Wygląd
|
||||||
|
|
|
||||||
|
|
@ -169,15 +169,6 @@ show-details = Mostrar detalhes
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = Configurações
|
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
|
||||||
appearance = Aparência
|
appearance = Aparência
|
||||||
|
|
|
||||||
|
|
@ -130,15 +130,6 @@ show-details = Mostrar detalhes
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = Definições
|
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
|
||||||
appearance = Aparência
|
appearance = Aparência
|
||||||
|
|
|
||||||
|
|
@ -69,15 +69,6 @@ properties = Свойства
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = Параметры
|
settings = Параметры
|
||||||
settings-tab = Вкладка
|
|
||||||
settings-show-hidden = Показывать скрытые файлы
|
|
||||||
default-view = Вид по умолчанию
|
|
||||||
icon-size-list = Размер иконок (список)
|
|
||||||
icon-size-grid = Размер иконок (сетка)
|
|
||||||
sorting-name = Отсортировать
|
|
||||||
direction = Направление
|
|
||||||
ascending = По возрастанию
|
|
||||||
descending = По убыванию
|
|
||||||
|
|
||||||
### Appearance
|
### Appearance
|
||||||
appearance = Оформление
|
appearance = Оформление
|
||||||
|
|
|
||||||
|
|
@ -116,15 +116,6 @@ properties = Podrobnosti
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = Nastavenia
|
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
|
||||||
appearance = Vzhľad
|
appearance = Vzhľad
|
||||||
|
|
|
||||||
|
|
@ -31,15 +31,6 @@ properties = Egenskaper
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = Inställningar
|
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
|
||||||
appearance = Utseende
|
appearance = Utseende
|
||||||
|
|
|
||||||
|
|
@ -114,15 +114,6 @@ properties = Властивості
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = Налаштування
|
settings = Налаштування
|
||||||
settings-tab = Вкладки
|
|
||||||
settings-show-hidden = Показувати приховані файли
|
|
||||||
default-view = Типовий режим перегляду
|
|
||||||
icon-size-list = Розмір піктограм (для списку)
|
|
||||||
icon-size-grid = Розмір піктограм (для ґратки)
|
|
||||||
sorting-name = Сортувати за
|
|
||||||
direction = Напрям
|
|
||||||
ascending = Зростання
|
|
||||||
descending = Спадання
|
|
||||||
|
|
||||||
### Appearance
|
### Appearance
|
||||||
appearance = Зовнішній вигляд
|
appearance = Зовнішній вигляд
|
||||||
|
|
|
||||||
|
|
@ -111,15 +111,6 @@ show-details = 显示详情
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = 设置
|
settings = 设置
|
||||||
settings-tab = 标签页
|
|
||||||
settings-show-hidden = 显示隐藏文件
|
|
||||||
default-view = 默认视图
|
|
||||||
icon-size-list = 图标大小(列表)
|
|
||||||
icon-size-grid = 图标大小(网格)
|
|
||||||
sorting-name = 排序方式
|
|
||||||
direction = 方向
|
|
||||||
ascending = 升序
|
|
||||||
descending = 降序
|
|
||||||
|
|
||||||
### Appearance
|
### Appearance
|
||||||
appearance = 外观
|
appearance = 外观
|
||||||
|
|
|
||||||
|
|
@ -167,15 +167,6 @@ show-details = 顯示詳細資料
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = 設定
|
settings = 設定
|
||||||
settings-tab = 分頁
|
|
||||||
settings-show-hidden = 顯示隱藏檔案
|
|
||||||
default-view = 預設檢視
|
|
||||||
icon-size-list = 圖示大小(列表)
|
|
||||||
icon-size-grid = 圖示大小(網格)
|
|
||||||
sorting-name = 排序依據
|
|
||||||
direction = 排序方向
|
|
||||||
ascending = 升序
|
|
||||||
descending = 降序
|
|
||||||
|
|
||||||
### Appearance
|
### Appearance
|
||||||
appearance = 外觀
|
appearance = 外觀
|
||||||
|
|
|
||||||
304
src/app.rs
304
src/app.rs
|
|
@ -181,15 +181,9 @@ impl Action {
|
||||||
Action::TabNew => Message::TabNew,
|
Action::TabNew => Message::TabNew,
|
||||||
Action::TabNext => Message::TabNext,
|
Action::TabNext => Message::TabNext,
|
||||||
Action::TabPrev => Message::TabPrev,
|
Action::TabPrev => Message::TabPrev,
|
||||||
Action::TabViewGrid => {
|
Action::TabViewGrid => Message::TabView(entity_opt, tab::View::Grid),
|
||||||
Message::TabMessage(entity_opt, tab::Message::View(tab::View::Grid))
|
Action::TabViewList => Message::TabView(entity_opt, tab::View::List),
|
||||||
}
|
Action::ToggleFoldersFirst => Message::ToggleFoldersFirst,
|
||||||
Action::TabViewList => {
|
|
||||||
Message::TabMessage(entity_opt, tab::Message::View(tab::View::List))
|
|
||||||
}
|
|
||||||
Action::ToggleFoldersFirst => {
|
|
||||||
Message::TabMessage(entity_opt, tab::Message::ToggleFoldersFirst)
|
|
||||||
}
|
|
||||||
Action::ToggleShowHidden => {
|
Action::ToggleShowHidden => {
|
||||||
Message::TabMessage(entity_opt, tab::Message::ToggleShowHidden)
|
Message::TabMessage(entity_opt, tab::Message::ToggleShowHidden)
|
||||||
}
|
}
|
||||||
|
|
@ -198,9 +192,9 @@ impl Action {
|
||||||
}
|
}
|
||||||
Action::WindowClose => Message::WindowClose,
|
Action::WindowClose => Message::WindowClose,
|
||||||
Action::WindowNew => Message::WindowNew,
|
Action::WindowNew => Message::WindowNew,
|
||||||
Action::ZoomDefault => Message::TabMessage(entity_opt, tab::Message::ZoomDefault),
|
Action::ZoomDefault => Message::ZoomDefault(entity_opt),
|
||||||
Action::ZoomIn => Message::TabMessage(entity_opt, tab::Message::ZoomIn),
|
Action::ZoomIn => Message::ZoomIn(entity_opt),
|
||||||
Action::ZoomOut => Message::TabMessage(entity_opt, tab::Message::ZoomOut),
|
Action::ZoomOut => Message::ZoomOut(entity_opt),
|
||||||
Action::Recents => Message::Recents,
|
Action::Recents => Message::Recents,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -312,12 +306,17 @@ pub enum Message {
|
||||||
TabMessage(Option<Entity>, tab::Message),
|
TabMessage(Option<Entity>, tab::Message),
|
||||||
TabNew,
|
TabNew,
|
||||||
TabRescan(Entity, Location, Vec<tab::Item>, Option<PathBuf>),
|
TabRescan(Entity, Location, Vec<tab::Item>, Option<PathBuf>),
|
||||||
|
TabView(Option<Entity>, tab::View),
|
||||||
ToggleContextPage(ContextPage),
|
ToggleContextPage(ContextPage),
|
||||||
|
ToggleFoldersFirst,
|
||||||
Undo(usize),
|
Undo(usize),
|
||||||
UndoTrash(widget::ToastId, Arc<[PathBuf]>),
|
UndoTrash(widget::ToastId, Arc<[PathBuf]>),
|
||||||
UndoTrashStart(Vec<TrashItem>),
|
UndoTrashStart(Vec<TrashItem>),
|
||||||
WindowClose,
|
WindowClose,
|
||||||
WindowNew,
|
WindowNew,
|
||||||
|
ZoomDefault(Option<Entity>),
|
||||||
|
ZoomIn(Option<Entity>),
|
||||||
|
ZoomOut(Option<Entity>),
|
||||||
DndHoverLocTimeout(Location),
|
DndHoverLocTimeout(Location),
|
||||||
DndHoverTabTimeout(Entity),
|
DndHoverTabTimeout(Entity),
|
||||||
DndEnterNav(Entity),
|
DndEnterNav(Entity),
|
||||||
|
|
@ -459,9 +458,6 @@ pub struct App {
|
||||||
config: Config,
|
config: Config,
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
app_themes: Vec<String>,
|
app_themes: Vec<String>,
|
||||||
default_view: Vec<String>,
|
|
||||||
sort_by_names: Vec<String>,
|
|
||||||
sort_direction: Vec<String>,
|
|
||||||
context_page: ContextPage,
|
context_page: ContextPage,
|
||||||
dialog_pages: VecDeque<DialogPage>,
|
dialog_pages: VecDeque<DialogPage>,
|
||||||
dialog_text_input: widget::Id,
|
dialog_text_input: widget::Id,
|
||||||
|
|
@ -622,7 +618,20 @@ impl App {
|
||||||
|
|
||||||
fn update_config(&mut self) -> Command<Message> {
|
fn update_config(&mut self) -> Command<Message> {
|
||||||
self.update_nav_model();
|
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) {
|
fn activate_nav_model_location(&mut self, location: &Location) {
|
||||||
|
|
@ -924,7 +933,7 @@ impl App {
|
||||||
let progress_bar_height = Length::Fixed(4.0);
|
let progress_bar_height = Length::Fixed(4.0);
|
||||||
|
|
||||||
if !self.pending_operations.is_empty() {
|
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() {
|
for (_id, (op, progress)) in self.pending_operations.iter().rev() {
|
||||||
section = section.add(widget::column::with_children(vec![
|
section = section.add(widget::column::with_children(vec![
|
||||||
widget::text(op.pending_text()).into(),
|
widget::text(op.pending_text()).into(),
|
||||||
|
|
@ -937,7 +946,7 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.failed_operations.is_empty() {
|
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() {
|
for (_id, (op, error)) in self.failed_operations.iter().rev() {
|
||||||
section = section.add(widget::column::with_children(vec![
|
section = section.add(widget::column::with_children(vec![
|
||||||
widget::text(op.pending_text()).into(),
|
widget::text(op.pending_text()).into(),
|
||||||
|
|
@ -948,7 +957,7 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.complete_operations.is_empty() {
|
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() {
|
for (_id, op) in self.complete_operations.iter().rev() {
|
||||||
section = section.add(widget::text(op.completed_text()));
|
section = section.add(widget::text(op.completed_text()));
|
||||||
}
|
}
|
||||||
|
|
@ -1003,133 +1012,27 @@ impl App {
|
||||||
|
|
||||||
fn settings(&self) -> Element<Message> {
|
fn settings(&self) -> Element<Message> {
|
||||||
// TODO: Should dialog be updated here too?
|
// TODO: Should dialog be updated here too?
|
||||||
widget::settings::view_column(vec![
|
widget::settings::view_column(vec![widget::settings::section()
|
||||||
widget::settings::view_section(fl!("appearance"))
|
.title(fl!("appearance"))
|
||||||
.add({
|
.add({
|
||||||
let app_theme_selected = match self.config.app_theme {
|
let app_theme_selected = match self.config.app_theme {
|
||||||
AppTheme::Dark => 1,
|
AppTheme::Dark => 1,
|
||||||
AppTheme::Light => 2,
|
AppTheme::Light => 2,
|
||||||
AppTheme::System => 0,
|
AppTheme::System => 0,
|
||||||
};
|
};
|
||||||
widget::settings::item::builder(fl!("theme")).control(widget::dropdown(
|
widget::settings::item::builder(fl!("theme")).control(widget::dropdown(
|
||||||
&self.app_themes,
|
&self.app_themes,
|
||||||
Some(app_theme_selected),
|
Some(app_theme_selected),
|
||||||
move |index| {
|
move |index| {
|
||||||
Message::AppTheme(match index {
|
Message::AppTheme(match index {
|
||||||
1 => AppTheme::Dark,
|
1 => AppTheme::Dark,
|
||||||
2 => AppTheme::Light,
|
2 => AppTheme::Light,
|
||||||
_ => AppTheme::System,
|
_ => AppTheme::System,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.add({
|
.into()])
|
||||||
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(),
|
|
||||||
])
|
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1183,9 +1086,6 @@ impl Application for App {
|
||||||
config: flags.config,
|
config: flags.config,
|
||||||
mode: flags.mode,
|
mode: flags.mode,
|
||||||
app_themes,
|
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,
|
context_page: ContextPage::Settings,
|
||||||
dialog_pages: VecDeque::new(),
|
dialog_pages: VecDeque::new(),
|
||||||
dialog_text_input: widget::Id::unique(),
|
dialog_text_input: widget::Id::unique(),
|
||||||
|
|
@ -1506,8 +1406,8 @@ impl Application for App {
|
||||||
log::warn!("TODO: retry operation {}", id);
|
log::warn!("TODO: retry operation {}", id);
|
||||||
}
|
}
|
||||||
DialogPage::NetworkAuth {
|
DialogPage::NetworkAuth {
|
||||||
mounter_key,
|
mounter_key: _,
|
||||||
uri,
|
uri: _,
|
||||||
auth,
|
auth,
|
||||||
auth_tx,
|
auth_tx,
|
||||||
} => {
|
} => {
|
||||||
|
|
@ -1520,9 +1420,9 @@ impl Application for App {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
DialogPage::NetworkError {
|
DialogPage::NetworkError {
|
||||||
mounter_key,
|
mounter_key: _,
|
||||||
uri,
|
uri,
|
||||||
error,
|
error: _,
|
||||||
} => {
|
} => {
|
||||||
//TODO: re-use mounter_key?
|
//TODO: re-use mounter_key?
|
||||||
return Command::batch([
|
return Command::batch([
|
||||||
|
|
@ -2248,23 +2148,15 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
Message::TabConfig(config) => {
|
Message::TabConfig(config) => {
|
||||||
if config != self.config.tab {
|
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);
|
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) => {
|
Message::TabMessage(entity_opt, tab_message) => {
|
||||||
let entity = entity_opt.unwrap_or_else(|| self.tab_model.active());
|
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::<Tab>(entity) {
|
||||||
|
tab.config.view = view;
|
||||||
|
}
|
||||||
|
let mut config = self.config.tab;
|
||||||
|
config.view = view;
|
||||||
|
return self.update(Message::TabConfig(config));
|
||||||
|
}
|
||||||
Message::ToggleContextPage(context_page) => {
|
Message::ToggleContextPage(context_page) => {
|
||||||
//TODO: ensure context menus are closed
|
//TODO: ensure context menus are closed
|
||||||
if self.context_page == context_page {
|
if self.context_page == context_page {
|
||||||
|
|
@ -2439,8 +2340,8 @@ impl Application for App {
|
||||||
self.context_page = context_page;
|
self.context_page = context_page;
|
||||||
self.set_context_title(self.context_page.title());
|
self.set_context_title(self.context_page.title());
|
||||||
}
|
}
|
||||||
Message::Undo(id) => {
|
Message::Undo(_id) => {
|
||||||
// TODO;
|
// TODO: undo
|
||||||
}
|
}
|
||||||
Message::UndoTrash(id, recently_trashed) => {
|
Message::UndoTrash(id, recently_trashed) => {
|
||||||
self.toasts.remove(id);
|
self.toasts.remove(id);
|
||||||
|
|
@ -2497,6 +2398,65 @@ impl Application for App {
|
||||||
log::error!("failed to get current executable path: {}", err);
|
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::<Tab>(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::<Tab>(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::<Tab>(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) => {
|
Message::DndEnterNav(entity) => {
|
||||||
if let Some(location) = self.nav_model.data::<Location>(entity) {
|
if let Some(location) = self.nav_model.data::<Location>(entity) {
|
||||||
self.nav_dnd_hover = Some((location.clone(), Instant::now()));
|
self.nav_dnd_hover = Some((location.clone(), Instant::now()));
|
||||||
|
|
@ -3011,8 +2971,8 @@ impl Application for App {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
DialogPage::NetworkError {
|
DialogPage::NetworkError {
|
||||||
mounter_key,
|
mounter_key: _,
|
||||||
uri,
|
uri: _,
|
||||||
error,
|
error,
|
||||||
} => widget::dialog(fl!("network-drive-error"))
|
} => widget::dialog(fl!("network-drive-error"))
|
||||||
.body(error)
|
.body(error)
|
||||||
|
|
@ -3313,7 +3273,7 @@ impl Application for App {
|
||||||
content
|
content
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view_window(&self, id: WindowId) -> Element<Self::Message> {
|
fn view_window(&self, _id: WindowId) -> Element<Self::Message> {
|
||||||
//TODO: distinct views per window?
|
//TODO: distinct views per window?
|
||||||
self.view_main().map(|message| match message {
|
self.view_main().map(|message| match message {
|
||||||
app::Message::App(app) => app,
|
app::Message::App(app) => app,
|
||||||
|
|
|
||||||
|
|
@ -158,9 +158,6 @@ pub struct TabConfig {
|
||||||
pub folders_first: bool,
|
pub folders_first: bool,
|
||||||
/// Show hidden files and folders
|
/// Show hidden files and folders
|
||||||
pub show_hidden: bool,
|
pub show_hidden: bool,
|
||||||
/// Sorter
|
|
||||||
pub sort_name: HeadingOptions,
|
|
||||||
pub sort_direction: bool,
|
|
||||||
/// Icon zoom
|
/// Icon zoom
|
||||||
pub icon_sizes: IconSizes,
|
pub icon_sizes: IconSizes,
|
||||||
}
|
}
|
||||||
|
|
@ -171,8 +168,6 @@ impl Default for TabConfig {
|
||||||
view: View::List,
|
view: View::List,
|
||||||
folders_first: true,
|
folders_first: true,
|
||||||
show_hidden: false,
|
show_hidden: false,
|
||||||
sort_name: HeadingOptions::Name,
|
|
||||||
sort_direction: true,
|
|
||||||
icon_sizes: IconSizes::default(),
|
icon_sizes: IconSizes::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -698,12 +698,12 @@ impl Application for App {
|
||||||
let tab_config = TabConfig {
|
let tab_config = TabConfig {
|
||||||
view: tab::View::List,
|
view: tab::View::List,
|
||||||
folders_first: false,
|
folders_first: false,
|
||||||
sort_name: tab::HeadingOptions::Modified,
|
|
||||||
sort_direction: false,
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let mut tab = Tab::new(location, tab_config);
|
let mut tab = Tab::new(location, tab_config);
|
||||||
tab.mode = tab::Mode::Dialog(flags.kind.clone());
|
tab.mode = tab::Mode::Dialog(flags.kind.clone());
|
||||||
|
tab.sort_name = tab::HeadingOptions::Modified;
|
||||||
|
tab.sort_direction = false;
|
||||||
|
|
||||||
let mut app = App {
|
let mut app = App {
|
||||||
core,
|
core,
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
// Copyright 2023 System76 <info@system76.com>
|
// Copyright 2023 System76 <info@system76.com>
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use cosmic::{
|
use cosmic::{app::Settings, iced::Limits};
|
||||||
app::{Application, Settings},
|
|
||||||
iced::Limits,
|
|
||||||
};
|
|
||||||
use std::{env, fs, path::PathBuf, process};
|
use std::{env, fs, path::PathBuf, process};
|
||||||
|
|
||||||
use app::{App, Flags};
|
use app::{App, Flags};
|
||||||
|
|
|
||||||
14
src/menu.rs
14
src/menu.rs
|
|
@ -15,7 +15,6 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::{Action, Message},
|
app::{Action, Message},
|
||||||
config::TabConfig,
|
|
||||||
fl,
|
fl,
|
||||||
tab::{self, HeadingOptions, Location, LocationMenuAction, Tab},
|
tab::{self, HeadingOptions, Location, LocationMenuAction, Tab},
|
||||||
};
|
};
|
||||||
|
|
@ -58,17 +57,12 @@ pub fn context_menu<'a>(
|
||||||
.on_press(tab::Message::ContextAction(action))
|
.on_press(tab::Message::ContextAction(action))
|
||||||
};
|
};
|
||||||
|
|
||||||
let TabConfig {
|
|
||||||
sort_name,
|
|
||||||
sort_direction,
|
|
||||||
..
|
|
||||||
} = tab.config;
|
|
||||||
let sort_item = |label, variant| {
|
let sort_item = |label, variant| {
|
||||||
menu_item(
|
menu_item(
|
||||||
format!(
|
format!(
|
||||||
"{} {}",
|
"{} {}",
|
||||||
label,
|
label,
|
||||||
match (sort_name == variant, sort_direction) {
|
match (tab.sort_name == variant, tab.sort_direction) {
|
||||||
(true, true) => "\u{2B07}",
|
(true, true) => "\u{2B07}",
|
||||||
(true, false) => "\u{2B06}",
|
(true, false) => "\u{2B06}",
|
||||||
_ => "",
|
_ => "",
|
||||||
|
|
@ -273,7 +267,7 @@ pub fn dialog_menu<'a>(
|
||||||
let sort_item = |label, sort, dir| {
|
let sort_item = |label, sort, dir| {
|
||||||
menu::Item::CheckBox(
|
menu::Item::CheckBox(
|
||||||
label,
|
label,
|
||||||
tab.config.sort_name == sort && tab.config.sort_direction == dir,
|
tab.sort_name == sort && tab.sort_direction == dir,
|
||||||
Action::SetSort(sort, dir),
|
Action::SetSort(sort, dir),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
@ -303,7 +297,7 @@ pub fn dialog_menu<'a>(
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
menu::Tree::with_children(
|
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"
|
"view-sort-ascending-symbolic"
|
||||||
} else {
|
} else {
|
||||||
"view-sort-descending-symbolic"
|
"view-sort-descending-symbolic"
|
||||||
|
|
@ -361,7 +355,7 @@ pub fn menu_bar<'a>(
|
||||||
menu::Item::CheckBox(
|
menu::Item::CheckBox(
|
||||||
label,
|
label,
|
||||||
tab_opt.map_or(false, |tab| {
|
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),
|
Action::SetSort(sort, dir),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use cosmic::{
|
||||||
Modifiers,
|
Modifiers,
|
||||||
},
|
},
|
||||||
layout,
|
layout,
|
||||||
mouse::{self, click, Event as MouseEvent},
|
mouse::{self, click},
|
||||||
overlay,
|
overlay,
|
||||||
renderer::{self, Quad, Renderer as _},
|
renderer::{self, Quad, Renderer as _},
|
||||||
touch,
|
touch,
|
||||||
|
|
@ -614,13 +614,11 @@ fn update<Message: Clone>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 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) {
|
||||||
if let Some(message) = on_scroll(delta.clone(), state.modifiers) {
|
shell.publish(message);
|
||||||
shell.publish(message);
|
return event::Status::Captured;
|
||||||
return event::Status::Captured;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,7 @@ use std::{
|
||||||
fs,
|
fs,
|
||||||
io::{self, Read, Write},
|
io::{self, Read, Write},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::{
|
sync::Arc,
|
||||||
atomic::{self, AtomicU64},
|
|
||||||
Arc,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use tokio::sync::{mpsc, Mutex};
|
use tokio::sync::{mpsc, Mutex};
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
|
||||||
98
src/tab.rs
98
src/tab.rs
|
|
@ -9,7 +9,7 @@ use cosmic::{
|
||||||
clipboard::dnd::DndAction,
|
clipboard::dnd::DndAction,
|
||||||
event,
|
event,
|
||||||
futures::SinkExt,
|
futures::SinkExt,
|
||||||
keyboard::{self, Modifiers},
|
keyboard::Modifiers,
|
||||||
subscription::{self, Subscription},
|
subscription::{self, Subscription},
|
||||||
//TODO: export in cosmic::widget
|
//TODO: export in cosmic::widget
|
||||||
widget::{
|
widget::{
|
||||||
|
|
@ -39,7 +39,6 @@ use cosmic::{
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use mime_guess::{mime, Mime};
|
use mime_guess::{mime, Mime};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use recently_used_xbel::{Error, RecentlyUsed};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
|
|
@ -48,10 +47,8 @@ use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
fmt::{self, Display},
|
fmt::{self, Display},
|
||||||
fs::{self, Metadata},
|
fs::{self, Metadata},
|
||||||
num::NonZeroU16,
|
|
||||||
os::unix::fs::MetadataExt,
|
os::unix::fs::MetadataExt,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
process,
|
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
time::{Duration, Instant, SystemTime},
|
time::{Duration, Instant, SystemTime},
|
||||||
};
|
};
|
||||||
|
|
@ -548,7 +545,7 @@ pub fn scan_search(tab_path: &PathBuf, term: &str, sizes: IconSizes) -> Vec<Item
|
||||||
path.to_path_buf(),
|
path.to_path_buf(),
|
||||||
file_name.to_string(),
|
file_name.to_string(),
|
||||||
metadata,
|
metadata,
|
||||||
IconSizes::default(),
|
sizes,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -759,7 +756,7 @@ pub fn scan_recents(sizes: IconSizes) -> Vec<Item> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scan_network(uri: &str, mounters: Mounters, sizes: IconSizes) -> Vec<Item> {
|
pub fn scan_network(uri: &str, mounters: Mounters, sizes: IconSizes) -> Vec<Item> {
|
||||||
for (key, mounter) in mounters.iter() {
|
for (_key, mounter) in mounters.iter() {
|
||||||
match mounter.network_scan(uri, sizes) {
|
match mounter.network_scan(uri, sizes) {
|
||||||
Some(Ok(items)) => return items,
|
Some(Ok(items)) => return items,
|
||||||
Some(Err(err)) => {
|
Some(Err(err)) => {
|
||||||
|
|
@ -867,7 +864,6 @@ pub enum Message {
|
||||||
SelectAll,
|
SelectAll,
|
||||||
SetSort(HeadingOptions, bool),
|
SetSort(HeadingOptions, bool),
|
||||||
Thumbnail(PathBuf, ItemThumbnail),
|
Thumbnail(PathBuf, ItemThumbnail),
|
||||||
ToggleFoldersFirst,
|
|
||||||
ToggleShowHidden,
|
ToggleShowHidden,
|
||||||
View(View),
|
View(View),
|
||||||
ToggleSort(HeadingOptions),
|
ToggleSort(HeadingOptions),
|
||||||
|
|
@ -877,9 +873,6 @@ pub enum Message {
|
||||||
DndLeave(Location),
|
DndLeave(Location),
|
||||||
WindowDrag,
|
WindowDrag,
|
||||||
WindowToggleMaximize,
|
WindowToggleMaximize,
|
||||||
ZoomDefault,
|
|
||||||
ZoomIn,
|
|
||||||
ZoomOut,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
|
|
@ -1152,7 +1145,7 @@ impl Item {
|
||||||
);
|
);
|
||||||
|
|
||||||
if self.mime.type_() == mime::IMAGE {
|
if self.mime.type_() == mime::IMAGE {
|
||||||
if let Some(path) = self.path_opt() {
|
if let Some(_path) = self.path_opt() {
|
||||||
row = row.push(
|
row = row.push(
|
||||||
widget::button::icon(widget::icon::from_name("view-fullscreen-symbolic"))
|
widget::button::icon(widget::icon::from_name("view-fullscreen-symbolic"))
|
||||||
.on_press(app::Message::TabMessage(None, Message::Gallery(true))),
|
.on_press(app::Message::TabMessage(None, Message::Gallery(true))),
|
||||||
|
|
@ -1374,6 +1367,8 @@ pub struct Tab {
|
||||||
pub history_i: usize,
|
pub history_i: usize,
|
||||||
pub history: Vec<Location>,
|
pub history: Vec<Location>,
|
||||||
pub config: TabConfig,
|
pub config: TabConfig,
|
||||||
|
pub sort_name: HeadingOptions,
|
||||||
|
pub sort_direction: bool,
|
||||||
pub gallery: bool,
|
pub gallery: bool,
|
||||||
pub(crate) items_opt: Option<Vec<Item>>,
|
pub(crate) items_opt: Option<Vec<Item>>,
|
||||||
pub dnd_hovered: Option<(Location, Instant)>,
|
pub dnd_hovered: Option<(Location, Instant)>,
|
||||||
|
|
@ -1422,6 +1417,8 @@ impl Tab {
|
||||||
history_i: 0,
|
history_i: 0,
|
||||||
history,
|
history,
|
||||||
config,
|
config,
|
||||||
|
sort_name: HeadingOptions::Name,
|
||||||
|
sort_direction: true,
|
||||||
gallery: false,
|
gallery: false,
|
||||||
items_opt: None,
|
items_opt: None,
|
||||||
scrollable_id: widget::Id::unique(),
|
scrollable_id: widget::Id::unique(),
|
||||||
|
|
@ -1827,9 +1824,7 @@ impl Tab {
|
||||||
if let Some(range) = self.select_range {
|
if let Some(range) = self.select_range {
|
||||||
let min = range.0.min(range.1);
|
let min = range.0.min(range.1);
|
||||||
let max = range.0.max(range.1);
|
let max = range.0.max(range.1);
|
||||||
if self.config.sort_name == HeadingOptions::Name
|
if self.sort_name == HeadingOptions::Name && self.sort_direction {
|
||||||
&& self.config.sort_direction
|
|
||||||
{
|
|
||||||
// A default/unsorted tab's view is consistent with how the
|
// A default/unsorted tab's view is consistent with how the
|
||||||
// Items are laid out internally (items_opt), so Items can be
|
// Items are laid out internally (items_opt), so Items can be
|
||||||
// linearly selected
|
// linearly selected
|
||||||
|
|
@ -1936,7 +1931,10 @@ impl Tab {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::Config(config) => {
|
Message::Config(config) => {
|
||||||
|
// View is preserved for existing tabs
|
||||||
|
let view = self.config.view;
|
||||||
self.config = config;
|
self.config = config;
|
||||||
|
self.config.view = view;
|
||||||
}
|
}
|
||||||
Message::ContextAction(action) => {
|
Message::ContextAction(action) => {
|
||||||
// Close context menu
|
// Close context menu
|
||||||
|
|
@ -2348,8 +2346,8 @@ impl Tab {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::SetSort(heading_option, dir) => {
|
Message::SetSort(heading_option, dir) => {
|
||||||
self.config.sort_name = heading_option;
|
self.sort_name = heading_option;
|
||||||
self.config.sort_direction = dir;
|
self.sort_direction = dir;
|
||||||
}
|
}
|
||||||
Message::Thumbnail(path, thumbnail) => {
|
Message::Thumbnail(path, thumbnail) => {
|
||||||
if let Some(ref mut items) = self.items_opt {
|
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::ToggleShowHidden => self.config.show_hidden = !self.config.show_hidden,
|
||||||
|
|
||||||
Message::View(view) => {
|
Message::View(view) => {
|
||||||
self.config.view = view;
|
self.config.view = view;
|
||||||
}
|
}
|
||||||
Message::ToggleSort(heading_option) => {
|
Message::ToggleSort(heading_option) => {
|
||||||
let heading_sort = if self.config.sort_name == heading_option {
|
let heading_sort = if self.sort_name == heading_option {
|
||||||
!self.config.sort_direction
|
!self.sort_direction
|
||||||
} else {
|
} else {
|
||||||
// Default modified to descending, and others to ascending.
|
// Default modified to descending, and others to ascending.
|
||||||
heading_option != HeadingOptions::Modified
|
heading_option != HeadingOptions::Modified
|
||||||
};
|
};
|
||||||
self.config.sort_direction = heading_sort;
|
self.sort_direction = heading_sort;
|
||||||
self.config.sort_name = heading_option;
|
self.sort_name = heading_option;
|
||||||
}
|
}
|
||||||
Message::Drop(Some((to, mut from))) => {
|
Message::Drop(Some((to, mut from))) => {
|
||||||
self.dnd_hovered = None;
|
self.dnd_hovered = None;
|
||||||
|
|
@ -2460,48 +2457,6 @@ impl Tab {
|
||||||
Message::WindowToggleMaximize => {
|
Message::WindowToggleMaximize => {
|
||||||
commands.push(Command::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
|
// Update preview timer
|
||||||
|
|
@ -2572,8 +2527,8 @@ impl Tab {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let mut items: Vec<_> = self.items_opt.as_ref()?.iter().enumerate().collect();
|
let mut items: Vec<_> = self.items_opt.as_ref()?.iter().enumerate().collect();
|
||||||
let heading_sort = self.config.sort_direction;
|
let heading_sort = self.sort_direction;
|
||||||
match self.config.sort_name {
|
match self.sort_name {
|
||||||
HeadingOptions::Size => {
|
HeadingOptions::Size => {
|
||||||
items.sort_by(|a, b| {
|
items.sort_by(|a, b| {
|
||||||
// entries take precedence over size
|
// entries take precedence over size
|
||||||
|
|
@ -2875,12 +2830,6 @@ impl Tab {
|
||||||
..
|
..
|
||||||
} = theme::active().cosmic().spacing;
|
} = 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 size = self.size_opt.get().unwrap_or(Size::new(0.0, 0.0));
|
||||||
|
|
||||||
let mut row = widget::row::with_capacity(5)
|
let mut row = widget::row::with_capacity(5)
|
||||||
|
|
@ -2923,7 +2872,7 @@ impl Tab {
|
||||||
.spacing(space_xxs)
|
.spacing(space_xxs)
|
||||||
.width(width);
|
.width(width);
|
||||||
row = row.push(widget::text::heading(name));
|
row = row.push(widget::text::heading(name));
|
||||||
match (sort_name == msg, sort_direction) {
|
match (self.sort_name == msg, self.sort_direction) {
|
||||||
(true, true) => {
|
(true, true) => {
|
||||||
row = row.push(widget::icon::from_name("pan-down-symbolic").size(16));
|
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);
|
mouse_area = mouse_area.on_right_press(Message::ContextMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
let should_propogate_events = true;
|
|
||||||
let mut popover = widget::popover(mouse_area);
|
let mut popover = widget::popover(mouse_area);
|
||||||
|
|
||||||
if let Some(point) = self.context_menu {
|
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(
|
tab_column = tab_column.push(
|
||||||
widget::layer_container(widget::row::with_children(vec![
|
widget::layer_container(widget::row::with_children(vec![
|
||||||
widget::horizontal_space(Length::Fill).into(),
|
widget::horizontal_space(Length::Fill).into(),
|
||||||
|
|
@ -4090,6 +4038,7 @@ pub fn respond_to_scroll_direction(delta: ScrollDelta, modifiers: Modifiers) ->
|
||||||
ScrollDelta::Pixels { y, .. } => y,
|
ScrollDelta::Pixels { y, .. } => y,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*TODO
|
||||||
if delta_y > 0.0 {
|
if delta_y > 0.0 {
|
||||||
return Some(Message::ZoomIn);
|
return Some(Message::ZoomIn);
|
||||||
}
|
}
|
||||||
|
|
@ -4097,6 +4046,7 @@ pub fn respond_to_scroll_direction(delta: ScrollDelta, modifiers: Modifiers) ->
|
||||||
if delta_y < 0.0 {
|
if delta_y < 0.0 {
|
||||||
return Some(Message::ZoomOut);
|
return Some(Message::ZoomOut);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,7 @@
|
||||||
|
|
||||||
use mime_guess::Mime;
|
use mime_guess::Mime;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use std::{
|
use std::{collections::HashMap, fs, path::Path, process, sync::Mutex, time::Instant};
|
||||||
cmp::Ordering,
|
|
||||||
collections::HashMap,
|
|
||||||
env, fs,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
process,
|
|
||||||
sync::Mutex,
|
|
||||||
time::Instant,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Thumbnailer {
|
pub struct Thumbnailer {
|
||||||
|
|
@ -75,8 +67,6 @@ impl ThumbnailerCache {
|
||||||
|
|
||||||
#[cfg(feature = "desktop")]
|
#[cfg(feature = "desktop")]
|
||||||
pub fn reload(&mut self) {
|
pub fn reload(&mut self) {
|
||||||
use crate::localize::LANGUAGE_SORTER;
|
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
self.cache.clear();
|
self.cache.clear();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue