/// <summary> /// Similar to AsPSObject(). /// </summary> internal static Meta AsMeta(object value) { Meta r = value as Meta; return(r == null ? new Meta(value) : r); }
public override void Open() { if (IsOpened) { return; } // make table if (Table == null) { if (Adapter == null) { if (string.IsNullOrEmpty(_XmlFile)) { throw new RuntimeException("Table, adapter, or file is not defined."); } // dataset var ds = new DataSet { Locale = CultureInfo.CurrentCulture // CA }; // read schema if (!string.IsNullOrEmpty(XmlSchema)) { ds.ReadXmlSchema(XmlSchema); } // read data ds.ReadXml(_XmlFile, XmlReadMode); _XmlFileTime = File.GetLastWriteTime(_XmlFile); // accept data ds.AcceptChanges(); // table Table = GetTable(ds, TableName); } else { if (Adapter.SelectCommand == null) { throw new RuntimeException("Adapter select command is null."); } Table = new DataTable { Locale = CultureInfo.CurrentCulture // CA }; } } // fill and drop the flag avoiding 2nd call on opening Fill(); NeedsNewFiles = false; // pass 1: collect the columns IList <Meta> metas; if (Columns == null) { // collect/filter table columns to be shown int Count = Math.Min(Table.Columns.Count, Settings.Default.MaximumPanelColumnCount); metas = new List <Meta>(Count); int nCollected = 0; foreach (DataColumn column in Table.Columns) { // skip hidden not calculated columns if (column.ColumnMapping == MappingType.Hidden && column.Expression.Length == 0) { continue; } // skip not linear data if (!Converter.IsLinearType(column.DataType)) { continue; } // infer column meta data Meta meta = new Meta(column.ColumnName) { Kind = FarColumn.DefaultColumnKinds[nCollected] }; metas.Add(meta); ++nCollected; if (nCollected >= Count) { break; } } } else { // setup user defined columns metas = Format.SetupColumns(Columns); } // at least one column if (metas.Count == 0) { throw new InvalidOperationException("There is no column to display."); } // pass 2: mapping foreach (Meta meta in metas) { DataColumn column = Table.Columns[meta.Property]; switch (meta.Kind[0]) { case 'N': Map.Name = column.Ordinal; break; case 'O': Map.Owner = column.Ordinal; break; case 'Z': Map.Description = column.Ordinal; break; case 'C': Map.Columns.Add(column.Ordinal); break; case 'S': { if (Map.Length >= 0) { throw new InvalidOperationException("Column 'S' is used twice."); } Map.Length = column.Ordinal; } break; case 'D': { if (meta.Kind.Length < 2) { throw new InvalidOperationException(Res.InvalidColumnKind + "D"); } switch (meta.Kind[1]) { case 'C': { if (Map.CreationTime >= 0) { throw new InvalidOperationException("Column 'DC' is used twice."); } Map.CreationTime = column.Ordinal; } break; case 'M': { if (Map.LastWriteTime >= 0) { throw new InvalidOperationException("Column 'DM' is used twice."); } Map.LastWriteTime = column.Ordinal; } break; case 'A': { if (Map.LastAccessTime >= 0) { throw new InvalidOperationException("Column 'DA' is used twice."); } Map.LastAccessTime = column.Ordinal; } break; default: throw new InvalidOperationException(Res.InvalidColumnKind + meta.Kind); } } break; default: throw new InvalidOperationException(Res.InvalidColumnKind + meta.Kind); } } // pass 3: set plan SetPlan(PanelViewMode.AlternativeFull, Format.SetupPanelMode(metas)); base.Open(); }
//! assume it is done for the active panel, it does not work well from the disk menu internal static Meta[] TryFormatByTableControl(PSObject value, int formatWidth) { // try to find a table TableControl table = A.FindTableControl(value.BaseObject.GetType().FullName, null); if (table == null) { return(null); } // convert all columns to meta Meta[] metas = new Meta[table.Rows[0].Columns.Count]; for (int i = metas.Length; --i >= 0;) { metas[i] = new Meta(table.Rows[0].Columns[i].DisplayEntry, table.Headers[i]); } // 1) set heuristic types, some columns are moved to the left SetBestTypes(metas, Settings.Default.MaximumPanelColumnCount); // 2) cut off too many columns metas = CutOffMetas(metas); // adjust formatting to the panel width int totalWidth = formatWidth - (metas.Length + 1); // N columns ~ N + 1 borders int setSum = 0; int setCount = 0; int setMaxValue = 0; int setMaxIndex = -1; for (int i = metas.Length; --i >= 0;) { int width = metas[i].Width; if (width > 0) { ++setCount; setSum += width; if (setMaxValue < width) { setMaxValue = width; setMaxIndex = i; } } } // fix too wide (less than 5 chars for unset columns), drop all positive widths if (setSum + (metas.Length - setCount) * 5 > totalWidth) { foreach (Meta meta in metas) { if (meta.Width > 0) { meta.Width = 0; } } } // fix too narrow (e.g. for Get-Service ~ 64), drop the maximum width else if (setCount == metas.Length && setSum < totalWidth) { metas[setMaxIndex].Width = 0; } return(metas); }
internal static void SetupMetas(Meta[] metas) { var availableColumnTypes = new List <string>(FarColumn.DefaultColumnKinds); // pass 1: pre-process specified default types, remove them from available int iCustom = 0; for (int iColumn = 0; iColumn < metas.Length; ++iColumn) { // meta data info Meta meta = metas[iColumn]; // skip not specified if (string.IsNullOrEmpty(meta.Kind)) { continue; } // pre-process only default types: N, Z, O, C switch (meta.Kind[0]) { case 'N': { if (!availableColumnTypes.Remove("N")) { throw new InvalidOperationException("Column 'N' is used twice."); } } break; case 'O': { if (!availableColumnTypes.Remove("O")) { throw new InvalidOperationException("Column 'O' is used twice."); } } break; case 'Z': { if (!availableColumnTypes.Remove("Z")) { throw new InvalidOperationException("Column 'Z' is used twice."); } } break; case 'C': { if (meta.Kind.Length < 2) { throw new InvalidOperationException(Res.InvalidColumnKind + "C"); } if (iCustom != (int)(meta.Kind[1] - '0')) { throw new InvalidOperationException(Res.InvalidColumnKind + meta.Kind + ". Expected: C" + iCustom); } availableColumnTypes.Remove(meta.Kind.Substring(0, 2)); ++iCustom; } break; } } // pass 2: set missed types from yet available int iAvailable = 0; foreach (Meta meta in metas) { if (string.IsNullOrEmpty(meta.Kind)) { if (iAvailable >= availableColumnTypes.Count) { throw new InvalidOperationException("Too many columns."); } meta.Kind = availableColumnTypes[iAvailable]; ++iAvailable; } } }
static bool SetBestType(Meta[] metas, int maximum, string type, params string[] patterns) { int iBestPattern = patterns.Length; int iBestMeta = -1; for (int iMeta = 0; iMeta < metas.Length; ++iMeta) { Meta meta = metas[iMeta]; if (meta.Kind != null) { continue; } bool done = false; string name = meta.Name; for (int iPattern = 0; iPattern < iBestPattern; ++iPattern) { string pattern = patterns[iPattern]; if (pattern[0] == '*') { if (name.EndsWith(patterns[iPattern].Substring(1), StringComparison.OrdinalIgnoreCase)) { iBestMeta = iMeta; iBestPattern = iPattern; } } else { if (string.Equals(name, patterns[iPattern], StringComparison.OrdinalIgnoreCase)) { iBestMeta = iMeta; if (iPattern == 0) { done = true; break; } iBestPattern = iPattern; } } } if (done) { break; } } // no candidates if (iBestMeta < 0) { return(false); } // set the column type metas[iBestMeta].Kind = type; // done for small column set if (metas.Length <= maximum) { return(true); } // move the best to the first free position int end = Math.Min(maximum, iBestMeta); for (int iFree = 0; iFree < end; ++iFree) { if (metas[iFree].Kind == null) { Meta meta = metas[iBestMeta]; for (int iMove = iBestMeta; iMove > iFree; --iMove) { metas[iMove] = metas[iMove - 1]; } metas[iFree] = meta; break; } } return(true); }