2005-11-08 [wwp] 1.9.100cvs1
[claws.git] / src / main.c
index 07e7a112e4edc534693df3a778750c3efa6e3352..3b35b587e46a0fb3f89c4c1aa0db45df900ee531 100644 (file)
@@ -14,7 +14,7 @@
  *
  * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -24,6 +24,7 @@
 #include "defs.h"
 
 #include <glib.h>
+#include <glib/gi18n.h>
 #include <gtk/gtkmain.h>
 #include <gtk/gtkrc.h>
 
@@ -35,7 +36,9 @@
 #include <time.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <signal.h>
+#ifdef G_OS_UNIX
+#  include <signal.h>
+#endif
 #include "wizard.h"
 #ifdef HAVE_STARTUP_NOTIFICATION
 # define SN_API_NOT_YET_FROZEN
 #endif
 
 #include "sylpheed.h"
-#include "intl.h"
 #include "main.h"
 #include "mainwindow.h"
 #include "folderview.h"
+#include "image_viewer.h"
 #include "summaryview.h"
 #include "prefs_common.h"
 #include "prefs_account.h"
 #include "prefs_actions.h"
 #include "prefs_ext_prog.h"
 #include "prefs_fonts.h"
+#include "prefs_image_viewer.h"
+#include "prefs_message.h"
+#include "prefs_receive.h"
 #include "prefs_msg_colors.h"
+#include "prefs_quote.h"
 #include "prefs_spelling.h"
+#include "prefs_summaries.h"
 #include "prefs_themes.h"
+#include "prefs_other.h"
+#include "prefs_send.h"
 #include "prefs_wrapping.h"
+#include "prefs_compose_writing.h"
 #include "prefs_display_header.h"
 #include "account.h"
 #include "procmsg.h"
 #include "imap_gtk.h"
 #include "news_gtk.h"
 #include "matcher.h"
+#ifdef HAVE_LIBETPAN
+#include "imap-thread.h"
+#endif
+#include "stock_pixmap.h"
 
 #if USE_OPENSSL
 #  include "ssl.h"
@@ -123,6 +138,7 @@ static struct RemoteCmd {
        gboolean crash;
        int online_mode;
        gchar   *crash_params;
+       gboolean exit;
 } cmd;
 
 static void parse_cmd_opt(int argc, char *argv[]);
@@ -148,18 +164,12 @@ static void quit_signal_handler         (int sig);
 static void install_basic_sighandlers   (void);
 static void exit_sylpheed              (MainWindow *mainwin);
 
-#if 0
-/* for gettext */
-_("File `%s' already exists.\n"
-  "Can't create folder.")
-#endif
-
 #define MAKE_DIR_IF_NOT_EXIST(dir) \
 { \
        if (!is_dir_exist(dir)) { \
                if (is_file_exist(dir)) { \
                        alertpanel_warning \
-                               (_("File `%s' already exists.\n" \
+                               (_("File '%s' already exists.\n" \
                                   "Can't create folder."), \
                                 dir); \
                        return 1; \
@@ -193,7 +203,7 @@ static void startup_notification_complete(gboolean with_window)
                 * We have to display a window, so let it be very little */
                hack = gtk_window_new(GTK_WINDOW_POPUP);
                gtk_widget_set_uposition(hack, 0, 0);
-               gtk_widget_set_usize(hack, 1, 1);
+               gtk_widget_set_size_request(hack, 1, 1);
                gtk_widget_show(hack);
        }
 
@@ -210,6 +220,8 @@ static void startup_notification_complete(gboolean with_window)
                sn_launchee_context_unref(sn_context);
                sn_display_unref(sn_display);
        }
+       if (with_window)
+               gtk_widget_destroy(hack);
 }
 #endif /* HAVE_STARTUP_NOTIFICATION */
 
@@ -217,6 +229,47 @@ void sylpheed_gtk_idle(void)
 {
        while(gtk_events_pending())
                gtk_main_iteration();
+       usleep(50000);
+}
+
+gboolean defer_check_all(void *data)
+{
+       gboolean autochk = GPOINTER_TO_INT(data);
+
+       inc_all_account_mail(static_mainwindow, autochk, 
+                       prefs_common.newmail_notify_manu);
+
+       return FALSE;
+}
+
+gboolean defer_check(void *data)
+{
+       inc_mail(static_mainwindow, prefs_common.newmail_notify_manu);
+
+       return FALSE;
+}
+
+static gboolean migrate_old_config(const gchar *old_cfg_dir, const gchar *new_cfg_dir)
+{
+       gchar *message = g_strdup_printf(_("Configuration for Sylpheed-Claws %s found.\n"
+                        "Do you want to migrate this configuration?"),
+                        !strcmp(old_cfg_dir, OLD_GTK1_RC_DIR)?
+                               _("1.0.5 or previous"):_("1.9.15 or previous"));
+       gint r = 0;
+       GtkWidget *window = NULL;
+       if (alertpanel(_("Migration of configuration"),
+                      message,
+                      GTK_STOCK_YES, GTK_STOCK_NO, NULL) != G_ALERTDEFAULT)
+               return FALSE;
+       
+       window = label_window_create(_("Copying configuration..."));
+       GTK_EVENTS_FLUSH();
+       r = copy_dir(old_cfg_dir, new_cfg_dir);
+       gtk_widget_destroy(window);
+       if (r != 0) {
+               alertpanel_error(_("Migration failed!"));
+       }
+       return (r == 0);
 }
 
 int main(int argc, char *argv[])
@@ -224,6 +277,8 @@ int main(int argc, char *argv[])
        gchar *userrc;
        MainWindow *mainwin;
        FolderView *folderview;
+       GdkPixbuf *icon;
+       gboolean crash_file_present = FALSE;
 
        if (!sylpheed_init(&argc, &argv)) {
                return 0;
@@ -246,8 +301,10 @@ int main(int argc, char *argv[])
        crash_install_handlers();
 #endif
        install_basic_sighandlers();
+       sock_init();
 
-       /* check and create unix domain socket */
+       /* check and create unix domain socket for remote operation */
+#ifdef G_OS_UNIX
        lock_socket = prohibit_duplicate_launch();
        if (lock_socket < 0) {
 #ifdef HAVE_STARTUP_NOTIFICATION
@@ -262,19 +319,19 @@ int main(int argc, char *argv[])
                lock_socket_remove();
                return 0;
        }
+#endif
+       g_thread_init(NULL);
+       /* gdk_threads_init(); */
 
        gtk_set_locale();
        gtk_init(&argc, &argv);
 
        gdk_rgb_init();
-       gtk_widget_set_default_colormap(gdk_rgb_get_cmap());
+       gtk_widget_set_default_colormap(gdk_rgb_get_colormap());
        gtk_widget_set_default_visual(gdk_rgb_get_visual());
 
-#if USE_THREADS || USE_LDAP
-       g_thread_init(NULL);
        if (!g_thread_supported())
                g_error(_("g_thread is not supported by glib.\n"));
-#endif
 
        /* parse gtkrc files */
        userrc = g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S, ".gtkrc-2.0",
@@ -285,6 +342,18 @@ int main(int argc, char *argv[])
                             G_DIR_SEPARATOR_S, "gtkrc-2.0", NULL);
        gtk_rc_parse(userrc);
        g_free(userrc);
+
+       CHDIR_RETURN_VAL_IF_FAIL(get_home_dir(), 1);
+       if (!is_dir_exist(RC_DIR)) {
+               gboolean r = FALSE;
+               if (is_dir_exist(OLD_GTK2_RC_DIR))
+                       r = migrate_old_config(OLD_GTK2_RC_DIR, RC_DIR);
+               else if (is_dir_exist(OLD_GTK1_RC_DIR))
+                       r = migrate_old_config(OLD_GTK1_RC_DIR, RC_DIR);
+               if (r == FALSE && !is_dir_exist(RC_DIR) && make_dir(RC_DIR) < 0)
+                       exit(1);
+       }
+
        userrc = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, "gtkrc-2.0", NULL);
        gtk_rc_parse(userrc);
        g_free(userrc);
@@ -297,33 +366,53 @@ int main(int argc, char *argv[])
                                       "gtk-can-change-accels",
                                       (glong)TRUE, "XProperty");
 
-       CHDIR_RETURN_VAL_IF_FAIL(get_home_dir(), 1);
+       CHDIR_RETURN_VAL_IF_FAIL(get_rc_dir(), 1);
 
-       MAKE_DIR_IF_NOT_EXIST(RC_DIR);
        MAKE_DIR_IF_NOT_EXIST(get_imap_cache_dir());
        MAKE_DIR_IF_NOT_EXIST(get_news_cache_dir());
        MAKE_DIR_IF_NOT_EXIST(get_mime_tmp_dir());
        MAKE_DIR_IF_NOT_EXIST(get_tmp_dir());
-       MAKE_DIR_IF_NOT_EXIST(RC_DIR G_DIR_SEPARATOR_S "uidl");
+       MAKE_DIR_IF_NOT_EXIST(UIDL_DIR);
 
-       set_log_file(RC_DIR G_DIR_SEPARATOR_S "sylpheed.log");
+       crash_file_present = is_file_exist(get_crashfile_name());
+       /* remove temporary files */
+       remove_all_files(get_tmp_dir());
+       remove_all_files(get_mime_tmp_dir());
+
+       if (is_file_exist("sylpheed.log")) {
+               if (rename_force("sylpheed.log", "sylpheed.log.bak") < 0)
+                       FILE_OP_ERROR("sylpheed.log", "rename");
+       }
+       set_log_file("sylpheed.log");
+
+       CHDIR_RETURN_VAL_IF_FAIL(get_home_dir(), 1);
 
        folder_system_init();
-       prefs_common_init();
        prefs_common_read_config();
 
        prefs_themes_init();
        prefs_fonts_init();
        prefs_ext_prog_init();
        prefs_wrapping_init();
+       prefs_compose_writing_init();
        prefs_msg_colors_init();
+       image_viewer_init();
+       prefs_image_viewer_init();
+       prefs_quote_init();
+       prefs_summaries_init();
+       prefs_message_init();
+       prefs_other_init();
+       prefs_receive_init();
+       prefs_send_init();
 #ifdef USE_ASPELL
        gtkaspell_checkers_init();
        prefs_spelling_init();
 #endif
        
        sock_set_io_timeout(prefs_common.io_timeout_secs);
-
+#ifdef HAVE_LIBETPAN
+       imap_main_set_timeout(prefs_common.io_timeout_secs);
+#endif
        prefs_actions_read_config();
        prefs_display_header_read_config();
        /* prefs_filtering_read_config(); */
@@ -331,8 +420,11 @@ int main(int argc, char *argv[])
        renderer_read_config();
 
        gtkut_widget_init();
+       stock_pixbuf_gdk(NULL, STOCK_PIXMAP_SYLPHEED_ICON, &icon);
+       gtk_window_set_default_icon(icon);
 
        folderview_initialize();
+
        mh_gtk_init();
        imap_gtk_init();
        news_gtk_init();
@@ -341,11 +433,16 @@ int main(int argc, char *argv[])
                (prefs_common.sep_folder | prefs_common.sep_msg << 1);
        folderview = mainwin->folderview;
 
+       gtk_clist_freeze(GTK_CLIST(mainwin->folderview->ctree));
+       folder_item_update_freeze();
+
        /* register the callback of unix domain socket input */
+#ifdef G_OS_UNIX
        lock_socket_tag = gdk_input_add(lock_socket,
                                        GDK_INPUT_READ | GDK_INPUT_EXCEPTION,
                                        lock_socket_input_cb,
                                        mainwin);
+#endif
 
        prefs_account_init();
        account_read_config_all();
@@ -364,6 +461,11 @@ int main(int argc, char *argv[])
                        exit_sylpheed(mainwin);
        }
 
+       gtk_window_deiconify(GTK_WINDOW(mainwin->window));
+
+#ifdef HAVE_LIBETPAN
+       imap_main_init();
+#endif 
        account_set_missing_folder();
        folder_set_missing_folders();
        folderview_set(folderview);
@@ -373,12 +475,14 @@ int main(int argc, char *argv[])
        /* make one all-folder processing before using sylpheed */
        main_window_cursor_wait(mainwin);
        folder_func_to_all_folders(initial_processing, (gpointer *)mainwin);
-       main_window_cursor_normal(mainwin);
 
        /* if Sylpheed crashed, rebuild caches */
-       if (!cmd.crash && is_file_exist(get_crashfile_name())) {
+       if (!cmd.crash && crash_file_present) {
                debug_print("Sylpheed crashed, checking for new messages in local folders\n");
+               folder_item_update_thaw();
                folderview_check_new(NULL);
+               folder_clean_cache_memory_force();
+               folder_item_update_freeze();
        }
        /* make the crash-indicator file */
        str_write_to_file("foo", get_crashfile_name());
@@ -388,12 +492,13 @@ int main(int argc, char *argv[])
        inc_autocheck_timer_init(mainwin);
 
        /* ignore SIGPIPE signal for preventing sudden death of program */
+#ifdef G_OS_UNIX
        signal(SIGPIPE, SIG_IGN);
-
+#endif
        if (cmd.online_mode == ONLINE_MODE_OFFLINE)
-               main_window_toggle_work_offline(mainwin, TRUE);
+               main_window_toggle_work_offline(mainwin, TRUE, FALSE);
        if (cmd.online_mode == ONLINE_MODE_ONLINE)
-               main_window_toggle_work_offline(mainwin, FALSE);
+               main_window_toggle_work_offline(mainwin, FALSE, FALSE);
 
        if (cmd.status_folders) {
                g_ptr_array_free(cmd.status_folders, TRUE);
@@ -415,15 +520,16 @@ int main(int argc, char *argv[])
 #ifdef HAVE_STARTUP_NOTIFICATION
        startup_notification_complete(FALSE);
 #endif
+       folder_item_update_thaw();
+       gtk_clist_thaw(GTK_CLIST(mainwin->folderview->ctree));
+       main_window_cursor_normal(mainwin);
 
        if (cmd.receive_all)
-               inc_all_account_mail(mainwin, FALSE, 
-                                    prefs_common.newmail_notify_manu);
+               g_timeout_add(1000, defer_check_all, GINT_TO_POINTER(FALSE));
        else if (prefs_common.chk_on_startup)
-               inc_all_account_mail(mainwin, TRUE, 
-                                    prefs_common.newmail_notify_manu);
+               g_timeout_add(1000, defer_check_all, GINT_TO_POINTER(TRUE));
        else if (cmd.receive)
-               inc_mail(mainwin, prefs_common.newmail_notify_manu);
+               g_timeout_add(1000, defer_check, NULL);
        else
                gtk_widget_grab_focus(folderview->ctree);
 
@@ -456,7 +562,6 @@ static void exit_sylpheed(MainWindow *mainwin)
        gchar *filename;
 
        debug_print("shutting down\n");
-
        inc_autocheck_timer_remove();
 
        if (prefs_common.clean_on_exit)
@@ -486,13 +591,17 @@ static void exit_sylpheed(MainWindow *mainwin)
        g_free(filename);
 
        /* delete temporary files */
+       remove_all_files(get_tmp_dir());
        remove_all_files(get_mime_tmp_dir());
 
        close_log_file();
 
+#ifdef HAVE_LIBETPAN
+       imap_main_done();
+#endif
        /* delete crashfile */
        if (!cmd.crash)
-               unlink(get_crashfile_name());
+               g_unlink(get_crashfile_name());
 
        lock_socket_remove();
 
@@ -508,7 +617,16 @@ static void exit_sylpheed(MainWindow *mainwin)
        prefs_fonts_done();
        prefs_ext_prog_done();
        prefs_wrapping_done();
+       prefs_compose_writing_done();
        prefs_msg_colors_done();
+       prefs_image_viewer_done();
+       image_viewer_done();
+       prefs_quote_done();
+       prefs_summaries_done();
+       prefs_message_done();
+       prefs_other_done();
+       prefs_receive_done();
+       prefs_send_done();
 #ifdef USE_ASPELL       
        prefs_spelling_done();
        gtkaspell_checkers_quit();
@@ -558,7 +676,7 @@ static void parse_cmd_opt(int argc, char *argv[])
                } else if (!strncmp(argv[i], "--send", 6)) {
                        cmd.send = TRUE;
                } else if (!strncmp(argv[i], "--version", 9)) {
-                       puts("Sylpheed version " VERSION);
+                       puts("Sylpheed-Claws version " VERSION);
                        exit(0);
                } else if (!strncmp(argv[i], "--status-full", 13)) {
                        const gchar *p = argv[i + 1];
@@ -593,22 +711,23 @@ static void parse_cmd_opt(int argc, char *argv[])
                        gchar *base = g_path_get_basename(argv[0]);
                        g_print(_("Usage: %s [OPTION]...\n"), base);
 
-                       puts(_("  --compose [address]    open composition window"));
-                       puts(_("  --attach file1 [file2]...\n"
-                              "                         open composition window with specified files\n"
-                              "                         attached"));
-                       puts(_("  --receive              receive new messages"));
-                       puts(_("  --receive-all          receive new messages of all accounts"));
-                       puts(_("  --send                 send all queued messages"));
-                       puts(_("  --status [folder]...   show the total number of messages"));
-                       puts(_("  --status-full [folder]...\n"
+                       g_print("%s\n", _("  --compose [address]    open composition window"));
+                       g_print("%s\n", _("  --attach file1 [file2]...\n"
+                                 "                         open composition window with specified files\n"
+                                 "                         attached"));
+                       g_print("%s\n", _("  --receive              receive new messages"));
+                       g_print("%s\n", _("  --receive-all          receive new messages of all accounts"));
+                       g_print("%s\n", _("  --send                 send all queued messages"));
+                       g_print("%s\n", _("  --status [folder]...   show the total number of messages"));
+                       g_print("%s\n", _("  --status-full [folder]...\n"
                               "                         show the status of each folder"));
-                       puts(_("  --online               switch to online mode"));
-                       puts(_("  --offline              switch to offline mode"));
-                       puts(_("  --debug                debug mode"));
-                       puts(_("  --help                 display this help and exit"));
-                       puts(_("  --version              output version information and exit"));
-                       puts(_("  --config-dir           output configuration directory"));
+                       g_print("%s\n", _("  --online               switch to online mode"));
+                       g_print("%s\n", _("  --offline              switch to offline mode"));
+                       g_print("%s\n", _("  --exit                 exit Sylpheed-Claws"));
+                       g_print("%s\n", _("  --debug                debug mode"));
+                       g_print("%s\n", _("  --help                 display this help and exit"));
+                       g_print("%s\n", _("  --version              output version information and exit"));
+                       g_print("%s\n", _("  --config-dir           output configuration directory"));
 
                        g_free(base);
                        exit(1);
@@ -619,6 +738,8 @@ static void parse_cmd_opt(int argc, char *argv[])
                } else if (!strncmp(argv[i], "--config-dir", sizeof "--config-dir" - 1)) {
                        puts(RC_DIR);
                        exit(0);
+               } else if (!strncmp(argv[i], "--exit", 6)) {
+                       cmd.exit = TRUE;
                }
                
        }
@@ -663,15 +784,11 @@ static void initial_processing(FolderItem *item, gpointer data)
 
 static void draft_all_messages(void)
 {
-       GList *compose_list = compose_get_compose_list();
-       GList *elem = NULL;
+       GList *compose_list = NULL;
        
-       if (compose_list) {
-               for (elem = compose_list; elem != NULL && elem->data != NULL; 
-                    elem = elem->next) {
-                       Compose *c = (Compose*)elem->data;
-                       compose_draft(c);
-               }
+       while ((compose_list = compose_get_compose_list()) != NULL) {
+               Compose *c = (Compose*)compose_list->data;
+               compose_draft(c);
        }       
 }
 
@@ -709,11 +826,11 @@ gboolean clean_quit(gpointer data)
 void app_will_exit(GtkWidget *widget, gpointer data)
 {
        MainWindow *mainwin = data;
-       
+
        if (compose_get_compose_list()) {
                gint val = alertpanel(_("Really quit?"),
                               _("Composing message exists."),
-                              _("Draft them"), _("Discard them"), _("Don't quit"));
+                              _("_Save to Draft"), _("_Discard them"), _("Do_n't quit"));
                switch (val) {
                        case G_ALERTOTHER:
                                return;
@@ -722,7 +839,7 @@ void app_will_exit(GtkWidget *widget, gpointer data)
                        default:
                                draft_all_messages();
                }
-               
+
                manage_window_focus_in(mainwin->window, NULL, NULL);
        }
 
@@ -734,6 +851,9 @@ void app_will_exit(GtkWidget *widget, gpointer data)
                        return;
                manage_window_focus_in(mainwin->window, NULL, NULL);
        }
+
+       sock_cleanup();
+
        gtk_main_quit();
 }
 
@@ -749,9 +869,13 @@ gchar *get_socket_name(void)
        static gchar *filename = NULL;
 
        if (filename == NULL) {
-               filename = g_strdup_printf("%s%csylpheed-%d",
+               filename = g_strdup_printf("%s%csylpheed-claws-%d",
                                           g_get_tmp_dir(), G_DIR_SEPARATOR,
+#if HAVE_GETUID
                                           getuid());
+#else
+                                          0);                                          
+#endif
        }
 
        return filename;
@@ -777,7 +901,7 @@ static gint prohibit_duplicate_launch(void)
        path = get_socket_name();
        uxsock = fd_connect_unix(path);
        if (uxsock < 0) {
-               unlink(path);
+               g_unlink(path);
                return fd_open_unix(path);
        }
 
@@ -849,6 +973,8 @@ static gint prohibit_duplicate_launch(void)
                        if (!strncmp(buf, ".\n", 2)) break;
                        fputs(buf, stdout);
                }
+       } else if (cmd.exit) {
+               fd_write_all(uxsock, "exit\n", 5);
        } else
                fd_write_all(uxsock, "popup\n", 6);
 
@@ -858,6 +984,7 @@ static gint prohibit_duplicate_launch(void)
 
 static gint lock_socket_remove(void)
 {
+#ifdef G_OS_UNIX
        gchar *filename;
 
        if (lock_socket < 0) return -1;
@@ -866,7 +993,8 @@ static gint lock_socket_remove(void)
                gdk_input_remove(lock_socket_tag);
        fd_close(lock_socket);
        filename = get_socket_name();
-       unlink(filename);
+       g_unlink(filename);
+#endif
 
        return 0;
 }
@@ -930,9 +1058,9 @@ static void lock_socket_input_cb(gpointer data,
        } else if (!strncmp(buf, "send", 4)) {
                send_queue();
        } else if (!strncmp(buf, "online", 6)) {
-               main_window_toggle_work_offline(mainwin, FALSE);
+               main_window_toggle_work_offline(mainwin, FALSE, FALSE);
        } else if (!strncmp(buf, "offline", 7)) {
-               main_window_toggle_work_offline(mainwin, TRUE);
+               main_window_toggle_work_offline(mainwin, TRUE, FALSE);
        } else if (!strncmp(buf, "status-full", 11) ||
                   !strncmp(buf, "status", 6)) {
                gchar *status;
@@ -945,6 +1073,8 @@ static void lock_socket_input_cb(gpointer data,
                fd_write_all(sock, ".\n", 2);
                g_free(status);
                if (folders) g_ptr_array_free(folders, TRUE);
+       } else if (!strncmp(buf, "exit", 4)) {
+               app_will_exit(NULL, mainwin);
        }
 
        fd_close(sock);