#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <QX11Info>
+#undef CursorShape
#undef None
#elif defined(QPA_XCB)
#include <xcb/xcb.h>
};
-////////////////////////////////////////////////////////////////////////
-//
-// Mac specific stuff goes here...
-//
-////////////////////////////////////////////////////////////////////////
-
-class MenuTranslator : public QTranslator
+class GuiTranslator : public QTranslator
{
public:
- MenuTranslator(QObject * parent)
+ GuiTranslator(QObject * parent = nullptr)
: QTranslator(parent)
{}
-#if QT_VERSION >= 0x050000
virtual QString translate(const char * /* context */,
const char *sourceText,
+#if QT_VERSION >= 0x050000
const char * /* disambiguation */ = 0, int /* n */ = -1) const
#else
- QString translate(const char * /*context*/,
- const char * sourceText,
- const char * /*comment*/ = 0) const
+ const char * /*comment*/ = 0) const
#endif
{
- string const s = sourceText;
- if (s == N_("About %1") || s == N_("Preferences")
- || s == N_("Reconfigure") || s == N_("Quit %1"))
- return qt_(s);
- else
- return QString();
+ // Here we declare the strings that need to be translated from Qt own GUI
+ // This is needed to include these strings to po files
+ _("About %1");
+ _("Preferences");
+ _("Reconfigure");
+ _("Quit %1");
+ _("&OK");
+ // Already in po: "Cancel", "&Cancel"
+ _("Apply"); // Already in po: "&Apply"
+ _("Reset"); // Already in po: "&Reset" "R&eset" "Rese&t"
+
+ docstring s = getGuiMessages().getIfFound(sourceText);
+ // This test should eventually be removed when translations are updated
+ if (s.empty())
+ LYXERR(Debug::LOCALE, "Missing translation for `"
+ << string(sourceText) << "'");
+ return toqstr(s);
}
};
+
+////////////////////////////////////////////////////////////////////////
+//
+// Mac specific stuff goes here...
+//
+////////////////////////////////////////////////////////////////////////
+
#ifdef Q_OS_MAC
// QMacPasteboardMimeGraphics can only be compiled on Mac.
FontLoader font_loader_;
///
ColorCache color_cache_;
- ///
+ /// the built-in Qt translation mechanism
QTranslator qt_trans_;
+ /// LyX gettext-based translation for Qt elements
+ GuiTranslator gui_trans_;
///
QHash<int, SocketNotifier *> socket_notifiers_;
///
qsrand(QDateTime::currentDateTime().toTime_t());
- // Install translator for GUI elements.
+ // Install LyX translator for missing Qt translations
+ installTranslator(&d->gui_trans_);
+ // Install Qt native translator for GUI elements.
installTranslator(&d->qt_trans_);
#ifdef QPA_XCB
// FIXME: Do we need a lyxrc setting for this on Mac? This behaviour
// seems to be the default case for applications like LyX.
setQuitOnLastWindowClosed(false);
- // This allows to translate the strings that appear in the LyX menu.
- /// A translator suitable for the entries in the LyX menu.
- /// Only needed with Qt/Mac.
- installTranslator(new MenuTranslator(this));
///
setupApplescript();
#endif
static docstring makeDispatchMessage(docstring const & msg,
FuncRequest const & cmd)
{
- const bool verbose = (cmd.origin() == FuncRequest::MENU
+ const bool be_verbose = (cmd.origin() == FuncRequest::MENU
|| cmd.origin() == FuncRequest::TOOLBAR
|| cmd.origin() == FuncRequest::COMMANDBUFFER);
- if (cmd.action() == LFUN_SELF_INSERT || !verbose) {
- LYXERR(Debug::ACTION, "dispatch msg is " << msg);
+ if (cmd.action() == LFUN_SELF_INSERT || !be_verbose) {
+ LYXERR(Debug::ACTION, "dispatch msg is `" << msg << "'");
return msg;
}
DispatchResult const & GuiApplication::dispatch(FuncRequest const & cmd)
{
+ DispatchResult dr;
+
Buffer * buffer = 0;
+ if (cmd.view_origin() && current_view_ != cmd.view_origin()) {
+ //setCurrentView(cmd.view_origin); //does not work
+ dr.setError(true);
+ dr.setMessage(_("Wrong focus!"));
+ d->dispatch_result_ = dr;
+ return d->dispatch_result_;
+ }
if (current_view_ && current_view_->currentBufferView()) {
current_view_->currentBufferView()->cursor().saveBeforeDispatchPosXY();
buffer = ¤t_view_->currentBufferView()->buffer();
- if (buffer)
- buffer->undo().beginUndoGroup();
}
- DispatchResult dr;
+ dr.screenUpdate(Update::FitCursor);
+ {
+ // This handles undo groups automagically
+ UndoGroupHelper ugh(buffer);
+ dispatch(cmd, dr);
+ }
+
// redraw the screen at the end (first of the two drawing steps).
// This is done unless explicitly requested otherwise
- dr.screenUpdate(Update::FitCursor);
- dispatch(cmd, dr);
updateCurrentView(cmd, dr);
-
- // the buffer may have been closed by one action
- if (theBufferList().isLoaded(buffer))
- buffer->undo().endUndoGroup();
-
d->dispatch_result_ = dr;
return d->dispatch_result_;
}
// UI, then, nothing would happen. This seems fairly unlikely, but
// it definitely is a bug.
+ dr.forceBufferUpdate();
break;
}
dr.setMessage(bformat(_("Cannot iterate more than %1$d times"), max_iter));
dr.setError(true);
} else {
- for (int i = 0; i < count; ++i)
- dispatch(lyxaction.lookupFunc(rest));
+ for (int i = 0; i < count; ++i) {
+ FuncRequest lfun = lyxaction.lookupFunc(rest);
+ lfun.allowAsync(false);
+ dispatch(lfun);
+ }
}
break;
}
// FIXME: this LFUN should also work without any view.
Buffer * buffer = (current_view_ && current_view_->documentBufferView())
? &(current_view_->documentBufferView()->buffer()) : 0;
- if (buffer)
- buffer->undo().beginUndoGroup();
+ // This handles undo groups automagically
+ UndoGroupHelper ugh(buffer);
while (!arg.empty()) {
string first;
arg = split(arg, first, ';');
FuncRequest func(lyxaction.lookupFunc(first));
+ func.allowAsync(false);
func.setOrigin(cmd.origin());
dispatch(func);
}
- // the buffer may have been closed by one action
- if (theBufferList().isLoaded(buffer))
- buffer->undo().endUndoGroup();
break;
}
case LFUN_BUFFER_FORALL: {
- FuncRequest const funcToRun = lyxaction.lookupFunc(cmd.getLongArg(0));
+ FuncRequest funcToRun = lyxaction.lookupFunc(cmd.getLongArg(0));
+ funcToRun.allowAsync(false);
map<Buffer *, GuiView *> views_lVisible;
map<GuiView *, Buffer *> activeBuffers;
void GuiApplication::processFuncRequestQueue()
{
while (!d->func_request_queue_.empty()) {
- processFuncRequest(d->func_request_queue_.front());
+ // take the item from the stack _before_ processing the
+ // request in order to avoid race conditions from nested
+ // or parallel requests (see #10406)
+ FuncRequest const fr(d->func_request_queue_.front());
d->func_request_queue_.pop();
+ processFuncRequest(fr);
}
}
bool GuiApplication::searchMenu(FuncRequest const & func,
docstring_list & names) const
{
- return d->menus_.searchMenu(func, names);
+ BufferView * bv = 0;
+ if (current_view_)
+ bv = current_view_->currentBufferView();
+ return d->menus_.searchMenu(func, names, bv);
+}
+
+
+bool GuiApplication::hasBufferView() const
+{
+ return (current_view_ && current_view_->currentBufferView());
}