Commit 105f78db authored by Ettore Perazzoli's avatar Ettore Perazzoli

I18N the message composer's title bar. Don't install header files.

Initial implementation of the "Open" and "Save as" commands (not
really tested/finished, I am just syncing the tree before leaving).
Put the cursor on the "To:" field when the message composer is shown.
Set the correct shadow type in the scroll frame.

svn path=/trunk/; revision=3603
parent 6c220a4a
2000-06-17 Ettore Perazzoli <ettore@helixcode.com>
* e-msg-composer.c (e_msg_composer_construct): I18N the title bar.
* Makefile.am (libcomposerinclude_HEADERS): Removed. Move all the
`.h' files into `libcomposer_la_SOURCES' so that they get
distributed, but not installed.
* e-msg-composer.c (open_cb): New; implement the `Open' command.
(save_as_cb): New; implement the `Save as' command.
(init): Initialize the `persist_file_interface' and
`persist_stream_interface' members to NULL.
(destroy): Release the PersistStream and PersistFile interfaces.
(e_msg_composer_construct): Query the PersistFile and
PersistStream interfaces on the control and save them in the
`persist_file_interface' and `persist_stream_interface' members.
(get_text): Renamed from `get_editor_text'. Get a
@persist_stream_interface instead of querying it a the control.
(build_message): Return NULL if `persist_stream_interface' is nil.
* e-msg-composer.h: New member `persist_file_interface' in
`EMsgComposer'.
* e-msg-composer-select-file.c: New.
* e-msg-composer-select-file.h: New.
* e-msg-composer.c (e_msg_composer_construct): Make the `To:'
entry grab the keyboard focus.
* e-msg-composer-hdrs.c (e_msg_composer_hdrs_get_to_entry): New.
(e_msg_composer_hdrs_get_cc_entry): New.
(e_msg_composer_hdrs_get_bcc_entry): New.
(e_msg_composer_hdrs_get_subject_entry): New.
* e-msg-composer.c (e_msg_composer_construct): Set the scroll
frame's shadow type to `GTK_SHADOW_IN'.
(format_text): Initialize `tabbing' to zero to shut down the
compiler.
2000-06-14 Dan Winship <danw@helixcode.com>
* e-msg-composer-attachment-bar.c (add_from_user): keep the
......
......@@ -25,32 +25,19 @@ CPPFLAGS = \
libcomposer_la_SOURCES = \
e-msg-composer-address-dialog.c \
e-msg-composer-address-entry.c \
e-msg-composer-attachment-bar.c \
e-msg-composer-attachment.c \
e-msg-composer-hdrs.c \
e-msg-composer.c
libcomposerinclude_HEADERS = \
e-msg-composer-address-dialog.h \
e-msg-composer-address-entry.c \
e-msg-composer-address-entry.h \
e-msg-composer-attachment-bar.c \
e-msg-composer-attachment-bar.h \
e-msg-composer-attachment.c \
e-msg-composer-attachment.h \
e-msg-composer-hdrs.c \
e-msg-composer-hdrs.h \
e-msg-composer-select-file.c \
e-msg-composer.c
e-msg-composer.h
## libcomposer_LDADD = \
$(top_builddir)/camel/libcamel.la \
$(BONOBO_GNOME_LIBS) \
$(GNOME_LIBDIR) \
$(GNOMEUI_LIBS) \
$(INTLLIBS) \
$(PTHREAD_LIB) \
$(EXTRA_GNOME_LIBS)
EXTRA_DIST = \
$(glade_DATA) \
ChangeLog
......@@ -233,8 +233,10 @@ GtkWidget *
e_msg_composer_hdrs_new (void)
{
EMsgComposerHdrs *new;
EMsgComposerHdrsPrivate *priv;
new = gtk_type_new (e_msg_composer_hdrs_get_type ());
priv = new->priv;
setup_headers (E_MSG_COMPOSER_HDRS (new));
......@@ -380,3 +382,41 @@ e_msg_composer_hdrs_get_subject (EMsgComposerHdrs *hdrs)
return gtk_entry_get_text
(GTK_ENTRY (hdrs->priv->subject_entry));
}
GtkWidget *
e_msg_composer_hdrs_get_to_entry (EMsgComposerHdrs *hdrs)
{
g_return_val_if_fail (hdrs != NULL, NULL);
g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL);
return hdrs->priv->to_entry;
}
GtkWidget *
e_msg_composer_hdrs_get_cc_entry (EMsgComposerHdrs *hdrs)
{
g_return_val_if_fail (hdrs != NULL, NULL);
g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL);
return hdrs->priv->cc_entry;
}
GtkWidget *
e_msg_composer_hdrs_get_bcc_entry (EMsgComposerHdrs *hdrs)
{
g_return_val_if_fail (hdrs != NULL, NULL);
g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL);
return hdrs->priv->bcc_entry;
}
GtkWidget *
e_msg_composer_hdrs_get_subject_entry (EMsgComposerHdrs *hdrs)
{
g_return_val_if_fail (hdrs != NULL, NULL);
g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL);
return hdrs->priv->subject_entry;
}
......@@ -56,24 +56,30 @@ struct _EMsgComposerHdrsClass {
};
GtkType e_msg_composer_hdrs_get_type (void);
GtkWidget *e_msg_composer_hdrs_new (void);
void e_msg_composer_hdrs_to_message (EMsgComposerHdrs *hdrs,
CamelMimeMessage *msg);
void e_msg_composer_hdrs_set_to (EMsgComposerHdrs *hdrs,
const GList *to_list);
void e_msg_composer_hdrs_set_cc (EMsgComposerHdrs *hdrs,
const GList *cc_list);
void e_msg_composer_hdrs_set_bcc (EMsgComposerHdrs *hdrs,
const GList *bcc_list);
void e_msg_composer_hdrs_set_subject (EMsgComposerHdrs *hdrs,
const char *subject);
GList *e_msg_composer_hdrs_get_to (EMsgComposerHdrs *hdrs);
GList *e_msg_composer_hdrs_get_cc (EMsgComposerHdrs *hdrs);
GList *e_msg_composer_hdrs_get_bcc (EMsgComposerHdrs *hdrs);
const char*e_msg_composer_hdrs_get_subject (EMsgComposerHdrs *hdrs);
GtkType e_msg_composer_hdrs_get_type (void);
GtkWidget *e_msg_composer_hdrs_new (void);
void e_msg_composer_hdrs_to_message (EMsgComposerHdrs *hdrs,
CamelMimeMessage *msg);
void e_msg_composer_hdrs_set_to (EMsgComposerHdrs *hdrs,
const GList *to_list);
void e_msg_composer_hdrs_set_cc (EMsgComposerHdrs *hdrs,
const GList *cc_list);
void e_msg_composer_hdrs_set_bcc (EMsgComposerHdrs *hdrs,
const GList *bcc_list);
void e_msg_composer_hdrs_set_subject (EMsgComposerHdrs *hdrs,
const char *subject);
GList *e_msg_composer_hdrs_get_to (EMsgComposerHdrs *hdrs);
GList *e_msg_composer_hdrs_get_cc (EMsgComposerHdrs *hdrs);
GList *e_msg_composer_hdrs_get_bcc (EMsgComposerHdrs *hdrs);
const char *e_msg_composer_hdrs_get_subject (EMsgComposerHdrs *hdrs);
GtkWidget *e_msg_composer_hdrs_get_to_entry (EMsgComposerHdrs *hdrs);
GtkWidget *e_msg_composer_hdrs_get_cc_entry (EMsgComposerHdrs *hdrs);
GtkWidget *e_msg_composer_hdrs_get_bcc_entry (EMsgComposerHdrs *hdrs);
GtkWidget *e_msg_composer_hdrs_get_subject_entry (EMsgComposerHdrs *hdrs);
#ifdef _cplusplus
}
......
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* e-msg-composer-select-file.c
*
* Copyright (C) 2000 Helix Code, Inc.
*
* This program 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 2 of the
* License, or (at your option) any later version.
*
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Author: Ettore Perazzoli
*/
#include <gtk/gtkfilesel.h>
#include "e-msg-composer-select-file.h"
struct _FileSelectionInfo {
GtkWidget *widget;
char *selected_file;
};
typedef struct _FileSelectionInfo FileSelectionInfo;
static void
confirm (FileSelectionInfo *info)
{
const char *filename;
filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION (info->widget));
info->selected_file = g_strdup (filename);
gtk_widget_hide (info->widget);
gtk_main_quit ();
}
static void
cancel (FileSelectionInfo *info)
{
g_assert (info->selected_file == NULL);
gtk_widget_hide (info->widget);
gtk_main_quit ();
}
/* Callbacks. */
static void
ok_clicked_cb (GtkWidget *widget,
void *data)
{
FileSelectionInfo *info;
info = (FileSelectionInfo *) data;
confirm (info);
}
static void
cancel_clicked_cb (GtkWidget *widget,
void *data)
{
FileSelectionInfo *info;
info = (FileSelectionInfo *) data;
cancel (info);
}
static int
delete_event_cb (GtkWidget *widget,
GdkEventAny *event,
void *data)
{
FileSelectionInfo *info;
info = (FileSelectionInfo *) data;
cancel (info);
return TRUE;
}
/* Setup. */
static FileSelectionInfo *
create_file_selection (EMsgComposer *composer)
{
FileSelectionInfo *info;
GtkWidget *widget;
GtkWidget *ok_button;
GtkWidget *cancel_button;
info = g_new (FileSelectionInfo, 1);
widget = gtk_file_selection_new (NULL);
ok_button = GTK_FILE_SELECTION (widget)->ok_button;
cancel_button = GTK_FILE_SELECTION (widget)->cancel_button;
gtk_signal_connect (GTK_OBJECT (ok_button),
"clicked", GTK_SIGNAL_FUNC (ok_clicked_cb), info);
gtk_signal_connect (GTK_OBJECT (cancel_button),
"clicked", GTK_SIGNAL_FUNC (cancel_clicked_cb), info);
gtk_signal_connect (GTK_OBJECT (widget), "delete_event",
GTK_SIGNAL_FUNC (delete_event_cb), info);
info->widget = widget;
info->selected_file = NULL;
return info;
}
static void
file_selection_info_destroy_notify (void *data)
{
FileSelectionInfo *info;
info = (FileSelectionInfo *) data;
g_free (info->selected_file);
g_free (info);
}
char *
e_msg_composer_select_file (EMsgComposer *composer,
const char *title)
{
FileSelectionInfo *info;
char *retval;
g_return_val_if_fail (composer != NULL, NULL);
g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL);
info = gtk_object_get_data (GTK_OBJECT (composer),
"e-msg-composer-file-selection-info");
if (info == NULL) {
info = create_file_selection (composer);
gtk_object_set_data_full (GTK_OBJECT (composer),
"e-msg-composer-file-selection-info", info,
file_selection_info_destroy_notify);
}
if (GTK_WIDGET_VISIBLE (info->widget))
return NULL; /* Busy! */
gtk_window_set_title (GTK_WINDOW (info->widget), title);
gtk_widget_show (info->widget);
gtk_main ();
retval = info->selected_file;
info->selected_file = NULL;
return retval;
}
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* e-msg-composer-select-file.c
*
* Copyright (C) 2000 Helix Code, Inc.
*
* This program 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 2 of the
* License, or (at your option) any later version.
*
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Author: Ettore Perazzoli
*/
#ifndef E_MSG_COMPOSER_SELECT_FILE_H
#define E_MSG_COMPOSER_SELECT_FILE_H
#include "e-msg-composer.h"
char *e_msg_composer_select_file (EMsgComposer *composer,
const char *title);
#endif /* E_MSG_COMPOSER_SELECT_FILE_H */
......@@ -45,12 +45,14 @@
#include "e-util/e-html-utils.h"
#include "e-util/e-setup.h"
#include "e-util/e-gui-utils.h"
#include "widgets/misc/e-scroll-frame.h"
#include "e-msg-composer.h"
#include "e-msg-composer-address-dialog.h"
#include "e-msg-composer-attachment-bar.h"
#include "e-msg-composer-hdrs.h"
#include "e-msg-composer-select-file.h"
#ifdef USING_OAF
#define HTML_EDITOR_CONTROL_ID "OAFIID:control:html-editor:63c5499b-8b0c-475a-9948-81ec96a9662c"
......@@ -102,21 +104,14 @@ free_string_list (GList *list)
}
static char *
get_editor_text (BonoboWidget *editor, char *format)
get_text (Bonobo_PersistStream persist, char *format)
{
Bonobo_PersistStream persist;
BonoboStream *stream;
BonoboStreamMem *stream_mem;
CORBA_Environment ev;
char *text;
CORBA_exception_init (&ev);
persist = (Bonobo_PersistStream)
bonobo_object_client_query_interface (
bonobo_widget_get_server (editor),
"IDL:Bonobo/PersistStream:1.0",
&ev);
g_assert (persist != CORBA_OBJECT_NIL);
stream = bonobo_stream_mem_create (NULL, 0, FALSE, TRUE);
Bonobo_PersistStream_save (persist, (Bonobo_Stream)bonobo_object_corba_objref (BONOBO_OBJECT (stream)), format, &ev);
......@@ -125,10 +120,6 @@ get_editor_text (BonoboWidget *editor, char *format)
return NULL;
}
if (ev._major != CORBA_SYSTEM_EXCEPTION)
CORBA_Object_release (persist, &ev);
Bonobo_Unknown_unref (persist, &ev);
CORBA_exception_free (&ev);
stream_mem = BONOBO_STREAM_MEM (stream);
......@@ -136,6 +127,7 @@ get_editor_text (BonoboWidget *editor, char *format)
memcpy (text, stream_mem->buffer, stream_mem->pos);
text[stream_mem->pos] = 0;
bonobo_object_unref (BONOBO_OBJECT(stream));
return text;
}
......@@ -152,6 +144,7 @@ format_text (char *text)
int len, tabbing, i;
gboolean linestart = TRUE, cited = FALSE;
tabbing = 0; /* Shut down compiler. */
len = strlen (text);
out = g_string_sized_new (len + len / LINE_LEN);
......@@ -231,6 +224,9 @@ build_message (EMsgComposer *composer)
MsgFormat type = MSG_FORMAT_ALTERNATIVE;
char *path;
if (composer->persist_stream_interface == CORBA_OBJECT_NIL)
return NULL;
path = g_strdup_printf ("=%s/config=/mail/msg_format", evolution_dir);
string = gnome_config_get_string (path);
g_free (path);
......@@ -248,13 +244,12 @@ build_message (EMsgComposer *composer)
composer->extra_hdr_values->pdata[i]);
}
plain = get_editor_text (BONOBO_WIDGET (composer->editor), "text/plain");
plain = get_text (composer->persist_stream_interface, "text/plain");
fmt = format_text (plain);
g_free (plain);
if (type != MSG_FORMAT_PLAIN) {
html = get_editor_text (BONOBO_WIDGET (composer->editor), "text/html");
}
if (type != MSG_FORMAT_PLAIN)
html = get_text (composer->persist_stream_interface, "text/html");
if (type == MSG_FORMAT_ALTERNATIVE) {
body = camel_multipart_new ();
......@@ -484,6 +479,45 @@ address_dialog_apply_cb (EMsgComposerAddressDialog *dialog,
/* Message composer window callbacks. */
static void
open_cb (GtkWidget *widget,
gpointer data)
{
EMsgComposer *composer;
CORBA_Environment ev;
char *file_name;
composer = E_MSG_COMPOSER (data);
file_name = e_msg_composer_select_file (composer, _("Open file"));
if (file_name == NULL)
return;
CORBA_exception_init (&ev);
Bonobo_PersistFile_load (composer->persist_file_interface, file_name, &ev);
if (ev._major != CORBA_NO_EXCEPTION)
e_notice (GTK_WINDOW (composer), GNOME_MESSAGE_BOX_ERROR,
_("Error loading file: %s"), g_basename (file_name));
CORBA_exception_free (&ev);
g_free (file_name);
}
static void
save_cb (GtkWidget *widget,
gpointer data)
{
}
static void
save_as_cb (GtkWidget *widget,
gpointer data)
{
}
static void
send_cb (GtkWidget *widget,
gpointer data)
......@@ -510,7 +544,6 @@ exit_cb (GtkWidget *widget, gpointer data)
exit_dialog_cb, composer, parent);
}
static void
menu_view_attachments_activate_cb (GtkWidget *widget,
gpointer data)
......@@ -609,9 +642,9 @@ attachment_bar_changed_cb (EMsgComposerAttachmentBar *bar,
/* Menu bar implementation. */
static GnomeUIInfo file_tree[] = {
GNOMEUIINFO_MENU_OPEN_ITEM (NULL, NULL),
GNOMEUIINFO_MENU_SAVE_ITEM (NULL, NULL),
GNOMEUIINFO_MENU_SAVE_AS_ITEM (NULL, NULL),
GNOMEUIINFO_MENU_OPEN_ITEM (open_cb, NULL),
GNOMEUIINFO_MENU_SAVE_ITEM (save_cb, NULL),
GNOMEUIINFO_MENU_SAVE_AS_ITEM (save_as_cb, NULL),
GNOMEUIINFO_ITEM_NONE (N_("Save in _folder..."), N_("Save the message in a specified folder"),
NULL),
GNOMEUIINFO_SEPARATOR,
......@@ -684,6 +717,7 @@ static void
destroy (GtkObject *object)
{
EMsgComposer *composer;
CORBA_Environment ev;
composer = E_MSG_COMPOSER (object);
......@@ -708,6 +742,20 @@ destroy (GtkObject *object)
g_ptr_array_free (composer->extra_hdr_values, TRUE);
}
CORBA_exception_init (&ev);
if (composer->persist_stream_interface != CORBA_OBJECT_NIL) {
Bonobo_Unknown_unref (composer->persist_stream_interface, &ev);
CORBA_Object_release (composer->persist_stream_interface, &ev);
}
if (composer->persist_file_interface != CORBA_OBJECT_NIL) {
Bonobo_Unknown_unref (composer->persist_file_interface, &ev);
CORBA_Object_release (composer->persist_file_interface, &ev);
}
CORBA_exception_free (&ev);
if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL)
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
......@@ -746,18 +794,21 @@ class_init (EMsgComposerClass *klass)
static void
init (EMsgComposer *composer)
{
composer->uih = NULL;
composer->uih = NULL;
composer->hdrs = NULL;
composer->extra_hdr_names = g_ptr_array_new ();
composer->extra_hdr_values = g_ptr_array_new ();
composer->hdrs = NULL;
composer->extra_hdr_names = g_ptr_array_new ();
composer->extra_hdr_values = g_ptr_array_new ();
composer->editor = NULL;
composer->editor = NULL;
composer->address_dialog = NULL;
composer->address_dialog = NULL;
composer->attachment_bar = NULL;
composer->attachment_scroll_frame = NULL;
composer->attachment_bar = NULL;
composer->attachment_scroll_frame = NULL;
composer->persist_file_interface = CORBA_OBJECT_NIL;
composer->persist_stream_interface = CORBA_OBJECT_NIL;
}
......@@ -795,6 +846,7 @@ void
e_msg_composer_construct (EMsgComposer *composer)
{
GtkWidget *vbox;
BonoboObject *editor_server;
g_return_if_fail (gtk_main_level () > 0);
......@@ -802,7 +854,7 @@ e_msg_composer_construct (EMsgComposer *composer)
DEFAULT_WIDTH, DEFAULT_HEIGHT);
gnome_app_construct (GNOME_APP (composer), "e-msg-composer",
"Compose a message");
_("Compose a message"));
composer->uih = bonobo_ui_handler_new ();
bonobo_ui_handler_set_app (composer->uih, GNOME_APP (composer));
......@@ -819,14 +871,23 @@ e_msg_composer_construct (EMsgComposer *composer)
create_toolbar (composer);
composer->editor = create_editor (composer);
editor_server = BONOBO_OBJECT (bonobo_widget_get_server (BONOBO_WIDGET (composer->editor)));
composer->persist_file_interface
= bonobo_object_query_interface (editor_server, "IDL:Bonobo/PersistFile:1.0");
composer->persist_stream_interface
= bonobo_object_query_interface (editor_server, "IDL:Bonobo/PersistStream:1.0");
gtk_widget_show (composer->editor);
gtk_box_pack_start (GTK_BOX (vbox), composer->editor, TRUE, TRUE, 0);
gtk_widget_show (composer->editor);
/* Attachment editor, wrapped into a GtkScrolledWindow. We don't
/* Attachment editor, wrapped into an EScrollFrame. We don't
show it for now. */
composer->attachment_scroll_frame = e_scroll_frame_new (NULL, NULL);
e_scroll_frame_set_shadow_type (E_SCROLL_FRAME (composer->attachment_scroll_frame),
GTK_SHADOW_IN);
e_scroll_frame_set_policy (E_SCROLL_FRAME (composer->attachment_scroll_frame),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
......@@ -845,6 +906,10 @@ e_msg_composer_construct (EMsgComposer *composer)
gtk_widget_show (vbox);
e_msg_composer_show_attachments (composer, FALSE);
/* Set focus on the `To:' field. */
gtk_widget_grab_focus (e_msg_composer_hdrs_get_to_entry (E_MSG_COMPOSER_HDRS (composer->hdrs)));
}
/**
......
......@@ -61,6 +61,9 @@ struct _EMsgComposer {
GtkWidget *address_dialog;
Bonobo_PersistFile persist_file_interface;
Bonobo_PersistStream persist_stream_interface;
gboolean attachment_bar_visible : 1;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment