[glade] GladeProjectProperties: added license page. Now it is posible to change license type and glade will



commit 325d7ebbfde0921bb6e2107e51d1aa85c4fa2fe5
Author: Juan Pablo Ugarte <juanpablougarte gmail com>
Date:   Tue Dec 17 23:46:26 2013 -0300

    GladeProjectProperties: added license page.
    Now it is posible to change license type and glade will automatically
    generate it for you if you supply copyright and authors
    
    GladeProject: save license data as comments.
    Make sure comments do not contain "--"
    
    glade-utils.c: added  _glade_util_strreplace() private function.

 gladeui/glade-private.h             |   27 ++
 gladeui/glade-project-properties.c  |  581 +++++++++++++++++-------------
 gladeui/glade-project-properties.ui |  686 ++++++++++++++++++++++-------------
 gladeui/glade-project.c             |  273 +++++++++-----
 gladeui/glade-utils.c               |   31 ++
 5 files changed, 1005 insertions(+), 593 deletions(-)
---
diff --git a/gladeui/glade-private.h b/gladeui/glade-private.h
index 0de48b2..ef27ca4 100644
--- a/gladeui/glade-private.h
+++ b/gladeui/glade-private.h
@@ -28,6 +28,8 @@
 #ifndef __GLADE_PRIVATE_H__
 #define __GLADE_PRIVATE_H__
 
+#include "glade-project-properties.h"
+
 G_BEGIN_DECLS
 
 /* glade-catalog.c */
@@ -35,6 +37,31 @@ G_BEGIN_DECLS
 GladeCatalog *_glade_catalog_get_catalog (const gchar *name);
 GList        *_glade_catalog_tsort       (GList *catalogs);
 
+
+/* glade-project-properties.c */
+void
+_glade_project_properties_set_license_data (GladeProjectProperties *props,
+                                            const gchar *license,
+                                            const gchar *name,
+                                            const gchar *description,
+                                            const gchar *copyright,
+                                            const gchar *authors);
+void
+_glade_project_properties_get_license_data (GladeProjectProperties *props,
+                                            gchar **license,
+                                            gchar **name,
+                                            gchar **description,
+                                            gchar **copyright,
+                                            gchar **authors);
+
+/* glade-utils.c */
+
+gchar *
+_glade_util_strreplace (gchar *str,
+                        gboolean free_str,
+                        const gchar *key,
+                        const gchar *replacement);
+
 /* glade-xml-utils.c */
 
 /* GladeXml Error handling */
diff --git a/gladeui/glade-project-properties.c b/gladeui/glade-project-properties.c
index fd71ff6..85213e2 100644
--- a/gladeui/glade-project-properties.c
+++ b/gladeui/glade-project-properties.c
@@ -27,6 +27,7 @@
 #include "glade-command.h"
 #include "glade-app.h"
 #include "glade-utils.h"
+#include "glade-private.h"
 
 /* GObjectClass */
 static void     glade_project_properties_finalize     (GObject                *object);
@@ -61,15 +62,17 @@ static void     on_domain_entry_changed               (GtkWidget              *e
                                                       GladeProjectProperties *properties);
 static void     target_button_clicked                 (GtkWidget              *widget,
                                                       GladeProjectProperties *properties);
-static void     on_license_textview_populate_popup    (GtkTextView            *text_view,
-                                                       GtkWidget              *popup,
-                                                       GladeProjectProperties *properties);
 static void     on_glade_project_properties_hide      (GtkWidget              *widget,
                                                        GladeProjectProperties *properties);
 static void     on_css_filechooser_file_set           (GtkFileChooserButton   *widget,
                                                        GladeProjectProperties *properties);
 static void     on_css_checkbutton_toggled            (GtkWidget              *widget,
                                                        GladeProjectProperties *properties);
+static void     on_license_comboboxtext_changed       (GtkComboBox *widget,
+                                                       GladeProjectProperties *properties);
+
+static void     on_license_data_changed               (GladeProjectProperties *properties);
+
 /* Project callbacks */
 static void     project_resource_path_changed         (GladeProject           *project,
                                                       GParamSpec             *pspec,
@@ -93,6 +96,7 @@ struct _GladeProjectPropertiesPrivate
 {
   GladeProject *project;
 
+  /* Properties */
   GtkWidget *project_wide_radio;
   GtkWidget *toplevel_contextual_radio;
   GtkWidget *toolkit_box;
@@ -105,12 +109,21 @@ struct _GladeProjectPropertiesPrivate
   GtkWidget *domain_entry;
   GtkWidget *template_combobox;
   GtkWidget *template_checkbutton;
-  GtkTextBuffer *license_textbuffer;
 
   GtkWidget *css_filechooser;
   GtkWidget *css_checkbutton;
   
   GHashTable *target_radios;
+
+  /* License */
+  GtkComboBox    *license_comboboxtext;
+  GtkTextView    *license_textview;
+  GtkEntryBuffer *name_entrybuffer;
+  GtkEntryBuffer *description_entrybuffer;
+  GtkTextBuffer  *authors_textbuffer;
+  GtkTextBuffer  *copyright_textbuffer;
+  GtkTextBuffer  *license_textbuffer;
+  
   gboolean ignore_ui_cb;
 };
 
@@ -172,10 +185,18 @@ glade_project_properties_class_init (GladeProjectPropertiesClass *klass)
   gtk_widget_class_bind_template_child_private (widget_class, GladeProjectProperties, template_checkbutton);
   gtk_widget_class_bind_template_child_private (widget_class, GladeProjectProperties, template_combobox);
   gtk_widget_class_bind_template_child_private (widget_class, GladeProjectProperties, toolkit_box);
-  gtk_widget_class_bind_template_child_private (widget_class, GladeProjectProperties, license_textbuffer);
   gtk_widget_class_bind_template_child_private (widget_class, GladeProjectProperties, css_filechooser);
   gtk_widget_class_bind_template_child_private (widget_class, GladeProjectProperties, css_checkbutton);
 
+  gtk_widget_class_bind_template_child_private (widget_class, GladeProjectProperties, license_comboboxtext);
+  gtk_widget_class_bind_template_child_private (widget_class, GladeProjectProperties, license_textview);
+  gtk_widget_class_bind_template_child_private (widget_class, GladeProjectProperties, name_entrybuffer);
+  gtk_widget_class_bind_template_child_private (widget_class, GladeProjectProperties, 
description_entrybuffer);
+  gtk_widget_class_bind_template_child_private (widget_class, GladeProjectProperties, authors_textbuffer);
+  gtk_widget_class_bind_template_child_private (widget_class, GladeProjectProperties, copyright_textbuffer);
+  gtk_widget_class_bind_template_child_private (widget_class, GladeProjectProperties, license_textbuffer);
+
+  
   /* Declare the callback ports that this widget class exposes, to bind with <signal>
    * connections defined in the GtkBuilder xml
    */
@@ -189,10 +210,11 @@ glade_project_properties_class_init (GladeProjectPropertiesClass *klass)
   gtk_widget_class_bind_template_callback (widget_class, on_domain_entry_changed);
   gtk_widget_class_bind_template_callback (widget_class, on_relative_path_entry_insert_text);
   gtk_widget_class_bind_template_callback (widget_class, on_relative_path_entry_changed);
-  gtk_widget_class_bind_template_callback (widget_class, on_license_textview_populate_popup);
   gtk_widget_class_bind_template_callback (widget_class, on_glade_project_properties_hide);  
   gtk_widget_class_bind_template_callback (widget_class, on_css_filechooser_file_set);
   gtk_widget_class_bind_template_callback (widget_class, on_css_checkbutton_toggled);
+  gtk_widget_class_bind_template_callback (widget_class, on_license_comboboxtext_changed);
+  gtk_widget_class_bind_template_callback (widget_class, on_license_data_changed);
 }
 
 /********************************************************
@@ -612,271 +634,283 @@ on_domain_entry_changed (GtkWidget *entry, GladeProjectProperties *properties)
   glade_command_set_project_domain (priv->project, gtk_entry_get_text (GTK_ENTRY (entry)));
 }
 
-static void
-on_gplv2_activate (GtkMenuItem *menuitem, GladeProjectProperties *properties)
-{
-  gtk_text_buffer_insert_at_cursor (properties->priv->license_textbuffer,
-    "one line to give the program's name and an idea of what it does.\n"
-    "Copyright (C) yyyy  name of author\n"
-    "\n"
-    "This program is free software; you can redistribute it and/or\n"
-    "modify it under the terms of the GNU General Public License\n"
-    "as published by the Free Software Foundation; either version 2\n"
-    "of the License, or (at your option) any later version.\n"
-    "\n"
-    "This program is distributed in the hope that it will be useful,\n"
-    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
-    "GNU General Public License for more details.\n"
-    "\n"
-    "You should have received a copy of the GNU General Public License\n"
-    "along with this program; if not, write to the Free Software\n"
-    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.",
-                                    -1);
-}
+#define GNU_GPLv2_TEXT \
+    "$(name) - $(description)\n" \
+    "Copyright (C) $(copyright)\n" \
+    "\n" \
+    "This program is free software; you can redistribute it and/or\n" \
+    "modify it under the terms of the GNU General Public License\n" \
+    "as published by the Free Software Foundation; either version 2\n" \
+    "of the License, or (at your option) any later version.\n" \
+    "\n" \
+    "This program is distributed in the hope that it will be useful,\n" \
+    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \
+    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n" \
+    "GNU General Public License for more details.\n" \
+    "\n" \
+    "You should have received a copy of the GNU General Public License\n" \
+    "along with this program; if not, write to the Free Software\n" \
+    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\n"
+
+#define GNU_LGPLv2_TEXT \
+    "$(name) - $(description)\n" \
+    "Copyright (C) $(copyright)\n" \
+    "\n" \
+    "This library is free software; you can redistribute it and/or\n" \
+    "modify it under the terms of the GNU Lesser General Public\n" \
+    "License as published by the Free Software Foundation; either\n" \
+    "version 2.1 of the License, or (at your option) any later version.\n" \
+    "\n" \
+    "This library is distributed in the hope that it will be useful,\n" \
+    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \
+    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n" \
+    "Lesser General Public License for more details.\n" \
+    "\n" \
+    "You should have received a copy of the GNU Lesser General Public\n" \
+    "License along with this library; if not, write to the Free Software\n" \
+    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n"
+
+#define GNU_GPLv3_TEXT \
+    "Copyright (C) $(copyright)\n" \
+    "\n" \
+    "This file is part of $(name).\n" \
+    "\n" \
+    "$(name) is free software: you can redistribute it and/or modify\n" \
+    "it under the terms of the GNU General Public License as published by\n" \
+    "the Free Software Foundation, either version 3 of the License, or\n" \
+    "(at your option) any later version.\n" \
+    "\n" \
+    "$(name) is distributed in the hope that it will be useful,\n" \
+    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \
+    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n" \
+    "GNU General Public License for more details.\n" \
+    "\n" \
+    "You should have received a copy of the GNU General Public License\n" \
+    "along with $(name).  If not, see <http://www.gnu.org/licenses/>.\n"
+
+#define GNU_LGPLv3_TEXT \
+    "Copyright (C) $(copyright)\n" \
+    "\n" \
+    "This file is part of $(name).\n" \
+    "\n" \
+    "$(name) is free software: you can redistribute it and/or modify\n" \
+    "it under the terms of the GNU Lesser General Public License as published by\n" \
+    "the Free Software Foundation, either version 3 of the License, or\n" \
+    "(at your option) any later version.\n" \
+    "\n" \
+    "$(name) is distributed in the hope that it will be useful,\n" \
+    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \
+    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n" \
+    "GNU Lesser General Public License for more details.\n" \
+    "\n" \
+    "You should have received a copy of the GNU Lesser General Public License\n" \
+    "along with $(name).  If not, see <http://www.gnu.org/licenses/>.\n"
+
+#define BSD3c_TEXT \
+    "Copyright (c) $(copyright)\n" \
+    "All rights reserved.\n" \
+    "\n" \
+    "Redistribution and use in source and binary forms, with or without\n" \
+    "modification, are permitted provided that the following conditions are met:\n" \
+    "    * Redistributions of source code must retain the above copyright\n" \
+    "      notice, this list of conditions and the following disclaimer.\n" \
+    "    * Redistributions in binary form must reproduce the above copyright\n" \
+    "      notice, this list of conditions and the following disclaimer in the\n" \
+    "      documentation and/or other materials provided with the distribution.\n" \
+    "    * Neither the name of the <organization> nor the\n" \
+    "      names of its contributors may be used to endorse or promote products\n" \
+    "      derived from this software without specific prior written permission.\n" \
+    "\n" \
+    "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n" \
+    "ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n" \
+    "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n" \
+    "DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\n" \
+    "DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n" \
+    "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n" \
+    "LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n" \
+    "ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" \
+    "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n" \
+    "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
 
-static void
-on_lgplv2_activate (GtkMenuItem *menuitem, GladeProjectProperties *properties)
-{
-  gtk_text_buffer_insert_at_cursor (properties->priv->license_textbuffer,
-    "one line to give the library's name and an idea of what it does.\n"
-    "Copyright (C) year  name of author\n"
-    "\n"
-    "This library is free software; you can redistribute it and/or\n"
-    "modify it under the terms of the GNU Lesser General Public\n"
-    "License as published by the Free Software Foundation; either\n"
-    "version 2.1 of the License, or (at your option) any later version.\n"
-    "\n"
-    "This library is distributed in the hope that it will be useful,\n"
-    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
-    "Lesser General Public License for more details.\n"
-    "\n"
-    "You should have received a copy of the GNU Lesser General Public\n"
-    "License along with this library; if not, write to the Free Software\n"
-    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA", -1);
-}
+#define BSD2c_TEXT \
+    "Copyright (c) $(copyright)\n" \
+    "All rights reserved.\n" \
+    "\n" \
+    "Redistribution and use in source and binary forms, with or without\n" \
+    "modification, are permitted provided that the following conditions are met:\n" \
+    "\n" \
+    "1. Redistributions of source code must retain the above copyright notice, this\n" \
+    "   list of conditions and the following disclaimer. \n" \
+    "2. Redistributions in binary form must reproduce the above copyright notice,\n" \
+    "   this list of conditions and the following disclaimer in the documentation\n" \
+    "   and/or other materials provided with the distribution. \n" \
+    "\n" \
+    "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n" \
+    "ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n" \
+    "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n" \
+    "DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\n" \
+    "ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n" \
+    "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n" \
+    "LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n" \
+    "ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" \
+    "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n" \
+    "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
 
-static void
-on_gplv3_activate (GtkMenuItem *menuitem, GladeProjectProperties *properties)
+#define APACHE2_TEXT \
+    "Copyright $(copyright)\n" \
+    "\n" \
+    "Licensed under the Apache License, Version 2.0 (the \"License\"); \n" \
+    "you may not use this file except in compliance with the License. \n" \
+    "You may obtain a copy of the License at \n" \
+    "\n" \
+    "    http://www.apache.org/licenses/LICENSE-2.0 \n" \
+    "\n" \
+    "Unless required by applicable law or agreed to in writing, software \n" \
+    "distributed under the License is distributed on an \"AS IS\" BASIS, \n" \
+    "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n" \
+    "See the License for the specific language governing permissions and \n" \
+    "limitations under the License. \n"
+
+#define GNU_ALL_PERMISSIVE_TEXT \
+    "Copyright (C) $(copyright)\n" \
+    "\n" \
+    "Copying and distribution of this file, with or without modification,\n" \
+    "are permitted in any medium without royalty provided the copyright\n" \
+    "notice and this notice are preserved.  This file is offered as-is,\n" \
+    "without any warranty.\n"
+
+#define MIT_TEXT \
+    "The MIT License (MIT)\n" \
+    "\n" \
+    "Copyright (c) $(copyright)\n" \
+    "\n" \
+    "Permission is hereby granted, free of charge, to any person obtaining a copy\n" \
+    "of this software and associated documentation files (the \"Software\"), to deal\n" \
+    "in the Software without restriction, including without limitation the rights\n" \
+    "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n" \
+    "copies of the Software, and to permit persons to whom the Software is\n" \
+    "furnished to do so, subject to the following conditions:\n" \
+    "\n" \
+    "The above copyright notice and this permission notice shall be included in\n" \
+    "all copies or substantial portions of the Software.\n" \
+    "\n" \
+    "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n" \
+    "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n" \
+    "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n" \
+    "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n" \
+    "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n" \
+    "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n" \
+    "THE SOFTWARE.\n"
+
+static gchar *
+gpp_get_license_from_id (const gchar *id)
 {
-  gtk_text_buffer_insert_at_cursor (properties->priv->license_textbuffer,
-    "Copyright (C) yyyy  name of author\n"
-    "\n"
-    "This file is part of Foobar.\n"
-    "\n"
-    "Foobar is free software: you can redistribute it and/or modify\n"
-    "it under the terms of the GNU General Public License as published by\n"
-    "the Free Software Foundation, either version 3 of the License, or\n"
-    "(at your option) any later version.\n"
-    "\n"
-    "Foobar is distributed in the hope that it will be useful,\n"
-    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
-    "GNU General Public License for more details.\n"
-    "\n"
-    "You should have received a copy of the GNU General Public License\n"
-    "along with Foobar.  If not, see <http://www.gnu.org/licenses/>.", -1);
+  if (!g_strcmp0 (id, "gplv2"))
+    return GNU_GPLv2_TEXT;
+  else if (!g_strcmp0 (id, "gplv3"))
+    return GNU_GPLv3_TEXT;
+  else if (!g_strcmp0 (id, "lgplv2"))
+    return GNU_LGPLv2_TEXT;
+  else if (!g_strcmp0 (id, "lgplv3"))
+    return GNU_LGPLv3_TEXT;
+  else if (!g_strcmp0 (id, "bsd2c"))
+    return BSD2c_TEXT;
+  else if (!g_strcmp0 (id, "bsd3c"))
+    return BSD3c_TEXT;
+  else if (!g_strcmp0 (id, "apache2"))
+    return APACHE2_TEXT;
+  else if (!g_strcmp0 (id, "mit"))
+    return MIT_TEXT;
+  else if (!g_strcmp0 (id, "all_permissive"))
+    return GNU_ALL_PERMISSIVE_TEXT;
+  else
+    return NULL;
 }
 
-static void
-on_lgplv3_activate (GtkMenuItem *menuitem, GladeProjectProperties *properties)
+static gint
+string_count_new_lines (const gchar *str)
 {
-  gtk_text_buffer_insert_at_cursor (properties->priv->license_textbuffer,
-    "Copyright (C) yyyy  name of author\n"
-    "\n"
-    "This file is part of Foobar.\n"
-    "\n"
-    "Foobar is free software: you can redistribute it and/or modify\n"
-    "it under the terms of the GNU Lesser General Public License as published by\n"
-    "the Free Software Foundation, either version 3 of the License, or\n"
-    "(at your option) any later version.\n"
-    "\n"
-    "Foobar is distributed in the hope that it will be useful,\n"
-    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
-    "GNU Lesser General Public License for more details.\n"
-    "\n"
-    "You should have received a copy of the GNU Lesser General Public License\n"
-    "along with Foobar.  If not, see <http://www.gnu.org/licenses/>.", -1);
-}
+  gint c = 0;
 
-static void
-on_bsd3c_activate (GtkMenuItem *menuitem, GladeProjectProperties *properties)
-{
-  gtk_text_buffer_insert_at_cursor (properties->priv->license_textbuffer,
-    "Copyright (c) <year>, <copyright holder>\n"
-    "All rights reserved.\n"
-    "\n"
-    "Redistribution and use in source and binary forms, with or without\n"
-    "modification, are permitted provided that the following conditions are met:\n"
-    "    * Redistributions of source code must retain the above copyright\n"
-    "      notice, this list of conditions and the following disclaimer.\n"
-    "    * Redistributions in binary form must reproduce the above copyright\n"
-    "      notice, this list of conditions and the following disclaimer in the\n"
-    "      documentation and/or other materials provided with the distribution.\n"
-    "    * Neither the name of the <organization> nor the\n"
-    "      names of its contributors may be used to endorse or promote products\n"
-    "      derived from this software without specific prior written permission.\n"
-    "\n"
-    "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n"
-    "ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n"
-    "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n"
-    "DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\n"
-    "DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n"
-    "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n"
-    "LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n"
-    "ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
-    "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n"
-    "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.", -1);
+  while (*str)
+    {
+      if (*str == '\n')
+        c++;
+      str = g_utf8_next_char (str);
+    }
+  return c;
 }
 
 static void
-on_bsd2c_activate (GtkMenuItem *menuitem, GladeProjectProperties *properties)
+gpp_update_license (GladeProjectProperties *properties, gchar *license)
 {
-  gtk_text_buffer_insert_at_cursor (properties->priv->license_textbuffer,
-    "Copyright (c) <YEAR>, <OWNER>\n"
-    "All rights reserved.\n"
-    "\n"
-    "Redistribution and use in source and binary forms, with or without\n"
-    "modification, are permitted provided that the following conditions are met:\n" 
-    "\n"
-    "1. Redistributions of source code must retain the above copyright notice, this\n"
-    "   list of conditions and the following disclaimer. \n"
-    "2. Redistributions in binary form must reproduce the above copyright notice,\n"
-    "   this list of conditions and the following disclaimer in the documentation\n"
-    "   and/or other materials provided with the distribution. \n"
-    "\n"
-    "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n"
-    "ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n"
-    "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n"
-    "DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\n"
-    "ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n"
-    "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n"
-    "LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n"
-    "ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
-    "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n"
-    "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
-    "\n"
-    "The views and conclusions contained in the software and documentation are those\n"
-    "of the authors and should not be interpreted as representing official policies, \n"
-    "either expressed or implied, of the FreeBSD Project.", -1);
-}
+  GladeProjectPropertiesPrivate *priv = properties->priv;
+  const gchar *name, *description;
+  gchar *copyright, *authors;
 
-static void
-on_apache2_activate (GtkMenuItem *menuitem, GladeProjectProperties *properties)
-{
-  gtk_text_buffer_insert_at_cursor (properties->priv->license_textbuffer,
-    "Copyright [yyyy] [name of copyright owner] \n"
-    "\n"
-    "Licensed under the Apache License, Version 2.0 (the \"License\"); \n"
-    "you may not use this file except in compliance with the License. \n"
-    "You may obtain a copy of the License at \n"
-    "\n"
-    "    http://www.apache.org/licenses/LICENSE-2.0 \n"
-    "\n"
-    "Unless required by applicable law or agreed to in writing, software \n"
-    "distributed under the License is distributed on an \"AS IS\" BASIS, \n"
-    "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n"
-    "See the License for the specific language governing permissions and \n"
-    "limitations under the License. \n", -1);
-}
+  if (!license)
+    return;
 
-static void
-on_all_permissive_activate (GtkMenuItem *menuitem, GladeProjectProperties *properties)
-{
-  gtk_text_buffer_insert_at_cursor (properties->priv->license_textbuffer,
-    "Copyright (C) yyyy  name of author\n"
-    "\n"
-    "Copying and distribution of this file, with or without modification,\n"
-    "are permitted in any medium without royalty provided the copyright\n"
-    "notice and this notice are preserved.  This file is offered as-is,\n"
-    "without any warranty.\n", -1);
-}
-static void
-on_mit_activate (GtkMenuItem *menuitem, GladeProjectProperties *properties)
-{
-  gtk_text_buffer_insert_at_cursor (properties->priv->license_textbuffer,
-    "The MIT License (MIT)\n"
-    "\n"
-    "Copyright (c) <year> <copyright holders>\n"
-    "\n"
-    "Permission is hereby granted, free of charge, to any person obtaining a copy\n"
-    "of this software and associated documentation files (the \"Software\"), to deal\n"
-    "in the Software without restriction, including without limitation the rights\n"
-    "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n"
-    "copies of the Software, and to permit persons to whom the Software is\n"
-    "furnished to do so, subject to the following conditions:\n"
-    "\n"
-    "The above copyright notice and this permission notice shall be included in\n"
-    "all copies or substantial portions of the Software.\n"
-    "\n"
-    "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n"
-    "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n"
-    "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n"
-    "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n"
-    "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n"
-    "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n"
-    "THE SOFTWARE.\n", -1);
-}
+  /* get data */
+  name = gtk_entry_buffer_get_text (priv->name_entrybuffer);
+  description = gtk_entry_buffer_get_text (priv->description_entrybuffer);
+  
+  g_object_get (priv->copyright_textbuffer, "text", &copyright, NULL);
+  g_object_get (priv->authors_textbuffer, "text", &authors, NULL);
+  
+  /* Now we can replace strings in the license template */
+  license = _glade_util_strreplace (license, FALSE, "$(name)", name);
+  license = _glade_util_strreplace (license, TRUE, "$(description)", description);
+  license = _glade_util_strreplace (license, TRUE, "$(copyright)", copyright);
 
-static void
-on_clear_text_activate (GtkMenuItem *menuitem, GladeProjectProperties *properties)
-{
-  gtk_text_buffer_set_text (properties->priv->license_textbuffer, "", -1);
+  if (authors && *authors)
+    {
+      gchar *tmp = license;
+
+      if (string_count_new_lines (authors))
+        license = g_strconcat (license, "\n", "Authors:", "\n", authors, NULL);
+      else
+        license = g_strconcat (license, "\n", "Author:", " ", authors, NULL);
+
+      g_free (tmp);
+    }
+  
+  gtk_text_buffer_set_text (priv->license_textbuffer, license, -1);
+
+  g_free (license);
+  g_free (copyright);
+  g_free (authors);
 }
 
 static void
-gpp_append_new_item (GladeProjectProperties *properties,
-                     GtkWidget              *popup,
-                     const gchar            *label,
-                     GCallback               activate_cb)
+on_license_data_changed (GladeProjectProperties *properties)
 {
-  GtkWidget *item;
-
-  if (label)
-    item = gtk_menu_item_new_with_label (label);
-  else
-    item = gtk_separator_menu_item_new ();
-
-  if (activate_cb)
-    g_signal_connect (item, "activate", activate_cb, properties);
+  const gchar *id = gtk_combo_box_get_active_id (properties->priv->license_comboboxtext);
+  gchar *license;
 
-  gtk_menu_shell_append (GTK_MENU_SHELL (popup), item);
-  gtk_widget_show (item);
+  if ((license = gpp_get_license_from_id (id)))
+    gpp_update_license (properties, license);
 }
 
 static void
-on_license_textview_populate_popup (GtkTextView            *text_view,
-                                    GtkWidget              *popup,
-                                    GladeProjectProperties *properties)
+on_license_comboboxtext_changed (GtkComboBox            *widget,
+                                 GladeProjectProperties *properties)
 {
-  if (!GTK_IS_MENU (popup))
-    return;
+  GladeProjectPropertiesPrivate *priv = properties->priv;
+  gchar *license;
 
-  gpp_append_new_item (properties, popup, _("Clear text"),
-                       G_CALLBACK (on_clear_text_activate));
-  
-  gpp_append_new_item (properties, popup, NULL, NULL);
-  
-  gpp_append_new_item (properties, popup, _("Insert GPL v2"),
-                       G_CALLBACK (on_gplv2_activate));
-  gpp_append_new_item (properties, popup, _("Insert GPL v3"),
-                       G_CALLBACK (on_gplv3_activate));
-  gpp_append_new_item (properties, popup, _("Insert LGPL v2.1"),
-                       G_CALLBACK (on_lgplv2_activate));
-  gpp_append_new_item (properties, popup, _("Insert LGPL v3"),
-                       G_CALLBACK (on_lgplv3_activate));
-  gpp_append_new_item (properties, popup, _("Insert BSD 2-clause"),
-                       G_CALLBACK (on_bsd2c_activate));
-  gpp_append_new_item (properties, popup, _("Insert BSD 3-clause"),
-                       G_CALLBACK (on_bsd3c_activate));
-  gpp_append_new_item (properties, popup, _("Insert Apache 2"),
-                       G_CALLBACK (on_apache2_activate));
-  gpp_append_new_item (properties, popup, _("Insert MIT"),
-                       G_CALLBACK (on_mit_activate));
-  gpp_append_new_item (properties, popup, _("Insert All permissive"),
-                       G_CALLBACK (on_all_permissive_activate));
+  if ((license = gpp_get_license_from_id (gtk_combo_box_get_active_id (widget))))
+    {
+      gpp_update_license (properties, license);
+      gtk_text_view_set_editable (priv->license_textview, FALSE);
+    }
+  else
+    {
+      /* Other license */
+      gtk_text_buffer_set_text (priv->license_textbuffer, "", -1);      
+      gtk_text_view_set_editable (priv->license_textview, TRUE);
+      gtk_widget_grab_focus (GTK_WIDGET (priv->license_textview));
+    }
 }
 
 static void
@@ -926,7 +960,7 @@ on_css_filechooser_file_set (GtkFileChooserButton   *widget,
     return;
 
   path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
-  g_message ("%s %s", __func__, path);
+
   glade_project_set_css_provider_path (priv->project, path);
 }
 
@@ -1103,6 +1137,57 @@ project_css_provider_path_changed (GladeProject           *project,
   priv->ignore_ui_cb = FALSE;
 }
 
+/* Private API */
+
+void
+_glade_project_properties_set_license_data (GladeProjectProperties *props,
+                                            const gchar *license,
+                                            const gchar *name,
+                                            const gchar *description,
+                                            const gchar *copyright,
+                                            const gchar *authors)
+{
+  if (!license ||
+      !gtk_combo_box_set_active_id (props->priv->license_comboboxtext, license))
+    {
+      gtk_combo_box_set_active_id (props->priv->license_comboboxtext, "other");
+      name = description = copyright = authors = "";
+      license = "other";
+    }
+        
+  gtk_entry_buffer_set_text (props->priv->name_entrybuffer, name ? name : "", -1);
+  gtk_entry_buffer_set_text (props->priv->description_entrybuffer, description ? description : "", -1);
+
+  gtk_text_buffer_set_text (props->priv->copyright_textbuffer, copyright ? copyright : "", -1);
+  gtk_text_buffer_set_text (props->priv->authors_textbuffer, authors ? authors : "", -1);
+
+  gpp_update_license (props, gpp_get_license_from_id (license));
+}
+
+void
+_glade_project_properties_get_license_data (GladeProjectProperties *props,
+                                            gchar **license,
+                                            gchar **name,
+                                            gchar **description,
+                                            gchar **copyright,
+                                            gchar **authors)
+{
+  const gchar *id = gtk_combo_box_get_active_id (props->priv->license_comboboxtext);
+
+  if (!g_strcmp0 (id, "other"))
+    {
+      *license = *name = *description = *copyright = *authors = NULL;
+      return;
+    }
+
+  *license = g_strdup (id);
+  *name = g_strdup (gtk_entry_buffer_get_text (props->priv->name_entrybuffer));
+  *description = g_strdup (gtk_entry_buffer_get_text (props->priv->description_entrybuffer));
+
+  g_object_get (props->priv->copyright_textbuffer, "text", copyright, NULL);
+  g_object_get (props->priv->authors_textbuffer, "text", authors, NULL);
+}
+
 /******************************************************
  *                         API                        *
  ******************************************************/
diff --git a/gladeui/glade-project-properties.ui b/gladeui/glade-project-properties.ui
index 98c5f0a..9a99c5a 100644
--- a/gladeui/glade-project-properties.ui
+++ b/gladeui/glade-project-properties.ui
@@ -2,7 +2,8 @@
 <!-- Generated with glade 3.16.0 
 
 libgladeui - Glade UI Designer core library
-Copyright (C) 2013 Tristan Van Berkom <tvb gnome org>
+Copyright (C)  2013 Tristan Van Berkom <tvb gnome org>
+               2013 Juan Pablo Ugarte <juanpablougarte gmail com>
 
 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
@@ -18,11 +19,24 @@ You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
-Author: Tristan Van Berkom <tvb gnome org>
+Authors:
+       Tristan Van Berkom <tvb gnome org>
+       Juan Pablo Ugarte <juanpablougarte gmail com>
 
 -->
 <interface domain="glade">
-  <requires lib="gtk+" version="3.10"/>
+  <!-- interface-requires gtk+ 3.10 -->
+  <!-- interface-license-type lgplv2 -->
+  <!-- interface-name libgladeui -->
+  <!-- interface-description Glade UI Designer core library -->
+  <!-- interface-copyright \t2013 Tristan Van Berkom <tvb gnome org>\n\t\t2013 Juan Pablo Ugarte 
<juanpablougarte gmail com> -->
+  <!-- interface-authors \tTristan Van Berkom <tvb gnome org>\n\tJuan Pablo Ugarte <juanpablougarte gmail 
com> -->
+  <object class="GtkTextBuffer" id="authors_textbuffer">
+    <signal name="changed" handler="on_license_data_changed" swapped="yes"/>
+  </object>
+  <object class="GtkTextBuffer" id="copyright_textbuffer">
+    <signal name="changed" handler="on_license_data_changed" swapped="yes"/>
+  </object>
   <object class="GtkFileFilter" id="css_filter">
     <mime-types>
       <mime-type>text/css</mime-type>
@@ -31,7 +45,9 @@ Author: Tristan Van Berkom <tvb gnome org>
       <pattern>*.css</pattern>
     </patterns>
   </object>
+  <object class="GtkEntryBuffer" id="description_entrybuffer"/>
   <object class="GtkTextBuffer" id="license_textbuffer"/>
+  <object class="GtkEntryBuffer" id="name_entrybuffer"/>
   <template class="GladeProjectProperties" parent="GtkDialog">
     <property name="can_focus">False</property>
     <property name="border_width">5</property>
@@ -45,246 +61,471 @@ Author: Tristan Van Berkom <tvb gnome org>
         <property name="orientation">vertical</property>
         <property name="spacing">4</property>
         <child>
-          <object class="GtkBox" id="box1">
+          <object class="GtkNotebook" id="notebook">
             <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="border_width">5</property>
-            <property name="orientation">vertical</property>
-            <property name="spacing">6</property>
+            <property name="can_focus">True</property>
             <child>
-              <object class="GtkFrame" id="frame1">
+              <object class="GtkBox" id="box1">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="label_xalign">0</property>
-                <property name="shadow_type">none</property>
+                <property name="border_width">5</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">6</property>
                 <child>
-                  <object class="GtkGrid" id="grid2">
+                  <object class="GtkFrame" id="frame1">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="margin_left">12</property>
-                    <property name="margin_top">6</property>
-                    <property name="row_spacing">4</property>
-                    <property name="column_spacing">4</property>
-                    <property name="row_homogeneous">True</property>
+                    <property name="label_xalign">0</property>
+                    <property name="shadow_type">none</property>
                     <child>
-                      <object class="GtkLabel" id="label1">
+                      <object class="GtkGrid" id="grid2">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">Translation domain:</property>
+                        <property name="margin_left">12</property>
+                        <property name="margin_top">6</property>
+                        <property name="row_spacing">4</property>
+                        <property name="column_spacing">4</property>
+                        <property name="row_homogeneous">True</property>
+                        <child>
+                          <object class="GtkLabel" id="label1">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Translation domain:</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">0</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkEntry" id="domain_entry">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="hexpand">True</property>
+                            <property name="invisible_char">●</property>
+                            <signal name="changed" handler="on_domain_entry_changed" swapped="no"/>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">0</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkComboBox" id="template_combobox">
+                            <property name="visible">True</property>
+                            <property name="sensitive">False</property>
+                            <property name="can_focus">False</property>
+                            <property name="hexpand">True</property>
+                            <signal name="changed" handler="on_template_combo_box_changed" swapped="no"/>
+                            <child>
+                              <object class="GtkCellRendererPixbuf" id="cellrenderertext1"/>
+                              <attributes>
+                                <attribute name="icon-name">0</attribute>
+                              </attributes>
+                            </child>
+                            <child>
+                              <object class="GtkCellRendererText" id="cellrenderertext2"/>
+                              <attributes>
+                                <attribute name="text">1</attribute>
+                              </attributes>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">1</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkCheckButton" id="template_checkbutton">
+                            <property name="label" translatable="yes">Composite template toplevel:</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="xalign">0</property>
+                            <property name="draw_indicator">True</property>
+                            <signal name="toggled" handler="on_template_checkbutton_toggled" swapped="no"/>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">1</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkFileChooserButton" id="css_filechooser">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="filter">css_filter</property>
+                            <property name="title" translatable="yes">Select a CSS to use as custom style 
provider</property>
+                            <signal name="file-set" handler="on_css_filechooser_file_set" swapped="no"/>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">2</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkCheckButton" id="css_checkbutton">
+                            <property name="label" translatable="yes">Custom CSS style provider:</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="xalign">0</property>
+                            <property name="draw_indicator">True</property>
+                            <signal name="toggled" handler="on_css_checkbutton_toggled" swapped="no"/>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">2</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
                       </object>
-                      <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">0</property>
-                        <property name="width">1</property>
-                        <property name="height">1</property>
-                      </packing>
                     </child>
+                    <child type="label_item">
+                      <placeholder/>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkFrame" id="frame2">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label_xalign">0</property>
+                    <property name="shadow_type">none</property>
                     <child>
-                      <object class="GtkEntry" id="domain_entry">
+                      <object class="GtkGrid" id="grid1">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="hexpand">True</property>
-                        <property name="invisible_char">●</property>
-                        <signal name="changed" handler="on_domain_entry_changed" swapped="no"/>
+                        <property name="can_focus">False</property>
+                        <property name="margin_left">12</property>
+                        <property name="margin_top">6</property>
+                        <property name="row_spacing">4</property>
+                        <property name="column_spacing">4</property>
+                        <child>
+                          <object class="GtkRadioButton" id="resource_default_radio">
+                            <property name="label" translatable="yes">From the project directory</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="xalign">0</property>
+                            <property name="active">True</property>
+                            <property name="draw_indicator">True</property>
+                            <signal name="toggled" handler="resource_default_toggled" swapped="no"/>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">0</property>
+                            <property name="width">2</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkRadioButton" id="resource_relative_radio">
+                            <property name="label" translatable="yes">From a project relative 
directory</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="xalign">0</property>
+                            <property name="active">True</property>
+                            <property name="draw_indicator">True</property>
+                            <property name="group">resource_default_radio</property>
+                            <signal name="toggled" handler="resource_relative_toggled" swapped="no"/>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">1</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkRadioButton" id="resource_fullpath_radio">
+                            <property name="label" translatable="yes">From this directory</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="xalign">0</property>
+                            <property name="active">True</property>
+                            <property name="draw_indicator">True</property>
+                            <property name="group">resource_default_radio</property>
+                            <signal name="toggled" handler="resource_fullpath_toggled" swapped="no"/>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">2</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkFileChooserButton" id="full_path_button">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="hexpand">True</property>
+                            <property name="action">select-folder</property>
+                            <property name="title" translatable="yes">Choose a path to load image 
resources</property>
+                            <signal name="file-set" handler="resource_full_path_set" swapped="no"/>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">2</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkEntry" id="relative_path_entry">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="hexpand">True</property>
+                            <property name="invisible_char">●</property>
+                            <signal name="changed" handler="on_relative_path_entry_changed" swapped="no"/>
+                            <signal name="insert-text" handler="on_relative_path_entry_insert_text" 
swapped="no"/>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">1</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                    <child type="label">
+                      <object class="GtkLabel" id="label2">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Image resources are loaded 
locally:</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                        </attributes>
                       </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="top_attach">0</property>
-                        <property name="width">1</property>
-                        <property name="height">1</property>
-                      </packing>
                     </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkFrame" id="frame3">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label_xalign">0</property>
+                    <property name="shadow_type">none</property>
                     <child>
-                      <object class="GtkComboBox" id="template_combobox">
+                      <object class="GtkBox" id="toolkit_box">
                         <property name="visible">True</property>
-                        <property name="sensitive">False</property>
                         <property name="can_focus">False</property>
-                        <property name="hexpand">True</property>
-                        <signal name="changed" handler="on_template_combo_box_changed" swapped="no"/>
+                        <property name="margin_left">12</property>
+                        <property name="margin_top">6</property>
+                        <property name="orientation">vertical</property>
                         <child>
-                          <object class="GtkCellRendererPixbuf" id="cellrenderertext1"/>
-                          <attributes>
-                            <attribute name="icon-name">0</attribute>
-                          </attributes>
-                        </child>
-                        <child>
-                          <object class="GtkCellRendererText" id="cellrenderertext2"/>
-                          <attributes>
-                            <attribute name="text">1</attribute>
-                          </attributes>
+                          <placeholder/>
                         </child>
                       </object>
+                    </child>
+                    <child type="label">
+                      <object class="GtkLabel" id="label3">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Toolkit version required:</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                        </attributes>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="label5">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Properties</property>
+                <property name="use_markup">True</property>
+                <attributes>
+                  <attribute name="weight" value="bold"/>
+                </attributes>
+              </object>
+              <packing>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkBox" id="box3">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="margin_left">12</property>
+                <property name="margin_right">6</property>
+                <property name="margin_top">6</property>
+                <property name="margin_bottom">6</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">6</property>
+                <child>
+                  <object class="GtkGrid" id="grid3">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="row_spacing">6</property>
+                    <property name="column_spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="label7">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Name:</property>
+                      </object>
                       <packing>
-                        <property name="left_attach">1</property>
-                        <property name="top_attach">1</property>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">0</property>
                         <property name="width">1</property>
                         <property name="height">1</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkCheckButton" id="template_checkbutton">
-                        <property name="label" translatable="yes">Composite template toplevel:</property>
+                      <object class="GtkLabel" id="label8">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
+                        <property name="can_focus">False</property>
                         <property name="xalign">0</property>
-                        <property name="draw_indicator">True</property>
-                        <signal name="toggled" handler="on_template_checkbutton_toggled" swapped="no"/>
+                        <property name="label" translatable="yes">Copyright:</property>
                       </object>
                       <packing>
                         <property name="left_attach">0</property>
-                        <property name="top_attach">1</property>
+                        <property name="top_attach">2</property>
                         <property name="width">1</property>
                         <property name="height">1</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkFileChooserButton" id="css_filechooser">
+                      <object class="GtkEntry" id="name_entry">
                         <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="filter">css_filter</property>
-                        <property name="title" translatable="yes">Select a CSS to use as custom style 
provider</property>
-                        <signal name="file-set" handler="on_css_filechooser_file_set" swapped="no"/>
+                        <property name="can_focus">True</property>
+                        <property name="hexpand">True</property>
+                        <property name="buffer">name_entrybuffer</property>
+                        <property name="placeholder_text" translatable="yes">program or library 
name</property>
+                        <signal name="changed" handler="on_license_data_changed" swapped="yes"/>
                       </object>
                       <packing>
                         <property name="left_attach">1</property>
-                        <property name="top_attach">2</property>
+                        <property name="top_attach">0</property>
                         <property name="width">1</property>
                         <property name="height">1</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkCheckButton" id="css_checkbutton">
-                        <property name="label" translatable="yes">Custom CSS style provider:</property>
+                      <object class="GtkLabel" id="label9">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
+                        <property name="can_focus">False</property>
                         <property name="xalign">0</property>
-                        <property name="draw_indicator">True</property>
-                        <signal name="toggled" handler="on_css_checkbutton_toggled" swapped="no"/>
+                        <property name="label" translatable="yes">Author(s):</property>
                       </object>
                       <packing>
                         <property name="left_attach">0</property>
-                        <property name="top_attach">2</property>
+                        <property name="top_attach">3</property>
                         <property name="width">1</property>
                         <property name="height">1</property>
                       </packing>
                     </child>
-                  </object>
-                </child>
-                <child type="label">
-                  <object class="GtkLabel" id="label5">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">Project properties:</property>
-                    <property name="use_markup">True</property>
-                    <attributes>
-                      <attribute name="weight" value="bold"/>
-                    </attributes>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkFrame" id="frame2">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label_xalign">0</property>
-                <property name="shadow_type">none</property>
-                <child>
-                  <object class="GtkGrid" id="grid1">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="margin_left">12</property>
-                    <property name="margin_top">6</property>
-                    <property name="row_spacing">4</property>
-                    <property name="column_spacing">4</property>
                     <child>
-                      <object class="GtkRadioButton" id="resource_default_radio">
-                        <property name="label" translatable="yes">From the project directory</property>
+                      <object class="GtkLabel" id="label6">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
+                        <property name="can_focus">False</property>
                         <property name="xalign">0</property>
-                        <property name="active">True</property>
-                        <property name="draw_indicator">True</property>
-                        <signal name="toggled" handler="resource_default_toggled" swapped="no"/>
+                        <property name="label" translatable="yes">License:</property>
                       </object>
                       <packing>
                         <property name="left_attach">0</property>
-                        <property name="top_attach">0</property>
-                        <property name="width">2</property>
+                        <property name="top_attach">4</property>
+                        <property name="width">1</property>
                         <property name="height">1</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkRadioButton" id="resource_relative_radio">
-                        <property name="label" translatable="yes">From a project relative 
directory</property>
+                      <object class="GtkScrolledWindow" id="scrolledwindow2">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="xalign">0</property>
-                        <property name="active">True</property>
-                        <property name="draw_indicator">True</property>
-                        <property name="group">resource_default_radio</property>
-                        <signal name="toggled" handler="resource_relative_toggled" swapped="no"/>
+                        <property name="shadow_type">in</property>
+                        <child>
+                          <object class="GtkTextView" id="copyright_textview">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="buffer">copyright_textbuffer</property>
+                          </object>
+                        </child>
                       </object>
                       <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">1</property>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">2</property>
                         <property name="width">1</property>
                         <property name="height">1</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkRadioButton" id="resource_fullpath_radio">
-                        <property name="label" translatable="yes">From this directory</property>
+                      <object class="GtkScrolledWindow" id="scrolledwindow3">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="xalign">0</property>
-                        <property name="active">True</property>
-                        <property name="draw_indicator">True</property>
-                        <property name="group">resource_default_radio</property>
-                        <signal name="toggled" handler="resource_fullpath_toggled" swapped="no"/>
+                        <property name="shadow_type">in</property>
+                        <child>
+                          <object class="GtkTextView" id="authors_textview">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="buffer">authors_textbuffer</property>
+                          </object>
+                        </child>
                       </object>
                       <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">2</property>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">3</property>
                         <property name="width">1</property>
                         <property name="height">1</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkFileChooserButton" id="full_path_button">
+                      <object class="GtkLabel" id="label10">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="hexpand">True</property>
-                        <property name="action">select-folder</property>
-                        <property name="title" translatable="yes">Choose a path to load image 
resources</property>
-                        <signal name="file-set" handler="resource_full_path_set" swapped="no"/>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Description:</property>
+                        <property name="max_width_chars">5</property>
                       </object>
                       <packing>
-                        <property name="left_attach">1</property>
-                        <property name="top_attach">2</property>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">1</property>
                         <property name="width">1</property>
                         <property name="height">1</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkEntry" id="relative_path_entry">
+                      <object class="GtkEntry" id="description_entry">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="hexpand">True</property>
-                        <property name="invisible_char">●</property>
-                        <signal name="changed" handler="on_relative_path_entry_changed" swapped="no"/>
-                        <signal name="insert-text" handler="on_relative_path_entry_insert_text" 
swapped="no"/>
+                        <property name="buffer">description_entrybuffer</property>
+                        <property name="placeholder_text" translatable="yes">program or library short 
description</property>
+                        <signal name="changed" handler="on_license_data_changed" swapped="yes"/>
                       </object>
                       <packing>
                         <property name="left_attach">1</property>
@@ -293,72 +534,43 @@ Author: Tristan Van Berkom <tvb gnome org>
                         <property name="height">1</property>
                       </packing>
                     </child>
-                  </object>
-                </child>
-                <child type="label">
-                  <object class="GtkLabel" id="label2">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">Image resources are loaded locally:</property>
-                    <attributes>
-                      <attribute name="weight" value="bold"/>
-                    </attributes>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkFrame" id="frame3">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label_xalign">0</property>
-                <property name="shadow_type">none</property>
-                <child>
-                  <object class="GtkBox" id="toolkit_box">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="margin_left">12</property>
-                    <property name="margin_top">6</property>
-                    <property name="orientation">vertical</property>
                     <child>
-                      <placeholder/>
+                      <object class="GtkComboBoxText" id="license_comboboxtext">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="active">0</property>
+                        <items>
+                          <item id="gplv2" translatable="yes">GNU GPL version 2</item>
+                          <item id="gplv3" translatable="yes">GNU GPL version 3</item>
+                          <item id="lgplv2" translatable="yes">GNU LGPL version 2.1</item>
+                          <item id="lgplv3" translatable="yes">GNU LGPL version 3</item>
+                          <item id="bsd2c" translatable="yes">BSD 2-clause</item>
+                          <item id="bsd3c" translatable="yes">BSD 3-clause</item>
+                          <item id="apache2" translatable="yes">Apache 2</item>
+                          <item id="mit" translatable="yes">MIT</item>
+                          <item id="all_permissive" translatable="yes">GNU All permissive</item>
+                          <item id="other" translatable="yes">Other</item>
+                        </items>
+                        <signal name="changed" handler="on_license_comboboxtext_changed" swapped="no"/>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">4</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
                     </child>
                   </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
                 </child>
-                <child type="label">
-                  <object class="GtkLabel" id="label3">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">Toolkit version required:</property>
-                    <attributes>
-                      <attribute name="weight" value="bold"/>
-                    </attributes>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkFrame" id="frame4">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label_xalign">0</property>
-                <property name="shadow_type">none</property>
                 <child>
                   <object class="GtkScrolledWindow" id="scrolledwindow1">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="margin_left">12</property>
-                    <property name="margin_top">6</property>
                     <property name="hexpand">True</property>
                     <property name="vexpand">True</property>
                     <property name="shadow_type">in</property>
@@ -366,54 +578,36 @@ Author: Tristan Van Berkom <tvb gnome org>
                       <object class="GtkTextView" id="license_textview">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
+                        <property name="hexpand">True</property>
+                        <property name="vexpand">True</property>
+                        <property name="editable">False</property>
                         <property name="buffer">license_textbuffer</property>
-                        <signal name="populate-popup" handler="on_license_textview_populate_popup" 
swapped="no"/>
                       </object>
                     </child>
                   </object>
-                </child>
-                <child type="label">
-                  <object class="GtkBox" id="box2">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="spacing">4</property>
-                    <child>
-                      <object class="GtkLabel" id="label4">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">License:</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                        </attributes>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label6">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">(Use right click to insert common 
licenses)</property>
-                        <attributes>
-                          <attribute name="style" value="italic"/>
-                        </attributes>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
                 </child>
               </object>
               <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">3</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="label4">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">License</property>
+                <attributes>
+                  <attribute name="weight" value="bold"/>
+                </attributes>
+              </object>
+              <packing>
+                <property name="position">1</property>
+                <property name="tab_fill">False</property>
               </packing>
             </child>
           </object>
diff --git a/gladeui/glade-project.c b/gladeui/glade-project.c
index 459de97..9e7e980 100644
--- a/gladeui/glade-project.c
+++ b/gladeui/glade-project.c
@@ -1361,22 +1361,55 @@ glade_project_fix_template (GladeProject *project)
 }
 
 static gchar *
-glade_project_read_requires_from_comment (GladeXmlNode *comment,
-                                          guint16 *major, guint16 *minor)
+gp_comment_strip_property (gchar *value, gchar *property)
 {
-  gint maj, min;
-  gchar *value, buffer[256];
-  gchar *required_lib = NULL;
+  if (g_str_has_prefix (value, property))
+    {
+      gchar *start = value + strlen (property);
 
-  if (!glade_xml_node_is_comment (comment))
-    return NULL;
+      if (*start == ' ')
+        start++;
+
+      memmove (value, start, strlen (start) + 1);
+      return value;
+    }
+
+  return NULL;
+}
+
+static gchar *
+gp_comment_get_content (GladeXmlNode *comment)
+{
+  gchar *value;
+
+  if (glade_xml_node_is_comment (comment) &&
+      (value = glade_xml_get_content (comment)))
+    {
+      gchar *compressed;
+      
+      /* Replace NON-BREAKING HYPHEN with regular HYPHEN */
+      value = _glade_util_strreplace (g_strstrip (value), TRUE, "\\‑\\‑", "--");
+      compressed = g_strcompress (value);
+      g_free (value);
+      return compressed;
+    }
 
-  value = glade_xml_get_content (comment);
+  return NULL;
+}
 
-  if (value &&
-      !strncmp (" interface-requires", value, strlen (" interface-requires")))
+static gchar *
+glade_project_read_requires_from_comment (GladeXmlNode *comment,
+                                          guint16 *major, guint16 *minor)
+{
+  gchar *value, *requires, *required_lib = NULL;
+  
+  if ((value = gp_comment_get_content (comment)) &&
+      (requires = gp_comment_strip_property (value, "interface-requires")))
     {
-      if (sscanf (value, " interface-requires %s %d.%d", buffer, &maj, &min) == 3)
+      gchar buffer[128];
+      gint maj, min;
+      
+      if (sscanf (requires, "%128s %d.%d", buffer, &maj, &min) == 3)
         {
           if (major)
             *major = maj;
@@ -1470,27 +1503,6 @@ glade_project_read_requires (GladeProject *project,
   return loadable;
 }
 
-static gchar *
-glade_project_read_resource_path_from_comment (GladeXmlNode *comment)
-{
-  gchar *value, buffer[FILENAME_MAX], *path = NULL;
-
-  if (!glade_xml_node_is_comment (comment))
-    return FALSE;
-
-  value = glade_xml_get_content (comment);
-  if (value &&
-      !strncmp (" interface-local-resource-path", value,
-                strlen (" interface-local-resource-path")))
-    {
-      if (sscanf (value, " interface-local-resource-path %s", buffer) == 1)
-        path = g_strdup (buffer);
-    }
-  g_free (value);
-
-  return path;
-}
-
 static void
 update_project_for_resource_path (GladeProject *project)
 {
@@ -1585,62 +1597,65 @@ glade_project_get_license (GladeProject *project)
 }
 
 static void
-glade_project_read_resource_path (GladeProject *project,
-                                  GladeXmlNode *root_node)
-{
-  GladeXmlNode *node;
-  gchar *path = NULL;
-
-  for (node = glade_xml_node_get_children_with_comments (root_node);
-       node; node = glade_xml_node_next_with_comments (node))
-    {
-      /* Skip non "requires" tags */
-      if ((path = glade_project_read_resource_path_from_comment (node)) != NULL)
-        break;
-    }
-
-  glade_project_set_resource_path (project, path);
-  g_free (path);
-}
-
-static void
-glade_project_read_css_provider_path (GladeProject *project,
-                                      GladeXmlNode *root_node)
+glade_project_read_comment_properties (GladeProject *project,
+                                       GladeXmlNode *root_node)
 {
+  GladeProjectPrivate *priv = project->priv;
+  gchar *license, *name, *description, *copyright, *authors;
   GladeXmlNode *node;
 
+  license = name = description = copyright = authors = NULL;
+  
   for (node = glade_xml_node_get_children_with_comments (root_node);
        node; node = glade_xml_node_next_with_comments (node))
     {
-      gchar *value;
+      gchar *val;
 
-      if (glade_xml_node_is_comment (node) &&
-          (value = glade_xml_get_content (node)))
+      if (!(val = gp_comment_get_content (node)))
+        continue;
+      
+      if (gp_comment_strip_property (val, "interface-local-resource-path"))
+        glade_project_set_resource_path (project, val);
+      else if (gp_comment_strip_property (val, "interface-css-provider-path"))
         {
-          gchar **tokens = g_strsplit (g_strstrip (value), " ", 2);
-
-          if (tokens[0] && !g_strcmp0 (tokens[0], "interface-css-provider-path"))
+          if (g_path_is_absolute (val))
+            glade_project_set_css_provider_path (project, val);
+          else
             {
-              gchar *path = tokens[1];
-
-              if (g_path_is_absolute (path))
-                glade_project_set_css_provider_path (project, path);
-              else
-                {
-                  gchar *dirname = g_path_get_dirname (project->priv->path);
-                  gchar *full_path = g_build_filename (dirname, path, NULL);
+              gchar *dirname = g_path_get_dirname (priv->path);
+              gchar *full_path = g_build_filename (dirname, val, NULL);
 
-                  glade_project_set_css_provider_path (project, full_path);
+              glade_project_set_css_provider_path (project, full_path);
 
-                  g_free (dirname);
-                  g_free (full_path);
-                }
+              g_free (dirname);
+              g_free (full_path);
             }
-
-          g_strfreev (tokens);
-          g_free (value);
         }
+      else if (!license && (license = gp_comment_strip_property (val, "interface-license-type")))
+        continue;
+      else if (!name && (name = gp_comment_strip_property (val, "interface-name")))
+        continue;
+      else if (!description && (description = gp_comment_strip_property (val, "interface-description")))
+        continue;
+      else if (!copyright && (copyright = gp_comment_strip_property (val, "interface-copyright")))
+        continue;
+      else if (!authors && (authors = gp_comment_strip_property (val, "interface-authors")))
+        continue;
+
+      g_free (val);
     }
+
+  _glade_project_properties_set_license_data (GLADE_PROJECT_PROPERTIES (priv->prefs_dialog),
+                                              license,
+                                              name,
+                                              description,
+                                              copyright,
+                                              authors);
+  g_free (license);
+  g_free (name);
+  g_free (description);
+  g_free (copyright);
+  g_free (authors);
 }
 
 static inline void
@@ -2049,9 +2064,8 @@ glade_project_load_internal (GladeProject *project)
    */
   glade_project_read_requires (project, root, load_path ? load_path : priv->path, &has_gtk_dep);
 
-  glade_project_read_resource_path (project, root);
-
-  glade_project_read_css_provider_path (project, root);
+  /* Read the rest of properties saved as comments */
+  glade_project_read_comment_properties (project, root);
 
   /* Launch a dialog if it's going to take enough time to be
    * worth showing at all */
@@ -2184,6 +2198,33 @@ glade_project_load (const gchar *path)
 #define GLADE_PROJECT_COMMENT " "GLADE_XML_COMMENT" "PACKAGE_VERSION" "
 
 static void
+glade_project_write_comment_property (GladeProject    *project,
+                                      GladeXmlContext *context,
+                                      GladeXmlNode    *root,
+                                      const gchar     *property,
+                                      gchar           *value)
+{
+  gchar *comment, *escaped;
+  GladeXmlNode *path_node;
+
+  if (!value || *value == '\0')
+    return;
+
+  /* The string "--" (double hyphen) is not allowed in xml comments, so we replace
+   * the regular HYPHEN with a NON-BREAKING HYPHEN which look the same but have
+   * a different encoding.
+   */
+  escaped = _glade_util_strreplace (g_strescape (value, "‑"), TRUE, "--", "\\‑\\‑");
+  
+  comment = g_strconcat (" ", property, " ", escaped, " ", NULL);
+  path_node = glade_xml_node_new_comment (context, comment);
+  glade_xml_node_append_child (root, path_node);
+
+  g_free (escaped);
+  g_free (comment);
+}
+
+static void
 glade_project_write_required_libs (GladeProject *project,
                                    GladeXmlContext *context,
                                    GladeXmlNode *root)
@@ -2218,15 +2259,16 @@ glade_project_write_required_libs (GladeProject *project,
               glade_xml_node_set_property_string (req_node,
                                                   GLADE_XML_TAG_VERSION,
                                                   version);
+              glade_xml_node_append_child (root, req_node);
             }
           else
             {
-              gchar *comment = g_strdup_printf (" interface-requires %s %s ",
-                                                library, version);
-              req_node = glade_xml_node_new_comment (context, comment);
-              g_free (comment);
+              gchar *value = g_strconcat (library, " ", version, NULL);
+              glade_project_write_comment_property (project, context, root,
+                                                    "interface-requires",
+                                                    value);
+              g_free (value);
             }
-          glade_xml_node_append_child (root, req_node);
         }
       g_list_free_full (required, g_free);
     }
@@ -2237,15 +2279,9 @@ glade_project_write_resource_path (GladeProject *project,
                                    GladeXmlContext *context,
                                    GladeXmlNode *root)
 {
-  GladeXmlNode *path_node;
-  if (project->priv->resource_path)
-    {
-      gchar *comment = g_strdup_printf (" interface-local-resource-path %s ",
+  glade_project_write_comment_property (project, context, root,
+                                        "interface-local-resource-path",
                                         project->priv->resource_path);
-      path_node = glade_xml_node_new_comment (context, comment);
-      glade_xml_node_append_child (root, path_node);
-      g_free (comment);
-    }
 }
 
 static void
@@ -2254,7 +2290,6 @@ glade_project_write_css_provider_path (GladeProject *project,
                                        GladeXmlNode *root)
 {
   GladeProjectPrivate *priv = project->priv;
-  GladeXmlNode *path_node;
   gchar *dirname;
 
   if (priv->css_provider_path && priv->path &&
@@ -2267,13 +2302,9 @@ glade_project_write_css_provider_path (GladeProject *project,
       css_provider_path = g_file_get_relative_path (project_path, file_path);
 
       if (css_provider_path)
-        {
-          gchar *comment = g_strdup_printf (" interface-css-provider-path %s ",
-                                            css_provider_path);
-          path_node = glade_xml_node_new_comment (context, comment);
-          glade_xml_node_append_child (root, path_node);
-          g_free (comment);
-        }
+        glade_project_write_comment_property (project, context, root,
+                                              "interface-css-provider-path",
+                                              css_provider_path);
       else
         g_warning ("g_file_get_relative_path () return NULL");
 
@@ -2284,6 +2315,46 @@ glade_project_write_css_provider_path (GladeProject *project,
     }
 }
 
+static void
+glade_project_write_license_data (GladeProject *project,
+                                  GladeXmlContext *context,
+                                  GladeXmlNode *root)
+{
+  gchar *license, *name, *description, *copyright, *authors;
+  
+  _glade_project_properties_get_license_data (GLADE_PROJECT_PROPERTIES (project->priv->prefs_dialog),
+                                              &license,
+                                              &name,
+                                              &description,
+                                              &copyright,
+                                              &authors);
+
+  if (!license)
+    return;
+  
+  glade_project_write_comment_property (project, context, root,
+                                        "interface-license-type",
+                                        license);
+  glade_project_write_comment_property (project, context, root,
+                                        "interface-name",
+                                        name);
+  glade_project_write_comment_property (project, context, root,
+                                        "interface-description",
+                                        description);
+  glade_project_write_comment_property (project, context, root,
+                                        "interface-copyright",
+                                        copyright);
+  glade_project_write_comment_property (project, context, root,
+                                        "interface-authors",
+                                        authors);
+
+  g_free (license);
+  g_free (name);
+  g_free (description);
+  g_free (copyright);
+  g_free (authors);
+}
+
 static gint
 glade_widgets_name_cmp (gconstpointer ga, gconstpointer gb)
 {
@@ -2498,7 +2569,9 @@ glade_project_write_comments (GladeProject *project,
 
   if (priv->license)
     {
-      gchar *comment = g_strdup_printf (GLADE_PROJECT_COMMENT"\n\n%s\n\n", priv->license);
+      /* Replace regular HYPHEN with NON-BREAKING HYPHEN */
+      gchar *license = _glade_util_strreplace (priv->license, FALSE, "--", "‑‑");
+      gchar *comment = g_strdup_printf (GLADE_PROJECT_COMMENT"\n\n%s\n\n", license);
       comment_node = glade_xml_doc_new_comment (doc, comment);
       g_free (comment);
     }
@@ -2540,6 +2613,8 @@ glade_project_write (GladeProject *project)
 
   glade_project_write_css_provider_path (project, context, root);
 
+  glade_project_write_license_data (project, context, root);
+
   /* Get sorted toplevels */
   toplevels = glade_project_get_ordered_toplevels (project);
 
diff --git a/gladeui/glade-utils.c b/gladeui/glade-utils.c
index 1ad1fa6..36b0490 100644
--- a/gladeui/glade-utils.c
+++ b/gladeui/glade-utils.c
@@ -39,6 +39,7 @@
 #include "glade-property.h"
 #include "glade-property-class.h"
 #include "glade-clipboard.h"
+#include "glade-private.h"
 
 #include <string.h>
 #include <gdk/gdkkeysyms.h>
@@ -522,6 +523,36 @@ glade_util_replace (gchar *str, gchar a, gchar b)
 }
 
 /**
+ * _glade_util_strreplace:
+ * @str: a string
+ * @free_str: wheter to free str or not
+ * @key: the key string to search for
+ * @replacement: string to replace key
+ *
+ * Replaces each occurance of the string @key in @str to @replacement.
+ */
+gchar *
+_glade_util_strreplace (gchar *str,
+                        gboolean free_str,
+                        const gchar *key,
+                        const gchar *replacement)
+{
+  gchar *retval, **array;
+
+  if ((array = g_strsplit (str, key, -1)) && array[0])
+    retval = g_strjoinv (replacement, array);
+  else
+    retval = g_strdup (str);
+
+  g_strfreev (array);
+
+  if (free_str)
+    g_free (str);
+       
+  return retval;
+}
+
+/**
  * glade_util_read_prop_name:
  * @str: a string
  *


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