summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-09-08 07:49:08 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-09-08 07:49:08 +0300
commit5ae35b010cfb44d3930cfc900bc71ff2449d39f7 (patch)
treed126e1cb97194ebcc1ea4e136c3a39ddb90798c8
parent92efe35c6b1ef4bea6aa1e43faf42610c1597340 (diff)
LookupWidget: Identities lookup and commands
-rw-r--r--src/app.c21
-rw-r--r--src/gmcerts.c10
-rw-r--r--src/gmcerts.h1
-rw-r--r--src/history.c16
-rw-r--r--src/ui/command.c8
-rw-r--r--src/ui/command.h2
-rw-r--r--src/ui/lookupwidget.c56
7 files changed, 94 insertions, 20 deletions
diff --git a/src/app.c b/src/app.c
index 6b78f2e4..5c857223 100644
--- a/src/app.c
+++ b/src/app.c
@@ -830,6 +830,27 @@ iBool handleCommand_App(const char *cmd) {
830 setCommandHandler_Widget(dlg, handleIdentityCreationCommands_); 830 setCommandHandler_Widget(dlg, handleIdentityCreationCommands_);
831 return iTrue; 831 return iTrue;
832 } 832 }
833 else if (equal_Command(cmd, "ident.signin")) {
834 const iString *url = collect_String(suffix_Command(cmd, "url"));
835 signIn_GmCerts(
836 d->certs,
837 findIdentity_GmCerts(d->certs, collect_Block(hexDecode_Rangecc(range_Command(cmd, "ident")))),
838 url);
839 postCommand_App("idents.changed");
840 return iTrue;
841 }
842 else if (equal_Command(cmd, "ident.signout")) {
843 iGmIdentity *ident = findIdentity_GmCerts(
844 d->certs, collect_Block(hexDecode_Rangecc(range_Command(cmd, "ident"))));
845 if (arg_Command(cmd)) {
846 clearUse_GmIdentity(ident);
847 }
848 else {
849 setUse_GmIdentity(ident, collect_String(suffix_Command(cmd, "url")), iFalse);
850 }
851 postCommand_App("idents.changed");
852 return iTrue;
853 }
833 else if (equal_Command(cmd, "theme.set")) { 854 else if (equal_Command(cmd, "theme.set")) {
834 const int isAuto = argLabel_Command(cmd, "auto"); 855 const int isAuto = argLabel_Command(cmd, "auto");
835 d->theme = arg_Command(cmd); 856 d->theme = arg_Command(cmd);
diff --git a/src/gmcerts.c b/src/gmcerts.c
index 0dc52041..addd75d3 100644
--- a/src/gmcerts.c
+++ b/src/gmcerts.c
@@ -253,7 +253,7 @@ static void loadIdentities_GmCerts_(iGmCerts *d) {
253 } 253 }
254} 254}
255 255
256static iGmIdentity *findIdentity_GmCerts_(iGmCerts *d, const iBlock *fingerprint) { 256iGmIdentity *findIdentity_GmCerts(iGmCerts *d, const iBlock *fingerprint) {
257 iForEach(PtrArray, i, &d->idents) { 257 iForEach(PtrArray, i, &d->idents) {
258 iGmIdentity *ident = i.ptr; 258 iGmIdentity *ident = i.ptr;
259 if (cmp_Block(fingerprint, &ident->fingerprint) == 0) { /* TODO: could use a hash */ 259 if (cmp_Block(fingerprint, &ident->fingerprint) == 0) { /* TODO: could use a hash */
@@ -273,7 +273,7 @@ static void loadIdentityFromCertificate_GmCerts_(iGmCerts *d, const iString *crt
273 } 273 }
274 iTlsCertificate *cert = newPemKey_TlsCertificate(readFile_(crtPath), readFile_(keyPath)); 274 iTlsCertificate *cert = newPemKey_TlsCertificate(readFile_(crtPath), readFile_(keyPath));
275 iBlock *finger = fingerprint_TlsCertificate(cert); 275 iBlock *finger = fingerprint_TlsCertificate(cert);
276 iGmIdentity *ident = findIdentity_GmCerts_(d, finger); 276 iGmIdentity *ident = findIdentity_GmCerts(d, finger);
277 if (!ident) { 277 if (!ident) {
278 /* User-provided certificate. */ 278 /* User-provided certificate. */
279 ident = new_GmIdentity(); 279 ident = new_GmIdentity();
@@ -497,8 +497,10 @@ const iPtrArray *identities_GmCerts(const iGmCerts *d) {
497} 497}
498 498
499void signIn_GmCerts(iGmCerts *d, iGmIdentity *identity, const iString *url) { 499void signIn_GmCerts(iGmCerts *d, iGmIdentity *identity, const iString *url) {
500 signOut_GmCerts(d, url); 500 if (identity) {
501 setUse_GmIdentity(identity, url, iTrue); 501 signOut_GmCerts(d, url);
502 setUse_GmIdentity(identity, url, iTrue);
503 }
502} 504}
503 505
504void signOut_GmCerts(iGmCerts *d, const iString *url) { 506void signOut_GmCerts(iGmCerts *d, const iString *url) {
diff --git a/src/gmcerts.h b/src/gmcerts.h
index 2ab4396e..f0ed37b5 100644
--- a/src/gmcerts.h
+++ b/src/gmcerts.h
@@ -82,6 +82,7 @@ void deleteIdentity_GmCerts (iGmCerts *, iGmIdentity *identity);
82const iString * certificatePath_GmCerts (const iGmCerts *, const iGmIdentity *identity); 82const iString * certificatePath_GmCerts (const iGmCerts *, const iGmIdentity *identity);
83 83
84iGmIdentity * identity_GmCerts (iGmCerts *, unsigned int id); 84iGmIdentity * identity_GmCerts (iGmCerts *, unsigned int id);
85iGmIdentity * findIdentity_GmCerts (iGmCerts *, const iBlock *fingerprint);
85const iGmIdentity * constIdentity_GmCerts (const iGmCerts *, unsigned int id); 86const iGmIdentity * constIdentity_GmCerts (const iGmCerts *, unsigned int id);
86const iGmIdentity * identityForUrl_GmCerts (const iGmCerts *, const iString *url); 87const iGmIdentity * identityForUrl_GmCerts (const iGmCerts *, const iString *url);
87const iPtrArray * identities_GmCerts (const iGmCerts *); 88const iPtrArray * identities_GmCerts (const iGmCerts *);
diff --git a/src/history.c b/src/history.c
index 10de5b9a..562c23bf 100644
--- a/src/history.c
+++ b/src/history.c
@@ -271,19 +271,25 @@ const iStringArray *searchContents_History(const iHistory *d, const iRegExp *pat
271 iString entry; 271 iString entry;
272 init_String(&entry); 272 init_String(&entry);
273 iRangei cap = m.range; 273 iRangei cap = m.range;
274 cap.start = iMax(cap.start - 15, 0); 274 const int prefix = iMin(10, cap.start);
275 cap.end = iMin(cap.end + 15, (int) size_Block(&resp->body)); 275 cap.start = cap.start - prefix;
276 cap.end = iMin(cap.end + 30, (int) size_Block(&resp->body));
277 const size_t maxLen = 60;
278 if (size_Range(&cap) > maxLen) {
279 cap.end = cap.start + maxLen;
280 }
276 iString content; 281 iString content;
277 initRange_String(&content, (iRangecc){ m.subject + cap.start, m.subject + cap.end }); 282 initRange_String(&content, (iRangecc){ m.subject + cap.start, m.subject + cap.end });
278 /* This needs cleaning up; highlight the matched word. */ 283 /* This needs cleaning up; highlight the matched word. */
279 replace_Block(&content.chars, '\n', ' '); 284 replace_Block(&content.chars, '\n', ' ');
280 replace_Block(&content.chars, '\r', ' '); 285 replace_Block(&content.chars, '\r', ' ');
281// insertData_Block(&content.chars, 10, uiTextStrong_ColorEscape, 2); 286 if (prefix + size_Range(&m.range) < size_String(&content)) {
282// insertData_Block(&content.chars, size_String(&content) - 10, uiText_ColorEscape, 2); 287 insertData_Block(&content.chars, prefix + size_Range(&m.range), uiText_ColorEscape, 2);
288 }
289 insertData_Block(&content.chars, prefix, uiTextStrong_ColorEscape, 2);
283 format_String( 290 format_String(
284 &entry, "match len:%zu str:%s", size_String(&content), cstr_String(&content)); 291 &entry, "match len:%zu str:%s", size_String(&content), cstr_String(&content));
285 deinit_String(&content); 292 deinit_String(&content);
286 //appendRange_String(&entry, );
287 appendFormat_String(&entry, " url:%s", cstr_String(&url->url)); 293 appendFormat_String(&entry, " url:%s", cstr_String(&url->url));
288 if (!contains_StringSet(&inserted, &url->url)) { 294 if (!contains_StringSet(&inserted, &url->url)) {
289 pushFront_StringArray(urls, &entry); 295 pushFront_StringArray(urls, &entry);
diff --git a/src/ui/command.c b/src/ui/command.c
index cf8c7032..44e66121 100644
--- a/src/ui/command.c
+++ b/src/ui/command.c
@@ -96,12 +96,16 @@ iString *suffix_Command(const char *cmd, const char *label) {
96} 96}
97 97
98const iString *string_Command(const char *cmd, const char *label) { 98const iString *string_Command(const char *cmd, const char *label) {
99 return collect_String(newRange_String(range_Command(cmd, label)));
100}
101
102iRangecc range_Command(const char *cmd, const char *label) {
99 iRangecc val = { suffixPtr_Command(cmd, label), NULL }; 103 iRangecc val = { suffixPtr_Command(cmd, label), NULL };
100 if (val.start) { 104 if (val.start) {
101 for (val.end = val.start; *val.end && !isspace(*val.end); val.end++) {} 105 for (val.end = val.start; *val.end && !isspace(*val.end); val.end++) {}
102 return collect_String(newRange_String(val)); 106 return val;
103 } 107 }
104 return collectNew_String(); 108 return iNullRange;
105} 109}
106 110
107iInt2 dir_Command(const char *cmd) { 111iInt2 dir_Command(const char *cmd) {
diff --git a/src/ui/command.h b/src/ui/command.h
index 4798baa6..43992b8e 100644
--- a/src/ui/command.h
+++ b/src/ui/command.h
@@ -22,6 +22,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
22 22
23#pragma once 23#pragma once
24 24
25#include <the_Foundation/range.h>
25#include <the_Foundation/vec2.h> 26#include <the_Foundation/vec2.h>
26 27
27iBool equal_Command (const char *commandWithArgs, const char *command); 28iBool equal_Command (const char *commandWithArgs, const char *command);
@@ -36,5 +37,6 @@ iInt2 coord_Command (const char *);
36iInt2 dir_Command (const char *); 37iInt2 dir_Command (const char *);
37 38
38const iString * string_Command (const char *, const char *label); /* space-delimited */ 39const iString * string_Command (const char *, const char *label); /* space-delimited */
40iRangecc range_Command (const char *, const char *label); /* space-delimited */
39const char * suffixPtr_Command (const char *, const char *label); /* until end-of-command */ 41const char * suffixPtr_Command (const char *, const char *label); /* until end-of-command */
40iString * suffix_Command (const char *, const char *label); /* until end-of-command */ 42iString * suffix_Command (const char *, const char *label); /* until end-of-command */
diff --git a/src/ui/lookupwidget.c b/src/ui/lookupwidget.c
index dbe734bf..676f8678 100644
--- a/src/ui/lookupwidget.c
+++ b/src/ui/lookupwidget.c
@@ -422,6 +422,8 @@ static void presentResults_LookupWidget_(iLookupWidget *d) {
422 clear_ListWidget(d->list); 422 clear_ListWidget(d->list);
423 sort_Array(&job->results, cmpPtr_LookupResult_); 423 sort_Array(&job->results, cmpPtr_LookupResult_);
424 enum iLookupResultType lastType = none_LookupResultType; 424 enum iLookupResultType lastType = none_LookupResultType;
425 const size_t maxPerType = 10; /* TODO: Setting? */
426 size_t perType = 0;
425 iConstForEach(PtrArray, i, &job->results) { 427 iConstForEach(PtrArray, i, &job->results) {
426 const iLookupResult *res = i.ptr; 428 const iLookupResult *res = i.ptr;
427 if (lastType != res->type) { 429 if (lastType != res->type) {
@@ -434,6 +436,42 @@ static void presentResults_LookupWidget_(iLookupWidget *d) {
434 addItem_ListWidget(d->list, item); 436 addItem_ListWidget(d->list, item);
435 iRelease(item); 437 iRelease(item);
436 lastType = res->type; 438 lastType = res->type;
439 perType = 0;
440 }
441 if (perType > maxPerType) {
442 continue;
443 }
444 if (res->type == identity_LookupResultType) {
445 const iString *docUrl = url_DocumentWidget(document_App());
446 iBlock *finger = hexDecode_Rangecc(range_String(&res->meta));
447 const iGmIdentity *ident = findIdentity_GmCerts(certs_App(), finger);
448 /* Sign in/out. */ {
449 const iBool isUsed = isUsedOn_GmIdentity(ident, docUrl);
450 iLookupItem *item = new_LookupItem(res);
451 item->fg = uiText_ColorId;
452 item->font = uiContent_FontId;
453 format_String(&item->text,
454 "%s \u2014 " uiTextStrong_ColorEscape "%s on this page",
455 cstr_String(&res->label),
456 isUsed ? "Stop using" : "Use");
457 format_String(&item->command, "ident.sign%s ident:%s url:%s",
458 isUsed ? "out arg:0" : "in", cstr_String(&res->meta), cstr_String(docUrl));
459 addItem_ListWidget(d->list, item);
460 iRelease(item);
461 }
462 if (isUsed_GmIdentity(ident)) {
463 iLookupItem *item = new_LookupItem(res);
464 item->fg = uiText_ColorId;
465 item->font = uiContent_FontId;
466 format_String(&item->text,
467 "%s \u2014 " uiTextStrong_ColorEscape "Stop using everywhere",
468 cstr_String(&res->label));
469 format_String(&item->command, "ident.signout arg:1 ident:%s", cstr_String(&res->meta));
470 addItem_ListWidget(d->list, item);
471 iRelease(item);
472 }
473 delete_Block(finger);
474 continue;
437 } 475 }
438 iLookupItem *item = new_LookupItem(res); 476 iLookupItem *item = new_LookupItem(res);
439 const char *url = cstr_String(&res->url); 477 const char *url = cstr_String(&res->url);
@@ -463,19 +501,16 @@ static void presentResults_LookupWidget_(iLookupWidget *d) {
463 case content_LookupResultType: { 501 case content_LookupResultType: {
464 item->fg = uiText_ColorId; 502 item->fg = uiText_ColorId;
465 item->font = uiContent_FontId; 503 item->font = uiContent_FontId;
466 format_String(&item->text, "%s \u2014 %s", cstr_String(&res->label), url); 504 format_String(&item->text, "%s \u2014 pe%s", url, cstr_String(&res->label));
467 format_String(&item->command, "open url:%s", cstr_String(&res->url)); 505 format_String(&item->command, "open url:%s", cstr_String(&res->url));
468 break; 506 break;
469 } 507 }
470 case identity_LookupResultType: { 508 default:
471 item->fg = uiText_ColorId;
472 item->font = uiContent_FontId;
473 format_String(&item->text, "%s", cstr_String(&res->label));
474 break; 509 break;
475 }
476 } 510 }
477 addItem_ListWidget(d->list, item); 511 addItem_ListWidget(d->list, item);
478 iRelease(item); 512 iRelease(item);
513 perType++;
479 } 514 }
480 delete_LookupJob(job); 515 delete_LookupJob(job);
481 /* Re-select the item at the cursor. */ 516 /* Re-select the item at the cursor. */
@@ -483,6 +518,7 @@ static void presentResults_LookupWidget_(iLookupWidget *d) {
483 d->cursor = iMin(d->cursor, numItems_ListWidget(d->list) - 1); 518 d->cursor = iMin(d->cursor, numItems_ListWidget(d->list) - 1);
484 ((iListItem *) item_ListWidget(d->list, d->cursor))->isSelected = iTrue; 519 ((iListItem *) item_ListWidget(d->list, d->cursor))->isSelected = iTrue;
485 } 520 }
521 scrollOffset_ListWidget(d->list, 0);
486 updateVisible_ListWidget(d->list); 522 updateVisible_ListWidget(d->list);
487 invalidate_ListWidget(d->list); 523 invalidate_ListWidget(d->list);
488 setFlags_Widget(as_Widget(d), hidden_WidgetFlag, numItems_ListWidget(d->list) == 0); 524 setFlags_Widget(as_Widget(d), hidden_WidgetFlag, numItems_ListWidget(d->list) == 0);
@@ -557,13 +593,15 @@ static iBool processEvent_LookupWidget_(iLookupWidget *d, const SDL_Event *ev) {
557 } 593 }
558 } 594 }
559 if (isCommand_Widget(w, ev, "list.clicked")) { 595 if (isCommand_Widget(w, ev, "list.clicked")) {
560 setTextCStr_InputWidget(findWidget_App("url"), ""); 596 iInputWidget *url = findWidget_App("url");
597// setTextCStr_InputWidget(findWidget_App("url"), "");
561 const iLookupItem *item = constItem_ListWidget(d->list, arg_Command(cmd)); 598 const iLookupItem *item = constItem_ListWidget(d->list, arg_Command(cmd));
562 if (item && !isEmpty_String(&item->command)) { 599 if (item && !isEmpty_String(&item->command)) {
563 postCommandString_App(&item->command); 600 setText_InputWidget(url, url_DocumentWidget(document_App()));
601 setFocus_Widget(NULL);
564 setFlags_Widget(w, hidden_WidgetFlag, iTrue); 602 setFlags_Widget(w, hidden_WidgetFlag, iTrue);
565 setCursor_LookupWidget_(d, iInvalidPos); 603 setCursor_LookupWidget_(d, iInvalidPos);
566 setFocus_Widget(NULL); 604 postCommandString_App(&item->command);
567 } 605 }
568 return iTrue; 606 return iTrue;
569 } 607 }