LyX does currently only support the X selection. The clipboard is 
unsupported, which is a problem especially on windows, since windows has 
no selection.

The selection should be filled whenever a text is highlighted. The 
selection contents should be pasted when the middle mouse button is 
pressed.
The clipboard should only be filled upon an explicit copy/cut request, and 
it should not be pasted via middle mouse button, but via a keyboard 
shortcut or menu entry.

If you want to know more, read
http://www.freedesktop.org/wiki/Standards_2fclipboards_2dspec

The attached patch implements this behaviour. If you want to try it you 
first have to copy *Clipboard* to 'Selection*, because the new files have 
been created with svn copy.

What is missing: Keyboard shortcuts for the new lfun, and a mechanism to 
disable the selection lfun on systems that do not support a selection. We 
also need to integrate the external clipboard with our internal 
clipboard, but I don't know how. Does anybody have an idea for shortcuts?

The selection classes are IMO finished. The long term goal is to enhance 
the clipboard classes to deal also with non-plain-text clipboard 
contents. See also http://bugzilla.lyx.org/show_bug.cgi?id=2138

We also have inconsistent naming e.g. in CutAndPaste.C: clipboard vs. 
selection. That should also be fixed someday.

Comments?


Georg
Index: src/LyXAction.C
===================================================================
--- src/LyXAction.C	(Revision 14378)
+++ 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 14378)
+++ 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 14378)
+++ 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 14378)
+++ 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 14378)
+++ 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 14378)
+++ src/BufferView_pimpl.C	(Arbeitskopie)
@@ -58,12 +58,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 "frontends/WorkArea.h"
 
 #include "graphics/Previews.h"
@@ -619,7 +619,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 14378)
+++ 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 14378)
+++ 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 14378)
+++ 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()));
 	guiCursor().connect(work_area_.get());
 
 	// FIXME BufferView creation should be independant of WorkArea creation
@@ -44,7 +44,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)
@@ -1,6 +1,6 @@
 // -*- C++ -*-
 /**
- * \file gtk/GuiClipboard.C
+ * \file gtk/GuiSelection.C
  * This file is part of LyX, the document processor.
  * Licence details can be found in the file COPYING.
  *
@@ -20,7 +20,7 @@
 #undef _GLIBCPP_CONCEPT_CHECKS
 #endif
 
-#include "GuiClipboard.h"
+#include "GuiSelection.h"
 #include "debug.h"
 
 #include <gtkmm.h>
@@ -33,7 +33,7 @@ namespace frontend {
 
 // ENCODING: Gtk::Clipboard returns UTF-8, we assume that the backend
 // wants ISO-8859-1 and convert it to that.
-string const GuiClipboard::get() const
+string const GuiSelection::get() const
 {
 	Glib::RefPtr<Gtk::Clipboard> clipboard =
 		Gtk::Clipboard::get(GDK_SELECTION_PRIMARY);
@@ -46,7 +46,7 @@ string const GuiClipboard::get() const
 
 // ENCODING: we assume that the backend passes us ISO-8859-1 and
 // convert from that to UTF-8 before passing to GTK
-void GuiClipboard::put(string const & str)
+void GuiSelection::put(string const & str)
 {
 	lyxerr[Debug::ACTION] << "GuiClipboard::put: " << str << endl;
 	Glib::RefPtr<Gtk::Clipboard> clipboard =
Index: src/frontends/gtk/GuiImplementation.h
===================================================================
--- src/frontends/gtk/GuiImplementation.h	(Revision 14378)
+++ 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 14378)
+++ 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)
@@ -1,6 +1,6 @@
 // -*- C++ -*-
 /**
- * \file gtk/Clipboard.h
+ * \file gtk/Selection.h
  * This file is part of LyX, the document processor.
  * Licence details can be found in the file COPYING.
  *
@@ -9,10 +9,10 @@
  * Full author contact details are available in file CREDITS.
  */
 
-#ifndef CLIPBOARD_H
-#define CLIPBOARD_H
+#ifndef SELECTION_H
+#define SELECTION_H
 
-#include "frontends/Clipboard.h"
+#include "frontends/Selection.h"
 
 #include "GWorkArea.h"
 
@@ -20,19 +20,19 @@ namespace lyx {
 namespace frontend {
 
 /**
- * The GTK version of the Clipboard.
+ * The GTK version of the Selection.
  */
-class GuiClipboard: public lyx::frontend::Clipboard
+class GuiSelection: public lyx::frontend::Selection
 {
 public:
-	GuiClipboard(GWorkArea * work_area)
+	GuiSelection(GWorkArea * work_area)
 		: old_work_area_(work_area)
 	{
 	}
 
-	virtual ~GuiClipboard() {}
+	virtual ~GuiSelection() {}
 
-	/** Clipboard overloaded methods
+	/** Selection overloaded methods
 	 */
 	//@{
 	void haveSelection(bool own)
@@ -40,15 +40,9 @@ public:
 		old_work_area_->haveSelection(own);
 	}
 
-	std::string const get() const
-	{
-		return old_work_area_->getClipboard();
-	}
+	std::string const get() const;
 
-	void put(std::string const & str)
-	{
-		old_work_area_->putClipboard(str);
-	}
+	void put(std::string const & str);
 	//@}
 
 private:
@@ -58,4 +52,4 @@ private:
 } // namespace frontend
 } // namespace lyx
 
-#endif // CLIPBOARD_H
+#endif // SELECTION_H
Index: src/frontends/gtk/GuiClipboard.C
===================================================================
--- src/frontends/gtk/GuiClipboard.C	(Revision 14378)
+++ 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 14378)
+++ 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 14378)
+++ 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 14378)
+++ 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)
@@ -1,6 +1,6 @@
 // -*- C++ -*-
 /**
- * \file qt3/GuiClipboard.C
+ * \file qt3/GuiSelection.C
  * This file is part of LyX, the document processor.
  * Licence details can be found in the file COPYING.
  *
@@ -12,7 +12,7 @@
 
 #include <config.h>
 
-#include "GuiClipboard.h"
+#include "GuiSelection.h"
 #include "qt_helpers.h"
 
 #include "debug.h"
@@ -31,10 +31,10 @@ using std::string;
 namespace lyx {
 namespace frontend {
 
-string const GuiClipboard::get() const
+string const GuiSelection::get() const
 {
 	QString const str = qApp->clipboard()->text(QClipboard::Selection);
-	lyxerr[Debug::ACTION] << "GuiClipboard::get: " << (const char*) str
+	lyxerr[Debug::ACTION] << "GuiSelection::get: " << (const char*) str
 	                      << endl;
 	if (str.isNull())
 		return string();
@@ -43,9 +43,9 @@ string const GuiClipboard::get() const
 }
 
 
-void GuiClipboard::put(string const & str)
+void GuiSelection::put(string const & str)
 {
-	lyxerr[Debug::ACTION] << "GuiClipboard::put: " << str << endl;
+	lyxerr[Debug::ACTION] << "GuiSelection::put: " << str << endl;
 
 	qApp->clipboard()->setText(toqstr(externalLineEnding(str)),
 	                           QClipboard::Selection);
Index: src/frontends/qt3/GuiImplementation.h
===================================================================
--- src/frontends/qt3/GuiImplementation.h	(Revision 14378)
+++ 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()));
 		guiCursor().connect(work_area_.get());
 
 		// FIXME BufferView creation should be independant of WorkArea creation
@@ -91,7 +97,7 @@ public:
 
 	void destroyWorkArea(int /*id*/)
 	{
-		clipboard_.reset();
+		selection_.reset();
 		work_area_.reset();
 		old_work_area_.reset();
 		old_screen_.reset();
@@ -99,7 +105,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 14378)
+++ 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)
@@ -1,6 +1,6 @@
 // -*- C++ -*-
 /**
- * \file qt3/GuiClipboard.h
+ * \file qt3/GuiSelection.h
  * This file is part of LyX, the document processor.
  * Licence details can be found in the file COPYING.
  *
@@ -9,10 +9,10 @@
  * Full author contact details are available in file CREDITS.
  */
 
-#ifndef CLIPBOARD_H
-#define CLIPBOARD_H
+#ifndef SELECTION_H
+#define SELECTION_H
 
-#include "frontends/Clipboard.h"
+#include "frontends/Selection.h"
 
 #include "QWorkArea.h"
 
@@ -20,19 +20,19 @@ namespace lyx {
 namespace frontend {
 
 /**
- * The Qt3 version of the Clipboard.
+ * The Qt3 version of the Selection.
  */
-class GuiClipboard: public lyx::frontend::Clipboard
+class GuiSelection: public lyx::frontend::Selection
 {
 public:
-	GuiClipboard(QWorkArea * work_area)
+	GuiSelection(QWorkArea * work_area)
 		: old_work_area_(work_area)
 	{
 	}
 
-	virtual ~GuiClipboard() {}
+	virtual ~GuiSelection() {}
 
-	/** Clipboard overloaded methods
+	/** Selection overloaded methods
 	 */
 	//@{
 	void haveSelection(bool own)
@@ -52,4 +52,4 @@ private:
 } // namespace frontend
 } // namespace lyx
 
-#endif // CLIPBOARD_H
+#endif // SELECTION_H
Index: src/frontends/qt3/GuiClipboard.C
===================================================================
--- src/frontends/qt3/GuiClipboard.C	(Revision 14378)
+++ 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 14378)
+++ 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 14378)
+++ 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)
@@ -1,6 +1,6 @@
 // -*- C++ -*-
 /**
- * \file qt4/GuiClipboard.C
+ * \file qt4/GuiSelection.C
  * This file is part of LyX, the document processor.
  * Licence details can be found in the file COPYING.
  *
@@ -12,7 +12,7 @@
 
 #include <config.h>
 
-#include "GuiClipboard.h"
+#include "GuiSelection.h"
 #include "qt_helpers.h"
 
 #include "debug.h"
@@ -31,32 +31,22 @@ 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)
+void GuiSelection::haveSelection(bool own)
 {
 	if (!qApp->clipboard()->supportsSelection())
 		return;
 
-	if (own) {
-		qApp->clipboard()->setText(QString(), CLIPBOARD_MODE);
-	}
+	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 GuiClipboard::get() const
+string const GuiSelection::get() const
 {
-	QString str = qApp->clipboard()->text(CLIPBOARD_MODE);
-	lyxerr[Debug::ACTION] << "GuiClipboard::get: " << (const char*) str
+	QString const str = qApp->clipboard()->text(QClipboard::Selection);
+	lyxerr[Debug::ACTION] << "GuiSelection::get: " << (const char*) str
 	                      << endl;
 	if (str.isNull())
 		return string();
@@ -65,11 +55,12 @@ string const GuiClipboard::get() const
 }
 
 
-void GuiClipboard::put(string const & str)
+void GuiSelection::put(string const & str)
 {
-	lyxerr[Debug::ACTION] << "GuiClipboard::put: " << str << endl;
+	lyxerr[Debug::ACTION] << "GuiSelection::put: " << str << endl;
 
-	qApp->clipboard()->setText(toqstr(externalLineEnding(str)), CLIPBOARD_MODE);
+	qApp->clipboard()->setText(toqstr(externalLineEnding(str)),
+	                           QClipboard::Selection);
 }
 
 } // namespace frontend
Index: src/frontends/qt4/GuiImplementation.h
===================================================================
--- src/frontends/qt4/GuiImplementation.h	(Revision 14378)
+++ 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 14378)
+++ 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)
@@ -1,6 +1,6 @@
 // -*- C++ -*-
 /**
- * \file qt4/GuiClipboard.h
+ * \file qt4/GuiSelection.h
  * This file is part of LyX, the document processor.
  * Licence details can be found in the file COPYING.
  *
@@ -11,25 +11,23 @@
  * Full author contact details are available in file CREDITS.
  */
 
-#ifndef CLIPBOARD_H
-#define CLIPBOARD_H
+#ifndef SELECTION_H
+#define SELECTION_H
 
-#include "frontends/Clipboard.h"
+#include "frontends/Selection.h"
 
 namespace lyx {
 namespace frontend {
 
 /**
- * The Qt4 version of the Clipboard.
+ * The Qt4 version of the Selection.
  */
-class GuiClipboard: public Clipboard
+class GuiSelection: public Selection
 {
 public:
-	GuiClipboard() {}
+	virtual ~GuiSelection() {}
 
-	virtual ~GuiClipboard() {}
-
-	/** Clipboard overloaded methods
+	/** Selection overloaded methods
 	 */
 	//@{
 	void haveSelection(bool own);
@@ -41,4 +39,4 @@ public:
 } // namespace frontend
 } // namespace lyx
 
-#endif // CLIPBOARD_H
+#endif // SELECTION_H
Index: src/frontends/qt4/GuiClipboard.C
===================================================================
--- src/frontends/qt4/GuiClipboard.C	(Revision 14378)
+++ 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 14378)
+++ 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 14378)
+++ src/frontends/Gui.h	(Arbeitskopie)
@@ -26,6 +26,7 @@ namespace lyx {
 namespace frontend {
 
 class Clipboard;
+class Selection;
 class WorkArea;
 
 
@@ -39,6 +40,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)
@@ -1,6 +1,6 @@
 // -*- C++ -*-
 /**
- * \file Clipboard.h
+ * \file Selection.h
  * This file is part of LyX, the document processor.
  * Licence details can be found in the file COPYING.
  *
@@ -11,8 +11,8 @@
  * Full author contact details are available in file CREDITS.
  */
 
-#ifndef BASE_CLIPBOARD_H
-#define BASE_CLIPBOARD_H
+#ifndef BASE_SELECTION_H
+#define BASE_SELECTION_H
 
 #include <string>
 
@@ -20,22 +20,32 @@ namespace lyx {
 namespace frontend {
 
 /**
- * A Clipboard class manages the clipboard.
+ * A Selection class manages the selection.
  */
-class Clipboard
+class Selection
 {
 public:
-	virtual ~Clipboard() {}
+	virtual ~Selection() {}
 
-	/// a selection exists
+	/// Tell the window system whether we have a selection.
 	virtual void haveSelection(bool) = 0;
-	/// get the X clipboard contents
+	/**
+	 * 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 clipboard
+	/**
+	 * 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_CLIPBOARD_H
+#endif // BASE_SELECTION_H
Index: src/frontends/Makefile.am
===================================================================
--- src/frontends/Makefile.am	(Revision 14378)
+++ src/frontends/Makefile.am	(Arbeitskopie)
@@ -34,6 +34,7 @@ libfrontends_la_SOURCES = \
 	Gui.h \
 	GuiCursor.C \
 	GuiCursor.h \
+	Selection.h \
 	WorkArea.C \
 	WorkArea.h \
 	font_metrics.h \
Index: src/text3.C
===================================================================
--- src/text3.C	(Revision 14378)
+++ 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,9 +984,12 @@ void LyXText::dispatch(LCursor & cur, Fu
 		break;
 	}
 
+	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 (!clip.empty()) {
 			recordUndo(cur);
 			if (cmd.argument == "paragraph")
@@ -1045,7 +1049,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 +1057,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 +1139,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 +1160,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 +1873,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 14378)
+++ 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 14378)
+++ 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