contentLister/src/gtkMetadataWnd.c File Reference

gtkMetadataWnd - eReader content metadata editor More...

#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <liberdm/display.h>
#include <liberdm/erdm.h>
#include <libergtk/ergtk.h>
#include <liberipc/eripctoolbar.h>
#include <libermanifest/ermanifest.h>
#include "contentListerLog.h"
#include "lister.h"
#include "gtkMetadataWnd.h"
#include "erConnect.h"
#include "system.h"
#include "gtkPincodeScreen.h"
#include "control.h"
#include "displayUpdate.h"
#include "languages.h"
#include "toolbar.h"
#include "erbusy.h"

Go to the source code of this file.

Defines

#define _GNU_SOURCE

Functions

static void on_changed (GtkEditable *widget, gpointer data)
static gboolean on_expose (GtkWidget *widget, GdkEventExpose *event, gpointer data)
static void createNameItem (GtkWidget *parent)
static void createDescItem (GtkWidget *parent)
static void createFinishItem (GtkWidget *parent)
GtkWidget * create_content_metadata_wnd (GtkWidget *parent)
void content_metadata_set_text ()
gboolean content_metadata_read_manifest (const gchar *szManifest)
gboolean content_metadata_rename_container (const gchar *szManifest, gchar *szContainer, gint len)
gboolean content_metadata_write_manifest (const gchar *szContainer)

Variables

static cmMetadata_t g_wnd


Detailed Description

gtkMetadataWnd - eReader content metadata editor

<File description>=""> The eReader content metadata editor provides gtk widgets to enable user change content title and description. Which are created and updated with the following API

Definition in file gtkMetadataWnd.c.


Define Documentation

#define _GNU_SOURCE

Definition at line 32 of file gtkMetadataWnd.c.


Function Documentation

gboolean content_metadata_read_manifest ( const gchar *  szManifest  ) 

read manifest file into content data

Parameters:
pathname of the manifest file

Definition at line 410 of file gtkMetadataWnd.c.

00411 {
00412     CL_LOGPRINTF("entry");
00413 
00414     g_assert(szManifest != NULL);
00415 
00416     int   ret;
00417     gchar szTitle[MD_MAX_TITLE_SIZE];
00418     gchar szDescription[MD_MAX_DESCRIPTION_SIZE];
00419        
00420     // open manifest file
00421     erManifest manifest;
00422     if (RET_OK != ermXmlOpenFile(szManifest, &manifest))
00423     {
00424         CL_ERRORPRINTF("Could not open manifest file [%s]", szManifest);
00425         return FALSE;
00426     }
00427     
00428     // get title
00429     ret = ermXmlGetString(&manifest, "/package/metadata/dc-metadata/Title", szTitle, sizeof(szTitle));
00430     if (ret != RET_OK)
00431     {
00432         strcpy(szTitle, "");
00433     }
00434     gtk_entry_set_text(GTK_ENTRY(g_wnd.nameEntry), szTitle);
00435     
00436     // get description
00437     ret = ermXmlGetString(&manifest, "/package/metadata/dc-metadata/Description", szDescription, sizeof(szDescription));
00438     if (ret != RET_OK)
00439     {
00440         strcpy(szDescription, "");
00441     }
00442     /****
00443      * Problems with multi-line text editor, see createDescEntry();
00444      *
00445     GtkTextBuffer* buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(g_wnd.descEntry));
00446     gtk_text_buffer_set_text(buffer, szDescription, -1);
00447     ****/
00448     char* cp = strchr(szDescription, '\n');
00449     if (cp)
00450     {
00451         *cp = '\0';
00452         gtk_entry_set_text(GTK_ENTRY(g_wnd.descEntry2), cp + 1);
00453     }
00454     else
00455     {
00456         gtk_entry_set_text(GTK_ENTRY(g_wnd.descEntry2), "");
00457     }
00458     gtk_entry_set_text(GTK_ENTRY(g_wnd.descEntry), szDescription);
00459         
00460     // close manifest file
00461     ermXmlClose(&manifest);
00462     return TRUE;
00463 }

Here is the call graph for this function:

gboolean content_metadata_rename_container ( const gchar *  szManifest,
gchar *  szContainer,
gint  len 
)

rename container when needed, depending on current title

Parameters:
in szManifest pathname of manifest file
out szContainer pathname of container directory
in len size in bytes of szContainer buffer

Definition at line 466 of file gtkMetadataWnd.c.

00467 {
00468     CL_LOGPRINTF("entry: manifest [%s]", szManifest);
00469 
00470     g_return_val_if_fail((szManifest != NULL), FALSE);
00471     
00472     gboolean retval = FALSE;
00473 
00474        
00475     // retrieve container path
00476     char* cp = strrchr(szManifest, '/');
00477     if (cp)
00478     {
00479         *cp = '\0';
00480         snprintf(szContainer, len, "%s", szManifest);
00481         *cp = '/';
00482     }
00483     else
00484     {
00485         CL_ERRORPRINTF("Illegal manifest path [%s]", szManifest);
00486     }
00487 
00488     // retrieve container name
00489     char* szContainerName = strrchr(szContainer, '/');
00490     if (szContainerName)
00491     {
00492         szContainerName++;
00493     }
00494     else
00495     {
00496         CL_ERRORPRINTF("Illegal container path [%s]", szContainer);
00497     }
00498 
00499     // retrieve title from screen object
00500     const char* szTitle = gtk_entry_get_text(GTK_ENTRY(g_wnd.nameEntry));
00501 
00502     // set container name to (modified) title
00503     if (   strlen(szTitle) > 0
00504         && strcmp(szTitle, szContainerName) != 0 )
00505     {
00506         // container name is different from title: rename container
00507 
00508         // determine new container name
00509         int  n = strlen(szContainer) - strlen(szContainerName);
00510         char* newContainer = alloca(n + strlen(szTitle) + 1);
00511         g_return_val_if_fail((newContainer != NULL), FALSE);
00512         strncpy(newContainer, szContainer, n);
00513         strcpy(&newContainer[n], szTitle);
00514         CL_LOGPRINTF("New container name [%s]", newContainer);        
00515         
00516         // rename container, but only when newName does not exist
00517         struct stat statbuf;
00518         if (   stat(newContainer, &statbuf) == -1
00519             && rename(szContainer, newContainer) ==  0 )
00520         {
00521             CL_LOGPRINTF("Renamed container ok");
00522             snprintf(szContainer, len, "%s", newContainer);
00523             retval = TRUE;
00524         }
00525         else
00526         {
00527             CL_ERRORPRINTF("Cannot rename container [%s]", strerror(errno));
00528             
00529             // rename failed: force title to container name
00530             gtk_entry_set_text(GTK_ENTRY(g_wnd.nameEntry), szContainerName);
00531         }
00532     }
00533     
00534     return retval;
00535 }

void content_metadata_set_text ( void   ) 

Set constant texts for metedata editor window

Definition at line 394 of file gtkMetadataWnd.c.

00395 {
00396     CL_LOGPRINTF("entry");
00397 
00398     // name item
00399     gtk_label_set_text( GTK_LABEL(g_wnd.nameTag), _("Step 1: Please enter a name for the content") );
00400             
00401     // desc item
00402     gtk_label_set_text( GTK_LABEL(g_wnd.descTag), _("Step 2: Enter a description by which you can identify the content") );
00403 
00404     // finish item
00405     gtk_label_set_text( GTK_LABEL(g_wnd.finishTag), _("Step 3: Click on the 'Tagging' icon to save your changes") );
00406 }

gboolean content_metadata_write_manifest ( const gchar *  szContainer  ) 

update the content metadata according to input parameter

Parameters:
pathname of container directory

Definition at line 538 of file gtkMetadataWnd.c.

00539 {
00540     CL_LOGPRINTF("entry: manifest [%s]", szContainer);
00541 
00542     g_return_val_if_fail((szContainer != NULL), FALSE);
00543 
00544     gboolean retval = FALSE;
00545     
00546        
00547     // retrieve title from screen object
00548     const char* szTitle = gtk_entry_get_text(GTK_ENTRY(g_wnd.nameEntry));
00549 
00550     // retrieve description from screen object
00551     /****
00552      * Problems with multi-line text editor, see createDescEntry();
00553      *
00554     GtkTextBuffer * buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(g_wnd.descEntry));
00555     GtkTextIter start, end;
00556     gtk_text_buffer_get_bounds(buffer, &start, &end);
00557     char* szDescription = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);      
00558     ****/
00559     const char* szDescription = gtk_entry_get_text(GTK_ENTRY(g_wnd.descEntry));
00560     const char* szDescription2 = gtk_entry_get_text(GTK_ENTRY(g_wnd.descEntry2));
00561     if (szDescription2 != NULL  &&  szDescription2[0] != '\0')
00562     {
00563         char* cp = alloca( strlen(szDescription) + strlen(szDescription2) + 2 );
00564         if (cp)
00565         {
00566             sprintf(cp, "%s\n%s", szDescription, szDescription2);
00567             szDescription = cp;
00568         }
00569     }
00570     
00571     // open manifest file and update it
00572     erManifest manifest;
00573     if (RET_OK == ermXmlOpenManifest(szContainer, &manifest))
00574     {
00575         // update title
00576         if (RET_OK == ermXmlExist(&manifest, "/package/metadata/dc-metadata/Title"))
00577         {
00578             ermXmlSetString( &manifest,
00579                              "/package/metadata/dc-metadata/Title",
00580                              szTitle );
00581         }
00582         else
00583         {
00584             ermXmlNewString( &manifest,
00585                              "/package/metadata/dc-metadata",
00586                              "Title",
00587                              szTitle );
00588         }
00589         
00590         // update description
00591         if (RET_OK == ermXmlExist(&manifest, "/package/metadata/dc-metadata/Description"))
00592         {
00593             ermXmlSetString( &manifest,
00594                              "/package/metadata/dc-metadata/Description",
00595                              szDescription );
00596         }
00597         else
00598         {
00599             ermXmlNewString( &manifest,
00600                              "/package/metadata/dc-metadata",
00601                              "Description",
00602                              szDescription );
00603         }
00604         
00605         // save manifest
00606         ermXmlSaveAndClose(&manifest);
00607 
00608         retval = TRUE;
00609     }
00610     else
00611     {
00612         CL_ERRORPRINTF("Could not open manifest file in [%s]", szContainer);
00613     }
00614     
00615     return retval;
00616 }

Here is the call graph for this function:

GtkWidget* create_content_metadata_wnd ( GtkWidget *  parent  ) 

Create content metadata editor window

Parameters:
data -
Returns:
instance pointer of window. Return NULL if failed.

Definition at line 344 of file gtkMetadataWnd.c.

00345 {
00346     CL_LOGPRINTF("entry");
00347 
00348     // main window
00349     g_wnd.window = parent;
00350     // g_signal_connect(G_OBJECT(g_wnd.window), "focus-in-event", G_CALLBACK(on_main_wnd_focus_in), wnd);
00351     // g_signal_connect(G_OBJECT(g_wnd.window), "key_press_event", G_CALLBACK(on_keypress), wnd);
00352     g_signal_connect(G_OBJECT(g_wnd.window), "expose-event", G_CALLBACK(on_expose), NULL);
00353 
00354     // background
00355     GtkWidget* background = gtk_event_box_new();
00356     gtk_widget_set_name(GTK_WIDGET(background), "content_wnd_background");   
00357     gtk_widget_set_size_request(GTK_WIDGET(background), METADATA_BK_IMG_WIDTH, METADATA_BK_IMG_HEIGHT);
00358     gtk_container_add(GTK_CONTAINER(parent), background);
00359     gtk_widget_show(background);
00360         
00361     // alignment
00362     GtkWidget* alignment = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
00363     gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), METADATA_VBORDER, METADATA_VBORDER, METADATA_HBORDER, METADATA_HBORDER);
00364     gtk_container_add(GTK_CONTAINER(background), alignment);
00365     gtk_widget_show(alignment);
00366 
00367     // vbox
00368     GtkWidget* vbox = gtk_vbox_new(FALSE, METADATA_WND_ITEM_SPACING);
00369     gtk_container_add(GTK_CONTAINER(alignment), vbox);
00370     gtk_widget_show(vbox);
00371    
00372     // name item
00373     createNameItem(vbox);
00374             
00375     // desc item
00376     createDescItem(vbox);
00377 
00378     // finish item
00379     createFinishItem(vbox);
00380 
00381     // set screen texts
00382     content_metadata_set_text();
00383 
00384     // instance-private data
00385     g_wnd.on_change_occurred     = FALSE;
00386     g_wnd.on_movecursor_occurred = FALSE;
00387     g_wnd.display_update_pending = FALSE;
00388 
00389     return background;
00390 }

Here is the call graph for this function:

static void createDescItem ( GtkWidget *  parent  )  [static]

Definition at line 249 of file gtkMetadataWnd.c.

00250 {
00251     GtkWidget* widget;
00252 
00253     CL_LOGPRINTF("entry");
00254 
00255     // title tag
00256     widget = gtk_label_new("");
00257     gtk_widget_set_name(GTK_WIDGET(widget), "content_wnd_text_bold");
00258     gtk_widget_set_size_request(widget, -1, METADATA_TAG_HEIGHT);
00259     gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 1.0);
00260     gtk_box_pack_start(GTK_BOX(parent), widget, FALSE, FALSE, 0);
00261     gtk_widget_show(widget);
00262     g_wnd.descTag = widget;
00263     
00264     /****
00265      * Multi-line text editor has strange side-effects.
00266      * For example, once it has the focus we cannot get the focus back to other objects.
00267      * Might be that we are doing something wrong, but for the time being we use two single-line entries.
00268      * 
00269     // multiline text editor
00270     widget = gtk_text_view_new();
00271     gtk_widget_set_name(GTK_WIDGET(widget), "content_wnd_edit");
00272     gtk_widget_set_size_request(widget, METADATA_ENTRY_WIDTH, METADATA_DESC_HEIGHT);
00273     gtk_text_view_set_accepts_tab(GTK_TEXT_VIEW(widget), FALSE);
00274     gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(widget), TRUE);
00275     gtk_text_view_set_editable(GTK_TEXT_VIEW(widget), TRUE);
00276     gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(widget), GTK_WRAP_CHAR);
00277     gtk_box_pack_start(GTK_BOX(parent), widget, FALSE, FALSE, 0);
00278     gtk_widget_show(widget);
00279     //
00280     // signals    
00281     GtkTextBuffer* buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
00282     g_signal_connect_after(G_OBJECT(widget), "move-focus",           G_CALLBACK(on_move_focus),     NULL);
00283     g_signal_connect_after(G_OBJECT(widget), "move-cursor",          G_CALLBACK(on_move_cursor),    NULL);
00284     g_signal_connect(      G_OBJECT(widget), "button-release-event", G_CALLBACK(on_button_release), NULL);
00285     g_signal_connect_after(G_OBJECT(buffer), "changed",              G_CALLBACK(on_changed),        NULL);
00286     ****/
00287 
00288     // descEdit
00289     widget = ergtk_entry_new();
00290     gtk_widget_set_name(GTK_WIDGET(widget), "content_wnd_edit");
00291     gtk_widget_set_size_request(widget, METADATA_ENTRY_WIDTH, METADATA_DESC_HEIGHT);
00292     g_signal_connect_after(G_OBJECT(widget), "changed",              G_CALLBACK(on_changed),        NULL);
00293     gtk_box_pack_start(GTK_BOX(parent), widget, FALSE, FALSE, 0);    
00294     gtk_widget_show(widget);
00295     g_wnd.descEntry = widget;
00296 
00297     // descEdit2
00298     widget = ergtk_entry_new();
00299     gtk_widget_set_name(GTK_WIDGET(widget), "content_wnd_edit");
00300     gtk_widget_set_size_request(widget, METADATA_ENTRY_WIDTH, METADATA_DESC_HEIGHT);
00301     g_signal_connect_after(G_OBJECT(widget), "changed",              G_CALLBACK(on_changed),        NULL);
00302     gtk_box_pack_start(GTK_BOX(parent), widget, FALSE, FALSE, 0);    
00303     gtk_widget_show(widget);
00304     g_wnd.descEntry2 = widget;
00305 }

Here is the call graph for this function:

static void createFinishItem ( GtkWidget *  parent  )  [static]

Definition at line 311 of file gtkMetadataWnd.c.

00312 {
00313     GtkWidget* widget;
00314 
00315     CL_LOGPRINTF("entry");
00316 
00317     // title tag
00318     widget = gtk_label_new("");
00319     gtk_widget_set_name(GTK_WIDGET(widget), "content_wnd_text_bold");
00320     gtk_widget_set_size_request(widget, -1, METADATA_TAG_HEIGHT);
00321     gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 1.0);
00322     gtk_box_pack_start(GTK_BOX(parent), widget, FALSE, FALSE, 0);
00323     gtk_widget_show(widget);
00324     g_wnd.finishTag = widget;
00325     
00326     return;
00327 }

static void createNameItem ( GtkWidget *  parent  )  [static]

Definition at line 153 of file gtkMetadataWnd.c.

00154 {
00155     GtkWidget* widget;
00156 
00157     CL_LOGPRINTF("entry");
00158 
00159     // nameTag
00160     widget = gtk_label_new("");
00161     gtk_widget_set_name(GTK_WIDGET(widget), "content_wnd_text_bold");
00162     gtk_widget_set_size_request(widget, -1, METADATA_TAG_HEIGHT);
00163     gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 1.0);
00164     gtk_box_pack_start(GTK_BOX(parent), widget, FALSE, FALSE, 0);
00165     gtk_widget_show(widget);
00166     g_wnd.nameTag = widget;
00167 
00168     // nameEntry
00169     widget = ergtk_entry_new();
00170     gtk_widget_set_name(GTK_WIDGET(widget), "content_wnd_edit");
00171     gtk_widget_set_size_request(widget, METADATA_ENTRY_WIDTH, METADATA_NAME_HEIGHT);
00172     g_signal_connect_after(G_OBJECT(widget), "changed",              G_CALLBACK(on_changed),        NULL);
00173     gtk_box_pack_start(GTK_BOX(parent), widget, FALSE, FALSE, 0);    
00174     gtk_widget_show(widget);
00175     g_wnd.nameEntry = widget;
00176 }

Here is the call graph for this function:

static void on_changed ( GtkEditable *  widget,
gpointer  data 
) [static]

Definition at line 75 of file gtkMetadataWnd.c.

00076 {
00077     CL_LOGPRINTF("entry");
00078 
00079     // check for illegal characters in title/filename
00080     if (GTK_WIDGET(widget) == g_wnd.nameEntry)
00081     {
00082         const char* illegal_chars = ILLEGAL_FILENAME_CHARS;
00083         const char* title = gtk_entry_get_text(GTK_ENTRY(widget));
00084         //
00085         char* new_title = alloca( strlen(title) + 1 );
00086         strcpy(new_title, title);
00087         //
00088         gboolean found = FALSE;
00089         char* cp = new_title;
00090         while (*cp)
00091         {
00092             if ( strchr(illegal_chars, *cp) )
00093             {
00094                 *cp = '-';
00095                 found = TRUE;
00096             }
00097             cp++;
00098         }
00099         if (found)
00100         {
00101             CL_ERRORPRINTF("illegal title [%s] new_title [%s]", title, new_title);
00102             gtk_entry_set_text(GTK_ENTRY(widget), new_title);
00103         }
00104     }
00105 }

static gboolean on_expose ( GtkWidget *  widget,
GdkEventExpose *  event,
gpointer  data 
) [static]

Definition at line 123 of file gtkMetadataWnd.c.

00124 {
00125     CL_LOGPRINTF("entry");
00126 
00127     gtk_widget_grab_focus(GTK_WIDGET(g_wnd.descEntry));
00128     /* problems with multi-line editor */
00129     const char* cp = gtk_entry_get_text(GTK_ENTRY(g_wnd.descEntry2));
00130     if (cp != NULL  &&  cp[0] != '\0')
00131     {
00132         gtk_widget_grab_focus(GTK_WIDGET(g_wnd.descEntry2));
00133     }
00134 
00135     // de-select all characters, cursor at end of input field
00136     gtk_editable_select_region(GTK_EDITABLE(g_wnd.descEntry), -1, -1);
00137     gtk_editable_select_region(GTK_EDITABLE(g_wnd.descEntry2), -1, -1);
00138 
00139     display_update_request_screen_refresh(LISTER_EXPOSE_LEVEL);
00140 
00141     return FALSE;
00142 }

Here is the call graph for this function:


Variable Documentation

cmMetadata_t g_wnd [static]

Definition at line 66 of file gtkMetadataWnd.c.


Generated on Sun Dec 14 17:13:30 2008 by  doxygen 1.5.6