diff --git a/src/widgets/channellist/channellistview.cpp b/src/widgets/channellist/channellistview.cpp index 854a7db1..0d01764c 100644 --- a/src/widgets/channellist/channellistview.cpp +++ b/src/widgets/channellist/channellistview.cpp @@ -1,128 +1,145 @@ /* Copyright (c) 2020 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "channellistview.h" #include "ruqola.h" #include "ruqolawidgets_debug.h" #include "rocketchataccount.h" #include "channellistdelegate.h" #include "model/roomfilterproxymodel.h" #include #include #include #include #include ChannelListView::ChannelListView(QWidget *parent) : QListView(parent) { auto *delegate = new ChannelListDelegate(this); setItemDelegate(delegate); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); connect(this, &ChannelListView::clicked, this, &ChannelListView::slotClicked); } ChannelListView::~ChannelListView() { } RoomFilterProxyModel *ChannelListView::model() const { return qobject_cast(QListView::model()); } void ChannelListView::setModel(QAbstractItemModel *model) { if (!qobject_cast(model)) { qCWarning(RUQOLAWIDGETS_LOG) << "Need to pass a RoomFilterProxyModel instance!"; return; } QListView::setModel(model); } void ChannelListView::slotClicked(const QModelIndex &index) { if (index.isValid()) { Q_EMIT channelSelected(index); } } void ChannelListView::contextMenuEvent(QContextMenuEvent *event) { const QModelIndex index = indexAt(event->pos()); if (!index.isValid()) { return; } QMenu menu(this); const QString roomType = index.data(RoomModel::RoomType).toString(); QAction *hideChannel = new QAction(QIcon::fromTheme(QStringLiteral("hide_table_row")), i18n("Hide Channel"), &menu); connect(hideChannel, &QAction::triggered, this, [=]() { slotHideChannel(index, roomType); }); menu.addAction(hideChannel); const bool isFavorite = index.data(RoomModel::RoomFavorite).toBool(); const QString actionFavoriteText = isFavorite ? i18n("Unset as Favorite") : i18n("Set as Favorite"); QAction *favoriteAction = new QAction(QIcon::fromTheme(QStringLiteral("favorite")), actionFavoriteText, &menu); connect(favoriteAction, &QAction::triggered, this, [=]() { slotChangeFavorite(index, isFavorite); }); menu.addAction(favoriteAction); if (roomType == QLatin1String("c") || roomType == QLatin1String("p")) { //Not direct channel auto *separator = new QAction(&menu); separator->setSeparator(true); menu.addAction(separator); QAction *quitChannel = new QAction(QIcon::fromTheme(QStringLiteral("dialog-close")), i18n("Quit Channel"), &menu); connect(quitChannel, &QAction::triggered, this, [=]() { slotLeaveChannel(index, roomType); }); menu.addAction(quitChannel); } if (!menu.actions().isEmpty()) { menu.exec(event->globalPos()); } } void ChannelListView::slotHideChannel(const QModelIndex &index, const QString &roomType) { auto *rcAccount = Ruqola::self()->rocketChatAccount(); const QString roomId = index.data(RoomModel::RoomID).toString(); rcAccount->hideRoom(roomId, roomType); } void ChannelListView::slotLeaveChannel(const QModelIndex &index, const QString &roomType) { auto *rcAccount = Ruqola::self()->rocketChatAccount(); const QString roomId = index.data(RoomModel::RoomID).toString(); rcAccount->leaveRoom(roomId, roomType); } void ChannelListView::slotChangeFavorite(const QModelIndex &index, bool isFavorite) { auto *rcAccount = Ruqola::self()->rocketChatAccount(); const QString roomId = index.data(RoomModel::RoomID).toString(); rcAccount->changeFavorite(roomId, !isFavorite); } + +void ChannelListView::selectChannelRequested(const QString &channelId) +{ + if (channelId.isEmpty()) { + return; + } + RoomFilterProxyModel *filterModel = model(); + for (int roomIdx = 0, nRooms = filterModel->rowCount(); roomIdx < nRooms; ++roomIdx) { + const auto roomModelIndex = filterModel->index(roomIdx, 0); + const auto roomId = roomModelIndex.data(RoomModel::RoomID).toString(); + if (roomId == channelId) { + Q_EMIT channelSelected(roomModelIndex); + selectionModel()->setCurrentIndex(filterModel->index(roomIdx, 0), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); + break; + } + } +} diff --git a/src/widgets/channellist/channellistview.h b/src/widgets/channellist/channellistview.h index 521829a0..285f8b82 100644 --- a/src/widgets/channellist/channellistview.h +++ b/src/widgets/channellist/channellistview.h @@ -1,53 +1,54 @@ /* Copyright (c) 2020 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef CHANNELLISTVIEW_H #define CHANNELLISTVIEW_H #include #include "libruqolawidgets_private_export.h" class RoomFilterProxyModel; class LIBRUQOLAWIDGETS_TESTS_EXPORT ChannelListView : public QListView { Q_OBJECT public: explicit ChannelListView(QWidget *parent = nullptr); ~ChannelListView(); RoomFilterProxyModel *model() const; void setModel(QAbstractItemModel *model) override; + void selectChannelRequested(const QString &channelId); Q_SIGNALS: void channelSelected(const QModelIndex &index); protected: void contextMenuEvent(QContextMenuEvent *event) override; private: void slotClicked(const QModelIndex &index); void slotHideChannel(const QModelIndex &index, const QString &roomType); void slotLeaveChannel(const QModelIndex &index, const QString &roomType); void slotChangeFavorite(const QModelIndex &index, bool isFavorite); }; #endif // CHANNELLISTVIEW_H diff --git a/src/widgets/channellist/channellistwidget.h b/src/widgets/channellist/channellistwidget.h index 86871b49..e98971c1 100644 --- a/src/widgets/channellist/channellistwidget.h +++ b/src/widgets/channellist/channellistwidget.h @@ -1,60 +1,61 @@ /* Copyright (c) 2020 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef CHANNELLISTWIDGET_H #define CHANNELLISTWIDGET_H #include #include "libruqolawidgets_private_export.h" #include "user.h" class StatusCombobox; class ChannelListView; class QLineEdit; class RocketChatAccount; class LIBRUQOLAWIDGETS_TESTS_EXPORT ChannelListWidget : public QWidget { Q_OBJECT public: explicit ChannelListWidget(QWidget *parent = nullptr); ~ChannelListWidget(); ChannelListView *channelListView() const; void setCurrentRocketChatAccount(RocketChatAccount *account); Q_REQUIRED_RESULT QString currentSelectedRoom() const; + Q_SIGNALS: void channelSelected(const QModelIndex &index); protected: bool eventFilter(QObject *object, QEvent *event) override; private: void setUserStatusUpdated(User::PresenceStatus status); void slotStatusChanged(); void slotSearchRoomTextChanged(); void clearFilterChannel(); StatusCombobox *mStatusComboBox = nullptr; ChannelListView *mChannelView = nullptr; QLineEdit *mSearchRoom = nullptr; RocketChatAccount *mCurrentRocketChatAccount = nullptr; }; #endif // CHANNELLISTWIDGET_H diff --git a/src/widgets/ruqolamainwidget.cpp b/src/widgets/ruqolamainwidget.cpp index 31f841a0..6a9a5bd0 100644 --- a/src/widgets/ruqolamainwidget.cpp +++ b/src/widgets/ruqolamainwidget.cpp @@ -1,131 +1,117 @@ /* Copyright (c) 2020 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "ruqolamainwidget.h" #include "channellist/channellistwidget.h" #include "room/roomwidget.h" #include "channellist/channellistview.h" #include #include #include #include #include #include namespace { static const char myConfigGroupName[] = "RuqolaMainWidget"; } RuqolaMainWidget::RuqolaMainWidget(QWidget *parent) : QWidget(parent) { auto *mainLayout = new QHBoxLayout(this); mainLayout->setObjectName(QStringLiteral("mainlayout")); mSplitter = new QSplitter(this); mSplitter->setObjectName(QStringLiteral("mSplitter")); mSplitter->setChildrenCollapsible(false); mainLayout->addWidget(mSplitter); mChannelList = new ChannelListWidget(this); mChannelList->setObjectName(QStringLiteral("mChannelList")); mSplitter->addWidget(mChannelList); mStackedRoomWidget = new QStackedWidget(this); mStackedRoomWidget->setObjectName(QStringLiteral("mStackedRoomWidget")); mSplitter->addWidget(mStackedRoomWidget); mRoomWidget = new RoomWidget(this); mRoomWidget->setObjectName(QStringLiteral("mRoomWidget")); mStackedRoomWidget->addWidget(mRoomWidget); - connect(mRoomWidget, &RoomWidget::selectChannelRequested, this, &RuqolaMainWidget::slotSelectChannelRequested); + connect(mRoomWidget, &RoomWidget::selectChannelRequested, this, [this](const QString &channelId) { + mChannelList->channelListView()->selectChannelRequested(channelId); + }); mEmptyRoomWidget = new QWidget(this); mEmptyRoomWidget->setObjectName(QStringLiteral("mEmptyRoomWidget")); mStackedRoomWidget->addWidget(mEmptyRoomWidget); mStackedRoomWidget->setCurrentWidget(mEmptyRoomWidget); connect(mChannelList, &ChannelListWidget::channelSelected, this, &RuqolaMainWidget::selectChannelRoom); KConfigGroup group(KSharedConfig::openConfig(), myConfigGroupName); mSplitter->restoreState(group.readEntry("SplitterSizes", QByteArray())); - slotSelectChannelRequested(group.readEntry("SelectedRoom", QString())); + //FIXME delay it until list of room are loaded. + mChannelList->channelListView()->selectChannelRequested(group.readEntry("SelectedRoom", QString())); } RuqolaMainWidget::~RuqolaMainWidget() { KConfigGroup group(KSharedConfig::openConfig(), myConfigGroupName); group.writeEntry("SplitterSizes", mSplitter->saveState()); const QString selectedRoom = mChannelList->currentSelectedRoom(); if (selectedRoom.isEmpty()) { group.deleteEntry("SelectedRoom"); } else { group.writeEntry("SelectedRoom", selectedRoom); } } void RuqolaMainWidget::selectChannelRoom(const QModelIndex &index) { Q_EMIT mRoomWidget->channelSelected(index); mStackedRoomWidget->setCurrentWidget(mRoomWidget); Q_EMIT channelSelected(); } RoomWrapper *RuqolaMainWidget::roomWrapper() const { return mRoomWidget->roomWrapper(); } QString RuqolaMainWidget::roomId() const { return mRoomWidget->roomId(); } QString RuqolaMainWidget::roomType() const { return mRoomWidget->roomType(); } void RuqolaMainWidget::setCurrentRocketChatAccount(RocketChatAccount *account) { mChannelList->setCurrentRocketChatAccount(account); mRoomWidget->setCurrentRocketChatAccount(account); mStackedRoomWidget->setCurrentWidget(mEmptyRoomWidget); } - -void RuqolaMainWidget::slotSelectChannelRequested(const QString &channelId) -{ - if (channelId.isEmpty()) { - return; - } - RoomFilterProxyModel *model = mChannelList->channelListView()->model(); - for (int roomIdx = 0, nRooms = model->rowCount(); roomIdx < nRooms; ++roomIdx) { - const auto roomModelIndex = model->index(roomIdx, 0); - const auto roomId = roomModelIndex.data(RoomModel::RoomID).toString(); - if (roomId == channelId) { - selectChannelRoom(roomModelIndex); - mChannelList->channelListView()->selectionModel()->setCurrentIndex(model->index(roomIdx, 0), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); - break; - } - } -} diff --git a/src/widgets/ruqolamainwidget.h b/src/widgets/ruqolamainwidget.h index b4744ee5..03ba990b 100644 --- a/src/widgets/ruqolamainwidget.h +++ b/src/widgets/ruqolamainwidget.h @@ -1,56 +1,55 @@ /* Copyright (c) 2020 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef RUQOLAMAINWIDGET_H #define RUQOLAMAINWIDGET_H #include #include #include "libruqolawidgets_private_export.h" class ChannelListWidget; class RoomWidget; class QSplitter; class RocketChatAccount; class RoomWrapper; class LIBRUQOLAWIDGETS_TESTS_EXPORT RuqolaMainWidget : public QWidget { Q_OBJECT public: explicit RuqolaMainWidget(QWidget *parent = nullptr); ~RuqolaMainWidget(); Q_REQUIRED_RESULT QString roomId() const; void setCurrentRocketChatAccount(RocketChatAccount *account); Q_REQUIRED_RESULT QString roomType() const; RoomWrapper *roomWrapper() const; + void selectChannelRoom(const QModelIndex &index); Q_SIGNALS: void channelSelected(); private: - void slotSelectChannelRequested(const QString &channelId); - void selectChannelRoom(const QModelIndex &index); ChannelListWidget *mChannelList = nullptr; RoomWidget *mRoomWidget = nullptr; QSplitter *mSplitter = nullptr; RocketChatAccount *mCurrentRocketChatAccount = nullptr; QStackedWidget *mStackedRoomWidget = nullptr; QWidget *mEmptyRoomWidget = nullptr; }; #endif // RUQOLAMAINWIDGET_H