_Ziens_

Редактирование полей

May 1st, 2020
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.18 KB | None | 0 0
  1. /// Возвращает Employee из элемента списка item если item != NULL, иначе возвращает пустой Employee
  2. Employee getOrCreate(ListItem *item) {
  3.     Employee emp;
  4.     if (item != NULL)
  5.         emp = item->employee;
  6.     else
  7.         memset(&emp, 0, sizeof(Employee));
  8.     return emp;
  9. }
  10.  
  11. /// Преобразует значение currentValue в строку из числа (если numberField == TRUE) или просто копирует в буфер buffer.
  12. void convertToString(char *buffer, void *currentValue, bool numberField) {
  13.     if (numberField) // Если формат - число переводим число в строку
  14.         sprintf(buffer, "%u", *((unsigned int *) currentValue));
  15.     else // Если формат - строка, то просто копируем её как есть
  16.         strcpy(buffer, currentValue);
  17. }
  18.  
  19. /// Рисует поле ввода для числового или текстового поля с ограничением символов maxChars, в окне win, в строке line с
  20. /// названием поля label. Текущее значение - currentValue, Буфер для преобразований - buffer
  21. int
  22. drawInputField(WINDOW *win, int line, int maxChars, bool numberField, char *buffer, char *label, void *currentValue) {
  23.     convertToString(buffer, currentValue, numberField);
  24.     unsigned firstByteValue = *((unsigned int *) currentValue); // Для числа - его значение, для строки - первый символ
  25.     char *format = firstByteValue == 0 ? "%L16s: " : "%L16s(%s): "; // Шаблон для названия поля
  26.     wprintMB(win, line, 1, A_NORMAL, format, label, buffer); // Название поля
  27.     int xPosition = getcurx(win); // Сохраняем текущую позицию курсора
  28.     wgetnstr(win, buffer, numberField ? maxChars : 40); // Ожидаем ввода не более maxChars для чисел и 40 для строк
  29.  
  30.     if (!*buffer && firstByteValue != 0)
  31.         // Если поле пусто, и есть значение по-умолчанию, вставляем значение по-умолчанию (текущее)
  32.         convertToString(buffer, currentValue, numberField);
  33.  
  34.     // Поле должно быть не пусто и содержать только цифры, если оно числовое и не превышает размера maxChars
  35.     bool isValid = *buffer && (!numberField || isNumber(buffer)) && getUTF8StrLen(buffer) <= maxChars;
  36.  
  37.     // Если в поле введено неверное значение, то подсвечиваем значение, если верное, то выделяем зелёным
  38.     wprintMB(win, line, xPosition, isValid ? COLOR_PAIR(4) : A_REVERSE, "%L14s", buffer);
  39.     wrefresh(win);
  40.  
  41.     if (isValid) { // Если введённое значение верное, обновляем переменную
  42.         if (numberField)
  43.             sscanf(buffer, "%u", (unsigned *) currentValue);
  44.         else
  45.             strcpy((char *) currentValue, buffer);
  46.         return 1;
  47.     }
  48.     return 0;
  49. }
  50.  
  51. bool showEditDialog(ListItem *item) {
  52.     Employee emp = getOrCreate(item); // Структура о сотруднике из списка или пустая
  53.     WINDOW *editorWindow = createDialog(45, 19);
  54.     char *title = item != NULL ? "Редактирование" : "Вставка";
  55.     char buffer[64]; // Буфер для хранения текущей переменной
  56.     int validFields; // Для подсчёта правильных значений поля
  57.  
  58.     do {
  59.         validFields = 0;
  60.         wclear(editorWindow);
  61.         box(editorWindow, 0, 0); // Рамка окна
  62.         mvwprintw(editorWindow, 1, (45 - getUTF8StrLen(title)) / 2, title); // Заголовок окна
  63.         echo(); // Включаем отображение введённых символов
  64.         validFields += drawInputField(editorWindow, 3, 6, true, buffer, "Номер отдела", &emp.depNumber);
  65.         validFields += drawInputField(editorWindow, 5, 8, true, buffer, "Таб. номер", &emp.employeeId);
  66.         validFields += drawInputField(editorWindow, 7, 6, true, buffer, "Тема", &emp.topicId);
  67.         validFields += drawInputField(editorWindow, 9, 4, true, buffer, "Длит.работы(мес)", &emp.workDurationInMonth);
  68.         validFields += drawInputField(editorWindow, 11, 6, true, buffer, "Код долж.", &emp.positionCode);
  69.         validFields += drawInputField(editorWindow, 13, 8, true, buffer, "Зарплата (руб)", &emp.salaryAmount);
  70.         validFields += drawInputField(editorWindow, 15, 20, false, buffer, "Фамилия", &emp.lastName);
  71.         noecho();// Отключаем отображение введённых символов
  72.  
  73.         int choice;
  74.         if (validFields == 7) {
  75.             const char *choices[] = {"Сохранить", "Снова", "Отмена"};
  76.             choice = drawButtonGroup(editorWindow, 17, choices, 3);
  77.         } else {
  78.             const char *choices[] = {"Снова", "Отмена"};
  79.             choice = drawButtonGroup(editorWindow, 17, choices, 2) + 1;
  80.         }
  81.  
  82.         switch (choice) {
  83.             case 1: // Снова
  84.                 continue;
  85.             case 0: // Сохранить
  86.                 if (item == NULL) { // Если новая запись - добавить в конец
  87.                     if (findListItemById(list, emp.employeeId) == NULL) { // Смотрим, есть ли в базе такой элемент
  88.                         add(list, emp);
  89.                         return true;
  90.                     } else {
  91.                         showMessageDialog("Запись с таким номером уже существует");
  92.                         continue;
  93.                     }
  94.                 } else {
  95.                     item->employee = emp; // Если редактирование - заменить
  96.                     return true;
  97.                 }
  98.             default: // Отмена
  99.                 return false;
  100.         }
  101.     } while (true);
  102. }
Add Comment
Please, Sign In to add comment