edit.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *            edit.c
00003  *
00004  *  Fri Aug 25 14:51:36 2006
00005  *  Copyright  2006-2007  Neil Williams
00006  *  linux@codehelp.co.uk
00007  ****************************************************************************/
00013 /*
00014     This package is free software; you can redistribute it and/or modify
00015     it under the terms of the GNU General Public License as published by
00016     the Free Software Foundation; either version 3 of the License, or
00017     (at your option) any later version.
00018 
00019     This program is distributed in the hope that it will be useful,
00020     but WITHOUT ANY WARRANTY; without even the implied warranty of
00021     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022     GNU General Public License for more details.
00023 
00024     You should have received a copy of the GNU General Public License
00025     along with this program.  If not, see <http://www.gnu.org/licenses/>.
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;            /* row or column buttons */
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     /* save this activate */
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';   /* actually change the clipboard */
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';   /* restore the clipboard */
00135 
00136             prevbufp = ++linebufp;
00137             colx++;
00138         }
00139     }
00140 }   /* end of actual_paste */
00141 
00142 static void
00143 clear_the_range (QlTabData * tab)
00144 {
00145     /*this clears, not for deleting */
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 }   /* end of clear_the_range */
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 }   /* end of edit_ditto */
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 /*  if (!paste_is_ok ())
00261         return;*/
00262     start_row = tab->view->sel_range.row0;
00263     start_col = tab->view->sel_range.col0;
00264     big_draw_start (tab);
00265 
00266     /* paste rows */
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     }   /* end of type R */
00283 
00284     /* paste the rest */
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 }   /* end of edit_paste */
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     /* adding a new row of data, ensure Data is updated. */
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     /* get rid of previous contents, if any */
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     {                           /* work backwards to keep rowx right */
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 }

Generated on Mon Jan 28 22:02:10 2008 for quicklist by  doxygen 1.5.4