// closing brace for a right-open macro (like \over)
cursor.remove();
advance(parent.parent());
+ frames.pop();
}
else
{
{
TNode m = doc.createC(name, nextId++);
cursor.replace(m);
+
+ cout << "ecco tutti i token del pattern della entry inserita" << endl;
+ for (unsigned i = 0; i < entry.pattern.size(); i++)
+ cout << entry.pattern[i].value << endl;
+
if (entry.leftOpen && entry.rightOpen)
{
assert(entry.pattern.empty());
if (parent.isG())
{
frames.push(Frame(entry));
+ cout << "do_control: valore di pos del frame inserito " << frames.top().pos << endl;
if (entry.paramDelimited(0))
{
TNode g = doc.createG();
void
TPushParser::gdelete_prev()
{
- // if in this function, the prev of cursor does exist, also the parent and we want a graphical deleting
+ // if in this function, the prev of cursor does exist, also the parent and we want a graphical deleting.
+
+ assert(cursor.prev());
+ assert(cursor.parent());
+
TNode prev = cursor.prev();
if (prev.is("i") || prev.is("o") || prev.is("n"))
{
// the control below is designed to handle the case in which val have more than one unicode character
DOM::UCS4String ucs4val(prev.element().getAttribute("val"));
- if (ucs4val.length() <= 1)
+ if ((ucs4val.length() <= 1) || prev.element().hasAttribute("name"))
{
cursor.remove();
prev.replace(cursor);
+
+ if (cursor.parent().isC())
+ {
+ // in this case we have removed an element of a MACRO.
+ // we can assert that this element was a non delimited argument
+ assert(!frames.empty());
+ Frame& frame = frames.top();
+ assert(frame.pos > 0);
+
+ frame.pos--;
+ }
}
else
{
{
cursor.remove();
prev.append(cursor);
- do_gdelete();
+ gdelete_prev();
} // end of if (prev.is("sp") || prev.is("sb"))
else if (prev.isG())
{
}
else if (prev.isC())
{
-// cursor.remove();
-// prev.append(cursor);
-// do_gdelete();
+ const TDictionary::Entry& entry = dictionary.find(prev["name"]);
+
+ // i start to remove a MACRO. The frame associated to this MACRO was
+ // popped from the stack (i think). So, i re-push the frame in the stack,
+ // but the pos member should be set correctly
+ cout << "gdelete_prev: i have to start to delete a MACRO" << endl;
+
+ // if the control element is leftOpen and rightOpen, the cursor should be placed after
+ // the last child of the control element's last child
+ if (entry.rightOpen)
+ {
+ cout << "gdelte_prev(): i have to delete a control rightOpen, so i push an element in the stack" << endl;
+ Frame frame(entry);
+ frames.push(frame);
+
+ cursor.remove();
+ prev.last().append(cursor);
+ do_gdelete();
+ }
+ else if (entry.leftOpen)
+ {
+ cout << "gdelete_prev: i have to delete a control element with leftOpen" << endl;
+ assert(prev.first());
+ assert(prev.first().isG());
+ assert(prev.first() == prev.last());
+ TNode g = prev.first();
+ g.remove();
+ prev.replace(g.first(), TNode());
+ }
+ else if (!entry.pattern.empty())
+ {
+ // we have to start removing a MACRO which accepts arguments.
+ // a MACRO without child does not exist
+
+ cout << "gdelete_prev: i have to remove a MACRO with argument" << endl;
+
+ assert(prev.size() >= 1);
+
+ if (prev.last().isG() && !prev.last().hasId())
+ {
+ // this means that the last child of the MACRO is a phantom group,
+ // which in turn means that it is a delimited argument
+ // so we have to ideally remove this delimiter
+ cursor.remove();
+ prev.last().append(cursor);
+ // i have to push a frame with a correct value of pos
+ Frame frame(entry);
+ frame.pos = entry.pattern.size() - 2;
+ frames.push(frame);
+ }
+ else
+ {
+ // in this case, the last child of the MACRO is
+ // an argument which is NOT delimited, so i try to
+ // remove it
+ cout << "gdelete_prev: i try to remove the last argumet of the MACRO" << endl;
+ cursor.remove();
+ prev.append(cursor); // now prev is the cursor's parent
+
+ Frame frame(entry);
+ frame.pos = entry.pattern.size();
+ frames.push(frame);
+
+ gdelete_prev();
+
+ }
+ }
}
else
{
} // end of method
+void
+TPushParser::rgreplace_futher(void)
+{
+ // this function MUST only be invoked, when the cursor
+ // is the only child of a group with id. This function
+ // replace the group with the cursor. But if the new parent
+ // is a group with id and the cursor is the only child of the
+ // group, the new parent is replaced...and so on.
+ // r stands for recursive, g stands for graphical
+ assert(cursor.parent());
+ assert(cursor.parent().isG() && cursor.parent().hasId());
+
+ TNode parent = cursor.parent();
+
+ while (parent.isG() && parent.hasId() && (parent.first() == cursor))
+ {
+ parent.replace(cursor);
+ parent = cursor.parent();
+ }
+
+ if (parent.isC())
+ {
+ // in this case we have removed a MACRO's child.
+ // I can assert that this MACRO accepts arguments.
+ assert(!frames.empty());
+ Frame& frame = frames.top();
+ assert(frame.pos > 0);
+ frame.pos--;
+ }
+}
+
void
TPushParser::do_gdelete()
{
// this function operates a graphical deleting
+ //if (!frames.empty())
+ // cout << "do_gdelete: c'e' un frame aperto e il suo pos vale: " << frames.top().pos << endl;
+
TNode parent = cursor.parent();
// if no parent, do nothing
{
// i try to delete the preceding element
gdelete_prev();
-
- // if gdelete_prev has removed all parent's child, and the group has Id, it should be removed.
- // this control should be re-done on the new parent and so on.
- while ((parent.first() == cursor) && parent.isG() && parent.hasId())
- {
- cursor.remove();
- parent.replace(cursor);
- parent = cursor.parent();
- }
+
+ if ((parent.first() == cursor) && parent.isG() && parent.hasId())
+ rgreplace_futher();
+
}
else // no previous node is present
{
- if (!parent.parent().is("math"))
+ // if here, we are in a gruop whose only child is the cursor.
+
+ if (!parent.hasId())
{
- cursor.remove();
- parent.replace(cursor);
-
- // if the new parent is a group with Id, it should be removed
- if (cursor.parent().isG() && cursor.parent().hasId()) do_gdelete();
+ // the parent is a phantom group
+ assert(parent.parent());
+ if (!parent.parent().is("math"))
+ {
+ TNode gfuther = parent.parent();
+
+ // if the grand futher is a group with Id, it should be removed,
+ // but i don't know if it will never occur...
+ if (gfuther.isG() && gfuther.hasId())
+ {
+ cursor.remove();
+ parent.replace(cursor);
+
+ // re-start the process
+ do_gdelete();
+ }
+ else if (gfuther.isC())
+ {
+ // the grand futher is a control element: since the parent is a phantom group,
+ // the TML tree should be in a inconsistent state (once removed the parent).
+
+ // being here means that there is a frame in the stack
+ assert(!frames.empty());
+ cout << "do_gdelete: i have to remove a phantom group whuch is a child of a MACRO" << endl;
+ Frame& frame = frames.top();
+ if (frame.entry.leftOpen && frame.entry.rightOpen)
+ {
+ // in this case, the cursor is in the second and last child
+ // of the MACRO. We can assert that the grand futher has two
+ // children. which are both phantom group
+ cout << "do_gdelete: the MACRO is leftOpen and rigthOpen" << endl;
+ assert(gfuther.size() == 2);
+ assert((gfuther.last() == parent) && (gfuther.first().isG() && !gfuther.first().hasId()));
+ assert(frame.pos == 0);
+
+ TNode ggfuther = gfuther.parent();
+ assert(ggfuther);
+ cursor.remove();
+ parent.remove();
+ // i have to replace the gfuther with the elements of its first child
+ gfuther.replace(gfuther.first().first(), TNode());
+ cout << "do_gdelete: i have removed the control element, and replaced it with its first child" << endl;
+ ggfuther.append(cursor);
+ cout << "do_gdelete: cursor appended to the grand grand futher" << endl;
+
+ // now we have the situation preceding the insertion of the MACRO leftOpen and rightOpen
+ // this MACRO no longer exists.
+ frames.pop();
+ }
+ else if (frame.entry.rightOpen)
+ {
+ // the user has inserted a MACRO rightOpen. Since the cursor is the
+ // only child of the MACRO, the user want to remove it.
+ // We can assert that cursor's parent is the only child of the MACRO
+ cout << "do_gdelete: the MACRO is rightOpen only" << endl;
+ assert(gfuther.size() == 1);
+ assert(frame.pos == 0); // i think this assert has no sense
+
+ cursor.remove();
+ parent.remove();
+ gfuther.replace(cursor);
+
+ // now we have the situation preceding the MACRO rightOpen, so i have to pop the frame
+ frames.pop();
+ }
+ else if (frame.entry.leftOpen)
+ {
+ // it' s an unpredicted situation
+ cout << "it's a bad situation, maybe handlable, but unpredicted" << endl;
+ }
+ else if (!frame.entry.pattern.empty())
+ {
+ // the MACRO (the cursor's grand futher) accepts arguments.
+ // we have to control if the cursor's uncle does exist.
+
+ if (parent.prev())
+ {
+ // in this case, we can assert that frame in the stack has
+ // pos greater than 0
+ assert(frame.pos > 0);
+
+ // cursor's uncle does exist. we have to control
+ // its nature (is it a phantom group?)
+ TNode uncle = parent.prev();
+ if (uncle.isG() && !uncle.hasId())
+ {
+ // the cursor's parent is a phantom group, so it was a
+ // delimited argument of the MACRO and the corrisponding
+ // delimeter is inserted. So, the action of deleting means
+ // removing this delimeter
+ cursor.remove();
+ parent.remove();
+ uncle.append(cursor);
+ frame.pos -= 2;
+ }
+ else
+ {
+ // the uncle was a NOT delimited argument. So i try to
+ // remove it
+ cursor.remove();
+ parent.replace(cursor);
+
+ parent = cursor.parent(); // i update the parent (it should be the MACRO)
+ assert(parent.isC());
+
+ gdelete_prev();
+
+ }
+ }
+ else
+ {
+ // cursor's parent is the only child of the MACRO, which accepts arguments
+ // i can assert that frame.pos == 0.
+ // In this case i can replace the MACRO with the cursor
+ assert(frame.pos == 0);
+
+ cursor.remove();
+ parent.remove();
+ gfuther.replace(cursor);
+
+ frames.pop();
+ }
+
+ }
+ }
+ }
+ else // the grand futher is math
+ {
+ // nothing to do...i think
+ assert(frames.empty());
+ }
}
else
- {
- // nothing to do...i think
+ {
+ // the parent is a group with id and has no elements other than cursor
+ // so we replace it with the cursor.
+ rgreplace_futher();
+
+ // i have to re-start the process, because it' a graphical delete
+ do_gdelete();
}
}
}
else if (parent.isC())
{
- // i think i have to implement different behaviors based on the attribute name and/or left-open
- }
- else if (parent.is("sp") || parent.is("sb"))
- {
- // being here means that a prev MUST exist
-
+ // being here means that there is an open frame for the control element
+ // and this element is closed at either side (no leftOpen no rightOpen)
+ // and the MACRO was waiting for a non delimited argument, so
+ // we can assert that frame.entry.pattern.size() >= 1
+ assert(!frames.empty());
+ Frame& frame = frames.top();
+
+ assert(frame.entry.pattern.size() >= 1);
+
+ cout << "do_gdelete: frames.top().pos = " << frames.top().pos << endl;
+
TNode prev = cursor.prev();
- if (!prev) cout << "qualcosa non va" << endl;
+ if (!prev)
+ {
+ // in this case we can replace the MACRO with the cursor
+ // and pop the stack and we can assert that frame.pos == 0
+ assert(frame.pos == 0);
+ cursor.remove(); // it should not be necessary, but i'm not shure
+ parent.replace(cursor);
+ frames.pop();
+ }
else
{
- if (parent.first().next() == cursor) // there's only an element preceding the cursor
+ // in this case the cursor has a preceding element
+ // and there are differnt things based on the nature
+ // of the prev: if it's a phantom group do something,
+ // else do something else
+ if (prev.isG() && !prev.hasId())
{
+ // in this case we have to append the cursor
+ // to the prev and decrement frame.pos of two units
+ // because the prev is a delimited argument and the
+ // delimiter is inserted. So we ideally remove this delimiter
cursor.remove();
- parent.replace(prev);
- prev.parent().append(cursor);
+ prev.append(cursor);
+ frame.pos -=2;
}
- else // there are two elements preceding the cursor
+ else
{
+ // the prev is an non delimited argument, so we try to
+ // remove it.
gdelete_prev();
}
}
}
+ else if (parent.is("sp") || parent.is("sb"))
+ {
+ // being here means that a prev MUST exist
+ // and that there is only an element preceding the cursor.
+ // A sp's (or sb's) MUST NOT be a MACRO
+
+ assert(parent.size() == 2);
+ assert(parent.parent() && !parent.parent().isC());
+
+ TNode prev = cursor.prev();
+ cursor.remove();
+ if (prev.isG() && !prev.hasId() && (prev.size() == 0))
+ {
+ prev.remove();
+ parent.replace(cursor);
+
+ // now, cursor should be the only parent's child
+ assert(cursor.parent().size() == 1);
+
+ if (cursor.parent().isG() && cursor.parent().hasId()) rgreplace_futher();
+ }
+ else
+ {
+ assert(prev.hasId());
+ parent.replace(prev);
+ prev.parent().append(cursor);
+ // now prev should have a preceding element
+ assert(cursor.parent().size() > 1);
+ }
+ }
else
{
// not handled: no control for tables, ...
}
else
{
- // do nothing ??
+ // the cursro has no parent!!!
+ // do nothing?
+ // emit an error? and if we want to emit an error, in which way?
}
} // end of method
TPushParser::push(const TToken& token)
{
cerr << "TPushParser::push " << token.value << " (cat: " << token.category << ")" << endl;
+
+ if (token.category == TToken::GDELETE)
+ {
+ cout << "push: i have to process a token with category member = GDELETE" << endl;
+ process(token);
+ }
+ else
+ {
+
TNode parent = cursor.parent();
// If the cursor has no parent then it is detached from the editing
// tree, which means this token will be ignored
+
if (parent)
// If the parent is a phantom group and the grand-parent is a
// control sequence, there are two cases:
// or a fixed token
Frame& frame = frames.top();
assert(frame.pos < frame.entry.pattern.size());
+
+ cout << "push: il valore di pos del frame inserito prima e': " << frame.pos << endl;
if (frame.entry.pattern[frame.pos].category == TToken::PARAMETER)
{
// As by the TeX parsing rules of undelimited parameters,
cout << "ignored token" << endl;
}
+ } // this end corresponds to the else of the if (token.category == GDELETE)
+
if (listener) listener->callback(doc);
+
+ if (frames.empty()) cout << "stack vuoto" << endl;
+ else cout << "stack non vuoto" << endl;
}
void
-
+/*
+ * Copyright (C) 2000, Luca Padovani <luca.padovani@cs.unibo.it>.
+ *
+ * This file is part of GtkMathView, a Gtk widget for MathML.
+ *
+ * GtkMathView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * GtkMathView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GtkMathView; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For details, see the GtkMathView World-Wide-Web page,
+ * http://cs.unibo.it/~lpadovan/mml-widget, or send a mail to
+ * <luca.padovani@cs.unibo.it>
+ */
+
+#include <config.h>
#include <stdio.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
static GtkWidget* status_bar;
static GtkMenuItem* anti_aliasing_item;
static GtkMenuItem* transparency_item;
-static GtkMenuItem* font_size_item;
static GdkCursor* normal_cursor;
static GdkCursor* link_cursor;
static gchar* doc_name = NULL;
static GdomeElement* root_selected = NULL;
-static GdomeElement* first_selected = NULL;
-static GdomeElement* last_selected = NULL;
-static GdomeElement* cursor = NULL;
-static gboolean selecting = FALSE;
-static gboolean button_pressed = FALSE;
static guint statusbar_context;
-static guint edit_timeout_id;
-static GdomeElement* cursor_ptr = NULL;
-static gboolean cursor_active = FALSE;
-
static void create_widget_set(gpointer);
static GtkWidget* get_main_menu(void);
-static void options_selection_mode(GtkWidget*, guint);
-static void options_font_size(GtkWidget*, guint);
+static void file_open(GtkWidget*, gpointer);
+static void file_re_open(GtkWidget*, gpointer);
+static void file_close(GtkWidget*, gpointer);
+static void options_font_manager(GtkWidget*, FontManagerId);
+static void options_set_font_size(GtkWidget*, gpointer);
+static void options_change_font_size(GtkWidget*, gboolean);
static void options_verbosity(GtkWidget*, guint);
static void options_anti_aliasing(GtkWidget*, gpointer);
static void options_transparency(GtkWidget*, gpointer);
-static void edit_delete_selection(GtkWidget*, gpointer);
-static void edit_select_parent(GtkWidget*, gpointer);
+static void selection_delete(GtkWidget*, gpointer);
+static void selection_parent(GtkWidget*, gpointer);
+static void selection_reset(GtkWidget*, gpointer);
static void help_about(GtkWidget*, gpointer);
-extern int edit_timeout(gpointer);
-extern void push_char(gpointer, gchar);
-
static GtkItemFactoryEntry menu_items[] = {
{ "/_File", NULL, NULL, 0, "<Branch>" },
+ { "/File/_Open...", "<control>O", file_open, 0, NULL },
+ { "/File/_Reopen", NULL, file_re_open, 0, NULL },
+ { "/File/_Close", "<control>W", file_close, 0, NULL },
+ { "/File/sep1", NULL, NULL, 0, "<Separator>" },
{ "/File/_Quit", "<control>Q", gtk_main_quit, 0, NULL },
- { "/_Edit", NULL, NULL, 0, "<Branch>" },
- { "/Edit/Delete Selection", NULL, edit_delete_selection, 0, NULL },
- { "/Edit/Select Parent", NULL, edit_select_parent, 0, NULL },
+ { "/_Selection", NULL, NULL, 0, "<Branch>" },
+ { "/Selection/Reset", NULL, selection_reset, 0, NULL },
+ { "/Selection/Delete", NULL, selection_delete, 0, NULL },
+ { "/Selection/Select Parent", NULL, selection_parent, 0, NULL },
{ "/_Options", NULL, NULL, 0, "<Branch>" },
- { "/Options/_Selection Mode", NULL, NULL, 0, "<Branch>" },
- { "/Options/Selection Mode/_Structure", NULL, options_selection_mode, 0, "<RadioItem>" },
- { "/Options/Selection Mode/_Linear", NULL, options_selection_mode, 1, "/Options/Selection Mode/Structure" },
{ "/Options/Default _Font Size", NULL, NULL, 0, "<Branch>" },
- { "/Options/Default Font Size/8pt", NULL, options_font_size, 8, "<RadioItem>" },
- { "/Options/Default Font Size/10pt", NULL, options_font_size, 10, "/Options/Default Font Size/8pt" },
- { "/Options/Default Font Size/12pt", NULL, options_font_size, 12, "/Options/Default Font Size/8pt" },
- { "/Options/Default Font Size/14pt", NULL, options_font_size, 14, "/Options/Default Font Size/8pt" },
- { "/Options/Default Font Size/18pt", NULL, options_font_size, 18, "/Options/Default Font Size/8pt" },
- { "/Options/Default Font Size/24pt", NULL, options_font_size, 24, "/Options/Default Font Size/8pt" },
- { "/Options/Default Font Size/48pt", NULL, options_font_size, 48, "/Options/Default Font Size/8pt" },
- { "/Options/Default Font Size/72pt", NULL, options_font_size, 72, "/Options/Default Font Size/8pt" },
+ { "/Options/Default Font Size/Set...", NULL, options_set_font_size, 0, NULL },
+ { "/Options/Default Font Size/sep1", NULL, NULL, 0, "<Separator>" },
+ { "/Options/Default Font Size/Larger", NULL, options_change_font_size, TRUE, NULL },
+ { "/Options/Default Font Size/Smaller", NULL, options_change_font_size, FALSE, NULL },
+ { "/Options/Font Manager", NULL, NULL, 0, "<Branch>" },
+ { "/Options/Font Manager/_GTK", NULL, options_font_manager, FONT_MANAGER_GTK, "<RadioItem>" },
+ { "/Options/Font Manager/_Type 1", NULL, options_font_manager, FONT_MANAGER_T1, "/Options/Font Manager/GTK" },
{ "/Options/Verbosity", NULL, NULL, 0, "<Branch>" },
{ "/Options/Verbosity/_Errors", NULL, options_verbosity, 0, "<RadioItem>" },
{ "/Options/Verbosity/_Warnings", NULL, options_verbosity, 1, "/Options/Verbosity/Errors" },
g_free(msg);
}
-static void
-cursor_off()
-{
- if (cursor_active)
- {
- cursor_active = FALSE;
- if (cursor_ptr != NULL &&
- gtk_math_view_is_selected(main_area, cursor_ptr))
- gtk_math_view_reset_selection(main_area, cursor_ptr);
- }
-}
-
-static void
-cursor_on()
-{
- if (!cursor_active)
- {
- cursor_active = FALSE;
- if (cursor_ptr != NULL &&
- !gtk_math_view_is_selected(main_area, cursor_ptr))
- gtk_math_view_set_selection(main_area, cursor_ptr);
- cursor_active = TRUE;
- }
-}
-
void
GUI_init(int* argc, char*** argv, char* title, guint width, guint height, gpointer context)
{
void
GUI_uninit()
{
- gtk_timeout_remove(edit_timeout_id);
}
int
return 0;
}
-int
-GUI_load_uri(const char* uri)
-{
- GtkMathView* math_view;
-
- g_return_val_if_fail(uri != NULL, -1);
- g_return_val_if_fail(main_area != NULL, -1);
- g_return_val_if_fail(GTK_IS_MATH_VIEW(main_area), -1);
-
- math_view = GTK_MATH_VIEW(main_area);
-
- if (!gtk_math_view_load_uri(math_view, uri)) return -1;
-
- return 0;
-}
-
void
GUI_freeze()
{
gtk_main();
}
+void
+GUI_set_font_manager(FontManagerId id)
+{
+ gboolean t1;
+ GtkMathView* math_view;
+
+ g_return_if_fail(id != FONT_MANAGER_UNKNOWN);
+ g_return_if_fail(main_area != NULL);
+ g_return_if_fail(GTK_IS_MATH_VIEW(main_area));
+
+ t1 = id == FONT_MANAGER_T1;
+
+ math_view = GTK_MATH_VIEW(main_area);
+
+ gtk_math_view_freeze(math_view);
+
+ if (id != gtk_math_view_get_font_manager_type(math_view))
+ gtk_math_view_set_font_manager_type(math_view, id);
+
+ gtk_widget_set_sensitive(anti_aliasing_item, t1);
+ gtk_widget_set_sensitive(transparency_item, t1);
+
+ if (t1)
+ {
+ gtk_math_view_set_anti_aliasing(math_view, GTK_CHECK_MENU_ITEM(anti_aliasing_item)->active);
+ gtk_math_view_set_transparency(math_view, GTK_CHECK_MENU_ITEM(transparency_item)->active);
+ }
+
+ gtk_math_view_thaw(math_view);
+}
+
static void
-options_selection_mode(GtkWidget* widget, guint mode)
+store_filename(GtkFileSelection* selector, GtkWidget* user_data)
{
+ gchar* selected_filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION(user_data));
+ if (selected_filename != NULL)
+ GUI_load_document(selected_filename);
}
static void
-options_font_size(GtkWidget* widget, guint size)
+file_close(GtkWidget* widget, gpointer data)
{
- GtkMathView* math_view;
+ GUI_unload_document();
+}
- g_return_if_fail(main_area != NULL);
- g_return_if_fail(GTK_IS_MATH_VIEW(main_area));
+static void
+file_re_open(GtkWidget* widget, gpointer data)
+{
+ if (doc_name != NULL) {
+ GUI_load_document(doc_name);
+ }
+}
- math_view = GTK_MATH_VIEW(main_area);
+static void
+file_open(GtkWidget* widget, gpointer data)
+{
+ GtkWidget* fs = gtk_file_selection_new("Open File");
+
+ gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(fs)->ok_button),
+ "clicked", GTK_SIGNAL_FUNC (store_filename), (gpointer) fs);
+
+ /* Ensure that the dialog box is destroyed when the user clicks a button. */
+
+ gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(fs)->ok_button),
+ "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
+ (gpointer) fs);
+
+ gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(fs)->cancel_button),
+ "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
+ (gpointer) fs);
+
+ /* Display that dialog */
+
+ gtk_widget_show (fs);
+}
- gtk_math_view_set_font_size(math_view, size);
+static void
+options_font_manager(GtkWidget* widget, FontManagerId id)
+{
+ g_return_if_fail(id != FONT_MANAGER_UNKNOWN);
+ GUI_set_font_manager(id);
}
static void
}
static void
-edit_delete_selection(GtkWidget* widget, gpointer data)
+selection_delete(GtkWidget* widget, gpointer data)
{
if (root_selected != NULL)
{
}
static void
-edit_select_parent(GtkWidget* widget, gpointer data)
+selection_parent(GtkWidget* widget, gpointer data)
{
if (root_selected != NULL)
{
GdomeException exc = 0;
- GdomeElement* parent = gdome_cast_el(gdome_n_parentNode(root_selected, &exc));
+ GdomeElement* parent = gdome_n_parentNode(root_selected, &exc);
g_assert(exc == 0);
gdome_el_unref(root_selected, &exc);
g_assert(exc == 0);
}
}
+static void
+selection_reset(GtkWidget* widget, gpointer data)
+{
+ if (root_selected != NULL)
+ {
+ GdomeException exc = 0;
+ gtk_math_view_reset_selection(GTK_MATH_VIEW(main_area), root_selected);
+ gdome_el_unref(root_selected, &exc);
+ g_assert(exc == 0);
+ root_selected = NULL;
+ }
+}
+
static void
help_about(GtkWidget* widget, gpointer data)
{
GtkWidget* ok;
dialog = gtk_dialog_new();
- label = gtk_label_new("\n MathML Viewer \n Copyright (C) 2000-2002 Luca Padovani \n");
+ label = gtk_label_new("\n MathML Viewer \n Copyright (C) 2000-2003 Luca Padovani \n");
ok = gtk_button_new_with_label("Close");
gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
gtk_widget_show_all (dialog);
}
-#if 0
-#if defined(HAVE_GMETADOM)
static void
-element_changed(GtkMathView* math_view, GdomeElement* node)
+change_default_font_size(GtkSpinButton* widget, GtkSpinButton* spin)
{
- GdomeException exc;
- GdomeDOMString* name;
- GdomeDOMString* ns_uri;
-
- g_return_if_fail(math_view != NULL);
- g_return_if_fail(GTK_IS_MATH_VIEW(math_view));
-
- name = gdome_str_mkref("href");
- ns_uri = gdome_str_mkref(XLINK_NS_URI);
-
- while (node != NULL && !gdome_el_hasAttributeNS(node, ns_uri, name, &exc))
- node = gdome_cast_el(gdome_el_parentNode(node, &exc));
-
- if (node != NULL && gdome_el_hasAttributeNS(node, ns_uri, name, &exc))
- gdk_window_set_cursor(GTK_WIDGET(math_view)->window, link_cursor);
- else
- gdk_window_set_cursor(GTK_WIDGET(math_view)->window, normal_cursor);
-
- gdome_str_unref(name);
- gdome_str_unref(ns_uri);
+ g_return_if_fail(spin != NULL);
+ gtk_math_view_set_font_size( GTK_MATH_VIEW(main_area), gtk_spin_button_get_value_as_int(spin));
}
-#endif
static void
-#if defined(HAVE_GMETADOM)
-action_changed(GtkMathView* math_view, GdomeElement* node)
-#endif
+options_change_font_size(GtkWidget* widget, gboolean larger)
{
- g_return_if_fail(math_view != NULL);
- g_return_if_fail(GTK_IS_MATH_VIEW(math_view));
+ gfloat size = gtk_math_view_get_font_size (GTK_MATH_VIEW(main_area));
+ if (larger) size = size / 0.71;
+ else size = size * 0.71;
+ if (size < 1) size = 1;
+ gtk_math_view_set_font_size (GTK_MATH_VIEW(main_area), (gint) size + 0.5);
}
static void
-#if defined(HAVE_GMETADOM)
-selection_changed(GtkMathView* math_view, GdomeElement* node)
-#endif
+options_set_font_size(GtkWidget* widget, gpointer data)
{
- g_return_if_fail(math_view != NULL);
- g_return_if_fail(GTK_IS_MATH_VIEW(math_view));
- gtk_math_view_set_selection(math_view, node);
+ GtkWidget* dialog;
+ GtkWidget* label;
+ GtkWidget* ok;
+ GtkWidget* cancel;
+ GtkWidget* spin;
+ GtkObject* adj;
+
+ dialog = gtk_dialog_new();
+ label = gtk_label_new("Default font size:");
+ ok = gtk_button_new_with_label("OK");
+ cancel = gtk_button_new_with_label("Cancel");
- cursor_off();
- cursor_ptr = node;
- cursor_on();
+ adj = gtk_adjustment_new (gtk_math_view_get_font_size (GTK_MATH_VIEW(main_area)), 1, 200, 1, 1, 1);
+ spin = gtk_spin_button_new (GTK_ADJUSTMENT(adj), 1, 0);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spin), TRUE);
+
+ gtk_signal_connect (GTK_OBJECT (ok), "clicked",
+ GTK_SIGNAL_FUNC (change_default_font_size), (gpointer) spin);
+
+ gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
+ GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
+
+ gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
+ GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
+
+ gtk_signal_connect_object (GTK_OBJECT (cancel), "clicked",
+ GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
+
+ gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), 5);
+
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area), ok);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area), cancel);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), label);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), spin);
+
+ gtk_widget_show_all (dialog);
}
+#if 0
#if defined(HAVE_GMETADOM)
static void
-clicked(GtkMathView* math_view, gpointer user_data)
+element_changed(GtkMathView* math_view, GdomeElement* elem)
{
- GdomeException exc;
- GdomeDOMString* name;
- GdomeDOMString* ns_uri;
- GdomeElement* p;
+ GdomeDOMString* link = NULL;
g_return_if_fail(math_view != NULL);
+ g_return_if_fail(GTK_IS_MATH_VIEW(math_view));
- name = gdome_str_mkref("href");
- ns_uri = gdome_str_mkref(XLINK_NS_URI);
-
- p = gtk_math_view_get_element(math_view);
- while (p != NULL && !gdome_el_hasAttributeNS(p, ns_uri, name, &exc))
- p = gdome_cast_el(gdome_el_parentNode(p, &exc));
+/* printf("pointer is on %p\n", elem); */
- if (p != NULL) {
- GdomeDOMString* href = gdome_el_getAttributeNS(p, ns_uri, name, &exc);
- g_assert(href != NULL);
+ link = find_hyperlink(elem, XLINK_NS_URI, "href");
+ if (link != NULL)
+ gdk_window_set_cursor(GTK_WIDGET(math_view)->window, link_cursor);
+ else
+ gdk_window_set_cursor(GTK_WIDGET(math_view)->window, normal_cursor);
- GUI_load_document(href->str);
- gdome_str_unref(href);
- } else if (gtk_math_view_get_action(math_view) != NULL)
- gtk_math_view_action_toggle(math_view);
+ if (link != NULL)
+ gdome_str_unref(link);
}
#endif
#endif
-static gint
-button_press_event(GtkWidget* widget,
- GdkEventButton* event,
- GtkMathView* math_view)
+static void
+selection_changed(GtkMathView* math_view, GdomeElement* first, GdomeElement* last)
{
- g_return_val_if_fail(event != NULL, FALSE);
- g_return_val_if_fail(math_view != NULL, FALSE);
-
- if (event->button == 1)
- {
- GdomeException exc;
+ g_return_if_fail(math_view != NULL);
+ g_return_if_fail(GTK_IS_MATH_VIEW(math_view));
+ g_return_if_fail(first != NULL);
+
+/* printf("selection changed %p %p\n", first, last); */
- cursor_off();
+ if (last != NULL)
+ {
+ GdomeException exc = 0;
if (root_selected != NULL)
{
- gtk_math_view_reset_selection(math_view, root_selected);
gdome_el_unref(root_selected, &exc);
g_assert(exc == 0);
- root_selected = NULL;
- }
-
- if (first_selected != NULL)
- {
- gdome_el_unref(first_selected, &exc);
- g_assert(exc == 0);
}
- if (last_selected != NULL)
- {
- gdome_el_unref(last_selected, &exc);
- g_assert(exc == 0);
- last_selected = NULL;
- }
-
- first_selected = gtk_math_view_get_element_at(math_view, event->x, event->y);
- button_pressed = TRUE;
- selecting = FALSE;
+ root_selected = find_common_ancestor(first, last);
+/* printf("selecting root %p\n", first, last, root_selected); */
+ gtk_math_view_set_selection(math_view, root_selected);
+ g_assert(exc == 0);
}
-
- return FALSE;
}
-static gint
-motion_notify_event(GtkWidget* widget,
- GdkEventMotion* event,
- GtkMathView* math_view)
+#if 0
+#if defined(HAVE_GMETADOM)
+static void
+clicked(GtkMathView* math_view, GdomeElement* elem)
{
- g_return_val_if_fail(event != NULL, FALSE);
- g_return_val_if_fail(math_view != NULL, FALSE);
-
- if (button_pressed && first_selected != NULL)
- {
- GdomeException exc;
- GdomeElement* el = gtk_math_view_get_element_at(math_view, event->x, event->y);
- GdomeElement* root;
-
- selecting = TRUE;
+ GdomeException exc;
+ GdomeDOMString* name;
+ GdomeDOMString* ns_uri;
+ GdomeElement* p;
- if (el != NULL && el != last_selected)
- {
- if (last_selected != NULL)
- {
- gdome_el_unref(last_selected, &exc);
- g_assert(exc == 0);
- }
+ g_return_if_fail(math_view != NULL);
- last_selected = el;
- }
+ /* printf("clicked on %p\n", elem); */
- if (last_selected != NULL)
+ if (elem != NULL)
+ {
+ GdomeElement* action;
+ GdomeDOMString* href = find_hyperlink(elem, XLINK_NS_URI, "href");
+ if (href != NULL)
{
- root = find_common_ancestor(first_selected, last_selected);
- g_assert(root != NULL);
-
- if (root != root_selected)
- {
- gtk_math_view_freeze(math_view);
- if (root_selected != NULL)
- {
- gtk_math_view_reset_selection(math_view, root_selected);
- gdome_el_unref(root_selected, &exc);
- g_assert(exc == 0);
- }
- root_selected = root;
- gtk_math_view_set_selection(math_view, root_selected);
- gtk_math_view_thaw(math_view);
- }
- else
- {
- gdome_el_unref(root, &exc);
- g_assert(exc == 0);
- }
+/* printf("hyperlink %s\n", href->str); */
+ gdome_str_unref(href);
}
- }
-
- return FALSE;
-}
-static gint
-button_release_event(GtkWidget* widget,
- GdkEventButton* event,
- GtkMathView* math_view)
-{
- g_return_val_if_fail(event != NULL, FALSE);
- g_return_val_if_fail(math_view != NULL, FALSE);
-
- if (event->button == 1)
- {
- if (!selecting)
+ action = find_self_or_ancestor(elem, MATHML_NS_URI, "maction");
+/* printf("action? %p\n", action); */
+ if (action != NULL)
{
- cursor_ptr = first_selected;
- cursor_on();
+ gtk_math_view_freeze(math_view);
+ action_toggle(action);
+ gtk_math_view_thaw(math_view);
+ gdome_el_unref(action, &exc);
+ g_assert(exc == 0);
}
-
- button_pressed = FALSE;
- selecting = FALSE;
}
-
- return FALSE;
}
+#endif
+#endif
static gboolean
key_press_event(gpointer context,
(gpointer) main_area);
#endif
- gtk_signal_connect_object (GTK_OBJECT (main_area),
- "button_press_event", GTK_SIGNAL_FUNC(button_press_event),
- (gpointer) main_area);
-
- gtk_signal_connect_object (GTK_OBJECT (main_area),
- "button_release_event", GTK_SIGNAL_FUNC(button_release_event),
- (gpointer) main_area);
-
- gtk_signal_connect_object (GTK_OBJECT (main_area),
- "motion_notify_event", GTK_SIGNAL_FUNC(motion_notify_event),
- (gpointer) main_area);
-
gtk_signal_connect_object (GTK_OBJECT(window),
"key_press_event", GTK_SIGNAL_FUNC(key_press_event),
context);
if (gtk_math_view_get_anti_aliasing(GTK_MATH_VIEW(main_area)))
gtk_menu_item_activate(anti_aliasing_item);
+}
+
+#if 0
+static void
+create_widget_set()
+{
+ GtkWidget* main_vbox;
+ GtkWidget* menu_bar;
+
+ main_vbox = gtk_vbox_new(FALSE, 1);
+ gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
+ gtk_container_add(GTK_CONTAINER(window), main_vbox);
+ gtk_widget_show(main_vbox);
+
+ menu_bar = get_main_menu();
+ gtk_box_pack_start(GTK_BOX(main_vbox), menu_bar, FALSE, TRUE, 0);
+ gtk_widget_show(menu_bar);
- gtk_menu_item_activate(font_size_item);
+ main_area = gtk_math_view_new(NULL, NULL);
+ gtk_widget_show(main_area);
+
+ gtk_signal_connect_object (GTK_OBJECT (main_area),
+ "selection_changed", GTK_SIGNAL_FUNC (selection_changed),
+ (gpointer) main_area);
+
+ gtk_signal_connect_object (GTK_OBJECT (main_area),
+ "element_changed", GTK_SIGNAL_FUNC (element_changed),
+ (gpointer) main_area);
+
+ gtk_signal_connect_object (GTK_OBJECT (main_area),
+ "clicked", GTK_SIGNAL_FUNC(clicked),
+ (gpointer) main_area);
+
+ gtk_widget_add_events(GTK_WIDGET(main_area),
+ GDK_BUTTON_PRESS_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_POINTER_MOTION_MASK);
+
+ scrolled_area = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_area),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+ gtk_widget_show(scrolled_area);
+ gtk_container_add(GTK_CONTAINER(scrolled_area), main_area);
+ gtk_box_pack_start(GTK_BOX(main_vbox), scrolled_area, TRUE, TRUE, 0);
+
+ status_bar = gtk_statusbar_new();
+ gtk_widget_show(status_bar);
+ gtk_box_pack_start(GTK_BOX(main_vbox), status_bar, FALSE, TRUE, 0);
+ statusbar_context = gtk_statusbar_get_context_id(GTK_STATUSBAR(status_bar), "filename");
+
+ gtk_widget_show(main_vbox);
+
+ if (gtk_math_view_get_anti_aliasing(GTK_MATH_VIEW(main_area)))
+ gtk_menu_item_activate(anti_aliasing_item);
}
+#endif
GtkWidget*
get_main_menu()
menu_item = gtk_item_factory_get_widget(item_factory, "/Options/Transparency");
transparency_item = GTK_MENU_ITEM(menu_item);
- /* !!!BEWARE!!! the default font size must be kept aligned with the definition
- * in math-engine-configuration.xml
- */
- menu_item = gtk_item_factory_get_widget(item_factory, "/Options/Default Font Size/12pt");
- font_size_item = GTK_MENU_ITEM(menu_item);
-
return gtk_item_factory_get_widget(item_factory, "<main>");
}