Files
HFUTCourseSimulation/HFUTCourseSimulation/MainWindow.xaml.cs

351 lines
13 KiB
C#
Raw Normal View History

2025-09-05 13:32:42 +08:00
using HFUTCourseSimulation.Dialog;
using HFUTCourseSimulation.Util;
2025-09-05 13:32:42 +08:00
using Newtonsoft.Json;
using System;
2018-12-22 23:44:18 +08:00
using System.Collections.Generic;
using System.IO;
2025-09-05 13:32:42 +08:00
using System.Linq;
2018-12-22 23:44:18 +08:00
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace HFUTCourseSimulation {
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
UpdateUiLayout();
2018-12-22 23:44:18 +08:00
}
#region Context and Assistant Functions
private Kernel.Data.Ui.Semester CurrentSemester { get; set; }
2025-09-05 13:32:42 +08:00
private string CurrentFilePath { get; set; }
/// <summary>
/// 返回当前是否有文件被加载。
/// </summary>
/// <returns></returns>
private bool IsFileLoaded() {
2025-09-05 13:32:42 +08:00
return !(CurrentSemester is null);
}
/// <summary>
/// 检查当前加载的文件是否是关联到某个本地文件上的。
/// </summary>
/// <returns></returns>
private bool HasAssocFile() {
2025-09-05 13:32:42 +08:00
return !(CurrentFilePath is null);
}
/// <summary>
/// 更新整个界面的UI状态包括启用与否等
/// </summary>
/// <returns></returns>
private void UpdateUiLayout() {
bool isFileLoaded = this.IsFileLoaded();
bool hasAssocFile = this.HasAssocFile();
// Menus
uiMenuNew.IsEnabled = !isFileLoaded;
uiMenuOpen.IsEnabled = !isFileLoaded;
uiMenuOpenOld.IsEnabled = !isFileLoaded;
uiMenuOpenV1.IsEnabled = uiMenuOpenOld.IsEnabled;
uiMenuSave.IsEnabled = isFileLoaded;
uiMenuSaveAs.IsEnabled = isFileLoaded;
uiMenuClose.IsEnabled = isFileLoaded;
uiMenuQuit.IsEnabled = true;
uiMenuSimulator.IsEnabled = isFileLoaded;
uiMenuRender.IsEnabled = isFileLoaded;
// Main Area
uiMainTab.Visibility = isFileLoaded ? Visibility.Visible : Visibility.Collapsed;
// Window Caption
if (isFileLoaded) {
if (hasAssocFile) {
2025-09-05 13:32:42 +08:00
this.Title = $"HFUT课表模拟 - {CurrentFilePath}";
} else {
this.Title = "HFUT课表模拟 - [未命名]";
}
2018-12-22 23:44:18 +08:00
} else {
this.Title = "HFUT课表模拟";
2018-12-22 23:44:18 +08:00
}
}
2018-12-26 15:55:33 +08:00
/// <summary>
/// 更新界面的数据源
/// </summary>
private void UpdateDataSource() {
if (this.IsFileLoaded()) {
2025-09-05 13:32:42 +08:00
this.DataContext = CurrentSemester;
} else {
this.DataContext = null;
}
}
2018-12-22 23:44:18 +08:00
#endregion
2018-12-22 23:44:18 +08:00
#region Menu Handlers
2018-12-22 23:44:18 +08:00
private void uiMenuNew_Click(object sender, RoutedEventArgs e) {
// Create new blank semester.
var new_obj = new Kernel.Data.Storage.Semester();
// Convert into struct for Ui and clean assoc file path.
CurrentSemester = new Kernel.Data.Ui.Semester(new_obj);
2025-09-05 13:32:42 +08:00
CurrentFilePath = null;
// Update UI and data source
UpdateUiLayout();
UpdateDataSource();
2018-12-22 23:44:18 +08:00
}
private void uiMenuOpen_Click(object sender, RoutedEventArgs e) {
// Fetch file path.
var filepath = Util.Win32Dialog.OpenSemester();
if (filepath is null) return;
2018-12-22 23:44:18 +08:00
// Try to read file.
try {
using (var fs = new StreamReader(filepath, Encoding.UTF8)) {
// Read semester object.
var obj = JsonConvert.DeserializeObject<Kernel.Data.Storage.Semester>(fs.ReadToEnd());
// Convert into struct for Ui and add assoc file path.
CurrentSemester = new Kernel.Data.Ui.Semester(obj);
2025-09-05 13:32:42 +08:00
CurrentFilePath = filepath;
}
} catch (Exception ex) {
Util.Win32Dialog.Error(ex.ToString(), "打开文件时出错");
2018-12-22 23:44:18 +08:00
return;
}
// Update UI and data source
UpdateUiLayout();
UpdateDataSource();
}
2018-12-22 23:44:18 +08:00
private void OpenLegacy<T>() where T : Kernel.Data.Storage.IFromLegacy {
2025-09-05 11:10:23 +08:00
// Fetch file path.
var filepath = Util.Win32Dialog.OpenSemester();
if (filepath is null) return;
// Try to read file.
try {
using (var fs = new StreamReader(filepath, Encoding.UTF8)) {
// Read legacy file and convert it into latest file.
var obj = JsonConvert.DeserializeObject<T>(fs.ReadToEnd());
var latest_obj = obj.ToLatest();
// Convert into struct for Ui and add assoc file path.
CurrentSemester = new Kernel.Data.Ui.Semester(latest_obj);
2025-09-05 13:32:42 +08:00
CurrentFilePath = filepath;
2025-09-05 11:10:23 +08:00
}
} catch (Exception ex) {
Util.Win32Dialog.Error(ex.ToString(), "打开文件时出错");
return;
}
2018-12-22 23:44:18 +08:00
// Update UI and data source
UpdateUiLayout();
UpdateDataSource();
2018-12-22 23:44:18 +08:00
}
private void uiMenuOpenV1_Click(object sender, RoutedEventArgs e) {
OpenLegacy<Kernel.Data.LegacyStorage.V1.Semester>();
}
2018-12-22 23:44:18 +08:00
private void uiMenuSave_Click(object sender, RoutedEventArgs e) {
// Check whether there is associated file.
// If it not, order user select one.
2025-09-05 13:32:42 +08:00
if (CurrentFilePath is null) {
var filepath = Util.Win32Dialog.SaveSemester();
if (filepath is null) return;
2025-09-05 13:32:42 +08:00
CurrentFilePath = filepath;
}
// Try to save file
try {
2025-09-05 13:32:42 +08:00
using (var fs = new StreamWriter(CurrentFilePath, false, Encoding.UTF8)) {
fs.Write(JsonConvert.SerializeObject(CurrentSemester.ToStorage()));
}
} catch (Exception ex) {
Util.Win32Dialog.Error(ex.ToString(), "保存文件时出错");
return;
}
// Update UI
UpdateUiLayout();
}
private void uiMenuSaveAs_Click(object sender, RoutedEventArgs e) {
// Always order user give a path
var filepath = Util.Win32Dialog.SaveSemester();
if (filepath is null) return;
// Update it to current path for following editing.
2025-09-05 13:32:42 +08:00
CurrentFilePath = filepath;
// Try to save file
try {
2025-09-05 13:32:42 +08:00
using (var fs = new StreamWriter(CurrentFilePath, false, Encoding.UTF8)) {
fs.Write(JsonConvert.SerializeObject(CurrentSemester.ToStorage()));
}
} catch (Exception ex) {
Util.Win32Dialog.Error(ex.ToString(), "保存文件时出错");
return;
}
// Update UI
UpdateUiLayout();
2018-12-22 23:44:18 +08:00
}
private void uiMenuClose_Click(object sender, RoutedEventArgs e) {
// Confirm close
var rv = Util.Win32Dialog.Confirm("确认关闭吗?所有未保存的更改都将永久丢失!", "确认关闭");
if (!rv) return;
2018-12-22 23:44:18 +08:00
// Clear semester and assoc file
2025-09-05 13:32:42 +08:00
CurrentSemester = null;
CurrentFilePath = null;
// Update UI and data source
UpdateUiLayout();
UpdateDataSource();
}
private void uiMenuQuit_Click(object sender, RoutedEventArgs e) {
// If there is an opened document, let we confirm it first
if (IsFileLoaded()) {
var rv = Util.Win32Dialog.Confirm("确认退出吗?所有未保存的更改都将永久丢失!", "确认退出");
if (!rv) return;
}
// Close window
this.Close();
2018-12-22 23:44:18 +08:00
}
2025-09-07 16:31:07 +08:00
private void uiMenuCheck_Click(object sender, RoutedEventArgs e) {
var semester = CurrentSemester.ToStorage();
var reporter = new Kernel.Reporter();
var rv = Kernel.Arranger.Arrange(semester, reporter);
}
2025-09-04 15:26:57 +08:00
private void uiMenuSimulator_Click(object sender, RoutedEventArgs e) {
2025-09-07 17:31:13 +08:00
var semester = CurrentSemester.ToStorage();
var reporter = new Kernel.Reporter();
var rv = Kernel.Arranger.Arrange(semester, reporter);
if (rv is null) return;
var dialog = new Dialog.Simulator();
dialog.CurrentSemester = rv;
dialog.ShowDialog();
2018-12-22 23:44:18 +08:00
}
2025-09-04 15:26:57 +08:00
private void uiMenuRender_Click(object sender, RoutedEventArgs e) {
////convert data
//int weekCount;
//DateTime originDate;
//try {
// originDate = DateTime.Parse(General.GeneralSheet.StartDate);
// weekCount = General.GeneralSheet.WeekCount;
//} catch (Exception) {
// MessageBox.Show("周数或日期转换错误,无法输出", "错误", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
// return;
//}
////open file
//var sp = new Microsoft.Win32.SaveFileDialog();
//sp.RestoreDirectory = true;
//sp.Filter = "图片文件(*.png)|*.png|所有文件(*.*)|*.*";
//var status = sp.ShowDialog();
//if (!(status.HasValue && status.Value)) return;
//var getFile = sp.FileName;
////export
//var res = ImageExport.Export(originDate, weekCount, getFile);
//if (!res) MessageBox.Show("当前课程安排存在冲突,请通过实时预览消除所有错误后才能使用此功能来导出为图片", "错误", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
//else MessageBox.Show("导出成功", "关于", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
2018-12-26 15:55:33 +08:00
}
2018-12-22 23:44:18 +08:00
private void uiMenuAbout_Click(object sender, RoutedEventArgs e) {
Win32Dialog.Info(@"本程序为开源程序。
https://gitee.com/yyc12345/HFUTCourseSimulation
PullRequest即可", "");
2018-12-22 23:44:18 +08:00
}
#endregion
#region Main Area Handlers
2018-12-22 23:44:18 +08:00
private void uiCoursesList_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
2025-09-05 13:32:42 +08:00
// It just an alias to edit
uiCtxMenuEditCourse_Click(sender, e);
2018-12-22 23:44:18 +08:00
}
private void uiCtxMenuNewCourse_Click(object sender, RoutedEventArgs e) {
2025-09-05 13:32:42 +08:00
// Create new item and order user edit it
var item = new Kernel.Data.Storage.Course();
2025-09-05 13:32:42 +08:00
var dialog = new Dialog.EditCourse();
dialog.CurrentCourse = new Kernel.Data.Ui.Course(item);
2025-09-05 13:32:42 +08:00
dialog.ShowDialog();
// Then insert or append it into list
var idx = uiCoursesList.SelectedIndex;
if (idx < 0) {
// No selection, append.
CurrentSemester.Courses.Add(dialog.CurrentCourse);
2025-09-05 13:32:42 +08:00
} else {
// Has selection, insert
CurrentSemester.Courses.Insert(idx, dialog.CurrentCourse);
2025-09-05 13:32:42 +08:00
}
2018-12-22 23:44:18 +08:00
}
private void uiCtxMenuEditCourse_Click(object sender, RoutedEventArgs e) {
2025-09-05 13:32:42 +08:00
var idx = uiCoursesList.SelectedIndex;
if (idx < 0) return;
2018-12-26 15:55:33 +08:00
2025-09-05 13:32:42 +08:00
var dialog = new Dialog.EditCourse();
dialog.CurrentCourse = CurrentSemester.Courses[idx];
dialog.ShowDialog();
2018-12-22 23:44:18 +08:00
}
private void uiCtxMenuDeleteCourse_Click(object sender, RoutedEventArgs e) {
2025-09-05 13:32:42 +08:00
// Check whether there is item can be deleted
var idx = uiCoursesList.SelectedIndex;
if (idx < 0) return;
// Order a confirm
var rv = Util.Win32Dialog.Confirm("确认删除选中的课程吗?该操作不可撤销!", "确认删除");
if (!rv) return;
// Remove it
CurrentSemester.Courses.RemoveAt(idx);
}
private void uiCtxMenuClearCourse_Click(object sender, RoutedEventArgs e) {
// Order a confirm
var rv = Util.Win32Dialog.Confirm("确认删除所有课程吗?该操作不可撤销!", "确认清空");
if (!rv) return;
2018-12-22 23:44:18 +08:00
2025-09-05 13:32:42 +08:00
// Clear all schedules
CurrentSemester.Courses.Clear();
2018-12-22 23:44:18 +08:00
}
#endregion
}
}