📄 plain.c
字号:
/* * File: plain.c * * Copyright (C) 1997 Raph Levien <raph@acm.org> * Copyright (C) 1999 James McCollough <jamesm@gtwn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *//* * Module for decoding a text/plain object into a gtk_page widget. */#include <string.h> /* for memcpy and memmove */#include <math.h> /* for rint() */#include <gtk/gtk.h>#include "prefs.h"#include "dw_page.h"#include "cache.h"#include "browser.h"#include "web.h"#include "interface.h"#include "progressbar.h"#include "misc.h"#include "history.h"#include "nav.h"#include "menu.h"typedef struct _DilloPlain { DwWidget *dw; size_t Start_Ofs; /* Offset of where to start reading next */ DwStyle *style; BrowserWindow *bw; gint state;} DilloPlain;/* FSM states */enum { ST_SeekingEol, ST_Eol, ST_Eof};/* * Forward declarations */static void Plain_write(DilloPlain *plain, void *Buf, gint BufSize, gint Eof);static void Plain_callback(int Op, CacheClient_t *Client);/* * Popup the page menu ("button_press_event" callback of the viewport) */static int Plain_page_menu(GtkWidget *viewport, GdkEventButton *event, BrowserWindow *bw){ if (event->button == 3) { a_Menu_popup_set_url(bw, a_History_get_url(NAV_TOP(bw))); gtk_menu_popup(GTK_MENU(bw->menu_popup.over_page), NULL, NULL, NULL, NULL, event->button, event->time); return TRUE; } else return FALSE;}/* * Create and initialize a new DilloPlain structure. */static DilloPlain *Plain_new(BrowserWindow *bw){ DilloPlain *plain; DwPage *page; DwStyle style_attrs; DwStyleFont font_attrs; plain = g_new(DilloPlain, 1); plain->state = ST_SeekingEol; plain->Start_Ofs = 0; plain->bw = bw; plain->dw = a_Dw_page_new(); page = (DwPage *) plain->dw; /* Create the font and attribute for the page. */ font_attrs.name = prefs.fw_fontname; font_attrs.size = rint(12.0 * prefs.font_factor); font_attrs.weight = 400; font_attrs.style = DW_STYLE_FONT_STYLE_NORMAL; a_Dw_style_init_values (&style_attrs, plain->bw->main_window->window); style_attrs.font = a_Dw_style_font_new (&font_attrs); style_attrs.color = a_Dw_style_color_new (prefs.text_color, plain->bw->main_window->window); plain->style = a_Dw_style_new (&style_attrs, plain->bw->main_window->window); //a_Dw_widget_set_style (plain->dw, plain->style); /* The context menu */ gtk_signal_connect_while_alive (GTK_OBJECT(GTK_BIN(plain->bw->docwin)->child),"button_press_event", GTK_SIGNAL_FUNC(Plain_page_menu), (gpointer)plain->bw, GTK_OBJECT (page)); return plain;}/* * Set callback function and callback data for "text/" MIME major-type. */DwWidget* a_Plain_text(const char *type, void *P, CA_Callback_t *Call, void **Data){ DilloWeb *web = P; DilloPlain *plain = Plain_new(web->bw); *Call = (CA_Callback_t)Plain_callback; *Data = (void*)plain; return plain->dw;}/* * This function is a cache client */static void Plain_callback(int Op, CacheClient_t *Client){ DilloPlain *plain= Client->CbData; DwPage *page = (DwPage *)plain->dw; if ( Op ) { /* Do the last line: */ if (plain->Start_Ofs < Client->BufSize) Plain_write(plain, Client->Buf, Client->BufSize, 1); /* remove this client from our active list */ a_Interface_close_client(plain->bw, Client->Key); /* set progress bar insensitive */ a_Progressbar_update(plain->bw->progress, NULL, 0); a_Dw_style_unref (plain->style); g_free(plain); } else { Plain_write(plain, Client->Buf, Client->BufSize, 0); } a_Dw_page_flush(page);}/* * Here we parse plain text and put it into the page structure. * (This function is called by Plain_callback whenever there's new data) */static void Plain_write(DilloPlain *plain, void *Buf, gint BufSize, gint Eof){ DwPage *page = (DwPage *)plain->dw; char *Start; char *data; gint i, len, MaxBytes; Start = (char*)Buf + plain->Start_Ofs; MaxBytes = BufSize - plain->Start_Ofs; i = len = 0; while ( i < MaxBytes ) { switch ( plain->state ) { case ST_SeekingEol: if ( Start[i] == '\n' || Start[i] == '\r' ) plain->state = ST_Eol; else { ++i; ++len; } break; case ST_Eol: data = g_strndup(Start + i - len, len); a_Dw_page_add_text(page, a_Misc_expand_tabs(data), plain->style); g_free(data); a_Dw_page_add_parbreak(page, 0, plain->style); if ( Start[i] == '\r' && Start[i + 1] == '\n' ) ++i; if ( i < MaxBytes ) ++i; plain->state = ST_SeekingEol; len = 0; break; } } plain->Start_Ofs += i - len; if ( Eof && len ) { data = g_strndup(Start + i - len, len); a_Dw_page_add_text(page, a_Misc_expand_tabs(data), plain->style); g_free(data); a_Dw_page_add_parbreak(page, 0, plain->style); plain->Start_Ofs += len; } if ( plain->bw ) { gchar completestr[32]; g_snprintf( completestr, 32, "%s%.1f Kb", PBAR_PSTR(prefs.panel_size == 1), (float)plain->Start_Ofs/1024); a_Progressbar_update(plain->bw->progress, completestr, 1); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -