diff options
Diffstat (limited to 'Swift/QtUI/Roster')
| -rw-r--r-- | Swift/QtUI/Roster/QtFilterWidget.cpp | 55 | ||||
| -rw-r--r-- | Swift/QtUI/Roster/QtFilterWidget.h | 6 | ||||
| -rw-r--r-- | Swift/QtUI/Roster/QtTreeWidget.cpp | 29 | ||||
| -rw-r--r-- | Swift/QtUI/Roster/QtTreeWidget.h | 2 | 
4 files changed, 59 insertions, 33 deletions
diff --git a/Swift/QtUI/Roster/QtFilterWidget.cpp b/Swift/QtUI/Roster/QtFilterWidget.cpp index 5bd4669..2f08981 100644 --- a/Swift/QtUI/Roster/QtFilterWidget.cpp +++ b/Swift/QtUI/Roster/QtFilterWidget.cpp @@ -1,132 +1,139 @@  /*   * Copyright (c) 2013 Tobias Markmann   * Licensed under the simplified BSD license.   * See Documentation/Licenses/BSD-simplified.txt for more information.   */ -#include <Swift/QtUI/Roster/QtFilterWidget.h> -  #include <QLayout>  #include <QVBoxLayout>  #include <QKeyEvent>  #include <QEvent>  #include <QString>  #include <QEvent> - +#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h> +#include <Swift/Controllers/UIEvents/UIEventStream.h>  #include <Swift/QtUI/QtSwiftUtil.h> +#include <Swift/QtUI/Roster/QtFilterWidget.h>  namespace Swift { -QtFilterWidget::QtFilterWidget(QWidget* parent, QtTreeWidget* treeView, QBoxLayout* layout) : QWidget(parent), treeView_(treeView), fuzzyRosterFilter_(0), isModifierSinglePressed_(false) { +QtFilterWidget::QtFilterWidget(QWidget* parent, QtTreeWidget* treeView, UIEventStream* eventStream, QBoxLayout* layout) : QWidget(parent), treeView_(treeView), eventStream_(eventStream), fuzzyRosterFilter_(0), isModifierSinglePressed_(false) {  	int targetIndex = layout->indexOf(treeView);  	QVBoxLayout* vboxLayout = new QVBoxLayout(this);  	vboxLayout->setSpacing(0);  	vboxLayout->setContentsMargins(0,0,0,0);  	filterLineEdit_ = new QLineEdit(this);  	filterLineEdit_->hide();  	vboxLayout->addWidget(filterLineEdit_);  	vboxLayout->addWidget(treeView);  	setLayout(vboxLayout);  	layout->insertWidget(targetIndex, this);  	filterLineEdit_->installEventFilter(this);  	treeView->installEventFilter(this);  	sourceModel_ = treeView_->model();  }  QtFilterWidget::~QtFilterWidget() {  }  bool QtFilterWidget::eventFilter(QObject*, QEvent* event) {  	if (event->type() == QEvent::KeyPress ||  		event->type() == QEvent::KeyRelease ||  		// InputMethodQuery got introduced in Qt 5.  #if QT_VERSION >= 0x050000  		event->type() == QEvent::InputMethodQuery ||  #endif  		event->type() == QEvent::InputMethod) {  		event->ignore();  		QKeyEvent* keyEvent = dynamic_cast<QKeyEvent*>(event);  		if (keyEvent) {  			if (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down) {  				return false;  			} else if ((keyEvent->key() == Qt::Key_Left || keyEvent->key() == Qt::Key_Right) && filterLineEdit_->text().isEmpty()) {  				return false;  			} else if (keyEvent->key() == Qt::Key_Alt && event->type() == QEvent::KeyPress) {  				isModifierSinglePressed_ = true;  			} else if (keyEvent->key() == Qt::Key_Alt && event->type() == QEvent::KeyRelease && isModifierSinglePressed_) {  				QPoint itemOffset(2,2);  				QPoint contextMenuPosition = treeView_->visualRect(treeView_->currentIndex()).topLeft() + itemOffset;;  				QApplication::postEvent(treeView_, new QContextMenuEvent(QContextMenuEvent::Keyboard, contextMenuPosition, treeView_->mapToGlobal(contextMenuPosition)));  				return true;  			} else if (keyEvent->key() == Qt::Key_Return) { +				JID target = treeView_->selectedJID(); +				if (target.isValid()) { +					eventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(target))); +				}  				filterLineEdit_->setText(""); -				return false; +				updateRosterFilters();  			} else if (keyEvent->key() == Qt::Key_Escape) {  				filterLineEdit_->setText("");  			} else {  				isModifierSinglePressed_ = false;  			}  		}  		filterLineEdit_->event(event);  		filterLineEdit_->setVisible(!filterLineEdit_->text().isEmpty()); -		// update roster filters  		if (event->type() == QEvent::KeyRelease) { -			if (fuzzyRosterFilter_) { -				if (filterLineEdit_->text().isEmpty()) { -					// remove currently installed search filter and put old filters back -					treeView_->getRoster()->removeFilter(fuzzyRosterFilter_); -					delete fuzzyRosterFilter_; -					fuzzyRosterFilter_ = NULL; -					pushAllFilters(); -				} else { -					// remove currently intsalled search filter and put new search filter in place -					updateSearchFilter(); -				} -			} else { -				if (!filterLineEdit_->text().isEmpty()) { -					// remove currently installed filters and put a search filter in place -					popAllFilters(); -					updateSearchFilter(); -				} -			} +			updateRosterFilters();  		}  		return true;  	}  	return false;  }  void QtFilterWidget::popAllFilters() {  	std::vector<RosterFilter*> filters = treeView_->getRoster()->getFilters();  	foreach(RosterFilter* filter, filters) {  		filters_.push_back(filter);  		treeView_->getRoster()->removeFilter(filter);  	}  }  void QtFilterWidget::pushAllFilters() {  	foreach(RosterFilter* filter, filters_) {  		treeView_->getRoster()->addFilter(filter);  	}  	filters_.clear();  } +void QtFilterWidget::updateRosterFilters() { +	if (fuzzyRosterFilter_) { +		if (filterLineEdit_->text().isEmpty()) { +			// remove currently installed search filter and put old filters back +			treeView_->getRoster()->removeFilter(fuzzyRosterFilter_); +			delete fuzzyRosterFilter_; +			fuzzyRosterFilter_ = NULL; +			pushAllFilters(); +		} else { +			// remove currently intsalled search filter and put new search filter in place +			updateSearchFilter(); +		} +	} else { +		if (!filterLineEdit_->text().isEmpty()) { +			// remove currently installed filters and put a search filter in place +			popAllFilters(); +			updateSearchFilter(); +		} +	} +} +  void QtFilterWidget::updateSearchFilter() {  	if (fuzzyRosterFilter_) {  		treeView_->getRoster()->removeFilter(fuzzyRosterFilter_);  		delete fuzzyRosterFilter_;  		fuzzyRosterFilter_ = NULL;  	}  	fuzzyRosterFilter_ = new FuzzyRosterFilter(Q2PSTRING(filterLineEdit_->text()));  	treeView_->getRoster()->addFilter(fuzzyRosterFilter_);  	treeView_->setCurrentIndex(sourceModel_->index(0, 0, sourceModel_->index(0,0)));  }  } diff --git a/Swift/QtUI/Roster/QtFilterWidget.h b/Swift/QtUI/Roster/QtFilterWidget.h index e33616b..94ebc2a 100644 --- a/Swift/QtUI/Roster/QtFilterWidget.h +++ b/Swift/QtUI/Roster/QtFilterWidget.h @@ -1,46 +1,50 @@  /*   * Copyright (c) 2013 Tobias Markmann   * Licensed under the simplified BSD license.   * See Documentation/Licenses/BSD-simplified.txt for more information.   */  #pragma once  #include <vector>  #include <QBoxLayout>  #include <QLineEdit>  #include <QWidget>  #include <Swift/Controllers/Roster/RosterFilter.h>  #include <Swift/Controllers/Roster/FuzzyRosterFilter.h>  #include <Swift/QtUI/Roster/QtTreeWidget.h>  namespace Swift { +class UIEventStream; +  class QtFilterWidget : public QWidget {  	Q_OBJECT  	public: -		QtFilterWidget(QWidget* parent, QtTreeWidget* treeView, QBoxLayout* layout = 0); +		QtFilterWidget(QWidget* parent, QtTreeWidget* treeView, UIEventStream* eventStream, QBoxLayout* layout = 0);  		virtual ~QtFilterWidget();  	protected:  		bool eventFilter(QObject*, QEvent* event);  	private:  		void popAllFilters();  		void pushAllFilters(); +		void updateRosterFilters();  		void updateSearchFilter();  	private:  		QLineEdit* filterLineEdit_;  		QtTreeWidget* treeView_; +		UIEventStream* eventStream_;  		std::vector<RosterFilter*> filters_;  		QAbstractItemModel* sourceModel_;  		FuzzyRosterFilter* fuzzyRosterFilter_;  		bool isModifierSinglePressed_;  };  } diff --git a/Swift/QtUI/Roster/QtTreeWidget.cpp b/Swift/QtUI/Roster/QtTreeWidget.cpp index fbe85de..5333260 100644 --- a/Swift/QtUI/Roster/QtTreeWidget.cpp +++ b/Swift/QtUI/Roster/QtTreeWidget.cpp @@ -106,78 +106,71 @@ void QtTreeWidget::handleClicked(const QModelIndex& index) {  QModelIndexList QtTreeWidget::getSelectedIndexes() const {  	// Not using selectedIndexes(), because this seems to cause a crash in Qt (4.7.0) in the  	// QModelIndexList destructor.  	// This is a workaround posted in http://www.qtcentre.org/threads/16933 (although this case  	// was resolved by linking against the debug libs, ours isn't, and we're not alone)  	QItemSelection ranges = selectionModel()->selection();  	QModelIndexList selectedIndexList;  	for (int i = 0; i < ranges.count(); ++i) {  		QModelIndex parent = ranges.at(i).parent();  		int right = ranges.at(i).model()->columnCount(parent) - 1;  		if (ranges.at(i).left() == 0 && ranges.at(i).right() == right) {  			for (int r = ranges.at(i).top(); r <= ranges.at(i).bottom(); ++r) {  				selectedIndexList.append(ranges.at(i).model()->index(r, 0, parent));  			}  		}  	}  	return selectedIndexList;  }  void QtTreeWidget::currentChanged(const QModelIndex& current, const QModelIndex& previous) {  	RosterItem* item = NULL;  	QModelIndexList selectedIndexList = getSelectedIndexes();  	if (selectedIndexList.empty() || !selectedIndexList[0].isValid()) {  		/* I didn't quite understand why using current didn't seem to work here.*/  	}  	else if (current.isValid()) {  		item = static_cast<RosterItem*>(current.internalPointer());  		item = dynamic_cast<ContactRosterItem*>(item);  	}  	onSomethingSelectedChanged(item);  	QTreeView::currentChanged(current, previous);  }  void QtTreeWidget::handleItemActivated(const QModelIndex& index) { -	JID target; -	if (messageTarget_ == MessageDisplayJID) { -		target = JID(Q2PSTRING(index.data(DisplayJIDRole).toString())); -		target = target.toBare(); -	} -	if (!target.isValid()) { -		target = JID(Q2PSTRING(index.data(JIDRole).toString())); -	} +	JID target = jidFromIndex(index);  	if (target.isValid()) {  		eventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(target)));  	}  }  void QtTreeWidget::dragEnterEvent(QDragEnterEvent *event) {  	if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) {  		event->acceptProposedAction();  	}  }  void QtTreeWidget::dropEvent(QDropEvent *event) {  	QModelIndex index = indexAt(event->pos());  	if (index.isValid()) {  		RosterItem* item = static_cast<RosterItem*>(index.internalPointer());  		if (ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item)) {  			if (contact->supportsFeature(ContactRosterItem::FileTransferFeature)) {  				QString filename = event->mimeData()->urls().at(0).toLocalFile();  				if (!filename.isEmpty()) {  					eventStream_->send(boost::make_shared<SendFileUIEvent>(contact->getJID(), Q2PSTRING(filename)));  				}  			}  		}  	}  }  void QtTreeWidget::dragMoveEvent(QDragMoveEvent* event) {  	QModelIndex index = indexAt(event->pos());  	if (index.isValid()) {  		RosterItem* item = static_cast<RosterItem*>(index.internalPointer());  		if (ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item)) {  			if (contact->supportsFeature(ContactRosterItem::FileTransferFeature)) {  				event->accept();  				return;  			} @@ -207,36 +200,56 @@ void QtTreeWidget::handleExpanded(const QModelIndex& index) {  	GroupRosterItem* item = dynamic_cast<GroupRosterItem*>(static_cast<RosterItem*>(index.internalPointer()));  	if (item) {  		item->setExpanded(true);  	}  }  void QtTreeWidget::handleCollapsed(const QModelIndex& index) {  	GroupRosterItem* item = dynamic_cast<GroupRosterItem*>(static_cast<RosterItem*>(index.internalPointer()));  	if (item) {  		item->setExpanded(false);  	}  }  void QtTreeWidget::handleModelItemExpanded(const QModelIndex& index, bool shouldExpand) {  	if (!index.isValid()) {  		return;  	}  	bool alreadyRight = this->isExpanded(index) == shouldExpand;  	if (alreadyRight) {  		return;  	}  	setExpanded(index, shouldExpand);  }  void QtTreeWidget::drawBranches(QPainter*, const QRect&, const QModelIndex&) const {  }  void QtTreeWidget::show() {  	QWidget::show();  }  void QtTreeWidget::setMessageTarget(MessageTarget messageTarget) {  	messageTarget_ = messageTarget;  } +JID QtTreeWidget::jidFromIndex(const QModelIndex& index) const { +	JID target; +	if (messageTarget_ == MessageDisplayJID) { +		target = JID(Q2PSTRING(index.data(DisplayJIDRole).toString())); +		target = target.toBare(); +	} +	if (!target.isValid()) { +		target = JID(Q2PSTRING(index.data(JIDRole).toString())); +	} +	return target; +} + +JID QtTreeWidget::selectedJID() const { +	QModelIndexList list = selectedIndexes(); +	if (list.size() != 1) { +		return JID(); +	} +	return jidFromIndex(list[0]); +} +  } diff --git a/Swift/QtUI/Roster/QtTreeWidget.h b/Swift/QtUI/Roster/QtTreeWidget.h index 29e985d..cf2f73e 100644 --- a/Swift/QtUI/Roster/QtTreeWidget.h +++ b/Swift/QtUI/Roster/QtTreeWidget.h @@ -2,70 +2,72 @@   * Copyright (c) 2010-2014 Kevin Smith   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */  #pragma once  #include <QDragEnterEvent>  #include <QDropEvent>  #include <QDragMoveEvent>  #include <QModelIndex>  #include <QTreeView>  #include <Swift/QtUI/Roster/RosterDelegate.h>  #include <Swift/QtUI/Roster/RosterModel.h>  #include <Swift/Controllers/UIInterfaces/ChatWindow.h>  namespace Swift {  class UIEventStream;  class SettingsProvider;  class QtTreeWidget : public QTreeView {  	Q_OBJECT  	public:  		enum MessageTarget {MessageDefaultJID, MessageDisplayJID};  		QtTreeWidget(UIEventStream* eventStream, SettingsProvider* settings, MessageTarget messageTarget, QWidget* parent = 0);  		~QtTreeWidget();  		void show();  		QtTreeWidgetItem* getRoot();  		void setRosterModel(Roster* roster);  		Roster* getRoster() {return roster_;}  		void refreshTooltip();  		void setMessageTarget(MessageTarget messageTarget); +		JID jidFromIndex(const QModelIndex& index) const; +		JID selectedJID() const;  	public:  		boost::signal<void (RosterItem*)> onSomethingSelectedChanged;  	private slots:  		void handleItemActivated(const QModelIndex&);  		void handleModelItemExpanded(const QModelIndex&, bool expanded);  		void handleExpanded(const QModelIndex&);  		void handleCollapsed(const QModelIndex&);  		void handleClicked(const QModelIndex&);  		void handleSettingChanged(const std::string& setting);  		void handleRefreshTooltip();  	protected:  		void dragEnterEvent(QDragEnterEvent* event);  		void dropEvent(QDropEvent* event);  		void dragMoveEvent(QDragMoveEvent* event);  		bool event(QEvent* event);  		QModelIndexList getSelectedIndexes() const;  	private:  		void drawBranches(QPainter*, const QRect&, const QModelIndex&) const;  	protected slots:  		virtual void currentChanged(const QModelIndex& current, const QModelIndex& previous);  	protected:  		UIEventStream* eventStream_;  	private:  		RosterModel* model_;  		Roster* roster_;  		RosterDelegate* delegate_;  		QtTreeWidgetItem* treeRoot_;  		SettingsProvider* settings_;  		bool tooltipShown_;  		MessageTarget messageTarget_;  | 
 Swift