📄 cursesd.cc
字号:
print_page (height - 4, width - 2); print_position (height, width); move (cur_y, cur_x); /* Restore cursor position */ refresh (); } break; case 'G': /* Last page */ case KEY_END: end_reached_ = true; /* Last page not in buffer? */ if ((fpos = lseek (fd_, 0, SEEK_CUR)) == -1) { endwin (); fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n"); exit (-1); } if (fpos < file_size_) { /* Yes, we have to read it in */ if (lseek (fd_, -buf_size_, SEEK_END) == -1) { endwin (); fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n"); exit (-1); } if ((bytes_read_ = read (fd_, buf_, buf_size_)) == -1) { endwin (); fprintf (stderr, "\nError reading file in dialog_textbox().\n"); exit (-1); } buf_[bytes_read_] = '\0'; } page_ = buf_ + bytes_read_; back_lines (height - 4); print_page (height - 4, width - 2); print_position (height, width); move (cur_y, cur_x); /* Restore cursor position */ refresh (); break; case 'K': /* Previous line */ case 'k': case KEY_UP: if (!begin_reached_) { back_lines (page_length_ + 1); /* We don't call print_page() here but use scrolling to ensure faster screen update. However, 'end_reached_' and 'page_length_' should still be updated, and 'page' should point to start of next page. This is done by calling get_line() in the following 'for' loop. */ text_->scrollok (TRUE); text_->scrl (-1); /* Scroll text region down one line */ text_->scrollok (FALSE); page_length_ = 0; bool passed_end = false; for (int i = 0; i < height - 4; i++) { if (!i) { /* print first line of page */ print_line (0, width - 2); text_->noutrefresh (); } else /* Called to update 'end_reached_' and 'page' */ get_line (); if (!passed_end) page_length_++; if (end_reached_ && !passed_end) passed_end = true; } print_position (height, width); move (cur_y, cur_x); /* Restore cursor position */ refresh (); } break; case 'B': /* Previous page */ case 'b': case KEY_PPAGE: if (begin_reached_) break; back_lines (page_length_ + height - 4); print_page (height - 4, width - 2); print_position (height, width); move (cur_y, cur_x); refresh (); break; case 'J': /* Next line */ case 'j': case KEY_DOWN: if (!end_reached_) { begin_reached_ = false; text_->scrollok (TRUE); text_->scroll (); /* Scroll text region up one line */ text_->scrollok (FALSE); print_line (height - 5, width - 2); text_->move (height - 5, 0); text_->addch (' '); text_->move (height - 5, width - 3); text_->addch (' '); text_->noutrefresh (); print_position (height, width); move (cur_y, cur_x); /* Restore cursor position */ refresh (); } break; case ' ': /* Next page */ case KEY_NPAGE: if (end_reached_) break; begin_reached_ = false; print_page (height - 4, width - 2); print_position (height, width); move (cur_y, cur_x); refresh (); break; case '0': /* Beginning of line */ case 'H': /* Scroll left */ case 'h': case KEY_LEFT: if (hscroll_ <= 0) break; if (key == '0') hscroll_ = 0; else hscroll_--; /* Reprint current page to scroll horizontally */ back_lines (page_length_); print_page (height - 4, width - 2); move (cur_y, cur_x); refresh (); break; case 'L': /* Scroll right */ case 'l': case KEY_RIGHT: if (hscroll_ >= str_max_len_) break; hscroll_++; /* Reprint current page to scroll horizontally */ back_lines (page_length_); print_page (height - 4, width - 2); move (cur_y, cur_x); refresh (); break; case '/': /* Forward search */ case 'n': /* Repeat forward search */ case '?': /* Backward search */ case 'N': /* Repeat backward search */ /* set search direction */ bool dir = (key == '/' || key == 'n'); if (dir ? !end_reached_ : !begin_reached_) { if (key == 'n' || key == 'N') { if (search_term[0] == '\0') { /* No search term yet */ fprintf (stderr, "\a"); /* beep */ break; } } else /* Get search term from user */ if (get_search_term (search_term, height - 4, width - 2) == -1) break; /* Save variables for restoring in case search term can't be found */ char* tempptr = page_; bool temp = begin_reached_; bool temp1 = end_reached_; if ((fpos = lseek (fd_, 0, SEEK_CUR)) == -1) { endwin (); fprintf (stderr, "\nError moving file pointer in " "dialog_textbox().\n"); exit (-1); } fpos -= bytes_read_; /* update 'page' to point to next (previous) line before forward (backward) searching */ back_lines (dir ? page_length_ - 1 : page_length_ + 1); char* found = NULL; if (dir) /* Forward search */ while ((found = strstr (get_line (), search_term)) == NULL) { if (end_reached_) break; } else /* Backward search */ while ((found = strstr (get_line (), search_term)) == NULL) { if (begin_reached_) break; back_lines (2); } if (found == NULL) { /* not found */ fprintf (stderr, "\a"); /* beep */ /* Restore program state to that before searching */ if (lseek (fd_, fpos, SEEK_SET) == -1) { endwin (); fprintf (stderr, "\nError moving file pointer in " "dialog_textbox().\n"); exit (-1); } if ((bytes_read_ = read (fd_, buf_, buf_size_)) == -1) { endwin (); fprintf (stderr, "\nError reading file in " "dialog_textbox().\n"); exit (-1); } buf_[bytes_read_] = '\0'; page_ = tempptr; begin_reached_ = temp; end_reached_ = temp1; /* move 'page' to point to start of current page in order to re-print current page. Note that 'page' always points to start of next page, so this is necessary */ back_lines (page_length_); } else /* Search term found */ back_lines (1); /* Reprint page */ text_->attrset (a(dialog_attr)); print_page (height - 4, width - 2); if (found != NULL) print_position (height, width); move (cur_y, cur_x); /* Restore cursor position */ refresh (); } else /* no need to find */ fprintf (stderr, "\a"); /* beep */ break;// case 0x1b:// break; } } close (fd_); key_=-1; return; /* ESC pressed */}//--------------------------------privates----------------------------------void NCtextbox::print_page (int height, int width){ bool passed_end = false; page_length_ = 0; for (int i = 0; i < height; i++) { print_line (i, width); if (!passed_end) page_length_++; if (end_reached_ && !passed_end) passed_end = true; } text_->noutrefresh();}void NCtextbox::print_line (int row, int width){ char* line = get_line (); line += (strlen (line) <? hscroll_); /* Scroll horizontally */ text_->move (row, 0); /* move cursor to correct line */ text_->addch (' '); text_->addnstr (line, (strlen (line) <? (width - 2))); int x,y; text_->getyx (y, x); /* Clear 'residue' of previous line */ for (int i = 0; i < width - x; i++) text_->addch (' ');}/* * Return current line of text. Called by dialog_textbox() and print_line(). * 'page' should point to start of current line before calling, and will be * updated to point to start of next line. */char * NCtextbox::get_line (void){ end_reached_ = false; int i=0; while (*page_ != '\n') { if (*page_ == '\0') { /* Either end of file or end of buffer reached_ */ int fpos; if ((fpos = lseek (fd_, 0, SEEK_CUR)) == -1) { endwin (); fprintf (stderr, "\nError moving file pointer in " "get_line().\n"); exit (-1); } if (fpos < file_size_) { /* Not end of file yet */ /* We've reached_ end of buffer, but not end of file yet, so read next part of file into buffer */ if ((bytes_read_ = read (fd_, buf_, buf_size_)) == -1) { endwin (); fprintf (stderr, "\nError reading file in get_line().\n"); exit (-1); } buf_[bytes_read_] = '\0'; page_ = buf_; } else { end_reached_ = true; break; } } else if (i < str_max_len_) line_[i++] = *(page_++); else { /* Truncate lines longer than MAX_LEN characters */ if (i == str_max_len_) line_[i++] = '\0'; page_++; } } if (i <= str_max_len_) line_[i] = '\0'; if (!end_reached_) page_++; /* move pass '\n' */ return line_;}/* * Display a dialog box and get the search term from user */int NCtextbox::get_search_term (char *search_term, int height, int width){ int box_height = 7, box_width = 30; int x = (width - box_width) / 2; int y = (height - box_height) / 2; int k; { NCinputbox box("X","Input search string:",x,y,box_height,box_width,search_term); strcpy(search_term, box.getstr()); k = box.getkey(); }// refresh();// text_->refresh(); keypad(TRUE); return k;}void NCtextbox::print_position (int height, int width){ int fpos; if ((fpos = lseek (fd_, 0, SEEK_CUR)) == -1) { endwin (); fprintf (stderr, "\nError moving file pointer in print_position().\n"); exit (-1); } int percent = !file_size_ ? 100 : ((fpos - bytes_read_ + page_ - buf_) * 100) / file_size_; attrset (a(position_indicator_attr)); move (height - 3, width - 9); printw ("(%3d%%)", percent);}void NCtextbox::back_lines (int n){ begin_reached_ = false; /* We have to distinguish between end_reached and !end_reached since at end of file, the line is not ended by a '\n'. The code inside 'if' basically does a '--page' to move one character backward so as to skip '\n' of the previous line */ if (!end_reached_) { /* Either beginning of buffer or beginning of file reached? */ if (page_ == buf_) { int fpos; if ((fpos = lseek (fd_, 0, SEEK_CUR)) == -1) { endwin (); fprintf (stderr, "\nError moving file pointer in " "back_lines().\n"); exit (-1); } if (fpos > bytes_read_) { /* Not beginning of file yet */ /* We've reached beginning of buffer, but not beginning of file yet, so read previous part of file into buffer. Note that we only move backward for BUF_SIZE/2 bytes, but not BUF_SIZE bytes to avoid re-reading again in print_page() later */ /* Really possible to move backward BUF_SIZE/2 bytes? */ if (fpos < buf_size_ / 2 + bytes_read_) { /* No, move less then */ if (lseek (fd_, 0, SEEK_SET) == -1) { endwin (); fprintf (stderr, "\nError moving file pointer in " "back_lines().\n"); exit (-1); } page_ = buf_ + fpos - bytes_read_; } else { /* Move backward BUF_SIZE/2 bytes */ if (lseek (fd_, -(buf_size_ / 2 + bytes_read_), SEEK_CUR) == -1) { endwin (); fprintf (stderr, "\nError moving file pointer in back_lines().\n"); exit (-1); } page_ = buf_ + buf_size_ / 2; } if ((bytes_read_ = read (fd_, buf_, buf_size_)) == -1) { endwin (); fprintf (stderr, "\nError reading file in back_lines().\n"); exit (-1); } buf_[bytes_read_] = '\0'; } else { /* Beginning of file reached */ begin_reached_ = true; return; } } if (*(--page_) != '\n') { /* '--page' here */ /* Something's wrong... */ endwin (); fprintf (stderr, "\nInternal error in back_lines().\n"); exit (-1); } } /* Go back 'n' lines */ for (int i = 0; i < n; i++) do { if (page_ == buf_) { int fpos; if ((fpos = lseek (fd_, 0, SEEK_CUR)) == -1) { endwin (); fprintf (stderr, "\nError moving file pointer in back_lines().\n"); exit (-1); } if (fpos > bytes_read_) { /* Really possible to move backward BUF_SIZE/2 bytes? */ if (fpos < buf_size_ / 2 + bytes_read_) { /* No, move less then */ if (lseek (fd_, 0, SEEK_SET) == -1) { endwin (); fprintf (stderr, "\nError moving file pointer " "in back_lines().\n"); exit (-1); } page_ = buf_ + fpos - bytes_read_; } else { /* Move backward BUF_SIZE/2 bytes */ if (lseek (fd_, -(buf_size_ / 2 + bytes_read_), SEEK_CUR) == -1) { endwin (); fprintf (stderr, "\nError moving file pointer" " in back_lines().\n"); exit (-1); } page_ = buf_ + buf_size_ / 2; } if ((bytes_read_ = read (fd_, buf_, buf_size_)) == -1) { endwin (); fprintf (stderr, "\nError reading file in " "back_lines().\n"); exit (-1); } buf_[bytes_read_] = '\0'; } else { /* Beginning of file reached */ begin_reached_ = true; return; } } } while (*(--page_) != '\n'); page_++;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -