]> repos.lx-s.de Git - winmute.git/commitdiff
Added dialog controls for editting quiet hours
authorlx-s <lx-s@users.noreply.github.com>
Sat, 7 Mar 2026 14:49:20 +0000 (15:49 +0100)
committerlx-s <lx-s@users.noreply.github.com>
Sat, 7 Mar 2026 14:49:20 +0000 (15:49 +0100)
WinMute/Settings_QuietHoursDlg.cpp
WinMute/WMSettings.cpp
WinMute/WinMute.rc

index 6a162a06ef4d33b44d54056144c71c7b5828ef63..dbaa51d1298bd4848d640bf68c5fc184c684cf70 100644 (file)
@@ -40,20 +40,60 @@ struct QuietHoursEntry {
 
 struct QuietHoursDlgData {
    WMSettings* settings = nullptr;
-   std::vector<std::pair<DWORD, DWORD>> quietHoursTimes;
 };
 
 static bool IsValidTimeRange(
    const LPSYSTEMTIME start,
    const LPSYSTEMTIME end)
 {
-   bool isValid = true;
-   if (start->wHour == end->wHour &&
-      start->wMinute == end->wMinute &&
-      start->wSecond == end->wSecond) {
-      isValid = false;
+   return !(start->wHour == end->wHour
+         && start->wMinute == end->wMinute
+         && start->wSecond == end->wSecond);
+}
+
+static std::wstring FormatQuietHoursTime(DWORD seconds)
+{
+   const WORD h = static_cast<WORD>(seconds / 3600);
+   const WORD m = static_cast<WORD>((seconds % 3600) / 60);
+   wchar_t buf[6];
+   swprintf_s(buf, L"%02d:%02d", h, m);
+   return buf;
+}
+
+static void AddQuietHoursEntryToListView(HWND hListView, QuietHoursEntry* entry)
+{
+   auto startText = FormatQuietHoursTime(entry->start);
+   auto endText   = FormatQuietHoursTime(entry->end);
+
+   LVITEM lvi{};
+   lvi.mask     = LVIF_TEXT | LVIF_PARAM;
+   lvi.iItem    = ListView_GetItemCount(hListView);
+   lvi.iSubItem = 0;
+   lvi.pszText  = const_cast<LPWSTR>(startText.c_str());
+   lvi.lParam   = reinterpret_cast<LPARAM>(entry);
+   const int idx = ListView_InsertItem(hListView, &lvi);
+   ListView_SetItemText(hListView, idx, 1, const_cast<LPWSTR>(endText.c_str()));
+}
+
+static void UpdateListViewItem(HWND hListView, int idx, const QuietHoursEntry* entry)
+{
+   auto startText = FormatQuietHoursTime(entry->start);
+   auto endText   = FormatQuietHoursTime(entry->end);
+   ListView_SetItemText(hListView, idx, 0, const_cast<LPWSTR>(startText.c_str()));
+   ListView_SetItemText(hListView, idx, 1, const_cast<LPWSTR>(endText.c_str()));
+}
+
+static void FreeListViewEntries(HWND hListView)
+{
+   const int count = ListView_GetItemCount(hListView);
+   for (int i = 0; i < count; ++i) {
+      LVITEM lvi{};
+      lvi.mask  = LVIF_PARAM;
+      lvi.iItem = i;
+      if (ListView_GetItem(hListView, &lvi) && lvi.lParam != 0) {
+         delete reinterpret_cast<QuietHoursEntry*>(lvi.lParam);
+      }
    }
-   return isValid;
 }
 
 static bool SaveQuietHours(
@@ -63,28 +103,11 @@ static bool SaveQuietHours(
    const int showNotifications,
    const std::vector<std::pair<DWORD, DWORD>>& times)
 {
-   //if (enabled) {
-   //   if (!IsValidTimeRange(start, end)) {
-   //      WMi18n &i18n = WMi18n::GetInstance();
-   //      TaskDialog(
-   //         nullptr,
-   //         nullptr,
-   //         PROGRAM_NAME,
-   //         i18n.GetTranslationW("settings.quiet-hours.error.invalid-time-range.title").c_str(),
-   //         i18n.GetTranslationW("settings.quiet-hours.error.invalid-time-range.text").c_str(),
-   //         TDCBF_OK_BUTTON,
-   //         TD_WARNING_ICON,
-   //         nullptr);
-   //      return false;
-   //   }
-   //}
-
    if (!settings->SetValue(SettingsKey::QUIETHOURS_ENABLE, enabled)
        || !settings->SetValue(SettingsKey::QUIETHOURS_FORCEUNMUTE, forceUnmute)
        || !settings->SetValue(SettingsKey::QUIETHOURS_NOTIFICATIONS, showNotifications)
        || !settings->StoreQuietHoursTimes(times)) {
       WMi18n &i18n = WMi18n::GetInstance();
-
       TaskDialog(
          nullptr,
          nullptr,
@@ -96,10 +119,14 @@ static bool SaveQuietHours(
          nullptr);
       return false;
    }
-
    return true;
 }
 
+
+// ===========================================================================
+//    Add / Edit sub-dialog
+// ===========================================================================
+
 static void LoadQuietHoursAddDlgTranslation(HWND hDlg, bool isEdit)
 {
    WMi18n &i18n = WMi18n::GetInstance();
@@ -109,8 +136,8 @@ static void LoadQuietHoursAddDlgTranslation(HWND hDlg, bool isEdit)
       i18n.SetItemText(hDlg, "settings.quiet-hours.add-edit.add-title");
    }
    i18n.SetItemText(hDlg, IDC_QUIET_HOURS_START_LABEL, "settings.quiet-hours.start-time-label");
-   i18n.SetItemText(hDlg, IDC_QUIET_HOURS_END_LABEL, "settings.quiet-hours.end-time-label");
-   i18n.SetItemText(hDlg, IDOK, "settings.btn-save");
+   i18n.SetItemText(hDlg, IDC_QUIET_HOURS_END_LABEL,   "settings.quiet-hours.end-time-label");
+   i18n.SetItemText(hDlg, IDOK,     "settings.btn-save");
    i18n.SetItemText(hDlg, IDCANCEL, "settings.btn-cancel");
 }
 
@@ -120,7 +147,7 @@ static void SetQuietHourPickerTime(HWND hPicker, DWORD savedTime)
    if (savedTime > 0) {
       tp.wSecond = static_cast<WORD>(savedTime % 60);
       tp.wMinute = static_cast<WORD>(((savedTime - tp.wSecond) / 60) % 60);
-      tp.wHour = static_cast<WORD>((savedTime - tp.wMinute - tp.wSecond) / 3600);
+      tp.wHour   = static_cast<WORD>((savedTime - tp.wMinute * 60 - tp.wSecond) / 3600);
    } else {
       GetLocalTime(&tp);
    }
@@ -133,7 +160,7 @@ static INT_PTR CALLBACK Settings_QuietHoursAddDlgProc(HWND hDlg, UINT msg, WPARA
    case WM_INITDIALOG:
    {
       HWND hStart = GetDlgItem(hDlg, IDC_QUIET_HOURS_START_PICKER);
-      HWND hEnd = GetDlgItem(hDlg, IDC_QUIET_HOURS_END_PICKER);
+      HWND hEnd   = GetDlgItem(hDlg, IDC_QUIET_HOURS_END_PICKER);
 
       QuietHoursEntry *qh_entry = reinterpret_cast<QuietHoursEntry *>(lParam);
       if (qh_entry == nullptr) {
@@ -141,23 +168,25 @@ static INT_PTR CALLBACK Settings_QuietHoursAddDlgProc(HWND hDlg, UINT msg, WPARA
       }
       SetWindowLongPtr(hDlg, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(qh_entry));
 
-      LoadQuietHoursAddDlgTranslation(hDlg, qh_entry != nullptr);
+      const bool isEdit = qh_entry->start != 0 || qh_entry->end != 0;
+      LoadQuietHoursAddDlgTranslation(hDlg, isEdit);
+
       if (qh_entry->start != 0) {
          SetQuietHourPickerTime(hStart, qh_entry->start);
       }
       if (qh_entry->end != 0) {
-         SetQuietHourPickerTime(hEnd, qh_entry->start);
+         SetQuietHourPickerTime(hEnd, qh_entry->end);
       }
       return TRUE;
    }
    case WM_COMMAND:
       if (LOWORD(wParam) == IDOK) {
          HWND hStart = GetDlgItem(hDlg, IDC_QUIET_HOURS_START_PICKER);
-         HWND hEnd = GetDlgItem(hDlg, IDC_QUIET_HOURS_END_PICKER);
+         HWND hEnd   = GetDlgItem(hDlg, IDC_QUIET_HOURS_END_PICKER);
          SYSTEMTIME start{};
          SYSTEMTIME end{};
          DateTime_GetSystemtime(hStart, &start);
-         DateTime_GetSystemtime(hEnd, &end);
+         DateTime_GetSystemtime(hEnd,   &end);
          if (!IsValidTimeRange(&start, &end)) {
             WMi18n &i18n = WMi18n::GetInstance();
             TaskDialog(
@@ -169,11 +198,11 @@ static INT_PTR CALLBACK Settings_QuietHoursAddDlgProc(HWND hDlg, UINT msg, WPARA
                TDCBF_OK_BUTTON,
                TD_WARNING_ICON,
                nullptr);
-            return false;
+            return FALSE;
          } else {
             auto *qh_entry = reinterpret_cast<QuietHoursEntry *>(GetWindowLongPtr(hDlg, GWLP_USERDATA));
             qh_entry->start = start.wHour * 3600 + start.wMinute * 60 + start.wSecond;
-            qh_entry->end = end.wHour * 3600 + end.wMinute * 60 + end.wSecond;
+            qh_entry->end   = end.wHour   * 3600 + end.wMinute   * 60 + end.wSecond;
             EndDialog(hDlg, 0);
          }
       } else if (LOWORD(wParam) == IDCANCEL) {
@@ -197,66 +226,67 @@ static INT_PTR CALLBACK Settings_QuietHoursAddDlgProc(HWND hDlg, UINT msg, WPARA
 static void LoadQuietHoursDlgTranslation(HWND hDlg)
 {
    WMi18n &i18n = WMi18n::GetInstance();
-
-   i18n.SetItemText(hDlg, IDC_QUIET_HOURS_DESCRIPTION, "settings.quiet-hours.intro");
-   i18n.SetItemText(hDlg, IDC_ENABLEQUIETHOURS, "settings.quiet-hours.enable");
-   i18n.SetItemText(hDlg, IDC_ENDPOINT_ADD, "settings.btn-add");
-   i18n.SetItemText(hDlg, IDC_ENDPOINT_EDIT, "settings.btn-edit");
-   i18n.SetItemText(hDlg, IDC_ENDPOINT_REMOVE, "settings.btn-remove");
-   i18n.SetItemText(hDlg, IDC_ENDPOINT_REMOVEALL, "settings.btn-remove-all");
-
-
-   //IDC_QUIET_HOURS_ADD
-//IDC_QUIET_HOURS_EDIT
-//IDC_QUIET_HOURS_REMOVE
-   i18n.SetItemText(hDlg, IDC_FORCEUNMUTE, "settings.quiet-hours.force-unmute");
+   i18n.SetItemText(hDlg, IDC_QUIET_HOURS_DESCRIPTION,           "settings.quiet-hours.intro");
+   i18n.SetItemText(hDlg, IDC_ENABLEQUIETHOURS,                  "settings.quiet-hours.enable");
+   i18n.SetItemText(hDlg, IDC_QUIET_HOURS_ADD,                   "settings.btn-add");
+   i18n.SetItemText(hDlg, IDC_QUIET_HOURS_EDIT,                  "settings.btn-edit");
+   i18n.SetItemText(hDlg, IDC_QUIET_HOURS_REMOVE,                "settings.btn-remove");
+   i18n.SetItemText(hDlg, IDC_QUIET_HOURS_REMOVEALL,             "settings.btn-remove-all");
+   i18n.SetItemText(hDlg, IDC_FORCEUNMUTE,                       "settings.quiet-hours.force-unmute");
    i18n.SetItemText(hDlg, IDC_QUIET_HOURS_FORCE_UNMUTE_DESCRIPTION, "settings.quiet-hours.force-unmute-description");
-   i18n.SetItemText(hDlg, IDC_SHOWNOTIFICATIONS, "settings.quiet-hours.show-notifications");
+   i18n.SetItemText(hDlg, IDC_SHOWNOTIFICATIONS,                 "settings.quiet-hours.show-notifications");
 }
 
 static void SetupListView(HWND hListView)
 {
+   ListView_SetExtendedListViewStyle(hListView, LVS_EX_FULLROWSELECT);
+
    auto& i18n = WMi18n::GetInstance();
    const auto textBegin = i18n.GetTranslationW("settings.quiet-hours.start-time-label");
-   const auto textEnd = i18n.GetTranslationW("settings.quiet-hours.end-time-label");
+   const auto textEnd   = i18n.GetTranslationW("settings.quiet-hours.end-time-label");
 
-   int order = 0;
    LVCOLUMN lvCol{};
-   lvCol.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_ORDER;
-   lvCol.fmt = LVCFMT_LEFT;
-   lvCol.cx = 100;
-   lvCol.pszText = const_cast<LPWSTR>(textBegin.c_str());
+   lvCol.mask   = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_ORDER;
+   lvCol.fmt    = LVCFMT_LEFT;
+   lvCol.cx     = 75;
+   lvCol.pszText    = const_cast<LPWSTR>(textBegin.c_str());
    lvCol.cchTextMax = static_cast<int>(textBegin.length());
-   lvCol.iOrder = order++;
+   lvCol.iOrder = 0;
    ListView_InsertColumn(hListView, 0, &lvCol);
 
-   lvCol.pszText = const_cast<LPWSTR>(textEnd.c_str());
+   lvCol.cx     = 75;
+   lvCol.pszText    = const_cast<LPWSTR>(textEnd.c_str());
    lvCol.cchTextMax = static_cast<int>(textEnd.length());
-   lvCol.iOrder = order++;
-   ListView_InsertColumn(hListView, 0, &lvCol);
+   lvCol.iOrder = 1;
+   ListView_InsertColumn(hListView, 1, &lvCol);
+}
+
+static void UpdateButtonStates(HWND hDlg, HWND hListView, bool qhEnabled)
+{
+   const bool hasSelection = ListView_GetNextItem(hListView, -1, LVNI_SELECTED) != -1;
+   const bool hasItems     = ListView_GetItemCount(hListView) > 0;
+   EnableWindow(GetDlgItem(hDlg, IDC_QUIET_HOURS_ADD),       qhEnabled);
+   EnableWindow(GetDlgItem(hDlg, IDC_QUIET_HOURS_EDIT),      qhEnabled && hasSelection);
+   EnableWindow(GetDlgItem(hDlg, IDC_QUIET_HOURS_REMOVE),    qhEnabled && hasSelection);
+   EnableWindow(GetDlgItem(hDlg, IDC_QUIET_HOURS_REMOVEALL), qhEnabled && hasItems);
 }
 
 INT_PTR CALLBACK Settings_QuietHoursDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 {
-   UNREFERENCED_PARAMETER(lParam);
    switch (msg) {
    case WM_INITDIALOG:
    {
-      HWND hEnable = GetDlgItem(hDlg, IDC_ENABLEQUIETHOURS);
-      HWND hForce = GetDlgItem(hDlg, IDC_FORCEUNMUTE);
-      HWND hNotify = GetDlgItem(hDlg, IDC_SHOWNOTIFICATIONS);
+      HWND hEnable          = GetDlgItem(hDlg, IDC_ENABLEQUIETHOURS);
+      HWND hForce           = GetDlgItem(hDlg, IDC_FORCEUNMUTE);
+      HWND hNotify          = GetDlgItem(hDlg, IDC_SHOWNOTIFICATIONS);
       HWND hQuietHoursTimes = GetDlgItem(hDlg, IDC_QUIET_HOURS_TIMES);
-      HWND hAdd = GetDlgItem(hDlg, IDC_QUIET_HOURS_ADD);
-      HWND hEdit = GetDlgItem(hDlg, IDC_QUIET_HOURS_EDIT);
-      HWND hDelete = GetDlgItem(hDlg, IDC_QUIET_HOURS_REMOVE);
-      HWND hDeleteAll = GetDlgItem(hDlg, IDC_QUIET_HOURS_REMOVEALL);
 
       auto settings = reinterpret_cast<WMSettings *>(lParam);
       assert(settings != nullptr);
 
       auto qhdata = new QuietHoursDlgData();
       assert(qhdata != nullptr);
-      qhdata->settings = reinterpret_cast<WMSettings *>(lParam);
+      qhdata->settings = settings;
       SetWindowLongPtr(hDlg, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(qhdata));
 
       if (IsAppThemed()) {
@@ -264,65 +294,68 @@ INT_PTR CALLBACK Settings_QuietHoursDlgProc(HWND hDlg, UINT msg, WPARAM wParam,
       }
       LoadQuietHoursDlgTranslation(hDlg);
 
-      DWORD qhEnabled = !!settings->QueryValue(SettingsKey::QUIETHOURS_ENABLE);
+      const DWORD qhEnabled = !!settings->QueryValue(SettingsKey::QUIETHOURS_ENABLE);
       Button_SetCheck(hEnable, qhEnabled ? BST_CHECKED : BST_UNCHECKED);
 
-      DWORD qhForceUnmute = !!settings->QueryValue(SettingsKey::QUIETHOURS_FORCEUNMUTE);
+      const DWORD qhForceUnmute = !!settings->QueryValue(SettingsKey::QUIETHOURS_FORCEUNMUTE);
       Button_SetCheck(hForce, qhForceUnmute ? BST_CHECKED : BST_UNCHECKED);
 
-      DWORD qhNotifications = !!settings->QueryValue(SettingsKey::QUIETHOURS_NOTIFICATIONS);
+      const DWORD qhNotifications = !!settings->QueryValue(SettingsKey::QUIETHOURS_NOTIFICATIONS);
       Button_SetCheck(hNotify, qhNotifications ? BST_CHECKED : BST_UNCHECKED);
 
       SetupListView(hQuietHoursTimes);
 
-      qhdata->quietHoursTimes = settings->GetQuietHoursTimes();
-      for (const auto &qh_time : qhdata->quietHoursTimes) {
-         LVITEM item{};
-         item.mask = LVIF_COLUMNS | LVIF_PARAM | LVIF_TEXT;
-         // item.
-         ListView_InsertItem(hQuietHoursTimes, &item) ;
+      for (const auto &t : settings->GetQuietHoursTimes()) {
+         auto* entry = new QuietHoursEntry();
+         entry->start = t.first;
+         entry->end   = t.second;
+         AddQuietHoursEntryToListView(hQuietHoursTimes, entry);
       }
 
-      EnableWindow(hForce, qhEnabled);
+      EnableWindow(hForce,  qhEnabled);
       EnableWindow(hNotify, qhEnabled);
       EnableWindow(hQuietHoursTimes, qhEnabled);
-      EnableWindow(hAdd, qhEnabled);
-      EnableWindow(hEdit, qhEnabled);
-      EnableWindow(hDelete, qhEnabled);
-      EnableWindow(hDeleteAll, qhEnabled);
+      UpdateButtonStates(hDlg, hQuietHoursTimes, !!qhEnabled);
 
       return TRUE;
    }
+   case WM_NOTIFY:
+   {
+      const NMHDR* pnmh = reinterpret_cast<const NMHDR*>(lParam);
+      if (pnmh->idFrom == IDC_QUIET_HOURS_TIMES && pnmh->code == LVN_ITEMCHANGED) {
+         HWND hQuietHoursTimes = GetDlgItem(hDlg, IDC_QUIET_HOURS_TIMES);
+         const bool qhEnabled  = Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLEQUIETHOURS)) == BST_CHECKED;
+         UpdateButtonStates(hDlg, hQuietHoursTimes, qhEnabled);
+      }
+      return 0;
+   }
    case WM_SAVESETTINGS:
    {
-      HWND hEnable  = GetDlgItem(hDlg, IDC_ENABLEQUIETHOURS);
-      HWND hForce  = GetDlgItem(hDlg, IDC_FORCEUNMUTE);
-      HWND hNotify = GetDlgItem(hDlg, IDC_SHOWNOTIFICATIONS);
+      HWND hEnable          = GetDlgItem(hDlg, IDC_ENABLEQUIETHOURS);
+      HWND hForce           = GetDlgItem(hDlg, IDC_FORCEUNMUTE);
+      HWND hNotify          = GetDlgItem(hDlg, IDC_SHOWNOTIFICATIONS);
       HWND hQuietHoursTimes = GetDlgItem(hDlg, IDC_QUIET_HOURS_TIMES);
       auto qhdata = reinterpret_cast<QuietHoursDlgData *>(GetWindowLongPtr(hDlg, GWLP_USERDATA));
-      int qhEnabled       = Button_GetCheck(hEnable) == BST_CHECKED;
-      int qhForceUnmute   = Button_GetCheck(hForce)  == BST_CHECKED;
-      int qhNotifications = Button_GetCheck(hNotify) == BST_CHECKED;
-      qhdata->settings->SetValue(SettingsKey::QUIETHOURS_ENABLE, qhEnabled);
-
-      // Get number of items from IDC_QUIET_HOURS_TIMES
-      // Get each item from IDC_QUIET_HOURS_TIMES
-      // Read meta data of each item
+
+      const int qhEnabled       = Button_GetCheck(hEnable) == BST_CHECKED;
+      const int qhForceUnmute   = Button_GetCheck(hForce)  == BST_CHECKED;
+      const int qhNotifications = Button_GetCheck(hNotify) == BST_CHECKED;
+
       const int entries = ListView_GetItemCount(hQuietHoursTimes);
-      std::vector<std::pair<DWORD, DWORD>> times(entries);
+      std::vector<std::pair<DWORD, DWORD>> times;
+      times.reserve(entries);
       for (int i = 0; i < entries; ++i) {
          LVITEM lvi{};
          lvi.iItem = i;
-         lvi.mask = LVIF_PARAM;
-         if (ListView_GetItem(hQuietHoursTimes, &lvi)) {
-            QuietHoursEntry* qh_entry = reinterpret_cast<QuietHoursEntry*>(lvi.lParam);
-            if (qh_entry != nullptr) {
-               times[i] = std::make_pair(qh_entry->start, qh_entry->end);
-            }
+         lvi.mask  = LVIF_PARAM;
+         if (ListView_GetItem(hQuietHoursTimes, &lvi) && lvi.lParam != 0) {
+            const QuietHoursEntry* qh_entry = reinterpret_cast<QuietHoursEntry*>(lvi.lParam);
+            times.emplace_back(qh_entry->start, qh_entry->end);
          }
       }
 
       if (SaveQuietHours(qhdata->settings, qhEnabled, qhForceUnmute, qhNotifications, times)) {
+         FreeListViewEntries(hQuietHoursTimes);
          delete qhdata;
          EndDialog(hDlg, 0);
       }
@@ -330,51 +363,77 @@ INT_PTR CALLBACK Settings_QuietHoursDlgProc(HWND hDlg, UINT msg, WPARAM wParam,
    }
    case WM_COMMAND:
    {
-      HWND hEnable = GetDlgItem(hDlg, IDC_ENABLEQUIETHOURS);
-      HWND hForce  = GetDlgItem(hDlg, IDC_FORCEUNMUTE);
-      HWND hNotify = GetDlgItem(hDlg, IDC_SHOWNOTIFICATIONS);
-      HWND hQuietHoursTimes  = GetDlgItem(hDlg, IDC_QUIET_HOURS_TIMES);
-      HWND hAdd = GetDlgItem(hDlg, IDC_QUIET_HOURS_ADD);
-      HWND hEdit = GetDlgItem(hDlg, IDC_QUIET_HOURS_EDIT);
-      HWND hDelete = GetDlgItem(hDlg, IDC_QUIET_HOURS_REMOVE);
-      HWND hDeleteAll = GetDlgItem(hDlg, IDC_QUIET_HOURS_REMOVEALL);
-      
+      HWND hEnable          = GetDlgItem(hDlg, IDC_ENABLEQUIETHOURS);
+      HWND hForce           = GetDlgItem(hDlg, IDC_FORCEUNMUTE);
+      HWND hNotify          = GetDlgItem(hDlg, IDC_SHOWNOTIFICATIONS);
+      HWND hQuietHoursTimes = GetDlgItem(hDlg, IDC_QUIET_HOURS_TIMES);
+
       if (LOWORD(wParam) == IDC_ENABLEQUIETHOURS) {
-         int qhEnabled = Button_GetCheck(hEnable) == BST_CHECKED;
-         EnableWindow(hQuietHoursTimes, qhEnabled);
-         EnableWindow(hAdd, qhEnabled);
-         EnableWindow(hEdit, qhEnabled);
-         EnableWindow(hDelete, qhEnabled);
-         EnableWindow(hDeleteAll, qhEnabled);
+         const bool qhEnabled = Button_GetCheck(hEnable) == BST_CHECKED;
+         EnableWindow(hForce,  qhEnabled);
          EnableWindow(hNotify, qhEnabled);
-         EnableWindow(hForce, qhEnabled);
-         
+         EnableWindow(hQuietHoursTimes, qhEnabled);
+         UpdateButtonStates(hDlg, hQuietHoursTimes, qhEnabled);
+
       } else if (LOWORD(wParam) == IDC_QUIET_HOURS_ADD) {
-         QuietHoursEntry qh_entry;
+         auto* qh_entry = new QuietHoursEntry();
          if (DialogBoxParam(
                nullptr,
                MAKEINTRESOURCE(IDD_SETTINGS_QUIETHOURS_ADD),
                hDlg,
                Settings_QuietHoursAddDlgProc,
-               reinterpret_cast<LPARAM>(&qh_entry)) == 0) {
-            // Add entry to ListView
-            // TODO
+               reinterpret_cast<LPARAM>(qh_entry)) == 0) {
+            AddQuietHoursEntryToListView(hQuietHoursTimes, qh_entry);
+            UpdateButtonStates(hDlg, hQuietHoursTimes, true);
+         } else {
+            delete qh_entry;
          }
+
       } else if (LOWORD(wParam) == IDC_QUIET_HOURS_EDIT) {
-         // Get selected item
-         // Open dialog with selected item data
-         // Update ListView item
-         // TODO
+         const int sel = ListView_GetNextItem(hQuietHoursTimes, -1, LVNI_SELECTED);
+         if (sel != -1) {
+            LVITEM lvi{};
+            lvi.mask  = LVIF_PARAM;
+            lvi.iItem = sel;
+            if (ListView_GetItem(hQuietHoursTimes, &lvi) && lvi.lParam != 0) {
+               QuietHoursEntry* entry = reinterpret_cast<QuietHoursEntry*>(lvi.lParam);
+               QuietHoursEntry editCopy = *entry;
+               if (DialogBoxParam(
+                     nullptr,
+                     MAKEINTRESOURCE(IDD_SETTINGS_QUIETHOURS_ADD),
+                     hDlg,
+                     Settings_QuietHoursAddDlgProc,
+                     reinterpret_cast<LPARAM>(&editCopy)) == 0) {
+                  entry->start = editCopy.start;
+                  entry->end   = editCopy.end;
+                  UpdateListViewItem(hQuietHoursTimes, sel, entry);
+               }
+            }
+         }
+
       } else if (LOWORD(wParam) == IDC_QUIET_HOURS_REMOVE) {
-         // Get selected item
-         // Remove from ListView
-         // TODO
+         const int sel = ListView_GetNextItem(hQuietHoursTimes, -1, LVNI_SELECTED);
+         if (sel != -1) {
+            LVITEM lvi{};
+            lvi.mask  = LVIF_PARAM;
+            lvi.iItem = sel;
+            if (ListView_GetItem(hQuietHoursTimes, &lvi) && lvi.lParam != 0) {
+               delete reinterpret_cast<QuietHoursEntry*>(lvi.lParam);
+            }
+            ListView_DeleteItem(hQuietHoursTimes, sel);
+            UpdateButtonStates(hDlg, hQuietHoursTimes, true);
+         }
+
       } else if (LOWORD(wParam) == IDC_QUIET_HOURS_REMOVEALL) {
+         FreeListViewEntries(hQuietHoursTimes);
          ListView_DeleteAllItems(hQuietHoursTimes);
+         UpdateButtonStates(hDlg, hQuietHoursTimes, true);
       }
       return 0;
    }
    case WM_CLOSE: {
+      HWND hQuietHoursTimes = GetDlgItem(hDlg, IDC_QUIET_HOURS_TIMES);
+      FreeListViewEntries(hQuietHoursTimes);
       auto qhdata = reinterpret_cast<QuietHoursDlgData *>(GetWindowLongPtr(hDlg, GWLP_USERDATA));
       delete qhdata;
       EndDialog(hDlg, 0);
index e7469e481b8bb156cfe30c33fb6baff5e7e5f98b..14a497dc942085e65c4e10ab7e89c507b401f2ab 100644 (file)
@@ -850,12 +850,12 @@ std::vector<std::pair<DWORD, DWORD>> WMSettings::GetQuietHoursTimes()
    }
 
    std::vector<std::pair<DWORD, DWORD>> times;
-   for (DWORD valIdx = 0; valIdx < numEntries; valIdx += 2) {
+   for (DWORD valIdx = 0; valIdx < numEntries / 2; valIdx += 1) {
       const std::wstring keyStart = L"Start" + std::to_wstring(valIdx);
       const std::wstring keyEnd = L"End" + std::to_wstring(valIdx);
 
       std::pair<DWORD, DWORD> timeEntry{};
-      DWORD size{};
+      DWORD size = sizeof(DWORD);
       regError = RegQueryValueExW(
          hQuietHoursTimesKey_,
          keyStart.c_str(),
@@ -865,10 +865,13 @@ std::vector<std::pair<DWORD, DWORD>> WMSettings::GetQuietHoursTimes()
          &size);
       if (regError != ERROR_SUCCESS) {
          WMLog::GetInstance().LogError(
-            L"Failed to read entry \"%s\" while initializing quiet hours",
-            keyStart.c_str());
+            L"Failed to read entry \"%s\" while initializing quiet hours (%d)",
+            keyStart.c_str(), regError
+        );
          continue;
       }
+
+      size = sizeof(DWORD);
       regError = RegQueryValueExW(
          hQuietHoursTimesKey_,
          keyEnd.c_str(),
@@ -878,8 +881,8 @@ std::vector<std::pair<DWORD, DWORD>> WMSettings::GetQuietHoursTimes()
          &size);
       if (regError != ERROR_SUCCESS) {
          WMLog::GetInstance().LogError(
-            L"Failed to read entry \"%s\" while initializing quiet hours",
-            keyStart.c_str());
+            L"Failed to read entry \"%s\" while initializing quiet hours (%d)",
+            keyStart.c_str(), regError);
          continue;
       }
       times.push_back(std::move(timeEntry));
index f15495e9c2e31e7d06f190ff9a5d0de7592009b3..2e8d6c5fee72498bbfe07fdbbb6319227d3c6814 100644 (file)
@@ -105,7 +105,7 @@ BEGIN
     LTEXT           "If force unmute is enabled, WinMute will unmute your workstation when quiet hours end and not take into account if your workstation was already muted before quiet hours started.",IDC_QUIET_HOURS_FORCE_UNMUTE_DESCRIPTION,33,140,204,37
     CONTROL         "Show quiet hours notifications",IDC_SHOWNOTIFICATIONS,
                     "Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,175,180,21
-    CONTROL         "",IDC_QUIET_HOURS_TIMES,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,22,47,155,72
+    CONTROL         "",IDC_QUIET_HOURS_TIMES,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,22,47,155,72
     PUSHBUTTON      "Add",IDC_QUIET_HOURS_ADD,183,46,56,16
     PUSHBUTTON      "Edit",IDC_QUIET_HOURS_EDIT,183,65,56,16
     PUSHBUTTON      "Remove",IDC_QUIET_HOURS_REMOVE,183,84,56,16