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 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 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 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. }
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(); }
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); } }
///<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); }
///<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); }