#include "support/lassert.h"
#include "support/lstrings.h"
#include "support/lyxalgo.h" // sorted
+#include "support/textutils.h"
#include "support/Messages.h"
#include "support/os.h"
#include "support/Package.h"
#include "support/TempFile.h"
-#include "support/textutils.h"
#ifdef Q_OS_MAC
#include "support/AppleScript.h"
#endif
#include <queue>
+#include <tuple>
#include <QByteArray>
#include <QDateTime>
using namespace lyx::support;
-static void initializeResources()
-{
- static bool initialized = false;
- if (!initialized) {
- Q_INIT_RESOURCE(Resources);
- initialized = true;
- }
-}
-
-
namespace lyx {
frontend::Application * createApplication(int & argc, char * argv[])
}
-QString iconName(FuncRequest const & f, bool unknown)
+// the returned bool is true if the icon needs to be flipped
+pair<QString,bool> iconName(FuncRequest const & f, bool unknown, bool rtl)
{
- initializeResources();
- QString name1;
- QString name2;
- QString path;
- switch (f.action()) {
- case LFUN_MATH_INSERT:
- if (!f.argument().empty()) {
- path = "math/";
- name1 = findImg(toqstr(f.argument()).mid(1));
- }
- break;
- case LFUN_MATH_DELIM:
- case LFUN_MATH_BIGDELIM:
- path = "math/";
- name1 = findImg(toqstr(f.argument()));
- break;
- case LFUN_CALL:
- path = "commands/";
- name1 = toqstr(f.argument());
- break;
- case LFUN_COMMAND_ALTERNATIVES: {
- // use the first of the alternative commands
- docstring firstcom;
- docstring dummy = split(f.argument(), firstcom, ';');
- name1 = toqstr(firstcom);
- name1.replace(' ', '_');
- break;
- }
- default:
- name2 = toqstr(lyxaction.getActionName(f.action()));
- name1 = name2;
+ QStringList names;
+ QString lfunname = toqstr(lyxaction.getActionName(f.action()));
+
+ if (!f.argument().empty()) {
+ // if there are arguments, first search an icon which name is the full thing
+ QString name = lfunname + ' ' + toqstr(f.argument());
+ name.replace(' ', '_');
+ name.replace(';', '_');
+ name.replace('\\', "backslash");
+ names << name;
- if (!f.argument().empty()) {
- name1 = name2 + ' ' + toqstr(f.argument());
+ // then special default icon for some lfuns
+ switch (f.action()) {
+ case LFUN_MATH_INSERT:
+ names << "math/" + findImg(toqstr(f.argument()).mid(1));
+ break;
+ case LFUN_MATH_DELIM:
+ case LFUN_MATH_BIGDELIM:
+ names << "math/" + findImg(toqstr(f.argument()));
+ break;
+ case LFUN_CALL:
+ names << "commands/" + toqstr(f.argument());
+ break;
+ case LFUN_COMMAND_ALTERNATIVES: {
+ // use the first of the alternative commands
+ docstring firstcom;
+ docstring dummy = split(f.argument(), firstcom, ';');
+ QString name1 = toqstr(firstcom);
name1.replace(' ', '_');
+ name1.replace(';', '_');
name1.replace('\\', "backslash");
+ names << name1;
+ break;
+ }
+ default:
+ break;
}
}
+ // next thing to try is function name alone
+ names << lfunname;
+
+ // and finally maybe the unkown icon
+ if (unknown)
+ names << "unknown";
+
+ search_mode const mode = theGuiApp()->imageSearchMode();
+ // The folders where icons are searched for
QStringList imagedirs;
imagedirs << "images/" << "images/ipa/";
- search_mode mode = theGuiApp()->imageSearchMode();
- for (int i = 0; i < imagedirs.size(); ++i) {
- QString imagedir = imagedirs.at(i) + path;
- FileName fname = imageLibFileSearch(imagedir, name1, "svgz,png", mode);
- if (fname.exists())
- return toqstr(fname.absFileName());
-
- fname = imageLibFileSearch(imagedir, name2, "svgz,png", mode);
- if (fname.exists())
- return toqstr(fname.absFileName());
- }
-
- path = ":/images/" + path;
- QDir res(path);
- if (!res.exists()) {
- LYXERR0("Directory " << path << " not found in resource!");
- return QString();
- }
- if (res.exists(name1 + ".svgz"))
- return path + name1 + ".svgz";
- else if (res.exists(name1 + ".png"))
- return path + name1 + ".png";
-
- if (res.exists(name2 + ".svgz"))
- return path + name2 + ".svgz";
- else if (res.exists(name2 + ".png"))
- return path + name2 + ".png";
-
- LYXERR(Debug::GUI, "Cannot find icon with filename "
- << "\"" << name1 << ".{svgz,png}\""
- << " or filename "
- << "\"" << name2 << ".{svgz,png}\""
- << " for command \""
+ // This is used to search for rtl version of icons which have the +rrtl suffix.
+ QStringList suffixes;
+ if (rtl)
+ suffixes << "+rtl";
+ suffixes << QString();
+
+ for (QString const & imagedir : imagedirs)
+ for (QString const & name : names)
+ for (QString const & suffix : suffixes) {
+ QString id = imagedir;
+ FileName fname = imageLibFileSearch(id, name + suffix, "svgz,png", mode);
+ if (fname.exists())
+ return make_pair(toqstr(fname.absFileName()),
+ rtl && suffix.isEmpty());
+ }
+
+ LYXERR(Debug::GUI, "Cannot find icon for command \""
<< lyxaction.getActionName(f.action())
<< '(' << to_utf8(f.argument()) << ")\"");
- if (unknown) {
- QString imagedir = "images/";
- FileName fname = imageLibFileSearch(imagedir, "unknown", "svgz,png", mode);
- if (fname.exists())
- return toqstr(fname.absFileName());
- return QString(":/images/unknown.svgz");
- }
-
- return QString();
-}
-
-
-bool getPixmap(QPixmap & pixmap, QString const & path)
-{
- return pixmap.load(path);
+ return make_pair(QString(), false);
}
QString fpath = toqstr(fname.absFileName());
QPixmap pixmap = QPixmap();
- if (getPixmap(pixmap, fpath)) {
+ if (pixmap.load(fpath))
return pixmap;
- }
-
- QStringList exts = ext.split(",");
- fpath = ":/" + path + name + ".";
- for (int i = 0; i < exts.size(); ++i) {
- if (getPixmap(pixmap, fpath + exts.at(i))) {
- return pixmap;
- }
- }
bool const list = ext.contains(",");
- LYXERR0("Cannot load pixmap \""
- << path << name << "." << (list ? "{" : "") << ext
- << (list ? "}" : "") << "\", please verify resource system!");
+ LYXERR(Debug::GUI, "Cannot load pixmap \""
+ << path << "/" << name << "." << (list ? "{" : "") << ext
+ << (list ? "}" : "") << "\".");
return QPixmap();
}
-QIcon getIcon(FuncRequest const & f, bool unknown)
+QIcon getIcon(FuncRequest const & f, bool unknown, bool rtl)
{
#if (QT_VERSION >= 0x040600)
if (lyxrc.use_system_theme_icons) {
}
#endif
- QString icon = iconName(f, unknown);
+ QString icon;
+ bool flip;
+ tie(icon, flip) = iconName(f, unknown, rtl);
if (icon.isEmpty())
return QIcon();
//LYXERR(Debug::GUI, "Found icon: " << icon);
QPixmap pixmap = QPixmap();
- if (!getPixmap(pixmap,icon)) {
- LYXERR0("Cannot load icon " << icon << " please verify resource system!");
+ if (!pixmap.load(icon)) {
+ LYXERR0("Cannot load icon " << icon << ".");
return QIcon();
}
- return QIcon(pixmap);
+ if (flip)
+ return QIcon(pixmap.transformed(QTransform().scale(-1, 1)));
+ else
+ return QIcon(pixmap);
}
struct GuiApplication::Private
{
Private(): language_model_(0), meta_fake_bit(NoModifier),
- global_menubar_(0)
+ global_menubar_(0)
{
#if (QT_VERSION < 0x050000) || (QT_VERSION >= 0x050400)
#if defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN)
docstring Application::iconName(FuncRequest const & f, bool unknown)
{
- return qstring_to_ucs4(lyx::frontend::iconName(f, unknown));
+ return qstring_to_ucs4(lyx::frontend::iconName(f, unknown, false).first);
}
break;
}
- case LFUN_BIDI: {
- string const dir = cmd.getArg(0);
- string const lfun = cmd.getLongArg(1);
+ case LFUN_IF_RELATIVES: {
+ string const lfun = to_utf8(cmd.argument());
BufferView const * bv =
current_view_ ? current_view_->currentBufferView() : nullptr;
- bool rtl = bv ? bv->cursor().innerParagraph().isRTL(bv->buffer().params())
- : layoutDirection() == Qt::RightToLeft;
- if (((rtl && dir != "rtl") || (!rtl && dir != "ltr"))) {
- flag.setUnknown(true);
- flag.setEnabled(false);
- } else {
- FuncRequest func(lyxaction.lookupFunc(lfun));
- func.setOrigin(cmd.origin());
- flag = getStatus(func);
+ if (!bv || (bv->buffer().parent() == nullptr && !bv->buffer().hasChildren())) {
+ enable = false;
+ break;
}
+ FuncRequest func(lyxaction.lookupFunc(lfun));
+ func.setOrigin(cmd.origin());
+ flag = getStatus(func);
break;
}
if (dr.needBufferUpdate()) {
bv->cursor().clearBufferUpdate();
bv->buffer().updateBuffer();
- } else if (dr.needChangesUpdate()) {
- // updateBuffer() already updates the change-tracking presence flag
- bv->buffer().updateChangesPresent();
}
// BufferView::update() updates the ViewMetricsInfo and
// also initializes the position cache for all insets in
lyxrc.cursor_follows_scrollbar = !lyxrc.cursor_follows_scrollbar;
break;
- // --- syntax commands ----------------------------
case LFUN_REPEAT: {
// repeat command
string countstr;
break;
}
- case LFUN_BIDI: {
- string const lfun = cmd.getLongArg(1);
- FuncRequest func(lyxaction.lookupFunc(cmd.getLongArg(1)));
+ case LFUN_IF_RELATIVES: {
+ string const lfun = to_utf8(cmd.argument());
+ FuncRequest func(lyxaction.lookupFunc(lfun));
func.setOrigin(cmd.origin());
FuncStatus const stat = getStatus(func);
if (stat.enabled()) {
}
+bool GuiApplication::rtlContext() const
+{
+ if (current_view_ && current_view_->currentBufferView()) {
+ BufferView const * bv = current_view_->currentBufferView();
+ return bv->cursor().innerParagraph().isRTL(bv->buffer().params());
+ } else
+ return layoutDirection() == Qt::RightToLeft;
+}
+
+
void GuiApplication::createView(int view_id)
{
createView(QString(), true, view_id);
// not doing that, maybe because of our
// "persistent selection" implementation
// (see comments in GuiSelection.cpp).
- xcb_selection_notify_event_t nev;
+ // It is expected that every X11 event is
+ // 32 bytes long, even if not all 32 bytes are
+ // needed. See:
+ // https://www.x.org/releases/current/doc/man/man3/xcb_send_event.3.xhtml
+ struct alignas(32) padded_event
+ : xcb_selection_notify_event_t {};
+ padded_event nev = {};
nev.response_type = XCB_SELECTION_NOTIFY;
nev.requestor = srev->requestor;
nev.selection = srev->selection;