Files
HFUTCourseSimulation/HFUTCourseSimulation/MainWindow.xaml.cs
2025-09-07 17:31:13 +08:00

351 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using HFUTCourseSimulation.Dialog;
using HFUTCourseSimulation.Util;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
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();
}
#region Context and Assistant Functions
private Kernel.Data.Ui.Semester CurrentSemester { get; set; }
private string CurrentFilePath { get; set; }
/// <summary>
/// 返回当前是否有文件被加载。
/// </summary>
/// <returns></returns>
private bool IsFileLoaded() {
return !(CurrentSemester is null);
}
/// <summary>
/// 检查当前加载的文件是否是关联到某个本地文件上的。
/// </summary>
/// <returns></returns>
private bool HasAssocFile() {
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) {
this.Title = $"HFUT课表模拟 - {CurrentFilePath}";
} else {
this.Title = "HFUT课表模拟 - [未命名]";
}
} else {
this.Title = "HFUT课表模拟";
}
}
/// <summary>
/// 更新界面的数据源
/// </summary>
private void UpdateDataSource() {
if (this.IsFileLoaded()) {
this.DataContext = CurrentSemester;
} else {
this.DataContext = null;
}
}
#endregion
#region Menu Handlers
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);
CurrentFilePath = null;
// Update UI and data source
UpdateUiLayout();
UpdateDataSource();
}
private void uiMenuOpen_Click(object sender, RoutedEventArgs e) {
// 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 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);
CurrentFilePath = filepath;
}
} catch (Exception ex) {
Util.Win32Dialog.Error(ex.ToString(), "打开文件时出错");
return;
}
// Update UI and data source
UpdateUiLayout();
UpdateDataSource();
}
private void OpenLegacy<T>() where T : Kernel.Data.Storage.IFromLegacy {
// 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);
CurrentFilePath = filepath;
}
} catch (Exception ex) {
Util.Win32Dialog.Error(ex.ToString(), "打开文件时出错");
return;
}
// Update UI and data source
UpdateUiLayout();
UpdateDataSource();
}
private void uiMenuOpenV1_Click(object sender, RoutedEventArgs e) {
OpenLegacy<Kernel.Data.LegacyStorage.V1.Semester>();
}
private void uiMenuSave_Click(object sender, RoutedEventArgs e) {
// Check whether there is associated file.
// If it not, order user select one.
if (CurrentFilePath is null) {
var filepath = Util.Win32Dialog.SaveSemester();
if (filepath is null) return;
CurrentFilePath = filepath;
}
// Try to save file
try {
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.
CurrentFilePath = filepath;
// Try to save file
try {
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 uiMenuClose_Click(object sender, RoutedEventArgs e) {
// Confirm close
var rv = Util.Win32Dialog.Confirm("确认关闭吗?所有未保存的更改都将永久丢失!", "确认关闭");
if (!rv) return;
// Clear semester and assoc file
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();
}
private void uiMenuCheck_Click(object sender, RoutedEventArgs e) {
var semester = CurrentSemester.ToStorage();
var reporter = new Kernel.Reporter();
var rv = Kernel.Arranger.Arrange(semester, reporter);
}
private void uiMenuSimulator_Click(object sender, RoutedEventArgs e) {
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();
}
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);
}
private void uiMenuAbout_Click(object sender, RoutedEventArgs e) {
Win32Dialog.Info(@"本程序为开源程序。
开源地址https://gitee.com/yyc12345/HFUTCourseSimulation
本程序旨在为各位选课的同学提供一个用于查验课程冲突以及查看课表的功能。如果您想参与开发提交PullRequest即可欢迎您的加入。", "关于");
}
#endregion
#region Main Area Handlers
private void uiCoursesList_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
// It just an alias to edit
uiCtxMenuEditCourse_Click(sender, e);
}
private void uiCtxMenuNewCourse_Click(object sender, RoutedEventArgs e) {
// Create new item and order user edit it
var item = new Kernel.Data.Storage.Course();
var dialog = new Dialog.EditCourse();
dialog.CurrentCourse = new Kernel.Data.Ui.Course(item);
dialog.ShowDialog();
// Then insert or append it into list
var idx = uiCoursesList.SelectedIndex;
if (idx < 0) {
// No selection, append.
CurrentSemester.Courses.Add(dialog.CurrentCourse);
} else {
// Has selection, insert
CurrentSemester.Courses.Insert(idx, dialog.CurrentCourse);
}
}
private void uiCtxMenuEditCourse_Click(object sender, RoutedEventArgs e) {
var idx = uiCoursesList.SelectedIndex;
if (idx < 0) return;
var dialog = new Dialog.EditCourse();
dialog.CurrentCourse = CurrentSemester.Courses[idx];
dialog.ShowDialog();
}
private void uiCtxMenuDeleteCourse_Click(object sender, RoutedEventArgs e) {
// 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;
// Clear all schedules
CurrentSemester.Courses.Clear();
}
#endregion
}
}