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