EditPage.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #include "pch.h"
  2. #include "EditPage.h"
  3. #if __has_include("EditPage.g.cpp")
  4. #include "EditPage.g.cpp"
  5. #endif
  6. using namespace std::literals::chrono_literals;
  7. using namespace winrt;
  8. using namespace winrt::Windows::Storage::Streams;
  9. using namespace winrt::Windows::UI::Text;
  10. namespace winrt::Maple_App::implementation
  11. {
  12. EditPage::EditPage()
  13. {
  14. InitializeComponent();
  15. }
  16. fire_and_forget EditPage::OnNavigatedTo(NavigationEventArgs const& e) {
  17. const auto lifetime = get_strong();
  18. const auto& param = e.Parameter().as<Maple_App::ConfigViewModel>();
  19. m_file = param.File();
  20. try {
  21. const auto& text = co_await FileIO::ReadTextAsync(param.File(), UnicodeEncoding::Utf8);
  22. EditBox().Document().SetText(TextSetOptions::None, text);
  23. }
  24. catch (const winrt::hresult_error&) {
  25. EditBox().Document().SetText(TextSetOptions::None, L"Invalid configuration file");
  26. }
  27. const auto weakThis = lifetime->get_weak();
  28. m_saveModifiedContent = [weakThis]() -> IAsyncAction {
  29. if (const auto self{ weakThis.get() }) {
  30. return self->SaveDocument();
  31. }
  32. return {};
  33. };
  34. }
  35. void EditPage::OnNavigatingFrom(NavigatingCancelEventArgs const&) {
  36. if (m_file == nullptr || !m_file.IsAvailable()) {
  37. return;
  38. }
  39. SaveDocument();
  40. }
  41. void EditPage::EditBox_TextChanging(IInspectable const&, RichEditBoxTextChangingEventArgs const&)
  42. {
  43. if (m_loaded == 2) {
  44. SaveModifiedContent = m_saveModifiedContent;
  45. SaveButton().IsEnabled(true);
  46. }
  47. else {
  48. m_loaded++;
  49. }
  50. }
  51. fire_and_forget EditPage::SaveButton_Click(IInspectable const& sender, RoutedEventArgs const&) {
  52. const auto lifetime = get_strong();
  53. const auto& placementTarget = sender.try_as<FrameworkElement>();
  54. const auto currentValidateRequest = ++validateRequest;
  55. ValidConfigFlyout().Hide();
  56. InvalidConfigFlyout().Hide();
  57. co_await SaveDocument();
  58. if (validateRequest != currentValidateRequest) {
  59. co_return;
  60. }
  61. // Validate
  62. const auto& path = winrt::to_string(m_file.Path());
  63. co_await winrt::resume_background();
  64. const auto result = leaf_test_config(path.data());
  65. co_await winrt::resume_foreground(Dispatcher());
  66. if (validateRequest != currentValidateRequest) {
  67. co_return;
  68. }
  69. switch (result)
  70. {
  71. case LEAF_ERR_OK:
  72. ValidConfigFlyout().ShowAt(placementTarget);
  73. break;
  74. case LEAF_ERR_CONFIG:
  75. InvalidConfigFlyout().ShowAt(placementTarget);
  76. break;
  77. default:
  78. // TODO: handle errors
  79. break;
  80. }
  81. co_await winrt::resume_after(2s);
  82. co_await winrt::resume_foreground(Dispatcher());
  83. if (validateRequest != currentValidateRequest) {
  84. co_return;
  85. }
  86. ValidConfigFlyout().Hide();
  87. InvalidConfigFlyout().Hide();
  88. }
  89. void EditPage::HelpButton_Click(IInspectable const&, RoutedEventArgs const&) {
  90. const auto _ = winrt::Windows::System::Launcher::LaunchUriAsync(Uri{ L"https://github.com/eycorsican/leaf/blob/master/README.zh.md" });
  91. }
  92. IAsyncAction EditPage::SaveDocument()
  93. {
  94. const auto lifetime = get_strong();
  95. if (!SaveButton().IsEnabled()) {
  96. co_return;
  97. }
  98. SaveModifiedContent = nullptr;
  99. SaveButton().IsEnabled(false);
  100. hstring content{};
  101. EditBox().Document().GetText(TextGetOptions::NoHidden | TextGetOptions::UseCrlf | TextGetOptions::AllowFinalEop, content);
  102. const auto data = to_string(content);
  103. co_return co_await FileIO::WriteBytesAsync(
  104. m_file,
  105. std::vector<uint8_t>(data.begin(), data.end()));
  106. }
  107. }