aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Ankarström <john@ankarstrom.se>2022-08-16 16:09:51 +0200
committerJohn Ankarström <john@ankarstrom.se>2022-08-16 16:09:51 +0200
commit8351d4c42c76584415e02a40d41f497a8f042c72 (patch)
tree6df66783c16130f943c78a8e09d6dfa2ef0359fe
parentab621173afc918797a4ea68b5d6ceee7cc043f72 (diff)
downloadEpisodeBrowser-8351d4c42c76584415e02a40d41f497a8f042c72.tar.gz
EpisodeListView: Use FileView consistently.
-rw-r--r--c/data.h1
-rw-r--r--c/episodelistview.cpp114
-rw-r--r--c/episodelistview.h3
-rw-r--r--c/main.cpp67
-rw-r--r--c/test.cpp10
5 files changed, 96 insertions, 99 deletions
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<ElvDataA*>(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<HMENU>(IDC_EPISODELISTVIEW), 0)
+ : ListView(hWndParent, reinterpret_cast<HMENU>(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<ElvDataA*>(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<NMLISTVIEW*>(lParam);
@@ -53,7 +117,7 @@ LRESULT EpisodeListView::HandleNotify(const LPARAM lParam)
case LVN_GETDISPINFO: /* Display item. */
{
NMLVDISPINFO* const nm = reinterpret_cast<NMLVDISPINFO*>(lParam);
- ElvDataA& e = m_vData.at(nm->item.lParam-1);
+ ElvDataA& e = reinterpret_cast<ElvDataA*>(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<ElvDataA*>(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<ElvDataA*>(elv->m_fv)[lvi1.lParam-1];
+ const ElvDataA& e2 = static_cast<ElvDataA*>(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<ElvDataA*>(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<ElvDataA> 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<unsigned char*>(static_cast<ElvDataA*>(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<unsigned char*>(static_cast<ElvDataA*>(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<ElvDataA*>(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");
}