first
This commit is contained in:
235
DCIManager6/dci6-support-reader/misc.go
Normal file
235
DCIManager6/dci6-support-reader/misc.go
Normal file
@@ -0,0 +1,235 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/dialog"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
)
|
||||
|
||||
// Вспомогательные методы
|
||||
func (a *App) showError(title, message string) {
|
||||
dialog.ShowError(fmt.Errorf(message), a.window)
|
||||
a.statusLabel.SetText("❌ " + title)
|
||||
}
|
||||
|
||||
func (a *App) showSuccess(title, message string) {
|
||||
dialog.ShowInformation(title, message, a.window)
|
||||
}
|
||||
|
||||
func (a *App) detectMimeType() string {
|
||||
ext := strings.ToLower(filepath.Ext(a.fileName))
|
||||
|
||||
mimeTypes := map[string]string{
|
||||
".txt": "text/plain",
|
||||
".pdf": "application/pdf",
|
||||
".jpg": "image/jpeg",
|
||||
".jpeg": "image/jpeg",
|
||||
".png": "image/png",
|
||||
".zip": "application/zip",
|
||||
".doc": "application/msword",
|
||||
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
}
|
||||
|
||||
if mime, ok := mimeTypes[ext]; ok {
|
||||
return mime
|
||||
}
|
||||
return "application/octet-stream"
|
||||
}
|
||||
|
||||
// // Это делал DeepSeek оно криво, но работает. Оставлю это так, потому что всё равно планирую не использовать больше fyne
|
||||
type JournalEntryWidget struct {
|
||||
widget.BaseWidget
|
||||
event journalctlEntry
|
||||
label *widget.Label
|
||||
}
|
||||
|
||||
func NewJournalEntryWidget(event journalctlEntry) *JournalEntryWidget {
|
||||
j := &JournalEntryWidget{
|
||||
event: event,
|
||||
}
|
||||
j.ExtendBaseWidget(j)
|
||||
return j
|
||||
}
|
||||
|
||||
func (j *JournalEntryWidget) CreateRenderer() fyne.WidgetRenderer {
|
||||
j.label = widget.NewLabel(j.formatEventText())
|
||||
j.label.Wrapping = fyne.TextWrapBreak
|
||||
j.label.Selectable = true
|
||||
|
||||
return widget.NewSimpleRenderer(j.label)
|
||||
}
|
||||
|
||||
func (j *JournalEntryWidget) formatEventText() string {
|
||||
return fmt.Sprintf("%s :: %s :: %s :: %s :: %s",
|
||||
j.event.Timestamp, j.event.CommandLine, j.event.CommandName,
|
||||
j.event.SyslogIdentifier, j.event.Message)
|
||||
}
|
||||
|
||||
func (j *JournalEntryWidget) UpdateEvent(event journalctlEntry) {
|
||||
j.event = event
|
||||
if j.label != nil {
|
||||
j.label.SetText(j.formatEventText())
|
||||
}
|
||||
j.Refresh()
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
// func (a *App) isTextFile() bool {
|
||||
// ext := strings.ToLower(filepath.Ext(a.fileName))
|
||||
// textExts := []string{".txt", ".csv", ".json", ".xml", ".yaml", ".yml", ".md", ".go", ".py", ".js"}
|
||||
|
||||
// for _, textExt := range textExts {
|
||||
// if ext == textExt {
|
||||
// return true
|
||||
// }
|
||||
// }ц=
|
||||
|
||||
// // Проверяем содержимое (простейшая проверка)
|
||||
// if len(a.fileContent) == 0 {
|
||||
// return false
|
||||
// }
|
||||
|
||||
// // Если файл содержит null-байты, это скорее бинарный файл
|
||||
// for _, b := range a.fileContent {
|
||||
// if b == 0 {
|
||||
// return false
|
||||
// }
|
||||
// }
|
||||
|
||||
// return true
|
||||
// }
|
||||
|
||||
// type TextStats struct {
|
||||
// lines int
|
||||
// words int
|
||||
// chars int
|
||||
// bytes int
|
||||
// }
|
||||
|
||||
// func (a *App) calculateTextStats() TextStats {
|
||||
// if len(a.fileContent) == 0 {
|
||||
// return TextStats{}
|
||||
// }
|
||||
|
||||
// content := string(a.fileContent)
|
||||
// stats := TextStats{
|
||||
// bytes: len(a.fileContent),
|
||||
// chars: len(content),
|
||||
// lines: strings.Count(content, "\n") + 1,
|
||||
// words: len(strings.Fields(content)),
|
||||
// }
|
||||
|
||||
// return stats
|
||||
// }
|
||||
|
||||
// Это делал DeepSeek оно криво, но работает. Оставлю это так, потому что всё равно планирую не использовать больше fyne
|
||||
// Кастомный виджет для элемента списка с динамической высотой
|
||||
type JournalListItem struct {
|
||||
widget.BaseWidget
|
||||
event journalctlEntry
|
||||
label *widget.Label
|
||||
}
|
||||
|
||||
func NewJournalListItem(event journalctlEntry) *JournalListItem {
|
||||
j := &JournalListItem{
|
||||
event: event,
|
||||
}
|
||||
j.ExtendBaseWidget(j)
|
||||
return j
|
||||
}
|
||||
|
||||
func (j *JournalListItem) CreateRenderer() fyne.WidgetRenderer {
|
||||
j.label = widget.NewLabel(j.formatText())
|
||||
j.label.Wrapping = fyne.TextWrapBreak
|
||||
j.label.Selectable = true
|
||||
|
||||
return &journalListItemRenderer{
|
||||
item: j,
|
||||
label: j.label,
|
||||
}
|
||||
}
|
||||
|
||||
func (j *JournalListItem) formatText() string {
|
||||
return fmt.Sprintf("%s :: %s :: %s :: %s :: %s",
|
||||
j.event.Timestamp, j.event.CommandLine, j.event.CommandName,
|
||||
j.event.SyslogIdentifier, j.event.Message)
|
||||
}
|
||||
|
||||
func (j *JournalListItem) Update(event journalctlEntry) {
|
||||
j.event = event
|
||||
if j.label != nil {
|
||||
j.label.SetText(j.formatText())
|
||||
}
|
||||
j.Refresh()
|
||||
}
|
||||
|
||||
type journalListItemRenderer struct {
|
||||
item *JournalListItem
|
||||
label *widget.Label
|
||||
}
|
||||
|
||||
func (r *journalListItemRenderer) Layout(size fyne.Size) {
|
||||
// Рассчитываем высоту label на основе его содержимого
|
||||
minSize := r.label.MinSize()
|
||||
labelHeight := minSize.Height
|
||||
|
||||
// Если высота label больше 50, используем её, иначе минимальную
|
||||
height := labelHeight
|
||||
if height < 50 {
|
||||
height = 50
|
||||
}
|
||||
|
||||
r.label.Resize(fyne.NewSize(size.Width, height))
|
||||
r.label.Move(fyne.NewPos(0, 0))
|
||||
}
|
||||
|
||||
func (r *journalListItemRenderer) MinSize() fyne.Size {
|
||||
minSize := r.label.MinSize()
|
||||
if minSize.Height < 50 {
|
||||
minSize.Height = 50
|
||||
}
|
||||
return minSize
|
||||
}
|
||||
|
||||
func (r *journalListItemRenderer) Refresh() {
|
||||
r.label.Refresh()
|
||||
}
|
||||
|
||||
func (r *journalListItemRenderer) Objects() []fyne.CanvasObject {
|
||||
return []fyne.CanvasObject{r.label}
|
||||
}
|
||||
|
||||
func (r *journalListItemRenderer) Destroy() {}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
// Вспомогательные функции
|
||||
func formatFileSize(bytes int64) string {
|
||||
const unit = 1024
|
||||
if bytes < unit {
|
||||
return fmt.Sprintf("%d Б", bytes)
|
||||
}
|
||||
div, exp := int64(unit), 0
|
||||
for n := bytes / unit; n >= unit; n /= unit {
|
||||
div *= unit
|
||||
exp++
|
||||
}
|
||||
return fmt.Sprintf("%.1f %cБ", float64(bytes)/float64(div), "КМГТП"[exp])
|
||||
}
|
||||
Reference in New Issue
Block a user