From 170c0c533dacc451d7853d0bc7ee0e11973b1008 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 24 Feb 2013 22:44:14 +0000 Subject: [PATCH] Removed tabs in chat lobbies: - unsubscribed lobbies display complete info in a blank page, with some additional help - double click to subscribe. - added unsubscribe button to ChatLobbyDialog. Needs a more appropriate icon (e.g. An open door with a leaving arrow) - the lobby list is now used to display typing status. It could be used to show all sorts of info, the exact same way, such as joining/leaving peers, etc, using various different icons. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6142 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/ChatLobbyWidget.cpp | 180 ++++++++++++++++-- retroshare-gui/src/gui/ChatLobbyWidget.h | 23 ++- retroshare-gui/src/gui/ChatLobbyWidget.ui | 49 ++++- .../src/gui/chat/ChatLobbyDialog.cpp | 37 +++- retroshare-gui/src/gui/chat/ChatLobbyDialog.h | 7 + 5 files changed, 260 insertions(+), 36 deletions(-) diff --git a/retroshare-gui/src/gui/ChatLobbyWidget.cpp b/retroshare-gui/src/gui/ChatLobbyWidget.cpp index 43c4b9c5f..9201869cb 100644 --- a/retroshare-gui/src/gui/ChatLobbyWidget.cpp +++ b/retroshare-gui/src/gui/ChatLobbyWidget.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include #include #include "ChatLobbyWidget.h" @@ -41,14 +43,9 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WFlags flags) QObject::connect(NotifyQt::getInstance(), SIGNAL(chatLobbyEvent(qulonglong,int,const QString&,const QString&)), this, SLOT(displayChatLobbyEvent(qulonglong,int,const QString&,const QString&))); QObject::connect(NotifyQt::getInstance(), SIGNAL(chatLobbyInviteReceived()), this, SLOT(readChatLobbyInvites())); - lobbyTreeWidget = new QTreeWidget ; - getTabWidget()->addTab(lobbyTreeWidget,tr("Lobby list")) ; - - layout()->addWidget( getTabWidget() ) ; - layout()->update() ; - - QObject::connect(lobbyTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(lobbyTreeWidgetCostumPopupMenu())); + QObject::connect(lobbyTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(lobbyTreeWidgetCustomPopupMenu(QPoint))); QObject::connect(lobbyTreeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(itemDoubleClicked(QTreeWidgetItem*,int))); + QObject::connect(lobbyTreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(updateCurrentLobby())); QObject::connect(newlobbytoolButton, SIGNAL(clicked()), this, SLOT(createChatLobby())); @@ -86,9 +83,17 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WFlags flags) publicLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC); lobbyTreeWidget->insertTopLevelItem(1, publicLobbyItem); + // add one blank page. + // + _lobby_blank_page = new QTextBrowser(this) ; + _lobby_blank_page->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding) ; + stackedWidget->addWidget(_lobby_blank_page) ; + lobbyTreeWidget->expandAll(); +// lobbyTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); lobbyChanged(); + showBlankPage(0) ; } ChatLobbyWidget::~ChatLobbyWidget() @@ -98,8 +103,9 @@ ChatLobbyWidget::~ChatLobbyWidget() } } -void ChatLobbyWidget::lobbyTreeWidgetCostumPopupMenu() +void ChatLobbyWidget::lobbyTreeWidgetCustomPopupMenu(QPoint) { + std::cerr << "Creating customPopupMennu" << std::endl; QTreeWidgetItem *item = lobbyTreeWidget->currentItem(); QMenu contextMnu(this); @@ -155,6 +161,26 @@ static void updateItem(QTreeWidgetItem *item, ChatLobbyId id, const std::string } } +void ChatLobbyWidget::addChatPage(ChatLobbyDialog *d) +{ + // check that the page does not already exist. + + if(_lobby_dialogs.find(d->id()) == _lobby_dialogs.end()) + { + stackedWidget->addWidget(d) ; + + connect(d,SIGNAL(lobbyLeave(ChatLobbyId)),this,SLOT(unsubscribeChatLobby(ChatLobbyId))) ; + connect(d,SIGNAL(typingEventReceived(ChatLobbyId)),this,SLOT(updateTypingStatus(ChatLobbyId))) ; + + _lobby_dialogs[d->id()] = d ; + } +} + +void ChatLobbyWidget::setCurrentChatPage(ChatLobbyDialog *d) +{ + stackedWidget->setCurrentWidget(d) ; +} + void ChatLobbyWidget::updateDisplay() { #ifdef CHAT_LOBBY_GUI_DEBUG @@ -314,6 +340,21 @@ void ChatLobbyWidget::createChatLobby() CreateLobbyDialog(friends, privacyLevel).exec(); } +void ChatLobbyWidget::showLobby(QTreeWidgetItem *item) +{ + if (item == NULL && item->type() != TYPE_LOBBY) { + showBlankPage(0) ; + return; + } + + ChatLobbyId id = item->data(COLUMN_DATA, ROLE_ID).toULongLong(); + + if(_lobby_dialogs.find(id) == _lobby_dialogs.end()) + showBlankPage(id) ; + else + stackedWidget->setCurrentWidget(_lobby_dialogs[id]) ; +} + static void subscribeLobby(QTreeWidgetItem *item) { if (item == NULL && item->type() != TYPE_LOBBY) { @@ -329,11 +370,94 @@ static void subscribeLobby(QTreeWidgetItem *item) } } +void ChatLobbyWidget::showBlankPage(ChatLobbyId id) +{ + // show the default blank page. + stackedWidget->setCurrentWidget(_lobby_blank_page) ; + + // Update information + std::vector lobbies; + rsMsgs->getListOfNearbyChatLobbies(lobbies); + + for(std::vector::const_iterator it(lobbies.begin());it!=lobbies.end();++it) + if( (*it).lobby_id == id) + { + QString lobby_description_string ; + + lobby_description_string += "

"+tr("Selected lobby info")+"

" ; + lobby_description_string += ""+tr("Lobby name: ")+"\t" + (*it).lobby_name.c_str() + "
" ; + lobby_description_string += ""+tr("Lobby Id: ")+"\t" + QString::number((*it).lobby_id,16) + "
" ; + lobby_description_string += ""+tr("Topic: ")+"\t" + (*it).lobby_topic.c_str() + "
" ; + lobby_description_string += ""+tr("Type: ")+"\t" + (( (*it).lobby_privacy_level == RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE)?tr("Private"):tr("Public")) + "
" ; + lobby_description_string += ""+tr("Peers: ")+"\t" + QString::number((*it).total_number_of_peers) + "
" ; + + lobby_description_string += "

"+tr("You're not subscribed to this lobby; Double click-it to enter and chat.") ; + + _lobby_blank_page->setText(lobby_description_string) ; + return ; + } + + QString text = tr("No lobby selected. \n\nSelect lobbies at left to show details.\n\nDouble click lobbies to enter and chat.") ; + _lobby_blank_page->setText(text) ; +} void ChatLobbyWidget::subscribeItem() { subscribeLobby(lobbyTreeWidget->currentItem()); } +QTreeWidgetItem *ChatLobbyWidget::getTreeWidgetItem(ChatLobbyId id) +{ + for(int p=0;p<2;++p) + { + QTreeWidgetItem *lobby_item = (p==0)?publicLobbyItem:privateLobbyItem ; + + int childCnt = lobby_item->childCount(); + int childIndex = 0; + + while (childIndex < childCnt) { + QTreeWidgetItem *itemLoop = lobby_item->child(childIndex); + + if (itemLoop->type() == TYPE_LOBBY && itemLoop->data(COLUMN_DATA, ROLE_ID).toULongLong() == id) + return itemLoop ; + } + } + return NULL ; +} +void ChatLobbyWidget::updateTypingStatus(ChatLobbyId id) +{ + QTreeWidgetItem *item = getTreeWidgetItem(id) ; + + if(item != NULL) + { + item->setIcon(0,QIcon(":images/typing.png")) ; + + _icon_changed_map[item] = time(NULL) ; + + QTimer::singleShot(5000,this,SLOT(resetLobbyTreeIcons())) ; + } + else + std::cerr << "Could not find item for lobby id " << (void*)id << std::endl; +} + +void ChatLobbyWidget::resetLobbyTreeIcons() +{ + time_t now = time(NULL) ; + + for(std::map::iterator it(_icon_changed_map.begin());it!=_icon_changed_map.end();) + if(it->second + 5 < now) + { + it->first->setIcon(0,QIcon()) ; + + std::map::iterator tmp(it) ; + ++tmp ; + + _icon_changed_map.erase(it) ; + it = tmp ; + } + else + ++it ; +} + void ChatLobbyWidget::unsubscribeItem() { QTreeWidgetItem *item = lobbyTreeWidget->currentItem(); @@ -343,26 +467,46 @@ void ChatLobbyWidget::unsubscribeItem() const ChatLobbyId id = item->data(COLUMN_DATA, ROLE_ID).toULongLong(); - std::string vpeer_id; - if (rsMsgs->getVirtualPeerId(id, vpeer_id)) { - ChatDialog::closeChat(vpeer_id); + unsubscribeChatLobby(id) ; +} + +void ChatLobbyWidget::unsubscribeChatLobby(ChatLobbyId id) +{ + std::cerr << "Unsubscribing from chat lobby" << std::endl; + + // close the tab. + + std::map::iterator it = _lobby_dialogs.find(id) ; + + if(it != _lobby_dialogs.end()) + { + stackedWidget->removeWidget(it->second) ; + _lobby_dialogs.erase(it) ; } + + // Unsubscribe the chat lobby + std::string vpeer_id; + if (rsMsgs->getVirtualPeerId(id, vpeer_id)) + ChatDialog::closeChat(vpeer_id); rsMsgs->unsubscribeChatLobby(id); } +void ChatLobbyWidget::updateCurrentLobby() +{ + QList items = lobbyTreeWidget->selectedItems() ; + + if(items.empty()) + showLobby(0) ; + else + showLobby(items.front()); +} + void ChatLobbyWidget::itemDoubleClicked(QTreeWidgetItem *item, int /*column*/) { subscribeLobby(item); } -ChatTabWidget *ChatLobbyWidget::getTabWidget() -{ - static ChatTabWidget *instance = new ChatTabWidget() ; - - return instance ; -} - void ChatLobbyWidget::displayChatLobbyEvent(qulonglong lobby_id, int event_type, const QString& nickname, const QString& str) { std::string vpid; diff --git a/retroshare-gui/src/gui/ChatLobbyWidget.h b/retroshare-gui/src/gui/ChatLobbyWidget.h index fbd337805..ac5296c0a 100644 --- a/retroshare-gui/src/gui/ChatLobbyWidget.h +++ b/retroshare-gui/src/gui/ChatLobbyWidget.h @@ -1,11 +1,14 @@ #pragma once #include +#include #include "ui_ChatLobbyWidget.h" #include "RsAutoUpdatePage.h" class RSTreeWidgetItemCompareRole; class ChatTabWidget ; +class ChatLobbyDialog ; +class QTextBrowser ; class ChatLobbyWidget : public RsAutoUpdatePage, Ui::ChatLobbyWidget { @@ -20,22 +23,36 @@ public: virtual void updateDisplay(); - static ChatTabWidget *getTabWidget() ; + void setCurrentChatPage(ChatLobbyDialog *) ; // used by ChatLobbyDialog to raise. + void addChatPage(ChatLobbyDialog *) ; + protected slots: void lobbyChanged(); - void lobbyTreeWidgetCostumPopupMenu(); + void lobbyTreeWidgetCustomPopupMenu(QPoint); void createChatLobby(); void subscribeItem(); void unsubscribeItem(); void itemDoubleClicked(QTreeWidgetItem *item, int column); + void updateCurrentLobby() ; void displayChatLobbyEvent(qulonglong lobby_id, int event_type, const QString& nickname, const QString& str); void readChatLobbyInvites(); + void showLobby(QTreeWidgetItem *lobby_item) ; + void showBlankPage(ChatLobbyId id) ; + void unsubscribeChatLobby(ChatLobbyId id) ; + void updateTypingStatus(ChatLobbyId id) ; + void resetLobbyTreeIcons() ; private: RSTreeWidgetItemCompareRole *compareRole; QTreeWidgetItem *privateLobbyItem; QTreeWidgetItem *publicLobbyItem; + QTreeWidgetItem *getTreeWidgetItem(ChatLobbyId); ChatTabWidget *tabWidget ; - QTreeWidget *lobbyTreeWidget ; + + std::map _lobby_dialogs ; + QTextBrowser *_lobby_blank_page ; + + std::map _icon_changed_map ; }; + diff --git a/retroshare-gui/src/gui/ChatLobbyWidget.ui b/retroshare-gui/src/gui/ChatLobbyWidget.ui index 6ad06bb08..0512d945d 100644 --- a/retroshare-gui/src/gui/ChatLobbyWidget.ui +++ b/retroshare-gui/src/gui/ChatLobbyWidget.ui @@ -7,15 +7,18 @@ 0 0 608 - 188 + 381 - - - 0 - - + + + + + 0 + 0 + + QFrame::Box @@ -89,6 +92,40 @@ + + + + Qt::Horizontal + + + + + 0 + 0 + + + + + 1 + + + + + + + 0 + 0 + + + + 0 + + + + + + + diff --git a/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp b/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp index 2ecb1449f..c864b7fb6 100644 --- a/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp +++ b/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp @@ -69,16 +69,39 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::WF inviteFriendsButton->setText(QString()) ; inviteFriendsButton->setToolTip(tr("Invite friends to this lobby")); + { QIcon icon ; icon.addPixmap(QPixmap(":/images/edit_add24.png")) ; inviteFriendsButton->setIcon(icon) ; inviteFriendsButton->setIconSize(QSize(22,22)) ; + } connect(inviteFriendsButton, SIGNAL(clicked()), this , SLOT(inviteFriends())); getChatWidget()->addChatButton(inviteFriendsButton) ; + + unsubscribeButton = new QPushButton ; + unsubscribeButton->setMinimumSize(QSize(28,28)) ; + unsubscribeButton->setMaximumSize(QSize(28,28)) ; + unsubscribeButton->setText(QString()) ; + unsubscribeButton->setToolTip(tr("Leave this lobby (Unsubscribe)")); + + { + QIcon icon ; + icon.addPixmap(QPixmap(":/images/deletemail24.png")) ; + unsubscribeButton->setIcon(icon) ; + unsubscribeButton->setIconSize(QSize(22,22)) ; + } + + connect(unsubscribeButton, SIGNAL(clicked()), this , SLOT(leaveLobby())); + + getChatWidget()->addChatButton(unsubscribeButton) ; } +void ChatLobbyDialog::leaveLobby() +{ + emit lobbyLeave(id()) ; +} void ChatLobbyDialog::inviteFriends() { std::cerr << "Inviting friends" << std::endl; @@ -161,11 +184,8 @@ void ChatLobbyDialog::init(const std::string &peerId, const QString &title) showParticipantsFrame(PeerSettings->getShowParticipantsFrame(peerId)); // add to window - ChatTabWidget *tabWidget = ChatLobbyWidget::getTabWidget(); - if (tabWidget) { - tabWidget->addDialog(this); - } + dynamic_cast(MainWindow::getPage(MainWindow::ChatLobby))->addChatPage(this) ; /** List of muted Participants */ mutedParticipants = new QStringList; @@ -463,6 +483,7 @@ void ChatLobbyDialog::displayLobbyEvent(int event_type, const QString& nickname, break; case RS_CHAT_LOBBY_EVENT_PEER_STATUS: ui.chatWidget->updateStatusString(nickname + " %1", str); + emit typingEventReceived(id()) ; break; case RS_CHAT_LOBBY_EVENT_PEER_CHANGE_NICKNAME: ui.chatWidget->addChatMsg(true, tr("Lobby management"), QDateTime::currentDateTime(), QDateTime::currentDateTime(), tr("%1 changed his name to: %2").arg(nickname, str), ChatWidget::TYPE_SYSTEM); @@ -499,12 +520,10 @@ bool ChatLobbyDialog::canClose() void ChatLobbyDialog::showDialog(uint chatflags) { - if (chatflags & RS_CHAT_FOCUS) { + if (chatflags & RS_CHAT_FOCUS) + { MainWindow::showWindow(MainWindow::ChatLobby); - ChatTabWidget *tabWidget = ChatLobbyWidget::getTabWidget(); - if (tabWidget) { - tabWidget->setCurrentWidget(this); - } + dynamic_cast(MainWindow::getPage(MainWindow::ChatLobby))->setCurrentChatPage(this) ; } } diff --git a/retroshare-gui/src/gui/chat/ChatLobbyDialog.h b/retroshare-gui/src/gui/chat/ChatLobbyDialog.h index 39bd52f67..781f73999 100644 --- a/retroshare-gui/src/gui/chat/ChatLobbyDialog.h +++ b/retroshare-gui/src/gui/chat/ChatLobbyDialog.h @@ -41,11 +41,17 @@ public: virtual bool notifyBlink(); void setNickname(const QString &nickname); bool isParticipantMuted(const QString &participant); + ChatLobbyId id() const { return lobbyId ;} private slots: void showParticipantsFrame(bool show); void participantsTreeWidgetCostumPopupMenu( QPoint point ); void inviteFriends() ; + void leaveLobby() ; + +signals: + void lobbyLeave(ChatLobbyId) ; + void typingEventReceived(ChatLobbyId) ; protected: /** Default constructor */ @@ -77,6 +83,7 @@ private: time_t lastUpdateListTime; QPushButton *inviteFriendsButton ; + QPushButton *unsubscribeButton ; /** Qt Designer generated object */ Ui::ChatLobbyDialog ui;