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