Am Donnerstag, 1. Juni 2006 22:20 schrieb Edwin Leuven:
> it looks like this whole clipboard thing needs a serious overhaul (small 
> cosmetics is not really worth the trouble i think).
> 
> i agree with one of the bugzilla posters that lyx's copy/paste behavior 
> is a mayor annoyance and probably confusing for many. i am not sure i 
> have the skills to repair this though...
> 
> in the meantime i suggest to use the clipboard under windows otherwise 
> it is impossible to paste something external into lyx
> 
> opinions?

The problem then would be that LyX would behave strangely regarding 
copy/paste: Selecting something will copy it to the system clipboard 
immediately, and the middle mouse button would paste the system 
clipboard.

IMO something like the attached is better. It does not solve the big 
problem (rich text copy/paste), but should get a text-only clipboard 
right. It is only roughly tested, but the qt3 version seems to work, and 
it should get you started.


Georg
Index: src/LyXAction.C
===================================================================
--- src/LyXAction.C	(Revision 13993)
+++ src/LyXAction.C	(Arbeitskopie)
@@ -251,6 +251,7 @@ void LyXAction::init()
 		{ LFUN_PARAGRAPH_UP_SELECT, "paragraph-up-select", ReadOnly },
 		{ LFUN_PASTE, "paste", Noop },
 		{ LFUN_PREFERENCES_SAVE, "preferences-save", NoBuffer },
+		{ LFUN_CLIPBOARD_PASTE, "clipboard-paste", Noop },
 		{ LFUN_PRIMARY_SELECTION_PASTE, "primary-selection-paste", Noop },
 		{ LFUN_QUOTE_INSERT, "quote-insert", Noop },
 		{ LFUN_RECONFIGURE, "reconfigure", NoBuffer },
Index: src/insets/insettabular.C
===================================================================
--- src/insets/insettabular.C	(Revision 13993)
+++ src/insets/insettabular.C	(Arbeitskopie)
@@ -664,8 +664,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().getClipboard();
+		string const clip = cmd.action == LFUN_CLIPBOARD_PASTE ?
+			cur.bv().getClipboard() :
+			cur.bv().getSelection();
 		if (clip.empty())
 			break;
 		// pass to InsertAsciiString, but
@@ -1686,7 +1689,7 @@ bool InsetTabular::copySelection(LCursor
 	ostringstream os;
 	OutputParams const runparams;
 	paste_tabular->plaintext(cur.buffer(), os, runparams, 0, true, '\t');
-	cur.bv().stuffClipboard(os.str());
+	cur.bv().stuffSelection(os.str());
 	// mark tabular stack dirty
 	// FIXME: this is a workaround for bug 1919. Should be removed for 1.5,
 	// when we (hopefully) have a one-for-all paste mechanism.
Index: src/insets/insetert.C
===================================================================
--- src/insets/insetert.C	(Revision 13993)
+++ 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/BufferView_pimpl.C
===================================================================
--- src/BufferView_pimpl.C	(Revision 13993)
+++ src/BufferView_pimpl.C	(Arbeitskopie)
@@ -618,7 +618,7 @@ void BufferView::Pimpl::selectionRequest
 		xsel_cache_.set = cur.selection();
 		sel = cur.selectionAsString(false);
 		if (!sel.empty())
-			workarea().putClipboard(sel);
+			workarea().putSelection(sel);
 	}
 }
 
@@ -871,12 +871,6 @@ void BufferView::Pimpl::center()
 }
 
 
-void BufferView::Pimpl::stuffClipboard(string const & content) const
-{
-	workarea().putClipboard(content);
-}
-
-
 void BufferView::Pimpl::menuInsertLyXFile(string const & filenm)
 {
 	BOOST_ASSERT(cursor_.inTexted());
Index: src/mathed/math_nestinset.C
===================================================================
--- src/mathed/math_nestinset.C	(Revision 13993)
+++ src/mathed/math_nestinset.C	(Arbeitskopie)
@@ -1083,7 +1083,7 @@ void MathNestInset::lfunMousePress(LCurs
 
 	if (cmd.button() == mouse_button::button2) {
 		MathArray ar;
-		asArray(cur.bv().getClipboard(), ar);
+		asArray(cur.bv().getSelection(), ar);
 		cur.clearSelection();
 		editXY(cur, cmd.x, cmd.y);
 		cur.insert(ar);
@@ -1116,7 +1116,7 @@ void MathNestInset::lfunMouseRelease(LCu
 	//lyxerr << "## lfunMouseRelease: buttons: " << cmd.button() << endl;
 
 	if (cmd.button() == mouse_button::button1) {
-		//cur.bv().stuffClipboard(cur.grabSelection());
+		//cur.bv().stuffSelection(cur.grabSelection());
 		return;
 	}
 
Index: src/BufferView_pimpl.h
===================================================================
--- src/BufferView_pimpl.h	(Revision 13993)
+++ src/BufferView_pimpl.h	(Arbeitskopie)
@@ -157,8 +157,6 @@ private:
 	///
 	Timeout cursor_timeout;
 	///
-	void stuffClipboard(std::string const &) const;
-	///
 	bool using_xterm_cursor;
 	///
 	class Position {
Index: src/CutAndPaste.C
===================================================================
--- src/CutAndPaste.C	(Revision 13993)
+++ src/CutAndPaste.C	(Arbeitskopie)
@@ -491,8 +491,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().stuffClipboard(cur.selectionAsString(true));
+		// calls to stuffSelection. (Lgb)
+//		cur.bv().stuffSelection(cur.selectionAsString(true));
 
 		// make sure that the depth behind the selection are restored, too
 		recordUndoSelection(cur);
Index: src/frontends/gtk/GWorkArea.h
===================================================================
--- src/frontends/gtk/GWorkArea.h	(Revision 13993)
+++ src/frontends/gtk/GWorkArea.h	(Arbeitskopie)
@@ -84,7 +84,11 @@ public:
 	///
 	virtual std::string const getClipboard() const;
 	///
+	virtual std::string const getSelection() const;
+	///
 	virtual void putClipboard(std::string const &) const;
+	///
+	virtual void putSelection(std::string const &) const;
 	void inputCommit(gchar * str);
 private:
 	bool onExpose(GdkEventExpose * event);
Index: src/frontends/gtk/ghelpers.C
===================================================================
--- src/frontends/gtk/ghelpers.C	(Revision 13993)
+++ 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/gtk/GWorkArea.C
===================================================================
--- src/frontends/gtk/GWorkArea.C	(Revision 13993)
+++ src/frontends/gtk/GWorkArea.C	(Arbeitskopie)
@@ -525,6 +525,17 @@ void GWorkArea::haveSelection(bool toHav
 string const GWorkArea::getClipboard() const
 {
 	Glib::RefPtr<Gtk::Clipboard> clipboard =
+		Gtk::Clipboard::get(GDK_SELECTION_CLIPBOARD);
+	return Glib::convert_with_fallback(
+		clipboard->wait_for_text(), "ISO-8859-1", "UTF-8");
+}
+
+
+// ENCODING: Gtk::Clipboard returns UTF-8, we assume that the backend
+// wants ISO-8859-1 and convert it to that.
+string const GWorkArea::getSelection() const
+{
+	Glib::RefPtr<Gtk::Clipboard> clipboard =
 		Gtk::Clipboard::get(GDK_SELECTION_PRIMARY);
 	return Glib::convert_with_fallback(
 		clipboard->wait_for_text(), "ISO-8859-1", "UTF-8");
@@ -536,6 +547,16 @@ string const GWorkArea::getClipboard() c
 void GWorkArea::putClipboard(string const & str) const
 {
 	Glib::RefPtr<Gtk::Clipboard> clipboard =
+		Gtk::Clipboard::get(GDK_SELECTION_CLIPBOARD);
+	clipboard->set_text(Glib::convert(str, "UTF-8", "ISO-8859-1"));
+}
+
+
+// ENCODING: we assume that the backend passes us ISO-8859-1 and
+// convert from that to UTF-8 before passing to GTK
+void GWorkArea::putSelection(string const & str) const
+{
+	Glib::RefPtr<Gtk::Clipboard> clipboard =
 		Gtk::Clipboard::get(GDK_SELECTION_PRIMARY);
 	clipboard->set_text(Glib::convert(str, "UTF-8", "ISO-8859-1"));
 }
Index: src/frontends/WorkArea.h
===================================================================
--- src/frontends/WorkArea.h	(Revision 13993)
+++ src/frontends/WorkArea.h	(Arbeitskopie)
@@ -54,10 +54,29 @@ public:
 	// FIXME: this is an odd place to have it, but xforms needs it here ...
 	/// a selection exists
 	virtual void haveSelection(bool) const = 0;
-	/// get the X clipboard contents
+	/**
+	 * Get the system clipboard contents.
+	 * This should be called when the user requests to paste from the
+	 * clipboard.
+	 */
 	virtual std::string const getClipboard() const = 0;
-	/// fill the clipboard
+	/**
+	 * Get the X primary selection contents.
+	 * This should be called when the user presses the middle mouse
+	 * button.
+	 */
+	virtual std::string const getSelection() const = 0;
+	/**
+	 * Fill the system clipboard.
+	 * This should be called when the user requests to cut or copy to
+	 * the clipboard.
+	 */
 	virtual void putClipboard(std::string const &) const = 0;
+	/**
+	 * Fill the X primary selection.
+	 * This should be called when the selection changes.
+	 */
+	virtual void putSelection(std::string const &) const = 0;
 };
 
 #endif // WORKAREA_H
Index: src/frontends/qt3/QWorkArea.C
===================================================================
--- src/frontends/qt3/QWorkArea.C	(Revision 13993)
+++ src/frontends/qt3/QWorkArea.C	(Arbeitskopie)
@@ -202,8 +202,23 @@ void QWorkArea::haveSelection(bool own) 
 
 string const QWorkArea::getClipboard() const
 {
-	QApplication::clipboard()->setSelectionMode(true);
-	QString str = QApplication::clipboard()->text();
+	QString str = QApplication::clipboard()->text(QClipboard::Clipboard);
+	if (str.isNull())
+		return string();
+#ifdef Q_OS_MAC
+	// The MAC clipboard uses \r for lineendings, and we use \n
+	return subst(fromqstr(str), '\r', '\n');
+#else
+	return fromqstr(str);
+#endif
+}
+
+
+string const QWorkArea::getSelection() const
+{
+	if (!QApplication::clipboard()->supportsSelection())
+		return string();
+	QString str = QApplication::clipboard()->text(QClipboard::Selection);
 	if (str.isNull())
 		return string();
 #ifdef Q_OS_MAC
@@ -217,12 +232,28 @@ string const QWorkArea::getClipboard() c
 
 void QWorkArea::putClipboard(string const & str) const
 {
-	QApplication::clipboard()->setSelectionMode(true);
 #ifdef Q_OS_MAC
 	// The MAC clipboard uses \r for lineendings, and we use \n
-	QApplication::clipboard()->setText(toqstr(subst(str, '\n', '\r')));
+	QApplication::clipboard()->setText(toqstr(subst(str, '\n', '\r')),
+			QClipboard::Clipboard);
+#else
+	QApplication::clipboard()->setText(toqstr(str),
+			QClipboard::Clipboard);
+#endif
+}
+
+
+void QWorkArea::putSelection(string const & str) const
+{
+	if (!QApplication::clipboard()->supportsSelection())
+		return;
+#ifdef Q_OS_MAC
+	// The MAC clipboard uses \r for lineendings, and we use \n
+	QApplication::clipboard()->setText(toqstr(subst(str, '\n', '\r')),
+			QClipboard::Selection);
 #else
-	QApplication::clipboard()->setText(toqstr(str));
+	QApplication::clipboard()->setText(toqstr(str),
+			QClipboard::Selection);
 #endif
 }
 
Index: src/frontends/qt3/QWorkArea.h
===================================================================
--- src/frontends/qt3/QWorkArea.h	(Revision 13993)
+++ src/frontends/qt3/QWorkArea.h	(Arbeitskopie)
@@ -52,8 +52,12 @@ public:
 	///
 	virtual std::string const getClipboard() const;
 	///
+	virtual std::string const getSelection() const;
+	///
 	virtual void putClipboard(std::string const &) const;
 	///
+	virtual void putSelection(std::string const &) const;
+	///
 	virtual void dragEnterEvent(QDragEnterEvent * event);
 	///
 	virtual void dropEvent(QDropEvent* event);
Index: src/frontends/qt4/QWorkArea.C
===================================================================
--- src/frontends/qt4/QWorkArea.C	(Revision 13993)
+++ src/frontends/qt4/QWorkArea.C	(Arbeitskopie)
@@ -248,7 +248,7 @@ void QWorkArea::haveSelection(bool own) 
 
 string const QWorkArea::getClipboard() const
 {
-	QString str = QApplication::clipboard()->text(QClipboard::Selection);
+	QString str = QApplication::clipboard()->text(QClipboard::Clipboard);
 	lyxerr[Debug::ACTION] << "getClipboard: " << (const char*) str << endl;
 	if (str.isNull())
 		return string();
@@ -261,11 +261,43 @@ string const QWorkArea::getClipboard() c
 }
 
 
+string const QWorkArea::getSelection() const
+{
+	if (!QApplication::clipboard()->supportsSelection())
+		return string();
+	QString str = QApplication::clipboard()->text(QClipboard::Selection);
+	lyxerr[Debug::ACTION] << "getSelection: " << (const char*) str << endl;
+	if (str.isNull())
+		return string();
+#ifdef Q_WS_MACX
+	// The MAC clipboard uses \r for lineendings, and we use \n
+	return subst(fromqstr(str), '\r', '\n');
+#else
+	return fromqstr(str);
+#endif
+}
+
+
 void QWorkArea::putClipboard(string const & str) const
 {
 #ifdef Q_WS_MACX
 	// The MAC clipboard uses \r for lineendings, and we use \n
 	QApplication::clipboard()->setText(toqstr(subst(str, '\n', '\r')),
+					   QClipboard::Clipboard);
+#else
+	QApplication::clipboard()->setText(toqstr(str), QClipboard::Clipboard);
+#endif
+	lyxerr[Debug::ACTION] << "putClipboard: " << str << endl;
+}
+
+
+void QWorkArea::putSelection(string const & str) const
+{
+	if (!QApplication::clipboard()->supportsSelection())
+		return;
+#ifdef Q_WS_MACX
+	// The MAC clipboard uses \r for lineendings, and we use \n
+	QApplication::clipboard()->setText(toqstr(subst(str, '\n', '\r')),
 					   QClipboard::Selection);
 #else
 	QApplication::clipboard()->setText(toqstr(str), QClipboard::Selection);
Index: src/frontends/qt4/QWorkArea.h
===================================================================
--- src/frontends/qt4/QWorkArea.h	(Revision 13993)
+++ src/frontends/qt4/QWorkArea.h	(Arbeitskopie)
@@ -118,9 +118,13 @@ public:
 
 	///
 	virtual std::string const getClipboard() const;
+	///
+	virtual std::string const getSelection() const;
 
 	///
 	virtual void putClipboard(std::string const &) const;
+	///
+	virtual void putSelection(std::string const &) const;
 
 	///
 	virtual void dragEnterEvent(QDragEnterEvent * event);
Index: src/frontends/xforms/XWorkArea.C
===================================================================
--- src/frontends/xforms/XWorkArea.C	(Revision 13993)
+++ src/frontends/xforms/XWorkArea.C	(Arbeitskopie)
@@ -622,6 +622,12 @@ void XWorkArea::haveSelection(bool yes) 
 
 string const XWorkArea::getClipboard() const
 {
+	return string();
+}
+
+
+string const XWorkArea::getSelection() const
+{
 	clipboard_read = false;
 
 	if (fl_request_clipboard(work_area, 0, request_clipboard_cb) == -1)
@@ -642,7 +648,12 @@ string const XWorkArea::getClipboard() c
 }
 
 
-void XWorkArea::putClipboard(string const & s) const
+void XWorkArea::putClipboard(string const &) const
+{
+}
+
+
+void XWorkArea::putSelection(string const & s) const
 {
 	static string hold;
 	hold = s;
Index: src/frontends/xforms/XWorkArea.h
===================================================================
--- src/frontends/xforms/XWorkArea.h	(Revision 13993)
+++ src/frontends/xforms/XWorkArea.h	(Arbeitskopie)
@@ -60,7 +60,11 @@ public:
 	///
 	virtual std::string const getClipboard() const;
 	///
+	virtual std::string const getSelection() const;
+	///
 	virtual void putClipboard(std::string const &) const;
+	///
+	virtual void putSelection(std::string const &) const;
 
 	/// handles SelectionRequest X Event, to fill the clipboard
 	int event_cb(XEvent * xev);
Index: src/text3.C
===================================================================
--- src/text3.C	(Revision 13993)
+++ src/text3.C	(Arbeitskopie)
@@ -980,9 +980,12 @@ void LyXText::dispatch(LCursor & cur, Fu
 		break;
 	}
 
+	case LFUN_CLIPBOARD_PASTE:
 	case LFUN_PRIMARY_SELECTION_PASTE: {
 		cur.clearSelection();
-		string const clip = bv->getClipboard();
+		string const clip = (cmd.action == LFUN_CLIPBOARD_PASTE) ? 
+			bv->getClipboard() :
+			bv->getSelection();
 		if (!clip.empty()) {
 			recordUndo(cur);
 			if (cmd.argument == "paragraph")
@@ -1867,6 +1870,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/BufferView.C
===================================================================
--- src/BufferView.C	(Revision 13993)
+++ src/BufferView.C	(Arbeitskopie)
@@ -216,9 +216,21 @@ string const BufferView::getClipboard() 
 }
 
 
+string const BufferView::getSelection() const
+{
+	return pimpl_->workarea().getSelection();
+}
+
+
 void BufferView::stuffClipboard(string const & stuff) const
 {
-	pimpl_->stuffClipboard(stuff);
+	pimpl_->workarea().putClipboard(stuff);
+}
+
+
+void BufferView::stuffSelection(string const & stuff) const
+{
+	pimpl_->workarea().putSelection(stuff);
 }
 
 
Index: src/lfuns.h
===================================================================
--- src/lfuns.h	(Revision 13993)
+++ 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: src/BufferView.h
===================================================================
--- src/BufferView.h	(Revision 13993)
+++ src/BufferView.h	(Arbeitskopie)
@@ -167,8 +167,12 @@ public:
 
 	/// get the contents of the window system clipboard
 	std::string const getClipboard() const;
+	/// get the contents of the window system primary selection
+	std::string const getSelection() const;
 	/// fill the window system clipboard
 	void stuffClipboard(std::string const &) const;
+	/// fill the window system primary selection
+	void stuffSelection(std::string const &) const;
 	/// tell the window system we have a selection
 	void haveSelection(bool sel);
 
Index: lib/ui/stdmenus.ui
===================================================================
--- lib/ui/stdmenus.ui	(Revision 13993)
+++ 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|L" "clipboard-paste"
+		Item "Clipboard as Paragraphs|P" "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