///<summary>Fills the grid with the contents of the corresponding wiki list table in the database. ///After filling the grid, FilterGrid() will get invoked to apply any advanced search options.</summary> private void FillGrid() { _listColumnHeaders = WikiListHeaderWidths.GetForList(WikiListCurName); _table = WikiLists.GetByName(WikiListCurName); if (_table.Rows.Count > 0 && _listColumnHeaders.Count != _table.Columns.Count) //if these do not match, something happened to be desynched at the right moment. { WikiListHeaderWidths.RefreshCache(); _table = WikiLists.GetByName(WikiListCurName); _listColumnHeaders = WikiListHeaderWidths.GetForList(WikiListCurName); if (_listColumnHeaders.Count != _table.Columns.Count) //if they still do not match, one of them did not get synched correctly. { MsgBox.Show(this, "Unable to open the wiki list."); return; } } gridMain.BeginUpdate(); gridMain.ListGridColumns.Clear(); gridMain.ListGridColumns.AddRange(_listColumnHeaders.Select(x => new GridColumn(x.ColName, x.ColWidth))); gridMain.ListGridRows.Clear(); gridMain.ListGridRows.AddRange(_table.Select().Select((x, index) => new GridRow(x.ItemArray.Select(y => y.ToString()).ToArray()) { Tag = index })); gridMain.Title = WikiListCurName; gridMain.EndUpdate(); FilterGrid(); }
private void butAddItem_Click(object sender, EventArgs e) { FormWikiListItemEdit FormWLIE = new FormWikiListItemEdit(); FormWLIE.WikiListCurName = WikiListCurName; FormWLIE.ItemNum = WikiLists.AddItem(WikiListCurName); FormWLIE.ListColumnHeaders = _listColumnHeaders; FormWLIE.ShowDialog(); if (FormWLIE.DialogResult != DialogResult.OK) { WikiLists.DeleteItem(FormWLIE.WikiListCurName, FormWLIE.ItemNum); //delete new item because dialog was not OK'ed. return; } long itemNum = FormWLIE.ItemNum; //capture itemNum to prevent marshall-by-reference warning SetIsEdited(); _table = WikiLists.GetByName(WikiListCurName); FillGrid(); for (int i = 0; i < gridMain.Rows.Count; i++) { if (gridMain.Rows[i].Cells[0].Text == itemNum.ToString()) { gridMain.Rows[i].ColorBackG = Color.FromArgb(255, 255, 128); gridMain.ScrollToIndex(i); } } }
private void butAddItem_Click(object sender, EventArgs e) { long itemNum = 0; using (FormWikiListItemEdit FormW = new FormWikiListItemEdit()) { FormW.WikiListCurName = WikiListCurName; FormW.ItemNum = WikiLists.AddItem(WikiListCurName); FormW.ListColumnHeaders = _listColumnHeaders; if (FormW.ShowDialog() != DialogResult.OK) { //delete new item because dialog was not OK'ed. WikiLists.DeleteItem(FormW.WikiListCurName, FormW.ItemNum, FormW.ListColumnHeaders.ElementAtOrDefault(0)?.ColName); return; } itemNum = FormW.ItemNum; //capture itemNum to prevent marshall-by-reference warning } SetIsEdited(); FillGrid(); for (int i = 0; i < gridMain.ListGridRows.Count; i++) { if (gridMain.ListGridRows[i].Cells[0].Text == itemNum.ToString()) { gridMain.ListGridRows[i].ColorBackG = Color.FromArgb(255, 255, 128); gridMain.ScrollToIndex(i); } } }
private void FormWikiListEdit_Load(object sender, EventArgs e) { _tableWikiList = WikiLists.GetItem(WikiListCurName, ItemNum); //Show the PK in the title bar for informational purposes. We don't put it in the grid because user can't change it. this.Text = this.Text + " - " + _tableWikiList.Columns[0] + " " + _tableWikiList.Rows[0][0].ToString(); //OK to use 0 indices here. If this fails something else is wrong. FillGrid(); }
private void FillList() { listBox1.Items.Clear(); wikiLists = WikiLists.GetAllLists(); foreach (string list in wikiLists) { listBox1.Items.Add(list.Substring(9)); } }
private void butColumnAdd_Click(object sender, EventArgs e) { if (!Security.IsAuthorized(Permissions.WikiListSetup)) //gives a message box if no permission { return; } WikiLists.AddColumn(WikiListCurName); Table = WikiLists.GetByName(WikiListCurName); FillGrid(); }
private void FormWikiListEdit_Load(object sender, EventArgs e) { if (!WikiLists.CheckExists(WikiListCurName)) { IsNew = true; WikiLists.CreateNewWikiList(WikiListCurName); } Table = WikiLists.GetByName(WikiListCurName); FillGrid(); ActiveControl = textSearch; //start in search box. }
private void butColumnAdd_Click(object sender, EventArgs e) { if (!Security.IsAuthorized(Permissions.WikiListSetup)) //gives a message box if no permission { return; } SetIsEdited(); WikiLists.AddColumn(WikiListCurName); _table = WikiLists.GetByName(WikiListCurName); _listColumnHeaders = WikiListHeaderWidths.GetForList(WikiListCurName); FillGrid(); }
private void FormWikiListEdit_Load(object sender, EventArgs e) { SetFilterControlsAndAction(() => FillGrid(), (int)TimeSpan.FromSeconds(0.5).TotalMilliseconds, textSearch); if (!WikiLists.CheckExists(WikiListCurName)) { IsNew = true; WikiLists.CreateNewWikiList(WikiListCurName); } _wikiListOld = WikiListHists.GenerateFromName(WikiListCurName, Security.CurUser.UserNum) ?? new WikiListHist(); FillGrid(); ActiveControl = textSearch; //start in search box. }
private void butDelete_Click(object sender, EventArgs e) { if (!Security.IsAuthorized(Permissions.WikiListSetup)) //might want to implement a new security permission. { return; } //maybe require all empty or admin priv if (!MsgBox.Show(this, MsgBoxButtons.OKCancel, "Delete this list item and all references to it?")) { return; } WikiLists.DeleteItem(WikiListCurName, ItemNum); DialogResult = DialogResult.OK; }
/// <summary></summary> private void FillGridCur() { gridCur.BeginUpdate(); gridCur.ListGridColumns.Clear(); gridCur.ListGridRows.Clear(); Dictionary <string, int> dictColWidths = WikiListHeaderWidths.GetForList(ListNameCur).ToDictionary(x => x.ColName, x => x.ColWidth); using (DataTable table = WikiLists.GetByName(ListNameCur)) { gridCur.ListGridColumns.AddRange( table.Columns.OfType <DataColumn>().Select(x => new GridColumn(x.ColumnName, dictColWidths.TryGetValue(x.ColumnName, out int width)?width:100))); gridCur.ListGridRows.AddRange(table.Select().Select(x => new GridRow(x.ItemArray.Select(y => y.ToString()).ToArray()))); } gridCur.EndUpdate(); }
private void gridMain_CellDoubleClick(object sender, OpenDental.UI.ODGridClickEventArgs e) { FormWikiListItemEdit FormWLIE = new FormWikiListItemEdit(); FormWLIE.WikiListCurName = WikiListCurName; FormWLIE.ItemNum = PIn.Long(Table.Rows[e.Row][0].ToString()); FormWLIE.ShowDialog(); //saving occurs from within the form. if (FormWLIE.DialogResult != DialogResult.OK) { return; } Table = WikiLists.GetByName(WikiListCurName); FillGrid(); }
private void butHeaders_Click(object sender, EventArgs e) { if (!Security.IsAuthorized(Permissions.WikiListSetup)) //gives a message box if no permission { return; } FormWikiListHeaders FormWLH = new FormWikiListHeaders(); FormWLH.WikiListCurName = WikiListCurName; FormWLH.ShowDialog(); if (FormWLH.DialogResult != DialogResult.OK) { return; } Table = WikiLists.GetByName(WikiListCurName); FillGrid(); }
private void butRenameList_Click(object sender, EventArgs e) { //Logic copied from FormWikiLists.butAdd_Click()--------------------- string newListName; using (InputBox inputListName = new InputBox("New List Name")) { if (inputListName.ShowDialog() != DialogResult.OK) { return; } //Format input as it would be saved in the database-------------------------------------------- newListName = inputListName.textResult.Text.ToLower().Replace(" ", ""); } //Validate list name--------------------------------------------------------------------------- if (string.IsNullOrEmpty(newListName)) { MsgBox.Show(this, "List name cannot be blank."); return; } if (DbHelper.isMySQLReservedWord(newListName)) { //Can become an issue when retrieving column header names. MsgBox.Show(this, "List name is a MySQL reserved word."); return; } if (WikiLists.CheckExists(newListName)) { MsgBox.Show(this, "List name already exists."); return; } try { Cursor = Cursors.WaitCursor; WikiLists.Rename(WikiListCurName, newListName); SetIsEdited(); WikiListHists.Rename(WikiListCurName, newListName); WikiListCurName = newListName; FillGrid(); } catch (Exception ex) { MessageBox.Show(this, ex.Message); } finally { Cursor = Cursors.Default; } }
private void butColumnRight_Click(object sender, EventArgs e) { if (!Security.IsAuthorized(Permissions.WikiListSetup)) //gives a message box if no permission { return; } if (gridMain.SelectedCell.X == -1) { return; } Point pointNewSelectedCell = gridMain.SelectedCell; pointNewSelectedCell.X = Math.Min(gridMain.Columns.Count - 1, pointNewSelectedCell.X + 1); WikiLists.ShiftColumnRight(WikiListCurName, Table.Columns[gridMain.SelectedCell.X].ColumnName); Table = WikiLists.GetByName(WikiListCurName); FillGrid(); gridMain.SetSelected(pointNewSelectedCell); }
private void butHistory_Click(object sender, EventArgs e) { FormWikiListHistory FormWLH = new FormWikiListHistory(); FormWLH.ListNameCur = WikiListCurName; FormWLH.ShowDialog(); if (!FormWLH.IsReverted) { return; } //Reversion has already saved a copy of the current revision. _wikiListOld = WikiListHists.GenerateFromName(WikiListCurName, Security.CurUser.UserNum); _table = WikiLists.GetByName(WikiListCurName); _listColumnHeaders = WikiListHeaderWidths.GetForList(WikiListCurName); FillGrid(); _isEdited = false; IsNew = false; }
private void butColumnRight_Click(object sender, EventArgs e) { if (!Security.IsAuthorized(Permissions.WikiListSetup)) //gives a message box if no permission { return; } if (gridMain.SelectedCell.X > gridMain.ListGridColumns.Count - 2) //can't shift the last column right { return; } SetIsEdited(); Point pointNewSelectedCell = gridMain.SelectedCell; pointNewSelectedCell.X = Math.Min(gridMain.ListGridColumns.Count - 1, pointNewSelectedCell.X + 1); WikiLists.ShiftColumnRight(WikiListCurName, _table.Columns[gridMain.SelectedCell.X].ColumnName); FillGrid(); gridMain.SetSelected(pointNewSelectedCell); }
private void butColumnLeft_Click(object sender, EventArgs e) { if (!Security.IsAuthorized(Permissions.WikiListSetup)) //gives a message box if no permission { return; } if (gridMain.SelectedCell.X < 2) //can't shift first col nor the 2nd col left since, the first col is the PK and can't be moved right { return; } SetIsEdited(); Point pointNewSelectedCell = gridMain.SelectedCell; pointNewSelectedCell.X = Math.Max(1, pointNewSelectedCell.X - 1); WikiLists.ShiftColumnLeft(WikiListCurName, _table.Columns[gridMain.SelectedCell.X].ColumnName); FillGrid(); gridMain.SetSelected(pointNewSelectedCell); }
private void butDelete_Click(object sender, EventArgs e) { if (!Security.IsAuthorized(Permissions.WikiListSetup)) //gives a message box if no permission { return; } if (gridMain.Rows.Count > 0) { MsgBox.Show(this, "Cannot delete a non-empty list. Remove all items first and try again."); return; } if (!MsgBox.Show(this, MsgBoxButtons.OKCancel, "Delete this entire list and all references to it?")) { return; } WikiLists.DeleteList(WikiListCurName); //Someday, if we have links to lists, then this is where we would update all the wikipages containing those links. Remove links to data that was contained in the table. DialogResult = DialogResult.OK; }
private void butColumnDelete_Click(object sender, EventArgs e) { if (!Security.IsAuthorized(Permissions.WikiListSetup)) //gives a message box if no permission { return; } if (gridMain.SelectedCell.X == -1) { MsgBox.Show(this, "Select cell in column to be deleted first."); return; } if (!WikiLists.CheckColumnEmpty(WikiListCurName, Table.Columns[gridMain.SelectedCell.X].ColumnName)) { MsgBox.Show(this, "Column cannot be deleted because it conatins data."); return; } WikiLists.DeleteColumn(WikiListCurName, Table.Columns[gridMain.SelectedCell.X].ColumnName); Table = WikiLists.GetByName(WikiListCurName); FillGrid(); }
private void FormWikiListEdit_Load(object sender, EventArgs e) { if (!WikiLists.CheckExists(WikiListCurName)) { IsNew = true; WikiLists.CreateNewWikiList(WikiListCurName); } _table = WikiLists.GetByName(WikiListCurName); _wikiListOld = WikiListHists.GenerateFromName(WikiListCurName, Security.CurUser.UserNum); if (_wikiListOld == null) { _wikiListOld = new WikiListHist(); } //Fill _columnHeaders _listColumnHeaders = WikiListHeaderWidths.GetForList(WikiListCurName); radioButHighlight.Checked = true; radioButFilter.Checked = false; FillGrid(); ActiveControl = textSearch; //start in search box. }
/*No longer necessary because gridMain_CellLeave does this as text is changed. * ///<summary>This is done before generating markup, when adding or removing rows or columns, and when changing from "none" view to another view. FillGrid can't be done until this is done.</summary> * private void PumpGridIntoTable() { * //table and grid will only have the same numbers of rows and columns if the view is none. * //Otherwise, table may have more columns * //So this is only allowed when switching from the none view to some other view. * if(ViewShowing!=0) { * return; * } * for(int i=0;i<Table.Rows.Count;i++) { * for(int c=0;c<Table.Columns.Count;c++) { * Table.Rows[i][c]=gridMain.Rows[i].Cells[c].Text; * } * } * }*/ private void butColumnLeft_Click(object sender, EventArgs e) { if (!Security.IsAuthorized(Permissions.WikiListSetup)) //gives a message box if no permission { return; } if (gridMain.SelectedCell.X == -1) { return; } SetIsEdited(); Point pointNewSelectedCell = gridMain.SelectedCell; pointNewSelectedCell.X = Math.Max(1, pointNewSelectedCell.X - 1); WikiLists.ShiftColumnLeft(WikiListCurName, _table.Columns[gridMain.SelectedCell.X].ColumnName); _table = WikiLists.GetByName(WikiListCurName); _listColumnHeaders = WikiListHeaderWidths.GetForList(WikiListCurName); FillGrid(); gridMain.SetSelected(pointNewSelectedCell); }
private void butRenameList_Click(object sender, EventArgs e) { //Logic copied from FormWikiLists.butAdd_Click()--------------------- InputBox inputListName = new InputBox("New List Name"); inputListName.ShowDialog(); if (inputListName.DialogResult != DialogResult.OK) { return; } //Format input as it would be saved in the database-------------------------------------------- inputListName.textResult.Text = inputListName.textResult.Text.ToLower().Replace(" ", ""); //Validate list name--------------------------------------------------------------------------- if (DbHelper.isMySQLReservedWord(inputListName.textResult.Text)) { //Can become an issue when retrieving column header names. MsgBox.Show(this, "List name is a reserved word in MySQL."); return; } if (inputListName.textResult.Text == "") { MsgBox.Show(this, "List name cannot be blank."); return; } if (WikiLists.CheckExists(inputListName.textResult.Text)) { MsgBox.Show(this, "List name already exists."); return; } try { WikiLists.Rename(WikiListCurName, inputListName.textResult.Text); SetIsEdited(); WikiListHists.Rename(WikiListCurName, inputListName.textResult.Text); WikiListCurName = inputListName.textResult.Text; _table = WikiLists.GetByName(WikiListCurName); FillGrid(); } catch (Exception ex) { MessageBox.Show(this, ex.Message); } }
private void butAdd_Click(object sender, EventArgs e) { if (!Security.IsAuthorized(Permissions.WikiListSetup)) { return; } InputBox inputListName = new InputBox("New List Name"); inputListName.ShowDialog(); if (inputListName.DialogResult != DialogResult.OK) { return; } //Format input as it would be saved in the database-------------------------------------------- inputListName.textResult.Text = inputListName.textResult.Text.ToLower().Replace(" ", ""); //Validate list name--------------------------------------------------------------------------- if (DbHelper.isMySQLReservedWord(inputListName.textResult.Text)) { //Can become an issue when retrieving column header names. MsgBox.Show(this, "List name is a reserved word in MySQL."); return; } if (inputListName.textResult.Text == "") { MsgBox.Show(this, "List name cannot be blank."); return; } if (WikiLists.CheckExists(inputListName.textResult.Text)) { if (!MsgBox.Show(this, MsgBoxButtons.YesNo, "List already exists with that name. Would you like to edit existing list?")) { return; } } FormWikiListEdit FormWLE = new FormWikiListEdit(); FormWLE.WikiListCurName = inputListName.textResult.Text; //FormWLE.IsNew=true;//set within the form. FormWLE.ShowDialog(); FillList(); }
/// <summary></summary> private void FillGridCur() { List <WikiListHeaderWidth> listColHeaderWidths = WikiListHeaderWidths.GetForList(ListNameCur); _tableCur = WikiLists.GetByName(ListNameCur); gridCur.BeginUpdate(); gridCur.Columns.Clear(); ODGridColumn col; for (int c = 0; c < _tableCur.Columns.Count; c++) { int colWidth = 100; //100 = default value in case something is malformed in the database. foreach (WikiListHeaderWidth colHead in listColHeaderWidths) { if (colHead.ColName == _tableCur.Columns[c].ColumnName) { colWidth = colHead.ColWidth; break; } } col = new ODGridColumn(_tableCur.Columns[c].ColumnName, colWidth, false); gridCur.Columns.Add(col); } gridCur.Rows.Clear(); ODGridRow row; for (int i = 0; i < _tableCur.Rows.Count; i++) { row = new ODGridRow(); for (int c = 0; c < _tableCur.Columns.Count; c++) { row.Cells.Add(_tableCur.Rows[i][c].ToString()); } gridCur.Rows.Add(row); gridCur.Rows[i].Tag = i; } gridCur.EndUpdate(); }
private void butAddItem_Click(object sender, EventArgs e) { FormWikiListItemEdit FormWLIE = new FormWikiListItemEdit(); FormWLIE.WikiListCurName = WikiListCurName; FormWLIE.ItemNum = WikiLists.AddItem(WikiListCurName); FormWLIE.ShowDialog(); if (FormWLIE.DialogResult != DialogResult.OK) { WikiLists.DeleteItem(FormWLIE.WikiListCurName, FormWLIE.ItemNum); //delete new item because dialog was not OK'ed. return; } Table = WikiLists.GetByName(WikiListCurName); FillGrid(); for (int i = 0; i < gridMain.Rows.Count; i++) { if (gridMain.Rows[i].Cells[0].Text == FormWLIE.ItemNum.ToString()) { gridMain.Rows[i].ColorBackG = Color.FromArgb(255, 255, 128); gridMain.ScrollToIndex(i); } } }
///<summary>Validates content, and keywords. isForSaving can be false if just validating for refresh.</summary> public static bool ValidateMarkup(ODcodeBox textContent, bool isForSaving, bool showMsgBox = true, bool isEmail = false) { MatchCollection matches; //xml validation---------------------------------------------------------------------------------------------------- string s = textContent.Text; //"<",">", and "&"----------------------------------------------------------------------------------------------------------- s = s.Replace("&", "&"); s = s.Replace("&<", "<"); //because "&" was changed to "&" in the line above. s = s.Replace("&>", ">"); //because "&" was changed to "&" in the line above. s = "<body>" + s + "</body>"; XmlDocument doc = new XmlDocument(); StringReader reader = new StringReader(s); try { doc.Load(reader); } catch (Exception ex) { if (showMsgBox) { MessageBox.Show(ex.Message); } return(false); } try{ //we do it this way to skip checking the main node itself since it's a dummy node. if (!isEmail) //We are allowing any XHTML markup in emails. { MarkupEdit.ValidateNodes(doc.DocumentElement.ChildNodes); } } catch (Exception ex) { if (showMsgBox) { MessageBox.Show(ex.Message); } return(false); } //Cannot have CR within tag definition--------------------------------------------------------------------------------- //(?<!&) means only match strings that do not start with an '&'. This is so we can continue to use '&' as an escape character for '<'. //<.*?> means anything as short as possible that is contained inside a tag MatchCollection tagMatches = Regex.Matches(textContent.Text, "(?<!&)<.*?>", RegexOptions.Singleline); for (int i = 0; i < tagMatches.Count; i++) { if (tagMatches[i].ToString().Contains("\n")) { if (showMsgBox) { MessageBox.Show(Lans.g(_lanThis, "Error at line:") + " " + textContent.GetLineFromCharIndex(tagMatches[i].Index) + " - " + Lans.g(_lanThis, "Tag definitions cannot contain a return line:") + " " + tagMatches[i].Value.Replace("\n", "")); } return(false); } } //wiki image validation----------------------------------------------------------------------------------------------------- if (!isEmail) { string wikiImagePath = ""; try { wikiImagePath = WikiPages.GetWikiPath(); //this also creates folder if it's missing. } catch (Exception ex) { ex.DoNothing(); //do nothing, the wikiImagePath is only important if the user adds an image to the wiki page and is checked below } matches = Regex.Matches(textContent.Text, @"\[\[(img:).*?\]\]"); // [[img:myimage.jpg]] if (matches.Count > 0 && PrefC.AtoZfolderUsed == DataStorageType.InDatabase) { if (showMsgBox) { MessageBox.Show(Lans.g(_lanThis, "Error at line:") + " " + textContent.GetLineFromCharIndex(matches[0].Index) + " - " + Lans.g(_lanThis, "Cannot use images in wiki if storing images in database.")); } return(false); } if (isForSaving) { for (int i = 0; i < matches.Count; i++) { string imgPath = FileAtoZ.CombinePaths(wikiImagePath, matches[i].Value.Substring(6).Trim(']')); if (!FileAtoZ.Exists(imgPath)) { if (showMsgBox) { MessageBox.Show(Lans.g(_lanThis, "Error at line:") + " " + textContent.GetLineFromCharIndex(matches[i].Index) + " - " + Lans.g(_lanThis, "Not allowed to save because image does not exist:") + " " + imgPath); } return(false); } } } } //Email image validation---------------------------------------------------------------------------------------------- if (isEmail) { string emailImagePath = ""; try { emailImagePath = ImageStore.GetEmailImagePath(); } catch (Exception ex) { ex.DoNothing(); } matches = Regex.Matches(textContent.Text, @"\[\[(img:).*?\]\]"); if (isForSaving) { for (int i = 0; i < matches.Count; i++) { string imgPath = FileAtoZ.CombinePaths(emailImagePath, matches[i].Value.Substring(6).Trim(']')); if (!FileAtoZ.Exists(imgPath)) { if (showMsgBox) { MessageBox.Show(Lans.g(_lanThis, "Error at line:") + " " + textContent.GetLineFromCharIndex(matches[i].Index) + " - " + Lans.g(_lanThis, "Not allowed to save because image does not exist: ") + " " + imgPath); } } } } } //List validation----------------------------------------------------------------------------------------------------- matches = Regex.Matches(textContent.Text, @"\[\[(list:).*?\]\]"); // [[list:CustomList]] foreach (Match match in matches) { if (!WikiLists.CheckExists(match.Value.Substring(7).Trim(']'))) { if (showMsgBox) { MessageBox.Show(Lans.g(_lanThis, "Error at line:") + " " + textContent.GetLineFromCharIndex(match.Index) + " - " + Lans.g(_lanThis, "Wiki list does not exist in database:") + " " + match.Value.Substring(7).Trim(']')); } return(false); } } //spacing around bullets----------------------------------------------------------------------------------------------- string[] lines = textContent.Text.Split(new string[] { "\n" }, StringSplitOptions.None); for (int i = 0; i < lines.Length; i++) { if (lines[i].Trim().StartsWith("*")) { if (!lines[i].StartsWith("*")) { if (showMsgBox) { MessageBox.Show(Lans.g(_lanThis, "Error at line:") + " " + (i + 1) + " - " + Lans.g(_lanThis, "Stars used for lists may not have a space before them.")); } return(false); } if (lines[i].Trim().StartsWith("* ")) { if (showMsgBox) { MessageBox.Show(Lans.g(_lanThis, "Error at line:") + " " + (i + 1) + " - " + Lans.g(_lanThis, "Stars used for lists may not have a space after them.")); } return(false); } } if (lines[i].Trim().StartsWith("#")) { if (!lines[i].StartsWith("#")) { if (showMsgBox) { MessageBox.Show(Lans.g(_lanThis, "Error at line:") + " " + (i + 1) + " - " + Lans.g(_lanThis, "Hashes used for lists may not have a space before them.")); } return(false); } if (lines[i].Trim().StartsWith("# ")) { if (showMsgBox) { MessageBox.Show(Lans.g(_lanThis, "Error at line:") + " " + (i + 1) + " - " + Lans.g(_lanThis, "Hashes used for lists may not have a space after them.")); } return(false); } } } //Invalid characters inside of various tags-------------------------------------------- matches = Regex.Matches(textContent.Text, @"\[\[.*?\]\]"); foreach (Match match in matches) { if (match.Value.Contains("\"") && !match.Value.StartsWith("[[color:") && !match.Value.StartsWith("[[font:")) //allow colored text to have quotes. { if (showMsgBox) { MessageBox.Show(Lans.g(_lanThis, "Error at line:") + " " + textContent.GetLineFromCharIndex(match.Index) + " - " + Lans.g(_lanThis, "Link cannot contain double quotes:") + " " + match.Value); } return(false); } //This is not needed because our regex doesn't even catch them if the span a line break. It's just interpreted as plain text. //if(match.Value.Contains("\r") || match.Value.Contains("\n")) { // MessageBox.Show(Lan.g(this,"Link cannot contain carriage returns: ")+match.Value); // return false; //} if (match.Value.StartsWith("[[img:") || match.Value.StartsWith("[[keywords:") || match.Value.StartsWith("[[file:") || match.Value.StartsWith("[[folder:") || match.Value.StartsWith("[[list:") || match.Value.StartsWith("[[color:") || match.Value.StartsWith("[[font:")) { //other tags } else { if (match.Value.Contains("|")) { if (showMsgBox) { MessageBox.Show(Lans.g(_lanThis, "Error at line:") + " " + textContent.GetLineFromCharIndex(match.Index) + " - " + Lans.g(_lanThis, "Internal link cannot contain a pipe character:") + " " + match.Value); } return(false); } } } //Table markup rigorously formatted---------------------------------------------------------------------- //{| //!Width="100"|Column Heading 1!!Width="150"|Column Heading 2!!Width="75"|Column Heading 3 //|- //|Cell 1||Cell 2||Cell 3 //|- //|Cell A||Cell B||Cell C //|} //Although rarely needed, it might still come in handy in certain cases, like paste, or when user doesn't add the |} until later, and other hacks. matches = Regex.Matches(s, @"\{\|\n.+?\n\|\}", RegexOptions.Singleline); //matches = Regex.Matches(textContent.Text, // @"(?<=(?:\n|<body>))" //Checks for preceding newline or beggining of file // +@"\{\|.+?\n\|\}" //Matches the table markup. // +@"(?=(?:\n|</body>))" //Checks for following newline or end of file // ,RegexOptions.Singleline); foreach (Match match in matches) { lines = match.Value.Split(new string[] { "{|\n", "\n|-\n", "\n|}" }, StringSplitOptions.RemoveEmptyEntries); if (!lines[0].StartsWith("!")) { if (showMsgBox) { MessageBox.Show(Lans.g(_lanThis, "Error at line:") + " " + textContent.GetLineFromCharIndex(match.Index) + " - " + Lans.g(_lanThis, "The second line of a table markup section must start with ! to indicate column headers.")); } return(false); } if (lines[0].StartsWith("! ")) { if (showMsgBox) { MessageBox.Show(Lans.g(_lanThis, "Error at line:") + " " + textContent.GetLineFromCharIndex(match.Index) + " - " + Lans.g(_lanThis, "In the table, at line 2, there cannot be a space after the first !")); } return(false); } string[] cells = lines[0].Substring(1).Split(new string[] { "!!" }, StringSplitOptions.None); //this also strips off the leading ! for (int c = 0; c < cells.Length; c++) { if (!Regex.IsMatch(cells[c], @"^(Width="")\d+""\|")) //e.g. Width="90"| { if (showMsgBox) { MessageBox.Show(Lans.g(_lanThis, "Error at line:") + " " + textContent.GetLineFromCharIndex(match.Index) + " - " + Lans.g(_lanThis, "In the table markup, each header must be formatted like this: Width=\"#\"|...")); } return(false); } } for (int i = 1; i < lines.Length; i++) //loop through the lines after the header { if (!lines[i].StartsWith("|")) { if (showMsgBox) { MessageBox.Show(Lans.g(_lanThis, "Table rows must start with |. At line ") + (i + 1).ToString() + Lans.g(_lanThis, ", this was found instead:") + lines[i]); } return(false); } } } return(true); }
private void butOK_Click(object sender, EventArgs e) { WikiLists.UpdateItem(WikiListCurName, _tableWikiList); DialogResult = DialogResult.OK; }
///<summary>Validates content, and keywords. isForSaving can be false if just validating for refresh.</summary> private bool ValidateWikiPage(bool isForSaving) { //xml validation---------------------------------------------------------------------------------------------------- string s = textContent.Text; //"<",">", and "&"----------------------------------------------------------------------------------------------------------- s = s.Replace("&", "&"); s = s.Replace("&<", "<"); //because "&" was changed to "&" in the line above. s = s.Replace("&>", ">"); //because "&" was changed to "&" in the line above. s = "<body>" + s + "</body>"; XmlDocument doc = new XmlDocument(); StringReader reader = new StringReader(s); try { doc.Load(reader); } catch (Exception ex) { MessageBox.Show(ex.Message); return(false); } try{ //we do it this way to skip checking the main node itself since it's a dummy node. ValidateNodes(doc.DocumentElement.ChildNodes); } catch (Exception ex) { MessageBox.Show(ex.Message); return(false); } //Cannot have CR within tag definition--------------------------------------------------------------------------------- //(?<!&) means only match strings that do not start with an '&'. This is so we can continue to use '&' as an escape character for '<'. //<.*?> means anything as short as possible that is contained inside a tag MatchCollection tagMatches = Regex.Matches(textContent.Text, "(?<!&)<.*?>", RegexOptions.Singleline); for (int i = 0; i < tagMatches.Count; i++) { if (tagMatches[i].ToString().Contains("\r\n")) { MessageBox.Show(Lan.g(this, "Tag definitions cannot contain a return line: ") + tagMatches[i].Value.Replace("\r\n", "")); return(false); } } //image validation----------------------------------------------------------------------------------------------------- string wikiImagePath = WikiPages.GetWikiPath(); //this also creates folder if it's missing. MatchCollection matches = Regex.Matches(textContent.Text, @"\[\[(img:).*?\]\]"); // [[img:myimage.jpg]] if (matches.Count > 0 && !PrefC.AtoZfolderUsed) { MsgBox.Show(this, "Cannot use images in wiki if storing images in database."); return(false); } if (isForSaving) { for (int i = 0; i < matches.Count; i++) { string imgPath = ODFileUtils.CombinePaths(wikiImagePath, matches[i].Value.Substring(6).Trim(']')); if (!System.IO.File.Exists(imgPath)) { MessageBox.Show(Lan.g(this, "Not allowed to save because image does not exist: ") + imgPath); return(false); } } } //List validation----------------------------------------------------------------------------------------------------- matches = Regex.Matches(textContent.Text, @"\[\[(list:).*?\]\]"); // [[list:CustomList]] foreach (Match match in matches) { if (!WikiLists.CheckExists(match.Value.Substring(7).Trim(']'))) { MessageBox.Show(Lan.g(this, "Wiki list does not exist in database") + " : " + match.Value.Substring(7).Trim(']')); return(false); } } //spacing around bullets----------------------------------------------------------------------------------------------- string[] lines = textContent.Text.Split(new string[] { "\r\n" }, StringSplitOptions.None); for (int i = 0; i < lines.Length; i++) { if (lines[i].Trim().StartsWith("*")) { if (!lines[i].StartsWith("*")) { MsgBox.Show(this, "Stars used for lists may not have a space before them."); return(false); } if (lines[i].Trim().StartsWith("* ")) { MsgBox.Show(this, "Stars used for lists may not have a space after them."); return(false); } } if (lines[i].Trim().StartsWith("#")) { if (!lines[i].StartsWith("#")) { MsgBox.Show(this, "Hashes used for lists may not have a space before them."); return(false); } if (lines[i].Trim().StartsWith("# ")) { MsgBox.Show(this, "Hashes used for lists may not have a space after them."); return(false); } } } //Invalid characters inside of various tags-------------------------------------------- matches = Regex.Matches(textContent.Text, @"\[\[.*?\]\]"); foreach (Match match in matches) { if (match.Value.Contains("\"") && !match.Value.StartsWith("[[color:")) //allow colored text to have quotes. { MessageBox.Show(Lan.g(this, "Link cannot contain double quotes: ") + match.Value); return(false); } //This is not needed because our regex doesn't even catch them if the span a line break. It's just interpreted as plain text. //if(match.Value.Contains("\r") || match.Value.Contains("\n")) { // MessageBox.Show(Lan.g(this,"Link cannot contain carriage returns: ")+match.Value); // return false; //} if (match.Value.StartsWith("[[img:") || match.Value.StartsWith("[[keywords:") || match.Value.StartsWith("[[file:") || match.Value.StartsWith("[[folder:") || match.Value.StartsWith("[[list:") || match.Value.StartsWith("[[color:")) { //other tags } else { if (match.Value.Contains("|")) { MessageBox.Show(Lan.g(this, "Internal link cannot contain a pipe character:") + match.Value); return(false); } } } //Table markup rigorously formatted---------------------------------------------------------------------- //{| //!Width="100"|Column Heading 1!!Width="150"|Column Heading 2!!Width="75"|Column Heading 3 //|- //|Cell 1||Cell 2||Cell 3 //|- //|Cell A||Cell B||Cell C //|} //Although this is rarely needed, it might still come in handy in certain cases, like paste, or when user doesn't add the |} until later, and other hacks. matches = Regex.Matches(s, @"\{\|(.+?)\|\}", RegexOptions.Singleline); foreach (Match match in matches) { lines = match.Value.Split(new string[] { "{|\r\n", "\r\n|-\r\n", "\r\n|}" }, StringSplitOptions.RemoveEmptyEntries); if (!match.Value.StartsWith("{|")) { MsgBox.Show(this, "The first line of a table markup section must be exactly {|, with no additional characters."); return(false); } if (!lines[0].StartsWith("!")) { MsgBox.Show(this, "The second line of a table markup section must start with ! to indicate column headers."); return(false); } if (lines[0].StartsWith("! ")) { MsgBox.Show(this, "In the table, at line 2, there cannot be a space after the first !"); return(false); } string[] cells = lines[0].Substring(1).Split(new string[] { "!!" }, StringSplitOptions.None); //this also strips off the leading ! for (int c = 0; c < cells.Length; c++) { if (!Regex.IsMatch(cells[c], @"^(Width="")\d+""\|")) //e.g. Width="90"| { MsgBox.Show(this, "In the table markup, each header must be formatted like this: Width=\"#\"|..."); return(false); } } for (int i = 1; i < lines.Length; i++) //loop through the lines after the header { if (!lines[i].StartsWith("|")) { MessageBox.Show(Lan.g(this, "Table rows must start with |. At line ") + (i + 1).ToString() + Lan.g(this, ", this was found instead:") + lines[i]); return(false); } //if(lines[i].StartsWith("| ")) { // MessageBox.Show(Lan.g(this,"In the table, at line ")+(i+1).ToString()+Lan.g(this,", there cannot be a space after the first |.")); // return false; //} //lines[i].in //I guess we don't really care what they put in a row. We can just interpret garbage as a single cell. } if (!match.Value.EndsWith("\r\n|}")) { MsgBox.Show(this, "The last line of a table markup section must be exactly |}, with no additional characters."); //this doesn't work since the match stops after |}. return(false); } } return(true); }