1947 lines
71 KiB
C
1947 lines
71 KiB
C
//
|
||
// Created by zhang on 2024/12/28.
|
||
//
|
||
#include <string.h>
|
||
#include <ctype.h>
|
||
#include <stdlib.h>
|
||
#include <windows.h>
|
||
#include <math.h>
|
||
#include "./include/function.h"
|
||
#include "./include/curses.h"
|
||
#include "./include/ui.h"
|
||
#include "./include/extern.h"
|
||
#include "./include/sqlite3.h"
|
||
|
||
// 定义窗口宽度和高度
|
||
#define WIN_HEIGHT 30
|
||
#define WIN_WIDTH 60
|
||
|
||
//定义每一行最多显示多少列数据
|
||
#define PAGE_SIZE 10
|
||
|
||
extern char Username[15];
|
||
extern char class[15];
|
||
struct bottom {
|
||
int x, y;
|
||
int width, height;
|
||
char test[30];
|
||
int private;
|
||
};
|
||
|
||
typedef struct Node {
|
||
char *str1; // 存储第一个字符串
|
||
char *str2; // 存储第二个字符串
|
||
int num; // 存储整数
|
||
struct Node *next; // 指向下一个节点的指针
|
||
} Node;
|
||
|
||
void free_list(Node *head) {
|
||
Node *temp;
|
||
while (head != NULL) {
|
||
temp = head;
|
||
head = head->next;
|
||
free(temp->str1); // 释放第一个字符串
|
||
free(temp->str2); // 释放第二个字符串
|
||
free(temp); // 释放节点本身
|
||
}
|
||
}
|
||
|
||
bool list_search(Node *head,int x) {
|
||
Node *temp = head;
|
||
while (temp != NULL) {
|
||
if(temp->num==x)return 1;
|
||
temp = temp->next;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
Node* create_node(const char *str1, const char *str2, int num) {
|
||
Node *new_node = (Node *)malloc(sizeof(Node)); // 分配内存
|
||
if (new_node == NULL) {
|
||
printf("Memory allocation failed\n");
|
||
return NULL;
|
||
}
|
||
|
||
new_node->str1 = strdup(str1); // 复制第一个字符串
|
||
new_node->str2 = strdup(str2); // 复制第二个字符串
|
||
new_node->num = num; // 设置整数
|
||
new_node->next = NULL; // 初始化 next 为 NULL
|
||
|
||
return new_node;
|
||
}
|
||
|
||
void insert_node(Node **head, const char *str1, const char *str2, int num) {
|
||
Node *new_node = create_node(str1, str2, num); // 创建新节点
|
||
if (new_node == NULL) {
|
||
return; // 如果创建节点失败,直接返回
|
||
}
|
||
|
||
if (*head == NULL) {
|
||
*head = new_node; // 如果链表为空,将新节点作为头节点
|
||
} else {
|
||
Node *temp = *head;
|
||
while (temp->next != NULL) {
|
||
temp = temp->next; // 找到链表的最后一个节点
|
||
}
|
||
temp->next = new_node; // 将新节点插入到链表末尾
|
||
}
|
||
}
|
||
|
||
void draw_bottom(WINDOW *win, struct bottom *bot) {
|
||
mvwprintw(win, bot->y, bot->x, "%s", bot->test);
|
||
}
|
||
|
||
struct bottom *creat_bottom(WINDOW *win, int x, int y, int width, int height, char *test[]) {
|
||
struct bottom *bot = malloc(sizeof(struct bottom));
|
||
bot->y = x;
|
||
bot->x = y;
|
||
bot->width = width;
|
||
bot->height = height;
|
||
strcpy(bot->test, test);
|
||
//mvwprintw(win,x,y,"%s",test);
|
||
return bot;
|
||
}
|
||
|
||
bool click_bottom(MEVENT event, struct bottom bottom, int sx, int sy) {
|
||
return event.x - sx >= bottom.x && event.x - sx < bottom.x + bottom.width && event.y - sy >= bottom.y &&
|
||
event.y - sy < bottom.y + bottom.height;
|
||
}
|
||
|
||
int Welcome_ui() {
|
||
MEVENT event;
|
||
int startx, starty;
|
||
initscr(); // 初始化curses
|
||
cbreak(); // 禁用行缓冲
|
||
noecho(); // 不显示输入字符
|
||
curs_set(0); // 隐藏光标
|
||
keypad(stdscr, TRUE); // 启用键盘按键的特殊处理
|
||
mousemask(ALL_MOUSE_EVENTS, NULL); // 启用鼠标事件
|
||
timeout(100); // 设置输入超时,防止程序卡死
|
||
// 获取屏幕的尺寸
|
||
// 计算按钮的显示位置
|
||
int start_y = (LINES - WIN_HEIGHT) / 2;
|
||
int start_x = (COLS - WIN_WIDTH) / 2;
|
||
WINDOW *welcome_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
|
||
keypad(welcome_win, TRUE);
|
||
wborder(welcome_win, '|', '|', '-', '-', '+', '+', '+', '+');
|
||
// 标题
|
||
mvwprintw(welcome_win, 1, 1, "Welcome to math calculate system!");
|
||
struct bottom *login = creat_bottom(welcome_win, 4, 1, 5, 1, "Login");
|
||
draw_bottom(welcome_win, login);
|
||
struct bottom *signin = creat_bottom(welcome_win, 8, 1, 6, 1, "Signin");
|
||
draw_bottom(welcome_win, signin);
|
||
struct bottom *exit = creat_bottom(welcome_win, 12, 1, 4, 1, "Exit");
|
||
draw_bottom(welcome_win, exit);
|
||
wrefresh(welcome_win);
|
||
while (1) {
|
||
int rc = wgetch(welcome_win);
|
||
if (rc == KEY_MOUSE) {
|
||
if (nc_getmouse(&event) == OK) {
|
||
//mvwprintw(welcome_win, 3, 1, "Mouse at (%d, %d), button %d", event.x-start_x, event.y-start_y, event.bstate);
|
||
if (click_bottom(event, *login, start_x, start_y)) {
|
||
free(login);
|
||
free(signin);
|
||
free(exit);
|
||
endwin();
|
||
return 2;
|
||
}
|
||
if (click_bottom(event, *signin, start_x, start_y)) {
|
||
free(login);
|
||
free(signin);
|
||
free(exit);
|
||
endwin();
|
||
return 3;
|
||
}
|
||
if (click_bottom(event, *exit, start_x, start_y)) {
|
||
free(login);
|
||
free(signin);
|
||
free(exit);
|
||
endwin();
|
||
return 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void
|
||
draw_login_window(WINDOW *win, struct bottom *login, struct bottom *signin, struct bottom *user, struct bottom *psword,
|
||
struct bottom *exit) {
|
||
// 清空窗口并绘制边框
|
||
wclear(win);
|
||
box(win, 0, 0);
|
||
|
||
// 标题
|
||
mvwprintw(win, 1, (WIN_WIDTH - 10) / 2, "Login Menu");
|
||
|
||
// 用户名输入框
|
||
mvwprintw(win, 3, 4, "Username:");
|
||
|
||
// 密码输入框
|
||
mvwprintw(win, 6, 4, "Password:");
|
||
//绘制剩余内容
|
||
draw_bottom(win, login);
|
||
draw_bottom(win, signin);
|
||
draw_bottom(win, exit);
|
||
draw_bottom(win, user);
|
||
draw_bottom(win, psword);
|
||
wrefresh(win); // 刷新窗口
|
||
}
|
||
|
||
void
|
||
draw_stu_type_window(WINDOW *win, struct bottom *ok, struct bottom *name_b, struct bottom *class_b,
|
||
struct bottom *majority_b, struct bottom *exit) {
|
||
// 清空窗口并绘制边框
|
||
wclear(win);
|
||
box(win, 0, 0);
|
||
|
||
// 标题
|
||
mvwprintw(win, 1, (WIN_WIDTH - 10) / 2, "Please input your message.");
|
||
|
||
// 用户名输入框
|
||
mvwprintw(win, 3, 4, "Name:");
|
||
|
||
// 密码输入框
|
||
mvwprintw(win, 6, 4, "Class:");
|
||
//绘制剩余内容
|
||
mvwprintw(win, 9, 4, "Majority:");
|
||
draw_bottom(win, ok);
|
||
draw_bottom(win, name_b);
|
||
draw_bottom(win, exit);
|
||
draw_bottom(win, class_b);
|
||
draw_bottom(win, majority_b);
|
||
wrefresh(win); // 刷新窗口
|
||
}
|
||
|
||
|
||
void
|
||
draw_signin_window(WINDOW *win, struct bottom *signin, struct bottom *user, struct bottom *psword,
|
||
struct bottom *exit) {
|
||
// 清空窗口并绘制边框
|
||
wclear(win);
|
||
box(win, 0, 0);
|
||
|
||
// 标题
|
||
mvwprintw(win, 1, (WIN_WIDTH - 10) / 2, "Signin");
|
||
|
||
// 用户名输入框
|
||
mvwprintw(win, 3, 4, "Username:");
|
||
|
||
// 密码输入框
|
||
mvwprintw(win, 6, 4, "Password:");
|
||
//绘制剩余内容
|
||
draw_bottom(win, signin);
|
||
draw_bottom(win, exit);
|
||
draw_bottom(win, user);
|
||
draw_bottom(win, psword);
|
||
wrefresh(win); // 刷新窗口
|
||
}
|
||
|
||
void
|
||
draw_StudentDesktop_window(WINDOW *win, struct bottom *bt1, struct bottom *bt2, struct bottom *bt3,
|
||
struct bottom *bt4) {
|
||
// 清空窗口并绘制边框
|
||
wclear(win);
|
||
box(win, 0, 0);
|
||
|
||
// 标题
|
||
mvwprintw(win, 1, 1, "Welcome! dear %s", Username);
|
||
|
||
//绘制剩余内容
|
||
|
||
draw_bottom(win, bt1);
|
||
draw_bottom(win, bt2);
|
||
draw_bottom(win, bt3);
|
||
draw_bottom(win, bt4);
|
||
|
||
wrefresh(win); // 刷新窗口
|
||
}
|
||
|
||
void
|
||
draw_TeacherDesktop_window(WINDOW *win, struct bottom *bt1, struct bottom *bt2, struct bottom *bt3,
|
||
struct bottom *bt4) {
|
||
// 清空窗口并绘制边框
|
||
wclear(win);
|
||
box(win, 0, 0);
|
||
|
||
// 标题
|
||
mvwprintw(win, 1, 1, "Welcome! Doctor %s", Username);
|
||
|
||
//绘制剩余内容
|
||
|
||
draw_bottom(win, bt1);
|
||
draw_bottom(win, bt2);
|
||
draw_bottom(win, bt3);
|
||
draw_bottom(win, bt4);
|
||
|
||
wrefresh(win); // 刷新窗口
|
||
}
|
||
|
||
void get_input(WINDOW *win, int y, int x, char *buffer, int max_len, struct bottom *bot, int sx, int sy) {
|
||
MEVENT event;
|
||
int ch, pos = 0;
|
||
char *test = bot->test;
|
||
while (pos < max_len && buffer[pos] != '\0')pos++;
|
||
while (1) {
|
||
ch = wgetch(win);
|
||
if (ch == KEY_BACKSPACE || ch == 8) { // 处理退格键
|
||
if (pos > 0) {
|
||
pos--;
|
||
buffer[pos] = '\0';
|
||
if(bot->private!=2)test[pos + 1] = '_';
|
||
else test[pos]='\0';
|
||
mvwprintw(win,1,8," ");
|
||
draw_bottom(win, bot);
|
||
wrefresh(win);
|
||
}
|
||
} else if (ch == KEY_MOUSE) {
|
||
if (nc_getmouse(&event) == OK) {
|
||
if (!click_bottom(event, *bot, sx, sy)) {
|
||
return;
|
||
}
|
||
}
|
||
} else if (pos < max_len - 1) {
|
||
if (bot->private == 1) {
|
||
if (ch >= 33 && ch <= 126) {}
|
||
else {
|
||
mvwprintw(win, 12, 5, "Incorrect input");
|
||
wrefresh(win);
|
||
continue;
|
||
}
|
||
} else if (bot->private == 0) {
|
||
if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9') {}
|
||
else {
|
||
mvwprintw(win, 12, 5, "Incorrect input");
|
||
wrefresh(win);
|
||
continue;
|
||
}
|
||
} else if (bot->private == 2) {
|
||
if (ch >= '0' && ch <= '9' || ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' ||ch == ')') {}
|
||
else {
|
||
mvwprintw(win, 12, 5, "Incorrect input");
|
||
wrefresh(win);
|
||
continue;
|
||
}
|
||
}
|
||
buffer[pos++] = ch;
|
||
if (bot->private == 0)test[pos] = ch;
|
||
else if(bot->private == 1)test[pos] = '*';
|
||
else if(bot->private == 2)test[pos-1]=ch;
|
||
draw_bottom(win, bot);
|
||
wrefresh(win);
|
||
}
|
||
if(ch=='\n')return;
|
||
}
|
||
}
|
||
|
||
void get_input_ez(WINDOW *win, int y, int x, char *buffer, int max_len) {
|
||
mvwprintw(win,y,x,"input here:");
|
||
int ch, pos = 0;
|
||
memset(buffer, 0, max_len); // 清空缓冲区
|
||
|
||
while ((ch = wgetch(win)) != '\n') { // 按回车结束输入
|
||
if (ch == 8 || ch == 127) { // 处理退格键
|
||
if (pos > 0) {
|
||
pos--; // 移动到前一个字符位置
|
||
buffer[pos] = '\0'; // 删除字符
|
||
mvwprintw(win,y, x+11, "%s ", buffer);
|
||
wrefresh(win);
|
||
mvwprintw(win,y, x+11, "%s", buffer);
|
||
}
|
||
} else if (pos < max_len - 1 && ch >= 32 && ch <= 126) { // 可打印字符
|
||
buffer[pos++] = ch; // 将字符加入输入内容
|
||
buffer[pos] = '\0'; // 添加字符串结束符
|
||
mvwprintw(win,y, x+11, "%s", buffer); // 在窗口中实时显示输入
|
||
}
|
||
}
|
||
}
|
||
|
||
int *display_t_test_page(WINDOW *win, sqlite3 *db, int offset, struct bottom *left,
|
||
struct bottom *right, struct bottom *exit,struct bottom *create) {
|
||
wclear(win);
|
||
box(win, 0, 0);
|
||
sqlite3_stmt *stmt;
|
||
int rc;
|
||
int row_count = 0;
|
||
char *sql_query="select test_name,Creater,problems_count,ID from tests";
|
||
// 准备 SQL 语句
|
||
rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
|
||
if (rc != SQLITE_OK) {
|
||
mvwprintw(win, 0, 0, "Failed to prepare statement: %s", sqlite3_errmsg(db));
|
||
wrefresh(win);
|
||
return 0;
|
||
}
|
||
int *id=malloc(PAGE_SIZE*sizeof(int));
|
||
// 计算总行数
|
||
int total_rows = 0;
|
||
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
|
||
total_rows++;
|
||
}
|
||
sqlite3_reset(stmt); // 重置stmt以便重新执行查询
|
||
|
||
// 设置窗口的高度和宽度
|
||
// 显示表格的头部
|
||
mvwprintw(win, 3, 1, "Name Creater problem_count operate ");
|
||
mvwprintw(win, 4, 1, "----------------------------------------------------------");
|
||
|
||
// 跳到指定的偏移位置
|
||
for (int i = 0; i < offset; i++) {
|
||
sqlite3_step(stmt); // 跳过前面的行
|
||
}
|
||
// 从指定的偏移位置开始,显示10行
|
||
int current_row = 5; // 数据开始显示的位置
|
||
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW && row_count < PAGE_SIZE) {
|
||
const char *name = (const char *) sqlite3_column_text(stmt, 0);
|
||
const char *creater = (const char *) sqlite3_column_text(stmt, 1);
|
||
int problem_c = sqlite3_column_int(stmt, 2);
|
||
int now_id= sqlite3_column_int(stmt,3);
|
||
*(id+row_count)=now_id;
|
||
// 输出当前行
|
||
mvwprintw(win, (current_row * 2) - 5, 1, "%-11s %-16s %-24d", name, creater, problem_c);
|
||
start_color();
|
||
init_pair(1, COLOR_BLACK, COLOR_WHITE);
|
||
wattron(win, COLOR_PAIR(1));
|
||
mvwprintw(win, (current_row * 2) - 5, 49, "delete");
|
||
wattroff(win, COLOR_PAIR(1));
|
||
row_count++;
|
||
current_row++;
|
||
}
|
||
|
||
// 打印分页信息
|
||
mvwprintw(win, WIN_HEIGHT - 3, (WIN_WIDTH - 9) / 2, "Page: %d/%d", (offset / PAGE_SIZE) + 1,
|
||
max(1,(total_rows + PAGE_SIZE - 1) / PAGE_SIZE));
|
||
draw_bottom(win, left);
|
||
draw_bottom(win, right);
|
||
draw_bottom(win, exit);
|
||
draw_bottom(win,create);
|
||
// 刷新窗口
|
||
wrefresh(win);
|
||
|
||
sqlite3_finalize(stmt);
|
||
return id;
|
||
}
|
||
|
||
int *display_stu_test_page(WINDOW *win, sqlite3 *db, int offset, struct bottom *left,
|
||
struct bottom *right, struct bottom *exit,int *t_l) {
|
||
wclear(win);
|
||
box(win, 0, 0);
|
||
sqlite3_stmt *stmt;
|
||
int rc;
|
||
int row_count = 0;
|
||
char *sql_query="select test_name,Creater,problems_count,ID from tests";
|
||
// 准备 SQL 语句
|
||
rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
|
||
if (rc != SQLITE_OK) {
|
||
mvwprintw(win, 0, 0, "Failed to prepare statement: %s", sqlite3_errmsg(db));
|
||
wrefresh(win);
|
||
return 0;
|
||
}
|
||
int *id=malloc(PAGE_SIZE*sizeof(int));
|
||
// 计算总行数
|
||
int total_rows = 0;
|
||
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
|
||
total_rows++;
|
||
}
|
||
*t_l=total_rows;
|
||
sqlite3_reset(stmt); // 重置stmt以便重新执行查询
|
||
|
||
// 设置窗口的高度和宽度
|
||
// 显示表格的头部
|
||
mvwprintw(win, 3, 1, "Name Creater problem_count operate ");
|
||
mvwprintw(win, 4, 1, "----------------------------------------------------------");
|
||
|
||
// 跳到指定的偏移位置
|
||
for (int i = 0; i < offset; i++) {
|
||
sqlite3_step(stmt); // 跳过前面的行
|
||
}
|
||
// 从指定的偏移位置开始,显示10行
|
||
int current_row = 5; // 数据开始显示的位置
|
||
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW && row_count < PAGE_SIZE) {
|
||
const char *name = (const char *) sqlite3_column_text(stmt, 0);
|
||
const char *creater = (const char *) sqlite3_column_text(stmt, 1);
|
||
int problem_c = sqlite3_column_int(stmt, 2);
|
||
int now_id= sqlite3_column_int(stmt,3);
|
||
*(id+row_count)=now_id;
|
||
// 输出当前行
|
||
mvwprintw(win, (current_row * 2) - 5, 1, "%-11s %-16s %-24d", name, creater, problem_c);
|
||
start_color();
|
||
init_pair(1, COLOR_BLACK, COLOR_WHITE);
|
||
wattron(win, COLOR_PAIR(1));
|
||
mvwprintw(win, (current_row * 2) - 5, 49, "enter");
|
||
wattroff(win, COLOR_PAIR(1));
|
||
row_count++;
|
||
current_row++;
|
||
}
|
||
|
||
// 打印分页信息
|
||
mvwprintw(win, WIN_HEIGHT - 3, (WIN_WIDTH - 9) / 2, "Page: %d/%d", (offset / PAGE_SIZE) + 1,
|
||
max(1,(total_rows + PAGE_SIZE - 1) / PAGE_SIZE));
|
||
draw_bottom(win, left);
|
||
draw_bottom(win, right);
|
||
draw_bottom(win, exit);
|
||
// 刷新窗口
|
||
wrefresh(win);
|
||
|
||
sqlite3_finalize(stmt);
|
||
return id;
|
||
}
|
||
int Login_ui() {
|
||
MEVENT event;
|
||
char *errmsg[30];
|
||
memset(errmsg, 0, 30);
|
||
int start_y = (LINES - WIN_HEIGHT) / 2;
|
||
int start_x = (COLS - WIN_WIDTH) / 2;
|
||
WINDOW *login_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
|
||
keypad(login_win, TRUE);
|
||
char *username[15]; //储存用户名
|
||
memset(username, '\0', 15); // 清空缓冲区
|
||
char *password[15]; //储存密码
|
||
memset(password, '\0', 15); // 清空缓冲区
|
||
struct bottom *login = creat_bottom(login_win, 10, 4, 5, 1, "Login");
|
||
struct bottom *signin = creat_bottom(login_win, 10, 14, 5, 1, "Signin");
|
||
struct bottom *exit = creat_bottom(login_win, 10, 25, 5, 1, "Exit");
|
||
struct bottom *users = creat_bottom(login_win, 4, 4, 16, 1, "[______________]");
|
||
struct bottom *psword = creat_bottom(login_win, 7, 4, 16, 1, "[______________]");
|
||
psword->private = 1;
|
||
users->private = 0;
|
||
int willdraw = 1;
|
||
while (1) {
|
||
if (willdraw)draw_login_window(login_win, login, signin, users, psword, exit);
|
||
int rc = wgetch(login_win);
|
||
if (rc == KEY_MOUSE) {
|
||
if (nc_getmouse(&event) == OK) {
|
||
//mvwprintw(welcome_win, 3, 1, "Mouse at (%d, %d), button %d", event.x-start_x, event.y-start_y, event.bstate);
|
||
if (willdraw)
|
||
if (click_bottom(event, *login, start_x, start_y)) {
|
||
int recall;
|
||
Login(username, password, &recall, errmsg);
|
||
if (recall == -1) {
|
||
wclear(login_win);
|
||
mvwprintw(login_win, 5, 5, "%s", errmsg);
|
||
exit->x = 5;
|
||
exit->y = 8;
|
||
draw_bottom(login_win, exit);
|
||
wrefresh(login_win);
|
||
willdraw = 0;
|
||
continue;
|
||
} else {
|
||
free(login);
|
||
free(signin);
|
||
free(exit);
|
||
free(users);
|
||
free(psword);
|
||
endwin();
|
||
return recall;
|
||
}
|
||
}
|
||
if (willdraw)
|
||
if (click_bottom(event, *signin, start_x, start_y)) {
|
||
free(login);
|
||
free(signin);
|
||
free(exit);
|
||
free(users);
|
||
free(psword);
|
||
endwin();
|
||
return SIGNIN_UI;
|
||
}
|
||
if (click_bottom(event, *exit, start_x, start_y)) {
|
||
free(login);
|
||
free(signin);
|
||
free(exit);
|
||
free(users);
|
||
free(psword);
|
||
endwin();
|
||
return willdraw == 1 ? WELCOME_UI : LOGIN_UI;
|
||
}
|
||
if (willdraw)
|
||
if (click_bottom(event, *users, start_x, start_y)) {
|
||
get_input(login_win, 4, 6, username, 15, users, start_x, start_y);
|
||
continue;
|
||
}
|
||
if (willdraw)
|
||
if (click_bottom(event, *psword, start_x, start_y)) {
|
||
get_input(login_win, 7, 6, password, 15, psword, start_x, start_y);
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
int Signin_ui() {
|
||
MEVENT event;
|
||
char *errmsg[100];
|
||
memset(errmsg, 0, 30);
|
||
int start_y = (LINES - WIN_HEIGHT) / 2;
|
||
int start_x = (COLS - WIN_WIDTH) / 2;
|
||
WINDOW *signin_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
|
||
keypad(signin_win, TRUE);
|
||
char *username[15]; //储存用户名
|
||
memset(username, '\0', 15); // 清空缓冲区
|
||
char *password[15]; //储存密码
|
||
memset(password, '\0', 15); // 清空缓冲区
|
||
struct bottom *signin = creat_bottom(signin_win, 10, 4, 5, 1, "Signin");
|
||
struct bottom *exit = creat_bottom(signin_win, 10, 25, 5, 1, "Exit");
|
||
struct bottom *users = creat_bottom(signin_win, 4, 4, 16, 1, "[______________]");
|
||
struct bottom *psword = creat_bottom(signin_win, 7, 4, 16, 1, "[______________]");
|
||
psword->private = 0;
|
||
users->private = 0;
|
||
int willdraw = 1;
|
||
while (1) {
|
||
if (willdraw == 1)draw_signin_window(signin_win, signin, users, psword, exit);
|
||
int rc = wgetch(signin_win);
|
||
if (rc == KEY_MOUSE) {
|
||
if (nc_getmouse(&event) == OK) {
|
||
//mvwprintw(welcome_win, 3, 1, "Mouse at (%d, %d), button %d", event.x-start_x, event.y-start_y, event.bstate);
|
||
if (willdraw == 1)
|
||
if (click_bottom(event, *signin, start_x, start_y)) {
|
||
int recall;
|
||
Signin(username, password, &recall, errmsg);
|
||
if (recall != 0) {
|
||
wclear(signin_win);
|
||
mvwprintw(signin_win, 5, 5, "%s", errmsg);
|
||
exit->x = 5;
|
||
exit->y = 8;
|
||
draw_bottom(signin_win, exit);
|
||
wrefresh(signin_win);
|
||
willdraw = 2;
|
||
continue;
|
||
} else {
|
||
wclear(signin_win);
|
||
mvwprintw(signin_win, 5, 5, "Accepted");
|
||
exit->x = 5;
|
||
exit->y = 8;
|
||
draw_bottom(signin_win, exit);
|
||
wrefresh(signin_win);
|
||
willdraw = 0;
|
||
continue;
|
||
}
|
||
}
|
||
if (click_bottom(event, *exit, start_x, start_y)) {
|
||
free(signin);
|
||
free(exit);
|
||
free(users);
|
||
free(psword);
|
||
endwin();
|
||
return willdraw == 2 ? SIGNIN_UI : WELCOME_UI;
|
||
}
|
||
if (willdraw == 1)
|
||
if (click_bottom(event, *users, start_x, start_y)) {
|
||
get_input(signin_win, 4, 6, username, 15, users, start_x, start_y);
|
||
continue;
|
||
}
|
||
if (willdraw == 1)
|
||
if (click_bottom(event, *psword, start_x, start_y)) {
|
||
get_input(signin_win, 7, 6, password, 15, psword, start_x, start_y);
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
int stu_type_ui() {
|
||
int recall = stu_type_check();
|
||
if (recall == -1)myexit();
|
||
if (recall == 1)return 0;
|
||
MEVENT event;
|
||
char *errmsg[30];
|
||
memset(errmsg, 0, 30);
|
||
int start_y = (LINES - WIN_HEIGHT) / 2;
|
||
int start_x = (COLS - WIN_WIDTH) / 2;
|
||
WINDOW *stu_type_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
|
||
keypad(stu_type_win, TRUE);
|
||
char *name[15]; //储存用户名
|
||
memset(name, '\0', 15); // 清空缓冲区
|
||
char *majority[15]; //储存用户名
|
||
memset(majority, '\0', 15); // 清空缓冲区
|
||
char *class[15]; //储存密码
|
||
memset(class, '\0', 15); // 清空缓冲区
|
||
struct bottom *ok = creat_bottom(stu_type_win, 13, 4, 5, 1, "OK");
|
||
struct bottom *exit = creat_bottom(stu_type_win, 13, 25, 5, 1, "Exit");
|
||
struct bottom *name_b = creat_bottom(stu_type_win, 4, 4, 16, 1, "[______________]");
|
||
struct bottom *class_b = creat_bottom(stu_type_win, 7, 4, 16, 1, "[______________]");
|
||
struct bottom *majority_b = creat_bottom(stu_type_win, 10, 4, 16, 1, "[______________]");
|
||
name_b->private = 0;
|
||
class_b->private = 0;
|
||
majority_b->private = 0;
|
||
int willdraw = 1;
|
||
while (1) {
|
||
if (willdraw)draw_stu_type_window(stu_type_win, ok, name_b, class_b, majority_b, exit);
|
||
int rc = wgetch(stu_type_win);
|
||
if (rc == KEY_MOUSE) {
|
||
if (nc_getmouse(&event) == OK) {
|
||
//mvwprintw(welcome_win, 3, 1, "Mouse at (%d, %d), button %d", event.x-start_x, event.y-start_y, event.bstate);
|
||
if (willdraw)
|
||
if (click_bottom(event, *ok, start_x, start_y)) {
|
||
int recall;
|
||
stu_type_insert(name, class, majority, &recall, errmsg);
|
||
if (recall == -1) {
|
||
wclear(stu_type_win);
|
||
mvwprintw(stu_type_win, 5, 5, "%s", errmsg);
|
||
exit->x = 5;
|
||
exit->y = 8;
|
||
draw_bottom(stu_type_win, exit);
|
||
wrefresh(stu_type_win);
|
||
willdraw = 0;
|
||
continue;
|
||
} else {
|
||
free(ok);
|
||
free(name_b);
|
||
free(exit);
|
||
free(class_b);
|
||
free(majority_b);
|
||
endwin();
|
||
return 0;
|
||
}
|
||
}
|
||
if (click_bottom(event, *exit, start_x, start_y)) {
|
||
free(ok);
|
||
free(exit);
|
||
free(name_b);
|
||
free(class_b);
|
||
free(majority_b);
|
||
endwin();
|
||
return -1;
|
||
}
|
||
if (willdraw)
|
||
if (click_bottom(event, *name_b, start_x, start_y)) {
|
||
get_input(stu_type_win, 4, 6, name, 15, name_b, start_x, start_y);
|
||
continue;
|
||
}
|
||
if (willdraw)
|
||
if (click_bottom(event, *class_b, start_x, start_y)) {
|
||
get_input(stu_type_win, 7, 6, class, 15, class_b, start_x, start_y);
|
||
continue;
|
||
}
|
||
if (willdraw)
|
||
if (click_bottom(event, *majority_b, start_x, start_y)) {
|
||
get_input(stu_type_win, 4, 6, majority, 15, majority_b, start_x, start_y);
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
int StudentsDesktop_ui() {
|
||
int recall = stu_type_ui();
|
||
if (recall == -1) {
|
||
memset(Username, 0, 15);
|
||
return WELCOME_UI;
|
||
}
|
||
MEVENT event;
|
||
char *errmsg[30];
|
||
memset(errmsg, 0, 30);
|
||
int start_y = (LINES - WIN_HEIGHT) / 2;
|
||
int start_x = (COLS - WIN_WIDTH) / 2;
|
||
WINDOW *StudentsDesktop_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
|
||
keypad(StudentsDesktop_win, TRUE);
|
||
struct bottom *test = creat_bottom(StudentsDesktop_win, 3, 4, 6, 1, "1.Test");
|
||
struct bottom *hissc = creat_bottom(StudentsDesktop_win, 6, 4, 15, 1, "2.History Score");
|
||
struct bottom *exercise = creat_bottom(StudentsDesktop_win, 9, 4, 10, 1, "3.Exercise");
|
||
struct bottom *exit = creat_bottom(StudentsDesktop_win, 12, 4, 6, 1, "4.Exit");
|
||
while (1) {
|
||
draw_StudentDesktop_window(StudentsDesktop_win, test, hissc, exercise, exit);
|
||
int rc = wgetch(StudentsDesktop_win);
|
||
if (rc == KEY_MOUSE) {
|
||
if (nc_getmouse(&event) == OK) {
|
||
if (click_bottom(event, *test, start_x, start_y)) {
|
||
int recall;
|
||
|
||
stu_test_ui(&recall, errmsg, class);
|
||
if (recall != 0) {
|
||
wclear(StudentsDesktop_win);
|
||
mvwprintw(StudentsDesktop_win, 1, 1, errmsg);
|
||
sqlite3_sleep(2000);
|
||
}
|
||
continue;
|
||
}
|
||
if (click_bottom(event, *hissc, start_x, start_y)) {
|
||
stu_his_sc_ui();
|
||
continue;
|
||
}
|
||
if (click_bottom(event, *exercise, start_x, start_y)) {
|
||
stu_exercise_ui();
|
||
continue;
|
||
}
|
||
if (click_bottom(event, *exit, start_x, start_y)) {
|
||
free(test);
|
||
free(hissc);
|
||
free(exit);
|
||
free(exercise);
|
||
endwin();
|
||
memset(Username, 0, 15);
|
||
return WELCOME_UI;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void stu_exercise_ui() {
|
||
|
||
}
|
||
|
||
void display_stu_score_page(WINDOW *win, sqlite3 *db, int offset, struct bottom *left,struct bottom *right, struct bottom *exit, struct bottom *search,int *row_count){
|
||
char *sql_query="select majority,class,name,test_name,score from stu where user=? and test_name like ?";
|
||
int *id=malloc(PAGE_SIZE*sizeof(int));
|
||
wclear(win);
|
||
box(win, 0, 0);
|
||
sqlite3_stmt *stmt;
|
||
int rc;
|
||
|
||
// 准备 SQL 语句
|
||
rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
|
||
if (rc != SQLITE_OK) {
|
||
mvwprintw(win, 0, 0, "Failed to prepare statement: %s", sqlite3_errmsg(db));
|
||
wrefresh(win);
|
||
return;
|
||
}
|
||
char query[100];
|
||
memset(query,0,sizeof(query));
|
||
snprintf(query, sizeof(query), "%%%s%%", search->test); // 构造 LIKE 查询参数
|
||
sqlite3_bind_text(stmt, 1, Username, -1, SQLITE_STATIC);
|
||
sqlite3_bind_text(stmt, 2, query, -1, SQLITE_STATIC);
|
||
// 计算总行数
|
||
int total_rows = 0;
|
||
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
|
||
total_rows++;
|
||
}
|
||
*row_count=total_rows;
|
||
sqlite3_reset(stmt); // 重置stmt以便重新执行查询
|
||
|
||
// 设置窗口的高度和宽度
|
||
// 显示表格的头部
|
||
mvwprintw(win, 1, 1, "Search:");
|
||
mvwprintw(win, 3, 1, "majority class name test_name score ");
|
||
mvwprintw(win, 4, 1, "----------------------------------------------------------");
|
||
|
||
// 跳到指定的偏移位置
|
||
for (int i = 0; i < offset; i++) {
|
||
sqlite3_step(stmt); // 跳过前面的行
|
||
}
|
||
int row_c=0;
|
||
// 从指定的偏移位置开始,显示10行
|
||
int current_row = 5; // 数据开始显示的位置
|
||
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW && row_c < PAGE_SIZE) {
|
||
const char *majority = (const char *) sqlite3_column_text(stmt, 0);
|
||
const char *class = (const char *) sqlite3_column_text(stmt, 1);
|
||
const char *name = (const char *) sqlite3_column_text(stmt, 2);
|
||
const char *test_name = (const char *) sqlite3_column_text(stmt, 3);
|
||
int score = sqlite3_column_int(stmt, 4);
|
||
// 输出当前行
|
||
mvwprintw(win, (current_row * 2) - 5, 1, "%-13s %-10s %-10s %-15s %-5d",majority,class,name,test_name,score);
|
||
row_c++;
|
||
current_row++;
|
||
}
|
||
|
||
// 打印分页信息
|
||
mvwprintw(win, WIN_HEIGHT - 3, (WIN_WIDTH - 9) / 2, "Page: %d/%d", (offset / PAGE_SIZE) + 1,
|
||
max(1,(total_rows + PAGE_SIZE - 1) / PAGE_SIZE));
|
||
draw_bottom(win, left);
|
||
draw_bottom(win, right);
|
||
draw_bottom(win, exit);
|
||
draw_bottom(win, search);
|
||
draw_bottom(win, add);
|
||
// 刷新窗口
|
||
wrefresh(win);
|
||
|
||
sqlite3_finalize(stmt);
|
||
return;
|
||
}
|
||
|
||
void display_t_score_page(WINDOW *win, sqlite3 *db, int offset, struct bottom *left,struct bottom *right, struct bottom *exit, struct bottom *search,int *row_count){
|
||
char *sql_query="select majority,class,name,test_name,score from stu where test_name like ?";
|
||
int *id=malloc(PAGE_SIZE*sizeof(int));
|
||
wclear(win);
|
||
box(win, 0, 0);
|
||
sqlite3_stmt *stmt;
|
||
int rc;
|
||
|
||
// 准备 SQL 语句
|
||
rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
|
||
if (rc != SQLITE_OK) {
|
||
mvwprintw(win, 0, 0, "Failed to prepare statement: %s", sqlite3_errmsg(db));
|
||
wrefresh(win);
|
||
return;
|
||
}
|
||
char query[100];
|
||
memset(query,0,sizeof(query));
|
||
snprintf(query, sizeof(query), "%%%s%%", search->test); // 构造 LIKE 查询参数
|
||
sqlite3_bind_text(stmt, 1, query, -1, SQLITE_STATIC);
|
||
// 计算总行数
|
||
int total_rows = 0;
|
||
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
|
||
total_rows++;
|
||
}
|
||
*row_count=total_rows;
|
||
sqlite3_reset(stmt); // 重置stmt以便重新执行查询
|
||
|
||
// 设置窗口的高度和宽度
|
||
// 显示表格的头部
|
||
mvwprintw(win, 1, 1, "Search:");
|
||
mvwprintw(win, 3, 1, "majority class name test_name score ");
|
||
mvwprintw(win, 4, 1, "----------------------------------------------------------");
|
||
|
||
// 跳到指定的偏移位置
|
||
for (int i = 0; i < offset; i++) {
|
||
sqlite3_step(stmt); // 跳过前面的行
|
||
}
|
||
int row_c=0;
|
||
// 从指定的偏移位置开始,显示10行
|
||
int current_row = 5; // 数据开始显示的位置
|
||
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW && row_c < PAGE_SIZE) {
|
||
const char *majority = (const char *) sqlite3_column_text(stmt, 0);
|
||
const char *class = (const char *) sqlite3_column_text(stmt, 1);
|
||
const char *name = (const char *) sqlite3_column_text(stmt, 2);
|
||
const char *test_name = (const char *) sqlite3_column_text(stmt, 3);
|
||
int score = sqlite3_column_int(stmt, 4);
|
||
// 输出当前行
|
||
mvwprintw(win, (current_row * 2) - 5, 1, "%-13s %-10s %-10s %-15s %-5d",majority,class,name,test_name,score);
|
||
row_c++;
|
||
current_row++;
|
||
}
|
||
|
||
// 打印分页信息
|
||
mvwprintw(win, WIN_HEIGHT - 3, (WIN_WIDTH - 9) / 2, "Page: %d/%d", (offset / PAGE_SIZE) + 1,
|
||
max(1,(total_rows + PAGE_SIZE - 1) / PAGE_SIZE));
|
||
draw_bottom(win, left);
|
||
draw_bottom(win, right);
|
||
draw_bottom(win, exit);
|
||
draw_bottom(win, search);
|
||
draw_bottom(win, add);
|
||
// 刷新窗口
|
||
wrefresh(win);
|
||
|
||
sqlite3_finalize(stmt);
|
||
return;
|
||
}
|
||
|
||
void stu_his_sc_ui() {
|
||
MEVENT event;
|
||
int start_y = (LINES - WIN_HEIGHT) / 2;
|
||
int start_x = (COLS - WIN_WIDTH) / 2;
|
||
WINDOW *stu_score_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
|
||
keypad(stu_score_win, TRUE);
|
||
int offset = 0;
|
||
sqlite3 *db;
|
||
const char *db_filename = "./data/msg.db"; // SQLite 数据库文件名
|
||
const char *sql_query; // 查询 SQL
|
||
struct bottom *left = creat_bottom(stu_score_win, WIN_HEIGHT - 3, 20, 2, 1, "<-");
|
||
struct bottom *right = creat_bottom(stu_score_win, WIN_HEIGHT - 3, 40, 2, 1, "->");
|
||
struct bottom *exit = creat_bottom(stu_score_win, WIN_HEIGHT - 3, 52, 4, 1, "Exit");
|
||
struct bottom *search = creat_bottom(stu_score_win, 1, 8, 20, 1, "");
|
||
memset(search->test,0,30);
|
||
search->private = 2;
|
||
char searchq[100];
|
||
memset(searchq, 0, 100);
|
||
// 打开数据库
|
||
if (sqlite3_open(db_filename, &db) != SQLITE_OK) {
|
||
return;
|
||
}
|
||
int *id;
|
||
sqlite3_stmt *stmt;
|
||
int row_count = 0;
|
||
while (1) {
|
||
// 清空窗口内容
|
||
werase(stu_score_win);
|
||
box(stu_score_win, 0, 0);
|
||
// 调用函数输出当前的滚动窗口内容
|
||
display_stu_score_page(stu_score_win, db, offset, left, right, exit, search,&row_count);
|
||
|
||
int rc = wgetch(stu_score_win);
|
||
if (rc == KEY_MOUSE) {
|
||
if (nc_getmouse(&event) == OK) {
|
||
if (click_bottom(event, *left, start_x, start_y)) {
|
||
if (offset >= PAGE_SIZE) {
|
||
offset -= PAGE_SIZE;
|
||
}
|
||
continue;
|
||
}
|
||
if (click_bottom(event, *right, start_x, start_y)) {
|
||
if (offset + PAGE_SIZE < row_count) { // 总共有100条数据可以调整
|
||
offset += PAGE_SIZE;
|
||
}
|
||
continue;
|
||
}
|
||
if (click_bottom(event, *exit, start_x, start_y)) {
|
||
free(left);
|
||
free(right);
|
||
free(exit);
|
||
delwin(stu_score_win);
|
||
return;
|
||
}
|
||
if (click_bottom(event, *search, start_x, start_y)) {
|
||
get_input(stu_score_win, 4, 6, searchq, 15, search, start_x, start_y);
|
||
offset = 0;
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void t_his_sc_ui() {
|
||
MEVENT event;
|
||
int start_y = (LINES - WIN_HEIGHT) / 2;
|
||
int start_x = (COLS - WIN_WIDTH) / 2;
|
||
WINDOW *t_score_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
|
||
keypad(t_score_win, TRUE);
|
||
int offset = 0;
|
||
sqlite3 *db;
|
||
const char *db_filename = "./data/msg.db"; // SQLite 数据库文件名
|
||
const char *sql_query; // 查询 SQL
|
||
struct bottom *left = creat_bottom(t_score_win, WIN_HEIGHT - 3, 20, 2, 1, "<-");
|
||
struct bottom *right = creat_bottom(t_score_win, WIN_HEIGHT - 3, 40, 2, 1, "->");
|
||
struct bottom *exit = creat_bottom(t_score_win, WIN_HEIGHT - 3, 52, 4, 1, "Exit");
|
||
struct bottom *search = creat_bottom(t_score_win, 1, 8, 20, 1, "");
|
||
memset(search->test,0,30);
|
||
search->private = 2;
|
||
char searchq[100];
|
||
memset(searchq, 0, 100);
|
||
// 打开数据库
|
||
if (sqlite3_open(db_filename, &db) != SQLITE_OK) {
|
||
return;
|
||
}
|
||
int *id;
|
||
sqlite3_stmt *stmt;
|
||
int row_count = 0;
|
||
while (1) {
|
||
// 清空窗口内容
|
||
werase(t_score_win);
|
||
box(t_score_win, 0, 0);
|
||
// 调用函数输出当前的滚动窗口内容
|
||
display_t_score_page(t_score_win, db, offset, left, right, exit, search,&row_count);
|
||
|
||
int rc = wgetch(t_score_win);
|
||
if (rc == KEY_MOUSE) {
|
||
if (nc_getmouse(&event) == OK) {
|
||
if (click_bottom(event, *left, start_x, start_y)) {
|
||
if (offset >= PAGE_SIZE) {
|
||
offset -= PAGE_SIZE;
|
||
}
|
||
continue;
|
||
}
|
||
if (click_bottom(event, *right, start_x, start_y)) {
|
||
if (offset + PAGE_SIZE < row_count) { // 总共有100条数据可以调整
|
||
offset += PAGE_SIZE;
|
||
}
|
||
continue;
|
||
}
|
||
if (click_bottom(event, *exit, start_x, start_y)) {
|
||
free(left);
|
||
free(right);
|
||
free(exit);
|
||
delwin(t_score_win);
|
||
return;
|
||
}
|
||
if (click_bottom(event, *search, start_x, start_y)) {
|
||
get_input(t_score_win, 4, 6, searchq, 15, search, start_x, start_y);
|
||
offset = 0;
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void enter(WINDOW *win,sqlite3 *db,int id,int start_x,int start_y){
|
||
int offset=0;
|
||
int correct_conuts=0;
|
||
int total_rows = 0;
|
||
double answer;
|
||
struct bottom *exit = creat_bottom(win, WIN_HEIGHT - 3, 52, 4, 1, "Exit");
|
||
while(1){
|
||
wclear(win);
|
||
box(win, 0, 0);
|
||
sqlite3_stmt *stmt;
|
||
int rc;
|
||
char *sql_query="select text,answer from test_include where test_index=?";
|
||
// 准备 SQL 语句
|
||
rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
|
||
if (rc != SQLITE_OK) {
|
||
mvwprintw(win, 0, 0, "Failed to prepare statement: %s", sqlite3_errmsg(db));
|
||
wrefresh(win);
|
||
return;
|
||
}
|
||
sqlite3_bind_int(stmt,1,id);
|
||
// 计算总行数
|
||
total_rows=0;
|
||
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
|
||
total_rows++;
|
||
}
|
||
sqlite3_reset(stmt); // 重置stmt以便重新执行查询
|
||
// 跳到指定的偏移位置
|
||
for (int i = 0; i < offset; i++) {
|
||
sqlite3_step(stmt); // 跳过前面的行
|
||
}
|
||
// 从指定的偏移位置开始,显示10行
|
||
if((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
|
||
const char *name = (const char *) sqlite3_column_text(stmt, 0);
|
||
answer = sqlite3_column_double(stmt, 1);
|
||
int now_id= sqlite3_column_int(stmt,2);
|
||
// 输出当前行
|
||
mvwprintw(win, 15, 15, "%-22s", name);
|
||
}
|
||
|
||
// 打印分页信息
|
||
mvwprintw(win, WIN_HEIGHT - 3, (WIN_WIDTH - 9) / 2, "Problem: %d/%d", offset + 1,total_rows);
|
||
draw_bottom(win, exit);
|
||
mvwprintw(win, 17, 15, "Please input your answer:", offset + 1,total_rows);
|
||
// 刷新窗口
|
||
wrefresh(win);
|
||
|
||
double ans;
|
||
cbreak(); // 禁用行缓冲
|
||
noecho(); // 禁用自动回显
|
||
curs_set(1); // 显示光标
|
||
mvwscanw(win,18,15,"%lf",&ans);
|
||
|
||
mvwprintw(win,18,15,"Your answer:%.3lf",ans);
|
||
mvwprintw(win,19,15,"standard answer:%.3lf",answer);
|
||
|
||
if(abs(ans-answer)<0.01){
|
||
mvwprintw(win,20,15,"Accepted");
|
||
correct_conuts++;
|
||
}
|
||
else{
|
||
mvwprintw(win,20,15,"Wrong answer");
|
||
}
|
||
wrefresh(win);
|
||
sqlite3_finalize(stmt);
|
||
sqlite3_sleep(2000);
|
||
offset++;
|
||
if(offset==total_rows)break;
|
||
}
|
||
wclear(win);
|
||
mvwprintw(win,15,15,"The text has finished.");
|
||
int score=(double)correct_conuts/(double)total_rows*100;
|
||
mvwprintw(win,16,15,"Your Score is:%d",score);wrefresh(win);
|
||
sqlite3_sleep(5000);
|
||
sqlite3_stmt *stmt;
|
||
int rc;
|
||
char *sql_select="select test_name from tests where ID=?;";
|
||
rc = sqlite3_prepare_v2(db, sql_select, -1, &stmt, 0);
|
||
if (rc != SQLITE_OK) {
|
||
return;
|
||
}
|
||
char *db_test_name;
|
||
// 绑定查询参数
|
||
sqlite3_bind_int(stmt, 1, id);
|
||
rc = sqlite3_step(stmt);
|
||
if (rc == SQLITE_ROW) {
|
||
|
||
db_test_name = sqlite3_column_text(stmt, 0);
|
||
}
|
||
else{
|
||
sqlite3_finalize(stmt);
|
||
free(exit);
|
||
return;
|
||
}
|
||
char *sql_query = "insert into stu (majority,class,name,test_name,test_index,score,user) select majority,class,name,?,?,?,user from students where user=?;";
|
||
// 编译 SQL 语句
|
||
rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
|
||
if (rc != SQLITE_OK) {
|
||
sqlite3_finalize(stmt);
|
||
sqlite3_close(db);
|
||
return;
|
||
}
|
||
|
||
sqlite3_bind_text(stmt,1,db_test_name,-1,SQLITE_STATIC);
|
||
sqlite3_bind_int(stmt,2,id);
|
||
sqlite3_bind_int(stmt,3,score);
|
||
sqlite3_bind_text(stmt,4,Username,-1,SQLITE_STATIC);
|
||
|
||
rc = sqlite3_step(stmt);
|
||
if (rc != SQLITE_DONE) {
|
||
sqlite3_finalize(stmt);
|
||
free(exit);
|
||
return;
|
||
}
|
||
sqlite3_finalize(stmt);
|
||
while(1) {
|
||
MEVENT event;
|
||
draw_bottom(win,exit);
|
||
wrefresh(win);
|
||
int rc = wgetch(win);
|
||
if (rc == KEY_MOUSE) {
|
||
if (nc_getmouse(&event) == OK) {
|
||
if (click_bottom(event, *exit, start_x, start_y)) {
|
||
free(exit);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void stu_test_ui(int *recall, char *errmsg, char *class) {
|
||
MEVENT event;
|
||
int start_y = (LINES - WIN_HEIGHT) / 2;
|
||
int start_x = (COLS - WIN_WIDTH) / 2;
|
||
WINDOW *stu_problem_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
|
||
keypad(stu_problem_win, TRUE);
|
||
int offset = 0;
|
||
sqlite3 *db;
|
||
const char *db_filename = "./data/msg.db"; // SQLite 数据库文件名
|
||
const char *sql_query; // 查询 SQL
|
||
struct bottom *left = creat_bottom(stu_problem_win, WIN_HEIGHT - 3, 20, 2, 1, "<-");
|
||
struct bottom *right = creat_bottom(stu_problem_win, WIN_HEIGHT - 3, 40, 2, 1, "->");
|
||
struct bottom *exit = creat_bottom(stu_problem_win, WIN_HEIGHT - 3, 52, 4, 1, "Exit");
|
||
// 打开数据库
|
||
if (sqlite3_open(db_filename, &db) != SQLITE_OK) {
|
||
*recall = -1;
|
||
return;
|
||
}
|
||
int *id;
|
||
sqlite3_stmt *stmt;
|
||
int row_count = 0;
|
||
while (1) {
|
||
// 清空窗口内容
|
||
werase(stu_problem_win);
|
||
box(stu_problem_win, 0, 0);
|
||
// 调用函数输出当前的滚动窗口内容
|
||
id = display_stu_test_page(stu_problem_win, db, offset, left, right, exit,&row_count);
|
||
|
||
int rc = wgetch(stu_problem_win);
|
||
if (rc == KEY_MOUSE) {
|
||
if (nc_getmouse(&event) == OK) {
|
||
if (click_bottom(event, *left, start_x, start_y)) {
|
||
if (offset >= PAGE_SIZE) {
|
||
offset -= PAGE_SIZE;
|
||
}
|
||
continue;
|
||
}
|
||
if (click_bottom(event, *right, start_x, start_y)) {
|
||
if (offset + PAGE_SIZE < row_count) { // 总共有100条数据可以调整
|
||
offset += PAGE_SIZE;
|
||
}
|
||
continue;
|
||
}
|
||
if (click_bottom(event, *exit, start_x, start_y)) {
|
||
free(left);
|
||
free(right);
|
||
free(exit);
|
||
free(id);
|
||
sqlite3_close(db);
|
||
delwin(stu_problem_win);
|
||
return;
|
||
}
|
||
if (event.x - start_x >= 49 && event.x - start_x <= 53) { //enter
|
||
int test_id=*(id+(((event.y-start_y)+5)/2-5));
|
||
enter(stu_problem_win,db,test_id,start_x,start_y);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void t_test_ui(int *recall, char *errmsg) {
|
||
MEVENT event;
|
||
memset(errmsg, 0, 30);
|
||
int start_y = (LINES - WIN_HEIGHT) / 2;
|
||
int start_x = (COLS - WIN_WIDTH) / 2;
|
||
WINDOW *t_test_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
|
||
keypad(t_test_win, TRUE);
|
||
int offset = 0;
|
||
sqlite3 *db;
|
||
const char *db_filename = "./data/msg.db"; // SQLite 数据库文件名
|
||
const char *sql_query; // 查询 SQL
|
||
struct bottom *left = creat_bottom(t_test_win, WIN_HEIGHT - 3, 20, 2, 1, "<-");
|
||
struct bottom *right = creat_bottom(t_test_win, WIN_HEIGHT - 3, 40, 2, 1, "->");
|
||
struct bottom *exit = creat_bottom(t_test_win, WIN_HEIGHT - 3, 52, 2, 1, "Exit");
|
||
struct bottom *create = creat_bottom(t_test_win,1,52,6,1,"Create");
|
||
// 打开数据库
|
||
if (sqlite3_open(db_filename, &db) != SQLITE_OK) {
|
||
strcpy(errmsg, "Error:database error");
|
||
*recall = -1;
|
||
return;
|
||
}
|
||
|
||
sqlite3_stmt *stmt;
|
||
const char *sql = "SELECT COUNT(*) FROM tests;";
|
||
int row_count = 0;
|
||
|
||
// 准备 SQL 查询
|
||
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||
if (rc != SQLITE_OK) {
|
||
strcpy(errmsg, "Error:database error");
|
||
sqlite3_close(db);
|
||
sqlite3_finalize(stmt);
|
||
*recall = -1;
|
||
return;
|
||
}
|
||
rc = sqlite3_step(stmt);
|
||
if (rc == SQLITE_ROW) {
|
||
// 获取 COUNT(*) 的值,列索引是 0
|
||
row_count = sqlite3_column_int(stmt, 0);
|
||
} else {
|
||
strcpy(errmsg, "Error:database error");
|
||
sqlite3_close(db);
|
||
sqlite3_finalize(stmt);
|
||
*recall = -1;
|
||
return;
|
||
}
|
||
sqlite3_finalize(stmt);
|
||
while (1) {
|
||
// 清空窗口内容
|
||
werase(t_test_win);
|
||
box(t_test_win, 0, 0);
|
||
|
||
// 调用函数输出当前的滚动窗口内容
|
||
int *id=display_t_test_page(t_test_win, db, offset, left, right, exit,create);
|
||
if(id==NULL){
|
||
sqlite3_close(db);
|
||
sqlite3_finalize(stmt);
|
||
return;
|
||
}
|
||
int rc = wgetch(t_test_win);
|
||
if (rc == KEY_MOUSE) {
|
||
if (nc_getmouse(&event) == OK) {
|
||
if (click_bottom(event, *left, start_x, start_y)) {
|
||
if (offset >= PAGE_SIZE) {
|
||
offset -= PAGE_SIZE;
|
||
}
|
||
continue;
|
||
}
|
||
if (click_bottom(event, *right, start_x, start_y)) {
|
||
if (offset + PAGE_SIZE < row_count) { // 总共有100条数据可以调整
|
||
offset += PAGE_SIZE;
|
||
}
|
||
continue;
|
||
}
|
||
if (click_bottom(event, *exit, start_x, start_y)) {
|
||
free(left);
|
||
free(right);
|
||
free(exit);
|
||
sqlite3_close(db);
|
||
*recall = 0;
|
||
return;
|
||
}
|
||
if(click_bottom(event,*create,start_x,start_y)){
|
||
create_ui();
|
||
continue;
|
||
}
|
||
if (event.x-start_x >= 49 && event.x-start_x <= 54) { //delete
|
||
sql_query="delete from tests where ID=?";
|
||
rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
|
||
if (rc != SQLITE_OK) {
|
||
sqlite3_finalize(stmt);
|
||
continue;
|
||
}
|
||
sqlite3_bind_int(stmt, 1, *(id+(((event.y-start_y)+5)/2-5)));
|
||
rc = sqlite3_step(stmt);
|
||
if (rc != SQLITE_DONE) {
|
||
sqlite3_finalize(stmt);
|
||
return;
|
||
}
|
||
sql_query="delete from test_include where test_index=?";
|
||
rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
|
||
if (rc != SQLITE_OK) {
|
||
sqlite3_finalize(stmt);
|
||
continue;
|
||
}
|
||
sqlite3_bind_int(stmt, 1, *(id+(((event.y-start_y)+5)/2-5)));
|
||
rc = sqlite3_step(stmt);
|
||
if (rc != SQLITE_DONE) {
|
||
sqlite3_finalize(stmt);
|
||
return;
|
||
}
|
||
sqlite3_finalize(stmt);
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
int *display_t_problem_page(WINDOW *win, sqlite3 *db, int offset, struct bottom *left,
|
||
struct bottom *right, struct bottom *exit, struct bottom *search, struct bottom *add,int *row_count) {
|
||
char *sql_query="select text,answer,ID from timu where text like ?";
|
||
int *id=malloc(PAGE_SIZE*sizeof(int));
|
||
wclear(win);
|
||
box(win, 0, 0);
|
||
sqlite3_stmt *stmt;
|
||
int rc;
|
||
|
||
// 准备 SQL 语句
|
||
rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
|
||
if (rc != SQLITE_OK) {
|
||
mvwprintw(win, 0, 0, "Failed to prepare statement: %s", sqlite3_errmsg(db));
|
||
wrefresh(win);
|
||
return 0;
|
||
}
|
||
char query[100];
|
||
memset(query,0,sizeof(query));
|
||
snprintf(query, sizeof(query), "%%%s%%", search->test); // 构造 LIKE 查询参数
|
||
sqlite3_bind_text(stmt, 1, query, -1, SQLITE_STATIC);
|
||
// 计算总行数
|
||
int total_rows = 0;
|
||
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
|
||
total_rows++;
|
||
}
|
||
*row_count=total_rows;
|
||
sqlite3_reset(stmt); // 重置stmt以便重新执行查询
|
||
|
||
// 设置窗口的高度和宽度
|
||
// 显示表格的头部
|
||
mvwprintw(win, 1, 1, "Search:");
|
||
mvwprintw(win, 3, 1, "timu answer operate ");
|
||
mvwprintw(win, 4, 1, "----------------------------------------------------------");
|
||
|
||
// 跳到指定的偏移位置
|
||
for (int i = 0; i < offset; i++) {
|
||
sqlite3_step(stmt); // 跳过前面的行
|
||
}
|
||
int row_c=0;
|
||
// 从指定的偏移位置开始,显示10行
|
||
int current_row = 5; // 数据开始显示的位置
|
||
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW && row_c < PAGE_SIZE) {
|
||
const char *name = (const char *) sqlite3_column_text(stmt, 0);
|
||
double answer = sqlite3_column_double(stmt, 1);
|
||
int now_id= sqlite3_column_int(stmt,2);
|
||
*(id+row_c)=now_id;
|
||
// 输出当前行
|
||
if(floor(answer)==answer)mvwprintw(win, (current_row * 2) - 5, 1, "%-22s %d", name, (int)answer);
|
||
else mvwprintw(win, (current_row * 2) - 5, 1, "%-22s %lf", name, answer);
|
||
start_color();
|
||
init_pair(1, COLOR_BLACK, COLOR_WHITE);
|
||
wattron(win, COLOR_PAIR(1));
|
||
mvwprintw(win, (current_row * 2) - 5, 42, "update");
|
||
mvwprintw(win, (current_row * 2) - 5, 52, "delete");
|
||
wattroff(win, COLOR_PAIR(1));
|
||
row_c++;
|
||
current_row++;
|
||
}
|
||
|
||
// 打印分页信息
|
||
mvwprintw(win, WIN_HEIGHT - 3, (WIN_WIDTH - 9) / 2, "Page: %d/%d", (offset / PAGE_SIZE) + 1,
|
||
max(1,(total_rows + PAGE_SIZE - 1) / PAGE_SIZE));
|
||
draw_bottom(win, left);
|
||
draw_bottom(win, right);
|
||
draw_bottom(win, exit);
|
||
draw_bottom(win, search);
|
||
draw_bottom(win, add);
|
||
// 刷新窗口
|
||
wrefresh(win);
|
||
|
||
sqlite3_finalize(stmt);
|
||
return id;
|
||
}
|
||
|
||
int add_ui(){
|
||
keypad(stdscr, FALSE); // 启用功能键(如退格键)
|
||
curs_set(1); // 显示光标
|
||
int start_y = (LINES - WIN_HEIGHT) / 2;
|
||
int start_x = (COLS - WIN_WIDTH) / 2;
|
||
WINDOW *add_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
|
||
char test[9999];
|
||
memset(test,0,9999);
|
||
int pos = 0;
|
||
char ch;
|
||
while (1) { // 按下 Ctrl+G 结束输入
|
||
mvwprintw(add_win,1,1,"input the text,enter means next row.Ctrl+G to exit.\n");
|
||
wrefresh(add_win);
|
||
ch= wgetch(add_win);
|
||
if(ch==7) {
|
||
delwin(add_win);
|
||
break;
|
||
}
|
||
if(ch=='\n'){
|
||
int recall;
|
||
char *errmsg[100];
|
||
add(test,&recall,errmsg);
|
||
memset(test,0,sizeof(test));
|
||
pos=0;
|
||
if(recall==-1){
|
||
wclear(add_win);
|
||
mvwprintw(add_win,1,1,"Error:%s",errmsg);
|
||
wrefresh(add_win);
|
||
sqlite3_sleep(2000);
|
||
continue;
|
||
}
|
||
else if(recall==1){
|
||
wclear(add_win);continue;
|
||
}
|
||
else{
|
||
wclear(add_win);
|
||
mvwprintw(add_win,1,1,"Accept.");
|
||
wrefresh(add_win);
|
||
sqlite3_sleep(2000);
|
||
continue;
|
||
}
|
||
}
|
||
if (ch == 8 || ch == 127) { // 处理退格键
|
||
if (pos > 0) {
|
||
pos--; // 移动到前一个字符位置
|
||
test[pos] = '\0'; // 删除字符
|
||
mvwprintw(add_win,3, 0, "%s ", test); // 用空格清除多余字符
|
||
wrefresh(add_win);
|
||
mvwprintw(add_win,3, 0, "%s", test); // 用空格清除多余字符
|
||
}
|
||
} else if ((ch >= 32 && ch <= 126||ch=='\n')) { // 处理可显示字符
|
||
if (pos < 9999 - 1) {
|
||
test[pos++] = ch; // 将字符加入输入内容
|
||
test[pos] = '\0'; // 添加字符串结束符
|
||
mvwprintw(add_win,3, 0, "%s", test); // 在窗口中实时显示输入
|
||
}
|
||
}
|
||
wrefresh(add_win); // 更新窗口显示
|
||
}
|
||
curs_set(0);
|
||
endwin();
|
||
return T_PROBLEM_UI;
|
||
}
|
||
|
||
int t_problem_ui() {
|
||
MEVENT event;
|
||
int start_y = (LINES - WIN_HEIGHT) / 2;
|
||
int start_x = (COLS - WIN_WIDTH) / 2;
|
||
WINDOW *t_problem_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
|
||
keypad(t_problem_win, TRUE);
|
||
int offset = 0;
|
||
sqlite3 *db;
|
||
const char *db_filename = "./data/msg.db"; // SQLite 数据库文件名
|
||
const char *sql_query; // 查询 SQL
|
||
struct bottom *left = creat_bottom(t_problem_win, WIN_HEIGHT - 3, 20, 2, 1, "<-");
|
||
struct bottom *right = creat_bottom(t_problem_win, WIN_HEIGHT - 3, 40, 2, 1, "->");
|
||
struct bottom *exit = creat_bottom(t_problem_win, WIN_HEIGHT - 3, 52, 4, 1, "Exit");
|
||
struct bottom *add = creat_bottom(t_problem_win, 1, 54, 3, 1, "Add");
|
||
struct bottom *search = creat_bottom(t_problem_win, 1, 8, 20, 1, "");
|
||
memset(search->test,0,30);
|
||
search->private = 2;
|
||
char searchq[100];
|
||
memset(searchq, 0, 100);
|
||
// 打开数据库
|
||
if (sqlite3_open(db_filename, &db) != SQLITE_OK) {
|
||
return TEACHER_UI;
|
||
}
|
||
int *id;
|
||
sqlite3_stmt *stmt;
|
||
int row_count = 0;
|
||
while (1) {
|
||
// 清空窗口内容
|
||
werase(t_problem_win);
|
||
box(t_problem_win, 0, 0);
|
||
// 调用函数输出当前的滚动窗口内容
|
||
id=display_t_problem_page(t_problem_win, db, offset, left, right, exit, search, add,&row_count);
|
||
|
||
int rc = wgetch(t_problem_win);
|
||
if (rc == KEY_MOUSE) {
|
||
if (nc_getmouse(&event) == OK) {
|
||
if (click_bottom(event, *left, start_x, start_y)) {
|
||
if (offset >= PAGE_SIZE) {
|
||
offset -= PAGE_SIZE;
|
||
}
|
||
continue;
|
||
}
|
||
if (click_bottom(event, *right, start_x, start_y)) {
|
||
if (offset + PAGE_SIZE < row_count) { // 总共有100条数据可以调整
|
||
offset += PAGE_SIZE;
|
||
}
|
||
continue;
|
||
}
|
||
if (click_bottom(event, *exit, start_x, start_y)) {
|
||
free(left);
|
||
free(right);
|
||
free(exit);
|
||
free(id);
|
||
sqlite3_close(db);
|
||
delwin(t_problem_win);
|
||
return TEACHER_UI;
|
||
}
|
||
if (click_bottom(event, *add, start_x, start_y)) {
|
||
free(left);
|
||
free(right);
|
||
free(exit);
|
||
free(id);
|
||
sqlite3_close(db);
|
||
delwin(t_problem_win);
|
||
return ADD_UI;
|
||
}
|
||
if (click_bottom(event, *search, start_x, start_y)) {
|
||
get_input(t_problem_win, 4, 6, searchq, 15, search, start_x, start_y);
|
||
offset=0;
|
||
continue;
|
||
}
|
||
if (event.x-start_x >= 52 && event.x-start_x <= 57) { //delete
|
||
sql_query="delete from timu where ID=?";
|
||
rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
|
||
if (rc != SQLITE_OK) {
|
||
sqlite3_finalize(stmt);
|
||
continue;
|
||
}
|
||
sqlite3_bind_int(stmt, 1, *(id+(((event.y-start_y)+5)/2-5)));
|
||
rc = sqlite3_step(stmt);
|
||
if (rc != SQLITE_DONE) {
|
||
sqlite3_finalize(stmt);
|
||
continue;
|
||
}
|
||
sqlite3_finalize(stmt);
|
||
continue;
|
||
}
|
||
if (event.x-start_x >= 42 && event.x-start_x <= 47) { //update
|
||
|
||
sql_query="update timu set text=? ,answer=? where ID=?";
|
||
rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
|
||
if (rc != SQLITE_OK) {
|
||
sqlite3_finalize(stmt);
|
||
continue;
|
||
}
|
||
char input[9999];
|
||
memset(input,0,sizeof(input));
|
||
get_input_ez(t_problem_win, WIN_HEIGHT-2,1, input, 15);
|
||
double ans;
|
||
int recall=0;
|
||
sqlite3_bind_text(stmt, 1, input,-1,SQLITE_STATIC);
|
||
char errmsg[100];
|
||
calculate(input,&recall,errmsg,&ans);
|
||
if(recall==-1){
|
||
mvwprintw(t_problem_win,WIN_HEIGHT-2,1,"Incorrect input!");
|
||
sqlite3_sleep(1000);
|
||
sqlite3_finalize(stmt);
|
||
continue;
|
||
}
|
||
sqlite3_bind_double(stmt, 2, ans);
|
||
sqlite3_bind_int(stmt, 3, *(id+(((event.y-start_y)+5)/2-5)));
|
||
rc = sqlite3_step(stmt);
|
||
if (rc != SQLITE_DONE) {
|
||
sqlite3_finalize(stmt);
|
||
continue;
|
||
}
|
||
sqlite3_finalize(stmt);
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
int TeachersDesktop_ui() {
|
||
MEVENT event;
|
||
char *errmsg[30];
|
||
memset(errmsg, 0, 30);
|
||
int start_y = (LINES - WIN_HEIGHT) / 2;
|
||
int start_x = (COLS - WIN_WIDTH) / 2;
|
||
WINDOW *TeacherDesktop_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
|
||
keypad(TeacherDesktop_win, TRUE);
|
||
struct bottom *test = creat_bottom(TeacherDesktop_win, 3, 4, 14, 1, "1.Test desktop");
|
||
struct bottom *problem = creat_bottom(TeacherDesktop_win, 6, 4, 17, 1, "2.Problem desktop");
|
||
struct bottom *score = creat_bottom(TeacherDesktop_win, 9, 4, 13, 1, "3.Score check");
|
||
struct bottom *exit = creat_bottom(TeacherDesktop_win, 12, 4, 6, 1, "4.Exit");
|
||
while (1) {
|
||
draw_TeacherDesktop_window(TeacherDesktop_win, test, problem, score, exit);
|
||
int rc = wgetch(TeacherDesktop_win);
|
||
if (rc == KEY_MOUSE) {
|
||
if (nc_getmouse(&event) == OK) {
|
||
if (click_bottom(event, *test, start_x, start_y)) {
|
||
int recall=0;
|
||
t_test_ui(&recall,errmsg);
|
||
}
|
||
if (click_bottom(event, *score, start_x, start_y)) {
|
||
t_his_sc_ui();
|
||
continue;
|
||
}
|
||
if (click_bottom(event, *problem, start_x, start_y)) {
|
||
int recall;
|
||
return T_PROBLEM_UI;
|
||
}
|
||
if (click_bottom(event, *exit, start_x, start_y)) {
|
||
free(test);
|
||
free(score);
|
||
free(exit);
|
||
free(problem);
|
||
endwin();
|
||
memset(Username, 0, 15);
|
||
return WELCOME_UI;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
int *display_t_problem_page_2(WINDOW *win, sqlite3 *db, int offset, struct bottom *left,struct bottom *right, struct bottom *ok, struct bottom *search,int *row_count,Node *head){
|
||
char *sql_query="select text,answer,ID from timu where text like ?";
|
||
int *id=malloc(PAGE_SIZE*sizeof(int));
|
||
wclear(win);
|
||
box(win, 0, 0);
|
||
sqlite3_stmt *stmt;
|
||
int rc;
|
||
|
||
// 准备 SQL 语句
|
||
rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
|
||
if (rc != SQLITE_OK) {
|
||
mvwprintw(win, 0, 0, "Failed to prepare statement: %s", sqlite3_errmsg(db));
|
||
wrefresh(win);
|
||
return 0;
|
||
}
|
||
char query[100];
|
||
memset(query,0,sizeof(query));
|
||
snprintf(query, sizeof(query), "%%%s%%", search->test); // 构造 LIKE 查询参数
|
||
sqlite3_bind_text(stmt, 1, query, -1, SQLITE_STATIC);
|
||
// 计算总行数
|
||
int total_rows = 0;
|
||
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
|
||
total_rows++;
|
||
}
|
||
*row_count=total_rows;
|
||
sqlite3_reset(stmt); // 重置stmt以便重新执行查询
|
||
|
||
// 设置窗口的高度和宽度
|
||
// 显示表格的头部
|
||
mvwprintw(win, 1, 1, "Search:");
|
||
mvwprintw(win, 3, 1, "timu answer operate ");
|
||
mvwprintw(win, 4, 1, "----------------------------------------------------------");
|
||
|
||
// 跳到指定的偏移位置
|
||
for (int i = 0; i < offset; i++) {
|
||
sqlite3_step(stmt); // 跳过前面的行
|
||
}
|
||
int row_c=0;
|
||
// 从指定的偏移位置开始,显示10行
|
||
int current_row = 5; // 数据开始显示的位置
|
||
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW && row_c < PAGE_SIZE) {
|
||
const char *name = (const char *) sqlite3_column_text(stmt, 0);
|
||
double answer = sqlite3_column_double(stmt, 1);
|
||
int now_id= sqlite3_column_int(stmt,2);
|
||
*(id+row_c)=now_id;
|
||
// 输出当前行
|
||
if(floor(answer)==answer)mvwprintw(win, (current_row * 2) - 5, 1, "%-22s %d", name, (int)answer);
|
||
else mvwprintw(win, (current_row * 2) - 5, 1, "%-22s %lf", name, answer);
|
||
start_color();
|
||
init_pair(1, COLOR_BLACK, COLOR_WHITE);
|
||
if(!list_search(head,now_id))
|
||
{
|
||
wattron(win, COLOR_PAIR(1));
|
||
mvwprintw(win, (current_row * 2) - 5, 45, "select");
|
||
wattroff(win, COLOR_PAIR(1));
|
||
}
|
||
else mvwprintw(win, (current_row * 2) - 5, 45, "selected");
|
||
row_c++;
|
||
current_row++;
|
||
}
|
||
|
||
// 打印分页信息
|
||
mvwprintw(win, WIN_HEIGHT - 3, (WIN_WIDTH - 9) / 2, "Page: %d/%d", (offset / PAGE_SIZE) + 1,
|
||
max(1,(total_rows + PAGE_SIZE - 1) / PAGE_SIZE));
|
||
draw_bottom(win, left);
|
||
draw_bottom(win, right);
|
||
draw_bottom(win, ok);
|
||
draw_bottom(win, search);
|
||
// 刷新窗口
|
||
wrefresh(win);
|
||
|
||
sqlite3_finalize(stmt);
|
||
return id;
|
||
}
|
||
|
||
// 插入节点到链表末尾
|
||
|
||
|
||
|
||
void create_ui(){
|
||
MEVENT event;
|
||
char *errmsg[30];
|
||
memset(errmsg, 0, 30);
|
||
int start_y = (LINES - WIN_HEIGHT) / 2;
|
||
int start_x = (COLS - WIN_WIDTH) / 2;
|
||
WINDOW *create_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
|
||
keypad(create_win, TRUE);
|
||
|
||
box(create_win,0,0);
|
||
mvwprintw(create_win,1,1,"Please input your test name:");
|
||
char testname[300];
|
||
get_input_ez(create_win,1,28,testname,300);
|
||
wclear(create_win);
|
||
int offset = 0;
|
||
sqlite3 *db;
|
||
const char *db_filename = "./data/msg.db"; // SQLite 数据库文件名
|
||
// 打开数据库
|
||
if (sqlite3_open(db_filename, &db) != SQLITE_OK) {
|
||
return;
|
||
}
|
||
const char *sql_query; // 查询 SQL
|
||
int rc;
|
||
|
||
sql_query="select * from tests where test_name=?";
|
||
sqlite3_stmt *sqlsearch;
|
||
rc = sqlite3_prepare_v2(db, sql_query, -1, &sqlsearch, 0);
|
||
if (rc != SQLITE_OK) {
|
||
strcpy(errmsg,"Error:database error.");
|
||
sqlite3_close(db);
|
||
return;
|
||
}
|
||
sqlite3_bind_text(sqlsearch, 1, testname, -1, SQLITE_STATIC);
|
||
|
||
rc = sqlite3_step(sqlsearch);
|
||
|
||
if(rc==SQLITE_ROW){
|
||
wclear(create_win);
|
||
mvwprintw(create_win,1,1,"Error:test name has been existed");
|
||
sqlite3_sleep(1000);
|
||
sqlite3_finalize(sqlsearch);
|
||
sqlite3_close(db);
|
||
delwin(create_win);
|
||
return;
|
||
}
|
||
sqlite3_finalize(sqlsearch);
|
||
|
||
struct bottom *left = creat_bottom(create_win, WIN_HEIGHT - 3, 20, 2, 1, "<-");
|
||
struct bottom *right = creat_bottom(create_win, WIN_HEIGHT - 3, 40, 2, 1, "->");
|
||
struct bottom *ok = creat_bottom(create_win, WIN_HEIGHT - 3, 52, 2, 1, "OK");
|
||
struct bottom *search = creat_bottom(create_win, 1, 8, 20, 1, "");
|
||
memset(search->test,0,30);
|
||
search->private = 2;
|
||
char searchq[100];
|
||
memset(searchq, 0, 100);
|
||
int *id;
|
||
sqlite3_stmt *stmt;
|
||
int row_count = 0;
|
||
Node *head = NULL; // 初始化链表为空
|
||
while (1) {
|
||
// 清空窗口内容
|
||
werase(create_win);
|
||
box(create_win, 0, 0);
|
||
// 调用函数输出当前的滚动窗口内容
|
||
id=display_t_problem_page_2(create_win, db, offset, left, right, ok, search,&row_count,head);
|
||
int rc = wgetch(create_win);
|
||
if (rc == KEY_MOUSE) {
|
||
if (nc_getmouse(&event) == OK) {
|
||
if (click_bottom(event, *left, start_x, start_y)) {
|
||
if (offset >= PAGE_SIZE) {
|
||
offset -= PAGE_SIZE;
|
||
}
|
||
continue;
|
||
}
|
||
if (click_bottom(event, *right, start_x, start_y)) {
|
||
if (offset + PAGE_SIZE < row_count) { // 总共有100条数据可以调整
|
||
offset += PAGE_SIZE;
|
||
}
|
||
continue;
|
||
}
|
||
if (click_bottom(event, *ok, start_x, start_y)) {
|
||
sql_query="insert into tests (test_name,Creater) values (?,?)";
|
||
sqlite3_stmt *insert;
|
||
rc = sqlite3_prepare_v2(db, sql_query, -1, &insert, 0);
|
||
if (rc != SQLITE_OK) {
|
||
wclear(create_win);
|
||
mvwprintw(create_win,1,1,"Error:data base error.");
|
||
sqlite3_finalize(insert);
|
||
sqlite3_close(db);
|
||
delwin(create_win);
|
||
return;
|
||
}
|
||
sqlite3_bind_text(insert, 1, testname, -1, SQLITE_STATIC);
|
||
|
||
sqlite3_bind_text(insert, 2, Username, -1, SQLITE_STATIC);
|
||
|
||
rc = sqlite3_step(insert);
|
||
if (rc != SQLITE_DONE) {
|
||
wclear(create_win);
|
||
sqlite3_finalize(insert);
|
||
sqlite3_close(db);return;
|
||
}
|
||
sql_query="select ID from tests where test_name=?";
|
||
rc = sqlite3_prepare_v2(db, sql_query, -1, &insert, 0);
|
||
if (rc != SQLITE_OK) {
|
||
wclear(create_win);
|
||
sqlite3_finalize(insert);
|
||
sqlite3_close(db);return;
|
||
}
|
||
sqlite3_bind_text(insert, 1, testname, -1, SQLITE_STATIC);
|
||
|
||
rc = sqlite3_step(insert);
|
||
|
||
if(rc!=SQLITE_ROW){
|
||
free_list(head);
|
||
free(left);
|
||
free(right);
|
||
free(ok);
|
||
free(id);
|
||
sqlite3_finalize(insert);
|
||
sqlite3_close(db);
|
||
delwin(create_win);
|
||
return;
|
||
}
|
||
int test_id = sqlite3_column_int(insert,0);
|
||
sql_query="insert into test_include (text,answer,test_index) values(?,?,?);";
|
||
Node *temp = head;
|
||
int problem_counts=0;
|
||
while (temp != NULL) {
|
||
problem_counts++;
|
||
sqlite3_stmt *insert;
|
||
rc = sqlite3_prepare_v2(db, sql_query, -1, &insert, 0);
|
||
if (rc != SQLITE_OK) {
|
||
wclear(create_win);
|
||
sqlite3_finalize(insert);
|
||
sqlite3_close(db);return;
|
||
}
|
||
sqlite3_bind_text(insert, 1, temp->str1, -1, SQLITE_STATIC);
|
||
sqlite3_bind_text(insert, 2, temp->str2, -1, SQLITE_STATIC);
|
||
sqlite3_bind_int(insert, 3, test_id);
|
||
rc = sqlite3_step(insert);
|
||
if(rc!=SQLITE_DONE){
|
||
wclear(create_win);
|
||
sqlite3_finalize(insert);
|
||
sqlite3_close(db);return;
|
||
}
|
||
temp = temp->next;
|
||
}
|
||
sql_query="update tests set problems_count =? where ID=?";
|
||
rc = sqlite3_prepare_v2(db, sql_query, -1, &insert, 0);
|
||
if (rc != SQLITE_OK) {
|
||
wclear(create_win);
|
||
sqlite3_finalize(insert);
|
||
sqlite3_close(db);return;
|
||
}
|
||
sqlite3_bind_int(insert, 1, problem_counts);
|
||
sqlite3_bind_int(insert, 2, test_id);
|
||
rc = sqlite3_step(insert);
|
||
if(rc!=SQLITE_DONE){
|
||
wclear(create_win);
|
||
sqlite3_finalize(insert);
|
||
sqlite3_close(db);return;
|
||
}
|
||
sqlite3_finalize(insert);
|
||
free_list(head);
|
||
free(left);
|
||
free(right);
|
||
free(ok);
|
||
free(id);
|
||
sqlite3_close(db);
|
||
delwin(create_win);
|
||
return;
|
||
}
|
||
if (click_bottom(event, *search, start_x, start_y)) {
|
||
get_input(create_win, 4, 6, searchq, 15, search, start_x, start_y);
|
||
offset=0;
|
||
continue;
|
||
}
|
||
if (event.x-start_x >= 45 && event.x-start_x <= 50) { //select
|
||
sql_query="select text,answer from timu where ID =?";
|
||
rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
|
||
if (rc != SQLITE_OK) {
|
||
sqlite3_finalize(stmt);
|
||
continue;
|
||
}
|
||
sqlite3_bind_int(stmt, 1, *(id+(((event.y-start_y)+5)/2-5)));
|
||
rc = sqlite3_step(stmt);
|
||
if (rc != SQLITE_ROW) {
|
||
sqlite3_finalize(stmt);
|
||
continue;
|
||
}
|
||
char *text1 = sqlite3_column_text(stmt, 0);
|
||
char *answer1 = sqlite3_column_text(stmt,1);
|
||
if(list_search(head,*(id+(((event.y-start_y)+5)/2-5))))continue;
|
||
insert_node(&head,text1,answer1,*(id+(((event.y-start_y)+5)/2-5)));
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|