static void
shell_app_system_finalize (GObject *object)
{
  ShellAppSystem *self = SHELL_APP_SYSTEM (object);
  ShellAppSystemPrivate *priv = self->priv;

  gmenu_tree_remove_monitor (priv->apps_tree, on_tree_changed_cb, self);
  gmenu_tree_remove_monitor (priv->settings_tree, on_tree_changed_cb, self);

  gmenu_tree_unref (priv->apps_tree);
  gmenu_tree_unref (priv->settings_tree);

  g_hash_table_destroy (priv->app_id_to_info);
  g_hash_table_destroy (priv->app_id_to_app);

  g_slist_foreach (priv->cached_flattened_apps, (GFunc)shell_app_info_unref, NULL);
  g_slist_free (priv->cached_flattened_apps);
  priv->cached_flattened_apps = NULL;

  g_slist_foreach (priv->known_vendor_prefixes, (GFunc)g_free, NULL);
  g_slist_free (priv->known_vendor_prefixes);
  priv->known_vendor_prefixes = NULL;

  g_slist_foreach (priv->cached_settings, (GFunc)shell_app_info_unref, NULL);
  g_slist_free (priv->cached_settings);
  priv->cached_settings = NULL;

  G_OBJECT_CLASS (shell_app_system_parent_class)->finalize(object);
}
/*! \fn gboolean CDesktopAppChooser::m_DoModal(void)
    \brief Desktop App Chooser runs in modal mode.

    \return TRUE or FALSE
*/
gboolean CDesktopAppChooser::m_DoModal(void)
{
  /* Sets a window modal or non-modal. */
  gtk_window_set_modal(GTK_WINDOW(m_pWidgets[APPCHOOSER_GtkWindow_Main]), TRUE);

  if( m_pwParent != NULL )
  {
     /* Dialog windows should be set transient for the main application window they were spawned from.
        This allows window managers to e.g. keep the dialog on top of the main window, or center the
        dialog over the main window. */
     gtk_window_set_transient_for(GTK_WINDOW(m_pWidgets[APPCHOOSER_GtkWindow_Main]), GTK_WINDOW(m_pwParent));

     /* Creates the GDK (windowing system) resources associated with a widget. */
     gtk_widget_realize(m_pWidgets[APPCHOOSER_GtkWindow_Main]);

     /* Sets hints about the window management functions to make available via buttons on the window frame. */
     gdk_window_set_functions(m_pWidgets[APPCHOOSER_GtkWindow_Main]->window, (GdkWMFunction)(GDK_FUNC_CLOSE|GDK_FUNC_MOVE));
  }

  /* Show all widgets */
  gtk_widget_show_all(m_pWidgets[APPCHOOSER_GtkWindow_Main]);

  /* Start to run. */
  gtk_main();

//-------------- When the modal is terminated, it must grab the current list store of the tree-view, else it will make a big big trouble!	
  /* To decrease the reference counter of the menu directory object. */
  gmenu_tree_item_unref(m_RootDir);

  /* To decrease the reference counter of the menu tree object. */
  gmenu_tree_unref(m_MenuTree);

  return TRUE;
}
Esempio n. 3
0
int main(int argc, char** argv)
{
    GOptionContext* opt_ctx;
    GError* err = NULL;
    GMenuTree* menu_tree = NULL;
    GMenuTreeDirectory* root_dir;
    GSList* l;
    FILE *of;
    int ofd;
    char *tmp;
    char *dir;
    const gchar* const * xdg_cfg_dirs;
    const gchar* const * pdir;
    const char* menu_prefix;
    char* menu_file;
    char* plus_ptr = NULL;

    setlocale (LC_ALL, "");

    opt_ctx = g_option_context_new("Generate cache for freedesktop.org compliant menus.");
    g_option_context_add_main_entries( opt_ctx, opt_entries, NULL );
    if( ! g_option_context_parse( opt_ctx, &argc, &argv, &err ) )
    {
        g_print( "%s", err->message );
        g_error_free( err );
        return 1;
    }

    if( lang )
        g_setenv( "LANGUAGE", lang, TRUE );
#if 0
    /* if the cache is already up-to-date, just leave it. */
    if( !force && is_menu_uptodate() )
    {
        g_print("upda-to-date, re-generation is not needed.");
        return 0;
    }
#endif

    /* some memory leaks happen here if g_free is not used to free the keys. */
    de_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
    g_hash_table_insert( de_hash, (gpointer)"LXDE", (gpointer)SHOW_IN_LXDE );
    g_hash_table_insert( de_hash, (gpointer)"GNOME", (gpointer)SHOW_IN_GNOME );
    g_hash_table_insert( de_hash, (gpointer)"KDE", (gpointer)SHOW_IN_KDE );
    g_hash_table_insert( de_hash, (gpointer)"XFCE", (gpointer)SHOW_IN_XFCE );
    g_hash_table_insert( de_hash, (gpointer)"ROX", (gpointer)SHOW_IN_ROX );

    if(ifile)
        plus_ptr = strrchr(ifile, '+');

    if(plus_ptr != NULL && strcmp(plus_ptr, "+hidden") != 0)
        plus_ptr = NULL;

    if(plus_ptr)
    {
        *plus_ptr = '\0';
        menu_tree = gmenu_tree_lookup( ifile, GMENU_TREE_FLAGS_INCLUDE_NODISPLAY | GMENU_TREE_FLAGS_INCLUDE_EXCLUDED | GMENU_TREE_FLAGS_SHOW_EMPTY );
        *plus_ptr = '+';
    }
    else
        menu_tree = gmenu_tree_lookup( ifile, GMENU_TREE_FLAGS_INCLUDE_EXCLUDED );
    if( ! menu_tree )
    {
        g_print("Error loading source menu file: %s\n", ifile);
        return 1;
    }

    dir = g_path_get_dirname( ofile );
    if( !g_file_test( dir, G_FILE_TEST_EXISTS ) )
        g_mkdir_with_parents( dir, 0700 );
    g_free( dir );

    /* write the tree to cache. */
    tmp = g_malloc( strlen( ofile ) + 7 );
    strcpy( tmp, ofile );
    strcat( tmp, "XXXXXX" );
    ofd = g_mkstemp( tmp );
    if( ofd == -1 )
    {
        g_print( "Error writing output file: %s\n", g_strerror(errno) );
        return 1;
    }

    of = fdopen( ofd, "w" );
    if( ! of )
    {
        g_print( "Error writing output file: %s\n", ofile );
        return 1;
    }

    /* Version number should be added to the head of this cache file. */
    fprintf( of, "%d.%d\n", VER_MAJOR, VER_MINOR );

    /* the first line is menu name */
    fprintf( of, "%s\n", ifile );

    root_dir = gmenu_tree_get_root_directory( menu_tree );

    /* add the source menu file itself to the list of files requiring monitor */
    if(plus_ptr)
        *plus_ptr = '\0';
    if( g_path_is_absolute(ifile) )
    {
        if( ! g_slist_find_custom(all_used_files, ifile, (GCompareFunc)strcmp ) )
            all_used_files = g_slist_prepend(all_used_files, g_strdup(ifile));
    }
    else
    {
        char* file_name;
        xdg_cfg_dirs = g_get_system_config_dirs();
        menu_prefix = g_getenv("XDG_MENU_PREFIX");
        file_name = menu_prefix ? g_strconcat(menu_prefix, ifile, NULL) : ifile;
        for( pdir = xdg_cfg_dirs; *pdir; ++pdir )
        {
            menu_file = g_build_filename( *pdir, "menus", file_name, NULL );
            if( ! g_slist_find_custom(all_used_dirs, menu_file, (GCompareFunc)strcmp ) )
                all_used_files = g_slist_prepend(all_used_files, menu_file);
            else
                g_free( menu_file );
        }
        menu_file = g_build_filename( g_get_user_config_dir(), "menus", file_name, NULL );
        if( file_name != ifile )
            g_free(file_name);

        if( ! g_slist_find_custom(all_used_dirs, menu_file, (GCompareFunc)strcmp ) )
            all_used_files = g_slist_prepend(all_used_files, menu_file);
        else
            g_free(menu_file);
    }

    /* write a list of all files which need to be monitored for changes. */
    /* write number of files first */
    fprintf( of, "%d\n", g_slist_length(all_used_dirs) + g_slist_length(all_used_files) );

    /* list all files.
     * add D or F at the begin of each line to indicate whether it's a
     * file or directory. */
    for( l = all_used_dirs; l; l = l->next )
    {
        fprintf( of, "D%s\n", (char*)l->data );
    }
    for( l = all_used_files; l; l = l->next )
    {
        fprintf( of, "F%s\n", (char*)l->data );
    }

    /* write all DE names in this menu. Known DEs such as LXDE, GNOME, and KDE don't need to be listed here */
    if( g_hash_table_size(de_hash) > N_KNOWN_DESKTOPS ) /* if there are some unknown DEs added to the hash */
        g_hash_table_foreach(de_hash, (GHFunc)write_de_name, of );
    fputc('\n', of);

    /* write the whole menu tree */
    write_dir( of, root_dir );

    fclose( of );

    gmenu_tree_unref( menu_tree );

    g_hash_table_destroy(de_hash);

    if( g_rename( tmp, ofile ) == -1 )
    {
        g_print( "Error writing output file: %s\n", g_strerror( errno ) );
    }
    g_free( tmp );
    /* g_print("success!\n"); */
    return 0;
}