00001
00002
00003
00004
00005
00006
00007
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "config.h"
00029
00030 #include <string.h>
00031 #include <gtk/gtk.h>
00032 #include <glib.h>
00033 #include <glib/gi18n.h>
00034 #include <gtkextra/gtksheet.h>
00035 #include "types.h"
00036 #include "dim_list_menu.h"
00037 #include "edit.h"
00038 #include "main.h"
00039 #include "dialog_initial.h"
00040
00041 static void
00042 dim_sum_menu (QlContext * qlc)
00043 {
00044 dim_list_edit_menu (qlc);
00045 dim_list_sort_menu (qlc);
00046 dim_list_column_menu (qlc);
00047 }
00048
00049 gboolean
00050 activate_callback (GtkSheet G_GNUC_UNUSED * sheet,
00051 gint row, gint col, gpointer data)
00052 {
00053 QlTabData * tab;
00054 gchar *textp;
00055 gboolean flag;
00056 gint colx, rowx;
00057
00058 tab = (QlTabData*) data;
00059 if (!tab)
00060 return FALSE;
00061 if (row < 0 || col < 0)
00062 return TRUE;
00063
00064 if (row >= tab->file->last_row)
00065 {
00066 flag = FALSE;
00067 if (tab->file->last_row < 7)
00068 flag = TRUE;
00069 else
00070 for (rowx = tab->file->last_row - 4;
00071 rowx <= tab->file->last_row && !flag; rowx++)
00072 for (colx = 0; colx <= tab->file->last_field; colx++)
00073 if (gtk_sheet_cell_get_text (tab->view->sheet,
00074 rowx, colx))
00075 {
00076 flag = TRUE;
00077 break;
00078 }
00079 if (flag)
00080 {
00081 big_draw_start (tab);
00082 add1row (tab);
00083 big_draw_end (tab);
00084 }
00085 }
00086 tab->view->sel_range.row0 = tab->view->sel_range.rowi = row;
00087 tab->view->sel_range.col0 = tab->view->sel_range.coli = col;
00088 tab->view->sel_type = SELECT_ENTRY;
00089 dim_sum_menu (tab->qlc);
00090
00091 if (row == tab->view->activate_row && col == tab->view->activate_col)
00092 return (TRUE);
00093
00094 check_if_changed (tab);
00095
00096 if (tab->view->activate_text)
00097 {
00098 g_free (tab->view->activate_text);
00099 tab->view->activate_text = NULL;
00100 }
00101
00102
00103 tab->view->activate_row = row;
00104 tab->view->activate_col = col;
00105 tab->view->activate_text = textp =
00106 gtk_sheet_cell_get_text (tab->view->sheet, row, col);
00107 if (textp)
00108 tab->view->activate_text = g_strdup (textp);
00109 return TRUE;
00110 }
00111
00113 static void
00114 actual_paste (QlTabData * tab, gint sheet_row, gint cb_row, gint col)
00115 {
00116 gchar *linebufp;
00117 gchar *prevbufp;
00118 gint colx;
00119 gint fieldx;
00120 prevbufp = linebufp = tab->view->cb[cb_row];
00121 colx = col;
00122 while (*linebufp != '\0')
00123 {
00124 if (*linebufp != '\t')
00125 linebufp++;
00126 else
00127 {
00128 if (colx > tab->file->last_field)
00129 return;
00130 *linebufp = '\0';
00131 fieldx = tab->file->col_to_field[colx];
00132 gtk_sheet_set_cell_text (tab->view->sheet, sheet_row,
00133 colx, prevbufp);
00134 *linebufp = '\t';
00135
00136 prevbufp = ++linebufp;
00137 colx++;
00138 }
00139 }
00140 }
00141
00142 static void
00143 clear_the_range (QlTabData * tab)
00144 {
00145
00146 gint rowx;
00147 gint16 colx;
00148 big_draw_start (tab);
00149 for (rowx = tab->view->sel_range.row0;
00150 rowx <= tab->view->sel_range.rowi; rowx++)
00151 {
00152
00153 if (row_is_visible (tab, rowx))
00154 for (colx = tab->view->sel_range.col0;
00155 colx <= tab->view->sel_range.coli; colx++)
00156 gtk_sheet_cell_clear (tab->view->sheet, rowx,
00157 colx);
00158 }
00159 big_draw_end (tab);
00160 front_is_changed (tab);
00161 }
00162
00163 void
00164 edit_ditto (GtkAction G_GNUC_UNUSED * w, gpointer data)
00165 {
00166 QlContext * qlc;
00167 QlTabData * tab;
00168 gint row0;
00169 gint col0;
00170 gint rowx;
00171 gchar *text;
00172
00173 qlc = ql_get_context (GTK_WIDGET(data));
00174 tab = ql_get_tabdata (qlc);
00175 CHECK_CHANGED(tab);
00176 if (tab->view->sel_type != SELECT_ENTRY)
00177 return;
00178 row0 = tab->view->sel_range.row0;
00179 col0 = tab->view->sel_range.col0;
00180 for (rowx = row0 - 1; rowx >= 0; rowx--)
00181 {
00182 if (row_is_visible (tab, rowx))
00183 {
00184 text = gtk_sheet_cell_get_text (tab->view->sheet,
00185 rowx, col0);
00186 if (text)
00187 gtk_sheet_set_cell_text (tab->view->sheet,
00188 row0, col0, text);
00189 else
00190 gtk_sheet_cell_clear (tab->view->sheet, row0,
00191 col0);
00192 break;
00193 }
00194 }
00195 }
00196
00197 void
00198 edit_clear (GtkAction G_GNUC_UNUSED * w, gpointer data)
00199 {
00200 QlContext * qlc;
00201 QlTabData * tab;
00202
00203 qlc = ql_get_context (GTK_WIDGET(data));
00204 tab = ql_get_tabdata (qlc);
00205 CHECK_CHANGED(tab);
00206 big_draw_start (tab);
00207 clear_the_range (tab);
00208 big_draw_end (tab);
00209 front_is_changed (tab);
00210 }
00211
00212 void
00213 edit_fill_down (GtkAction G_GNUC_UNUSED * w, gpointer data)
00214 {
00215 gint colx, rowx;
00216 gchar *text;
00217 QlContext * qlc;
00218 QlTabData * tab;
00219
00220 qlc = ql_get_context (GTK_WIDGET(data));
00221 tab = ql_get_tabdata (qlc);
00222 CHECK_CHANGED(tab);
00223 big_draw_start (tab);
00224 if (tab->view->sel_type && tab->view->sel_range.row0 != tab->view->sel_range.rowi)
00225 for (colx = tab->view->sel_range.col0;
00226 colx <= tab->view->sel_range.coli; colx++)
00227 {
00228 text = gtk_sheet_cell_get_text (tab->view->sheet,
00229 tab->view->sel_range.row0, colx);
00230 for (rowx = tab->view->sel_range.row0 + 1;
00231 rowx <= tab->view->sel_range.rowi; rowx++)
00232 if (row_is_visible (tab, rowx))
00233 {
00234 if (text)
00235 gtk_sheet_set_cell_text (tab->view->sheet,
00236 rowx, colx, text);
00237 else
00238 gtk_sheet_cell_clear (tab->view->sheet,
00239 rowx, colx);
00240 }
00241 }
00242 big_draw_end (tab);
00243 front_is_changed (tab);
00244 }
00245
00246 void
00247 edit_paste (GtkAction G_GNUC_UNUSED * w, gpointer data)
00248 {
00249 gint rowx;
00250 gint start_row;
00251 gint start_col;
00252 gint cb_row;
00253 gint sheet_row;
00254 QlContext * qlc;
00255 QlTabData * tab;
00256
00257 qlc = ql_get_context (GTK_WIDGET(data));
00258 tab = ql_get_tabdata (qlc);
00259 CHECK_CHANGED(tab);
00260
00261
00262 start_row = tab->view->sel_range.row0;
00263 start_col = tab->view->sel_range.col0;
00264 big_draw_start (tab);
00265
00266
00267 if (tab->view->cb_sel_type == SELECT_ROW)
00268 {
00269 gtk_sheet_insert_rows (tab->view->sheet,
00270 start_row, tab->view->cb_rows);
00272 tab->file->last_row += tab->view->cb_rows;
00273 for (rowx = 0; rowx < tab->view->cb_rows; rowx++)
00274 {
00275 gtk_sheet_row_button_add_label (tab->view->sheet,
00276 start_row + rowx, " ");
00277 actual_paste (tab, start_row + rowx, rowx, 0);
00278 }
00279 big_draw_end (tab);
00280 front_is_changed (tab);
00281 return;
00282 }
00283
00284
00285 cb_row = 0;
00286 sheet_row = start_row;
00287 while (cb_row < tab->view->cb_rows)
00288 {
00289 if (sheet_row >= tab->file->last_row)
00290 add1row (tab);
00291 if (row_is_visible (tab, sheet_row))
00292 {
00293 actual_paste (tab, sheet_row, cb_row, start_col);
00294 cb_row++;
00295 }
00296 sheet_row++;
00297 }
00298 big_draw_end (tab);
00299 front_is_changed (tab);
00300 }
00301
00302 void
00303 edit_select_all (GtkAction G_GNUC_UNUSED * w, gpointer data)
00304 {
00305 GtkSheetRange range;
00306 QlContext * qlc;
00307 QlTabData * tab;
00308
00309 qlc = ql_get_context (GTK_WIDGET(data));
00310 tab = ql_get_tabdata (qlc);
00311 CHECK_CHANGED(tab);
00312 range.row0 = range.col0 = 0;
00313 range.rowi = tab->file->last_row - 1;
00314 range.coli = tab->file->last_field;
00315 gtk_sheet_select_range (tab->view->sheet, &range);
00316 }
00317
00318 void
00319 edit_insert_rows (GtkAction G_GNUC_UNUSED * w, gpointer data)
00320 {
00321 QlContext * qlc;
00322 QlTabData * tab;
00323
00324 qlc = ql_get_context (GTK_WIDGET(data));
00325 tab = ql_get_tabdata (qlc);
00326 CHECK_CHANGED(tab);
00327 if (tab->view->sel_type == SELECT_COLUMN)
00328 return;
00329 gtk_sheet_insert_rows (tab->view->sheet, tab->view->sel_range.row0,
00330 1);
00331 gtk_sheet_row_button_add_label (tab->view->sheet,
00332 tab->view->sel_range.row0, " ");
00333 front_is_changed (tab);
00334
00335 tab->file->last_row++;
00336 }
00337
00338 void
00339 new_column_width (GtkSheet G_GNUC_UNUSED * sheet, gint col,
00340 gint width, gpointer data)
00341 {
00342 QlTabData * tab;
00343 QlFieldInfo * field;
00344
00345 tab = (QlTabData*)data;
00346 front_is_changed (tab);
00347 field = ql_get_fieldinfo (tab, tab->file->col_to_field[col]);
00348 field->width = width / 8;
00349 }
00350
00352 static void
00353 put_range_on_clipboard (QlTabData * tab)
00354 {
00355 gchar linebuf[4096];
00356 gchar *text;
00357 gchar *linebufp;
00358 gint rowx;
00359 gint16 colx;
00360
00361
00362 if (tab->view->cb_rows)
00363 for (rowx = 0; rowx < tab->view->cb_rows; rowx++)
00364 g_free (tab->view->cb[rowx]);
00365 tab->view->cb_sel_type = tab->view->sel_type;
00366 tab->view->cb_rows = 0;
00367 tab->view->cb_cols = tab->view->sel_range.coli - tab->view->sel_range.col0 + 1;
00368
00369 for (rowx = tab->view->sel_range.row0;
00370 rowx <= tab->view->sel_range.rowi; rowx++)
00371 {
00372 if (row_is_visible (tab, rowx))
00373 {
00374 if (tab->view->cb_rows >= MAX_CLIPBOARD - 2)
00375 level1_error (tab, _("Clipboard is limited to 5,000 rows"));
00376 linebufp = linebuf;
00377 for (colx = tab->view->sel_range.col0;
00378 colx <= tab->view->sel_range.coli; colx++)
00379 {
00380 text = gtk_sheet_cell_get_text (tab->view->sheet,
00381 rowx, colx);
00382 if (text)
00383 {
00384 strcpy (linebufp, text);
00385 linebufp += strlen (text);
00386 }
00387 *linebufp++ = '\t';
00388 }
00389 *linebufp = '\0';
00390 tab->view->cb[tab->view->cb_rows] = g_strdup (linebuf);
00391 tab->view->cb_rows++;
00392 }
00393 }
00394 }
00395
00396 void
00397 edit_cut (GtkAction G_GNUC_UNUSED * w, gpointer data)
00398 {
00399 gint rowx;
00400 QlContext * qlc;
00401 QlTabData * tab;
00402
00403 qlc = ql_get_context (GTK_WIDGET(data));
00404 tab = ql_get_tabdata (qlc);
00405 CHECK_CHANGED(tab);
00406
00407 big_draw_start (tab);
00408 put_range_on_clipboard (tab);
00409 if (tab->view->sel_type == SELECT_ROW)
00410 {
00411 for (rowx = tab->view->sel_range.rowi; rowx >= tab->view->sel_range.row0;
00412 rowx--)
00413 if (rowx != tab->file->last_row)
00414 {
00415 if (row_is_visible (tab, rowx))
00416 {
00417 unselect (tab);
00418 gtk_sheet_delete_rows (tab->view->sheet, rowx,
00419 1);
00420 tab->file->last_row--;
00421 }
00422 }
00423 gtk_sheet_select_row (tab->view->sheet, tab->view->sel_range.row0);
00424 }
00425 else
00426 clear_the_range (tab);
00427
00428 dim_sum_menu (qlc);
00429 big_draw_end (tab);
00430 front_is_changed (tab);
00431 }
00432
00433 void
00434 edit_copy (GtkAction G_GNUC_UNUSED * w, gpointer data)
00435 {
00436 QlContext * qlc;
00437 QlTabData * tab;
00438
00439 qlc = ql_get_context (GTK_WIDGET(data));
00440 tab = ql_get_tabdata (qlc);
00441 CHECK_CHANGED(tab);
00442 put_range_on_clipboard (tab);
00443 }
00444
00445 gboolean
00446 row_is_visible (QlTabData * tab, gint testrow)
00447 {
00448 return (tab->view->sheet->row[testrow].is_visible);
00449 }
00450
00451 void
00452 select_range_callback (GtkSheet G_GNUC_UNUSED * sheet, GtkSheetRange * range,
00453 gpointer data)
00454 {
00455 QlTabData * tab;
00456
00457 tab = (QlTabData*)data;
00458 tab->view->sel_range = *range;
00459 if (!tab->view->sel_range.row0 && tab->view->sel_range.rowi >= tab->file->last_row)
00460 tab->view->sel_type = SELECT_COLUMN;
00461 else if (!tab->view->sel_range.col0
00462 && tab->view->sel_range.coli >= tab->file->last_field)
00463 tab->view->sel_type = SELECT_ROW;
00464 else
00465 {
00466 if (tab->view->sel_range.row0 == tab->view->sel_range.rowi &&
00467 tab->view->sel_range.col0 == tab->view->sel_range.coli)
00468 tab->view->sel_type = SELECT_ENTRY;
00469 else
00470 tab->view->sel_type = SELECT_BLOCK;
00471 }
00472 dim_sum_menu (tab->qlc);
00473 }