treewide: Replace <name>_cnt by n_<name>s and <name>_cap by allocated_<name>.
[pspp] / src / ui / gui / psppire-text-file.c
index 9030896638d2ef2358a37626a36c7acb291353c4..be66a2873e924588c164df582b863b20196a7c71 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2017 Free Software Foundation
+   Copyright (C) 2017, 2020 Free Software Foundation
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -36,15 +36,18 @@ enum
   {
     PROP_0,
     PROP_FILE_NAME,
-    PROP_ENCODING
+    PROP_ENCODING,
+    PROP_MAXIMUM_LINES,
+    PROP_LINE_COUNT
   };
 
-enum {MAX_LINE_LEN = 16384};  /* Max length of an acceptable line. */
-
 
 static void
 read_lines (PsppireTextFile *tf)
 {
+  /* Max length of an acceptable line. */
+  static const int MAX_LINE_LEN = 16384;
+
   if (tf->file_name && 0 != g_strcmp0 ("unset", tf->encoding))
     {
       struct line_reader *reader = line_reader_for_file (tf->encoding, tf->file_name, O_RDONLY);
@@ -57,7 +60,7 @@ read_lines (PsppireTextFile *tf)
 
       struct string input;
       ds_init_empty (&input);
-      for (tf->line_cnt = 0; tf->line_cnt < MAX_PREVIEW_LINES; tf->line_cnt++)
+      for (tf->n_lines = 0; tf->n_lines < MAX_PREVIEW_LINES; tf->n_lines++)
        {
          ds_clear (&input);
          if (!line_reader_read (reader, &input, MAX_LINE_LEN + 1)
@@ -75,34 +78,34 @@ read_lines (PsppireTextFile *tf)
                           "a text file."),
                     tf->file_name, MAX_LINE_LEN);
              line_reader_close (reader);
-             for (i = 0; i < tf->line_cnt; i++)
-               g_free (&tf->lines[i]);
-             tf->line_cnt = 0;
+             for (i = 0; i < tf->n_lines; i++)
+                g_free (tf->lines[i].string);
+             tf->n_lines = 0;
              ds_destroy (&input);
              return;
            }
 
-         tf->lines[tf->line_cnt]
+         tf->lines[tf->n_lines]
            = recode_substring_pool ("UTF-8",
                                     line_reader_get_encoding (reader),
                                     input.ss, NULL);
-       }
+        }
       ds_destroy (&input);
 
-      if (tf->line_cnt == 0)
+      if (tf->n_lines == 0)
        {
          int i;
          msg (ME, _("`%s' is empty."), tf->file_name);
          line_reader_close (reader);
-         for (i = 0; i < tf->line_cnt; i++)
-           g_free (&tf->lines[i]);
-         tf->line_cnt = 0;
+         for (i = 0; i < tf->n_lines; i++)
+           g_free (tf->lines[i].string);
+         tf->n_lines = 0;
          goto done;
        }
 
-      if (tf->line_cnt < MAX_PREVIEW_LINES)
+      if (tf->n_lines < MAX_PREVIEW_LINES)
        {
-         tf->total_lines = tf->line_cnt;
+         tf->total_lines = tf->n_lines;
          tf->total_is_exact = true;
        }
       else
@@ -112,7 +115,7 @@ read_lines (PsppireTextFile *tf)
          off_t position = line_reader_tell (reader);
          if (fstat (line_reader_fileno (reader), &s) == 0 && position > 0)
            {
-             tf->total_lines = (double) tf->line_cnt / position * s.st_size;
+             tf->total_lines = (double) tf->n_lines / position * s.st_size;
              tf->total_is_exact = false;
            }
          else
@@ -124,7 +127,6 @@ read_lines (PsppireTextFile *tf)
     done:
       line_reader_close (reader);
     }
-
 }
 
 static void
@@ -137,6 +139,9 @@ psppire_text_file_set_property (GObject         *object,
 
   switch (prop_id)
     {
+    case PROP_MAXIMUM_LINES:
+      tf->maximum_lines = g_value_get_int (value);
+      break;
     case PROP_FILE_NAME:
       tf->file_name = g_value_dup_string (value);
       read_lines (tf);
@@ -163,6 +168,12 @@ psppire_text_file_get_property (GObject         *object,
 
   switch (prop_id)
     {
+    case PROP_MAXIMUM_LINES:
+      g_value_set_int (value, text_file->maximum_lines);
+      break;
+    case PROP_LINE_COUNT:
+      g_value_set_int (value, text_file->n_lines);
+      break;
     case PROP_FILE_NAME:
       g_value_set_string (value, text_file->file_name);
       break;
@@ -175,16 +186,11 @@ psppire_text_file_get_property (GObject         *object,
     };
 }
 
-
-static void psppire_text_file_init            (PsppireTextFile      *text_file);
-static void psppire_text_file_class_init      (PsppireTextFileClass *class);
-
 static void psppire_text_file_finalize        (GObject           *object);
 static void psppire_text_file_dispose        (GObject           *object);
 
 static GObjectClass *parent_class = NULL;
 
-
 static gboolean
 __tree_get_iter (GtkTreeModel *tree_model,
                 GtkTreeIter *iter,
@@ -199,7 +205,7 @@ __tree_get_iter (GtkTreeModel *tree_model,
 
   gint n = *indices;
 
-  if (n >= file->line_cnt)
+  if (n >= file->n_lines)
     return FALSE;
 
   iter->user_data = GINT_TO_POINTER (n);
@@ -218,7 +224,7 @@ __tree_iter_next (GtkTreeModel *tree_model,
 
   gint n = GPOINTER_TO_INT (iter->user_data) + 1;
 
-  if (n >= file->line_cnt)
+  if (n >= file->n_lines)
     return FALSE;
 
   iter->user_data = GINT_TO_POINTER (n);
@@ -281,7 +287,7 @@ __tree_model_iter_n_children (GtkTreeModel *tree_model,
 {
   PsppireTextFile *file  = PSPPIRE_TEXT_FILE (tree_model);
   g_assert (iter == NULL);
-  return file->line_cnt;
+  return file->n_lines;
 }
 
 static GtkTreeModelFlags
@@ -295,7 +301,6 @@ __tree_model_get_flags (GtkTreeModel *model)
 static gint
 __tree_model_get_n_columns (GtkTreeModel *tree_model)
 {
-  PsppireTextFile *tf  = PSPPIRE_TEXT_FILE (tree_model);
   return 2;
 }
 
@@ -312,7 +317,7 @@ __iter_nth_child (GtkTreeModel *tree_model,
 
   g_return_val_if_fail (file, FALSE);
 
-  if (n >= file->line_cnt)
+  if (n >= file->n_lines)
     {
       iter->stamp = -1;
       iter->user_data = NULL;
@@ -338,7 +343,7 @@ __get_value (GtkTreeModel *tree_model,
 
   gint n = GPOINTER_TO_INT (iter->user_data);
 
-  g_return_if_fail (n < file->line_cnt);
+  g_return_if_fail (n < file->n_lines);
 
   if (column == 0)
     {
@@ -379,44 +384,9 @@ __tree_model_init (GtkTreeModelIface *iface)
   iface->iter_parent     = __iter_parent;
 }
 
-
-GType
-psppire_text_file_get_type (void)
-{
-  static GType text_file_type = 0;
-
-  if (!text_file_type)
-    {
-      static const GTypeInfo text_file_info =
-       {
-         sizeof (PsppireTextFileClass),
-         NULL,         /* base_init */
-         NULL,         /* base_finalize */
-         (GClassInitFunc) psppire_text_file_class_init,
-         NULL,         /* class_finalize */
-         NULL,         /* class_data */
-         sizeof (PsppireTextFile),
-         0,
-         (GInstanceInitFunc) psppire_text_file_init,
-       };
-
-      static const GInterfaceInfo tree_model_info = {
-       (GInterfaceInitFunc) __tree_model_init,
-       NULL,
-       NULL
-      };
-
-      text_file_type = g_type_register_static (G_TYPE_OBJECT,
-                                              "PsppireTextFile",
-                                              &text_file_info, 0);
-
-      g_type_add_interface_static (text_file_type, GTK_TYPE_TREE_MODEL,
-                                  &tree_model_info);
-    }
-
-  return text_file_type;
-}
-
+G_DEFINE_TYPE_WITH_CODE (PsppireTextFile, psppire_text_file, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
+                                               __tree_model_init))
 
 static void
 psppire_text_file_class_init (PsppireTextFileClass *class)
@@ -424,7 +394,21 @@ psppire_text_file_class_init (PsppireTextFileClass *class)
   GObjectClass *object_class;
 
   parent_class = g_type_class_peek_parent (class);
-  object_class = (GObjectClass*) class;
+  object_class = G_OBJECT_CLASS (class);
+
+  GParamSpec *maximum_lines_spec =
+    g_param_spec_int ("maximum-lines",
+                     "Maximum Lines",
+                     P_("An upper limit on the number of lines to consider"),
+                     0, G_MAXINT, G_MAXINT,
+                     G_PARAM_READWRITE);
+
+  GParamSpec *line_count_spec =
+    g_param_spec_int ("line-count",
+                     "Line Count",
+                     P_("The number of lines in the file"),
+                     0, G_MAXINT, G_MAXINT,
+                     G_PARAM_READABLE);
 
   GParamSpec *file_name_spec =
     g_param_spec_string ("file-name",
@@ -443,6 +427,14 @@ psppire_text_file_class_init (PsppireTextFileClass *class)
   object_class->set_property = psppire_text_file_set_property;
   object_class->get_property = psppire_text_file_get_property;
 
+  g_object_class_install_property (object_class,
+                                   PROP_MAXIMUM_LINES,
+                                   maximum_lines_spec);
+
+  g_object_class_install_property (object_class,
+                                   PROP_LINE_COUNT,
+                                   line_count_spec);
+
   g_object_class_install_property (object_class,
                                    PROP_FILE_NAME,
                                    file_name_spec);
@@ -455,7 +447,6 @@ psppire_text_file_class_init (PsppireTextFileClass *class)
   object_class->dispose = psppire_text_file_dispose;
 }
 
-
 static void
 psppire_text_file_init (PsppireTextFile *text_file)
 {
@@ -484,6 +475,9 @@ psppire_text_file_finalize (GObject *object)
 {
   PsppireTextFile *tf = PSPPIRE_TEXT_FILE (object);
 
+  for (int i = 0; i < tf->n_lines; i++)
+    g_free (tf->lines[i].string);
+
   g_free (tf->encoding);
   g_free (tf->file_name);