Пример #1
0
void CloudTableView::selectChanged(QModelIndexList lst)
{
    m_selectedtems.clear();
    foreach (QModelIndex idx, lst) {
        if (idx.column()!=0) lst.removeOne(idx);
    }

    foreach (QModelIndex idx, lst) {
        QString tmp =  cs->fullPath + myProxyModel->
                data(myProxyModel->index(idx.row(),0),Qt::DisplayRole).toString();
        if (!tmp.contains("/.."))
            m_selectedtems << cs->fullPath + CTModel->
                              data(ConvertIndexToRealModel(myProxyModel->index(idx.row(),0))
                                   ,Qt::DisplayRole).toString();
    }
Пример #2
0
QItemSelectionModel::SelectionFlags AMActionHistoryTreeView3::selectionCommand(const QModelIndex &index, const QEvent *selectionEvent) const{
	// Initialize by calling the parent version
	QItemSelectionModel::SelectionFlags retFlags = QTreeView::selectionCommand(index, selectionEvent);
	bool hasShiftModifier, hasControlModifier;

	// If we have a valid index we have a lot of work to do (also make sure this thing is actually an AMActionHistoryModel viewing tree)
	if(index.isValid()){
		AMActionHistoryModel3 *historyModel = qobject_cast<AMActionHistoryModel3*>(model());


		// We only care about the mouse button press events otherwise return the parent class call
		if( !historyModel || (selectionEvent->type() != QEvent::MouseButtonPress) )
			return QTreeView::selectionCommand(index, selectionEvent);
		QMouseEvent *mouseEvent = (QMouseEvent*)selectionEvent;

		// Ignore clicks on non-selectable indices
		// We can ignore: not enabled indexes, and not selectable indexes
		if(!index.flags().testFlag(Qt::ItemIsEnabled) || !index.flags().testFlag(Qt::ItemIsSelectable))
			return QTreeView::selectionCommand(index, selectionEvent);

		// Grab keyboard shift and control modifiers
		Qt::KeyboardModifiers currentModifiers = mouseEvent->modifiers();
		hasControlModifier = currentModifiers&Qt::ControlModifier;
		hasShiftModifier = currentModifiers&Qt::ShiftModifier;

		ParentSelectMap selectMap = model()->data(index, AMActionHistoryModel3::ParentSelectRole).value<ParentSelectMap>();
		// This is pretty bad, you can tell too much is in here that doesn't belong when I need to do a const cast
		AMActionHistoryTreeView3 *checkViewer = const_cast<AMActionHistoryTreeView3*>(this);
		bool parentIsSelected = false;
		// Figure out if the parent is selected via the mapping or the selection model
		if(index.parent().isValid()){
			ParentSelectMap parentsSelectMap = model()->data(index.parent(), AMActionHistoryModel3::ParentSelectRole).value<ParentSelectMap>();
			if(parentsSelectMap.contains(checkViewer))
				parentIsSelected |= parentsSelectMap.value(checkViewer);
			parentIsSelected |= selectionModel()->isSelected(index.parent());
		}

		// On control clicks where the parent is selected and this index is as well, do the group deselect and return noUpdate in the selection flags
		if(hasControlModifier && index.parent().isValid() && parentIsSelected && selectMap.contains(checkViewer) && selectMap.value(checkViewer)){
			historyModel->markIndexGroupAsDeselected(index, checkViewer);
			return QItemSelectionModel::NoUpdate;
		}
		// On control clicks where the parent is selected and this index is not, do the group select and return noUpdate in the selection flags
		else if(hasControlModifier && index.parent().isValid() && parentIsSelected && selectMap.contains(checkViewer) && !selectMap.value(checkViewer)){
			historyModel->markIndexGroupAsSelected(index, checkViewer);
			return QItemSelectionModel::NoUpdate;
		}

		// Ignore regular clicks on the an index that is already actually selected if it's the only one selected
		if( !hasControlModifier && (actuallySelectedByClickingCount_ == 1) && (selectionModel()->selectedIndexes().contains(index)) ){
			return QItemSelectionModel::NoUpdate;
		}
	}

	// Log some flags ... might be an easier way now that I know how to use QFlag::testFlag()
	bool clearFlag = (retFlags&QItemSelectionModel::Clear);
	bool selectFlag = (retFlags&QItemSelectionModel::Select);
	bool deselectFlag = (retFlags&QItemSelectionModel::Deselect);
	bool toggleFlag = (retFlags&QItemSelectionModel::Toggle);
	bool indexAlreadyOn = selectionModel()->selectedIndexes().contains(index);
	bool noUpdateFlag = (retFlags&QItemSelectionModel::NoUpdate);

	// An actual selection! Selected OR (Toggled AND NOT Currently On) OR (noUpdate AND Currently On)
	bool selectedTrue = selectFlag || (toggleFlag && !indexAlreadyOn) || (noUpdateFlag && indexAlreadyOn);
	// An actual deselection! Deselected OR (Toggled AND Currently On) OR (noUpdate AND NOT Currently On) OR (Actually selected an invalid index)
	bool selectedFalse = deselectFlag || (toggleFlag && indexAlreadyOn) || (noUpdateFlag && !indexAlreadyOn) || (selectedTrue && !index.isValid());

	// If we actually selected and the column is 0 (we only care about that one) log the state and emit actuallySelectedByClicking
	if(selectedTrue && (index.column() == 0) ){
		lastClickWasDeselect_ = false;
		lastClickedIndex_ = index;
		emit actuallySelectedByClicking(index, clearFlag);
	}
	// If we actually deselected and the column is 0 (we only care about that one) log the state (particularily lastClickWasDeselect) and emit actuallyDeselectedByClicking
	else if(selectedFalse && (index.column() == 0) ){
		QModelIndexList currentSelections = selectionModel()->selection().indexes();
		if(currentSelections.count() == 2){
			currentSelections.removeOne(index);
			lastClickedIndex_ = currentSelections.at(0);
			lastClickWasDeselect_ = false;
		}
		else
			lastClickWasDeselect_ = true;
		emit actuallyDeselectedByClicking(index, clearFlag);
	}
	// If neither selected nor deselected but clear flag is on then emit clearedByClicking
	else if(clearFlag){
		lastClickWasDeselect_ = false;
		emit clearedByClicking();
	}

	// Return the flags we have
	return retFlags;
}
Пример #3
0
void AMActionHistoryTreeView3::mousePressEvent(QMouseEvent *event){
	// Ignore mouse clicks if the cursor shows forbidden
	if(shiftKeyDown_ && hasOverriddenShiftCursor_){
		event->ignore();
	}
	// Actually handling valid shift-clicks
	else if(shiftKeyDown_){
		AMActionHistoryModel3 *historyModel = qobject_cast<AMActionHistoryModel3*>(model());
		QModelIndex index = indexAt(event->pos());

		// We can ignore: bad models, invalid indexes, not enabled indexes, and not selectable indexes
		if(!historyModel || !index.isValid() || !index.flags().testFlag(Qt::ItemIsEnabled) || !index.flags().testFlag(Qt::ItemIsSelectable))
			event->ignore();

		// Grab current selection from model and the indices between the shift click
		QItemSelection currentSelection = selectionModel()->selection();
		QItemSelection newSelection = historyModel->indicesBetween(index, lastClickedIndex_);

		// Call the selectionCommand function and merge the current and new selections
		QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
		currentSelection.merge(newSelection, command);

		// Clear the selection and select the combined list
		selectionModel()->clearSelection();
		selectionModel()->select(currentSelection, command);

		// Grab the list indices between the shift click so we can apply the right parentSelected states to them
		QModelIndexList interiorIndices = newSelection.indexes();
		// We only care about lists that have interior elements, the indicesBetween call returns the ends as well
		if(interiorIndices.count() >= 2){
			// Grab the clear flag for the signal emitted below
			bool clearFlag = command.testFlag(QItemSelectionModel::Clear);

			// Not sure if the indices are ordered correctly, so figure out the min and max to remove them (they should be the ends we don't care about)
			QModelIndex minRowIndex = interiorIndices.at(0);
			int minRowValue = minRowIndex.row();
			QModelIndex maxRowIndex = interiorIndices.at(1);
			int maxRowValue = maxRowIndex.row();
			for(int x = 0; x < interiorIndices.count(); x++){
				if(interiorIndices.at(x).row() < minRowValue){
					minRowIndex = interiorIndices.at(x);
					minRowValue = minRowIndex.row();
				}
				if(interiorIndices.at(x).row() > maxRowValue){
					maxRowIndex = interiorIndices.at(x);
					maxRowValue = maxRowIndex.row();
				}
			}

			// Remove both ends
			interiorIndices.removeOne(maxRowIndex);
			interiorIndices.removeOne(minRowIndex);

			// For all interior indices emulate a click by emitting the actuallySelectedByClicking signal ... then the regular chain of events can happen to parentSelect the children
			for(int x = 0; x < interiorIndices.count(); x++)
				emit actuallySelectedByClicking(interiorIndices.at(x), clearFlag);
		}

		// Accept the event
		event->accept();
	}
	// Ignore mouse clicks if the cursor shows forbidden
	else if(controlKeyDown_ && hasOverriddenControlCursor_){
		event->ignore();
	}
	// Falls through, call the parent class
	else
		QTreeView::mousePressEvent(event);
}