diff options
author | John Ankarström <john@ankarstrom.se> | 2022-04-05 04:15:20 +0200 |
---|---|---|
committer | John Ankarström <john@ankarstrom.se> | 2022-04-05 04:15:20 +0200 |
commit | 4d6cbcdc97fd79befca82ed9ddc0d96ce86f744f (patch) | |
tree | 07c4cb66a4914c4cd38b723928c69d39b507c451 | |
parent | ec4bf0b3d1fac134793dd4cccff24e42ce682f09 (diff) | |
download | EpisodeBrowser-4d6cbcdc97fd79befca82ed9ddc0d96ce86f744f.tar.gz |
Add episode ratings.
-rw-r--r-- | c/episodelistview.c | 56 | ||||
-rw-r--r-- | c/main.c | 50 | ||||
-rw-r--r-- | c/resource.h | 6 | ||||
-rw-r--r-- | c/resource.rc | 9 | ||||
-rw-r--r-- | pl/episode_data.pl | 29 |
5 files changed, 120 insertions, 30 deletions
diff --git a/c/episodelistview.c b/c/episodelistview.c index 6b00b31..26122c7 100644 --- a/c/episodelistview.c +++ b/c/episodelistview.c @@ -25,9 +25,14 @@ ElvCreate() ListView_InsertColumn(HElv, 0, &lvc); lvc.iSubItem = 1; + lvc.pszText = TEXT("/"); + lvc.cx = Dpi(20); + ListView_InsertColumn(HElv, 1, &lvc); + + lvc.iSubItem = 1; lvc.pszText = TEXT("Title"); lvc.cx = 500; - ListView_InsertColumn(HElv, 1, &lvc); + ListView_InsertColumn(HElv, 2, &lvc); return HElv; } @@ -145,7 +150,9 @@ ElvSelectRecent() iItem = ListView_FindItem(HElv, -1, &lvfi); if (iItem == -1) return; -s: ElvSetTop(iItem > 5? iItem-5: 0); +s: + ListView_SetItemState(HElv, -1, LVIF_STATE, LVIS_SELECTED); + ElvSetTop(iItem > 5? iItem-5: 0); ListView_SetItemState(HElv, iItem, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED); LpLviElvSelection->iItem = iItem; @@ -159,7 +166,7 @@ void ElvUpdate() { int iEpisodes, iTop; - LVITEM lviEpisode, lviName; + LVITEM lviEpisode, lviName, lviRating; term_t t; SendMessage(HElv, WM_SETREDRAW, FALSE, 0); @@ -168,6 +175,7 @@ ElvUpdate() lviEpisode.mask = LVIF_TEXT|LVIF_PARAM; lviName.mask = LVIF_TEXT; + lviRating.mask = LVIF_TEXT; t = T(1); P("episode_data","ensure_episode_data",0,t) return; @@ -176,19 +184,28 @@ ElvUpdate() for (int i = 0; i < iEpisodes; i++) { char *szName; - int cb; - TCHAR *tszEpisode, *tszName; - term_t t; + int cb, iRating; + TCHAR *tszEpisode, *tszName, tszRating[10]; + term_t t, t2; + + tszName = NULL; + tszRating[0] = 0; /* Format name string. */ t = T(2); PI(t,i+1) return; - tszName = NULL; P("episode_data","episode_title",2,t) goto ep; GAC(t+1,&szName) goto ep; tszName = TszFromSz(szName, CP_UTF8); if (!tszName) return; + /* Format rating string. */ + t2 = T(2); + PI(t2,i+1) return; + P("episode_data","episode_rating",2,t2) goto ep; + GI(t2+1,&iRating) goto ep; + _itot(iRating, tszRating, 10); + /* Format episode number string. */ ep: cb = 100; tszEpisode = malloc(cb*sizeof(TCHAR)); @@ -202,9 +219,16 @@ ElvUpdate() lviEpisode.lParam = i+1; ListView_InsertItem(HElv, &lviEpisode); + if (*tszRating) { + lviRating.iItem = i; + lviRating.iSubItem = 1; + lviRating.pszText = tszRating; + ListView_SetItem(HElv, &lviRating); + } + if (tszName) { lviName.iItem = i; - lviName.iSubItem = 1; + lviName.iSubItem = 2; lviName.pszText = tszName; ListView_SetItem(HElv, &lviName); } @@ -228,8 +252,9 @@ void ElvUpdateName(LPLVITEM lpLvi) { char *szName; - TCHAR *tszName; - term_t t; + int iRating; + TCHAR *tszName, tszRating[10]; + term_t t, t2; t = T(2); PI(t,lpLvi->lParam) return; @@ -241,6 +266,15 @@ ElvUpdateName(LPLVITEM lpLvi) tszName = TszFromSz(szName, CP_UTF8); if (!tszName) return; + ListView_SetItemText(HElv, lpLvi->iItem, 2, tszName); - ListView_SetItemText(HElv, lpLvi->iItem, 1, tszName); + t2 = T(2); + PI(t2,lpLvi->lParam) return; + P("episode_data","episode_rating",2,t2) { + ListView_SetItemText(HElv, lpLvi->iItem, 1, TEXT("")); + return; + } + GI(t2+1,&iRating) return; + _itot(iRating, tszRating, 10); + ListView_SetItemText(HElv, lpLvi->iItem, 1, tszRating); } @@ -188,12 +188,8 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ElvUpdate(); break; case ID_FILE_RESET: - { - extern HWND HElv; - ListView_SetItemState(HElv, -1, LVIF_STATE, LVIS_SELECTED); ElvSelectRecent(); break; - } case ID_FILE_ABOUT: DialogBox( GetModuleHandle(NULL), @@ -206,6 +202,12 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case ID_TOGGLE: case ID_FORGET: case ID_LOOKUP: + case ID_RATE5: + case ID_RATE4: + case ID_RATE3: + case ID_RATE2: + case ID_RATE1: + case ID_RATE0: { LVITEM lvi; term_t t; @@ -216,7 +218,7 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) lvi.mask = LVIF_PARAM; lvi.iItem = -1; - t = T(1); + t = T(2); while ((lvi.iItem = ListView_GetNextItem( HElv, lvi.iItem, LVNI_SELECTED)) != -1) { if (!ListView_GetItem(HElv, &lvi)) goto b; @@ -241,6 +243,27 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ElvRedraw(); DlvShowEpisode(lvi.lParam); break; + case ID_RATE5: + PI(t+1,5) break; + goto r; + case ID_RATE4: + PI(t+1,4) break; + goto r; + case ID_RATE3: + PI(t+1,3) break; + goto r; + case ID_RATE2: + PI(t+1,2) break; + goto r; + case ID_RATE1: + PI(t+1,1) break; + goto r; + case ID_RATE0: + PI(t+1,0) break; + r: P("episode_data","rate_episode",2,t); + ElvUpdateName(&lvi); + ElvRedraw(); + break; } } b: break; @@ -321,23 +344,24 @@ UpdateLayout() GetClientRect(HWnd, &rc); -#define SETCOLW(lv) \ - ListView_SetColumnWidth(lv, 0, LVSCW_AUTOSIZE); \ - cxColumn = ListView_GetColumnWidth(lv, 0)+4; \ - ListView_SetColumnWidth(lv, 0, cxColumn); \ - ListView_SetColumnWidth(lv, 1, rc.right-cxColumn-CxVScroll-4); - /* Resize data list view. */ SendMessage(HDlv, WM_SETREDRAW, FALSE, 0); cyDlv = rc.bottom - LvHeight(HDlv, 0); MoveWindow(HDlv, 0, cyDlv, rc.right, rc.bottom, TRUE); - SETCOLW(HDlv); + ListView_SetColumnWidth(HDlv, 0, LVSCW_AUTOSIZE); + cxColumn = ListView_GetColumnWidth(HDlv, 0)+4; + ListView_SetColumnWidth(HDlv, 0, cxColumn); + ListView_SetColumnWidth(HDlv, 1, rc.right-cxColumn-CxVScroll-4); SendMessage(HDlv, WM_SETREDRAW, TRUE, 0); /* Resize episode list view. */ SendMessage(HElv, WM_SETREDRAW, FALSE, 0); MoveWindow(HElv, 0, 0, rc.right, cyDlv+1, TRUE); - SETCOLW(HElv); + ListView_SetColumnWidth(HElv, 0, LVSCW_AUTOSIZE); + cxColumn = ListView_GetColumnWidth(HElv, 0)+4; + ListView_SetColumnWidth(HElv, 0, cxColumn); + cxColumn += ListView_GetColumnWidth(HElv, 1); + ListView_SetColumnWidth(HElv, 2, rc.right-cxColumn-CxVScroll-4); SendMessage(HElv, WM_SETREDRAW, TRUE, 0); #undef SETCOLW diff --git a/c/resource.h b/c/resource.h index e810a30..a7c3d28 100644 --- a/c/resource.h +++ b/c/resource.h @@ -15,5 +15,11 @@ #define ID_TOGGLE 422 #define ID_FORGET 423 #define ID_LOOKUP 424 +#define ID_RATE5 425 +#define ID_RATE4 426 +#define ID_RATE3 427 +#define ID_RATE2 428 +#define ID_RATE1 429 +#define ID_RATE0 430 #endif diff --git a/c/resource.rc b/c/resource.rc index 134fe72..de9e1dc 100644 --- a/c/resource.rc +++ b/c/resource.rc @@ -25,6 +25,15 @@ BEGIN MENUITEM "&Toggle", ID_TOGGLE MENUITEM "&Forget", ID_FORGET MENUITEM "&Lookup", ID_LOOKUP + POPUP "&Rate" + BEGIN + MENUITEM "&5", ID_RATE5 + MENUITEM "&4", ID_RATE4 + MENUITEM "&3", ID_RATE3 + MENUITEM "&2", ID_RATE2 + MENUITEM "&1", ID_RATE1 + MENUITEM "&Remove Rating", ID_RATE0 + END END END diff --git a/pl/episode_data.pl b/pl/episode_data.pl index 6fa5b8d..e944243 100644 --- a/pl/episode_data.pl +++ b/pl/episode_data.pl @@ -1,6 +1,8 @@ :- module(episode_data, [ensure_episode_data/0, retract_episode/1, - episode_count/1]). + episode_count/1, + rate_episode/2, + episode_rating/2]). :- use_module(library(clpfd)). :- use_module(library(dcg/basics)). @@ -12,6 +14,7 @@ :- persistent episode_title(episode:integer, title:atom). :- persistent episode_datum(episode:integer, key:atom, value:atom). +:- persistent episode_rating(episode:integer, rating:integer). attach :- absolute_file_name('episode_data.db', F, [access(write)]), @@ -37,6 +40,20 @@ episode_count(N) :- setof(E, T^episode_title(E,T), Es), last(Es, N). +rate_episode(Ep, 0) :- + ( episode_rating(Ep, _) + -> retractall_episode_rating(Ep, _) + ; true + ), + !. + +rate_episode(Ep, R) :- + dif(R, 0), + ( episode_rating(Ep, R) + -> true + ; assert_episode_rating(Ep, R) + ). + % Remote data retrieval. episode_number(Ep) --> integer(Ep). @@ -80,14 +97,14 @@ remote_html(H) :- remote_episode_title_data(Ep, Title, ['Date'-Date, 'Source'-Source, 'Hint'-Hint]) :- remote_html(H), xpath(H, //tr(td(index(3),@style='background:#f2fde9;')), R), - xpath(R, td(index(1),text), Ep0), + xpath(R, td(index(1),normalize_space), Ep0), atom_phrase(episode_number(Ep), Ep0), - xpath(R, td(index(3),text), Title), - xpath(R, td(index(4),text), Date), - xpath(R, td(index(7),text), Source0), + xpath(R, td(index(3),normalize_space), Title), + xpath(R, td(index(4),normalize_space), Date), + xpath(R, td(index(7),normalize_space), Source0), re_replace('\\(([0-9])', ' (\\1', Source0, Source1), atom_string(Source, Source1), - xpath(R, td(index(8),text), Hint). + xpath(R, td(index(8),normalize_space), Hint). http_load_html(URL, DOM) :- setup_call_cleanup(http_open(URL, In, |