lyx_mirror/src/frontends/qt4/GuiSelectionManager.h
Richard Heck d5d665482e This commit changes the way individual LyXModule's are represented, both internally and in the .lyx files. The earlier version represented them by their `descriptive name', e.g., "Endnote" or "Theorems (AMS)", these being the same names used in the UI. This was a mistake, as becomes readily apparent when one starts to think about translating these strings. The modules ought to be represented by their filename, without the extension, just as TextClass's are.
The changes that accomplish this part are in ModuleList.{h,cpp}, configure.py, and the *.module files themselves. This is a format change, and the lyx2lyx is in those files.

By itself, that change would not be major, except for the fact that we do not want the module to be represented in the UI by its filename---e.g., theorems-std---but rather by a descriptive name, such as "Theorems". But that change turns out to be wholly non-trivial. The mechanism for choosing modules was the same as---indeed, was borrowed from---that in GuiCitation: You get a list of modules, and choosing them involves moving strings from one QListView to another. The models underlying these views are just QStringListModels, which means that, when you want to know what modules have been selected, you see what strings are in the "selected" QListView. But these are just the descriptive names, and we can't look up a module by its descriptive name if it's been translated. That, indeed, was the whole point of the change to the new representation.

So, we need a more complicated model underlying the QListView, one that will pair an identifying string---the filename minus the extension, in this case---with each item. This turns out not to be terribly difficult, though it took rather a while for me to understand why it's not difficult. There are two parts:
(i)  GuiSelectionManger gets re-written to use any QAbstractListModel, not just a QStringListModel. This actually seems to improve the code, independently.
(ii) We then subclass QAbstractListModel to get the associated ID string, using the Qt::UserRole slot associated with each item to store its ID. This would be almost completely trivial if QAbstractListItem::itemData() included the QVariant associated with this role, but it doesn't, so there are some additional hoops through which to jump.

The new model, a GuiIdListModel, is defined in the files by that name. The changes in GuiSelectionManger.{h,cpp} make it more abstract; the changes in GuiDocument.{h,cpp} adapt it to the new framework. 

I've also updated the module documenation to accord with this change.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22501 a592a061-630c-0410-9148-cb99ea01b6c8
2008-01-12 04:28:12 +00:00

146 lines
3.9 KiB
C++

/**
* \file GuiSelectionManager.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 GUISELECTIONMANAGER_H
#define GUISELECTIONMANAGER_H
#include "Dialog.h"
#include <QObject>
#include <QKeyEvent>
#include <QStringList>
#include <QAbstractListModel>
#include <QListView>
#include <QPushButton>
#include "support/qstring_helpers.h"
#include <vector>
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 GuiCitationDialog.
* 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 GuiSelectionManager : public QObject
{
Q_OBJECT
public:
///
GuiSelectionManager(
QListView * availableLV,
QListView * selectedLV,
QPushButton * addPB,
QPushButton * delPB,
QPushButton * upPB,
QPushButton * downPB,
QAbstractListModel * availableModel,
QAbstractListModel * 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.)
/// Note: this is separated out into updateAddPB(), etc, below,
/// for easy over-riding of these functions.
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 updateView(). 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 updateView().
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);
///
bool insertRowToSelected(int i, QMap<int, QVariant> const & itemData);
///
QListView * availableLV;
///
QListView * selectedLV;
///
QPushButton * addPB;
///
QPushButton * deletePB;
///
QPushButton * upPB;
///
QPushButton * downPB;
///
QAbstractListModel * availableModel;
///
QAbstractListModel * selectedModel;
protected Q_SLOTS:
///
void availableChanged(const QModelIndex & idx, const QModelIndex &);
///
void selectedChanged(const QModelIndex & idx, const QModelIndex &);
///
virtual void addPB_clicked();
///
virtual void deletePB_clicked();
///
virtual void upPB_clicked();
///
virtual void downPB_clicked();
///
void availableLV_clicked(const QModelIndex &);
///
void availableLV_doubleClicked(const QModelIndex &);
///
void selectedLV_clicked(const QModelIndex &);
///
bool eventFilter(QObject *, QEvent *);
private:
///
virtual void updateAddPB();
///
virtual void updateDelPB();
///
virtual void updateDownPB();
///
virtual void updateUpPB();
///
bool selectedHasFocus_;
};
} // namespace frontend
} // namespace lyx
#endif // GUISELECTIONMANAGER