Am Sonntag, 9. Juli 2006 01:41 schrieb Lars Gullik Bjønnes:
> "Bo Peng" <[EMAIL PROTECTED]> writes:
> 
>   +   case LFUN_CLIPBOARD_PASTE:
> |     case LFUN_PRIMARY_SELECTION_PASTE: {
> |             cur.clearSelection();
> | -           string const clip = bv->owner()->gui().clipboard().get();
> | +           string const clip = (cmd.action == LFUN_CLIPBOARD_PASTE) ?
> | +                   bv->owner()->gui().clipboard().get() :
> | +                   bv->owner()->gui().selection().get();
> | 
> | If the body is not long, I still prefer separating these two
> | actions, rather than telling them apart from cmd.action.
> 
> I might even agree...

In did this now only in text3.C, but not in insettabular.C, since the 
latter would involve duplicating ~40 lines of code.

Attached is an updated patch for easier trying: The new files are 
contained completely. I will commit this tomorrow unless I get new 
complaints. I suggest that the next steps are

- Disable the selection on windows
- Enable the external clipboard to store LyX contents
- Merge the external and internal clipboard and get rid of 
LFUN_CLIPBOARD_PASTE again (probably by simply using the external 
clipboard as the top position of the stack)

I will not have the time to do these steps soon, but this patch is a 
monotonic improvement over the current state of affairs.


Georg

Log:
Split clipboard and X selection
        * src/LyXAction.C
        (LyXAction::init): handle new LFUN_CLIPBOARD_PASTE

        * src/insets/insettabular.C
        (InsetTabular::doDispatch): ditto

        * src/insets/insetbox.C
        (InsetBox::doDispatch): ditto

        * src/insets/insetert.C
        (InsetERT::doDispatch): ditto
        (InsetERT::getStatus): ditto

        * src/insets/insetcharstyle.C
        (InsetCharStyle::doDispatch): ditto

        * src/BufferView_pimpl.C
        (BufferView::Pimpl::selectionRequest): stuff selection, not clipboard

        * src/mathed/math_nestinset.C
        (MathNestInset::lfunMousePress): get stuff selection, not clipboard
        (MathNestInset::lfunMouseRelease): clipboard -> selection in
        commented code

        * src/CutAndPaste.C
        (cutSelection): ditto

        * src/frontends/{qt3,gtk}/GuiImplementation.C
        (GuiImplementation::newWorkArea): create new selection, not clipboard,
        since the clipboard is now an object
        (GuiImplementation::destroyWorkArea): destroy selection, not clipboard

        * src/frontends/{qt4,qt3,gtk}/GuiSelection.h: new, copied from
        GuiClipboard.h

        * src/frontends/{qt4,qt3,gtk}/GuiSelection.C: new, copied from
        GuiClipboard.C

        * src/frontends/{qt3,gtk}/GuiImplementation.h
        (selection): new accessor for selection_
        (selection_): new, the global selection object

        * src/frontends/{qt4,qt3,gtk}/Makefile.am: add GuiSelection.C and
        GuiSelection.h

        * src/frontends/{qt4,qt3,gtk}/GuiClipboard.C
        (GuiClipboard::get): return clipboard, not selection
        (GuiClipboard::put): stuff clipboard, not selection

        * src/frontends/{qt4,qt3,gtk}/GuiClipboard.h
        (haveSelection): remove (this is now in GuiSelection)

        * src/frontends/{qt3,gtk}/GuiClipboard.h
        (old_work_area_): remove, since it is not needed anymore

        * src/frontends/gtk/ghelpers.C
        (getGTKStockIcon): handle LFUN_CLIPBOARD_PASTE

        * src/frontends/Clipboard.h
        (haveSelection): remove (this is now in Selection)

        * src/frontends/qt4/GuiImplementation.[Ch]
        (GuiImplementation::selection): new accessor for selection_

        * src/frontends/Gui.h
        (selection): New accessor for the global selection object

        * src/frontends/Selection.h; new, copied from Clipboard.h

        * src/frontends/Makefile.am: add Selection.h

        * src/text3.C
        (various): s/clipboard().haveSelection/selection().haveSelection/

        (LyXText::dispatch): handle LFUN_CLIPBOARD_PASTE
        (LyXText::getStatus): ditto

        * src/lfuns.h: new lfun LFUN_CLIPBOARD_PASTE

        * lib/ui/stdmenus.ui: add new lfun LFUN_CLIPBOARD_PASTE
Index: src/LyXAction.C
===================================================================
--- src/LyXAction.C	(Revision 14392)
+++ src/LyXAction.C	(Arbeitskopie)
@@ -134,6 +134,7 @@ void LyXAction::init()
 		{ LFUN_CHAR_DELETE_FORWARD, "delete-forward", SingleParUpdate },
 		{ LFUN_CHAR_FORWARD, "char-forward", ReadOnly | NoUpdate},
 		{ LFUN_CHAR_FORWARD_SELECT, "forward-select", ReadOnly | SingleParUpdate },
+		{ LFUN_CLIPBOARD_PASTE, "clipboard-paste", Noop },
 		{ LFUN_COMMAND_EXECUTE, "command-execute", NoBuffer },
 		{ LFUN_COMMAND_PREFIX, "command-prefix", NoBuffer },
 		{ LFUN_COMMAND_SEQUENCE, "command-sequence", NoBuffer },
Index: src/insets/insettabular.C
===================================================================
--- src/insets/insettabular.C	(Revision 14392)
+++ src/insets/insettabular.C	(Arbeitskopie)
@@ -42,6 +42,7 @@
 #include "frontends/LyXView.h"
 #include "frontends/Clipboard.h"
 #include "frontends/Painter.h"
+#include "frontends/Selection.h"
 #include "frontends/nullpainter.h"
 
 #include <sstream>
@@ -686,8 +687,11 @@ void InsetTabular::doDispatch(LCursor & 
 			cell(cur.idx())->dispatch(cur, cmd);
 		break;
 
+	case LFUN_CLIPBOARD_PASTE:
 	case LFUN_PRIMARY_SELECTION_PASTE: {
-		string const clip = cur.bv().owner()->gui().clipboard().get();
+		string const clip = (cmd.action == LFUN_CLIPBOARD_PASTE) ?
+			cur.bv().owner()->gui().clipboard().get() :
+			cur.bv().owner()->gui().selection().get();
 		if (clip.empty())
 			break;
 		// pass to InsertAsciiString, but
Index: src/insets/insetbox.C
===================================================================
--- src/insets/insetbox.C	(Revision 14392)
+++ src/insets/insetbox.C	(Arbeitskopie)
@@ -199,6 +199,7 @@ void InsetBox::doDispatch(LCursor & cur,
 		InsetCollapsable::doDispatch(cur, cmd);
 		break;
 	case LFUN_PASTE:
+	case LFUN_CLIPBOARD_PASTE:
 	case LFUN_PRIMARY_SELECTION_PASTE:
 		InsetCollapsable::doDispatch(cur, cmd);
 		if (!params_.inner_box)
Index: src/insets/insetert.C
===================================================================
--- src/insets/insetert.C	(Revision 14392)
+++ src/insets/insetert.C	(Arbeitskopie)
@@ -239,6 +239,7 @@ void InsetERT::doDispatch(LCursor & cur,
 		break;
 	}
 	case LFUN_PASTE:
+	case LFUN_CLIPBOARD_PASTE:
 	case LFUN_PRIMARY_SELECTION_PASTE: {
 		InsetCollapsable::doDispatch(cur, cmd);
 
@@ -380,6 +381,7 @@ bool InsetERT::getStatus(LCursor & cur, 
 		case LFUN_QUOTE_INSERT:
 		case LFUN_INSET_MODIFY:
 		case LFUN_PASTE:
+		case LFUN_CLIPBOARD_PASTE:
 		case LFUN_PRIMARY_SELECTION_PASTE:
 			status.enabled(true);
 			return true;
Index: src/insets/insetcharstyle.C
===================================================================
--- src/insets/insetcharstyle.C	(Revision 14392)
+++ src/insets/insetcharstyle.C	(Arbeitskopie)
@@ -236,6 +236,7 @@ void InsetCharStyle::doDispatch(LCursor 
 				InsetText::doDispatch(cur, cmd);
 			break;
 	case LFUN_PASTE:
+	case LFUN_CLIPBOARD_PASTE:
 	case LFUN_PRIMARY_SELECTION_PASTE: {
 		InsetCollapsable::doDispatch(cur, cmd);
 		forceParagraphsToDefault(cur);
Index: src/BufferView_pimpl.C
===================================================================
--- src/BufferView_pimpl.C	(Revision 14392)
+++ src/BufferView_pimpl.C	(Arbeitskopie)
@@ -57,12 +57,12 @@
 #include "insets/insettext.h"
 
 #include "frontends/Alert.h"
-#include "frontends/Clipboard.h"
 #include "frontends/Dialogs.h"
 #include "frontends/FileDialog.h"
 #include "frontends/font_metrics.h"
 #include "frontends/Gui.h"
 #include "frontends/LyXView.h"
+#include "frontends/Selection.h"
 
 #include "graphics/Previews.h"
 
@@ -589,7 +589,7 @@ void BufferView::Pimpl::selectionRequest
 		xsel_cache_.set = cur.selection();
 		sel = cur.selectionAsString(false);
 		if (!sel.empty())
-			owner_->gui().clipboard().put(sel);
+			owner_->gui().selection().put(sel);
 	}
 }
 
Index: src/mathed/math_nestinset.C
===================================================================
--- src/mathed/math_nestinset.C	(Revision 14392)
+++ src/mathed/math_nestinset.C	(Arbeitskopie)
@@ -52,8 +52,8 @@
 #include "frontends/Dialogs.h"
 #include "frontends/Gui.h"
 #include "frontends/LyXView.h"
-#include "frontends/Clipboard.h"
 #include "frontends/Painter.h"
+#include "frontends/Selection.h"
 #include "frontends/nullpainter.h"
 
 #include <sstream>
@@ -1088,7 +1088,7 @@ void MathNestInset::lfunMousePress(LCurs
 
 	if (cmd.button() == mouse_button::button2) {
 		MathArray ar;
-		asArray(cur.bv().owner()->gui().clipboard().get(), ar);
+		asArray(cur.bv().owner()->gui().selection().get(), ar);
 		cur.clearSelection();
 		editXY(cur, cmd.x, cmd.y);
 		cur.insert(ar);
@@ -1121,7 +1121,7 @@ void MathNestInset::lfunMouseRelease(LCu
 	//lyxerr << "## lfunMouseRelease: buttons: " << cmd.button() << endl;
 
 	if (cmd.button() == mouse_button::button1) {
-		//cur.bv().owner()->gui().clipboard().put(cur.grabSelection());
+		//cur.bv().owner()->gui().selection().put(cur.grabSelection());
 		return;
 	}
 
Index: src/CutAndPaste.C
===================================================================
--- src/CutAndPaste.C	(Revision 14392)
+++ src/CutAndPaste.C	(Arbeitskopie)
@@ -498,8 +498,8 @@ void cutSelection(LCursor & cur, bool do
 		// solved by running the line below only when the selection has
 		// finished. The solution used currently just works, to make it
 		// faster we need to be more clever and probably also have more
-		// calls to stuffClipboard. (Lgb)
-//		cur.bv().owner()->gui().clipboard().put(cur.selectionAsString(true));
+		// calls to cur.bv().owner()->gui().selection().put. (Lgb)
+//		cur.bv().owner()->gui().selection().put(cur.selectionAsString(true));
 	
 
 		// make sure that the depth behind the selection are restored, too
Index: src/frontends/gtk/GuiImplementation.C
===================================================================
--- src/frontends/gtk/GuiImplementation.C	(Revision 14392)
+++ src/frontends/gtk/GuiImplementation.C	(Arbeitskopie)
@@ -31,7 +31,7 @@ int GuiImplementation::newWorkArea(unsig
 	old_work_area_.reset(new GWorkArea(*view_.get(), w, h));
 	old_screen_.reset(new GScreen(*old_work_area_.get()));
 	work_area_.reset(new GuiWorkArea(old_screen_.get(), old_work_area_.get()));
-	clipboard_.reset(new GuiClipboard(old_work_area_.get()));
+	selection_.reset(new GuiSelection(old_work_area_.get()));
 
 	// FIXME BufferView creation should be independant of WorkArea creation
 	buffer_views_[0].reset(new BufferView(view_.get()));
@@ -43,7 +43,7 @@ int GuiImplementation::newWorkArea(unsig
 
 void GuiImplementation::destroyWorkArea(int /*id*/)
 {
-	clipboard_.reset();
+	selection_.reset();
 	work_area_.reset();
 	old_work_area_.reset();
 	old_screen_.reset();
Index: src/frontends/gtk/GuiSelection.C
===================================================================
--- src/frontends/gtk/GuiSelection.C	(Revision 14378)
+++ src/frontends/gtk/GuiSelection.C	(Arbeitskopie)
@@ -0,0 +1,58 @@
+// -*- C++ -*-
+/**
+ * \file gtk/GuiSelection.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Huang Ying
+ * \author Abdelrazak Younes
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+// Too hard to make concept checks work with this file
+#ifdef _GLIBCXX_CONCEPT_CHECKS
+#undef _GLIBCXX_CONCEPT_CHECKS
+#endif
+#ifdef _GLIBCPP_CONCEPT_CHECKS
+#undef _GLIBCPP_CONCEPT_CHECKS
+#endif
+
+#include "GuiSelection.h"
+#include "debug.h"
+
+#include <gtkmm.h>
+
+using std::endl;
+using std::string;
+
+namespace lyx {
+namespace frontend {
+
+// ENCODING: Gtk::Clipboard returns UTF-8, we assume that the backend
+// wants ISO-8859-1 and convert it to that.
+string const GuiSelection::get() const
+{
+	Glib::RefPtr<Gtk::Clipboard> clipboard =
+		Gtk::Clipboard::get(GDK_SELECTION_PRIMARY);
+	string const str = Glib::convert_with_fallback(
+			clipboard->wait_for_text(), "ISO-8859-1", "UTF-8");
+	lyxerr[Debug::ACTION] << "GuiClipboard::get: " << str << endl;
+	return str;
+}
+
+
+// ENCODING: we assume that the backend passes us ISO-8859-1 and
+// convert from that to UTF-8 before passing to GTK
+void GuiSelection::put(string const & str)
+{
+	lyxerr[Debug::ACTION] << "GuiClipboard::put: " << str << endl;
+	Glib::RefPtr<Gtk::Clipboard> clipboard =
+		Gtk::Clipboard::get(GDK_SELECTION_PRIMARY);
+	clipboard->set_text(Glib::convert(str, "UTF-8", "ISO-8859-1"));
+}
+
+} // namespace frontend
+} // namespace lyx
Index: src/frontends/gtk/GuiImplementation.h
===================================================================
--- src/frontends/gtk/GuiImplementation.h	(Revision 14392)
+++ src/frontends/gtk/GuiImplementation.h	(Arbeitskopie)
@@ -19,6 +19,7 @@
 #include "GWorkArea.h"
 
 #include "GuiClipboard.h"
+#include "GuiSelection.h"
 #include "GuiWorkArea.h"
 
 #include <boost/shared_ptr.hpp>
@@ -42,7 +43,12 @@ public:
 
 	lyx::frontend::Clipboard & clipboard()
 	{
-		return *clipboard_;
+		return clipboard_;
+	}
+
+	lyx::frontend::Selection & selection()
+	{
+		return *selection_;
 	}
 
 	int newView(unsigned int w, unsigned int h);
@@ -68,7 +74,9 @@ public:
 
 private:
 	///
-	boost::shared_ptr<GuiClipboard> clipboard_;
+	GuiClipboard clipboard_;
+	///
+	boost::shared_ptr<GuiSelection> selection_;
 	///
 	boost::shared_ptr<GuiWorkArea> work_area_;
 	///
Index: src/frontends/gtk/Makefile.am
===================================================================
--- src/frontends/gtk/Makefile.am	(Revision 14392)
+++ src/frontends/gtk/Makefile.am	(Arbeitskopie)
@@ -112,6 +112,7 @@ libgtk_la_SOURCES = \
 	GUrl.C \
 	GUrl.h \
 	GuiClipboard.C GuiClipboard.h \
+	GuiSelection.C GuiSelection.h \
 	GuiWorkArea.h \
 	GView.C \
 	GView.h \
Index: src/frontends/gtk/GuiSelection.h
===================================================================
--- src/frontends/gtk/GuiSelection.h	(Revision 14375)
+++ src/frontends/gtk/GuiSelection.h	(Arbeitskopie)
@@ -0,0 +1,55 @@
+// -*- C++ -*-
+/**
+ * \file gtk/Selection.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Abdelrazak Younes
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef SELECTION_H
+#define SELECTION_H
+
+#include "frontends/Selection.h"
+
+#include "GWorkArea.h"
+
+namespace lyx {
+namespace frontend {
+
+/**
+ * The GTK version of the Selection.
+ */
+class GuiSelection: public lyx::frontend::Selection
+{
+public:
+	GuiSelection(GWorkArea * work_area)
+		: old_work_area_(work_area)
+	{
+	}
+
+	virtual ~GuiSelection() {}
+
+	/** Selection overloaded methods
+	 */
+	//@{
+	void haveSelection(bool own)
+	{
+		old_work_area_->haveSelection(own);
+	}
+
+	std::string const get() const;
+
+	void put(std::string const & str);
+	//@}
+
+private:
+	GWorkArea * old_work_area_;
+};
+
+} // namespace frontend
+} // namespace lyx
+
+#endif // SELECTION_H
Index: src/frontends/gtk/GuiClipboard.C
===================================================================
--- src/frontends/gtk/GuiClipboard.C	(Revision 14392)
+++ src/frontends/gtk/GuiClipboard.C	(Arbeitskopie)
@@ -36,7 +36,7 @@ namespace frontend {
 string const GuiClipboard::get() const
 {
 	Glib::RefPtr<Gtk::Clipboard> clipboard =
-		Gtk::Clipboard::get(GDK_SELECTION_PRIMARY);
+		Gtk::Clipboard::get(GDK_SELECTION_CLIPBOARD);
 	string const str = Glib::convert_with_fallback(
 			clipboard->wait_for_text(), "ISO-8859-1", "UTF-8");
 	lyxerr[Debug::ACTION] << "GuiClipboard::get: " << str << endl;
@@ -50,7 +50,7 @@ void GuiClipboard::put(string const & st
 {
 	lyxerr[Debug::ACTION] << "GuiClipboard::put: " << str << endl;
 	Glib::RefPtr<Gtk::Clipboard> clipboard =
-		Gtk::Clipboard::get(GDK_SELECTION_PRIMARY);
+		Gtk::Clipboard::get(GDK_SELECTION_CLIPBOARD);
 	clipboard->set_text(Glib::convert(str, "UTF-8", "ISO-8859-1"));
 }
 
Index: src/frontends/gtk/GuiClipboard.h
===================================================================
--- src/frontends/gtk/GuiClipboard.h	(Revision 14392)
+++ src/frontends/gtk/GuiClipboard.h	(Arbeitskopie)
@@ -14,8 +14,6 @@
 
 #include "frontends/Clipboard.h"
 
-#include "GWorkArea.h"
-
 namespace lyx {
 namespace frontend {
 
@@ -25,28 +23,16 @@ namespace frontend {
 class GuiClipboard: public lyx::frontend::Clipboard
 {
 public:
-	GuiClipboard(GWorkArea * work_area)
-		: old_work_area_(work_area)
-	{
-	}
-
 	virtual ~GuiClipboard() {}
 
 	/** Clipboard overloaded methods
 	 */
 	//@{
-	void haveSelection(bool own)
-	{
-		old_work_area_->haveSelection(own);
-	}
 
 	std::string const get() const;
 
 	void put(std::string const & str);
 	//@}
-
-private:
-	GWorkArea * old_work_area_;
 };
 
 } // namespace frontend
Index: src/frontends/gtk/ghelpers.C
===================================================================
--- src/frontends/gtk/ghelpers.C	(Revision 14392)
+++ src/frontends/gtk/ghelpers.C	(Arbeitskopie)
@@ -54,6 +54,7 @@ Gtk::BuiltinStockID getGTKStockIcon(Func
 		case LFUN_UNDO: return Gtk::Stock::UNDO;
 		case LFUN_REDO: return Gtk::Stock::REDO;
 		case LFUN_PASTE: return Gtk::Stock::PASTE;
+		case LFUN_CLIPBOARD_PASTE: return Gtk::Stock::PASTE;
 		case LFUN_PRIMARY_SELECTION_PASTE: return Gtk::Stock::PASTE;
 		case LFUN_CUT: return Gtk::Stock::CUT;
 		case LFUN_COPY: return Gtk::Stock::COPY;
Index: src/frontends/Clipboard.h
===================================================================
--- src/frontends/Clipboard.h	(Revision 14392)
+++ src/frontends/Clipboard.h	(Arbeitskopie)
@@ -27,11 +27,17 @@ class Clipboard
 public:
 	virtual ~Clipboard() {}
 
-	/// a selection exists
-	virtual void haveSelection(bool) = 0;
-	/// get the X clipboard contents
+	/**
+	 * Get the window system clipboard contents.
+	 * This should be called when the user requests to paste from the
+	 * clipboard.
+	 */
 	virtual std::string const get() const = 0;
-	/// fill the clipboard
+	/**
+	 * Fill the window system clipboard.
+	 * This should be called when the user requests to cut or copy to
+	 * the clipboard.
+	 */
 	virtual void put(std::string const &) = 0;
 };
 
Index: src/frontends/qt3/GuiSelection.C
===================================================================
--- src/frontends/qt3/GuiSelection.C	(Revision 14378)
+++ src/frontends/qt3/GuiSelection.C	(Arbeitskopie)
@@ -0,0 +1,55 @@
+// -*- C++ -*-
+/**
+ * \file qt3/GuiSelection.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author John Levon
+ * \author Abdelrazak Younes
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "GuiSelection.h"
+#include "qt_helpers.h"
+
+#include "debug.h"
+
+#include <qapplication.h>
+#include <qclipboard.h>
+#include <qstring.h>
+
+#include "support/lstrings.h"
+using lyx::support::internalLineEnding;
+using lyx::support::externalLineEnding;
+
+using std::endl;
+using std::string;
+
+namespace lyx {
+namespace frontend {
+
+string const GuiSelection::get() const
+{
+	QString const str = qApp->clipboard()->text(QClipboard::Selection);
+	lyxerr[Debug::ACTION] << "GuiSelection::get: " << (const char*) str
+	                      << endl;
+	if (str.isNull())
+		return string();
+
+	return internalLineEnding(fromqstr(str));
+}
+
+
+void GuiSelection::put(string const & str)
+{
+	lyxerr[Debug::ACTION] << "GuiSelection::put: " << str << endl;
+
+	qApp->clipboard()->setText(toqstr(externalLineEnding(str)),
+	                           QClipboard::Selection);
+}
+
+} // namespace frontend
+} // namespace lyx
Index: src/frontends/qt3/GuiImplementation.h
===================================================================
--- src/frontends/qt3/GuiImplementation.h	(Revision 14392)
+++ src/frontends/qt3/GuiImplementation.h	(Arbeitskopie)
@@ -19,6 +19,7 @@
 #include "QWorkArea.h"
 
 #include "GuiClipboard.h"
+#include "GuiSelection.h"
 #include "GuiWorkArea.h"
 
 #include "BufferView.h"
@@ -48,7 +49,12 @@ public:
 
 	lyx::frontend::Clipboard& clipboard()
 	{
-		return *clipboard_;
+		return clipboard_;
+	}
+
+	lyx::frontend::Selection& selection()
+	{
+		return *selection_;
 	}
 
 	int newView(unsigned int /*w*/, unsigned int /*h*/)
@@ -74,7 +80,7 @@ public:
 		old_work_area_.reset(new FWorkArea(*view_.get(), w, h));
 		old_screen_.reset(new FScreen(*old_work_area_.get()));
 		work_area_.reset(new GuiWorkArea(old_screen_.get(), old_work_area_.get()));
-		clipboard_.reset(new GuiClipboard(old_work_area_.get()));
+		selection_.reset(new GuiSelection(old_work_area_.get()));
 
 		// FIXME BufferView creation should be independant of WorkArea creation
 		buffer_views_[0].reset(new BufferView(view_.get()));
@@ -90,7 +96,7 @@ public:
 
 	void destroyWorkArea(int /*id*/)
 	{
-		clipboard_.reset();
+		selection_.reset();
 		work_area_.reset();
 		old_work_area_.reset();
 		old_screen_.reset();
@@ -98,7 +104,9 @@ public:
 
 private:
 	///
-	boost::shared_ptr<GuiClipboard> clipboard_;
+	GuiClipboard clipboard_;
+	///
+	boost::shared_ptr<GuiSelection> selection_;
 	///
 	boost::shared_ptr<GuiWorkArea> work_area_;
 	///
Index: src/frontends/qt3/Makefile.am
===================================================================
--- src/frontends/qt3/Makefile.am	(Revision 14392)
+++ src/frontends/qt3/Makefile.am	(Arbeitskopie)
@@ -29,6 +29,7 @@ libqt3_la_SOURCES = \
 	FileDialog.C \
 	GuiClipboard.C GuiClipboard.h \
 	GuiImplementation.h \
+	GuiSelection.C GuiSelection.h \
 	GuiWorkArea.h \
 	LyXKeySymFactory.C \
 	QLMenubar.C QLMenubar.h \
Index: src/frontends/qt3/GuiSelection.h
===================================================================
--- src/frontends/qt3/GuiSelection.h	(Revision 14378)
+++ src/frontends/qt3/GuiSelection.h	(Arbeitskopie)
@@ -0,0 +1,55 @@
+// -*- C++ -*-
+/**
+ * \file qt3/GuiSelection.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Abdelrazak Younes
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef SELECTION_H
+#define SELECTION_H
+
+#include "frontends/Selection.h"
+
+#include "QWorkArea.h"
+
+namespace lyx {
+namespace frontend {
+
+/**
+ * The Qt3 version of the Selection.
+ */
+class GuiSelection: public lyx::frontend::Selection
+{
+public:
+	GuiSelection(QWorkArea * work_area)
+		: old_work_area_(work_area)
+	{
+	}
+
+	virtual ~GuiSelection() {}
+
+	/** Selection overloaded methods
+	 */
+	//@{
+	void haveSelection(bool own)
+	{
+		old_work_area_->haveSelection(own);
+	}
+
+	std::string const get() const;
+
+	void put(std::string const & str);
+	//@}
+
+private:
+	QWorkArea * old_work_area_;
+};
+
+} // namespace frontend
+} // namespace lyx
+
+#endif // SELECTION_H
Index: src/frontends/qt3/GuiClipboard.C
===================================================================
--- src/frontends/qt3/GuiClipboard.C	(Revision 14392)
+++ src/frontends/qt3/GuiClipboard.C	(Arbeitskopie)
@@ -33,7 +33,7 @@ namespace frontend {
 
 string const GuiClipboard::get() const
 {
-	QString const str = qApp->clipboard()->text(QClipboard::Selection);
+	QString const str = qApp->clipboard()->text(QClipboard::Clipboard);
 	lyxerr[Debug::ACTION] << "GuiClipboard::get: " << (const char*) str
 	                      << endl;
 	if (str.isNull())
@@ -48,7 +48,7 @@ void GuiClipboard::put(string const & st
 	lyxerr[Debug::ACTION] << "GuiClipboard::put: " << str << endl;
 
 	qApp->clipboard()->setText(toqstr(externalLineEnding(str)),
-	                           QClipboard::Selection);
+	                           QClipboard::Clipboard);
 }
 
 } // namespace frontend
Index: src/frontends/qt3/GuiClipboard.h
===================================================================
--- src/frontends/qt3/GuiClipboard.h	(Revision 14392)
+++ src/frontends/qt3/GuiClipboard.h	(Arbeitskopie)
@@ -14,8 +14,6 @@
 
 #include "frontends/Clipboard.h"
 
-#include "QWorkArea.h"
-
 namespace lyx {
 namespace frontend {
 
@@ -25,28 +23,16 @@ namespace frontend {
 class GuiClipboard: public lyx::frontend::Clipboard
 {
 public:
-	GuiClipboard(QWorkArea * work_area)
-		: old_work_area_(work_area)
-	{
-	}
-
 	virtual ~GuiClipboard() {}
 
 	/** Clipboard overloaded methods
 	 */
 	//@{
-	void haveSelection(bool own)
-	{
-		old_work_area_->haveSelection(own);
-	}
 
 	std::string const get() const;
 
 	void put(std::string const & str);
 	//@}
-
-private:
-	QWorkArea * old_work_area_;
 };
 
 } // namespace frontend
Index: src/frontends/qt4/GuiImplementation.C
===================================================================
--- src/frontends/qt4/GuiImplementation.C	(Revision 14392)
+++ src/frontends/qt4/GuiImplementation.C	(Arbeitskopie)
@@ -37,6 +37,12 @@ Clipboard& GuiImplementation::clipboard(
 }
 
 
+Selection& GuiImplementation::selection()
+{
+	return selection_;
+}
+
+
 int GuiImplementation::newView(unsigned int /*w*/, unsigned int /*h*/)
 {
 	size_t const id = max_view_id_;
Index: src/frontends/qt4/GuiSelection.C
===================================================================
--- src/frontends/qt4/GuiSelection.C	(Revision 14378)
+++ src/frontends/qt4/GuiSelection.C	(Arbeitskopie)
@@ -0,0 +1,67 @@
+// -*- C++ -*-
+/**
+ * \file qt4/GuiSelection.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author John Levon
+ * \author Abdelrazak Younes
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "GuiSelection.h"
+#include "qt_helpers.h"
+
+#include "debug.h"
+
+#include <QApplication>
+#include <QClipboard>
+#include <QString>
+
+#include "support/lstrings.h"
+using lyx::support::internalLineEnding;
+using lyx::support::externalLineEnding;
+
+using std::endl;
+using std::string;
+
+namespace lyx {
+namespace frontend {
+
+void GuiSelection::haveSelection(bool own)
+{
+	if (!qApp->clipboard()->supportsSelection())
+		return;
+
+	if (own)
+		qApp->clipboard()->setText(QString(), QClipboard::Selection);
+	// We don't need to do anything if own = false, as this case is
+	// handled by QT.
+}
+
+
+string const GuiSelection::get() const
+{
+	QString const str = qApp->clipboard()->text(QClipboard::Selection);
+	lyxerr[Debug::ACTION] << "GuiSelection::get: " << (const char*) str
+	                      << endl;
+	if (str.isNull())
+		return string();
+
+	return internalLineEnding(fromqstr(str));
+}
+
+
+void GuiSelection::put(string const & str)
+{
+	lyxerr[Debug::ACTION] << "GuiSelection::put: " << str << endl;
+
+	qApp->clipboard()->setText(toqstr(externalLineEnding(str)),
+	                           QClipboard::Selection);
+}
+
+} // namespace frontend
+} // namespace lyx
Index: src/frontends/qt4/GuiImplementation.h
===================================================================
--- src/frontends/qt4/GuiImplementation.h	(Revision 14392)
+++ src/frontends/qt4/GuiImplementation.h	(Arbeitskopie)
@@ -15,6 +15,7 @@
 
 #include "frontends/Gui.h"
 #include "GuiClipboard.h"
+#include "GuiSelection.h"
 
 #include <boost/shared_ptr.hpp>
 
@@ -38,6 +39,7 @@ public:
 	virtual ~GuiImplementation() {}
 
 	Clipboard& clipboard();
+	Selection& selection();
 
 	int newView(unsigned int width, unsigned int height);
 	LyXView& view(int id);
@@ -52,6 +54,8 @@ private:
 	///
 	GuiClipboard clipboard_;
 	///
+	GuiSelection selection_;
+	///
 	std::map<int, boost::shared_ptr<GuiView> > views_;
 	///
 	std::map<int, boost::shared_ptr<GuiWorkArea> > work_areas_;
Index: src/frontends/qt4/Makefile.am
===================================================================
--- src/frontends/qt4/Makefile.am	(Revision 14392)
+++ src/frontends/qt4/Makefile.am	(Arbeitskopie)
@@ -37,6 +37,7 @@ libqt4_la_SOURCES = \
 	FileDialog.C \
 	FontLoader.h FontLoader.C \
 	GuiClipboard.h GuiClipboard.C \
+	GuiSelection.h GuiSelection.C \
 	GuiImplementation.h GuiImplementation.C \
 	LyXKeySymFactory.C \
 	QLMenubar.C QLMenubar.h \
Index: src/frontends/qt4/GuiSelection.h
===================================================================
--- src/frontends/qt4/GuiSelection.h	(Revision 14375)
+++ src/frontends/qt4/GuiSelection.h	(Arbeitskopie)
@@ -0,0 +1,42 @@
+// -*- C++ -*-
+/**
+ * \file qt4/GuiSelection.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author unknown
+ * \author John Levon
+ * \author Abdelrazak Younes
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef SELECTION_H
+#define SELECTION_H
+
+#include "frontends/Selection.h"
+
+namespace lyx {
+namespace frontend {
+
+/**
+ * The Qt4 version of the Selection.
+ */
+class GuiSelection: public Selection
+{
+public:
+	virtual ~GuiSelection() {}
+
+	/** Selection overloaded methods
+	 */
+	//@{
+	void haveSelection(bool own);
+	std::string const get() const;
+	void put(std::string const & str);
+	//@}
+};
+
+} // namespace frontend
+} // namespace lyx
+
+#endif // SELECTION_H
Index: src/frontends/qt4/GuiClipboard.C
===================================================================
--- src/frontends/qt4/GuiClipboard.C	(Revision 14392)
+++ src/frontends/qt4/GuiClipboard.C	(Arbeitskopie)
@@ -31,31 +31,9 @@ using std::string;
 namespace lyx {
 namespace frontend {
 
-#ifdef Q_WS_X11
-QClipboard::Mode const CLIPBOARD_MODE = QClipboard::Selection;
-#else
-// FIXME external clipboard support is mostly broken for windows
-// because the following fixe would involves too much side effects WRT mouse selection.
-//QClipboard::Mode const CLIPBOARD_MODE = QClipboard::Clipboard;
-QClipboard::Mode const CLIPBOARD_MODE = QClipboard::Selection;
-#endif
-
-void GuiClipboard::haveSelection(bool own)
-{
-	if (!qApp->clipboard()->supportsSelection())
-		return;
-
-	if (own) {
-		qApp->clipboard()->setText(QString(), CLIPBOARD_MODE);
-	}
-	// We don't need to do anything if own = false, as this case is
-	// handled by QT.
-}
-
-
 string const GuiClipboard::get() const
 {
-	QString str = qApp->clipboard()->text(CLIPBOARD_MODE);
+	QString const str = qApp->clipboard()->text(QClipboard::Clipboard);
 	lyxerr[Debug::ACTION] << "GuiClipboard::get: " << (const char*) str
 	                      << endl;
 	if (str.isNull())
@@ -69,7 +47,8 @@ void GuiClipboard::put(string const & st
 {
 	lyxerr[Debug::ACTION] << "GuiClipboard::put: " << str << endl;
 
-	qApp->clipboard()->setText(toqstr(externalLineEnding(str)), CLIPBOARD_MODE);
+	qApp->clipboard()->setText(toqstr(externalLineEnding(str)),
+	                           QClipboard::Clipboard);
 }
 
 } // namespace frontend
Index: src/frontends/qt4/GuiClipboard.h
===================================================================
--- src/frontends/qt4/GuiClipboard.h	(Revision 14392)
+++ src/frontends/qt4/GuiClipboard.h	(Arbeitskopie)
@@ -25,14 +25,11 @@ namespace frontend {
 class GuiClipboard: public Clipboard
 {
 public:
-	GuiClipboard() {}
-
 	virtual ~GuiClipboard() {}
 
 	/** Clipboard overloaded methods
 	 */
 	//@{
-	void haveSelection(bool own);
 	std::string const get() const;
 	void put(std::string const & str);
 	//@}
Index: src/frontends/Gui.h
===================================================================
--- src/frontends/Gui.h	(Revision 14392)
+++ src/frontends/Gui.h	(Arbeitskopie)
@@ -25,6 +25,7 @@ namespace lyx {
 namespace frontend {
 
 class Clipboard;
+class Selection;
 class WorkArea;
 
 
@@ -38,6 +39,8 @@ public:
 
 	///
 	virtual Clipboard & clipboard() = 0;
+	///
+	virtual Selection & selection() = 0;
 
 	///
 	virtual int newView(unsigned int width, unsigned int height) = 0;
Index: src/frontends/Selection.h
===================================================================
--- src/frontends/Selection.h	(Revision 14367)
+++ src/frontends/Selection.h	(Arbeitskopie)
@@ -0,0 +1,51 @@
+// -*- C++ -*-
+/**
+ * \file Selection.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author unknown
+ * \author John Levon
+ * \author Abdelrazak Younes
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef BASE_SELECTION_H
+#define BASE_SELECTION_H
+
+#include <string>
+
+namespace lyx {
+namespace frontend {
+
+/**
+ * A Selection class manages the selection.
+ */
+class Selection
+{
+public:
+	virtual ~Selection() {}
+
+	/// Tell the window system whether we have a selection.
+	virtual void haveSelection(bool) = 0;
+	/**
+	 * Get the X selection contents.
+	 * This is a noop on systems that don't have a selection.
+	 * The format is plain text.
+	 * This should be called when the user presses the middle mouse
+	 * button.
+	 */
+	virtual std::string const get() const = 0;
+	/**
+	 * Fill the X selection.
+	 * Does nothing on systems that don't have a selection.
+	 * This should be called whenever some text is highlighted.
+	 */
+	virtual void put(std::string const &) = 0;
+};
+
+} // namespace frontend
+} // namespace lyx
+
+#endif // BASE_SELECTION_H
Index: src/frontends/Makefile.am
===================================================================
--- src/frontends/Makefile.am	(Revision 14392)
+++ src/frontends/Makefile.am	(Arbeitskopie)
@@ -32,6 +32,7 @@ libfrontends_la_SOURCES = \
 	Toolbars.h \
 	Clipboard.h \
 	Gui.h \
+	Selection.h \
 	WorkArea.C \
 	WorkArea.h \
 	font_metrics.h \
Index: src/text3.C
===================================================================
--- src/text3.C	(Revision 14392)
+++ src/text3.C	(Arbeitskopie)
@@ -50,6 +50,7 @@
 #include "frontends/Gui.h"
 #include "frontends/LyXView.h"
 #include "frontends/Clipboard.h"
+#include "frontends/Selection.h"
 
 #include "insets/insetcommand.h"
 #include "insets/insetfloatlist.h"
@@ -124,7 +125,7 @@ namespace {
 		if (selecting || cur.mark())
 			cur.setSelection();
 		if (!cur.selection())
-			cur.bv().owner()->gui().clipboard().haveSelection(false);
+			cur.bv().owner()->gui().selection().haveSelection(false);
 		cur.bv().switchKeyMap();
 	}
 
@@ -983,7 +984,7 @@ void LyXText::dispatch(LCursor & cur, Fu
 		break;
 	}
 
-	case LFUN_PRIMARY_SELECTION_PASTE: {
+	case LFUN_CLIPBOARD_PASTE: {
 		cur.clearSelection();
 		string const clip = bv->owner()->gui().clipboard().get();
 		if (!clip.empty()) {
@@ -996,6 +997,19 @@ void LyXText::dispatch(LCursor & cur, Fu
 		break;
 	}
 
+	case LFUN_PRIMARY_SELECTION_PASTE: {
+		cur.clearSelection();
+		string const clip = bv->owner()->gui().selection().get();
+		if (!clip.empty()) {
+			recordUndo(cur);
+			if (cmd.argument == "paragraph")
+				insertStringAsParagraphs(cur, clip);
+			else
+				insertStringAsLines(cur, clip);
+		}
+		break;
+	}
+
 	case LFUN_QUOTE_INSERT: {
 		lyx::cap::replaceSelection(cur);
 		Paragraph & par = cur.paragraph();
@@ -1045,7 +1059,7 @@ void LyXText::dispatch(LCursor & cur, Fu
 			cursorEnd(cur);
 			cur.setSelection();
 			bv->cursor() = cur;
-			bv->owner()->gui().clipboard().haveSelection(cur.selection());
+			bv->owner()->gui().selection().haveSelection(cur.selection());
 		}
 		break;
 
@@ -1053,7 +1067,7 @@ void LyXText::dispatch(LCursor & cur, Fu
 		if (cmd.button() == mouse_button::button1) {
 			selectWord(cur, lyx::WHOLE_WORD_STRICT);
 			bv->cursor() = cur;
-			bv->owner()->gui().clipboard().haveSelection(cur.selection());
+			bv->owner()->gui().selection().haveSelection(cur.selection());
 		}
 		break;
 
@@ -1135,7 +1149,7 @@ void LyXText::dispatch(LCursor & cur, Fu
 
 		// finish selection
 		if (cmd.button() == mouse_button::button1)
-			bv->owner()->gui().clipboard().haveSelection(cur.selection());
+			bv->owner()->gui().selection().haveSelection(cur.selection());
 
 		bv->switchKeyMap();
 		bv->owner()->updateMenubar();
@@ -1156,7 +1170,7 @@ void LyXText::dispatch(LCursor & cur, Fu
 		if (lyxrc.auto_region_delete) {
 			if (cur.selection())
 				cutSelection(cur, false, false);
-			bv->owner()->gui().clipboard().haveSelection(false);
+			bv->owner()->gui().selection().haveSelection(false);
 		}
 
 		cur.clearSelection();
@@ -1869,6 +1883,7 @@ bool LyXText::getStatus(LCursor & cur, F
 	case LFUN_SERVER_GET_FONT:
 	case LFUN_SERVER_GET_LAYOUT:
 	case LFUN_LAYOUT:
+	case LFUN_CLIPBOARD_PASTE:
 	case LFUN_PRIMARY_SELECTION_PASTE:
 	case LFUN_DATE_INSERT:
 	case LFUN_SELF_INSERT:
Index: src/lfuns.h
===================================================================
--- src/lfuns.h	(Revision 14392)
+++ src/lfuns.h	(Arbeitskopie)
@@ -367,6 +367,7 @@ enum kb_action {
 	// 280
 	LFUN_BUFFER_TOGGLE_COMPRESSION,                 // bpeng 20060427
 	LFUN_MATH_BIGDELIM,
+	LFUN_CLIPBOARD_PASTE,
 
 	LFUN_LASTACTION                  // end of the table
 };
Index: lib/ui/stdmenus.ui
===================================================================
--- lib/ui/stdmenus.ui	(Revision 14392)
+++ lib/ui/stdmenus.ui	(Arbeitskopie)
@@ -85,7 +85,7 @@ Menuset
 		Item "Copy" "copy"
 		Item "Paste" "paste"
 		Submenu "Paste Recent" "pasterecent"
-		Submenu "Paste External Selection" "edit_paste"
+		Submenu "Paste External Clipboard/Selection" "edit_paste"
 		Separator
 		Item "Find & Replace...|F" "dialog-show findreplace"
 		Separator
@@ -118,6 +118,8 @@ Menuset
 	End
 
 	Menu "edit_paste"
+		Item "Clipboard as Lines|C" "clipboard-paste"
+		Item "Clipboard as Paragraphs|a" "clipboard-paste paragraph"
 		Item "Selection as Lines|L" "primary-selection-paste"
 		Item "Selection as Paragraphs|P" "primary-selection-paste paragraph"
 	End

Reply via email to