| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
| file Copyright.txt or https://cmake.org/licensing for details. */ |
| #include "cmCursesLongMessageForm.h" |
| |
| #include "cmCursesForm.h" |
| #include "cmCursesMainForm.h" |
| #include "cmCursesStandardIncludes.h" |
| #include "cmVersion.h" |
| |
| #include <stdio.h> |
| #include <string.h> |
| |
| inline int ctrl(int z) |
| { |
| return (z & 037); |
| } |
| |
| cmCursesLongMessageForm::cmCursesLongMessageForm( |
| std::vector<std::string> const& messages, const char* title) |
| { |
| // Append all messages into on big string |
| std::vector<std::string>::const_iterator it; |
| for (it = messages.begin(); it != messages.end(); it++) { |
| this->Messages += (*it); |
| // Add one blank line after each message |
| this->Messages += "\n\n"; |
| } |
| this->Title = title; |
| this->Fields[0] = nullptr; |
| this->Fields[1] = nullptr; |
| } |
| |
| cmCursesLongMessageForm::~cmCursesLongMessageForm() |
| { |
| if (this->Fields[0]) { |
| free_field(this->Fields[0]); |
| } |
| } |
| |
| void cmCursesLongMessageForm::UpdateStatusBar() |
| { |
| int x, y; |
| getmaxyx(stdscr, y, x); |
| |
| char bar[cmCursesMainForm::MAX_WIDTH]; |
| size_t size = this->Title.size(); |
| if (size >= cmCursesMainForm::MAX_WIDTH) { |
| size = cmCursesMainForm::MAX_WIDTH - 1; |
| } |
| strncpy(bar, this->Title.c_str(), size); |
| for (size_t i = size - 1; i < cmCursesMainForm::MAX_WIDTH; i++) { |
| bar[i] = ' '; |
| } |
| int width; |
| if (x < cmCursesMainForm::MAX_WIDTH) { |
| width = x; |
| } else { |
| width = cmCursesMainForm::MAX_WIDTH - 1; |
| } |
| |
| bar[width] = '\0'; |
| |
| char version[cmCursesMainForm::MAX_WIDTH]; |
| char vertmp[128]; |
| sprintf(vertmp, "CMake Version %s", cmVersion::GetCMakeVersion()); |
| size_t sideSpace = (width - strlen(vertmp)); |
| for (size_t i = 0; i < sideSpace; i++) { |
| version[i] = ' '; |
| } |
| sprintf(version + sideSpace, "%s", vertmp); |
| version[width] = '\0'; |
| |
| char fmt_s[] = "%s"; |
| curses_move(y - 4, 0); |
| attron(A_STANDOUT); |
| printw(fmt_s, bar); |
| attroff(A_STANDOUT); |
| curses_move(y - 3, 0); |
| printw(fmt_s, version); |
| pos_form_cursor(this->Form); |
| } |
| |
| void cmCursesLongMessageForm::PrintKeys() |
| { |
| int x, y; |
| getmaxyx(stdscr, y, x); |
| if (x < cmCursesMainForm::MIN_WIDTH || y < cmCursesMainForm::MIN_HEIGHT) { |
| return; |
| } |
| char firstLine[512]; |
| sprintf(firstLine, "Press [e] to exit help"); |
| |
| char fmt_s[] = "%s"; |
| curses_move(y - 2, 0); |
| printw(fmt_s, firstLine); |
| pos_form_cursor(this->Form); |
| } |
| |
| void cmCursesLongMessageForm::Render(int /*left*/, int /*top*/, int /*width*/, |
| int /*height*/) |
| { |
| int x, y; |
| getmaxyx(stdscr, y, x); |
| |
| if (this->Form) { |
| unpost_form(this->Form); |
| free_form(this->Form); |
| this->Form = nullptr; |
| } |
| |
| const char* msg = this->Messages.c_str(); |
| |
| curses_clear(); |
| |
| if (this->Fields[0]) { |
| free_field(this->Fields[0]); |
| this->Fields[0] = nullptr; |
| } |
| |
| this->Fields[0] = new_field(y - 6, x - 2, 1, 1, 0, 0); |
| |
| field_opts_off(this->Fields[0], O_STATIC); |
| |
| this->Form = new_form(this->Fields); |
| post_form(this->Form); |
| |
| int i = 0; |
| form_driver(this->Form, REQ_BEG_FIELD); |
| while (msg[i] != '\0' && i < 60000) { |
| if (msg[i] == '\n' && msg[i + 1] != '\0') { |
| form_driver(this->Form, REQ_NEW_LINE); |
| } else { |
| form_driver(this->Form, msg[i]); |
| } |
| i++; |
| } |
| form_driver(this->Form, REQ_BEG_FIELD); |
| |
| this->UpdateStatusBar(); |
| this->PrintKeys(); |
| touchwin(stdscr); |
| refresh(); |
| } |
| |
| void cmCursesLongMessageForm::HandleInput() |
| { |
| if (!this->Form) { |
| return; |
| } |
| |
| char debugMessage[128]; |
| |
| for (;;) { |
| int key = getch(); |
| |
| sprintf(debugMessage, "Message widget handling input, key: %d", key); |
| cmCursesForm::LogMessage(debugMessage); |
| |
| // quit |
| if (key == 'o' || key == 'e') { |
| break; |
| } |
| if (key == KEY_DOWN || key == ctrl('n')) { |
| form_driver(this->Form, REQ_SCR_FLINE); |
| } else if (key == KEY_UP || key == ctrl('p')) { |
| form_driver(this->Form, REQ_SCR_BLINE); |
| } else if (key == KEY_NPAGE || key == ctrl('d')) { |
| form_driver(this->Form, REQ_SCR_FPAGE); |
| } else if (key == KEY_PPAGE || key == ctrl('u')) { |
| form_driver(this->Form, REQ_SCR_BPAGE); |
| } |
| |
| this->UpdateStatusBar(); |
| this->PrintKeys(); |
| touchwin(stdscr); |
| wrefresh(stdscr); |
| } |
| } |