mirror of
https://github.com/reactos/CMake.git
synced 2025-02-26 06:55:34 +00:00

Use cmSystemTools to report some messages. These should now be caught and displayed properly, both in ccmake and cmake-gui Avoid log display flickering during processing - Don't clear the screen each time the long message form is rendered. It always renders the whole screen again so clearing it only causes flickering. - Add scroll down capabilities to the long message form so that it can draw itself directly in the correct state. This removes the need to programatically scroll down just after that also caused flickering. Fixes #19882 Fixes #13288
181 lines
4.1 KiB
C++
181 lines
4.1 KiB
C++
/* 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 <cstdio>
|
|
#include <cstring>
|
|
|
|
#include "cmCursesForm.h"
|
|
#include "cmCursesMainForm.h"
|
|
#include "cmCursesStandardIncludes.h"
|
|
#include "cmStringAlgorithms.h"
|
|
#include "cmVersion.h"
|
|
|
|
inline int ctrl(int z)
|
|
{
|
|
return (z & 037);
|
|
}
|
|
|
|
cmCursesLongMessageForm::cmCursesLongMessageForm(
|
|
std::vector<std::string> const& messages, const char* title,
|
|
ScrollBehavior scrollBehavior)
|
|
: Scrolling(scrollBehavior)
|
|
{
|
|
// Append all messages into on big string
|
|
this->Messages = cmJoin(messages, "\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;
|
|
int 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; 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;
|
|
int y;
|
|
getmaxyx(stdscr, y, x);
|
|
if (x < cmCursesMainForm::MIN_WIDTH || y < cmCursesMainForm::MIN_HEIGHT) {
|
|
return;
|
|
}
|
|
char firstLine[512];
|
|
sprintf(firstLine, "Press [e] to exit screen");
|
|
|
|
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;
|
|
int 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();
|
|
|
|
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++;
|
|
}
|
|
if (this->Scrolling == ScrollBehavior::ScrollDown) {
|
|
form_driver(this->Form, REQ_END_FIELD);
|
|
} else {
|
|
form_driver(this->Form, REQ_BEG_FIELD);
|
|
}
|
|
|
|
this->UpdateStatusBar();
|
|
touchwin(stdscr);
|
|
refresh();
|
|
}
|
|
|
|
void cmCursesLongMessageForm::HandleInput()
|
|
{
|
|
if (!this->Form) {
|
|
return;
|
|
}
|
|
|
|
char debugMessage[128];
|
|
|
|
for (;;) {
|
|
this->PrintKeys();
|
|
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();
|
|
touchwin(stdscr);
|
|
wrefresh(stdscr);
|
|
}
|
|
}
|