cmCursesLongMessageForm.cxx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmCursesLongMessageForm.h"
  4. #include "cmCursesForm.h"
  5. #include "cmCursesMainForm.h"
  6. #include "cmCursesStandardIncludes.h"
  7. #include "cmVersion.h"
  8. #include <stdio.h>
  9. #include <string.h>
  10. inline int ctrl(int z)
  11. {
  12. return (z & 037);
  13. }
  14. cmCursesLongMessageForm::cmCursesLongMessageForm(
  15. std::vector<std::string> const& messages, const char* title)
  16. {
  17. // Append all messages into on big string
  18. std::vector<std::string>::const_iterator it;
  19. for (it = messages.begin(); it != messages.end(); it++) {
  20. this->Messages += (*it);
  21. // Add one blank line after each message
  22. this->Messages += "\n\n";
  23. }
  24. this->Title = title;
  25. this->Fields[0] = nullptr;
  26. this->Fields[1] = nullptr;
  27. }
  28. cmCursesLongMessageForm::~cmCursesLongMessageForm()
  29. {
  30. if (this->Fields[0]) {
  31. free_field(this->Fields[0]);
  32. }
  33. }
  34. void cmCursesLongMessageForm::UpdateStatusBar()
  35. {
  36. int x, y;
  37. getmaxyx(stdscr, y, x);
  38. char bar[cmCursesMainForm::MAX_WIDTH];
  39. size_t size = strlen(this->Title.c_str());
  40. if (size >= cmCursesMainForm::MAX_WIDTH) {
  41. size = cmCursesMainForm::MAX_WIDTH - 1;
  42. }
  43. strncpy(bar, this->Title.c_str(), size);
  44. for (size_t i = size - 1; i < cmCursesMainForm::MAX_WIDTH; i++) {
  45. bar[i] = ' ';
  46. }
  47. int width;
  48. if (x < cmCursesMainForm::MAX_WIDTH) {
  49. width = x;
  50. } else {
  51. width = cmCursesMainForm::MAX_WIDTH - 1;
  52. }
  53. bar[width] = '\0';
  54. char version[cmCursesMainForm::MAX_WIDTH];
  55. char vertmp[128];
  56. sprintf(vertmp, "CMake Version %s", cmVersion::GetCMakeVersion());
  57. size_t sideSpace = (width - strlen(vertmp));
  58. for (size_t i = 0; i < sideSpace; i++) {
  59. version[i] = ' ';
  60. }
  61. sprintf(version + sideSpace, "%s", vertmp);
  62. version[width] = '\0';
  63. char fmt_s[] = "%s";
  64. curses_move(y - 4, 0);
  65. attron(A_STANDOUT);
  66. printw(fmt_s, bar);
  67. attroff(A_STANDOUT);
  68. curses_move(y - 3, 0);
  69. printw(fmt_s, version);
  70. pos_form_cursor(this->Form);
  71. }
  72. void cmCursesLongMessageForm::PrintKeys()
  73. {
  74. int x, y;
  75. getmaxyx(stdscr, y, x);
  76. if (x < cmCursesMainForm::MIN_WIDTH || y < cmCursesMainForm::MIN_HEIGHT) {
  77. return;
  78. }
  79. char firstLine[512];
  80. sprintf(firstLine, "Press [e] to exit help");
  81. char fmt_s[] = "%s";
  82. curses_move(y - 2, 0);
  83. printw(fmt_s, firstLine);
  84. pos_form_cursor(this->Form);
  85. }
  86. void cmCursesLongMessageForm::Render(int /*left*/, int /*top*/, int /*width*/,
  87. int /*height*/)
  88. {
  89. int x, y;
  90. getmaxyx(stdscr, y, x);
  91. if (this->Form) {
  92. unpost_form(this->Form);
  93. free_form(this->Form);
  94. this->Form = nullptr;
  95. }
  96. const char* msg = this->Messages.c_str();
  97. curses_clear();
  98. if (this->Fields[0]) {
  99. free_field(this->Fields[0]);
  100. this->Fields[0] = nullptr;
  101. }
  102. this->Fields[0] = new_field(y - 6, x - 2, 1, 1, 0, 0);
  103. field_opts_off(this->Fields[0], O_STATIC);
  104. this->Form = new_form(this->Fields);
  105. post_form(this->Form);
  106. int i = 0;
  107. form_driver(this->Form, REQ_BEG_FIELD);
  108. while (msg[i] != '\0' && i < 60000) {
  109. if (msg[i] == '\n' && msg[i + 1] != '\0') {
  110. form_driver(this->Form, REQ_NEW_LINE);
  111. } else {
  112. form_driver(this->Form, msg[i]);
  113. }
  114. i++;
  115. }
  116. form_driver(this->Form, REQ_BEG_FIELD);
  117. this->UpdateStatusBar();
  118. this->PrintKeys();
  119. touchwin(stdscr);
  120. refresh();
  121. }
  122. void cmCursesLongMessageForm::HandleInput()
  123. {
  124. if (!this->Form) {
  125. return;
  126. }
  127. char debugMessage[128];
  128. for (;;) {
  129. int key = getch();
  130. sprintf(debugMessage, "Message widget handling input, key: %d", key);
  131. cmCursesForm::LogMessage(debugMessage);
  132. // quit
  133. if (key == 'o' || key == 'e') {
  134. break;
  135. }
  136. if (key == KEY_DOWN || key == ctrl('n')) {
  137. form_driver(this->Form, REQ_SCR_FLINE);
  138. } else if (key == KEY_UP || key == ctrl('p')) {
  139. form_driver(this->Form, REQ_SCR_BLINE);
  140. } else if (key == KEY_NPAGE || key == ctrl('d')) {
  141. form_driver(this->Form, REQ_SCR_FPAGE);
  142. } else if (key == KEY_PPAGE || key == ctrl('u')) {
  143. form_driver(this->Form, REQ_SCR_BPAGE);
  144. }
  145. this->UpdateStatusBar();
  146. this->PrintKeys();
  147. touchwin(stdscr);
  148. wrefresh(stdscr);
  149. }
  150. }