Now ESC cancels long Advanced Find and Replace operations.

(see #7217 and #7965 for related issues and discussion)


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@40877 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Tommaso Cucinotta 2012-03-06 23:21:12 +00:00
parent 8d55d452ff
commit c324d6eae6
5 changed files with 92 additions and 3 deletions

View File

@ -239,6 +239,14 @@ public:
/// Handle a accented char key sequence /// Handle a accented char key sequence
/// FIXME: this is only needed for LFUN_ACCENT_* in Text::dispatch() /// FIXME: this is only needed for LFUN_ACCENT_* in Text::dispatch()
virtual void handleKeyFunc(FuncCode action) = 0; virtual void handleKeyFunc(FuncCode action) = 0;
/// Start a long operation with some cancel possibility (button or ESC)
virtual void startLongOperation() = 0;
/// This needs to be periodically called to avoid freezing the GUI
virtual bool longOperationCancelled() = 0;
/// Stop the long operation mode (i.e., release the GUI)
virtual void stopLongOperation() = 0;
}; };
/// Return the list of loadable formats. /// Return the list of loadable formats.

View File

@ -294,6 +294,8 @@ bool FindAndReplaceWidget::findAndReplaceScope(FindAndReplaceOptions & opt, bool
oss << opt; oss << opt;
FuncRequest cmd(LFUN_WORD_FINDADV, from_utf8(oss.str())); FuncRequest cmd(LFUN_WORD_FINDADV, from_utf8(oss.str()));
view_.message(_("Advanced search started: please wait . . ."));
theApp()->startLongOperation();
view_.setBusy(true); view_.setBusy(true);
if (opt.scope == FindAndReplaceOptions::S_ALL_MANUALS) { if (opt.scope == FindAndReplaceOptions::S_ALL_MANUALS) {
vector<string> const & v = allManualsFiles(); vector<string> const & v = allManualsFiles();
@ -301,7 +303,9 @@ bool FindAndReplaceWidget::findAndReplaceScope(FindAndReplaceOptions & opt, bool
FileName const & fname = FileName(*v.begin()); FileName const & fname = FileName(*v.begin());
if (!theBufferList().exists(fname)) { if (!theBufferList().exists(fname)) {
guiApp->currentView()->setBusy(false); guiApp->currentView()->setBusy(false);
theApp()->stopLongOperation();
guiApp->currentView()->loadDocument(fname, false); guiApp->currentView()->loadDocument(fname, false);
theApp()->startLongOperation();
guiApp->currentView()->setBusy(true); guiApp->currentView()->setBusy(true);
} }
buf = theBufferList().getBuffer(fname); buf = theBufferList().getBuffer(fname);
@ -327,10 +331,19 @@ bool FindAndReplaceWidget::findAndReplaceScope(FindAndReplaceOptions & opt, bool
if (replace_all) if (replace_all)
continue; continue;
view_.setBusy(false); view_.setBusy(false);
theApp()->stopLongOperation();
return true; return true;
} else if (replace_all) } else if (replace_all)
bv->clearSelection(); bv->clearSelection();
if (theApp()->longOperationCancelled()) {
// Search aborted by user
view_.message(_("Advanced search cancelled by user"));
view_.setBusy(false);
theApp()->stopLongOperation();
return false;
}
// No match found in current buffer (however old selection might have been replaced) // No match found in current buffer (however old selection might have been replaced)
// select next buffer in scope, if any // select next buffer in scope, if any
bool const prompt = nextPrevBuffer(buf, opt); bool const prompt = nextPrevBuffer(buf, opt);
@ -341,9 +354,11 @@ bool FindAndReplaceWidget::findAndReplaceScope(FindAndReplaceOptions & opt, bool
break; break;
docstring q = getQuestionString(opt); docstring q = getQuestionString(opt);
view_.setBusy(false); view_.setBusy(false);
theApp()->stopLongOperation();
wrap_answer = frontend::Alert::prompt( wrap_answer = frontend::Alert::prompt(
_("Wrap search?"), q, _("Wrap search?"), q,
0, 1, _("&Yes"), _("&No")); 0, 1, _("&Yes"), _("&No"));
theApp()->startLongOperation();
view_.setBusy(true); view_.setBusy(true);
if (wrap_answer == 1) if (wrap_answer == 1)
break; break;
@ -373,6 +388,7 @@ bool FindAndReplaceWidget::findAndReplaceScope(FindAndReplaceOptions & opt, bool
cur_orig.pos() = cur_orig.lastpos(); cur_orig.pos() = cur_orig.lastpos();
bv->cursor().setCursor(cur_orig); bv->cursor().setCursor(cur_orig);
view_.setBusy(false); view_.setBusy(false);
theApp()->stopLongOperation();
return false; return false;
} }

View File

@ -80,12 +80,14 @@
#include <QClipboard> #include <QClipboard>
#include <QDateTime> #include <QDateTime>
#include <QDir> #include <QDir>
#include <QEvent>
#include <QEventLoop> #include <QEventLoop>
#include <QFileOpenEvent> #include <QFileOpenEvent>
#include <QFileInfo> #include <QFileInfo>
#include <QHash> #include <QHash>
#include <QIcon> #include <QIcon>
#include <QImageReader> #include <QImageReader>
#include <QKeyEvent>
#include <QLocale> #include <QLocale>
#include <QLibraryInfo> #include <QLibraryInfo>
#include <QList> #include <QList>
@ -98,6 +100,7 @@
#include <QRegExp> #include <QRegExp>
#include <QSessionManager> #include <QSessionManager>
#include <QSettings> #include <QSettings>
#include <QShowEvent>
#include <QSocketNotifier> #include <QSocketNotifier>
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
#include <QStandardItemModel> #include <QStandardItemModel>
@ -675,6 +678,43 @@ public:
#endif // Q_WS_WIN #endif // Q_WS_WIN
/// Allows to check whether ESC was pressed during a long operation
class KeyChecker : public QObject {
private:
bool pressed_;
public:
KeyChecker() {
pressed_ = false;
}
void start() {
QCoreApplication::instance()->installEventFilter(this);
pressed_ = false;
}
void stop() {
QCoreApplication::instance()->removeEventFilter(this);
}
bool pressed() {
QCoreApplication::processEvents();
return pressed_;
}
bool eventFilter(QObject *obj, QEvent *event) {
LYXERR(Debug::ACTION, "Event Type: " << event->type());
switch (event->type()) {
case QEvent::Show:
case QEvent::Hide:
case QEvent::Resize:
return QObject::eventFilter(obj, event);
default:
QKeyEvent *keyEvent = dynamic_cast<QKeyEvent*>(event);
if (keyEvent && keyEvent->key() == Qt::Key_Escape)
pressed_ = true;
return true;
}
}
};
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// GuiApplication::Private definition and implementation. // GuiApplication::Private definition and implementation.
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -752,6 +792,9 @@ struct GuiApplication::Private
/// WMF Mime handler for Windows clipboard. /// WMF Mime handler for Windows clipboard.
QWindowsMimeMetafile * wmf_mime_; QWindowsMimeMetafile * wmf_mime_;
#endif #endif
/// Allows to check whether ESC was pressed during a long operation
KeyChecker key_checker_;
}; };
@ -2529,6 +2572,21 @@ void GuiApplication::onLastWindowClosed()
} }
void GuiApplication::startLongOperation() {
d->key_checker_.start();
}
bool GuiApplication::longOperationCancelled() {
return d->key_checker_.pressed();
}
void GuiApplication::stopLongOperation() {
d->key_checker_.stop();
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// //
// X11 specific stuff goes here... // X11 specific stuff goes here...

View File

@ -169,6 +169,13 @@ public:
/// not the current buffer /// not the current buffer
void gotoBookmark(unsigned int idx, bool openFile, bool switchToBuffer); void gotoBookmark(unsigned int idx, bool openFile, bool switchToBuffer);
/// Start a long operation with some cancel possibility (button or ESC)
void startLongOperation();
/// This needs to be periodically called to avoid freezing the GUI
bool longOperationCancelled();
/// Stop the long operation mode (i.e., release the GUI)
void stopLongOperation();
private Q_SLOTS: private Q_SLOTS:
/// ///
void execBatchCommands(); void execBatchCommands();

View File

@ -1133,12 +1133,12 @@ int findForwardAdv(DocIterator & cur, MatchStringAdv & match)
{ {
if (!cur) if (!cur)
return 0; return 0;
while (cur) { while (!theApp()->longOperationCancelled() && cur) {
LYXERR(Debug::FIND, "findForwardAdv() cur: " << cur); LYXERR(Debug::FIND, "findForwardAdv() cur: " << cur);
int match_len = match(cur, -1, false); int match_len = match(cur, -1, false);
LYXERR(Debug::FIND, "match_len: " << match_len); LYXERR(Debug::FIND, "match_len: " << match_len);
if (match_len) { if (match_len) {
for (; cur; cur.forwardPos()) { for (; !theApp()->longOperationCancelled() && cur; cur.forwardPos()) {
LYXERR(Debug::FIND, "Advancing cur: " << cur); LYXERR(Debug::FIND, "Advancing cur: " << cur);
int match_len = match(cur); int match_len = match(cur);
LYXERR(Debug::FIND, "match_len: " << match_len); LYXERR(Debug::FIND, "match_len: " << match_len);
@ -1235,7 +1235,7 @@ int findBackwardsAdv(DocIterator & cur, MatchStringAdv & match) {
else else
cur.backwardPos(); cur.backwardPos();
pit_changed = true; pit_changed = true;
} while (true); } while (!theApp()->longOperationCancelled());
return 0; return 0;
} }