From c32e1bb340d2d40d0a5b61e37e6fd55f84953633 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Sun, 23 Feb 2020 17:16:22 +0000 Subject: Page info: Implement page info window creation and destruction. --- desktop/page-info.c | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) (limited to 'desktop') diff --git a/desktop/page-info.c b/desktop/page-info.c index ad0a71a1e..0666aaf4c 100644 --- a/desktop/page-info.c +++ b/desktop/page-info.c @@ -311,3 +311,253 @@ nserror page_info_fini(void) { return NSERROR_OK; } + +/** + * Measure the text in the page_info window. + * + * \param[in] pi The page info window handle. + * \return NSERROR_OK on success, appropriate error code otherwise. + */ +static nserror page_info__measure_text_entry( + struct page_info_text *pit) +{ + nserror err; + int height_px; + + err = guit->layout->width(pit->style, + pit->text, strlen(pit->text), + &pit->width); + if (err != NSERROR_OK) { + return err; + } + + /* \todo: This needs to be a helper in plot style or in nscss. */ + height_px = ((pit->style->size / PLOT_STYLE_SCALE) * + FIXTOINT(nscss_screen_dpi) + 36) / 72; + + pit->height = (height_px * 8 + 3) / 6; + + return NSERROR_OK; +} + +/** + * Measure the text in the page_info window. + * + * \param[in] pi The page info window handle. + * \return NSERROR_OK on success, appropriate error code otherwise. + */ +static nserror page_info__measure_text( + struct page_info *pi) +{ + nserror err; + + for (unsigned i = 0; i < PI_ENTRY__COUNT; i++) { + struct page_info_entry *entry = pi->entries + i; + int padding; + + switch (entry->type) { + case PAGE_INFO_ENTRY_TYPE_TEXT: + err = page_info__measure_text_entry( + &entry->text); + if (err != NSERROR_OK) { + return err; + } + if (i == PI_ENTRY_DOMAIN) { + entry->text.padding_bottom = + entry->text.height * 3 / 2; + } + break; + + case PAGE_INFO_ENTRY_TYPE_ITEM: + err = page_info__measure_text_entry( + &entry->item.item); + if (err != NSERROR_OK) { + return err; + } + err = page_info__measure_text_entry( + &entry->item.detail); + if (err != NSERROR_OK) { + return err; + } + padding = entry->item.item.height / 4; + entry->item.padding_top = padding; + entry->item.padding_bottom = padding; + + break; + } + } + + pi->window_padding = pi->entries[PI_ENTRY_DOMAIN].item.item.height / 2; + + return NSERROR_OK; +} + +/** + * Set the text for the page_info window. + * + * \todo Use messages for internationalisation. + * + * \param[in] pi The page info window handle. + * \return NSERROR_OK on success, appropriate error code otherwise. + */ +static nserror page_info__set_text( + struct page_info *pi) +{ + int printed; + static const char *header[PAGE_STATE__COUNT] = { + [PAGE_STATE_UNKNOWN] = "Provenience unknown", + [PAGE_STATE_INTERNAL] = "NetSurf data", + [PAGE_STATE_LOCAL] = "Local data", + [PAGE_STATE_INSECURE] = "Connection not secure", + [PAGE_STATE_SECURE_OVERRIDE] = "Connection not secure", + [PAGE_STATE_SECURE_ISSUES] = "Connection not secure", + [PAGE_STATE_SECURE] = "Connection is secure", + }; + static const char *certificate[PAGE_STATE__COUNT] = { + [PAGE_STATE_UNKNOWN] = "Missing", + [PAGE_STATE_INTERNAL] = "None", + [PAGE_STATE_LOCAL] = "None", + [PAGE_STATE_INSECURE] = "Not valid", + [PAGE_STATE_SECURE_OVERRIDE] = "Not valid", + [PAGE_STATE_SECURE_ISSUES] = "Not valid", + [PAGE_STATE_SECURE] = "Valid", + }; + + assert(pi != NULL); + assert(pi->state < PAGE_STATE__COUNT); + + pi->entries[PI_ENTRY_HEADER].text.style = &pi__heading[pi->state]; + pi->entries[PI_ENTRY_HEADER].text.text = header[pi->state]; + pi->entries[PI_ENTRY_DOMAIN].text.text = (pi->domain) ? + lwc_string_data(pi->domain) : ""; + + pi->entries[PI_ENTRY_CERT].item.item.text = "Certificate: "; + pi->entries[PI_ENTRY_CERT].item.detail.text = certificate[pi->state]; + + printed = snprintf(pi->cookie_text, sizeof(pi->cookie_text), + "(%u in use)", pi->cookies); + if (printed < 0) { + return NSERROR_UNKNOWN; + + } else if ((unsigned) printed >= sizeof(pi->cookie_text)) { + return NSERROR_NOSPACE; + } + pi->entries[PI_ENTRY_COOKIES].item.item.text = "Cookies: "; + pi->entries[PI_ENTRY_COOKIES].item.detail.text = pi->cookie_text; + + return page_info__measure_text(pi); +} + +/** + * Create page info from a browser window. + * + * \param[in] pi The page info window handle. + * \param[in] bw Browser window to show page info for. + * \return NSERROR_OK on success, appropriate error code otherwise. + */ +static nserror page_info__create_from_bw( + struct page_info *pi, + const struct browser_window *bw) +{ + nsurl *url = browser_window_access_url(bw); + + pi->bw = bw; + pi->state = browser_window_get_page_info_state(bw); + pi->cookies = browser_window_get_cookie_count(bw); + pi->domain = nsurl_get_component(url, NSURL_HOST); + + return page_info__set_text(pi); +} + +/** + * Lay out the page info window. + * + * \param[in] pi The page info window handle. + * \return NSERROR_OK on success, appropriate error code otherwise. + */ +static nserror page_info__layout( + struct page_info *pi) +{ + int cur_y = 0; + int max_x = 0; + + cur_y += pi->window_padding; + for (unsigned i = 0; i < PI_ENTRY__COUNT; i++) { + struct page_info_entry *entry = pi->entries + i; + + switch (entry->type) { + case PAGE_INFO_ENTRY_TYPE_TEXT: + cur_y += entry->text.height; + if (max_x < entry->text.width) { + max_x = entry->text.width; + } + cur_y += entry->text.padding_bottom; + break; + + case PAGE_INFO_ENTRY_TYPE_ITEM: + { + int full_width = entry->item.item.width + + entry->item.detail.width; + cur_y += entry->item.padding_top; + cur_y += entry->item.item.height; + if (max_x < full_width) { + max_x = full_width; + } + cur_y += entry->item.padding_bottom; + } + break; + } + } + cur_y += pi->window_padding; + max_x += pi->window_padding * 2; + + pi->width = max_x; + pi->height = cur_y; + return pi->cw_t->update_size(pi->cw_h, max_x, cur_y); +} + +/* Exported interface documented in desktop/page_info.h */ +nserror page_info_create( + const struct core_window_callback_table *cw_t, + struct core_window *cw_h, + const struct browser_window *bw, + struct page_info **pi_out) +{ + struct page_info *pi; + nserror err; + + pi = calloc(1, sizeof(*pi)); + if (pi == NULL) { + return NSERROR_NOMEM; + } + + pi->cw_t = cw_t; + pi->cw_h = cw_h; + + memcpy(pi->entries, pi__entries, sizeof(pi__entries)); + + err = page_info__create_from_bw(pi, bw); + if (err != NSERROR_OK) { + page_info_destroy(pi); + return err; + } + + err = page_info__layout(pi); + if (err != NSERROR_OK) { + page_info_destroy(pi); + return err; + } + + *pi_out = pi; + return NSERROR_OK; +} + +/* Exported interface documented in desktop/page_info.h */ +void page_info_destroy( + struct page_info *pi) +{ + if (pi->domain != NULL) { + lwc_string_unref(pi->domain); + } + free(pi); +} -- cgit v1.2.3