text-edit.cpp revision 63c922ae7e6ea7c10d390ed6c570f03f4d09f660
/** @file
* @brief Text editing dialog
*/
/* Authors:
* Lauris Kaplinski <lauris@ximian.com>
* bulia byak <buliabyak@users.sf.net>
* Johan Engelen <goejendaagh@zonnet.nl>
* Abhishek Sharma
*
* Copyright (C) 1999-2007 Authors
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <libnrtype/font-instance.h>
#ifdef WITH_GTKSPELL
extern "C" {
# include <gtkspell/gtkspell.h>
}
#endif
#include "macros.h"
#include "../widgets/font-selector.h"
#include "../inkscape.h"
#include "../document.h"
#include "../desktop-style.h"
#include "../desktop-handles.h"
#include "../selection.h"
#include "../style.h"
#include "../sp-text.h"
#include "../sp-flowtext.h"
#include "../text-editing.h"
#include "../ui/icon-names.h"
#include <libnrtype/font-style-to-pos.h>
#include "dialog-events.h"
#include "../preferences.h"
#include "../verbs.h"
#include "../interface.h"
#include "svg/css-ostringstream.h"
#include "util/ege-appear-time-tracker.h"
using Inkscape::DocumentUndo;
using ege::AppearTimeTracker;
#define VB_MARGIN 4
#define MIN_ONSCREEN_DISTANCE 50
static void sp_text_edit_dialog_selection_modified (Inkscape::Application *inkscape, Inkscape::Selection *sel, guint flags, GtkWidget *dlg);
static void sp_text_edit_dialog_selection_changed (Inkscape::Application *inkscape, Inkscape::Selection *sel, GtkWidget *dlg);
static void sp_text_edit_dialog_subselection_changed ( Inkscape::Application *inkscape, SPDesktop *desktop, GtkWidget *dlg);
static void sp_text_edit_dialog_font_changed (SPFontSelector *fontsel, font_instance *font, GtkWidget *dlg);
static SPItem *sp_ted_get_selected_text_item (void);
static unsigned sp_ted_get_selected_text_count (void);
static const gchar *spacings[] = {"50%", "80%", "90%", "100%", "110%", "120%", "130%", "140%", "150%", "200%", "300%", NULL};
// impossible original values to make sure they are read from prefs
static void
{
}
static gboolean
{
if (x<0) x=0;
if (y<0) y=0;
return FALSE; // which means, go ahead and destroy it
}
/**
These callbacks set the eatkeys flag when the text editor is entered and cancel it when it's left.
This flag is used to prevent passing keys from the dialog to canvas, so that the text editor
can handle keys like Esc and Ctrl+Z itself.
*/
{
return FALSE;
}
{
return FALSE;
}
void
sp_text_edit_dialog (void)
{
if (!dlg) {
if (x == -1000 || y == -1000) {
}
if (w ==0 || h == 0) {
}
// if (x<0) x=0;
// if (y<0) y=0;
if (w && h)
if (x >= 0 && y >= 0 && (x < (gdk_screen_width()-MIN_ONSCREEN_DISTANCE)) && (y < (gdk_screen_height()-MIN_ONSCREEN_DISTANCE))) {
} else {
}
g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_transientize_callback), &wd );
g_signal_connect ( G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (sp_text_edit_dialog_delete), dlg );
// box containing the notebook and the bottom buttons
// notebook
// Font tab
{
/* HBox containing font selection and layout */
// font and style selector
g_signal_connect ( G_OBJECT (fontsel), "font_set", G_CALLBACK (sp_text_edit_dialog_font_changed), dlg );
"row-activated",
dlg);
// Layout
{
{
// align left
{
// TODO - replace with Inkscape-specific call
gtk_widget_set_tooltip_text (b, _("Align lines left"));
}
// align center
{
// TODO - replace with Inkscape-specific call
/* TRANSLATORS: `Center' here is a verb. */
gtk_widget_set_tooltip_text (b, _("Center lines"));
}
// align right
{
// TODO - replace with Inkscape-specific call
gtk_widget_set_tooltip_text (b, _("Align lines right"));
}
// align justify
{
// TODO - replace with Inkscape-specific call
gtk_widget_set_tooltip_text (b, _("Justify lines"));
}
}
{
// horizontal
{
gtk_widget_set_tooltip_text (b, _("Horizontal text"));
}
// vertical
{
gtk_widget_set_tooltip_text (b, _("Vertical text"));
}
}
{
l = gtk_label_new (_("Line spacing:"));
}
{
//This would introduce dependency on gtk version 2.24 which is currently not available in
//This conditional and its #else block can be deleted in the future.
#else
GtkWidget *c = gtk_combo_new ();
#endif
//This would introduce dependency on gtk version 2.24 which is currently not available in
//This conditional and its #else block can be deleted in the future.
{ /* Setup strings */
for (int i = 0; spacings[i]; i++) {
}
}
#else
{ /* Setup strings */
for (int i = 0; spacings[i]; i++) {
}
g_list_free (sl);
}
#endif
//This would introduce dependency on gtk version 2.24 which is currently not available in
//This conditional and its #else block can be deleted in the future.
g_signal_connect ( (GObject *) c,
#else
#endif
"changed",
dlg );
}
}
/* Font preview */
}
// Text tab
{
#ifdef WITH_GTKSPELL
/* todo: Use computed xml:lang attribute of relevant element, if present, to specify the
language (either as 2nd arg of gtkspell_new_attach, or with explicit
gtkspell_set_language call in; see advanced.c example in gtkspell docs).
sp_text_edit_dialog_read_selection looks like a suitable place. */
}
#endif
}
/* Buttons */
{
dlg );
}
{
}
{
}
g_signal_connect (INKSCAPE, "change_subselection", G_CALLBACK (sp_text_edit_dialog_subselection_changed), dlg);
}
if ( wantTiming ) {
// Time tracker takes ownership of the timer.
tracker->setAutodelete(true);
timer = 0;
}
} // end of sp_text_edit_dialog()
static void
{
style =
((flags & ( SP_OBJECT_CHILD_MODIFIED_FLAG |
SP_OBJECT_STYLE_MODIFIED_FLAG )) != 0 );
content =
((flags & ( SP_OBJECT_CHILD_MODIFIED_FLAG |
SP_TEXT_CONTENT_MODIFIED_FLAG )) != 0 );
}
static void
{
}
static void sp_text_edit_dialog_subselection_changed( Inkscape::Application */*inkscape*/, SPDesktop */*desktop*/, GtkWidget *dlg )
{
}
static void
{
/* write text */
if (gtk_text_buffer_get_modified (tb)) {
}
}
{
/* font */
if ( font ) {
gchar c[256];
os << sp_font_selector_get_size (SP_FONT_SELECTOR (fontsel)) << "px"; // must specify px, see inkscape bug 1221626 and 1610103
}
/* Layout */
// Align Left
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (b))) {
} else {
// Align Center
"text_anchor_middle");
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (b))) {
} else {
// Align Right
"text_anchor_end");
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (b))) {
} else {
// Align Justify
}
}
}
b = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), INKSCAPE_ICON_FORMAT_TEXT_DIRECTION_HORIZONTAL );
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (b))) {
} else {
}
// Note that CSS 1.1 does not support line-height; we set it for consistency, but also set
// sodipodi:linespacing for backwards compatibility; in 1.2 we use line-height for flowtext
//This would introduce dependency on gtk version 2.24 which is currently not available in
//This conditional and its #else block can be deleted in the future.
#else
#endif
return css;
}
static void
{
}
static void
{
unsigned items = 0;
// apply style to the reprs of all text objects in the selection
// backwards compatibility:
reinterpret_cast<SPObject*>(item_list->data)->getRepr()->setAttribute("sodipodi:linespacing", sp_repr_css_property (css, "line-height", NULL));
++items;
}
// no need to set sodipodi:linespacing, because Inkscape never supported it on flowtext
++items;
}
if (items == 0) {
// no text objects; apply style to prefs for new objects
} else if (items == 1) {
/* exactly one text object; now set its text, too */
}
}
// complete the transaction
_("Set text style"));
}
static void
{
}
static void
{
return;
//GtkWidget *notebook = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "notebook");
/* TRANSLATORS: Test string used in text and font dialog (when no
* text has been entered) to get a preview of the font. Choose
* some representative characters that users of your locale will be
* interested in. */
if (text)
{
if (items == 1) {
} else {
}
if (docontent) {
if (str) {
int pos;
pos = 0;
if (items == 1) {
}
} else {
}
} // end of if (docontent)
} else {
}
if (dostyle) {
// create temporary style
// query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection
//int result_fontspec = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION);
int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY);
int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE);
int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
// If querying returned nothing, read the style from the text tool prefs (default style for new texts)
// (Ok to not get a font specification - must just rely on the family and style in that case)
|| result_numbers == QUERY_STYLE_NOTHING) {
}
// FIXME: process result_family/style == QUERY_STYLE_MULTIPLE_DIFFERENT by showing "Many" in the lists
// Get a font_instance using the font-specification attribute stored in SPStyle if available
if (font) {
// the font is oversized, so we need to pass the true size separately
}
GtkWidget *b;
} else {
}
} else {
}
b = (GtkWidget*)g_object_get_data ( G_OBJECT (dlg), INKSCAPE_ICON_FORMAT_TEXT_DIRECTION_HORIZONTAL );
} else {
}
double height;
//This would introduce dependency on gtk version 2.24 which is currently not available in
//This conditional and its #else block can be deleted in the future.
#else
#endif
}
}
static void
{
return;
if (font) {
} else {
}
if (text) {
}
} // end of sp_text_edit_dialog_text_changed()
void
{
if (!dlg) return;
if (!data) return;
}
static void
{
return;
if (font) {
} else {
}
if (text) {
}
} // end of sp_text_edit_dialog_font_changed()
static void
{
return;
if (text) {
}
}
static void
{
return;
if (text) {
}
}
static SPItem *
{
if (!SP_ACTIVE_DESKTOP)
return NULL;
{
}
return NULL;
}
static unsigned
{
if (!SP_ACTIVE_DESKTOP)
return 0;
unsigned int items = 0;
{
++items;
}
return items;
}
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :