cmCursesLongMessageForm.cxx 4.5 KB

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