📄 pages.cs
字号:
return done;
}
/// <summary>
/// Gets the list of all the Pages of the Wiki. The List shouldn't be modified.
/// </summary>
public List<PageInfo> AllPages {
get { return pages; }
}
/// <summary>
/// Finds a Category.
/// </summary>
/// <param name="name">The name of the Category to Find (case <b>unsensitive</b>).</param>
/// <returns>The CategoryInfo or null.</returns>
public CategoryInfo FindCategory(string name) {
if(name == null || name.Length == 0) return null;
lock(categories) {
int idx = categories.BinarySearch(new CategoryInfo(name, null), new CategoryNameComparer());
if(idx >= 0) return categories[idx];
}
return null;
}
#endregion
#region Categories
/// <summary>
/// Creates a new Category.
/// </summary>
/// <param name="name">The Name of the Category.</param>
/// <returns>True if the Category has been created successfully.</returns>
public bool CreateCategory(string name) {
return CreateCategory(name, Collectors.PagesProviderCollector.GetProvider(Settings.DefaultPagesProvider));
}
/// <summary>
/// Creates a new Category in the specifued Provider.
/// </summary>
/// <param name="name">The Name of the Category.</param>
/// <param name="provider">The Provider.</param>
/// <returns>True if the Category has been created successfully.</returns>
public bool CreateCategory(string name, IPagesStorageProvider provider) {
if(FindCategory(name) != null) return false;
if(provider == null) provider = Collectors.PagesProviderCollector.GetProvider(Settings.DefaultPagesProvider);
CategoryInfo newCat = provider.AddCategory(name);
if(newCat != null) {
lock(categories) {
categories.Add(newCat);
categories.Sort(new CategoryNameComparer());
}
Log.LogEntry("Category " + name + " created", EntryType.General, "SYSTEM");
return true;
}
else {
Log.LogEntry("Category creation failed for " + name, EntryType.Error, "SYSTEM");
return false;
}
}
/// <summary>
/// Removes a Category.
/// </summary>
/// <param name="category">The Category to remove.</param>
/// <returns>True if the Category has been removed successfully.</returns>
public bool RemoveCategory(CategoryInfo category) {
bool done = category.Provider.RemoveCategory(category);
if(done) {
lock(categories) {
categories.Remove(category);
}
Log.LogEntry("Category " + category.Name + " removed", EntryType.General, "SYSTEM");
}
else Log.LogEntry("Category deletion failed for " + category.Name, EntryType.Error, "SYSTEM");
return done;
}
/// <summary>
/// Renames a Category.
/// </summary>
/// <param name="category">The Category to rename.</param>
/// <param name="newName">The new Name of the Category.</param>
/// <returns>True if the Category has been renamed successfully.</returns>
public bool RenameCategory(CategoryInfo category, string newName) {
if(FindCategory(newName) != null) return false;
string oldName = category.Name;
CategoryInfo newCat = category.Provider.RenameCategory(category, newName);
if(newCat != null) {
lock(categories) {
categories.Remove(category);
categories.Add(newCat);
categories.Sort(new CategoryNameComparer());
}
Log.LogEntry("Category " + oldName + " renamed to " + newName, EntryType.General, "SYSTEM");
}
else Log.LogEntry("Category rename failed for " + oldName + " (" + newName + ")", EntryType.Error, "SYSTEM");
return newCat != null;
}
/// <summary>
/// Gets the Categories of a Page.
/// </summary>
/// <param name="page">The Page.</param>
/// <returns>The Categories of the Page.</returns>
public CategoryInfo[] GetCategoriesPerPage(PageInfo page) {
List<CategoryInfo> result = new List<CategoryInfo>();
lock(categories) {
for(int i = 0; i < categories.Count; i++) {
if(ContainsString(categories[i].Pages, page.Name)) result.Add(categories[i]);
}
}
return result.ToArray();
}
/// <summary>
/// Gets all the Uncategorized Pages.
/// </summary>
/// <returns>The Uncategorized Pages.</returns>
public PageInfo[] GetUncategorizedPages() {
List<PageInfo> result = new List<PageInfo>();
lock(pages) {
lock(categories) {
for(int i = 0; i < pages.Count; i++) {
bool found = false;
for(int k = 0; k < categories.Count; k++) {
if(ContainsString(categories[k].Pages, pages[i].Name)) {
found = true;
break;
}
}
if(!found) result.Add(pages[i]);
}
}
}
return result.ToArray();
}
/// <summary>
/// Gets the valid Categories for a Page, i.e. the Categories managed by the Page's Provider.
/// </summary>
/// <param name="page">The Page, or null to use the default provider.</param>
/// <returns>The valid Categories.</returns>
public CategoryInfo[] GetAvailableCategories(PageInfo page) {
if(page != null) {
return page.Provider.AllCategories;
}
else {
return Collectors.PagesProviderCollector.GetProvider(Settings.DefaultPagesProvider).AllCategories;
}
}
/// <summary>
/// Gets the other Categories of the Provider of the specified Category.
/// </summary>
/// <param name="category">The Category.</param>
/// <returns>The matching Categories.</returns>
public CategoryInfo[] GetMatchingCategories(CategoryInfo category) {
List<CategoryInfo> result = new List<CategoryInfo>();
lock(categories) {
for(int i = 0; i < categories.Count; i++) {
if(categories[i].Provider == category.Provider && categories[i] != category) {
result.Add(categories[i]);
}
}
}
return result.ToArray();
}
private bool ContainsPageInfo(PageInfo[] pages, PageInfo page) {
PageNameComparer comp = new PageNameComparer();
for(int i = 0; i < pages.Length; i++) {
if(comp.Compare(pages[i], page) == 0) return true;
}
return false;
}
/// <summary>
/// Binds a Page with some Categories.
/// </summary>
/// <param name="page">The Page to rebind.</param>
/// <param name="categories">The Categories to bind the Page with.</param>
/// <remarks>
/// The specified Categories must be managed by the same Provider that manages the Page.
/// The operation removes all the previous bindings.
/// </remarks>
/// <returns>True if the binding succeeded.</returns>
public bool Rebind(PageInfo page, CategoryInfo[] cats) {
string[] names = new string[cats.Length];
for(int i = 0; i < cats.Length; i++) {
if(cats[i].Provider != page.Provider) return false;
names[i] = cats[i].Name; // Saves one cycle
}
bool done = page.Provider.Rebind(page, names);
if(done) {
// Update data in memory (this implementation is not very efficient)
lock(categories) {
// 1 - Remove the Page from ALL the Categories
for(int i = 0; i < categories.Count; i++) {
int idx;
if(ContainsString(categories[i].Pages, page.Name, out idx)) {
List<string> tmp = new List<string>(categories[i].Pages);
tmp.RemoveAt(idx);
categories[i].Pages = tmp.ToArray();
}
}
// 2 - Add the Page to the selected Categories
for(int i = 0; i < cats.Length; i++) {
List<string> tmp = new List<string>(cats[i].Pages);
tmp.Add(page.Name);
cats[i].Pages = tmp.ToArray();
}
}
Log.LogEntry("Page " + page.Name + " rebound", EntryType.General, "SYSTEM");
}
else Log.LogEntry("Page rebind failed for " + page.Name, EntryType.Error, "SYSTEM");
return done;
}
private bool ContainsString(string[] pages, string page) {
int idx;
return ContainsString(pages, page, out idx);
}
private bool ContainsString(string[] pages, string page, out int idx) {
for(int i = 0; i < pages.Length; i++) {
if(pages[i].ToLower().Equals(page.ToLower())) {
idx = i;
return true;
}
}
idx = -1;
return false;
}
/// <summary>
/// Merges two Categories.
/// </summary>
/// <param name="source">The source Category.</param>
/// <param name="destination">The destination Category.</param>
/// <returns>True if the Categories have been merged successfully.</returns>
/// <remarks>The <b>destination</b> Category remains, while the <b>source</b> Category is deleted, and all its Pages re-binded in the <b>destination</b> Category.
/// The two Categories must have the same provider.</remarks>
public bool MergeCategories(CategoryInfo source, CategoryInfo destination) {
if(source.Provider != destination.Provider) return false;
CategoryInfo newCat = source.Provider.MergeCategories(source, destination);
if(newCat != null) {
// Update data in memory
lock(categories) {
// 1 - Remove Source and Destination
categories.Remove(source);
categories.Remove(destination);
// 2 - Add new Category
categories.Add(newCat);
categories.Sort(new CategoryNameComparer());
}
Log.LogEntry("Category " + source.Name + " merged into " + destination.Name, EntryType.General, "SYSTEM");
}
else Log.LogEntry("Categories merging failed for " + source.Name + " into " + destination.Name, EntryType.Error, "SYSTEM");
return newCat != null;
}
/// <summary>
/// Gets the list of all the Categories of the Wiki. The list shouldn't be modified.
/// </summary>
public List<CategoryInfo> AllCategories {
get { return categories; }
}
#endregion
#region Page Discussion
/// <summary>
/// Gets the Page Messages.
/// </summary>
/// <param name="page">The Page.</param>
/// <returns>The list of the <b>first-level</b> Messages, containing the replies properly nested.</returns>
public Message[] GetPageMessages(PageInfo page) {
return page.Provider.GetMessages(page);
}
/// <summary>
/// Gets the total number of Messages in a Page Discussion.
/// </summary>
/// <param name="page">The Page.</param>
/// <returns>The number of messages.</returns>
public int GetMessageCount(PageInfo page) {
return page.Provider.GetMessageCount(page);
}
/// <summary>
/// Finds a Message.
/// </summary>
/// <param name="messages">The Messages.</param>
/// <param name="id">The Message ID.</param>
/// <returns>The Message or null.</returns>
public Message FindMessage(List<Message> messages, int id) {
Message result = null;
for(int i = 0; i < messages.Count; i++) {
if(messages[i].ID == id) {
result = messages[i];
}
if(result == null) {
result = FindMessage(messages[i].Replies, id);
}
if(result != null) break;
}
return result;
}
/// <summary>
/// Adds a new Message to a Page.
/// </summary>
/// <param name="page">The Page.</param>
/// <param name="username">The Username.</param>
/// <param name="subject">The Subject.</param>
/// <param name="dateTime">The Date/Time.</param>
/// <param name="body">The Body.</param>
/// <param name="parent">The Parent Message ID, or -1.</param>
/// <returns>True if the Message has been added successfully.</returns>
public bool AddMessage(PageInfo page, string username, string subject, DateTime dateTime, string body, int parent) {
return page.Provider.AddMessage(page, username, subject, dateTime, body, parent);
}
/// <summary>
/// Removes a Message.
/// </summary>
/// <param name="page">The Page.</param>
/// <param name="id">The ID of the Message to remove.</param>
/// <param name="removeReplies">A value specifying whether or not to remove the replies.</param>
/// <returns>True if the Message has been removed successfully.</returns>
public bool RemoveMessage(PageInfo page, int id, bool removeReplies) {
return page.Provider.RemoveMessage(page, id, removeReplies);
}
/// <summary>
/// Modifies a Message.
/// </summary>
/// <param name="page">The Page.</param>
/// <param name="id">The ID of the Message to modify.</param>
/// <param name="username">The Username.</param>
/// <param name="subject">The Subject.</param>
/// <param name="dateTime">The Date/Time.</param>
/// <param name="body">The Body.</param>
/// <returns>True if the Message has been modified successfully.</returns>
public bool ModifyMessage(PageInfo page, int id, string username, string subject, DateTime dateTime, string body) {
return page.Provider.ModifyMessage(page, id, username, subject, dateTime, body);
}
#endregion
/// <summary>
/// Checks the validity of a Page name.
/// </summary>
/// <param name="name">The Page name.</param>
/// <returns>True if the name is valid.</returns>
public static bool IsValidName(string name) {
if(name.Replace(" ", "").Length == 0 ||
name.Contains("?") || name.Contains("<") || name.Contains(">") || name.Contains("|") || name.Contains(":") ||
name.Contains("*") || name.Contains("\"") || name.Contains("/") || name.Contains("\\") || name.Contains("&") ||
name.Contains("%") || name.Contains("'") || name.Contains("\"") || name.Contains("+") || name.EndsWith(".")) {
return false;
}
else return true;
}
}
/// <summary>
/// Compares PageContent objects.
/// </summary>
public class PageContentDateComparer : IComparer<PageContent> {
/// <summary>
/// Compares two PageContent objects, using the DateTime as parameter.
/// </summary>
/// <param name="x">The first object.</param>
/// <param name="y">The second object.</param>
/// <returns>The result of the comparison (1, 0 or -1).</returns>
public int Compare(PageContent x, PageContent y) {
return x.LastModified.CompareTo(y.LastModified);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -