mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-09 18:31:04 +00:00
add generic helper class for calling functions in gui thread
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@35735 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
e35f55975e
commit
c259957b69
@ -14,7 +14,6 @@
|
||||
|
||||
#include "alert.h"
|
||||
|
||||
|
||||
#include "frontends/Application.h"
|
||||
|
||||
#include "qt_helpers.h"
|
||||
@ -25,6 +24,7 @@
|
||||
#include "support/docstring.h"
|
||||
#include "support/lstrings.h"
|
||||
#include "support/ProgressInterface.h"
|
||||
#include "support/InGuiThread.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCheckBox>
|
||||
@ -37,6 +37,11 @@
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
// sync with GuiView.cpp
|
||||
#define EXPORT_in_THREAD 0
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace lyx::support;
|
||||
|
||||
@ -124,7 +129,8 @@ void noAppDialog(QString const & title, QString const & msg, QMessageBox::Icon m
|
||||
|
||||
namespace Alert {
|
||||
|
||||
int prompt(docstring const & title0, docstring const & question,
|
||||
|
||||
int doPrompt(docstring const & title0, docstring const & question,
|
||||
int default_button, int cancel_button,
|
||||
docstring const & b1, docstring const & b2,
|
||||
docstring const & b3, docstring const & b4)
|
||||
@ -178,8 +184,21 @@ int prompt(docstring const & title0, docstring const & question,
|
||||
return res;
|
||||
}
|
||||
|
||||
int prompt(docstring const & title0, docstring const & question,
|
||||
int default_button, int cancel_button,
|
||||
docstring const & b1, docstring const & b2,
|
||||
docstring const & b3, docstring const & b4)
|
||||
{
|
||||
#ifdef EXPORT_in_THREAD
|
||||
return InGuiThread<int>().call(&doPrompt,
|
||||
#else
|
||||
return doPrompt(
|
||||
#endif
|
||||
title0, question, default_button,
|
||||
cancel_button, b1, b2, b3, b4);
|
||||
}
|
||||
|
||||
void warning(docstring const & title0, docstring const & message,
|
||||
void doWarning(docstring const & title0, docstring const & message,
|
||||
bool const & askshowagain)
|
||||
{
|
||||
lyxerr << "Warning: " << title0 << '\n'
|
||||
@ -213,8 +232,18 @@ void warning(docstring const & title0, docstring const & message,
|
||||
qApp->restoreOverrideCursor();
|
||||
}
|
||||
|
||||
void warning(docstring const & title0, docstring const & message,
|
||||
bool const & askshowagain)
|
||||
{
|
||||
#ifdef EXPORT_in_THREAD
|
||||
InGuiThread<void>().call(&doWarning,
|
||||
#else
|
||||
doWarning(
|
||||
#endif
|
||||
title0, message, askshowagain);
|
||||
}
|
||||
|
||||
void error(docstring const & title0, docstring const & message)
|
||||
void doError(docstring const & title0, docstring const & message)
|
||||
{
|
||||
lyxerr << "Error: " << title0 << '\n'
|
||||
<< "----------------------------------------\n"
|
||||
@ -240,8 +269,17 @@ void error(docstring const & title0, docstring const & message)
|
||||
qApp->restoreOverrideCursor();
|
||||
}
|
||||
|
||||
void error(docstring const & title0, docstring const & message)
|
||||
{
|
||||
#ifdef EXPORT_in_THREAD
|
||||
InGuiThread<void>().call(&doError,
|
||||
#else
|
||||
doError(
|
||||
#endif
|
||||
title0, message);
|
||||
}
|
||||
|
||||
void information(docstring const & title0, docstring const & message)
|
||||
void doInformation(docstring const & title0, docstring const & message)
|
||||
{
|
||||
if (!use_gui || lyxerr.debugging())
|
||||
lyxerr << title0 << '\n'
|
||||
@ -268,8 +306,17 @@ void information(docstring const & title0, docstring const & message)
|
||||
qApp->restoreOverrideCursor();
|
||||
}
|
||||
|
||||
void information(docstring const & title0, docstring const & message)
|
||||
{
|
||||
#ifdef EXPORT_in_THREAD
|
||||
InGuiThread<void>().call(&doInformation,
|
||||
#else
|
||||
doInformation(
|
||||
#endif
|
||||
title0, message);
|
||||
}
|
||||
|
||||
bool askForText(docstring & response, docstring const & msg,
|
||||
bool doAskForText(docstring & response, docstring const & msg,
|
||||
docstring const & dflt)
|
||||
{
|
||||
if (!use_gui || lyxerr.debugging()) {
|
||||
@ -300,6 +347,16 @@ bool askForText(docstring & response, docstring const & msg,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool askForText(docstring & response, docstring const & msg,
|
||||
docstring const & dflt)
|
||||
{
|
||||
#ifdef EXPORT_in_THREAD
|
||||
return InGuiThread<bool>().call(&doAskForText,
|
||||
#else
|
||||
return doAskGForText(
|
||||
#endif
|
||||
response, msg, dflt);
|
||||
}
|
||||
|
||||
} // namespace Alert
|
||||
} // namespace frontend
|
||||
|
52
src/support/InGuiThread.cpp
Normal file
52
src/support/InGuiThread.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* \file InGuiThread.cpp
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Peter Kümmel
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#include "InGuiThread.h"
|
||||
|
||||
#include <QThread>
|
||||
#include <QEventLoop>
|
||||
#include <QApplication>
|
||||
|
||||
namespace lyx {
|
||||
namespace frontend {
|
||||
|
||||
|
||||
IntoGuiThreadMover::IntoGuiThreadMover()
|
||||
{
|
||||
moveToThread(QApplication::instance()->thread());
|
||||
connect(this, SIGNAL(triggerCall()), this, SLOT(doFunctionCall()),
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
|
||||
void IntoGuiThreadMover::callInGuiThread()
|
||||
{
|
||||
if (QThread::currentThread() == QApplication::instance()->thread()) {
|
||||
synchronousFunctionCall();
|
||||
} else {
|
||||
QEventLoop loop;
|
||||
connect(this, SIGNAL(called()), &loop, SLOT(quit()));
|
||||
Q_EMIT triggerCall();
|
||||
loop.exec();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IntoGuiThreadMover::doFunctionCall()
|
||||
{
|
||||
synchronousFunctionCall();
|
||||
Q_EMIT called();
|
||||
}
|
||||
|
||||
|
||||
} // namespace frontend
|
||||
} // namespace lyx
|
||||
|
||||
|
172
src/support/InGuiThread.h
Normal file
172
src/support/InGuiThread.h
Normal file
@ -0,0 +1,172 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file InGuiThread.h
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Peter Kümmel
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#ifndef INGUITHREAD_H
|
||||
#define INGUITHREAD_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "support/bind.h"
|
||||
#include "support/functional.h"
|
||||
|
||||
namespace lyx {
|
||||
namespace frontend {
|
||||
|
||||
|
||||
class IntoGuiThreadMover : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
|
||||
IntoGuiThreadMover();
|
||||
|
||||
void callInGuiThread();
|
||||
|
||||
Q_SIGNALS:
|
||||
void triggerCall();
|
||||
void called();
|
||||
|
||||
private Q_SLOTS:
|
||||
void doFunctionCall();
|
||||
|
||||
private:
|
||||
virtual void synchronousFunctionCall() = 0;
|
||||
};
|
||||
|
||||
|
||||
template<class R>
|
||||
class InGuiThread : private IntoGuiThreadMover
|
||||
{
|
||||
public:
|
||||
|
||||
InGuiThread() {}
|
||||
|
||||
template<class F>
|
||||
R call(F f)
|
||||
{
|
||||
func_ = f;
|
||||
callInGuiThread();
|
||||
return return_value_;
|
||||
}
|
||||
|
||||
template<class F, class P1>
|
||||
R call(F f, P1 p1)
|
||||
{
|
||||
return call(bind(f, p1));
|
||||
}
|
||||
|
||||
template<class F, class P1, class P2>
|
||||
R call(F f, P1 p1, P2 p2)
|
||||
{
|
||||
return call(bind(f, p1, p2));
|
||||
}
|
||||
|
||||
template<class F, class P1, class P2, class P3>
|
||||
R call(F f, P1 p1, P2 p2, P3 p3)
|
||||
{
|
||||
return call(bind(f, p1, p2, p3));
|
||||
}
|
||||
|
||||
template<class F, class P1, class P2, class P3, class P4>
|
||||
R call(F f, P1 p1, P2 p2, P3 p3, P4 p4)
|
||||
{
|
||||
return call(bind(f, p1, p2, p3, p4));
|
||||
}
|
||||
|
||||
/*
|
||||
...
|
||||
*/
|
||||
|
||||
template<class F, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
|
||||
R call(F f, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
|
||||
{
|
||||
return call(bind(f, p1, p2, p3, p4, p5, p6, p7, p8));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void synchronousFunctionCall()
|
||||
{
|
||||
return_value_ = func_();
|
||||
}
|
||||
|
||||
private:
|
||||
R return_value_;
|
||||
function<R()> func_;
|
||||
};
|
||||
|
||||
|
||||
// void specialisation
|
||||
template<>
|
||||
class InGuiThread<void> : private IntoGuiThreadMover
|
||||
{
|
||||
public:
|
||||
|
||||
InGuiThread() {}
|
||||
|
||||
template<class F>
|
||||
void call(F f)
|
||||
{
|
||||
func_ = f;
|
||||
callInGuiThread();
|
||||
}
|
||||
|
||||
template<class F, class P1>
|
||||
void call(F f, P1 p1)
|
||||
{
|
||||
call(bind(f, p1));
|
||||
}
|
||||
|
||||
template<class F, class P1, class P2>
|
||||
void call(F f, P1 p1, P2 p2)
|
||||
{
|
||||
call(bind(f, p1, p2));
|
||||
}
|
||||
|
||||
template<class F, class P1, class P2, class P3>
|
||||
void call(F f, P1 p1, P2 p2, P3 p3)
|
||||
{
|
||||
call(bind(f, p1, p2, p3));
|
||||
}
|
||||
|
||||
template<class F, class P1, class P2, class P3, class P4>
|
||||
void call(F f, P1 p1, P2 p2, P3 p3, P4 p4)
|
||||
{
|
||||
call(bind(f, p1, p2, p3, p4));
|
||||
}
|
||||
|
||||
/*
|
||||
...
|
||||
*/
|
||||
|
||||
template<class F, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
|
||||
void call(F f, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
|
||||
{
|
||||
call(bind(f, p1, p2, p3, p4, p5, p6, p7, p8));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void synchronousFunctionCall()
|
||||
{
|
||||
func_();
|
||||
}
|
||||
|
||||
private:
|
||||
function<void()> func_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace frontend
|
||||
} // namespace lyx
|
||||
|
||||
#endif // GUIABOUT_H
|
@ -56,10 +56,13 @@ liblyxsupport_a_SOURCES = \
|
||||
foreach.h \
|
||||
ForkedCalls.cpp \
|
||||
ForkedCalls.h \
|
||||
functional.h \
|
||||
gettext.cpp \
|
||||
gettext.h \
|
||||
gzstream.cpp \
|
||||
gzstream.h \
|
||||
InGuiThread.h \
|
||||
InGuiThread.cpp \
|
||||
kill.cpp \
|
||||
lassert.h \
|
||||
lassert.cpp \
|
||||
|
41
src/support/functional.h
Normal file
41
src/support/functional.h
Normal file
@ -0,0 +1,41 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file functional.h
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Peter Kümmel
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#ifndef LYX_FUNCTIONAL_H
|
||||
#define LYX_FUNCTIONAL_H
|
||||
|
||||
#ifdef LYX_USE_TR1
|
||||
|
||||
#include <functional>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include <tr1/functional>
|
||||
#endif
|
||||
|
||||
namespace lyx
|
||||
{
|
||||
using std::tr1::function;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/functional.hpp>
|
||||
|
||||
namespace lyx
|
||||
{
|
||||
using boost::function;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user