cmCursesLongMessageForm.cxx 4.6 KB

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