using SharedComponents; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace AppDiagnostic { public class LogAdapter { private ListView _listView; public string _filterText = string.Empty; private bool _isUserScrolling = false; // Indikátor, že používateľ manuálne scrolluje private bool _autoScrollEnabled = true; // Indikátor, že automatické scrollovanie je povolené private Timer _refreshTimer; private const int RefreshInterval = 1000; public LogAdapter(ListView listView) { _listView = listView; // Nastavenie ListView _listView.View = View.Details; _listView.Columns.Clear(); _listView.Columns.Add("Logs"); _listView.Scrollable = true; // Nastavenie šírky stĺpca na celú šírku ListView AdjustColumnWidth(); // Udalosť pre dynamickú zmenu veľkosti stĺpca pri zmene veľkosti ListView _listView.Resize += (sender, args) => AdjustColumnWidth(); // Pridanie udalosti pre manuálne skrolovanie _listView.MouseWheel += ListView_MouseWheel; // Inicializácia časovača na pravidelný refresh _refreshTimer = new Timer { Interval = RefreshInterval }; _refreshTimer.Tick += (sender, args) => RefreshListView(); _refreshTimer.Start(); } private void ListView_MouseWheel(object sender, MouseEventArgs e) { _isUserScrolling = true; // Ak sa manuálnym scrollovaním používateľ dostane na koniec, obnovíme automatické scrollovanie if (IsOnLastItem()) { _isUserScrolling = false; _autoScrollEnabled = true; } else { _autoScrollEnabled = false; } } public void RefreshListView() { //LiveLogCache.Instance.AddLog(string.Format("-------------------------------RunDeviceAfter()-------------------------------")); if (_listView.InvokeRequired) { _listView.Invoke(new Action(RefreshListView)); return; } _listView.BeginUpdate(); try { // Získanie pozície prvého viditeľného prvku pre stabilizáciu scrollovania int topIndexBeforeRefresh = _listView.TopItem?.Index ?? 0; // Pred pridaním nových položiek si pamätáme, či bol používateľ na poslednej položke bool wasOnLastItem = IsOnLastItem(); // Uchovanie aktuálne označených položiek (indexov) var selectedIndices = _listView.SelectedIndices.Cast().ToList(); // Načítanie logov var logs = LiveLogCache.Instance.GetLogs(0, LiveLogCache.Instance.GetCount()) .Where(log => string.IsNullOrEmpty(_filterText) || log.IndexOf(_filterText, StringComparison.OrdinalIgnoreCase) >= 0) .ToList(); // Vymazanie existujúcich položiek a pridanie nových _listView.Items.Clear(); foreach (var log in logs) { var item = new ListViewItem(log) { BackColor = _listView.Items.Count % 2 == 0 ? Color.White : Color.FromArgb(240, 240, 240) }; _listView.Items.Add(item); } // Obnovenie označených položiek foreach (var index in selectedIndices) { if (index < _listView.Items.Count) { _listView.Items[index].Selected = true; } } // Ak bol používateľ na poslednom prvku, nastavíme focus a scroll na posledný prvok if (_autoScrollEnabled && wasOnLastItem && _listView.Items.Count > 0) { var lastItemIndex = _listView.Items.Count - 1; _listView.EnsureVisible(lastItemIndex); _listView.Items[lastItemIndex].Focused = true; } else { // Ak používateľ nebol na spodku, vrátime sa na predchádzajúcu pozíciu scrollu if (topIndexBeforeRefresh < _listView.Items.Count) { _listView.TopItem = _listView.Items[topIndexBeforeRefresh]; } } } finally { _listView.EndUpdate(); } } public void ApplyFilter(string filterText) { _filterText = filterText?.Trim() ?? string.Empty; RefreshListView(); } private bool IsOnLastItem() { if (_listView.Items.Count == 0) return false; // Získame poslednú položku int lastItemIndex = _listView.Items.Count - 1; var lastItem = _listView.Items[lastItemIndex]; // Overíme, či je posledná položka úplne viditeľná return lastItem.Bounds.Bottom <= _listView.ClientRectangle.Bottom; } public void EnableAutoScroll() { _autoScrollEnabled = true; } public void DisableAutoScroll() { _autoScrollEnabled = false; } private void AdjustColumnWidth() { if (_listView.Columns.Count > 0) { _listView.Columns[0].Width = _listView.ClientSize.Width; } } } }