diff --git a/source/ChanSort.Loader.Hisense/ChannelDb/ChannelDbSerializer.cs b/source/ChanSort.Loader.Hisense/ChannelDb/ChannelDbSerializer.cs index 90e53c8..22b9873 100644 --- a/source/ChanSort.Loader.Hisense/ChannelDb/ChannelDbSerializer.cs +++ b/source/ChanSort.Loader.Hisense/ChannelDb/ChannelDbSerializer.cs @@ -114,7 +114,7 @@ namespace ChanSort.Loader.Hisense.ChannelDb { "OldPosition", "Position", - "Source", + //"Source", "NewProgramNr", "Name", "ShortName", diff --git a/source/ChanSort/Config.cs b/source/ChanSort/Config.cs index 3287bd9..825c509 100644 --- a/source/ChanSort/Config.cs +++ b/source/ChanSort/Config.cs @@ -12,6 +12,7 @@ namespace ChanSort.Ui private static readonly string ConfigFilePath; #region class ColumnInfo + public class ColumnInfo { [XmlAttribute("name")] public string Name { get; set; } @@ -23,11 +24,12 @@ namespace ChanSort.Ui get => this.Visible ?? true; set => this.Visible = value; } - + [XmlIgnore] public bool? Visible { get; set; } } + #endregion @@ -41,8 +43,8 @@ namespace ChanSort.Ui ConfigFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "ChanSort", "config.xml"); if (File.Exists(ConfigFilePath)) { - using (var stream = new StreamReader(ConfigFilePath, System.Text.Encoding.UTF8)) - Default = (Config)Serializer.Deserialize(stream); + using var stream = new StreamReader(ConfigFilePath, System.Text.Encoding.UTF8); + Default = (Config)Serializer.Deserialize(stream); return; } } @@ -78,9 +80,12 @@ namespace ChanSort.Ui //public string LeftGridLayout { get; set; } //public string RightGridLayout { get; set; } + [XmlArrayItem("Column")] public List LeftColumns { get; set; } = new(); + [XmlArrayItem("Column")] public List RightColumns { get; set; } = new(); public bool AutoHideColumns { get; set; } = true; + public bool LoadLastListAfterStart { get; set; } = true; /// /// The LeftGridLayout and RightGridLayout contain Width values which are scaled to this ScaleFactor. @@ -98,7 +103,7 @@ namespace ChanSort.Ui if (!allowSave) return; - var folder = Path.GetDirectoryName(ConfigFilePath); + var folder = Path.GetDirectoryName(ConfigFilePath) ?? "."; Directory.CreateDirectory(folder); using var stream = new FileStream(ConfigFilePath, FileMode.Create); diff --git a/source/ChanSort/MainForm.Designer.cs b/source/ChanSort/MainForm.Designer.cs index bc5a312..bbaf239 100644 --- a/source/ChanSort/MainForm.Designer.cs +++ b/source/ChanSort/MainForm.Designer.cs @@ -167,6 +167,7 @@ this.miTheme = new DevExpress.XtraBars.BarButtonItem(); this.miSplitView = new DevExpress.XtraBars.BarButtonItem(); this.miAutoHideColumns = new DevExpress.XtraBars.BarButtonItem(); + this.miLoadListAfterStart = new DevExpress.XtraBars.BarButtonItem(); this.miShowWarningsAfterLoad = new DevExpress.XtraBars.BarCheckItem(); this.miAllowEditPredefinedLists = new DevExpress.XtraBars.BarButtonItem(); this.miExplorerIntegration = new DevExpress.XtraBars.BarButtonItem(); @@ -359,7 +360,6 @@ this.gviewLeft.ShowingEditor += new System.ComponentModel.CancelEventHandler(this.gview_ShowingEditor); this.gviewLeft.ShownEditor += new System.EventHandler(this.gview_ShownEditor); this.gviewLeft.EndSorting += new System.EventHandler(this.gviewLeft_EndSorting); - this.gviewLeft.ColumnPositionChanged += new System.EventHandler(this.gviewLeft_ColumnPositionChanged); this.gviewLeft.FocusedRowChanged += new DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventHandler(this.gviewLeft_FocusedRowChanged); this.gviewLeft.CellValueChanged += new DevExpress.XtraGrid.Views.Base.CellValueChangedEventHandler(this.gviewLeft_CellValueChanged); this.gviewLeft.CustomUnboundColumnData += new DevExpress.XtraGrid.Views.Base.CustomColumnDataEventHandler(this.gview_CustomUnboundColumnData); @@ -713,7 +713,6 @@ this.gviewRight.SelectionChanged += new DevExpress.Data.SelectionChangedEventHandler(this.gviewRight_SelectionChanged); this.gviewRight.ShowingEditor += new System.ComponentModel.CancelEventHandler(this.gview_ShowingEditor); this.gviewRight.ShownEditor += new System.EventHandler(this.gview_ShownEditor); - this.gviewRight.ColumnPositionChanged += new System.EventHandler(this.gviewRight_ColumnPositionChanged); this.gviewRight.FocusedRowChanged += new DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventHandler(this.gviewRight_FocusedRowChanged); this.gviewRight.CellValueChanged += new DevExpress.XtraGrid.Views.Base.CellValueChangedEventHandler(this.gviewRight_CellValueChanged); this.gviewRight.CustomColumnSort += new DevExpress.XtraGrid.Views.Base.CustomColumnSortEventHandler(this.gviewRight_CustomColumnSort); @@ -1141,9 +1140,10 @@ this.miResetAndRestart, this.miSplitView, this.miTheme, - this.miAutoHideColumns}); + this.miAutoHideColumns, + this.miLoadListAfterStart}); this.barManager1.MainMenu = this.bar1; - this.barManager1.MaxItemId = 116; + this.barManager1.MaxItemId = 117; this.barManager1.ShowFullMenus = true; this.barManager1.ShortcutItemClick += new DevExpress.XtraBars.ShortcutItemClickEventHandler(this.barManager1_ShortcutItemClick); // @@ -1638,6 +1638,7 @@ new DevExpress.XtraBars.LinkPersistInfo(this.miTheme), new DevExpress.XtraBars.LinkPersistInfo(this.miSplitView), new DevExpress.XtraBars.LinkPersistInfo(this.miAutoHideColumns), + new DevExpress.XtraBars.LinkPersistInfo(this.miLoadListAfterStart), new DevExpress.XtraBars.LinkPersistInfo(this.miShowWarningsAfterLoad), new DevExpress.XtraBars.LinkPersistInfo(this.miAllowEditPredefinedLists), new DevExpress.XtraBars.LinkPersistInfo(this.miExplorerIntegration), @@ -1893,6 +1894,17 @@ this.miAutoHideColumns.Name = "miAutoHideColumns"; this.miAutoHideColumns.DownChanged += new DevExpress.XtraBars.ItemClickEventHandler(this.miAutoHideColumns_DownChanged); // + // miLoadListAfterStart + // + resources.ApplyResources(this.miLoadListAfterStart, "miLoadListAfterStart"); + this.miLoadListAfterStart.ButtonStyle = DevExpress.XtraBars.BarButtonStyle.Check; + this.miLoadListAfterStart.Down = true; + this.miLoadListAfterStart.Id = 116; + this.miLoadListAfterStart.ImageOptions.ImageIndex = ((int)(resources.GetObject("miLoadListAfterStart.ImageOptions.ImageIndex"))); + this.miLoadListAfterStart.ImageOptions.LargeImageIndex = ((int)(resources.GetObject("miLoadListAfterStart.ImageOptions.LargeImageIndex"))); + this.miLoadListAfterStart.ImageOptions.SvgImage = ((DevExpress.Utils.Svg.SvgImage)(resources.GetObject("miLoadListAfterStart.ImageOptions.SvgImage"))); + this.miLoadListAfterStart.Name = "miLoadListAfterStart"; + // // miShowWarningsAfterLoad // resources.ApplyResources(this.miShowWarningsAfterLoad, "miShowWarningsAfterLoad"); @@ -2710,6 +2722,7 @@ private DevExpress.XtraBars.BarButtonItem miTheme; private System.Windows.Forms.Timer timerSelectFocusedRow; private DevExpress.XtraBars.BarButtonItem miAutoHideColumns; + private DevExpress.XtraBars.BarButtonItem miLoadListAfterStart; } } diff --git a/source/ChanSort/MainForm.cs b/source/ChanSort/MainForm.cs index 7d19975..da3b8ac 100644 --- a/source/ChanSort/MainForm.cs +++ b/source/ChanSort/MainForm.cs @@ -37,8 +37,8 @@ namespace ChanSort.Ui public static string AppVersionFull { get; private set; } private const int MaxMruEntries = 10; - private readonly List isoEncodings = new List(); - private readonly List mruFiles = new List(); + private readonly List isoEncodings = new(); + private readonly List mruFiles = new(); private readonly string title; private EditMode curEditMode = EditMode.InsertAfter; @@ -53,10 +53,8 @@ namespace ChanSort.Ui private bool ignoreLanguageChange; private GridView lastFocusedGrid; private int subListIndex; - private SizeF absScaleFactor = new SizeF(1,1); + private SizeF absScaleFactor = new (1,1); private bool splitView = true; - private readonly List columnOrderLeft = new(); - private readonly List columnOrderRight = new(); private int ignoreEvents; #region ctor() @@ -69,7 +67,7 @@ namespace ChanSort.Ui InitializeComponent(); - this.DoubleBuffered = true; + base.DoubleBuffered = true; var version = this.GetType().Assembly.GetName().Version; AppVersion = new DateTime(2000, 1, 1).AddDays(version.Build).ToString("yyyy-MM-dd"); @@ -123,9 +121,6 @@ namespace ChanSort.Ui } ChannelList.DefaultVisibleColumns = defaultColumns; this.UpdateMenu(true); // disable menu items that depend on an open file - - this.SaveColumnOrder(this.gviewLeft, this.columnOrderLeft); - this.SaveColumnOrder(this.gviewRight, this.columnOrderRight); } #endregion @@ -151,7 +146,7 @@ namespace ChanSort.Ui lbl.Appearance.TextOptions.WordWrap = WordWrap.Wrap; lbl.Text = html; if (onUrlClick != null) - lbl.HyperlinkClick += (sender, args) => onUrlClick(args.Link); + lbl.HyperlinkClick += (_, args) => onUrlClick(args.Link); dlg.Controls.Add(lbl); var btn = new SimpleButton(); @@ -230,7 +225,7 @@ namespace ChanSort.Ui HandleException(new IOException("Plugin " + file + "\n" + ex.Message, ex)); } } - list.Sort((a, b) => a.PluginName.CompareTo(b.PluginName)); + list.Sort((a, b) => String.Compare(a.PluginName, b.PluginName, StringComparison.Ordinal)); return list; } @@ -714,7 +709,9 @@ namespace ChanSort.Ui private void ShowOpenReferenceFileDialog(bool addChannels) { - new ReferenceListForm(this).ShowDialog(this); + _ = addChannels; // param for future use + using var dlg = new ReferenceListForm(this); + dlg.ShowDialog(this); } #endregion @@ -726,9 +723,14 @@ namespace ChanSort.Ui this.CurrentChannelList = channelList; this.Editor.ChannelList = channelList; + this.gviewLeft.BeginUpdate(); + this.gviewRight.BeginUpdate(); + if (channelList != null) { - this.LoadInputGridLayout(); + this.UpdateColumnVisiblity(); + this.ClearRightFilter(); + this.gridRight.DataSource = channelList.Channels; this.gridLeft.DataSource = channelList.Channels; @@ -783,6 +785,9 @@ namespace ChanSort.Ui this.mnuFavList.Enabled = this.grpSubList.Visible; if (!this.grpSubList.Visible) this.tabSubList.SelectedTabPageIndex = 0; + + this.gviewLeft.EndUpdate(); + this.gviewRight.EndUpdate(); } #endregion @@ -1388,7 +1393,6 @@ namespace ChanSort.Ui #endregion #region LoadSettings() - private void LoadSettings() { // note: WindowSize must be restored in ctor in order to make WindowStartPosition.CenterScreen work @@ -1400,8 +1404,6 @@ namespace ChanSort.Ui this.splitContainerControl1.SplitterPosition = (int)(width * this.absScaleFactor.Width); // set unscaled value because the whole Form will be scaled later this.SelectLanguageMenuItem(); - //this.SetGridLayout(this.gviewLeft, Config.Default.OutputListLayout); - this.miShowWarningsAfterLoad.Checked = Config.Default.ShowWarningsAfterLoading; this.cbCloseGap.Checked = Config.Default.CloseGaps; this.ClearLeftFilter(); @@ -1422,110 +1424,15 @@ namespace ChanSort.Ui } } - //if (Config.Default.LeftGridLayout != null) - //{ - // this.gridLeft.ForceInitialize(); - // var xml = Config.Default.LeftGridLayout; - // this.gviewLeft.LoadLayoutFromXml(xml); - // if (Config.Default.ScaleFactor.Width != 0) - // { - // foreach (GridColumn col in this.gviewLeft.Columns) - // col.Width = (int) (col.Width / Config.Default.ScaleFactor.Width); - // } - //} - this.LoadGridLayout(this.gviewLeft, Config.Default.LeftColumns, this.columnOrderLeft); - this.LoadGridLayout(this.gviewRight, Config.Default.RightColumns, this.columnOrderRight); + // LoadSettings is called from MainForm_Shown. At this time automatic UI scaling is already done and we need to manually scale stored column widths + this.SetColumnWidths(this.gviewLeft, Config.Default.LeftColumns); + this.SetColumnWidths(this.gviewRight, Config.Default.RightColumns); + + this.gviewLeft.SetColumnOrder(Config.Default.LeftColumns.Select(c => c.Name), false); + this.gviewRight.SetColumnOrder(Config.Default.RightColumns.Select(c => c.Name), false); this.miAutoHideColumns.Down = Config.Default.AutoHideColumns; - - //if (Config.Default.RightGridLayout != null) - //{ - // this.gridRight.ForceInitialize(); - // var xml = Config.Default.RightGridLayout; - // this.gviewRight.LoadLayoutFromXml(xml); - // if (Config.Default.ScaleFactor.Width != 0) - // { - // foreach (GridColumn col in this.gviewRight.Columns) - // col.Width = (int) (col.Width / Config.Default.ScaleFactor.Width); - // } - //} - - this.miSplitView.Down = Config.Default.SplitView; // will change column visibility and must happen after restoring the grid layout - } - - private void SaveColumnOrder(GridView view, List columns) - { - // for this to work, the columns in absolute index order must represent the intended visible order - columns.AddRange(view.Columns.OrderBy(c => c.AbsoluteIndex)); - } - - private void LoadGridLayout(XGridView view, List configColumns, List list) - { - // must handle situations where new columns were added to the program, which are not included in the config - // These columns should be kept at their relative position in the default visible order - - - // build a dictionary with FieldName => "desired visible order" - var colsInConfig = new Dictionary(); - int visIndex = 0; - foreach (var info in configColumns) - { - if (view.Columns[info.Name] != null) - colsInConfig.Add(info.Name, visIndex++); - } - - ++this.ignoreEvents; - var oldList = new List(list); - var newList = new List(); - foreach (var info in configColumns) - { - var col = view.Columns[info.Name]; - - // ignore columns from config that don't exist in the program - if (col == null) - continue; - - col.Width = info.Width.Scale(this.absScaleFactor.Width); - - - // prepend columns that don't exist in the config and come before the current column in the default order - while (oldList.Count > 0) - { - var oldCol = oldList[0]; - if (oldCol == col) - break; - if (colsInConfig.ContainsKey(oldCol.FieldName)) - break; - newList.Add(oldCol); - oldList.Remove(oldCol); - } - - newList.Add(col); - oldList.Remove(col); - } - - newList.AddRange(oldList); - list.Clear(); - list.AddRange(newList); - --this.ignoreEvents; - } - - private void SaveGridLayout(List configColumns, List list) - { - var oldCfg = new Dictionary(); - foreach (var info in configColumns) - oldCfg[info.Name] = info; - - var setVisible = !this.miAutoHideColumns.Down; - - configColumns.Clear(); - foreach (var col in list) - { - var info = new Config.ColumnInfo(); - info.Name = col.FieldName; - info.Width = col.Width.Unscale(this.absScaleFactor.Width); - info.Visible = setVisible ? col.Visible : oldCfg.TryGetValue(col.FieldName, out var oldInfo) ? oldInfo.Visible : null; - configColumns.Add(info); - } + this.miSplitView.Down = Config.Default.SplitView; + this.miLoadListAfterStart.Down = Config.Default.LoadLastListAfterStart; } #endregion @@ -1629,15 +1536,16 @@ namespace ChanSort.Ui #endregion - #region LoadInputGridLayout() - - private void LoadInputGridLayout() + #region SetColumnWidths + private void SetColumnWidths(GridView view, List cols) { - this.ShowGridColumns(this.gviewLeft); - this.ShowGridColumns(this.gviewRight); - this.ClearRightFilter(); + foreach (var info in cols) + { + var col = view.Columns[info.Name]; + if (col != null) + col.Width = info.Width.Scale(this.absScaleFactor.Width); + } } - #endregion #region UpdateColumnVisibility() @@ -1646,17 +1554,12 @@ namespace ChanSort.Ui this.ShowGridColumns(this.gviewLeft); this.ShowGridColumns(this.gviewRight); } - #endregion #region ShowGridColumns() - private void ShowGridColumns(XGridView gview) { - //foreach (GridColumn col in gview.Columns) - // gview.SetColumnVisibility(col, GetGridColumnVisibility(col)); - - var list = gview == this.gviewLeft ? this.columnOrderLeft : this.columnOrderRight; + var list = gview.GetColumnOrder(); var visIndex = 0; ++this.ignoreEvents; foreach (var col in list) @@ -1665,11 +1568,9 @@ namespace ChanSort.Ui } --this.ignoreEvents; } - #endregion #region GetGridColumnVisibility() - private bool GetGridColumnVisibility(GridColumn col) { if (!this.miAutoHideColumns.Down) @@ -1736,7 +1637,6 @@ namespace ChanSort.Ui return true; } - #endregion #region SetFavorite() @@ -1815,7 +1715,6 @@ namespace ChanSort.Ui #endregion #region UpdateMenu - private void UpdateMenu(bool afterFileLoad = false) { var fileLoaded = this.DataRoot != null; @@ -1865,14 +1764,13 @@ namespace ChanSort.Ui this.miAddChannel.Enabled = mayEdit; // && isRight; - var visRight = isRight ? BarItemVisibility.Always : BarItemVisibility.Never; var visLeft = isRight ? BarItemVisibility.Never : BarItemVisibility.Always; this.miSort.Visibility = visLeft; this.miRenum.Visibility = visLeft; this.miMoveUp.Visibility = visLeft; this.miMoveDown.Visibility = visLeft; - //this.miAddChannel.Visibility = visRight; + this.miSkipOn.Enabled = this.miSkipOff.Enabled = this.currentTvSerializer?.Features.CanSkipChannels ?? false; this.miLockOn.Enabled = this.miLockOff.Enabled = this.currentTvSerializer?.Features.CanLockChannels ?? false; this.miHideOn.Enabled = this.miHideOff.Enabled = this.currentTvSerializer?.Features.CanHideChannels ?? false; @@ -2174,7 +2072,7 @@ namespace ChanSort.Ui var args = Environment.GetCommandLineArgs(); if (args.Length > 1) this.TryExecute(() => this.LoadFiles(null, args[args.Length - 1])); - else if (this.mruFiles.Count > 0) + else if (this.mruFiles.Count > 0 && Config.Default.LoadLastListAfterStart) this.TryExecute(() => this.LoadFiles(null, this.mruFiles[0])); } @@ -2236,7 +2134,7 @@ namespace ChanSort.Ui this.absScaleFactor = absScaleFactor.Scale(new SizeF(fact, fact)); this.SuspendRedraw(); this.bar1.Visible = false; - GlobalImageCollection.Scale((float)e.DeviceDpiNew / 96f, false); + GlobalImageCollection.Scale(e.DeviceDpiNew / 96f, false); this.bar1.Visible = true; base.OnDpiChanged(e); this.ResumeRedraw(); @@ -2889,41 +2787,6 @@ namespace ChanSort.Ui #endregion - #region gviewLeft_ColumnPositionChanged, gviewRight_ColumnPositionChanged - private void gviewLeft_ColumnPositionChanged(object sender, EventArgs e) - { - TryExecute(() => this.ColumnPositionChanged((GridColumn)sender, this.columnOrderLeft)); - } - - private void gviewRight_ColumnPositionChanged(object sender, EventArgs e) - { - TryExecute(() => this.ColumnPositionChanged((GridColumn)sender, this.columnOrderRight)); - } - - private void ColumnPositionChanged(GridColumn col, List list) - { - if (this.ignoreEvents > 0) - return; - - // columnOrderLeft and columnOrderRight are kept in desired column order including hidden columns - // when a column is moved to a new visible position, it is put behind all columns (including invisible ones) that have a lower position - - var visIdx = col.VisibleIndex; - if (visIdx < 0) - return; - - var listIdx = list.IndexOf(col); - list.RemoveAt(listIdx); - int i; - for (i = 0; i < list.Count; i++) - { - if (list[i].VisibleIndex >= 0 && list[i].VisibleIndex >= visIdx) - break; - } - list.Insert(i, col); - } - #endregion - #region rbInsertMode_CheckedChanged @@ -3080,8 +2943,8 @@ namespace ChanSort.Ui #endregion - #region SaveSettings(), GetGridLayout() + #region SaveSettings() private void SaveSettings() { this.gviewRight.PostEditor(); @@ -3099,16 +2962,39 @@ namespace ChanSort.Ui config.ExplorerIntegration = this.miExplorerIntegration.Down; config.CheckForUpdates = this.miCheckUpdates.Down; config.SplitView = this.miSplitView.Down; - this.SaveGridLayout(config.LeftColumns, this.columnOrderLeft); - this.SaveGridLayout(config.RightColumns, this.columnOrderRight); + + var updateVisible = !this.miAutoHideColumns.Down; + this.SaveGridLayout(config.LeftColumns, this.gviewLeft.GetColumnOrder(), updateVisible); + this.SaveGridLayout(config.RightColumns, this.gviewRight.GetColumnOrder(), updateVisible); config.AutoHideColumns = this.miAutoHideColumns.Down; config.ScaleFactor = this.absScaleFactor; + config.LoadLastListAfterStart = this.miLoadListAfterStart.Down; config.Save(); } #endregion + #region SaveGridLayout() + private void SaveGridLayout(List configColumns, List list, bool updateVisible) + { + var oldCfg = new Dictionary(); + foreach (var info in configColumns) + oldCfg[info.Name] = info; + + configColumns.Clear(); + foreach (var col in list) + { + var info = new Config.ColumnInfo(); + info.Name = col.FieldName; + info.Width = col.Width.Unscale(this.absScaleFactor.Width); + info.Visible = updateVisible ? col.Visible : oldCfg.TryGetValue(col.FieldName, out var oldInfo) ? oldInfo.Visible : null; + configColumns.Add(info); + } + } + #endregion + + #region ClearLeftFilter(), ClearRightFilter() private void ClearLeftFilter() @@ -3622,7 +3508,16 @@ namespace ChanSort.Ui #region miAutoHideColumns_DownChanged private void miAutoHideColumns_DownChanged(object sender, ItemClickEventArgs e) { - this.TryExecute(this.UpdateColumnVisiblity); + this.TryExecute(() => + { + // when switching from manual to auto-hide mode, store the manually configured column visibility + if (this.miAutoHideColumns.Down && this.ignoreEvents <= 0) + { + this.SaveGridLayout(Config.Default.LeftColumns, gviewLeft.GetColumnOrder(), true); + this.SaveGridLayout(Config.Default.RightColumns, gviewRight.GetColumnOrder(), true); + } + this.UpdateColumnVisiblity(); + }); } #endregion diff --git a/source/ChanSort/MainForm.de.resx b/source/ChanSort/MainForm.de.resx index 7635a7b..076f5f0 100644 --- a/source/ChanSort/MainForm.de.resx +++ b/source/ChanSort/MainForm.de.resx @@ -148,10 +148,16 @@ Center + + + None + + + Pr. Index @@ -714,6 +720,18 @@ + + Beim Start zuletzt geöffnete Liste laden + + + -1 + + + -1 + + + + Warnungen beim Laden anzeigen @@ -1095,6 +1113,15 @@ tauschen + + + + + + + + + Default @@ -1104,6 +1131,15 @@ dahinter + + + + + + + + + Default @@ -1113,6 +1149,15 @@ davor + + + + + + + + + Default @@ -1122,6 +1167,15 @@ Lücken beim Verschieben/Entfernen von Sendern schließen + + + + + + + + + Default @@ -1236,9 +1290,15 @@ Center + + + None + + + Pr. Index diff --git a/source/ChanSort/MainForm.resx b/source/ChanSort/MainForm.resx index e7ed353..9b5884b 100644 --- a/source/ChanSort/MainForm.resx +++ b/source/ChanSort/MainForm.resx @@ -168,6 +168,9 @@ DevExpress.XtraGrid.Columns.GridColumn, DevExpress.XtraGrid.v21.1, Version=21.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a + + Load last used list after start + @@ -359,7 +362,7 @@ ChanSort website... - ChanSort.XGridView, ChanSort, Version=1.0.7925.40855, Culture=neutral, PublicKeyToken=null + ChanSort.XGridView, ChanSort, Version=1.0.7926.932, Culture=neutral, PublicKeyToken=null Encrypted @@ -377,15 +380,14 @@ miSkipOff - - pnlEditControlRight + + DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.1, Version=21.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a Remove selected channels from sorted list English - @Invariant Right @@ -411,7 +413,6 @@ Magyar - @Invariant 182, 5 @@ -525,6 +526,9 @@ 1402, 0 + + + Sor&t channels alphabetically @@ -648,6 +652,9 @@ DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.1, Version=21.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a + + -1 + DevExpress.XtraEditors.SimpleButton, DevExpress.XtraEditors.v21.1, Version=21.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a @@ -789,7 +796,6 @@ XL - Segoe UI 11pt - @Invariant 23, 23 @@ -896,6 +902,9 @@ &Quit + + + 2, 23 @@ -1095,7 +1104,7 @@ colLogicalIndex - 09/12/2021 22:56:51 + 09/13/2021 01:36:15 437, 5 @@ -1148,6 +1157,9 @@ lblInsertMode + + + 23, 23 @@ -1162,7 +1174,6 @@ &Deutsch - @Invariant 15 @@ -1184,7 +1195,6 @@ ру́сский - @Invariant 23, 23 @@ -1237,6 +1247,9 @@ grpOutputList + + + DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.1, Version=21.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a @@ -1331,7 +1344,7 @@ 1 - ChanSort.XGridView, ChanSort, Version=1.0.7925.40855, Culture=neutral, PublicKeyToken=null + ChanSort.XGridView, ChanSort, Version=1.0.7926.932, Culture=neutral, PublicKeyToken=null DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.1, Version=21.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a @@ -1359,7 +1372,6 @@ Português - @Invariant btnRemoveRight @@ -1417,11 +1429,13 @@ Türkçe - @Invariant New program number + + + @@ -1479,6 +1493,9 @@ miFileInformation + + + @@ -1569,6 +1586,9 @@ PCR PID + + + 10 @@ -1709,6 +1729,9 @@ + + -1 + repositoryItemCheckedComboBoxEdit2 @@ -1736,6 +1759,9 @@ grpInputList + + + DevExpress.XtraBars.BarListItem, DevExpress.XtraBars.v21.1, Version=21.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a @@ -1748,6 +1774,9 @@ btnClearLeftFilter + + + 2 @@ -2076,9 +2105,6 @@ - - DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.1, Version=21.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a - 334, 5 @@ -2229,6 +2255,9 @@ True + + -1 + 6 @@ -2268,7 +2297,6 @@ UTF-16 Big Endian (Unicode MSB first) - @Invariant System.Windows.Forms.Timer, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -2344,7 +2372,6 @@ Polski - @Invariant 28 @@ -2362,7 +2389,7 @@ False - ChanSort.Ui.GlobalImageCollection, ChanSort, Version=1.0.7925.40855, Culture=neutral, PublicKeyToken=null + ChanSort.Ui.GlobalImageCollection, ChanSort, Version=1.0.7926.932, Culture=neutral, PublicKeyToken=null -1 @@ -2396,7 +2423,6 @@ L - Segoe UI 10pt - @Invariant DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.1, Version=21.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a @@ -2406,7 +2432,6 @@ Česky - @Invariant 0, 0 @@ -2432,6 +2457,9 @@ $this + + + mnuLanguage @@ -2474,14 +2502,17 @@ 7 + + pnlEditControlRight + colUid Select program/&favorite list - - -1 + + miLoadListAfterStart barSubItem2 @@ -2517,7 +2548,7 @@ -1 - ChanSort.XGridControl, ChanSort, Version=1.0.7925.40855, Culture=neutral, PublicKeyToken=null + ChanSort.XGridControl, ChanSort, Version=1.0.7926.932, Culture=neutral, PublicKeyToken=null repositoryItemTextEdit1 @@ -2538,7 +2569,7 @@ 8 - ChanSort.XGridControl, ChanSort, Version=1.0.7925.40855, Culture=neutral, PublicKeyToken=null + ChanSort.XGridControl, ChanSort, Version=1.0.7926.932, Culture=neutral, PublicKeyToken=null 1 @@ -2552,6 +2583,9 @@ -1 + + + DevExpress.XtraEditors.CheckEdit, DevExpress.XtraEditors.v21.1, Version=21.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a @@ -2612,7 +2646,6 @@ \d{1,4} - @Invariant Fill @@ -2736,7 +2769,6 @@ UTF-8 (Unicode) - @Invariant DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.1, Version=21.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a @@ -2771,6 +2803,9 @@ 55, 20 + + + DevExpress.XtraEditors.SimpleButton, DevExpress.XtraEditors.v21.1, Version=21.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a @@ -2942,6 +2977,9 @@ -1 + + + DevExpress.XtraGrid.Columns.GridColumn, DevExpress.XtraGrid.v21.1, Version=21.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a @@ -2984,6 +3022,9 @@ 48 + + + 47, 20 @@ -3161,8 +3202,8 @@ DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.1, Version=21.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a - - 0, 27 + + DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.1, Version=21.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a -1 @@ -3253,7 +3294,6 @@ UTF-16 Little Endian (Unicode LSB first) - @Invariant -1 @@ -3366,8 +3406,8 @@ - - grpInputList + + 0, 27 DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.1, Version=21.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a @@ -3401,7 +3441,6 @@ S - Tahoma 8pt - @Invariant miOpen @@ -3487,6 +3526,9 @@ DevExpress.XtraEditors.PanelControl, DevExpress.Utils.v21.1, Version=21.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a + + grpInputList + 8 @@ -3525,7 +3567,6 @@ XXL - Segoe UI 12pt - @Invariant 3 @@ -3575,6 +3616,9 @@ Crypt + + + ±H diff --git a/source/ChanSort/XGrid/XGridView.LayoutPersister.cs b/source/ChanSort/XGrid/XGridView.LayoutPersister.cs index 312ebc7..48b3c88 100644 --- a/source/ChanSort/XGrid/XGridView.LayoutPersister.cs +++ b/source/ChanSort/XGrid/XGridView.LayoutPersister.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Text; using System.Xml; +using System.Xml.Serialization; using ChanSort.Api; using DevExpress.Data; using DevExpress.XtraGrid.Columns; @@ -15,24 +16,157 @@ namespace ChanSort { public partial class XGridView { - public void StoreVisibleOrder() + private List columnOrder = new(); + private int ignoreEvents; + + private void StoreDefaultColumnOrder() { - // place invisible column based on the absolute order + // for this to work, the columns in absolute index order must represent the intended visible order this.columnOrder.Clear(); - int visIndex = 0; - var comparer = new DelegateComparer((a, b) => Tools.FirstNotDefault(a.VisibleIndex.CompareTo(b.VisibleIndex), a.AbsoluteIndex.CompareTo(b.AbsoluteIndex))); - var cleanVisList = this.Columns.Where(c => c.VisibleIndex >= 0).OrderBy(c => c, comparer).ToList(); - foreach (GridColumn col in this.Columns) - { - if (!col.Visible) - this.columnOrder.Add(col); - else - { - this.columnOrder.Add(cleanVisList[visIndex]); - visIndex++; - } - } + this.columnOrder.AddRange(this.Columns.OrderBy(c => c.AbsoluteIndex)); } + #region SetColumnOrder + public void SetColumnOrder(IEnumerable names, bool updateVisibleIndex = true) + { + // must handle situations where new columns were added to the program, which are not included in the config + // These columns should be kept at their relative position in the default visible order + + var fieldNames = names.ToList(); + + // build a dictionary with FieldName => "desired visible order" + var colsInConfig = new Dictionary(); + int visIndex = 0; + foreach (var name in fieldNames) + { + if (this.Columns[name] != null) + colsInConfig.Add(name, visIndex++); + } + + ++this.ignoreEvents; + var oldList = new List(this.columnOrder); + var newList = new List(); + foreach (var name in fieldNames) + { + var col = this.Columns[name]; + + // ignore columns from config that don't exist in the program + if (col == null) + continue; + + // prepend columns that don't exist in the config and come before the current column in the default order + while (oldList.Count > 0) + { + var oldCol = oldList[0]; + if (oldCol == col) + break; + if (colsInConfig.ContainsKey(oldCol.FieldName)) + break; + newList.Add(oldCol); + oldList.Remove(oldCol); + } + + newList.Add(col); + oldList.Remove(col); + } + + newList.AddRange(oldList); + this.columnOrder = newList; + + + if (updateVisibleIndex) + { + visIndex = 0; + foreach (var col in newList) + col.VisibleIndex = col.Visible ? visIndex++ : -1; + } + + --this.ignoreEvents; + } + #endregion + + public List GetColumnOrder() => this.columnOrder.ToList(); + + protected override void RaiseColumnPositionChanged(GridColumn column) + { + this.OnColumnPositionChanged(column); + base.RaiseColumnPositionChanged(column); + } + + private void OnColumnPositionChanged(GridColumn col) + { + // internal reordering should be ignored + if (this.ignoreEvents > 0) + return; + + // columnOrderLeft and columnOrderRight are kept in desired column order including hidden columns + // when a column is moved to a new visible position, it is put behind all columns (including invisible ones) that have a lower position + + var visIdx = col.VisibleIndex; + if (visIdx < 0) + return; + + var list = this.columnOrder; + var listIdx = list.IndexOf(col); + list.RemoveAt(listIdx); + int i; + for (i = 0; i < list.Count; i++) + { + if (list[i].VisibleIndex >= 0 && list[i].VisibleIndex >= visIdx) + break; + } + list.Insert(i, col); + } + + public void SetColumnVisibility(GridColumn column, bool visible) + { + if (column.Visible == visible) + return; + if (!visible) + { + column.Visible = false; + return; + } + + int idx = 0; + foreach (var col in this.columnOrder) + { + if (col == column) + { + col.VisibleIndex = idx; + return; + } + + if (col.Visible) + ++idx; + } + + // fallback + column.VisibleIndex = this.VisibleColumns.Count; + } + + //protected override void SetColumnVisibleIndex(GridColumn column, int newValue) + //{ + // int oldVisIndex = column.VisibleIndex; + // int newIdx = newValue > column.VisibleIndex ? newValue - 1 : newValue; + // base.SetColumnVisibleIndex(column, newValue); + + // if (newIdx < 0 || oldVisIndex == newIdx) + // { + // // hide or no change: keep as-is + // } + // else if (newIdx >= 0) + // { + // // move + // columnOrder.Remove(column); + // if (newIdx == 0) + // columnOrder.Insert(0, column); + // else + // { + // var afterCol = this.VisibleColumns[column.VisibleIndex - 1]; + // columnOrder.Insert(columnOrder.IndexOf(afterCol) + 1, column); + // } + // } + //} } } diff --git a/source/ChanSort/XGrid/XGridView.cs b/source/ChanSort/XGrid/XGridView.cs index f4476ea..7d6a1b8 100644 --- a/source/ChanSort/XGrid/XGridView.cs +++ b/source/ChanSort/XGrid/XGridView.cs @@ -1,13 +1,7 @@ using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.IO; -using System.Linq; using System.Windows.Forms; -using ChanSort.Api; using DevExpress.XtraEditors; using DevExpress.XtraGrid; -using DevExpress.XtraGrid.Columns; using DevExpress.XtraGrid.Registrator; using DevExpress.XtraGrid.Views.Base; using DevExpress.XtraGrid.Views.Base.Handler; @@ -20,7 +14,6 @@ namespace ChanSort { public partial class XGridView : GridView { - private readonly List columnOrder = new List(); protected override string ViewName => "XGridView"; #region ctor @@ -34,72 +27,9 @@ namespace ChanSort public override void EndInit() { base.EndInit(); - this.StoreVisibleOrder(); + this.StoreDefaultColumnOrder(); } - protected override void SetColumnVisibleIndex(GridColumn column, int newValue) - { - int oldVisIndex = column.VisibleIndex; - int newIdx = newValue > column.VisibleIndex ? newValue - 1 : newValue; - base.SetColumnVisibleIndex(column, newValue); - - if (newIdx < 0 || oldVisIndex == newIdx) - { - // hide or no change: keep as-is - } - else if (newIdx >= 0) - { - // move - columnOrder.Remove(column); - if (newIdx == 0) - columnOrder.Insert(0, column); - else - { - var afterCol = this.VisibleColumns[column.VisibleIndex - 1]; - columnOrder.Insert(columnOrder.IndexOf(afterCol) + 1, column); - } - } - } - - protected override void OnColumnDeleted(GridColumn column) - { - this.columnOrder.Remove(column); - base.OnColumnDeleted(column); - } - - protected override void OnColumnAdded(GridColumn column) - { - base.OnColumnAdded(column); - if (this.IsInitialized) - this.StoreVisibleOrder(); - } - - public void SetColumnVisibility(GridColumn column, bool visible) - { - if (column.Visible == visible) - return; - if (!visible) - { - column.Visible = false; - return; - } - - int idx = 0; - foreach (var col in this.columnOrder) - { - if (col == column) - { - col.VisibleIndex = idx; - return; - } - - if (col.Visible) - ++idx; - } - - // fallback - column.VisibleIndex = this.VisibleColumns.Count; - } internal new GridViewInfo ViewInfo => base.ViewInfo; diff --git a/source/Translation.xlsx b/source/Translation.xlsx index fb43f93..1e9ce4e 100644 Binary files a/source/Translation.xlsx and b/source/Translation.xlsx differ diff --git a/source/changelog.md b/source/changelog.md index cd71b09..1ae1d80 100644 --- a/source/changelog.md +++ b/source/changelog.md @@ -1,6 +1,13 @@ ChanSort Change Log =================== +2021-09-13 +- column order is now preserved between program starts even when lists with different supported columns + were loaded and columns reordered. +- added option to enabled/disable auto-loading of the last opened list when starting the program +- added UI option "Hide/unhide columns automatically". When turned off, the program will no longer hide columns + automatically based on the selected list. It is recommended to leave this setting turned on. + 2021-09-07 - added turkish readme - Reference lists can now also be applied to a particular favorites list as the target