/// <summary> /// cTor[2]. /// </summary> /// <param name="id"></param> /// <param name="cells"></param> /// <param name="brush"></param> /// <param name="grid"></param> /// <remarks>Used by <c><see cref="Clone()">Clone()</see></c>.</remarks> internal Row(int id, Cell[] cells, Brush brush, YataGrid grid) { _id = id; Length = (_cells = cells).Length; _brush = brush; _grid = grid; }
/// <summary> /// Imports the current contents of the Windows clipboard to /// <c><see cref="_copyr"/></c> and enables /// <c><see cref="it_PasteRange"/></c> and /// <c><see cref="it_ClipExport"/></c>. /// </summary> /// <param name="sender"><c><see cref="it_ClipImport"/></c></param> /// <param name="e"></param> void clipclick_ImportCopy(object sender, EventArgs e) { _copyr.Clear(); string clip = ClipboardService.GetText(); if (clip.Length != 0) { string[] lines = clip.Split(new[] { Environment.NewLine }, StringSplitOptions.None); string line; for (int i = 0; i != lines.Length; ++i) { if ((line = lines[i].Trim()).Length != 0) { string[] fields = YataGrid.ParseTableRow(line); _copyr.Add(fields); } } if (_fclip != null) { _fclip.SetRowsBufferText(); } it_PasteRange.Enabled = Table != null && !Table.Readonly; it_ClipExport.Enabled = true; } }
/// <summary> /// Disallows any/all TabFastedit keystrokes - typically <c>[Up]</c>, /// <c>[Down]</c>, <c>[PageUp]</c>, and <c>[PageDown]</c> - for textbox /// navigation on this <c>YataEditbox</c>. /// </summary> /// <param name="keyData"></param> /// <returns></returns> /// <remarks><c>[Up]</c>, <c>[Down]</c>, <c>[PageUp]</c>, and /// <c>[PageDown]</c> shall be used for TabFastedit by /// <c><see cref="YataGrid._editor">YataGrid._editor</see></c> and/or /// <c><see cref="Propanel._editor">Propanel._editor</see></c>.</remarks> /// <remarks>TAB, RETURN, ESC, and the UP ARROW, DOWN ARROW, LEFT ARROW, /// and RIGHT ARROW. kL_note: Also PageUp/Down what else you gnits.</remarks> protected override bool IsInputKey(Keys keyData) { #if Keys if ((keyData & ~gc.ControlShift) != 0) { logfile.Log("YataEditbox.IsInputKey() keyData= " + keyData); } #endif if (YataGrid.IsTabfasteditKey(keyData)) { // return FALSE to disable use of these keystrokes in the // textbox, thereby allowing them for use by // - ProcessCmdKey (as long as 'e.IsInputKey' was *not* set TRUE in OnPreviewKeyDown()) // - ProcessDialogKey // // Note that a return of FALSE bypasses the KeyDown/Up events; // ie, handle the keystroke in Process*Key() funct(s). #if Keys logfile.Log(". YataEditbox.IsInputKey force FALSE (TabFastedit)"); #endif return(false); } bool ret = base.IsInputKey(keyData); #if Keys if ((keyData & ~gc.ControlShift) != 0) { logfile.Log(". YataEditbox.IsInputKey ret= " + ret); } #endif return(ret); }
/// <summary> /// cTor[1]. /// </summary> /// <param name="id"></param> /// <param name="cols"></param> /// <param name="brush"></param> /// <param name="grid"></param> internal Row(int id, int cols, Brush brush, YataGrid grid) { _id = id; _cells = new Cell[Length = cols]; _brush = brush; _grid = grid; }
/// <summary> /// Autosizes all cols of a given <c><see cref="YataGrid"/></c>. /// </summary> /// <param name="table"></param> /// <remarks>Helper for /// <c><see cref="opsclick_AutosizeCols()">opsclick_AutosizeCols()</see></c> /// and <c><see cref="DiffReset()">DiffReset()</see></c>.</remarks> static void AutosizeCols(YataGrid table) { foreach (var col in table.Cols) { col.UserSized = false; } table.Calibrate(0, table.RowCount - 1); }
/// <summary> /// cTor. /// </summary> /// <param name="grid"></param> internal YataPanelRows(YataGrid grid) { DrawRegulator.SetDoubleBuffered(this); _grid = grid; Dock = DockStyle.Left; BackColor = Colors.RowheadPanel; }
/// <summary> /// cTor. /// </summary> /// <param name="grid"></param> internal YataPanelCols(YataGrid grid) { DrawRegulator.SetDoubleBuffered(this); _grid = grid; Dock = DockStyle.Top; BackColor = Colors.ColheadPanel; Height = YataGrid.HeightColhead; }
/// <summary> /// cTor. /// </summary> /// <param name="grid"></param> /// <param name="w"></param> internal YataPanelFrozen(YataGrid grid, int w) { DrawRegulator.SetDoubleBuffered(this); _grid = grid; Dock = DockStyle.Left; BackColor = Colors.FrozenPanel; Width = w; }
/// <summary> /// Helper for <c><see cref="GotoDiffCell()">GotoDiffCell()</see></c>. /// </summary> /// <param name="sel">a <c><see cref="Cell"/></c> in the current table</param> /// <param name="table">the other <c><see cref="YataGrid"/></c></param> static void gotodiff(Cell sel, YataGrid table) { Table.SelectCell(sel, false); if (table != null && sel.y < table.RowCount && sel.x < table.ColCount) { table[sel.y, sel.x].selected = true; } }
/// <summary> /// cTor. Instantiates this <c>FileWatcherDialog</c>. /// </summary> /// <param name="grid">the <c><see cref="YataGrid"/></c> being watched</param> /// <param name="fwdType"><c><see cref="FwdType"/></c> /// <list type="bullet"> /// <item><c><see cref="FwdType.FileDeleted">Fwd.FileDeleted</see></c></item> /// <item><c><see cref="FwdType.FileChanged">Fwd.FileChanged</see></c></item> /// </list></param> internal FileWatcherDialog( YataGrid grid, FwdType fwdType) { //logfile.Log("FileWatcherDialog.cTor()"); _f = (_grid = grid)._f; // 'YataDialog._f' is used only to set UI parameters. InitializeComponent(); Initialize(YataDialog.METRIC_NON); string text = String.Empty; switch (_fwdType = fwdType) { case FwdType.FileDeleted: text = FILE_Del; bu_Action.Text = "Resave"; break; case FwdType.FileChanged: text = FILE_Wsc; bu_Action.Text = "Reload"; break; } if (_grid.Readonly) { text += " CANCEL DISABLES THE READONLY FLAG."; } la_Info.Text = text; int wInfo = YataGraphics.MeasureWidth(la_Info.Text, la_Info.Font); tb_Pfe.Text = _grid.Fullpath; int wPfe = YataGraphics.MeasureWidth(tb_Pfe.Text, tb_Pfe.Font); ClientSize = new Size(Math.Max(wInfo, wPfe) + 20, ClientSize.Height); MinimumSize = new Size(Math.Max(WIDTH_Min, Width), Height); MaximumSize = new Size(Int32.MaxValue, Height); _t1.Tick += t1_OnTick; _t1.Interval = 330; // enable button delay. _t1.Start(); _t2.Tick += t2_OnTick; _t2.Interval = 300; // watch file period. _t2.Start(); }
/// <summary> /// Helper for /// <c><see cref="tabclick_DiffReset()">tabclick_DiffReset()</see></c>. /// </summary> /// <param name="table">a <c><see cref="YataGrid"/></c></param> /// <remarks>Check that <paramref name="table"/> is not null before /// call.</remarks> void DiffReset(YataGrid table) { for (int r = 0; r != table.RowCount; ++r) { for (int c = 0; c != table.ColCount; ++c) { table[r, c].diff = false; } } if (table == Table) { opsclick_AutosizeCols(null, EventArgs.Empty); } else { AutosizeCols(table); } }
/// <summary> /// Helper for /// <c><see cref="ShowCellContext()">ShowCellContext()</see></c>. /// </summary> /// <returns><c>true</c> if merge operations (cell or row) will be /// enabled</returns> bool isMergeEnabled() { if (_sel.diff && _diff1 != null && _diff2 != null) { YataGrid table = null; if (Table == _diff1) { table = _diff2; } else if (Table == _diff2) { table = _diff1; } return(table != null && !table.Readonly && table.ColCount > _sel.x && table.RowCount > _sel.y); } return(false); }
/// <summary> /// Handles textchanged in the Codepage textbox. /// </summary> /// <param name="sender"><c><see cref="tb_Codepage"/></c></param> /// <param name="e"></param> void tb_Codepage_textchanged(object sender, EventArgs e) { Encoding enc = null; if (tb_Codepage.Text.Length == 0) { la_CodepageInfo.Text = String.Empty; _pre = 0; } else if (tb_Codepage.Text.StartsWith("0", StringComparison.Ordinal)) { tb_Codepage.Text = tb_Codepage.Text.Substring(1); // recurse tb_Codepage.SelectionStart = tb_Codepage.Text.Length; } else { int result; if (!Int32.TryParse(tb_Codepage.Text, out result) || result < 0 || result > 65535) { tb_Codepage.Text = _pre.ToString(CultureInfo.InvariantCulture); // recurse tb_Codepage.SelectionStart = tb_Codepage.Text.Length; } else if (YataGrid.CheckCodepage(_pre = result)) { enc = Encoding.GetEncoding(_pre); la_CodepageInfo.ForeColor = Colors.Text; la_CodepageInfo.Text = enc.HeaderName + Environment.NewLine + enc.EncodingName + Environment.NewLine + enc.CodePage; } else { la_CodepageInfo.ForeColor = Colors.TextReadonly; la_CodepageInfo.Text = "Codepage invalid."; } } bu_Accept.Enabled = (enc != null); }
/// <summary> /// Re-widths and re-locates the frozen labels. /// </summary> /// <param name="table"></param> internal static void metricFrozenLabels(YataGrid table) { if (table.ColCount != 0) { int w0 = table.Cols[0].width(); table._labelid.Location = new Point(0, 0); table._labelid.Size = new Size(WidthRowhead + w0, HeightColhead - 1); // -1 so these don't cover the long // horizontal line under the colhead. if (table.ColCount > 1) { int w1 = table.Cols[1].width(); table._labelfirst.Location = new Point(WidthRowhead + w0, 0); table._labelfirst.Size = new Size(w1, HeightColhead - 1); if (table.ColCount > 2) { table._labelsecond.Location = new Point(WidthRowhead + w0 + w1, 0); table._labelsecond.Size = new Size(table.Cols[2].width(), HeightColhead - 1); } } } }
/// <summary> /// Handles it-click to create a new 2da-file. /// </summary> /// <param name="sender"><c><see cref="it_Create"/></c></param> /// <param name="e"></param> void fileclick_Create(object sender, EventArgs e) { Table = new YataGrid(this, String.Empty, false); Table.CreateTable(); // <- instead of LoadTable() _isCreate = true; fileclick_SaveAs(it_SaveAs, EventArgs.Empty); // shall set Fullpath (incl. tab-string). _isCreate = false; if (File.Exists(Table.Fullpath)) // instead of CreatePage() -> { DrawRegulator.SuspendDrawing(Table); var tab = new TabPage(); Tabs.TabPages.Add(tab); tab.Tag = Table; tab.Text = Path.GetFileNameWithoutExtension(Table.Fullpath); tab.Controls.Add(Table); Tabs.SelectedTab = tab; Table.Init(); DrawRegulator.ResumeDrawing(Table); } else { YataGrid._init = false; Table.Dispose(); } _bypassVerifyFile = true; tab_SelectedIndexChanged(null, EventArgs.Empty); _bypassVerifyFile = false; }
/// <summary> /// Handles a click on the Okay button. /// </summary> /// <param name="sender"><c><see cref="bu_Okay"/></c></param> /// <param name="e"></param> void click_Okay(object sender, EventArgs e) { if (YataGrid.VerifyText_edit(tb_Input)) { _readyTextchanged = true; la_Head.ForeColor = Color.Firebrick; la_Head.Text = "The text has changed."; } else { var f = _f as Yata; f._copytext = new string[, ] { { tb_Input.Text } }; if (f._fclip != null) { f._fclip.SetCellsBufferText(); } DialogResult = DialogResult.OK; } }
/// <summary> /// Writes a 2da-file to /// <c><see cref="YataGrid.Fullpath">YataGrid.Fullpath</see></c> based /// on user's /// <c><see cref="Settings._alignoutput">Settings._alignoutput</see></c>. /// <list type="bullet"> /// <item><c><see cref="Settings.AoFalse">Settings.AoFalse</see></c></item> /// <item><c><see cref="Settings.AoTrue">Settings.AoTrue</see></c></item> /// <item><c><see cref="Settings.AoTabs">Settings.AoTabs</see></c></item> /// </list> /// </summary> /// <param name="table">a <c><see cref="YataGrid"/> to write the data /// for</c></param> internal static void Write(YataGrid table) { if (table.RowCount != 0) { if (Settings._alignoutput == Settings.AoFalse) { using (var sw = new StreamWriter(table.Fullpath)) { sw.WriteLine(gs.TwodaVer); // header -> if (table._defaultval.Length != 0) { sw.WriteLine(gs.Default + table._defaultval); // default value -> } else { sw.WriteLine(); } string line = String.Empty; for (int i = 0; i != table.Fields.Length; ++i) // col-fields -> { line += gs.Space + table.Fields[i]; } sw.WriteLine(line); string val; for (int r = 0; r != table.RowCount; ++r) // row-cells -> { line = String.Empty; for (int c = 0; c != table.ColCount; ++c) { if (c != 0) { line += gs.Space; } if (!String.IsNullOrEmpty(val = table[r, c].text)) // safety. { line += val; } else { line += gs.Stars; } } sw.WriteLine(line); } } } else { // find longest string-width in each col (incl/ colheads) var widths = new int[table.ColCount]; // check cols -> int width, widthtest; for (int c = 0; c != table.ColCount; ++c) { width = 0; for (int r = 0; r != table.RowCount; ++r) { if ((widthtest = table[r, c].text.Length) > width) { width = widthtest; } } widths[c] = width; } // check colheads -> NOTE: There is one more col than colheads. for (int i = 0; i != table.Fields.Length; ++i) { if (widths[i + 1] < table.Fields[i].Length) { widths[i + 1] = table.Fields[i].Length; } } if (Settings._alignoutput == Settings.AoTrue) { using (var sw = new StreamWriter(table.Fullpath)) { sw.WriteLine(gs.TwodaVer); // header -> if (table._defaultval.Length != 0) { sw.WriteLine(gs.Default + table._defaultval); // default value -> } else { sw.WriteLine(); } string line = String.Empty; for (int i = 0; i != table.Fields.Length; ++i) // col-fields -> { if (i == 0) { for (int j = 0; j != widths[0]; ++j) { line += gs.Space; } } if (i != table.Fields.Length - 1) { line += gs.Space + table.Fields[i].PadRight(widths[i + 1]); } else { line += gs.Space + table.Fields[i]; } } sw.WriteLine(line); string val; for (int r = 0; r != table.RowCount; ++r) // row-cells -> { line = String.Empty; for (int c = 0; c != table.ColCount; ++c) { val = table[r, c].text; if (c != table.ColCount - 1) { if (!String.IsNullOrEmpty(val)) // safety. { line += val.PadRight(widths[c] + 1); } else { line += gs.Stars.PadRight(widths[c] + 1); } } else if (!String.IsNullOrEmpty(val)) // safety. { line += val; } else { line += gs.Stars; } } sw.WriteLine(line); } } } else if (Settings._alignoutput == Settings.AoTabs) { const int TabWidth = 4; using (var sw = new StreamWriter(table.Fullpath)) { sw.WriteLine(gs.TwodaVer); // header -> if (table._defaultval.Length != 0) { sw.WriteLine(gs.Default + table._defaultval); // default value -> } else { sw.WriteLine(); } var tabstops = new int[table.ColCount]; tabstops[0] = 0; for (int i = 1; i != widths.Length; ++i) { // to deter the position of the current tabstop [i] // add the start-pos of the preceeding tabstop + // the width of the longest preceeding field + // any remaining spaces that are required to bring // the total to a value that is divisible by TabWidth: // the result is the position of the current tabstop [i] tabstops[i] = tabstops[i - 1] + widths[i - 1] + TabWidth - widths[i - 1] % TabWidth; } string line = String.Empty; for (int i = 0; i != table.Fields.Length; ++i) // col-fields -> { if (i == 0) // insert whitespace at the start of the colheads -> { int spaces = widths[0] + TabWidth - widths[0] % TabWidth; do { line += "\t"; }while ((spaces -= TabWidth) > 0); } if (i != table.Fields.Length - 1) // 2+ fields in row -> { line += table.Fields[i]; width = tabstops[i + 2] - tabstops[i + 1] - table.Fields[i].Length; int tabs = width / TabWidth; if (table.Fields[i].Length % TabWidth != 0) { ++tabs; } while (tabs-- != 0) { line += "\t"; } } else // last field in row -> { line += table.Fields[i]; } } sw.WriteLine(line); string val; for (int r = 0; r != table.RowCount; ++r) // row-cells -> { line = String.Empty; for (int c = 0; c != table.ColCount; ++c) { val = table[r, c].text; if (String.IsNullOrEmpty(val)) // safety. { val = gs.Stars; } if (c != table.ColCount - 1) // 2+ cells in row -> { line += val; width = tabstops[c + 1] - tabstops[c] - val.Length; int tabs = width / TabWidth; if (val.Length % TabWidth != 0) { ++tabs; } while (tabs-- != 0) { line += "\t"; } } else // last cell in row -> { line += val; } } sw.WriteLine(line); } } } } } else // is freshly Created { using (var sw = new StreamWriter(table.Fullpath)) { sw.WriteLine(gs.TwodaVer); // header sw.WriteLine(); // default value switch (Settings._alignoutput) { case Settings.AoFalse: sw.WriteLine(" " + gs.DefaultColLabel); // col-fields sw.WriteLine("0 " + gs.Stars); // row-cells break; case Settings.AoTrue: sw.WriteLine(" " + gs.DefaultColLabel); sw.WriteLine("0 " + gs.Stars); break; case Settings.AoTabs: sw.WriteLine("\t" + gs.DefaultColLabel); sw.WriteLine("0\t" + gs.Stars); break; } } } table.Lastwrite = File.GetLastWriteTime(table.Fullpath); }
/// <summary> /// cTor. /// </summary> /// <param name="grid">a <c><see cref="YataGrid"/></c> that this /// <c>UndoRedo</c> will track changes for</param> internal UndoRedo(YataGrid grid) { _grid = grid; }
/// <summary> /// Applies a specified <c>Font</c> to Yata. /// </summary> /// <param name="font"></param> internal void doFont(Font font) { // NOTE: Cf f.AutoScaleMode (None,Font,DPI,Inherit) // Since I'm doing all the necessary scaling due to font-changes // w/ code the AutoScaleMode should not be set to default "Font". // It might better be set to "DPI" for those weirdos and I don't // know what "Inherit" means (other than the obvious). // AutoScaleMode is currently set to "None". // // See also SetProcessDPIAware() // NOTE: Apparently setting GraphicsUnit.Pixel when creating new // Font-objects effectively bypasses the OS's DPI user-setting. Font.Dispose(); Font = font; Settings._fontdialog.Dispose(); Settings._fontdialog = Settings.CreateDialogFont(Font); FontAccent.Dispose(); FontAccent = new Font(Font, getStyleAccented(Font.FontFamily)); YataGrid.SetStaticMetrics(this); if (Table != null) { Obfuscate(); DrawRegulator.SuspendDrawing(Table); SetTabSize(); YataGrid table; for (int tab = 0; tab != Tabs.TabCount; ++tab) { table = Tabs.TabPages[tab].Tag as YataGrid; table.CreateCols(true); table.Calibrate(0, table.RowCount - 1); // font // TODO: This is effed because the Height (at least) of each // table is not well-defined by .NET - OnResize() for the // tables gets called multiples times per table and the // value of Height changes arbitrarily. Since an accurate // Height is required by InitScrollers() a glitch occurs // when the height of Font increases. That is if a cell or // a row is currently selected it will NOT be fully // displayed if it is NOT on the currently displayed page // and it is near the bottom of the tab-control's page-area; // several pixels of the selected cell or row will still be // covered by the horizontal scroller. Given the arbitrary // Height changes that occur throughout this function's // sequence in fact it's surprising/remarkable that things // turn out even almost correct. // NOTE: Height of any table should NOT be changing at all. if (table == Table) { table.Invalidator(table.EnsureDisplayed()); } } DrawRegulator.ResumeDrawing(Table); Obfuscate(false); if (_ffont != null) // layout for big tables will send the Font dialog below the form -> { _ffont.BringToFront(); // (although it should never be behind the form because its owner IS the form) } } }
/// <summary> /// cTor. /// </summary> /// <remarks>Each tabbed table gets its own Propanel.</remarks> internal Propanel(YataGrid grid) { DrawRegulator.SetDoubleBuffered(this); _grid = grid; if (Settings._gradient) { BackColor = Color.SkyBlue; } else { BackColor = Color.LightBlue; } Anchor = AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom; TabStop = false; // <- the Propanel is not currently coded to cope w/ keyboard-input. if (Settings._font3 != null) { // Font.Dispose(); // be wary. Be very wary. -> Do NOT Dispose() // debug builds don't throw // but release builds CTD when invoking the SettingsEditor after // the Propanel has been opened ... eg. Font = Settings._font3; } else { Font = new Font("Verdana", 7.25F, FontStyle.Regular, GraphicsUnit.Point, (byte)0); } if (_heightr == -1) { _heightr = YataGraphics.MeasureHeight(YataGraphics.HEIGHT_TEST, Font) + _padVert * 2; } _editRect.Height = _heightr - 1; // cf YataGrid.EditCell() HeightProps = _grid.ColCount * _heightr; int wT; for (int c = 0; c != _grid.ColCount; ++c) { wT = YataGraphics.MeasureWidth(_grid.Cols[c].text, Font); if (wT > _widthVars) { _widthVars = wT; } } _widthVars += _padHori * 2 + 1; _scroll.Dock = DockStyle.Right; _scroll.LargeChange = _heightr; _scroll.ValueChanged += scroll_valuechanged; widthValcol(); Controls.Add(_scroll); _grid.Controls.Add(this); _editor.Leave += editor_leave; Controls.Add(_editor); }