On 06/25/2016 02:58 AM, Liviu Andronic wrote: > On Sat, Jun 25, 2016 at 12:23 AM, Richard Heck <rgh...@lyx.org> wrote: >> Attached please find a patch that implements a combo box for custom >> insets, much like the layout box. This is a very simple version. More >> complicated ones might also have an InsetLayout tag that governed >> whether an inset would appear here. It would also be very easy to adapt >> this also to give us a combo for charstyles. >> > Looks good. Couple of comments: > - since unlike styles we don't always have a "default" chunk, probably > the first item in the list should be something like: <Insert Custom > Inset>. This will also make the UI more intuitive. > - using the knitr module, while I can insert Chunks without trouble, > for S/R expression and Sweave Opts I get "undefined" inset
I've fixed both these issues with the attached. Richard
>From 001716da6eb23aff6f38fdbb8cc07d2c5d900498 Mon Sep 17 00:00:00 2001 From: Richard Heck <rgh...@lyx.org> Date: Fri, 24 Jun 2016 17:47:30 -0400 Subject: [PATCH] Initial work for inset toolbar combo. --- lib/ui/stdtoolbars.inc | 2 + src/frontends/qt4/GuiToolbar.cpp | 9 ++ src/frontends/qt4/GuiView.cpp | 24 ++++- src/frontends/qt4/GuiView.h | 3 + src/frontends/qt4/InsetCombo.cpp | 207 +++++++++++++++++++++++++++++++++++++++ src/frontends/qt4/InsetCombo.h | 56 +++++++++++ src/frontends/qt4/Makefile.am | 2 + src/frontends/qt4/Toolbars.cpp | 9 +- src/frontends/qt4/Toolbars.h | 4 +- 9 files changed, 312 insertions(+), 4 deletions(-) create mode 100644 src/frontends/qt4/InsetCombo.cpp create mode 100644 src/frontends/qt4/InsetCombo.h diff --git a/lib/ui/stdtoolbars.inc b/lib/ui/stdtoolbars.inc index d375afa..c504e4a 100644 --- a/lib/ui/stdtoolbars.inc +++ b/lib/ui/stdtoolbars.inc @@ -95,6 +95,8 @@ ToolbarSet Item "Toggle outline" "dialog-toggle toc" Item "Toggle math toolbar" "toolbar-toggle math" Item "Toggle table toolbar" "toolbar-toggle table" + Separator + Insets End Toolbar "view/update" "View/Update" diff --git a/src/frontends/qt4/GuiToolbar.cpp b/src/frontends/qt4/GuiToolbar.cpp index 77471c9..8958813 100644 --- a/src/frontends/qt4/GuiToolbar.cpp +++ b/src/frontends/qt4/GuiToolbar.cpp @@ -23,6 +23,7 @@ #include "GuiView.h" #include "IconPalette.h" #include "InsertTableWidget.h" +#include "InsetCombo.h" #include "LayoutBox.h" #include "qt_helpers.h" #include "Toolbars.h" @@ -277,6 +278,14 @@ void GuiToolbar::add(ToolbarItem const & item) action->setVisible(true); break; } + case ToolbarItem::INSETS: { + InsetCombo * insets = owner_.getInsetCombo(); + QObject::connect(this, SIGNAL(iconSizeChanged(QSize)), + insets, SLOT(setIconSize(QSize))); + QAction * action = addWidget(insets); + action->setVisible(true); + break; + } case ToolbarItem::MINIBUFFER: command_buffer_ = new GuiCommandBuffer(&owner_); addWidget(command_buffer_); diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index 87ee553..34da998 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -27,6 +27,7 @@ #include "GuiToolbar.h" #include "GuiWorkArea.h" #include "GuiProgress.h" +#include "InsetCombo.h" #include "LayoutBox.h" #include "Menus.h" #include "TocModel.h" @@ -277,7 +278,7 @@ class GuiView::GuiViewPrivate public: GuiViewPrivate(GuiView * gv) : gv_(gv), current_work_area_(0), current_main_work_area_(0), - layout_(0), autosave_timeout_(5000), + layout_(0), insets_(0), autosave_timeout_(5000), in_show_(false) { // hardcode here the platform specific icon size @@ -328,6 +329,7 @@ public: delete splitter_; delete bg_widget_; delete stack_widget_; + delete insets_; } QMenu * toolBarPopup(GuiView * parent) @@ -462,6 +464,7 @@ public: * to only one dialog. */ LayoutBox * layout_; + InsetCombo * insets_; /// map<string, DialogPtr> dialogs_; @@ -808,6 +811,7 @@ void GuiView::constructToolbars() d.layout_ = new LayoutBox(*this); d.stack_widget_->addWidget(d.layout_); d.layout_->move(0,0); + d.insets_ = new InsetCombo(*this); // extracts the toolbars from the backend Toolbars::Infos::iterator cit = guiApp->toolbars().begin(); @@ -1344,7 +1348,8 @@ void GuiView::setBusy(bool busy) return; } QApplication::restoreOverrideCursor(); - updateLayoutList(); + updateLayoutList(); + updateInsetCombo(); } @@ -1535,6 +1540,12 @@ LayoutBox * GuiView::getLayoutDialog() const } +InsetCombo * GuiView::getInsetCombo() const +{ + return d.insets_; +} + + void GuiView::updateLayoutList() { if (d.layout_) @@ -1542,6 +1553,13 @@ void GuiView::updateLayoutList() } +void GuiView::updateInsetCombo() +{ + if (d.insets_) + d.insets_->updateContents(false); +} + + void GuiView::updateToolbars() { ToolbarMap::iterator end = d.toolbars_.end(); @@ -4213,6 +4231,7 @@ void GuiView::resetDialogs() constructToolbars(); guiApp->menus().fillMenuBar(menuBar(), this, false); d.layout_->updateContents(true); + d.insets_->updateContents(true); // Now update controls with current buffer. guiApp->setCurrentView(this); restoreLayout(); @@ -4350,6 +4369,7 @@ void GuiView::updateDialogs() } updateToolbars(); updateLayoutList(); + updateInsetCombo(); } Dialog * createDialog(GuiView & lv, string const & name); diff --git a/src/frontends/qt4/GuiView.h b/src/frontends/qt4/GuiView.h index c3ccdbd..e11db90 100644 --- a/src/frontends/qt4/GuiView.h +++ b/src/frontends/qt4/GuiView.h @@ -46,6 +46,7 @@ class Dialog; class LayoutBox; class GuiToolbar; class GuiWorkArea; +class InsetCombo; class TabWorkArea; class TocModels; class ToolbarInfo; @@ -144,11 +145,13 @@ public: /// updates the possible layouts selectable void updateLayoutList(); + void updateInsetCombo(); void updateToolbars(); QMenu * createPopupMenu(); /// LayoutBox * getLayoutDialog() const; + InsetCombo * getInsetCombo() const; /// hides the workarea and makes sure it is clean bool hideWorkArea(GuiWorkArea * wa); diff --git a/src/frontends/qt4/InsetCombo.cpp b/src/frontends/qt4/InsetCombo.cpp new file mode 100644 index 0000000..41c13ab --- /dev/null +++ b/src/frontends/qt4/InsetCombo.cpp @@ -0,0 +1,207 @@ +/** + * \file qt4/InsetCombo.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Lars Gullik Bjønnes + * \author John Levon + * \author Jean-Marc Lasgouttes + * \author Angus Leeming + * \author Stefan Schimanski + * \author Abdelrazak Younes + * \author Richard Heck + * + * Full author contact details are available in file CREDITS. + */ + +#include <config.h> + +#include "InsetCombo.h" + +#include "GuiView.h" +#include "qt_helpers.h" + +#include "Buffer.h" +#include "BufferParams.h" +#include "BufferView.h" +#include "Cursor.h" +#include "DocumentClassPtr.h" +#include "FuncRequest.h" +#include "FuncStatus.h" +#include "LyX.h" +#include "TextClass.h" + +#include "insets/InsetLayout.h" +#include "insets/InsetText.h" + +#include "support/debug.h" +#include "support/gettext.h" +#include "support/lstrings.h" + +#include <QStandardItemModel> + +using namespace std; +using namespace lyx::support; + +namespace lyx { +namespace frontend { + + +///////////////////////////////////////////////////////////////////// +// +// InsetCombo::Private +// +///////////////////////////////////////////////////////////////////// + +class InsetCombo::Private +{ + /// noncopyable + Private(Private const &); + void operator=(Private const &); +public: + Private(InsetCombo * parent, GuiView & gv) : p(parent), owner_(gv), + inset_(0), + // set the layout model with two columns + // 1st: translated layout names + // 2nd: raw layout names + model_(new QStandardItemModel(0, 2, p)), + lastSel_(-1) + {} + + InsetCombo * p; + /// + GuiView & owner_; + /// + DocumentClassConstPtr text_class_; + /// + Inset const * inset_; + /// the layout model: 1st column translated, 2nd column raw layout name + QStandardItemModel * model_; + /// the (model-) index of the last successful selection + int lastSel_; +}; + + +InsetCombo::InsetCombo(GuiView & owner) + : d(new Private(this, owner)) +{ + setSizeAdjustPolicy(QComboBox::AdjustToContents); + setFocusPolicy(Qt::ClickFocus); + setMinimumWidth(sizeHint().width()); + setMaxVisibleItems(100); + + setModel(d->model_); + + QObject::connect(this, SIGNAL(activated(int)), + this, SLOT(selected(int))); + + updateContents(true); +} + + +InsetCombo::~InsetCombo() { + delete d; +} + + +void InsetCombo::setIconSize(QSize size) +{ +#ifdef Q_OS_MAC + bool small = size.height() < 20; + setAttribute(Qt::WA_MacSmallSize, small); + setAttribute(Qt::WA_MacNormalSize, !small); +#else + (void)size; // suppress warning +#endif +} + + +void InsetCombo::updateContents(bool reset) +{ + static string first_line = N_("<Custom Insets>"); + BufferView const * bv = d->owner_.currentBufferView(); + if (!bv) { + d->model_->clear(); + setEnabled(false); + setMinimumWidth(sizeHint().width()); + d->text_class_.reset(); + d->inset_ = 0; + return; + } + // we'll only update the inset list if the text class has changed + // or we've moved from one inset to another + DocumentClassConstPtr text_class = bv->buffer().params().documentClassPtr(); + Inset const * inset = &(bv->cursor().innerText()->inset()); + if (!reset && d->text_class_ == text_class && d->inset_ == inset) + return; + + d->inset_ = inset; + d->text_class_ = text_class; + d->model_->clear(); + + QList<QStandardItem *> row1; + row1.append(new QStandardItem(toqstr(first_line))); + row1.append(new QStandardItem(QString())); + d->model_->appendRow(row1); + + TextClass::InsetLayouts const & insetLayouts = d->text_class_->insetLayouts(); + TextClass::InsetLayouts::const_iterator iit = insetLayouts.begin(); + TextClass::InsetLayouts::const_iterator ien = insetLayouts.end(); + bool enable = false; + + for (; iit != ien; ++iit) { + InsetLayout const & il = iit->second; + if (il.lyxtype() != InsetLayout::CUSTOM) + continue; + docstring name = iit->first; + QString qitem = toqstr(name); + QString const loc_item = + toqstr(translateIfPossible( + prefixIs(name, from_ascii("Flex:")) ? + name.substr(5) : name)); + + QList<QStandardItem *> row; + row.append(new QStandardItem(loc_item)); + row.append(new QStandardItem(qitem)); + + d->model_->appendRow(row); + enable = true; + } + + setMinimumWidth(sizeHint().width()); + setEnabled(!bv->buffer().isReadonly() && enable && + d->inset_->insetAllowed(FLEX_CODE)); +} + + +void InsetCombo::selected(int index) +{ + if (index == 0) + return; + // get selection + docstring insetName = qstring_to_ucs4( + d->model_->item(index, 1)->text()); + d->owner_.setFocus(); + + if (!d->text_class_) { + updateContents(false); + return; + } + + if (!d->text_class_->hasInsetLayout(insetName)) { + LYXERR0("ERROR (inset toolbar): inset " << insetName << " not found!"); + return; + } + + LYXERR0(insetName); + FuncRequest const func(LFUN_FLEX_INSERT, + from_ascii("\"") + insetName + from_ascii("\""), FuncRequest::TOOLBAR); + lyx::dispatch(func); + updateContents(false); +} + + +} // namespace frontend +} // namespace lyx + +#include "moc_InsetCombo.cpp" diff --git a/src/frontends/qt4/InsetCombo.h b/src/frontends/qt4/InsetCombo.h new file mode 100644 index 0000000..11da027 --- /dev/null +++ b/src/frontends/qt4/InsetCombo.h @@ -0,0 +1,56 @@ +// -*- C++ -*- +/** + * \file LayoutBox.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Lars Gullik Bjønnes + * \author John Levon + * \author Jean-Marc Lasgouttes + * \author Angus Leeming + * \author Abdelrazak Younes + * \author Richard Heck + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef LYX_INSET_BOX_H +#define LYX_INSET_BOX_H + +#include "support/strfwd.h" + +#include <QComboBox> + +namespace lyx { + +class DocumentClass; + +namespace frontend { + +class GuiView; + +class InsetCombo : public QComboBox +{ + Q_OBJECT +public: + InsetCombo(GuiView &); + ~InsetCombo(); + + /// Populate the combobox. + void updateContents(bool reset); + +private Q_SLOTS: + /// + void selected(int index); + /// + void setIconSize(QSize size); + +private: + class Private; + Private * const d; +}; + +} // namespace frontend +} // namespace lyx + +#endif // LYX_LAYOUT_BOX_H diff --git a/src/frontends/qt4/Makefile.am b/src/frontends/qt4/Makefile.am index 103105e..c418e10 100644 --- a/src/frontends/qt4/Makefile.am +++ b/src/frontends/qt4/Makefile.am @@ -142,6 +142,7 @@ SOURCEFILES = \ InsertTableWidget.cpp \ InsetParamsDialog.cpp \ InsetParamsWidget.cpp \ + InsetCombo.cpp \ LengthCombo.cpp \ LyXFileDialog.cpp \ LyXToolBox.cpp \ @@ -249,6 +250,7 @@ MOCHEADER = \ IconPalette.h \ InGuiThread.h \ InsertTableWidget.h \ + InsetCombo.h \ InsetParamsDialog.h \ InsetParamsWidget.h \ LayoutBox.h \ diff --git a/src/frontends/qt4/Toolbars.cpp b/src/frontends/qt4/Toolbars.cpp index 20eee93..a1d5ce9 100644 --- a/src/frontends/qt4/Toolbars.cpp +++ b/src/frontends/qt4/Toolbars.cpp @@ -74,7 +74,8 @@ ToolbarInfo & ToolbarInfo::read(Lexer & lex) TO_EXPORTFORMATS, TO_IMPORTFORMATS, TO_UPDATEFORMATS, - TO_VIEWFORMATS + TO_VIEWFORMATS, + TO_INSETS }; struct LexerKeyword toolTags[] = { @@ -82,6 +83,7 @@ ToolbarInfo & ToolbarInfo::read(Lexer & lex) { "exportformats", TO_EXPORTFORMATS }, { "iconpalette", TO_ICONPALETTE }, { "importformats", TO_IMPORTFORMATS }, + { "insets", TO_INSETS }, { "item", TO_COMMAND }, { "layouts", TO_LAYOUTS }, { "minibuffer", TO_MINIBUFFER }, @@ -178,6 +180,11 @@ ToolbarInfo & ToolbarInfo::read(Lexer & lex) FuncRequest(FuncCode(ToolbarItem::LAYOUTS)))); break; + case TO_INSETS: + add(ToolbarItem(ToolbarItem::INSETS, + FuncRequest(FuncCode(ToolbarItem::INSETS)))); + break; + case TO_TABLEINSERT: if (lex.next(true)) { docstring const tooltip = lex.getDocString(); diff --git a/src/frontends/qt4/Toolbars.h b/src/frontends/qt4/Toolbars.h index 02d0ebe..01d4679 100644 --- a/src/frontends/qt4/Toolbars.h +++ b/src/frontends/qt4/Toolbars.h @@ -43,7 +43,9 @@ public: /// a button that expands a menu but remembers the last choice STICKYPOPUPMENU, /// - ICONPALETTE + ICONPALETTE, + /// + INSETS }; ToolbarItem(Type type, -- 2.1.0