2007-07-23 15:41:08 +00:00
/*
* htmlchars . c - this file is part of Geany , a fast and lightweight IDE
*
2009-03-20 17:22:18 +00:00
* Copyright 2009 Frank Lanitz < frank ( at ) frank ( dot ) uvena ( dot ) de >
2009-01-04 18:30:42 +00:00
* Copyright 2006 - 2009 Enrico Tröger < enrico ( dot ) troeger ( at ) uvena ( dot ) de >
* Copyright 2007 - 2009 Nick Treleaven < nick ( dot ) treleaven ( at ) btinternet ( dot ) com >
2007-07-23 15:41:08 +00:00
*
* 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 . , 51 Franklin Street , Fifth Floor , Boston ,
* MA 02110 - 1301 , USA .
*
* $ Id $
*/
/* HTML Characters plugin (Inserts HTML character entities like '&') */
# include "geany.h"
# include "support.h"
# include "plugindata.h"
# include "document.h"
2008-07-08 16:30:37 +00:00
# include "editor.h"
2008-03-07 18:00:22 +00:00
# include "keybindings.h"
2008-05-22 14:41:28 +00:00
# include "ui_utils.h"
2008-06-12 20:09:57 +00:00
# include "utils.h"
2008-12-04 17:05:36 +00:00
# include "geanyfunctions.h"
2007-07-23 15:41:08 +00:00
2007-07-27 10:37:22 +00:00
GeanyData * geany_data ;
2008-05-19 12:35:35 +00:00
GeanyFunctions * geany_functions ;
2007-07-23 15:41:08 +00:00
2008-10-14 17:03:44 +00:00
PLUGIN_VERSION_CHECK ( GEANY_API_VERSION )
2007-07-23 15:41:08 +00:00
2008-05-23 17:08:58 +00:00
PLUGIN_SET_INFO ( _ ( " HTML Characters " ) , _ ( " Inserts HTML character entities like '&'. " ) , VERSION ,
2007-11-20 18:15:46 +00:00
_ ( " The Geany developer team " ) )
2007-07-23 15:41:08 +00:00
2008-03-07 18:00:22 +00:00
/* Keybinding(s) */
enum
{
KB_INSERT_HTML_CHARS ,
2009-03-20 17:22:18 +00:00
KB_REPLACE_HTML_ENTITIES ,
KB_HTMLTOGGLE_ACTIVE ,
2008-03-07 18:00:22 +00:00
KB_COUNT
} ;
PLUGIN_KEY_GROUP ( html_chars , KB_COUNT )
2007-07-23 15:41:08 +00:00
enum
{
COLUMN_CHARACTER ,
COLUMN_HTML_NAME ,
N_COLUMNS
} ;
2008-10-14 17:03:44 +00:00
static GtkWidget * main_menu_item = NULL ;
2009-03-20 17:22:18 +00:00
static GtkWidget * main_menu = NULL ;
static GtkWidget * main_menu_submenu = NULL ;
static GtkWidget * menu_bulk_replace = NULL ;
2007-07-23 15:41:08 +00:00
static GtkWidget * sc_dialog = NULL ;
static GtkTreeStore * sc_store = NULL ;
static GtkTreeView * sc_tree = NULL ;
2009-03-20 17:22:18 +00:00
static GtkWidget * menu_htmltoggle = NULL ;
static gboolean plugin_active = FALSE ;
const gchar * chars [ ] [ 2 ] = {
{ N_ ( " HTML characters " ) , NULL } ,
{ " \" " , " " " } ,
{ " & " , " & " } ,
{ " < " , " < " } ,
{ " > " , " > " } ,
{ N_ ( " ISO 8859-1 characters " ) , NULL } ,
{ " " , " " } ,
{ " ¡ " , " ¡ " } ,
{ " ¢ " , " ¢ " } ,
{ " £ " , " £ " } ,
{ " ¤ " , " ¤ " } ,
{ " ¥ " , " ¥ " } ,
{ " ¦ " , " ¦ " } ,
{ " § " , " § " } ,
{ " ¨ " , " ¨ " } ,
{ " © " , " © " } ,
{ " ® " , " ® " } ,
{ " « " , " « " } ,
{ " » " , " » " } ,
{ " ¬ " , " ¬ " } ,
{ " " , " ­ " } ,
{ " ¯ " , " ¯ " } ,
{ " ° " , " ° " } ,
{ " ± " , " ± " } ,
{ " ¹ " , " ¹ " } ,
{ " ² " , " ² " } ,
{ " ³ " , " ³ " } ,
{ " ¼ " , " ¼ " } ,
{ " ½ " , " ½ " } ,
{ " ¾ " , " ¾ " } ,
{ " × " , " × " } ,
{ " ÷ " , " ÷ " } ,
{ " ´ " , " ´ " } ,
{ " µ " , " µ " } ,
{ " ¶ " , " ¶ " } ,
{ " · " , " · " } ,
{ " ¸ " , " ¸ " } ,
{ " ª " , " ª " } ,
{ " º " , " º " } ,
{ " ¿ " , " ¿ " } ,
{ " À " , " À " } ,
{ " Á " , " Á " } ,
{ " Â " , " Â " } ,
{ " Ã " , " Ã " } ,
{ " Ä " , " Ä " } ,
{ " Å " , " Å " } ,
{ " Æ " , " Æ " } ,
{ " Ç " , " Ç " } ,
{ " È " , " È " } ,
{ " É " , " É " } ,
{ " Ê " , " Ê " } ,
{ " Ë " , " Ë " } ,
{ " Ì " , " Ì " } ,
{ " Í " , " Í " } ,
{ " Î " , " Î " } ,
{ " Ï " , " Ï " } ,
{ " Ð " , " Ð " } ,
{ " Ñ " , " Ñ " } ,
{ " Ò " , " Ò " } ,
{ " Ó " , " Ó " } ,
{ " Ô " , " Ô " } ,
{ " Õ " , " Õ " } ,
{ " Ö " , " Ö " } ,
{ " Ø " , " Ø " } ,
{ " Ù " , " Ù " } ,
{ " Ú " , " Ú " } ,
{ " Û " , " Û " } ,
{ " Ü " , " Ü " } ,
{ " Ý " , " Ý " } ,
{ " Þ " , " Þ " } ,
{ " ß " , " ß " } ,
{ " à " , " à " } ,
{ " á " , " á " } ,
{ " â " , " â " } ,
{ " ã " , " ã " } ,
{ " ä " , " ä " } ,
{ " å " , " å " } ,
{ " æ " , " æ " } ,
{ " ç " , " ç " } ,
{ " è " , " è " } ,
{ " é " , " é " } ,
{ " ê " , " ê " } ,
{ " ë " , " ë " } ,
{ " ì " , " ì " } ,
{ " í " , " í " } ,
{ " î " , " î " } ,
{ " ï " , " ï " } ,
{ " ð " , " ð " } ,
{ " ñ " , " ñ " } ,
{ " ò " , " ò " } ,
{ " ó " , " ó " } ,
{ " ô " , " ô " } ,
{ " õ " , " õ " } ,
{ " ö " , " ö " } ,
{ " ø " , " ø " } ,
{ " ù " , " ù " } ,
{ " ú " , " ú " } ,
{ " û " , " û " } ,
{ " ü " , " ü " } ,
{ " ý " , " ý " } ,
{ " þ " , " þ " } ,
{ " ÿ " , " ÿ " } ,
{ N_ ( " Greek characters " ) , NULL } ,
{ " Α " , " Α " } ,
{ " α " , " α " } ,
{ " Β " , " Β " } ,
{ " β " , " β " } ,
{ " Γ " , " Γ " } ,
{ " γ " , " γ " } ,
{ " Δ " , " Δ " } ,
{ " δ " , " Δ " } ,
{ " δ " , " δ " } ,
{ " Ε " , " Ε " } ,
{ " ε " , " ε " } ,
{ " Ζ " , " Ζ " } ,
{ " ζ " , " ζ " } ,
{ " Η " , " Η " } ,
{ " η " , " η " } ,
{ " Θ " , " Θ " } ,
{ " θ " , " θ " } ,
{ " Ι " , " Ι " } ,
{ " ι " , " ι " } ,
{ " Κ " , " Κ " } ,
{ " κ " , " κ " } ,
{ " Λ " , " Λ " } ,
{ " λ " , " λ " } ,
{ " Μ " , " Μ " } ,
{ " μ " , " μ " } ,
{ " Ν " , " Ν " } ,
{ " ν " , " ν " } ,
{ " Ξ " , " Ξ " } ,
{ " ξ " , " ξ " } ,
{ " Ο " , " Ο " } ,
{ " ο " , " ο " } ,
{ " Π " , " Π " } ,
{ " π " , " π " } ,
{ " Ρ " , " Ρ " } ,
{ " ρ " , " ρ " } ,
{ " Σ " , " Σ " } ,
{ " ς " , " ς " } ,
{ " σ " , " σ " } ,
{ " Τ " , " Τ " } ,
{ " τ " , " τ " } ,
{ " Υ " , " Υ " } ,
{ " υ " , " υ " } ,
{ " Φ " , " Φ " } ,
{ " φ " , " φ " } ,
{ " Χ " , " Χ " } ,
{ " χ " , " χ " } ,
{ " Ψ " , " Ψ " } ,
{ " ψ " , " ψ " } ,
{ " Ω " , " Ω " } ,
{ " ω " , " ω " } ,
{ " ϑ " , " ϑ " } ,
{ " ϒ " , " ϒ " } ,
{ " ϖ " , " ϖ " } ,
{ N_ ( " Mathematical characters " ) , NULL } ,
{ " ∀ " , " ∀ " } ,
{ " ∂ " , " ∂ " } ,
{ " ∃ " , " ∃ " } ,
{ " ∅ " , " ∅ " } ,
{ " ∇ " , " ∇ " } ,
{ " ∈ " , " ∈ " } ,
{ " ∉ " , " ∉ " } ,
{ " ∋ " , " ∋ " } ,
{ " ∏ " , " ∏ " } ,
{ " ∑ " , " ∑ " } ,
{ " − " , " − " } ,
{ " ∗ " , " ∗ " } ,
{ " √ " , " √ " } ,
{ " ∝ " , " ∝ " } ,
{ " ∞ " , " ∞ " } ,
{ " ∠ " , " ∠ " } ,
{ " ∧ " , " ∧ " } ,
{ " ∨ " , " ∨ " } ,
{ " ∩ " , " ∩ " } ,
{ " ∪ " , " ∪ " } ,
{ " ∫ " , " ∫ " } ,
{ " ∴ " , " ∴ " } ,
{ " ∼ " , " ∼ " } ,
{ " ≅ " , " ≅ " } ,
{ " ≈ " , " ≈ " } ,
{ " ≠ " , " ≠ " } ,
{ " ≡ " , " ≡ " } ,
{ " ≤ " , " ≤ " } ,
{ " ≥ " , " ≥ " } ,
{ " ⊂ " , " ⊂ " } ,
{ " ⊃ " , " ⊃ " } ,
{ " ⊄ " , " ⊄ " } ,
{ " ⊆ " , " ⊆ " } ,
{ " ⊇ " , " ⊇ " } ,
{ " ⊕ " , " ⊕ " } ,
{ " ⊗ " , " ⊗ " } ,
{ " ⊥ " , " ⊥ " } ,
{ " ⋅ " , " ⋅ " } ,
{ " ◊ " , " ◊ " } ,
{ N_ ( " Technical characters " ) , NULL } ,
{ " ⌈ " , " ⌈ " } ,
{ " ⌉ " , " ⌉ " } ,
{ " ⌊ " , " ⌊ " } ,
{ " ⌋ " , " ⌋ " } ,
{ " 〈 " , " ⟨ " } ,
{ " 〉 " , " ⟩ " } ,
{ N_ ( " Arrow characters " ) , NULL } ,
{ " ← " , " ← " } ,
{ " ↑ " , " ↑ " } ,
{ " → " , " → " } ,
{ " ↓ " , " ↓ " } ,
{ " ↔ " , " ↔ " } ,
{ " ↵ " , " ↵ " } ,
{ " ⇐ " , " ⇐ " } ,
{ " ⇑ " , " ⇑ " } ,
{ " ⇒ " , " ⇒ " } ,
{ " ⇓ " , " ⇓ " } ,
{ " ⇔ " , " ⇔ " } ,
{ N_ ( " Punctuation characters " ) , NULL } ,
{ " – " , " – " } ,
{ " — " , " — " } ,
{ " ‘ " , " ‘ " } ,
{ " ’ " , " ’ " } ,
{ " ‚ " , " ‚ " } ,
{ " “ " , " “ " } ,
{ " ” " , " ” " } ,
{ " „ " , " „ " } ,
{ " † " , " † " } ,
{ " ‡ " , " ‡ " } ,
{ " … " , " … " } ,
{ " ‰ " , " ‰ " } ,
{ " ‹ " , " ‹ " } ,
{ " › " , " › " } ,
{ N_ ( " Miscellaneous characters " ) , NULL } ,
{ " • " , " • " } ,
{ " ′ " , " ′ " } ,
{ " ″ " , " ″ " } ,
{ " ‾ " , " ‾ " } ,
{ " ⁄ " , " ⁄ " } ,
{ " ℘ " , " ℘ " } ,
{ " ℑ " , " ℑ " } ,
{ " ℜ " , " ℜ " } ,
{ " ™ " , " ™ " } ,
{ " € " , " € " } ,
{ " ℵ " , " ℵ " } ,
{ " ♠ " , " ♠ " } ,
{ " ♣ " , " ♣ " } ,
{ " ♥ " , " ♥ " } ,
{ " ♦ " , " ♦ " } ,
{ " Œ " , " Œ " } ,
{ " œ " , " œ " } ,
{ " Š " , " Š " } ,
{ " š " , " š " } ,
{ " Ÿ " , " Ÿ " } ,
{ " ƒ " , " ƒ " } ,
} ;
static gboolean ht_editor_notify_cb ( GObject * object , GeanyEditor * editor ,
SCNotification * nt , gpointer data ) ;
PluginCallback plugin_callbacks [ ] =
{
{ " editor-notify " , ( GCallback ) & ht_editor_notify_cb , FALSE , NULL } ,
{ NULL , NULL , FALSE , NULL }
} ;
/* Functions to toggle the status of plugin */
void set_status ( gboolean new_status )
{
/* No more function at the moment.*/
if ( plugin_active ! = new_status )
plugin_active = new_status ;
}
static void toggle_status ( G_GNUC_UNUSED GtkMenuItem * menuitem )
{
if ( plugin_active = = TRUE )
set_status ( FALSE ) ;
else
set_status ( TRUE ) ;
}
2007-07-23 15:41:08 +00:00
static void sc_on_tools_show_dialog_insert_special_chars_response
( GtkDialog * dialog , gint response , gpointer user_data ) ;
static void sc_on_tree_row_activated
( GtkTreeView * treeview , GtkTreePath * path , GtkTreeViewColumn * col , gpointer user_data ) ;
static void sc_fill_store ( GtkTreeStore * store ) ;
static gboolean sc_insert ( GtkTreeModel * model , GtkTreeIter * iter ) ;
2009-03-20 17:22:18 +00:00
/* Function takes over value of key which was pressed and returns
* HTML / SGML entity if any */
const gchar * get_entity ( gchar * letter )
{
guint i , len ;
len = G_N_ELEMENTS ( chars ) ;
/* Ignore tags marking caracters as well as spaces*/
for ( i = 7 ; i < len ; i + + )
{
if ( utils_str_equal ( chars [ i ] [ 0 ] , letter ) & &
! utils_str_equal ( " " , letter ) )
{
return chars [ i ] [ 1 ] ;
}
}
/* if the char is not in the list */
return NULL ;
}
static gboolean ht_editor_notify_cb ( GObject * object , GeanyEditor * editor ,
SCNotification * nt , gpointer data )
{
g_return_val_if_fail ( editor ! = NULL , FALSE ) ;
if ( plugin_active ! = TRUE )
return FALSE ;
if ( nt - > nmhdr . code = = SCN_CHARADDED )
{
gchar buf [ 7 ] ;
gint len ;
len = g_unichar_to_utf8 ( nt - > ch , buf ) ;
if ( len > 0 )
{
const gchar * entity ;
buf [ len ] = ' \0 ' ;
entity = get_entity ( buf ) ;
if ( entity ! = NULL )
{
gint pos = sci_get_current_position ( editor - > sci ) ;
sci_set_selection_start ( editor - > sci , pos - len ) ;
sci_set_selection_end ( editor - > sci , pos ) ;
sci_replace_sel ( editor - > sci , entity ) ;
}
}
}
return FALSE ;
}
/* Called when keys were pressed */
static void kbhtmltoggle_toggle ( G_GNUC_UNUSED guint key_id )
{
if ( plugin_active = = TRUE )
set_status ( FALSE ) ;
else
set_status ( TRUE ) ;
}
2008-02-20 11:24:23 +00:00
static void tools_show_dialog_insert_special_chars ( void )
2007-07-23 15:41:08 +00:00
{
if ( sc_dialog = = NULL )
{
gint height ;
GtkCellRenderer * renderer ;
GtkTreeViewColumn * column ;
GtkWidget * swin , * vbox , * label ;
sc_dialog = gtk_dialog_new_with_buttons (
2008-07-07 16:16:18 +00:00
_ ( " Special Characters " ) , GTK_WINDOW ( geany - > main_widgets - > window ) ,
2007-07-23 15:41:08 +00:00
GTK_DIALOG_DESTROY_WITH_PARENT , GTK_STOCK_CANCEL , GTK_RESPONSE_CANCEL ,
_ ( " _Insert " ) , GTK_RESPONSE_OK , NULL ) ;
2008-12-04 17:05:36 +00:00
vbox = ui_dialog_vbox_new ( GTK_DIALOG ( sc_dialog ) ) ;
2007-07-23 15:41:08 +00:00
gtk_box_set_spacing ( GTK_BOX ( vbox ) , 6 ) ;
gtk_widget_set_name ( sc_dialog , " GeanyDialog " ) ;
height = GEANY_WINDOW_MINIMAL_HEIGHT ;
2008-02-20 11:24:23 +00:00
gtk_window_set_default_size ( GTK_WINDOW ( sc_dialog ) , height * 8 / 10 , height ) ;
2007-07-23 15:41:08 +00:00
gtk_dialog_set_default_response ( GTK_DIALOG ( sc_dialog ) , GTK_RESPONSE_CANCEL ) ;
label = gtk_label_new ( _ ( " Choose a special character from the list below and double click on it or use the button to insert it at the current cursor position. " ) ) ;
gtk_label_set_line_wrap ( GTK_LABEL ( label ) , TRUE ) ;
gtk_misc_set_alignment ( GTK_MISC ( label ) , 0 , 0.5 ) ;
gtk_box_pack_start ( GTK_BOX ( vbox ) , label , FALSE , FALSE , 0 ) ;
sc_tree = GTK_TREE_VIEW ( gtk_tree_view_new ( ) ) ;
sc_store = gtk_tree_store_new ( N_COLUMNS , G_TYPE_STRING , G_TYPE_STRING ) ;
gtk_tree_view_set_model ( GTK_TREE_VIEW ( sc_tree ) ,
GTK_TREE_MODEL ( sc_store ) ) ;
2008-10-07 18:51:50 +00:00
g_object_unref ( sc_store ) ;
2007-07-23 15:41:08 +00:00
renderer = gtk_cell_renderer_text_new ( ) ;
column = gtk_tree_view_column_new_with_attributes (
_ ( " Character " ) , renderer , " text " , COLUMN_CHARACTER , NULL ) ;
gtk_tree_view_column_set_resizable ( column , TRUE ) ;
gtk_tree_view_append_column ( GTK_TREE_VIEW ( sc_tree ) , column ) ;
renderer = gtk_cell_renderer_text_new ( ) ;
column = gtk_tree_view_column_new_with_attributes (
_ ( " HTML (name) " ) , renderer , " text " , COLUMN_HTML_NAME , NULL ) ;
gtk_tree_view_column_set_resizable ( column , TRUE ) ;
gtk_tree_view_append_column ( GTK_TREE_VIEW ( sc_tree ) , column ) ;
swin = gtk_scrolled_window_new ( NULL , NULL ) ;
gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW ( swin ) , GTK_POLICY_AUTOMATIC ,
GTK_POLICY_AUTOMATIC ) ;
gtk_scrolled_window_add_with_viewport (
GTK_SCROLLED_WINDOW ( swin ) , GTK_WIDGET ( sc_tree ) ) ;
gtk_box_pack_start ( GTK_BOX ( vbox ) , swin , TRUE , TRUE , 0 ) ;
2008-07-18 13:40:48 +00:00
g_signal_connect ( sc_tree , " row-activated " , G_CALLBACK ( sc_on_tree_row_activated ) , NULL ) ;
2007-07-23 15:41:08 +00:00
2008-07-18 13:40:48 +00:00
g_signal_connect ( sc_dialog , " response " ,
2007-07-23 15:41:08 +00:00
G_CALLBACK ( sc_on_tools_show_dialog_insert_special_chars_response ) , NULL ) ;
2008-07-18 13:40:48 +00:00
g_signal_connect ( sc_dialog , " delete-event " , G_CALLBACK ( gtk_widget_hide_on_delete ) , NULL ) ;
2007-07-23 15:41:08 +00:00
sc_fill_store ( sc_store ) ;
2008-02-27 13:17:29 +00:00
/*gtk_tree_view_expand_all(special_characters_tree);*/
2007-07-23 15:41:08 +00:00
gtk_tree_view_set_search_column ( sc_tree , COLUMN_HTML_NAME ) ;
}
gtk_widget_show_all ( sc_dialog ) ;
}
2008-02-27 13:17:29 +00:00
/* fill the tree model with data
* * TODO move this in a file and make it extendable for more data types */
2007-07-23 15:41:08 +00:00
static void sc_fill_store ( GtkTreeStore * store )
{
GtkTreeIter iter ;
GtkTreeIter * parent_iter = NULL ;
2009-02-10 21:11:25 +00:00
guint i , len ;
2007-07-23 15:41:08 +00:00
2009-02-10 21:11:25 +00:00
len = G_N_ELEMENTS ( chars ) ;
for ( i = 0 ; i < len ; i + + )
2007-07-23 15:41:08 +00:00
{
if ( chars [ i ] [ 1 ] = = NULL )
2008-02-27 13:17:29 +00:00
{ /* add a category */
2007-07-23 15:41:08 +00:00
gtk_tree_store_append ( store , & iter , NULL ) ;
gtk_tree_store_set ( store , & iter , COLUMN_CHARACTER , chars [ i ] [ 0 ] , - 1 ) ;
if ( parent_iter ! = NULL ) gtk_tree_iter_free ( parent_iter ) ;
parent_iter = gtk_tree_iter_copy ( & iter ) ;
}
else
2008-02-27 13:17:29 +00:00
{ /* add child to parent_iter */
2007-07-23 15:41:08 +00:00
gtk_tree_store_append ( store , & iter , parent_iter ) ;
gtk_tree_store_set ( store , & iter , COLUMN_CHARACTER , chars [ i ] [ 0 ] ,
COLUMN_HTML_NAME , chars [ i ] [ 1 ] , - 1 ) ;
}
}
}
/* just inserts the HTML_NAME coloumn of the selected row at current position
* returns only TRUE if a valid selection ( i . e . no category ) could be found */
static gboolean sc_insert ( GtkTreeModel * model , GtkTreeIter * iter )
{
2008-12-04 17:05:36 +00:00
GeanyDocument * doc = document_get_current ( ) ;
2007-07-23 15:41:08 +00:00
gboolean result = FALSE ;
2008-06-12 20:09:57 +00:00
if ( doc ! = NULL )
2007-07-23 15:41:08 +00:00
{
gchar * str ;
2008-12-04 17:05:36 +00:00
gint pos = sci_get_current_position ( doc - > editor - > sci ) ;
2007-07-23 15:41:08 +00:00
gtk_tree_model_get ( model , iter , COLUMN_HTML_NAME , & str , - 1 ) ;
2008-06-12 20:09:57 +00:00
if ( NZV ( str ) )
2007-07-23 15:41:08 +00:00
{
2008-12-04 17:05:36 +00:00
sci_insert_text ( doc - > editor - > sci , pos , str ) ;
2007-07-23 15:41:08 +00:00
g_free ( str ) ;
result = TRUE ;
}
}
return result ;
}
static void sc_on_tools_show_dialog_insert_special_chars_response ( GtkDialog * dialog , gint response ,
gpointer user_data )
{
if ( response = = GTK_RESPONSE_OK )
{
GtkTreeSelection * selection ;
GtkTreeModel * model ;
GtkTreeIter iter ;
selection = gtk_tree_view_get_selection ( sc_tree ) ;
if ( gtk_tree_selection_get_selected ( selection , & model , & iter ) )
{
2008-02-27 13:17:29 +00:00
/* only hide dialog if selection was not a category */
2007-07-23 15:41:08 +00:00
if ( sc_insert ( model , & iter ) )
gtk_widget_hide ( GTK_WIDGET ( dialog ) ) ;
}
}
else
gtk_widget_hide ( GTK_WIDGET ( dialog ) ) ;
}
static void sc_on_tree_row_activated ( GtkTreeView * treeview , GtkTreePath * path ,
GtkTreeViewColumn * col , gpointer user_data )
{
GtkTreeIter iter ;
GtkTreeModel * model = GTK_TREE_MODEL ( sc_store ) ;
if ( gtk_tree_model_get_iter ( model , & iter , path ) )
{
2008-02-27 13:17:29 +00:00
/* only hide dialog if selection was not a category */
2007-07-23 15:41:08 +00:00
if ( sc_insert ( model , & iter ) )
gtk_widget_hide ( sc_dialog ) ;
else
2008-02-27 13:17:29 +00:00
{ /* double click on a category to toggle the expand or collapse it */
2007-07-23 15:41:08 +00:00
if ( gtk_tree_view_row_expanded ( sc_tree , path ) )
gtk_tree_view_collapse_row ( sc_tree , path ) ;
else
gtk_tree_view_expand_row ( sc_tree , path , FALSE ) ;
}
}
}
2009-03-20 17:22:18 +00:00
static void replace_special_character ( )
{
GeanyDocument * doc = NULL ;
doc = document_get_current ( ) ;
if ( doc ! = NULL & & sci_has_selection ( doc - > editor - > sci ) )
{
gint selection_len = sci_get_selected_text_length ( doc - > editor - > sci ) ;
gchar * selection = g_malloc ( selection_len + 1 ) ;
GString * replacement = g_string_new ( NULL ) ;
gint i ;
gchar * new = NULL ;
const gchar * entity = NULL ;
gchar buf [ 7 ] ;
gint len ;
sci_get_selected_text ( doc - > editor - > sci , selection ) ;
selection_len = sci_get_selected_text_length ( doc - > editor - > sci ) - 1 ;
for ( i = 0 ; i < selection_len ; i + + )
{
len = g_unichar_to_utf8 ( g_utf8_get_char ( selection + i ) , buf ) ;
i = len - 1 + i ;
buf [ len ] = ' \0 ' ;
entity = get_entity ( buf ) ;
if ( entity ! = NULL )
{
replacement = g_string_append ( replacement , entity ) ;
}
else
{
replacement = g_string_append ( replacement , buf ) ;
}
}
new = g_string_free ( replacement , FALSE ) ;
sci_replace_sel ( doc - > editor - > sci , new ) ;
g_free ( selection ) ;
g_free ( new ) ;
}
}
/* Callback for special chars menu */
2007-07-23 15:41:08 +00:00
static void
item_activate ( GtkMenuItem * menuitem , gpointer gdata )
{
tools_show_dialog_insert_special_chars ( ) ;
}
2008-03-07 18:00:22 +00:00
static void kb_activate ( G_GNUC_UNUSED guint key_id )
{
item_activate ( NULL , NULL ) ;
}
2009-03-20 17:22:18 +00:00
/* Callback for bulk replacement of selected text */
static void
replace_special_character_activated ( GtkMenuItem * menuitem , gpointer gdata )
{
replace_special_character ( ) ;
}
static void kb_special_chars_replacement ( G_GNUC_UNUSED guint key_id )
{
replace_special_character ( ) ;
}
2007-07-23 15:41:08 +00:00
/* Called by Geany to initialize the plugin */
2008-05-26 17:24:11 +00:00
void plugin_init ( GeanyData * data )
2007-07-23 15:41:08 +00:00
{
2008-10-14 17:03:44 +00:00
GtkWidget * menu_item ;
2008-03-07 18:00:22 +00:00
const gchar * menu_text = _ ( " _Insert Special HTML Characters " ) ;
2007-07-23 15:41:08 +00:00
2009-03-20 17:22:18 +00:00
/* Add an item to the Tools menu for html chars dialog*/
2008-10-14 17:03:44 +00:00
menu_item = gtk_menu_item_new_with_mnemonic ( menu_text ) ;
gtk_widget_show ( menu_item ) ;
gtk_container_add ( GTK_CONTAINER ( geany - > main_widgets - > tools_menu ) , menu_item ) ;
g_signal_connect ( menu_item , " activate " , G_CALLBACK ( item_activate ) , NULL ) ;
2007-07-23 15:41:08 +00:00
2008-02-27 13:17:29 +00:00
/* disable menu_item when there are no documents open */
2008-12-04 17:05:36 +00:00
ui_add_document_sensitive ( menu_item ) ;
2009-03-20 17:22:18 +00:00
/* Add menuitem for html replacement functions*/
main_menu = gtk_menu_item_new_with_mnemonic ( _ ( " HTML Replacement " ) ) ;
gtk_widget_show_all ( main_menu ) ;
gtk_container_add ( GTK_CONTAINER ( geany - > main_widgets - > tools_menu ) , main_menu ) ;
main_menu_submenu = gtk_menu_new ( ) ;
gtk_menu_item_set_submenu ( GTK_MENU_ITEM ( main_menu ) , main_menu_submenu ) ;
menu_htmltoggle = gtk_check_menu_item_new_with_mnemonic ( _ ( " _HTMLToggle " ) ) ;
gtk_check_menu_item_set_active ( GTK_CHECK_MENU_ITEM ( menu_htmltoggle ) ,
plugin_active ) ;
gtk_container_add ( GTK_CONTAINER ( main_menu_submenu ) , menu_htmltoggle ) ;
g_signal_connect ( ( gpointer ) menu_htmltoggle , " activate " ,
G_CALLBACK ( toggle_status ) , NULL ) ;
menu_bulk_replace = gtk_menu_item_new_with_mnemonic (
_ ( " Bulk replacement of special chars " ) ) ;
g_signal_connect ( ( gpointer ) menu_bulk_replace , " activate " ,
G_CALLBACK ( replace_special_character_activated ) , NULL ) ;
gtk_container_add ( GTK_CONTAINER ( main_menu_submenu ) , menu_bulk_replace ) ;
ui_add_document_sensitive ( main_menu ) ;
gtk_widget_show ( menu_bulk_replace ) ;
gtk_widget_show ( menu_htmltoggle ) ;
2008-10-14 17:03:44 +00:00
main_menu_item = menu_item ;
2008-03-07 18:00:22 +00:00
/* setup keybindings */
2009-03-20 17:22:18 +00:00
keybindings_set_item ( plugin_key_group , KB_INSERT_HTML_CHARS ,
kb_activate , 0 , 0 , " insert_html_chars " ,
_ ( " Insert Special HTML Characters " ) , menu_item ) ;
keybindings_set_item ( plugin_key_group , KB_REPLACE_HTML_ENTITIES ,
kb_special_chars_replacement , 0 , 0 , " replace_special_characters " ,
_ ( " Replace special characters " ) , NULL ) ;
keybindings_set_item ( plugin_key_group , KB_HTMLTOGGLE_ACTIVE ,
kbhtmltoggle_toggle , 0 , 0 , " htmltoogle_toggle_plugin_status " ,
_ ( " Toggle plugin status " ) , menu_htmltoggle ) ;
2007-07-23 15:41:08 +00:00
}
2007-07-25 11:59:34 +00:00
/* Destroy widgets */
2008-05-26 17:24:11 +00:00
void plugin_cleanup ( void )
2007-07-23 15:41:08 +00:00
{
2008-10-14 17:03:44 +00:00
gtk_widget_destroy ( main_menu_item ) ;
2009-03-20 17:22:18 +00:00
gtk_widget_destroy ( main_menu ) ;
2007-07-25 11:59:34 +00:00
2007-07-23 16:06:07 +00:00
if ( sc_dialog ! = NULL )
gtk_widget_destroy ( sc_dialog ) ;
2007-07-23 15:41:08 +00:00
}