[Xfce4-commits] <mousepad:master> * mousepad/mousepad-utils.c: Add functions that extent the default Gtk word start/end function. Use them in the search functions, transpose and double click selection. * mousepad/mousepad-view.c: Implement transpose for multi selections. * mousepad/mousepad-view.c: Improve word swap function. * docs/manual/C/Mousepad.xml.in: Other layout of the help file. Content will follow. * mousepad/mousepad-{document, window, view}.c: Show the selection length in the statusbar. Also merged two signals and a couple of functions. * mousepad/mousepad-window.c: Change default keybinding of new document (Ctrl+N) and new window (Shift+Ctrl+N). Assign Ctrl+T to transpose. * mousepad/mousepad-window.c: Update the window title after saving a file with a new name. * mousepad/mousepad-file.c: Set readonly to FALSE when starting with a non-existing filename in the argument. * mousepad/mousepad-print.c: Improve the print backend. Settings are now saved. You can set the paper type, toggle options for line numbers, wrap and page heading and use a custom font.
Nick Schermer
noreply at xfce.org
Sat May 5 21:30:58 CEST 2012
Updating branch refs/heads/master
to f3a364cda15d48093802adbb4190a1d027e6a102 (commit)
from 03cd4c266c5d539c85dbe22f505d1d54c1b011b4 (commit)
commit f3a364cda15d48093802adbb4190a1d027e6a102
Author: Nick Schermer <nick at xfce.org>
Date: Thu Nov 29 16:38:43 2007 +0000
* mousepad/mousepad-utils.c: Add functions that extent the default
Gtk word start/end function. Use them in the search functions,
transpose and double click selection.
* mousepad/mousepad-view.c: Implement transpose for multi selections.
* mousepad/mousepad-view.c: Improve word swap function.
* docs/manual/C/Mousepad.xml.in: Other layout of the help file. Content
will follow.
* mousepad/mousepad-{document,window,view}.c: Show the selection length
in the statusbar. Also merged two signals and a couple of functions.
* mousepad/mousepad-window.c: Change default keybinding of new document
(Ctrl+N) and new window (Shift+Ctrl+N). Assign Ctrl+T to transpose.
* mousepad/mousepad-window.c: Update the window title after saving a
file with a new name.
* mousepad/mousepad-file.c: Set readonly to FALSE when starting with
a non-existing filename in the argument.
* mousepad/mousepad-print.c: Improve the print backend. Settings are
now saved. You can set the paper type, toggle options for line
numbers, wrap and page heading and use a custom font.
(Old svn revision: 26404)
ChangeLog | 21 ++
docs/manual/C/Mousepad.xml.in | 355 +++++++++++++++++---
mousepad/mousepad-document.c | 75 +----
mousepad/mousepad-document.h | 4 -
mousepad/mousepad-file.c | 8 +-
mousepad/mousepad-marshal.list | 2 +-
mousepad/mousepad-preferences.c | 31 +--
mousepad/mousepad-preferences.h | 2 +
mousepad/mousepad-print.c | 701 +++++++++++++++++++++++++++++++++++----
mousepad/mousepad-print.h | 12 +-
mousepad/mousepad-statusbar.c | 20 +-
mousepad/mousepad-statusbar.h | 3 +-
mousepad/mousepad-util.c | 224 ++++++++++++-
mousepad/mousepad-util.h | 62 +++--
mousepad/mousepad-view.c | 446 +++++++++++++++----------
mousepad/mousepad-view.h | 2 +-
mousepad/mousepad-window.c | 68 ++---
17 files changed, 1575 insertions(+), 461 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 2d87175..72fca2a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2007-11-29 Nick Schermer <nick at xfce.org>
+ * mousepad/mousepad-utils.c: Add functions that extent the default
+ Gtk word start/end function. Use them in the search functions,
+ transpose and double click selection.
+ * mousepad/mousepad-view.c: Implement transpose for multi selections.
+ * mousepad/mousepad-view.c: Improve word swap function.
+ * docs/manual/C/Mousepad.xml.in: Other layout of the help file. Content
+ will follow.
+ * mousepad/mousepad-{document,window,view}.c: Show the selection length
+ in the statusbar. Also merged two signals and a couple of functions.
+ * mousepad/mousepad-window.c: Change default keybinding of new document
+ (Ctrl+N) and new window (Shift+Ctrl+N). Assign Ctrl+T to transpose.
+ * mousepad/mousepad-window.c: Update the window title after saving a
+ file with a new name.
+ * mousepad/mousepad-file.c: Set readonly to FALSE when starting with
+ a non-existing filename in the argument.
+ * mousepad/mousepad-print.c: Improve the print backend. Settings are
+ now saved. You can set the paper type, toggle options for line
+ numbers, wrap and page heading and use a custom font.
+
+
2007-10-26 Nick Schermer <nick at xfce.org>
* mousepad/mousepad-view.c: Implement transpose:
- Selection on one line: Inverse selected text.
diff --git a/docs/manual/C/Mousepad.xml.in b/docs/manual/C/Mousepad.xml.in
index 48cf014..e31cef3 100644
--- a/docs/manual/C/Mousepad.xml.in
+++ b/docs/manual/C/Mousepad.xml.in
@@ -7,7 +7,6 @@
]>
<article id="index" lang="en">
- <!-- Header -->
<articleinfo>
<title>Mousepad Text Editor</title>
@@ -45,70 +44,334 @@
</releaseinfo>
</articleinfo>
- <sect1 id="intro">
- <title>Introduction to &application;</title>
+ <sect1 id="preface">
+ <title>Preface</title>
- <para>
- Mousepad is the default text editor for the Xfce Desktop Environment. It has been design to be a
- lightweight editor you would use for basic file editing. Therefore Mousepad starts quickly, but
- also has features like editing multiple documents, vertical selection, type-ahead search, full tab
- drag and drop and much more.
- </para>
+ <sect2 id="introduction">
+ <title>Introduction</title>
- <para>
- Mousepad started as a fork of Leafpad to provide printing support using Xfprint, but as of version
- 0.3 is has been completely rewritten to add support for tabs and DBus. Although the rewrite added
- a lot of new features, it is still as fast as the Leafpad based fork and therefore fits perfectly
- in the Xfce philosophy.
- </para>
+ <para>
+ &application; is the default text editor for the Xfce Desktop Environment. It has been design to be a
+ lightweight editor you would use for basic file editing. Therefore &application; starts quickly, but
+ also has features like editing multiple documents, vertical selection, type-ahead search, full tab
+ drag and drop and much more.
+ </para>
+
+ <para>
+ &application; started as a fork of Leafpad to provide printing support using Xfprint, but as of version
+ 0.3 is has been completely rewritten to add support for tabs and DBus. Although the rewrite added
+ a lot of new features, it is still as fast as the Leafpad based fork and therefore fits perfectly
+ in the Xfce philosophy.
+ </para>
+ </sect2>
+
+ <sect2 id="terminology">
+ <title>Terminology</title>
+
+ <para>
+ There might be a couple of words in this manual that could be the source of misunderstanding. The table
+ below will clarify those words.
+ </para>
+
+ <table frame="all">
+ <title>Terminology</title>
+ <tgroup cols='2'>
+ <thead>
+ <row>
+ <entry>Term</entry>
+ <entry>Explanation</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Caret</entry>
+ <entry>The text insertion point.</entry>
+ </row>
+ <row>
+ <entry>Cursor</entry>
+ <entry>Mouse pointer.</entry>
+ </row>
+ <row>
+ <entry>Document</entry>
+ <entry>A file loaded in &application;.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+ </sect1>
+
+ <sect1 id="mousepad">
+ <title>Working With &application;</title>
+
+ <sect2 id="window">
+ <title>Main Window</title>
+
+ <sect3 id="menu-bar">
+ <title>Menu Bar</title>
+ </sect3>
+
+ <sect3 id="statusbar">
+ <title>Statsbar</title>
+ </sect3>
+ </sect2>
+
+ <sect2 id="navigation">
+ <title>Navigation</title>
+
+ <sect3 id="go-to-line">
+ <title>Go To Line</title>
+ </sect3>
+ </sect2>
+
+ <sect2 id="ordering-documents">
+ <title>Ordering Documents</title>
+ </sect2>
+
+ <sect2 id="documents">
+ <title>Documents</title>
+
+ <sect3 id="new-documents">
+ <title>Creating New Documents</title>
+ </sect3>
+
+ <sect3 id="opening-documents">
+ <title>Opening Documents</title>
+ </sect3>
+
+ <sect3 id="recent-documents">
+ <title>Recent Documents</title>
+ </sect3>
+ </sect2>
</sect1>
- <sect1 id="mousepad-window">
- <title>The Mousepad Window</title>
+ <sect1 id="text">
+ <title>Working With Text</title>
+
+ <sect2 id="keyboard-shortcuts">
+ <title>Keyboard Shortcuts</title>
+ </sect2>
+
+ <sect2 id="auto-indent">
+ <title>Auto Indent</title>
+ </sect2>
+
+ <sect2 id="selections">
+ <title>Selecting Text</title>
+
+ <sect3 id="multi-and-column-selections">
+ <title>Multi- And Column-Selections</title>
+ </sect3>
+
+ <sect3 id="indentation">
+ <title>Indentation</title>
+ </sect3>
+ </sect2>
+
+ <sect2 id="clipboard">
+ <title>Copy, Cut and Paste From The Clipboard</title>
+ </sect2>
+
+ <sect2 id="search-and-replace">
+ <title>Search And Replace</title>
+ </sect2>
+
+ <sect2 id="tabs">
+ <title>Tabs</title>
+
+ <sect3 id="insert-spaces">
+ <title>Insert Spaces</title>
+ </sect3>
+ </sect2>
+
+ <sect2 id="transpose">
+ <title>Transpose</title>
+ </sect2>
+
+ <sect2 id="printing">
+ <title>Printing</title>
+ </sect2>
+ </sect1>
+
+ <sect1 id="faq">
+ <title>Frequently Asked Questions</title>
<para>
+ The intent of this section is to collect the quite numerous frequently asked
+ questions that relate to working with &application;. If you know of a question that
+ is missing from this page, please <ulink type="http"
+ url="http://bugzilla.xfce.org/enter_bug.cgi?product=Mousepad&format=guided">
+ file a request</ulink>.
</para>
- <sect2 id="editing-multiple-documents">
- <title>Editing Multiple Documents</title>
+ <sect3 id="faq-hidden-settings">
+ <title>Does &application; has hidden settings?</title>
<para>
- By defaul the window hides the tab labels unless more then one document has been opened. If you have
- more then one document opened, you can switch between then by clicking on the tab, use the
- <guimenuitem>go</guimenuitem> menu or press the key combination <keycap>Alt</keycap> with the tab number.
+ Yes, some of the settings in the mousepadrc file are not configurable from
+ the interface and can only be modified by hand. To find the mousepadrc file
+ see <xref linkend="faq-mousepadrc" />. It is not recommended to change the
+ rc file using &application;, since it might be overwritten when you
+ close the window after editing. You must also restart &application; to
+ apply the settings. The hidden settings, starting with <varname>Misc</varname>,
+ are explained in the list below:
</para>
+ <variablelist>
+ <varlistentry>
+ <term><varname>MiscAlwaysShowTabs</varname></term>
+ <listitem>
+ <para>
+ If <literal>TRUE</literal> the tab headers will always be displayed even if only a single
+ document tab is open. This option is useful if you want to drag-and-drop the last tab to
+ another window. See <xref linkend="ordering-documents" />.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>MiscCycleTabs</varname></term>
+ <listitem>
+ <para>
+ This option controls whether you can circulate through document tabs. That is, whether
+ you are able to go from the last tab to the first tab using the <menuchoice>
+ <guimenu>Navigation</guimenu><guimenuitem>Forward</guimenuitem></menuchoice> entry
+ (or the associated keyboard shortcut), and from the first tab to the last tab using the
+ <menuchoice><guimenu>Navigation</guimenu><guimenuitem>Back</guimenuitem></menuchoice> entry.
+ The option can be either <literal>TRUE</literal> or <literal>FALSE</literal> (default).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>MiscPathInTitle</varname></term>
+ <listitem>
+ <para>
+ This option controls whether the full document path is displayed in the window title.
+ By default, <literal>FALSE</literal>, only the filename is shown. The option can be either
+ <literal>TRUE</literal> or <literal>FALSE</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>MiscRecentMenuItems</varname></term>
+ <listitem>
+ <para>
+ This option controls the maximum number of items shown in the
+ <menuchoice><guimenu>File</guimenu><guimenuitem>Open Recent</guimenuitem>
+ </menuchoice> menu. When you set the value to <literal>0</literal>, so
+ entire menu will be hidden. The integer can be in a range of <literal>0</literal>
+ ..<literal>4096</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>MiscRememberGeometry</varname></term>
+ <listitem>
+ <para>
+ Whether &application; should remember the size of windows and apply that size to
+ new windows. If <literal>TRUE</literal> (default) the width and height are saved
+ to <varname>WindowWidth</varname> and <varname>WindowHeight</varname>. If
+ <literal>FALSE</literal> the user may specify the start size in
+ <varname>WindowWidth</varname> and <varname>WindowHeight</varname>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>MiscDefaultTabSizes</varname></term>
+ <listitem>
+ <para>
+ This is the default list of tab sizes displayed in the <menuchoice>
+ <guimenu>Document</guimenu><guimenuitem>Tab Size</guimenuitem></menuchoice>
+ menu. Each size must be in a range of <literal>1</literal>..<literal>32</literal>.
+ By defaul the value is <literal>2,3,4,8</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id="faq-mousepadrc">
+ <title>Where does &application; store its preferences?</title>
+
<para>
- When you have multiple files opened in one window, you detach a document by choosing
- <menuchoice><guimenu>File</guimenu><guimenuitem>Detach Tab</guimenuitem></menuchoice> or press
- <keycombo><keycap>Ctrl</keycap><keycap>D</keycap></keycombo>. When Mousepad is compiled with Gtk+ 2.12,
- it is also possible to drag a tab and drop it on another location on the screen.
+ &application; stores the user configurable preferences (and hidden settings) in
+ an <filename>.ini</filename> file, which is located at
+ <filename>$XDG_CONFIG_HOME/&application;/mousepadrc</filename>. If you make changes
+ to this file, make sure you restart &application;. It's also not recommended to
+ use &application; to edito this file, since it might overwrite it after you've
+ changed the file.
</para>
- </sect2>
- </sect1>
+ </sect3>
- <sect1 id="multi-selection">
- <title>Multi Editing</title>
+ <sect3 id="faq-assign-keyboard-shortcuts">
+ <title>How do I assign different keyboard shortcuts?</title>
- <para>
- Mousepad supports multiple- and column-selections. You can start a column selection by pressing the <keycap>Ctrl</keycap>
- key and starting a drag with your mouse. To add single words to the selection press <keycap>Ctrl</keycap> and double-click
- a word with the mouse pointer. As long as you press <keycap>Ctrl</keycap> you can add content to the selection.
- </para>
+ <para>
+ If you want to rebind a shortcut, &application; supports the standard GTK+ way
+ of changing shortcuts: simply hover over the menu option with the mouse
+ pointer and press the keyboard shortcut you want to rebind it to.
+ </para>
- <para>
- When you've created a multi-selection, it is possible to cut or copy this to the clipboard. When you start typing after a
- multi-selection, the selected content will be removed and the typed characters will appear in each selected part.
- </para>
+ <para>
+ To delete a keyboard assignment, press the <keycap>Backspace</keycap> key
+ while you are on the menu entry.
+ </para>
- <para>
- It is also possible to use this for multi typing. When you press <keycap>Ctrl</keycap> and drag at the end of a couple of lines
- you will see blue retangles appear at the end of the lines. When you start typing the characters will be added to each selected
- line. You can add as much of these insert points as you want as long you don't select a whole character.
+ <para>
+ If the shortcut doesn't change, then you need to enable the feature in
+ GTK+. This can be achieved in 3 ways:
+ </para>
- Another useful key combination with multi typing is <keycombo><keycap>Ctrl</keycap><keycap>Backspace</keycap></keycombo>, this will
- also remove character left or the insert point, while <keycap>Backspace</keycap> only removes characters inside the selection.
- </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ If you are running Xfce 4.3 or above then you can enable <guilabel>Editable
+ menu accelerators</guilabel> in the <guilabel>User Interface Preferences</guilabel>
+ dialog.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If you are running GNOME then you can enable <guilabel>Editable menu
+ accelerators</guilabel> in the <guilabel>Menu and Toolbars</guilabel> control
+ center dialog.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Otherwise put the following in your <filename>~/.gtkrc-2.0</filename> file
+ (create the file if it doesn't exist):<screen>gtk-can-change-accels=1</screen>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+
+ <sect3 id="faq-store-keyboard-shortcuts">
+ <title>Where does &application; store the keyboard shortcuts?</title>
+
+ <para>
+ The custom keyboard shortcuts are stored in the standard GTK+ accel map format in a
+ file located at <filename>$XDG_CONFIG_HOME/&application;/accels.scm</filename>. Lines starting
+ with <literal>;</literal> are comments. See the GTK+ documentation for details about the
+ file format.
+ </para>
+
+ <para>
+ If you are a packager or a system administrator and want to provide a system wide default
+ for the keyboard shortcuts, that is different from the default shortcuts in &application;, you
+ can create a file <filename>&application;/accels.scm</filename> in one of the <envar>$XDG_CONFIG_DIRS</envar>.
+ For example, if <filename role="directory">/etc/xdg</filename> is part of <envar>$XDG_CONFIG_DIRS</envar>
+ (the default for most Linux distributions), you can install system wide defaults to
+ <filename>/etc/xdg/&application;/accels.scm</filename>. &application; will then load shortcuts from
+ this file on first startup.
+ </para>
+ </sect3>
</sect1>
</article>
<!--
diff --git a/mousepad/mousepad-document.c b/mousepad/mousepad-document.c
index 7a55dac..3a318e2 100644
--- a/mousepad/mousepad-document.c
+++ b/mousepad/mousepad-document.c
@@ -47,9 +47,6 @@
static void mousepad_document_class_init (MousepadDocumentClass *klass);
static void mousepad_document_init (MousepadDocument *document);
static void mousepad_document_finalize (GObject *object);
-static void mousepad_document_notify_has_selection (GtkTextBuffer *buffer,
- GParamSpec *pspec,
- MousepadDocument *document);
static void mousepad_document_notify_cursor_position (GtkTextBuffer *buffer,
GParamSpec *pspec,
MousepadDocument *document);
@@ -73,7 +70,6 @@ static void mousepad_document_tab_button_clicked (GtkWidget
enum
{
CLOSE_TAB,
- SELECTION_CHANGED,
CURSOR_CHANGED,
OVERWRITE_CHANGED,
LAST_SIGNAL,
@@ -156,21 +152,13 @@ mousepad_document_class_init (MousepadDocumentClass *klass)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
- document_signals[SELECTION_CHANGED] =
- g_signal_new (I_("selection-changed"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_NO_HOOKS,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__BOOLEAN,
- G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
-
document_signals[CURSOR_CHANGED] =
g_signal_new (I_("cursor-changed"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_NO_HOOKS,
0, NULL, NULL,
- _mousepad_marshal_VOID__UINT_UINT,
- G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
+ _mousepad_marshal_VOID__INT_INT_INT,
+ G_TYPE_NONE, 3, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
document_signals[OVERWRITE_CHANGED] =
g_signal_new (I_("overwrite-changed"),
@@ -257,7 +245,6 @@ mousepad_document_init (MousepadDocument *document)
g_free (font_name);
/* attach signals to the text view and buffer */
- g_signal_connect (G_OBJECT (document->buffer), "notify::has-selection", G_CALLBACK (mousepad_document_notify_has_selection), document);
g_signal_connect (G_OBJECT (document->buffer), "notify::cursor-position", G_CALLBACK (mousepad_document_notify_cursor_position), document);
g_signal_connect (G_OBJECT (document->textview), "notify::overwrite", G_CALLBACK (mousepad_document_toggle_overwrite), document);
g_signal_connect (G_OBJECT (document->textview), "drag-data-received", G_CALLBACK (mousepad_document_drag_data_received), document);
@@ -287,24 +274,6 @@ mousepad_document_finalize (GObject *object)
}
-static void
-mousepad_document_notify_has_selection (GtkTextBuffer *buffer,
- GParamSpec *pspec,
- MousepadDocument *document)
-{
- gboolean has_selection;
-
- _mousepad_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
- _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
-
- /* check if we have selected text or not */
- has_selection = mousepad_view_get_has_selection (document->textview);
-
- /* emit the signal */
- g_signal_emit (G_OBJECT (document), document_signals[SELECTION_CHANGED], 0, has_selection);
-}
-
-
static void
mousepad_document_notify_cursor_position (GtkTextBuffer *buffer,
@@ -312,7 +281,7 @@ mousepad_document_notify_cursor_position (GtkTextBuffer *buffer,
MousepadDocument *document)
{
GtkTextIter iter;
- guint line, column = 0;
+ guint line, column, selection;
gint tab_size;
_mousepad_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
@@ -330,8 +299,11 @@ mousepad_document_notify_cursor_position (GtkTextBuffer *buffer,
/* get the column */
column = mousepad_util_get_real_line_offset (&iter, tab_size) + 1;
+ /* get length of the selection */
+ selection = mousepad_view_get_selection_length (document->textview);
+
/* emit the signal */
- g_signal_emit (G_OBJECT (document), document_signals[CURSOR_CHANGED], 0, line, column);
+ g_signal_emit (G_OBJECT (document), document_signals[CURSOR_CHANGED], 0, line, column, selection);
}
@@ -612,36 +584,3 @@ mousepad_document_get_word_wrap (MousepadDocument *document)
return document->priv->word_wrap;
}
-
-
-
-void
-mousepad_document_get_font_information (MousepadDocument *document,
- PangoFontDescription **font_desc,
- gint *font_height)
-{
- PangoContext *context;
- PangoFontMetrics *metrics;
- PangoFontDescription *font;
-
- /* get the textview context */
- context = gtk_widget_get_pango_context (GTK_WIDGET (document->textview));
-
- /* get the font description */
- font = pango_context_get_font_description (context);
-
- if (font_desc)
- *font_desc = font;
-
- if (G_LIKELY (font_height))
- {
- /* get metric information about the font */
- metrics = pango_context_get_metrics (context, font, pango_context_get_language (context));
-
- /* calculate the real font height */
- *font_height = (pango_font_metrics_get_ascent (metrics) + pango_font_metrics_get_descent (metrics)) / PANGO_SCALE;
-
- /* release the metrics */
- pango_font_metrics_unref (metrics);
- }
-}
diff --git a/mousepad/mousepad-document.h b/mousepad/mousepad-document.h
index 0906563..c07f4d5 100644
--- a/mousepad/mousepad-document.h
+++ b/mousepad/mousepad-document.h
@@ -93,10 +93,6 @@ const gchar *mousepad_document_get_filename (MousepadDocument
gboolean mousepad_document_get_word_wrap (MousepadDocument *document);
-void mousepad_document_get_font_information (MousepadDocument *document,
- PangoFontDescription **font_desc,
- gint *font_height);
-
G_END_DECLS
#endif /* !__MOUSEPAD_DOCUMENT_H__ */
diff --git a/mousepad/mousepad-file.c b/mousepad/mousepad-file.c
index a02e28e..b0ed998 100644
--- a/mousepad/mousepad-file.c
+++ b/mousepad/mousepad-file.c
@@ -294,9 +294,13 @@ mousepad_file_open (MousepadFile *file,
_mousepad_return_val_if_fail (error == NULL || *error == NULL, FALSE);
_mousepad_return_val_if_fail (file->filename != NULL, FALSE);
- /* check if the file exists */
+ /* check if the file exists, if not, it's a filename from the command line */
if (g_file_test (file->filename, G_FILE_TEST_EXISTS) == FALSE)
- return TRUE;
+ {
+ file->readonly = FALSE;
+
+ return TRUE;
+ }
/* open the channel */
channel = g_io_channel_new_file (file->filename, "r", error);
diff --git a/mousepad/mousepad-marshal.list b/mousepad/mousepad-marshal.list
index ba02bfc..4b5c216 100644
--- a/mousepad/mousepad-marshal.list
+++ b/mousepad/mousepad-marshal.list
@@ -1,3 +1,3 @@
-VOID:UINT,UINT
+VOID:INT,INT,INT
INT:FLAGS,STRING,STRING
VOID:OBJECT,INT,INT
diff --git a/mousepad/mousepad-preferences.c b/mousepad/mousepad-preferences.c
index 69ff461..86b6b3c 100644
--- a/mousepad/mousepad-preferences.c
+++ b/mousepad/mousepad-preferences.c
@@ -38,6 +38,7 @@
#include <glib-object.h>
#include <mousepad/mousepad-private.h>
+#include <mousepad/mousepad-util.h>
#include <mousepad/mousepad-preferences.h>
@@ -442,11 +443,8 @@ mousepad_preferences_set_property (GObject *object,
static void
mousepad_preferences_check_option_name (GParamSpec *pspec)
{
- const gchar *s;
const gchar *name, *nick;
- gboolean upper = TRUE;
gchar *option;
- gchar *t;
/* get property name and nick */
name = g_param_spec_get_name (pspec);
@@ -458,27 +456,8 @@ mousepad_preferences_check_option_name (GParamSpec *pspec)
}
else
{
- /* allocate string for option name */
- option = g_new (gchar, strlen (name) + 1);
-
- /* convert name */
- for (s = name, t = option; *s != '\0'; ++s)
- {
- if (*s == '-')
- {
- upper = TRUE;
- }
- else if (upper)
- {
- *t++ = g_ascii_toupper (*s);
- upper = FALSE;
- }
- else
- {
- *t++ = *s;
- }
- }
- *t = '\0';
+ /* get option name */
+ option = mousepad_util_config_name (name);
/* compare the strings */
if (G_UNLIKELY (!option || strcmp (option, nick) != 0))
@@ -505,7 +484,7 @@ mousepad_preferences_load (MousepadPreferences *preferences)
guint n;
/* try to open the config file */
- rc = xfce_rc_config_open (XFCE_RESOURCE_CONFIG, "Mousepad/mousepadrc", TRUE);
+ rc = xfce_rc_config_open (XFCE_RESOURCE_CONFIG, MOUSEPAD_PREFERENCES_REL_PATH, TRUE);
if (G_UNLIKELY (rc == NULL))
{
g_warning (_("Failed to load the preferences."));
@@ -601,7 +580,7 @@ mousepad_preferences_store_idle (gpointer user_data)
guint n;
/* open the config file */
- rc = xfce_rc_config_open (XFCE_RESOURCE_CONFIG, "Mousepad/mousepadrc", FALSE);
+ rc = xfce_rc_config_open (XFCE_RESOURCE_CONFIG, MOUSEPAD_PREFERENCES_REL_PATH, FALSE);
if (G_UNLIKELY (rc == NULL))
{
g_warning (_("Failed to store the preferences."));
diff --git a/mousepad/mousepad-preferences.h b/mousepad/mousepad-preferences.h
index d3161a0..c782432 100644
--- a/mousepad/mousepad-preferences.h
+++ b/mousepad/mousepad-preferences.h
@@ -27,6 +27,8 @@ G_BEGIN_DECLS
#define MOUSEPAD_IS_PREFERENCES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOUSEPAD_TYPE_PREFERENCES))
#define MOUSEPAD_PREFERENCES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOUSEPAD_TYPE_PREFERENCES, MousepadPreferencesClass))
+#define MOUSEPAD_PREFERENCES_REL_PATH ("Mousepad" G_DIR_SEPARATOR_S "mousepadrc")
+
typedef struct _MousepadPreferencesClass MousepadPreferencesClass;
typedef struct _MousepadPreferences MousepadPreferences;
diff --git a/mousepad/mousepad-print.c b/mousepad/mousepad-print.c
index 532103d..94bc85f 100644
--- a/mousepad/mousepad-print.c
+++ b/mousepad/mousepad-print.c
@@ -19,21 +19,44 @@
#include <config.h>
#endif
+#include <pango/pango.h>
+#include <cairo.h>
+
#include <mousepad/mousepad-private.h>
#include <mousepad/mousepad-preferences.h>
#include <mousepad/mousepad-document.h>
+#include <mousepad/mousepad-util.h>
#include <mousepad/mousepad-print.h>
-
-
-static void mousepad_print_class_init (MousepadPrintClass *klass);
-static void mousepad_print_init (MousepadPrint *print);
-static void mousepad_print_finalize (GObject *object);
-static void mousepad_print_begin_print (GtkPrintOperation *operation, GtkPrintContext *context);
-static void mousepad_print_draw_page (GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr);
-static void mousepad_print_end_print (GtkPrintOperation *operation, GtkPrintContext *context);
-static GtkWidget *mousepad_print_create_custom_widget (GtkPrintOperation *operation);
-static void mousepad_print_status_changed (GtkPrintOperation *operation);
+#define DOCUMENT_SPACING (10)
+
+
+
+static void mousepad_print_class_init (MousepadPrintClass *klass);
+static void mousepad_print_init (MousepadPrint *print);
+static void mousepad_print_finalize (GObject *object);
+static void mousepad_print_settings_load (GtkPrintOperation *operation);
+static void mousepad_print_settings_save_foreach (const gchar *key,
+ const gchar *value,
+ gpointer user_data);
+static void mousepad_print_settings_save (GtkPrintOperation *operation);
+static void mousepad_print_begin_print (GtkPrintOperation *operation,
+ GtkPrintContext *context);
+static void mousepad_print_draw_page (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gint page_nr);
+static void mousepad_print_end_print (GtkPrintOperation *operation,
+ GtkPrintContext *context);
+static void mousepad_print_page_setup_dialog (GtkWidget *button,
+ GtkPrintOperation *operation);
+static void mousepad_print_button_toggled (GtkWidget *button,
+ MousepadPrint *print);
+static void mousepad_print_button_font_set (GtkFontButton *button,
+ MousepadPrint *print);
+static GtkWidget *mousepad_print_create_custom_widget (GtkPrintOperation *operation);
+static void mousepad_print_status_changed (GtkPrintOperation *operation);
+static void mousepad_print_done (GtkPrintOperation *operation,
+ GtkPrintOperationResult result);
@@ -47,10 +70,31 @@ struct _MousepadPrint
GtkPrintOperation __parent__;
/* the document we're going to print */
- MousepadDocument *document;
+ MousepadDocument *document;
+
+ /* pango layout containing all text */
+ PangoLayout *layout;
+
+ /* array with the lines drawn on each page */
+ GArray *lines;
- /* calculated lines per page */
- gint lines_per_page;
+ /* drawing offsets */
+ gint x_offset;
+ gint y_offset;
+
+ /* page line number counter */
+ gint line_number;
+
+ /* print dialog widgets */
+ GtkWidget *widget_page_headers;
+ GtkWidget *widget_line_numbers;
+ GtkWidget *widget_text_wrapping;
+
+ /* settings */
+ guint print_page_headers : 1;
+ guint print_line_numbers : 1;
+ guint text_wrapping : 1;
+ gchar *font_name;
};
@@ -97,6 +141,7 @@ mousepad_print_class_init (MousepadPrintClass *klass)
gtkprintoperation_class->end_print = mousepad_print_end_print;
gtkprintoperation_class->create_custom_widget = mousepad_print_create_custom_widget;
gtkprintoperation_class->status_changed = mousepad_print_status_changed;
+ gtkprintoperation_class->done = mousepad_print_done;
}
@@ -104,8 +149,17 @@ mousepad_print_class_init (MousepadPrintClass *klass)
static void
mousepad_print_init (MousepadPrint *print)
{
+ /* init */
+ print->print_page_headers = FALSE;
+ print->print_line_numbers = FALSE;
+ print->text_wrapping = FALSE;
+ print->x_offset = 0;
+ print->y_offset = 0;
+ print->line_number = 0;
+ print->font_name = NULL;
+
/* set a custom tab label */
- //gtk_print_operation_set_custom_tab_label (GTK_PRINT_OPERATION (print), _("Document Settings"));
+ gtk_print_operation_set_custom_tab_label (GTK_PRINT_OPERATION (print), _("Document Settings"));
}
@@ -113,103 +167,447 @@ mousepad_print_init (MousepadPrint *print)
static void
mousepad_print_finalize (GObject *object)
{
+ MousepadPrint *print = MOUSEPAD_PRINT (object);
+
+ /* cleanup */
+ g_free (print->font_name);
+
(*G_OBJECT_CLASS (mousepad_print_parent_class)->finalize) (object);
}
static void
-mousepad_print_begin_print (GtkPrintOperation *operation,
- GtkPrintContext *context)
+mousepad_print_settings_load (GtkPrintOperation *operation)
{
- MousepadPrint *print = MOUSEPAD_PRINT (operation);
- gint n_lines, font_height;
- gint page_height, n_pages;
+ MousepadPrint *print = MOUSEPAD_PRINT (operation);
+ XfceRc *rc;
+ GtkPrintSettings *settings = NULL;
+ gchar **keys;
+ gint i;
+ gchar *key;
+ const gchar *value;
+ GtkPageSetup *page_setup;
+ GtkPaperSize *paper_size;
+ PangoContext *context;
+ PangoFontDescription *font_desc;
- _mousepad_return_if_fail (MOUSEPAD_IS_PRINT (print));
_mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (print->document));
- _mousepad_return_if_fail (GTK_IS_TEXT_BUFFER (print->document->buffer));
+ _mousepad_return_if_fail (GTK_IS_WIDGET (print->document->textview));
- /* get the document font information */
- mousepad_document_get_font_information (print->document, NULL, &font_height);
+ /* open the config file */
+ rc = xfce_rc_config_open (XFCE_RESOURCE_CONFIG, MOUSEPAD_PREFERENCES_REL_PATH, TRUE);
- /* get the number of lines in the buffer */
- n_lines = gtk_text_buffer_get_line_count (print->document->buffer);
+ if (G_LIKELY (rc != NULL))
+ {
+ /* get all the keys from the config file */
+ keys = xfce_rc_get_entries (rc, "Print Settings");
+
+ if (G_LIKELY (keys))
+ {
+ /* create new settings object */
+ settings = gtk_print_settings_new ();
+
+ /* set all the keys */
+ for (i = 0; keys[i] != NULL; i++)
+ {
+ /* read the value from the config file */
+ value = xfce_rc_read_entry (rc, keys[i], NULL);
+
+ /* set the value */
+ if (G_LIKELY (value))
+ {
+ key = mousepad_util_key_name (keys[i]);
+ gtk_print_settings_set (settings, key, value);
+ g_free (key);
+ }
+ }
+
+ /* cleanup */
+ g_strfreev (keys);
+ }
+
+ /* close */
+ xfce_rc_close (rc);
+ }
- /* get the page height */
- page_height = gtk_print_context_get_height (context);
+ if (G_LIKELY (settings))
+ {
+ /* apply the settings */
+ gtk_print_operation_set_print_settings (operation, settings);
+
+ if (gtk_print_settings_get_bool (settings, "page-setup-saved") == TRUE)
+ {
+ /* create new page setup */
+ page_setup = gtk_page_setup_new ();
+
+ /* set orientation */
+ gtk_page_setup_set_orientation (page_setup, gtk_print_settings_get_orientation (settings));
+
+ /* restore margins */
+ gtk_page_setup_set_top_margin (page_setup, gtk_print_settings_get_double (settings, "top-margin"), GTK_UNIT_MM);
+ gtk_page_setup_set_bottom_margin (page_setup, gtk_print_settings_get_double (settings, "bottom-margin"), GTK_UNIT_MM);
+ gtk_page_setup_set_right_margin (page_setup, gtk_print_settings_get_double (settings, "right-margin"), GTK_UNIT_MM);
+ gtk_page_setup_set_left_margin (page_setup, gtk_print_settings_get_double (settings, "left-margin"), GTK_UNIT_MM);
+
+ /* set paper size */
+ paper_size = gtk_print_settings_get_paper_size (settings);
+ if (G_LIKELY (paper_size))
+ gtk_page_setup_set_paper_size (page_setup, paper_size);
+
+ /* set the default page setup */
+ gtk_print_operation_set_default_page_setup (operation, page_setup);
+
+ /* release reference */
+ g_object_unref (G_OBJECT (page_setup));
+ }
+
+ /* restore print settings */
+ print->print_page_headers = gtk_print_settings_get_bool (settings, "print-page-headers");
+ print->print_line_numbers = gtk_print_settings_get_bool (settings, "print-line-numbers");
+ print->text_wrapping = gtk_print_settings_get_bool (settings, "text-wrapping");
+ print->font_name = g_strdup (gtk_print_settings_get (settings, "font-name"));
+
+ /* release reference */
+ g_object_unref (G_OBJECT (settings));
+ }
- /* lines per page */
- print->lines_per_page = page_height / font_height;
+ /* if no font name is set, get the one used in the widget */
+ if (G_UNLIKELY (print->font_name == NULL))
+ {
+ /* get the font description from the context and convert it into a string */
+ context = gtk_widget_get_pango_context (GTK_WIDGET (print->document->textview));
+ font_desc = pango_context_get_font_description (context);
+ print->font_name = pango_font_description_to_string (font_desc);
+ }
+}
- /* calculate the number of pages */
- n_pages = (n_lines / print->lines_per_page) + 1;
- /* set the number of pages */
- gtk_print_operation_set_n_pages (operation, n_pages);
+
+static void
+mousepad_print_settings_save_foreach (const gchar *key,
+ const gchar *value,
+ gpointer user_data)
+{
+ XfceRc *rc = (XfceRc *) user_data;
+ gchar *config;
+
+ /* save the setting */
+ if (G_LIKELY (key && value))
+ {
+ config = mousepad_util_config_name (key);
+ xfce_rc_write_entry (rc, config, value);
+ g_free (config);
+ }
}
static void
-mousepad_print_draw_page (GtkPrintOperation *operation,
- GtkPrintContext *context,
- gint page_nr)
+mousepad_print_settings_save (GtkPrintOperation *operation)
+{
+ MousepadPrint *print = MOUSEPAD_PRINT (operation);
+ XfceRc *rc;
+ GtkPrintSettings *settings;
+ GtkPageSetup *page_setup;
+ GtkPaperSize *paper_size;
+
+ /* open the config file */
+ rc = xfce_rc_config_open (XFCE_RESOURCE_CONFIG, MOUSEPAD_PREFERENCES_REL_PATH, FALSE);
+
+ if (G_LIKELY (rc != NULL))
+ {
+ /* set print settings group */
+ xfce_rc_set_group (rc, "Print Settings");
+
+ /* get the print settings */
+ settings = gtk_print_operation_get_print_settings (operation);
+
+ if (G_LIKELY (settings != NULL))
+ {
+ /* get the page setup */
+ page_setup = gtk_print_operation_get_default_page_setup (operation);
+
+ /* restore the page setup */
+ if (G_LIKELY (page_setup != NULL))
+ {
+ /* the the settings page orienation */
+ gtk_print_settings_set_orientation (settings, gtk_page_setup_get_orientation (page_setup));
+
+ /* save margins */
+ gtk_print_settings_set_double (settings, "top-margin", gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_MM));
+ gtk_print_settings_set_double (settings, "bottom-margin", gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_MM));
+ gtk_print_settings_set_double (settings, "right-margin", gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_MM));
+ gtk_print_settings_set_double (settings, "left-margin", gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_MM));
+
+ /* get the paper size */
+ paper_size = gtk_page_setup_get_paper_size (page_setup);
+
+ /* set settings page size */
+ if (G_LIKELY (paper_size))
+ gtk_print_settings_set_paper_size (settings, paper_size);
+ }
+
+ /* a bool we use for loading */
+ gtk_print_settings_set_bool (settings, "page-setup-saved", page_setup != NULL);
+
+ /* set print settings */
+ gtk_print_settings_set_bool (settings, "print-page-headers", print->print_page_headers);
+ gtk_print_settings_set_bool (settings, "print-line-numbers", print->print_line_numbers);
+ gtk_print_settings_set_bool (settings, "text-wrapping", print->text_wrapping);
+ gtk_print_settings_set (settings, "font-name", print->font_name);
+
+ /* store all the print settings */
+ gtk_print_settings_foreach (settings, mousepad_print_settings_save_foreach, rc);
+ }
+
+ /* close */
+ xfce_rc_close (rc);
+ }
+}
+
+
+
+static void
+mousepad_print_begin_print (GtkPrintOperation *operation,
+ GtkPrintContext *context)
{
MousepadPrint *print = MOUSEPAD_PRINT (operation);
- PangoLayout *layout;
+ MousepadDocument *document = print->document;
+ GtkTextIter start_iter, end_iter;
+ gint page_height;
+ gint page_width;
+ gint layout_height;
+ PangoRectangle rect;
PangoLayoutLine *line;
PangoFontDescription *font_desc;
- gint start, end;
- gint i, font_height;
- GtkTextIter start_iter, end_iter;
- MousepadDocument *document = print->document;
gchar *text;
- cairo_t *cr;
+ gint i;
+ gint size;
+ gint n_pages = 1;
- _mousepad_return_if_fail (MOUSEPAD_IS_PRINT (print));
+ /* create the pango layout */
+ print->layout = gtk_print_context_create_pango_layout (context);
- /* start and end line in the buffer */
- start = print->lines_per_page * page_nr;
- end = start + print->lines_per_page - 1;
+ /* set layout font */
+ font_desc = pango_font_description_from_string (print->font_name);
+ pango_layout_set_font_description (print->layout, font_desc);
+ pango_font_description_free (font_desc);
- /* get the iters */
- gtk_text_buffer_get_iter_at_line (document->buffer, &start_iter, start);
- gtk_text_buffer_get_iter_at_line (document->buffer, &end_iter, end);
- gtk_text_iter_forward_to_line_end (&end_iter);
+ /* calculate page header height */
+ if (print->print_page_headers)
+ {
+ /* set some pango layout text */
+ pango_layout_set_text (print->layout, "Page 1234", -1);
- /* create the pango layout */
- layout = gtk_print_context_create_pango_layout (context);
+ /* get the height */
+ pango_layout_get_pixel_size (print->layout, NULL, &size);
+
+ /* set the header offset */
+ print->y_offset = size + DOCUMENT_SPACING;
+ }
+
+ /* calculate the line number offset */
+ if (print->print_line_numbers)
+ {
+ /* insert the highest line number in the layout */
+ text = g_strdup_printf ("%d", MAX (99, gtk_text_buffer_get_line_count (document->buffer)));
+ pango_layout_set_text (print->layout, text, -1);
+ g_free (text);
+
+ /* get the width of the layout */
+ pango_layout_get_pixel_size (print->layout, &size, NULL);
- /* get the document font information */
- mousepad_document_get_font_information (document, &font_desc, &font_height);
+ /* set the text offset */
+ print->x_offset = size + DOCUMENT_SPACING;
+ }
- /* set the layout font description */
- pango_layout_set_font_description (layout, font_desc);
+ /* set the layout width */
+ page_width = gtk_print_context_get_width (context);
+ pango_layout_set_width (print->layout, PANGO_SCALE * (page_width - print->x_offset));
- /* get the text slice */
+ /* wrapping mode for the layout */
+ pango_layout_set_wrap (print->layout, print->text_wrapping ? PANGO_WRAP_WORD_CHAR : PANGO_WRAP_CHAR);
+
+ /* get the text in the entire buffer */
+ gtk_text_buffer_get_bounds (document->buffer, &start_iter, &end_iter);
text = gtk_text_buffer_get_slice (document->buffer, &start_iter, &end_iter, TRUE);
- /* set the pango layout text */
- pango_layout_set_text (layout, text, -1);
+ /* set the layout text */
+ pango_layout_set_text (print->layout, text, -1);
/* cleanup */
g_free (text);
+ /* get the page height in pango units */
+ page_height = gtk_print_context_get_height (context) - print->y_offset;
+
+ /* create and empty array to store the line numbers */
+ print->lines = g_array_new (FALSE, FALSE, sizeof (gint));
+
+ /* reset layout height */
+ layout_height = 0;
+
+ /* start with a zerro */
+ g_array_append_val (print->lines, layout_height);
+
+ for (i = 0; i < pango_layout_get_line_count (print->layout); i++)
+ {
+ /* get the line */
+ line = pango_layout_get_line_readonly (print->layout, i);
+
+ /* if we don't wrap lines, skip the lines that don't start a paragraph */
+ if (print->text_wrapping == FALSE && line->is_paragraph_start == FALSE)
+ continue;
+
+ /* get the line height */
+ pango_layout_line_get_pixel_extents (line, NULL, &rect);
+
+ /* append the height to the total page height */
+ layout_height += rect.height;
+
+ /* check if the layout still fits in the page */
+ if (layout_height > page_height)
+ {
+ /* reset the layout height */
+ layout_height = 0;
+
+ /* increase page counter */
+ n_pages++;
+
+ /* append the line number to the array */
+ g_array_append_val (print->lines, i);
+ }
+ }
+
+ /* append the last line to the array */
+ g_array_append_val (print->lines, i);
+
+ /* set the number of pages we're going to draw */
+ gtk_print_operation_set_n_pages (operation, n_pages);
+}
+
+
+
+static void
+mousepad_print_draw_page (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gint page_nr)
+{
+ MousepadPrint *print = MOUSEPAD_PRINT (operation);
+ MousepadDocument *document = print->document;
+ PangoLayoutLine *line;
+ cairo_t *cr;
+ PangoRectangle rect;
+ gint i;
+ gint x, y;
+ gint width, height;
+ gint start, end;
+ gchar *text;
+ PangoLayout *layout;
+
/* get the cairo context */
cr = gtk_print_context_get_cairo_context (context);
- /* show all the lines at the correct position */
- for (i = 0; i < pango_layout_get_line_count (layout); i++)
+ /* get the start and end line from the array */
+ start = g_array_index (print->lines, gint, page_nr);
+ end = g_array_index (print->lines, gint, page_nr + 1);
+
+ /* set line width */
+ cairo_set_line_width (cr, 1);
+
+ /* create an empty pango layout */
+ layout = gtk_print_context_create_pango_layout (context);
+ pango_layout_set_font_description (layout, pango_layout_get_font_description (print->layout));
+
+ /* print header */
+ if (print->print_page_headers)
+ {
+ /* create page number */
+ text = g_strdup_printf (_("Page %d of %d"), page_nr + 1, print->lines->len - 1);
+ pango_layout_set_text (layout, text, -1);
+ g_free (text);
+
+ /* get layout size */
+ pango_layout_get_pixel_size (layout, &width, &height);
+
+ /* position right of the document */
+ x = gtk_print_context_get_width (context) - width;
+
+ /* show the layout */
+ cairo_move_to (cr, x, 0);
+ pango_cairo_show_layout (cr, layout);
+
+ /* set the layout width of the filename */
+ pango_layout_set_width (layout, PANGO_SCALE * (x - DOCUMENT_SPACING * 2));
+
+ /* ellipsize the start of the filename */
+ pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_START);
+
+ /* set the document filename as text */
+ if (mousepad_document_get_filename (document))
+ pango_layout_set_text (layout, mousepad_document_get_filename (document), -1);
+ else
+ pango_layout_set_text (layout, mousepad_document_get_basename (document), -1);
+
+ /* show the layout */
+ cairo_move_to (cr, 0, 0);
+ pango_cairo_show_layout (cr, layout);
+
+ /* stroke a line under the header */
+ cairo_move_to (cr, 0, height + 1);
+ cairo_rel_line_to (cr, gtk_print_context_get_width (context), 0);
+ cairo_stroke (cr);
+
+ /* restore the layout for the line numbers */
+ pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_NONE);
+ pango_layout_set_width (layout, -1);
+ }
+
+ /* position and render all lines */
+ for (i = start, y = print->y_offset; i < end; i++)
{
/* get the line */
- line = pango_layout_get_line_readonly (layout, i);
+ line = pango_layout_get_line_readonly (print->layout, i);
- /* move the cairo position */
- cairo_move_to (cr, 0, font_height * (i + 1));
+ /* if we don't wrap lines, skip the lines that don't start a paragraph */
+ if (print->text_wrapping == FALSE && line->is_paragraph_start == FALSE)
+ continue;
+
+ /* get the line rectangle */
+ pango_layout_line_get_pixel_extents (line, NULL, &rect);
+
+ /* fix the start position */
+ if (G_UNLIKELY (i == start))
+ y -= rect.height / 3;
+
+ /* add the line hight to the top offset */
+ y += rect.height;
+
+ /* move the cursor to the start of the text */
+ cairo_move_to (cr, print->x_offset, y);
/* show the line at the new position */
pango_cairo_show_layout_line (cr, line);
+
+ /* print line number */
+ if (print->print_line_numbers && line->is_paragraph_start)
+ {
+ /* increase page number */
+ print->line_number++;
+
+ /* render a page number in the layout */
+ text = g_strdup_printf ("%d", print->line_number);
+ pango_layout_set_text (layout, text, -1);
+ g_free (text);
+
+ /* move the cursor to the start of the line */
+ cairo_move_to (cr, 0, y);
+
+ /* pick the first line and draw it on the cairo context */
+ line = pango_layout_get_line_readonly (layout, 0);
+ pango_cairo_show_layout_line (cr, line);
+ }
}
/* release the layout */
@@ -222,7 +620,73 @@ static void
mousepad_print_end_print (GtkPrintOperation *operation,
GtkPrintContext *context)
{
+ MousepadPrint *print = MOUSEPAD_PRINT (operation);
+ /* release the layout */
+ g_object_unref (G_OBJECT (print->layout));
+
+ /* free array */
+ g_array_free (print->lines, TRUE);
+}
+
+
+
+static void
+mousepad_print_page_setup_dialog (GtkWidget *button,
+ GtkPrintOperation *operation)
+{
+ GtkWidget *toplevel;
+ GtkPrintSettings *settings;
+ GtkPageSetup *page_setup;
+
+ /* get the toplevel of the button */
+ toplevel = gtk_widget_get_toplevel (button);
+ if (G_UNLIKELY (!GTK_WIDGET_TOPLEVEL (toplevel)))
+ toplevel = NULL;
+
+ /* get the print settings */
+ settings = gtk_print_operation_get_print_settings (operation);
+ if (G_UNLIKELY (settings == NULL))
+ settings = gtk_print_settings_new ();
+
+ /* get the page setup */
+ page_setup = gtk_print_operation_get_default_page_setup (operation);
+
+ /* run the dialog */
+ page_setup = gtk_print_run_page_setup_dialog (GTK_WINDOW (toplevel), page_setup, settings);
+
+ /* set the new page setup */
+ gtk_print_operation_set_default_page_setup (operation, page_setup);
+}
+
+
+
+static void
+mousepad_print_button_toggled (GtkWidget *button,
+ MousepadPrint *print)
+{
+ gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+
+ /* save the correct setting */
+ if (button == print->widget_page_headers)
+ print->print_page_headers = active;
+ else if (button == print->widget_line_numbers)
+ print->print_line_numbers = active;
+ else if (button == print->widget_text_wrapping)
+ print->text_wrapping = active;
+}
+
+
+
+static void
+mousepad_print_button_font_set (GtkFontButton *button,
+ MousepadPrint *print)
+{
+ /* remove old font name */
+ g_free (print->font_name);
+
+ /* set new font */
+ print->font_name = g_strdup (gtk_font_button_get_font_name (button));
}
@@ -230,7 +694,94 @@ mousepad_print_end_print (GtkPrintOperation *operation,
static GtkWidget *
mousepad_print_create_custom_widget (GtkPrintOperation *operation)
{
- return NULL;
+ MousepadPrint *print = MOUSEPAD_PRINT (operation);
+ GtkWidget *button;
+ GtkWidget *vbox, *vbox2;
+ GtkWidget *frame;
+ GtkWidget *alignment;
+ GtkWidget *label;
+
+ vbox = gtk_vbox_new (FALSE, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
+
+ frame = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
+ gtk_widget_show (frame);
+
+ label = gtk_label_new (_("<b>Page Setup</b>"));
+ gtk_frame_set_label_widget (GTK_FRAME (frame), label);
+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+ gtk_widget_show (label);
+
+ alignment = gtk_alignment_new (0.0, 0.5, 0.0, 1.0);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 6, 12, 6);
+ gtk_container_add (GTK_CONTAINER (frame), alignment);
+ gtk_widget_show (alignment);
+
+ button = mousepad_util_image_button (GTK_STOCK_PROPERTIES, _("_Adjust page size and orientation"));
+ g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (mousepad_print_page_setup_dialog), operation);
+ gtk_container_add (GTK_CONTAINER (alignment), button);
+ gtk_widget_show (button);
+
+ frame = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
+ gtk_widget_show (frame);
+
+ label = gtk_label_new (_("<b>Appearance</b>"));
+ gtk_frame_set_label_widget (GTK_FRAME (frame), label);
+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+ gtk_widget_show (label);
+
+ alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 6, 12, 6);
+ gtk_container_add (GTK_CONTAINER (frame), alignment);
+ gtk_widget_show (alignment);
+
+ vbox2 = gtk_vbox_new (FALSE, 6);
+ gtk_container_add (GTK_CONTAINER (alignment), vbox2);
+ gtk_widget_show (vbox2);
+
+ button = print->widget_page_headers = gtk_check_button_new_with_mnemonic (_("Print page _headers"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), print->print_page_headers);
+ g_signal_connect (G_OBJECT (button), "toggled", G_CALLBACK (mousepad_print_button_toggled), print);
+ gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
+ gtk_widget_show (button);
+
+ button = print->widget_line_numbers = gtk_check_button_new_with_mnemonic (_("Print _line numbers"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), print->print_line_numbers);
+ g_signal_connect (G_OBJECT (button), "toggled", G_CALLBACK (mousepad_print_button_toggled), print);
+ gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
+ gtk_widget_show (button);
+
+ button = print->widget_text_wrapping = gtk_check_button_new_with_mnemonic (_("Enable text _wrapping"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), print->text_wrapping);
+ g_signal_connect (G_OBJECT (button), "toggled", G_CALLBACK (mousepad_print_button_toggled), print);
+ gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
+ gtk_widget_show (button);
+
+ frame = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
+ gtk_widget_show (frame);
+
+ label = gtk_label_new (_("<b>Font</b>"));
+ gtk_frame_set_label_widget (GTK_FRAME (frame), label);
+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+ gtk_widget_show (label);
+
+ alignment = gtk_alignment_new (0.0, 0.5, 0.0, 1.0);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 6, 12, 6);
+ gtk_container_add (GTK_CONTAINER (frame), alignment);
+ gtk_widget_show (alignment);
+
+ button = gtk_font_button_new_with_font (print->font_name);
+ gtk_container_add (GTK_CONTAINER (alignment), button);
+ g_signal_connect (G_OBJECT (button), "font-set", G_CALLBACK (mousepad_print_button_font_set), print);
+ gtk_widget_show (button);
+
+ return vbox;
}
@@ -238,7 +789,21 @@ mousepad_print_create_custom_widget (GtkPrintOperation *operation)
static void
mousepad_print_status_changed (GtkPrintOperation *operation)
{
+ /* nothing usefull for now, we could set a statusbar text or something */
+}
+
+
+static void
+mousepad_print_done (GtkPrintOperation *operation,
+ GtkPrintOperationResult result)
+{
+ /* check if the print succeeded */
+ if (result == GTK_PRINT_OPERATION_RESULT_APPLY)
+ {
+ /* save the settings */
+ mousepad_print_settings_save (operation);
+ }
}
@@ -268,6 +833,12 @@ mousepad_print_document_interactive (MousepadPrint *print,
/* set the document */
print->document = document;
+ /* load settings */
+ mousepad_print_settings_load (GTK_PRINT_OPERATION (print));
+
+ /* allow async printing is support by the platform */
+ gtk_print_operation_set_allow_async (GTK_PRINT_OPERATION (print), TRUE);
+
/* run the operation */
result = gtk_print_operation_run (GTK_PRINT_OPERATION (print),
GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
diff --git a/mousepad/mousepad-print.h b/mousepad/mousepad-print.h
index 45677b7..28011ae 100644
--- a/mousepad/mousepad-print.h
+++ b/mousepad/mousepad-print.h
@@ -30,14 +30,14 @@ typedef struct _MousepadPrint MousepadPrint;
#define MOUSEPAD_IS_PRINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOUSEPAD_TYPE_PRINT))
#define MOUSEPAD_PRINT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOUSEPAD_TYPE_PRINT, MousepadPrintClass))
-GType mousepad_print_get_type (void) G_GNUC_CONST;
+GType mousepad_print_get_type (void) G_GNUC_CONST;
-MousepadPrint *mousepad_print_new (void);
+MousepadPrint *mousepad_print_new (void);
-gboolean mousepad_print_document_interactive (MousepadPrint *print,
- MousepadDocument *document,
- GtkWindow *parent,
- GError **error);
+gboolean mousepad_print_document_interactive (MousepadPrint *print,
+ MousepadDocument *document,
+ GtkWindow *parent,
+ GError **error);
G_END_DECLS
diff --git a/mousepad/mousepad-statusbar.c b/mousepad/mousepad-statusbar.c
index 81e851d..613bc05 100644
--- a/mousepad/mousepad-statusbar.c
+++ b/mousepad/mousepad-statusbar.c
@@ -113,7 +113,7 @@ mousepad_statusbar_class_init (MousepadStatusbarClass *klass)
static void
mousepad_statusbar_init (MousepadStatusbar *statusbar)
{
- GtkWidget *ebox, *box;
+ GtkWidget *ebox, *box, *separator;
GtkStatusbar *bar = GTK_STATUSBAR (statusbar);
/* init statusbar */
@@ -130,11 +130,21 @@ mousepad_statusbar_init (MousepadStatusbar *statusbar)
gtk_box_pack_start (GTK_BOX (box), bar->label, TRUE, TRUE, 0);
g_object_unref (G_OBJECT (bar->label));
+ /* separator */
+ separator = gtk_vseparator_new ();
+ gtk_box_pack_start (GTK_BOX (box), separator, FALSE, FALSE, 0);
+ gtk_widget_show (separator);
+
/* line and column numbers */
statusbar->position = gtk_label_new (NULL);
gtk_box_pack_start (GTK_BOX (box), statusbar->position, FALSE, TRUE, 0);
gtk_widget_show (statusbar->position);
+ /* separator */
+ separator = gtk_vseparator_new ();
+ gtk_box_pack_start (GTK_BOX (box), separator, FALSE, FALSE, 0);
+ gtk_widget_show (separator);
+
/* overwrite event box */
ebox = gtk_event_box_new ();
gtk_box_pack_start (GTK_BOX (box), ebox, FALSE, TRUE, 0);
@@ -176,14 +186,18 @@ mousepad_statusbar_overwrite_clicked (GtkWidget *widget,
void
mousepad_statusbar_set_cursor_position (MousepadStatusbar *statusbar,
gint line,
- gint column)
+ gint column,
+ gint selection)
{
gchar string[64];
_mousepad_return_if_fail (MOUSEPAD_IS_STATUSBAR (statusbar));
/* create printable string */
- g_snprintf (string, sizeof (string), _("Line %d Col %d"), line, column);
+ if (G_UNLIKELY (selection > 0))
+ g_snprintf (string, sizeof (string), _("Line: %d Column: %d Selection: %d"), line, column, selection);
+ else
+ g_snprintf (string, sizeof (string), _("Line: %d Column: %d"), line, column);
/* set label */
gtk_label_set_text (GTK_LABEL (statusbar->position), string);
diff --git a/mousepad/mousepad-statusbar.h b/mousepad/mousepad-statusbar.h
index bd5b265..28c7c59 100644
--- a/mousepad/mousepad-statusbar.h
+++ b/mousepad/mousepad-statusbar.h
@@ -36,7 +36,8 @@ GtkWidget *mousepad_statusbar_new (void);
void mousepad_statusbar_set_cursor_position (MousepadStatusbar *statusbar,
gint line,
- gint column);
+ gint column,
+ gint selection);
void mousepad_statusbar_set_overwrite (MousepadStatusbar *statusbar,
gboolean overwrite);
diff --git a/mousepad/mousepad-util.c b/mousepad/mousepad-util.c
index 4e5a2f8..a0ef459 100644
--- a/mousepad/mousepad-util.c
+++ b/mousepad/mousepad-util.c
@@ -19,11 +19,231 @@
#include <config.h>
#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
#include <mousepad/mousepad-private.h>
#include <mousepad/mousepad-util.h>
+static inline gboolean
+mousepad_util_iter_word_characters (const GtkTextIter *iter)
+{
+ gunichar c;
+
+ /* get the characters */
+ c = gtk_text_iter_get_char (iter);
+
+ /* character we'd like to see in a word */
+ if (g_unichar_isalnum (c) || c == '_')
+ return TRUE;
+
+ return FALSE;
+}
+
+
+
+gboolean
+mousepad_util_iter_starts_word (const GtkTextIter *iter)
+{
+ GtkTextIter prev;
+
+ /* normal gtk word start */
+ if (!gtk_text_iter_starts_word (iter))
+ return FALSE;
+
+ /* init iter for previous char */
+ prev = *iter;
+
+ /* return true when we could not step backwards (start of buffer) */
+ if (!gtk_text_iter_backward_char (&prev))
+ return TRUE;
+
+ /* check if the previous char also belongs to the word */
+ if (mousepad_util_iter_word_characters (&prev))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+
+gboolean
+mousepad_util_iter_ends_word (const GtkTextIter *iter)
+{
+ if (!gtk_text_iter_ends_word (iter))
+ return FALSE;
+
+ /* check if it's a character we'd like to see in a word */
+ if (mousepad_util_iter_word_characters (iter))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+
+gboolean
+mousepad_util_iter_inside_word (const GtkTextIter *iter)
+{
+ GtkTextIter prev;
+
+ /* not inside a word when at beginning or end of a word */
+ if (mousepad_util_iter_starts_word (iter) || mousepad_util_iter_ends_word (iter))
+ return FALSE;
+
+ /* normal gtk function */
+ if (gtk_text_iter_inside_word (iter))
+ return TRUE;
+
+ /* check if the character is a word char */
+ if (!mousepad_util_iter_word_characters (iter))
+ return FALSE;
+
+ /* initialize previous iter */
+ prev = *iter;
+
+ /* get one character backwards */
+ if (!gtk_text_iter_backward_char (&prev))
+ return FALSE;
+
+ return mousepad_util_iter_word_characters (&prev);
+}
+
+
+
+gboolean
+mousepad_util_iter_forward_word_end (GtkTextIter *iter)
+{
+ if (mousepad_util_iter_ends_word (iter))
+ return TRUE;
+
+ while (gtk_text_iter_forward_char (iter))
+ if (mousepad_util_iter_ends_word (iter))
+ return TRUE;
+
+ return mousepad_util_iter_ends_word (iter);
+}
+
+
+
+gboolean
+mousepad_util_iter_backward_word_start (GtkTextIter *iter)
+{
+ /* return true if the iter already starts a word */
+ if (mousepad_util_iter_starts_word (iter))
+ return TRUE;
+
+ /* move backwards until we find a word start */
+ while (gtk_text_iter_backward_char (iter))
+ if (mousepad_util_iter_starts_word (iter))
+ return TRUE;
+
+ /* while stops when we hit the first char in the buffer */
+ return mousepad_util_iter_starts_word (iter);
+}
+
+
+
+gboolean
+mousepad_util_iter_forward_text_start (GtkTextIter *iter)
+{
+ _mousepad_return_val_if_fail (!mousepad_util_iter_inside_word (iter), FALSE);
+
+ /* keep until we hit text or a line end */
+ while (g_unichar_isspace (gtk_text_iter_get_char (iter)))
+ if (gtk_text_iter_ends_line (iter) || !gtk_text_iter_forward_char (iter))
+ break;
+
+ return TRUE;
+}
+
+
+
+gboolean
+mousepad_util_iter_backward_text_start (GtkTextIter *iter)
+{
+ GtkTextIter prev = *iter;
+
+ _mousepad_return_val_if_fail (!mousepad_util_iter_inside_word (iter), FALSE);
+
+ while (!gtk_text_iter_starts_line (&prev) && gtk_text_iter_backward_char (&prev))
+ {
+ if (g_unichar_isspace (gtk_text_iter_get_char (&prev)))
+ *iter = prev;
+ else
+ break;
+ }
+
+ return TRUE;
+}
+
+
+
+gchar *
+mousepad_util_config_name (const gchar *name)
+{
+ const gchar *s;
+ gchar *config, *t;
+ gboolean upper = TRUE;
+
+ /* allocate string */
+ config = g_new (gchar, strlen (name) + 1);
+
+ /* convert name */
+ for (s = name, t = config; *s != '\0'; ++s)
+ {
+ if (*s == '-')
+ {
+ upper = TRUE;
+ }
+ else if (upper)
+ {
+ *t++ = g_ascii_toupper (*s);
+ upper = FALSE;
+ }
+ else
+ {
+ *t++ = g_ascii_tolower (*s);
+ }
+ }
+
+ /* zerro terminate string */
+ *t = '\0';
+
+ return config;
+}
+
+
+
+gchar *
+mousepad_util_key_name (const gchar *name)
+{
+ const gchar *s;
+ gchar *key, *t;
+
+ /* allocate string (max of 9 extra - chars) */
+ key = g_new (gchar, strlen (name) + 10);
+
+ /* convert name */
+ for (s = name, t = key; *s != '\0'; ++s)
+ {
+ if (g_ascii_isupper (*s) && s != name)
+ *t++ = '-';
+
+ *t++ = g_ascii_tolower (*s);
+ }
+
+ /* zerro terminate string */
+ *t = '\0';
+
+ return key;
+}
+
+
+
GtkWidget *
mousepad_util_image_button (const gchar *stock_id,
const gchar *label)
@@ -291,7 +511,7 @@ mousepad_util_search_iter (const GtkTextIter *start,
gtk_text_iter_forward_char (&iter);
/* check if we match a whole word */
- if (whole_word && !(gtk_text_iter_starts_word (&begin) && gtk_text_iter_ends_word (&iter)))
+ if (whole_word && !(mousepad_util_iter_starts_word (&begin) && mousepad_util_iter_ends_word (&iter)))
goto reset_and_continue_searching;
}
else
@@ -300,7 +520,7 @@ mousepad_util_search_iter (const GtkTextIter *start,
gtk_text_iter_forward_char (&begin);
/* check if we match a whole word */
- if (whole_word && !(gtk_text_iter_starts_word (&iter) && gtk_text_iter_ends_word (&begin)))
+ if (whole_word && !(mousepad_util_iter_starts_word (&iter) && mousepad_util_iter_ends_word (&begin)))
goto reset_and_continue_searching;
}
diff --git a/mousepad/mousepad-util.h b/mousepad/mousepad-util.h
index 7af6066..b25681a 100644
--- a/mousepad/mousepad-util.h
+++ b/mousepad/mousepad-util.h
@@ -56,39 +56,55 @@ enum _MousepadSearchFlags
MOUSEPAD_SEARCH_FLAGS_ACTION_REPLACE = 1 << 17, /* replace the match */
};
+gboolean mousepad_util_iter_starts_word (const GtkTextIter *iter);
+gboolean mousepad_util_iter_ends_word (const GtkTextIter *iter);
-GtkWidget *mousepad_util_image_button (const gchar *stock_id,
- const gchar *label);
+gboolean mousepad_util_iter_inside_word (const GtkTextIter *iter);
-void mousepad_util_entry_error (GtkWidget *widget,
- gboolean error);
+gboolean mousepad_util_iter_forward_word_end (GtkTextIter *iter);
-void mousepad_util_dialog_header (GtkDialog *dialog,
- const gchar *title,
- const gchar *subtitle,
- const gchar *icon);
+gboolean mousepad_util_iter_backward_word_start (GtkTextIter *iter);
-void mousepad_util_set_tooltip (GtkWidget *widget,
- const gchar *string);
+gboolean mousepad_util_iter_forward_text_start (GtkTextIter *iter);
-gint mousepad_util_get_real_line_offset (const GtkTextIter *iter,
- gint tab_size);
+gboolean mousepad_util_iter_backward_text_start (GtkTextIter *iter);
-gboolean mousepad_util_forward_iter_to_text (GtkTextIter *iter,
- const GtkTextIter *limit);
+gchar *mousepad_util_config_name (const gchar *name);
-GType mousepad_util_search_flags_get_type (void) G_GNUC_CONST;
+gchar *mousepad_util_key_name (const gchar *name);
-gint mousepad_util_highlight (GtkTextBuffer *buffer,
- GtkTextTag *tag,
- const gchar *string,
- MousepadSearchFlags flags);
+GtkWidget *mousepad_util_image_button (const gchar *stock_id,
+ const gchar *label);
-gint mousepad_util_search (GtkTextBuffer *buffer,
- const gchar *string,
- const gchar *replace,
- MousepadSearchFlags flags);
+void mousepad_util_entry_error (GtkWidget *widget,
+ gboolean error);
+
+void mousepad_util_dialog_header (GtkDialog *dialog,
+ const gchar *title,
+ const gchar *subtitle,
+ const gchar *icon);
+
+void mousepad_util_set_tooltip (GtkWidget *widget,
+ const gchar *string);
+
+gint mousepad_util_get_real_line_offset (const GtkTextIter *iter,
+ gint tab_size);
+
+gboolean mousepad_util_forward_iter_to_text (GtkTextIter *iter,
+ const GtkTextIter *limit);
+
+GType mousepad_util_search_flags_get_type (void) G_GNUC_CONST;
+
+gint mousepad_util_highlight (GtkTextBuffer *buffer,
+ GtkTextTag *tag,
+ const gchar *string,
+ MousepadSearchFlags flags);
+
+gint mousepad_util_search (GtkTextBuffer *buffer,
+ const gchar *string,
+ const gchar *replace,
+ MousepadSearchFlags flags);
G_END_DECLS
diff --git a/mousepad/mousepad-view.c b/mousepad/mousepad-view.c
index 2fed762..a91c643 100644
--- a/mousepad/mousepad-view.c
+++ b/mousepad/mousepad-view.c
@@ -31,8 +31,7 @@
-#define mousepad_view_get_buffer(view) (GTK_TEXT_VIEW (view)->buffer)
-#define MOUSEPAD_VIEW_RECT_WIDTH (3)
+#define mousepad_view_get_buffer(view) (GTK_TEXT_VIEW (view)->buffer)
@@ -49,21 +48,21 @@ static gboolean mousepad_view_button_press_event (GtkWidget
GdkEventButton *event);
static gboolean mousepad_view_button_release_event (GtkWidget *widget,
GdkEventButton *event);
+static gboolean mousepad_view_selection_word_range (const GtkTextIter *iter,
+ GtkTextIter *range_start,
+ GtkTextIter *range_end);
static void mousepad_view_selection_key_press_event (MousepadView *view,
GdkEventKey *event,
guint modifiers);
static void mousepad_view_selection_delete_content (MousepadView *view);
static void mousepad_view_selection_destroy (MousepadView *view);
-static void mousepad_view_selection_add_word (MousepadView *view);
static void mousepad_view_selection_cleanup_equal_marks (MousepadView *view);
static void mousepad_view_selection_add_marks (MousepadView *view,
GtkTextIter *start_iter,
GtkTextIter *end_iter);
static void mousepad_view_selection_draw (MousepadView *view,
- gboolean draw_rectangles,
+ gboolean draw_cursors,
gboolean add_marks);
-static void mousepad_view_selection_emit_has_selection (MousepadView *view,
- gboolean has_content);
static gboolean mousepad_view_selection_timeout (gpointer user_data);
static void mousepad_view_selection_timeout_destroy (gpointer user_data);
static void mousepad_view_indent_increase (MousepadView *view,
@@ -77,6 +76,8 @@ static gchar *mousepad_view_indent_string (GtkTextBuffer
static gint mousepad_view_calculate_layout_width (GtkWidget *widget,
gsize length,
gchar fill_char);
+static void mousepad_view_transpose_multi_selection (GtkTextBuffer *buffer,
+ MousepadView *view);
static void mousepad_view_transpose_range (GtkTextBuffer *buffer,
GtkTextIter *start_iter,
GtkTextIter *end_iter);
@@ -124,6 +125,9 @@ struct _MousepadView
gint selection_end_x;
gint selection_end_y;
+ /* length of the selection */
+ gint selection_length;
+
/* settings */
guint auto_indent : 1;
guint line_numbers : 1;
@@ -193,6 +197,7 @@ mousepad_view_init (MousepadView *view)
view->flags = 0;
view->selection_tag = NULL;
view->marks = NULL;
+ view->selection_length = 0;
}
@@ -497,7 +502,7 @@ mousepad_view_key_press_event (GtkWidget *widget,
{
goto selection_key_press;
}
- else if (mousepad_view_get_has_selection (view))
+ else if (gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL))
{
/* indent the selection */
mousepad_view_indent_selection (view, (modifiers & GDK_SHIFT_MASK));
@@ -551,40 +556,68 @@ static gboolean
mousepad_view_button_press_event (GtkWidget *widget,
GdkEventButton *event)
{
- MousepadView *view = MOUSEPAD_VIEW (widget);
- GtkTextView *textview = GTK_TEXT_VIEW (widget);;
+ MousepadView *view = MOUSEPAD_VIEW (widget);
+ GtkTextView *textview = GTK_TEXT_VIEW (widget);
+ GtkTextIter iter, start_iter, end_iter;
+ GtkTextBuffer *buffer;
/* work with vertical selection while ctrl is pressed */
if (event->state & GDK_CONTROL_MASK
&& event->x >= 0
&& event->y >= 0
- && event->button == 1)
+ && event->button == 1
+ && event->type == GDK_BUTTON_PRESS)
{
/* set the vertical selection start position, inclusing textview offset */
view->selection_start_x = event->x + textview->xoffset;
view->selection_start_y = event->y + textview->yoffset;
- if (event->type == GDK_BUTTON_PRESS)
- {
- /* whether this is going to be a multiple selection */
- if (view->flags != 0)
- MOUSEPAD_SET_FLAG (view->flags, MULTIPLE);
+ /* whether this is going to be a multiple selection */
+ if (view->flags != 0)
+ MOUSEPAD_SET_FLAG (view->flags, MULTIPLE);
- /* enable dragging */
- MOUSEPAD_SET_FLAG (view->flags, DRAGGING);
+ /* enable dragging */
+ MOUSEPAD_SET_FLAG (view->flags, DRAGGING);
- /* start a vertical selection timeout */
- view->selection_timeout_id = g_timeout_add_full (G_PRIORITY_LOW, 50, mousepad_view_selection_timeout,
- view, mousepad_view_selection_timeout_destroy);
- }
- else if (event->type == GDK_2BUTTON_PRESS)
+ /* start a vertical selection timeout */
+ view->selection_timeout_id = g_timeout_add_full (G_PRIORITY_LOW, 50, mousepad_view_selection_timeout,
+ view, mousepad_view_selection_timeout_destroy);
+
+ return TRUE;
+ }
+ else if (event->type == GDK_2BUTTON_PRESS) /* todo, button 1 en pos x coords */
+ {
+ /* get the iter under the cursor */
+ gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (view), &iter,
+ event->x + textview->xoffset, event->y + textview->yoffset);
+
+ /* try to select a whole word or space */
+ if (mousepad_view_selection_word_range (&iter, &start_iter, &end_iter))
{
- /* whether this is going to be a multiple selection */
- if (view->flags != 0)
- MOUSEPAD_SET_FLAG (view->flags, MULTIPLE);
+ /* get buffer */
+ buffer = mousepad_view_get_buffer (view);
+
+ /* add to normal selection or multiple selection */
+ if (event->state & GDK_CONTROL_MASK)
+ {
+ /* make it a multiple selection when there is already something selected */
+ if (view->flags != 0)
+ MOUSEPAD_SET_FLAG (view->flags, MULTIPLE);
- /* add the word under the cursor to the selection */
- mousepad_view_selection_add_word (view);
+ /* add to the list */
+ mousepad_view_selection_add_marks (view, &start_iter, &end_iter);
+
+ /* redraw */
+ mousepad_view_selection_draw (view, FALSE, FALSE);
+
+ /* set the cursor at the end of the word */
+ gtk_text_buffer_place_cursor (buffer, &end_iter);
+ }
+ else
+ {
+ /* select range */
+ gtk_text_buffer_select_range (buffer, &start_iter, &end_iter);
+ }
}
return TRUE;
@@ -631,6 +664,46 @@ mousepad_view_button_release_event (GtkWidget *widget,
/**
* Selection Functions
**/
+static gboolean
+mousepad_view_selection_word_range (const GtkTextIter *iter,
+ GtkTextIter *range_start,
+ GtkTextIter *range_end)
+{
+ /* init iters */
+ *range_start = *range_end = *iter;
+
+ /* get the iter character */
+ if (!mousepad_util_iter_inside_word (iter))
+ {
+ /* walk back and forward to select as much spaces as possible */
+ if (!mousepad_util_iter_forward_text_start (range_end))
+ return FALSE;
+
+ if (!mousepad_util_iter_backward_text_start (range_start))
+ return FALSE;
+ }
+ else
+ {
+ /* return false when we could not find a word start */
+ if (!mousepad_util_iter_backward_word_start (range_start))
+ return FALSE;
+
+ /* return false when we could not find a word end */
+ if (!mousepad_util_iter_forward_word_end (range_end))
+ return FALSE;
+ }
+
+ /* sort iters */
+ gtk_text_iter_order (range_start, range_end);
+
+ /* when the iters are not equal and the origional iter is in the range, we succeeded */
+ return (!gtk_text_iter_equal (range_start, range_end)
+ && gtk_text_iter_compare (iter, range_start) >= 0
+ && gtk_text_iter_compare (iter, range_end) <= 0);
+}
+
+
+
static void
mousepad_view_selection_key_press_event (MousepadView *view,
GdkEventKey *event,
@@ -711,11 +784,10 @@ mousepad_view_selection_key_press_event (MousepadView *view,
li = li->next;
}
+ /* TODO content */
+
/* end user action */
gtk_text_buffer_end_user_action (buffer);
-
- /* update selection status */
- mousepad_view_selection_emit_has_selection (view, has_content);
}
@@ -753,11 +825,11 @@ mousepad_view_selection_delete_content (MousepadView *view)
gtk_text_buffer_delete (buffer, &start_iter, &end_iter);
}
+ /* set the selection length to zerro */
+ view->selection_length = 0;
+
/* end user action */
gtk_text_buffer_end_user_action (buffer);
-
- /* update selection status */
- mousepad_view_selection_emit_has_selection (view, FALSE);
}
@@ -796,46 +868,8 @@ mousepad_view_selection_destroy (MousepadView *view)
/* reset status */
view->flags = 0;
- /* update selection status */
- mousepad_view_selection_emit_has_selection (view, FALSE);
-}
-
-
-
-static void
-mousepad_view_selection_add_word (MousepadView *view)
-{
- GtkTextBuffer *buffer;
- GtkTextIter start_iter, end_iter;
-
- /* get buffer */
- buffer = mousepad_view_get_buffer (view);
-
- /* get the iter at the start coordinate */
- gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (view), &start_iter, view->selection_start_x, view->selection_start_y);
-
- /* move the iter to the start of the word */
- while (!gtk_text_iter_starts_word (&start_iter))
- if (!gtk_text_iter_backward_char (&start_iter))
- break;
-
- /* set end iter */
- end_iter = start_iter;
-
- /* walk forward to end of the word */
- while (!gtk_text_iter_ends_word (&end_iter))
- if (!gtk_text_iter_forward_char (&end_iter))
- break;
-
- /* add the section when the iters are not equal */
- if (!gtk_text_iter_equal (&start_iter, &end_iter))
- {
- /* add to the list */
- mousepad_view_selection_add_marks (view, &start_iter, &end_iter);
-
- /* redraw */
- mousepad_view_selection_draw (view, FALSE, FALSE);
- }
+ /* set selection length to zerro */
+ view->selection_length = 0;
}
@@ -885,7 +919,7 @@ mousepad_view_selection_add_marks (MousepadView *view,
GSList *li, *lnext;
gboolean is_start = FALSE;
gboolean handled_start = FALSE;
- gint compare;
+ gint compare, length;
_mousepad_return_if_fail (view->marks == NULL || g_slist_length (view->marks) % 2 == 0);
@@ -895,6 +929,12 @@ mousepad_view_selection_add_marks (MousepadView *view,
/* get buffer */
buffer = mousepad_view_get_buffer (view);
+ /* calculate length of selection */
+ length = gtk_text_iter_get_line_offset (end_iter) - gtk_text_iter_get_line_offset (start_iter);
+
+ /* add to selection length */
+ view->selection_length += length;
+
/* create marks */
start_mark = gtk_text_buffer_create_mark (buffer, NULL, start_iter, TRUE);
end_mark = gtk_text_buffer_create_mark (buffer, NULL, end_iter, FALSE);
@@ -983,12 +1023,13 @@ mousepad_view_selection_add_marks (MousepadView *view,
static void
mousepad_view_selection_draw (MousepadView *view,
- gboolean draw_rectangles,
+ gboolean draw_cursors,
gboolean add_marks)
{
GtkTextBuffer *buffer;
GtkTextView *textview = GTK_TEXT_VIEW (view);
GtkTextIter start_iter, end_iter;
+ gint line_x, line_y;
gint y, y_begin, y_height, y_end;
gboolean has_content = FALSE;
GdkRectangle rect;
@@ -1024,16 +1065,19 @@ mousepad_view_selection_draw (MousepadView *view,
/* next element in the list */
li = li->next;
- if (draw_rectangles)
+ if (draw_cursors)
{
/* get the iter location and size */
gtk_text_view_get_iter_location (textview, &start_iter, &rect);
- /* draw a thin retangle in front of the iter */
- gdk_draw_rectangle (GDK_DRAWABLE (window),
- GTK_WIDGET (view)->style->base_gc[GTK_STATE_SELECTED],
- TRUE, rect.x - textview->xoffset, rect.y - textview->yoffset,
- MOUSEPAD_VIEW_RECT_WIDTH, rect.height);
+ /* calculate line coordinates */
+ line_x = rect.x - textview->xoffset;
+ line_y = rect.y - textview->yoffset;
+
+ /* draw a line in front of the iter */
+ gdk_draw_line (GDK_DRAWABLE (window),
+ GTK_WIDGET (view)->style->text_gc[GTK_STATE_NORMAL],
+ line_x, line_y, line_x, line_y + rect.height - 1);
}
else
{
@@ -1076,16 +1120,19 @@ mousepad_view_selection_draw (MousepadView *view,
gtk_text_view_get_iter_at_location (textview, &start_iter, view->selection_start_x, y);
gtk_text_view_get_iter_at_location (textview, &end_iter, view->selection_end_x, y);
- if (draw_rectangles)
+ if (draw_cursors)
{
/* get the iter location and size */
gtk_text_view_get_iter_location (textview, &end_iter, &rect);
- /* draw a thin retangle in front of the iter */
- gdk_draw_rectangle (GDK_DRAWABLE (window),
- GTK_WIDGET (view)->style->base_gc[GTK_STATE_SELECTED],
- TRUE, rect.x - textview->xoffset, rect.y - textview->yoffset,
- MOUSEPAD_VIEW_RECT_WIDTH, rect.height);
+ /* calculate line cooridinates */
+ line_x = rect.x - textview->xoffset;
+ line_y = rect.y - textview->yoffset;
+
+ /* draw a line in front of the iter */
+ gdk_draw_line (GDK_DRAWABLE (window),
+ GTK_WIDGET (view)->style->text_gc[GTK_STATE_NORMAL],
+ line_x, line_y, line_x, line_y + rect.height - 1);
}
else if (!gtk_text_iter_equal (&start_iter, &end_iter))
{
@@ -1109,50 +1156,25 @@ mousepad_view_selection_draw (MousepadView *view,
mousepad_view_selection_add_marks (view, &start_iter, &end_iter);
}
}
+
+ /* update selection status */
+ g_object_notify (G_OBJECT (buffer), "cursor-position");
}
/* update status when marks have been added */
if (add_marks && has_content && MOUSEPAD_HAS_FLAG (view->flags, MULTIPLE))
mousepad_view_selection_cleanup_equal_marks (view);
+ if (has_content)
+ MOUSEPAD_SET_FLAG (view->flags, HAS_CONTENT);
+ else
+ MOUSEPAD_UNSET_FLAG (view->flags, HAS_CONTENT);
+
/* there is something in the list, prevent 0 flag */
if (view->marks != NULL)
MOUSEPAD_SET_FLAG (view->flags, HAS_SELECTION);
- /* update selection status */
- mousepad_view_selection_emit_has_selection (view, has_content);
-}
-
-
-
-static void
-mousepad_view_selection_emit_has_selection (MousepadView *view,
- gboolean has_content)
-{
- GtkTextBuffer *buffer;
-
- /* jump when there is not selection */
- if (view->flags == 0)
- goto emit_has_selection;
-
- /* check if we need to emit */
- if (has_content != MOUSEPAD_HAS_FLAG (view->flags, HAS_CONTENT))
- {
- /* update flag */
- if (has_content)
- MOUSEPAD_SET_FLAG (view->flags, HAS_CONTENT);
- else
- MOUSEPAD_UNSET_FLAG (view->flags, HAS_CONTENT);
-
- /* label */
- emit_has_selection:
-
- /* get the buffer */
- buffer = mousepad_view_get_buffer (view);
- buffer->has_selection = has_content;
- g_object_notify (G_OBJECT (buffer), "has-selection");
- }
}
@@ -1505,6 +1527,59 @@ mousepad_view_put_cursor_on_screen (MousepadView *view)
static void
+mousepad_view_transpose_multi_selection (GtkTextBuffer *buffer,
+ MousepadView *view)
+{
+ GSList *li, *ls;
+ GSList *strings = NULL;
+ GtkTextIter start_iter, end_iter;
+
+ _mousepad_return_if_fail (MOUSEPAD_IS_VIEW (view));
+
+ /* get the strings and delete the existing strings */
+ for (li = view->marks; li != NULL; li = li->next)
+ {
+ /* get the iters */
+ gtk_text_buffer_get_iter_at_mark (buffer, &start_iter, li->data);
+ li = li->next;
+ gtk_text_buffer_get_iter_at_mark (buffer, &end_iter, li->data);
+
+ /* prepend the text between the iters to an internal list */
+ strings = g_slist_prepend (strings, gtk_text_buffer_get_slice (buffer, &start_iter, &end_iter, FALSE));
+
+ /* delete the content */
+ gtk_text_buffer_delete (buffer, &start_iter, &end_iter);
+ }
+
+ /* insert the strings in reversed order */
+ for (li = view->marks, ls = strings; li != NULL && ls != NULL; li = li->next, ls = ls->next)
+ {
+ /* get the end iter */
+ gtk_text_buffer_get_iter_at_mark (buffer, &end_iter, li->next->data);
+
+ /* insert the string */
+ gtk_text_buffer_insert (buffer, &end_iter, ls->data, -1);
+
+ /* get the start iter */
+ gtk_text_buffer_get_iter_at_mark (buffer, &start_iter, li->data);
+
+ /* apply tag */
+ gtk_text_buffer_apply_tag (buffer, view->selection_tag, &start_iter, &end_iter);
+
+ /* free string */
+ g_free (ls->data);
+
+ /* next iter */
+ li = li->next;
+ }
+
+ /* free list */
+ g_slist_free (strings);
+}
+
+
+
+static void
mousepad_view_transpose_range (GtkTextBuffer *buffer,
GtkTextIter *start_iter,
GtkTextIter *end_iter)
@@ -1601,68 +1676,78 @@ mousepad_view_transpose_lines (GtkTextBuffer *buffer,
gtk_text_buffer_get_iter_at_line (buffer, start_iter, start_line);
}
-
-
static void
mousepad_view_transpose_words (GtkTextBuffer *buffer,
GtkTextIter *iter)
{
- GtkTextIter start_one, end_one, end_two;
- gchar *word_left, *word_right, *word_space;
-
- /* move the iter to the start of first word */
- gtk_text_iter_backward_word_start (iter);
- start_one = *iter;
- if (!gtk_text_iter_starts_word (iter))
+ GtkTextMark *left_mark, *right_mark;
+ GtkTextIter start_left, end_left, start_right, end_right;
+ gchar *word_left, *word_right;
+ gboolean restore_cursor;
+
+ /* left word end */
+ end_left = *iter;
+ if (!mousepad_util_iter_backward_text_start (&end_left))
return;
- /* move to end of first word */
- gtk_text_iter_forward_word_end (iter);
- end_one = *iter;
- if (!gtk_text_iter_ends_word (iter))
+ /* left word start */
+ start_left = end_left;
+ if (!mousepad_util_iter_backward_word_start (&start_left))
return;
- /* move to end of second word */
- gtk_text_iter_forward_word_end (iter);
- end_two = *iter;
- if (!gtk_text_iter_ends_word (iter))
+ /* right word start */
+ start_right = *iter;
+ if (!mousepad_util_iter_forward_text_start (&start_right))
return;
- /* move to start of second word */
- gtk_text_iter_backward_word_start (iter);
- if (!gtk_text_iter_starts_word (iter))
+ /* right word end */
+ end_right = start_right;
+ if (!mousepad_util_iter_forward_word_end (&end_right))
return;
- /* only do this on the same line */
- if (gtk_text_iter_get_line (&start_one) != gtk_text_iter_get_line (&end_two))
- return;
+ /* check if we selected something usefull */
+ if (gtk_text_iter_get_line (&start_left) == gtk_text_iter_get_line (&end_right)
+ && !gtk_text_iter_equal (&start_left, &end_left)
+ && !gtk_text_iter_equal (&start_right, &end_right)
+ && !gtk_text_iter_equal (&end_left, &start_right))
+ {
+ /* get the words */
+ word_left = gtk_text_buffer_get_slice (buffer, &start_left, &end_left, FALSE);
+ word_right = gtk_text_buffer_get_slice (buffer, &start_right, &end_right, FALSE);
- /* get the three parts */
- word_left = gtk_text_buffer_get_slice (buffer, &start_one, &end_one, FALSE);
- word_space = gtk_text_buffer_get_slice (buffer, &end_one, iter, FALSE);
- word_right = gtk_text_buffer_get_slice (buffer, iter, &end_two, FALSE);
+ /* check if we need to restore the cursor afterwards */
+ restore_cursor = gtk_text_iter_equal (iter, &start_right);
- /* build string */
- gtk_text_buffer_delete (buffer, &start_one, &end_two);
- *iter = end_two;
+ /* insert marks at the start and end of the right word */
+ left_mark = gtk_text_buffer_create_mark (buffer, NULL, &start_right, TRUE);
+ right_mark = gtk_text_buffer_create_mark (buffer, NULL, &end_right, FALSE);
- /* insert right word */
- gtk_text_buffer_insert (buffer, iter, word_right, -1);
- g_free (word_right);
+ /* delete the left word and insert the right word there */
+ gtk_text_buffer_delete (buffer, &start_left, &end_left);
+ gtk_text_buffer_insert (buffer, &start_left, word_right, -1);
+ g_free (word_right);
- /* insert space */
- gtk_text_buffer_insert (buffer, iter, word_space, -1);
- g_free (word_space);
+ /* restore the right word iters */
+ gtk_text_buffer_get_iter_at_mark (buffer, &start_right, left_mark);
+ gtk_text_buffer_get_iter_at_mark (buffer, &end_right, right_mark);
- /* insert left word */
- gtk_text_buffer_insert (buffer, iter, word_left, -1);
- g_free (word_left);
+ /* delete the right words and insert the left word there */
+ gtk_text_buffer_delete (buffer, &start_right, &end_right);
+ gtk_text_buffer_insert (buffer, &end_right, word_left, -1);
+ g_free (word_left);
- /* return valid iter */
- gtk_text_iter_backward_word_start (iter);
+ /* restore the cursor if needed */
+ if (restore_cursor)
+ {
+ /* restore the iter from the left mark (left gravity) */
+ gtk_text_buffer_get_iter_at_mark (buffer, &start_right, left_mark);
+ gtk_text_buffer_place_cursor (buffer, &start_right);
+ }
- /* place cursor */
- gtk_text_buffer_place_cursor (buffer, iter);
+ /* cleanup the marks */
+ gtk_text_buffer_delete_mark (buffer, left_mark);
+ gtk_text_buffer_delete_mark (buffer, right_mark);
+ }
}
@@ -1683,7 +1768,8 @@ mousepad_view_transpose (MousepadView *view)
if (view->flags != 0)
{
-
+ /* transpose a multi selection */
+ mousepad_view_transpose_multi_selection (buffer, view);
}
else if (gtk_text_buffer_get_selection_bounds (buffer, &sel_start, &sel_end))
{
@@ -1722,7 +1808,7 @@ mousepad_view_transpose (MousepadView *view)
if (gtk_text_iter_forward_line (&sel_end))
mousepad_view_transpose_lines (buffer, &sel_start, &sel_end);
}
- else if (gtk_text_iter_inside_word (&sel_start) && !gtk_text_iter_starts_word (&sel_start))
+ else if (mousepad_util_iter_inside_word (&sel_start))
{
/* reverse the characters before and after the cursor */
if (gtk_text_iter_backward_char (&sel_start) && gtk_text_iter_forward_char (&sel_end))
@@ -1748,7 +1834,7 @@ mousepad_view_clipboard_cut (MousepadView *view)
GtkTextBuffer *buffer;
_mousepad_return_if_fail (MOUSEPAD_IS_VIEW (view));
- _mousepad_return_if_fail (mousepad_view_get_has_selection (view));
+ _mousepad_return_if_fail (mousepad_view_get_selection_length (view) > 0);
/* get the clipboard */
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (view), GDK_SELECTION_CLIPBOARD);
@@ -1786,7 +1872,7 @@ mousepad_view_clipboard_copy (MousepadView *view)
GtkTextBuffer *buffer;
_mousepad_return_if_fail (MOUSEPAD_IS_VIEW (view));
- _mousepad_return_if_fail (mousepad_view_get_has_selection (view));
+ _mousepad_return_if_fail (mousepad_view_get_selection_length (view) > 0);
/* get the clipboard */
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (view), GDK_SELECTION_CLIPBOARD);
@@ -1909,7 +1995,7 @@ mousepad_view_delete_selection (MousepadView *view)
GtkTextBuffer *buffer;
_mousepad_return_if_fail (MOUSEPAD_IS_VIEW (view));
- _mousepad_return_if_fail (mousepad_view_get_has_selection (view));
+ _mousepad_return_if_fail (mousepad_view_get_selection_length (view) > 0);
if (view->flags != 0)
{
@@ -2038,21 +2124,31 @@ mousepad_view_set_insert_spaces (MousepadView *view,
gboolean
-mousepad_view_get_has_selection (MousepadView *view)
+mousepad_view_get_selection_length (MousepadView *view)
{
GtkTextBuffer *buffer;
+ GtkTextIter sel_start, sel_end;
+ gint sel_length = 0;
_mousepad_return_val_if_fail (MOUSEPAD_IS_VIEW (view), FALSE);
- /* we have a vertical selection */
- if (view->flags != 0)
- return TRUE;
-
/* get the text buffer */
buffer = mousepad_view_get_buffer (view);
- /* normal selection */
- return gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL);
+ /* we have a vertical selection */
+ if (view->flags != 0)
+ {
+ /* get the selection count from the selection draw function */
+ sel_length = view->selection_length;
+ }
+ else if (gtk_text_buffer_get_selection_bounds (buffer, &sel_start, &sel_end))
+ {
+ /* calculate the selection length from the iter offset (absolute) */
+ sel_length = ABS (gtk_text_iter_get_offset (&sel_end) - gtk_text_iter_get_offset (&sel_start));
+ }
+
+ /* return length */
+ return sel_length;
}
diff --git a/mousepad/mousepad-view.h b/mousepad/mousepad-view.h
index 8a1933f..7623fc3 100644
--- a/mousepad/mousepad-view.h
+++ b/mousepad/mousepad-view.h
@@ -60,7 +60,7 @@ void mousepad_view_set_tab_size (MousepadView *view
void mousepad_view_set_insert_spaces (MousepadView *view,
gboolean insert_spaces);
-gboolean mousepad_view_get_has_selection (MousepadView *view);
+gint mousepad_view_get_selection_length (MousepadView *view);
gboolean mousepad_view_get_line_numbers (MousepadView *view);
diff --git a/mousepad/mousepad-window.c b/mousepad/mousepad-window.c
index e68914c..504ce43 100644
--- a/mousepad/mousepad-window.c
+++ b/mousepad/mousepad-window.c
@@ -139,15 +139,13 @@ static GtkNotebook *mousepad_window_notebook_create_window (GtkNotebo
/* document signals */
static void mousepad_window_modified_changed (MousepadWindow *window);
static void mousepad_window_cursor_changed (MousepadDocument *document,
- guint line,
- guint column,
+ gint line,
+ gint column,
+ gint selection,
MousepadWindow *window);
static void mousepad_window_overwrite_changed (MousepadDocument *document,
gboolean overwrite,
MousepadWindow *window);
-static void mousepad_window_selection_changed (MousepadDocument *document,
- gboolean selected,
- MousepadWindow *window);
static void mousepad_window_can_undo (MousepadWindow *window,
gboolean can_undo);
static void mousepad_window_can_redo (MousepadWindow *window,
@@ -329,8 +327,8 @@ struct _MousepadWindow
static const GtkActionEntry action_entries[] =
{
{ "file-menu", NULL, N_("_File"), NULL, NULL, NULL, },
- { "new-tab", "tab-new", N_("New Documen_t"), "<control>T", N_("Create a new document"), G_CALLBACK (mousepad_window_action_open_new_tab), },
- { "new-window", "window-new", N_("_New Window"), "<control>N", N_("Create a new document in a new window"), G_CALLBACK (mousepad_window_action_open_new_window), },
+ { "new-tab", "tab-new", N_("New Documen_t"), "<control>N", N_("Create a new document"), G_CALLBACK (mousepad_window_action_open_new_tab), },
+ { "new-window", "window-new", N_("_New Window"), "<shift><control>N", N_("Create a new document in a new window"), G_CALLBACK (mousepad_window_action_open_new_window), },
{ "open-file", GTK_STOCK_OPEN, N_("_Open File"), NULL, N_("Open a file"), G_CALLBACK (mousepad_window_action_open_file), },
{ "recent-menu", NULL, N_("Open _Recent"), NULL, NULL, NULL, },
{ "no-recent-items", NULL, N_("No items found"), NULL, NULL, NULL, },
@@ -352,7 +350,7 @@ static const GtkActionEntry action_entries[] =
{ "paste-column", GTK_STOCK_PASTE, N_("Paste _Column"), "<control><shift>V", N_("Paste the clipboard text in a clumn"), G_CALLBACK (mousepad_window_action_paste_column), },
{ "delete", GTK_STOCK_DELETE, NULL, NULL, N_("Delete the selected text"), G_CALLBACK (mousepad_window_action_delete), },
{ "select-all", GTK_STOCK_SELECT_ALL, NULL, NULL, N_("Select the entire document"), G_CALLBACK (mousepad_window_action_select_all), },
- { "transpose", NULL, N_("_Transpose"), NULL, N_("Reverse the order of something"), G_CALLBACK (mousepad_window_action_transpose), },
+ { "transpose", NULL, N_("_Transpose"), "<control>T", N_("Reverse the order of something"), G_CALLBACK (mousepad_window_action_transpose), },
{ "search-menu", NULL, N_("_Search"), NULL, NULL, NULL, },
{ "find", GTK_STOCK_FIND, NULL, NULL, N_("Search for text"), G_CALLBACK (mousepad_window_action_find), },
@@ -1227,7 +1225,6 @@ mousepad_window_notebook_added (GtkNotebook *notebook,
/* connect signals to the document for this window */
g_signal_connect (G_OBJECT (page), "close-tab", G_CALLBACK (mousepad_window_button_close_tab), window);
- g_signal_connect (G_OBJECT (page), "selection-changed", G_CALLBACK (mousepad_window_selection_changed), window);
g_signal_connect (G_OBJECT (page), "cursor-changed", G_CALLBACK (mousepad_window_cursor_changed), window);
g_signal_connect (G_OBJECT (page), "overwrite-changed", G_CALLBACK (mousepad_window_overwrite_changed), window);
g_signal_connect (G_OBJECT (page), "drag-data-received", G_CALLBACK (mousepad_window_drag_data_received), window);
@@ -1273,7 +1270,6 @@ mousepad_window_notebook_removed (GtkNotebook *notebook,
/* disconnect the old document signals */
g_signal_handlers_disconnect_by_func (G_OBJECT (page), mousepad_window_button_close_tab, window);
- g_signal_handlers_disconnect_by_func (G_OBJECT (page), mousepad_window_selection_changed, window);
g_signal_handlers_disconnect_by_func (G_OBJECT (page), mousepad_window_cursor_changed, window);
g_signal_handlers_disconnect_by_func (G_OBJECT (page), mousepad_window_overwrite_changed, window);
g_signal_handlers_disconnect_by_func (G_OBJECT (page), mousepad_window_drag_data_received, window);
@@ -1446,16 +1442,33 @@ mousepad_window_modified_changed (MousepadWindow *window)
static void
mousepad_window_cursor_changed (MousepadDocument *document,
- guint line,
- guint column,
+ gint line,
+ gint column,
+ gint selection,
MousepadWindow *window)
{
+ GtkAction *action;
+ gboolean has_selection;
+
_mousepad_return_if_fail (MOUSEPAD_IS_WINDOW (window));
_mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
- /* set the new statusbar position */
+ /* set the new statusbar cursor position and selection length */
if (window->statusbar)
- mousepad_statusbar_set_cursor_position (MOUSEPAD_STATUSBAR (window->statusbar), line, column);
+ mousepad_statusbar_set_cursor_position (MOUSEPAD_STATUSBAR (window->statusbar), line, column, selection);
+
+ /* whether we have a selection */
+ has_selection = (selection > 0);
+
+ /* update actions */
+ action = gtk_action_group_get_action (window->action_group, "cut");
+ gtk_action_set_sensitive (action, has_selection);
+
+ action = gtk_action_group_get_action (window->action_group, "copy");
+ gtk_action_set_sensitive (action, has_selection);
+
+ action = gtk_action_group_get_action (window->action_group, "delete");
+ gtk_action_set_sensitive (action, has_selection);
}
@@ -1476,25 +1489,6 @@ mousepad_window_overwrite_changed (MousepadDocument *document,
static void
-mousepad_window_selection_changed (MousepadDocument *document,
- gboolean selected,
- MousepadWindow *window)
-{
- GtkAction *action;
-
- action = gtk_action_group_get_action (window->action_group, "cut");
- gtk_action_set_sensitive (action, selected);
-
- action = gtk_action_group_get_action (window->action_group, "copy");
- gtk_action_set_sensitive (action, selected);
-
- action = gtk_action_group_get_action (window->action_group, "delete");
- gtk_action_set_sensitive (action, selected);
-}
-
-
-
-static void
mousepad_window_can_undo (MousepadWindow *window,
gboolean can_undo)
{
@@ -1708,7 +1702,6 @@ mousepad_window_update_actions (MousepadWindow *window)
gboolean cycle_tabs;
gint n_pages;
gint page_num;
- gboolean has_selection;
gboolean active;
_mousepad_return_if_fail (MOUSEPAD_IS_WINDOW (window));
@@ -1769,10 +1762,6 @@ mousepad_window_update_actions (MousepadWindow *window)
mousepad_window_can_undo (window, mousepad_undo_can_undo (document->undo));
mousepad_window_can_redo (window, mousepad_undo_can_redo (document->undo));
- /* set the sensitivity of the selection actions */
- has_selection = mousepad_view_get_has_selection (document->textview);
- mousepad_window_selection_changed (document, has_selection, window);
-
/* active this tab in the go menu */
action = g_object_get_data (G_OBJECT (document), I_("navigation-menu-action"));
if (G_LIKELY (action != NULL))
@@ -2579,6 +2568,9 @@ mousepad_window_action_save_file (GtkAction *action,
/* save the document */
succeed = mousepad_file_save (document->file, &error);
+ /* update the window title */
+ mousepad_window_set_title (window);
+
if (G_UNLIKELY (succeed == FALSE))
{
/* show the warning */
More information about the Xfce4-commits
mailing list