The Gtk patch.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@7632 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Lars Gullik Bjønnes 2003-09-02 10:29:05 +00:00
parent 9d3229d5d7
commit f268743f8c
54 changed files with 6492 additions and 2 deletions

View File

@ -188,6 +188,19 @@ for frontend in $FRONTENDS ; do
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)"
@ -395,6 +408,8 @@ AC_CONFIG_FILES([Makefile \
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 \

View File

@ -35,6 +35,8 @@ src/frontends/controllers/character.C
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

View File

@ -31,7 +31,7 @@ OTHERLIBS = $(BOOST_LIBS) $(INTLLIBS) $(AIKSAURUS_LIBS) @LIBS@
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)
@ -42,6 +42,10 @@ lyx_qt_LDADD = $(lyx_OBJECTS) $(LYX_PRE_LIBS) \
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) $< $@

View File

@ -2,7 +2,7 @@ include $(top_srcdir)/config/common.am
SUBDIRS = controllers $(FRONTENDS_SUBDIRS)
DIST_SUBDIRS = controllers xforms qt2 gnome
DIST_SUBDIRS = controllers xforms qt2 gnome gtk
noinst_LTLIBRARIES = libfrontends.la

View File

@ -0,0 +1,103 @@
/**
* \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());
}

View File

@ -0,0 +1,3 @@
2003-9-2 hying_caritas@163.com
* initial release

481
src/frontends/gtk/Dialogs.C Normal file
View File

@ -0,0 +1,481 @@
/**
* \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();
}

View File

@ -0,0 +1,52 @@
/**
* \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);
}

View File

@ -0,0 +1,99 @@
/**
* \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);
}

View File

@ -0,0 +1,45 @@
// -*- 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

View File

@ -0,0 +1,168 @@
/**
* \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 += "&lt;";
break;
case '>':
pangoMarkup.erase(--(pangoMarkup.end()));
pangoMarkup += "&gt;";
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));
}

View File

@ -0,0 +1,29 @@
// -*- 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

39
src/frontends/gtk/GBC.C Normal file
View File

@ -0,0 +1,39 @@
/**
* \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));
}

39
src/frontends/gtk/GBC.h Normal file
View File

@ -0,0 +1,39 @@
// -*- 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

View File

@ -0,0 +1,97 @@
/**
* \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();
}

View File

@ -0,0 +1,35 @@
// -*- 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

View File

@ -0,0 +1,228 @@
/**
* \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);
}

View File

@ -0,0 +1,36 @@
// -*- 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

View File

@ -0,0 +1,281 @@
/**
* \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);
}

View File

@ -0,0 +1,70 @@
// -*- 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

View File

@ -0,0 +1,272 @@
/**
* \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);
}

View File

@ -0,0 +1,129 @@
// -*- 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

156
src/frontends/gtk/GPrint.C Normal file
View File

@ -0,0 +1,156 @@
// 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));
}

View File

@ -0,0 +1,43 @@
// -*- 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

134
src/frontends/gtk/GScreen.C Normal file
View File

@ -0,0 +1,134 @@
/**
* \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);
}

View File

@ -0,0 +1,63 @@
// -*- 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

77
src/frontends/gtk/GText.C Normal file
View File

@ -0,0 +1,77 @@
/**
* \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, &GText::onEntryChanged));
}
void GText::onEntryChanged()
{
bc().valid(!entry_->get_text().empty());
}

33
src/frontends/gtk/GText.h Normal file
View File

@ -0,0 +1,33 @@
// -*- 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

View File

@ -0,0 +1,69 @@
/**
* \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, &GTimeout::timeoutEvent),
timeout_ms()
);
running_ = true;
}
void GTimeout::stop()
{
conn_.disconnect();
running_ = false;
}
bool GTimeout::timeoutEvent()
{
emit();
return false; // discontinue emitting timeouts.
}

View File

@ -0,0 +1,47 @@
// -*- 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

View File

@ -0,0 +1,261 @@
/**
* \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,
&GToolbar::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, &GToolbar::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, &GToolbar::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;
}

View File

@ -0,0 +1,62 @@
// -*- 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

124
src/frontends/gtk/GView.C Normal file
View File

@ -0,0 +1,124 @@
/**
* \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());
}

48
src/frontends/gtk/GView.h Normal file
View File

@ -0,0 +1,48 @@
// -*- 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

View File

@ -0,0 +1,124 @@
/**
* \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;
}

View File

@ -0,0 +1,123 @@
// -*- 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

View File

@ -0,0 +1,355 @@
/**
* \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));
}

View File

@ -0,0 +1,125 @@
// -*- 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

View File

@ -0,0 +1,64 @@
// -*- 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

35
src/frontends/gtk/IdSc.C Normal file
View File

@ -0,0 +1,35 @@
/**
* \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;
}

28
src/frontends/gtk/IdSc.h Normal file
View File

@ -0,0 +1,28 @@
// -*- 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

View File

@ -0,0 +1,27 @@
/**
* \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();
}
}

View File

@ -0,0 +1,29 @@
/**
* \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));
}
}

View File

@ -0,0 +1,132 @@
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

View File

@ -0,0 +1,28 @@
/**
* \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);
}
}

View File

@ -0,0 +1,36 @@
// -*- 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

View File

@ -0,0 +1,20 @@
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\*` ;

View File

@ -0,0 +1,245 @@
<?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>

View File

@ -0,0 +1,568 @@
<?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>

View File

@ -0,0 +1,194 @@
<?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>

454
src/frontends/gtk/lyx_gui.C Normal file
View File

@ -0,0 +1,454 @@
/**
* \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
}

View File

@ -0,0 +1,213 @@
/**
* \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;
}

View File

@ -0,0 +1,81 @@
// -*- 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

View File

@ -0,0 +1,265 @@
/**
* \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