aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Ankarström <john@ankarstrom.se>2022-04-05 04:15:20 +0200
committerJohn Ankarström <john@ankarstrom.se>2022-04-05 04:15:20 +0200
commit4d6cbcdc97fd79befca82ed9ddc0d96ce86f744f (patch)
tree07c4cb66a4914c4cd38b723928c69d39b507c451
parentec4bf0b3d1fac134793dd4cccff24e42ce682f09 (diff)
downloadEpisodeBrowser-4d6cbcdc97fd79befca82ed9ddc0d96ce86f744f.tar.gz
Add episode ratings.
-rw-r--r--c/episodelistview.c56
-rw-r--r--c/main.c50
-rw-r--r--c/resource.h6
-rw-r--r--c/resource.rc9
-rw-r--r--pl/episode_data.pl29
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);
}
diff --git a/c/main.c b/c/main.c
index 3b370ff..a03e7b5 100644
--- a/c/main.c
+++ b/c/main.c
@@ -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,