diff --git a/src/LogExpert/Classes/PaintHelper.cs b/src/LogExpert/Classes/PaintHelper.cs index 232863a9..bb87f832 100644 --- a/src/LogExpert/Classes/PaintHelper.cs +++ b/src/LogExpert/Classes/PaintHelper.cs @@ -17,16 +17,13 @@ internal class PaintHelper private static readonly ILogger _logger = LogManager.GetCurrentClassLogger(); - private Color bookmarkColor = Color.FromArgb(165, 200, 225); + private Color _bookmarkColor = Color.FromArgb(165, 200, 225); #endregion #region Properties - private static Preferences Preferences - { - get { return ConfigManager.Settings.preferences; } - } + private static Preferences Preferences => ConfigManager.Settings.preferences; #endregion @@ -43,7 +40,7 @@ public static void CellPainting(ILogPaintContext logPaintCtx, DataGridView gridV ILogLine line = logPaintCtx.GetLogLine(rowIndex); if (line != null) { - HilightEntry entry = logPaintCtx.FindHilightEntry(line, true); + HilightEntry entry = logPaintCtx.FindHighlightEntry(line, true); e.Graphics.SetClip(e.CellBounds); if ((e.State & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected) { @@ -216,6 +213,7 @@ public static void AutoResizeColumns(DataGridView gridView) catch (NullReferenceException e) { // See https://connect.microsoft.com/VisualStudio/feedback/details/366943/autoresizecolumns-in-datagridview-throws-nullreferenceexception + // possible solution => https://stackoverflow.com/questions/36287553/nullreferenceexception-when-trying-to-set-datagridview-column-width-brings-th // There are some rare situations with null ref exceptions when resizing columns and on filter finished // So catch them here. Better than crashing. _logger.Error(e, "Error while resizing columns: "); @@ -289,36 +287,37 @@ public static Rectangle BorderWidths(DataGridViewAdvancedBorderStyle advancedBor #region Private Methods - private static void PaintCell(ILogPaintContext logPaintCtx, DataGridViewCellPaintingEventArgs e, - DataGridView gridView, bool noBackgroundFill, HilightEntry groundEntry) + private static void PaintCell(ILogPaintContext logPaintCtx, DataGridViewCellPaintingEventArgs e, DataGridView gridView, bool noBackgroundFill, HilightEntry groundEntry) { PaintHighlightedCell(logPaintCtx, e, gridView, noBackgroundFill, groundEntry); } - private static void PaintHighlightedCell(ILogPaintContext logPaintCtx, DataGridViewCellPaintingEventArgs e, - DataGridView gridView, bool noBackgroundFill, HilightEntry groundEntry) + private static void PaintHighlightedCell(ILogPaintContext logPaintCtx, DataGridViewCellPaintingEventArgs e, DataGridView gridView, bool noBackgroundFill, HilightEntry groundEntry) { - object value = e.Value != null ? e.Value : ""; - IList matchList = logPaintCtx.FindHilightMatches(value as ILogLine); + object value = e.Value ?? string.Empty; + + IList matchList = logPaintCtx.FindHighlightMatches(value as ILogLine); // too many entries per line seem to cause problems with the GDI while (matchList.Count > 50) { matchList.RemoveAt(50); } - HilightMatchEntry hme = new HilightMatchEntry(); - hme.StartPos = 0; - hme.Length = (value as string).Length; - hme.HilightEntry = new HilightEntry(value as string, - groundEntry != null ? groundEntry.ForegroundColor : Color.FromKnownColor(KnownColor.Black), - groundEntry != null ? groundEntry.BackgroundColor : Color.Empty, - false); - matchList = MergeHighlightMatchEntries(matchList, hme); + if (value is Column column) + { + if (string.IsNullOrEmpty(column.FullValue) == false) + { + HilightMatchEntry hme = new HilightMatchEntry(); + hme.StartPos = 0; + hme.Length = column.FullValue.Length; + hme.HilightEntry = new HilightEntry(column.FullValue, groundEntry?.ForegroundColor ?? Color.FromKnownColor(KnownColor.Black), groundEntry?.BackgroundColor ?? Color.Empty, false); + matchList = MergeHighlightMatchEntries(matchList, hme); + } + } int leftPad = e.CellStyle.Padding.Left; - RectangleF rect = new RectangleF(e.CellBounds.Left + leftPad, e.CellBounds.Top, e.CellBounds.Width, - e.CellBounds.Height); + RectangleF rect = new RectangleF(e.CellBounds.Left + leftPad, e.CellBounds.Top, e.CellBounds.Width, e.CellBounds.Height); Rectangle borderWidths = BorderWidths(e.AdvancedBorderStyle); Rectangle valBounds = e.CellBounds; valBounds.Offset(borderWidths.X, borderWidths.Y); @@ -339,14 +338,11 @@ private static void PaintHighlightedCell(ILogPaintContext logPaintCtx, DataGridV | TextFormatFlags.PreserveGraphicsClipping | TextFormatFlags.NoPadding | TextFormatFlags.VerticalCenter - | TextFormatFlags.TextBoxControl - ; + | TextFormatFlags.TextBoxControl; // | TextFormatFlags.VerticalCenter // | TextFormatFlags.TextBoxControl // TextFormatFlags.SingleLine - - //TextRenderer.DrawText(e.Graphics, e.Value as String, e.CellStyle.Font, valBounds, Color.FromKnownColor(KnownColor.Black), flags); Point wordPos = valBounds.Location; @@ -360,10 +356,20 @@ private static void PaintHighlightedCell(ILogPaintContext logPaintCtx, DataGridV Font font = matchEntry != null && matchEntry.HilightEntry.IsBold ? logPaintCtx.BoldFont : logPaintCtx.NormalFont; + Brush bgBrush = matchEntry.HilightEntry.BackgroundColor != Color.Empty ? new SolidBrush(matchEntry.HilightEntry.BackgroundColor) : null; - string matchWord = (value as string).Substring(matchEntry.StartPos, matchEntry.Length); + + string matchWord = string.Empty; + if (value is Column again) + { + if (string.IsNullOrEmpty(again.FullValue) == false) + { + matchWord = again.FullValue.Substring(matchEntry.StartPos, matchEntry.Length); + } + } + Size wordSize = TextRenderer.MeasureText(e.Graphics, matchWord, font, proposedSize, flags); wordSize.Height = e.CellBounds.Height; Rectangle wordRect = new Rectangle(wordPos, wordSize); @@ -383,14 +389,10 @@ private static void PaintHighlightedCell(ILogPaintContext logPaintCtx, DataGridV foreColor = Color.White; } } - TextRenderer.DrawText(e.Graphics, matchWord, font, wordRect, - foreColor, flags); + TextRenderer.DrawText(e.Graphics, matchWord, font, wordRect, foreColor, flags); wordPos.Offset(wordSize.Width, 0); - if (bgBrush != null) - { - bgBrush.Dispose(); - } + bgBrush?.Dispose(); } } @@ -404,8 +406,7 @@ private static void PaintHighlightedCell(ILogPaintContext logPaintCtx, DataGridV /// List of all highlight matches for the current cell /// The entry that is used as the default. /// List of HilightMatchEntry objects. The list spans over the whole cell and contains color infos for every substring. - private static IList MergeHighlightMatchEntries(IList matchList, - HilightMatchEntry groundEntry) + private static IList MergeHighlightMatchEntries(IList matchList, HilightMatchEntry groundEntry) { // Fill an area with lenth of whole text with a default hilight entry HilightEntry[] entryArray = new HilightEntry[groundEntry.Length]; @@ -425,10 +426,10 @@ private static IList MergeHighlightMatchEntries(IList= 0) + if (_reloadMemento.firstDisplayedLine < dataGridView.RowCount && _reloadMemento.firstDisplayedLine >= 0) { dataGridView.FirstDisplayedScrollingRowIndex = _reloadMemento.firstDisplayedLine; } @@ -656,7 +654,7 @@ private void UpdateGrid(LogEventArgs e) int currentLineNum = dataGridView.CurrentCellAddress.Y; dataGridView.RowCount = 0; dataGridView.RowCount = e.LineCount; - if (!_guiStateArgs.FollowTail) + if (_guiStateArgs.FollowTail == false) { if (currentLineNum >= dataGridView.RowCount) { @@ -672,6 +670,7 @@ private void UpdateGrid(LogEventArgs e) } _logger.Debug("UpdateGrid(): new RowCount={0}", dataGridView.RowCount); + if (e.IsRollover) { // Multifile rollover @@ -922,7 +921,7 @@ private void SetColumnizerInternal(ILogLineColumnizer columnizer) // Check if the filtered columns disappeared, if so must refresh the UI if (_filterParams.columnRestrict) { - string[] newColumns = columnizer != null ? columnizer.GetColumnNames() : new string[0]; + string[] newColumns = columnizer != null ? columnizer.GetColumnNames() : Array.Empty(); bool colChanged = false; if (dataGridView.ColumnCount - 2 == newColumns.Length) // two first columns are 'marker' and 'line number' @@ -950,6 +949,7 @@ private void SetColumnizerInternal(ILogLineColumnizer columnizer) Type oldColType = _filterParams.currentColumnizer?.GetType(); Type newColType = columnizer?.GetType(); + if (oldColType != newColType && _filterParams.columnRestrict && _filterParams.isFilterTail) { _filterParams.columnList.Clear(); @@ -1072,6 +1072,7 @@ private void AutoResizeColumns(DataGridView gridView) catch (NullReferenceException e) { // See https://connect.microsoft.com/VisualStudio/feedback/details/366943/autoresizecolumns-in-datagridview-throws-nullreferenceexception + // possible solution => https://stackoverflow.com/questions/36287553/nullreferenceexception-when-trying-to-set-datagridview-column-width-brings-th // There are some rare situations with null ref exceptions when resizing columns and on filter finished // So catch them here. Better than crashing. _logger.Error(e, "Error while resizing columns: "); @@ -1095,7 +1096,7 @@ private void PaintHighlightedCell(DataGridViewCellPaintingEventArgs e, DataGridV column = Column.EmptyColumn; } - IList matchList = FindHilightMatches(column); + IList matchList = FindHighlightMatches(column); // too many entries per line seem to cause problems with the GDI while (matchList.Count > 50) { @@ -1263,12 +1264,12 @@ private IList MergeHighlightMatchEntries(IList FindMatchingHilightEntries(ITextValue line) return resultList; } - private void GetHighlightEntryMatches(ITextValue line, IList hilightEntryList, - IList resultList) + private void GetHighlightEntryMatches(ITextValue line, IList hilightEntryList, IList resultList) { foreach (HilightEntry entry in hilightEntryList) { @@ -1499,7 +1499,7 @@ private void SyncTimestampDisplayWorker() { if (!IsMultiFile && dataGridView.SelectedRows.Count == 1) { - StatusLineText(""); + StatusLineText(string.Empty); } } } @@ -1521,7 +1521,7 @@ private void SyncFilterGridPos() } } - if (filterGridView.Rows.Count > 0) // exception no rows + if (filterGridView.Rows.GetRowCount(DataGridViewElementStates.None) > 0) // exception no rows { filterGridView.CurrentCell = filterGridView.Rows[index].Cells[0]; } @@ -1674,7 +1674,7 @@ private void SearchComplete(IAsyncResult result) return; } - dataGridView.Invoke(new SelectLineFx((line1, triggerSyncCall) => SelectLine(line1, triggerSyncCall, true)), new object[] { line, true }); + dataGridView.Invoke(new SelectLineFx((line1, triggerSyncCall) => SelectLine(line1, triggerSyncCall, true)), line, true); } catch (Exception ex) // in the case the windows is already destroyed { @@ -1706,15 +1706,15 @@ private void SelectLine(int line, bool triggerSyncCall, bool shouldScroll) if (line == -1) { - MessageBox.Show(this, "Not found:", - "Search result"); // Hmm... is that experimental code from early days? + // Hmm... is that experimental code from early days? + MessageBox.Show(this, "Not found:", "Search result"); return; } // Prevent ArgumentOutOfRangeException - else if (line >= dataGridView.Rows.Count) + if (line >= dataGridView.Rows.GetRowCount(DataGridViewElementStates.None)) { - line = dataGridView.Rows.Count - 1; + line = dataGridView.Rows.GetRowCount(DataGridViewElementStates.None) - 1; } dataGridView.Rows[line].Selected = true; @@ -2502,10 +2502,8 @@ private void AdjustMinimumGridWith() if (diff > 0) { diff -= dataGridView.RowHeadersWidth / 2; - dataGridView.Columns[dataGridView.Columns.Count - 1].Width = - dataGridView.Columns[dataGridView.Columns.Count - 1].Width + diff; - filterGridView.Columns[filterGridView.Columns.Count - 1].Width = - filterGridView.Columns[filterGridView.Columns.Count - 1].Width + diff; + dataGridView.Columns[dataGridView.Columns.GetColumnCount(DataGridViewElementStates.None) - 1].Width += diff; + filterGridView.Columns[filterGridView.Columns.GetColumnCount(DataGridViewElementStates.None) - 1].Width += diff; } } } @@ -2893,18 +2891,18 @@ private void SetExplicitEncoding(Encoding encoding) private void ApplyDataGridViewPrefs(DataGridView dataGridView, Preferences prefs) { - if (dataGridView.Columns.Count > 1) + if (dataGridView.Columns.GetColumnCount(DataGridViewElementStates.None) > 1) { if (prefs.setLastColumnWidth) { - dataGridView.Columns[dataGridView.Columns.Count - 1].MinimumWidth = prefs.lastColumnWidth; + dataGridView.Columns[dataGridView.Columns.GetColumnCount(DataGridViewElementStates.None) - 1].MinimumWidth = prefs.lastColumnWidth; } else { // Workaround for a .NET bug which brings the DataGridView into an unstable state (causing lots of NullReferenceExceptions). dataGridView.FirstDisplayedScrollingColumnIndex = 0; - dataGridView.Columns[dataGridView.Columns.Count - 1].MinimumWidth = 5; // default + dataGridView.Columns[dataGridView.Columns.GetColumnCount(DataGridViewElementStates.None) - 1].MinimumWidth = 5; // default } } @@ -2938,9 +2936,9 @@ private IList GetSelectedContent() return new List(); } - /* ======================================================================== - * Timestamp stuff - * =======================================================================*/ + /* ======================================================================== + * Timestamp stuff + * =======================================================================*/ private void SetTimestampLimits() { @@ -2990,7 +2988,7 @@ private string CalculateColumnNames(FilterParams filter) { foreach (int colIndex in filter.columnList) { - if (colIndex < dataGridView.Columns.Count - 2) + if (colIndex < dataGridView.Columns.GetColumnCount(DataGridViewElementStates.None) - 2) { if (names.Length > 0) { @@ -3429,7 +3427,7 @@ private void ChangeRowHeight(bool decrease) else { RowHeightEntry entry = _rowHeightList[rowNum]; - entry.Height = entry.Height - _lineHeight; + entry.Height -= _lineHeight; if (entry.Height <= _lineHeight) { _rowHeightList.Remove(rowNum); @@ -3451,7 +3449,7 @@ private void ChangeRowHeight(bool decrease) entry = _rowHeightList[rowNum]; } - entry.Height = entry.Height + _lineHeight; + entry.Height += _lineHeight; } dataGridView.UpdateRowHeightInfo(rowNum, false); @@ -3507,7 +3505,7 @@ private void AddBookmarkComment(string text) bookmark = _bookmarkProvider.GetBookmarkForLine(lineNum); } - bookmark.Text = bookmark.Text + text; + bookmark.Text += text; dataGridView.Refresh(); filterGridView.Refresh(); OnBookmarkTextChanged(bookmark); @@ -3709,8 +3707,7 @@ private void SelectColumn() int currentLine = dataGridView.CurrentCellAddress.Y; if (currentLine >= 0) { - dataGridView.CurrentCell = - dataGridView.Rows[dataGridView.CurrentCellAddress.Y].Cells[col.Index]; + dataGridView.CurrentCell = dataGridView.Rows[dataGridView.CurrentCellAddress.Y].Cells[col.Index]; } } } diff --git a/src/LogExpert/Controls/LogWindow/LogWindowsPublic.cs b/src/LogExpert/Controls/LogWindow/LogWindowsPublic.cs index 30d9a64a..25a274e1 100644 --- a/src/LogExpert/Controls/LogWindow/LogWindowsPublic.cs +++ b/src/LogExpert/Controls/LogWindow/LogWindowsPublic.cs @@ -96,6 +96,7 @@ public void LoadFile(string fileName, EncodingOptions encodingOptions) _logFileReader.IsXmlMode = true; _logFileReader.XmlLogConfig = xmlColumnizer.GetXmlLogConfiguration(); } + if (_forcedColumnizerForLoading != null) { CurrentColumnizer = _forcedColumnizerForLoading; @@ -492,7 +493,7 @@ public void dataGridView_CellPainting(object sender, DataGridViewCellPaintingEve /// /// /// - public HilightEntry FindHilightEntry(ITextValue line, bool noWordMatches) + public HilightEntry FindHighlightEntry(ITextValue line, bool noWordMatches) { // first check the temp entries lock (_tempHighlightEntryListLock) @@ -527,7 +528,7 @@ public HilightEntry FindHilightEntry(ITextValue line, bool noWordMatches) } } - public IList FindHilightMatches(ITextValue column) + public IList FindHighlightMatches(ITextValue column) { IList resultList = new List(); if (column != null) @@ -604,7 +605,7 @@ public void StartSearch() _progressEventArgs.Visible = true; SendProgressBarUpdate(); - SearchFx searchFx = new SearchFx(Search); + SearchFx searchFx = Search; searchFx.BeginInvoke(searchParams, SearchComplete, null); RemoveAllSearchHighlightEntries(); @@ -818,7 +819,7 @@ public void AddBookmarkOverlays() _logger.Debug("AddBookmarkOverlay() r.Location={0}, width={1}, scroll_offset={2}", r.Location.X, r.Width, dataGridView.HorizontalScrollingOffset); } overlay.Position = r.Location - new Size(dataGridView.HorizontalScrollingOffset, 0); - overlay.Position = overlay.Position + new Size(10, r.Height / 2); + overlay.Position += new Size(10, r.Height / 2); dataGridView.AddOverlay(overlay); } } @@ -1108,12 +1109,14 @@ public void SetCellSelectionMode(bool isCellMode) { if (isCellMode) { + //possible performance issue, see => https://docs.microsoft.com/en-us/dotnet/desktop/winforms/controls/best-practices-for-scaling-the-windows-forms-datagridview-control?view=netframeworkdesktop-4.8#using-the-selected-cells-rows-and-columns-collections-efficiently dataGridView.SelectionMode = DataGridViewSelectionMode.CellSelect; } else { dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect; } + _guiStateArgs.CellSelectMode = isCellMode; } diff --git a/src/LogExpert/Dialogs/BookmarkWindow.cs b/src/LogExpert/Dialogs/BookmarkWindow.cs index 36f5c65e..e33a5aca 100644 --- a/src/LogExpert/Dialogs/BookmarkWindow.cs +++ b/src/LogExpert/Dialogs/BookmarkWindow.cs @@ -121,7 +121,7 @@ public void SelectBookmark(int lineNum) { if (bookmarkData.IsBookmarkAtLine(lineNum)) { - if (bookmarkDataGridView.Rows.Count < bookmarkData.Bookmarks.Count) + if (bookmarkDataGridView.Rows.GetRowCount(DataGridViewElementStates.None) < bookmarkData.Bookmarks.Count) { // just for the case... There was an exception but I cannot find the cause UpdateView(); diff --git a/src/LogExpert/Interface/ILogPaintContext.cs b/src/LogExpert/Interface/ILogPaintContext.cs index d793b4af..367d4ff1 100644 --- a/src/LogExpert/Interface/ILogPaintContext.cs +++ b/src/LogExpert/Interface/ILogPaintContext.cs @@ -27,9 +27,9 @@ public interface ILogPaintContext Bookmark GetBookmarkForLine(int lineNum); - HilightEntry FindHilightEntry(ITextValue line, bool noWordMatches); + HilightEntry FindHighlightEntry(ITextValue line, bool noWordMatches); - IList FindHilightMatches(ITextValue line); + IList FindHighlightMatches(ITextValue line); #endregion }