diff --git a/src/frontends/gtk/ChangeLog b/src/frontends/gtk/ChangeLog index de12548bc5..680bbafaf0 100644 --- a/src/frontends/gtk/ChangeLog +++ b/src/frontends/gtk/ChangeLog @@ -1,3 +1,8 @@ +2004-10-06 John Spray + + * The Spellchecker dialog + * Dialogs.C, GSpellchecker.C, GSpellchecker.h, Makefile.am + 2004-10-06 John Spray * GView.C (c-tor): get the layout engine working correctly by diff --git a/src/frontends/gtk/Dialogs.C b/src/frontends/gtk/Dialogs.C index 1d15cab602..83058457ac 100644 --- a/src/frontends/gtk/Dialogs.C +++ b/src/frontends/gtk/Dialogs.C @@ -83,7 +83,7 @@ #include "FormTabular.h" #include "FormTexinfo.h" #include "FormShowFile.h" -#include "FormSpellchecker.h" +#include "GSpellchecker.h" #include "GTableCreate.h" #include "GToc.h" #include "GUrl.h" @@ -479,8 +479,9 @@ Dialogs::DialogPtr Dialogs::build(string const & name) dialog->setView(new FormSendto(*dialog)); dialog->bc().bp(new OkApplyCancelPolicy); } else if (name == "spellchecker") { + dialog->bc().view(new GBC(dialog->bc())); dialog->setController(new ControlSpellchecker(*dialog)); - dialog->setView(new FormSpellchecker(*dialog)); + dialog->setView(new GSpellchecker(*dialog)); dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); } else if (name == "tabular") { dialog->setController(new ControlTabular(*dialog)); diff --git a/src/frontends/gtk/GSpellchecker.C b/src/frontends/gtk/GSpellchecker.C new file mode 100644 index 0000000000..815de850c2 --- /dev/null +++ b/src/frontends/gtk/GSpellchecker.C @@ -0,0 +1,184 @@ +/** + * \file GSpellchecker.C + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author John Spray + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "GSpellchecker.h" +#include "controllers/ControlSpellchecker.h" + +#include "ghelpers.h" + +#include "support/tostr.h" + +using std::string; + +namespace lyx { +namespace frontend { + +GSpellchecker::GSpellchecker(Dialog & parent) + : GViewCB + (parent, _("Spell-check document"), false) +{} + + +void GSpellchecker::doBuild() +{ + string const gladeName = findGladeFile("spellcheck"); + xml_ = Gnome::Glade::Xml::create(gladeName); + + Gtk::Button * button; + xml_->get_widget("Close", button); + setCancel(button); + + xml_->get_widget("Suggestions", suggestionsview_); + xml_->get_widget("Unknown", unknownentry_); + xml_->get_widget("Replacement", replacemententry_); + xml_->get_widget("Progress", progress_); + + listCols_.add(listCol_); + suggestionsstore_ = Gtk::ListStore::create(listCols_); + suggestionsview_->set_model(suggestionsstore_); + suggestionsview_->append_column("Suggestion", listCol_); + suggestionssel_ = suggestionsview_->get_selection(); + + // Single click in suggestion list + suggestionssel_->signal_changed().connect( + sigc::mem_fun(*this, &GSpellchecker::onSuggestionSelection)); + + // Double click in suggestion list + suggestionsview_->signal_row_activated().connect( + sigc::mem_fun(*this, &GSpellchecker::onSuggestionActivate)); + + // Because it's like a Replace button when double clicked + bcview().addReadOnly(suggestionsview_); + + xml_->get_widget("Replace", button); + bcview().addReadOnly(button); + button->signal_clicked().connect( + sigc::bind( + sigc::mem_fun(*this, &GSpellchecker::onReplace), false)); + + xml_->get_widget("ReplaceAll", button); + bcview().addReadOnly(button); + button->signal_clicked().connect( + sigc::bind( + sigc::mem_fun(*this, &GSpellchecker::onReplace), true)); + + xml_->get_widget("Ignore", ignorebutton_); + ignorebutton_->signal_clicked().connect( + sigc::mem_fun(*this, &GSpellchecker::onIgnore)); + + xml_->get_widget("IgnoreAll", button); + button->signal_clicked().connect( + sigc::mem_fun(*this, &GSpellchecker::onIgnoreAll)); + + xml_->get_widget("Add", button); + button->signal_clicked().connect( + sigc::mem_fun(*this, &GSpellchecker::onAdd)); +} + + +void GSpellchecker::show() +{ + if (!window()) { + build(); + } + bcview().refreshReadOnly(); + controller().check(); + if (!controller().getWord().empty()) + window()->show(); +} + +void GSpellchecker::partialUpdate(int s) +{ + ControlSpellchecker::State const state = + static_cast(s); + + if (state == ControlSpellchecker::SPELL_FOUND_WORD) { + string word = controller().getWord(); + Glib::ustring utfword = Glib::locale_to_utf8(word); + unknownentry_->set_text(utfword); + replacemententry_->set_text(utfword); + + // Get the list of suggestions + suggestionsstore_->clear(); + while (!(word = controller().getSuggestion()).empty()) { + utfword = Glib::locale_to_utf8(word); + (*suggestionsstore_->append())[listCol_] = utfword; + } + + if (readOnly()) + // In readonly docs the user must just be browsing through + ignorebutton_->grab_focus(); + else + // In general we expect the user to type their replacement + replacemententry_->grab_focus(); + } + + int const progress = controller().getProgress(); + if (progress != 0) { + progress_->set_fraction(float(progress)/100.0f); + progress_->set_text(tostr(progress) + "% " + _("checked")); + } +} + + +void GSpellchecker::onSuggestionActivate( + Gtk::TreeModel::Path const & path, + Gtk::TreeViewColumn * col) +{ + Glib::ustring const suggestion = + (*suggestionsstore_->get_iter(path))[listCol_]; + + if (!suggestion.empty()) + controller().replace(suggestion); +} + + +void GSpellchecker::onSuggestionSelection() +{ + Glib::ustring const suggestion = + (*suggestionssel_->get_selected())[listCol_]; + + if (!suggestion.empty()) + replacemententry_->set_text(suggestion); +} + + +void GSpellchecker::onIgnore() +{ + controller().check(); +} + + +void GSpellchecker::onIgnoreAll() +{ + controller().ignoreAll(); +} + + +void GSpellchecker::onAdd() +{ + controller().insert(); +} + + +void GSpellchecker::onReplace(bool const all) +{ + Glib::ustring const replacement = replacemententry_->get_text(); + if (all) + controller().replaceAll(replacement); + else + controller().replace(replacement); +} + + +} // namespace frontend +} // namespace lyx diff --git a/src/frontends/gtk/GSpellchecker.h b/src/frontends/gtk/GSpellchecker.h new file mode 100644 index 0000000000..c588c167ae --- /dev/null +++ b/src/frontends/gtk/GSpellchecker.h @@ -0,0 +1,71 @@ +// -*- C++ -*- +/** + * \file GSpellchecker.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author John Spray + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef GSPELLCHECKER_H +#define GSPELLCHECKER_H + +#include "GViewBase.h" + +namespace lyx { +namespace frontend { + +class ControlSpellchecker; + +/** This class provides a GTK+ implementation of the FormSpellchecker Dialog. + */ +class GSpellchecker + : public GViewCB { +public: + + GSpellchecker(Dialog &); +private: + // not needed. + virtual void apply() {} + // Build the dialog + virtual void doBuild(); + + virtual void update() {} + + virtual void show(); + + // Fill in unknown word, suggestions, progress from backend + virtual void partialUpdate(int); + + Glib::RefPtr suggestionsstore_; + Glib::RefPtr suggestionssel_; + + Gtk::TreeModelColumn listCol_; + Gtk::TreeModel::ColumnRecord listCols_; + + Gtk::TreeView * suggestionsview_; + Gtk::Entry * replacemententry_; + Gtk::Entry * unknownentry_; + Gtk::ProgressBar * progress_; + Gtk::Button * ignorebutton_; + + // Replace button + void onReplace(bool const all); + // Suggestion list single click + void onSuggestionSelection(); + // Suggestion list double click + void onSuggestionActivate(Gtk::TreeModel::Path const & path, Gtk::TreeViewColumn * col); + // Ignore button + void onIgnore(); + // Ignore All button + void onIgnoreAll(); + // Add button + void onAdd(); +}; + +} // namespace frontend +} // namespace lyx + +#endif // GSPELLCHECKER_H diff --git a/src/frontends/gtk/Makefile.am b/src/frontends/gtk/Makefile.am index 4c14451910..8b231db326 100644 --- a/src/frontends/gtk/Makefile.am +++ b/src/frontends/gtk/Makefile.am @@ -48,6 +48,8 @@ libgtk_la_SOURCES = \ GScreen.h \ GSearch.C \ GSearch.h \ + GSpellchecker.C \ + GSpellchecker.h \ GTableCreate.C \ GTableCreate.h \ GText.C \ @@ -120,7 +122,6 @@ xforms_objects = \ ../xforms/FormSendto.lo \ ../xforms/forms_gettext.lo \ ../xforms/FormShowFile.lo \ - ../xforms/FormSpellchecker.lo \ ../xforms/FormTabular.lo \ ../xforms/FormTexinfo.lo \ ../xforms/FormText.lo \ @@ -135,11 +136,3 @@ xforms_objects = \ ../xforms/xforms_helpers.lo \ ../xforms/xformsImage.lo \ ../xforms/xforms_resize.lo - -# ../xforms/Dialogs.lo -# ../xforms/FormFiledialog.lo -# ../xforms/FileDialog.lo -# ../xforms/FormAboutlyx.lo -# ../xforms/FormUrl.lo -# ../xforms/FormTabularCreate.lo -# ../xforms/FormMathsPanel.lo diff --git a/src/frontends/gtk/glade/spellcheck.glade b/src/frontends/gtk/glade/spellcheck.glade new file mode 100644 index 0000000000..e98c03283c --- /dev/null +++ b/src/frontends/gtk/glade/spellcheck.glade @@ -0,0 +1,607 @@ + + + + + + + 6 + Spell Check + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_CENTER_ON_PARENT + True + False + False + True + False + False + GDK_WINDOW_TYPE_HINT_DIALOG + GDK_GRAVITY_NORTH_WEST + False + + + + True + False + 0 + + + + True + GTK_BUTTONBOX_END + + + + True + True + True + gtk-close + True + GTK_RELIEF_NORMAL + True + -7 + + + + + 0 + False + True + GTK_PACK_END + + + + + + True + False + 0 + + + + True + False + 0 + + + + True + _Unknown word: + True + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + Unknown + + + 5 + False + False + + + + + + True + True + False + True + 0 + + True + * + False + + + 0 + False + False + + + + + + True + False + 0 + + + + True + Ignore unknown word + True + GTK_RELIEF_NORMAL + True + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-cancel + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + _Ignore + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + + + + 0 + False + False + GTK_PACK_END + + + + + + True + Accept unknown word as known in this session + True + GTK_RELIEF_NORMAL + True + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-cancel + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Ignore _All + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + + + + 6 + False + False + GTK_PACK_END + + + + + + True + Add unknown word to personal dictionary + True + gtk-add + True + GTK_RELIEF_NORMAL + True + + + 0 + False + False + GTK_PACK_END + + + + + 6 + True + True + + + + + + True + R_eplace with: + True + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + Replacement + + + 5 + False + False + + + + + + True + Type replacement word or select from list of suggestions + True + True + True + 0 + + True + * + False + + + 0 + False + False + + + + + + True + False + 0 + + + + + + + + True + Replace unknown word + True + GTK_RELIEF_NORMAL + True + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-spell-check + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + _Replace + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + + + + 0 + False + False + GTK_PACK_END + + + + + + True + Replace all instances of unknown word + True + GTK_RELIEF_NORMAL + True + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-spell-check + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Replace A_ll + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + + + + 6 + False + False + GTK_PACK_END + + + + + 6 + True + True + + + + + + True + Proportion of document checked + GTK_PROGRESS_LEFT_TO_RIGHT + 0 + 0.1 + + + 0 + False + False + + + + + 0 + False + True + + + + + + True + + + 5 + False + True + + + + + + True + False + 0 + + + + True + _Suggested Replacements: + True + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + Suggestions + + + 4 + False + False + + + + + + 3 + True + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + List of replacement suggestions from dictionary + True + False + False + False + True + + + + + 0 + True + True + + + + + 0 + True + True + + + + + 0 + False + True + + + + + + +