dnl FRONTEND_INCLUDES="${GNOME_FRONTEND_CFLAGS}"
dnl FRONTEND_LIBS="@XPM_LIB@ @XFORMS_LIB@ ${GNOME_FRONTEND_LIBS}"
dnl ;;
+ gtk)
+ XFORMS_DO_IT_ALL
+ PKG_CHECK_MODULES(GTK_FRONTEND, gtkmm-2.0 libglademm-2.0)
+ FRONTENDS_PROGS="$FRONTENDS_PROGS lyx-gtk\$(EXEEXT)"
+ FRONTENDS_SUBDIRS="$FRONTENDS_SUBDIRS xforms gtk"
+ RPM_FRONTEND="gtk"
+ RPM_FRONTEND_DEPS='gtkmm >= 2.2.0'
+ GTKMM_VERSION=`pkg-config --modversion gtkmm-2.0`
+ LIBGLADEMM_VERSION=`pkg-config --modversion libglademm-2.0`
+ FRONTEND_INFO=" libgtkmm version: ${GTKMM_VERSION}\n\
+ libglademm version: ${LIBGLADEMM_VERSION}\n"
+ ;;
+
qt)
QT_DO_IT_ALL
FRONTENDS_PROGS="$FRONTENDS_PROGS lyx-qt\$(EXEEXT)"
src/frontends/xforms/lyx_forms.h-tmp:src/frontends/xforms/lyx_forms.h.in \
src/frontends/xforms/lyx_xpm.h-tmp:src/frontends/xforms/lyx_xpm.h.in \
src/frontends/xforms/forms/Makefile \
+ src/frontends/gtk/Makefile \
+ src/frontends/gtk/glade/Makefile \
src/frontends/qt2/Makefile \
src/frontends/qt2/moc/Makefile \
src/frontends/qt2/ui/Makefile \
src/frontends/controllers/frnt_lang.C
src/frontends/controllers/helper_funcs.C
src/frontends/gnome/GLog.C
+src/frontends/gtk/Dialogs.C
+src/frontends/gtk/GBC.h
src/frontends/qt2/Alert_pimpl.C
src/frontends/qt2/BulletsModule.C
src/frontends/qt2/Dialogs.C
bin_PROGRAMS = lyx
noinst_PROGRAMS = $(FRONTENDS_PROGS)
-EXTRA_PROGRAMS = lyx-xforms lyx-qt
+EXTRA_PROGRAMS = lyx-xforms lyx-qt lyx-gtk
lyx_xforms_LDADD = $(lyx_OBJECTS) $(LYX_PRE_LIBS) \
frontends/xforms/libxforms.la $(LYX_POST_LIBS) $(OTHERLIBS)
frontends/qt2/libqt2.la $(LYX_POST_LIBS) $(OTHERLIBS)
lyx_qt_SOURCES = main.C
+lyx_gtk_LDADD = $(lyx_OBJECTS) $(LYX_PRE_LIBS) \
+ frontends/gtk/libgtk.la $(LYX_POST_LIBS) $(OTHERLIBS)
+lyx_gtk_SOURCES = main.C
+
lyx$(EXEEXT): $(FRONTENDS_PROGS)
rm -f $@
$(LN_S) $< $@
SUBDIRS = controllers $(FRONTENDS_SUBDIRS)
-DIST_SUBDIRS = controllers xforms qt2 gnome
+DIST_SUBDIRS = controllers xforms qt2 gnome gtk
noinst_LTLIBRARIES = libfrontends.la
--- /dev/null
+/**
+ * \file Alert_pimpl.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+
+#include "frontends/Alert.h"
+#include "frontends/Alert_pimpl.h"
+
+
+namespace {
+
+
+string translateShortcut(string const & str)
+{
+ string::size_type i = str.find_first_of("&");
+ if (i == string::npos || i == str.length() - 1)
+ return str;
+ string tstr = str;
+ tstr[i] = '_';
+ return tstr;
+}
+
+
+}
+
+
+void warning_pimpl(string const &, string const & message)
+{
+ Gtk::MessageDialog dlg(Glib::locale_to_utf8(message),
+ Gtk::MESSAGE_WARNING,
+ Gtk::BUTTONS_CLOSE, true, true);
+ dlg.run();
+}
+
+
+void error_pimpl(string const &, string const & message)
+{
+ Gtk::MessageDialog dlg(Glib::locale_to_utf8(message),
+ Gtk::MESSAGE_ERROR,
+ Gtk::BUTTONS_CLOSE, true, true);
+ dlg.run();
+}
+
+
+void information_pimpl(string const &, string const & message)
+{
+ Gtk::MessageDialog dlg(Glib::locale_to_utf8(message),
+ Gtk::MESSAGE_INFO,
+ Gtk::BUTTONS_CLOSE, true, true);
+ dlg.run();
+}
+
+
+int prompt_pimpl(string const &, string const & question,
+ int defaultButton, int /*escapeButton*/,
+ string const & b1, string const & b2, string const & b3)
+{
+ Glib::ustring gb1 = Glib::locale_to_utf8(translateShortcut(b1));
+ Glib::ustring gb2 = Glib::locale_to_utf8(translateShortcut(b2));
+ Glib::ustring gb3;
+ if (!b3.empty())
+ gb3 = Glib::locale_to_utf8(translateShortcut(b3));
+ Gtk::MessageDialog dlg(Glib::locale_to_utf8(question),
+ Gtk::MESSAGE_QUESTION,
+ Gtk::BUTTONS_NONE, true, true);
+ dlg.add_button(gb1, 0);
+ dlg.add_button(gb2, 1);
+ if (!b3.empty())
+ dlg.add_button(gb3, 2);
+ dlg.set_default_response(defaultButton);
+ return dlg.run();
+}
+
+
+std::pair<bool, string> const askForText_pimpl(string const & msg,
+ string const & dflt)
+{
+ Gtk::MessageDialog dlg(Glib::locale_to_utf8(msg),
+ Gtk::MESSAGE_QUESTION,
+ Gtk::BUTTONS_OK_CANCEL,
+ true, true);
+ Gtk::Entry entry;
+ entry.set_text(Glib::locale_to_utf8(dflt));
+ entry.set_position(-1);
+ entry.show();
+ dlg.get_vbox()->children().push_back(
+ Gtk::Box_Helpers::Element(entry));
+ int response = dlg.run();
+ if (response == Gtk::RESPONSE_OK) {
+ string str = Glib::locale_from_utf8(entry.get_text());
+ return std::make_pair<bool, string>(true, str);
+ }
+ else
+ return std::make_pair<bool, string>(false, string());
+}
--- /dev/null
+2003-9-2 hying_caritas@163.com
+
+ * initial release
--- /dev/null
+/**
+ * \file xforms/Dialogs.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Angus Leeming
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+
+#include "Dialogs.h"
+#include "Dialog.h"
+
+#include "Tooltips.h"
+
+#include "ControlAboutlyx.h"
+#include "ControlBibtex.h"
+#include "ControlBranch.h"
+#include "ControlChanges.h"
+#include "ControlCharacter.h"
+#include "ControlCitation.h"
+#include "ControlCommand.h"
+#include "ControlErrorList.h"
+#include "ControlERT.h"
+#include "ControlExternal.h"
+#include "ControlFloat.h"
+#include "ControlGraphics.h"
+#include "ControlInclude.h"
+#include "ControlLog.h"
+#include "ControlMath.h"
+#include "ControlMinipage.h"
+#include "ControlNote.h"
+#include "ControlParagraph.h"
+#include "ControlRef.h"
+#include "ControlShowFile.h"
+#include "ControlTabular.h"
+#include "ControlTabularCreate.h"
+#include "ControlTexinfo.h"
+#include "ControlToc.h"
+#include "ControlVCLog.h"
+#include "ControlWrap.h"
+
+#include "GAboutlyx.h"
+#include "GText.h"
+#include "FormBibitem.h"
+#include "FormBibtex.h"
+#include "FormBranch.h"
+#include "FormChanges.h"
+#include "FormCharacter.h"
+#include "FormCitation.h"
+#include "FormErrorList.h"
+#include "FormERT.h"
+#include "FormExternal.h"
+#include "FormFloat.h"
+#include "FormGraphics.h"
+#include "FormInclude.h"
+#include "FormLog.h"
+#include "FormMathsPanel.h"
+#include "FormMathsBitmap.h"
+#include "FormMathsDelim.h"
+#include "FormMathsMatrix.h"
+#include "FormMathsSpace.h"
+#include "FormMathsStyle.h"
+#include "FormMinipage.h"
+#include "FormNote.h"
+#include "FormParagraph.h"
+#include "FormRef.h"
+#include "FormTabular.h"
+#include "FormTexinfo.h"
+#include "FormShowFile.h"
+#include "FormTabularCreate.h"
+#include "FormToc.h"
+#include "FormUrl.h"
+#include "FormVCLog.h"
+#include "FormWrap.h"
+
+#ifdef HAVE_LIBAIKSAURUS
+#include "ControlThesaurus.h"
+#include "FormThesaurus.h"
+#endif
+
+#include "xformsBC.h"
+#include "ButtonController.h"
+
+#include "arrows.xbm"
+#include "bop.xbm"
+#include "brel.xbm"
+#include "deco.xbm"
+#include "dots.xbm"
+#include "greek.xbm"
+#include "misc.xbm"
+#include "varsz.xbm"
+
+#include "ams_misc.xbm"
+#include "ams_arrows.xbm"
+#include "ams_rel.xbm"
+#include "ams_nrel.xbm"
+#include "ams_ops.xbm"
+
+#include <vector>
+
+
+namespace {
+
+FormMathsBitmap * createFormBitmap(Dialog & parent, string const & title,
+ char const * const * data, int size)
+{
+ char const * const * const end = data + size;
+ return new FormMathsBitmap(parent, title, std::vector<string>(data, end));
+}
+
+
+char const * const dialognames[] = { "aboutlyx", "bibitem", "bibtex", "branch", "changes",
+"character", "citation", "error", "errorlist" , "ert", "external", "file",
+"float", "graphics", "include", "index", "label", "latexlog", "mathpanel",
+"mathaccents", "matharrows", "mathoperators", "mathrelations", "mathgreek",
+"mathmisc", "mathdots", "mathbigoperators", "mathamsmisc",
+"mathamsarrows", "mathamsrelations", "mathamsnegatedrelations", "mathamsoperators",
+"mathdelimiter", "mathmatrix", "mathspace", "mathstyle",
+"minipage", "note", "paragraph", "ref", "tabular", "tabularcreate", "texinfo",
+
+#ifdef HAVE_LIBAIKSAURUS
+"thesaurus",
+#endif
+
+"toc", "url", "vclog", "wrap" };
+
+char const * const * const end_dialognames =
+ dialognames + (sizeof(dialognames) / sizeof(char *));
+
+struct cmpCStr {
+ cmpCStr(char const * name) : name_(name) {}
+ bool operator()(char const * other) {
+ return strcmp(other, name_) == 0;
+ }
+private:
+ char const * name_;
+};
+
+} // namespace anon
+
+
+bool Dialogs::isValidName(string const & name) const
+{
+ return std::find_if(dialognames, end_dialognames,
+ cmpCStr(name.c_str())) != end_dialognames;
+}
+
+
+Dialog * Dialogs::build(string const & name)
+{
+ if (!isValidName(name))
+ return 0;
+
+ Dialog * dialog = new Dialog(lyxview_, name);
+ dialog->bc().view(new xformsBC(dialog->bc()));
+
+ if (name == "aboutlyx") {
+ dialog->bc().view(new GBC(dialog->bc()));
+ dialog->setController(new ControlAboutlyx(*dialog));
+ dialog->setView(new GAboutlyx(*dialog));
+ dialog->bc().bp(new OkCancelPolicy);
+ } else if (name == "bibitem") {
+ dialog->setController(new ControlCommand(*dialog, name));
+ dialog->setView(new FormBibitem(*dialog));
+ dialog->bc().bp(new OkCancelReadOnlyPolicy);
+ } else if (name == "bibtex") {
+ dialog->setController(new ControlBibtex(*dialog));
+ dialog->setView(new FormBibtex(*dialog));
+ dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
+ } else if (name == "character") {
+ dialog->setController(new ControlCharacter(*dialog));
+ dialog->setView(new FormCharacter(*dialog));
+ dialog->bc().bp(new OkApplyCancelReadOnlyPolicy);
+ } else if (name == "changes") {
+ dialog->setController(new ControlChanges(*dialog));
+ dialog->setView(new FormChanges(*dialog));
+ dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
+ } else if (name == "citation") {
+ dialog->setController(new ControlCitation(*dialog));
+ dialog->setView(new FormCitation(*dialog));
+ dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
+ } else if (name == "errorlist") {
+ dialog->setController(new ControlErrorList(*dialog));
+ dialog->setView(new FormErrorList(*dialog));
+ dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
+ } else if (name == "ert") {
+ dialog->setController(new ControlERT(*dialog));
+ dialog->setView(new FormERT(*dialog));
+ dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
+ } else if (name == "external") {
+ dialog->setController(new ControlExternal(*dialog));
+ dialog->setView(new FormExternal(*dialog));
+ dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
+ } else if (name == "file") {
+ dialog->setController(new ControlShowFile(*dialog));
+ dialog->setView(new FormShowFile(*dialog));
+ dialog->bc().bp(new OkCancelPolicy);
+ } else if (name == "float") {
+ dialog->setController(new ControlFloat(*dialog));
+ dialog->setView(new FormFloat(*dialog));
+ dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
+ } else if (name == "graphics") {
+ dialog->setController(new ControlGraphics(*dialog));
+ dialog->setView(new FormGraphics(*dialog));
+ dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
+ } else if (name == "include") {
+ dialog->setController(new ControlInclude(*dialog));
+ dialog->setView(new FormInclude(*dialog));
+ dialog->bc().bp(new OkApplyCancelReadOnlyPolicy);
+ } else if (name == "index") {
+ dialog->bc().view(new GBC(dialog->bc()));
+ dialog->setController(new ControlCommand(*dialog, name));
+ dialog->setView(new GText(*dialog,
+ _("Index"), _("Keyword:|#K")));
+ dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
+ } else if (name == "label") {
+ dialog->bc().view(new GBC(dialog->bc()));
+ dialog->setController(new ControlCommand(*dialog, name));
+ dialog->setView(new GText(*dialog,
+ _("Label"), _("Label:|#L")));
+ dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
+ } else if (name == "latexlog") {
+ dialog->setController(new ControlLog(*dialog));
+ dialog->setView(new FormLog(*dialog));
+ dialog->bc().bp(new OkCancelPolicy);
+
+ } else if (name == "mathpanel") {
+ dialog->setController(new ControlMath(*dialog));
+ dialog->setView(new FormMathsPanel(*dialog));
+ dialog->bc().bp(new IgnorantPolicy);
+
+ } else if (name == "mathaccents") {
+ FormMathsBitmap * bitmap =
+ createFormBitmap(*dialog, _("Maths Decorations & Accents"),
+ latex_deco, nr_latex_deco);
+ bitmap->addBitmap(
+ BitmapStore(12, 3, 4, deco1_width, deco1_height, deco1_bits, true));
+ bitmap->addBitmap(
+ BitmapStore(10, 4, 3, deco2_width, deco2_height, deco2_bits, true));
+
+ dialog->setController(new ControlMath(*dialog));
+ dialog->setView(bitmap);
+ dialog->bc().bp(new IgnorantPolicy);
+
+ } else if (name == "matharrows") {
+ FormMathsBitmap * bitmap =
+ createFormBitmap(*dialog, _("Arrows"), latex_arrow, nr_latex_arrow);
+ bitmap->addBitmap(
+ BitmapStore(20, 5, 4, arrow_width, arrow_height, arrow_bits, true));
+ bitmap->addBitmap(
+ BitmapStore(7, 2, 4, larrow_width, larrow_height, larrow_bits, false));
+ bitmap->addBitmap(
+ BitmapStore(4, 2, 2, darrow_width, darrow_height, darrow_bits, true));
+
+ dialog->setController(new ControlMath(*dialog));
+ dialog->setView(bitmap);
+ dialog->bc().bp(new IgnorantPolicy);
+
+ } else if (name == "mathoperators") {
+ FormMathsBitmap * bitmap =
+ createFormBitmap(*dialog, _("Binary Ops"),
+ latex_bop, nr_latex_bop);
+ bitmap->addBitmap(
+ BitmapStore(31, 4, 8, bop_width, bop_height, bop_bits, true));
+
+ dialog->setController(new ControlMath(*dialog));
+ dialog->setView(bitmap);
+ dialog->bc().bp(new IgnorantPolicy);
+
+ } else if (name == "mathrelations") {
+ FormMathsBitmap * bitmap =
+ createFormBitmap(*dialog, _("Binary Relations"),
+ latex_brel, nr_latex_brel);
+ bitmap->addBitmap(
+ BitmapStore(35, 4, 9, brel_width, brel_height, brel_bits, true));
+
+ dialog->setController(new ControlMath(*dialog));
+ dialog->setView(bitmap);
+ dialog->bc().bp(new IgnorantPolicy);
+
+ } else if (name == "mathgreek") {
+ FormMathsBitmap * bitmap =
+ createFormBitmap(*dialog, _("Greek"),
+ latex_greek, nr_latex_greek);
+ bitmap->addBitmap(
+ BitmapStore(11, 6, 2, Greek_width, Greek_height, Greek_bits, true));
+ bitmap->addBitmap(
+ BitmapStore(28, 7, 4, greek_width, greek_height, greek_bits, true));
+
+ dialog->setController(new ControlMath(*dialog));
+ dialog->setView(bitmap);
+ dialog->bc().bp(new IgnorantPolicy);
+
+ } else if (name == "mathmisc") {
+ FormMathsBitmap * bitmap =
+ createFormBitmap(*dialog, _("Misc"),
+ latex_misc, nr_latex_misc);
+ bitmap->addBitmap(
+ BitmapStore(29, 5, 6, misc_width, misc_height, misc_bits, true));
+ bitmap->addBitmap(
+ BitmapStore(5, 5, 1, misc4_width, misc4_height, misc4_bits, true));
+ bitmap->addBitmap(
+ BitmapStore(6, 3, 2, misc2_width, misc2_height, misc2_bits, false));
+ bitmap->addBitmap(
+ BitmapStore(4, 2, 2, misc3_width, misc3_height, misc3_bits, true));
+
+ dialog->setController(new ControlMath(*dialog));
+ dialog->setView(bitmap);
+ dialog->bc().bp(new IgnorantPolicy);
+
+ } else if (name == "mathdots") {
+ FormMathsBitmap * bitmap =
+ createFormBitmap(*dialog, _("Dots"),
+ latex_dots, nr_latex_dots);
+ bitmap->addBitmap(
+ BitmapStore(4, 4, 1, dots_width, dots_height, dots_bits, true));
+
+ dialog->setController(new ControlMath(*dialog));
+ dialog->setView(bitmap);
+ dialog->bc().bp(new IgnorantPolicy);
+
+ } else if (name == "mathbigoperators") {
+ FormMathsBitmap * bitmap =
+ createFormBitmap(*dialog, _("Big Operators"),
+ latex_varsz, nr_latex_varsz);
+ bitmap->addBitmap(
+ BitmapStore(14, 3, 5, varsz_width, varsz_height, varsz_bits, true));
+
+ dialog->setController(new ControlMath(*dialog));
+ dialog->setView(bitmap);
+ dialog->bc().bp(new IgnorantPolicy);
+
+ } else if (name == "mathamsmisc") {
+ FormMathsBitmap * bitmap =
+ createFormBitmap(*dialog, _("AMS Misc"),
+ latex_ams_misc, nr_latex_ams_misc);
+ bitmap->addBitmap(
+ BitmapStore(9, 5, 2, ams1_width, ams1_height, ams1_bits, true));
+ bitmap->addBitmap(
+ BitmapStore(26, 3, 9, ams7_width, ams7_height, ams7_bits, true));
+
+ dialog->setController(new ControlMath(*dialog));
+ dialog->setView(bitmap);
+ dialog->bc().bp(new IgnorantPolicy);
+
+ } else if (name == "mathamsarrows") {
+ FormMathsBitmap * bitmap =
+ createFormBitmap(*dialog, _("AMS Arrows"),
+ latex_ams_arrows, nr_latex_ams_arrows);
+ bitmap->addBitmap(
+ BitmapStore(32, 3, 11, ams2_width, ams2_height, ams2_bits, true));
+ bitmap->addBitmap(
+ BitmapStore(6, 3, 2, ams3_width, ams3_height, ams3_bits, true));
+
+ dialog->setController(new ControlMath(*dialog));
+ dialog->setView(bitmap);
+ dialog->bc().bp(new IgnorantPolicy);
+
+ } else if (name == "mathamsrelations") {
+ FormMathsBitmap * bitmap =
+ createFormBitmap(*dialog, _("AMS Relations"),
+ latex_ams_rel, nr_latex_ams_rel);
+ bitmap->addBitmap(
+ BitmapStore(66, 6, 11, ams_rel_width, ams_rel_height, ams_rel_bits, true));
+
+ dialog->setController(new ControlMath(*dialog));
+ dialog->setView(bitmap);
+ dialog->bc().bp(new IgnorantPolicy);
+
+ } else if (name == "mathamsnegatedrelations") {
+ FormMathsBitmap * bitmap =
+ createFormBitmap(*dialog, _("AMS Negated Rel"),
+ latex_ams_nrel, nr_latex_ams_nrel);
+ bitmap->addBitmap(
+ BitmapStore(51, 6, 9, ams_nrel_width, ams_nrel_height, ams_nrel_bits, true));
+
+ dialog->setController(new ControlMath(*dialog));
+ dialog->setView(bitmap);
+ dialog->bc().bp(new IgnorantPolicy);
+
+ } else if (name == "mathamsoperators") {
+ FormMathsBitmap * bitmap =
+ createFormBitmap(*dialog, _("AMS Operators"),
+ latex_ams_ops, nr_latex_ams_ops);
+ bitmap->addBitmap(
+ BitmapStore(23, 3, 8, ams_ops_width, ams_ops_height, ams_ops_bits, true));
+
+ dialog->setController(new ControlMath(*dialog));
+ dialog->setView(bitmap);
+ dialog->bc().bp(new IgnorantPolicy);
+
+ } else if (name == "mathdelimiter") {
+ dialog->setController(new ControlMath(*dialog));
+ dialog->setView(new FormMathsDelim(*dialog));
+ dialog->bc().bp(new OkApplyCancelReadOnlyPolicy);
+ } else if (name == "mathmatrix") {
+ dialog->setController(new ControlMath(*dialog));
+ dialog->setView(new FormMathsMatrix(*dialog));
+ dialog->bc().bp(new OkApplyCancelReadOnlyPolicy);
+ } else if (name == "mathspace") {
+ dialog->setController(new ControlMath(*dialog));
+ dialog->setView(new FormMathsSpace(*dialog));
+ dialog->bc().bp(new IgnorantPolicy);
+ } else if (name == "mathstyle") {
+ dialog->setController(new ControlMath(*dialog));
+ dialog->setView(new FormMathsStyle(*dialog));
+ dialog->bc().bp(new IgnorantPolicy);
+ } else if (name == "minipage") {
+ dialog->setController(new ControlMinipage(*dialog));
+ dialog->setView(new FormMinipage(*dialog));
+ dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
+ } else if (name == "note") {
+ dialog->setController(new ControlNote(*dialog));
+ dialog->setView(new FormNote(*dialog));
+ dialog->bc().bp(new OkApplyCancelReadOnlyPolicy);
+ } else if (name == "branch") {
+ dialog->setController(new ControlBranch(*dialog));
+ dialog->setView(new FormBranch(*dialog));
+ dialog->bc().bp(new OkApplyCancelReadOnlyPolicy);
+ } else if (name == "paragraph") {
+ dialog->setController(new ControlParagraph(*dialog));
+ dialog->setView(new FormParagraph(*dialog));
+ dialog->bc().bp(new OkApplyCancelReadOnlyPolicy);
+ } else if (name == "ref") {
+ dialog->setController(new ControlRef(*dialog));
+ dialog->setView(new FormRef(*dialog));
+ dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
+ } else if (name == "tabular") {
+ dialog->setController(new ControlTabular(*dialog));
+ dialog->setView(new FormTabular(*dialog));
+ dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
+ } else if (name == "tabularcreate") {
+ dialog->setController(new ControlTabularCreate(*dialog));
+ dialog->setView(new FormTabularCreate(*dialog));
+ dialog->bc().bp(new IgnorantPolicy);
+ } else if (name == "texinfo") {
+ dialog->setController(new ControlTexinfo(*dialog));
+ dialog->setView(new FormTexinfo(*dialog));
+ dialog->bc().bp(new OkCancelPolicy);
+#ifdef HAVE_LIBAIKSAURUS
+ } else if (name == "thesaurus") {
+ dialog->setController(new ControlThesaurus(*dialog));
+ dialog->setView(new FormThesaurus(*dialog));
+ dialog->bc().bp(new OkApplyCancelReadOnlyPolicy);
+#endif
+ } else if (name == "toc") {
+ dialog->setController(new ControlToc(*dialog));
+ dialog->setView(new FormToc(*dialog));
+ dialog->bc().bp(new OkCancelPolicy);
+ } else if (name == "url") {
+ dialog->setController(new ControlCommand(*dialog, name));
+ dialog->setView(new FormUrl(*dialog));
+ dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
+ } else if (name == "vclog") {
+ dialog->setController(new ControlVCLog(*dialog));
+ dialog->setView(new FormVCLog(*dialog));
+ dialog->bc().bp(new OkCancelPolicy);
+ } else if (name == "wrap") {
+ dialog->setController(new ControlWrap(*dialog));
+ dialog->setView(new FormWrap(*dialog));
+ dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
+ }
+
+ return dialog;
+}
+
+
+void Dialogs::toggleTooltips()
+{
+ Tooltips::toggleEnabled();
+}
+
+
+/// Are the tooltips on or off?
+bool Dialogs::tooltipsEnabled()
+{
+ return Tooltips::enabled();
+}
--- /dev/null
+/**
+ * \file FileDialog.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+
+#include "FileDialogPrivate.h"
+
+
+FileDialog::FileDialog(string const & title,
+ kb_action action,
+ Button b1,
+ Button b2)
+{
+ private_ = new FileDialog::Private(title, action, b1, b2);
+}
+
+
+FileDialog::~FileDialog()
+{
+ delete private_;
+}
+
+
+FileDialog::Result const FileDialog::open(string const & path,
+ string const & mask,
+ string const & suggested)
+{
+ return private_->open(path, mask, suggested);
+}
+
+
+FileDialog::Result const FileDialog::opendir(string const & path,
+ string const & suggested)
+{
+ return private_->opendir(path, suggested);
+}
+
+
+FileDialog::Result const FileDialog::save(string const & path,
+ string const & mask,
+ string const & suggested)
+{
+ return private_->save(path, mask, suggested);
+}
--- /dev/null
+/**
+ * \file FileDialogPrivate.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+
+#include "LString.h"
+
+#include "FileDialogPrivate.h"
+
+
+FileDialog::Private::Private(string const & title,
+ kb_action action,
+ FileDialog::Button b1,
+ FileDialog::Button b2) :
+ action_(action)
+{
+ fileSelection_.set_title(title);
+ fileSelection_.get_button_area()->children().push_back(
+ Gtk::Box_Helpers::Element(button1_));
+ fileSelection_.get_button_area()->children().push_back(
+ Gtk::Box_Helpers::Element(button2_));
+ button1_.signal_clicked().connect(
+ SigC::slot(*this, &FileDialog::Private::onButton1Clicked));
+ button2_.signal_clicked().connect(
+ SigC::slot(*this, &FileDialog::Private::onButton2Clicked));
+ if (!b1.first.empty() && !b1.second.empty()) {
+ string::size_type pos = b1.first.find('|');
+ button1_.set_label(
+ Glib::locale_to_utf8(b1.first.substr(0, pos)));
+ dir1_ = b1.second;
+ button1_.show();
+ }
+ if (!b2.first.empty() && !b2.second.empty()) {
+ string::size_type pos = b2.first.find('|');
+ button2_.set_label(
+ Glib::locale_to_utf8(b2.first.substr(0, pos)));
+ dir2_ = b2.second;
+ button2_.show();
+ }
+}
+
+
+void FileDialog::Private::onButton1Clicked()
+{
+ fileSelection_.set_filename(dir1_);
+}
+
+
+void FileDialog::Private::onButton2Clicked()
+{
+ fileSelection_.set_filename(dir2_);
+}
+
+
+FileDialog::Result const FileDialog::Private::open(string const & path,
+ string const & /*mask*/,
+ string const & /*suggested*/)
+{
+ fileSelection_.set_filename(path);
+ fileSelection_.get_file_list()->get_parent()->show();
+ Result result;
+ result.first = FileDialog::Chosen;
+ if (fileSelection_.run() == Gtk::RESPONSE_OK)
+ result.second = fileSelection_.get_filename();
+ else
+ result.second = string();
+ return result;
+}
+
+
+FileDialog::Result const FileDialog::Private::opendir(string const & path,
+ string const & /*suggested*/)
+{
+ fileSelection_.set_filename(path);
+ fileSelection_.get_file_list()->get_parent()->hide();
+ Result result;
+ result.first = FileDialog::Chosen;
+ if (fileSelection_.run() == Gtk::RESPONSE_OK)
+ result.second = fileSelection_.get_filename();
+ else
+ result.second = string();
+ return result;
+}
+
+
+FileDialog::Result const FileDialog::Private::save(string const & path,
+ string const & mask,
+ string const & suggested)
+{
+ return open(path, mask, suggested);
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file FileDialogPrivate.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#ifndef FILE_DIALOG_PRIVATE_H
+#define FILE_DIALOG_PRIVATE_H
+
+#include <gtkmm.h>
+#include "frontends/FileDialog.h"
+
+class FileDialog::Private : public SigC::Object
+{
+public:
+ Private(string const & title,
+ kb_action action,
+ FileDialog::Button b1, FileDialog::Button b2);
+ FileDialog::Result const open(string const & path,
+ string const & mask,
+ string const & suggested);
+ FileDialog::Result const opendir(string const & path,
+ string const & suggested);
+
+ FileDialog::Result const save(string const & path,
+ string const & mask,
+ string const & suggested);
+
+private:
+ void onButton1Clicked();
+ void onButton2Clicked();
+ Gtk::FileSelection fileSelection_;
+ Gtk::Button button1_;
+ Gtk::Button button2_;
+ string dir1_;
+ string dir2_;
+ kb_action action_;
+};
+
+#endif
--- /dev/null
+/**
+ * \file GAboutlyx.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+
+#include <libglademm.h>
+#include <sstream>
+
+#include "ControlAboutlyx.h"
+#include "GAboutlyx.h"
+#include "support/filetools.h"
+#include "version.h"
+
+namespace {
+
+enum TranslateState {NORMAL, BEGIN, IN_AT, IN_BOLD, IN_ITALIC};
+
+
+Glib::ustring translateMarkup(Glib::ustring const & lyxMarkup)
+{
+ Glib::ustring::const_iterator it = lyxMarkup.begin();
+ Glib::ustring pangoMarkup;
+ TranslateState state = BEGIN;
+ for (; it != lyxMarkup.end(); it++) {
+ switch (state) {
+ case BEGIN:
+ switch (*it) {
+ case '@':
+ state = IN_AT;
+ break;
+ case '\n':
+ state = BEGIN;
+ pangoMarkup.push_back('\n');
+ break;
+ default:
+ state = NORMAL;
+ pangoMarkup.push_back(*it);
+ break;
+ }
+ break;
+ case IN_AT:
+ switch (*it) {
+ case 'b':
+ state = IN_BOLD;
+ pangoMarkup += "<b>";
+ break;
+ case 'i':
+ state = IN_ITALIC;
+ pangoMarkup += "<i>";
+ break;
+ case '\n':
+ state = BEGIN;
+ pangoMarkup.push_back('@');
+ pangoMarkup.push_back('\n');
+ break;
+ default:
+ state = NORMAL;
+ pangoMarkup.push_back('@');
+ pangoMarkup.push_back(*it);
+ }
+ break;
+ case IN_BOLD:
+ switch (*it) {
+ case '\n':
+ state = BEGIN;
+ pangoMarkup += "</b>\n";
+ break;
+ default:
+ pangoMarkup.push_back(*it);
+ }
+ break;
+ case IN_ITALIC:
+ switch (*it) {
+ case '\n':
+ state = BEGIN;
+ pangoMarkup += "</i>\n";
+ break;
+ default:
+ pangoMarkup.push_back(*it);
+ }
+ break;
+ case NORMAL:
+ switch (*it) {
+ case '\n':
+ state = BEGIN;
+ pangoMarkup.push_back('\n');
+ break;
+ default:
+ pangoMarkup.push_back(*it);
+ }
+ }
+ switch (*it) {
+ case '&':
+ pangoMarkup += "amp;";
+ break;
+ case '<':
+ pangoMarkup.erase(--(pangoMarkup.end()));
+ pangoMarkup += "<";
+ break;
+ case '>':
+ pangoMarkup.erase(--(pangoMarkup.end()));
+ pangoMarkup += ">";
+ break;
+ default:
+ break;
+ }
+ }
+ switch (state) {
+ case IN_AT:
+ pangoMarkup.push_back('@');
+ break;
+ case IN_ITALIC:
+ pangoMarkup += "</i>";
+ break;
+ case IN_BOLD:
+ pangoMarkup += "</b>";
+ break;
+ default:
+ break;
+ }
+ return pangoMarkup;
+}
+
+
+}
+
+
+GAboutlyx::GAboutlyx(Dialog & parent)
+ : GViewCB<ControlAboutlyx, GViewGladeB>(parent, "About LyX")
+{
+}
+
+
+void GAboutlyx::doBuild()
+{
+ string const gladeName =
+ lyx::support::LibFileSearch("glade", "aboutlyx", "glade");
+ xml_ = Gnome::Glade::Xml::create(gladeName);
+ Gtk::Label * version;
+ Gtk::Label * credits;
+ Gtk::Label * license;
+ xml_->get_widget("version", version);
+ xml_->get_widget("credits", credits);
+ xml_->get_widget("license", license);
+ std::ostringstream vs;
+ vs << controller().getVersion()
+ << std::endl << lyx_version_info;
+ version->set_text(Glib::locale_to_utf8(vs.str()));
+ std::ostringstream crs;
+ controller().getCredits(crs);
+ credits->set_markup(translateMarkup(Glib::locale_to_utf8(crs.str())));
+ std::ostringstream ls;
+ ls << controller().getCopyright() << "\n\n"
+ << controller().getLicense() << "\n\n"
+ << controller().getDisclaimer();
+ license->set_text(Glib::locale_to_utf8(ls.str()));
+ Gtk::Button * btn;
+ xml_->get_widget("close_button", btn);
+ btn->signal_clicked().connect(SigC::slot(*this, &GViewBase::onCancel));
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file GAboutlyx.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#ifndef GABOUTLYX_H
+#define GABOUTLYX_H
+
+#include "GViewBase.h"
+
+class ControlAboutlyx;
+
+class GAboutlyx : public GViewCB<ControlAboutlyx, GViewGladeB>
+{
+public:
+ GAboutlyx(Dialog &);
+private:
+ virtual void apply() {}
+ virtual void update() {}
+ virtual void doBuild();
+};
+
+#endif
--- /dev/null
+/**
+ * \file GBC.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+
+#include "GBC.h"
+
+
+GBC::GBC(ButtonController const & parent,
+ string const & cancel, string const & close)
+ : GuiBC<Gtk::Button, Gtk::Widget>(parent, cancel, close)
+{
+}
+
+
+void GBC::setButtonEnabled(Gtk::Button * btn, bool enabled) const
+{
+ btn->set_sensitive(enabled);
+}
+
+
+void GBC::setWidgetEnabled(Gtk::Widget * widget, bool enabled) const
+{
+ widget->set_sensitive(enabled);
+}
+
+
+void GBC::setButtonLabel(Gtk::Button * btn, string const & label) const
+{
+ btn->set_label(Glib::locale_to_utf8(label));
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file GBC.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#ifndef GBUTTONCONTROLLER_H
+#define GBUTTONCONTROLLER_H
+
+#include <gtkmm.h>
+
+#include "ButtonController.h"
+#include "BCView.h"
+#include "LString.h"
+#include "gettext.h"
+
+class GBC : public GuiBC<Gtk::Button, Gtk::Widget>
+{
+public:
+ GBC(ButtonController const & parent,
+ string const & cancel = _("Cancel"),
+ string const & close = _("Close"));
+private:
+ /// Updates the button sensitivity (enabled/disabled)
+ void setButtonEnabled(Gtk::Button *, bool enabled) const;
+
+ /// Updates the widget sensitivity (enabled/disabled)
+ void setWidgetEnabled(Gtk::Widget *, bool enabled) const;
+
+ /// Set the label on the button
+ void setButtonLabel(Gtk::Button *, string const & label) const;
+};
+
+#endif
--- /dev/null
+/**
+ * \file GLyXKeySym.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+
+#include <gdk/gdkkeysyms.h>
+#include "GLyXKeySym.h"
+
+
+GLyXKeySym::GLyXKeySym() : keyval_(GDK_VoidSymbol)
+{
+}
+
+
+GLyXKeySym::GLyXKeySym(unsigned int keyval) : keyval_(keyval)
+{
+}
+
+
+void GLyXKeySym::setKeyval(unsigned int keyval)
+{
+ keyval_ = keyval;
+}
+
+
+void GLyXKeySym::init(string const & symbolname)
+{
+ keyval_ = gdk_keyval_from_name(symbolname.c_str());
+}
+
+
+bool GLyXKeySym::isOK() const
+{
+ return keyval_ != GDK_VoidSymbol;
+}
+
+
+bool GLyXKeySym::isModifier() const
+{
+ return ((keyval_ >= GDK_Shift_L && keyval_ <= GDK_Hyper_R)
+ || keyval_ == GDK_Mode_switch || keyval_ == 0);
+}
+
+
+string GLyXKeySym::getSymbolName() const
+{
+ const char * name = gdk_keyval_name(keyval_);
+ return name ? name : string();
+}
+
+
+char GLyXKeySym::getISOEncoded(string const & /*encoding*/) const
+{
+ if (keyval_ == GDK_VoidSymbol)
+ return 0;
+
+ unsigned int c = keyval_;
+
+ switch (c & 0x0000FF00) {
+ // latin 1 byte 3 = 0
+ case 0x00000000: break;
+ // latin 2 byte 3 = 1
+ case 0x00000100:
+ // latin 3 byte 3 = 2
+ case 0x00000200:
+ // latin 4 byte 3 = 3
+ case 0x00000300:
+ // cyrillic KOI8 & Co
+ case 0x00000600:
+ // greek
+ case 0x00000700:
+ // latin 8 byte 3 = 18 (0x12)
+ case 0x00001200:
+ // latin 9 byte 3 = 19 (0x13)
+ case 0x00001300:
+ c &= 0x000000FF;
+ break;
+ default:
+ c = 0;
+ }
+ return c;
+}
+
+
+bool operator==(LyXKeySym const & k1, LyXKeySym const & k2)
+{
+ return static_cast<GLyXKeySym const &>(k1).getKeyval()
+ == static_cast<GLyXKeySym const &>(k2).getKeyval();
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file GLyXKeySym.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#ifndef GLYX_KEYSYM_H
+#define GLYX_KEYSYM_H
+
+#include "LString.h"
+#include "frontends/LyXKeySym.h"
+
+class GLyXKeySym : public LyXKeySym
+{
+public:
+ GLyXKeySym();
+ GLyXKeySym(unsigned int keyval);
+ void setKeyval(unsigned int keyval);
+ unsigned int getKeyval() const { return keyval_; }
+ virtual void init(string const & symbolname);
+ virtual ~GLyXKeySym() {}
+ virtual bool isOK() const;
+ virtual bool isModifier() const;
+ virtual string getSymbolName() const;
+ virtual char getISOEncoded(string const & encoding) const;
+private:
+ unsigned int keyval_;
+};
+
+#endif
--- /dev/null
+/**
+ * \file GMenubar.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+
+#include "GMenubar.h"
+#include "GView.h"
+#include "debug.h"
+#include "lyxfunc.h"
+
+namespace
+{
+
+class LyxMenu : public Gtk::Menu
+{
+public:
+ LyxMenu() { menu_.reset(new ::Menu); }
+
+ ::Menu& getBackMenu() { return *menu_.get(); }
+
+ void clearBackMenu() { menu_.reset(new ::Menu); }
+private:
+ std::auto_ptr< ::Menu > menu_;
+};
+
+
+Glib::ustring labelTrans(string const & label, string const & shortcut)
+{
+ string labelN = label;
+ string::size_type i = label.find(shortcut);
+ if (i == string::npos)
+ return Glib::locale_to_utf8(label);
+ labelN.insert(i, "_");
+ return Glib::locale_to_utf8(labelN);
+}
+
+
+void ClearMenu(Gtk::MenuShell * menu)
+{
+ Gtk::Menu_Helpers::MenuList::iterator m, end;
+ m = menu->items().begin();
+ end = menu->items().end();
+ Gtk::Menu * subMenu;
+ for (; m != end; ++m) {
+ if ((subMenu = m->get_submenu()) != 0) {
+ ClearMenu(subMenu);
+ delete subMenu;
+ }
+ }
+ menu->items().clear();
+}
+
+
+}
+
+
+GMenubar::GMenubar(LyXView *lyxView, MenuBackend const & /*menuBackend*/) :
+ view_(lyxView)
+{
+ GView * gview = static_cast<GView*>(lyxView);
+ Gtk::VBox& vbox = gview->getVBox();
+ Menu const & menu = menubackend.getMenubar();
+ Menu::const_iterator i = menu.begin();
+ Menu::const_iterator end = menu.end();
+ for (; i != end; ++i) {
+ if (i->kind() != MenuItem::Submenu) {
+ lyxerr << "ERROR: GMenubar::createMenubar:"
+ " only submenus can appear in a menubar"
+ << std::endl;
+ continue;
+ }
+ Gtk::Menu * gmenu = new LyxMenu;
+ menubar_.items().push_back(
+ Gtk::Menu_Helpers::MenuElem(
+ labelTrans(i->label(), i->shortcut()),
+ *gmenu));
+ menubar_.items().back().signal_activate().connect(
+ SigC::bind(SigC::slot(*this, &GMenubar::onSubMenuActivate), &(*i),
+ &menubar_.items().back()));
+ mainMenuNames_.push_back(i->submenuname());
+ }
+ menubar_.show();
+ vbox.children().push_back(Gtk::Box_Helpers::Element(menubar_,
+ Gtk::PACK_SHRINK));
+}
+
+
+GMenubar::~GMenubar()
+{
+ ClearMenu(&menubar_);
+}
+
+
+void GMenubar::update()
+{
+}
+
+
+void GMenubar::openByName(string const & name)
+{
+ Glib::ustring uname = Glib::locale_to_utf8(name);
+ std::vector<Glib::ustring>::iterator it =
+ std::find(mainMenuNames_.begin(), mainMenuNames_.end(),
+ uname);
+ if (it != mainMenuNames_.end()) {
+ Gtk::MenuItem& mitem = menubar_.items()[it - mainMenuNames_.begin()];
+ mitem.select();
+ mitem.activate();
+ return;
+ }
+ lyxerr << "GMenubar::openByName: menu "
+ << name << " not found" << std::endl;
+}
+
+
+bool GMenubar::submenuDisabled(MenuItem const * item)
+{
+ Menu & from = menubackend.getMenu(item->submenuname());
+ Menu to;
+ menubackend.expand(from, to, view_);
+ Menu::const_iterator i = to.begin();
+ Menu::const_iterator end = to.end();
+ for (; i != end; ++i) {
+ switch (i->kind()) {
+ case MenuItem::Submenu:
+ if (!submenuDisabled(&(*i)))
+ return false;
+ break;
+ case MenuItem::Command:
+ {
+ FuncStatus const flag =
+ view_->getLyXFunc().getStatus(i->action());
+ if (!flag.disabled())
+ return false;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return true;
+}
+
+
+void GMenubar::onSubMenuActivate(MenuItem const * item,
+ Gtk::MenuItem * gitem)
+{
+ Gtk::Menu * gmenu = gitem->get_submenu();
+ ClearMenu(gmenu);
+ LyxMenu * lyxmenu = static_cast<LyxMenu*>(gmenu);
+ lyxmenu->clearBackMenu();
+ Menu * fmenu = &menubackend.getMenu(item->submenuname());
+ menubackend.expand(*fmenu, lyxmenu->getBackMenu(), view_);
+ Menu::const_iterator i = lyxmenu->getBackMenu().begin();
+ Menu::const_iterator end = lyxmenu->getBackMenu().end();
+ Gtk::Menu * gmenu_new;
+ for (; i != end; ++i) {
+ switch (i->kind()) {
+ case MenuItem::Submenu:
+ gmenu_new = new LyxMenu;
+ gmenu->items().push_back(
+ Gtk::Menu_Helpers::MenuElem(
+ labelTrans(i->label(), i->shortcut()),
+ *gmenu_new));
+ gmenu->items().back().signal_activate().connect(
+ SigC::bind(SigC::slot(*this, &GMenubar::onSubMenuActivate),
+ &(*i),
+ &gmenu->items().back()));
+ if (submenuDisabled(&(*i)))
+ gmenu->items().back().set_sensitive(false);
+ break;
+ case MenuItem::Command:
+ {
+ FuncStatus const flag =
+ view_->getLyXFunc().getStatus(i->action());
+ bool on, off;
+ on = flag.onoff(true);
+ off = flag.onoff(false);
+
+ if (on || off) {
+ gmenu->items().push_back(
+ Gtk::Menu_Helpers::CheckMenuElem(
+ labelTrans(i->label(),
+ i->shortcut())));
+ Gtk::CheckMenuItem& citem =
+ static_cast<Gtk::CheckMenuItem&>(
+ gmenu->items().back());
+ citem.set_active(on);
+ } else {
+ gmenu->items().push_back(
+ Gtk::Menu_Helpers::MenuElem(
+ labelTrans(i->label(),
+ i->shortcut())));
+ }
+ Gtk::MenuItem & item = gmenu->items().back();
+ item.signal_activate().connect(
+ SigC::bind(SigC::slot(*this, &GMenubar::onCommandActivate),
+ &(*i), &item));
+ if (flag.disabled())
+ item.set_sensitive(false);
+ break;
+ }
+ case MenuItem::Separator:
+ gmenu->items().push_back(
+ Gtk::Menu_Helpers::SeparatorElem());
+ break;
+ default:
+ lyxerr << "GMenubar::create_submenu: "
+ "this should not happen" << std::endl;
+ break;
+ }
+ }
+}
+
+
+void GMenubar::onCommandActivate(MenuItem const * item,
+ Gtk::MenuItem * /*gitem*/)
+{
+ view_->getLyXFunc().dispatch(item->action(), true);
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file gtk/GMenubar.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#ifndef MENUBAR_PIMPL_H
+#define MENUBAR_PIMPL_H
+
+#include "frontends/Menubar.h"
+#include "MenuBackend.h"
+#include <vector>
+
+class LyXView;
+
+class GMenubar : public Menubar, public SigC::Object {
+public:
+ GMenubar(LyXView *, MenuBackend const &);
+ ~GMenubar();
+ void update();
+ void openByName(string const &);
+private:
+ void onCommandActivate(MenuItem const * item, Gtk::MenuItem * gitem);
+ void onSubMenuActivate(MenuItem const * item, Gtk::MenuItem * gitem);
+ bool submenuDisabled(MenuItem const * item);
+ Gtk::MenuBar menubar_;
+ LyXView * view_;
+ std::vector<Glib::ustring> mainMenuNames_;
+};
+
+#endif
--- /dev/null
+/**
+ * \file GMiniBuffer.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+
+#include "GView.h"
+#include "GMiniBuffer.h"
+#include "debug.h"
+#include "bufferview_funcs.h"
+#include <boost/bind.hpp>
+#include <vector>
+#include "frontends/controllers/ControlCommandBuffer.h"
+
+
+GMiniBuffer::GMiniBuffer(GView * view, ControlCommandBuffer & control) :
+ controller_(control), view_(view)
+{
+ listCols_.add(listCol_);
+ listStore_ = Gtk::ListStore::create(listCols_);
+ listView_.set_model(listStore_);
+ listView_.append_column("Completions", listCol_);
+ listView_.signal_key_press_event().connect(
+ SigC::slot(*this, &GMiniBuffer::onListKeyPress));
+ listView_.signal_focus_in_event().connect(
+ SigC::slot(*this, &GMiniBuffer::onListFocusIn));
+ listView_.signal_focus_out_event().connect(
+ SigC::slot(*this, &GMiniBuffer::onFocusOut));
+ listSel_ = listView_.get_selection();
+ listSel_->signal_changed().connect(
+ SigC::slot(*this, &GMiniBuffer::onSelected));
+ listView_.show();
+ scrolledWindow_.set_policy(Gtk::POLICY_AUTOMATIC,
+ Gtk::POLICY_AUTOMATIC);
+ scrolledWindow_.set_size_request(300, 150);
+ scrolledWindow_.add(listView_);
+ view_->getVBox().children().push_back(
+ Gtk::Box_Helpers::Element(scrolledWindow_,
+ Gtk::PACK_SHRINK));
+ entry_.signal_key_press_event().connect(
+ SigC::slot(*this, &GMiniBuffer::onKeyPress));
+ entry_.signal_focus_in_event().connect(
+ SigC::slot(*this, &GMiniBuffer::onFocusIn));
+ entry_.signal_focus_out_event().connect(
+ SigC::slot(*this, &GMiniBuffer::onFocusOut));
+ entry_.signal_activate().connect(
+ SigC::slot(*this, &GMiniBuffer::onCommit));
+ entry_.show();
+ view_->getVBox().children().push_back(
+ Gtk::Box_Helpers::Element(entry_,
+ Gtk::PACK_SHRINK));
+ infoTimer_.reset(new Timeout(1500));
+ idleTimer_.reset(new Timeout(6000));
+ focusTimer_.reset(new Timeout(50));
+ infoCon_ = infoTimer_->timeout.connect(
+ boost::bind(&GMiniBuffer::infoTimeout, this));
+ idleCon_ = idleTimer_->timeout.connect(
+ boost::bind(&GMiniBuffer::idleTimeout, this));
+ focusTimer_->timeout.connect(
+ boost::bind(&GMiniBuffer::focusTimeout, this));
+ idleTimer_->start();
+ messageMode();
+}
+
+
+GMiniBuffer::~GMiniBuffer()
+{
+}
+
+
+void GMiniBuffer::message(string const & str)
+{
+ if (!isEditMode())
+ setInput(Glib::locale_to_utf8(str));
+}
+
+
+void GMiniBuffer::showInfo(Glib::ustring const & info, bool append)
+{
+ storedInput_ = entry_.get_text();
+ entry_.set_editable(false);
+ infoShown_ = true;
+ if (append)
+ setInput(storedInput_ + ' ' + info);
+ else
+ setInput(info);
+ infoTimer_->start();
+}
+
+
+void GMiniBuffer::onSelected()
+{
+ if (!listSel_->count_selected_rows())
+ return;
+ Gtk::TreeModel::iterator it = listSel_->get_selected();
+ Glib::ustring sel = (*it)[listCol_];
+ setInput(sel + ' ');
+}
+
+
+void GMiniBuffer::onCommit()
+{
+ controller_.dispatch(Glib::locale_from_utf8(entry_.get_text()));
+ messageMode();
+}
+
+
+bool GMiniBuffer::onListFocusIn(GdkEventFocus * /*event*/)
+{
+ if (focusTimer_->running())
+ focusTimer_->stop();
+ if (infoShown_) {
+ infoTimer_->stop();
+ infoTimeout();
+ }
+ return false;
+}
+
+
+bool GMiniBuffer::onFocusIn(GdkEventFocus * /*event*/)
+{
+ if (infoShown_) {
+ infoTimer_->stop();
+ infoTimeout();
+ }
+ if (focusTimer_->running()) {
+ focusTimer_->stop();
+ return false;
+ }
+ setInput("");
+ idleTimer_->stop();
+ return false;
+}
+
+
+bool GMiniBuffer::onFocusOut(GdkEventFocus * /*event*/)
+{
+ focusTimer_->start();
+ return false;
+}
+
+
+void GMiniBuffer::focusTimeout()
+{
+ if (infoShown_) {
+ infoTimer_->stop();
+ infoTimeout();
+ }
+ focusTimer_->stop();
+ setInput("");
+ idleTimer_->start();
+ scrolledWindow_.hide();
+}
+
+
+bool GMiniBuffer::onListKeyPress(GdkEventKey * event)
+{
+ if (infoShown_) {
+ infoTimer_->stop();
+ infoTimeout();
+ }
+ switch (event->keyval) {
+ case GDK_Escape:
+ messageMode();
+ break;
+ case GDK_Tab:
+ entry_.grab_focus();
+ setInput(entry_.get_text() + ' ');
+ break;
+ }
+ return true;
+}
+
+
+bool GMiniBuffer::onKeyPress(GdkEventKey * event)
+{
+ if (infoShown_) {
+ infoTimer_->stop();
+ infoTimeout();
+ }
+ switch (event->keyval) {
+ case GDK_Down:
+ {
+ Glib::ustring const h =
+ Glib::locale_to_utf8(controller_.historyDown());
+ if (h.empty())
+ showInfo("[End of history]", false);
+ else
+ setInput(h);
+ break;
+ }
+ case GDK_Up:
+ {
+ Glib::ustring const h =
+ Glib::locale_to_utf8(controller_.historyUp());
+ if (h.empty())
+ showInfo("[Beginning of history]", false);
+ else
+ setInput(h);
+ break;
+ }
+ case GDK_Escape:
+ messageMode();
+ break;
+ case GDK_Tab:
+ {
+ Glib::ustring new_input, input;
+ string new_input_locale;
+ input = entry_.get_text();
+ std::vector<string> comp =
+ controller_.completions(Glib::locale_from_utf8(input),
+ new_input_locale);
+ new_input = Glib::locale_to_utf8(new_input_locale);
+ if (comp.empty() && new_input == input) {
+ showInfo("[no match]");
+ break;
+ }
+
+ if (comp.empty()) {
+ setInput(new_input + ' ');
+ showInfo("[only completion]");
+ break;
+ }
+ setInput(new_input);
+ listStore_->clear();
+ std::vector<string>::iterator it;
+ for (it = comp.begin(); it != comp.end(); ++it)
+ (*listStore_->append())[listCol_] =
+ Glib::locale_to_utf8(*it);
+ scrolledWindow_.show();
+ break;
+ }
+ }
+ return true;
+}
+
+
+bool GMiniBuffer::isEditMode() const
+{
+ return entry_.has_focus() || listView_.has_focus();
+}
+
+
+void GMiniBuffer::infoTimeout()
+{
+ infoShown_ = false;
+ setInput(storedInput_);
+ entry_.set_editable(true);
+}
+
+
+void GMiniBuffer::idleTimeout()
+{
+ setInput(Glib::locale_to_utf8(controller_.getCurrentState()));
+}
+
+
+void GMiniBuffer::editMode()
+{
+ entry_.grab_focus();
+}
+
+
+void GMiniBuffer::messageMode()
+{
+ view_->focusWorkArea();
+}
+
+
+void GMiniBuffer::setInput(Glib::ustring const & input)
+{
+ entry_.set_text(input);
+ entry_.set_position(-1);
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file GMiniBuffer.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+
+#ifndef GMINI_BUFFER_H
+#define GMINI_BUFFER_H
+
+#include "frontends/Timeout.h"
+#include "LString.h"
+class ControlCommandBuffer;
+
+class GMiniBuffer : public SigC::Object
+{
+public:
+ GMiniBuffer(GView * view, ControlCommandBuffer & control);
+ ~GMiniBuffer();
+ void message(string const & str);
+ /// go into edit mode
+ void editMode();
+private:
+ bool onKeyPress(GdkEventKey * event);
+ bool onListKeyPress(GdkEventKey * event);
+ void onCommit();
+ bool onListFocusIn(GdkEventFocus * event);
+ bool onFocusIn(GdkEventFocus * event);
+ bool onFocusOut(GdkEventFocus * event);
+ void focusTimeout();
+ void onSelected();
+ /// Are we in edit mode?
+ bool isEditMode() const;
+ /// reset buffer to stored input text
+ void infoTimeout();
+ /// go back to "at rest" message
+ void idleTimeout();
+ /// go into message mode
+ void messageMode();
+ /// show a temporary message whilst in edit mode
+ void showInfo(Glib::ustring const & info, bool append = true);
+ void setInput(Glib::ustring const & input);
+ ControlCommandBuffer & controller_;
+ GView * view_;
+ Gtk::Entry entry_;
+ /// info timer
+ boost::scoped_ptr<Timeout> infoTimer_;
+ boost::signals::connection infoCon_;
+ /// idle timer
+ boost::scoped_ptr<Timeout> idleTimer_;
+ boost::signals::connection idleCon_;
+ Glib::ustring storedInput_;
+ /// are we showing an informational temporary message ?
+ bool infoShown_;
+ boost::scoped_ptr<Timeout> focusTimer_;
+
+ Gtk::ScrolledWindow scrolledWindow_;
+ Gtk::TreeModelColumn<Glib::ustring> listCol_;
+ Gtk::TreeModel::ColumnRecord listCols_;
+ Glib::RefPtr<Gtk::ListStore> listStore_;
+ Gtk::TreeView listView_;
+ Glib::RefPtr<Gtk::TreeSelection> listSel_;
+};
+
+#endif
--- /dev/null
+/**
+ * \file GPainter.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+
+#include "GPainter.h"
+#include "LString.h"
+#include "debug.h"
+#include "GWorkArea.h"
+#include "lyxrc.h"
+#include "encoding.h"
+#include "language.h"
+#include "xftFontLoader.h"
+#include "xformsImage.h"
+#include "frontends/font_metrics.h"
+#include "codeConvert.h"
+
+#include "support/LAssert.h"
+#include "support/lstrings.h"
+
+#include <boost/scoped_array.hpp>
+#include <X11/Xft/Xft.h>
+#include <cmath>
+
+
+GPainter::GPainter(GWorkArea & xwa)
+ : Painter(), owner_(xwa)
+{
+}
+
+
+int GPainter::paperWidth() const
+{
+ return owner_.workWidth();
+}
+
+
+int GPainter::paperHeight() const
+{
+ return owner_.workHeight();
+}
+
+
+void GPainter::setForeground(Glib::RefPtr<Gdk::GC> gc, LColor::color clr)
+{
+ Gdk::Color * gclr = owner_.getColorHandler().getGdkColor(clr);
+ gc->set_foreground(*gclr);
+}
+
+
+void GPainter::setLineParam(Glib::RefPtr<Gdk::GC> gc,
+ line_style ls, line_width lw)
+{
+ int width;
+ Gdk::LineStyle style;
+ switch (lw) {
+ case Painter::line_thin:
+ width = 0;
+ break;
+ case Painter::line_thick:
+ width = 2;
+ break;
+ }
+
+ switch (ls) {
+ case Painter::line_solid:
+ style = Gdk::LINE_SOLID;
+ break;
+ case Painter::line_onoffdash:
+ style = Gdk::LINE_ON_OFF_DASH;
+ break;
+ }
+ gc->set_line_attributes(width, style,
+ Gdk::CAP_NOT_LAST, Gdk::JOIN_MITER);
+}
+
+
+Painter & GPainter::point(int x, int y, LColor::color c)
+{
+ setForeground(owner_.getGC(), c);
+ owner_.getPixmap()->draw_point(owner_.getGC(), x, y);
+ return *this;
+}
+
+
+Painter & GPainter::line(int x1, int y1,
+ int x2, int y2,
+ LColor::color col,
+ line_style ls,
+ line_width lw)
+{
+ setForeground(owner_.getGC(), col);
+ setLineParam(owner_.getGC(), ls, lw);
+ owner_.getPixmap()->draw_line(owner_.getGC(), x1, y1, x2, y2);
+ return *this;
+}
+
+
+Painter & GPainter::lines(int const * xp, int const * yp,
+ int np,
+ LColor::color col,
+ line_style ls,
+ line_width lw)
+{
+ setForeground(owner_.getGC(), col);
+ setLineParam(owner_.getGC(), ls, lw);
+ std::vector<Gdk::Point> points(np);
+
+ for (int i = 0; i < np; ++i) {
+ points[i].set_x(xp[i]);
+ points[i].set_y(yp[i]);
+ }
+ owner_.getPixmap()->draw_lines(owner_.getGC(), points);
+ return *this;
+}
+
+
+Painter & GPainter::rectangle(int x, int y,
+ int w, int h,
+ LColor::color col,
+ line_style ls,
+ line_width lw)
+{
+ setForeground(owner_.getGC(), col);
+ setLineParam(owner_.getGC(), ls, lw);
+ owner_.getPixmap()->draw_rectangle(owner_.getGC(), false, x, y, w, h);
+ return *this;
+}
+
+
+Painter & GPainter::fillRectangle(int x, int y,
+ int w, int h,
+ LColor::color col)
+{
+ setForeground(owner_.getGC(), col);
+ owner_.getPixmap()->draw_rectangle(owner_.getGC(), true, x, y, w, h);
+ return *this;
+}
+
+
+Painter & GPainter::fillPolygon(int const * xp, int const * yp,
+ int np, LColor::color col)
+{
+ setForeground(owner_.getGC(), col);
+ std::vector<Gdk::Point> points(np);
+
+ for (int i = 0; i < np; ++i) {
+ points[i].set_x(xp[i]);
+ points[i].set_y(yp[i]);
+ }
+ owner_.getPixmap()->draw_polygon(owner_.getGC(), true, points);
+ return *this;
+}
+
+
+Painter & GPainter::arc(int x, int y,
+ unsigned int w, unsigned int h,
+ int a1, int a2, LColor::color col)
+{
+ setForeground(owner_.getGC(), col);
+ owner_.getPixmap()->draw_arc(owner_.getGC(),
+ false, x, y, w, h, a1, a2);
+ return *this;
+}
+
+
+Painter & GPainter::image(int x, int y,
+ int w, int h,
+ lyx::graphics::Image const & i)
+{
+ lyx::graphics::xformsImage const & image =
+ static_cast<lyx::graphics::xformsImage const &>(i);
+ Pixmap pixmap = GDK_PIXMAP_XID(owner_.getPixmap()->gobj());
+ GC gc = GDK_GC_XGC(owner_.getGC()->gobj());
+ XCopyArea(owner_.getDisplay(), image.getPixmap(), pixmap,
+ gc, 0, 0, w, h, x, y);
+ return *this;
+}
+
+
+Painter & GPainter::text(int x, int y,
+ string const & s, LyXFont const & f)
+{
+ size_t size = s.length() + 1;
+ wchar_t * wcs = (wchar_t *) alloca(size * sizeof(wchar_t));
+ size = mbstowcs(wcs, s.c_str(), size);
+ return text(x, y, wcs, size, f);
+}
+
+
+Painter & GPainter::text(int x, int y,
+ char c, LyXFont const & f)
+{
+ char s[2] = { c, '\0' };
+ return text(x, y, s, 1, f);
+}
+
+
+inline XftFont * getXftFont(LyXFont const & f)
+{
+ return fontLoader.load(f.family(), f.series(),
+ f.realShape(), f.size());
+}
+
+
+namespace font_metrics
+{
+
+int width(wchar_t const *s, size_t n, LyXFont const & f);
+
+}
+
+
+Painter & GPainter::text(int x, int y, wchar_t const * s, int ls,
+ LyXFont const & f)
+{
+ XftFont * font = getXftFont(f);
+ XftColor * xftClr = owner_.getColorHandler().
+ getXftColor(f.realColor());
+// getXftColor(f.realColor());
+ XftDraw * draw = owner_.getXftDraw();
+ if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) {
+ XftDrawString32(draw, xftClr, font, x, y,
+ wcsToFcChar32StrFast(s), ls);
+ } else {
+ LyXFont smallfont(f);
+ smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
+ XftFont * fontS = getXftFont(smallfont);
+ wchar_t c;
+ int tmpx = x;
+ for(int i = 0; i < ls; ++i) {
+ c = lyx::support::uppercase(s[i]);
+ if(c != s[i]) {
+ XftDrawString32(draw, xftClr, fontS, tmpx, y,
+ wcsToFcChar32StrFast(&c), 1);
+ tmpx += font_metrics::width(c, smallfont);
+ } else {
+ XftDrawString32(draw, xftClr, font, tmpx, y,
+ wcsToFcChar32StrFast(&c), 1);
+ tmpx += font_metrics::width(c, f);
+ }
+ }
+ }
+ if (f.underbar() == LyXFont::ON)
+ underline(f, x, y, font_metrics::width(s, ls, f));
+ return *this;
+}
+
+
+Painter & GPainter::text(int x, int y,
+ char const * s, size_t ls,
+ LyXFont const & f)
+{
+ boost::scoped_array<wchar_t> wcs(new wchar_t[ls + 1]);
+ size_t len;
+ if (fontLoader.isSpecial(f)) {
+ unsigned char const * us =
+ reinterpret_cast<unsigned char const *>(s);
+ len = ls;
+ std::copy(us, us + ls, wcs.get());
+ } else
+ len = mbstowcs(wcs.get(), s, ls + 1);
+ return text(x, y, wcs.get(), len, f);
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file GPainter.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#ifndef GPAINTER_H
+#define GPAINTER_H
+
+#include <config.h>
+#include <X11/Xft/Xft.h>
+
+#include <map>
+#include "frontends/Painter.h"
+#include "LString.h"
+
+class LyXFont;
+class GWorkArea;
+
+/**
+ * GPainter - a painter implementation for Gtkmm
+ */
+class GPainter : public Painter {
+public:
+ GPainter(GWorkArea &);
+
+ /// return the width of the work area in pixels
+ virtual int paperWidth() const;
+ /// return the height of the work area in pixels
+ virtual int paperHeight() const;
+
+ void setForeground(Glib::RefPtr<Gdk::GC> gc, LColor::color clr);
+ void setLineParam(Glib::RefPtr<Gdk::GC> gc,
+ line_style ls, line_width lw);
+ XftColor * getXftColor(LColor::color clr);
+ /// draw a line from point to point
+ virtual Painter & line(
+ int x1, int y1,
+ int x2, int y2,
+ LColor::color = LColor::foreground,
+ line_style = line_solid,
+ line_width = line_thin);
+
+ /**
+ * lines - draw a set of lines
+ * @param xp array of points' x co-ords
+ * @param yp array of points' y co-ords
+ * @param np size of the points array
+ */
+ virtual Painter & lines(
+ int const * xp,
+ int const * yp,
+ int np,
+ LColor::color = LColor::foreground,
+ line_style = line_solid,
+ line_width = line_thin);
+
+ /// draw a rectangle
+ virtual Painter & rectangle(
+ int x, int y,
+ int w, int h,
+ LColor::color = LColor::foreground,
+ line_style = line_solid,
+ line_width = line_thin);
+
+ /// draw a filled rectangle
+ virtual Painter & fillRectangle(
+ int x, int y,
+ int w, int h,
+ LColor::color);
+
+ /// draw a filled (irregular) polygon
+ virtual Painter & fillPolygon(
+ int const * xp,
+ int const * yp,
+ int np,
+ LColor::color = LColor::foreground);
+
+ /// draw an arc
+ virtual Painter & arc(
+ int x, int y,
+ unsigned int w, unsigned int h,
+ int a1, int a2,
+ LColor::color = LColor::foreground);
+
+ /// draw a pixel
+ virtual Painter & point(
+ int x, int y,
+ LColor::color = LColor::foreground);
+
+ /// draw an image from the image cache
+ virtual Painter & image(int x, int y,
+ int w, int h,
+ lyx::graphics::Image const & image);
+
+ /// draw a string at position x, y (y is the baseline)
+ virtual Painter & text(int x, int y,
+ string const & str, LyXFont const & f);
+
+ /** Draw a string at position x, y (y is the baseline)
+ * This is just for fast drawing
+ */
+ virtual Painter & text(int x, int y,
+ char const * str, size_t l,
+ LyXFont const & f);
+
+ virtual Painter & text(int x, int y, wchar_t const * str, int l,
+ LyXFont const & f);
+
+ /// draw a char at position x, y (y is the baseline)
+ virtual Painter & text(int x, int y,
+ char c, LyXFont const & f);
+
+ /// draw a wide string at position x, y
+ Painter & text(int x, int y,
+ XChar2b const * str, size_t l,
+ LyXFont const & f);
+
+private:
+ /// our owner who we paint upon
+ GWorkArea & owner_;
+};
+
+#endif // XPAINTER_H
--- /dev/null
+// GPrint.C
+
+#include <config.h>
+#include <gtkmm.h>
+#include <libglademm.h>
+
+#include "GPrint.h"
+#include "ControlPrint.h"
+#include "support/filetools.h"
+#include "PrinterParams.h"
+#include "support/lstrings.h"
+
+
+GPrint::GPrint(Dialog & parent, string title)
+ : GViewCB<ControlPrint, GViewGladeB>(parent, title, false)
+{
+}
+
+
+void GPrint::apply()
+{
+ PrinterParams pp;
+ pp.target = printer_->get_active() ? PrinterParams::PRINTER : PrinterParams::FILE;
+ pp.printer_name = printerEntry_->get_text();
+ pp.file_name = printerEntry_->get_text();
+ pp.all_pages = all_->get_active();
+ pp.from_page = pp.to_page = 0;
+ if (!fromEntry_->get_text().empty()) {
+ pp.from_page = strToInt(fromEntry_->get_text());
+ if (!toEntry_->get_text().empty())
+ pp.to_page = strToInt(toEntry_->get_text());
+ }
+ pp.odd_pages = odd_->get_active();
+ pp.even_pages = even_->get_active();
+ pp.count_copies = number_->get_value_as_int();
+ pp.sorted_copies = sorted_->get_active();
+ pp.reverse_order = reverse_->get_active();
+ controller().params() = pp;
+}
+
+
+void GPrint::update()
+{
+ PrinterParams & pp = controller().params();
+ printer_->set_active(pp.target == PrinterParams::PRINTER);
+ printerEntry_->set_text(pp.printer_name);
+ fileEntry_->set_text(pp.file_name);
+ all_->set_active(pp.all_pages);
+
+ string const from = ( pp.from_page ? tostr(pp.from_page) : string() );
+ string const to = ( pp.to_page ? tostr(pp.to_page) : string() );
+ fromEntry_->set_text(from);
+ toEntry_->set_text(to);
+ odd_->set_active(pp.odd_pages);
+ even_->set_active(pp.even_pages);
+ reverse_->set_active(pp.reverse_order);
+ sorted_->set_active(pp.sorted_copies);
+ number_->set_value(pp.count_copies);
+ bool const enable_counter = pp.target == PrinterParams::PRINTER;
+ number_->set_sensitive(enable_counter);
+ sorted_->set_sensitive(enable_counter && pp.count_copies > 1);
+}
+
+
+void GPrint::updateUI()
+{
+ ButtonPolicy::SMInput activate = ButtonPolicy::SMI_VALID;
+ // disable OK/Apply buttons when file output is selected, but no file name entered
+ if (file_->get_active() && fileEntry_->get_text().empty())
+ activate = ButtonPolicy::SMI_INVALID;
+ // check 'from' and 'to' fields only when 'from/to' radio button is selected
+ if (fromTo_->get_active()) {
+ string from = fromEntry_->get_text();
+ string to = toEntry_->get_text();
+ if (from.empty() || (!to.empty() && strToInt(from) > strToInt(to)))
+ activate = ButtonPolicy::SMI_INVALID;
+ }
+ bool const enableCounter = printer_->get_active();
+ number_->set_sensitive(enableCounter);
+ bool const enableSorted = enableCounter && number_->get_value_as_int() > 1;
+ sorted_->set_sensitive(enableSorted);
+ bc().input(activate);
+}
+
+
+void GPrint::onBrowse()
+{
+ string const inName = fileEntry_->get_text();
+ string const outName = Glib::locale_to_utf8(controller().Browse(Glib::locale_from_utf8(inName)));
+ if (outName != inName && !outName.empty())
+ fileEntry_->set_text(outName);
+ if (!outName.empty())
+ file_->set_active(true);
+ updateUI();
+}
+
+
+void GPrint::onTargetEdit(Gtk::Entry const * who)
+{
+ if (who == fileEntry_)
+ file_->set_active(true);
+ else if (who == printerEntry_)
+ printer_->set_active(true);
+ updateUI();
+}
+
+
+void GPrint::onFromToEdit()
+{
+ fromTo_->set_active(true);
+ updateUI();
+}
+
+
+void GPrint::doBuild()
+{
+ string const gladeName = LibFileSearch("glade", "print", "glade");
+ xml_ = Gnome::Glade::Xml::create(gladeName);
+ xml_->get_widget("Printer", printer_);
+ xml_->get_widget("File", file_);
+ xml_->get_widget("All", all_);
+ xml_->get_widget("FromTo", fromTo_);
+ xml_->get_widget("Odd", odd_);
+ xml_->get_widget("Even", even_);
+ xml_->get_widget("Reverse", reverse_);
+ xml_->get_widget("Number", number_);
+ xml_->get_widget("Sorted", sorted_);
+ xml_->get_widget("FromEntry", fromEntry_);
+ xml_->get_widget("ToEntry", toEntry_);
+ xml_->get_widget("PrinterEntry", printerEntry_);
+ xml_->get_widget("FileEntry", fileEntry_);
+ Gtk::Button * ok;
+ Gtk::Button * cancel;
+ Gtk::Button * apply;
+ xml_->get_widget("OkButton", ok);
+ xml_->get_widget("CancelButton", cancel);
+ xml_->get_widget("ApplyButton", apply);
+ bc().setOK(ok);
+ bc().setApply(apply);
+ bc().setCancel(cancel);
+ ok->signal_clicked().connect(SigC::slot(*this, &GViewBase::onOK));
+ apply->signal_clicked().connect(SigC::slot(*this, &GViewBase::onApply));
+ cancel->signal_clicked().connect(SigC::slot(*this, &GViewBase::onCancel));
+ Gtk::Button * browse;
+ xml_->get_widget("Browse", browse);
+ browse->signal_clicked().connect(SigC::slot(*this, &GPrint::onBrowse));
+ fileEntry_->signal_changed().connect(SigC::bind(SigC::slot(*this, &GPrint::onTargetEdit), fileEntry_));
+ printerEntry_->signal_changed().connect(SigC::bind(SigC::slot(*this, &GPrint::onTargetEdit), printerEntry_));
+ fromEntry_->signal_changed().connect(SigC::slot(*this, &GPrint::onFromToEdit));
+ toEntry_->signal_changed().connect(SigC::slot(*this, &GPrint::onFromToEdit));
+ printer_->signal_toggled().connect(SigC::slot(*this, &GPrint::updateUI));
+ file_->signal_toggled().connect(SigC::slot(*this, &GPrint::updateUI));
+ all_->signal_toggled().connect(SigC::slot(*this, &GPrint::updateUI));
+ fromTo_->signal_toggled().connect(SigC::slot(*this, &GPrint::updateUI));
+ number_->signal_changed().connect(SigC::slot(*this, &GPrint::updateUI));
+}
--- /dev/null
+// -*- C++ -*-
+/*
+ * /file GPrint.h
+ */
+
+#ifndef GPRINT_H
+#define GPRINT_H
+
+#include "LString.h"
+#include "GViewBase.h"
+
+class ControlPrint;
+
+class GPrint : public GViewCB<ControlPrint, GViewGladeB>
+{
+public:
+ GPrint(Dialog & parent, string title = "Print Document");
+private:
+ virtual void apply();
+ virtual void update();
+ virtual void doBuild();
+ void updateUI();
+ void onBrowse();
+ void onTargetEdit(Gtk::Entry const * who);
+ void onFromToEdit();
+
+ Gtk::RadioButton * printer_;
+ Gtk::RadioButton * file_;
+ Gtk::RadioButton * all_;
+ Gtk::RadioButton * fromTo_;
+ Gtk::CheckButton * odd_;
+ Gtk::CheckButton * even_;
+ Gtk::CheckButton * reverse_;
+ Gtk::SpinButton * number_;
+ Gtk::CheckButton * sorted_;
+ Gtk::Entry * printerEntry_;
+ Gtk::Entry * fileEntry_;
+ Gtk::Entry * fromEntry_;
+ Gtk::Entry * toEntry_;
+};
+
+#endif
+
--- /dev/null
+/**
+ * \file GScreen.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+
+#include <algorithm>
+
+#include "frontends/screen.h"
+#include "frontends/font_metrics.h"
+#include "GWorkArea.h"
+#include "GScreen.h"
+#include "lyxtext.h"
+#include "lyxrow.h"
+#include "Painter.h"
+#include "WorkArea.h"
+#include "buffer.h"
+#include "BufferView.h"
+#include "insets/insettext.h"
+#include "language.h"
+#include "debug.h"
+
+
+GScreen::GScreen(GWorkArea & o)
+ : LyXScreen(), owner_(o)
+{
+ // the cursor isnt yet visible
+ cursorX_ = 0;
+ cursorY_ = 0;
+ cursorW_ = 0;
+ cursorH_ = 0;
+}
+
+
+GScreen::~GScreen()
+{
+}
+
+
+void GScreen::setCursorColor(Glib::RefPtr<Gdk::GC> gc)
+{
+ Gdk::Color * clr = owner_.getColorHandler().
+ getGdkColor(LColor::cursor);
+ gc->set_foreground(*clr);
+}
+
+
+void GScreen::showCursor(int x, int y,
+ int h, Cursor_Shape shape)
+{
+ // Update the cursor color.
+ setCursorColor(owner_.getGC());
+
+ cursorX_ = x;
+ cursorY_ = y;
+ cursorH_ = h;
+
+ switch (shape) {
+ case BAR_SHAPE:
+ cursorW_ = 1;
+ break;
+ case L_SHAPE:
+ cursorW_ = cursorH_ / 3;
+ break;
+ case REVERSED_L_SHAPE:
+ cursorW_ = cursorH_ / 3;
+ cursorX_ = x - cursorW_ + 1;
+ break;
+ }
+
+ int fx, fy, fwidth, fheight, fdepth;
+ owner_.getWindow()->get_geometry(fx, fy, fwidth, fheight, fdepth);
+ cursorPixmap_ = Gdk::Pixmap::create(owner_.getWindow(),
+ cursorW_,
+ cursorH_,
+ fdepth);
+ cursorPixmap_->draw_drawable(owner_.getGC(),
+ owner_.getWindow(),
+ owner_.xpos() + cursorX_,
+ owner_.ypos() + cursorY_,
+ 0, 0,
+ cursorW_,
+ cursorH_);
+ owner_.getWindow()->draw_line(owner_.getGC(),
+ x + owner_.xpos(),
+ y + owner_.ypos(),
+ x + owner_.xpos(),
+ y + h - 1 + owner_.ypos());
+ switch (shape) {
+ case BAR_SHAPE:
+ break;
+ case L_SHAPE:
+ case REVERSED_L_SHAPE:
+ owner_.getWindow()->draw_line(owner_.getGC(),
+ owner_.xpos() + cursorX_,
+ owner_.ypos() + y + h - 1,
+ owner_.xpos() + cursorX_ + cursorW_ - 1,
+ owner_.xpos() + y + h - 1);
+ break;
+ }
+}
+
+
+void GScreen::removeCursor()
+{
+ if (cursorPixmap_) {
+ owner_.getWindow()->draw_drawable(owner_.getGC(),
+ cursorPixmap_,
+ 0, 0,
+ cursorX_ + owner_.xpos(),
+ cursorY_ + owner_.ypos(),
+ cursorW_, cursorH_);
+ }
+}
+
+
+void GScreen::expose(int x, int y, int w, int h)
+{
+ lyxerr[Debug::GUI] << "expose " << w << 'x' << h
+ << '+' << x << '+' << y << std::endl;
+ owner_.getWindow()->draw_drawable(owner_.getGC(),
+ owner_.getPixmap(),
+ x, y,
+ x + owner_.xpos(),
+ y + owner_.ypos(),
+ w, h);
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file GScreen.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#ifndef GSCREEN_H
+#define GSCREEN_H
+
+#include "screen.h"
+
+class GWorkArea;
+
+/** The class GScreen is used for the main Textbody.
+ Concretely, the screen is held in a pixmap. This pixmap is kept up to
+ date and used to optimize drawing on the screen.
+ This class also handles the drawing of the cursor and partly the selection.
+ */
+class GScreen : public LyXScreen {
+public:
+ ///
+ GScreen(GWorkArea &);
+
+ ///
+ virtual ~GScreen();
+
+ /// Sets the cursor color to LColor::cursor.
+ virtual void setCursorColor(Glib::RefPtr<Gdk::GC> gc);
+ ///
+ virtual void removeCursor();
+ ///
+ virtual void showCursor(int x, int y, int h,
+ Cursor_Shape shape);
+
+protected:
+ /// get the work area
+ virtual WorkArea & workarea() const { return owner_; }
+
+ /// Copies specified area of pixmap to screen
+ virtual void expose(int x, int y, int w, int h);
+
+private:
+ /// our owning widget
+ GWorkArea & owner_;
+
+ ///
+ Glib::RefPtr<Gdk::Pixmap> cursorPixmap_;
+ ///
+ int cursorX_;
+ ///
+ int cursorY_;
+ ///
+ int cursorW_;
+ ///
+ int cursorH_;
+};
+
+#endif
--- /dev/null
+/**
+ * \file GText.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+#include <libglademm.h>
+
+#include "support/lstrings.h"
+#include "support/filetools.h"
+#include "ControlCommand.h"
+#include "GText.h"
+#include "IdSc.h"
+
+GText::GText(Dialog & parent, string const & title, string const & label)
+ : GViewCB<ControlCommand, GViewGladeB>(parent, title),
+ label_(label), entry_(0)
+{
+}
+
+void GText::apply()
+{
+ string const contents = Glib::locale_from_utf8(entry_->get_text());
+ controller().params().setContents(contents);
+}
+
+void GText::update()
+{
+ string const contents = lyx::support::trim(
+ controller().params().getContents());
+ entry_->set_text(Glib::locale_to_utf8(contents));
+}
+
+void GText::doBuild()
+{
+ string const gladeName =
+ lyx::support::LibFileSearch("glade", "text", "glade");
+ xml_ = Gnome::Glade::Xml::create(gladeName);
+ Gtk::Label * label;
+ Gtk::Button * restore;
+ Gtk::Button * cancel;
+ Gtk::Button * apply;
+ Gtk::Button * ok;
+ xml_->get_widget("Label", label);
+ xml_->get_widget("Text", entry_);
+ xml_->get_widget("Restore", restore);
+ xml_->get_widget("Cancel", cancel);
+ xml_->get_widget("Apply", apply);
+ xml_->get_widget("OK", ok);
+ label->set_text(Glib::locale_to_utf8(id_sc::id(label_)));
+ bcview().setOK(ok);
+ bcview().setApply(apply);
+ bcview().setCancel(cancel);
+ bcview().setRestore(restore);
+ bcview().addReadOnly(entry_);
+ ok->signal_clicked().connect(
+ SigC::slot(*this, &GViewBase::onOK));
+ apply->signal_clicked().connect(
+ SigC::slot(*this, &GViewBase::onApply));
+ cancel->signal_clicked().connect(
+ SigC::slot(*this, &GViewBase::onCancel));
+ restore->signal_clicked().connect(
+ SigC::slot(*this, &GViewBase::onRestore));
+ entry_->signal_changed().connect(
+ SigC::slot(*this, >ext::onEntryChanged));
+}
+
+void GText::onEntryChanged()
+{
+ bc().valid(!entry_->get_text().empty());
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file GText.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#ifndef GTEXT_H
+#define GTEXT_H
+
+#include "GViewBase.h"
+#include "LString.h"
+
+class ControlCommand;
+
+class GText : public GViewCB<ControlCommand, GViewGladeB>
+{
+public:
+ GText(Dialog & parent, string const & title, string const & label);
+private:
+ virtual void apply();
+ virtual void update();
+ virtual void doBuild();
+ void onEntryChanged();
+ string const label_;
+ Gtk::Entry * entry_;
+};
+
+#endif
--- /dev/null
+/**
+ * \file gtk/GTimeout.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Baruch Even
+ * \author Michael Koziarski
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+
+#include "GTimeout.h"
+#include "debug.h"
+
+
+Timeout::Timeout(unsigned int msec, Type t)
+ : pimpl_(new GTimeout(*this)), type(t), timeout_ms(msec)
+{}
+
+
+GTimeout::GTimeout(Timeout & owner)
+ : Timeout::Impl(owner)
+{
+}
+
+
+void GTimeout::reset()
+{
+ stop();
+}
+
+
+bool GTimeout::running() const
+{
+ return running_;
+}
+
+
+void GTimeout::start()
+{
+ if (conn_.connected()) {
+ lyxerr << "Timeout::start: already running!" << std::endl;
+ stop();
+ }
+
+ conn_ = Glib::signal_timeout().connect(
+ SigC::slot(*this, >imeout::timeoutEvent),
+ timeout_ms()
+ );
+ running_ = true;
+}
+
+
+void GTimeout::stop()
+{
+ conn_.disconnect();
+ running_ = false;
+}
+
+
+bool GTimeout::timeoutEvent()
+{
+ emit();
+ return false; // discontinue emitting timeouts.
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file gtk/GTimeout.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Baruch Even
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#ifndef GTIMEOUT_H
+#define GTIMEOUT_H
+
+#include "frontends/Timeout.h"
+
+#include <sigc++/sigc++.h>
+
+/**
+ * This class executes the callback when the timeout expires
+ * using Gtk mechanisms
+ */
+class GTimeout : public Timeout::Impl, public SigC::Object {
+public:
+ ///
+ GTimeout(Timeout & owner_);
+ /// start the timer
+ void start();
+ /// stop the timer
+ void stop();
+ /// reset
+ void reset();
+ /// Is the timer running?
+ bool running() const;
+
+public:
+ /// The timeout signal, this gets called when the timeout passed.
+ bool timeoutEvent();
+private:
+ /// Timer connection
+ SigC::Connection conn_;
+ /// Used for running as SigC::Connection::connected() isn't const
+ bool running_;
+};
+
+#endif
--- /dev/null
+/**
+ * \file GToolbar.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+
+#include "GToolbar.h"
+#include "GView.h"
+#include "LyXAction.h"
+#include "lyxfunc.h"
+#include "FuncStatus.h"
+#include "buffer.h"
+#include "funcrequest.h"
+#include "gettext.h"
+#include "Tooltips.h"
+#include "support/filetools.h"
+#include "support/lstrings.h"
+#include "debug.h"
+
+
+namespace
+{
+
+
+char const * gToolData = "tool_data";
+
+
+inline void comboClear(Gtk::Combo & combo)
+{
+ std::vector<Glib::ustring> strings;
+ strings.push_back("");
+ combo.set_popdown_strings(strings);
+}
+
+
+inline bool comboIsEmpty(Gtk::Combo & combo)
+{
+ std::vector<Glib::ustring> strings = combo.get_popdown_strings();
+ return (strings.empty() || (strings.size() == 1 && strings[0] == ""));
+}
+
+
+}
+
+
+GToolbar::GToolbar(LyXView * lyxView, int /*x*/, int /*y*/)
+ : view_(lyxView), internal_(false)
+{
+ combo_.set_value_in_list();
+ combo_.get_entry()->set_editable(false);
+ combo_.unset_flags(Gtk::CAN_FOCUS | Gtk::CAN_DEFAULT);
+ combo_.get_entry()->unset_flags(Gtk::CAN_FOCUS | Gtk::CAN_DEFAULT);
+ comboClear(combo_);
+ combo_.get_entry()->signal_changed().connect(
+ SigC::slot(*this,
+ >oolbar::onLayoutSelected));
+ GView * gview = static_cast<GView*>(lyxView);
+ vbox_.show();
+ Gtk::VBox & vbox = gview->getVBox();
+ vbox.children().push_back(Gtk::Box_Helpers::Element(vbox_,
+ Gtk::PACK_SHRINK));
+}
+
+
+GToolbar::~GToolbar()
+{
+}
+
+
+void GToolbar::add(ToolbarBackend::Toolbar const & tb)
+{
+ Gtk::Toolbar * toolbar = manage(new Gtk::Toolbar());
+ ToolbarBackend::item_iterator it = tb.items.begin();
+ ToolbarBackend::item_iterator end = tb.items.end();
+ for (; it != end; ++it)
+ add(toolbar, it->first, it->second);
+ toolbar->set_toolbar_style(Gtk::TOOLBAR_ICONS);
+ toolbar->show();
+ vbox_.children().push_back(
+ Gtk::Box_Helpers::Element(*toolbar,
+ Gtk::PACK_SHRINK));
+ toolbars_.push_back(toolbar);
+}
+
+
+void GToolbar::add(Gtk::Toolbar * toolbar,
+ int action,
+ string const & tooltip)
+{
+ switch (action) {
+ case ToolbarBackend::SEPARATOR:
+ toolbar->tools().push_back(Gtk::Toolbar_Helpers::Space());
+ break;
+ case ToolbarBackend::MINIBUFFER:
+ // Not supported yet.
+ break;
+ case ToolbarBackend::LAYOUTS:
+ {
+ combo_.show();
+ toolbar->tools().push_back(
+ Gtk::Toolbar_Helpers::Element(combo_));
+ toolbar->tools().back().get_widget()->set_data(
+ gToolData,
+ reinterpret_cast<void*>(LFUN_LAYOUT));
+ break;
+ }
+ default:
+ {
+ Glib::ustring xpmName =
+ Glib::locale_to_utf8(toolbarbackend.getIcon(action));
+ Glib::ustring tip = Glib::locale_to_utf8(tooltip);
+ if (xpmName.size() == 0) {
+ toolbar->tools().push_back(
+ Gtk::Toolbar_Helpers::ButtonElem(
+ "",
+ SigC::bind(SigC::slot(*this, >oolbar::onButtonClicked),
+ action),
+ tip));
+ } else {
+ Gtk::Image * image =
+ Gtk::manage(new Gtk::Image(xpmName));
+ image->show();
+ toolbar->tools().push_back(
+ Gtk::Toolbar_Helpers::ButtonElem(
+ "",
+ *image,
+ SigC::bind(SigC::slot(*this, >oolbar::onButtonClicked),
+ action),
+ tip));
+ }
+ toolbar->tools().back().get_content()->set_data(
+ gToolData,
+ reinterpret_cast<void*>(action));
+ break;
+ }
+ }
+}
+
+
+void GToolbar::onButtonClicked(int action)
+{
+ view_->getLyXFunc().dispatch(action, true);
+}
+
+
+void GToolbar::onLayoutSelected()
+{
+ if (internal_)
+ return;
+ string layoutGuiName = combo_.get_entry()->get_text();
+ // we get two signal, one of it is empty and useless
+ if (layoutGuiName.empty())
+ return;
+ LyXTextClass const & tc =
+ view_->buffer()->params.getLyXTextClass();
+
+ LyXTextClass::const_iterator end = tc.end();
+ for (LyXTextClass::const_iterator cit = tc.begin();
+ cit != end; ++cit) {
+ if ((*cit)->name() == layoutGuiName) {
+ view_->getLyXFunc().dispatch(
+ FuncRequest(LFUN_LAYOUT, (*cit)->name()),
+ true);
+ return;
+ }
+ }
+ lyxerr << "ERROR (GToolbar::layoutSelected): layout not found! name : "
+ << layoutGuiName
+ << std::endl;
+}
+
+
+void GToolbar::displayToolbar(ToolbarBackend::Toolbar const & /*tb*/, bool /*show*/)
+{
+}
+
+
+void GToolbar::update()
+{
+ std::vector<Gtk::Toolbar*>::iterator itToolbar;
+ for (itToolbar = toolbars_.begin();
+ itToolbar != toolbars_.end(); ++itToolbar) {
+ Gtk::Toolbar * toolbar = *itToolbar;
+ Gtk::Toolbar_Helpers::ToolList::iterator it;
+ for (it = toolbar->tools().begin();
+ it != toolbar->tools().end(); ++it) {
+ Gtk::Widget * widget;
+ switch (it->get_type()) {
+ case Gtk::TOOLBAR_CHILD_WIDGET:
+ widget = it->get_widget();
+ break;
+ case Gtk::TOOLBAR_CHILD_SPACE:
+ continue;
+ default:
+ widget = it->get_content();
+ }
+ int action = reinterpret_cast<int>(
+ widget->get_data(gToolData));
+ FuncStatus const status = view_->
+ getLyXFunc().getStatus(action);
+ bool sensitive = !status.disabled();
+ widget->set_sensitive(sensitive);
+ if (it->get_type() != Gtk::TOOLBAR_CHILD_BUTTON)
+ return;
+ if (status.onoff(true))
+ static_cast<Gtk::Button*>(widget)->
+ set_relief(Gtk::RELIEF_NORMAL);
+ if (status.onoff(false))
+ static_cast<Gtk::Button*>(widget)->
+ set_relief(Gtk::RELIEF_NONE);
+ }
+ }
+}
+
+
+void GToolbar::setLayout(string const & layout)
+{
+ LyXTextClass const & tc =
+ view_->buffer()->params.getLyXTextClass();
+ internal_ = true;
+ combo_.get_entry()->set_text(tc[layout]->name());
+ internal_ = false;
+}
+
+
+void GToolbar::updateLayoutList()
+{
+ LyXTextClass const & tc =
+ view_->buffer()->params.getLyXTextClass();
+ LyXTextClass::const_iterator end = tc.end();
+ std::vector<Glib::ustring> strings;
+ for (LyXTextClass::const_iterator cit = tc.begin();
+ cit != end; ++cit)
+ if ((*cit)->obsoleted_by().empty())
+ strings.push_back(
+ Glib::locale_to_utf8((*cit)->name()));
+ internal_ = true;
+ combo_.set_popdown_strings(strings);
+ internal_ = false;
+}
+
+
+void GToolbar::openLayoutList()
+{
+ combo_.get_list()->activate();
+}
+
+
+void GToolbar::clearLayoutList()
+{
+ internal_ = true;
+ comboClear(combo_);
+ internal_ = false;
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file GToolbar.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#ifndef TOOLBAR_PIMPL_H
+#define TOOLBAR_PIMPL_H
+
+#include <gtkmm.h>
+#include "frontends/Toolbar.h"
+#include "ToolbarBackend.h"
+#include "LString.h"
+
+class GToolbar : public Toolbar, public SigC::Object
+{
+public:
+ GToolbar(LyXView * o, int x, int y);
+
+ ~GToolbar();
+
+ // add a new toolbar
+ void add(ToolbarBackend::Toolbar const & tb);
+
+ /// add a new button to the toolbar.
+ void add(Gtk::Toolbar * toolbar,
+ int action,
+ string const & tooltip);
+
+ /// display toolbar, not implemented
+ void displayToolbar(ToolbarBackend::Toolbar const & tb, bool show);
+
+ /// update the state of the icons
+ void update();
+
+ /// select the right layout in the combox
+ void setLayout(string const & layout);
+
+ /// Populate the layout combox; re-do everything if force is true.
+ void updateLayoutList();
+
+ /// Drop down the layout list
+ void openLayoutList();
+
+ /// Erase the layout list
+ void clearLayoutList();
+private:
+ void onButtonClicked(int action);
+ void onLayoutSelected();
+ Gtk::VBox vbox_;
+ std::vector<Gtk::Toolbar*> toolbars_;
+ Gtk::Combo combo_;
+ LyXView * view_;
+ bool internal_;
+};
+
+#endif
--- /dev/null
+/**
+ * \file GView.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+
+#include "GView.h"
+#include "MenuBackend.h"
+#include "support/filetools.h"
+#include "GMenubar.h"
+#include "GToolbar.h"
+#include "BufferView.h"
+#include "XWorkArea.h"
+#include "lyx_cb.h"
+#include "GMiniBuffer.h"
+#include "lyxfunc.h"
+#include <boost/bind.hpp>
+
+BufferView * current_view;
+
+GView * GView::view_ = 0;
+
+
+GView::GView()
+{
+ view_ = this;
+ vbox_.reset(new Gtk::VBox());
+ add(*vbox_.get());
+ menubar_.reset(new GMenubar(this, menubackend));
+ toolbar_.reset(new GToolbar(this, 0, 0));
+ toolbar_->init();
+ bufferview_.reset(new BufferView(this, 0, 0, 300, 300));
+ ::current_view = bufferview_.get();
+ minibuffer_.reset(new GMiniBuffer(this, *controlcommand_));
+ vbox_->show();
+ focus_command_buffer.connect(
+ boost::bind(&GMiniBuffer::editMode, minibuffer_.get()));
+ view_state_changed.connect(boost::bind(&GView::showViewState, this));
+ signal_focus_in_event().connect(SigC::slot(*this, &GView::onFocusIn));
+ set_default_size(500, 550);
+ // Make sure the buttons are disabled if needed.
+ updateToolbar();
+ string const iconName =
+ lyx::support::LibFileSearch("images", "lyx", "xpm");
+ if (!iconName.empty())
+ set_icon_from_file(iconName);
+}
+
+
+GView::~GView()
+{
+}
+
+
+bool GView::on_delete_event(GdkEventAny * /*event*/)
+{
+ QuitLyX();
+ return true;
+}
+
+
+bool GView::onFocusIn(GdkEventFocus * /*event*/)
+{
+ workArea_->grab_focus();
+ return true;
+}
+
+
+void GView::prohibitInput() const
+{
+ view()->hideCursor();
+ const_cast<GView*>(this)->set_sensitive(false);
+}
+
+
+void GView::allowInput() const
+{
+ const_cast<GView*>(this)->set_sensitive(true);
+}
+
+
+void GView::message(string const & msg)
+{
+ minibuffer_->message(msg);
+}
+
+
+void GView::showViewState()
+{
+ message(getLyXFunc().view_status_message());
+}
+
+
+void GView::setWindowTitle(string const & t, string const & /*it*/)
+{
+ set_title(Glib::locale_to_utf8(t));
+}
+
+
+void GView::busy(bool yes) const
+{
+ if (yes ) {
+ view()->hideCursor();
+ Gdk::Cursor cursor(Gdk::WATCH);
+ const_cast<GView*>(this)->get_window()->set_cursor(cursor);
+ const_cast<GView*>(this)->set_sensitive(false);
+ } else {
+ const_cast<GView*>(this)->get_window()->set_cursor();
+ const_cast<GView*>(this)->set_sensitive(true);
+ }
+}
+
+
+void GView::clearMessage()
+{
+ message(getLyXFunc().view_status_message());
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file GView.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#ifndef GVIEW_H
+#define GVIEW_H
+
+#include "frontends/LyXView.h"
+#include "bufferview_funcs.h"
+#include <memory>
+class GMiniBuffer;
+
+class GView : public LyXView, public Gtk::Window
+{
+public:
+ virtual ~GView();
+
+ virtual void prohibitInput() const;
+ virtual void allowInput() const;
+ virtual void message(string const &);
+ Gtk::VBox & getVBox() { return *vbox_.get(); }
+ GView();
+ bool on_delete_event(GdkEventAny * event);
+ void focusWorkArea() { workArea_->grab_focus(); }
+ void setGWorkArea(Gtk::Widget * w) { workArea_ = w; }
+ static GView * instance() { return view_; }
+ /// show busy cursor
+ virtual void busy(bool) const;
+ /// clear any temporary message and replace with current status
+ virtual void clearMessage();
+private:
+ void showViewState();
+ bool onFocusIn(GdkEventFocus * event);
+ virtual void setWindowTitle(string const & t, string const & it);
+ static GView * view_;
+ std::auto_ptr<Gtk::VBox> vbox_;
+ boost::scoped_ptr<GMiniBuffer> minibuffer_;
+ Gtk::Widget * workArea_;
+};
+
+#endif
--- /dev/null
+/**
+ * \file GViewBase.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+
+#include "GViewBase.h"
+#include "ControlButtons.h"
+#include "support/filetools.h"
+
+
+GViewBase::GViewBase(Dialog & parent, string const & t, bool allowResize) :
+ Dialog::View(parent, t), allowResize_(allowResize)
+{
+}
+
+
+GViewBase::~GViewBase()
+{
+}
+
+
+void GViewBase::hide()
+{
+ window()->hide();
+}
+
+
+void GViewBase::build()
+{
+ doBuild();
+ string const iconName =
+ lyx::support::LibFileSearch("images", "lyx", "xpm");
+ if (!iconName.empty())
+ window()->set_icon_from_file(iconName);
+ window()->signal_delete_event().connect(
+ SigC::slot(*this, &GViewBase::onDeleteEvent));
+ window()->set_title(Glib::locale_to_utf8(getTitle()));
+}
+
+
+void GViewBase::show()
+{
+ if (!window()) {
+ build();
+ }
+ window()->show();
+}
+
+
+bool GViewBase::isVisible() const
+{
+ return window() && window()->is_visible();
+}
+
+
+GBC & GViewBase::bcview()
+{
+ return static_cast<GBC &>(dialog().bc().view());
+}
+
+
+void GViewBase::onApply()
+{
+ dialog().ApplyButton();
+}
+
+
+void GViewBase::onOK()
+{
+ dialog().OKButton();
+}
+
+
+void GViewBase::onCancel()
+{
+ dialog().CancelButton();
+}
+
+
+void GViewBase::onRestore()
+{
+ dialog().RestoreButton();
+}
+
+
+bool GViewBase::onDeleteEvent(GdkEventAny *)
+{
+ dialog().CancelButton();
+ return false;
+}
+
+
+GViewGladeB::GViewGladeB(Dialog & parent, string const & t, bool allowResize) :
+ GViewBase(parent, t, allowResize)
+{
+}
+
+
+Gtk::Window * GViewGladeB::window()
+{
+ Gtk::Window * win;
+ if (!xml_)
+ return 0;
+ xml_->get_widget("dialog", win);
+ return win;
+}
+
+
+const Gtk::Window * GViewGladeB::window() const
+{
+ Gtk::Window * win;
+ if (!xml_)
+ return 0;
+ xml_->get_widget("dialog", win);
+ return win;
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file GViewBase.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#ifndef GVIEWBASE_H
+#define GVIEWBASE_H
+
+#include <gtkmm.h>
+#include <libglademm.h>
+#include <boost/scoped_ptr.hpp>
+#include "Dialog.h"
+#include "ButtonPolicies.h"
+#include "GBC.h"
+
+class GViewBase : public Dialog::View, public SigC::Object
+{
+public:
+ GViewBase(Dialog &, string const &, bool allowResize);
+ virtual ~GViewBase();
+protected:
+ // Build the dialog
+ virtual void build();
+ virtual void doBuild() = 0;
+ // Hide the dialog
+ virtual void hide();
+ // Create the dialog if necessary, update it and display it.
+ virtual void show();
+ //
+ virtual bool isVisible() const;
+ GBC & bcview();
+ void onApply();
+ void onOK();
+ void onCancel();
+ void onRestore();
+ bool onDeleteEvent(GdkEventAny *);
+private:
+ virtual Gtk::Window * window() = 0;
+ virtual Gtk::Window const * window() const = 0;
+ bool allowResize_;
+};
+
+template <class Dialog>
+class GViewDB : public GViewBase
+{
+protected:
+ GViewDB(Dialog &, string const &, bool allowResize);
+ virtual const Gtk::Window * window() const;
+ virtual Gtk::Window * window();
+ boost::scoped_ptr<Dialog> dialog_;
+};
+
+
+template <class Dialog>
+GViewDB<Dialog>::GViewDB(Dialog & parent, string const & t, bool allowResize) :
+ GViewBase(parent, t, allowResize)
+{
+}
+
+
+template <class Dialog>
+Gtk::Window * GViewDB<Dialog>::window()
+{
+ return dialog_.get();
+}
+
+
+template <class Dialog>
+const Gtk::Window * GViewDB<Dialog>::window() const
+{
+ return dialog_.get();
+}
+
+
+class GViewGladeB : public GViewBase
+{
+protected:
+ GViewGladeB(Dialog & parent, string const & t, bool allowResize);
+ virtual const Gtk::Window * window() const;
+ virtual Gtk::Window * window();
+ Glib::RefPtr<Gnome::Glade::Xml> xml_;
+};
+
+
+template <class Controller, class Base>
+class GViewCB : public Base
+{
+public:
+ Controller & controller();
+ Controller const & controller() const;
+protected:
+ GViewCB(Dialog & parent, string const & t, bool allowResize = false);
+};
+
+
+template <class Controller, class Base>
+GViewCB<Controller, Base>::GViewCB(Dialog & parent, string const & t,
+ bool allowResize) :
+ Base(parent, t, allowResize)
+{
+}
+
+
+template <class Controller, class Base>
+Controller & GViewCB<Controller, Base>::controller()
+{
+ return static_cast<Controller &>(getController());
+}
+
+
+template <class Controller, class Base>
+Controller const & GViewCB<Controller, Base>::controller() const
+{
+ return static_cast<Controller const &>(getController());
+}
+
+#endif
--- /dev/null
+/**
+ * \file GWorkArea.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+#include <X11/Xft/Xft.h>
+
+#include "GWorkArea.h"
+#include "debug.h"
+#include "funcrequest.h"
+#include "GView.h"
+#include "GtkmmX.h"
+#include "GLyXKeySym.h"
+
+ColorCache colorCache;
+
+
+void ColorCache::clear()
+{
+ MapIt it = cache_.begin();
+ for (; it != cache_.end(); ++it)
+ delete it->second;
+ cache_.clear();
+ MapIt2 it2 = cache2_.begin();
+ for (; it2 != cache2_.end(); ++it2)
+ delete it2->second;
+ cache2_.clear();
+}
+
+
+XftColor * ColorHandler::getXftColor(LColor::color clr)
+{
+ XftColor * xclr = colorCache.getXftColor(clr);
+ if (!xclr) {
+ xclr = new XftColor;
+ Colormap colormap = GDK_COLORMAP_XCOLORMAP(
+ owner_.getColormap()->gobj());
+ Visual * visual = GDK_VISUAL_XVISUAL(
+ owner_.getColormap()->get_visual()->gobj());
+ XftColorAllocName(owner_.getDisplay(), visual, colormap,
+ lcolor.getX11Name(clr).c_str(), xclr);
+ colorCache.cacheXftColor(clr, xclr);
+ }
+ return xclr;
+}
+
+
+Gdk::Color * ColorHandler::getGdkColor(LColor::color clr)
+{
+ Gdk::Color * gclr = colorCache.getColor(clr);
+ if (!gclr) {
+ gclr = new Gdk::Color;
+ gclr->parse(lcolor.getX11Name(clr));
+ owner_.getColormap()->alloc_color(*gclr);
+ colorCache.cacheColor(clr, gclr);
+ }
+ return gclr;
+}
+
+
+namespace
+{
+
+
+mouse_button::state gtkButtonState(unsigned int state)
+{
+ mouse_button::state b = mouse_button::none;
+ if (state & GDK_BUTTON1_MASK)
+ b = mouse_button::button1;
+ else if (state & GDK_BUTTON2_MASK)
+ b = mouse_button::button2;
+ else if (state & GDK_BUTTON3_MASK)
+ b = mouse_button::button3;
+ else if (state & GDK_BUTTON3_MASK)
+ b = mouse_button::button3;
+ else if (state & GDK_BUTTON4_MASK)
+ b = mouse_button::button4;
+ else if (state & GDK_BUTTON5_MASK)
+ b = mouse_button::button5;
+ return b;
+}
+
+
+key_modifier::state gtkKeyState(guint state)
+{
+ key_modifier::state k = key_modifier::none;
+ if (state & GDK_CONTROL_MASK)
+ k |= key_modifier::ctrl;
+ if (state & GDK_SHIFT_MASK)
+ k |= key_modifier::shift;
+ if (state & GDK_MOD1_MASK)
+ k |= key_modifier::alt;
+ return k;
+}
+
+
+void inputCommitRelay(GtkIMContext */*imcontext*/, gchar * str, GWorkArea * area)
+{
+ area->inputCommit(str);
+}
+
+
+}
+
+
+GWorkArea::GWorkArea(int width, int height)
+ : workAreaPixmap_(0), painter_(*this), draw_(0), colorHandler_(*this)
+{
+ workArea_.set_size_request(width, height);
+ workArea_.set_double_buffered(false);
+ workArea_.add_events(Gdk::STRUCTURE_MASK | Gdk::EXPOSURE_MASK |
+ Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK |
+ Gdk::KEY_PRESS_MASK | Gdk::BUTTON1_MOTION_MASK);
+ workArea_.signal_expose_event().connect(
+ SigC::slot(*this, &GWorkArea::onExpose));
+ workArea_.signal_configure_event().connect(
+ SigC::slot(*this, &GWorkArea::onConfigure));
+ workArea_.signal_button_press_event().connect(
+ SigC::slot(*this, &GWorkArea::onButtonPress));
+ workArea_.signal_button_release_event().connect(
+ SigC::slot(*this, &GWorkArea::onButtonRelease));
+ workArea_.signal_key_press_event().connect(
+ SigC::slot(*this, &GWorkArea::onKeyPress));
+ workArea_.signal_motion_notify_event().connect(
+ SigC::slot(*this, &GWorkArea::onMotionNotify));
+ workArea_.show();
+ vscrollbar_.get_adjustment()->signal_value_changed().connect(
+ SigC::slot(*this, &GWorkArea::onScroll));
+ vscrollbar_.show();
+ hbox_.children().push_back(Gtk::Box_Helpers::Element(workArea_));
+ hbox_.children().push_back(
+ Gtk::Box_Helpers::Element(vscrollbar_,Gtk::PACK_SHRINK));
+ hbox_.show();
+ GView::instance()->getVBox().children().push_back(
+ Gtk::Box_Helpers::Element(hbox_));
+ workArea_.set_flags(workArea_.get_flags() | Gtk::CAN_DEFAULT |
+ Gtk::CAN_FOCUS);
+ workArea_.grab_default();
+ GView::instance()->setGWorkArea(&workArea_);
+ imContext_ = GTK_IM_CONTEXT(gtk_im_multicontext_new());
+ g_signal_connect(G_OBJECT(imContext_), "commit",
+ G_CALLBACK(&inputCommitRelay),
+ this);
+}
+
+
+GWorkArea::~GWorkArea()
+{
+ g_object_unref(imContext_);
+}
+
+
+bool GWorkArea::onExpose(GdkEventExpose * event)
+{
+ workArea_.get_window()->draw_drawable(
+ workArea_.get_style()->get_black_gc(),
+ workAreaPixmap_,
+ event->area.x, event->area.y,
+ event->area.x, event->area.y,
+ event->area.width, event->area.height);
+ return true;
+}
+
+
+bool GWorkArea::onConfigure(GdkEventConfigure * /*event*/)
+{
+ int x, y, width, height, depth;
+ workArea_.get_window()->get_geometry(x, y, width, height, depth);
+ if (draw_)
+ XftDrawDestroy(draw_);
+ workAreaPixmap_ = Gdk::Pixmap::create(workArea_.get_window(),
+ width, height, depth);
+ Pixmap pixmap = GDK_PIXMAP_XID(workAreaPixmap_->gobj());
+ Colormap colormap = GDK_COLORMAP_XCOLORMAP(
+ workArea_.get_colormap()->gobj());
+ Visual * visual = GDK_VISUAL_XVISUAL(
+ workArea_.get_colormap()->get_visual()->gobj());
+ draw_ = XftDrawCreate(getDisplay(), pixmap,
+ visual, colormap);
+ if (!workAreaGC_) {
+ workAreaGC_ = Gdk::GC::create(workArea_.get_window());
+ Gdk::Cursor cursor(Gdk::XTERM);
+ workArea_.get_window()->set_cursor(cursor);
+ gtk_im_context_set_client_window(
+ imContext_, workArea_.get_window()->gobj());
+ }
+ workAreaResize();
+ return true;
+}
+
+
+void GWorkArea::setScrollbarParams(int height, int pos, int line_height)
+{
+ Gtk::Adjustment * adjustment = vscrollbar_.get_adjustment();
+ adjustment->set_lower(0);
+ int workAreaHeight = workHeight();
+ if (!height || height < workAreaHeight) {
+ adjustment->set_upper(workAreaHeight);
+ adjustment->set_page_size(workAreaHeight);
+ adjustment->set_value(0);
+ adjustment->changed();
+ return;
+ }
+ adjustment->set_step_increment(line_height);
+ adjustment->set_page_increment(workAreaHeight - line_height);
+ adjustment->set_upper(height);
+ adjustment->set_page_size(workAreaHeight);
+ adjustment->set_value(pos);
+ adjustment->changed();
+}
+
+
+void GWorkArea::onScroll()
+{
+ double val = vscrollbar_.get_adjustment()->get_value();
+ scrollDocView(static_cast<int>(val));
+}
+
+
+bool GWorkArea::onButtonPress(GdkEventButton * event)
+{
+ kb_action ka = LFUN_MOUSE_PRESS;
+ switch (event->type) {
+ case GDK_BUTTON_PRESS:
+ ka = LFUN_MOUSE_PRESS;
+ break;
+ case GDK_2BUTTON_PRESS:
+ ka = LFUN_MOUSE_DOUBLE;
+ break;
+ case GDK_3BUTTON_PRESS:
+ ka = LFUN_MOUSE_TRIPLE;
+ break;
+ default:
+ break;
+ }
+ dispatch(FuncRequest(ka,
+ static_cast<int>(event->x),
+ static_cast<int>(event->y),
+ static_cast<mouse_button::state>(event->button)));
+ workArea_.grab_focus();
+ return true;
+}
+
+
+bool GWorkArea::onButtonRelease(GdkEventButton * event)
+{
+ dispatch(FuncRequest(LFUN_MOUSE_RELEASE,
+ static_cast<int>(event->x),
+ static_cast<int>(event->y),
+ static_cast<mouse_button::state>(event->button)));
+ return true;
+}
+
+
+bool GWorkArea::onMotionNotify(GdkEventMotion * event)
+{
+ static guint32 timeBefore;
+ Gtk::Adjustment * adjustment = vscrollbar_.get_adjustment();
+ double step = adjustment->get_step_increment();
+ double value = adjustment->get_value();
+ if (event->x < 0)
+ value -= step;
+ else if (event->x > workArea_.get_height())
+ value += step;
+ if (value != adjustment->get_value()) {
+ if (event->time - timeBefore > 200) {
+ adjustment->set_value(value);
+ adjustment->value_changed();
+ }
+ timeBefore = event->time;
+ }
+ dispatch(FuncRequest(LFUN_MOUSE_MOTION,
+ static_cast<int>(event->x),
+ static_cast<int>(event->y),
+ gtkButtonState(event->state)));
+ return true;
+}
+
+
+void GWorkArea::inputCommit(gchar * str)
+{
+ inputCache_ = Glib::locale_from_utf8(str);
+}
+
+
+bool GWorkArea::onKeyPress(GdkEventKey * event)
+{
+#ifdef I18N
+ inputCache_ = "";
+ bool inputGet = gtk_im_context_filter_keypress(imContext_, event);
+ // cope with ascii
+ if ((inputGet && inputCache_.size() == 1 && inputCache_[0] < 128) ||
+ !inputGet) {
+#endif
+ GLyXKeySym *glk = new GLyXKeySym(event->keyval);
+ workAreaKeyPress(LyXKeySymPtr(glk),
+ gtkKeyState(event->state));
+#ifdef I18N
+ } else if (!inputCache_.empty())
+ workAreaCJK_IMprocess(inputCache_.size(), inputCache_.data());
+#endif
+ return true;
+}
+
+
+void GWorkArea::onClipboardGet(Gtk::SelectionData & /*selection_data*/,
+ guint /*info*/)
+{
+ selectionRequested();
+}
+
+
+void GWorkArea::onClipboardClear()
+{
+// selectionLost();
+}
+
+
+void GWorkArea::haveSelection(bool toHave) const
+{
+ if (toHave) {
+ Glib::RefPtr<Gtk::Clipboard> clipboard =
+ Gtk::Clipboard::get(GDK_SELECTION_PRIMARY);
+ std::vector<Gtk::TargetEntry> listTargets;
+ listTargets.push_back(Gtk::TargetEntry("UTF8_STRING"));
+ clipboard->set(listTargets,
+ SigC::slot(const_cast<GWorkArea&>(*this),
+ &GWorkArea::onClipboardGet),
+ SigC::slot(const_cast<GWorkArea&>(*this),
+ &GWorkArea::onClipboardClear));
+ }
+}
+
+
+string const GWorkArea::getClipboard() const
+{
+ Glib::RefPtr<Gtk::Clipboard> clipboard =
+ Gtk::Clipboard::get(GDK_SELECTION_PRIMARY);
+ return Glib::locale_from_utf8(clipboard->wait_for_text());
+}
+
+
+void GWorkArea::putClipboard(string const & str) const
+{
+ Glib::RefPtr<Gtk::Clipboard> clipboard =
+ Gtk::Clipboard::get(GDK_SELECTION_PRIMARY);
+ clipboard->set_text(Glib::locale_to_utf8(str));
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file GWorkArea.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#ifndef GWORKAREA_H
+#define GWORKAREA_H
+
+#include <gdk/gdkx.h>
+#include "frontends/WorkArea.h"
+#include "GPainter.h"
+#include "LColor.h"
+#include <gtk/gtk.h>
+#include <X11/Xft/Xft.h>
+
+class ColorCache
+{
+ typedef std::map<LColor::color, Gdk::Color *> Map;
+ typedef Map::iterator MapIt;
+ typedef std::map<LColor::color, XftColor *> Map2;
+ typedef Map2::iterator MapIt2;
+public:
+ ~ColorCache() { clear(); }
+ Gdk::Color * getColor(LColor::color clr)
+ {
+ MapIt it = cache_.find(clr);
+ return it == cache_.end() ? 0 : it->second;
+ }
+ XftColor * getXftColor(LColor::color clr)
+ {
+ MapIt2 it = cache2_.find(clr);
+ return it == cache2_.end() ? 0 : it->second;
+ }
+ void cacheColor(LColor::color clr, Gdk::Color * gclr)
+ {
+ cache_[clr] = gclr;
+ }
+ void cacheXftColor(LColor::color clr, XftColor * xclr)
+ {
+ cache2_[clr] = xclr;
+ }
+ void clear();
+private:
+ Map cache_;
+ Map2 cache2_;
+};
+
+extern ColorCache colorCache;
+
+class ColorHandler
+{
+public:
+ ColorHandler(GWorkArea& owner) : owner_(owner) {}
+ XftColor * getXftColor(LColor::color clr);
+ Gdk::Color * getGdkColor(LColor::color clr);
+private:
+ GWorkArea & owner_;
+};
+
+class GWorkArea : public WorkArea, public SigC::Object
+{
+public:
+ GWorkArea(int width, int height);
+ ~GWorkArea();
+
+ virtual Painter & getPainter() { return painter_; }
+ ///
+ virtual int workWidth() const { return workArea_.get_width(); }
+ ///
+ virtual int workHeight() const { return workArea_.get_height(); }
+ /// return x position of window
+ int xpos() const { return 0; }
+ /// return y position of window
+ int ypos() const { return 0; }
+ ///
+ Glib::RefPtr<Gdk::Window> getWindow() { return workArea_.get_window(); }
+ Display * getDisplay() const
+ { return GDK_WINDOW_XDISPLAY(
+ const_cast<GdkWindow*>(workArea_.get_window()->gobj())); }
+ Glib::RefPtr<Gdk::Pixmap> getPixmap() { return workAreaPixmap_; }
+ Glib::RefPtr<Gdk::GC> getGC() { return workAreaGC_; }
+ Glib::RefPtr<Gdk::Colormap> getColormap()
+ { return workArea_.get_colormap(); }
+ XftDraw * getXftDraw() { return draw_; }
+ ColorHandler & getColorHandler() { return colorHandler_; }
+
+ virtual void setScrollbarParams(int height, int pos, int line_height);
+ /// a selection exists
+ virtual void haveSelection(bool) const;
+ ///
+ virtual string const getClipboard() const;
+ ///
+ virtual void putClipboard(string const &) const;
+ void inputCommit(gchar * str);
+private:
+ bool onExpose(GdkEventExpose * event);
+ bool onConfigure(GdkEventConfigure * event);
+ void onScroll();
+ bool onButtonPress(GdkEventButton * event);
+ bool onButtonRelease(GdkEventButton * event);
+ bool onMotionNotify(GdkEventMotion * event);
+ bool onKeyPress(GdkEventKey * event);
+ void onClipboardGet(Gtk::SelectionData& selection_data, guint info);
+ void onClipboardClear();
+ Gtk::HBox hbox_;
+ Gtk::DrawingArea workArea_;
+ Gtk::VScrollbar vscrollbar_;
+ /// The pixmap overlay on the workarea
+ Glib::RefPtr<Gdk::Pixmap> workAreaPixmap_;
+ Glib::RefPtr<Gdk::GC> workAreaGC_;
+ /// the xforms-specific painter
+ GPainter painter_;
+ XftDraw * draw_;
+ ColorHandler colorHandler_;
+ GtkIMContext * imContext_;
+ string inputCache_;
+};
+
+#endif
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file GtkmmX.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#ifndef GTKMMX_H
+#define GTKMMX_H
+
+#include <X11/Xlib.h>
+#include <gtkmm.h>
+#include <gdk/gdkx.h>
+
+
+inline Display * getDisplay()
+{
+ return gdk_x11_get_default_xdisplay();
+}
+
+
+inline int getScreen()
+{
+ return gdk_x11_get_default_screen();
+}
+
+
+inline Window getRootWindow()
+{
+ static Window rootWin =
+ GDK_WINDOW_XID(Gdk::Display::get_default()->
+ get_default_screen()->
+ get_root_window()->gobj());
+ return rootWin;
+}
+
+
+inline int getDepth()
+{
+ static int depth;
+ if (!depth) {
+ int width, height, x, y;
+ Gdk::Display::get_default()->get_default_screen()->
+ get_root_window()->
+ get_geometry(x, y, width, height, depth);
+ }
+ return depth;
+}
+
+
+inline Colormap getColormap()
+{
+ static Colormap colormap = GDK_COLORMAP_XCOLORMAP(
+ Gdk::Display::get_default()->get_default_screen()->
+ get_default_colormap()->gobj());
+ return colormap;
+}
+
+
+#endif
--- /dev/null
+/**
+ * \file IdSc.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+
+#include "IdSc.h"
+#include "support/lstrings.h"
+
+using lyx::support::split;
+
+
+/// Extract shortcut from "<identifer>|#<shortcut>" string
+string const id_sc::shortcut(string const & idsc)
+{
+ string sc = split(idsc, '|');
+ if (!sc.empty() && sc[0] == '#')
+ sc.erase(sc.begin());
+ return sc;
+}
+
+
+/// Extract identifier from "<identifer>|#<shortcut>" string
+string const id_sc::id(string const & idsc)
+{
+ string id;
+ split(idsc, id, '|');
+ return id;
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file IdSc.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#ifndef ID_SC_H
+#define ID_SC_H
+
+#include "LString.h"
+
+namespace id_sc
+{
+
+/// Extract shortcut from "<identifer>|<shortcut>" string
+string const shortcut(string const &);
+
+/// Extract identifier from "<identifer>|<shortcut>" string
+string const id(string const &);
+
+}
+
+#endif
--- /dev/null
+/**
+ * \file gtk/LyXKeySymFactory.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+
+#include "frontends/LyXKeySymFactory.h"
+
+#include "GLyXKeySym.h"
+
+
+namespace LyXKeySymFactory {
+
+
+LyXKeySym * create()
+{
+ return new GLyXKeySym();
+}
+
+
+}
--- /dev/null
+/**
+ * \file gtk/LyXScreenFactory.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+
+#include <gtkmm.h>
+#include "frontends/LyXScreenFactory.h"
+
+#include "GWorkArea.h"
+#include "GScreen.h"
+
+
+namespace LyXScreenFactory {
+
+
+LyXScreen * create(WorkArea & owner)
+{
+ return new GScreen(static_cast<GWorkArea &>(owner));
+}
+
+
+}
--- /dev/null
+include $(top_srcdir)/config/common.am
+
+SUBDIRS = glade
+
+noinst_LTLIBRARIES = libgtk.la
+
+INCLUDES = -I$(top_srcdir)/images -I$(top_srcdir)/src \
+ -I$(top_srcdir)/src/frontends \
+ -I$(top_srcdir)/src/frontends/controllers \
+ -I$(top_srcdir)/src/frontends/xforms \
+ $(BOOST_INCLUDES) @GTK_FRONTEND_CFLAGS@
+
+libgtk_la_LIBADD = xforms.lo @GTK_FRONTEND_LIBS@ @XFORMS_LIBS@
+
+# Alphabetical order please. It makes it easier to figure out what's missing.
+libgtk_la_SOURCES = \
+ lyx_gui.C \
+ GtkmmX.h \
+ xftFontLoader.C \
+ xftFontLoader.h \
+ codeConvert.h \
+ xftFontMetrics.C \
+ GScreen.C \
+ GScreen.h \
+ LyXScreenFactory.C \
+ GMenubar.C \
+ GMenubar.h \
+ GTimeout.C \
+ GTimeout.h \
+ GToolbar.C \
+ GToolbar.h \
+ WorkAreaFactory.C \
+ GMiniBuffer.C \
+ GMiniBuffer.h \
+ GPainter.C \
+ GPainter.h \
+ GWorkArea.h \
+ GWorkArea.C \
+ GLyXKeySym.h \
+ GLyXKeySym.C \
+ LyXKeySymFactory.C \
+ Alert_pimpl.C \
+ GView.h \
+ GView.C \
+ Dialogs.C \
+ GAboutlyx.h \
+ GAboutlyx.C \
+ GViewBase.h \
+ GViewBase.C \
+ GBC.h \
+ GBC.C \
+ FileDialogPrivate.h \
+ FileDialogPrivate.C \
+ FileDialog.C \
+ GText.h \
+ GText.C \
+ IdSc.h \
+ IdSc.C
+
+# GPrint.h
+# GPrint.C
+
+xforms_objects = \
+ ../xforms/bmtable.lo \
+ ../xforms/checkedwidgets.lo \
+ ../xforms/ColorHandler.lo \
+ ../xforms/Color.lo \
+ ../xforms/combox.lo \
+ ../xforms/Dialogs2.lo \
+ ../xforms/fdesign_base.lo \
+ ../xforms/FormBase.lo \
+ ../xforms/FormBibitem.lo \
+ ../xforms/FormBibtex.lo \
+ ../xforms/FormBranch.lo \
+ ../xforms/FormBrowser.lo \
+ ../xforms/FormChanges.lo \
+ ../xforms/FormCharacter.lo \
+ ../xforms/FormCitation.lo \
+ ../xforms/FormColorpicker.lo \
+ ../xforms/FormDialogView.lo \
+ ../xforms/FormDocument.lo \
+ ../xforms/FormErrorList.lo \
+ ../xforms/FormERT.lo \
+ ../xforms/FormExternal.lo \
+ ../xforms/FormFloat.lo \
+ ../xforms/FormForks.lo \
+ ../xforms/FormGraphics.lo \
+ ../xforms/FormInclude.lo \
+ ../xforms/FormLog.lo \
+ ../xforms/FormMathsBitmap.lo \
+ ../xforms/FormMathsDelim.lo \
+ ../xforms/FormMathsMatrix.lo \
+ ../xforms/FormMathsPanel.lo \
+ ../xforms/FormMathsSpace.lo \
+ ../xforms/FormMathsStyle.lo \
+ ../xforms/FormMinipage.lo \
+ ../xforms/FormNote.lo \
+ ../xforms/FormParagraph.lo \
+ ../xforms/FormPreamble.lo \
+ ../xforms/FormPreferences.lo \
+ ../xforms/FormPrint.lo \
+ ../xforms/FormRef.lo \
+ ../xforms/FormSearch.lo \
+ ../xforms/FormSendto.lo \
+ ../xforms/forms_gettext.lo \
+ ../xforms/FormShowFile.lo \
+ ../xforms/FormSpellchecker.lo \
+ ../xforms/FormTabularCreate.lo \
+ ../xforms/FormTabular.lo \
+ ../xforms/FormTexinfo.lo \
+ ../xforms/FormText.lo \
+ ../xforms/FormThesaurus.lo \
+ ../xforms/FormToc.lo \
+ ../xforms/FormUrl.lo \
+ ../xforms/FormVCLog.lo \
+ ../xforms/FormWrap.lo \
+ ../xforms/freebrowser.lo \
+ ../xforms/input_validators.lo \
+ ../xforms/RadioButtonGroup.lo \
+ ../xforms/Tooltips.lo \
+ ../xforms/xformsBC.lo \
+ ../xforms/xforms_helpers.lo \
+ ../xforms/xformsImage.lo \
+ ../xforms/xforms_resize.lo
+
+# ../xforms/Dialogs.lo
+# ../xforms/FormFiledialog.lo
+# ../xforms/FileDialog.lo
+# ../xforms/FormAboutlyx.lo
+
+xforms.lo: $(xforms_objects) ../xforms/forms/*.lo
+ $(CXXLINK) $(xforms_objects) ../xforms/forms/*.lo
--- /dev/null
+/**
+ * \file gtk/WorkAreaFactory.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+
+#include "frontends/WorkAreaFactory.h"
+
+#include "GWorkArea.h"
+
+
+namespace WorkAreaFactory {
+
+
+WorkArea * create(int /*x*/, int /*y*/, int w, int h)
+{
+ return new GWorkArea(w, h);
+}
+
+
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file codeConvert.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#ifndef CODE_CONVERT_H
+#define CODE_CONVERT_H
+
+#include <X11/Xft/Xft.h>
+
+
+inline FcChar32 * wcsToFcChar32StrFast(wchar_t * wcs)
+{
+ return reinterpret_cast<FcChar32*>(wcs);
+}
+
+
+inline FcChar32 const * wcsToFcChar32StrFast(wchar_t const * wcs)
+{
+ return reinterpret_cast<FcChar32 const *>(wcs);
+}
+
+
+inline FcChar32 wcToFcChar32(wchar_t wc)
+{
+ return static_cast<FcChar32>(wc);
+}
+
+
+#endif
--- /dev/null
+DISTCLEANFILES = *.orig *.rej *~ *.bak *.gladep
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+
+GLADE_DIR = glade
+
+GLADE_FILES = *.glade
+
+EXTRA_DIST = ${GLADE_FILES}
+
+gladeinstalldirs:
+ $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)/${GLADE_DIR} ;
+
+install-data-local: gladeinstalldirs
+ files=`cd $(srcdir) ; echo $(GLADE_FILES)` ; \
+ for i in $${files} ; do \
+ $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(pkgdatadir)/${GLADE_DIR}/$$i ; \
+ done
+
+dist-hook:
+ cd $(distdir) ; rm -rf `find . -name \*CVS\*` ;
--- /dev/null
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkDialog" id="dialog">
+ <property name="title" translatable="yes">About LyX</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="default_width">300</property>
+ <property name="default_height">200</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="close_button">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-close</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="response_id">-7</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkNotebook" id="notebook1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="show_tabs">True</property>
+ <property name="show_border">True</property>
+ <property name="tab_pos">GTK_POS_TOP</property>
+ <property name="scrollable">False</property>
+ <property name="enable_popup">False</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow3">
+ <property name="width_request">400</property>
+ <property name="height_request">250</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkViewport" id="viewport3">
+ <property name="visible">True</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+
+ <child>
+ <widget class="GtkLabel" id="version">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">version</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">True</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Version</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow4">
+ <property name="width_request">400</property>
+ <property name="height_request">250</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkViewport" id="viewport4">
+ <property name="visible">True</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+
+ <child>
+ <widget class="GtkLabel" id="credits">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">credits</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">True</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Credits</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow5">
+ <property name="width_request">400</property>
+ <property name="height_request">250</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkViewport" id="viewport5">
+ <property name="visible">True</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+
+ <child>
+ <widget class="GtkLabel" id="license">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">license</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">True</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">License</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>
--- /dev/null
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkDialog" id="dialog">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">LyX:Print</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="resizable">False</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="has_separator">False</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="CancelButton">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="ApplyButton">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-apply</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="response_id">-10</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="OkButton">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+ <child>
+ <widget class="GtkTable" id="table1">
+ <property name="border_width">5</property>
+ <property name="visible">True</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">2</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">0</property>
+ <property name="column_spacing">0</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkButton" id="Browse">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">_Browse...</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ </widget>
+ <packing>
+ <property name="padding">5</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_padding">5</property>
+ <property name="x_options">shrink|fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="PrinterEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_padding">5</property>
+ <property name="y_padding">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="FileEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_padding">5</property>
+ <property name="y_padding">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkRadioButton" id="File">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">_File:</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_padding">2</property>
+ <property name="y_padding">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkRadioButton" id="Printer">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">_Printer:</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">File</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_padding">2</property>
+ <property name="y_padding">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Destination</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox2">
+ <property name="border_width">5</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">10</property>
+
+ <child>
+ <widget class="GtkRadioButton" id="All">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">A_ll</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkRadioButton" id="FromTo">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Fro_m:</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">All</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="FromEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">5</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">5</property>
+ </widget>
+ <packing>
+ <property name="padding">10</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">To:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="ToEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">5</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">5</property>
+ </widget>
+ <packing>
+ <property name="padding">10</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="Odd">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">_Odd numbered pages</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="Even">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">_Even numbered pages</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="Reverse">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">_Reverse order</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Pages</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox3">
+ <property name="border_width">10</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="spacing">5</property>
+
+ <child>
+ <widget class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Number</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkSpinButton" id="Number">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="climb_rate">1</property>
+ <property name="digits">0</property>
+ <property name="numeric">True</property>
+ <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+ <property name="snap_to_ticks">False</property>
+ <property name="wrap">False</property>
+ <property name="adjustment">1 0 100 1 10 10</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="Sorted">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">_Sorted</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Copies</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>
--- /dev/null
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkDialog" id="dialog">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">dialog1</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="Restore">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="response_id">0</property>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">2</property>
+
+ <child>
+ <widget class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gtk-undo</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Restore</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="Cancel">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="Apply">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-apply</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="response_id">-10</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="OK">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="border_width">5</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">5</property>
+
+ <child>
+ <widget class="GtkLabel" id="Label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">label</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="Text">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>
--- /dev/null
+/**
+ * \file gtk/lyx_gui.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Lars Gullik Bjnes
+ * \author John Levon
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+
+#include "lyx_gui.h"
+
+#include "support/lyxlib.h"
+#include "support/os.h"
+#include "support/filetools.h"
+#include "support/path_defines.h"
+
+#include "debug.h"
+#include "gettext.h"
+
+#include "lyx_main.h"
+#include "lyxrc.h"
+#include "lyxfont.h"
+#include "graphics/LoaderQueue.h"
+
+// FIXME: move this stuff out again
+#include "bufferlist.h"
+#include "buffer_funcs.h"
+#include "lyxfunc.h"
+#include "lyxserver.h"
+#include "BufferView.h"
+
+#include "GView.h"
+#include "GtkmmX.h"
+
+#include "xftFontLoader.h"
+#include "GWorkArea.h"
+
+#include "Lsstream.h"
+#include <iomanip>
+#include <fcntl.h>
+#include <boost/bind.hpp>
+
+//just for xforms
+#include "lyx_forms.h"
+#include "xformsImage.h"
+#include "xforms_helpers.h"
+
+extern BufferList bufferlist;
+
+// FIXME: wrong place !
+LyXServer * lyxserver;
+
+bool lyx_gui::use_gui = true;
+
+namespace {
+
+/// quit lyx
+bool finished = false;
+
+
+/// estimate DPI from X server
+float getDPI()
+{
+ Screen * scr = ScreenOfDisplay(getDisplay(), getScreen());
+ return ((HeightOfScreen(scr) * 25.4 / HeightMMOfScreen(scr)) +
+ (WidthOfScreen(scr) * 25.4 / WidthMMOfScreen(scr))) / 2;
+}
+
+
+/// set default GUI configuration
+void setDefaults()
+{
+ FL_IOPT cntl;
+ cntl.buttonFontSize = FL_NORMAL_SIZE;
+ cntl.browserFontSize = FL_NORMAL_SIZE;
+ cntl.labelFontSize = FL_NORMAL_SIZE;
+ cntl.choiceFontSize = FL_NORMAL_SIZE;
+ cntl.inputFontSize = FL_NORMAL_SIZE;
+ cntl.menuFontSize = FL_NORMAL_SIZE;
+ cntl.borderWidth = -1;
+ cntl.vclass = FL_DefaultVisual;
+ fl_set_defaults(FL_PDVisual
+ | FL_PDButtonFontSize
+ | FL_PDBrowserFontSize
+ | FL_PDLabelFontSize
+ | FL_PDChoiceFontSize
+ | FL_PDInputFontSize
+ | FL_PDMenuFontSize
+ | FL_PDBorderWidth, &cntl);
+}
+
+
+extern "C" {
+
+
+int LyX_XErrHandler(Display * display, XErrorEvent * xeev) {
+ // We don't abort on BadWindow
+ if (xeev->error_code == BadWindow) {
+ lyxerr << "BadWindow received !" << std::endl;
+ lyxerr << "If you're using xforms 1.0 or greater, "
+ << " please report this to lyx-devel@lists.lyx.org"
+ << std::endl;
+ return 0;
+ }
+
+ // emergency cleanup
+ LyX::emergencyCleanup();
+
+ // Get the reason for the crash.
+ char etxt[513];
+ XGetErrorText(display, xeev->error_code, etxt, 512);
+ lyxerr << etxt << " id: " << xeev->resourceid << std::endl;
+ // By doing an abort we get a nice backtrace. (hopefully)
+ lyx::support::abort();
+ return 0;
+}
+
+}
+
+/// read in geometry specification
+char geometry[40];
+
+} // namespace anon
+
+
+void parse_init_xforms(int & argc, char * argv[])
+{
+ setDefaults();
+
+ FL_CMD_OPT cmdopt[] = {
+ {"-geometry", "*.geometry", XrmoptionSepArg, "690x510"}
+ };
+
+ FL_resource res[] = {
+ {"geometry", "geometryClass", FL_STRING, geometry, "", 40}
+ };
+
+ const int num_res = sizeof(res)/sizeof(FL_resource);
+ fl_initialize(&argc, argv, "LyX", cmdopt, num_res);
+
+ // It appears that, in xforms >=0.89.5, fl_initialize()
+ // calls setlocale() and ruins our LC_NUMERIC setting.
+
+ fl_get_app_resources(res, num_res);
+
+ Display * display = fl_get_display();
+
+ if (!display) {
+ lyxerr << "LyX: unable to access X display, exiting"
+ << std::endl;
+ lyx::support::os::warn("Unable to access X display, exiting");
+ ::exit(1);
+ }
+
+ fcntl(ConnectionNumber(display), F_SETFD, FD_CLOEXEC);
+
+ XSetErrorHandler(LyX_XErrHandler);
+
+ using namespace lyx::graphics;
+
+ // connect the image loader based on the xforms library
+ Image::newImage = boost::bind(&xformsImage::newImage);
+ Image::loadableFormats = boost::bind(&xformsImage::loadableFormats);
+}
+
+
+void lyx_gui::parse_init(int & argc, char * argv[])
+{
+ new Gtk::Main(argc, argv);
+
+ parse_init_xforms(argc, argv);
+
+ locale_init();
+
+ // must do this /before/ lyxrc gets read
+ lyxrc.dpi = getDPI();
+}
+
+
+void parse_lyxrc_xforms()
+{
+ XformsColor::read(lyx::support::AddName(
+ lyx::support::user_lyxdir(), "preferences.xform"));
+
+ if (lyxrc.popup_font_encoding.empty())
+ lyxrc.popup_font_encoding = lyxrc.font_norm;
+ // Set the font name for popups and menus
+ string boldfontname = lyxrc.popup_bold_font
+ + "-*-*-*-?-*-*-*-*-"
+ + lyxrc.popup_font_encoding;
+ // "?" means "scale that font"
+ string fontname = lyxrc.popup_normal_font
+ + "-*-*-*-?-*-*-*-*-"
+ + lyxrc.popup_font_encoding;
+
+ int bold = fl_set_font_name(FL_BOLD_STYLE, boldfontname.c_str());
+ int normal = fl_set_font_name(FL_NORMAL_STYLE, fontname.c_str());
+ if (bold < 0)
+ lyxerr << "Could not set menu font to "
+ << boldfontname << std::endl;
+
+ if (normal < 0)
+ lyxerr << "Could not set popup font to "
+ << fontname << std::endl;
+
+ if (bold < 0 && normal < 0) {
+ lyxerr << "Using 'helvetica' font for menus" << std::endl;
+ boldfontname = "-*-helvetica-bold-r-*-*-*-?-*-*-*-*-iso8859-1";
+ fontname = "-*-helvetica-medium-r-*-*-*-?-*-*-*-*-iso8859-1";
+ bold = fl_set_font_name(FL_BOLD_STYLE, boldfontname.c_str());
+ normal = fl_set_font_name(FL_NORMAL_STYLE, fontname.c_str());
+
+ if (bold < 0 && normal < 0) {
+ lyxerr << "Could not find helvetica font. Using 'fixed'."
+ << std::endl;
+ fl_set_font_name(FL_NORMAL_STYLE, "fixed");
+ normal = bold = 0;
+ }
+ }
+ if (bold < 0)
+ fl_set_font_name(FL_BOLD_STYLE, fontname.c_str());
+ else if (normal < 0)
+ fl_set_font_name(FL_NORMAL_STYLE, boldfontname.c_str());
+
+ fl_setpup_fontstyle(FL_NORMAL_STYLE);
+ fl_setpup_fontsize(FL_NORMAL_SIZE);
+ fl_setpup_color(FL_MCOL, FL_BLACK);
+ fl_set_goodies_font(FL_NORMAL_STYLE, FL_NORMAL_SIZE);
+ fl_set_tooltip_font(FL_NORMAL_STYLE, FL_NORMAL_SIZE);
+}
+
+
+void lyx_gui::parse_lyxrc()
+{
+ parse_lyxrc_xforms();
+}
+
+
+void start_xforms()
+{
+ // initial geometry
+ int xpos = -1;
+ int ypos = -1;
+ unsigned int width = 690;
+ unsigned int height = 510;
+
+ int const geometryBitmask =
+ XParseGeometry(geometry,
+ &xpos, &ypos, &width, &height);
+
+ // if width is not set by geometry, check it against monitor width
+ if (!(geometryBitmask & WidthValue)) {
+ Screen * scr = ScreenOfDisplay(fl_get_display(), fl_screen);
+ if (WidthOfScreen(scr) - 8 < int(width))
+ width = WidthOfScreen(scr) - 8;
+ }
+
+ // if height is not set by geometry, check it against monitor height
+ if (!(geometryBitmask & HeightValue)) {
+ Screen * scr = ScreenOfDisplay(fl_get_display(), fl_screen);
+ if (HeightOfScreen(scr) - 24 < int(height))
+ height = HeightOfScreen(scr) - 24;
+ }
+
+ Screen * s = ScreenOfDisplay(fl_get_display(), fl_screen);
+
+ // recalculate xpos if it's not set
+ if (xpos == -1)
+ xpos = (WidthOfScreen(s) - width) / 2;
+
+ // recalculate ypos if it's not set
+ if (ypos == -1)
+ ypos = (HeightOfScreen(s) - height) / 2;
+
+ lyxerr[Debug::GUI] << "Creating view: " << width << 'x' << height
+ << '+' << xpos << '+' << ypos << std::endl;
+
+// XFormsView view(width, height);
+// view.show(xpos, ypos, "LyX");
+// view.init();
+}
+
+
+static void events_xforms()
+{
+ if (fl_check_forms() == FL_EVENT) {
+ XEvent ev;
+ fl_XNextEvent(&ev);
+ lyxerr[Debug::GUI]
+ << "Received unhandled X11 event" << std::endl
+ << "Type: " << ev.xany.type
+ << " Target: 0x" << std::hex << ev.xany.window
+ << std::dec << std::endl;
+ }
+}
+
+
+void lyx_gui::start(string const & batch, std::vector<string> const & files)
+{
+ start_xforms();
+ // just for debug
+ XSynchronize(getDisplay(), true);
+ GView view;
+ view.show();
+ view.init();
+
+ Buffer * last = 0;
+
+ // FIXME: some code below needs moving
+
+ lyxserver = new LyXServer(&view.getLyXFunc(), lyxrc.lyxpipes);
+
+ std::vector<string>::const_iterator cit = files.begin();
+ std::vector<string>::const_iterator end = files.end();
+ for (; cit != end; ++cit) {
+ Buffer * b = bufferlist.newBuffer(*cit);
+ if (loadLyXFile(b, *cit))
+ last = b;
+ }
+
+ // switch to the last buffer successfully loaded
+ if (last) {
+ view.view()->buffer(last);
+ }
+
+ // handle the batch commands the user asked for
+ if (!batch.empty()) {
+ view.getLyXFunc().dispatch(batch);
+ }
+
+ // enter the event loop
+ while (!finished) {
+ while (Gtk::Main::events_pending())
+ Gtk::Main::iteration(false);
+ events_xforms();
+ }
+
+ // FIXME: breaks emergencyCleanup
+ delete lyxserver;
+}
+
+
+void lyx_gui::exit()
+{
+ finished = true;
+}
+
+
+FuncStatus lyx_gui::getStatus(FuncRequest const & /*ev*/)
+{
+ // Nothing interesting to do here
+ return FuncStatus();
+}
+
+
+string const lyx_gui::hexname(LColor::color col)
+{
+ Gdk::Color gdkColor;
+ Gdk::Color * gclr = colorCache.getColor(col);
+ if (!gclr) {
+ gclr = &gdkColor;
+ gclr->parse(lcolor.getX11Name(col));
+ }
+
+ std::ostringstream os;
+
+ // Note that X stores the RGB values in the range 0 - 65535
+ // whilst we require them in the range 0 - 255.
+ os << std::setbase(16) << std::setfill('0')
+ << std::setw(2) << (gclr->get_red() / 256)
+ << std::setw(2) << (gclr->get_green() / 256)
+ << std::setw(2) << (gclr->get_blue() / 256);
+
+ return os.str();
+}
+
+
+void lyx_gui::update_color(LColor::color /*col*/)
+{
+ colorCache.clear();
+}
+
+
+void lyx_gui::update_fonts()
+{
+ fontLoader.update();
+}
+
+
+bool lyx_gui::font_available(LyXFont const & font)
+{
+ return fontLoader.available(font);
+}
+
+
+namespace {
+
+
+bool readCallback(Glib::IOCondition /*condition*/, LyXComm * comm)
+{
+ comm->read_ready();
+ return true;
+}
+
+
+std::map<int, SigC::Connection> gReadCallbackMap;
+
+}
+
+
+void lyx_gui::set_read_callback(int fd, LyXComm * comm)
+{
+ gReadCallbackMap[fd] = Glib::signal_io().connect(
+ SigC::bind(SigC::slot(readCallback), comm),
+ fd,
+ Glib::IO_IN);
+}
+
+
+void lyx_gui::remove_read_callback(int fd)
+{
+ gReadCallbackMap[fd].disconnect();
+ gReadCallbackMap.erase(fd);
+}
+
+
+string const lyx_gui::roman_font_name()
+{
+ return "times";
+}
+
+
+string const lyx_gui::sans_font_name()
+{
+ return "helvetica";
+}
+
+
+string const lyx_gui::typewriter_font_name()
+{
+ return "courier";
+}
+
+
+void lyx_gui::sync_events()
+{
+ // FIXME
+}
--- /dev/null
+/**
+ * \file xftFontLoader.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+#include <cmath> // fabs()
+
+#include <X11/Xft/Xft.h>
+#include "xftFontLoader.h"
+#include "FontInfo.h"
+#include "gettext.h"
+#include "debug.h"
+#include "lyxrc.h" // lyxrc.font_*
+#include "BufferView.h"
+#include "frontends/LyXView.h"
+#include "support/systemcall.h"
+#include "support/filetools.h"
+#include "GtkmmX.h"
+#include <vector>
+#include "frontends/lyx_gui.h"
+
+using std::endl;
+
+// The global fontLoader
+xftFontLoader fontLoader;
+
+
+// Initialize font loader
+xftFontLoader::xftFontLoader()
+{
+}
+
+
+// Destroy font loader
+xftFontLoader::~xftFontLoader()
+{
+ unload();
+}
+
+
+// Update fonts after zoom, dpi, font names, or norm change
+// For now, we just ditch all fonts we have. Later, we should
+// reuse the ones that are already loaded.
+void xftFontLoader::update()
+{
+ unload();
+}
+
+
+// Unload all fonts
+void xftFontLoader::unload()
+{
+ // Unload all fonts
+ for (int i1 = 0; i1 < LyXFont::NUM_FAMILIES; ++i1)
+ for (int i2 = 0; i2 < 2; ++i2)
+ for (int i3 = 0; i3 < 4; ++i3)
+ for (int i4 = 0; i4 < 10; ++i4) {
+ if (fonts_[i1][i2][i3][i4]){
+ XftFontClose(getDisplay(), fonts_[i1][i2][i3][i4]);
+ fonts_[i1][i2][i3][i4] = 0;
+ }
+ }
+}
+
+
+string xftFontLoader::familyString(LyXFont::FONT_FAMILY family)
+{
+ string ffamily;
+ switch (family) {
+ case LyXFont::ROMAN_FAMILY:
+ ffamily = lyxrc.roman_font_name;
+ break;
+ case LyXFont::SANS_FAMILY:
+ ffamily = lyxrc.sans_font_name;
+ break;
+ case LyXFont::TYPEWRITER_FAMILY:
+ ffamily = lyxrc.typewriter_font_name;
+ break;
+ case LyXFont::CMR_FAMILY:
+ ffamily = "cmr10";
+ break;
+ case LyXFont::CMSY_FAMILY:
+ ffamily = "cmsy10";
+ break;
+ case LyXFont::CMM_FAMILY:
+ ffamily = "cmmi10";
+ break;
+ case LyXFont::CMEX_FAMILY:
+ ffamily = "cmex10";
+ break;
+ case LyXFont::MSA_FAMILY:
+ ffamily = "msam10";
+ break;
+ case LyXFont::MSB_FAMILY:
+ ffamily = "msbm10";
+ break;
+ default:
+ ffamily = "Sans";
+ break;
+ }
+ return ffamily;
+}
+
+
+// Get font pattern
+/* Takes care of finding which font that can match the given request. Tries
+different alternatives. */
+XftPattern * xftFontLoader::getFontPattern(LyXFont::FONT_FAMILY family,
+ LyXFont::FONT_SERIES series,
+ LyXFont::FONT_SHAPE shape,
+ LyXFont::FONT_SIZE size)
+{
+ // Normal font. Let's search for an existing name that matches.
+ string ffamily;
+ int fweight;
+ int fslant;
+ double fsize = lyxrc.font_sizes[size] * lyxrc.zoom / 100.0;
+ XftPattern *fpat = XftPatternCreate();
+
+ ffamily = familyString(family);
+ switch (series) {
+ case LyXFont::MEDIUM_SERIES:
+ fweight = XFT_WEIGHT_MEDIUM;
+ break;
+ case LyXFont::BOLD_SERIES:
+ fweight = XFT_WEIGHT_BOLD;
+ break;
+ default:
+ fweight = XFT_WEIGHT_MEDIUM;
+ break;
+ }
+
+ switch (shape) {
+ case LyXFont::UP_SHAPE:
+ case LyXFont::SMALLCAPS_SHAPE:
+ fslant = XFT_SLANT_ROMAN;
+ break;
+ case LyXFont::ITALIC_SHAPE:
+ fslant = XFT_SLANT_ITALIC;
+ break;
+ case LyXFont::SLANTED_SHAPE:
+ fslant = XFT_SLANT_OBLIQUE;
+ break;
+ default:
+ fslant = XFT_SLANT_ROMAN;
+ break;
+ }
+ XftPatternAddString(fpat, XFT_FAMILY, ffamily.c_str());
+ XftPatternAddInteger(fpat, XFT_WEIGHT, fweight);
+ XftPatternAddInteger(fpat, XFT_SLANT, fslant);
+ XftPatternAddDouble(fpat, XFT_SIZE, fsize);
+ return fpat;
+}
+
+
+/// Do load font
+XftFont * xftFontLoader::doLoad(LyXFont::FONT_FAMILY family,
+ LyXFont::FONT_SERIES series,
+ LyXFont::FONT_SHAPE shape,
+ LyXFont::FONT_SIZE size)
+{
+ XftPattern *fpat = getFontPattern(family, series, shape, size);
+ XftResult result;
+ XftPattern *fpat2 = XftFontMatch(getDisplay(), getScreen(),
+ fpat, &result);
+ XftFont * font = XftFontOpenPattern(getDisplay(), fpat2);
+ fonts_[family][series][shape][size] = font;
+ return font;
+}
+
+
+bool xftFontLoader::available(LyXFont const & f)
+{
+ if (!lyx_gui::use_gui)
+ return false;
+
+ static std::vector<bool> cache_set(LyXFont::NUM_FAMILIES, false);
+ static std::vector<bool> cache(LyXFont::NUM_FAMILIES, false);
+
+ LyXFont::FONT_FAMILY family = f.family();
+ if (cache_set[family])
+ return cache[family];
+ cache_set[family] = true;
+
+ string const ffamily = familyString(family);
+ if (isSpecial(f)) {
+ cache_set[family] = true;
+ XftPattern *fpat = XftPatternCreate();
+ XftPatternAddString(fpat, XFT_FAMILY, ffamily.c_str());
+ XftResult result;
+ XftPattern *fpat2 = XftFontMatch(getDisplay(), getScreen(),
+ fpat, &result);
+ XftPatternDestroy(fpat);
+ char * familyM;
+ XftPatternGetString(fpat2, XFT_FAMILY, 0, &familyM);
+ if (ffamily == familyM) {
+ cache[family] = true;
+ return true;
+ }
+ // We don't need to set cache[family] to false, as it
+ // is initialized to false;
+ return false;
+ }
+ // We don't care about non-symbol fonts
+ return false;
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file xftFontLoader.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#ifndef XFT_FONT_LOADER_H
+#define XFT_FONT_LOADER_H
+
+#include "lyxfont.h"
+#include "LString.h"
+#include <X11/Xft/Xft.h>
+
+class GWorkArea;
+
+
+class xftFontLoader {
+public:
+ ///
+ xftFontLoader();
+
+ ///
+ ~xftFontLoader();
+
+ /// Update fonts after zoom, dpi, font names, or norm change
+ void update();
+
+ bool available(LyXFont const & f);
+
+ /// Load font
+ XftFont * load(LyXFont::FONT_FAMILY family,
+ LyXFont::FONT_SERIES series,
+ LyXFont::FONT_SHAPE shape,
+ LyXFont::FONT_SIZE size)
+ {
+ if (fonts_[family][series][shape][size])
+ return fonts_[family][series][shape][size];
+ else
+ return doLoad(family, series, shape, size);
+ }
+ bool isSpecial(LyXFont const & f)
+ {
+ switch (f.family()) {
+ case LyXFont::CMR_FAMILY:
+ case LyXFont::EUFRAK_FAMILY:
+ return true;
+ default:
+ break;
+ }
+ return f.isSymbolFont();
+ }
+private:
+ /// Array of fonts
+ XftFont * fonts_[LyXFont::NUM_FAMILIES][2][4][10];
+ XftPattern * getFontPattern(LyXFont::FONT_FAMILY family,
+ LyXFont::FONT_SERIES series,
+ LyXFont::FONT_SHAPE shape,
+ LyXFont::FONT_SIZE size);
+ string familyString(LyXFont::FONT_FAMILY family);
+ /// Reset font handler
+ void reset();
+
+ /// Unload all fonts
+ void unload();
+
+ /** Does the actual loading of a font. Updates fontstruct. */
+ XftFont * doLoad(LyXFont::FONT_FAMILY family,
+ LyXFont::FONT_SERIES series,
+ LyXFont::FONT_SHAPE shape,
+ LyXFont::FONT_SIZE size);
+};
+
+///
+extern xftFontLoader fontLoader;
+
+#endif
--- /dev/null
+/**
+ * \file xfont_metrics.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+#include <gtkmm.h>
+
+#include <algorithm>
+#include "GtkmmX.h"
+#include "support/lstrings.h"
+#include "xftFontLoader.h"
+#include "font_metrics.h"
+#include "lyxrc.h"
+#include "encoding.h"
+#include "language.h"
+#include "codeConvert.h"
+
+#include <boost/scoped_array.hpp>
+
+
+namespace {
+
+
+inline XftFont * getXftFont(LyXFont const & f)
+{
+ return fontLoader.load(f.family(), f.series(),
+ f.realShape(), f.size());
+}
+
+
+inline int XGlyphAscent(XGlyphInfo const & info)
+{
+ return info.y;
+}
+
+
+inline int XGlyphDescent(XGlyphInfo const & info)
+{
+ return info.height - info.y;
+}
+
+
+inline int XGlyphLbearing(XGlyphInfo const & info)
+{
+ return -info.x;
+}
+
+
+inline int XGlyphRbearing(XGlyphInfo const & info)
+{
+ return -info.x + info.width;
+}
+
+
+inline int XGlyphLogWidth(XGlyphInfo const & info)
+{
+ return info.xOff;
+}
+
+
+wchar_t C2WC(char ch)
+{
+ wchar_t wcs[2] = {0, 0};
+ char mbs[2] = {0, 0};
+ mbs[0] = ch;
+ mbstowcs(wcs, mbs, 2);
+ return wcs[0];
+}
+
+
+} // namespace anon
+
+
+namespace font_metrics {
+
+
+int maxAscent(LyXFont const & f)
+{
+ XftFont * font = getXftFont(f);
+ return font->ascent;
+}
+
+
+int maxDescent(LyXFont const & f)
+{
+ XftFont * font = getXftFont(f);
+ return font->descent;
+}
+
+
+int ascent(wchar_t c,LyXFont const & f)
+{
+ XftFont * font = getXftFont(f);
+ XGlyphInfo glyph;
+ XftTextExtents32(getDisplay(), font,
+ wcsToFcChar32StrFast(&c),
+ 1,
+ &glyph);
+ return XGlyphAscent(glyph);
+}
+
+
+int ascent(char c, LyXFont const & f)
+{
+ return ascent(C2WC(c), f);
+}
+
+
+int descent(wchar_t c,LyXFont const & f)
+{
+ XftFont * font = getXftFont(f);
+ XGlyphInfo glyph;
+ XftTextExtents32(getDisplay(), font,
+ wcsToFcChar32StrFast(&c),
+ 1,
+ &glyph);
+ return XGlyphDescent(glyph);
+}
+
+
+int descent(char c, LyXFont const & f)
+{
+ return descent(C2WC(c), f);
+}
+
+
+int lbearing(wchar_t c,LyXFont const & f)
+ {
+ XftFont * font = getXftFont(f);
+ XGlyphInfo glyph;
+ XftTextExtents32(getDisplay(), font,
+ wcsToFcChar32StrFast(&c),
+ 1,
+ &glyph);
+ return XGlyphLbearing(glyph);
+ }
+
+
+int rbearing(wchar_t c,LyXFont const & f)
+{
+ XftFont * font = getXftFont(f);
+ XGlyphInfo glyph;
+ XftTextExtents32(getDisplay(), font,
+ wcsToFcChar32StrFast(&c),
+ 1,
+ &glyph);
+ return XGlyphRbearing(glyph);
+}
+
+
+int lbearing(char c, LyXFont const & f)
+{
+ return lbearing(C2WC(c), f);
+}
+
+
+int rbearing(char c, LyXFont const & f)
+{
+ return rbearing(C2WC(c), f);
+}
+
+
+int width(wchar_t const * s, size_t n, LyXFont const & f)
+{
+ XftFont * font = getXftFont(f);
+ XGlyphInfo glyph;
+ if (f.realShape() != LyXFont::SMALLCAPS_SHAPE){
+ XftTextExtents32(getDisplay(), font,
+ wcsToFcChar32StrFast(s),
+ n,
+ &glyph);
+ return XGlyphLogWidth(glyph);
+ } else {
+ int result = 0;
+ LyXFont smallfont(f);
+ smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
+ XftFont * fontS = getXftFont(smallfont);
+ for (size_t i = 0; i < n; ++i) {
+ wchar_t wc = lyx::support::uppercase(s[i]);
+ if (wc != s[i]) {
+ XftTextExtents32(getDisplay(), fontS,
+ wcsToFcChar32StrFast(&wc),
+ 1,
+ &glyph);
+ result += XGlyphLogWidth(glyph);
+ } else {
+ XftTextExtents32(getDisplay(), font,
+ wcsToFcChar32StrFast(&wc),
+ 1,
+ &glyph);
+ result += XGlyphLogWidth(glyph);
+ }
+ }
+ return result;
+ }
+}
+
+
+int width(wchar_t c,LyXFont const & f)
+{
+ return width(&c, 1, f);
+}
+
+
+int width(char const * s, size_t n,LyXFont const & f)
+{
+ boost::scoped_array<wchar_t> wcs(new wchar_t[n]);
+ size_t len;
+ if (fontLoader.isSpecial(f)) {
+ unsigned char const * us =
+ reinterpret_cast<unsigned char const *>(s);
+ len = n;
+ std::copy(us, us + n, wcs.get());
+ } else
+ len = mbstowcs(wcs.get(), s, n);
+ return width(wcs.get(), len, f);
+}
+
+
+int signedWidth(string const & s, LyXFont const & f)
+{
+ if (s.empty())
+ return 0;
+ boost::scoped_array<wchar_t> wcs(new wchar_t[s.length() + 1]);
+ int len = mbstowcs(wcs.get(), s.c_str(), s.length());
+ if (wcs[0] == '-')
+ return width(wcs.get() + 1, len - 1, f);
+ else
+ return width(wcs.get(), len, f);
+}
+
+
+void rectText(string const & str, LyXFont const & font,
+ int & width,
+ int & ascent,
+ int & descent)
+{
+ static int const d = 2;
+ width = font_metrics::width(str, font) + d * 2 + 2;
+ ascent = font_metrics::maxAscent(font) + d;
+ descent = font_metrics::maxDescent(font) + d;
+}
+
+
+void buttonText(string const & str, LyXFont const & font,
+ int & width,
+ int & ascent,
+ int & descent)
+{
+ static int const d = 3;
+
+ width = font_metrics::width(str, font) + d * 2 + 2;
+ ascent = font_metrics::maxAscent(font) + d;
+ descent = font_metrics::maxDescent(font) + d;
+}
+
+
+} // namespace font_metrics
+