[gnome-builder/wip/slaf/pack] xml-pack: limit length of symbol tree label



commit c0f849fba2e5e1110dea9539982868b2f04b13f0
Author: Sebastien Lafargue <slafargue gnome org>
Date:   Thu Jul 26 22:04:16 2018 +0200

    xml-pack: limit length of symbol tree label
    
    On some xml files, label length can gets pretty long,
    we do some approximate length limitation so we don't
    get an oversized popover.

 src/plugins/xml-pack/ide-xml-parser-generic.c | 25 +++++++++--
 src/plugins/xml-pack/ide-xml-utils.c          | 62 +++++++++++++++++++++++++++
 src/plugins/xml-pack/ide-xml-utils.h          |  4 ++
 3 files changed, 87 insertions(+), 4 deletions(-)
---
diff --git a/src/plugins/xml-pack/ide-xml-parser-generic.c b/src/plugins/xml-pack/ide-xml-parser-generic.c
index 7d9b6656e..cfb842f23 100644
--- a/src/plugins/xml-pack/ide-xml-parser-generic.c
+++ b/src/plugins/xml-pack/ide-xml-parser-generic.c
@@ -16,21 +16,29 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <string.h>
 #include <libxml/parser.h>
 
 #include "ide-xml-parser.h"
 #include "ide-xml-parser-generic.h"
 #include "ide-xml-sax.h"
 #include "ide-xml-stack.h"
+#include "ide-xml-utils.h"
 
 #include "ide-xml-parser-generic.h"
 
+#define NODE_NAME_LIMIT 60
+
+static gchar ellipsis [] = " …";
+
 static gchar *
 collect_attributes (IdeXmlParser  *self,
-                    const gchar  **attributes)
+                    const gchar  **attributes,
+                    gsize          limit)
 {
   GString *string;
   const gchar **l = attributes;
+  gsize total_len = 0;
 
   g_assert (IDE_IS_XML_PARSER (self));
 
@@ -40,7 +48,16 @@ collect_attributes (IdeXmlParser  *self,
   string = g_string_new (NULL);
   while (l [0] != NULL && *l [0] != '\0')
     {
-      g_autofree gchar *value = _ide_xml_parser_get_color_tag (self, l [0], COLOR_TAG_ATTRIBUTE, TRUE, TRUE, 
TRUE);
+      g_autofree gchar *value = NULL;
+
+      total_len += strlen (l[0]) + strlen (l[1]) + sizeof (ellipsis);
+      if (total_len > limit)
+        {
+          g_string_append (string, ellipsis);
+          break;
+        }
+
+      value = _ide_xml_parser_get_color_tag (self, l [0], COLOR_TAG_ATTRIBUTE, TRUE, TRUE, TRUE);
 
       g_string_append (string, value);
       g_string_append (string, l [1]);
@@ -63,7 +80,7 @@ ide_xml_parser_generic_start_element_sax_cb (ParserState    *state,
 
   g_assert (IDE_IS_XML_PARSER (self));
 
-  attr = collect_attributes (self, (const gchar **)attributes);
+  attr = collect_attributes (self, (const gchar **)attributes, NODE_NAME_LIMIT - strlen ((gchar *)name));
   label = g_strconcat ((const gchar *)name, attr, NULL);
 
   node = ide_xml_symbol_node_new (label, NULL, (gchar *)name, IDE_SYMBOL_XML_ELEMENT);
@@ -83,7 +100,7 @@ ide_xml_parser_generic_comment_sax_cb (ParserState   *state,
 
   g_assert (IDE_IS_XML_PARSER (self));
 
-  strip_name = g_strstrip (g_strdup ((const gchar *)name));
+  strip_name = ide_xml_utils_limit_str ((const gchar *)name, NODE_NAME_LIMIT, TRUE, TRUE);
   node = ide_xml_symbol_node_new (strip_name, NULL, NULL, IDE_SYMBOL_XML_COMMENT);
   _ide_xml_parser_state_processing (self, state, "comment", node, IDE_XML_SAX_CALLBACK_TYPE_COMMENT, FALSE);
 }
diff --git a/src/plugins/xml-pack/ide-xml-utils.c b/src/plugins/xml-pack/ide-xml-utils.c
index d2b68e7a1..2451b877d 100644
--- a/src/plugins/xml-pack/ide-xml-utils.c
+++ b/src/plugins/xml-pack/ide-xml-utils.c
@@ -420,3 +420,65 @@ ide_xml_utils_gi_class_walker (IdeGiBase             *object,
 
   return gi_class_walker (object, name, func, visited, data);
 }
+
+/* Return a copy of str, limited to 'limit' chars,
+ * with possibly stripped whitespaces and added
+ * ellispsis at te end.
+ */
+gchar *
+ide_xml_utils_limit_str (const gchar *str,
+                         gsize        limit,
+                         gboolean     strip,
+                         gboolean     add_ellipsis)
+{
+  const gchar *begin = str;
+  const gchar *end;
+  gsize count = 0;
+  gunichar ch;
+
+  g_return_val_if_fail (!dzl_str_empty0 (str), NULL);
+  g_return_val_if_fail (limit > 0, NULL);
+
+  if (strip)
+    for (begin = (gchar*) str; *begin && g_ascii_isspace (*begin); begin++)
+     ;
+
+  end = begin;
+  while ((ch = g_utf8_get_char (end)))
+    {
+      if (++count > limit)
+        break;
+
+      end = g_utf8_next_char (end);
+    }
+
+  if (end > begin)
+    {
+      if (strip)
+        {
+          do
+            {
+              --end;
+              if (!g_ascii_isspace (*end))
+                {
+                  end++;
+                  break;
+                }
+
+              count--;
+            } while (end > begin);
+        }
+    }
+
+  if (add_ellipsis && count > limit)
+    {
+      GString *new_str = g_string_sized_new (end - begin + 4);
+
+      g_string_append_len (new_str, begin, end - begin);
+      g_string_append (new_str, " …");
+
+      return g_string_free (new_str, FALSE);
+    }
+  else
+    return g_strndup (begin, end - begin);
+}
diff --git a/src/plugins/xml-pack/ide-xml-utils.h b/src/plugins/xml-pack/ide-xml-utils.h
index 0bc32bdb5..a7ee3bf54 100644
--- a/src/plugins/xml-pack/ide-xml-utils.h
+++ b/src/plugins/xml-pack/ide-xml-utils.h
@@ -37,6 +37,10 @@ gboolean ide_xml_utils_gi_class_walker      (IdeGiBase              *object,
                                              IdeXmlUtilsWalkerFunc   func,
                                              gpointer                data);
 gboolean ide_xml_utils_is_name_char         (gunichar                ch);
+gchar   *ide_xml_utils_limit_str             (const gchar           *str,
+                                             gsize                   limit,
+                                             gboolean                strip,
+                                             gboolean                add_ellipsis);
 gboolean ide_xml_utils_skip_attribute_name  (const gchar           **cursor);
 gboolean ide_xml_utils_skip_attribute_value (const gchar           **cursor,
                                              gchar                   term);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]