mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-25 23:49:35 -05:00
Add Ability to undock a chat lobby to a window.
This commit is contained in:
parent
27bbd50f1f
commit
b529de29e6
@ -418,9 +418,7 @@ void ChatLobbyWidget::addChatPage(ChatLobbyDialog *d)
|
|||||||
|
|
||||||
if(_lobby_infos.find(d->id()) == _lobby_infos.end())
|
if(_lobby_infos.find(d->id()) == _lobby_infos.end())
|
||||||
{
|
{
|
||||||
ui.stackedWidget->addWidget(d) ;
|
connect(d,SIGNAL(dialogClose(ChatDialog*)),this,SLOT(dialogClose(ChatDialog*)));
|
||||||
|
|
||||||
connect(d,SIGNAL(lobbyLeave(ChatLobbyId)),this,SLOT(unsubscribeChatLobby(ChatLobbyId))) ;
|
|
||||||
connect(d,SIGNAL(typingEventReceived(ChatLobbyId)),this,SLOT(updateTypingStatus(ChatLobbyId))) ;
|
connect(d,SIGNAL(typingEventReceived(ChatLobbyId)),this,SLOT(updateTypingStatus(ChatLobbyId))) ;
|
||||||
connect(d,SIGNAL(messageReceived(bool,ChatLobbyId,QDateTime,QString,QString)),this,SLOT(updateMessageChanged(bool,ChatLobbyId,QDateTime,QString,QString))) ;
|
connect(d,SIGNAL(messageReceived(bool,ChatLobbyId,QDateTime,QString,QString)),this,SLOT(updateMessageChanged(bool,ChatLobbyId,QDateTime,QString,QString))) ;
|
||||||
connect(d,SIGNAL(peerJoined(ChatLobbyId)),this,SLOT(updatePeerEntering(ChatLobbyId))) ;
|
connect(d,SIGNAL(peerJoined(ChatLobbyId)),this,SLOT(updatePeerEntering(ChatLobbyId))) ;
|
||||||
@ -429,14 +427,33 @@ void ChatLobbyWidget::addChatPage(ChatLobbyDialog *d)
|
|||||||
ChatLobbyId id = d->id();
|
ChatLobbyId id = d->id();
|
||||||
_lobby_infos[id].dialog = d ;
|
_lobby_infos[id].dialog = d ;
|
||||||
_lobby_infos[id].default_icon = QIcon() ;
|
_lobby_infos[id].default_icon = QIcon() ;
|
||||||
_lobby_infos[id].last_typing_event = time(NULL) ;
|
_lobby_infos[id].last_typing_event = time(nullptr) ;
|
||||||
|
|
||||||
ChatLobbyInfo linfo ;
|
ChatLobbyInfo linfo ;
|
||||||
if(rsMsgs->getChatLobbyInfo(id,linfo))
|
if(rsMsgs->getChatLobbyInfo(id,linfo))
|
||||||
_lobby_infos[id].default_icon = (linfo.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC) ? QIcon(IMAGE_PUBLIC):QIcon(IMAGE_PRIVATE) ;
|
_lobby_infos[id].default_icon = (linfo.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC) ? QIcon(IMAGE_PUBLIC):QIcon(IMAGE_PRIVATE) ;
|
||||||
else
|
else
|
||||||
std::cerr << "(EE) cannot find info for room " << std::hex << id << std::dec << std::endl;
|
std::cerr << "(EE) cannot find info for room " << std::hex << id << std::dec << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui.stackedWidget->addWidget(d) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatLobbyWidget::removeChatPage(ChatLobbyDialog *d)
|
||||||
|
{
|
||||||
|
// check that the page already exist.
|
||||||
|
|
||||||
|
if(_lobby_infos.find(d->id()) != _lobby_infos.end())
|
||||||
|
{
|
||||||
|
ui.stackedWidget->removeWidget(d) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatLobbyWidget::dialogClose(ChatDialog* cd)
|
||||||
|
{
|
||||||
|
ChatLobbyDialog* d = dynamic_cast<ChatLobbyDialog*>(cd);
|
||||||
|
if(_lobby_infos.find(d->id()) != _lobby_infos.end())
|
||||||
|
unsubscribeChatLobby(d->id());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatLobbyWidget::setCurrentChatPage(ChatLobbyDialog *d)
|
void ChatLobbyWidget::setCurrentChatPage(ChatLobbyDialog *d)
|
||||||
@ -708,7 +725,7 @@ void ChatLobbyWidget::createChatLobby()
|
|||||||
|
|
||||||
void ChatLobbyWidget::showLobby(QTreeWidgetItem *item)
|
void ChatLobbyWidget::showLobby(QTreeWidgetItem *item)
|
||||||
{
|
{
|
||||||
if (item == NULL || item->type() != TYPE_LOBBY) {
|
if (item == nullptr || item->type() != TYPE_LOBBY) {
|
||||||
showBlankPage(0) ;
|
showBlankPage(0) ;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -718,7 +735,11 @@ void ChatLobbyWidget::showLobby(QTreeWidgetItem *item)
|
|||||||
if(_lobby_infos.find(id) == _lobby_infos.end())
|
if(_lobby_infos.find(id) == _lobby_infos.end())
|
||||||
showBlankPage(id) ;
|
showBlankPage(id) ;
|
||||||
else
|
else
|
||||||
ui.stackedWidget->setCurrentWidget(_lobby_infos[id].dialog) ;
|
{
|
||||||
|
_lobby_infos[id].dialog->showDialog(RS_CHAT_FOCUS);
|
||||||
|
if (_lobby_infos[id].dialog->isWindowed())
|
||||||
|
showBlankPage(id, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function is for the case where we don't have any identity yet
|
// this function is for the case where we don't have any identity yet
|
||||||
@ -772,17 +793,17 @@ bool ChatLobbyWidget::showLobbyAnchor(ChatLobbyId id, QString anchor)
|
|||||||
{
|
{
|
||||||
QTreeWidgetItem *item = getTreeWidgetItem(id) ;
|
QTreeWidgetItem *item = getTreeWidgetItem(id) ;
|
||||||
|
|
||||||
if(item != NULL) {
|
if(item != nullptr) {
|
||||||
if(item->type() == TYPE_LOBBY) {
|
if(item->type() == TYPE_LOBBY) {
|
||||||
|
|
||||||
if(_lobby_infos.find(id) == _lobby_infos.end()) {
|
if(_lobby_infos.find(id) == _lobby_infos.end()) {
|
||||||
showBlankPage(id) ;
|
showBlankPage(id) ;
|
||||||
} else {
|
} else {
|
||||||
//ChatLobbyDialog cldChatLobby =_lobby_infos[id].dialog;
|
_lobby_infos[id].dialog->showDialog(RS_CHAT_FOCUS);
|
||||||
ui.stackedWidget->setCurrentWidget(_lobby_infos[id].dialog) ;
|
if (_lobby_infos[id].dialog->isWindowed())
|
||||||
ChatLobbyDialog *cldCW=NULL ;
|
showBlankPage(id, true);
|
||||||
if (NULL != (cldCW = dynamic_cast<ChatLobbyDialog *>(ui.stackedWidget->currentWidget())))
|
|
||||||
cldCW->getChatWidget()->scrollToAnchor(anchor);
|
_lobby_infos[id].dialog->getChatWidget()->scrollToAnchor(anchor);
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.lobbyTreeWidget->setCurrentItem(item);
|
ui.lobbyTreeWidget->setCurrentItem(item);
|
||||||
@ -857,19 +878,19 @@ void ChatLobbyWidget::autoSubscribeLobby(QTreeWidgetItem *item)
|
|||||||
subscribeChatLobbyAtItem(item);
|
subscribeChatLobbyAtItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatLobbyWidget::showBlankPage(ChatLobbyId id)
|
void ChatLobbyWidget::showBlankPage(ChatLobbyId id, bool subscribed /*= false*/)
|
||||||
{
|
{
|
||||||
// show the default blank page.
|
// show the default blank page.
|
||||||
ui.stackedWidget->setCurrentWidget(ui._lobby_blank_page) ;
|
ui.stackedWidget->setCurrentWidget(ui._lobby_blank_page) ;
|
||||||
|
|
||||||
// Update information
|
// Update information
|
||||||
std::vector<VisibleChatLobbyRecord> lobbies;
|
std::vector<VisibleChatLobbyRecord> lobbies;
|
||||||
rsMsgs->getListOfNearbyChatLobbies(lobbies);
|
rsMsgs->getListOfNearbyChatLobbies(lobbies);
|
||||||
|
|
||||||
std::list<RsGxsId> my_ids ;
|
std::list<RsGxsId> my_ids ;
|
||||||
rsIdentity->getOwnIds(my_ids) ;
|
rsIdentity->getOwnIds(my_ids) ;
|
||||||
|
|
||||||
trimAnonIds(my_ids) ;
|
trimAnonIds(my_ids) ;
|
||||||
|
|
||||||
for(std::vector<VisibleChatLobbyRecord>::const_iterator it(lobbies.begin());it!=lobbies.end();++it)
|
for(std::vector<VisibleChatLobbyRecord>::const_iterator it(lobbies.begin());it!=lobbies.end();++it)
|
||||||
if( (*it).lobby_id == id)
|
if( (*it).lobby_id == id)
|
||||||
@ -881,8 +902,10 @@ void ChatLobbyWidget::showBlankPage(ChatLobbyId id)
|
|||||||
ui.lobbysec_lineEdit->setText( (( (*it).lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED)?tr("No anonymous IDs"):tr("Anonymous IDs accepted")) );
|
ui.lobbysec_lineEdit->setText( (( (*it).lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED)?tr("No anonymous IDs"):tr("Anonymous IDs accepted")) );
|
||||||
ui.lobbypeers_lineEdit->setText( QString::number((*it).total_number_of_peers) );
|
ui.lobbypeers_lineEdit->setText( QString::number((*it).total_number_of_peers) );
|
||||||
|
|
||||||
QString text = tr("You're not subscribed to this chat room; Double click-it to enter and chat.") ;
|
QString text = tr("You're subscribed to this chat room; Double click to show window and chat.") ;
|
||||||
|
if (!subscribed)
|
||||||
|
{
|
||||||
|
text = tr("You're not subscribed to this chat room; Double click-it to enter and chat.") ;
|
||||||
if(my_ids.empty())
|
if(my_ids.empty())
|
||||||
{
|
{
|
||||||
if( (*it).lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED)
|
if( (*it).lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED)
|
||||||
@ -890,8 +913,9 @@ void ChatLobbyWidget::showBlankPage(ChatLobbyId id)
|
|||||||
else
|
else
|
||||||
text += "\n\n"+tr("You will need to create an identity in order to join chat rooms.") ;
|
text += "\n\n"+tr("You will need to create an identity in order to join chat rooms.") ;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ui.lobbyInfoLabel->setText(text);
|
ui.lobbyInfoLabel->setText(text);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1037,6 +1061,8 @@ void ChatLobbyWidget::unsubscribeChatLobby(ChatLobbyId id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ui.stackedWidget->removeWidget(it->second.dialog) ;
|
ui.stackedWidget->removeWidget(it->second.dialog) ;
|
||||||
|
disconnect(it->second.dialog,SIGNAL(dialogClose(ChatDialog*)),this,SLOT(dialogClose(ChatDialog*)));
|
||||||
|
it->second.dialog->leaveLobby();
|
||||||
_lobby_infos.erase(it) ;
|
_lobby_infos.erase(it) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
class RSTreeWidgetItemCompareRole;
|
class RSTreeWidgetItemCompareRole;
|
||||||
class ChatTabWidget ;
|
class ChatTabWidget ;
|
||||||
|
class ChatDialog ;
|
||||||
class ChatLobbyDialog ;
|
class ChatLobbyDialog ;
|
||||||
class QTextBrowser ;
|
class QTextBrowser ;
|
||||||
|
|
||||||
@ -69,6 +70,7 @@ public:
|
|||||||
|
|
||||||
void setCurrentChatPage(ChatLobbyDialog *) ; // used by ChatLobbyDialog to raise.
|
void setCurrentChatPage(ChatLobbyDialog *) ; // used by ChatLobbyDialog to raise.
|
||||||
void addChatPage(ChatLobbyDialog *) ;
|
void addChatPage(ChatLobbyDialog *) ;
|
||||||
|
void removeChatPage(ChatLobbyDialog *) ;
|
||||||
bool showLobbyAnchor(ChatLobbyId id, QString anchor) ;
|
bool showLobbyAnchor(ChatLobbyId id, QString anchor) ;
|
||||||
|
|
||||||
uint unreadCount();
|
uint unreadCount();
|
||||||
@ -77,6 +79,7 @@ signals:
|
|||||||
void unreadCountChanged(uint unreadCount);
|
void unreadCountChanged(uint unreadCount);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
|
void dialogClose(ChatDialog*);
|
||||||
void lobbyChanged();
|
void lobbyChanged();
|
||||||
void lobbyTreeWidgetCustomPopupMenu(QPoint);
|
void lobbyTreeWidgetCustomPopupMenu(QPoint);
|
||||||
void createChatLobby();
|
void createChatLobby();
|
||||||
@ -87,7 +90,7 @@ protected slots:
|
|||||||
void displayChatLobbyEvent(qulonglong lobby_id, int event_type, const RsGxsId& gxs_id, const QString& str);
|
void displayChatLobbyEvent(qulonglong lobby_id, int event_type, const RsGxsId& gxs_id, const QString& str);
|
||||||
void readChatLobbyInvites();
|
void readChatLobbyInvites();
|
||||||
void showLobby(QTreeWidgetItem *lobby_item) ;
|
void showLobby(QTreeWidgetItem *lobby_item) ;
|
||||||
void showBlankPage(ChatLobbyId id) ;
|
void showBlankPage(ChatLobbyId id, bool subscribed = false) ;
|
||||||
void unsubscribeChatLobby(ChatLobbyId id) ;
|
void unsubscribeChatLobby(ChatLobbyId id) ;
|
||||||
void createIdentityAndSubscribe();
|
void createIdentityAndSubscribe();
|
||||||
void subscribeChatLobbyAs() ;
|
void subscribeChatLobbyAs() ;
|
||||||
|
@ -62,7 +62,7 @@ const static uint32_t timeToInactivity = 60 * 10; // in seconds
|
|||||||
|
|
||||||
/** Default constructor */
|
/** Default constructor */
|
||||||
ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::WindowFlags flags)
|
ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::WindowFlags flags)
|
||||||
: ChatDialog(parent, flags), lobbyId(lid),
|
: ChatDialog(parent, flags), lobbyId(lid), mWindowedSetted(false), mPCWindow(nullptr),
|
||||||
bullet_red_128(":/icons/bullet_red_128.png"), bullet_grey_128(":/icons/bullet_grey_128.png"),
|
bullet_red_128(":/icons/bullet_red_128.png"), bullet_grey_128(":/icons/bullet_grey_128.png"),
|
||||||
bullet_green_128(":/icons/bullet_green_128.png"), bullet_yellow_128(":/icons/bullet_yellow_128.png")
|
bullet_green_128(":/icons/bullet_green_128.png"), bullet_yellow_128(":/icons/bullet_yellow_128.png")
|
||||||
{
|
{
|
||||||
@ -129,6 +129,15 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
|
|||||||
double scaler_factor = S > 25 ? 2.4 : 1.8;
|
double scaler_factor = S > 25 ? 2.4 : 1.8;
|
||||||
QSize icon_size(scaler_factor * S, scaler_factor * S);
|
QSize icon_size(scaler_factor * S, scaler_factor * S);
|
||||||
|
|
||||||
|
// Add a button to undock dialog.
|
||||||
|
//
|
||||||
|
undockButton = new QToolButton;
|
||||||
|
undockButton->setText(QString());
|
||||||
|
undockButton->setAutoRaise(true);
|
||||||
|
connect(undockButton, SIGNAL(clicked()), this , SLOT(toggleWindowed()));
|
||||||
|
|
||||||
|
getChatWidget()->addTitleBarWidget(undockButton) ;
|
||||||
|
|
||||||
// Add a button to invite friends.
|
// Add a button to invite friends.
|
||||||
//
|
//
|
||||||
inviteFriendsButton = new QToolButton ;
|
inviteFriendsButton = new QToolButton ;
|
||||||
@ -201,8 +210,12 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
|
|||||||
|
|
||||||
void ChatLobbyDialog::leaveLobby()
|
void ChatLobbyDialog::leaveLobby()
|
||||||
{
|
{
|
||||||
emit lobbyLeave(id()) ;
|
emit dialogClose(this);
|
||||||
|
|
||||||
|
if (mPCWindow)
|
||||||
|
mPCWindow = nullptr;// Windows deleted by events just before.
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatLobbyDialog::inviteFriends()
|
void ChatLobbyDialog::inviteFriends()
|
||||||
{
|
{
|
||||||
std::cerr << "Inviting friends" << std::endl;
|
std::cerr << "Inviting friends" << std::endl;
|
||||||
@ -404,12 +417,8 @@ void ChatLobbyDialog::init(const ChatId &/*id*/, const QString &/*title*/)
|
|||||||
|
|
||||||
lastUpdateListTime = 0;
|
lastUpdateListTime = 0;
|
||||||
|
|
||||||
// add to window
|
// add to stacked lobby list
|
||||||
|
setWindowed(false);
|
||||||
ChatLobbyWidget *chatLobbyPage = dynamic_cast<ChatLobbyWidget*>(MainWindow::getPage(MainWindow::ChatLobby));
|
|
||||||
if (chatLobbyPage) {
|
|
||||||
chatLobbyPage->addChatPage(this) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** List of muted Participants */
|
/** List of muted Participants */
|
||||||
mutedParticipants.clear() ;
|
mutedParticipants.clear() ;
|
||||||
@ -421,11 +430,15 @@ void ChatLobbyDialog::init(const ChatId &/*id*/, const QString &/*title*/)
|
|||||||
/** Destructor. */
|
/** Destructor. */
|
||||||
ChatLobbyDialog::~ChatLobbyDialog()
|
ChatLobbyDialog::~ChatLobbyDialog()
|
||||||
{
|
{
|
||||||
// announce leaving of lobby
|
if (mPCWindow)
|
||||||
|
{
|
||||||
|
mPCWindow->removeDialog(this);
|
||||||
|
mPCWindow = nullptr;
|
||||||
|
}
|
||||||
// check that the lobby still exists.
|
// check that the lobby still exists.
|
||||||
if (mChatId.isLobbyId())
|
// announce leaving of lobby
|
||||||
rsMsgs->sendLobbyStatusPeerLeaving(mChatId.toLobbyId());
|
if (mChatId.isLobbyId())
|
||||||
|
rsMsgs->sendLobbyStatusPeerLeaving(mChatId.toLobbyId());
|
||||||
|
|
||||||
// save settings
|
// save settings
|
||||||
processSettings(false);
|
processSettings(false);
|
||||||
@ -910,11 +923,17 @@ void ChatLobbyDialog::showDialog(uint chatflags)
|
|||||||
{
|
{
|
||||||
if (chatflags & RS_CHAT_FOCUS)
|
if (chatflags & RS_CHAT_FOCUS)
|
||||||
{
|
{
|
||||||
MainWindow::showWindow(MainWindow::ChatLobby);
|
if (isWindowed() && mPCWindow) {
|
||||||
MainPage *p = MainWindow::getPage(MainWindow::ChatLobby);
|
mPCWindow->showDialog(this, chatflags);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MainWindow::showWindow(MainWindow::ChatLobby);
|
||||||
|
MainPage *p = MainWindow::getPage(MainWindow::ChatLobby);
|
||||||
|
|
||||||
if(p != NULL)
|
if(p)
|
||||||
dynamic_cast<ChatLobbyWidget*>(p)->setCurrentChatPage(this) ;
|
dynamic_cast<ChatLobbyWidget*>(p)->setCurrentChatPage(this) ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -941,3 +960,54 @@ void ChatLobbyDialog::filterIds()
|
|||||||
|
|
||||||
ui.participantsList->filterItems(filterColumn, text);
|
ui.participantsList->filterItems(filterColumn, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatLobbyDialog::setWindowed(bool windowed)
|
||||||
|
{
|
||||||
|
if (mWindowedSetted && (windowed == isWindowed()) )
|
||||||
|
{
|
||||||
|
RsErr() << __PRETTY_FUNCTION__ << " Attempt to set windowed same as last state." << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mWindowedSetted = true;
|
||||||
|
// just empiric values
|
||||||
|
qreal S = QFontMetricsF(font()).height();
|
||||||
|
int size = static_cast<int>(S > 25.0 ? 2.4 * S : 1.8 * S);
|
||||||
|
QSize icon_size(size, size);
|
||||||
|
|
||||||
|
QIcon icon ;
|
||||||
|
// chatLobbyPage could be NULL for first autosubscribe lobby as Dialog is created before main widget
|
||||||
|
ChatLobbyWidget *chatLobbyPage = dynamic_cast<ChatLobbyWidget*>(MainWindow::getPage(MainWindow::ChatLobby));
|
||||||
|
if (!mPCWindow)
|
||||||
|
mPCWindow = PopupChatWindow::getWindow(true);
|
||||||
|
|
||||||
|
if (windowed)
|
||||||
|
{
|
||||||
|
if (chatLobbyPage)
|
||||||
|
chatLobbyPage->removeChatPage(this);
|
||||||
|
if (mPCWindow)
|
||||||
|
mPCWindow->addDialog(this);
|
||||||
|
|
||||||
|
undockButton->setToolTip(tr("Redock to Main window"));
|
||||||
|
icon.addPixmap(QPixmap(":/icons/png/dock.png")) ;
|
||||||
|
undockButton->setIcon(icon) ;
|
||||||
|
undockButton->setIconSize(icon_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mPCWindow)
|
||||||
|
{
|
||||||
|
mPCWindow->removeDialog(this);
|
||||||
|
mPCWindow = nullptr;
|
||||||
|
}
|
||||||
|
if (chatLobbyPage)
|
||||||
|
chatLobbyPage->addChatPage(this);
|
||||||
|
|
||||||
|
undockButton->setToolTip(tr("Undock to a new window"));
|
||||||
|
icon.addPixmap(QPixmap(":/icons/png/undock.png")) ;
|
||||||
|
undockButton->setIcon(icon) ;
|
||||||
|
undockButton->setIconSize(icon_size);
|
||||||
|
}
|
||||||
|
show();
|
||||||
|
if (chatLobbyPage)// If not defined, we are on autosubscribe loop of lobby widget constructor. So don't recall it.
|
||||||
|
showDialog(RS_CHAT_FOCUS);
|
||||||
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "ui_ChatLobbyDialog.h"
|
#include "ui_ChatLobbyDialog.h"
|
||||||
#include "gui/common/RSTreeWidgetItem.h"
|
#include "gui/common/RSTreeWidgetItem.h"
|
||||||
#include "ChatDialog.h"
|
#include "ChatDialog.h"
|
||||||
|
#include "PopupChatWindow.h"
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(RsGxsId)
|
Q_DECLARE_METATYPE(RsGxsId)
|
||||||
Q_DECLARE_METATYPE(QList<RsGxsId>)
|
Q_DECLARE_METATYPE(QList<RsGxsId>)
|
||||||
@ -51,16 +52,20 @@ public:
|
|||||||
ChatLobbyId id() const { return lobbyId ;}
|
ChatLobbyId id() const { return lobbyId ;}
|
||||||
void sortParcipants();
|
void sortParcipants();
|
||||||
|
|
||||||
|
inline bool isWindowed() const { return dynamic_cast<PopupChatWindow*>(this->window()) != nullptr; }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void leaveLobby() ;
|
||||||
private slots:
|
private slots:
|
||||||
void participantsTreeWidgetCustomPopupMenu( QPoint point );
|
void participantsTreeWidgetCustomPopupMenu( QPoint point );
|
||||||
void textBrowserAskContextMenu(QMenu* contextMnu, QString anchorForPosition, const QPoint point);
|
void textBrowserAskContextMenu(QMenu* contextMnu, QString anchorForPosition, const QPoint point);
|
||||||
void inviteFriends() ;
|
void inviteFriends() ;
|
||||||
void leaveLobby() ;
|
|
||||||
void filterChanged(const QString &text);
|
void filterChanged(const QString &text);
|
||||||
void showInPeopleTab();
|
void showInPeopleTab();
|
||||||
|
void toggleWindowed(){setWindowed(!isWindowed());}
|
||||||
|
void setWindowed(bool windowed);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void lobbyLeave(ChatLobbyId) ;
|
|
||||||
void typingEventReceived(ChatLobbyId) ;
|
void typingEventReceived(ChatLobbyId) ;
|
||||||
void messageReceived(bool incoming, ChatLobbyId lobby_id, QDateTime time, QString senderName, QString msg) ;
|
void messageReceived(bool incoming, ChatLobbyId lobby_id, QDateTime time, QString senderName, QString msg) ;
|
||||||
void peerJoined(ChatLobbyId) ;
|
void peerJoined(ChatLobbyId) ;
|
||||||
@ -103,9 +108,13 @@ private:
|
|||||||
|
|
||||||
RSTreeWidgetItemCompareRole *mParticipantCompareRole ;
|
RSTreeWidgetItemCompareRole *mParticipantCompareRole ;
|
||||||
|
|
||||||
QToolButton *inviteFriendsButton ;
|
QToolButton *undockButton ;
|
||||||
|
QToolButton *inviteFriendsButton ;
|
||||||
QToolButton *unsubscribeButton ;
|
QToolButton *unsubscribeButton ;
|
||||||
|
|
||||||
|
bool mWindowedSetted;
|
||||||
|
PopupChatWindow* mPCWindow;
|
||||||
|
|
||||||
/** Qt Designer generated object */
|
/** Qt Designer generated object */
|
||||||
Ui::ChatLobbyDialog ui;
|
Ui::ChatLobbyDialog ui;
|
||||||
|
|
||||||
|
@ -64,15 +64,13 @@ static PopupChatWindow *instance = NULL;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Default constructor */
|
/** Default constructor */
|
||||||
PopupChatWindow::PopupChatWindow(bool tabbed, QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags)
|
PopupChatWindow::PopupChatWindow(bool tabbed, QWidget *parent, Qt::WindowFlags flags)
|
||||||
|
: QMainWindow(parent, flags),tabbedWindow(tabbed),firstShow(true)
|
||||||
|
, chatDialog(nullptr),mEmptyIcon(nullptr)
|
||||||
{
|
{
|
||||||
/* Invoke Qt Designer generated QObject setup routine */
|
/* Invoke Qt Designer generated QObject setup routine */
|
||||||
ui.setupUi(this);
|
ui.setupUi(this);
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
tabbedWindow = tabbed;
|
|
||||||
firstShow = true;
|
|
||||||
chatDialog = NULL;
|
|
||||||
mEmptyIcon = NULL;
|
|
||||||
|
|
||||||
ui.tabWidget->setVisible(tabbedWindow);
|
ui.tabWidget->setVisible(tabbedWindow);
|
||||||
|
|
||||||
@ -204,15 +202,16 @@ void PopupChatWindow::addDialog(ChatDialog *dialog)
|
|||||||
if (tabbedWindow) {
|
if (tabbedWindow) {
|
||||||
ui.tabWidget->addDialog(dialog);
|
ui.tabWidget->addDialog(dialog);
|
||||||
} else {
|
} else {
|
||||||
ui.horizontalLayout->addWidget(dialog);
|
ui.chatcentralLayout->addWidget(dialog);
|
||||||
dialog->addToParent(this);
|
dialog->addToParent(this);
|
||||||
ui.horizontalLayout->setContentsMargins(0, 0, 0, 0);
|
ui.chatcentralLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
chatId = dialog->getChatId();
|
chatId = dialog->getChatId();
|
||||||
chatDialog = dialog;
|
chatDialog = dialog;
|
||||||
calculateStyle(dialog);
|
calculateStyle(dialog);
|
||||||
|
calculateTitle(dialog);
|
||||||
|
|
||||||
/* signal toggled is called */
|
/* signal toggled is called */
|
||||||
ui.actionSetOnTop->setChecked(PeerSettings->getPrivateChatOnTop(chatId));
|
ui.actionSetOnTop->setChecked(PeerSettings->getPrivateChatOnTop(chatId));
|
||||||
|
|
||||||
QObject::connect(dialog, SIGNAL(dialogClose(ChatDialog*)), this, SLOT(dialogClose(ChatDialog*)));
|
QObject::connect(dialog, SIGNAL(dialogClose(ChatDialog*)), this, SLOT(dialogClose(ChatDialog*)));
|
||||||
}
|
}
|
||||||
@ -233,14 +232,15 @@ void PopupChatWindow::removeDialog(ChatDialog *dialog)
|
|||||||
deleteLater();
|
deleteLater();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
QObject::disconnect(dialog, SIGNAL(dialogClose(ChatDialog*)), this, SLOT(dialogClose(ChatDialog*)));
|
|
||||||
|
|
||||||
if (chatDialog == dialog) {
|
if (chatDialog == dialog) {
|
||||||
|
QObject::disconnect(dialog, SIGNAL(dialogClose(ChatDialog*)), this, SLOT(dialogClose(ChatDialog*)));
|
||||||
saveSettings();
|
saveSettings();
|
||||||
dialog->removeFromParent(this);
|
dialog->removeFromParent(this);
|
||||||
ui.horizontalLayout->removeWidget(dialog);
|
ui.chatcentralLayout->removeWidget(dialog);
|
||||||
chatDialog = NULL;
|
chatDialog = nullptr;
|
||||||
chatId = ChatId();
|
chatId = ChatId();
|
||||||
|
close();
|
||||||
deleteLater();
|
deleteLater();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<string notr="true">MainWindow</string>
|
<string notr="true">MainWindow</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="chatcentralwidget">
|
<widget class="QWidget" name="chatcentralwidget">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="chatcentralLayout">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>5</number>
|
<number>5</number>
|
||||||
</property>
|
</property>
|
||||||
|
@ -69,6 +69,7 @@
|
|||||||
<file>icons/png/chat-lobbies.png</file>
|
<file>icons/png/chat-lobbies.png</file>
|
||||||
<file>icons/png/circles.png</file>
|
<file>icons/png/circles.png</file>
|
||||||
<file>icons/png/digital-key.png</file>
|
<file>icons/png/digital-key.png</file>
|
||||||
|
<file>icons/png/dock.png</file>
|
||||||
<file>icons/png/empty-circle.png</file>
|
<file>icons/png/empty-circle.png</file>
|
||||||
<file>icons/png/enter.png</file>
|
<file>icons/png/enter.png</file>
|
||||||
<file>icons/png/exit.png</file>
|
<file>icons/png/exit.png</file>
|
||||||
@ -121,6 +122,7 @@
|
|||||||
<file>icons/png/thumbs-neutral.png</file>
|
<file>icons/png/thumbs-neutral.png</file>
|
||||||
<file>icons/png/thumbs-up.png</file>
|
<file>icons/png/thumbs-up.png</file>
|
||||||
<file>icons/png/typing.png</file>
|
<file>icons/png/typing.png</file>
|
||||||
|
<file>icons/png/undock.png</file>
|
||||||
<file>icons/png/video.png</file>
|
<file>icons/png/video.png</file>
|
||||||
<file>icons/quit_128.png</file>
|
<file>icons/quit_128.png</file>
|
||||||
<file>icons/search_red_128.png</file>
|
<file>icons/search_red_128.png</file>
|
||||||
|
BIN
retroshare-gui/src/gui/icons/png/dock.png
Normal file
BIN
retroshare-gui/src/gui/icons/png/dock.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
BIN
retroshare-gui/src/gui/icons/png/undock.png
Normal file
BIN
retroshare-gui/src/gui/icons/png/undock.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
95
retroshare-gui/src/gui/icons/svg/dock.svg
Normal file
95
retroshare-gui/src/gui/icons/svg/dock.svg
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
id="svg4823"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
|
||||||
|
xml:space="preserve"
|
||||||
|
width="80"
|
||||||
|
height="80"
|
||||||
|
viewBox="0 0 80 80"
|
||||||
|
sodipodi:docname="dock.svg"
|
||||||
|
inkscape:export-filename="/home/phenom/GIT/RetroShare/trunk/retroshare-gui/src/gui/icons/png/dock.png"
|
||||||
|
inkscape:export-xdpi="153.60001"
|
||||||
|
inkscape:export-ydpi="153.60001"><metadata
|
||||||
|
id="metadata4829"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs4827" /><sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1015"
|
||||||
|
id="namedview4825"
|
||||||
|
showgrid="false"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
inkscape:zoom="8.34386"
|
||||||
|
inkscape:cx="-8.1326614"
|
||||||
|
inkscape:cy="38.591301"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="g4831" /><g
|
||||||
|
id="g4831"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
inkscape:label="ink_ext_XXXXXX"
|
||||||
|
transform="matrix(1.25,0,0,-1.25,0,80)"><path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4835"
|
||||||
|
style="fill:#039bd5;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||||
|
d="M 64,32 C 64,14.327 49.673,0 32,0 14.327,0 0,14.327 0,32 0,49.673 14.327,64 32,64 49.673,64 64,49.673 64,32" /><path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path5452-3"
|
||||||
|
style="fill:#000000;fill-opacity:0.15686275;fill-rule:nonzero;stroke:none;stroke-width:2.16372085"
|
||||||
|
d="M 48,17.599999 C 48,15.3906 46.2094,13.6 44.000001,13.6 h -24 C 17.7906,13.6 16,15.3906 16,17.599999 16,19.809401 17.7906,21.6 20.000001,21.6 h 24 C 46.2094,21.6 48,19.809401 48,17.599999" /><path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path5452"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.16372061"
|
||||||
|
d="M 48,19.999999 C 48,17.7906 46.2094,16 44.000001,16 h -24 C 17.7906,16 16,17.7906 16,19.999999 16,22.209401 17.7906,24 20.000001,24 h 24 C 46.2094,24 48,22.209401 48,19.999999" /><path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="fill:#000000;fill-opacity:0.15686275;stroke-width:0.80000001"
|
||||||
|
id="path4575-7"
|
||||||
|
sodipodi:sides="3"
|
||||||
|
sodipodi:cx="32.203388"
|
||||||
|
sodipodi:cy="-39.322033"
|
||||||
|
sodipodi:r1="18.807909"
|
||||||
|
sodipodi:r2="9.4039545"
|
||||||
|
sodipodi:arg1="2.6179939"
|
||||||
|
sodipodi:arg2="3.6651914"
|
||||||
|
inkscape:flatsided="false"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 15.915261,-29.918079 8.144064,-14.105931 8.144064,-14.105932 8.144063,14.105932 8.144063,14.105932 -16.288127,0 z"
|
||||||
|
transform="matrix(0.98231064,0,0,0.85070592,0.36626977,79.051486)"
|
||||||
|
inkscape:transform-center-y="5.0000002" /><path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke-width:0.80000001"
|
||||||
|
id="path4575"
|
||||||
|
sodipodi:sides="3"
|
||||||
|
sodipodi:cx="32.203388"
|
||||||
|
sodipodi:cy="-39.322033"
|
||||||
|
sodipodi:r1="18.807909"
|
||||||
|
sodipodi:r2="9.4039545"
|
||||||
|
sodipodi:arg1="2.6179939"
|
||||||
|
sodipodi:arg2="3.6651914"
|
||||||
|
inkscape:flatsided="false"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 15.915261,-29.918079 8.144064,-14.105931 8.144064,-14.105932 8.144063,14.105932 8.144063,14.105932 -16.288127,0 z"
|
||||||
|
transform="matrix(0.98231061,0,0,0.85070593,0.36627025,81.451486)"
|
||||||
|
inkscape:transform-center-y="5.0000009" /></g></svg>
|
After Width: | Height: | Size: 4.1 KiB |
95
retroshare-gui/src/gui/icons/svg/undock.svg
Normal file
95
retroshare-gui/src/gui/icons/svg/undock.svg
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
id="svg4823"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
|
||||||
|
xml:space="preserve"
|
||||||
|
width="80"
|
||||||
|
height="80"
|
||||||
|
viewBox="0 0 80 80"
|
||||||
|
sodipodi:docname="undock.svg"
|
||||||
|
inkscape:export-filename="/home/phenom/GIT/RetroShare/trunk/retroshare-gui/src/gui/icons/png/undock.png"
|
||||||
|
inkscape:export-xdpi="153.60001"
|
||||||
|
inkscape:export-ydpi="153.60001"><metadata
|
||||||
|
id="metadata4829"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs4827" /><sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1015"
|
||||||
|
id="namedview4825"
|
||||||
|
showgrid="false"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
inkscape:zoom="8.34386"
|
||||||
|
inkscape:cx="-8.1326614"
|
||||||
|
inkscape:cy="38.591301"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="g4831" /><g
|
||||||
|
id="g4831"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
inkscape:label="ink_ext_XXXXXX"
|
||||||
|
transform="matrix(1.25,0,0,-1.25,0,80)"><path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4835"
|
||||||
|
style="fill:#039bd5;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||||
|
d="M 64,32 C 64,14.327 49.673,0 32,0 14.327,0 0,14.327 0,32 0,49.673 14.327,64 32,64 49.673,64 64,49.673 64,32" /><path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path5452-3"
|
||||||
|
style="fill:#000000;fill-opacity:0.15686275;fill-rule:nonzero;stroke:none;stroke-width:2.16372085"
|
||||||
|
d="M 48,17.599999 C 48,15.3906 46.2094,13.6 44.000001,13.6 h -24 C 17.7906,13.6 16,15.3906 16,17.599999 16,19.809401 17.7906,21.6 20.000001,21.6 h 24 C 46.2094,21.6 48,19.809401 48,17.599999" /><path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path5452"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.16372061"
|
||||||
|
d="M 48,19.999999 C 48,17.7906 46.2094,16 44.000001,16 h -24 C 17.7906,16 16,17.7906 16,19.999999 16,22.209401 17.7906,24 20.000001,24 h 24 C 46.2094,24 48,22.209401 48,19.999999" /><path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="fill:#000000;fill-opacity:0.15686275;stroke-width:0.80000001"
|
||||||
|
id="path4575-7"
|
||||||
|
sodipodi:sides="3"
|
||||||
|
sodipodi:cx="32.203388"
|
||||||
|
sodipodi:cy="-39.322033"
|
||||||
|
sodipodi:r1="18.807909"
|
||||||
|
sodipodi:r2="9.4039545"
|
||||||
|
sodipodi:arg1="2.6179939"
|
||||||
|
sodipodi:arg2="3.6651914"
|
||||||
|
inkscape:flatsided="false"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 15.915261,-29.918079 8.144064,-14.105931 8.144064,-14.105932 8.144063,14.105932 8.144063,14.105932 -16.288127,0 z"
|
||||||
|
transform="matrix(0.98231064,0,0,-0.85070592,0.36626977,4.1485139)"
|
||||||
|
inkscape:transform-center-y="-5.0000005" /><path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke-width:0.80000001"
|
||||||
|
id="path4575"
|
||||||
|
sodipodi:sides="3"
|
||||||
|
sodipodi:cx="32.203388"
|
||||||
|
sodipodi:cy="-39.322033"
|
||||||
|
sodipodi:r1="18.807909"
|
||||||
|
sodipodi:r2="9.4039545"
|
||||||
|
sodipodi:arg1="2.6179939"
|
||||||
|
sodipodi:arg2="3.6651914"
|
||||||
|
inkscape:flatsided="false"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 15.915261,-29.918079 8.144064,-14.105931 8.144064,-14.105932 8.144063,14.105932 8.144063,14.105932 -16.288127,0 z"
|
||||||
|
transform="matrix(0.98231061,0,0,-0.85070593,0.36627025,6.5485136)"
|
||||||
|
inkscape:transform-center-y="-5.0000005" /></g></svg>
|
After Width: | Height: | Size: 4.1 KiB |
Loading…
Reference in New Issue
Block a user