[glom] Move some functions to string_utils.h
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glom] Move some functions to string_utils.h
- Date: Thu, 17 Mar 2016 12:34:34 +0000 (UTC)
commit 1d39c4561054e6fe407c0d71ab8c3569928997e5
Author: Murray Cumming <murrayc murrayc com>
Date: Wed Mar 16 20:29:52 2016 +0100
Move some functions to string_utils.h
CMakeLists.txt | 2 +
glom/appwindow.cc | 1 +
glom/box_reports.cc | 1 +
glom/frame_glom.cc | 1 +
glom/glom_import_po_all.cc | 1 +
glom/libglom/data_structure/field.cc | 1 +
glom/libglom/data_structure/glomconversions.cc | 2 +-
glom/libglom/db_utils.cc | 1 +
glom/libglom/document/document.cc | 1 +
glom/libglom/filelist.am | 2 +
glom/libglom/glom_postgres.cc | 1 +
glom/libglom/string_utils.cc | 393 ++++++++++++++++++++
glom/libglom/string_utils.h | 69 ++++
glom/libglom/utils.cc | 356 +------------------
glom/libglom/utils.h | 31 --
glom/libglom/xml_utils.cc | 1 +
glom/mode_data/db_adddel/db_adddel.cc | 1 +
glom/mode_design/box_db_table_relationships.cc | 1 +
glom/mode_design/dialog_add_related_table.cc | 1 +
glom/mode_design/fields/box_db_table_definition.cc | 1 +
glom/mode_design/layout/dialog_layout_details.cc | 1 +
.../mode_design/print_layouts/box_print_layouts.cc | 1 +
glom/utility_widgets/adddel/adddel.cc | 1 +
23 files changed, 484 insertions(+), 387 deletions(-)
---
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 879136e..18b2d33 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -252,6 +252,8 @@ set(SOURCE_FILES
glom/libglom/standard_table_prefs_fields.h
glom/libglom/translations_po.cc
glom/libglom/translations_po.h
+ glom/libglom/string_utils.cc
+ glom/libglom/string_utils.h
glom/libglom/utils.cc
glom/libglom/utils.h
glom/libglom/xml_utils.cc
diff --git a/glom/appwindow.cc b/glom/appwindow.cc
index 1977c1b..f631da4 100644
--- a/glom/appwindow.cc
+++ b/glom/appwindow.cc
@@ -23,6 +23,7 @@
#include <glom/appwindow.h>
#include <glom/dialog_existing_or_new.h>
#include <glom/bakery/dialog_offersave.h>
+#include <libglom/string_utils.h>
#ifndef GLOM_ENABLE_CLIENT_ONLY
#include <glom/mode_design/translation/dialog_change_language.h>
diff --git a/glom/box_reports.cc b/glom/box_reports.cc
index 516ed80..5e1cee4 100644
--- a/glom/box_reports.cc
+++ b/glom/box_reports.cc
@@ -22,6 +22,7 @@
#include <glom/appwindow.h>
#include <libglom/algorithms_utils.h>
#include <libglom/utils.h> //For bold_message()).
+#include <libglom/string_utils.h>
#include <gtkmm/alignment.h>
#include <gtkmm/dialog.h>
#include <gtkmm/messagedialog.h>
diff --git a/glom/frame_glom.cc b/glom/frame_glom.cc
index 502eb06..1077b91 100644
--- a/glom/frame_glom.cc
+++ b/glom/frame_glom.cc
@@ -27,6 +27,7 @@
#include <glom/import_csv/dialog_import_csv_progress.h>
#include <libglom/appstate.h>
#include <libglom/db_utils_export.h>
+#include <libglom/string_utils.h>
#include <libglom/connectionpool.h>
diff --git a/glom/glom_import_po_all.cc b/glom/glom_import_po_all.cc
index 89086a6..5c642e9 100644
--- a/glom/glom_import_po_all.cc
+++ b/glom/glom_import_po_all.cc
@@ -26,6 +26,7 @@
#include <libglom/init.h>
#include <libglom/translations_po.h>
#include <libglom/utils.h>
+#include <libglom/string_utils.h>
#include <giomm/file.h>
#include <glibmm/optioncontext.h>
#include <glibmm/convert.h>
diff --git a/glom/libglom/data_structure/field.cc b/glom/libglom/data_structure/field.cc
index 575a32b..9d95ff4 100644
--- a/glom/libglom/data_structure/field.cc
+++ b/glom/libglom/data_structure/field.cc
@@ -23,6 +23,7 @@
#include <libglom/connectionpool.h>
#include <libglom/data_structure/glomconversions.h>
#include <libglom/utils.h>
+#include <libglom/string_utils.h>
#include <libgda/gda-blob-op.h>
#include <glibmm/i18n.h>
diff --git a/glom/libglom/data_structure/glomconversions.cc b/glom/libglom/data_structure/glomconversions.cc
index e1bf806..977085e 100644
--- a/glom/libglom/data_structure/glomconversions.cc
+++ b/glom/libglom/data_structure/glomconversions.cc
@@ -24,6 +24,7 @@
#include <libglom/data_structure/glomconversions.h>
#include <libglom/connectionpool.h>
#include <libglom/utils.h>
+#include <libglom/string_utils.h>
#include <glibmm/convert.h>
#include <sstream> //For stringstream
@@ -33,7 +34,6 @@
#include <iostream> // for cout, endl
#include <iomanip>
#include <string.h> // for strlen, memset, strcmp
-#include <stdexcept>
#include <glibmm/i18n.h>
diff --git a/glom/libglom/db_utils.cc b/glom/libglom/db_utils.cc
index 48c780a..ff18b82 100644
--- a/glom/libglom/db_utils.cc
+++ b/glom/libglom/db_utils.cc
@@ -30,6 +30,7 @@
#include <libgdamm/metastore.h>
#include <glibmm/timer.h>
#include <libgda/libgda.h> // For gda_g_type_from_string
+#include "string_utils.h"
#include <glibmm/i18n.h>
diff --git a/glom/libglom/document/document.cc b/glom/libglom/document/document.cc
index bcd2b21..4fa7dee 100644
--- a/glom/libglom/document/document.cc
+++ b/glom/libglom/document/document.cc
@@ -22,6 +22,7 @@
#include <libglom/xml_utils.h>
#include <libglom/algorithms_utils.h>
#include <libglom/utils.h>
+#include <libglom/string_utils.h>
//#include <libglom/data_structure/glomconversions.h>
#include <libglom/data_structure/layout/report_parts/layoutitem_summary.h>
#include <libglom/data_structure/layout/report_parts/layoutitem_fieldsummary.h>
diff --git a/glom/libglom/filelist.am b/glom/libglom/filelist.am
index 8035f29..fecc488 100644
--- a/glom/libglom/filelist.am
+++ b/glom/libglom/filelist.am
@@ -117,6 +117,8 @@ libglom_sources = \
glom/libglom/report_builder.h \
glom/libglom/spawn_with_feedback.cc \
glom/libglom/spawn_with_feedback.h \
+ glom/libglom/string_utils.cc \
+ glom/libglom/string_utils.h \
glom/libglom/translations_po.cc \
glom/libglom/translations_po.h \
glom/libglom/utils.cc \
diff --git a/glom/libglom/glom_postgres.cc b/glom/libglom/glom_postgres.cc
index 4223a09..9584907 100644
--- a/glom/libglom/glom_postgres.cc
+++ b/glom/libglom/glom_postgres.cc
@@ -20,6 +20,7 @@
#include "glom_postgres.h"
#include <libglom/utils.h>
+#include <libglom/string_utils.h>
namespace Glom
{
diff --git a/glom/libglom/string_utils.cc b/glom/libglom/string_utils.cc
new file mode 100644
index 0000000..31ae130
--- /dev/null
+++ b/glom/libglom/string_utils.cc
@@ -0,0 +1,393 @@
+/* Glom
+ *
+ * Copyright (C) 2001-2016 Murray Cumming
+ *
+ * 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 the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#include "string_utils.h"
+#include <libglom/data_structure/field.h>
+#include <libglom/document/document.h>
+#include <giomm/file.h>
+#include <libglom/utils.h>
+#include <giomm/resource.h>
+#include <glibmm/convert.h>
+#include <glibmm/fileutils.h>
+#include <glibmm/miscutils.h>
+#include <stack>
+#include <iostream>
+
+namespace Glom
+{
+
+namespace Utils
+{
+
+Glib::ustring trim_whitespace(const Glib::ustring& text)
+{
+ //TODO_Performance:
+
+ Glib::ustring result = text;
+
+ //Find non-whitespace from front:
+ Glib::ustring::size_type posFront = Glib::ustring::npos;
+ Glib::ustring::size_type pos = 0;
+ for (const auto& item : result)
+ {
+ if (!Glib::Unicode::isspace(item))
+ {
+ posFront = pos;
+ break;
+ }
+
+ ++pos;
+ }
+
+ //Remove the white space from the front:
+ result = result.substr(posFront);
+
+
+ //Find non-whitespace from back:
+ Glib::ustring::size_type posBack = Glib::ustring::npos;
+ pos = 0;
+ for (auto iter = result.rbegin(); iter != result.rend(); ++iter)
+ {
+ if (!Glib::Unicode::isspace(*iter))
+ {
+ posBack = pos;
+ break;
+ }
+
+ ++pos;
+ }
+
+ //Remove the white space from the front:
+ result = result.substr(0, result.size() - posBack);
+
+ return result;
+}
+
+Glib::ustring string_replace(const Glib::ustring& src, const Glib::ustring& search_for, const Glib::ustring&
replace_with)
+{
+ if(search_for.empty())
+ {
+ std::cerr << G_STRFUNC << ": search_for was empty.\n";
+ return src;
+ }
+
+ //std::cout << "debug: " << G_STRFUNC << ": src=" << src << ", search_for=" << search_for << ",
replace_with=" << replace_with << std::endl;
+
+ std::string result = src;
+
+ std::string::size_type pos = 0;
+ const std::string::size_type len_search = search_for.size();
+ const std::string::size_type len_replace = replace_with.size();
+
+ std::string::size_type pos_after_prev = 0;
+ while((pos = result.find(search_for, pos_after_prev)) != std::string::npos)
+ {
+ //std::cout << " debug: pos=" << pos << ", found=" << search_for << ", in string: " <<
result.substr(pos_after_prev, 20) << std::endl;
+ //std::cout << " debug: before: result =" << result << ", pos_after_prev=pos_after_prev\n";
+ result.replace(pos, len_search, replace_with);
+ //std::cout << " after: before: result = result\n";
+ pos_after_prev = pos + len_replace;
+ }
+
+ return result;
+
+/*
+ //TODO_Performance:
+
+ Glib::ustring result;
+ const size_t src_length = src.size();
+ const size_t search_for_length = search_for.size();
+ //const size_t replace_with_length = replace_with.size();
+
+ size_t src_index = 0;
+ size_t src_index_section_start = 0;
+ while(src_index < src_length)
+ {
+ const bool found = (src.find(search_for, src_index) == src_index);
+ if(found)
+ {
+ result += src.substr(src_index_section_start, src_index - src_index_section_start);
+ result += replace_with;
+
+ src_index_section_start = src_index + search_for_length;
+ src_index = src_index_section_start;
+ }
+ else
+ ++src_index;
+ }
+
+ if(src_index_section_start < src_length)
+ {
+ result += src.substr(src_index_section_start);
+ }
+
+ return result;
+*/
+}
+
+Glib::ustring string_clean_for_xml(const Glib::ustring& src)
+{
+ // The form feed character may not be in XML, even if escaped.
+ // So lets just lose it.
+ // Other unusual characters, such as &, are escaped by libxml later.
+ // TODO_Performance: Find a quicker way to do this.
+ return string_replace(src, "\f", Glib::ustring());
+}
+
+Glib::ustring create_name_from_title(const Glib::ustring& title)
+{
+ Glib::ustring result = string_replace(title, " ", "");
+ return result.lowercase(); //TODO: Maybe they need to be ASCII (not UTF8)?
+}
+
+Glib::ustring string_escape_underscores(const Glib::ustring& text)
+{
+ Glib::ustring result;
+ for(const auto& item : text)
+ {
+ if(item == '_')
+ result += "__";
+ else
+ result += item;
+ }
+
+ return result;
+}
+
+Glib::ustring string_trim(const Glib::ustring& str, const Glib::ustring& to_remove)
+{
+ Glib::ustring result = str;
+
+ //Remove from the start:
+ Glib::ustring::size_type posOpenBracket = result.find(to_remove);
+ if(posOpenBracket == 0)
+ {
+ result = result.substr(to_remove.size());
+ }
+
+ //Remove from the end:
+ Glib::ustring::size_type posCloseBracket = result.rfind(to_remove);
+ if(posCloseBracket == (result.size() - to_remove.size()))
+ {
+ result = result.substr(0, posCloseBracket);
+ }
+
+ return result;
+}
+
+Glib::ustring string_remove_suffix(const Glib::ustring& str, const Glib::ustring& suffix, bool
case_sensitive)
+{
+ //There is also g_string_has_suffix(), but I assume that is case sensitive. murrayc.
+
+ const Glib::ustring::size_type size = str.size();
+ const Glib::ustring::size_type suffix_size = suffix.size();
+ if(size < suffix_size)
+ return str;
+
+ const Glib::ustring possible_suffix = str.substr(size - suffix_size);
+
+ if(case_sensitive)
+ {
+ if(possible_suffix == suffix)
+ return str.substr(0, size - suffix_size);
+ }
+ else
+ {
+ if(g_ascii_strcasecmp(possible_suffix.c_str(), suffix.c_str()) == 0) //TODO: I don't understand the
warnings about using this function in the glib documentation. murrayc.
+ return str.substr(0, size - suffix_size);
+ }
+
+ return str;
+}
+
+Glib::ustring title_from_string(const Glib::ustring& text)
+{
+ Glib::ustring result;
+
+ bool capitalise_next_char = true;
+ for(const auto& ch : text)
+ {
+ if(ch == '_') //Replace _ with space.
+ {
+ capitalise_next_char = true; //Capitalise all words.
+ result += " ";
+ }
+ else
+ {
+ if(capitalise_next_char)
+ result += Glib::Unicode::toupper(ch);
+ else
+ result += ch;
+
+ capitalise_next_char = false;
+ }
+ }
+
+ return result;
+}
+
+Glib::ustring string_from_decimal(guint decimal)
+{
+ //TODO_Performance:
+
+ std::stringstream stream;
+ stream.imbue(std::locale("")); //Use the user's current locale.
+ stream << decimal;
+
+ Glib::ustring result;
+ stream >> result;
+
+ return result;
+}
+
+type_vec_strings string_separate(const Glib::ustring& str, const Glib::ustring& separator, bool
ignore_quoted_separator)
+{
+ //std::cout << "debug: " << G_STRFUNC << ": separator=" << separator << std::endl;
+
+ type_vec_strings result;
+
+ const Glib::ustring::size_type size = str.size();
+ const Glib::ustring::size_type size_separator = separator.size();
+
+ //A stack of quotes, so that we can handle nested quotes, whether they are " or ':
+ typedef std::stack<Glib::ustring> type_queue_quotes;
+ type_queue_quotes m_current_quotes;
+
+ Glib::ustring::size_type unprocessed_start = 0;
+ Glib::ustring::size_type item_start = 0;
+ while(unprocessed_start < size)
+ {
+ //std::cout << "while unprocessed: un_processed_start=" << unprocessed_start << std::endl;
+ Glib::ustring::size_type posComma = str.find(separator, unprocessed_start);
+
+ Glib::ustring item;
+ if(posComma != Glib::ustring::npos)
+ {
+ //Check that the separator was not in quotes:
+ bool in_quotes = false;
+
+ if(ignore_quoted_separator)
+ {
+ //std::cout << " debug: attempting to ignore quoted separators: " << separator << std::endl;
+
+ Glib::ustring::size_type posLastQuote = unprocessed_start;
+
+ //std::cout << " debug: posLastQuote=" << posLastQuote << std::endl;
+ //std::cout << " debug: posComma=" << posComma << std::endl;
+
+
+ bool bContinue = true;
+ while(bContinue && (posLastQuote < posComma))
+ {
+ //std::cout << " continue\n";
+ Glib::ustring closing_quote;
+ if(!m_current_quotes.empty())
+ closing_quote = m_current_quotes.top();
+
+ //std::cout << " posLastQuote=" << posLastQuote << std::endl;
+ const Glib::ustring::size_type posSingleQuote = str.find("'", posLastQuote);
+ const Glib::ustring::size_type posDoubleQuote = str.find("\"", posLastQuote);
+
+ // std::cout << " posSingleQuote=" << posSingleQuote << "posDoubleQuote=" << posDoubleQuote <<
std::endl;
+
+ //Which quote, if any, is first:
+ Glib::ustring::size_type posFirstQuote = posSingleQuote;
+ if( (posDoubleQuote != Glib::ustring::npos) && (posDoubleQuote < posFirstQuote) )
+ posFirstQuote = posDoubleQuote;
+
+ //Ignore quotes that are _after_ the separator:
+ if( posFirstQuote >= posComma)
+ posFirstQuote = Glib::ustring::npos;
+
+ //std::cout << " posFirstQuote=" << posFirstQuote << std::endl;
+
+ //If any quote character was found:
+ if(posFirstQuote != Glib::ustring::npos)
+ {
+ //std::cout << "quote found: posFirstQuote=" << posFirstQuote << std::endl;
+
+ //Which quote was it?
+ const Glib::ustring first_quote = (posFirstQuote == posSingleQuote ? "'" : "\"");
+ //std::cout << " first_quote=" << first_quote << std::endl;
+
+ //Was it an expected closing quote, if we expected any:
+ if(first_quote == closing_quote)
+ {
+ //std::cout << " popping quote\n";
+ //Yes, so remove that quote from our stack, because we found the closing quote:
+ m_current_quotes.pop();
+ }
+ else
+ {
+ //std::cout << " pushing quote\n";
+ //This must be an opening quote, so remember it:
+ m_current_quotes.push(first_quote);
+ }
+
+ posLastQuote = posFirstQuote + 1; //Do the next find after the quote.
+ }
+ else
+ {
+ //There were no quotes, or no closing quotes:
+ bContinue = false;
+ }
+ } //while(bContinue)
+
+ //If there were any unclosed quotes then this separator must have been in quotes:
+ if(!m_current_quotes.empty())
+ in_quotes = true;
+ } //If ignore_quoted_separator
+
+ if(!in_quotes) //or if we don't care about quotes.
+ {
+ //std::cout << "!in_quotes\n";
+
+ //Store this item, and start the next item after it:
+ item = str.substr(item_start, posComma - item_start);
+ //std::cout << " ITEM. pos_comma=" << posComma << ", ITEM= " << item << std::endl;
+ item_start = posComma + size_separator;
+ }
+ else
+ {
+ //std::cout << "in quotes.\n";
+ // Continue behind separator
+ unprocessed_start = posComma + size_separator;
+ // Do not add this item to the result, because it was quoted.
+ continue;
+ }
+
+ unprocessed_start = posComma + size_separator; //The while loops stops when this is empty.
+ }
+ else //if no separator found:
+ {
+ item = str.substr(item_start);
+ unprocessed_start = size; //Stop.
+ }
+
+ item = string_trim(item, " ");
+ result.emplace_back(item);
+ } //while
+
+ return result;
+}
+
+} //namespace Utils
+
+} //namespace Glom
\ No newline at end of file
diff --git a/glom/libglom/string_utils.h b/glom/libglom/string_utils.h
new file mode 100644
index 0000000..28c27ad
--- /dev/null
+++ b/glom/libglom/string_utils.h
@@ -0,0 +1,69 @@
+//
+// Created by murrayc on 3/16/16.
+//
+/* Glom
+ *
+ * Copyright (C) 2001-20016 Murray Cumming
+ *
+ * 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 the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#include <glibmm/ustring.h>
+#include <vector>
+
+#ifndef GLOM_STRING_UTILS_H
+#define GLOM_STRING_UTILS_H
+
+namespace Glom {
+
+namespace Utils {
+
+Glib::ustring trim_whitespace(const Glib::ustring &text);
+
+Glib::ustring string_replace(const Glib::ustring& src, const Glib::ustring& search_for, const Glib::ustring&
replace_with);
+
+/** Remove any characters that may not be in XML even when escaped.
+ */
+Glib::ustring string_clean_for_xml(const Glib::ustring& src);
+
+/** Guess an appropriate identifier name based on a human-readable title
+ */
+Glib::ustring create_name_from_title(const Glib::ustring& title);
+
+Glib::ustring string_escape_underscores(const Glib::ustring& text);
+
+Glib::ustring string_trim(const Glib::ustring& str, const Glib::ustring& to_remove);
+
+Glib::ustring string_remove_suffix(const Glib::ustring& str, const Glib::ustring& suffix, bool
case_sensitive = true);
+
+/** Create an appropriate title for an ID string.
+ * For instance, date_of_birth would become Date Of Birth.
+ */
+Glib::ustring title_from_string(const Glib::ustring& text);
+
+/** Get a decimal text representation of the number,
+ * in the current locale.
+ */
+Glib::ustring string_from_decimal(guint decimal);
+
+typedef std::vector<Glib::ustring> type_vec_strings;
+type_vec_strings string_separate(const Glib::ustring& str, const Glib::ustring& separator, bool
ignore_quoted_separator = false);
+
+} //namespace Utils
+
+} //namespace Glom
+
+#endif //GLOM_STRING_UTILS_H
diff --git a/glom/libglom/utils.cc b/glom/libglom/utils.cc
index 69a4760..4446ba6 100644
--- a/glom/libglom/utils.cc
+++ b/glom/libglom/utils.cc
@@ -26,6 +26,7 @@
#include <libglom/connectionpool.h>
#include <libglom/data_structure/layout/report_parts/layoutitem_fieldsummary.h>
#include <libglom/data_structure/glomconversions.h>
+#include <libglom/string_utils.h>
#include <giomm/file.h>
#include <giomm/resource.h>
@@ -74,122 +75,6 @@ auto find_if_uses_relationship_has_relationship(T_Container& container, const st
);
}
-Glib::ustring Utils::trim_whitespace(const Glib::ustring& text)
-{
- //TODO_Performance:
-
- Glib::ustring result = text;
-
- //Find non-whitespace from front:
- Glib::ustring::size_type posFront = Glib::ustring::npos;
- Glib::ustring::size_type pos = 0;
- for(const auto& item : result)
- {
- if(!Glib::Unicode::isspace(item))
- {
- posFront = pos;
- break;
- }
-
- ++pos;
- }
-
- //Remove the white space from the front:
- result = result.substr(posFront);
-
-
- //Find non-whitespace from back:
- Glib::ustring::size_type posBack = Glib::ustring::npos;
- pos = 0;
- for(auto iter = result.rbegin(); iter != result.rend(); ++iter)
- {
- if(!Glib::Unicode::isspace(*iter))
- {
- posBack = pos;
- break;
- }
-
- ++pos;
- }
-
- //Remove the white space from the front:
- result = result.substr(0, result.size() - posBack);
-
- return result;
-}
-
-Glib::ustring Utils::string_replace(const Glib::ustring& src, const Glib::ustring& search_for, const
Glib::ustring& replace_with)
-{
- if(search_for.empty())
- {
- std::cerr << G_STRFUNC << ": search_for was empty.\n";
- return src;
- }
-
- //std::cout << "debug: " << G_STRFUNC << ": src=" << src << ", search_for=" << search_for << ",
replace_with=" << replace_with << std::endl;
-
- std::string result = src;
-
- std::string::size_type pos = 0;
- const std::string::size_type len_search = search_for.size();
- const std::string::size_type len_replace = replace_with.size();
-
- std::string::size_type pos_after_prev = 0;
- while((pos = result.find(search_for, pos_after_prev)) != std::string::npos)
- {
- //std::cout << " debug: pos=" << pos << ", found=" << search_for << ", in string: " <<
result.substr(pos_after_prev, 20) << std::endl;
- //std::cout << " debug: before: result =" << result << ", pos_after_prev=pos_after_prev\n";
- result.replace(pos, len_search, replace_with);
- //std::cout << " after: before: result = result\n";
- pos_after_prev = pos + len_replace;
- }
-
- return result;
-
-/*
- //TODO_Performance:
-
- Glib::ustring result;
- const size_t src_length = src.size();
- const size_t search_for_length = search_for.size();
- //const size_t replace_with_length = replace_with.size();
-
- size_t src_index = 0;
- size_t src_index_section_start = 0;
- while(src_index < src_length)
- {
- const bool found = (src.find(search_for, src_index) == src_index);
- if(found)
- {
- result += src.substr(src_index_section_start, src_index - src_index_section_start);
- result += replace_with;
-
- src_index_section_start = src_index + search_for_length;
- src_index = src_index_section_start;
- }
- else
- ++src_index;
- }
-
- if(src_index_section_start < src_length)
- {
- result += src.substr(src_index_section_start);
- }
-
- return result;
-*/
-}
-
-Glib::ustring Utils::string_clean_for_xml(const Glib::ustring& src)
-{
- // The form feed character may not be in XML, even if escaped.
- // So lets just lose it.
- // Other unusual characters, such as &, are escaped by libxml later.
- // TODO_Performance: Find a quicker way to do this.
- return string_replace(src, "\f", Glib::ustring());
-}
-
-
Glib::RefPtr<Gnome::Gda::SqlBuilder> Utils::build_sql_select_with_where_clause(const Glib::ustring&
table_name, const type_vecLayoutFields& fieldsToGet, const Gnome::Gda::SqlExpr& where_clause, const
std::shared_ptr<const Relationship>& extra_join, const type_sort_clause& sort_clause, guint limit)
{
//TODO_Performance:
@@ -627,26 +512,6 @@ Utils::type_list_values_with_second Utils::get_choice_values(const std::shared_p
return result;
}
-Glib::ustring Utils::create_name_from_title(const Glib::ustring& title)
-{
- Glib::ustring result = string_replace(title, " ", "");
- return result.lowercase(); //TODO: Maybe they need to be ASCII (not UTF8)?
-}
-
-Glib::ustring Utils::string_escape_underscores(const Glib::ustring& text)
-{
- Glib::ustring result;
- for(const auto& item : text)
- {
- if(item == '_')
- result += "__";
- else
- result += item;
- }
-
- return result;
-}
-
/** Get just the first part of a locale, such as de_DE,
* ignoring, for instance, .UTF-8 or \ euro at the end.
*/
@@ -750,225 +615,6 @@ Glib::ustring Utils::create_local_image_uri(const Gnome::Gda::Value& value)
return ("file://" + result);
}
-Glib::ustring Utils::string_from_decimal(guint decimal)
-{
- //TODO_Performance:
-
- std::stringstream stream;
- stream.imbue(std::locale("")); //Use the user's current locale.
- stream << decimal;
-
- Glib::ustring result;
- stream >> result;
-
- return result;
-}
-
-Glib::ustring Utils::title_from_string(const Glib::ustring& text)
-{
- Glib::ustring result;
-
- bool capitalise_next_char = true;
- for(const auto& ch : text)
- {
- if(ch == '_') //Replace _ with space.
- {
- capitalise_next_char = true; //Capitalise all words.
- result += " ";
- }
- else
- {
- if(capitalise_next_char)
- result += Glib::Unicode::toupper(ch);
- else
- result += ch;
-
- capitalise_next_char = false;
- }
- }
-
- return result;
-}
-
-Utils::type_vec_strings Utils::string_separate(const Glib::ustring& str, const Glib::ustring& separator,
bool ignore_quoted_separator)
-{
- //std::cout << "debug: " << G_STRFUNC << ": separator=" << separator << std::endl;
-
- type_vec_strings result;
-
- const Glib::ustring::size_type size = str.size();
- const Glib::ustring::size_type size_separator = separator.size();
-
- //A stack of quotes, so that we can handle nested quotes, whether they are " or ':
- typedef std::stack<Glib::ustring> type_queue_quotes;
- type_queue_quotes m_current_quotes;
-
- Glib::ustring::size_type unprocessed_start = 0;
- Glib::ustring::size_type item_start = 0;
- while(unprocessed_start < size)
- {
- //std::cout << "while unprocessed: un_processed_start=" << unprocessed_start << std::endl;
- Glib::ustring::size_type posComma = str.find(separator, unprocessed_start);
-
- Glib::ustring item;
- if(posComma != Glib::ustring::npos)
- {
- //Check that the separator was not in quotes:
- bool in_quotes = false;
-
- if(ignore_quoted_separator)
- {
- //std::cout << " debug: attempting to ignore quoted separators: " << separator << std::endl;
-
- Glib::ustring::size_type posLastQuote = unprocessed_start;
-
- //std::cout << " debug: posLastQuote=" << posLastQuote << std::endl;
- //std::cout << " debug: posComma=" << posComma << std::endl;
-
-
- bool bContinue = true;
- while(bContinue && (posLastQuote < posComma))
- {
- //std::cout << " continue\n";
- Glib::ustring closing_quote;
- if(!m_current_quotes.empty())
- closing_quote = m_current_quotes.top();
-
- //std::cout << " posLastQuote=" << posLastQuote << std::endl;
- const Glib::ustring::size_type posSingleQuote = str.find("'", posLastQuote);
- const Glib::ustring::size_type posDoubleQuote = str.find("\"", posLastQuote);
-
- // std::cout << " posSingleQuote=" << posSingleQuote << "posDoubleQuote=" << posDoubleQuote <<
std::endl;
-
- //Which quote, if any, is first:
- Glib::ustring::size_type posFirstQuote = posSingleQuote;
- if( (posDoubleQuote != Glib::ustring::npos) && (posDoubleQuote < posFirstQuote) )
- posFirstQuote = posDoubleQuote;
-
- //Ignore quotes that are _after_ the separator:
- if( posFirstQuote >= posComma)
- posFirstQuote = Glib::ustring::npos;
-
- //std::cout << " posFirstQuote=" << posFirstQuote << std::endl;
-
- //If any quote character was found:
- if(posFirstQuote != Glib::ustring::npos)
- {
- //std::cout << "quote found: posFirstQuote=" << posFirstQuote << std::endl;
-
- //Which quote was it?
- const Glib::ustring first_quote = (posFirstQuote == posSingleQuote ? "'" : "\"");
- //std::cout << " first_quote=" << first_quote << std::endl;
-
- //Was it an expected closing quote, if we expected any:
- if(first_quote == closing_quote)
- {
- //std::cout << " popping quote\n";
- //Yes, so remove that quote from our stack, because we found the closing quote:
- m_current_quotes.pop();
- }
- else
- {
- //std::cout << " pushing quote\n";
- //This must be an opening quote, so remember it:
- m_current_quotes.push(first_quote);
- }
-
- posLastQuote = posFirstQuote + 1; //Do the next find after the quote.
- }
- else
- {
- //There were no quotes, or no closing quotes:
- bContinue = false;
- }
- } //while(bContinue)
-
- //If there were any unclosed quotes then this separator must have been in quotes:
- if(!m_current_quotes.empty())
- in_quotes = true;
- } //If ignore_quoted_separator
-
- if(!in_quotes) //or if we don't care about quotes.
- {
- //std::cout << "!in_quotes\n";
-
- //Store this item, and start the next item after it:
- item = str.substr(item_start, posComma - item_start);
- //std::cout << " ITEM. pos_comma=" << posComma << ", ITEM= " << item << std::endl;
- item_start = posComma + size_separator;
- }
- else
- {
- //std::cout << "in quotes.\n";
- // Continue behind separator
- unprocessed_start = posComma + size_separator;
- // Do not add this item to the result, because it was quoted.
- continue;
- }
-
- unprocessed_start = posComma + size_separator; //The while loops stops when this is empty.
- }
- else //if no separator found:
- {
- item = str.substr(item_start);
- unprocessed_start = size; //Stop.
- }
-
- item = string_trim(item, " ");
- result.emplace_back(item);
- } //while
-
- return result;
-}
-
-Glib::ustring Utils::string_trim(const Glib::ustring& str, const Glib::ustring& to_remove)
-{
- Glib::ustring result = str;
-
- //Remove from the start:
- Glib::ustring::size_type posOpenBracket = result.find(to_remove);
- if(posOpenBracket == 0)
- {
- result = result.substr(to_remove.size());
- }
-
- //Remove from the end:
- Glib::ustring::size_type posCloseBracket = result.rfind(to_remove);
- if(posCloseBracket == (result.size() - to_remove.size()))
- {
- result = result.substr(0, posCloseBracket);
- }
-
- return result;
-}
-
-Glib::ustring Utils::string_remove_suffix(const Glib::ustring& str, const Glib::ustring& suffix, bool
case_sensitive)
-{
- //There is also g_string_has_suffix(), but I assume that is case sensitive. murrayc.
-
- const Glib::ustring::size_type size = str.size();
- const Glib::ustring::size_type suffix_size = suffix.size();
- if(size < suffix_size)
- return str;
-
- const Glib::ustring possible_suffix = str.substr(size - suffix_size);
-
- if(case_sensitive)
- {
- if(possible_suffix == suffix)
- return str.substr(0, size - suffix_size);
- }
- else
- {
- if(g_ascii_strcasecmp(possible_suffix.c_str(), suffix.c_str()) == 0) //TODO: I don't understand the
warnings about using this function in the glib documentation. murrayc.
- return str.substr(0, size - suffix_size);
- }
-
- return str;
-}
-
-
-
bool Utils::file_exists(const Glib::ustring& uri)
{
if(uri.empty())
diff --git a/glom/libglom/utils.h b/glom/libglom/utils.h
index fe35caa..8e97020 100644
--- a/glom/libglom/utils.h
+++ b/glom/libglom/utils.h
@@ -40,14 +40,6 @@ typedef std::vector<type_pair_sort_field> type_sort_clause;
namespace Utils
{
-Glib::ustring trim_whitespace(const Glib::ustring& text);
-
-Glib::ustring string_replace(const Glib::ustring& src, const Glib::ustring& search_for, const Glib::ustring&
replace_with);
-
-/** Remove any characters that may not be in XML even when escaped.
- */
-Glib::ustring string_clean_for_xml(const Glib::ustring& src);
-
//typedef Base_DB::type_vecLayoutFields type_vecLayoutFields;
typedef std::vector< std::shared_ptr<LayoutItem_Field> > type_vecLayoutFields;
typedef std::vector< std::shared_ptr<const LayoutItem_Field> > type_vecConstLayoutFields;
@@ -144,12 +136,6 @@ type_list_values_with_second get_choice_values(const std::shared_ptr<const Docum
std::string sqlbuilder_get_full_query(
const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& builder);
-/** Guess an appropriate identifier name based on a human-readable title
- */
-Glib::ustring create_name_from_title(const Glib::ustring& title);
-
-Glib::ustring string_escape_underscores(const Glib::ustring& text);
-
/** Get just the first part of a locale, such as de_DE,
* ignoring, for instance, .UTF-8 or \ euro at the end.
*/
@@ -161,23 +147,6 @@ Glib::ustring locale_language_id(const Glib::ustring& locale_id);
Glib::ustring create_local_image_uri(const Gnome::Gda::Value& value);
-/** Get a decimal text representation of the number,
- * in the current locale.
- */
-Glib::ustring string_from_decimal(guint decimal);
-
-/** Create an appropriate title for an ID string.
- * For instance, date_of_birth would become Date Of Birth.
- */
-Glib::ustring title_from_string(const Glib::ustring& text);
-
-typedef std::vector<Glib::ustring> type_vec_strings;
-type_vec_strings string_separate(const Glib::ustring& str, const Glib::ustring& separator, bool
ignore_quoted_separator = false);
-
-Glib::ustring string_trim(const Glib::ustring& str, const Glib::ustring& to_remove);
-
-Glib::ustring string_remove_suffix(const Glib::ustring& str, const Glib::ustring& suffix, bool
case_sensitive = true);
-
bool file_exists(const Glib::ustring& uri);
bool file_exists(const Glib::RefPtr<Gio::File>& file);
diff --git a/glom/libglom/xml_utils.cc b/glom/libglom/xml_utils.cc
index f5ddab6..ff04619 100644
--- a/glom/libglom/xml_utils.cc
+++ b/glom/libglom/xml_utils.cc
@@ -20,6 +20,7 @@
#include <libglom/xml_utils.h>
#include <libglom/utils.h>
+#include <libglom/string_utils.h>
#include <limits> // for numeric_limits
static const char GLOM_ATTRIBUTE_IMAGE_DATA_FORMAT[] = "format";
diff --git a/glom/mode_data/db_adddel/db_adddel.cc b/glom/mode_data/db_adddel/db_adddel.cc
index 9bbd113..40163c8 100644
--- a/glom/mode_data/db_adddel/db_adddel.cc
+++ b/glom/mode_data/db_adddel/db_adddel.cc
@@ -27,6 +27,7 @@
#include "db_treeviewcolumn_glom.h"
#include <libglom/data_structure/glomconversions.h>
#include <libglom/utils.h>
+#include <libglom/string_utils.h>
#include <glom/dialog_invalid_data.h>
#include <glom/appwindow.h>
#include <glom/utils_ui.h> //For UiUtils::image_scale_keeping_ratio().
diff --git a/glom/mode_design/box_db_table_relationships.cc b/glom/mode_design/box_db_table_relationships.cc
index 7340aa7..900d1cd 100644
--- a/glom/mode_design/box_db_table_relationships.cc
+++ b/glom/mode_design/box_db_table_relationships.cc
@@ -23,6 +23,7 @@
#include <glom/appwindow.h>
#include <libglom/db_utils.h>
#include <libglom/utils.h>
+#include <libglom/string_utils.h>
#include <algorithm>
#include <glibmm/i18n.h>
diff --git a/glom/mode_design/dialog_add_related_table.cc b/glom/mode_design/dialog_add_related_table.cc
index 6455145..2462240 100644
--- a/glom/mode_design/dialog_add_related_table.cc
+++ b/glom/mode_design/dialog_add_related_table.cc
@@ -22,6 +22,7 @@
#include <glom/frame_glom.h> //For show_ok_dialog.h
#include <libglom/db_utils.h>
#include <libglom/utils.h>
+#include <libglom/string_utils.h>
#include <glibmm/i18n.h>
namespace Glom
diff --git a/glom/mode_design/fields/box_db_table_definition.cc
b/glom/mode_design/fields/box_db_table_definition.cc
index 8eb62df..2c36519 100644
--- a/glom/mode_design/fields/box_db_table_definition.cc
+++ b/glom/mode_design/fields/box_db_table_definition.cc
@@ -26,6 +26,7 @@
#include <libglom/libglom_config.h>
#include <libglom/db_utils.h>
#include <libglom/utils.h>
+#include <libglom/string_utils.h>
#include <glibmm/i18n.h>
namespace Glom
diff --git a/glom/mode_design/layout/dialog_layout_details.cc
b/glom/mode_design/layout/dialog_layout_details.cc
index db6c035..6ee034b 100644
--- a/glom/mode_design/layout/dialog_layout_details.cc
+++ b/glom/mode_design/layout/dialog_layout_details.cc
@@ -26,6 +26,7 @@
//#include <libgnome/gnome-i18n.h>
#include <glom/utils_ui.h> //For bold_message()).
#include <libglom/utils.h>
+#include <libglom/string_utils.h>
#include <glom/appwindow.h>
#include <glibmm/i18n.h>
#include <sstream> //For stringstream
diff --git a/glom/mode_design/print_layouts/box_print_layouts.cc
b/glom/mode_design/print_layouts/box_print_layouts.cc
index 9476d21..92b1814 100644
--- a/glom/mode_design/print_layouts/box_print_layouts.cc
+++ b/glom/mode_design/print_layouts/box_print_layouts.cc
@@ -24,6 +24,7 @@
#include <gtkmm/messagedialog.h>
#include <libglom/algorithms_utils.h>
#include <libglom/utils.h> //For bold_message()).
+#include <libglom/string_utils.h>
#include <glibmm/i18n.h>
#include <iostream>
diff --git a/glom/utility_widgets/adddel/adddel.cc b/glom/utility_widgets/adddel/adddel.cc
index 30f5cf1..6e1df60 100644
--- a/glom/utility_widgets/adddel/adddel.cc
+++ b/glom/utility_widgets/adddel/adddel.cc
@@ -29,6 +29,7 @@
#include <glom/dialog_invalid_data.h>
#include <glom/utils_ui.h>
#include <libglom/utils.h>
+#include <libglom/string_utils.h>
#include <gtkmm/builder.h>
#include <giomm/menu.h>
//#include <glom/bakery/app_gtk.h>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]