]> git.sur5r.net Git - glabels/commitdiff
Created new "New label dialog"
authorJim Evins <evins@snaught.com>
Thu, 11 Mar 2010 03:38:28 +0000 (22:38 -0500)
committerJim Evins <evins@snaught.com>
Thu, 11 Mar 2010 03:38:28 +0000 (22:38 -0500)
Created a new re-designed "New label dialog."  The dialog now shows meta-data
for the selected template, including hyperlinks to vendor and product
websites, if available.  The new dialog is more compact and thus should
be usable on small displays such as netbooks (probably not hand-helds).

The menu is somewhat clumbsy to navigate still -- will need to reorganize
to make navigation easier and more intuitive.

24 files changed:
data/builder/Makefile.am
data/builder/media-select.builder [deleted file]
data/builder/new-label-dialog.builder [new file with mode: 0644]
libglabels/db.c
libglabels/db.h
libglabels/str.c
libglabels/str.h
libglabels/template.c
libglabels/template.h
src/Makefile.am
src/media-combo-menu-item.c [new file with mode: 0644]
src/media-combo-menu-item.h [new file with mode: 0644]
src/media-combo-menu.c [new file with mode: 0644]
src/media-combo-menu.h [new file with mode: 0644]
src/media-combo.c [new file with mode: 0644]
src/media-combo.h [new file with mode: 0644]
src/media-select.c [deleted file]
src/media-select.h [deleted file]
src/mini-preview.c
src/mini-preview.h
src/new-label-dialog.c
src/rotate-label-button.c
src/str-util.c
src/str-util.h

index a4cf3f3faf4fd4a886a107007060b64714592701..4b48a699dea6ddab9df4b64ea8c8e5a212378dfd 100644 (file)
@@ -5,7 +5,7 @@ builderdir = $(datadir)/$(GLABELS_BRANCH)/builder/
 builder_DATA = \
        property-bar.builder            \
        print-op-dialog-custom-widget.builder   \
-       media-select.builder            \
+       new-label-dialog.builder        \
        merge-properties-dialog.builder \
        template-designer.builder       \
        prefs-dialog.builder            \
diff --git a/data/builder/media-select.builder b/data/builder/media-select.builder
deleted file mode 100644 (file)
index 707057a..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-<?xml version="1.0"?>
-<interface>
-  <requires lib="gtk+" version="2.16"/>
-  <!-- interface-naming-policy toplevel-contextual -->
-  <object class="GtkWindow" id="window1">
-    <property name="visible">True</property>
-    <property name="title" translatable="yes">window1</property>
-    <child>
-      <object class="GtkHBox" id="media_select_hbox">
-        <property name="visible">True</property>
-        <child>
-          <object class="GtkNotebook" id="notebook">
-            <property name="visible">True</property>
-            <property name="border_width">12</property>
-            <child>
-              <object class="GtkVBox" id="recent_tab_vbox">
-                <property name="height_request">320</property>
-                <property name="visible">True</property>
-                <property name="border_width">6</property>
-                <property name="orientation">vertical</property>
-                <child>
-                  <object class="GtkVBox" id="recent_info_vbox">
-                    <property name="visible">True</property>
-                    <property name="orientation">vertical</property>
-                    <child>
-                      <placeholder/>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkScrolledWindow" id="scrolledwindow2">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="hscrollbar_policy">automatic</property>
-                    <property name="vscrollbar_policy">automatic</property>
-                    <property name="shadow_type">in</property>
-                    <child>
-                      <object class="GtkTreeView" id="recent_treeview">
-                        <property name="visible">True</property>
-                        <property name="headers_visible">False</property>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </object>
-            </child>
-            <child type="tab">
-              <object class="GtkLabel" id="recent_tab_label">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Recent templates</property>
-              </object>
-              <packing>
-                <property name="tab_fill">False</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkVBox" id="search_all_tab_vbox">
-                <property name="visible">True</property>
-                <property name="border_width">6</property>
-                <property name="orientation">vertical</property>
-                <child>
-                  <object class="GtkHBox" id="hbox6">
-                    <property name="visible">True</property>
-                    <property name="spacing">12</property>
-                    <child>
-                      <object class="GtkHBox" id="hbox9">
-                        <property name="visible">True</property>
-                        <property name="spacing">6</property>
-                        <child>
-                          <object class="GtkLabel" id="label14">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">Brand:</property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                            <property name="position">0</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkComboBox" id="brand_combo">
-                            <property name="visible">True</property>
-                            <property name="focus_on_click">False</property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="position">1</property>
-                          </packing>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkHBox" id="hbox7">
-                        <property name="visible">True</property>
-                        <property name="spacing">6</property>
-                        <child>
-                          <object class="GtkLabel" id="label12">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">Page size:</property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                            <property name="position">0</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkComboBox" id="page_size_combo">
-                            <property name="visible">True</property>
-                            <property name="focus_on_click">False</property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="position">1</property>
-                          </packing>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkHBox" id="hbox8">
-                        <property name="visible">True</property>
-                        <property name="spacing">6</property>
-                        <child>
-                          <object class="GtkLabel" id="label13">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">Category:</property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                            <property name="position">0</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkComboBox" id="category_combo">
-                            <property name="visible">True</property>
-                            <property name="focus_on_click">False</property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="position">1</property>
-                          </packing>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="position">2</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="padding">6</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkVBox" id="search_all_info_vbox">
-                    <property name="visible">True</property>
-                    <property name="orientation">vertical</property>
-                    <child>
-                      <placeholder/>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkScrolledWindow" id="scrolledwindow1">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="hscrollbar_policy">automatic</property>
-                    <property name="vscrollbar_policy">automatic</property>
-                    <property name="shadow_type">in</property>
-                    <child>
-                      <object class="GtkTreeView" id="search_all_treeview">
-                        <property name="visible">True</property>
-                        <property name="headers_visible">False</property>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="position">2</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child type="tab">
-              <object class="GtkLabel" id="search_all_tabLlabel">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Search all templates</property>
-              </object>
-              <packing>
-                <property name="position">1</property>
-                <property name="tab_fill">False</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="position">0</property>
-          </packing>
-        </child>
-      </object>
-    </child>
-  </object>
-</interface>
diff --git a/data/builder/new-label-dialog.builder b/data/builder/new-label-dialog.builder
new file mode 100644 (file)
index 0000000..9cb16a5
--- /dev/null
@@ -0,0 +1,362 @@
+<?xml version="1.0"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy project-wide -->
+  <object class="GtkWindow" id="window1">
+    <child>
+      <object class="GtkHBox" id="new_label_dialog_hbox">
+        <property name="visible">True</property>
+        <property name="border_width">6</property>
+        <property name="spacing">18</property>
+        <child>
+          <object class="GtkVBox" id="vbox1">
+            <property name="visible">True</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkFrame" id="frame1">
+                <property name="visible">True</property>
+                <property name="label_xalign">0</property>
+                <property name="shadow_type">none</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment1">
+                    <property name="visible">True</property>
+                    <property name="left_padding">12</property>
+                    <child>
+                      <object class="GtkTable" id="table2">
+                        <property name="visible">True</property>
+                        <property name="n_rows">2</property>
+                        <property name="n_columns">2</property>
+                        <property name="column_spacing">12</property>
+                        <property name="row_spacing">6</property>
+                        <child>
+                          <object class="GtkLabel" id="label6">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Template:</property>
+                          </object>
+                          <packing>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkHBox" id="combo_hbox">
+                            <property name="visible">True</property>
+                            <child>
+                              <placeholder/>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label12">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="yalign">0</property>
+                            <property name="label" translatable="yes">Orientation:</property>
+                          </object>
+                          <packing>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkHBox" id="rotate_hbox">
+                            <property name="visible">True</property>
+                            <child>
+                              <placeholder/>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel" id="label9">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Select media&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkFrame" id="frame2">
+                <property name="visible">True</property>
+                <property name="label_xalign">0</property>
+                <property name="shadow_type">none</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment2">
+                    <property name="visible">True</property>
+                    <property name="left_padding">12</property>
+                    <child>
+                      <object class="GtkTable" id="table1">
+                        <property name="visible">True</property>
+                        <property name="n_rows">7</property>
+                        <property name="n_columns">2</property>
+                        <property name="column_spacing">12</property>
+                        <property name="row_spacing">6</property>
+                        <child>
+                          <object class="GtkLabel" id="label1">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Description:</property>
+                          </object>
+                          <packing>
+                            <property name="top_attach">2</property>
+                            <property name="bottom_attach">3</property>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label2">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Page size:</property>
+                          </object>
+                          <packing>
+                            <property name="top_attach">3</property>
+                            <property name="bottom_attach">4</property>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label3">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Label size:</property>
+                          </object>
+                          <packing>
+                            <property name="top_attach">4</property>
+                            <property name="bottom_attach">5</property>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label4">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Layout:</property>
+                          </object>
+                          <packing>
+                            <property name="top_attach">5</property>
+                            <property name="bottom_attach">6</property>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label7">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="yalign">0</property>
+                            <property name="label" translatable="yes">Similar products:</property>
+                          </object>
+                          <packing>
+                            <property name="top_attach">6</property>
+                            <property name="bottom_attach">7</property>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="desc_label">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">2</property>
+                            <property name="bottom_attach">3</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="page_size_label">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">3</property>
+                            <property name="bottom_attach">4</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label_size_label">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">4</property>
+                            <property name="bottom_attach">5</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="layout_label">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">5</property>
+                            <property name="bottom_attach">6</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label5">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Vendor:</property>
+                          </object>
+                          <packing>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="vendor_label">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label8">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Part #:</property>
+                          </object>
+                          <packing>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="part_label">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkScrolledWindow" id="scrolledwindow1">
+                            <property name="height_request">77</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="hscrollbar_policy">never</property>
+                            <property name="vscrollbar_policy">automatic</property>
+                            <property name="shadow_type">in</property>
+                            <child>
+                              <object class="GtkViewport" id="viewport1">
+                                <property name="visible">True</property>
+                                <property name="resize_mode">queue</property>
+                                <property name="shadow_type">none</property>
+                                <child>
+                                  <object class="GtkLabel" id="similar_label">
+                                    <property name="visible">True</property>
+                                    <property name="xalign">0</property>
+                                    <property name="yalign">0</property>
+                                    <property name="label" translatable="yes">1
+2
+3
+4</property>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">6</property>
+                            <property name="bottom_attach">7</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel" id="label10">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Information&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkFrame" id="frame3">
+            <property name="visible">True</property>
+            <property name="label_xalign">0</property>
+            <property name="shadow_type">none</property>
+            <child>
+              <object class="GtkAlignment" id="alignment3">
+                <property name="visible">True</property>
+                <property name="left_padding">12</property>
+                <child>
+                  <object class="GtkVBox" id="preview_vbox">
+                    <property name="visible">True</property>
+                    <property name="orientation">vertical</property>
+                    <child>
+                      <placeholder/>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child type="label">
+              <object class="GtkLabel" id="label11">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">&lt;b&gt;Preview&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
index b43ff6b3343648da9b53f382250cdcde5592004e..af2adcaed4b491255e906f45c9ce7737e3055137 100644 (file)
@@ -1149,7 +1149,7 @@ read_vendor_files_from_dir (GList      *vendors,
 
                if (extension != NULL) {
 
-                       if ( ASCII_EQUAL (filename, "vendor-sizes.xml") )
+                       if ( ASCII_EQUAL (filename, "vendors.xml") )
                         {
 
                                full_filename =
@@ -1555,6 +1555,77 @@ lgl_db_get_template_name_list_all (const gchar *brand,
 }
 
 
+/**
+ * lgl_db_get_similar_template_name_list:
+ * @name:     Name of template under test.
+ *
+ * Get a list of all valid names and aliases of templates in the template database that
+ * have the same size and layout characteristics as the given template.
+ *
+ * Returns: a list of template names and aliases.
+ */
+GList *
+lgl_db_get_similar_template_name_list (const gchar  *name)
+{
+       GList            *p_tmplt, *p_alias;
+       lglTemplate      *template1;
+       lglTemplate      *template2;
+       lglTemplateAlias *alias;
+        gchar            *name2;
+       GList            *names = NULL;
+
+       if (!templates)
+        {
+               lgl_db_init ();
+       }
+
+        if ( !name )
+        {
+                return NULL;
+        }
+
+        template1 = lgl_db_lookup_template_from_name (name);
+        if ( !template1 )
+        {
+                return NULL;
+        }
+
+        for (p_alias = template1->aliases; p_alias != NULL; p_alias = p_alias->next)
+        {
+                alias = (lglTemplateAlias *)p_alias->data;
+
+                name2 = g_strdup_printf ("%s %s", alias->brand, alias->part);
+                if ( !UTF8_EQUAL (name2, name) )
+                {
+                        names = g_list_insert_sorted (names, name2,
+                                                      (GCompareFunc)lgl_str_part_name_cmp);
+                }
+        }
+
+       for (p_tmplt = templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
+        {
+               template2 = (lglTemplate *) p_tmplt->data;
+
+                if ( lgl_template_are_templates_identical (template1, template2) )
+                {
+                       for (p_alias = template2->aliases; p_alias != NULL; p_alias = p_alias->next)
+                        {
+                                alias = (lglTemplateAlias *)p_alias->data;
+
+                                name2 = g_strdup_printf ("%s %s", alias->brand, alias->part);
+                                if ( !UTF8_EQUAL (name2, name) )
+                                {
+                                        names = g_list_insert_sorted (names, name2,
+                                                                      (GCompareFunc)lgl_str_part_name_cmp);
+                                }
+                       }
+               }
+       }
+
+       return names;
+}
+
+
 /**
  * lgl_db_free_template_name_list:
  * @names: List of template name strings to be freed.
@@ -1819,7 +1890,7 @@ template_full_page (const gchar *paper_id)
        }
 
        part = g_strdup_printf ("%s-Full-Page", paper->id);
-       desc = g_strdup_printf (_("Generic %s full page template"), paper->name);
+       desc = g_strdup_printf (_("%s full page label"), paper->name);
 
        template = lgl_template_new ("Generic", part, desc,
                                      paper_id, paper->width, paper->height);
index 3fd9f3a8bfafe82da68d70a17facd99cfeea7c1c..343573eb85b8d979a02c2bb68603a6f547e20bd7 100644 (file)
@@ -130,6 +130,8 @@ GList         *lgl_db_get_template_name_list_all     (const gchar         *brand
                                                       const gchar         *paper_id,
                                                       const gchar         *category_id);
 
+GList         *lgl_db_get_similar_template_name_list (const gchar         *name);
+
 void           lgl_db_free_template_name_list        (GList               *names);
 
 lglTemplate   *lgl_db_lookup_template_from_name      (const gchar         *name);
@@ -149,6 +151,8 @@ void           lgl_db_print_known_templates          (void);
 
 void           lgl_db_print_aliases                  (const lglTemplate    *template);
 
+void           lgl_db_print_known_vendors            (void);
+
 
 
 G_END_DECLS
index e93a9913756c6adb5bd9e3246a8a7ad95f761f0c..0f0339bafde6589292579c9487d9cc2723b2085f 100644 (file)
  *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-//#include <config.h>
+#include <config.h>
 
 #include "str.h"
 
 #include <string.h>
+#include <math.h>
+
+#define FRAC_EPSILON 0.00005
+
 
 /*===========================================*/
 /* Private types                             */
@@ -217,6 +221,41 @@ span_non_digits (gchar **p)
 }
 
 
+/****************************************************************************/
+/* Create fractional representation of number, if possible.                 */
+/****************************************************************************/
+gchar *
+lgl_str_format_fraction (gdouble x)
+{
+       static gdouble denom[] = { 1., 2., 3., 4., 8., 16., 32., 0. };
+       gint i;
+       gdouble product, remainder;
+       gint n, d;
+
+       for ( i=0; denom[i] != 0.0; i++ ) {
+               product = x * denom[i];
+               remainder = fabs(product - ((gint)(product+0.5)));
+               if ( remainder < FRAC_EPSILON ) break;
+       }
+
+       if ( denom[i] == 0.0 ) {
+               /* None of our denominators work. */
+               return g_strdup_printf ("%.5g", x);
+       }
+       if ( denom[i] == 1.0 ) {
+               /* Simple integer. */
+               return g_strdup_printf ("%d", (gint)x);
+       }
+       n = (gint)( x * denom[i] + 0.5 );
+       d = (gint)denom[i];
+       if ( n > d ) {
+               return g_strdup_printf ("%d_%d/%d", (n/d), (n%d), d);
+       } else {
+               return g_strdup_printf ("%d/%d", (n%d), d);
+       }
+}
+
+
 
 /*
  * Local Variables:       -- emacs
index 2675029d80d487188d8c8f99c16beed341058c87..b22f13b53c5661d2a3b44007cff3e45a691d1e24 100644 (file)
 
 G_BEGIN_DECLS
 
-gint  lgl_str_utf8_casecmp  (const gchar *s1,
-                             const gchar *s2);
+gint   lgl_str_utf8_casecmp    (const gchar *s1,
+                                const gchar *s2);
 
-gint  lgl_str_part_name_cmp (const gchar *s1,
-                             const gchar *s2);
+gint   lgl_str_part_name_cmp   (const gchar *s1,
+                                const gchar *s2);
+
+gchar *lgl_str_format_fraction (gdouble      x);
 
 G_END_DECLS
 
index 0af4e5deda2a72111bf1f864a5aee5451ed699a7..50271fbb890e442be80157eba52c4fa98a943595 100644 (file)
@@ -180,7 +180,7 @@ lgl_template_get_name (const lglTemplate  *template)
  * This function tests if the given templates match.  This is a simple test that only tests
  * the brand and part name/number. It does not test if they are actually identical.
  *
- * Returns:  TRUE if the two template matche.
+ * Returns:  TRUE if the two templates match.
  *
  */
 gboolean
@@ -283,6 +283,108 @@ lgl_template_does_category_match  (const lglTemplate  *template,
 }
 
 
+/**
+ * lgl_template_are_templates_identical:
+ *   @template1:  Pointer to 1st template structure to test
+ *   @template2:  Pointer to 2nd template structure to test
+ *
+ * This function tests if the given templates have identical size and layout properties.
+ *
+ * Returns:  TRUE if the two templates are identical.
+ *
+ */
+gboolean
+lgl_template_are_templates_identical (const lglTemplate   *template1,
+                                      const lglTemplate   *template2)
+{
+        lglTemplateFrame  *frame1;
+        lglTemplateFrame  *frame2;
+        GList             *p1;
+        GList             *p2;
+        lglTemplateLayout *layout1;
+        lglTemplateLayout *layout2;
+        gboolean           match_found;
+
+
+        if (!UTF8_EQUAL (template1->paper_id, template2->paper_id) ||
+            (template1->page_width  != template2->page_width)      ||
+            (template1->page_height != template2->page_height))
+        {
+                return FALSE;
+        }
+
+        frame1 = (lglTemplateFrame *)template1->frames->data;
+        frame2 = (lglTemplateFrame *)template2->frames->data;
+
+        if ( frame1->shape != frame2->shape )
+        {
+                return FALSE;
+        }
+
+        switch ( frame1->shape )
+        {
+
+        case LGL_TEMPLATE_FRAME_SHAPE_RECT:
+                if ((frame1->rect.w != frame2->rect.w) ||
+                    (frame1->rect.h != frame2->rect.h))
+                {
+                        return FALSE;
+                }
+                break;
+
+        case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
+                if ((frame1->ellipse.w != frame2->ellipse.w) ||
+                    (frame1->ellipse.h != frame2->ellipse.h))
+                {
+                        return FALSE;
+                }
+                break;
+
+        case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
+                if ((frame1->round.r != frame2->round.r))
+                {
+                        return FALSE;
+                }
+                break;
+
+        case LGL_TEMPLATE_FRAME_SHAPE_CD:
+                if ((frame1->cd.r1 != frame2->cd.r1) ||
+                    (frame1->cd.r2 != frame2->cd.r2))
+                {
+                        return FALSE;
+                }
+        }
+
+        for ( p1 = frame1->all.layouts; p1; p1 = p1->next )
+        {
+                layout1 = (lglTemplateLayout *)p1->data;
+
+                match_found = FALSE;
+                for ( p2 = frame2->all.layouts; p2 && !match_found; p2 = p2->next )
+                {
+                        layout2 = (lglTemplateLayout *)p2->data;
+
+                        if ( (layout1->nx == layout2->nx) &&
+                             (layout1->ny == layout2->ny) &&
+                             (layout1->x0 == layout2->x0) &&
+                             (layout1->y0 == layout2->y0) &&
+                             (layout1->dx == layout2->dx) &&
+                             (layout1->dy == layout2->dy) )
+                        {
+                                match_found = TRUE;
+                        }
+
+                }
+                if ( !match_found )
+                {
+                        return FALSE;
+                }
+        }
+
+        return TRUE;
+}
+
+
 /**
  * lgl_template_alias_new:
  *   @brand:        Alias brand
@@ -588,6 +690,134 @@ lgl_template_frame_get_n_labels (const lglTemplateFrame *frame)
 }
 
 
+/**
+ * lgl_template_frame_get_layout_description
+ * @frame: #lglTemplateFrame structure to query
+ *
+ * Get a description of the label layout including number of labels per sheet.
+ *
+ * Returns: a newly allocation description string.
+ *
+ */
+gchar *
+lgl_template_frame_get_layout_description (const lglTemplateFrame *frame)
+{
+        gint                    n_labels;
+        gchar                  *string;
+        lglTemplateLayout      *layout;
+
+        n_labels = lgl_template_frame_get_n_labels (frame);
+
+        if ( frame->all.layouts && (frame->all.layouts->next == NULL) )
+        {
+                layout = (lglTemplateLayout *)frame->all.layouts->data;
+                string = g_strdup_printf ("%d Ã— %d (%d %s)", layout->nx, layout->ny, n_labels, _("per sheet"));
+        }
+        else
+        {
+                string = g_strdup_printf (_("%d %s"), n_labels, _("per sheet"));
+        }
+
+        return string;
+}
+
+
+/**
+ * lgl_template_frame_get_size_description
+ * @frame: #lglTemplateFrame structure to query
+ * @units: #lglUnits
+ *
+ * Get a description of the label size.
+ *
+ * Returns: a newly allocation description string.
+ *
+ */
+gchar *
+lgl_template_frame_get_size_description (const lglTemplateFrame *frame,
+                                         lglUnits                units)
+{
+        const gchar               *units_string;
+        gdouble                    units_per_point;
+        gchar                     *string = NULL;
+
+        units_string    = lgl_units_get_name (units);
+        units_per_point = lgl_units_get_units_per_point (units);
+
+        switch (frame->shape) {
+        case LGL_TEMPLATE_FRAME_SHAPE_RECT:
+                if ( units == LGL_UNITS_INCH ) {
+                        gchar *xstr, *ystr;
+
+                        xstr = lgl_str_format_fraction (frame->rect.w*units_per_point);
+                        ystr = lgl_str_format_fraction (frame->rect.h*units_per_point);
+                        string = g_strdup_printf ("%s Ã— %s %s",
+                                                  xstr, ystr, units_string);
+                        g_free (xstr);
+                        g_free (ystr);
+                } else {
+                        string = g_strdup_printf ("%.5g Ã— %.5g %s",
+                                                  frame->rect.w*units_per_point,
+                                                  frame->rect.h*units_per_point,
+                                                  units_string);
+                }
+                break;
+        case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
+                if ( units == LGL_UNITS_INCH ) {
+                        gchar *xstr, *ystr;
+
+                        xstr = lgl_str_format_fraction (frame->ellipse.w*units_per_point);
+                        ystr = lgl_str_format_fraction (frame->ellipse.h*units_per_point);
+                        string = g_strdup_printf ("%s Ã— %s %s",
+                                                  xstr, ystr, units_string);
+                        g_free (xstr);
+                        g_free (ystr);
+                } else {
+                        string = g_strdup_printf ("%.5g Ã— %.5g %s",
+                                                  frame->ellipse.w*units_per_point,
+                                                  frame->ellipse.h*units_per_point,
+                                                  units_string);
+                }
+                break;
+        case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
+                if ( units == LGL_UNITS_INCH ) {
+                        gchar *dstr;
+
+                        dstr = lgl_str_format_fraction (2.0*frame->round.r*units_per_point);
+                        string = g_strdup_printf ("%s %s %s",
+                                                  dstr, units_string,
+                                                  _("diameter"));
+                        g_free (dstr);
+                } else {
+                        string = g_strdup_printf ("%.5g %s %s",
+                                                  2.0*frame->round.r*units_per_point,
+                                                  units_string,
+                                                  _("diameter"));
+                }
+                break;
+        case LGL_TEMPLATE_FRAME_SHAPE_CD:
+                if ( units == LGL_UNITS_INCH ) {
+                        gchar *dstr;
+
+                        dstr = lgl_str_format_fraction (2.0*frame->cd.r1*units_per_point);
+                        string = g_strdup_printf ("%s %s %s",
+                                                  dstr, units_string,
+                                                  _("diameter"));
+                        g_free (dstr);
+                } else {
+                        string = g_strdup_printf ("%.5g %s %s",
+                                                  2.0*frame->cd.r1*units_per_point,
+                                                  units_string,
+                                                  _("diameter"));
+                }
+                break;
+        default:
+                break;
+        }
+
+        return string;
+}
+
+
 /**
  * lgl_template_frame_get_origins:
  * @frame: #lglTemplateFrame structure to query
index 6adfa83e2a3c47386bfd0db9794376a54e6a73a8..a3c01115cec276de1bdb58c828f44bdf7fbf2ac5 100644 (file)
@@ -22,6 +22,7 @@
 #define __LGL_TEMPLATE_H__
 
 #include <glib.h>
+#include "units.h"
 
 G_BEGIN_DECLS
 
@@ -285,19 +286,24 @@ struct _lglTemplateOrigin {
 /* 
  * Template query functions
  */
-gchar                     *lgl_template_get_name             (const lglTemplate   *template);
+gchar                     *lgl_template_get_name                (const lglTemplate   *template);
 
-gboolean                   lgl_template_do_templates_match   (const lglTemplate   *template1,
-                                                              const lglTemplate   *template2);
+gboolean                   lgl_template_do_templates_match      (const lglTemplate   *template1,
+                                                                 const lglTemplate   *template2);
 
-gboolean                   lgl_template_does_brand_match     (const lglTemplate   *template,
-                                                              const gchar         *brand);
+gboolean                   lgl_template_does_brand_match        (const lglTemplate   *template,
+                                                                 const gchar         *brand);
+
+gboolean                   lgl_template_does_page_size_match    (const lglTemplate   *template,
+                                                                 const gchar         *paper_id);
+
+gboolean                   lgl_template_does_category_match     (const lglTemplate   *template,
+                                                                 const gchar         *category_id);
+
+gboolean                   lgl_template_are_templates_identical (const lglTemplate   *template1,
+                                                                 const lglTemplate   *template2);
 
-gboolean                   lgl_template_does_page_size_match (const lglTemplate   *template,
-                                                              const gchar         *paper_id);
 
-gboolean                   lgl_template_does_category_match  (const lglTemplate   *template,
-                                                              const gchar         *category_id);
 
 
 /*
@@ -311,6 +317,13 @@ gint                 lgl_template_frame_get_n_labels   (const lglTemplateFrame
 
 lglTemplateOrigin   *lgl_template_frame_get_origins    (const lglTemplateFrame    *frame);
 
+gchar               *lgl_template_frame_get_layout_description (const lglTemplateFrame *frame);
+
+gchar               *lgl_template_frame_get_size_description   (const lglTemplateFrame *frame,
+                                                                lglUnits                units);
+
+
+
 
 /*
  * Template Construction
index cf0b81a5ffda3c0a5ec514b32dfca6417a5be56a..49e6e0ef26952712584dc4fa5346fe359005ec6b 100644 (file)
@@ -162,8 +162,12 @@ glabels_3_SOURCES =                        \
        mini-preview-pixbuf.h           \
        mini-preview-pixbuf-cache.c     \
        mini-preview-pixbuf-cache.h     \
-       media-select.c                  \
-       media-select.h                  \
+       media-combo.c                   \
+       media-combo.h                   \
+       media-combo-menu.c              \
+       media-combo-menu.h              \
+       media-combo-menu-item.c         \
+       media-combo-menu-item.h         \
        message-bar.c                   \
        message-bar.h                   \
        template-history.c              \
diff --git a/src/media-combo-menu-item.c b/src/media-combo-menu-item.c
new file mode 100644 (file)
index 0000000..0c3225f
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ *  media-combo-menu-item.c
+ *  Copyright (C) 2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of gLabels.
+ *
+ *  gLabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  gLabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "media-combo-menu-item.h"
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include <libglabels/libglabels.h>
+#include "mini-preview-pixbuf-cache.h"
+#include "prefs.h"
+#include "str-util.h"
+#include "marshal.h"
+
+
+
+/*===========================================*/
+/* Private macros and constants.             */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Private types                             */
+/*===========================================*/
+
+struct _glMediaComboMenuItemPrivate {
+
+        gchar *name;
+
+};
+
+
+/*===========================================*/
+/* Private globals                           */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Local function prototypes                 */
+/*===========================================*/
+
+static void   gl_media_combo_menu_item_finalize    (GObject                *object);
+
+
+/****************************************************************************/
+/* Boilerplate Object stuff.                                                */
+/****************************************************************************/
+G_DEFINE_TYPE (glMediaComboMenuItem, gl_media_combo_menu_item, GTK_TYPE_MENU_ITEM);
+
+
+/*****************************************************************************/
+/* Class Init Function.                                                      */
+/*****************************************************************************/
+static void
+gl_media_combo_menu_item_class_init (glMediaComboMenuItemClass *class)
+{
+       GObjectClass   *gobject_class = G_OBJECT_CLASS (class);
+
+        gl_media_combo_menu_item_parent_class = g_type_class_peek_parent (class);
+
+       gobject_class->finalize = gl_media_combo_menu_item_finalize;
+}
+
+
+/*****************************************************************************/
+/* Object Instance Init Function.                                            */
+/*****************************************************************************/
+static void
+gl_media_combo_menu_item_init (glMediaComboMenuItem *this)
+{
+       this->priv = g_new0 (glMediaComboMenuItemPrivate, 1);
+}
+
+
+/*****************************************************************************/
+/* Finalize Method.                                                          */
+/*****************************************************************************/
+static void
+gl_media_combo_menu_item_finalize (GObject *object)
+{
+       glMediaComboMenuItem *this = GL_MEDIA_COMBO_MENU_ITEM (object);
+
+       g_return_if_fail (object != NULL);
+       g_return_if_fail (GL_IS_MEDIA_COMBO_MENU_ITEM (object));
+
+        g_free (this->priv->name);
+       g_free (this->priv);
+
+       G_OBJECT_CLASS (gl_media_combo_menu_item_parent_class)->finalize (object);
+}
+
+
+/*****************************************************************************/
+/** New Object Generator.                                                    */
+/*****************************************************************************/
+GtkWidget *
+gl_media_combo_menu_item_new (gchar *name)
+{
+       glMediaComboMenuItem *this;
+        GtkWidget            *hbox;
+        GtkWidget            *preview;
+        GtkWidget            *label;
+        GdkPixbuf            *pixbuf;
+        lglTemplate          *template;
+        lglTemplateFrame     *frame;
+        gchar                *size_string;
+        gchar                *layout_string;
+        gchar                *label_markup;
+
+       this = g_object_new (GL_TYPE_MEDIA_COMBO_MENU_ITEM, NULL);
+
+        this->priv->name = g_strdup (name);
+
+        hbox = gtk_hbox_new (FALSE, 6);
+        gtk_container_add (GTK_CONTAINER (this), hbox);
+
+        pixbuf = gl_mini_preview_pixbuf_cache_get_pixbuf (name);
+        preview = gtk_image_new_from_pixbuf (pixbuf);
+        gtk_box_pack_start (GTK_BOX (hbox), preview, FALSE, FALSE, 0);
+        g_object_unref (G_OBJECT (pixbuf));
+
+        template      = lgl_db_lookup_template_from_name (name);
+        frame         = (lglTemplateFrame *)template->frames->data;
+        size_string   = lgl_template_frame_get_size_description (frame, gl_prefs_model_get_units (gl_prefs));
+        layout_string = lgl_template_frame_get_layout_description (frame);
+        label_markup  = g_strdup_printf ("<b>%s: %s</b>\n%s\n%s",
+                                         name, template->description, size_string, layout_string);
+        g_free (size_string);
+        g_free (layout_string);
+        lgl_template_free (template);
+
+        label = gtk_label_new (NULL);
+        gtk_label_set_markup (GTK_LABEL (label), label_markup);
+        g_free (label_markup);
+        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+       return GTK_WIDGET (this);
+}
+
+
+/*****************************************************************************/
+/* Get family.                                                               */
+/*****************************************************************************/
+gchar *
+gl_media_combo_menu_item_get_name (glMediaComboMenuItem *this)
+{
+        return g_strdup (this->priv->name);
+}
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/src/media-combo-menu-item.h b/src/media-combo-menu-item.h
new file mode 100644 (file)
index 0000000..4aa6ad4
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *  media-combo-menu-item.h
+ *  Copyright (C) 2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of gLabels.
+ *
+ *  gLabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  gLabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MEDIA_COMBO_MENU_ITEM_H__
+#define __MEDIA_COMBO_MENU_ITEM_H__
+
+
+#include <gtk/gtk.h>
+
+
+G_BEGIN_DECLS
+
+#define GL_TYPE_MEDIA_COMBO_MENU_ITEM (gl_media_combo_menu_item_get_type ())
+#define GL_MEDIA_COMBO_MENU_ITEM(obj) \
+        (G_TYPE_CHECK_INSTANCE_CAST((obj), GL_TYPE_MEDIA_COMBO_MENU_ITEM, glMediaComboMenuItem ))
+#define GL_MEDIA_COMBO_MENU_ITEM_CLASS(klass) \
+        (G_TYPE_CHECK_CLASS_CAST ((klass), GL_TYPE_MEDIA_COMBO_MENU_ITEM, glMediaComboMenuItemClass))
+#define GL_IS_MEDIA_COMBO_MENU_ITEM(obj) \
+        (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GL_TYPE_MEDIA_COMBO_MENU_ITEM))
+#define GL_IS_MEDIA_COMBO_MENU_ITEM_CLASS(klass) \
+        (G_TYPE_CHECK_CLASS_TYPE ((klass), GL_TYPE_MEDIA_COMBO_MENU_ITEM))
+
+typedef struct _glMediaComboMenuItem        glMediaComboMenuItem;
+typedef struct _glMediaComboMenuItemPrivate glMediaComboMenuItemPrivate;
+typedef struct _glMediaComboMenuItemClass   glMediaComboMenuItemClass;
+
+struct _glMediaComboMenuItem {
+       GtkMenuItem            parent_widget;
+
+       glMediaComboMenuItemPrivate *priv;
+};
+
+struct _glMediaComboMenuItemClass {
+       GtkMenuItemClass       parent_class;
+};
+
+
+GType      gl_media_combo_menu_item_get_type   (void) G_GNUC_CONST;
+
+GtkWidget *gl_media_combo_menu_item_new        (gchar                *name);
+
+gchar     *gl_media_combo_menu_item_get_name   (glMediaComboMenuItem *this);
+
+
+G_END_DECLS
+
+#endif /* __MEDIA_COMBO_MENU_ITEM_H__ */
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/src/media-combo-menu.c b/src/media-combo-menu.c
new file mode 100644 (file)
index 0000000..4f117d5
--- /dev/null
@@ -0,0 +1,332 @@
+/*
+ *  media-combo-menu.c
+ *  Copyright (C) 2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of gLabels.
+ *
+ *  gLabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  gLabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "media-combo-menu.h"
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include <libglabels/libglabels.h>
+#include "media-combo-menu-item.h"
+#include "template-history.h"
+#include "marshal.h"
+
+
+/*===========================================*/
+/* Private macros and constants.             */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Private types                             */
+/*===========================================*/
+
+struct _glMediaComboMenuPrivate {
+
+        gchar     *media;
+
+        GtkWidget *recent_menu_item;
+        GtkWidget *recent_sub_menu;
+
+};
+
+enum {
+        MEDIA_CHANGED,
+        LAST_SIGNAL
+};
+
+
+/*===========================================*/
+/* Private globals                           */
+/*===========================================*/
+
+static guint signals[LAST_SIGNAL] = {0};
+
+
+/*===========================================*/
+/* Local function prototypes                 */
+/*===========================================*/
+
+static void       gl_media_combo_menu_finalize (GObject             *object);
+
+static void       menu_item_activate_cb        (glMediaComboMenuItem *item,
+                                                glMediaComboMenu     *this);
+
+static GtkWidget *new_brand_sub_menu           (glMediaComboMenu     *this,
+                                                const gchar          *paper_id,
+                                                const GList          *brand_list);
+
+static GtkWidget *new_part_sub_menu            (glMediaComboMenu     *this,
+                                                const GList          *part_list);
+
+static void       media_history_changed_cb     (glMediaComboMenu     *this);
+
+
+
+/****************************************************************************/
+/* Boilerplate Object stuff.                                                */
+/****************************************************************************/
+G_DEFINE_TYPE (glMediaComboMenu, gl_media_combo_menu, GTK_TYPE_MENU);
+
+
+/*****************************************************************************/
+/* Class Init Function.                                                      */
+/*****************************************************************************/
+static void
+gl_media_combo_menu_class_init (glMediaComboMenuClass *class)
+{
+       GObjectClass   *gobject_class = G_OBJECT_CLASS (class);
+
+        gl_media_combo_menu_parent_class = g_type_class_peek_parent (class);
+
+       gobject_class->finalize = gl_media_combo_menu_finalize;
+
+        signals[MEDIA_CHANGED] =
+                g_signal_new ("media_changed",
+                              G_OBJECT_CLASS_TYPE (gobject_class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (glMediaComboMenuClass, media_changed),
+                              NULL, NULL,
+                              gl_marshal_VOID__VOID,
+                              G_TYPE_NONE, 0);
+}
+
+
+/*****************************************************************************/
+/* Object Instance Init Function.                                            */
+/*****************************************************************************/
+static void
+gl_media_combo_menu_init (glMediaComboMenu *this)
+{
+        GtkWidget    *menu_item;
+        GtkWidget    *sub_menu;
+        const GList  *list;
+        GList        *paper_id_list, *p_id;
+        gchar        *paper_id, *paper_name;
+        GList        *brand_list;
+
+       this->priv = g_new0 (glMediaComboMenuPrivate, 1);
+
+
+        menu_item = gtk_menu_item_new_with_label (_("Recent templates"));
+        gtk_menu_shell_append (GTK_MENU_SHELL (this), menu_item);
+
+        list = gl_template_history_model_get_name_list (gl_template_history);
+        sub_menu = new_part_sub_menu (this, list);
+        gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
+        gtk_widget_set_sensitive (menu_item, list != NULL);
+
+        this->priv->recent_menu_item = menu_item;
+        this->priv->recent_sub_menu  = sub_menu;
+
+        menu_item = gtk_separator_menu_item_new ();
+        gtk_menu_shell_append (GTK_MENU_SHELL (this), menu_item);
+
+        paper_id_list = lgl_db_get_paper_id_list ();
+
+        for ( p_id = paper_id_list; p_id; p_id = p_id->next )
+        {
+                paper_id = p_id->data;
+                paper_name = lgl_db_lookup_paper_name_from_id (paper_id);
+
+                brand_list = lgl_db_get_brand_list (paper_id, NULL);
+                if ( brand_list )
+                {
+                        menu_item = gtk_menu_item_new_with_label (paper_name);
+                        gtk_menu_shell_append (GTK_MENU_SHELL (this), menu_item);
+
+                        sub_menu = new_brand_sub_menu (this, paper_id, brand_list);
+                        gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
+                }
+                lgl_db_free_brand_list ( brand_list );
+        }
+
+        lgl_db_free_paper_id_list (paper_id_list);
+
+        g_signal_connect_swapped (gl_template_history, "changed",
+                                  G_CALLBACK (media_history_changed_cb), this);
+
+}
+
+
+/*****************************************************************************/
+/* Finalize Method.                                                          */
+/*****************************************************************************/
+static void
+gl_media_combo_menu_finalize (GObject *object)
+{
+       glMediaComboMenu *this = GL_MEDIA_COMBO_MENU (object);
+
+       g_return_if_fail (object != NULL);
+       g_return_if_fail (GL_IS_MEDIA_COMBO_MENU (object));
+
+       g_free (this->priv);
+
+       G_OBJECT_CLASS (gl_media_combo_menu_parent_class)->finalize (object);
+}
+
+
+/*****************************************************************************/
+/** New Object Generator.                                                    */
+/*****************************************************************************/
+GtkWidget *
+gl_media_combo_menu_new (void)
+{
+       glMediaComboMenu *this;
+
+       this = g_object_new (gl_media_combo_menu_get_type (), NULL);
+
+       return GTK_WIDGET (this);
+}
+
+
+/*****************************************************************************/
+/* menu_item activate callback.                                              */
+/*****************************************************************************/
+static void menu_item_activate_cb (glMediaComboMenuItem *item,
+                                   glMediaComboMenu     *this)
+{
+        this->priv->media = gl_media_combo_menu_item_get_name (item);
+
+        g_signal_emit (this, signals[MEDIA_CHANGED], 0);
+
+        gtk_widget_hide (GTK_WIDGET (this));
+}
+
+
+/*****************************************************************************/
+/* Get media name.                                                           */
+/*****************************************************************************/
+gchar *
+gl_media_combo_menu_get_name (glMediaComboMenu *this)
+{
+        return g_strdup (this->priv->media);
+}
+
+
+/*****************************************************************************/
+/* Create a new brand sub menu from media list.                              */
+/*****************************************************************************/
+static GtkWidget *
+new_brand_sub_menu (glMediaComboMenu *this,
+                    const gchar      *paper_id,
+                    const GList      *brand_list)
+{
+        GtkWidget   *menu;
+        GtkWidget   *menu_item;
+        GtkWidget    *sub_menu;
+        GList       *p_brand;
+        gchar       *brand;
+        GList       *part_list;
+
+        menu = gtk_menu_new ();
+
+        for ( p_brand = (GList *)brand_list; p_brand; p_brand = p_brand->next )
+        {
+                brand = p_brand->data;
+
+                part_list = lgl_db_get_template_name_list_all (brand, paper_id, NULL);
+                if ( part_list )
+                {
+                        menu_item = gtk_menu_item_new_with_label (brand);
+                        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+
+                        sub_menu = new_part_sub_menu (this, part_list);
+                        gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
+                }
+                lgl_db_free_brand_list ( part_list );
+        }
+
+        gtk_widget_show (menu);
+
+        return menu;
+}
+
+
+/*****************************************************************************/
+/* Create a new part sub menu from part list.                                */
+/*****************************************************************************/
+static GtkWidget *
+new_part_sub_menu (glMediaComboMenu *this,
+                   const GList      *part_list)
+{
+        GtkWidget   *menu;
+        GtkWidget   *menu_item;
+        GList       *p;
+
+        menu = gtk_menu_new ();
+
+        for ( p = (GList *)part_list; p != NULL; p = p->next )
+        {
+                menu_item = gl_media_combo_menu_item_new (p->data);
+                gtk_widget_show_all (menu_item);
+                gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+                g_signal_connect (menu_item, "activate",
+                                  G_CALLBACK (menu_item_activate_cb), this);
+        }
+
+        gtk_widget_show (menu);
+        return menu;
+}
+
+
+/*****************************************************************************/
+/* Media history changed callback.                                           */
+/*****************************************************************************/
+static void
+media_history_changed_cb (glMediaComboMenu     *this)
+{
+        GList *list;
+
+        /*
+         * Remove old sub menu
+         */
+        gtk_menu_item_set_submenu (GTK_MENU_ITEM (this->priv->recent_menu_item),
+                                   NULL);
+
+        /*
+         * Build new sub menu
+         */
+        list = gl_template_history_model_get_name_list (gl_template_history);
+        this->priv->recent_sub_menu = new_part_sub_menu (this, list);
+
+        /*
+         * Attach to top-level menu item
+         */
+        gtk_menu_item_set_submenu (GTK_MENU_ITEM (this->priv->recent_menu_item),
+                                   this->priv->recent_sub_menu);
+        gtk_widget_set_sensitive (this->priv->recent_menu_item, list != NULL);
+
+        gl_template_history_model_free_name_list (list);
+}
+
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/src/media-combo-menu.h b/src/media-combo-menu.h
new file mode 100644 (file)
index 0000000..5c83e58
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  media-combo-menu.h
+ *  Copyright (C) 2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of gLabels.
+ *
+ *  gLabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  gLabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MEDIA_COMBO_MENU_H__
+#define __MEDIA_COMBO_MENU_H__
+
+#include <gtk/gtk.h>
+
+
+G_BEGIN_DECLS
+
+#define GL_TYPE_MEDIA_COMBO_MENU (gl_media_combo_menu_get_type ())
+#define GL_MEDIA_COMBO_MENU(obj) \
+        (G_TYPE_CHECK_INSTANCE_CAST((obj), GL_TYPE_MEDIA_COMBO_MENU, glMediaComboMenu ))
+#define GL_MEDIA_COMBO_MENU_CLASS(klass) \
+        (G_TYPE_CHECK_CLASS_CAST ((klass), GL_TYPE_MEDIA_COMBO_MENU, glMediaComboMenuClass))
+#define GL_IS_MEDIA_COMBO_MENU(obj) \
+        (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GL_TYPE_MEDIA_COMBO_MENU))
+#define GL_IS_MEDIA_COMBO_MENU_CLASS(klass) \
+        (G_TYPE_CHECK_CLASS_TYPE ((klass), GL_TYPE_MEDIA_COMBO_MENU))
+
+typedef struct _glMediaComboMenu        glMediaComboMenu;
+typedef struct _glMediaComboMenuPrivate glMediaComboMenuPrivate;
+typedef struct _glMediaComboMenuClass   glMediaComboMenuClass;
+
+struct _glMediaComboMenu {
+       GtkMenu                  parent_widget;
+
+       glMediaComboMenuPrivate *priv;
+};
+
+struct _glMediaComboMenuClass {
+       GtkMenuClass             parent_class;
+
+        /*
+         * Signals
+         */
+        void (*media_changed) (glMediaComboMenu *object,
+                               gpointer          user_data);
+
+};
+
+
+GType      gl_media_combo_menu_get_type     (void) G_GNUC_CONST;
+
+GtkWidget *gl_media_combo_menu_new          (void);
+
+gchar     *gl_media_combo_menu_get_name     (glMediaComboMenu *this);
+
+
+G_END_DECLS
+
+
+#endif /* __MEDIA_COMBO_MENU_H__ */
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
+
diff --git a/src/media-combo.c b/src/media-combo.c
new file mode 100644 (file)
index 0000000..6c7104e
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+ *  media-combo.c
+ *  Copyright (C) 2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of gLabels.
+ *
+ *  gLabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  gLabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "media-combo.h"
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "media-combo-menu.h"
+#include "marshal.h"
+
+
+
+/*========================================================*/
+/* Private types.                                         */
+/*========================================================*/
+
+/** GL_MEDIA_COMBO Private fields */
+struct _glMediaComboPrivate {
+
+        gchar      *name;
+
+        GtkWidget  *label;
+
+        GtkWidget  *menu;
+};
+
+enum {
+        CHANGED,
+        LAST_SIGNAL
+};
+
+
+/*========================================================*/
+/* Private globals.                                       */
+/*========================================================*/
+
+static guint signals[LAST_SIGNAL] = {0};
+
+
+/*========================================================*/
+/* Private function prototypes.                           */
+/*========================================================*/
+
+static void gl_media_combo_finalize      (GObject             *object);
+
+static gboolean
+button_press_event_cb   (GtkWidget         *widget,
+                         GdkEventButton    *event,
+                         glMediaCombo      *this);
+
+static void
+menu_media_changed_cb   (glMediaComboMenu  *menu,
+                         glMediaCombo      *this);
+
+static void
+menu_selection_done_cb  (GtkMenuShell      *object,
+                         glMediaCombo      *this);
+
+
+/*****************************************************************************/
+/* Object infrastructure.                                                    */
+/*****************************************************************************/
+G_DEFINE_TYPE (glMediaCombo, gl_media_combo, GTK_TYPE_TOGGLE_BUTTON);
+
+
+/*****************************************************************************/
+/* Class Init Function.                                                      */
+/*****************************************************************************/
+static void
+gl_media_combo_class_init (glMediaComboClass *class)
+{
+        GObjectClass      *gobject_class = (GObjectClass *) class;
+
+        gl_media_combo_parent_class = g_type_class_peek_parent (class);
+
+        gobject_class->finalize = gl_media_combo_finalize;
+
+        signals[CHANGED] =
+                g_signal_new ("changed",
+                              G_OBJECT_CLASS_TYPE (gobject_class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (glMediaComboClass, changed),
+                              NULL, NULL,
+                              gl_marshal_VOID__VOID,
+                              G_TYPE_NONE, 0);
+}
+
+
+/*****************************************************************************/
+/* Object Instance Init Function.                                            */
+/*****************************************************************************/
+static void
+gl_media_combo_init (glMediaCombo *this)
+{
+        GtkWidget *hbox;
+        GtkWidget *arrow;
+
+        this->priv = g_new0 (glMediaComboPrivate, 1);
+
+        hbox = gtk_hbox_new (FALSE, 3);
+        gtk_container_add (GTK_CONTAINER (this), hbox);
+        
+        this->priv->label = gtk_label_new ("");
+        gtk_misc_set_alignment (GTK_MISC (this->priv->label), 0.0, 0.5);
+       gtk_widget_set_size_request (this->priv->label, 180, -1);
+        gtk_box_pack_start (GTK_BOX (hbox), this->priv->label, TRUE, TRUE, 0);
+
+        arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_IN);
+        gtk_box_pack_end (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
+
+        g_signal_connect (this, "button_press_event",
+                          G_CALLBACK(button_press_event_cb), this);
+}
+
+
+/*****************************************************************************/
+/* Finalize Method.                                                          */
+/*****************************************************************************/
+static void
+gl_media_combo_finalize (GObject *object)
+{
+        glMediaCombo    *this;
+
+        g_return_if_fail (object && IS_GL_MEDIA_COMBO (object));
+        this = GL_MEDIA_COMBO (object);
+
+        g_free (this->priv->name);
+        g_object_ref_sink (this->priv->menu);
+        g_free (this->priv);
+
+        G_OBJECT_CLASS (gl_media_combo_parent_class)->finalize (object);
+}
+
+
+/*****************************************************************************/
+/** New Object Generator.                                                    */
+/*****************************************************************************/
+GtkWidget *
+gl_media_combo_new (void)
+{
+        glMediaCombo  *this;
+
+        this = g_object_new (TYPE_GL_MEDIA_COMBO, NULL);
+
+        this->priv->menu = gl_media_combo_menu_new ();
+
+        gtk_widget_show_all (this->priv->menu);
+
+        g_signal_connect (this->priv->menu, "media_changed",
+                          G_CALLBACK (menu_media_changed_cb), this);
+        g_signal_connect (this->priv->menu, "selection_done",
+                          G_CALLBACK (menu_selection_done_cb), this);
+
+        return GTK_WIDGET (this);
+}
+
+
+/*****************************************************************************/
+/* Set media name.                                                           */
+/*****************************************************************************/
+void
+gl_media_combo_set_name (glMediaCombo  *this,
+                         const gchar   *name)
+{
+
+        g_free (this->priv->name);
+        this->priv->name = g_strdup (name);
+
+        gtk_label_set_text (GTK_LABEL (this->priv->label), this->priv->name);
+}
+
+
+/*****************************************************************************/
+/* Get media name.                                                           */
+/*****************************************************************************/
+gchar *
+gl_media_combo_get_name (glMediaCombo  *this)
+{
+        return g_strdup (this->priv->name);
+}
+
+
+/*****************************************************************************/
+/* Menu positioning function.                                                */
+/*****************************************************************************/
+static void
+menu_position_function (GtkMenu       *menu,
+                        gint          *x,
+                        gint          *y,
+                        gboolean      *push_in,
+                        glMediaCombo  *this)
+{
+        GdkScreen          *screen;
+        gint                w_screen, h_screen;
+        GdkWindow          *window;
+        gint                x_window, y_window;
+        GtkAllocation       allocation;
+        gint                x_this, y_this, h_this;
+        GtkRequisition      menu_requisition;
+        gint                h_menu, w_menu;
+
+        /*
+         * Screen size
+         */
+        screen = gtk_widget_get_screen (GTK_WIDGET (this));
+        w_screen = gdk_screen_get_width (screen);
+        h_screen = gdk_screen_get_height (screen);
+
+        /*
+         * Absolute position of "this" window on screen.
+         */
+        window = gtk_widget_get_window (GTK_WIDGET (this));
+        gdk_window_get_origin (window, &x_window, &y_window);
+
+        /*
+         *  Position and size of "this" inside window
+         */
+        gtk_widget_get_allocation (GTK_WIDGET (this), &allocation);
+        x_this = allocation.x;
+        y_this = allocation.y;
+        h_this = allocation.height;
+
+        /*
+         * Size of menu.
+         */
+        gtk_widget_size_request (this->priv->menu, &menu_requisition);
+        h_menu = menu_requisition.height;
+        w_menu = menu_requisition.width;
+
+        /*
+         * Default position anchored to lower left corner of "this".
+         */
+        *x = x_window + x_this;
+        *y = y_window + y_this + h_this;
+                
+        /*
+         * Adjust vertical position if menu if extends past bottom of screen.
+         */
+        if ( (*y + h_menu) > h_screen )
+        {
+                *y = y_window + y_this - h_menu;
+
+                if ( *y < 0 )
+                {
+                        *y = h_screen - h_menu;
+                }
+        }
+
+        /*
+         * Adjust horizontal position if menu if extends past edge of screen.
+         */
+        if ( (*x + w_menu) > w_screen )
+        {
+                *x = w_screen - w_menu;
+        }
+
+
+        *push_in = TRUE;
+}
+
+
+/*****************************************************************************/
+/* Button "button_press_event" callback.                                     */
+/*****************************************************************************/
+static gboolean
+button_press_event_cb (GtkWidget      *widget,
+                       GdkEventButton *event,
+                       glMediaCombo   *this)
+{
+        switch (event->button)
+        {
+
+        case 1:
+                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this), TRUE);
+
+                gtk_menu_popup (GTK_MENU (this->priv->menu),
+                                NULL, NULL,
+                                (GtkMenuPositionFunc)menu_position_function, this,
+                                event->button, event->time);
+                break;
+
+        default:
+                break;
+
+        }
+
+        return FALSE;
+}
+
+
+/*****************************************************************************/
+/* Menu "media changed" callback.                                            */
+/*****************************************************************************/
+static void
+menu_media_changed_cb (glMediaComboMenu     *menu,
+                       glMediaCombo         *this)
+{
+        this->priv->name = gl_media_combo_menu_get_name (menu);
+
+        gtk_label_set_text (GTK_LABEL (this->priv->label), this->priv->name);
+
+        g_signal_emit (this, signals[CHANGED], 0);
+}
+
+
+/*****************************************************************************/
+/* Menu "selection done" callback.                                           */
+/*****************************************************************************/
+static void
+menu_selection_done_cb (GtkMenuShell         *object,
+                        glMediaCombo         *this)
+{
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this), FALSE);
+}
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/src/media-combo.h b/src/media-combo.h
new file mode 100644 (file)
index 0000000..c413d14
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ *  media-combo.h
+ *  Copyright (C) 2009  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of gLabels.
+ *
+ *  gLabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  gLabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GL_MEDIA_COMBO_H__
+#define __GL_MEDIA_COMBO_H__
+
+
+#include <gtk/gtk.h>
+
+
+G_BEGIN_DECLS
+
+#define TYPE_GL_MEDIA_COMBO              (gl_media_combo_get_type ())
+#define GL_MEDIA_COMBO(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_GL_MEDIA_COMBO, glMediaCombo))
+#define GL_MEDIA_COMBO_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_GL_MEDIA_COMBO, glMediaComboClass))
+#define IS_GL_MEDIA_COMBO(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_GL_MEDIA_COMBO))
+#define IS_GL_MEDIA_COMBO_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_GL_MEDIA_COMBO))
+#define GL_MEDIA_COMBO_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), TYPE_GL_MEDIA_COMBO, glMediaComboClass))
+
+
+typedef struct _glMediaCombo          glMediaCombo;
+typedef struct _glMediaComboPrivate   glMediaComboPrivate;
+typedef struct _glMediaComboClass     glMediaComboClass;
+
+
+struct _glMediaCombo {
+        GtkToggleButton               parent;
+
+        glMediaComboPrivate          *priv;
+};
+
+struct _glMediaComboClass {
+        GtkToggleButtonClass          parent_class;
+
+        /*
+         * Signals
+         */
+        void (*changed) (glMediaCombo *object,
+                         gpointer     user_data);
+
+};
+
+
+GType            gl_media_combo_get_type          (void) G_GNUC_CONST;
+
+GtkWidget       *gl_media_combo_new               (void);
+
+void             gl_media_combo_set_name          (glMediaCombo   *this,
+                                                   const gchar    *name);
+
+gchar           *gl_media_combo_get_name          (glMediaCombo   *this);
+
+
+G_END_DECLS
+
+#endif /* __GL_COLOR_COMBO_H__ */
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/src/media-select.c b/src/media-select.c
deleted file mode 100644 (file)
index 98dc844..0000000
+++ /dev/null
@@ -1,937 +0,0 @@
-/*
- *  media-select.c
- *  Copyright (C) 2001-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of gLabels.
- *
- *  gLabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  gLabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-
-#include "media-select.h"
-
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-#include <string.h>
-
-#include <libglabels.h>
-#include "mini-preview-pixbuf-cache.h"
-#include "prefs.h"
-#include "message-bar.h"
-#include "template-history.h"
-#include "str-util.h"
-#include "combo-util.h"
-#include "builder-util.h"
-#include "color.h"
-#include "marshal.h"
-
-#include "debug.h"
-
-
-#define HISTORY_SIZE 5
-
-/*===========================================*/
-/* Private types                             */
-/*===========================================*/
-
-enum {
-       NAME_COLUMN,
-       PREVIEW_COLUMN,
-       PREVIEW_COLUMN_STOCK,
-       PREVIEW_COLUMN_STOCK_SIZE,
-       DESCRIPTION_COLUMN,
-       N_COLUMNS
-};
-
-struct _glMediaSelectPrivate {
-
-        GtkBuilder   *builder;
-
-        GtkWidget    *notebook;
-        guint         current_page_num;
-
-        gint          recent_page_num;
-        GtkWidget    *recent_tab_vbox;
-        GtkWidget    *recent_info_vbox;
-        GtkWidget    *recent_info_bar;
-        GtkWidget    *recent_treeview;
-        GtkListStore *recent_store;
-
-        gint          search_all_page_num;
-        GtkWidget    *search_all_tab_vbox;
-        GtkWidget    *search_all_info_vbox;
-        GtkWidget    *search_all_info_bar;
-        GtkWidget    *brand_combo;
-        GtkWidget    *page_size_combo;
-        GtkWidget    *category_combo;
-        GtkWidget    *search_all_treeview;
-        GtkListStore *search_all_store;
-
-        /* Prevent recursion */
-       gboolean    stop_signals;
-};
-
-enum {
-        CHANGED,
-        LAST_SIGNAL
-};
-
-
-/*===========================================*/
-/* Private globals                           */
-/*===========================================*/
-
-static gint media_select_signals[LAST_SIGNAL] = { 0 };
-
-
-/*===========================================*/
-/* Local function prototypes                 */
-/*===========================================*/
-
-static void   gl_media_select_finalize   (GObject                *object);
-
-static void   gl_media_select_construct  (glMediaSelect          *this);
-
-static void   filter_changed_cb          (GtkComboBox            *combo,
-                                          gpointer                user_data);
-
-static void   selection_changed_cb       (GtkTreeSelection       *selection,
-                                          gpointer                user_data);
-
-static void   page_changed_cb            (GtkNotebook            *notebook,
-                                          GtkNotebookPage        *page,
-                                          guint                   page_num,
-                                          gpointer                user_data);
-
-static gchar *get_layout_desc            (const lglTemplate      *template);
-
-static gchar *get_label_size_desc        (const lglTemplate      *template);
-
-static void   load_recent_list           (glMediaSelect          *this,
-                                          GtkListStore           *store,
-                                          GtkTreeSelection       *selection,
-                                          GList                  *list);
-
-static void   load_search_all_list       (glMediaSelect          *this,
-                                          GtkListStore           *store,
-                                          GtkTreeSelection       *selection,
-                                          GList                  *list);
-
-
-/****************************************************************************/
-/* Boilerplate Object stuff.                                                */
-/****************************************************************************/
-G_DEFINE_TYPE (glMediaSelect, gl_media_select, GTK_TYPE_VBOX);
-
-
-static void
-gl_media_select_class_init (glMediaSelectClass *class)
-{
-        GObjectClass *object_class = G_OBJECT_CLASS (class);
-
-        gl_debug (DEBUG_MEDIA_SELECT, "START");
-
-        gl_media_select_parent_class = g_type_class_peek_parent (class);
-
-        object_class->finalize = gl_media_select_finalize;
-
-        media_select_signals[CHANGED] =
-            g_signal_new ("changed",
-                          G_OBJECT_CLASS_TYPE(object_class),
-                          G_SIGNAL_RUN_LAST,
-                          G_STRUCT_OFFSET (glMediaSelectClass, changed),
-                          NULL, NULL,
-                          gl_marshal_VOID__VOID,
-                          G_TYPE_NONE, 0);
-
-        gl_debug (DEBUG_MEDIA_SELECT, "END");
-}
-
-
-static void
-gl_media_select_init (glMediaSelect *this)
-{
-        gl_debug (DEBUG_MEDIA_SELECT, "START");
-
-        this->priv = g_new0 (glMediaSelectPrivate, 1);
-
-        gl_debug (DEBUG_MEDIA_SELECT, "END");
-}
-
-
-static void
-gl_media_select_finalize (GObject *object)
-{
-        glMediaSelect *this = GL_MEDIA_SELECT (object);
-
-        gl_debug (DEBUG_MEDIA_SELECT, "START");
-
-        g_return_if_fail (object != NULL);
-        g_return_if_fail (GL_IS_MEDIA_SELECT (object));
-
-        if (this->priv->builder)
-        {
-                g_object_unref (this->priv->builder);
-        }
-        g_object_unref (this->priv->recent_store);
-        g_object_unref (this->priv->search_all_store);
-        g_free (this->priv);
-
-        G_OBJECT_CLASS (gl_media_select_parent_class)->finalize (object);
-
-        gl_debug (DEBUG_MEDIA_SELECT, "END");
-}
-
-
-GtkWidget *
-gl_media_select_new (void)
-{
-        glMediaSelect *this;
-
-        gl_debug (DEBUG_MEDIA_SELECT, "START");
-
-        this = g_object_new (gl_media_select_get_type (), NULL);
-
-        gl_media_select_construct (this);
-
-        gl_debug (DEBUG_MEDIA_SELECT, "END");
-
-        return GTK_WIDGET (this);
-}
-
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Construct composite widget.                                    */
-/*--------------------------------------------------------------------------*/
-static void
-gl_media_select_construct (glMediaSelect *this)
-{
-        gchar             *builder_filename;
-        GtkBuilder        *builder;
-        static gchar      *object_ids[] = { "media_select_hbox", NULL };
-        GError            *error = NULL;
-        GtkWidget         *hbox;
-        GList             *recent_list = NULL;
-        GList             *brands = NULL;
-        GList             *page_sizes = NULL;
-        GList             *categories = NULL;
-        GList             *search_all_names = NULL;
-        const gchar       *page_size_id;
-        gchar             *page_size_name;
-        GtkCellRenderer   *renderer;
-        GtkTreeViewColumn *column;
-        GtkTreeSelection  *recent_selection;
-        GtkTreeSelection  *search_all_selection;
-
-        gl_debug (DEBUG_MEDIA_SELECT, "START");
-
-        g_return_if_fail (GL_IS_MEDIA_SELECT (this));
-        g_return_if_fail (this->priv != NULL);
-
-        builder = gtk_builder_new ();
-        builder_filename = g_build_filename (GLABELS_DATA_DIR, "builder", "media-select.builder", NULL);
-        gtk_builder_add_objects_from_file (builder, builder_filename, object_ids, &error);
-        g_free (builder_filename);
-       if (error) {
-               g_critical ("%s\n\ngLabels may not be installed correctly!", error->message);
-                g_error_free (error);
-               return;
-       }
-
-        gl_builder_util_get_widgets (builder,
-                                     "media_select_hbox",      &hbox,
-                                     "notebook",               &this->priv->notebook,
-                                     "recent_tab_vbox",        &this->priv->recent_tab_vbox,
-                                     "recent_info_vbox",       &this->priv->recent_info_vbox,
-                                     "recent_treeview",        &this->priv->recent_treeview,
-                                     "search_all_tab_vbox",    &this->priv->search_all_tab_vbox,
-                                     "brand_combo",            &this->priv->brand_combo,
-                                     "page_size_combo",        &this->priv->page_size_combo,
-                                     "category_combo",         &this->priv->category_combo,
-                                     "search_all_info_vbox",   &this->priv->search_all_info_vbox,
-                                     "search_all_treeview",    &this->priv->search_all_treeview,
-                                     NULL);
-
-        gtk_container_add (GTK_CONTAINER (this), hbox);
-        this->priv->builder = builder;
-
-        this->priv->recent_page_num =
-                gtk_notebook_page_num (GTK_NOTEBOOK (this->priv->notebook),
-                                       this->priv->recent_tab_vbox);
-        this->priv->search_all_page_num =
-                gtk_notebook_page_num (GTK_NOTEBOOK (this->priv->notebook),
-                                       this->priv->search_all_tab_vbox);
-
-        gtk_widget_show_all (GTK_WIDGET (this));
-
-        /* Recent templates treeview */
-        this->priv->recent_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING);
-        gtk_tree_view_set_model (GTK_TREE_VIEW (this->priv->recent_treeview),
-                                 GTK_TREE_MODEL (this->priv->recent_store));
-        renderer = gtk_cell_renderer_pixbuf_new ();
-        column = gtk_tree_view_column_new_with_attributes ("", renderer,
-                                                           "pixbuf", PREVIEW_COLUMN,
-                                                           "stock-id", PREVIEW_COLUMN_STOCK,
-                                                           "stock-size", PREVIEW_COLUMN_STOCK_SIZE,
-                                                           NULL);
-        gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-        gtk_tree_view_append_column (GTK_TREE_VIEW (this->priv->recent_treeview), column);
-        renderer = gtk_cell_renderer_text_new ();
-        column = gtk_tree_view_column_new_with_attributes ("", renderer,
-                                                           "markup", DESCRIPTION_COLUMN,
-                                                           NULL);
-        gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-        gtk_tree_view_append_column (GTK_TREE_VIEW (this->priv->recent_treeview), column);
-        recent_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (this->priv->recent_treeview));
-        recent_list = gl_template_history_model_get_name_list (gl_template_history);
-        load_recent_list (this, this->priv->recent_store, recent_selection, recent_list);
-
-        page_size_id = gl_prefs_model_get_default_page_size (gl_prefs);
-        page_size_name = lgl_db_lookup_paper_name_from_id (page_size_id);
-
-        /* Brand selection control */
-        gl_combo_util_add_text_model (GTK_COMBO_BOX (this->priv->brand_combo));
-        brands = lgl_db_get_brand_list (NULL, NULL);
-        brands = g_list_prepend (brands, g_strdup (_("Any")));
-        gl_combo_util_set_strings (GTK_COMBO_BOX (this->priv->brand_combo), brands);
-        lgl_db_free_brand_list (brands);
-        gl_combo_util_set_active_text (GTK_COMBO_BOX (this->priv->brand_combo),
-                                       _("Any"));
-
-        /* Page size selection control */
-        gl_combo_util_add_text_model (GTK_COMBO_BOX (this->priv->page_size_combo));
-        page_sizes = lgl_db_get_paper_name_list ();
-        page_sizes = g_list_prepend (page_sizes, g_strdup (_("Any")));
-        gl_combo_util_set_strings (GTK_COMBO_BOX (this->priv->page_size_combo), page_sizes);
-        lgl_db_free_paper_name_list (page_sizes);
-        gl_combo_util_set_active_text (GTK_COMBO_BOX (this->priv->page_size_combo),
-                                       page_size_name);
-
-        /* Category selection control */
-        gl_combo_util_add_text_model (GTK_COMBO_BOX (this->priv->category_combo));
-        categories = lgl_db_get_category_name_list ();
-        categories = g_list_prepend (categories, g_strdup (_("Any")));
-        gl_combo_util_set_strings (GTK_COMBO_BOX (this->priv->category_combo), categories);
-        gl_combo_util_set_active_text (GTK_COMBO_BOX (this->priv->category_combo),
-                                       _("Any"));
-        lgl_db_free_category_name_list (categories);
-
-        /* Search all treeview */
-        this->priv->search_all_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING);
-        gtk_tree_view_set_model (GTK_TREE_VIEW (this->priv->search_all_treeview),
-                                 GTK_TREE_MODEL (this->priv->search_all_store));
-        renderer = gtk_cell_renderer_pixbuf_new ();
-        column = gtk_tree_view_column_new_with_attributes ("", renderer,
-                                                           "pixbuf", PREVIEW_COLUMN,
-                                                           "stock-id", PREVIEW_COLUMN_STOCK,
-                                                           "stock-size", PREVIEW_COLUMN_STOCK_SIZE,
-                                                           NULL);
-        gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-        gtk_tree_view_append_column (GTK_TREE_VIEW (this->priv->search_all_treeview), column);
-        renderer = gtk_cell_renderer_text_new ();
-        column = gtk_tree_view_column_new_with_attributes ("", renderer,
-                                                           "markup", DESCRIPTION_COLUMN,
-                                                           NULL);
-        gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-        gtk_tree_view_append_column (GTK_TREE_VIEW (this->priv->search_all_treeview), column);
-        search_all_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (this->priv->search_all_treeview));
-        search_all_names = lgl_db_get_template_name_list_all (NULL, page_size_id, NULL);
-        load_search_all_list (this, this->priv->search_all_store, search_all_selection, search_all_names);
-        lgl_db_free_template_name_list (search_all_names);
-
-        /* Connect signals to controls */
-        g_signal_connect (G_OBJECT (this->priv->brand_combo), "changed",
-                          G_CALLBACK (filter_changed_cb),
-                          this);
-        g_signal_connect (G_OBJECT (this->priv->page_size_combo), "changed",
-                          G_CALLBACK (filter_changed_cb),
-                          this);
-        g_signal_connect (G_OBJECT (this->priv->category_combo), "changed",
-                          G_CALLBACK (filter_changed_cb),
-                          this);
-        g_signal_connect (G_OBJECT (recent_selection), "changed",
-                          G_CALLBACK (selection_changed_cb),
-                          this);
-        g_signal_connect (G_OBJECT (search_all_selection), "changed",
-                          G_CALLBACK (selection_changed_cb),
-                          this);
-        g_signal_connect (G_OBJECT (this->priv->notebook), "switch-page",
-                          G_CALLBACK (page_changed_cb),
-                          this);
-
-        g_free (page_size_name);
-
-        if ( recent_list )
-        {
-                gtk_notebook_set_current_page (GTK_NOTEBOOK (this->priv->notebook),
-                                               this->priv->recent_page_num);
-        }
-        else
-        {
-                gtk_notebook_set_current_page (GTK_NOTEBOOK (this->priv->notebook),
-                                               this->priv->search_all_page_num);
-        }
-        gl_template_history_model_free_name_list (recent_list);
-
-        gl_debug (DEBUG_MEDIA_SELECT, "END");
-}
-
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  modify widget due to change in selection                       */
-/*--------------------------------------------------------------------------*/
-static void
-filter_changed_cb (GtkComboBox *combo,
-                   gpointer     user_data)
-{
-        glMediaSelect     *this = GL_MEDIA_SELECT (user_data);
-        gchar             *brand;
-        gchar             *page_size_name, *page_size_id;
-        gchar             *category_name, *category_id;
-        GList             *search_all_names;
-        GtkTreeSelection  *selection;
-
-        gl_debug (DEBUG_MEDIA_SELECT, "START");
-
-
-       this->priv->stop_signals = TRUE;
-
-        /* Update template selections for new filter settings */
-        brand = gtk_combo_box_get_active_text (GTK_COMBO_BOX (this->priv->brand_combo));
-        page_size_name = gtk_combo_box_get_active_text (GTK_COMBO_BOX (this->priv->page_size_combo));
-        category_name = gtk_combo_box_get_active_text (GTK_COMBO_BOX (this->priv->category_combo));
-        if ( brand && strlen(brand) &&
-             page_size_name && strlen(page_size_name) &&
-             category_name && strlen(category_name) )
-        {
-                gl_debug (DEBUG_MEDIA_SELECT, "brand = \"%s\"", brand);
-                gl_debug (DEBUG_MEDIA_SELECT, "page_size_name = \"%s\"", page_size_name);
-                gl_debug (DEBUG_MEDIA_SELECT, "category_name = \"%s\"", category_name);
-                if (!g_utf8_collate (brand, _("Any")))
-                {
-                        g_free (brand);
-                        brand = NULL;
-                }
-                page_size_id = lgl_db_lookup_paper_id_from_name (page_size_name);
-                category_id = lgl_db_lookup_category_id_from_name (category_name);
-                gl_debug (DEBUG_MEDIA_SELECT, "page_size_id = \"%s\"", page_size_id);
-                gl_debug (DEBUG_MEDIA_SELECT, "category_id = \"%s\"", category_id);
-                search_all_names = lgl_db_get_template_name_list_all (brand, page_size_id, category_id);
-                selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (this->priv->search_all_treeview));
-                load_search_all_list (this, this->priv->search_all_store, selection, search_all_names);
-                lgl_db_free_template_name_list (search_all_names);
-                g_free (page_size_id);
-                g_free (category_id);
-
-                /* Emit our "changed" signal */
-                g_signal_emit (G_OBJECT (user_data),
-                               media_select_signals[CHANGED], 0);
-        }
-        g_free (brand);
-        g_free (page_size_name);
-        g_free (category_name);
-
-
-       this->priv->stop_signals = FALSE;
-
-        gl_debug (DEBUG_MEDIA_SELECT, "END");
-}
-
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  modify widget due to change in selection                       */
-/*--------------------------------------------------------------------------*/
-static void
-selection_changed_cb (GtkTreeSelection       *selection,
-                      gpointer                user_data)
-{
-        glMediaSelect *this = GL_MEDIA_SELECT (user_data);
-
-       if (this->priv->stop_signals) return;
-
-        gl_debug (DEBUG_MEDIA_SELECT, "START");
-
-        /* Emit our "changed" signal */
-        g_signal_emit (G_OBJECT (user_data),
-                       media_select_signals[CHANGED], 0);
-
-        gl_debug (DEBUG_MEDIA_SELECT, "END");
-}
-
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  modify widget due to change in selection                       */
-/*--------------------------------------------------------------------------*/
-static void
-page_changed_cb (GtkNotebook            *notebook,
-                 GtkNotebookPage        *page,
-                 guint                   page_num,
-                 gpointer                user_data)
-{
-        glMediaSelect *this = GL_MEDIA_SELECT (user_data);
-
-       if (this->priv->stop_signals) return;
-
-        gl_debug (DEBUG_MEDIA_SELECT, "START");
-
-        /*
-         * Store new current page, because this signal is emitted before the actual page change.
-         */
-       this->priv->current_page_num = page_num;
-
-        /* Emit our "changed" signal */
-        g_signal_emit (G_OBJECT (user_data),
-                       media_select_signals[CHANGED], 0);
-
-        gl_debug (DEBUG_MEDIA_SELECT, "END");
-}
-
-
-/****************************************************************************/
-/* query selected label template name.                                      */
-/****************************************************************************/
-gchar *
-gl_media_select_get_name (glMediaSelect *this)
-{
-        gint               page_num;
-        GtkTreeSelection  *selection;
-        GtkTreeIter        iter;
-        GtkTreeModel      *model;        
-        gchar             *name;
-
-        gl_debug (DEBUG_MEDIA_SELECT, "START");
-
-        page_num = this->priv->current_page_num;
-        if (page_num == this->priv->recent_page_num)
-        {
-                selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (this->priv->recent_treeview));
-        }
-        else if (page_num == this->priv->search_all_page_num)
-        {
-                selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (this->priv->search_all_treeview));
-        }
-        else
-        {
-                g_print ("notebook page = %d\n", page_num);
-                g_assert_not_reached ();
-        }
-
-        if (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_NONE)
-        {
-                name = NULL;
-        }
-        else
-        {
-                gtk_tree_selection_get_selected (selection, &model, &iter);
-                gtk_tree_model_get (model, &iter, NAME_COLUMN, &name, -1);
-        }
-
-        gl_debug (DEBUG_MEDIA_SELECT, "END");
-        return name;
-}
-
-
-/****************************************************************************/
-/* set selected label template name.                                        */
-/****************************************************************************/
-void
-gl_media_select_set_name (glMediaSelect *this,
-                          gchar         *name)
-{
-        GtkTreeSelection  *selection;
-        GtkTreeModel      *model;
-        GtkTreeIter        iter;
-        GtkTreePath       *path;
-        gchar             *name_i;
-        gboolean           flag;
-
-        gl_debug (DEBUG_MEDIA_SELECT, "START");
-
-        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (this->priv->search_all_treeview));
-        g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
-
-        model = GTK_TREE_MODEL (this->priv->search_all_store);
-
-        for ( flag = gtk_tree_model_get_iter_first (model, &iter);
-              flag;
-              flag = gtk_tree_model_iter_next(model, &iter) )
-        {
-                gtk_tree_model_get (model, &iter, NAME_COLUMN, &name_i, -1); 
-                if (strcasecmp(name, name_i) == 0)
-                {
-                        gtk_tree_selection_select_iter (selection, &iter);
-                        path = gtk_tree_model_get_path (model, &iter);
-                        gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (this->priv->search_all_treeview),
-                                                      path,
-                                                      NULL,
-                                                      TRUE, 0.5, 0.0);
-                        gtk_tree_path_free (path);
-                        break;
-                }
-        }
-
-        gl_debug (DEBUG_MEDIA_SELECT, "END");
-}
-
-
-/****************************************************************************/
-/* query current filter parameters.                                         */
-/****************************************************************************/
-void
-gl_media_select_get_filter_parameters (glMediaSelect  *this,
-                                       gchar         **page_size_id,
-                                       gchar         **category_id)
-{
-        gchar *page_size_name, *category_name;
-
-        gl_debug (DEBUG_MEDIA_SELECT, "");
-
-        g_free (*page_size_id);
-        g_free (*category_id);
-
-        page_size_name =
-                gtk_combo_box_get_active_text (GTK_COMBO_BOX (this->priv->page_size_combo));
-
-        *page_size_id = lgl_db_lookup_paper_id_from_name (page_size_name);
-
-        category_name =
-                gtk_combo_box_get_active_text (GTK_COMBO_BOX (this->priv->category_combo));
-
-        *category_id = lgl_db_lookup_category_id_from_name (category_name);
-
-        g_free (page_size_name);
-        g_free (category_name);
-}
-
-
-/****************************************************************************/
-/* set filter parameters.                                                   */
-/****************************************************************************/
-void
-gl_media_select_set_filter_parameters (glMediaSelect  *this,
-                                       const gchar    *page_size_id,
-                                       const gchar    *category_id)
-{
-        gchar *page_size_name;
-        gchar *category_name;
-
-        gl_debug (DEBUG_MEDIA_SELECT, "START");
-
-        page_size_name = lgl_db_lookup_paper_name_from_id (page_size_id);
-        if (page_size_name == NULL)
-        {
-                page_size_name = g_strdup (_("Any"));
-        }
-
-        gl_combo_util_set_active_text (GTK_COMBO_BOX (this->priv->page_size_combo),
-                                       page_size_name);
-
-        category_name = lgl_db_lookup_category_name_from_id (category_id);
-        if (category_name == NULL)
-        {
-                category_name = g_strdup (_("Any"));
-        }
-
-        gl_combo_util_set_active_text (GTK_COMBO_BOX (this->priv->category_combo),
-                                       category_name);
-        g_free (page_size_name);
-        g_free (category_name);
-
-        gl_debug (DEBUG_MEDIA_SELECT, "END");
-}
-
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Get a description of the layout and number of labels.          */
-/*--------------------------------------------------------------------------*/
-static gchar *
-get_layout_desc (const lglTemplate *template)
-{
-        const lglTemplateFrame *frame;
-        gint                    n_labels;
-        gchar                  *string;
-
-        frame = (lglTemplateFrame *)template->frames->data;
-
-        n_labels = lgl_template_frame_get_n_labels (frame);
-
-        string = g_strdup_printf (_("%d per sheet"), n_labels);
-
-        return string;
-}
-
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Get label size description.                                    */ 
-/*--------------------------------------------------------------------------*/
-static gchar *
-get_label_size_desc (const lglTemplate *template)
-{
-        lglUnits                   units;
-        const gchar               *units_string;
-        gdouble                    units_per_point;
-        const lglTemplateFrame    *frame;
-        gchar                     *string = NULL;
-
-        units           = gl_prefs_model_get_units (gl_prefs);
-        units_string    = lgl_units_get_name (units);
-        units_per_point = lgl_units_get_units_per_point (units);
-
-        frame = (lglTemplateFrame *)template->frames->data;
-
-        switch (frame->shape) {
-        case LGL_TEMPLATE_FRAME_SHAPE_RECT:
-                if ( units == LGL_UNITS_INCH ) {
-                        gchar *xstr, *ystr;
-
-                        xstr = gl_str_util_fraction_to_string (frame->rect.w*units_per_point);
-                        ystr = gl_str_util_fraction_to_string (frame->rect.h*units_per_point);
-                        string = g_strdup_printf ("%s Ã— %s %s",
-                                                  xstr, ystr, units_string);
-                        g_free (xstr);
-                        g_free (ystr);
-                } else {
-                        string = g_strdup_printf ("%.5g Ã— %.5g %s",
-                                                  frame->rect.w*units_per_point,
-                                                  frame->rect.h*units_per_point,
-                                                  units_string);
-                }
-                break;
-        case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
-                if ( units == LGL_UNITS_INCH ) {
-                        gchar *dstr;
-
-                        dstr = gl_str_util_fraction_to_string (2.0*frame->round.r*units_per_point);
-                        string = g_strdup_printf ("%s %s %s",
-                                                  dstr, units_string,
-                                                  _("diameter"));
-                        g_free (dstr);
-                } else {
-                        string = g_strdup_printf ("%.5g %s %s",
-                                                  2.0*frame->round.r*units_per_point,
-                                                  units_string,
-                                                  _("diameter"));
-                }
-                break;
-        case LGL_TEMPLATE_FRAME_SHAPE_CD:
-                if ( units == LGL_UNITS_INCH ) {
-                        gchar *dstr;
-
-                        dstr = gl_str_util_fraction_to_string (2.0*frame->cd.r1*units_per_point);
-                        string = g_strdup_printf ("%s %s %s",
-                                                  dstr, units_string,
-                                                  _("diameter"));
-                        g_free (dstr);
-                } else {
-                        string = g_strdup_printf ("%.5g %s %s",
-                                                  2.0*frame->cd.r1*units_per_point,
-                                                  units_string,
-                                                  _("diameter"));
-                }
-                break;
-        default:
-                break;
-        }
-
-        return string;
-}
-
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Load list store from template name list.                       */
-/*--------------------------------------------------------------------------*/
-static void
-load_recent_list (glMediaSelect      *this,
-                  GtkListStore       *store,
-                  GtkTreeSelection   *selection,
-                  GList              *list)
-{
-        GList       *p;
-        GtkTreeIter  iter;
-        lglTemplate *template;
-        GdkPixbuf   *pixbuf;
-        gchar       *size;
-        gchar       *layout;
-        gchar       *description;
-
-        gl_debug (DEBUG_MEDIA_SELECT, "START");
-
-        gtk_list_store_clear (store);
-
-
-        if ( this->priv->recent_info_bar )
-        {
-                gtk_container_remove (GTK_CONTAINER (this->priv->recent_info_vbox),
-                                      this->priv->recent_info_bar);
-                this->priv->recent_info_bar = NULL;
-        }
-
-        if (list)
-        {
-
-                for ( p=list; p!=NULL; p=p->next )
-                {
-
-                        gl_debug (DEBUG_MEDIA_SELECT, "p->data = \"%s\"", p->data);
-
-                        template = lgl_db_lookup_template_from_name (p->data);
-                        pixbuf = gl_mini_preview_pixbuf_cache_get_pixbuf (p->data);
-
-                        size = get_label_size_desc (template);
-                        layout = get_layout_desc (template);
-                        description = g_strdup_printf ("<b>%s: %s</b>\n%s\n%s",
-                                                       (gchar *)p->data,
-                                                       template->description,
-                                                       size,
-                                                       layout);
-                        g_free (size);
-                        g_free (layout);
-
-                        lgl_template_free (template);
-
-                        gtk_list_store_append (store, &iter);
-                        gtk_list_store_set (store, &iter,
-                                            NAME_COLUMN, p->data,
-                                            PREVIEW_COLUMN, pixbuf,
-                                            DESCRIPTION_COLUMN, description,
-                                            -1);
-
-                        g_object_unref (G_OBJECT (pixbuf));
-                        g_free (description);
-                }
-
-                gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
-                gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
-                gtk_tree_selection_select_iter (selection, &iter);
-
-        }
-        else
-        {
-                this->priv->recent_info_bar = gl_message_bar_new (GTK_MESSAGE_INFO,
-                                                                          GTK_BUTTONS_NONE,
-                                                                          "%s", _("No recent templates found."));
-                gl_message_bar_format_secondary_text (GL_MESSAGE_BAR (this->priv->recent_info_bar),
-                                                      "%s", _("Try selecting a template from the \"Search all templates\" page."));
-
-                gtk_box_pack_start (GTK_BOX (this->priv->recent_info_vbox),
-                                    this->priv->recent_info_bar,
-                                    FALSE, FALSE, 0);
-                gtk_widget_show_all (this->priv->recent_info_bar);
-
-                gtk_tree_selection_set_mode (selection, GTK_SELECTION_NONE);
-
-        }
-
-        gl_debug (DEBUG_MEDIA_SELECT, "END");
-}
-
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Load list store from template name list.                       */
-/*--------------------------------------------------------------------------*/
-static void
-load_search_all_list (glMediaSelect      *this,
-                      GtkListStore       *store,
-                      GtkTreeSelection   *selection,
-                      GList              *list)
-{
-        GList       *p;
-        GtkTreeIter  iter;
-        lglTemplate *template;
-        GdkPixbuf   *pixbuf;
-        gchar       *size;
-        gchar       *layout;
-        gchar       *description;
-
-        gl_debug (DEBUG_MEDIA_SELECT, "START");
-
-        gtk_list_store_clear (store);
-
-        if ( this->priv->search_all_info_bar )
-        {
-                gtk_container_remove (GTK_CONTAINER (this->priv->search_all_info_vbox),
-                                      this->priv->search_all_info_bar);
-                this->priv->search_all_info_bar = NULL;
-        }
-
-        if (list)
-        {
-
-                for ( p=list; p!=NULL; p=p->next )
-                {
-
-                        gl_debug (DEBUG_MEDIA_SELECT, "p->data = \"%s\"", p->data);
-
-                        template = lgl_db_lookup_template_from_name (p->data);
-                        pixbuf = gl_mini_preview_pixbuf_cache_get_pixbuf (p->data);
-
-                        size = get_label_size_desc (template);
-                        layout = get_layout_desc (template);
-                        description = g_strdup_printf ("<b>%s: %s</b>\n%s\n%s",
-                                                       (gchar *)p->data,
-                                                       template->description,
-                                                       size,
-                                                       layout);
-                        g_free (size);
-                        g_free (layout);
-
-                        lgl_template_free (template);
-
-                        gtk_list_store_append (store, &iter);
-                        gtk_list_store_set (store, &iter,
-                                            NAME_COLUMN, p->data,
-                                            PREVIEW_COLUMN, pixbuf,
-                                            DESCRIPTION_COLUMN, description,
-                                            -1);
-
-                        g_object_unref (G_OBJECT (pixbuf));
-                        g_free (description);
-                }
-
-                gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
-                gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
-                gtk_tree_selection_select_iter (selection, &iter);
-
-        }
-        else
-        {
-                this->priv->search_all_info_bar = gl_message_bar_new (GTK_MESSAGE_INFO,
-                                                                              GTK_BUTTONS_NONE,
-                                                                              "%s", _("No match."));
-                gl_message_bar_format_secondary_text (GL_MESSAGE_BAR (this->priv->search_all_info_bar),
-                                                      "%s", _("Try selecting a different brand, page size or category."));
-
-                gtk_box_pack_start (GTK_BOX (this->priv->search_all_info_vbox),
-                                    this->priv->search_all_info_bar,
-                                    FALSE, FALSE, 0);
-                gtk_widget_show_all (this->priv->search_all_info_bar);
-
-                gtk_tree_selection_set_mode (selection, GTK_SELECTION_NONE);
-
-        }
-
-        gl_debug (DEBUG_MEDIA_SELECT, "END");
-}
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/src/media-select.h b/src/media-select.h
deleted file mode 100644 (file)
index 6d086ea..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- *  media-select.h
- *  Copyright (C) 2001-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of gLabels.
- *
- *  gLabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  gLabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __MEDIA_SELECT_H__
-#define __MEDIA_SELECT_H__
-
-#include <gtk/gtk.h>
-
-
-G_BEGIN_DECLS
-
-#define GL_TYPE_MEDIA_SELECT (gl_media_select_get_type ())
-#define GL_MEDIA_SELECT(obj) \
-        (G_TYPE_CHECK_INSTANCE_CAST((obj), GL_TYPE_MEDIA_SELECT, glMediaSelect ))
-#define GL_MEDIA_SELECT_CLASS(klass) \
-        (G_TYPE_CHECK_CLASS_CAST ((klass), GL_TYPE_MEDIA_SELECT, glMediaSelectClass))
-#define GL_IS_MEDIA_SELECT(obj) \
-        (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GL_TYPE_MEDIA_SELECT))
-#define GL_IS_MEDIA_SELECT_CLASS(klass) \
-        (G_TYPE_CHECK_CLASS_TYPE ((klass), GL_TYPE_MEDIA_SELECT))
-
-typedef struct _glMediaSelect         glMediaSelect;
-typedef struct _glMediaSelectClass    glMediaSelectClass;
-
-typedef struct _glMediaSelectPrivate  glMediaSelectPrivate;
-
-struct _glMediaSelect {
-        GtkVBox                    parent_widget;
-
-        glMediaSelectPrivate  *priv;
-};
-
-struct _glMediaSelectClass {
-        GtkVBoxClass               parent_class;
-
-        void (*changed) (glMediaSelect * media_select, gpointer user_data);
-};
-
-
-GType      gl_media_select_get_type      (void) G_GNUC_CONST;
-
-GtkWidget *gl_media_select_new           (void);
-
-gchar     *gl_media_select_get_name      (glMediaSelect *this);
-
-void       gl_media_select_set_name      (glMediaSelect *this,
-                                          gchar         *name);
-
-void       gl_media_select_get_filter_parameters (glMediaSelect *this,
-                                                  gchar        **page_size_id,
-                                                  gchar        **category_id);
-
-void       gl_media_select_set_filter_parameters (glMediaSelect *this,
-                                                  const gchar   *page_size_id,
-                                                  const gchar   *category_id);
-
-G_END_DECLS
-
-#endif
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
index 2b7984e2d5920e39d76a1bde5f964115eeb50d0a..abbc10462a07725c401597f393f528a7e26e833c 100644 (file)
@@ -40,6 +40,8 @@
 #define MARGIN 2
 #define SHADOW_OFFSET 3
 
+#define ARROW_SCALE 0.35
+#define ARROW_RGBA_ARGS 1.0, 0.0, 0.0, 0.05
 
 /*===========================================*/
 /* Private types                             */
@@ -73,6 +75,9 @@ struct _glMiniPreviewPrivate {
        gint            last_i;
        gint            prev_i;
 
+        gboolean        draw_arrow_flag;
+        gboolean        rotate_flag;
+
         gboolean        update_scheduled_flag;
 
         glLabel        *label;
@@ -139,6 +144,11 @@ static void     draw_labels                    (glMiniPreview          *this,
                                                cairo_t                *cr,
                                                lglTemplate            *template,
                                                gdouble                 line_width);
+static void     draw_arrow                     (glMiniPreview          *this,
+                                                cairo_t                *cr,
+                                                gdouble                 width,
+                                                gdouble                 height);
+
 static void     draw_rich_preview              (glMiniPreview          *this,
                                                cairo_t                *cr);
 
@@ -397,6 +407,36 @@ gl_mini_preview_highlight_range (glMiniPreview *this,
 }
 
 
+/****************************************************************************/
+/* Set draw arrow.                                                          */
+/****************************************************************************/
+void
+gl_mini_preview_set_draw_arrow (glMiniPreview     *this,
+                                gboolean           draw_arrow_flag)
+{
+        if ( draw_arrow_flag != this->priv->draw_arrow_flag )
+        {
+                this->priv->draw_arrow_flag = draw_arrow_flag;
+                redraw (this);
+        }
+}
+
+
+/****************************************************************************/
+/* Set rotate flag.                                                         */
+/****************************************************************************/
+void
+gl_mini_preview_set_rotate (glMiniPreview     *this,
+                            gboolean           rotate_flag)
+{
+        if ( rotate_flag != this->priv->rotate_flag )
+        {
+                this->priv->rotate_flag = rotate_flag;
+                redraw (this);
+        }
+}
+
+
 /****************************************************************************/
 /* Set label.                                                               */
 /****************************************************************************/
@@ -858,7 +898,13 @@ draw (glMiniPreview  *this,
                            template->page_width, template->page_height,
                            1.0/scale);
 
-               draw_labels (this, cr, template, 1.0/scale);
+               draw_labels (this, cr, template, 2.0/scale);
+
+                if (this->priv->draw_arrow_flag)
+                {
+                        draw_arrow (this, cr,
+                                    template->page_width, template->page_height);
+                }
 
                 if (this->priv->label)
                 {
@@ -971,7 +1017,7 @@ draw_labels (glMiniPreview *this,
         if (this->priv->label)
         {
                 /* Outlines are more subtle when doing a rich preview. */
-                outline_color   = gl_color_set_opacity (base_color, 0.05);
+                outline_color   = gl_color_set_opacity (base_color, 0.25);
         }
         else
         {
@@ -1007,6 +1053,46 @@ draw_labels (glMiniPreview *this,
 }
 
 
+/*--------------------------------------------------------------------------*/
+/* Draw arrow to indicate top of labels.                                    */
+/*--------------------------------------------------------------------------*/
+static void
+draw_arrow  (glMiniPreview      *this,
+             cairo_t            *cr,
+             gdouble             width,
+             gdouble             height)
+{
+        gdouble min;
+
+        cairo_save (cr);
+
+        min = MIN (width, height);
+
+        cairo_translate (cr, width/2, height/2);
+        cairo_scale (cr, 1, -1);
+        if ( this->priv->rotate_flag )
+        {
+                cairo_rotate (cr, -M_PI/2.0);
+        }
+
+        cairo_new_path (cr);
+        cairo_move_to (cr, 0, -min*ARROW_SCALE/2);
+        cairo_line_to (cr, 0, min*ARROW_SCALE);
+
+        cairo_new_sub_path (cr);
+        cairo_move_to (cr, -min*ARROW_SCALE/2, min*ARROW_SCALE/2);
+        cairo_line_to (cr, 0, min*ARROW_SCALE);
+        cairo_line_to (cr, min*ARROW_SCALE/2, min*ARROW_SCALE/2);
+
+        cairo_set_line_width (cr, 0.25*min*ARROW_SCALE);
+        cairo_set_source_rgba (cr, ARROW_RGBA_ARGS);
+
+        cairo_stroke (cr);
+
+        cairo_restore (cr);
+}
+
+
 /*--------------------------------------------------------------------------*/
 /* Draw rich preview using print renderers.                                 */
 /*--------------------------------------------------------------------------*/
index caf77ebbbfffb926e820792dbfd6ef89bec66b19..d2d9210f753bfbe497b811dbfc92e4cb2c725270 100644 (file)
@@ -83,6 +83,12 @@ void       gl_mini_preview_highlight_range     (glMiniPreview     *this,
                                                 gint               first_label,
                                                 gint               last_label);
 
+void       gl_mini_preview_set_draw_arrow      (glMiniPreview     *this,
+                                                gboolean           draw_arrow_flag);
+
+void       gl_mini_preview_set_rotate          (glMiniPreview     *this,
+                                                gboolean           rotate_flag);
+
 
 /*
  * If label is set, the preview will be rich.
index f01d0fb6a0c627e3c45902a591efcdf5ceccab2c..ffea6dc06ac33500dac4a7355e71650498987d94 100644 (file)
 #include <gtk/gtk.h>
 
 #include "hig.h"
-#include "media-select.h"
+#include "builder-util.h"
+#include "prefs.h"
+#include "template-history.h"
+#include "mini-preview.h"
+#include "media-combo.h"
 #include "rotate-label-button.h"
 
 #include "debug.h"
 
 
+#define MINI_PREVIEW_MIN_HEIGHT 300
+#define MINI_PREVIEW_MIN_WIDTH  256
+
+
 /*===========================================*/
 /* Private data types                        */
 /*===========================================*/
 
 struct _glNewLabelDialogPrivate {
 
-       GtkWidget  *media_select;
-       GtkWidget  *rotate_label;
+        GtkBuilder *builder;
+
+       GtkWidget  *preview_vbox;
+        GtkWidget  *combo_hbox;
+       GtkWidget  *rotate_hbox;
 
+        GtkWidget  *desc_label;
+        GtkWidget  *page_size_label;
+        GtkWidget  *label_size_label;
+        GtkWidget  *layout_label;
+        GtkWidget  *vendor_label;
+        GtkWidget  *part_label;
+        GtkWidget  *similar_label;
+
+        GtkWidget  *preview;
+        GtkWidget  *combo;
+        GtkWidget  *rotate_button;
 };
 
 
@@ -55,8 +77,13 @@ struct _glNewLabelDialogPrivate {
 
 static void       gl_new_label_dialog_finalize        (GObject           *object);
 
-static void       template_changed_cb                 (glMediaSelect     *select,
-                                                      gpointer           data);
+static void       combo_changed_cb                    (glNewLabelDialog  *this);
+static void       rotate_toggled_cb                   (glNewLabelDialog  *this);
+
+static gchar     *get_default_name                    (void);
+
+static void       set_info                            (glNewLabelDialog  *this,
+                                                       const gchar       *name);
 
 
 /*****************************************************************************/
@@ -77,7 +104,7 @@ gl_new_label_dialog_class_init (glNewLabelDialogClass *class)
        
        gl_new_label_dialog_parent_class = g_type_class_peek_parent (class);
 
-       object_class->finalize = gl_new_label_dialog_finalize;          
+       object_class->finalize = gl_new_label_dialog_finalize;
 }
 
 
@@ -85,59 +112,84 @@ gl_new_label_dialog_class_init (glNewLabelDialogClass *class)
 /* Object Instance Init Function.                                            */
 /*****************************************************************************/
 static void
-gl_new_label_dialog_init (glNewLabelDialog *dialog)
+gl_new_label_dialog_init (glNewLabelDialog *this)
 {
        GtkWidget    *vbox;
-        GtkWidget    *label;
-       GtkWidget    *frame;
-       gchar        *name;
+        GtkBuilder   *builder;
+        gchar        *builder_filename;
+        static gchar *object_ids[] = { "new_label_dialog_hbox", NULL };
+        GError       *error = NULL;
+        GtkWidget    *new_label_dialog_hbox;
+        gchar        *name;
 
        gl_debug (DEBUG_FILE, "START");
 
-       g_return_if_fail (GL_IS_NEW_LABEL_DIALOG (dialog));
+       g_return_if_fail (GL_IS_NEW_LABEL_DIALOG (this));
 
-       dialog->priv = g_new0 (glNewLabelDialogPrivate, 1);
+       this->priv = g_new0 (glNewLabelDialogPrivate, 1);
 
-       gtk_container_set_border_width (GTK_CONTAINER (dialog), GL_HIG_PAD1);
+       gtk_container_set_border_width (GTK_CONTAINER (this), GL_HIG_PAD1);
 
-       gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
-       gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+       gtk_dialog_set_has_separator (GTK_DIALOG (this), FALSE);
+       gtk_dialog_add_buttons (GTK_DIALOG (this),
                                 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                 GTK_STOCK_OK, GTK_RESPONSE_OK,
                                 NULL);
-        gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
-       gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
-       gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-
-        vbox = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
-
-        label = gtk_label_new (_("<b>Media type</b>"));
-        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
-        frame = gtk_frame_new ("");
-        gtk_frame_set_label_widget (GTK_FRAME (frame), label);
-        gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
-       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, GL_HIG_PAD1);
-
-       dialog->priv->media_select = gl_media_select_new ();
-        gtk_container_add (GTK_CONTAINER (frame), dialog->priv->media_select);
-
-        label = gtk_label_new (_("<b>Label orientation</b>"));
-        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
-        frame = gtk_frame_new ("");
-        gtk_frame_set_label_widget (GTK_FRAME (frame), label);
-        gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
-       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
-
-       dialog->priv->rotate_label = gl_rotate_label_button_new ();
-        gtk_container_add (GTK_CONTAINER (frame), dialog->priv->rotate_label);
-
-       /* Sync template name from media select with rotate widget. */
-       name = gl_media_select_get_name (GL_MEDIA_SELECT (dialog->priv->media_select));
-       gl_rotate_label_button_set_template_name (GL_ROTATE_LABEL_BUTTON (dialog->priv->rotate_label),
-                                                  name);
-
-       g_signal_connect (G_OBJECT (dialog->priv->media_select), "changed",
-                         G_CALLBACK (template_changed_cb), dialog);
+        gtk_dialog_set_default_response (GTK_DIALOG (this), GTK_RESPONSE_OK);
+       gtk_window_set_destroy_with_parent (GTK_WINDOW (this), TRUE);
+       gtk_window_set_modal (GTK_WINDOW (this), TRUE);
+
+        vbox = gtk_dialog_get_content_area (GTK_DIALOG (this));
+
+
+        builder = gtk_builder_new ();
+        builder_filename = g_build_filename (GLABELS_DATA_DIR, "builder", "new-label-dialog.builder", NULL);
+        gtk_builder_add_objects_from_file (builder, builder_filename, object_ids, &error);
+        g_free (builder_filename);
+       if (error) {
+               g_critical ("%s\n\ngLabels may not be installed correctly!", error->message);
+                g_error_free (error);
+               return;
+       }
+
+        gl_builder_util_get_widgets (builder,
+                                     "new_label_dialog_hbox",  &new_label_dialog_hbox,
+                                     "preview_vbox",           &this->priv->preview_vbox,
+                                     "combo_hbox",             &this->priv->combo_hbox,
+                                     "rotate_hbox",            &this->priv->rotate_hbox,
+                                     "desc_label",             &this->priv->desc_label,
+                                     "page_size_label",        &this->priv->page_size_label,
+                                     "label_size_label",       &this->priv->label_size_label,
+                                     "layout_label",           &this->priv->layout_label,
+                                     "vendor_label",           &this->priv->vendor_label,
+                                     "part_label",             &this->priv->part_label,
+                                     "similar_label",          &this->priv->similar_label,
+                                     NULL);
+
+        gtk_container_add (GTK_CONTAINER (vbox), new_label_dialog_hbox);
+        this->priv->builder = builder;
+
+        this->priv->preview = gl_mini_preview_new (MINI_PREVIEW_MIN_HEIGHT, MINI_PREVIEW_MIN_WIDTH);
+        gl_mini_preview_set_draw_arrow (GL_MINI_PREVIEW (this->priv->preview), TRUE);
+        gl_mini_preview_set_rotate (GL_MINI_PREVIEW (this->priv->preview), FALSE);
+        gtk_container_add (GTK_CONTAINER (this->priv->preview_vbox), this->priv->preview);
+
+        this->priv->combo = gl_media_combo_new ();
+        gtk_container_add (GTK_CONTAINER (this->priv->combo_hbox), this->priv->combo);
+
+        this->priv->rotate_button = gl_rotate_label_button_new ();
+        gtk_container_add (GTK_CONTAINER (this->priv->rotate_hbox), this->priv->rotate_button);
+
+       g_signal_connect_swapped (G_OBJECT (this->priv->combo), "changed",
+                         G_CALLBACK (combo_changed_cb), this);
+       g_signal_connect_swapped (G_OBJECT (this->priv->rotate_button), "changed",
+                         G_CALLBACK (rotate_toggled_cb), this);
+
+        name = get_default_name ();
+        gl_media_combo_set_name (GL_MEDIA_COMBO (this->priv->combo), name);
+        gl_rotate_label_button_set_template_name (GL_ROTATE_LABEL_BUTTON (this->priv->rotate_button), name);
+        g_free (name);
+        combo_changed_cb (this);
 
        gl_debug (DEBUG_FILE, "END");
 }
@@ -149,15 +201,16 @@ gl_new_label_dialog_init (glNewLabelDialog *dialog)
 static void 
 gl_new_label_dialog_finalize (GObject *object)
 {
-       glNewLabelDialog* dialog = GL_NEW_LABEL_DIALOG (object);;
+       glNewLabelDialog* this = GL_NEW_LABEL_DIALOG (object);;
        
        gl_debug (DEBUG_FILE, "START");
 
        g_return_if_fail (object != NULL);
-       g_return_if_fail (GL_IS_NEW_LABEL_DIALOG (dialog));
-       g_return_if_fail (dialog->priv != NULL);
+       g_return_if_fail (GL_IS_NEW_LABEL_DIALOG (this));
+       g_return_if_fail (this->priv != NULL);
 
-       g_free (dialog->priv);
+        g_object_unref (G_OBJECT (this->priv->builder));
+       g_free (this->priv);
 
        G_OBJECT_CLASS (gl_new_label_dialog_parent_class)->finalize (object);
 
@@ -172,38 +225,33 @@ gl_new_label_dialog_finalize (GObject *object)
 GtkWidget *
 gl_new_label_dialog_new (GtkWindow    *win)
 {
-       GtkWidget *dialog;
+       GtkWidget *this;
 
        gl_debug (DEBUG_FILE, "");
 
-       dialog = GTK_WIDGET (g_object_new (GL_TYPE_NEW_LABEL_DIALOG, NULL));
+       this = GTK_WIDGET (g_object_new (GL_TYPE_NEW_LABEL_DIALOG, NULL));
 
-       gtk_window_set_transient_for (GTK_WINDOW (dialog), win);
+       gtk_window_set_transient_for (GTK_WINDOW (this), win);
 
-       return dialog;
+       return this;
 }
 
 
 /*---------------------------------------------------------------------------*/
-/* PRIVATE.  New template changed callback.                                  */
+/* PRIVATE.  Template changed callback.                                      */
 /*---------------------------------------------------------------------------*/
 static void
-template_changed_cb (glMediaSelect *select,
-                    gpointer       data)
+combo_changed_cb (glNewLabelDialog  *this)
 {
-       glNewLabelDialog  *dialog = GL_NEW_LABEL_DIALOG (data);
        gchar             *name;
 
        gl_debug (DEBUG_FILE, "START");
 
-       name = gl_media_select_get_name (GL_MEDIA_SELECT (select));
+       name = gl_media_combo_get_name (GL_MEDIA_COMBO (this->priv->combo));
 
-       gl_rotate_label_button_set_template_name (GL_ROTATE_LABEL_BUTTON (dialog->priv->rotate_label),
-                                                  name);
-
-       gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
-                                          GTK_RESPONSE_OK,
-                                          (name != NULL));
+       gl_mini_preview_set_by_name (GL_MINI_PREVIEW (this->priv->preview), name);
+        gl_rotate_label_button_set_template_name (GL_ROTATE_LABEL_BUTTON (this->priv->rotate_button), name);
+        set_info (this, name);
 
        g_free (name);
 
@@ -211,15 +259,144 @@ template_changed_cb (glMediaSelect *select,
 }
 
 
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Rotate toggled callback.                                        */
+/*---------------------------------------------------------------------------*/
+static void
+rotate_toggled_cb (glNewLabelDialog  *this)
+{
+        gboolean state;
+
+       gl_debug (DEBUG_FILE, "START");
+
+        state = gl_rotate_label_button_get_state (GL_ROTATE_LABEL_BUTTON (this->priv->rotate_button));
+        gl_mini_preview_set_rotate (GL_MINI_PREVIEW (this->priv->preview), state);
+
+       gl_debug (DEBUG_FILE, "END");
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Get default template name.                                      */
+/*---------------------------------------------------------------------------*/
+static gchar *
+get_default_name (void)
+{
+        gchar *name = NULL;
+        GList *list;
+
+        list = gl_template_history_model_get_name_list (gl_template_history);
+
+        if ( list )
+        {
+                name = g_strdup (list->data);
+                gl_template_history_model_free_name_list (list);
+        }
+        else
+        {
+                gchar *page_size;
+
+                page_size = gl_prefs_model_get_default_page_size (gl_prefs);
+                list = lgl_db_get_template_name_list_all (NULL, page_size, NULL);
+                g_free (page_size);
+
+                if ( list )
+                {
+                        name = g_strdup (list->data);
+                        lgl_db_free_template_name_list (list);
+                }
+        }
+
+        return name;
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Set information labels.                                         */
+/*---------------------------------------------------------------------------*/
+static void
+set_info (glNewLabelDialog  *this,
+          const gchar       *name)
+{
+        lglTemplate          *template;
+        lglTemplateFrame     *frame;
+        lglVendor            *vendor;
+        lglUnits              units;
+        gchar                *page_size_string;
+        gchar                *label_size_string;
+        gchar                *layout_string;
+        GList                *list, *p;
+        GString              *list_string;
+
+        template = lgl_db_lookup_template_from_name (name);
+        frame    = template->frames->data;
+        vendor   = lgl_db_lookup_vendor_from_name (template->brand);
+
+        units    = gl_prefs_model_get_units (gl_prefs);
+
+        page_size_string  = lgl_db_lookup_paper_name_from_id (template->paper_id);
+        label_size_string = lgl_template_frame_get_size_description (frame, units);
+        layout_string     = lgl_template_frame_get_layout_description (frame);
+
+        gtk_label_set_text (GTK_LABEL (this->priv->desc_label),       template->description);
+        gtk_label_set_text (GTK_LABEL (this->priv->page_size_label),  page_size_string);
+        gtk_label_set_text (GTK_LABEL (this->priv->label_size_label), label_size_string);
+        gtk_label_set_text (GTK_LABEL (this->priv->layout_label),     layout_string);
+
+        if ( vendor && vendor->url )
+        {
+                gchar *markup;
+
+                markup = g_strdup_printf ("<a href='%s'>%s</a>", vendor->url, vendor->name);
+                gtk_label_set_markup (GTK_LABEL (this->priv->vendor_label), markup);
+                g_free (markup);
+        }
+        else
+        {
+                /* FIXME: Using set_markup instead of set_text to clear out previous link. */
+                gtk_label_set_markup (GTK_LABEL (this->priv->vendor_label), template->brand);
+        }
+
+        if ( template->product_url )
+        {
+                gchar *markup;
+
+                markup = g_strdup_printf ("<a href='%s'>%s</a>", template->product_url, template->part);
+                gtk_label_set_markup (GTK_LABEL (this->priv->part_label), markup);
+                g_free (markup);
+        }
+        else
+        {
+                /* FIXME: Using set_markup instead of set_text to clear out previous link. */
+                gtk_label_set_markup (GTK_LABEL (this->priv->part_label), template->part);
+        }
+
+        list = lgl_db_get_similar_template_name_list (name);
+        list_string = g_string_new ("");
+        for ( p = list; p; p = p->next )
+        {
+                g_string_append_printf (list_string, "%s\n", (char *)p->data);
+        }
+        gtk_label_set_text (GTK_LABEL (this->priv->similar_label), list_string->str);
+
+        lgl_db_free_template_name_list (list);
+        g_string_free (list_string, TRUE);
+
+        g_free (page_size_string);
+        g_free (label_size_string);
+        g_free (layout_string);
+}
+
+
 /*****************************************************************************/
 /* Get template name.                                                        */
 /*****************************************************************************/
 gchar *
-gl_new_label_dialog_get_template_name (glNewLabelDialog *dialog)
+gl_new_label_dialog_get_template_name (glNewLabelDialog *this)
 {
        gchar *name;
 
-       name = gl_media_select_get_name (GL_MEDIA_SELECT (dialog->priv->media_select));
+       name = gl_media_combo_get_name (GL_MEDIA_COMBO (this->priv->combo));
 
        return name;
 }
@@ -229,10 +406,12 @@ gl_new_label_dialog_get_template_name (glNewLabelDialog *dialog)
 /* Set template name.                                                        */
 /*****************************************************************************/
 void
-gl_new_label_dialog_set_template_name (glNewLabelDialog *dialog,
+gl_new_label_dialog_set_template_name (glNewLabelDialog *this,
                                       gchar            *name)
 {
-       gl_media_select_set_name (GL_MEDIA_SELECT (dialog->priv->media_select), name);
+       gl_mini_preview_set_by_name (GL_MINI_PREVIEW (this->priv->preview), name);
+       gl_media_combo_set_name (GL_MEDIA_COMBO (this->priv->combo), name);
+        set_info (this, name);
 }
 
 
@@ -240,13 +419,10 @@ gl_new_label_dialog_set_template_name (glNewLabelDialog *dialog,
 /* Get current filter parameters.                                            */
 /*****************************************************************************/
 void
-gl_new_label_dialog_get_filter_parameters (glNewLabelDialog  *dialog,
+gl_new_label_dialog_get_filter_parameters (glNewLabelDialog  *this,
                                           gchar            **page_size_id,
                                           gchar            **category_id)
 {
-       gl_media_select_get_filter_parameters (
-               GL_MEDIA_SELECT (dialog->priv->media_select),
-               page_size_id, category_id);
 }
 
 
@@ -254,13 +430,10 @@ gl_new_label_dialog_get_filter_parameters (glNewLabelDialog  *dialog,
 /* Set current filter parameters.                                            */
 /*****************************************************************************/
 void
-gl_new_label_dialog_set_filter_parameters (glNewLabelDialog *dialog,
+gl_new_label_dialog_set_filter_parameters (glNewLabelDialog *this,
                                           const gchar      *page_size_id,
                                           const gchar      *category_id)
 {
-       gl_media_select_set_filter_parameters (
-               GL_MEDIA_SELECT (dialog->priv->media_select),
-               page_size_id, category_id);
 }
 
 
@@ -268,10 +441,9 @@ gl_new_label_dialog_set_filter_parameters (glNewLabelDialog *dialog,
 /* Get rotate state.                                                         */
 /*****************************************************************************/
 gboolean
-gl_new_label_dialog_get_rotate_state (glNewLabelDialog *dialog)
+gl_new_label_dialog_get_rotate_state (glNewLabelDialog *this)
 {
-       return gl_rotate_label_button_get_state (
-               GL_ROTATE_LABEL_BUTTON (dialog->priv->rotate_label));
+       return gl_rotate_label_button_get_state (GL_ROTATE_LABEL_BUTTON (this->priv->rotate_button));
 }
 
 
@@ -279,11 +451,11 @@ gl_new_label_dialog_get_rotate_state (glNewLabelDialog *dialog)
 /* Set rotate state.                                                         */
 /*****************************************************************************/
 void
-gl_new_label_dialog_set_rotate_state (glNewLabelDialog *dialog,
+gl_new_label_dialog_set_rotate_state (glNewLabelDialog *this,
                                      gboolean          state)
 {
-       gl_rotate_label_button_set_state (
-               GL_ROTATE_LABEL_BUTTON (dialog->priv->rotate_label), state);
+        gl_rotate_label_button_set_state (GL_ROTATE_LABEL_BUTTON (this->priv->rotate_button), state);
+        gl_mini_preview_set_rotate (GL_MINI_PREVIEW (this->priv->preview), state);
 }
 
 
index d477edf551051664a532e60f028da2942f1ee7eb..cf65db06a99095059180fe59ee014e1208467d9c 100644 (file)
@@ -111,7 +111,7 @@ gl_rotate_label_button_init (glRotateLabelButton *this)
 
         this->priv = g_new0 (glRotateLabelButtonPrivate, 1);
 
-        gtk_container_set_border_width (GTK_CONTAINER (this), GL_HIG_PAD2);
+        gtk_box_set_spacing (GTK_BOX (this), GL_HIG_PAD2);
 
         this->priv->no_rotate_radio = gtk_radio_button_new (NULL);
         gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (this->priv->no_rotate_radio),
@@ -134,12 +134,8 @@ gl_rotate_label_button_init (glRotateLabelButton *this)
         gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
         gtk_container_add (GTK_CONTAINER (this->priv->rotate_radio), vbox);
 
-        gtk_box_pack_start (GTK_BOX (this),
-                            this->priv->no_rotate_radio,
-                            FALSE, FALSE, GL_HIG_PAD1);
-        gtk_box_pack_start (GTK_BOX (this),
-                            this->priv->rotate_radio,
-                            FALSE, FALSE, GL_HIG_PAD1);
+        gtk_box_pack_start (GTK_BOX (this), this->priv->no_rotate_radio, FALSE, FALSE, 0);
+        gtk_box_pack_start (GTK_BOX (this), this->priv->rotate_radio, FALSE, FALSE, 0);
         
         /* Connect signals to controls */
        g_signal_connect (G_OBJECT (this->priv->no_rotate_radio),
index d48ec007b7b9fdb1f6ffc119a3fd92613183318e..6aa2dd1f3e521493f316139fff967757079e7722 100644 (file)
 #include <string.h>
 #include <math.h>
 
-#define FRAC_EPSILON 0.00005
-
-
-/****************************************************************************/
-/* Create fractional representation of number, if possible.                 */
-/****************************************************************************/
-gchar *
-gl_str_util_fraction_to_string (gdouble x)
-{
-       static gdouble denom[] = { 1., 2., 3., 4., 8., 16., 32., 0. };
-       gint i;
-       gdouble product, remainder;
-       gint n, d;
-
-       for ( i=0; denom[i] != 0.0; i++ ) {
-               product = x * denom[i];
-               remainder = fabs(product - ((gint)(product+0.5)));
-               if ( remainder < FRAC_EPSILON ) break;
-       }
-
-       if ( denom[i] == 0.0 ) {
-               /* None of our denominators work. */
-               return g_strdup_printf ("%.5g", x);
-       }
-       if ( denom[i] == 1.0 ) {
-               /* Simple integer. */
-               return g_strdup_printf ("%d", (gint)x);
-       }
-       n = (gint)( x * denom[i] + 0.5 );
-       d = (gint)denom[i];
-       if ( n > d ) {
-               return g_strdup_printf ("%d_%d/%d", (n/d), (n%d), d);
-       } else {
-               return g_strdup_printf ("%d/%d", (n%d), d);
-       }
-}
-
 
 /****************************************************************************/
 /* Utilities to deal with PangoAlignment types.                             */
index 0253392b5e0152dbb8646bce6f0ff9c6f3a8b6c9..76dda77933e9010edc71f274cc870c38ab88ea5b 100644 (file)
@@ -26,8 +26,6 @@
 
 G_BEGIN_DECLS
 
-gchar              *gl_str_util_fraction_to_string    (gdouble            x);
-
 const gchar        *gl_str_util_align_to_string       (PangoAlignment     align);
 PangoAlignment      gl_str_util_string_to_align       (const gchar       *string);