X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FGuiSelectionManager.cpp;h=825115cb3a368fff67470dc774a2269ff427bd25;hb=43c09d723435a5b203f2ac0c39e2086de836b386;hp=4d172bc35d890cb52de14e27d6ec9f50f9edcfaf;hpb=daba8bda2e60e9e3b4c616117c81c5ad5ada941d;p=lyx.git diff --git a/src/frontends/qt4/GuiSelectionManager.cpp b/src/frontends/qt4/GuiSelectionManager.cpp index 4d172bc35d..825115cb3a 100644 --- a/src/frontends/qt4/GuiSelectionManager.cpp +++ b/src/frontends/qt4/GuiSelectionManager.cpp @@ -18,10 +18,11 @@ #include "support/debug.h" -#include +#include +#include #include +#include #include -#include #ifdef KeyPress #undef KeyPress @@ -31,6 +32,10 @@ #undef ControlModifier #endif +#ifdef FocusIn +#undef FocusIn +#endif + namespace lyx { namespace frontend { @@ -44,25 +49,26 @@ GuiSelectionManager::GuiSelectionManager( QPushButton * down, QAbstractListModel * amod, QAbstractListModel * smod) + : availableLV(avail), selectedLV(sel), addPB(add), deletePB(del), + upPB(up), downPB(down), availableModel(amod), selectedModel(smod), + selectedHasFocus_(false) { - 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(QModelIndex,QModelIndex)), + SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(availableChanged(QModelIndex, QModelIndex))); connect(selectedLV->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(selectedChanged(QModelIndex, QModelIndex))); + connect(availableLV->selectionModel(), + SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(availableChanged(QItemSelection, QItemSelection))); + connect(selectedLV->selectionModel(), + SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(selectedChanged(QItemSelection, QItemSelection))); connect(addPB, SIGNAL(clicked()), this, SLOT(addPB_clicked())); connect(deletePB, SIGNAL(clicked()), @@ -71,12 +77,8 @@ GuiSelectionManager::GuiSelectionManager( this, SLOT(upPB_clicked())); connect(downPB, SIGNAL(clicked()), this, SLOT(downPB_clicked())); - connect(availableLV, SIGNAL(clicked(QModelIndex)), - this, SLOT(availableLV_clicked(QModelIndex))); connect(availableLV, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(availableLV_doubleClicked(QModelIndex))); - connect(selectedLV, SIGNAL(clicked(QModelIndex)), - this, SLOT(selectedLV_clicked(QModelIndex))); availableLV->installEventFilter(this); selectedLV->installEventFilter(this); @@ -92,6 +94,29 @@ void GuiSelectionManager::update() } +QModelIndex GuiSelectionManager::getSelectedIndex() const +{ + QModelIndexList avail = availableLV->selectionModel()->selectedIndexes(); + QModelIndexList sel = selectedLV->selectionModel()->selectedIndexes(); + bool const have_avl = !avail.isEmpty(); + bool const have_sel = !sel.isEmpty(); + + if (selectedFocused()) { + if (have_sel) + return sel.front(); + if (have_avl) + return avail.front(); + } + else { // available has focus + if (have_avl) + return avail.front(); + if (have_sel) + return sel.front(); + } + return QModelIndex(); +} + + void GuiSelectionManager::updateAddPB() { int const arows = availableModel->rowCount(); @@ -158,6 +183,15 @@ bool GuiSelectionManager::isSelected(const QModelIndex & idx) } +void GuiSelectionManager::availableChanged(QItemSelection const & qis, QItemSelection const &) +{ + QModelIndexList il = qis.indexes(); + if (il.empty()) + return; + availableChanged(il.front(), QModelIndex()); +} + + void GuiSelectionManager::availableChanged(const QModelIndex & idx, const QModelIndex &) { if (!idx.isValid()) @@ -168,6 +202,15 @@ void GuiSelectionManager::availableChanged(const QModelIndex & idx, const QModel } +void GuiSelectionManager::selectedChanged(QItemSelection const & qis, QItemSelection const &) +{ + QModelIndexList il = qis.indexes(); + if (il.empty()) + return; + selectedChanged(il.front(), QModelIndex()); +} + + void GuiSelectionManager::selectedChanged(const QModelIndex & idx, const QModelIndex &) { if (!idx.isValid()) @@ -181,8 +224,10 @@ void GuiSelectionManager::selectedChanged(const QModelIndex & idx, const QModelI bool GuiSelectionManager::insertRowToSelected(int i, QMap const & itemData) { - if (i <= -1 || i > selectedModel->rowCount()) - return false; + if (i <= -1) + i = 0; + if (i > selectedModel->rowCount()) + i = selectedModel->rowCount(); if (!selectedModel->insertRow(i)) return false; return selectedModel->setItemData(selectedModel->index(i), itemData); @@ -237,7 +282,11 @@ void GuiSelectionManager::deletePB_clicked() void GuiSelectionManager::upPB_clicked() { - QModelIndex idx = selectedLV->currentIndex(); + QModelIndexList selIdx = + selectedLV->selectionModel()->selectedIndexes(); + if (selIdx.isEmpty()) + return; + QModelIndex idx = selIdx.first(); int const pos = idx.row(); if (pos <= 0) @@ -258,7 +307,11 @@ void GuiSelectionManager::upPB_clicked() void GuiSelectionManager::downPB_clicked() { - QModelIndex idx = selectedLV->currentIndex(); + QModelIndexList selIdx = + selectedLV->selectionModel()->selectedIndexes(); + if (selIdx.isEmpty()) + return; + QModelIndex idx = selIdx.first(); int const pos = idx.row(); if (pos >= selectedModel->rowCount() - 1) @@ -277,18 +330,6 @@ void GuiSelectionManager::downPB_clicked() } -// 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) -// Or by installing an event listener.. (andre) -void GuiSelectionManager::availableLV_clicked(const QModelIndex &) -{ - selectedHasFocus_ = false; - updateHook(); -} - - void GuiSelectionManager::availableLV_doubleClicked(const QModelIndex & idx) { if (isSelected(idx) || !addPB->isEnabled()) @@ -301,74 +342,82 @@ void GuiSelectionManager::availableLV_doubleClicked(const QModelIndex & idx) } -void GuiSelectionManager::selectedLV_clicked(const QModelIndex &) -{ - selectedHasFocus_ = true; - updateHook(); -} - - bool GuiSelectionManager::eventFilter(QObject * obj, QEvent * event) { + QEvent::Type etype = event->type(); if (obj == availableLV) { - if (event->type() != QEvent::KeyPress) - return QObject::eventFilter(obj, event); - QKeyEvent * keyEvent = static_cast(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) { - if (!keyModifiers) - addPB_clicked(); - else if (keyModifiers == Qt::ControlModifier || - keyModifiers == Qt::KeypadModifier || - keyModifiers == (Qt::ControlModifier | Qt::KeypadModifier)) { - if (addPB->isEnabled()) { + if (etype == QEvent::KeyPress) { + QKeyEvent * keyEvent = static_cast(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) { + if (!keyModifiers) addPB_clicked(); - okHook(); //signal + else if (keyModifiers == Qt::ControlModifier || + keyModifiers == Qt::KeypadModifier || + keyModifiers == (Qt::ControlModifier | Qt::KeypadModifier)) { + if (addPB->isEnabled()) { + addPB_clicked(); + okHook(); //signal + } } + event->accept(); + return true; + } + } else if (etype == QEvent::FocusIn) { + if (selectedHasFocus_) { + selectedHasFocus_ = false; + updateHook(); } event->accept(); return true; - } - } else if (obj == selectedLV) { - if (event->type() != QEvent::KeyPress) - return QObject::eventFilter(obj, event); - QKeyEvent * keyEvent = static_cast(event); - int const keyPressed = keyEvent->key(); - Qt::KeyboardModifiers const keyModifiers = keyEvent->modifiers(); - // Delete or backspace key will delete current item - // ...with control modifier will clear the list - if (keyPressed == Qt::Key_Delete || keyPressed == Qt::Key_Backspace) { - if (keyModifiers == Qt::NoModifier && deletePB->isEnabled()) { - deletePB_clicked(); - updateHook(); - } else if (keyModifiers == Qt::ControlModifier) { - selectedModel->removeRows(0, selectedModel->rowCount()); - updateHook(); - } else - return QObject::eventFilter(obj, event); } - // Ctrl-Up activates upPB - else if (keyPressed == Qt::Key_Up) { - if (keyModifiers == Qt::ControlModifier) { - if (upPB->isEnabled()) - upPB_clicked(); - event->accept(); - return true; + } else if (obj == selectedLV) { + if (etype == QEvent::KeyPress) { + QKeyEvent * keyEvent = static_cast(event); + int const keyPressed = keyEvent->key(); + Qt::KeyboardModifiers const keyModifiers = keyEvent->modifiers(); + // Delete or backspace key will delete current item + // ...with control modifier will clear the list + if (keyPressed == Qt::Key_Delete || keyPressed == Qt::Key_Backspace) { + if (keyModifiers == Qt::NoModifier && deletePB->isEnabled()) { + deletePB_clicked(); + updateHook(); + } else if (keyModifiers == Qt::ControlModifier) { + selectedModel->removeRows(0, selectedModel->rowCount()); + updateHook(); + } else + return QObject::eventFilter(obj, event); + } + // Ctrl-Up activates upPB + else if (keyPressed == Qt::Key_Up) { + if (keyModifiers == Qt::ControlModifier) { + if (upPB->isEnabled()) + upPB_clicked(); + event->accept(); + return true; + } + } + // Ctrl-Down activates downPB + else if (keyPressed == Qt::Key_Down) { + if (keyModifiers == Qt::ControlModifier) { + if (downPB->isEnabled()) + downPB_clicked(); + event->accept(); + return true; + } } - } - // Ctrl-Down activates downPB - else if (keyPressed == Qt::Key_Down) { - if (keyModifiers == Qt::ControlModifier) { - if (downPB->isEnabled()) - downPB_clicked(); - event->accept(); - return true; + } else if (etype == QEvent::FocusIn) { + if (!selectedHasFocus_) { + selectedHasFocus_ = true; + updateHook(); } + event->accept(); + return true; } } return QObject::eventFilter(obj, event);