aboutsummaryrefslogblamecommitdiffstats
path: root/shell/e-shell.c
blob: 9678790d7279e0bf07df11fa420735e6f03886e2 (plain) (tree)
1
2
3
4
5
6
7
8
9


                                                                           
                                                        

                                                                
                                                                   
                                                        
  



                                                                    
  

                                                            

                                                                   
   
 
                    
 
                       
                                 
                          



                             
                                                       
 
                             
 
               
                                                         
 


                                                                     
 

                                                         


           

                                                           
 
                                                                              
 


                                                      

 
               
                             
 



                                       
 
                                                    
                                                
 



                                                                       
 



                                                               
 


                                                                        

         
                                                 
 







                                                                        
 




                                                                       
 


                                                                     

 
              
                            
 
                                
                           
 




                                                                        
 
                                                                       
 


                                                                 
 


                                                      
 



                                                                     
                                       

                                             
 




































                                                                            


                                        


                                                               




















                                          

                                     
 
                                                    
 

                                                                 
 
                                  
 




















                      
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* e-shell.c
 *
 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "e-shell.h"

#include <glib/gi18n.h>
#include <e-preferences-window.h>
#include <e-util/e-util.h>

#include "e-shell-module.h"
#include "e-shell-registry.h"

#define SHUTDOWN_TIMEOUT    500  /* milliseconds */

static GList *active_windows;

static gboolean
shell_window_delete_event_cb (EShellWindow *shell_window)
{
    /* If other windows are open we can safely close this one. */
    if (g_list_length (active_windows) > 1)
        return FALSE;

    /* Otherwise we initiate application shutdown. */
    return !e_shell_quit ();
}

static void
shell_window_weak_notify_cb (gpointer unused,
                             GObject *where_the_object_was)
{
    active_windows = g_list_remove (active_windows, where_the_object_was);

    /* If that was the last window, we're done. */
    if (active_windows == NULL)
        gtk_main_quit ();
}

static gboolean
shell_shutdown_timeout (void)
{
    GList *list, *iter;
    gboolean proceed = TRUE;
    static guint source_id = 0;
    static guint message_timer = 1;

    /* Module list is read-only; do not free. */
    list = e_shell_registry_list_modules ();

    /* Any module can defer shutdown if it's still busy. */
    for (iter = list; proceed && iter != NULL; iter = iter->next) {
        EShellModule *shell_module = iter->data;
        proceed = e_shell_module_shutdown (shell_module);

        /* Emit a message every few seconds to indicate
         * which module(s) we're still waiting on. */
        if (proceed || message_timer == 0)
            continue;

        g_message (
            _("Waiting for the \"%s\" module to finish..."),
            G_TYPE_MODULE (shell_module)->name);
    }

    message_timer = (message_timer + 1) % 10;

    /* If we're go for shutdown, destroy all shell windows.  Note,
     * we iterate over a /copy/ of the active windows list because
     * the act of destroying a shell window will modify the active
     * windows list, which would otherwise derail the iteration. */
    if (proceed) {
        list = g_list_copy (active_windows);
        g_list_foreach (list, (GFunc) gtk_widget_destroy, NULL);
        g_list_free (list);

    /* If a module is still busy, try again after a short delay. */
    } else if (source_id == 0)
        source_id = g_timeout_add (
            SHUTDOWN_TIMEOUT, (GSourceFunc)
            shell_shutdown_timeout, NULL);

    /* Return TRUE to repeat the timeout, FALSE to stop it.  This
     * may seem backwards if the function was called directly. */
    return !proceed;
}

EShellWindow *
e_shell_create_window (void)
{
    GtkWidget *shell_window;
    gboolean safe_mode;

    /* Put the first window into safe mode if we detect the previous
     * session did not shut down cleanly, perhaps due to a crash. */
    safe_mode = (active_windows == NULL) && e_file_lock_exists ();

    shell_window = e_shell_window_new (safe_mode);

    active_windows = g_list_prepend (active_windows, shell_window);

    g_signal_connect (
        shell_window, "delete-event",
        G_CALLBACK (shell_window_delete_event_cb), NULL);

    g_object_weak_ref (
        G_OBJECT (shell_window), (GWeakNotify)
        shell_window_weak_notify_cb, NULL);

    g_list_foreach (
        e_shell_registry_list_modules (),
        (GFunc) e_shell_module_window_created, shell_window);

    gtk_widget_show (shell_window);

    return E_SHELL_WINDOW (shell_window);
}

gboolean
e_shell_handle_uri (const gchar *uri)
{
    EShellModule *shell_module;
    GFile *file;
    gchar *scheme;

    g_return_val_if_fail (uri != NULL, FALSE);

    file = g_file_new_for_uri (uri);
    scheme = g_file_get_uri_scheme (file);
    g_object_unref (file);

    if (scheme == NULL)
        return FALSE;

    shell_module = e_shell_registry_get_module_by_scheme (scheme);

    /* Scheme lookup failed so try looking up the shell module by
     * name.  Note, we only open a shell window if the URI refers
     * to a shell module by name, not by scheme. */
    if (shell_module == NULL) {
        EShellWindow *shell_window;

        shell_module = e_shell_registry_get_module_by_name (scheme);

        if (shell_module == NULL)
            return FALSE;

        shell_window = e_shell_create_window ();
        /* FIXME  Set window to appropriate view. */
    }

    return e_shell_module_handle_uri (shell_module, uri);
}

void
e_shell_send_receive (GtkWindow *parent)
{
    g_list_foreach (
        e_shell_registry_list_modules (),
        (GFunc) e_shell_module_send_and_receive, NULL);
}

void
e_shell_go_offline (void)
{
    /* FIXME */
}

void
e_shell_go_online (void)
{
    /* FIXME */
}

EShellLineStatus
e_shell_get_line_status (void)
{
    /* FIXME */
    return E_SHELL_LINE_STATUS_ONLINE;
}

GtkWidget *
e_shell_get_preferences_window (void)
{
    static GtkWidget *preferences_window = NULL;

    if (G_UNLIKELY (preferences_window == NULL))
        preferences_window = e_preferences_window_new ();

    return preferences_window;
}

gboolean
e_shell_is_busy (void)
{
    /* FIXME */
    return FALSE;
}

gboolean
e_shell_do_quit (void)
{
    /* FIXME */
    return TRUE;
}

gboolean
e_shell_quit (void)
{
    /* FIXME */
    return TRUE;
}