void MList::selectItem(const QModelIndex &index) { QItemSelectionModel *sModel = selectionModel(); if (index.isValid() && sModel->model() != index.model()) { qWarning("MList::selectItem() failed: " "Trying to select an item that is for" " a different model than the view "); return; } if (sModel != NULL) { if (selectionMode() == MList::MultiSelection) { if (sModel->isSelected(index)) { sModel->select(index, QItemSelectionModel::Deselect); } else { sModel->select(index, QItemSelectionModel::Select); } } else if (selectionMode() == MList::SingleSelection) { sModel->select(index, QItemSelectionModel::ClearAndSelect); } } emit itemClicked(index); }
bool HistoryView::update() { int stRow = row(st->sha()); if (stRow == -1) return false; // main/tree view asked us a sha not in history QModelIndex index = currentIndex(); QItemSelectionModel* sel = selectionModel(); if (index.isValid() && (index.row() == stRow)) { if (sel->isSelected(index) != st->selectItem()) sel->select(index, QItemSelectionModel::Toggle); scrollTo(index); } else { // setCurrentIndex() does not clear previous // selections in a multi selection QListView clearSelection(); QModelIndex newIndex = model()->index(stRow, 0); if (newIndex.isValid()) { // emits QItemSelectionModel::currentChanged() setCurrentIndex(newIndex); scrollTo(newIndex); if (!st->selectItem()) sel->select(newIndex, QItemSelectionModel::Deselect); } } if (git->isMainHistory(fh)) emit diffTargetChanged(row(st->diffToSha())); return currentIndex().isValid(); }
// this slot handles auto-selection of items. void FolderView::onAutoSelectionTimeout() { if(QApplication::mouseButtons() != Qt::NoButton) return; Qt::KeyboardModifiers mods = QApplication::keyboardModifiers(); QPoint pos = view->viewport()->mapFromGlobal(QCursor::pos()); // convert to viewport coordinates QModelIndex index = view->indexAt(pos); // find out the hovered item QItemSelectionModel::SelectionFlags flags = (mode == DetailedListMode ? QItemSelectionModel::Rows : QItemSelectionModel::NoUpdate); QItemSelectionModel* selModel = view->selectionModel(); if(mods & Qt::ControlModifier) { // Ctrl key is pressed if(selModel->isSelected(index) && index != lastAutoSelectionIndex_) { // unselect a previously selected item selModel->select(index, flags|QItemSelectionModel::Deselect); lastAutoSelectionIndex_ = QModelIndex(); } else { // select an unselected item selModel->select(index, flags|QItemSelectionModel::Select); lastAutoSelectionIndex_ = index; } selModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate); // move the cursor } else if(mods & Qt::ShiftModifier) { // Shift key is pressed // select all items between current index and the hovered index. QModelIndex current = selModel->currentIndex(); if(selModel->hasSelection() && current.isValid()) { selModel->clear(); // clear old selection selModel->setCurrentIndex(current, QItemSelectionModel::NoUpdate); int begin = current.row(); int end = index.row(); if(begin > end) qSwap(begin, end); for(int row = begin; row <= end; ++row) { QModelIndex sel = model_->index(row, 0); selModel->select(sel, flags|QItemSelectionModel::Select); } } else { // no items are selected, select the hovered item. if(index.isValid()) { selModel->select(index, flags|QItemSelectionModel::SelectCurrent); selModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate); } } lastAutoSelectionIndex_ = index; } else if(mods == Qt::NoModifier) { // no modifier keys are pressed. if(index.isValid()) { // select the hovered item view->clearSelection(); selModel->select(index, flags|QItemSelectionModel::SelectCurrent); selModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate); } lastAutoSelectionIndex_ = index; } autoSelectionTimer_->deleteLater(); autoSelectionTimer_ = nullptr; }
void GeoTreeView::selectionChangedFromOutside( const QItemSelection &selected, const QItemSelection &deselected ) { QItemSelectionModel* selModel = this->selectionModel(); selModel->blockSignals(true); selModel->select(deselected, QItemSelectionModel::Deselect); selModel->select(selected, QItemSelectionModel::Select); selModel->blockSignals(false); QTreeView::selectionChanged(selected, deselected); }
void ccDBRoot::selectEntity(ccHObject* obj) { bool ctrlPushed = (QApplication::keyboardModifiers () & Qt::ControlModifier); QItemSelectionModel* selectionModel = m_dbTreeWidget->selectionModel(); assert(selectionModel); //valid object? then we will try to select (or toggle) it if (obj) { QModelIndex selectedIndex = index(obj); if (selectedIndex.isValid()) { //if CTRL is pushed if (ctrlPushed) { //default case: toggle current item selection state if (!obj->isSelected()) { QModelIndexList selectedIndexes = selectionModel->selectedIndexes(); if (!selectedIndexes.empty()) { //special case: labels can only be merged with labels! if (obj->isA(CC_2D_LABEL) != static_cast<ccHObject*>(selectedIndexes[0].internalPointer())->isA(CC_2D_LABEL)) { ccLog::Warning("[Selection] Labels and other entities can't be mixed! (release the CTRL key to start a new selection)"); return; } } } selectionModel->select(selectedIndex,QItemSelectionModel::Toggle); } else { if (selectionModel->isSelected(selectedIndex)) //nothing to do return; selectionModel->select(selectedIndex,QItemSelectionModel::ClearAndSelect); } //hack: auto-scroll to selected element if (obj->isSelected() && !ctrlPushed) m_dbTreeWidget->scrollTo(selectedIndex); } } //otherwise we clear current selection (if CTRL is not pushed) else if (!ctrlPushed) { selectionModel->clear(); } }
void NotesModel::matchSelToStreams() { QModelIndexList lSelStreams (m_pCommonData->m_pStreamsG->selectionModel()->selection().indexes()); const vector<DataStream*>& vCrtStreams (m_pCommonData->getViewHandlers()[m_pCommonData->getFilesGCrtRow()]->getStreams()); vector<const DataStream*> vSelStreams; for (QModelIndexList::iterator it = lSelStreams.begin(), end = lSelStreams.end(); it != end; ++it) { int nRow (it->row()); vSelStreams.push_back(vCrtStreams[nRow]); } QItemSelectionModel* pNotesSelModel (m_pCommonData->m_pNotesG->selectionModel()); pNotesSelModel->clearSelection(); bool bFirstFound (false); for (int i = 0, nNoteCnt = cSize(m_pCommonData->getCrtNotes()); i < nNoteCnt; ++i) { const Note* pNote (m_pCommonData->getCrtNotes()[i]); if (isInList(pNote, vSelStreams)) { if (!bFirstFound) { bFirstFound = true; m_pCommonData->m_pNotesG->setCurrentIndex(index(i, 0)); } pNotesSelModel->select(index(i, 0), QItemSelectionModel::Select | QItemSelectionModel::Rows); } } }
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); QStandardItemModel *model = new QStandardItemModel(7, 4, this); for (int row = 0; row < 7; ++row) { for (int column = 0; column < 4; ++column) { QStandardItem *item = new QStandardItem(QString("%1") .arg(row * 4 + column)); model->setItem(row, column, item); } } tableView = new QTableView; tableView->setModel(model); setCentralWidget(tableView); // 获取视图的项目选择模型 QItemSelectionModel *selectionModel = tableView->selectionModel(); // 定义左上角和右下角的索引,然后使用这两个索引创建选择 QModelIndex topLeft; QModelIndex bottomRight; topLeft = model->index(1, 1, QModelIndex()); bottomRight = model->index(5, 2, QModelIndex()); QItemSelection selection(topLeft, bottomRight); // 使用指定的选择模式来选择项目 selectionModel->select(selection, QItemSelectionModel::Select); }
void NotesModel::matchSelToMain() { QModelIndexList lSelFiles (m_pCommonData->m_pFilesG->selectionModel()->selection().indexes()); set<int> sSel; for (QModelIndexList::iterator it = lSelFiles.begin(), end = lSelFiles.end(); it != end; ++it) { int nCol (it->column()); if (nCol > 0) // skip file name { sSel.insert(nCol - 1); } } QItemSelectionModel* pNotesSelModel (m_pCommonData->m_pNotesG->selectionModel()); pNotesSelModel->clearSelection(); bool bFirstFound (false); for (int i = 0, nNoteCnt = cSize(m_pCommonData->getCrtNotes()); i < nNoteCnt; ++i) { const Note* pNote (m_pCommonData->getCrtNotes()[i]); int nPos (m_pCommonData->findPos(pNote)); if (sSel.count(nPos) > 0) { if (!bFirstFound) { bFirstFound = true; m_pCommonData->m_pNotesG->setCurrentIndex(index(i, 0)); } pNotesSelModel->select(index(i, 0), QItemSelectionModel::Select | QItemSelectionModel::Rows); } } }
// Check if any managed widgets are selected. If so, iterate over // selection and deselect all unmanaged objects bool ObjectInspector::ObjectInspectorPrivate::checkManagedWidgetSelection(const QModelIndexList &rowSelection) { bool isManagedWidgetSelection = false; QItemSelectionModel *selectionModel = m_treeView->selectionModel(); const QModelIndexList::const_iterator cscend = rowSelection.constEnd(); for (QModelIndexList::const_iterator it = rowSelection.constBegin(); it != cscend; ++it) { QObject *object = m_model->objectAt(*it); if (selectionType(m_formWindow, object) == ManagedWidgetSelection) { isManagedWidgetSelection = true; break; } } if (!isManagedWidgetSelection) return false; // Need to unselect unmanaged ones const bool blocked = selectionModel->blockSignals(true); for (QModelIndexList::const_iterator it = rowSelection.constBegin(); it != cscend; ++it) { QObject *object = m_model->objectAt(*it); if (selectionType(m_formWindow, object) != ManagedWidgetSelection) selectionModel->select(*it, QItemSelectionModel::Deselect|QItemSelectionModel::Rows); } selectionModel->blockSignals(blocked); return true; }
SpeedLimitsDlg::SpeedLimitsDlg(bt::TorrentInterface* current, Core* core, QWidget* parent) : QDialog(parent), core(core), current(current) { setupUi(this); setWindowIcon(QIcon::fromTheme("kt-speed-limits")); setWindowTitle(i18n("Speed Limits")); model = new SpeedLimitsModel(core, this); QSortFilterProxyModel* pm = new QSortFilterProxyModel(this); pm->setSourceModel(model); pm->setSortRole(Qt::UserRole); m_speed_limits_view->setModel(pm); m_speed_limits_view->setItemDelegate(new SpinBoxDelegate(this)); m_speed_limits_view->setUniformRowHeights(true); m_speed_limits_view->setSortingEnabled(true); m_speed_limits_view->sortByColumn(0, Qt::AscendingOrder); m_speed_limits_view->header()->setSortIndicatorShown(true); m_speed_limits_view->header()->setClickable(true); m_speed_limits_view->setAlternatingRowColors(true); QPushButton* apply_btn = m_buttonBox->button(QDialogButtonBox::Apply); apply_btn->setEnabled(false); connect(model, &SpeedLimitsModel::enableApply, apply_btn, &QPushButton::setEnabled); connect(apply_btn, &QPushButton::clicked, this, &SpeedLimitsDlg::apply); connect(m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); m_upload_rate->setValue(Settings::maxUploadRate()); m_download_rate->setValue(Settings::maxDownloadRate()); connect(m_upload_rate, SIGNAL(valueChanged(int)), this, SLOT(spinBoxValueChanged(int))); connect(m_download_rate, SIGNAL(valueChanged(int)), this, SLOT(spinBoxValueChanged(int))); connect(m_filter, SIGNAL(textChanged(QString)), pm, SLOT(setFilterFixedString(QString))); loadState(); // if current is specified, select it and scroll to it if (current) { kt::QueueManager* qman = core->getQueueManager(); int idx = 0; QList<bt::TorrentInterface*>::iterator itr = qman->begin(); while (itr != qman->end()) { if (*itr == current) break; idx++; itr++; } if (itr != qman->end()) { QItemSelectionModel* sel = m_speed_limits_view->selectionModel(); QModelIndex midx = pm->mapFromSource(model->index(idx, 0)); QModelIndex midx2 = pm->mapFromSource(model->index(idx, 4)); sel->select(QItemSelection(midx, midx2), QItemSelectionModel::Select); m_speed_limits_view->scrollTo(midx); } } }
void ProjectCreatePopup::showEvent(QShowEvent *) { int i; QString fldName; for (i = 0; i < m_folderFlds.size(); i++) { fldName = QString::fromStdString(m_folderFlds[i].first); m_folderFlds[i].second->setPath(fldName); } for (i = 0; i < m_useScenePathCbs.size(); i++) { CheckBox *cb = m_useScenePathCbs[i].second; bool signalesAlreadyBlocked = cb->blockSignals(true); cb->setChecked(false); cb->blockSignals(signalesAlreadyBlocked); } m_nameFld->setText(""); // Must refresh the tree. DvDirModelNode *rootNode = m_model->getNode(QModelIndex()); QModelIndex index = m_model->getIndexByNode(rootNode); m_model->refreshFolderChild(index); // Select the first Item in the treeView QItemSelectionModel *selection = new QItemSelectionModel(m_model); index = m_model->index(0, 0, QModelIndex()); selection->select(index, QItemSelectionModel::Select); m_treeView->setSelectionModel(selection); }
/* Select all messages from a set of threads (passed as a set of mail.thread_id). Return the number of selected messages. */ int mail_listview::select_threads(const QSet<uint>& threads) { if (threads.empty()) return 0; int cnt=0; QStandardItem* item = model()->first_top_level_item(); QItemSelectionModel* sel = this->selectionModel(); while (item) { QVariant v = item->data(mail_item_model::mail_msg_role); mail_msg* msg = v.value<mail_msg*>(); QModelIndex index = item->index(); if (threads.contains(msg->thread_id())) { DBG_PRINTF(4, "selecting index for mail_id=%d", msg->get_id()); sel->select(index, QItemSelectionModel::Select|QItemSelectionModel::Rows); cnt++; } // next item QModelIndex index_below = indexBelow(index); if (index_below.isValid()) { item = model()->itemFromIndex(index_below); } else item=NULL; } return cnt; }
/** * Synchronizes the selection with the given stamp. Ignored when the stamp is * changing because of a selection change in the TilesetDock. */ void TilesetDock::selectTilesInStamp(const TileStamp &stamp) { if (mEmittingStampCaptured) return; QSet<Tile*> processed; QMap<QItemSelectionModel*, QItemSelection> selections; for (const TileStampVariation &variation : stamp.variations()) { const TileLayer &tileLayer = *variation.tileLayer(); for (const Cell &cell : tileLayer) { if (Tile *tile = cell.tile) { if (processed.contains(tile)) continue; processed.insert(tile); // avoid spending time on duplicates Tileset *tileset = tile->tileset(); int tilesetIndex = mTilesets.indexOf(tileset->sharedPointer()); if (tilesetIndex != -1) { TilesetView *view = tilesetViewAt(tilesetIndex); if (!view->model()) // Lazily set up the model setupTilesetModel(view, tileset); const TilesetModel *model = view->tilesetModel(); const QModelIndex modelIndex = model->tileIndex(tile); QItemSelectionModel *selectionModel = view->selectionModel(); selections[selectionModel].select(modelIndex, modelIndex); } } } } if (!selections.isEmpty()) { mSynchronizingSelection = true; // Mark captured tiles as selected for (auto i = selections.constBegin(); i != selections.constEnd(); ++i) { QItemSelectionModel *selectionModel = i.key(); const QItemSelection &selection = i.value(); selectionModel->select(selection, QItemSelectionModel::SelectCurrent); } // Show/edit properties of all captured tiles mMapDocument->setSelectedTiles(processed.toList()); // Update the current tile (useful for animation and collision editors) auto first = selections.begin(); QItemSelectionModel *selectionModel = first.key(); const QItemSelection &selection = first.value(); const QModelIndex currentIndex = selection.first().topLeft(); if (selectionModel->currentIndex() != currentIndex) selectionModel->setCurrentIndex(currentIndex, QItemSelectionModel::NoUpdate); else currentChanged(currentIndex); mSynchronizingSelection = false; } }
void Pageview::selectPage (QModelIndex ind) { QItemSelectionModel *sel = selectionModel (); sel->select (QItemSelection (ind, ind), QItemSelectionModel::Clear | QItemSelectionModel::Select); scrollTo (ind); }
void VtkVisPipelineView::selectItem(const QModelIndex &index) { if (!index.isValid()) return; QItemSelectionModel* selectionModel = this->selectionModel(); selectionModel->clearSelection(); selectionModel->select(index, QItemSelectionModel::Select); }
void FilesModel::fixSelection() // deselects cells that are selected but are on a different row from the "current" cell and selects the file name { // it works OK when getFltHandlers() is empty QItemSelectionModel* pSelModel (m_pCommonData->m_pFilesG->selectionModel()); QModelIndexList lstSel (pSelModel->selection().indexes()); QModelIndex crt (m_pCommonData->m_pFilesG->selectionModel()->currentIndex()); int nCrtRow (crt.row()); int nCrtCol (crt.column()); if (0 == nCrtCol) { for (QModelIndexList::iterator it = lstSel.begin(), end = lstSel.end(); it != end; ++it) { if (0 != it->column()) { pSelModel->select(*it, QItemSelectionModel::Deselect); } } } else { set<int> sSelectableColumns; sSelectableColumns.insert(0); for (int i = 0, n = cSize(m_pCommonData->getCrtNotes()); i < n; ++i) // ttt2 poor performance { const Note* pNote (m_pCommonData->getCrtNotes()[i]); sSelectableColumns.insert(m_pCommonData->findPos(pNote) + 1); } for (QModelIndexList::iterator it = lstSel.begin(), end = lstSel.end(); it != end; ++it) { if ((it->row() != nCrtRow && 0 != it->column()) || 0 == sSelectableColumns.count(it->column())) { pSelModel->select(*it, QItemSelectionModel::Deselect); } } if (nCrtRow >= 0) { pSelModel->select(index(nCrtRow, 0), QItemSelectionModel::Select); } } }
void KitOptionsPageWidget::addNewKit() { Kit *k = m_model->markForAddition(0); QModelIndex newIdx = m_model->indexOf(k); m_selectionModel->select(newIdx, QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); }
void FolderView::invertSelection() { if(model_) { QItemSelectionModel* selModel = view->selectionModel(); int rows = model_->rowCount(); for(int row = 0; row < rows; ++row) { QModelIndex index = model_->index(row, 0); selModel->select(index, QItemSelectionModel::Toggle|QItemSelectionModel::Rows); } } }
void CategoryDialog::setParentCategory(int parent) { QItemSelectionModel *selection = ui->treeView->selectionModel(); QModelIndex index = model->indexById(parent); selection->select(model->index(index.row(),0,index.parent()),QItemSelectionModel::Select); while(index != model->index(0,0) && index != QModelIndex()) { ui->treeView->setExpanded(index,true); index = index.parent(); } }
void PropertiesDialog::deleteSelectedProperties() { QItemSelectionModel *selection = mUi->propertiesView->selectionModel(); const QModelIndexList indices = selection->selectedRows(); if (!indices.isEmpty()) { mModel->deleteProperties(indices); selection->select(mUi->propertiesView->currentIndex(), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); } }
void EventsWindow::cursorIndexUpdated() { const int row = m_modelEventsCursor->index(); QItemSelectionModel *selectionModel = m_resultsView->selectionModel(); const QModelIndexList selectedIndexes = selectionModel->selectedIndexes(); if (selectedIndexes.count() == 1 && selectedIndexes.at(0).row() == row) return; selectionModel->select(m_resultsView->model()->index(row, 0), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); }
void VtkVisPipelineView::selectItem( vtkProp3D* actor ) { QModelIndex index = ((VtkVisPipeline*)(this->model()))->getIndex(actor); if (!index.isValid()) return; blockSignals(true); QItemSelectionModel* selectionModel = this->selectionModel(); selectionModel->clearSelection(); selectionModel->select(index, QItemSelectionModel::Select); blockSignals(false); }
void ObjectTypesEditor::addObjectType() { const QModelIndex newIndex = mObjectTypesModel->addNewObjectType(); // Select and focus the new row and ensure it is visible QItemSelectionModel *sm = mUi->objectTypesTable->selectionModel(); sm->select(newIndex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); sm->setCurrentIndex(newIndex, QItemSelectionModel::Current); mUi->objectTypesTable->edit(newIndex); }
void NavigationDock::setActiveNode(NodeId id) { for(int i = 0; i < _model->rowCount(); ++i) { QVariant data = _model->data(_model->index(i)); if(data.canConvert<const Node*>()) { const Node* node = data.value<const Node*>(); if(node && node->getId() == id) { QItemSelectionModel* selectModel = _view->selectionModel(); selectModel->select(_model->index(i), QItemSelectionModel::ClearAndSelect); } } } }
void ccDBRoot::unselectEntity(ccHObject* obj) { if (obj && obj->isSelected()) { QModelIndex objIndex = index(obj); if (objIndex.isValid()) { QItemSelectionModel* selectionModel = m_dbTreeWidget->selectionModel(); assert(selectionModel); selectionModel->select(objIndex,QItemSelectionModel::Deselect); } } }
void CommandTreeView::handleRowsRemoved(const QModelIndex &parent, int, int) { if (parent.isValid()) return; // Reselect the same row index of the removed row QItemSelectionModel *sModel = selectionModel(); QModelIndex index = sModel->currentIndex(); sModel->select(index.sibling(index.row() + 1,index.column()), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); }
void FolderView::invertSelection() { if(model_) { QItemSelectionModel* selModel = view->selectionModel(); int rows = model_->rowCount(); QItemSelectionModel::SelectionFlags flags = QItemSelectionModel::Toggle; if(mode == DetailedListMode) flags |= QItemSelectionModel::Rows; for(int row = 0; row < rows; ++row) { QModelIndex index = model_->index(row, 0); selModel->select(index, flags); } } }
void GraphTableWidget::highlightElements(const std::set<unsigned int>& elementsToHighligh) { QItemSelectionModel *itemSelectionModel = new QItemSelectionModel(_tulipTableModel); for(int i = 0 ; i < _tulipTableModel->rowCount() ; ++i) { if(elementsToHighligh.find(_tulipTableModel->idForIndex(i))!=elementsToHighligh.end()) { itemSelectionModel->select(_tulipTableModel->index(i,0),QItemSelectionModel::Select| QItemSelectionModel::Rows); } } QItemSelectionModel *oldSelectionModel = selectionModel(); setSelectionModel(itemSelectionModel); oldSelectionModel->deleteLater(); }
void KitOptionsPageWidget::cloneKit() { Kit *current = currentKit(); if (!current) return; Kit *k = m_model->markForAddition(current); QModelIndex newIdx = m_model->indexOf(k); m_kitsView->scrollTo(newIdx); m_selectionModel->select(newIdx, QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); }
void FolderManager::runCommand(const QString &name) { qDebug() << "FolderManager::runCommand()" << name; FolderView *sourceView = currentFolderView(m_active_side); FolderView *targetView = currentFolderView((m_active_side == LeftSide) ? RightSide : LeftSide); if (! sourceView) { qDebug() << "no source view"; return; } if (name == "parent") { QDir dir(sourceView->fileSystemModel()->rootPath()); dir.cdUp(); sourceView->navigateToPath(dir.absolutePath()); } else if (name == "select-all") { sourceView->selectAll(); } else if (name == "select-none") { sourceView->clearSelection(); } else if (name == "invert-selection") { QItemSelectionModel *selectionModel = sourceView->selectionModel(); selectionModel->select(selectionModel->selection(), QItemSelectionModel::Toggle); #if 0 QAbstractItemModel *model = sourceView->model(); QModelIndex topLeft = model->index(0, 0); QModelIndex bottomRight = model->index(model->rowCount(parent)-1, model->columnCount(parent)-1); QItemSelection selection(topLeft, bottomRight); selectionModel->select(selection, QItemSelectionModel::Toggle); #endif } }