Subversion Repositories Kolibri OS

Rev

Rev 7498 | Rev 7503 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. //не идёт дальше 98 строки
  2. //если выделить область ячеек и сдвинуть курсор ввода с помощью клавиш, "следы" остануться
  3. //нельзя перемещаться по буквам в редактируемой строке
  4.  
  5. #include "func.h"
  6. #include "parser.h"
  7. #include "calc.h"
  8. #include "use_library.h"
  9.  
  10. #define TABLE_VERSION "0.98.1"
  11.  
  12. // строки, которые выводит программа
  13. const char *sFileSign = "KolibriTable File\n";
  14. const char sFilename[] = "Filename:";
  15. const char sSave[] = "Save";
  16. const char sLoad[] = "Load";
  17. const char sNew[] = "New";
  18.  
  19. const char er_file_not_found[] = "Cannot open file. ";
  20. const char er_format[] = "Error: bad format. ";
  21. const char msg_save[] = "File saved. ";
  22. const char msg_load[] = "File loaded. ";
  23. const char msg_new[] = "Memory cleared. ";
  24.  
  25. // initial window sizes
  26. #define WND_W 640
  27. #define WND_H 480
  28. // new window size and coordinates
  29. int cWidth;
  30. int cHeight;
  31.  
  32. // interface colors
  33. #define GRID_COLOR 0xa0a0a0
  34. #define TEXT_COLOR 0x000000
  35. #define CELL_COLOR 0xffffff
  36. #define SEL_CELL_COLOR 0xe0e0ff
  37. #define FIXED_CELL_COLOR 0xe0e0ff
  38. #define SEL_FIXED_CELL_COLOR 0x758FC1
  39. #define TEXT_SEL_FIXED_COLOR 0xffffff
  40. #define PANEL_BG_COLOR 0xe4dfe1
  41.  
  42. #define SCROLL_SIZE 16
  43.  
  44. // button IDs
  45. #define FILENAME_BUTTON 0x10
  46. #define SAVE_BUTTON 0x11
  47. #define LOAD_BUTTON 0x12
  48. #define NEW_BUTTON 0x13
  49. #define DRAG_BUTTON 0x20
  50.  
  51. #define COL_BUTTON 0x100
  52. #define ROW_BUTTON (COL_BUTTON + 0x100)
  53. #define COL_HEAD_BUTTON (ROW_BUTTON + 0x100)
  54. #define ROW_HEAD_BUTTON (COL_HEAD_BUTTON + 0x100)
  55. #define CELL_BUTTON (ROW_HEAD_BUTTON + 0x100)
  56.  
  57. // bottom panel
  58. #define MENU_PANEL_HEIGHT 40
  59. Dword panel_y = 0;
  60. Dword mouse_dd;
  61.  
  62. // editbox data
  63. char edit_text[256] = "";
  64. edit_box cell_box = {0,9*8-5,WND_H - 16-32,0xffffff,0x6a9480,0,0x808080,0,255,(dword)&edit_text,(dword)&mouse_dd,0};
  65. scroll_bar scroll_v = { SCROLL_SIZE,200,398, NULL, SCROLL_SIZE,0,115,15,0,0xeeeeee,0xD2CED0,0x555555,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1};
  66. scroll_bar scroll_h = { 200,NULL,SCROLL_SIZE, NULL, SCROLL_SIZE,0,115,15,0,0xeeeeee,0xD2CED0,0x555555,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1};
  67.  
  68. // ячейки - их параметры и текст
  69. DWORD def_col_width = 80, def_row_height = 16;
  70. DWORD col_count = 200, row_count = 100;
  71. DWORD *col_width, *row_height;
  72. char ***cells;
  73.  
  74. struct GRID
  75. {
  76.         int x,y,w,h;
  77. } grid;
  78.  
  79. char ***values; // значения формул, если есть
  80.  
  81. bool display_formulas = 0;      // отображать ли формулы вместо значений
  82.  
  83. // координаты отображаемых столбцов и строк
  84. DWORD *col_left, *row_top;
  85.  
  86. // буфер обмена
  87. char ***buffer = NULL;
  88. DWORD buf_col, buf_row;
  89. DWORD buf_old_x, buf_old_y;
  90.  
  91. // это координаты ячейки, отображаемой в ЛВ угле
  92. DWORD scroll_x = 1, scroll_y = 1;
  93. // это выделенная ячейка
  94. DWORD sel_x = 1, sel_y = 1;
  95. DWORD prev_x = 0, prev_y = 0;   // предыдущая выделенная
  96. int was_single_selection = 0;
  97.  
  98. // конец выделения если выделено несколько ячеек
  99. DWORD sel_end_x = sel_x, sel_end_y = sel_y;
  100.  
  101. // флаг
  102. bool sel_moved = 0;
  103. bool sel_end_move = 0;
  104. // сколько ячеек помещается в окне по х и у
  105. DWORD nx = 0, ny = 0;
  106.  
  107. // флаг реадктирования ячейки
  108. //bool is_edit = 0;
  109. #define ed_focus 2
  110. #define is_edit (cell_box.flags & ed_focus)
  111.  
  112. // редактирование имени файла
  113. bool fn_edit = 0;
  114. char fname[256];
  115. edit_box file_box = {98,9*8-5,WND_H - 16-32,0xffffff,0x6a9480,0,0x808080,0,255,(dword)&fname,(dword)&mouse_dd,0};
  116.  
  117. // изменение размеров
  118. #define SIZE_X 1 // состояние
  119. #define SIZE_Y 2
  120. #define SIZE_SELECT 3
  121. #define SIZE_DRAG 4
  122. int size_mouse_x, size_mouse_y, size_id, size_state = 0;
  123.  
  124. // растаскивание ячейки при ее тащении за правый нижний угол, с заполнением ячеек
  125. int drag_x, drag_y;
  126. int old_end_x, old_end_y;
  127.  
  128. void draw_window();
  129.  
  130. void kos_DrawRegion(Word x, Word y,Word width, Word height, Dword color1, Word invert)
  131. {
  132.         kos_DrawLine(x,y,x+width-2,y,color1,invert);
  133.         kos_DrawLine(x,y+1,x,y+height-1,color1,invert);
  134.         kos_DrawLine(x+width-1,y,x+width-1,y+height-2,color1,invert);
  135.         kos_DrawLine(x+1,y+height-1,x+width-1,y+height-1,color1,invert);
  136. }
  137.  
  138. void kos_DebugValue(char *str, int n)
  139. {
  140.         char debuf[50];
  141.         sprintf(debuf, "%S: %U\n", str, n);
  142.         rtlDebugOutString(debuf);
  143. }
  144.  
  145. void DrawScrolls()
  146. {
  147.         // HOR
  148.         scroll_h.x = 0;
  149.         scroll_h.y = grid.y + grid.h;
  150.         scroll_h.w = grid.w;
  151.         scroll_h.all_redraw = true;
  152.         scroll_h.max_area = col_count;
  153.         scroll_h.cur_area = nx-scroll_x-1;
  154.         scroll_h.position = scroll_x-1;
  155.         scrollbar_h_draw((DWORD)&scroll_h);
  156.  
  157.         // VER
  158.         scroll_v.x = grid.x + grid.w;
  159.         scroll_v.y = 0;
  160.         scroll_v.h = grid.h;
  161.         scroll_v.all_redraw = true;
  162.         scroll_v.max_area = row_count;
  163.         scroll_v.cur_area = ny-scroll_y-1;
  164.         scroll_v.position = scroll_y-1;
  165.         scrollbar_v_draw((DWORD)&scroll_v);
  166. }
  167.  
  168. void DrawSelectedFrame(int x, int y, int w, int h, DWORD col)
  169. {
  170.         kos_DrawBar(x,y,w,2,col);          // up
  171.         kos_DrawBar(x,y,2,h,col);          // left
  172.         kos_DrawBar(x,y+h-2,w-2-3,2,col);  // bottom
  173.         kos_DrawBar(x+w-2,y, 2,h-2-3,col); // right
  174.         kos_DrawBar(x+w-4,y+h-4,4,4,col);
  175. }
  176.  
  177. void kos_DeleteButton(int id)
  178. {
  179.         kos_DefineButton(NULL, NULL, NULL, NULL, id+BT_DEL, NULL);
  180. }
  181.  
  182. void start_edit(int x, int y)
  183. {
  184.         int ch = 0;
  185.         if (x < scroll_x || x > nx - 1)
  186.         {
  187.                 scroll_x = x;
  188.                 ch = 1;
  189.         }
  190.         if (y < scroll_y || y > ny - 1)
  191.         {
  192.                 scroll_y = y;
  193.                 ch = 1;
  194.         }
  195.         if (ch)
  196.         {
  197.                 sel_moved = 1;
  198.                 draw_window();
  199.         }
  200.  
  201.         file_box.flags &= ~ed_focus;
  202.  
  203.         cell_box.flags |= ed_focus;
  204.         cell_box.left = col_left[x] + 1;
  205.         cell_box.top = row_top[y] + 1;
  206.         cell_box.width = col_width[x] - 2;
  207.         //cell_box.height= row_height[y];
  208.         memset((Byte*)edit_text, 0, sizeof(edit_text));
  209.         if (cells[x][y])
  210.         {
  211.                 strcpy(edit_text, cells[x][y]);
  212.                 edit_text[strlen(cells[x][y]) - 1] = '\0';
  213.         }
  214.         cell_box.pos = cell_box.offset = 0;
  215.  
  216.         draw_window();
  217. }
  218.  
  219. void stop_edit()
  220. {
  221.         if (is_edit)
  222.         {
  223.                 cell_box.flags &= ~ed_focus;
  224.                 if (cells[sel_x][sel_y])
  225.                         freemem(cells[sel_x][sel_y]);
  226.                 if (strlen(edit_text) > 0)
  227.                 {
  228.                         cells[sel_x][sel_y] = (char*)allocmem(strlen(edit_text)+1);
  229.                         strcpy(cells[sel_x][sel_y], edit_text);
  230.                 }
  231.                 else
  232.                         cells[sel_x][sel_y] = NULL;
  233.                 //memset((Byte*)edit_text,0, 256);
  234.                 calculate_values();
  235.         }
  236. }
  237.  
  238. void cancel_edit()
  239. {
  240.         if (!is_edit)
  241.                 return;
  242.         cell_box.flags &= ~ed_focus;
  243.         memset((Byte*)edit_text,0, 256);
  244.         draw_window();
  245. }
  246.  
  247. void check_sel()
  248. {
  249.         DWORD sx0=scroll_x, sy0=scroll_y;
  250.  
  251.         if (sel_x >= nx - 1  /*&& sel_x < col_count - nx + scroll_x + 1*/)
  252.                 //if (sel_x == nx)
  253.                         scroll_x++;
  254.                 //else
  255.                 //      scroll_x = sel_x;
  256.         if (sel_y >= ny - 1 /*&& sel_y < row_count - ny + scroll_y */)
  257.                 //if (sel_y == ny)
  258.                         scroll_y++;
  259.                 //else
  260.                 //      scroll_y = sel_y;
  261.  
  262.         if (sel_x < scroll_x)
  263.                 scroll_x = sel_x;
  264.         if (sel_y < scroll_y)
  265.                 scroll_y = sel_y;
  266.  
  267.         if (sx0 != scroll_x || sy0 != scroll_y)
  268.                 sel_moved = 0;                  // надо перерисовать все
  269.  
  270. }
  271.  
  272. void move_selection(DWORD new_x, DWORD new_y)
  273. {
  274.         sel_moved = 1;
  275.         stop_edit();
  276.         prev_x = sel_x;
  277.         prev_y = sel_y;
  278.         sel_x = new_x;
  279.         if (sel_x < 1)
  280.                 sel_x = 1;
  281.         if (sel_x > col_count - 1)
  282.                 sel_x = col_count - 1;
  283.         sel_end_x = sel_x;
  284.         sel_y = new_y;
  285.         if (sel_y < 1)
  286.                 sel_y = 1;
  287.         if (sel_y > row_count - 1)
  288.                 sel_y = row_count - 1;
  289.         sel_end_y = sel_y;
  290.         check_sel();
  291.         draw_window();
  292. }
  293.  
  294. // x - между low и high ? - необязательно low<high
  295. bool is_between(Dword x, Dword low, Dword high)
  296. {
  297.         return ((low<high)?(x >= low && x <= high):(x >= high && x <= low));
  298. }
  299.  
  300. void clear_cell_slow(int px, int py)
  301. {
  302.         int i;
  303.         int x0 = col_width[0];
  304.         for (i = scroll_x; i < px; i++)
  305.         {
  306.                 x0 += col_width[i];
  307.         }
  308.         int x1 = x0;
  309.         x1 += col_width[px];
  310.         int y0 = row_height[0];
  311.         for (i = scroll_y; i < py; i++)
  312.         {
  313.                 y0 += row_height[i];
  314.         }
  315.         int y1 = y0;
  316.         y1 += row_height[py];
  317.         kos_DrawBar(x0 + 1, y0 + 1, x1 - x0 - 1, y1 - y0 - 1, 0xffffff);
  318. }
  319.  
  320.  
  321.  
  322. // рисование ячеек
  323. #define is_x_changed(v) ((v) == sel_x || (v) == prev_x)
  324. #define is_y_changed(v) ((v) == sel_y || (v) == prev_y)
  325.  
  326. void draw_grid()
  327. {
  328.         int i,j;
  329.         long x0 = 0, y0 = 0, x = 0, y = 0, dx;
  330.         DWORD text_color;
  331.         DWORD bg_color;
  332.  
  333.         nx=ny=0;
  334.  
  335.         // очистить область около выделенной ячейки
  336.         if (sel_moved)
  337.         {
  338.                 clear_cell_slow(sel_x, sel_y);
  339.                 clear_cell_slow(prev_x, prev_y);
  340.         }
  341.         else
  342.         {
  343.                 // очистить всю область ячеек
  344.                 //kos_DrawBar(col_width[0]+1, row_height[0]+1, grid.w - SCROLL_SIZE-col_width[0]-1, he - SCROLL_SIZE-row_height[0]-1, 0xffffff);
  345.         }
  346.  
  347.         col_left[0] = 0;
  348.         // ячейки - заголовки столбцов + вертикальные линии
  349.         x = col_width[0];
  350.         nx = 1;
  351.         for (i = 1; i < col_count; i++)
  352.         {
  353.                 col_left[i] = -1;
  354.                 if (i >= scroll_x)
  355.                 {
  356.                         {                              
  357.                                 if (!sel_moved || is_x_changed(i)) {
  358.                                         kos_DrawLine(x-x0, 0, x-x0, row_height[0], GRID_COLOR, 0);
  359.                                 }
  360.                                 // и заголовок ячейки по х
  361.                                 text_color = TEXT_COLOR;
  362.                                 dx = (col_width[i]-6)/2;
  363.                                 int dy = (row_height[0] - 8) / 2 + 1;
  364.                                 int cur_width = col_width[i] - 1;
  365.                                 if (cur_width + x - x0 > grid.w)
  366.                                         cur_width = grid.w - x + x0 -1;
  367.                                 if (!sel_moved || (is_x_changed(i))) {
  368.                                         if (is_between(i,sel_x,sel_end_x))     
  369.                                         {
  370.                                                 bg_color = SEL_FIXED_CELL_COLOR;
  371.                                                 text_color = TEXT_SEL_FIXED_COLOR;
  372.                                         }
  373.                                         else
  374.                                         {
  375.                                                 bg_color = FIXED_CELL_COLOR;
  376.                                                 text_color = TEXT_COLOR;
  377.                                         }
  378.                                         kos_DrawBar(x - x0 + 1,0,cur_width,row_height[0],bg_color);
  379.                                         kos_WriteTextToWindow(x-x0+2+dx,dy,0,text_color,cells[i][0],strlen(cells[i][0]));      
  380.                                 }
  381.                                 // есть кнопка стоблца и еще кнопка изменения ширины
  382.                                 if (x - x0 + col_width[i] <= grid.w - col_width[0])
  383.                                 {
  384.                                         kos_DeleteButton(COL_HEAD_BUTTON+i);
  385.                                         kos_DefineButton(x-x0+5,0,cur_width - 10,row_height[0]-1,BT_NODRAW+COL_HEAD_BUTTON+i,0);
  386.                                 }
  387.                                 //kos_DefineButton(x-x0+col_width[i]-10,0,15,row_height[0]-1,BT_NODRAW+COL_SIZE_BUTTON+i,0);
  388.                                 col_left[i] = x - x0;
  389.                         }
  390.                         if (x - x0 > grid.w - col_width[0])
  391.                         {
  392.                                 x += col_width[i];
  393.                                 nx++;
  394.                                 break;
  395.                         }
  396.                 }
  397.                 else
  398.                 {
  399.                         x0 += col_width[i];
  400.                 }
  401.                 x += col_width[i];
  402.                 nx++;
  403.         }
  404.  
  405.         //kos_DefineButton(0,0,0,0,0x80000000+COL_HEAD_BUTTON+i,0);
  406.  
  407.         for (j = i + 1; j < col_count; j++)
  408.                 col_left[j] = grid.w;
  409.         //if (!sel_moved || (is_x_changed(nx))) kos_DrawLine(x - x0, 0, x - x0, grid.h, GRID_COLOR, 0);
  410.  
  411.         // ячейки - заголовки строк + горизонт. линии
  412.         y = row_height[0];
  413.         ny = 1;
  414.         row_top[0] = 0;
  415.         for (i = 1; i < row_count && y - y0 < grid.h; i++)
  416.         {
  417.                 row_top[i] = -1;
  418.                 if (i >= scroll_y)
  419.                 {
  420.                         {
  421.                                 if (!sel_moved || (is_y_changed(i)))
  422.                                         kos_DrawLine(0, y - y0, grid.w - 1, y - y0, GRID_COLOR, 0);
  423.                                 // и заголовок ячейки по y
  424.                                 text_color = TEXT_COLOR;
  425.                                 dx = (col_width[0]-6 * strlen(cells[0][i]))/2;  // optimize this, change strlen
  426.                                 int dy = (row_height[i] - 8) / 2 + 1;
  427.                                 if (!sel_moved || (is_y_changed(i)))
  428.                                         if (is_between(i,sel_y,sel_end_y))
  429.                                         {
  430.                                                 kos_DrawBar(0,y-y0+1,col_width[0],row_height[i] - 1,SEL_FIXED_CELL_COLOR);
  431.                                                 text_color = TEXT_SEL_FIXED_COLOR;
  432.                                         }
  433.                                         else
  434.                                         {
  435.                                                 kos_DrawBar(0,y-y0+1,col_width[0],row_height[i] - 1,FIXED_CELL_COLOR);
  436.                                                 text_color = TEXT_COLOR;
  437.                                         }
  438.  
  439.                                 if (!sel_moved || (is_y_changed(i)))
  440.                                         kos_WriteTextToWindow(2+dx,y-y0+dy,0,text_color,cells[0][i],strlen(cells[0][i]));
  441.  
  442.                                 kos_DeleteButton(ROW_HEAD_BUTTON+i);
  443.                                 kos_DefineButton(0,y-y0+5,col_width[0]-1,row_height[i]-6,BT_NODRAW+ROW_HEAD_BUTTON+i,0);
  444.                                 //kos_DefineButton(0,y-y0+row_height[i]-5,col_width[0]-1,10,BT_NODRAW+ROW_SIZE_BUTTON+i,0);
  445.                                 row_top[i] = y - y0;
  446.                         }
  447.                 }
  448.                 else
  449.                 {
  450.                         y0 += row_height[i];
  451.                 }
  452.                 y += row_height[i];
  453.                 ny++;
  454.         }
  455.        
  456.         kos_DefineButton(0,0,0,0,0x80000000+ROW_HEAD_BUTTON+ny-1,0);
  457.  
  458.         for (j = i + 1; j < row_count; j++)
  459.                 row_top[j] = grid.h;
  460.         if (!sel_moved || (is_y_changed(ny)))
  461.                 kos_DrawLine(0, y - y0, grid.w, y - y0, GRID_COLOR, 0);
  462.  
  463.         if (!sel_moved || (is_x_changed(0) && is_y_changed(0)))
  464.                 kos_DrawBar(0,0,col_width[0],row_height[0],FIXED_CELL_COLOR);
  465.         // ЛВ ячейка
  466.  
  467.         //sprintf(debuf, "%U, %U; %U, %U", x0, y0, nx, ny);
  468.         //rtlDebugOutString(debuf);
  469.  
  470.         // cells itself
  471.  
  472.         y = row_height[0];
  473.         for (i = scroll_y; i < ny; i++)
  474.         {
  475.                 x = col_width[0];
  476.                 if (!sel_moved)
  477.                         kos_DrawBar(col_width[0]+1, y+1, grid.w -col_width[0]-1, row_height[i]-1, 0xffffff);
  478.                 for (j = scroll_x; j < nx-1; j++)
  479.                 {
  480.                         if (!sel_moved || is_x_changed(j) || is_y_changed(i))
  481.                                 kos_DrawLine(col_left[j], row_top[i], col_left[j], row_height[i], GRID_COLOR, 0);
  482.  
  483.                         // заголовки уже нарисованы - пропускаем их
  484.                         if (i && j)    
  485.                         {
  486.                                 //kos_DrawBar(x+1, y+1, col_width[i]-1, row_height[i]-1, 0xffffff);
  487.  
  488.                                 //rtlDebugOutString(cap);
  489.                                 //if (j >= sel_x && j <= sel_end_x && i >= sel_y && i <= sel_end_y)
  490.                                 if (is_between(j,sel_x,sel_end_x) && is_between(i, sel_y, sel_end_y)    // (j,i) - âûäåëåíà
  491.                                 && ((!sel_moved) || (is_x_changed(j) && is_y_changed(i))))                      // è åå íóæíî íàðèñîâàòü
  492.                                 {
  493.                                         if (i == sel_y && j == sel_x) // frame
  494.                                         {
  495.                                                 DrawSelectedFrame(x+1,y, col_width[j]-1, row_height[j], TEXT_COLOR);
  496.                                                 drag_x = x + col_width[j] - 4;
  497.                                                 drag_y = y + row_height[i] - 4;
  498.                                         }
  499.                                         else
  500.                                                 kos_DrawBar(x + 1,y + 1,col_width[j] - 2,row_height[i] - 2,SEL_CELL_COLOR);     //      âûäåëåíà íî íå îñíîâíàÿ(ñåðàÿ)
  501.  
  502.                                 }
  503.                                 //kos_DefineButton(x,y,col_width[j]-1,row_height[i]-1,BT_NODRAW+CELL_BUTTON+((i << 8) + j),0);
  504.  
  505.                                 char *text;
  506.                                 if (values[j][i] && values[j][i][0] == '#')
  507.                                 {
  508.                                         text = cells[j][i];
  509.                                         kos_DrawRegion(x+1, y+1, col_width[j]-1, row_height[i]-1, 0xff0000, 0);
  510.                                 }
  511.                                 else
  512.                                         text = (values[j][i] && !display_formulas ? values[j][i] : cells[j][i]);
  513.  
  514.                                 int dy = (row_height[i] - 8) / 2 + 1;
  515.  
  516.                                 if (text)
  517.                                         if (strlen(text) < col_width[j]/6)
  518.                                                 kos_WriteTextToWindow(x+2,y+dy,0,text_color,text,strlen(text));
  519.                                         else
  520.                                                 kos_WriteTextToWindow(x+2,y+dy,0,text_color,text,col_width[j]/6);
  521.  
  522.                         }
  523.                         if (!sel_moved || is_x_changed(j) || is_y_changed(i))  
  524.                                 kos_DrawLine(col_left[j]+col_width[j], row_top[i], col_left[j]+col_width[j], row_height[i], GRID_COLOR, 0);
  525.                         x += col_width[j];
  526.                 }
  527.                 y += row_height[i];
  528.         }
  529.  
  530.         DrawScrolls();
  531. }
  532.  
  533. // очень быстрое рисование сетки, в процессе изменения размеров ячеек
  534. void draw_size_grid()
  535. {
  536.         //rtlDebugOutString("draw size grid");
  537.  
  538.         if (size_state == SIZE_X)
  539.         {
  540.                 int x, x0, i;
  541.  
  542.                 x = col_width[0];
  543.                 x0 = 0;
  544.                 for (i = 1; i < col_count && x - x0 + col_width[i] < grid.w - 10; i++)
  545.                 {
  546.                         if (i >= scroll_x)
  547.                         {
  548.                                 if (i >= size_id)
  549.                                         kos_DrawLine(x - x0, 0, x - x0, grid.h, 0, 1);
  550.                         }
  551.                         else
  552.                                 x0 += col_width[i];
  553.                         x += col_width[i];
  554.                 }
  555.                 kos_DrawLine(x - x0, 0, x - x0, grid.h, 0, 1);
  556.         }
  557.         else
  558.         {
  559.                 int y, y0, i;
  560.  
  561.                 y = row_height[0];
  562.                 y0 = 0;
  563.                 for (i = 1; i < col_count && y - y0 + row_height[i] < grid.h - 10; i++)
  564.                 {
  565.                         if (i >= scroll_y)
  566.                         {
  567.                                 if (i >= size_id)
  568.                                         kos_DrawLine(0, y - y0, grid.w, y - y0, 0, 1);
  569.                         }
  570.                         else
  571.                                 y0 += row_height[i];
  572.                         y += row_height[i];
  573.                 }
  574.                 kos_DrawLine(0, y - y0, grid.w, y - y0, 0, 1);
  575.         }
  576.  
  577. }
  578.  
  579.  
  580. // быстрое рисование выделенной области при выделении мышью
  581. #define DCOLOR 0
  582. //0xff0000
  583. #define DINVERT 1
  584. void draw_drag()
  585. {
  586.         // inverted lines
  587.  
  588.         int k0 = min(sel_x, sel_end_x);
  589.         int k1 = max(sel_x, sel_end_x);
  590.         int n0 = min(sel_y, sel_end_y);
  591.         int n1 = max(sel_y, sel_end_y);
  592.  
  593.         DWORD x0 = col_left[k0] - 1;
  594.         DWORD x1 = col_left[k1] + col_width[k1] + 1;
  595.         DWORD y0 = row_top[n0] - 1;    
  596.         DWORD y1 = row_top[n1] + row_height[n1] + 1;
  597.         if (x0 > grid.w - 1) x0 = grid.w - 1;
  598.         if (x1 > grid.w - 1) x1 = grid.w - 1;
  599.         if (y0 > grid.h - 1) y0 = grid.h - 1;
  600.         if (y1 > grid.h - 1) y1 = grid.h - 1;
  601.  
  602.         //sprintf(debuf,"drag %U %U %U %U",k0,k1,n0,n1);
  603.         //rtlDebugOutString(debuf);
  604.  
  605.         kos_DrawLine(x0, y0, x0, y1, DCOLOR, DINVERT);
  606.         kos_DrawLine(x0, y0, x1, y0, DCOLOR, DINVERT);
  607.         kos_DrawLine(x1, y0, x1, y1, DCOLOR, DINVERT);
  608.         kos_DrawLine(x0, y1, x1, y1, DCOLOR, DINVERT);
  609. }
  610.  
  611. bool draw_and_define_window()
  612. {
  613.         kos_WindowRedrawStatus(1);
  614.         kos_DefineAndDrawWindow(110,40,WND_W,WND_H,0x73,0x40FFFFFF,0,0,(Dword)"Table v" TABLE_VERSION);
  615.         kos_WindowRedrawStatus(2);
  616.  
  617.         sProcessInfo info;
  618.         kos_ProcessInfo(&info, 0xFFFFFFFF);
  619.         cWidth = info.processInfo.width - 9;
  620.         cHeight = info.processInfo.height - kos_GetSkinHeight() - 4;
  621.  
  622.         grid.x = 0;
  623.         grid.y = 0;
  624.         grid.w = cWidth - SCROLL_SIZE;
  625.         grid.h = cHeight - MENU_PANEL_HEIGHT - SCROLL_SIZE;
  626.  
  627.         if (info.processInfo.status_window&0x04) return false; //draw nothing if window is rolled-up
  628.  
  629.         if (grid.h < 100) { kos_ChangeWindow( -1, -1, -1, 180 ); return false; }
  630.         if (grid.w < 340) { kos_ChangeWindow( -1, -1, 350, -1 ); return false; }
  631.  
  632.         return true;
  633. }
  634.  
  635. void draw_window()
  636. {
  637.  
  638.         if (sel_end_move)
  639.                 sel_moved = 0;
  640.  
  641.         panel_y = cHeight - MENU_PANEL_HEIGHT;
  642.  
  643.         if (!sel_moved)
  644.         {
  645.                 kos_DrawBar(cWidth-SCROLL_SIZE, panel_y - SCROLL_SIZE, SCROLL_SIZE, SCROLL_SIZE, PANEL_BG_COLOR);
  646.                 kos_DrawBar(0, panel_y, cWidth, MENU_PANEL_HEIGHT, PANEL_BG_COLOR);
  647.                 kos_WriteTextToWindow(3 + 1, panel_y + 16, 0x80, 0x000000, (char*)sFilename, 0);       
  648.         }
  649.  
  650.         file_box.top = panel_y + 12;
  651.  
  652.         //save
  653.         kos_DefineButton(20 + 160, panel_y + 9, 60, 20, SAVE_BUTTON, 0xd0d0d0);
  654.         kos_WriteTextToWindow(22 + 160 + (60 - strlen(sSave) * 6) / 2, panel_y + 16, 0x80, 0x000000, (char*)sSave, 0);
  655.  
  656.         //load
  657.         kos_DefineButton(90 + 160, panel_y + 9, 60, 20, LOAD_BUTTON, 0xd0d0d0);
  658.         kos_WriteTextToWindow(92 + 160 + (60 - strlen(sLoad) * 6) / 2, panel_y + 16, 0x80, 0x000000, (char*)sLoad, 0);
  659.  
  660.         //new (clean)
  661.         /*
  662.         kos_DefineButton(90 + 160 + 70, panel_y + 9, 60, 20, NEW_BUTTON, 0xd0d0d0);
  663.         kos_WriteTextToWindow(92 + 160 + 10 + 70, panel_y + 16, 0, 0x000000, (char*)sNew, strlen(sNew));
  664.         */
  665.  
  666.         if ((void*)edit_box_draw != NULL)
  667.         {
  668.                 if (is_edit)
  669.                         edit_box_draw((DWORD)&cell_box);
  670.                 edit_box_draw((DWORD)&file_box);
  671.         }
  672.  
  673.         draw_grid();
  674.         sel_moved = 0;
  675. }
  676.  
  677. void process_mouse()
  678. {
  679.         Dword mouse_btn, ckeys, shift, ctrl;
  680.         int mouse_x, mouse_y, i, dx = 0, dy = 0;
  681.         bool window_is_dragged=false;
  682.        
  683.         edit_box_mouse((dword)&cell_box);
  684.         edit_box_mouse((dword)&file_box);
  685.  
  686.         int vert, hor;
  687.         kos_GetScrollInfo(vert, hor);
  688.  
  689.         //sprintf(debuf, "scroll %U %U", vert, hor);
  690.         //rtlDebugOutString(debuf);
  691.                
  692.         if (vert != 0)
  693.         {
  694.                 stop_edit();
  695.                 scroll_y += vert;
  696.                 if (scroll_y<1) scroll_y=1;
  697.                 if (scroll_y>row_count-25) scroll_y=row_count-25;
  698.                 draw_grid();
  699.                 return;
  700.         }
  701.  
  702.         if (!sel_moved && !size_state) //do not handle scrollbars when user selects cells
  703.         {
  704.                 scrollbar_v_mouse((DWORD)&scroll_v);
  705.                 if (scroll_v.position != scroll_y-1)
  706.                 {
  707.                         scroll_y = scroll_v.position + 1;
  708.                         draw_grid();
  709.                 }
  710.  
  711.                 scrollbar_h_mouse((DWORD)&scroll_h);
  712.                 if (scroll_h.position != scroll_x-1)
  713.                 {
  714.                         scroll_x = scroll_h.position + 1;
  715.                         draw_grid();
  716.                 }              
  717.         }
  718.  
  719.         kos_GetMouseState(mouse_btn, mouse_x, mouse_y);
  720.         mouse_x -= 5;
  721.         mouse_y -= kos_GetSkinHeight();
  722.  
  723.         mouse_btn &= 0x0001;
  724.  
  725.         if (mouse_btn)
  726.         {
  727.                 if (mouse_y < 0) return; // do nothing if mouse over header
  728.                 if (mouse_y > grid.y + grid.h) return;
  729.         }
  730.  
  731.         ckeys = kos_GetSpecialKeyState();
  732.         shift = ckeys & 0x3;
  733.  
  734.         if (!size_state && !mouse_btn)
  735.                 return;
  736.         if (mouse_btn && !size_state)           // LMB down                            
  737.         {
  738.                 //rtlDebugOutString("lmb down and not resize");
  739.  
  740.                 if (mouse_x >= drag_x && mouse_x <= drag_x + 4 && mouse_y >= drag_y && mouse_y <= drag_y + 4)
  741.                 {
  742.                         size_state = SIZE_DRAG;
  743.                         old_end_x = sel_end_x;
  744.                         old_end_y = sel_end_y;
  745.                 }
  746.                 else if (mouse_y <= row_height[0])
  747.                 {
  748.                         //rtlDebugOutString("can resize cols");
  749.                         int kx = -1, i;
  750.                         for (i = 0; i < col_count - 1; i++)
  751.                         if (mouse_x >= col_left[i] + col_width[i] - 5 &&
  752.                                 mouse_x <= col_left[i + 1] + 5)
  753.                         {
  754.                                 kx = i; break;
  755.                         }
  756.                         if (kx != -1)
  757.                         {
  758.                                 //sprintf(debuf,"size x %U",k);
  759.                                 //rtlDebugOutString(debuf);
  760.                                 size_id = kx;
  761.                                 size_state = SIZE_X;
  762.                         }
  763.                 }
  764.                 else if (mouse_x <= col_width[0])
  765.                 {
  766.                         int ky = -1;
  767.                         for (i = 0; i < row_count - 1; i++)
  768.                         if (mouse_y >= row_top[i] + row_height[i] - 5 &&
  769.                                 mouse_y <= row_top[i + 1] + 5)
  770.                         {
  771.                                 ky = i; break;
  772.                         }
  773.                         if (ky != -1)
  774.                         {
  775.                                 size_id = ky;
  776.                                 size_state = SIZE_Y;
  777.                         }
  778.                 }
  779.                 else            // click on cell
  780.                 if (mouse_x <= col_left[nx - 1] &&  mouse_y <= row_top[ny - 1])
  781.                 {
  782.                         was_single_selection = sel_x == sel_end_x && sel_y == sel_end_y;
  783.                         int kx = -1, i;
  784.                         for (i = 0; i < col_count - 1; i++)
  785.                         if (mouse_x >= col_left[i] &&
  786.                                 mouse_x <= col_left[i] + col_width[i])
  787.                         {
  788.                                 kx = i; break;
  789.                         }
  790.                         int ky = -1;
  791.                         for (i = 0; i < row_count - 1; i++)
  792.                         if (mouse_y >= row_top[i] &&
  793.                                 mouse_y <= row_top[i] + row_height[i])
  794.                         {
  795.                                 ky = i; break;
  796.                         }
  797.                         if (kx != -1 && ky != -1)
  798.                         {
  799.                                 if (!shift)
  800.                                 {
  801.                                         move_selection(kx, ky);
  802.                                         //return;
  803.                                 }
  804.                                 else
  805.                                 {
  806.                                         sel_end_x = kx;
  807.                                         sel_end_y = ky;
  808.                                 }
  809.                                 size_state = SIZE_SELECT;
  810.                         }
  811.                 }
  812.                 if (size_state)
  813.                 {
  814.                         size_mouse_x = mouse_x;
  815.                         size_mouse_y = mouse_y;
  816.                 }
  817.                 return;
  818.         }
  819.         else if (!mouse_btn && size_state)
  820.         {
  821.                 sel_moved = 0;          // for a good redraw
  822.                 //rtlDebugOutString("resize end");
  823.  
  824.                 if (size_state == SIZE_DRAG)
  825.                 {
  826.                         fill_cells(sel_x, sel_y, sel_end_x, sel_end_y, old_end_x, old_end_y);
  827.                 }
  828.  
  829.                 //sel_moved = (size_state == SIZE_SELECT && sel_x == sel_end_x && sel_y == sel_end_y && was_single_selection);
  830.                 size_state = 0;
  831.                 draw_window();          // все сдвинулось - надо обновиться
  832.                 return;
  833.         }
  834.         if (size_state == SIZE_X && mouse_x != size_mouse_x)
  835.         {
  836.                 draw_size_grid();
  837.                 col_width[size_id] += mouse_x - size_mouse_x;
  838.                 if (col_width[size_id] < 15)
  839.                         col_width[size_id] = 15;
  840.                 else if (col_width[size_id] > grid.w / 2)
  841.                         col_width[size_id] = grid.w / 2;
  842.                 draw_size_grid();
  843.         }
  844.         if (size_state == SIZE_Y && mouse_y != size_mouse_y)
  845.         {
  846.                 draw_size_grid();
  847.                 row_height[size_id] += mouse_y - size_mouse_y;
  848.                 if (row_height[size_id] < 15)
  849.                         row_height[size_id] = 15;
  850.                 else if (row_height[size_id] > grid.h / 2)
  851.                         row_height[size_id] = grid.h / 2;
  852.                 draw_size_grid();
  853.         }
  854.         if ((size_state == SIZE_SELECT || size_state == SIZE_DRAG) && (mouse_x != size_mouse_x || mouse_y != size_mouse_y))
  855.         {
  856.                 draw_drag();
  857.                 int kx = -1, i;
  858.                 for (i = 0; i < col_count - 1; i++)
  859.                         if (mouse_x >= col_left[i] &&
  860.                                 mouse_x <= col_left[i + 1])
  861.                         {
  862.                                 //sprintf(debuf, "yyy %U",col_left[i+1]);
  863.                                 //rtlDebugOutString(debuf);
  864.                                 kx = i; break;
  865.                         }
  866.                 int ky = -1;
  867.                 for (i = 0; i < row_count - 1; i++)
  868.                         if (mouse_y >= row_top[i] &&
  869.                                 mouse_y <= row_top[i + 1])
  870.                         {
  871.                                 ky = i; break;
  872.                         }
  873.                 if (kx != -1) sel_end_x = kx;
  874.                 if (kx != -1) sel_end_y = ky;
  875.                 if (size_state == SIZE_DRAG)
  876.                 {
  877.                         if (abs(sel_end_x - sel_x) > 0)
  878.                         {
  879.                                 sel_end_y = old_end_y;
  880.                         }
  881.                         else if (abs(sel_end_y - sel_y) > 0)
  882.                         {
  883.                                 sel_end_x = old_end_x;
  884.                         }
  885.                 }
  886.                 draw_drag();
  887.         }        
  888.         size_mouse_x = mouse_x;
  889.         size_mouse_y = mouse_y;
  890. }
  891.  
  892. void process_key()
  893. {
  894.         Dword mouse_btn, ckeys, shift, ctrl;
  895.         int mouse_x, mouse_y, dx = 0, dy = 0;
  896.  
  897.         // key pressed, read it
  898.         Byte keyCode;
  899.         ckeys = kos_GetSpecialKeyState();
  900.         shift = ckeys & 0x3;
  901.         ctrl = ckeys & 0x0c;
  902.         //if (ctrl)
  903.         //      rtlDebugOutString("control pressed!");
  904.         dx = 0, dy = 0;
  905.         sel_moved = 0;
  906.         sel_end_move = 0;
  907.         kos_GetKey(keyCode);
  908.  
  909.         __asm
  910.         {
  911.                 mov ah, keyCode
  912.         }
  913.         edit_box_key((dword)&cell_box);
  914.         edit_box_key((dword)&file_box);
  915.  
  916.  
  917.         switch (keyCode)
  918.         {
  919.                 case 178:
  920.                         //dx = 0;
  921.                         dy = -1;
  922.                         break;
  923.                 case 176:
  924.                         dx = -1;
  925.                         //dy = 0;
  926.                         break;
  927.                 case 179:
  928.                         dx = 1;
  929.                         //dy = 0;
  930.                         break;
  931.                 case 177:
  932.                         //dx = 0;
  933.                         dy = 1;
  934.                         break;
  935.                 case 183:
  936.                 /*
  937.                         if (sel_y < row_count-(ny - scroll_y))  // page down
  938.                                 dy = ny - scroll_y;
  939.                         else
  940.                                 dy = row_count-(ny - scroll_y) - sel_y;
  941.                         dx = 0;
  942.                         redraw = 1;
  943.                 */
  944.                         break;
  945.                 case 184:
  946.                 /*
  947.                         if (sel_y > ny - scroll_y)              // page up
  948.                                 dy= - (ny - scroll_y);
  949.                         else
  950.                                 dy = - (ny - scroll_y) + sel_y;
  951.                         dx = 0;
  952.                         redraw = 1;
  953.                 */
  954.                         break;
  955.                 case 180: //home
  956.                         dx = -sel_x + 1;
  957.                         dy = 0;
  958.                         draw_grid();
  959.                         break;
  960.                 case 181: //end
  961.                         dx = col_count - (nx - scroll_x) - 1 - sel_x;
  962.                         dy = 0;
  963.                         draw_grid();
  964.                         break;
  965.                 case 27:                // escape
  966.                         cancel_edit();
  967.                         break;
  968.                 case 182:                       // delete
  969.                         {
  970.                                 int i,j,n0,n1,k0,k1;
  971.                                 n0 = min(sel_x, sel_end_x);
  972.                                 n1 = max(sel_x, sel_end_x);
  973.                                 k0 = min(sel_y, sel_end_y);
  974.                                 k1 = max(sel_y, sel_end_y);
  975.  
  976.                                 for (i = n0; i <= n1; i++)
  977.                                         for (j = k0; j <= k1; j++)
  978.                                         {
  979.                                                 if (cells[i][j])
  980.                                                 {
  981.                                                         freemem(cells[i][j]);
  982.                                                         cells[i][j] = NULL;
  983.                                                 }
  984.                                         }
  985.                                 calculate_values();
  986.                                 draw_grid();
  987.                                 break;
  988.                         }
  989.                 case 0x0D:                      // enter
  990.                         if (is_edit)
  991.                         {
  992.                                 stop_edit();
  993.                                 draw_window();
  994.                         }
  995.                         break;
  996.                 case 22:        // contol-v
  997.                         {
  998.                                 if (ctrl)
  999.                                 {
  1000.                                         int i, j, x0, y0;
  1001.                                         x0 = min(sel_x, sel_end_x);
  1002.                                         y0 = min(sel_y, sel_end_y);
  1003.                                         int delta_x = x0 - buf_old_x;
  1004.                                         int delta_y = y0 - buf_old_y;
  1005.  
  1006.                                         for (i = 0; i < buf_col; i++)
  1007.                                                 for (j = 0; j < buf_row; j++)
  1008.                                                 {
  1009.                                                         if (i + x0 >= col_count || j + y0 >= row_count)
  1010.                                                                 continue;
  1011.                                                         if (cells[i + x0][j + y0])
  1012.                                                                 freemem(cells[i + x0][j + y0]);
  1013.                                                         if (buffer[i][j])
  1014.                                                         {
  1015.                                                                 cf_x0 = buf_old_x; cf_y0 = buf_old_y;
  1016.                                                                 cf_x1 = buf_old_x + buf_col;
  1017.                                                                 cf_y1 = buf_old_y + buf_row;
  1018.                                                                 cells[i + x0][j + y0] = change_formula(buffer[i][j], delta_x, delta_y);
  1019.                                                                 //cells[i + x0][j + y0] = (char*)allocmem(strlen(buffer[i][j]));
  1020.                                                                 //strcpy(cells[i + x0][j + y0], buffer[i][j]);
  1021.                                                         }
  1022.                                                         else
  1023.                                                                 cells[i + x0][j + y0] = NULL;
  1024.                                                 }
  1025.  
  1026.                                         calculate_values();
  1027.                                         draw_grid();
  1028.                                         break;
  1029.                                 }
  1030.                         }
  1031.                         case 24:        // control-x
  1032.                         case 03:        // control-c
  1033.                         {
  1034.                                 if (ctrl)
  1035.                                 {
  1036.                                         //rtlDebugOutString("control-c!");
  1037.                                         int i, j, x0, y0;
  1038.  
  1039.                                         freeBuffer();
  1040.  
  1041.                                         buf_col = abs(sel_end_x - sel_x) + 1;
  1042.                                         buf_row = abs(sel_end_y - sel_y) + 1;
  1043.                                         x0 = min(sel_x, sel_end_x);
  1044.                                         y0 = min(sel_y, sel_end_y);
  1045.                                         buf_old_x = x0;
  1046.                                         buf_old_y = y0;
  1047.  
  1048.                                         //sprintf(debuf, "%U %U %U %U", buf_col, buf_row, x0, y0);
  1049.                                         //rtlDebugOutString(debuf);
  1050.                                
  1051.                                         buffer = (char***)allocmem(buf_col * sizeof(char**));
  1052.                                         for (i = 0; i < buf_col; i++)
  1053.                                         {
  1054.                                                 buffer[i] = (char**)allocmem(buf_row * sizeof(char*));
  1055.                                                 for (j = 0; j < buf_row; j++)
  1056.                                                 {
  1057.                                                         if (cells[i + x0][j + y0])
  1058.                                                         {
  1059.                                                                 if (keyCode == 03)      // ctrl-c
  1060.                                                                 {
  1061.                                                                         buffer[i][j] = (char*)allocmem(strlen(cells[i + x0][j + y0]));
  1062.                                                                         strcpy(buffer[i][j], cells[i + x0][j + y0]);
  1063.                                                                 }
  1064.                                                                 else
  1065.                                                                 {
  1066.                                                                         buffer[i][j] = cells[i + x0][j + y0];
  1067.                                                                         cells[i + x0][j + y0] = NULL;
  1068.                                                                 }
  1069.                                                         }
  1070.                                                         else
  1071.                                                                 buffer[i][j] = NULL;
  1072.                                                 }
  1073.                                         }
  1074.                                         if (keyCode == 24)
  1075.                                                 calculate_values();
  1076.                                         draw_grid();
  1077.                                         break;
  1078.                                 }
  1079.                         }
  1080.                 case 06:                // control-f
  1081.                         {
  1082.                                 display_formulas = !display_formulas;
  1083.                                 draw_grid();
  1084.                                 break;
  1085.                         }
  1086.                 default:               
  1087.                         if (!is_edit && !(file_box.flags & ed_focus))
  1088.                         {
  1089.                                 start_edit(sel_x, sel_y);
  1090.                                 if (keyCode == 8)
  1091.                                 {
  1092.                                         cell_box.pos = strlen(edit_text);
  1093.                                 }
  1094.                                 else
  1095.                                 {
  1096.                                         __asm
  1097.                                         {
  1098.                                                 mov ah, keyCode
  1099.                                         }
  1100.                                         edit_box_key((dword)&cell_box);
  1101.                                 }
  1102.                         }
  1103.                         if (is_edit)
  1104.                                 edit_box_draw((dword)&cell_box);
  1105.                         break;
  1106.         }
  1107.         if (dx != 0)
  1108.         {
  1109.                 if (shift)
  1110.                 {
  1111.                         sel_end_x += dx;
  1112.                         if (sel_end_x <= 1)
  1113.                                 sel_end_x = 1;
  1114.                         else if (sel_end_x >= col_count)
  1115.                                 sel_end_x = col_count - 1;
  1116.                 //      sprintf(debuf,"sel end x change. sel end %U %U",sel_end_x,sel_end_y);
  1117.                 //      rtlDebugOutString(debuf);
  1118.                         sel_moved = sel_end_move = 1;
  1119.                         //stop_edit();
  1120.                         //draw_grid();
  1121.                 }
  1122.                 else
  1123.                 {
  1124.                 }
  1125.         }
  1126.         if (dy != 0)
  1127.         {
  1128.                 if (shift)
  1129.                 {
  1130.                         sel_end_y += dy;
  1131.                         if (sel_end_y <= 1)
  1132.                                 sel_end_y = 1;
  1133.                         else if (sel_end_y >= row_count)
  1134.                                 sel_end_y = row_count - 1;
  1135.                 //      sprintf(debuf,"sel end y change. sel end %U %U",sel_end_x,sel_end_y);
  1136.                 //      rtlDebugOutString(debuf);
  1137.                         sel_moved = sel_end_move = 1;
  1138.                         //stop_edit();
  1139.                         //draw_grid();
  1140.                 }
  1141.         }
  1142.         /*
  1143.         if (sel_end_x < sel_x)
  1144.         {
  1145.                 Dword tmp = sel_end_x; sel_end_x = sel_x; sel_x = tmp;
  1146.         }
  1147.         if (sel_end_y < sel_y)
  1148.         {
  1149.                 Dword tmp = sel_end_y; sel_end_y = sel_y; sel_y = tmp;
  1150.         }
  1151.         */
  1152.         if ((dx || dy))
  1153.         {
  1154.                 if (!shift)
  1155.                 {
  1156.                         if ((sel_end_x + dx) >= (col_count-1)) {dx=0;} //stub
  1157.                         else if ((sel_end_y + dy) >= (row_count-1)) {dy=0;}
  1158.                         else {
  1159.                         move_selection(sel_x + dx, sel_y + dy);
  1160.                         }
  1161.                 }
  1162.                 else
  1163.                 {
  1164.                         sel_moved = 0;
  1165.                         stop_edit();
  1166.                         draw_grid();
  1167.                 }
  1168.         }
  1169. }
  1170.  
  1171.  
  1172. void process_button()
  1173. {
  1174.         Dword mouse_btn, ckeys, shift, ctrl;
  1175.         int mouse_x, mouse_y, i, p, dx = 0, dy = 0;
  1176.         int redraw = 0;
  1177.  
  1178.         Dword button;
  1179.         if (!kos_GetButtonID(button)) return;
  1180.  
  1181.         // sprintf(debuf, "button %U", button);
  1182.         // rtlDebugOutString(debuf);
  1183.  
  1184.         switch (button)
  1185.         {
  1186.         case 1:
  1187.                 kos_ExitApp();
  1188.  
  1189.         case NEW_BUTTON:        // clear the table
  1190.                 reinit();
  1191.                 draw_window();
  1192.                 break;
  1193.  
  1194.         case FILENAME_BUTTON:
  1195.                 sel_moved = 1;
  1196.                 stop_edit();
  1197.                 fn_edit = 1;
  1198.                 strcpy(edit_text, fname);
  1199.                 draw_window();
  1200.                 break;
  1201.  
  1202.         case SAVE_BUTTON:
  1203.                 stop_edit();
  1204.                 if (SaveFile(fname)) {
  1205.                         kos_DrawBar(320, panel_y + 16, cWidth - 320, 12, PANEL_BG_COLOR);
  1206.                         kos_WriteTextToWindow(320, panel_y + 16, 0x80, 0x000000, (char*)msg_save, 0);                  
  1207.                 }
  1208.                 break;
  1209.  
  1210.         case LOAD_BUTTON:
  1211.                 stop_edit();
  1212.                 int r = LoadFile(fname);
  1213.                 kos_DrawBar(320, panel_y + 16, cWidth - 320, 12, PANEL_BG_COLOR);
  1214.                 char *result;
  1215.                 if (r > 0)
  1216.                 {
  1217.                         calculate_values();
  1218.                         sel_moved = 0;
  1219.                         draw_window();
  1220.                         result = (char*)msg_load;
  1221.                 }
  1222.                 else if (r == -1) result = (char*)er_file_not_found;
  1223.                 else if (r == -2) result = (char*)er_format;
  1224.                 kos_WriteTextToWindow(320, panel_y + 16, 0x80, 0x000000, result, 0);
  1225.                 break;
  1226.         }
  1227.         if (button >= COL_HEAD_BUTTON && button < ROW_HEAD_BUTTON)
  1228.         {
  1229.                 sel_end_x = sel_x = button - COL_HEAD_BUTTON;
  1230.                 sel_y = 1;
  1231.                 sel_end_y = row_count - 1;
  1232.                 stop_edit();
  1233.                 draw_grid();
  1234.                 return;
  1235.         }
  1236.         else if (button >= ROW_HEAD_BUTTON && button < CELL_BUTTON)
  1237.         {
  1238.                 sel_end_y = sel_y = button - ROW_HEAD_BUTTON;
  1239.                 sel_x = 1;
  1240.                 sel_end_x = col_count - 1;
  1241.                 stop_edit();
  1242.                 draw_grid();
  1243.                 return;
  1244.         }
  1245.  
  1246. }
  1247.  
  1248. void kos_Main()
  1249. {
  1250.         kos_InitHeap();
  1251.         load_edit_box();
  1252.         init();
  1253.         kos_SetMaskForEvents(EVM_REDRAW + EVM_KEY + EVM_BUTTON + EVM_MOUSE + EVM_MOUSE_FILTER);
  1254.        
  1255.         for (;;)
  1256.         {
  1257.                 switch (kos_WaitForEvent())
  1258.                 {
  1259.                 case EM_MOUSE_EVENT:
  1260.                         process_mouse();
  1261.                         break;
  1262.  
  1263.                 case EM_KEY_PRESS:
  1264.                         process_key();
  1265.                         break;
  1266.  
  1267.                 case EM_BUTTON_CLICK:
  1268.                         process_button();
  1269.                         break;
  1270.                
  1271.                 case EM_WINDOW_REDRAW:
  1272.                         if (draw_and_define_window()) draw_window();
  1273.                         break;
  1274.                 }
  1275.         }
  1276. }
  1277.  
  1278.