Il 10/05/2011 13:30, LyX Ticket Tracker ha scritto:
I think that the possibility to cancel the search with ESC is a
  good feature. Please send it to the lyx-devel list for discussion.

I made a quick update of the patch on the current branch, and here it is, just in case you like having it in for 2.0.4.

Among issues that might be related to the lack of this feature, we have:
-) http://www.lyx.org/trac/ticket/7965
-) http://www.lyx.org/trac/ticket/7217
(just replaced the patch attached to the ticket with this one I'm sending)

Bye,

    Tommaso
Index: src/lyxfind.cpp
===================================================================
--- src/lyxfind.cpp	(revisione 40874)
+++ src/lyxfind.cpp	(copia locale)
@@ -1133,12 +1133,12 @@
 {
 	if (!cur)
 		return 0;
-	while (cur) {
+	while (!theApp()->longOperationCancelled() && cur) {
 		LYXERR(Debug::FIND, "findForwardAdv() cur: " << cur);
 		int match_len = match(cur, -1, false);
 		LYXERR(Debug::FIND, "match_len: " << match_len);
 		if (match_len) {
-			for (; cur; cur.forwardPos()) {
+			for (; !theApp()->longOperationCancelled() && cur; cur.forwardPos()) {
 				LYXERR(Debug::FIND, "Advancing cur: " << cur);
 				int match_len = match(cur);
 				LYXERR(Debug::FIND, "match_len: " << match_len);
@@ -1235,7 +1235,7 @@
 		else
 			cur.backwardPos();
 		pit_changed = true;
-	} while (true);
+	} while (!theApp()->longOperationCancelled());
 	return 0;
 }
 
Index: src/frontends/Application.h
===================================================================
--- src/frontends/Application.h	(revisione 40874)
+++ src/frontends/Application.h	(copia locale)
@@ -239,6 +239,14 @@
 	/// Handle a accented char key sequence
 	/// FIXME: this is only needed for LFUN_ACCENT_* in Text::dispatch()
 	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.
Index: src/frontends/qt4/GuiApplication.cpp
===================================================================
--- src/frontends/qt4/GuiApplication.cpp	(revisione 40874)
+++ src/frontends/qt4/GuiApplication.cpp	(copia locale)
@@ -80,12 +80,14 @@
 #include <QClipboard>
 #include <QDateTime>
 #include <QDir>
+#include <QEvent>
 #include <QEventLoop>
 #include <QFileOpenEvent>
 #include <QFileInfo>
 #include <QHash>
 #include <QIcon>
 #include <QImageReader>
+#include <QKeyEvent>
 #include <QLocale>
 #include <QLibraryInfo>
 #include <QList>
@@ -98,6 +100,7 @@
 #include <QRegExp>
 #include <QSessionManager>
 #include <QSettings>
+#include <QShowEvent>
 #include <QSocketNotifier>
 #include <QSortFilterProxyModel>
 #include <QStandardItemModel>
@@ -675,6 +678,43 @@
 
 #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.
 ////////////////////////////////////////////////////////////////////////
@@ -752,6 +792,9 @@
 	/// WMF Mime handler for Windows clipboard.
 	QWindowsMimeMetafile * wmf_mime_;
 #endif
+
+	/// Allows to check whether ESC was pressed during a long operation
+	KeyChecker key_checker_;
 };
 
 
@@ -2529,6 +2572,21 @@
 }
 
 
+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...
Index: src/frontends/qt4/FindAndReplace.cpp
===================================================================
--- src/frontends/qt4/FindAndReplace.cpp	(revisione 40874)
+++ src/frontends/qt4/FindAndReplace.cpp	(copia locale)
@@ -294,6 +294,8 @@
 	oss << opt;
 	FuncRequest cmd(LFUN_WORD_FINDADV, from_utf8(oss.str()));
 
+	view_.message(_("Advanced search started: please wait . . ."));
+	theApp()->startLongOperation();
 	view_.setBusy(true);
 	if (opt.scope == FindAndReplaceOptions::S_ALL_MANUALS) {
 		vector<string> const & v = allManualsFiles();
@@ -301,7 +303,9 @@
 			FileName const & fname = FileName(*v.begin());
 			if (!theBufferList().exists(fname)) {
 				guiApp->currentView()->setBusy(false);
+				theApp()->stopLongOperation();
 				guiApp->currentView()->loadDocument(fname, false);
+				theApp()->startLongOperation();
 				guiApp->currentView()->setBusy(true);
 			}
 			buf = theBufferList().getBuffer(fname);
@@ -327,10 +331,19 @@
 			if (replace_all)
 				continue;
 			view_.setBusy(false);
+			theApp()->stopLongOperation();
 			return true;
 		} else if (replace_all)
 			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)
 		// select next buffer in scope, if any
 		bool const prompt = nextPrevBuffer(buf, opt);
@@ -341,9 +354,11 @@
 				break;
 			docstring q = getQuestionString(opt);
 			view_.setBusy(false);
+			theApp()->stopLongOperation();
 			wrap_answer = frontend::Alert::prompt(
 				_("Wrap search?"), q,
 				0, 1, _("&Yes"), _("&No"));
+			theApp()->startLongOperation();
 			view_.setBusy(true);
 			if (wrap_answer == 1)
 				break;
@@ -373,6 +388,7 @@
 		cur_orig.pos() = cur_orig.lastpos();
 	bv->cursor().setCursor(cur_orig);
 	view_.setBusy(false);
+	theApp()->stopLongOperation();
 	return false;
 }
 
Index: src/frontends/qt4/GuiApplication.h
===================================================================
--- src/frontends/qt4/GuiApplication.h	(revisione 40874)
+++ src/frontends/qt4/GuiApplication.h	(copia locale)
@@ -169,6 +169,13 @@
 	///		not the current buffer
 	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:
 	///
 	void execBatchCommands();

Reply via email to