Subversion Repositories Kolibri OS

Rev

Rev 7504 | Rev 7516 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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