mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-25 05:55:34 +00:00
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
This commit is contained in:
parent
471cf26b11
commit
d5d665482e
@ -1,11 +1,14 @@
|
||||
LyX file-format changes
|
||||
-----------------------
|
||||
|
||||
2008-01-12 Richard Heck <rgheck@comcast.net>
|
||||
* Format incremented to 313: change in how modules are represented
|
||||
|
||||
2008-01-11 Jürgen Spitzmüller <j.spitzmueller@gmx.de>
|
||||
* Format incremented to 312: support for sidewaysalgorithm (rotfloat)
|
||||
and wide sideways{figure,table}.
|
||||
|
||||
2008-01-10 Richard Heck <rgheck@bobjweil.com>
|
||||
2008-01-10 Richard Heck <rgheck@comcast.net>
|
||||
* Format incremented to 311: dummy format to drive the AMS conversion
|
||||
|
||||
2007-12-28 Bernhard Reiter <ockham@gmx.net>
|
||||
|
@ -730,6 +730,7 @@ src_frontends_qt4_header_files = Split('''
|
||||
GuiGraphics.h
|
||||
GuiGraphicsUi.h
|
||||
GuiHyperlink.h
|
||||
GuiIdListModel.h
|
||||
GuiImage.h
|
||||
GuiInclude.h
|
||||
GuiIndex.h
|
||||
@ -818,6 +819,7 @@ src_frontends_qt4_files = Split('''
|
||||
GuiFontMetrics.cpp
|
||||
GuiGraphics.cpp
|
||||
GuiHyperlink.cpp
|
||||
GuiIdListModel.cpp
|
||||
GuiImage.cpp
|
||||
GuiInclude.cpp
|
||||
GuiIndex.cpp
|
||||
|
@ -754,6 +754,8 @@ def processModuleFile(file, bool_docbook, bool_linuxdoc):
|
||||
modname = desc = pkgs = req = excl = ""
|
||||
readingDescription = False
|
||||
descLines = []
|
||||
filename = file.split(os.sep)[-1]
|
||||
filename = filename[:-7]
|
||||
|
||||
for line in open(file).readlines():
|
||||
if readingDescription:
|
||||
@ -776,8 +778,6 @@ def processModuleFile(file, bool_docbook, bool_linuxdoc):
|
||||
else:
|
||||
tmp = [s.strip() for s in pkgs.split(",")]
|
||||
pkgs = ",".join(tmp)
|
||||
|
||||
filename = file.split(os.sep)[-1]
|
||||
continue
|
||||
res = r.search(line)
|
||||
if res != None:
|
||||
|
@ -1,5 +1,5 @@
|
||||
#LyX 1.6.0svn created this file. For more info see http://www.lyx.org/
|
||||
\lyxformat 310
|
||||
\lyxformat 313
|
||||
\begin_document
|
||||
\begin_header
|
||||
\textclass book
|
||||
@ -58,7 +58,7 @@
|
||||
\usepackage{multicol}
|
||||
\end_preamble
|
||||
\begin_modules
|
||||
Logical Markup
|
||||
logicalmkup
|
||||
\end_modules
|
||||
\language english
|
||||
\inputencoding default
|
||||
@ -5907,11 +5907,11 @@ theendnotes in ERT where you
|
||||
\end_layout
|
||||
|
||||
\begin_layout LyX-Code
|
||||
#Requires: Some Module | Some Other Module
|
||||
#Requires: somemodule | othermodule
|
||||
\end_layout
|
||||
|
||||
\begin_layout LyX-Code
|
||||
#Excludes: Bad Module
|
||||
#Excludes: badmodule
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
@ -5936,6 +5936,32 @@ at least one
|
||||
no
|
||||
\emph default
|
||||
excluded module may be used.
|
||||
Note that modules are identified here by their
|
||||
\emph on
|
||||
filenames
|
||||
\emph default
|
||||
without the .module extension.
|
||||
So
|
||||
\begin_inset Flex CharStyle:Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Standard
|
||||
somemodule
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
is really
|
||||
\begin_inset Flex CharStyle:Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Standard
|
||||
somemodule.module
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
@ -5947,7 +5973,7 @@ After creating a new module, you will need to reconfigure and then restart
|
||||
Document\SpecialChar \menuseparator
|
||||
Settings
|
||||
\family default
|
||||
, make some change (or even just highlight something), and then hit
|
||||
, highlight something, and then hit
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
#Condition, Note, Notation, Summary, Acknowledgement, Conclusion,
|
||||
#Fact, Assumption, and Case, in both starred and non-starred forms.
|
||||
#DescriptionEnd
|
||||
#Requires: Theorems (AMS)
|
||||
#Requires: theorems-ams
|
||||
|
||||
# Original Author : David L. Johnson <dlj0@lehigh.edu>
|
||||
# Probably broken by Jean-Marc Lasgouttes <Jean-Marc.Lasgouttes@inria.fr>
|
||||
|
@ -5,7 +5,7 @@
|
||||
#the theorems are numbered consecutively throughout the document. This can be
|
||||
#changed by loading one of the Theorems (Ordered By ...) modules.
|
||||
#DescriptionEnd
|
||||
#Excludes: Theorems | Theorems (Starred)
|
||||
#Excludes: theorems-std | theorems-starred
|
||||
|
||||
# Original Author : David L. Johnson <dlj0@lehigh.edu>
|
||||
# Probably broken by Jean-Marc Lasgouttes <Jean-Marc.Lasgouttes@inria.fr>
|
||||
|
@ -2,7 +2,7 @@
|
||||
#DescriptionBegin
|
||||
#Numbers theorems and the like by chapter.
|
||||
#DescriptionEnd
|
||||
#Requires: Theorems | Theorems (AMS)
|
||||
#Requires: theorems-std | theorems-ams
|
||||
|
||||
# Author: Richard Heck <rgheck@comcast.net>
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#DescriptionBegin
|
||||
#Numbers theorems and the like by section.
|
||||
#DescriptionEnd
|
||||
#Requires: Theorems | Theorems (AMS)
|
||||
#Requires: theorems-std | theorems-ams
|
||||
|
||||
# Author: Richard Heck <rgheck@comcast.net>
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#Defines only unnumbered theorem environments, and the proof environment, using
|
||||
#the extended AMS machinery.
|
||||
##DescriptionEnd
|
||||
#Excludes: Theorems (AMS) | Theorems (Starred) | Theorems (Order By Section) | Theorems (Order By Chapter)
|
||||
#Excludes: theorems-std | theorems-ams
|
||||
|
||||
# Author: Richard Heck <rgheck@comcast.net>
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#the theorems are numbered consecutively throughout the document. This can be
|
||||
#changed by loading one of the Theorems (Ordered By ...) modules.
|
||||
#DescriptionEnd
|
||||
#Excludes: Theorems (AMS) | Theorems (Starred)
|
||||
#Excludes: theorems-ams | theorems-starred
|
||||
|
||||
# Author: Richard Heck <rgheck@comcast.net>
|
||||
|
||||
|
@ -80,7 +80,7 @@ format_relation = [("0_06", [200], minor_versions("0.6" , 4)),
|
||||
("1_3", [221], minor_versions("1.3" , 7)),
|
||||
("1_4", range(222,246), minor_versions("1.4" , 5)),
|
||||
("1_5", range(246,277), minor_versions("1.5" , 2)),
|
||||
("1_6", range(277,313), minor_versions("1.6" , 0))] # JSpitzm: rotfloat support
|
||||
("1_6", range(277,314), minor_versions("1.6" , 0))] # Richard Heck: conversion of module representations
|
||||
|
||||
|
||||
def formats_list():
|
||||
@ -412,6 +412,30 @@ class LyX_base:
|
||||
self.header.insert(j, module)
|
||||
|
||||
|
||||
def get_module_list(self):
|
||||
i = find_token(self.header, "\\begin_modules", 0)
|
||||
if (i == -1):
|
||||
return []
|
||||
j = find_token(self.header, "\\end_modules", i)
|
||||
return self.header[i + 1 : j]
|
||||
|
||||
|
||||
def set_module_list(self, mlist):
|
||||
modbegin = find_token(self.header, "\\begin_modules", 0)
|
||||
if (modbegin == -1):
|
||||
#No modules yet included
|
||||
modbegin = find_token(self.header, "\\textclass", 0)
|
||||
if modbegin == -1:
|
||||
self.warning("Malformed LyX document: No \\textclass!!")
|
||||
return
|
||||
modend = find_token(self.header, "\\end_modules", modbegin)
|
||||
if modend == -1:
|
||||
self.warning("Malformed LyX document: No \\end_modules.")
|
||||
return
|
||||
newmodlist = ['\\begin_modules'] + mlist + ['\\end_modules']
|
||||
self.header[modbegin:modend + 1] = newmodlist
|
||||
|
||||
|
||||
def set_parameter(self, param, value):
|
||||
" Set the value of the header parameter."
|
||||
i = find_token(self.header, '\\' + param, 0)
|
||||
|
@ -922,6 +922,40 @@ def convert_framed_notes(document):
|
||||
i = i + 1
|
||||
|
||||
|
||||
def convert_module_names(document):
|
||||
modulemap = { 'Braille' : 'braille', 'Endnote' : 'endnotes', 'Foot to End' : 'foottoend',\
|
||||
'Hanging' : 'hanging', 'Linguistics' : 'linguistics', 'Logical Markup' : 'logicalmkup', \
|
||||
'Theorems (AMS-Extended)' : 'theorems-ams-extended', 'Theorems (AMS)' : 'theorems-ams', \
|
||||
'Theorems (Order By Chapter)' : 'theorems-chap', 'Theorems (Order By Section)' : 'theorems-sec', \
|
||||
'Theorems (Starred)' : 'theorems-starred', 'Theorems' : 'theorems-std' }
|
||||
modlist = document.get_module_list()
|
||||
newmodlist = []
|
||||
for mod in modlist:
|
||||
if modulemap.has_key(mod):
|
||||
newmodlist.append(modulemap[mod])
|
||||
else:
|
||||
document.warning("Can't find module %s in the module map!" % mod)
|
||||
newmodlist.append(mod)
|
||||
document.set_module_list(newmodlist)
|
||||
|
||||
|
||||
def revert_module_names(document):
|
||||
modulemap = { 'braille' : 'Braille', 'endnotes' : 'Endnote', 'foottoend' : 'Foot to End',\
|
||||
'hanging' : 'Hanging', 'linguistics' : 'Linguistics', 'logicalmkup' : 'Logical Markup', \
|
||||
'theorems-ams-extended' : 'Theorems (AMS-Extended)', 'theorems-ams' : 'Theorems (AMS)', \
|
||||
'theorems-chap' : 'Theorems (Order By Chapter)', 'theorems-sec' : 'Theorems (Order By Section)', \
|
||||
'theorems-starred' : 'Theorems (Starred)', 'theorems-std' : 'Theorems'}
|
||||
modlist = document.get_module_list()
|
||||
newmodlist = []
|
||||
for mod in modlist:
|
||||
if modulemap.has_key(mod):
|
||||
newmodlist.append(modulemap[mod])
|
||||
else:
|
||||
document.warning("Can't find module %s in the module map!" % mod)
|
||||
newmodlist.append(mod)
|
||||
document.set_module_list(newmodlist)
|
||||
|
||||
|
||||
def revert_framed_notes(document):
|
||||
"Revert framed boxes to notes. "
|
||||
i = 0
|
||||
@ -1213,9 +1247,11 @@ convert = [[277, [fix_wrong_tables]],
|
||||
[310, []],
|
||||
[311, [convert_ams_classes]],
|
||||
[312, []],
|
||||
[313, [convert_module_names]]
|
||||
]
|
||||
|
||||
revert = [[311, [revert_rotfloat, revert_widesideways]],
|
||||
revert = [[312, [revert_module_names]],
|
||||
[311, [revert_rotfloat, revert_widesideways]],
|
||||
[310, []],
|
||||
[309, [revert_btprintall]],
|
||||
[308, [revert_nocite]],
|
||||
|
@ -118,7 +118,7 @@ namespace os = support::os;
|
||||
|
||||
namespace {
|
||||
|
||||
int const LYX_FORMAT = 312; // JSpitzm: rotfloat support
|
||||
int const LYX_FORMAT = 313; // Richard Heck: conversion of module representations
|
||||
|
||||
} // namespace anon
|
||||
|
||||
|
@ -34,13 +34,15 @@ namespace lyx {
|
||||
ModuleList moduleList;
|
||||
|
||||
|
||||
LyXModule::LyXModule(string const & n, string const & f,
|
||||
LyXModule::LyXModule(string const & n, string const & i,
|
||||
string const & d, vector<string> const & p,
|
||||
vector<string> const & r, vector<string> const & e):
|
||||
name(n), filename(f), description(d),
|
||||
name(n), id(i), description(d),
|
||||
packageList(p), requiredModules(r), excludedModules(e),
|
||||
checked(false)
|
||||
{}
|
||||
{
|
||||
filename = id + ".module";
|
||||
}
|
||||
|
||||
|
||||
bool LyXModule::isAvailable() {
|
||||
@ -204,7 +206,7 @@ LyXModuleList::iterator ModuleList::end()
|
||||
}
|
||||
|
||||
|
||||
LyXModule * ModuleList::operator[](string const & str)
|
||||
LyXModule * ModuleList::getModuleByName(string const & str)
|
||||
{
|
||||
LyXModuleList::iterator it = modlist_.begin();
|
||||
for (; it != modlist_.end(); ++it)
|
||||
@ -215,4 +217,15 @@ LyXModule * ModuleList::operator[](string const & str)
|
||||
return 0;
|
||||
}
|
||||
|
||||
LyXModule * ModuleList::operator[](string const & str)
|
||||
{
|
||||
LyXModuleList::iterator it = modlist_.begin();
|
||||
for (; it != modlist_.end(); ++it)
|
||||
if (it->getID() == str) {
|
||||
LyXModule & mod = *it;
|
||||
return &mod;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace lyx
|
||||
|
@ -28,7 +28,7 @@ namespace lyx {
|
||||
class LyXModule {
|
||||
public:
|
||||
///
|
||||
LyXModule(std::string const & n, std::string const & f,
|
||||
LyXModule(std::string const & n, std::string const & i,
|
||||
std::string const & d, std::vector<std::string> const & p,
|
||||
std::vector<std::string> const & r,
|
||||
std::vector<std::string> const & e);
|
||||
@ -37,6 +37,8 @@ public:
|
||||
///
|
||||
std::string const & getName() const { return name; }
|
||||
///
|
||||
std::string const & getID() const { return id; }
|
||||
///
|
||||
std::string const & getFilename() const { return filename; }
|
||||
///
|
||||
std::string const & getDescription() const { return description; }
|
||||
@ -53,7 +55,10 @@ public:
|
||||
private:
|
||||
/// what appears in the ui
|
||||
std::string name;
|
||||
/// the filename, without any path
|
||||
/// the module's unique identifier
|
||||
/// at present, this is the filename, without the extension
|
||||
std::string id;
|
||||
/// the filename
|
||||
std::string filename;
|
||||
/// a short description for use in the ui
|
||||
std::string description;
|
||||
@ -93,8 +98,11 @@ public:
|
||||
bool empty() const { return modlist_.empty(); }
|
||||
/// Returns a pointer to the LyXModule with name str.
|
||||
/// Returns a null pointer if no such module is found.
|
||||
LyXModule * getModuleByName(std::string const & str);
|
||||
/// Returns a pointer to the LyXModule with filename str.
|
||||
/// Returns a null pointer if no such module is found.
|
||||
LyXModule * operator[](std::string const & str);
|
||||
private:
|
||||
private:
|
||||
/// noncopyable
|
||||
ModuleList(ModuleList const &);
|
||||
///
|
||||
|
@ -189,16 +189,29 @@ ModuleSelMan::ModuleSelMan(
|
||||
QPushButton * delPB,
|
||||
QPushButton * upPB,
|
||||
QPushButton * downPB,
|
||||
QStringListModel * availableModel,
|
||||
QStringListModel * selectedModel) :
|
||||
GuiIdListModel * availableModel,
|
||||
GuiIdListModel * selectedModel) :
|
||||
GuiSelectionManager(availableLV, selectedLV, addPB, delPB,
|
||||
upPB, downPB, availableModel, selectedModel)
|
||||
{}
|
||||
|
||||
|
||||
namespace {
|
||||
QModelIndex getSelectedIndex(QListView * lv)
|
||||
{
|
||||
QModelIndex retval = QModelIndex();
|
||||
QModelIndexList selIdx =
|
||||
lv->selectionModel()->selectedIndexes();
|
||||
if (!selIdx.empty())
|
||||
retval = selIdx.first();
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ModuleSelMan::updateAddPB()
|
||||
{
|
||||
int const arows = availableModel->stringList().size();
|
||||
int const arows = availableModel->rowCount();
|
||||
QModelIndexList const availSels =
|
||||
availableLV->selectionModel()->selectedIndexes();
|
||||
if (arows == 0 || availSels.isEmpty() || isSelected(availSels.first())) {
|
||||
@ -207,7 +220,7 @@ void ModuleSelMan::updateAddPB()
|
||||
}
|
||||
|
||||
QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
|
||||
string const modName = fromqstr(idx.data().toString());
|
||||
string const modName = getAvailableModel()->getIDString(idx.row());
|
||||
vector<string> reqs = getRequiredList(modName);
|
||||
vector<string> excl = getExcludedList(modName);
|
||||
|
||||
@ -216,7 +229,13 @@ void ModuleSelMan::updateAddPB()
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList const & qsl = selectedModel->stringList();
|
||||
int const srows = selectedModel->rowCount();
|
||||
vector<string> selModList;
|
||||
for (int i = 0; i < srows; ++i)
|
||||
selModList.push_back(getSelectedModel()->getIDString(i));
|
||||
|
||||
vector<string>::const_iterator selModStart = selModList.begin();
|
||||
vector<string>::const_iterator selModEnd = selModList.end();
|
||||
|
||||
//Check whether some required module is available
|
||||
if (!reqs.empty()) {
|
||||
@ -224,7 +243,7 @@ void ModuleSelMan::updateAddPB()
|
||||
vector<string>::const_iterator it = reqs.begin();
|
||||
vector<string>::const_iterator end = reqs.end();
|
||||
for (; it != end; ++it) {
|
||||
if (qsl.contains(toqstr(*it))) {
|
||||
if (find(selModStart, selModEnd, *it) != selModEnd) {
|
||||
foundOne = true;
|
||||
break;
|
||||
}
|
||||
@ -240,7 +259,7 @@ void ModuleSelMan::updateAddPB()
|
||||
vector<string>::const_iterator it = excl.begin();
|
||||
vector<string>::const_iterator end = excl.end();
|
||||
for (; it != end; ++it) {
|
||||
if (qsl.contains(toqstr(*it))) {
|
||||
if (find(selModStart, selModEnd, *it) != selModEnd) {
|
||||
addPB->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
@ -250,9 +269,10 @@ void ModuleSelMan::updateAddPB()
|
||||
addPB->setEnabled(true);
|
||||
}
|
||||
|
||||
|
||||
void ModuleSelMan::updateDownPB()
|
||||
{
|
||||
int const srows = selectedModel->stringList().size();
|
||||
int const srows = selectedModel->rowCount();
|
||||
if (srows == 0) {
|
||||
downPB->setEnabled(false);
|
||||
return;
|
||||
@ -265,15 +285,14 @@ void ModuleSelMan::updateDownPB()
|
||||
return;
|
||||
}
|
||||
//determine whether immediately succeding element requires this one
|
||||
QString const curModName =
|
||||
selectedLV->selectionModel()->currentIndex().data().toString();
|
||||
QStringList const & qsl = selectedModel->stringList();
|
||||
int const curIdx = qsl.indexOf(curModName);
|
||||
if (curIdx < 0 || curIdx == srows - 1) { //this shouldn't happen...
|
||||
QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
|
||||
int curRow = curIdx.row();
|
||||
if (curRow < 0 || curRow >= srows - 1) { //this shouldn't happen...
|
||||
downPB->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
string nextModName = fromqstr(qsl[curIdx + 1]);
|
||||
string const curModName = getSelectedModel()->getIDString(curRow);
|
||||
string const nextModName = getSelectedModel()->getIDString(curRow + 1);
|
||||
|
||||
vector<string> reqs = getRequiredList(nextModName);
|
||||
|
||||
@ -287,12 +306,12 @@ void ModuleSelMan::updateDownPB()
|
||||
//if this one is required, there is also an earlier one that is required.
|
||||
//enable it if this module isn't required
|
||||
downPB->setEnabled(
|
||||
find(reqs.begin(), reqs.end(), fromqstr(curModName)) == reqs.end());
|
||||
find(reqs.begin(), reqs.end(), curModName) == reqs.end());
|
||||
}
|
||||
|
||||
void ModuleSelMan::updateUpPB()
|
||||
{
|
||||
int const srows = selectedModel->stringList().size();
|
||||
int const srows = selectedModel->rowCount();
|
||||
if (srows == 0) {
|
||||
upPB->setEnabled(false);
|
||||
return;
|
||||
@ -304,10 +323,16 @@ void ModuleSelMan::updateUpPB()
|
||||
upPB->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
//determine whether immediately preceding element is required by this one
|
||||
QString const curModName =
|
||||
selectedLV->selectionModel()->currentIndex().data().toString();
|
||||
vector<string> reqs = getRequiredList(fromqstr(curModName));
|
||||
QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
|
||||
int curRow = curIdx.row();
|
||||
if (curRow <= -1 || curRow > srows - 1) { //sanity check
|
||||
downPB->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
string const curModName = getSelectedModel()->getIDString(curRow);
|
||||
vector<string> reqs = getRequiredList(curModName);
|
||||
|
||||
//if this one doesn't require anything....
|
||||
if (reqs.empty()) {
|
||||
@ -315,13 +340,7 @@ void ModuleSelMan::updateUpPB()
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList const & qsl = selectedModel->stringList();
|
||||
int const curIdx = qsl.indexOf(curModName);
|
||||
if (curIdx <= 0) { //this shouldn't happen...
|
||||
upPB->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
string preModName = fromqstr(qsl[curIdx - 1]);
|
||||
string preModName = getSelectedModel()->getIDString(curRow - 1);
|
||||
|
||||
//NOTE This is less flexible than it might be. You could check whether, even
|
||||
//if this one is required, there is also an earlier one that is required.
|
||||
@ -331,7 +350,7 @@ void ModuleSelMan::updateUpPB()
|
||||
|
||||
void ModuleSelMan::updateDelPB()
|
||||
{
|
||||
int const srows = selectedModel->stringList().size();
|
||||
int const srows = selectedModel->rowCount();
|
||||
if (srows == 0) {
|
||||
deletePB->setEnabled(false);
|
||||
return;
|
||||
@ -346,59 +365,49 @@ void ModuleSelMan::updateDelPB()
|
||||
//determine whether some LATER module requires this one
|
||||
//NOTE Things are arranged so that this is the only way there
|
||||
//can be a problem. At least, we hope so.
|
||||
QString const curModName =
|
||||
selectedLV->selectionModel()->currentIndex().data().toString();
|
||||
QStringList const & qsl = selectedModel->stringList();
|
||||
QModelIndex const & curIdx =
|
||||
selectedLV->selectionModel()->currentIndex();
|
||||
int const curRow = curIdx.row();
|
||||
if (curRow < 0 || curRow >= srows) { //this shouldn't happen
|
||||
deletePB->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
QString const curModName = curIdx.data().toString();
|
||||
|
||||
//We're looking here for a reason NOT to enable the button. If we
|
||||
//find one, we disable it and return. If we don't, we'll end up at
|
||||
//the end of the function, and then we enable it.
|
||||
QStringList::const_iterator it = qsl.begin();
|
||||
QStringList::const_iterator end = qsl.end();
|
||||
bool found = false;
|
||||
for (; it != end; ++it) {
|
||||
//skip over the ones preceding this one
|
||||
if (!found) {
|
||||
if (*it == curModName) {
|
||||
found = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
string const mod = fromqstr(*it);
|
||||
vector<string> reqs = getRequiredList(mod);
|
||||
for (int i = curRow + 1; i < srows; ++i) {
|
||||
string const thisMod = getSelectedModel()->getIDString(i);
|
||||
vector<string> reqs = getRequiredList(thisMod);
|
||||
//does this one require us?
|
||||
if (find(reqs.begin(), reqs.end(), fromqstr(curModName)) == reqs.end())
|
||||
//no...
|
||||
continue;
|
||||
|
||||
//OK, so there is a module that requires us
|
||||
//is there an EARLIER module that satisfies the require?
|
||||
//OK, so this module requires us
|
||||
//is there an EARLIER module that also satisfies the require?
|
||||
//NOTE We demand that it be earlier to keep the list of modules
|
||||
//consistent with the rule that a module must be proceeded by a
|
||||
//required module. There would be more flexible ways to proceed,
|
||||
//but that would be a lot more complicated, and the logic here is
|
||||
//already complicated. (That's why I've left the debugging code.)
|
||||
//lyxerr << "Testing " << mod << std::endl;
|
||||
QStringList::const_iterator it2 = qsl.begin();
|
||||
QStringList::const_iterator end2 = qsl.end();
|
||||
for (; it2 != end2; ++it2) {
|
||||
//lyxerr << "In loop: Testing " << fromqstr(*it2) << std::endl;
|
||||
if (*it2 == curModName) { //EARLIER!!
|
||||
//no other module was found before this one, so...
|
||||
//lyxerr << "Reached the end of the loop." << std::endl;
|
||||
deletePB->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
//lyxerr << "Testing " << thisMod << std::endl;
|
||||
bool foundOne = false;
|
||||
for (int j = 0; j < curRow; ++j) {
|
||||
string const mod = getSelectedModel()->getIDString(j);
|
||||
//lyxerr << "In loop: Testing " << mod << std::endl;
|
||||
//do we satisfy the require?
|
||||
if (find(reqs.begin(), reqs.end(), fromqstr(*it2)) != reqs.end()) {
|
||||
//lyxerr << fromqstr(*it2) << " does the trick." << std::endl;
|
||||
if (find(reqs.begin(), reqs.end(), mod) != reqs.end()) {
|
||||
//lyxerr << mod << " does the trick." << std::endl;
|
||||
foundOne = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//did we reach the end of the list?
|
||||
if (it2 == end2) {
|
||||
//lyxerr << "Reached end of list." << std::endl;
|
||||
//did we find a module to satisfy the require?
|
||||
if (!foundOne) {
|
||||
//lyxerr << "No matching module found." << std::endl;
|
||||
deletePB->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
@ -1221,54 +1230,75 @@ namespace {
|
||||
t = subst(t, _("and"), s);
|
||||
return bformat(t, retval, from_ascii(v[vSize - 2]), from_ascii(v[vSize - 1]));
|
||||
}
|
||||
|
||||
vector<string> idsToNames(vector<string> const & idList)
|
||||
{
|
||||
vector<string> retval;
|
||||
vector<string>::const_iterator it = idList.begin();
|
||||
vector<string>::const_iterator end = idList.end();
|
||||
for (; it != end; ++it) {
|
||||
LyXModule const * const mod = moduleList[*it];
|
||||
if (!mod)
|
||||
retval.push_back(*it + " (Unavailable)");
|
||||
else
|
||||
retval.push_back(mod->getName());
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GuiDocument::updateModuleInfo()
|
||||
{
|
||||
selectionManager->update();
|
||||
|
||||
//Module description
|
||||
QListView const * const lv = selectionManager->selectedFocused() ?
|
||||
latexModule->selectedLV :
|
||||
latexModule->availableLV;
|
||||
if (lv->selectionModel()->selectedIndexes().isEmpty())
|
||||
bool const focusOnSelected = selectionManager->selectedFocused();
|
||||
QListView const * const lv =
|
||||
focusOnSelected ? latexModule->selectedLV : latexModule->availableLV;
|
||||
if (lv->selectionModel()->selectedIndexes().isEmpty()) {
|
||||
latexModule->infoML->document()->clear();
|
||||
else {
|
||||
QModelIndex const & idx = lv->selectionModel()->currentIndex();
|
||||
string const modName = fromqstr(idx.data().toString());
|
||||
docstring desc = getModuleDescription(modName);
|
||||
|
||||
vector<string> pkgList = getPackageList(modName);
|
||||
docstring pkgdesc = formatStrVec(pkgList, _("and"));
|
||||
if (!pkgdesc.empty()) {
|
||||
if (!desc.empty())
|
||||
desc += "\n";
|
||||
desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
|
||||
}
|
||||
|
||||
pkgList = getRequiredList(modName);
|
||||
pkgdesc = formatStrVec(pkgList, _("or"));
|
||||
if (!pkgdesc.empty()) {
|
||||
if (!desc.empty())
|
||||
desc += "\n";
|
||||
desc += bformat(_("Module required: %1$s."), pkgdesc);
|
||||
}
|
||||
|
||||
pkgList = getExcludedList(modName);
|
||||
pkgdesc = formatStrVec(pkgList, _( "and"));
|
||||
if (!pkgdesc.empty()) {
|
||||
if (!desc.empty())
|
||||
desc += "\n";
|
||||
desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
|
||||
}
|
||||
|
||||
if (!isModuleAvailable(modName)) {
|
||||
if (!desc.empty())
|
||||
desc += "\n";
|
||||
desc += _("WARNING: Some packages are unavailable!");
|
||||
}
|
||||
latexModule->infoML->document()->setPlainText(toqstr(desc));
|
||||
return;
|
||||
}
|
||||
QModelIndex const & idx = lv->selectionModel()->currentIndex();
|
||||
GuiIdListModel const & idModel =
|
||||
focusOnSelected ? selected_model_ : available_model_;
|
||||
string const modName = idModel.getIDString(idx.row());
|
||||
docstring desc = getModuleDescription(modName);
|
||||
|
||||
vector<string> pkgList = getPackageList(modName);
|
||||
docstring pkgdesc = formatStrVec(pkgList, _("and"));
|
||||
if (!pkgdesc.empty()) {
|
||||
if (!desc.empty())
|
||||
desc += "\n";
|
||||
desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
|
||||
}
|
||||
|
||||
pkgList = getRequiredList(modName);
|
||||
if (!pkgList.empty()) {
|
||||
vector<string> const reqDescs = idsToNames(pkgList);
|
||||
pkgdesc = formatStrVec(reqDescs, _("or"));
|
||||
if (!desc.empty())
|
||||
desc += "\n";
|
||||
desc += bformat(_("Module required: %1$s."), pkgdesc);
|
||||
}
|
||||
|
||||
pkgList = getExcludedList(modName);
|
||||
if (!pkgList.empty()) {
|
||||
vector<string> const reqDescs = idsToNames(pkgList);
|
||||
pkgdesc = formatStrVec(reqDescs, _( "and"));
|
||||
if (!desc.empty())
|
||||
desc += "\n";
|
||||
desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
|
||||
}
|
||||
|
||||
if (!isModuleAvailable(modName)) {
|
||||
if (!desc.empty())
|
||||
desc += "\n";
|
||||
desc += _("WARNING: Some packages are unavailable!");
|
||||
}
|
||||
|
||||
latexModule->infoML->document()->setPlainText(toqstr(desc));
|
||||
}
|
||||
|
||||
|
||||
@ -1408,9 +1438,10 @@ void GuiDocument::apply(BufferParams & params)
|
||||
|
||||
// Modules
|
||||
params.clearLayoutModules();
|
||||
QStringList const selMods = selectedModel()->stringList();
|
||||
for (int i = 0; i != selMods.size(); ++i)
|
||||
params.addLayoutModule(lyx::fromqstr(selMods[i]));
|
||||
int const srows = selected_model_.rowCount();
|
||||
vector<string> selModList;
|
||||
for (int i = 0; i < srows; ++i)
|
||||
params.addLayoutModule(selected_model_.getIDString(i));
|
||||
|
||||
if (mathsModule->amsautoCB->isChecked()) {
|
||||
params.use_amsmath = BufferParams::package_auto;
|
||||
@ -1922,27 +1953,40 @@ void GuiDocument::saveDocDefault()
|
||||
}
|
||||
|
||||
|
||||
void GuiDocument::updateAvailableModules()
|
||||
{
|
||||
available_model_.clear();
|
||||
vector<modInfoStruct> const modInfoList = getModuleInfo();
|
||||
int const mSize = modInfoList.size();
|
||||
for (int i = 0; i < mSize; ++i) {
|
||||
modInfoStruct const & modInfo = modInfoList[i];
|
||||
available_model_.insertRow(i, modInfo.name, modInfo.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GuiDocument::updateSelectedModules()
|
||||
{
|
||||
//and selected ones, too
|
||||
selected_model_.clear();
|
||||
vector<modInfoStruct> const selModList = getSelectedModules();
|
||||
int const sSize = selModList.size();
|
||||
for (int i = 0; i < sSize; ++i) {
|
||||
modInfoStruct const & modInfo = selModList[i];
|
||||
selected_model_.insertRow(i, modInfo.name, modInfo.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GuiDocument::updateContents()
|
||||
{
|
||||
//update list of available modules
|
||||
QStringList strlist;
|
||||
vector<string> const modNames = getModuleNames();
|
||||
vector<string>::const_iterator it = modNames.begin();
|
||||
for (; it != modNames.end(); ++it)
|
||||
strlist.push_back(toqstr(*it));
|
||||
available_model_.setStringList(strlist);
|
||||
//and selected ones, too
|
||||
QStringList strlist2;
|
||||
vector<string> const & selMods = getSelectedModules();
|
||||
it = selMods.begin();
|
||||
for (; it != selMods.end(); ++it)
|
||||
strlist2.push_back(toqstr(*it));
|
||||
updateAvailableModules();
|
||||
updateSelectedModules();
|
||||
|
||||
//FIXME It'd be nice to make sure here that the selected
|
||||
//modules are consistent: That required modules are actually
|
||||
//selected, and that we don't have conflicts. If so, we could
|
||||
//at least pop up a warning.
|
||||
selected_model_.setStringList(strlist2);
|
||||
|
||||
updateParams(bp_);
|
||||
}
|
||||
|
||||
@ -1973,7 +2017,7 @@ char const * GuiDocument::fontfamilies_gui[5] = {
|
||||
bool GuiDocument::initialiseParams(string const &)
|
||||
{
|
||||
bp_ = buffer().params();
|
||||
loadModuleNames();
|
||||
loadModuleInfo();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1990,15 +2034,29 @@ BufferId GuiDocument::id() const
|
||||
}
|
||||
|
||||
|
||||
vector<string> const & GuiDocument::getModuleNames()
|
||||
vector<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
|
||||
{
|
||||
return moduleNames_;
|
||||
}
|
||||
|
||||
|
||||
vector<string> const & GuiDocument::getSelectedModules()
|
||||
vector<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
|
||||
{
|
||||
return params().getModules();
|
||||
vector<string> const & mods = params().getModules();
|
||||
vector<string>::const_iterator it = mods.begin();
|
||||
vector<string>::const_iterator end = mods.end();
|
||||
vector<modInfoStruct> mInfo;
|
||||
for (; it != end; ++it) {
|
||||
modInfoStruct m;
|
||||
m.id = *it;
|
||||
LyXModule * mod = moduleList[*it];
|
||||
if (mod)
|
||||
m.name = mod->getName();
|
||||
else
|
||||
m.name = *it + " (Not Found)";
|
||||
mInfo.push_back(m);
|
||||
}
|
||||
return mInfo;
|
||||
}
|
||||
|
||||
|
||||
@ -2118,14 +2176,17 @@ bool GuiDocument::providesScale(string const & font) const
|
||||
}
|
||||
|
||||
|
||||
void GuiDocument::loadModuleNames ()
|
||||
void GuiDocument::loadModuleInfo()
|
||||
{
|
||||
moduleNames_.clear();
|
||||
LyXModuleList::const_iterator it = moduleList.begin();
|
||||
for (; it != moduleList.end(); ++it)
|
||||
moduleNames_.push_back(it->getName());
|
||||
if (!moduleNames_.empty())
|
||||
sort(moduleNames_.begin(), moduleNames_.end());
|
||||
LyXModuleList::const_iterator it = moduleList.begin();
|
||||
LyXModuleList::const_iterator end = moduleList.end();
|
||||
for (; it != end; ++it) {
|
||||
modInfoStruct m;
|
||||
m.id = it->getID();
|
||||
m.name = it->getName();
|
||||
moduleNames_.push_back(m);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -13,10 +13,13 @@
|
||||
#ifndef GUIDOCUMENT_H
|
||||
#define GUIDOCUMENT_H
|
||||
|
||||
#include "GuiDialog.h"
|
||||
#include "BulletsModule.h"
|
||||
#include "GuiSelectionManager.h"
|
||||
#include <QDialog>
|
||||
|
||||
#include "BufferParams.h"
|
||||
#include "BulletsModule.h"
|
||||
#include "GuiDialog.h"
|
||||
#include "GuiIdListModel.h"
|
||||
#include "GuiSelectionManager.h"
|
||||
|
||||
#include "support/types.h"
|
||||
|
||||
@ -52,13 +55,6 @@ class PreambleModule;
|
||||
///
|
||||
typedef void const * BufferId;
|
||||
|
||||
#include <QDialog>
|
||||
#include <QStringList>
|
||||
#include <QStringListModel>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
template<class UI>
|
||||
class UiWidget : public QWidget, public UI
|
||||
{
|
||||
@ -77,8 +73,8 @@ public:
|
||||
QPushButton * delPB,
|
||||
QPushButton * upPB,
|
||||
QPushButton * downPB,
|
||||
QStringListModel * availableModel,
|
||||
QStringListModel * selectedModel);
|
||||
GuiIdListModel * availableModel,
|
||||
GuiIdListModel * selectedModel);
|
||||
private:
|
||||
///
|
||||
virtual void updateAddPB();
|
||||
@ -88,6 +84,16 @@ private:
|
||||
virtual void updateDownPB();
|
||||
///
|
||||
virtual void updateDelPB();
|
||||
/// returns availableModel as a GuiIdListModel
|
||||
GuiIdListModel * getAvailableModel()
|
||||
{
|
||||
return dynamic_cast<GuiIdListModel *>(availableModel);
|
||||
};
|
||||
/// returns selectedModel as a GuiIdListModel
|
||||
GuiIdListModel * getSelectedModel()
|
||||
{
|
||||
return dynamic_cast<GuiIdListModel *>(selectedModel);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -158,22 +164,26 @@ private:
|
||||
std::vector<std::string> lang_;
|
||||
|
||||
/// Available modules
|
||||
QStringListModel * availableModel() { return &available_model_; }
|
||||
GuiIdListModel * availableModel() { return &available_model_; }
|
||||
/// Selected modules
|
||||
QStringListModel * selectedModel() { return &selected_model_; }
|
||||
GuiIdListModel * selectedModel() { return &selected_model_; }
|
||||
private:
|
||||
/// Apply changes
|
||||
void applyView();
|
||||
/// update
|
||||
void updateContents();
|
||||
///
|
||||
void updateAvailableModules();
|
||||
///
|
||||
void updateSelectedModules();
|
||||
/// save as default template
|
||||
void saveDocDefault();
|
||||
/// reset to default params
|
||||
void useClassDefaults();
|
||||
/// available modules
|
||||
QStringListModel available_model_;
|
||||
GuiIdListModel available_model_;
|
||||
/// selected modules
|
||||
QStringListModel selected_model_;
|
||||
GuiIdListModel selected_model_;
|
||||
|
||||
protected:
|
||||
/// return false if validate_listings_params returns error
|
||||
@ -201,10 +211,15 @@ protected:
|
||||
BufferParams const & params() const { return bp_; }
|
||||
///
|
||||
BufferId id() const;
|
||||
///
|
||||
struct modInfoStruct {
|
||||
std::string name;
|
||||
std::string id;
|
||||
};
|
||||
/// List of available modules
|
||||
std::vector<std::string> const & getModuleNames();
|
||||
std::vector<modInfoStruct> const & getModuleInfo();
|
||||
/// Modules in use in current buffer
|
||||
std::vector<std::string> const & getSelectedModules();
|
||||
std::vector<modInfoStruct> const getSelectedModules();
|
||||
///
|
||||
void setLanguage() const;
|
||||
///
|
||||
@ -219,11 +234,11 @@ protected:
|
||||
bool providesScale(std::string const & font) const;
|
||||
private:
|
||||
///
|
||||
void loadModuleNames();
|
||||
void loadModuleInfo();
|
||||
///
|
||||
BufferParams bp_;
|
||||
/// List of names of available modules
|
||||
std::vector<std::string> moduleNames_;
|
||||
std::vector<modInfoStruct> moduleNames_;
|
||||
};
|
||||
|
||||
|
||||
@ -256,4 +271,4 @@ private:
|
||||
} // namespace frontend
|
||||
} // namespace lyx
|
||||
|
||||
#endif // QDOCUMENT_H
|
||||
#endif // GUIDOCUMENT_H
|
||||
|
@ -15,10 +15,14 @@
|
||||
#include <config.h>
|
||||
#include "GuiSelectionManager.h"
|
||||
|
||||
#include "support/debug.h"
|
||||
|
||||
using std::vector;
|
||||
|
||||
namespace lyx {
|
||||
namespace frontend {
|
||||
|
||||
|
||||
GuiSelectionManager::GuiSelectionManager(
|
||||
QListView * avail,
|
||||
QListView * sel,
|
||||
@ -26,8 +30,8 @@ GuiSelectionManager::GuiSelectionManager(
|
||||
QPushButton * del,
|
||||
QPushButton * up,
|
||||
QPushButton * down,
|
||||
QStringListModel * amod,
|
||||
QStringListModel * smod)
|
||||
QAbstractListModel * amod,
|
||||
QAbstractListModel * smod)
|
||||
{
|
||||
availableLV = avail;
|
||||
selectedLV = sel;
|
||||
@ -78,7 +82,7 @@ void GuiSelectionManager::update()
|
||||
|
||||
void GuiSelectionManager::updateAddPB()
|
||||
{
|
||||
int const arows = availableModel->stringList().size();
|
||||
int const arows = availableModel->rowCount();
|
||||
QModelIndexList const availSels =
|
||||
availableLV->selectionModel()->selectedIndexes();
|
||||
addPB->setEnabled(arows > 0 &&
|
||||
@ -89,7 +93,7 @@ void GuiSelectionManager::updateAddPB()
|
||||
|
||||
void GuiSelectionManager::updateDelPB()
|
||||
{
|
||||
int const srows = selectedModel->stringList().size();
|
||||
int const srows = selectedModel->rowCount();
|
||||
if (srows == 0) {
|
||||
deletePB->setEnabled(false);
|
||||
return;
|
||||
@ -103,7 +107,7 @@ void GuiSelectionManager::updateDelPB()
|
||||
|
||||
void GuiSelectionManager::updateUpPB()
|
||||
{
|
||||
int const srows = selectedModel->stringList().size();
|
||||
int const srows = selectedModel->rowCount();
|
||||
if (srows == 0) {
|
||||
upPB->setEnabled(false);
|
||||
return;
|
||||
@ -117,7 +121,7 @@ void GuiSelectionManager::updateUpPB()
|
||||
|
||||
void GuiSelectionManager::updateDownPB()
|
||||
{
|
||||
int const srows = selectedModel->stringList().size();
|
||||
int const srows = selectedModel->rowCount();
|
||||
if (srows == 0) {
|
||||
downPB->setEnabled(false);
|
||||
return;
|
||||
@ -128,10 +132,17 @@ void GuiSelectionManager::updateDownPB()
|
||||
downPB->setEnabled(sel_nr >= 0 && sel_nr < srows - 1);
|
||||
}
|
||||
|
||||
|
||||
bool GuiSelectionManager::isSelected(const QModelIndex & idx)
|
||||
{
|
||||
QString const str = idx.data().toString();
|
||||
return selectedModel->stringList().contains(str);
|
||||
if (selectedModel->rowCount() == 0)
|
||||
return false;
|
||||
QVariant const & str = availableModel->data(idx, Qt::DisplayRole);
|
||||
QModelIndexList qmil =
|
||||
selectedModel->match(selectedModel->index(0),
|
||||
Qt::DisplayRole, str,
|
||||
Qt::MatchExactly | Qt::MatchWrap);
|
||||
return !qmil.empty();
|
||||
}
|
||||
|
||||
|
||||
@ -155,7 +166,8 @@ void GuiSelectionManager::selectedChanged(const QModelIndex & idx, const QModelI
|
||||
}
|
||||
|
||||
|
||||
static QModelIndex getSelectedIndex(QListView * lv)
|
||||
namespace {
|
||||
QModelIndex getSelectedIndex(QListView * lv)
|
||||
{
|
||||
QModelIndex retval = QModelIndex();
|
||||
QModelIndexList selIdx =
|
||||
@ -164,6 +176,18 @@ static QModelIndex getSelectedIndex(QListView * lv)
|
||||
retval = selIdx.first();
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool GuiSelectionManager::insertRowToSelected(int i,
|
||||
QMap<int, QVariant> const & itemData)
|
||||
{
|
||||
if (i <= -1 || i > selectedModel->rowCount())
|
||||
return false;
|
||||
if (!selectedModel->insertRow(i))
|
||||
return false;
|
||||
return selectedModel->setItemData(selectedModel->index(i), itemData);
|
||||
}
|
||||
|
||||
|
||||
void GuiSelectionManager::addPB_clicked()
|
||||
@ -171,15 +195,17 @@ void GuiSelectionManager::addPB_clicked()
|
||||
QModelIndex const idxToAdd = getSelectedIndex(availableLV);
|
||||
if (!idxToAdd.isValid())
|
||||
return;
|
||||
QModelIndex idx = selectedLV->currentIndex();
|
||||
QModelIndex const idx = selectedLV->currentIndex();
|
||||
int const srows = selectedModel->rowCount();
|
||||
|
||||
QMap<int, QVariant> qm = availableModel->itemData(idxToAdd);
|
||||
insertRowToSelected(srows, qm);
|
||||
|
||||
QStringList keys = selectedModel->stringList();
|
||||
keys.append(idxToAdd.data().toString());
|
||||
selectedModel->setStringList(keys);
|
||||
selectionChanged(); //signal
|
||||
|
||||
if (idx.isValid())
|
||||
selectedLV->setCurrentIndex(idx);
|
||||
|
||||
updateHook();
|
||||
}
|
||||
|
||||
@ -190,9 +216,7 @@ void GuiSelectionManager::deletePB_clicked()
|
||||
if (!idx.isValid())
|
||||
return;
|
||||
|
||||
QStringList keys = selectedModel->stringList();
|
||||
keys.removeAt(idx.row());
|
||||
selectedModel->setStringList(keys);
|
||||
selectedModel->removeRow(idx.row());
|
||||
selectionChanged(); //signal
|
||||
|
||||
int nrows = selectedLV->model()->rowCount();
|
||||
@ -211,13 +235,18 @@ void GuiSelectionManager::deletePB_clicked()
|
||||
void GuiSelectionManager::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
|
||||
if (pos <= 0)
|
||||
return;
|
||||
|
||||
QMap<int, QVariant> qm = selectedModel->itemData(idx);
|
||||
|
||||
selectedModel->removeRow(pos);
|
||||
insertRowToSelected(pos - 1, qm);
|
||||
|
||||
selectionChanged(); //signal
|
||||
|
||||
selectedLV->setCurrentIndex(idx.sibling(idx.row() - 1, idx.column()));
|
||||
selectedHasFocus_ = true;
|
||||
updateHook();
|
||||
@ -227,11 +256,16 @@ void GuiSelectionManager::upPB_clicked()
|
||||
void GuiSelectionManager::downPB_clicked()
|
||||
{
|
||||
QModelIndex idx = selectedLV->currentIndex();
|
||||
|
||||
|
||||
int const pos = idx.row();
|
||||
QStringList keys = selectedModel->stringList();
|
||||
keys.swap(pos, pos + 1);
|
||||
selectedModel->setStringList(keys);
|
||||
if (pos >= selectedModel->rowCount() - 1)
|
||||
return;
|
||||
|
||||
QMap<int, QVariant> qm = selectedModel->itemData(idx);
|
||||
|
||||
selectedModel->removeRow(pos);
|
||||
insertRowToSelected(pos + 1, qm);
|
||||
|
||||
selectionChanged(); //signal
|
||||
|
||||
selectedLV->setCurrentIndex(idx.sibling(idx.row() + 1, idx.column()));
|
||||
@ -311,9 +345,7 @@ bool GuiSelectionManager::eventFilter(QObject * obj, QEvent * event)
|
||||
if (keyModifiers == Qt::NoModifier && deletePB->isEnabled())
|
||||
deletePB_clicked();
|
||||
else if (keyModifiers == Qt::ControlModifier) {
|
||||
QStringList list = selectedModel->stringList();
|
||||
list.clear();
|
||||
selectedModel->setStringList(list);
|
||||
selectedModel->removeRows(0, selectedModel->rowCount());
|
||||
updateHook();
|
||||
} else
|
||||
//ignore it otherwise
|
||||
|
@ -17,10 +17,14 @@
|
||||
#include <QObject>
|
||||
#include <QKeyEvent>
|
||||
#include <QStringList>
|
||||
#include <QStringListModel>
|
||||
#include <QAbstractListModel>
|
||||
#include <QListView>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "support/qstring_helpers.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace lyx {
|
||||
namespace frontend {
|
||||
|
||||
@ -45,8 +49,8 @@ public:
|
||||
QPushButton * delPB,
|
||||
QPushButton * upPB,
|
||||
QPushButton * downPB,
|
||||
QStringListModel * availableModel,
|
||||
QStringListModel * selectedModel);
|
||||
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.)
|
||||
@ -82,6 +86,8 @@ protected:
|
||||
///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;
|
||||
@ -94,9 +100,9 @@ protected:
|
||||
///
|
||||
QPushButton * downPB;
|
||||
///
|
||||
QStringListModel * availableModel;
|
||||
QAbstractListModel * availableModel;
|
||||
///
|
||||
QStringListModel * selectedModel;
|
||||
QAbstractListModel * selectedModel;
|
||||
|
||||
protected Q_SLOTS:
|
||||
///
|
||||
@ -104,13 +110,13 @@ protected Q_SLOTS:
|
||||
///
|
||||
void selectedChanged(const QModelIndex & idx, const QModelIndex &);
|
||||
///
|
||||
void addPB_clicked();
|
||||
virtual void addPB_clicked();
|
||||
///
|
||||
void deletePB_clicked();
|
||||
virtual void deletePB_clicked();
|
||||
///
|
||||
void upPB_clicked();
|
||||
virtual void upPB_clicked();
|
||||
///
|
||||
void downPB_clicked();
|
||||
virtual void downPB_clicked();
|
||||
///
|
||||
void availableLV_clicked(const QModelIndex &);
|
||||
///
|
||||
@ -129,7 +135,7 @@ private:
|
||||
virtual void updateDownPB();
|
||||
///
|
||||
virtual void updateUpPB();
|
||||
|
||||
///
|
||||
bool selectedHasFocus_;
|
||||
};
|
||||
|
||||
|
@ -86,6 +86,7 @@ SOURCEFILES = \
|
||||
GuiFontMetrics.cpp \
|
||||
GuiGraphics.cpp \
|
||||
GuiHyperlink.cpp \
|
||||
GuiIdListModel.cpp \
|
||||
GuiImage.cpp \
|
||||
GuiInclude.cpp \
|
||||
GuiIndex.cpp \
|
||||
@ -175,6 +176,7 @@ MOCHEADER = \
|
||||
GuiFontExample.h \
|
||||
GuiGraphics.h \
|
||||
GuiHyperlink.h \
|
||||
GuiIdListModel.h \
|
||||
GuiInclude.h \
|
||||
GuiIndex.h \
|
||||
GuiKeySymbol.h \
|
||||
|
Loading…
Reference in New Issue
Block a user