From 8351d4c42c76584415e02a40d41f497a8f042c72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Tue, 16 Aug 2022 16:09:51 +0200 Subject: EpisodeListView: Use FileView consistently. --- c/data.h | 1 + c/episodelistview.cpp | 114 ++++++++++++++++++++++++++++++++++++++------------ c/episodelistview.h | 3 +- c/main.cpp | 67 +---------------------------- c/test.cpp | 10 ++--- 5 files changed, 96 insertions(+), 99 deletions(-) (limited to 'c') diff --git a/c/data.h b/c/data.h index e584442..2cc4c14 100644 --- a/c/data.h +++ b/c/data.h @@ -35,6 +35,7 @@ struct FileView FileView(const wchar_t* filename, size_t cb); ~FileView(); inline operator unsigned char*() { return view; } + inline operator ElvDataA*() { return reinterpret_cast(view); } HANDLE hf; HANDLE hm; unsigned char* view; diff --git a/c/episodelistview.cpp b/c/episodelistview.cpp index 3f2104f..0451132 100644 --- a/c/episodelistview.cpp +++ b/c/episodelistview.cpp @@ -13,7 +13,8 @@ #include "win.h" EpisodeListView::EpisodeListView(const HWND hWndParent) - : ListView(hWndParent, reinterpret_cast(IDC_EPISODELISTVIEW), 0) + : ListView(hWndParent, reinterpret_cast(IDC_EPISODELISTVIEW), 0), + m_fv(L"elvdata.dat", sizeof(ElvDataA)*8192) { LVCOLUMN lvc; @@ -45,6 +46,69 @@ void EpisodeListView::EnsureFocusVisible() ListView_EnsureVisible(hWnd, iEpFocus, TRUE); } +void EpisodeListView::HandleContextMenu(const WORD command) +{ + int cNotFound = 0; + + /* Look through selected items, applying the + * selected command to each one. */ + + LVITEM lvi = {LVIF_PARAM, -1}; + while (FindNextItem(&lvi, LVNI_SELECTED)) { + ElvDataA& e = static_cast(m_fv)[lvi.lParam-1]; + + if (ID_SUBGROUP(command) == IDG_CTX_RATE) { + /* Process rate commands. */ + if (e.rating = ID_RATING(command)) + Swprintf(e.sRating, L"%d", e.rating); + else + e.sRating[0] = 0; + } else { + /* Process other commands. */ + switch (command) { + case IDM_WATCH_LOCALLY: + if (!Pl("local_episode","open_episode_locally",lvi.lParam)) + cNotFound++; + break; + + case IDM_WATCH_ONLINE: + Pl("local_episode","open_episode_online",lvi.lParam); + break; + + case IDM_TOGGLE: + e.bWatched = !e.bWatched; + break; + + case IDM_FORGET: + Pl("track_episodes","forget_episode",lvi.lParam); + Pl("track_episodes","update_tracked_episodes"); + break; + + case IDM_WIKI: + Pl("episode_data","open_episode_wiki",lvi.lParam); + break; + } + } + } + + Redraw(); + + if (ID_SUBGROUP(command) == IDG_CTX_RATE) { + /* If ratings changed, the episodes may need to be resorted. */ + Sort(); + ShowFocus(); + } else if (cNotFound) { + /* Show warning if local episodes were not found. */ + if (cNotFound == 1) + EBMessageBox(L"Episode could not be opened locally.", L"Error", MB_ICONWARNING); + else { + wchar_t msg[64] = {0}; + Swprintf(msg, L"%d episodes could not be opened locally.", cNotFound); + EBMessageBox(msg, L"Error", MB_ICONWARNING); + } + } +} + LRESULT EpisodeListView::HandleNotify(const LPARAM lParam) { const NMLISTVIEW* const nm = reinterpret_cast(lParam); @@ -53,7 +117,7 @@ LRESULT EpisodeListView::HandleNotify(const LPARAM lParam) case LVN_GETDISPINFO: /* Display item. */ { NMLVDISPINFO* const nm = reinterpret_cast(lParam); - ElvDataA& e = m_vData.at(nm->item.lParam-1); + ElvDataA& e = reinterpret_cast(m_fv.view)[nm->item.lParam-1]; wchar_t* vs[] = {e.siEp, e.title, e.sRating}; /* ELVSIEPISODE, ELVSITITLE, ELVSIRATING */ nm->item.pszText = vs[nm->item.iSubItem]; return 0; @@ -101,12 +165,15 @@ LRESULT EpisodeListView::HandleNotify(const LPARAM lParam) return CDRF_NOTIFYITEMDRAW; break; case CDDS_ITEMPREPAINT: - if (!Pl("track_episodes","watched",nm->nmcd.lItemlParam)) { + { + const ElvDataA& e = static_cast(m_fv)[nm->nmcd.lItemlParam-1]; + if (!e.bWatched) { extern HFONT g_hfBold; Require(SelectObject(nm->nmcd.hdc, g_hfBold)); return CDRF_NEWFONT; } break; + } } return 0; } @@ -218,7 +285,7 @@ void EpisodeListView::SelectUnwatched(int dir) lvfi.lParam = lviFocus.lParam; do { - if (!Pl("track_episodes",dir > 0? "push_unwatched": "previous_unwatched", + if (!Pl("track_episodes",dir > 0? "next_unwatched": "previous_unwatched", lvfi.lParam,&iEpNew)) return; @@ -262,30 +329,26 @@ int CALLBACK EpisodeListView::SortProc(const LPARAM iItem1, const LPARAM iItem2, * If m_iSortCol is negative, the order is descending. */ const int order = Cmp(elv->m_iSortCol, 0); + const ElvDataA& e1 = static_cast(elv->m_fv)[lvi1.lParam-1]; + const ElvDataA& e2 = static_cast(elv->m_fv)[lvi2.lParam-1]; + switch (abs(elv->m_iSortCol)-1) { case ELVSIEPISODE: return order*Cmp(lvi1.lParam, lvi2.lParam); case ELVSIRATING: { - int rating1, rating2; - rating1 = elv->m_iSortCol > 0? 99: -1; - rating2 = elv->m_iSortCol > 0? 99: -1; - Pl("episode_data","episode_rating",lvi1.lParam,&rating1); - Pl("episode_data","episode_rating",lvi2.lParam,&rating2); + int rating1 = e1.rating; + int rating2 = e2.rating; + if (!rating1) + rating1 = elv->m_iSortCol > 0? 99: -1; + if (!rating2) + rating2 = elv->m_iSortCol > 0? 99: -1; if (rating1 == rating2) return Cmp(lvi1.lParam, lvi2.lParam); return order*Cmp(rating1, rating2); } case ELVSITITLE: - { - Mark m; - WcharPtr s1, s2; - if (!Pl("episode_data","episode_title",lvi1.lParam,&s1)) - return 0; - if (!Pl("episode_data","episode_title",lvi2.lParam,&s2)) - return 0; - return order*_wcsicmp(s1, s2); - } + return order*_wcsicmp(e1.title, e2.title); default: return 0; } @@ -333,24 +396,23 @@ void EpisodeListView::Update() /* Retrieve episode data and add list view items. */ SendMessage(hWnd, WM_SETREDRAW, FALSE, 0); - m_vData.clear(); ListView_DeleteAllItems(hWnd); for (int iEp = 1; iEp <= cEp; iEp++) { - ElvDataA e; + ElvDataA e = static_cast(m_fv)[iEp-1]; - if (!FromProlog(iEp, e)) - goto push; + if (!e.siEp[0]) + continue; if (extern char g_limitScreenwriter[]; g_limitScreenwriter[0] && !Pl("episode_data","episode_datum",iEp, "Screenwriter",g_limitScreenwriter)) - goto push; + continue; if (extern int g_bViewWatched; !g_bViewWatched && e.bWatched) - goto push; + continue; if (extern int g_bViewTVOriginal; !g_bViewTVOriginal && e.bTVOriginal) - goto push; + continue; /* Insert item. */ lviEpisode.iItem = cItem++; @@ -361,8 +423,6 @@ void EpisodeListView::Update() ListView_SetItemText(hWnd, lviEpisode.iItem, ELVSITITLE, LPSTR_TEXTCALLBACK); ListView_SetItemText(hWnd, lviEpisode.iItem, ELVSIRATING, LPSTR_TEXTCALLBACK); - - push: m_vData.push_back(std::move(e)); } /* Show number of displayed items in status bar. */ diff --git a/c/episodelistview.h b/c/episodelistview.h index 0fcf444..0604d15 100644 --- a/c/episodelistview.h +++ b/c/episodelistview.h @@ -16,6 +16,7 @@ struct EpisodeListView : public ListView { EpisodeListView(HWND hWndParent); void EnsureFocusVisible(); + void HandleContextMenu(WORD); LRESULT HandleNotify(LPARAM lParam); void Redraw(); void ResizeColumns(int w) override; @@ -32,7 +33,7 @@ struct EpisodeListView : public ListView private: int m_iSortCol; static int CALLBACK SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM extra); - std::vector m_vData; + FileView m_fv; }; #endif diff --git a/c/main.cpp b/c/main.cpp index 14b4904..9a4bcf2 100644 --- a/c/main.cpp +++ b/c/main.cpp @@ -66,8 +66,6 @@ static void InitializeMainWindow(HWND); static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); /* Process main menu commands. */ static void HandleMainMenu(HWND, WORD); -/* Process context menu commands. */ -static void HandleContextMenu(HWND, WORD); /* Call Prolog predicate in other thread, if available. */ static void WaitFor(const char*, const char*); /* Handle messages to Help > About dialog. */ @@ -323,7 +321,7 @@ LRESULT CALLBACK WndProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam, HandleMainMenu(hWnd, command); return 0; case IDG_CTX: - HandleContextMenu(hWnd, command); + g_elv->HandleContextMenu(command); return 0; default: return 0; @@ -469,69 +467,6 @@ void HandleMainMenu(const HWND hWnd, const WORD command) } } -void HandleContextMenu(const HWND, const WORD command) -{ - int cNotFound = 0; - - /* Look through selected items, applying the - * selected command to each one. */ - - LVITEM lvi = {LVIF_PARAM, -1}; - while (g_elv->FindNextItem(&lvi, LVNI_SELECTED)) { - if (ID_SUBGROUP(command) == IDG_CTX_RATE) { - /* Process rate commands. */ - Pl("episode_data","rate_episode",lvi.lParam,ID_RATING(command)); - } else { - /* Process other commands. */ - switch (command) { - case IDM_WATCH_LOCALLY: - if (!Pl("local_episode","open_episode_locally",lvi.lParam)) - cNotFound++; - break; - - case IDM_WATCH_ONLINE: - Pl("local_episode","open_episode_online",lvi.lParam); - break; - - case IDM_TOGGLE: - Pl("track_episodes","toggle_episode",lvi.lParam); - break; - - case IDM_FORGET: - Pl("track_episodes","forget_episode",lvi.lParam); - Pl("track_episodes","update_tracked_episodes"); - break; - - case IDM_LOOKUP: /* TODO: Remove IDM_LOOKUP. */ - Pl("episode_data","retract_episode",lvi.lParam); - g_dlv->ShowEpisode(lvi.lParam); - break; - - case IDM_WIKI: - Pl("episode_data","open_episode_wiki",lvi.lParam); - break; - } - } - } - - g_elv->Redraw(); - - if (ID_SUBGROUP(command) == IDG_CTX_RATE) { - /* If ratings changed, the episodes may need to be resorted. */ - g_elv->Sort(); - g_elv->ShowFocus(); - } else if (cNotFound) { - /* Show warning if local episodes were not found. */ - if (cNotFound == 1) - EBMessageBox(L"Episode could not be opened locally.", L"Error", MB_ICONWARNING); - else { - wchar_t msg[64] = {0}; - Swprintf(msg, L"%d episodes could not be opened locally.", cNotFound); - EBMessageBox(msg, L"Error", MB_ICONWARNING); - } - } -} - void WaitFor(const char* mod, const char* pred) { /* WaitFor uses a thread on the Prolog side to execute a diff --git a/c/test.cpp b/c/test.cpp index 9402eed..cecc408 100644 --- a/c/test.cpp +++ b/c/test.cpp @@ -56,7 +56,7 @@ TESTS { FileView fv{L"tmp.dat", sizeof(ElvDataA)*2}; Write(fv, e1_0); - Write(fv+sizeof(ElvDataA), e2_0); + Write(reinterpret_cast(static_cast(fv)+1), e2_0); } { FileView fv{L"tmp.dat", sizeof(ElvDataA)}; @@ -76,7 +76,7 @@ TESTS } { FileView fv{L"tmp.dat", sizeof(ElvDataA)*2}; - ElvDataA* e2 = Read(fv+sizeof(ElvDataA)); + ElvDataA* e2 = Read(reinterpret_cast(static_cast(fv)+1)); if (e2_0.rating != e2->rating) FAIL("rating is different (%d/%d)", e2_0.rating, e2->rating); if (e2_0.bWatched != e2->bWatched) @@ -100,7 +100,7 @@ TESTS return; { - FileView fv{L"tmp.dat", sizeof(ElvDataA)*cEp}; + FileView fv{L"tmp.dat", sizeof(ElvDataA)*8192}; unsigned char* p = fv; for (int iEp = 1; iEp <= cEp; iEp++) { @@ -111,9 +111,9 @@ TESTS } } { - FileView fv{L"tmp.dat", sizeof(ElvDataA)*cEp}; + FileView fv{L"tmp.dat", sizeof(ElvDataA)*8192}; ElvDataA* ve = reinterpret_cast(fv.view); - ElvDataA e = ve[9]; + ElvDataA& e = ve[9]; if (wcscmp(e.title, L"Pro Soccer Player Blackmail Case") != 0) FAIL("title is not correct"); } -- cgit v1.2.3