QPrefs.cpp \
QRef.cpp \
QSearch.cpp \
+ QSelectionManager.cpp \
QSendto.cpp \
QSetBorder.cpp \
QShowFile.cpp \
QPrefs.h \
QRef.h \
QSearch.h \
+ QSelectionManager.h \
QSendto.h \
QSetBorder.h \
QShowFile.h \
-/*
+/**
* \file QCitation.cpp
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
* \author Angus Leeming
* \author Kalle Dalheimer
* \author Abdelrazak Younes
+ * \author Richard Heck (adapted to QSelectionManager)
*
* Full author contact details are available in file CREDITS.
*/
}
-void QCitation::addKey(QModelIndex const & index)
-{
- cited_keys_.append(index.data().toString());
- selected_model_.setStringList(cited_keys_);
-}
-
-
-void QCitation::deleteKey(QModelIndex const & index)
-{
- cited_keys_.removeAt(index.row());
- selected_model_.setStringList(cited_keys_);
-}
-
-
-void QCitation::upKey(QModelIndex const & index)
-{
- int pos = index.row();
- cited_keys_.swap(pos, pos - 1);
- selected_model_.setStringList(cited_keys_);
-}
-
-
-void QCitation::downKey(QModelIndex const & index)
-{
- int pos = index.row();
- cited_keys_.swap(pos, pos + 1);
- selected_model_.setStringList(cited_keys_);
-}
-
-
QStringList QCitation::citationStyles(int sel)
{
docstring const key = qstring_to_ucs4(cited_keys_[sel]);
return toqstr(getInfo(qstring_to_ucs4(sel)));
}
+void QCitation::setCitedKeys()
+{
+ cited_keys_ = selected_model_.stringList();
+}
+
} // namespace frontend
} // namespace lyx
* \author Angus Leeming
* \author Kalle Dalheimer
* \author Abdelrazak Younes
+ * \author Richard Heck (adapted to QSelectionManager)
*
* Full author contact details are available in file CREDITS.
*/
bool reset = false //< whether to reset and search all keys
);
- /// Add key to selected keys
- void addKey(QModelIndex const &);
-
- /// Delete key from selected keys
- void deleteKey(QModelIndex const &);
-
- /// Move selected key one place up
- void upKey(QModelIndex const &);
-
- /// Move selected key one place down
- void downKey(QModelIndex const &);
-
/// List of example cite strings
QStringList citationStyles(int);
/// Set the Params variable for the Controller.
virtual void apply(int const choice, bool const full, bool const force,
QString before, QString after);
+
+ void setCitedKeys();
private:
/// available keys.
* \author John Levon
* \author Jürgen Spitzmüller
* \author Abdelrazak Younes
+ * \author Richard Heck
*
* Full author contact details are available in file CREDITS.
*/
#include "frontends/controllers/frontend_helpers.h"
#include "frontends/controllers/ControlCitation.h"
+#include "qt_helpers.h"
#include "support/docstring.h"
setWindowTitle(toqstr("LyX: " + getTitle()));
- selectedLV->setModel(form_->selected());
- availableLV->setModel(form_->available());
-
connect(citationStyleCO, SIGNAL(activated(int)),
this, SLOT(changed()));
connect(fulllistCB, SIGNAL(clicked()),
this, SLOT(changed()));
connect(clearPB, SIGNAL(clicked()),
findLE, SLOT(clear()));
- connect(availableLV->selectionModel(),
- SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
- this, SLOT(availableChanged(const QModelIndex &, const QModelIndex &)));
- connect(selectedLV->selectionModel(),
- SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
- this, SLOT(selectedChanged(const QModelIndex &, const QModelIndex &)));
connect(this, SIGNAL(rejected()), this, SLOT(cleanUp()));
- availableLV->installEventFilter(this);
- selectedLV->installEventFilter(this);
- availableFocused_ = true;
-}
+ selectionManager =
+ new QSelectionManager(availableLV, selectedLV,
+ addPB, deletePB, upPB, downPB,
+ form_->available(), form_->selected());
+ connect(selectionManager, SIGNAL(selectionChanged()),
+ this, SLOT(setCitedKeys()));
+ connect(selectionManager, SIGNAL(updateHook()),
+ this, SLOT(updateDialog()));
+ connect(selectionManager, SIGNAL(okHook()),
+ this, SLOT(on_okPB_clicked()));
-QCitationDialog::~QCitationDialog()
-{
}
-bool QCitationDialog::eventFilter(QObject * obj, QEvent * event)
-{
- if (obj == availableLV) {
- if (event->type() != QEvent::KeyPress)
- return QObject::eventFilter(obj, event);
- QKeyEvent * keyEvent = static_cast<QKeyEvent *>(event);
- int const keyPressed = keyEvent->key();
- Qt::KeyboardModifiers const keyModifiers = keyEvent->modifiers();
- //Enter key without modifier will add current item.
- //Ctrl-Enter will add it and close the dialog.
- //This is designed to work both with the main enter key
- //and the one on the numeric keypad.
- if ((keyPressed == Qt::Key_Enter || keyPressed == Qt::Key_Return) &&
- //We want one or both of Control and Keypad, and nothing else
- //(KeypadModifier is what you get if you use the Enter key on the
- //numeric keypad.)
- (!keyModifiers ||
- (keyModifiers == Qt::ControlModifier) ||
- (keyModifiers == Qt::KeypadModifier) ||
- (keyModifiers == (Qt::ControlModifier | Qt::KeypadModifier))
- )
- ) {
- if (addPB->isEnabled())
- on_addPB_clicked();
- if (keyModifiers & Qt::ControlModifier)
- on_okPB_clicked();
- event->accept();
- return true;
- }
- } else if (obj == selectedLV) {
- //Delete or backspace key will delete current item
- //...with control modifier will clear the list
- if (event->type() != QEvent::KeyPress)
- return QObject::eventFilter(obj, event);
- QKeyEvent * keyEvent = static_cast<QKeyEvent *>(event);
- int const keyPressed = keyEvent->key();
- Qt::KeyboardModifiers const keyModifiers = keyEvent->modifiers();
- if (keyPressed == Qt::Key_Delete || keyPressed == Qt::Key_Backspace) {
- if (keyModifiers == Qt::NoModifier && deletePB->isEnabled())
- on_deletePB_clicked();
- else if (keyModifiers == Qt::ControlModifier) {
- form_->clearSelection();
- updateDialog();
- } else
- //ignore it otherwise
- return QObject::eventFilter(obj, event);
- event->accept();
- return true;
- }
- }
- return QObject::eventFilter(obj, event);
-}
+QCitationDialog::~QCitationDialog()
+{}
void QCitationDialog::cleanUp()
//two methods, though they should be divisible.
void QCitationDialog::updateDialog()
{
- if (availableFocused_ ||
- selectedLV->selectionModel()->selectedIndexes().isEmpty()) {
- if (availableLV->selectionModel()->selectedIndexes().isEmpty()
- && availableLV->model()->rowCount() > 0)
- availableLV->setCurrentIndex(availableLV->model()->index(0,0));
- updateInfo(availableLV);
- } else
- updateInfo(selectedLV);
-
+ if (selectionManager->selectedFocused()) {
+ if (selectedLV->selectionModel()->selectedIndexes().isEmpty())
+ updateInfo(availableLV->currentIndex());
+ else
+ updateInfo(selectedLV->currentIndex());
+ } else {
+ if (availableLV->selectionModel()->selectedIndexes().isEmpty())
+ updateInfo(QModelIndex());
+ else
+ updateInfo(availableLV->currentIndex());
+ }
setButtons();
textBeforeED->setText(form_->textBefore());
void QCitationDialog::setButtons()
{
- int const arows = availableLV->model()->rowCount();
- QModelIndexList const availSels =
- availableLV->selectionModel()->selectedIndexes();
- addPB->setEnabled(arows > 0 &&
- !availSels.isEmpty() &&
- !isSelected(availSels.first()));
-
+ selectionManager->update();
int const srows = selectedLV->model()->rowCount();
- QModelIndexList const selSels =
- selectedLV->selectionModel()->selectedIndexes();
- int const sel_nr = selSels.empty() ? -1 : selSels.first().row();
- deletePB->setEnabled(sel_nr >= 0);
- upPB->setEnabled(sel_nr > 0);
- downPB->setEnabled(sel_nr >= 0 && sel_nr < srows - 1);
+ applyPB->setEnabled(srows > 0);
+ okPB->setEnabled(srows > 0);
}
-void QCitationDialog::updateInfo(QListView const * const qlv)
+void QCitationDialog::updateInfo(QModelIndex const & idx)
{
- QModelIndex idx = qlv->currentIndex();
if (idx.isValid()) {
QString const keytxt = form_->getKeyInfo(idx.data().toString());
infoML->document()->setPlainText(keytxt);
}
-void QCitationDialog::on_selectedLV_clicked(const QModelIndex &)
-{
- availableFocused_ = false;
- updateDialog();
-}
-
-
-void QCitationDialog::selectedChanged(const QModelIndex & idx, const QModelIndex &)
-{
- if (!idx.isValid())
- return;
- updateDialog();
-}
-
-
-void QCitationDialog::on_availableLV_clicked(const QModelIndex &)
-{
- availableFocused_ = true;
- updateDialog();
-}
-
-
-void QCitationDialog::availableChanged(const QModelIndex & idx, const QModelIndex &)
-{
- if (!idx.isValid())
- return;
- availableFocused_ = true;
- updateDialog();
-}
-
-
-void QCitationDialog::on_availableLV_doubleClicked(const QModelIndex & idx)
-{
- if (isSelected(idx))
- return;
- availableFocused_ = true;
- on_addPB_clicked();
-}
-
-
-namespace {
-//helper function for next two
-QModelIndex getSelectedIndex(QListView * lv) {
- //Encourage compiler to use NRVO
- QModelIndex retval = QModelIndex();
- QModelIndexList selIdx =
- lv->selectionModel()->selectedIndexes();
- if (!selIdx.empty())
- retval = selIdx.first();
- return retval;
-}
-}//anonymous namespace
-
-
-void QCitationDialog::on_addPB_clicked()
-{
- QModelIndex const idxToAdd = getSelectedIndex(availableLV);
- if (!idxToAdd.isValid())
- return;
- QModelIndex idx = selectedLV->currentIndex();
- form_->addKey(idxToAdd);
- if (idx.isValid())
- selectedLV->setCurrentIndex(idx);
- availableFocused_ = true;
- updateDialog();
-}
-
-
-void QCitationDialog::on_deletePB_clicked()
-{
- QModelIndex idx = getSelectedIndex(selectedLV);
- if (!idx.isValid())
- return;
- int nrows = selectedLV->model()->rowCount();
-
- form_->deleteKey(idx);
-
- if (idx.row() == nrows - 1)
- idx = idx.sibling(idx.row() - 1, idx.column());
-
- if (nrows>1)
- selectedLV->setCurrentIndex(idx);
- availableFocused_ = true;
- updateDialog();
-}
-
-
-void QCitationDialog::on_upPB_clicked()
-{
- QModelIndex idx = selectedLV->currentIndex();
- form_->upKey(idx);
- selectedLV->setCurrentIndex(idx.sibling(idx.row() - 1, idx.column()));
- availableLV->selectionModel()->reset();
- availableFocused_ = false;
- updateDialog();
-}
-
-
-void QCitationDialog::on_downPB_clicked()
+void QCitationDialog::setCitedKeys()
{
- QModelIndex idx = selectedLV->currentIndex();
- form_->downKey(idx);
- selectedLV->setCurrentIndex(idx.sibling(idx.row() + 1, idx.column()));
- availableLV->selectionModel()->reset();
- availableFocused_ = false;
- updateDialog();
+ form_->setCitedKeys();
}
*
* \author Kalle Dalheimer
* \author Abdelrazak Younes
+ * \author Richard Heck
*
* Full author contact details are available in file CREDITS.
*/
#define QCITATIONDIALOG_H
#include "Dialog.h"
+#include "QSelectionManager.h"
#include "ui_CitationUi.h"
#include <QCloseEvent>
#include <QKeyEvent>
+#include <QStringList>
+#include <QStringListModel>
namespace lyx {
namespace frontend {
/// Create the dialog if necessary, update it and display it.
void show();
- /// Update the display of the dialog whilst it is still visible.
- void update();
-
/// \return true if the dialog is visible.
bool isVisible() const;
-
- ///
- bool eventFilter(QObject *, QEvent *);
+
+public Q_SLOTS:
+ /// Update the display of the dialog whilst it is still visible.
+ void update();
protected:
void closeEvent (QCloseEvent * e);
/// check whether key is already selected
bool isSelected(const QModelIndex &);
/// update the display of BibTeX information
- void updateInfo(QListView const * const);
+ void updateInfo(QModelIndex const &);
protected Q_SLOTS:
void cleanUp();
void on_cancelPB_clicked();
void on_restorePB_clicked();
void on_applyPB_clicked();
- void on_addPB_clicked();
- void on_deletePB_clicked();
- void on_upPB_clicked();
- void on_downPB_clicked();
void on_findLE_textChanged(const QString & text);
void on_fieldsCO_currentIndexChanged(int index);
void on_entriesCO_currentIndexChanged(int index);
void on_caseCB_stateChanged(int);
void on_regexCB_stateChanged(int);
- void on_selectedLV_clicked(const QModelIndex &);
- void selectedChanged(const QModelIndex &, const QModelIndex &);
- void on_availableLV_clicked(const QModelIndex &);
- void on_availableLV_doubleClicked(const QModelIndex &);
- void availableChanged(const QModelIndex &, const QModelIndex &);
virtual void changed();
-
+ ///
+ void setCitedKeys();
+ /// performs a limited update, suitable for internal call
+ void updateDialog();
+
private:
/// enable/disable buttons
void setButtons();
void fillEntries();
/// set the styles combo
void updateStyle();
- /// performs a limited update, suitable for internal call
- void updateDialog();
/// last used citation style
int style_;
- /// which of available and selected is "focused", in the sense
- /// of which one should be used for updating the info via updateInfo().
- /// true, obviously, if it is availableLV.
- bool availableFocused_;
QCitation * form_;
+
+ QSelectionManager * selectionManager;
};
} // namespace frontend
--- /dev/null
+/**
+ * \file QSelectionManager.cpp
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Richard Heck
+ * \author Et Alia
+ *
+ * Some of the material in this file previously appeared in
+ * QCitationDialog.cpp.
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+#include "QSelectionManager.h"
+
+
+namespace lyx {
+namespace frontend {
+
+QSelectionManager::QSelectionManager(
+ QListView * avail,
+ QListView * sel,
+ QPushButton * add,
+ QPushButton * del,
+ QPushButton * up,
+ QPushButton * down,
+ QStringListModel * amod,
+ QStringListModel * smod)
+{
+ availableLV = avail;
+ selectedLV = sel;
+ addPB = add;
+ deletePB = del;
+ upPB = up;
+ downPB = down;
+ availableModel = amod;
+ selectedModel = smod;
+
+ selectedLV->setModel(smod);
+ availableLV->setModel(amod);
+
+ connect(availableLV->selectionModel(),
+ SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
+ this, SLOT(availableChanged(const QModelIndex &, const QModelIndex &)));
+ connect(selectedLV->selectionModel(),
+ SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
+ this, SLOT(selectedChanged(const QModelIndex &, const QModelIndex &)));
+ connect(addPB, SIGNAL(clicked()),
+ this, SLOT(addPB_clicked()));
+ connect(deletePB, SIGNAL(clicked()),
+ this, SLOT(deletePB_clicked()));
+ connect(upPB, SIGNAL(clicked()),
+ this, SLOT(upPB_clicked()));
+ connect(downPB, SIGNAL(clicked()),
+ this, SLOT(downPB_clicked()));
+ connect(availableLV, SIGNAL(clicked(const QModelIndex &)),
+ this, SLOT(availableLV_clicked(const QModelIndex &)));
+ connect(availableLV, SIGNAL(doubleClicked(const QModelIndex &)),
+ this, SLOT(availableLV_doubleClicked(const QModelIndex &)));
+ connect(selectedLV, SIGNAL(clicked(const QModelIndex &)),
+ this, SLOT(selectedLV_clicked(const QModelIndex &)));
+
+ availableLV->installEventFilter(this);
+ selectedLV->installEventFilter(this);
+}
+
+
+void QSelectionManager::update() {
+ int const arows = availableLV->model()->rowCount();
+ QModelIndexList const availSels =
+ availableLV->selectionModel()->selectedIndexes();
+ addPB->setEnabled(arows > 0 &&
+ !availSels.isEmpty() &&
+ !isSelected(availSels.first()));
+
+ int const srows = selectedLV->model()->rowCount();
+ QModelIndexList const selSels =
+ selectedLV->selectionModel()->selectedIndexes();
+ int const sel_nr = selSels.empty() ? -1 : selSels.first().row();
+ deletePB->setEnabled(sel_nr >= 0);
+ upPB->setEnabled(sel_nr > 0);
+ downPB->setEnabled(sel_nr >= 0 && sel_nr < srows - 1);
+}
+
+
+bool QSelectionManager::isSelected(const QModelIndex & idx)
+{
+ QString const str = idx.data().toString();
+ return selectedModel->stringList().contains(str);
+}
+
+
+void QSelectionManager::availableChanged(const QModelIndex & idx, const QModelIndex &)
+{
+ if (!idx.isValid())
+ return;
+
+ selectedHasFocus_ = false;
+ updateHook();
+}
+
+
+void QSelectionManager::selectedChanged(const QModelIndex & idx, const QModelIndex &)
+{
+ if (!idx.isValid())
+ return;
+
+ selectedHasFocus_ = true;
+ updateHook();
+}
+
+
+namespace {
+//helper function for next two
+ QModelIndex getSelectedIndex(QListView * lv) {
+ //Encourage compiler to use NRVO
+ QModelIndex retval = QModelIndex();
+ QModelIndexList selIdx =
+ lv->selectionModel()->selectedIndexes();
+ if (!selIdx.empty())
+ retval = selIdx.first();
+ return retval;
+ }
+}//anonymous namespace
+
+
+void QSelectionManager::addPB_clicked()
+{
+ QModelIndex const idxToAdd = getSelectedIndex(availableLV);
+ if (!idxToAdd.isValid())
+ return;
+ QModelIndex idx = selectedLV->currentIndex();
+
+ QStringList keys = selectedModel->stringList();
+ keys.append(idxToAdd.data().toString());
+ selectedModel->setStringList(keys);
+ selectionChanged(); //signal
+
+ if (idx.isValid())
+ selectedLV->setCurrentIndex(idx);
+ updateHook();
+}
+
+
+void QSelectionManager::deletePB_clicked()
+{
+ QModelIndex idx = getSelectedIndex(selectedLV);
+ if (!idx.isValid())
+ return;
+
+ QStringList keys = selectedModel->stringList();
+ keys.removeAt(idx.row());
+ selectedModel->setStringList(keys);
+ selectionChanged(); //signal
+
+ int nrows = selectedLV->model()->rowCount();
+ if (idx.row() == nrows) //was last item on list
+ idx = idx.sibling(idx.row() - 1, idx.column());
+
+ if (nrows > 1)
+ selectedLV->setCurrentIndex(idx);
+ else if (nrows == 1)
+ selectedLV->setCurrentIndex(selectedLV->model()->index(0,0));
+ selectedHasFocus_ = (nrows > 0);
+ updateHook();
+}
+
+
+void QSelectionManager::upPB_clicked()
+{
+ QModelIndex idx = selectedLV->currentIndex();
+
+ int const pos = idx.row();
+ QStringList keys = selectedModel->stringList();
+ keys.swap(pos, pos - 1);
+ selectedModel->setStringList(keys);
+ selectionChanged(); //signal
+
+ selectedLV->setCurrentIndex(idx.sibling(idx.row() - 1, idx.column()));
+ selectedHasFocus_ = true;
+ updateHook();
+}
+
+
+void QSelectionManager::downPB_clicked()
+{
+ QModelIndex idx = selectedLV->currentIndex();
+
+ int const pos = idx.row();
+ QStringList keys = selectedModel->stringList();
+ keys.swap(pos, pos + 1);
+ selectedModel->setStringList(keys);
+ selectionChanged(); //signal
+
+ selectedLV->setCurrentIndex(idx.sibling(idx.row() + 1, idx.column()));
+ selectedHasFocus_ = true;
+ updateHook();
+}
+
+
+//FIXME These slots do not really do what they need to do, since focus
+//can enter the QListView in other ways. But there are no signals sent
+//in that case. We need to reimplement focusInEvent() to capture those,
+//which means subclassing QListView. (rgh)
+void QSelectionManager::availableLV_clicked(const QModelIndex &)
+{
+ selectedHasFocus_ = false;
+ updateHook();
+}
+
+
+void QSelectionManager::availableLV_doubleClicked(const QModelIndex & idx)
+{
+ if (isSelected(idx))
+ return;
+
+ if (idx.isValid())
+ selectedHasFocus_ = false;
+ addPB_clicked();
+ //updateHook() will be emitted there
+}
+
+
+void QSelectionManager::selectedLV_clicked(const QModelIndex &)
+{
+ selectedHasFocus_ = true;
+ updateHook();
+}
+
+
+bool QSelectionManager::eventFilter(QObject * obj, QEvent * event)
+{
+ if (obj == availableLV) {
+ if (event->type() != QEvent::KeyPress)
+ return QObject::eventFilter(obj, event);
+ QKeyEvent * keyEvent = static_cast<QKeyEvent *>(event);
+ int const keyPressed = keyEvent->key();
+ Qt::KeyboardModifiers const keyModifiers = keyEvent->modifiers();
+ //Enter key without modifier will add current item.
+ //Ctrl-Enter will add it and close the dialog.
+ //This is designed to work both with the main enter key
+ //and the one on the numeric keypad.
+ if ((keyPressed == Qt::Key_Enter || keyPressed == Qt::Key_Return) &&
+ //We want one or both of Control and Keypad, and nothing else
+ //(KeypadModifier is what you get if you use the Enter key on the
+ //numeric keypad.)
+ (!keyModifiers ||
+ (keyModifiers == Qt::ControlModifier) ||
+ (keyModifiers == Qt::KeypadModifier) ||
+ (keyModifiers == (Qt::ControlModifier | Qt::KeypadModifier))
+ )
+ ) {
+ if (addPB->isEnabled()) {
+ addPB_clicked();
+ okHook(); //signal
+ }
+ event->accept();
+ return true;
+ }
+ } else if (obj == selectedLV) {
+ //Delete or backspace key will delete current item
+ //...with control modifier will clear the list
+ if (event->type() != QEvent::KeyPress)
+ return QObject::eventFilter(obj, event);
+ QKeyEvent * keyEvent = static_cast<QKeyEvent *>(event);
+ int const keyPressed = keyEvent->key();
+ Qt::KeyboardModifiers const keyModifiers = keyEvent->modifiers();
+ if (keyPressed == Qt::Key_Delete || keyPressed == Qt::Key_Backspace) {
+ if (keyModifiers == Qt::NoModifier && deletePB->isEnabled())
+ deletePB_clicked();
+ else if (keyModifiers == Qt::ControlModifier) {
+ QStringList list = selectedModel->stringList();
+ list.clear();
+ selectedModel->setStringList(list);
+ updateHook();
+ } else
+ //ignore it otherwise
+ return QObject::eventFilter(obj, event);
+ event->accept();
+ return true;
+ }
+ }
+ return QObject::eventFilter(obj, event);
+}
+
+}//namespace frontend
+}//namespace lyx
+
+#include "QSelectionManager_moc.cpp"
--- /dev/null
+/**
+ * \file QSelectionManager.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Richard Heck
+ * \author Et Alia
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef QSELECTIONMANAGER_H
+#define QSELECTIONMANAGER_H
+
+#include "Dialog.h"
+#include <QObject>
+#include <QKeyEvent>
+#include <QStringList>
+#include <QStringListModel>
+#include <QListView>
+#include <QPushButton>
+
+namespace lyx {
+namespace frontend {
+
+/** Class to manage a collection of widgets that allows selection
+ * of items from a list of available items. Adapted from code originally
+ * written for QCitationDialog.
+ * Note that this is a not a QWidget, though it could be converted to
+ * one. Rather, the managed widgets---see constructor for descripton
+ * of them---should be created independently, and then passed to the
+ * constructor.
+ */
+class QSelectionManager: public QObject {
+ Q_OBJECT
+
+ public:
+ ///
+ QSelectionManager(
+ QListView * availableLV,
+ QListView * selectedLV,
+ QPushButton * addPB,
+ QPushButton * delPB,
+ QPushButton * upPB,
+ QPushButton * downPB,
+ QStringListModel * availableModel,
+ QStringListModel * selectedModel);
+ /// Sets the state of the various push buttons, depending upon the
+ /// state of the widgets. (E.g., "delete" is enabled only if the
+ /// selection is non-empty.)
+ virtual void update();
+
+ /// Not strictly a matter of focus, which may be elsewhere, but
+ /// whether selectedLV is `more focused' than availableLV. Intended
+ /// to be used, for example, in displaying information about a
+ /// highlighted item: should it be the highlighted available item
+ /// or the highlighted selected item that is displayed?
+ bool selectedFocused() { return selectedHasFocus_; };
+
+ Q_SIGNALS:
+ ///Emitted when the list of selected items has changed.
+ void selectionChanged();
+ ///Emitted when something has changed that might lead the containing
+ ///dialog to want to update---the focused subwidget or selected item.
+ ///(Specifically, it is emitted by *_PB_clicked() and *_LV_clicked.)
+ ///NOTE: No automatic update of the button state is done here. If you
+ ///just want to do that, connect updateHook() to update(). Much of the
+ ///time, though, you will want to do a bit more processing first, so
+ ///you can connect to some other function that itself calls update().
+ void updateHook();
+ ///Emitted on Ctrl-Enter in the availableLV. Intended to be connected
+ ///to an "OK" event in the parent dialog.
+ void okHook();
+
+
+ protected:
+ ///Given a QModelIndex from availableLV, determines whether it has
+ ///been selected (i.e., is also in selectedLV).
+ bool isSelected(const QModelIndex & idx);
+
+ protected Q_SLOTS:
+ ///
+ void availableChanged(const QModelIndex & idx, const QModelIndex &);
+ ///
+ void selectedChanged(const QModelIndex & idx, const QModelIndex &);
+ ///
+ void addPB_clicked();
+ ///
+ void deletePB_clicked();
+ ///
+ void upPB_clicked();
+ ///
+ void downPB_clicked();
+ ///
+ void availableLV_clicked(const QModelIndex &);
+ ///
+ void availableLV_doubleClicked(const QModelIndex &);
+ ///
+ void selectedLV_clicked(const QModelIndex &);
+ ///
+ bool eventFilter(QObject *, QEvent *);
+
+ private:
+ QListView * availableLV;
+ QListView * selectedLV;
+ QPushButton * addPB;
+ QPushButton * deletePB;
+ QPushButton * upPB;
+ QPushButton * downPB;
+ QStringListModel * availableModel;
+ QStringListModel * selectedModel;
+ Dialog::View * dialog;
+
+ bool selectedHasFocus_;
+};
+}//namespace frontend
+}//namespace lyx
+#endif