📄 reader.cxx
字号:
return (ch != EOF);}class myoutput : public Fl_Widget { Fl_Font m_textfont; int m_textsize; CBuffer** textarray; unsigned int numlines;public: bool tight; myoutput(int x, int y, int w, int h, const char *label=0) : Fl_Widget(x,y,w,h,label), textarray(NULL), numlines(0), tight(true) {} virtual void draw(); virtual int handle(int event); void load_file(char *newfile, unsigned int lcn=0); BuffDoc buffdoc; CList<Bkmk>* getbkmklist() { return buffdoc.getbkmklist(); } bool locate(unsigned int n); void jumpto(unsigned int n) { buffdoc.locate(n); } unsigned int locate() { return buffdoc.locate(); } unsigned int pagelocate() { return pagepos; } unsigned int pagepos, mylastpos; void setfilter(CFilterChain *f) { buffdoc.setfilter(f); locate(pagepos); } void restore() { jumpto(mylastpos); } void dopageup(); void dopagedn() { if (locate() != mylastpos) jumpto(mylastpos); if (fillbuffer()) { redraw(); Fl::flush(); } } virtual void resize(int X, int Y, int W, int H) { buffdoc.locate(pagepos); fillbuffer(); Fl_Widget::resize(X,Y,W,H); } // bool bold; int textsize() { return m_textsize; } void textsize(int ts) { m_textsize = ts; } Fl_Font textfont() { return m_textfont; } void textfont(Fl_Font tf) { m_textfont = tf; } bool fillbuffer(); int screenlines(); void sizes(unsigned long& fs, unsigned long& ts) { buffdoc.sizes(fs,ts); }};bool myoutput::locate(unsigned int n) { //printf("Locate\n"); buffdoc.locate(n); fillbuffer(); redraw();}int myoutput::screenlines(){ fl_font(textfont(),textsize()); int linespacing = (tight) ? fl_height() : fl_height()+fl_descent(); // int delta = (h()-fl_height())/(fl_height()); //int delta = (parent()->h()-tb->h())/(fl_height());#ifdef AGENDA // return (parent()->h()-fl_descent())/(fl_height()); return (h()-fl_descent())/(linespacing);#else return (h()-fl_descent())/(linespacing);#endif};bool myoutput::fillbuffer() { //printf("Fillbuffer\n"); int ch; bool ret = false; int delta = screenlines(); if (delta != numlines) { if (textarray != NULL) { for (int i = 0; i < numlines; i++) delete textarray[i]; delete [] textarray; } numlines = delta; textarray = new CBuffer*[numlines]; for (int i = 0; i < numlines; i++) textarray[i] = new CBuffer; } unsigned int oldpagepos = pagepos; pagepos = locate(); for (int i = 0; i < delta; i++) { ch = buffdoc.getline(textarray[i],w()); // if (ch == EOF) { if (!ch) { if (i == 0) { pagepos = oldpagepos; return false; } else { ret = true; for (int j = i; j < delta; j++) (*(textarray[j]))[0] = '\0'; break; } } if (ch == '\012') ret = true; } mylastpos = locate(); return true;}void myoutput::dopageup(){ fl_font(textfont(),textsize()); CBuffer** buff = textarray; unsigned int *loc = new unsigned int[numlines]; int cbptr = 0; if (locate() != mylastpos) jumpto(mylastpos); unsigned int target = pagelocate(); if (buffdoc.hasrandomaccess()) { unsigned int delta = locate()-pagelocate(); if (delta < 64) delta = 64; do { delta <<= 1; if (delta >= target) { delta = target; jumpto(0); for (int i = 0; i < numlines; i++) { loc[i] = locate(); buffdoc.getline(buff[i],w()); } break; } jumpto(target-delta); do { buffdoc.getline(buff[0],w());#ifdef WS //printf("Trying:%s\n",buff[0]);#endif if (locate() > target) continue; } while (!buffdoc.iseol()); for (int i = 0; i < numlines; i++) { loc[i] = locate(); buffdoc.getline(buff[i],w());#ifdef WS //printf("Filling:%s\n",buff[i]);#endif } } while (locate() >= target && delta < 4096);#ifdef WS //printf("Delta:%u\n",delta);#endif } else { jumpto(0); for (int i = 0; i < numlines; i++) { loc[i] = locate(); buffdoc.getline(buff[i],w()); } } cbptr = 0; while (locate() < target) { loc[cbptr] = locate(); buffdoc.getline(buff[cbptr], w());#ifdef WS //printf("Adding:%s\n",buff[cbptr]->data());#endif cbptr = (cbptr+1) % numlines; } pagepos = loc[cbptr]; textarray = new CBuffer*[numlines]; for (int i = 0; i < numlines; i++) { textarray[i] = buff[(cbptr+i)%numlines]; } delete [] buff; delete [] loc; mylastpos = locate(); redraw(); Fl::flush();}int myoutput::handle(int event){ // printf("Event:%d\n",event); if (event == FL_FOCUS || event == FL_UNFOCUS) { return 1; } else if (event == FL_KEYBOARD) { switch (Fl::event_key()) { case FL_Page_Up: { dopageup(); } return 1; case FL_Page_Down: { dopagedn(); } return 1; } } else if (event == FL_PUSH) { if (Fl::event_y() < h()/2) { dopageup(); } else { dopagedn(); } return 1; } return Fl_Widget::handle(event);}void myoutput::load_file(char *newfile, unsigned int lcn){ if (buffdoc.openfile(newfile) == 0) { locate(lcn); } redraw();}#ifdef USEBKMKSvoid setbkmkkey(const char *file, const char *mark, DBT* key){ static char buffer[2048]; int flen = strlen(file); int clen = strlen(mark); // buffer = new char[flen+1+clen]; strcpy(buffer,file); memcpy(buffer+flen+1,mark,clen); key->data = buffer; key->size = flen+1+clen;}void getdefaultbkmk(char *file, DBT* key){ setbkmkkey(file,"CURRENT",key);}#endifvoid myoutput::draw() { fl_color(7); fl_rectf(x(),y(),x()+w(),y()+h()); fl_color(0); int sl = screenlines(); if (sl < numlines) { size_t offset = 0; CBuffer** nta = new CBuffer*[sl]; for (int i = 0; i < sl; i++) { nta[i] = textarray[i]; offset += nta[i]->length()+1; } for (int i = sl; i < numlines; i++) delete textarray[i]; delete [] textarray; textarray = nta; numlines = sl; jumpto(mylastpos = pagepos+offset); } if (sl > numlines) { size_t offset = 0; CBuffer** nta = new CBuffer*[sl]; for (int i = 0; i < numlines; i++) { nta[i] = textarray[i]; offset += nta[i]->length(); } if (locate() != mylastpos) jumpto(mylastpos); for (int i = numlines; i < sl; i++) { nta[i] = new CBuffer; buffdoc.getline(nta[i],w()); } mylastpos = locate(); delete [] textarray; textarray = nta; numlines = sl; } int ypos = (tight) ? y() : y()-fl_descent(); int linespacing = (tight) ? fl_height() : fl_height()+fl_descent(); for (int i = 0; i < numlines; i++) { fl_draw(textarray[i]->data(),x(),ypos += linespacing); }}struct prefs_t{ int textsize; Fl_Font textfont; bool bold; bool bstripcr, bunindent, brepara, bdblspce, btight; unsigned char bindenter;};class reader_ui{ bool bold; char g_filename[1024]; myoutput *input;#ifdef AGENDA Fl_App_Window *window;#else Fl_Window *window;#endif#ifdef USEBKMKS unsigned int initlocation(char *file);#endif Fl_Int_Input *locn;#ifdef USEBKMKS Fl_Window* bkmkwindow; bool bkmkfind;#endif bool bstripcr, bunindent, brepara, bdblspce, btight; unsigned char bindenter;#ifdef USEBKMKS#ifdef AGENDA Fl_Paged_Select_Browser* bkmkbrowser;#else Fl_Select_Browser* bkmkbrowser;#endif#endif void setfilter() { input->setfilter(GetFilter()); } CFilterChain* GetFilter() { CFilterChain * filt = new CFilterChain; if (bstripcr) filt->addfilter(new stripcr); if (bunindent) filt->addfilter(new unindent); if (brepara) filt->addfilter(new repara); if (bindenter) filt->addfilter(new indenter(bindenter)); if (bdblspce) filt->addfilter(new dblspce); return filt; } //Fl_Menu_Bar *menubar;#ifdef USEBKMKS static void save_cb(Fl_Widget *widget, void *_data) { myoutput* input = (((reader_ui*)_data)->input); if (((reader_ui*)_data)->g_filename[0] != '\0') { const char *bkmark = fl_input("Bookmark name", "CURRENT"); if (bkmark != NULL) { DBT key, data; memset(&key,0,sizeof(key)); memset(&data,0,sizeof(data)); setbkmkkey(((reader_ui*)_data)->g_filename,bkmark,&key); unsigned int lcn = input->pagelocate(); data.data = (char*)&lcn; data.size = sizeof(lcn); bkmks->put(bkmks, &key, &data, 0); //printf("sync:%x\n",bkmks->sync); bkmks->sync(bkmks, 0); } } }#endif#ifdef USEBKMKS static void autogenbkmk_cb(Fl_Widget *widget, void *data) { static Fl_Window* win = NULL; static CBar* bar = NULL; if (win == NULL) { win = new Fl_Window(133,228,27,12); // win->resizable(win); bar = new CBar(1,1,25,10); win->border(0); win->box(FL_UP_BOX); win->end(); } bar->value(0); win->show(); ((reader_ui*)data)->do_autogen(bar); win->hide(); } void do_autogen(CBar* pbar) { CBuffer buff; unsigned long fs,ts; input->sizes(fs,ts); int ch = 0; if (pbar->value(0)) {#ifdef _SLOW sleep(1);#endif Fl::check(); } input->jumpto(0); int i = 0; while (i >= 0) { unsigned int lcn = input->locate(); if (pbar->value(((100*lcn)/ts))) {#ifdef _SLOW sleep(1);#endif unsigned long pos = input->locate(); Fl::check(); if (input->locate() != pos) input->jumpto(pos); } i = input->buffdoc.getpara(buff); if (i > 0) { i--; while (i > 0 && (ch = buff[i]) == ' ') i--;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -