2019-04-11 14:58:59 +00:00
/*
2019-08-14 14:54:46 +00:00
* Squawk messenger .
2019-04-12 15:22:10 +00:00
* Copyright ( C ) 2019 Yury Gubich < blue @ macaw . me >
2019-04-11 14:58:59 +00:00
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program 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 General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "messageline.h"
2019-04-13 20:38:20 +00:00
# include <QDebug>
2019-09-05 23:44:20 +00:00
# include <cmath>
2019-04-11 14:58:59 +00:00
2019-08-29 14:19:35 +00:00
MessageLine : : MessageLine ( bool p_room , QWidget * parent ) :
2019-04-11 14:58:59 +00:00
QWidget ( parent ) ,
messageIndex ( ) ,
messageOrder ( ) ,
2019-09-10 14:33:39 +00:00
myMessages ( ) ,
palMessages ( ) ,
layout ( new QVBoxLayout ( this ) ) ,
2019-04-12 15:22:10 +00:00
myName ( ) ,
2019-04-13 20:38:20 +00:00
palNames ( ) ,
2019-08-28 11:40:55 +00:00
views ( ) ,
2019-09-05 15:25:31 +00:00
room ( p_room ) ,
2019-09-05 23:44:20 +00:00
busyPixmap ( new QGraphicsPixmapItem ( Shared : : icon ( " view-refresh " , true ) . pixmap ( 70 ) ) ) ,
busyScene ( ) ,
busyLabel ( & busyScene ) ,
2019-09-05 15:25:31 +00:00
busyLayout ( ) ,
busyShown ( false ) ,
rotation ( )
2019-04-11 14:58:59 +00:00
{
setBackgroundRole ( QPalette : : Base ) ;
2019-04-12 05:51:36 +00:00
layout - > addStretch ( ) ;
2019-09-05 15:25:31 +00:00
2019-09-05 23:44:20 +00:00
busyScene . addItem ( busyPixmap ) ;
2019-09-05 15:25:31 +00:00
busyLayout . addStretch ( ) ;
busyLayout . addWidget ( & busyLabel ) ;
busyLayout . addStretch ( ) ;
2019-09-05 23:44:20 +00:00
busyLabel . setMaximumSize ( 70 , 70 ) ;
busyLabel . setMinimumSize ( 70 , 70 ) ;
busyLabel . setSceneRect ( 0 , 0 , 70 , 70 ) ;
busyLabel . setFrameStyle ( 0 ) ;
busyLabel . setContentsMargins ( 0 , 0 , 0 , 0 ) ;
busyLabel . setInteractive ( false ) ;
busyPixmap - > setTransformOriginPoint ( 35 , 35 ) ;
busyPixmap - > setTransformationMode ( Qt : : SmoothTransformation ) ;
busyPixmap - > setOffset ( 0 , 0 ) ; ;
2019-09-05 15:25:31 +00:00
rotation . setDuration ( 500 ) ;
rotation . setStartValue ( 0.0f ) ;
rotation . setEndValue ( 180.0f ) ;
rotation . setLoopCount ( - 1 ) ;
connect ( & rotation , SIGNAL ( valueChanged ( const QVariant & ) ) , this , SLOT ( onAnimationValueChanged ( const QVariant & ) ) ) ;
2019-04-11 14:58:59 +00:00
}
MessageLine : : ~ MessageLine ( )
{
2019-04-13 20:38:20 +00:00
for ( Index : : const_iterator itr = messageIndex . begin ( ) , end = messageIndex . end ( ) ; itr ! = end ; + + itr ) {
delete itr - > second ;
}
2019-04-11 14:58:59 +00:00
}
2019-04-13 20:38:20 +00:00
MessageLine : : Position MessageLine : : message ( const Shared : : Message & msg )
2019-04-11 14:58:59 +00:00
{
2019-04-13 20:38:20 +00:00
QString id = msg . getId ( ) ;
Index : : iterator itr = messageIndex . find ( id ) ;
if ( itr ! = messageIndex . end ( ) ) {
qDebug ( ) < < " received more then one message with the same id, skipping yet the new one " ;
return invalid ;
}
2019-09-10 14:33:39 +00:00
QString sender ;
bool outgoing ;
if ( room ) {
if ( msg . getFromResource ( ) = = myName ) {
sender = myName ;
outgoing = false ;
} else {
sender = msg . getFromResource ( ) ;
outgoing = true ;
}
} else {
if ( msg . getOutgoing ( ) ) {
sender = myName ;
outgoing = false ;
} else {
QString jid = msg . getFromJid ( ) ;
std : : map < QString , QString > : : iterator itr = palNames . find ( jid ) ;
if ( itr ! = palNames . end ( ) ) {
sender = itr - > second ;
} else {
sender = jid ;
}
outgoing = true ;
}
}
Message * message = new Message ( msg , outgoing , sender ) ;
std : : pair < Order : : const_iterator , bool > result = messageOrder . insert ( std : : make_pair ( msg . getTime ( ) , message ) ) ;
2019-04-13 20:38:20 +00:00
if ( ! result . second ) {
qDebug ( ) < < " Error appending a message into a message list - seems like the time of that message exactly matches the time of some other message, can't put them in order, skipping yet " ;
2019-09-10 14:33:39 +00:00
delete message ;
2019-04-13 20:38:20 +00:00
return invalid ;
}
2019-09-10 14:33:39 +00:00
if ( outgoing ) {
if ( room ) {
} else {
QString jid = msg . getFromJid ( ) ;
std : : map < QString , Index > : : iterator pItr = palMessages . find ( jid ) ;
if ( pItr = = palMessages . end ( ) ) {
pItr = palMessages . insert ( std : : make_pair ( jid , Index ( ) ) ) . first ;
}
pItr - > second . insert ( std : : make_pair ( id , message ) ) ;
}
} else {
myMessages . insert ( std : : make_pair ( id , message ) ) ;
}
messageIndex . insert ( std : : make_pair ( id , message ) ) ;
2019-04-13 20:38:20 +00:00
int index = std : : distance < Order : : const_iterator > ( messageOrder . begin ( ) , result . first ) ; //need to make with binary indexed tree
Position res = invalid ;
if ( index = = 0 ) {
res = beggining ;
} else if ( index = = messageIndex . size ( ) - 1 ) {
res = end ;
} else {
res = middle ;
}
2019-09-05 15:25:31 +00:00
if ( busyShown ) {
index + = 1 ;
}
2019-08-28 11:40:55 +00:00
2019-04-13 20:38:20 +00:00
if ( res = = end ) {
2019-09-10 14:33:39 +00:00
layout - > addLayout ( message ) ;
2019-04-13 20:38:20 +00:00
} else {
2019-09-10 14:33:39 +00:00
layout - > insertLayout ( index , message ) ;
2019-04-13 20:38:20 +00:00
}
return res ;
2019-04-11 14:58:59 +00:00
}
2019-04-12 15:22:10 +00:00
void MessageLine : : setMyName ( const QString & name )
{
myName = name ;
2019-09-10 14:33:39 +00:00
for ( Index : : const_iterator itr = myMessages . begin ( ) , end = myMessages . end ( ) ; itr ! = end ; + + itr ) {
itr - > second - > setSender ( name ) ;
}
2019-04-12 15:22:10 +00:00
}
void MessageLine : : setPalName ( const QString & jid , const QString & name )
{
std : : map < QString , QString > : : iterator itr = palNames . find ( jid ) ;
if ( itr = = palNames . end ( ) ) {
palNames . insert ( std : : make_pair ( jid , name ) ) ;
} else {
itr - > second = name ;
}
2019-09-10 14:33:39 +00:00
std : : map < QString , Index > : : iterator pItr = palMessages . find ( jid ) ;
if ( pItr ! = palMessages . end ( ) ) {
for ( Index : : const_iterator itr = pItr - > second . begin ( ) , end = pItr - > second . end ( ) ; itr ! = end ; + + itr ) {
itr - > second - > setSender ( name ) ;
}
}
2019-04-12 15:22:10 +00:00
}
2019-04-13 20:38:20 +00:00
void MessageLine : : resizeEvent ( QResizeEvent * event )
{
QWidget : : resizeEvent ( event ) ;
emit resize ( event - > size ( ) . height ( ) - event - > oldSize ( ) . height ( ) ) ;
}
2019-05-15 17:36:37 +00:00
QString MessageLine : : firstMessageId ( ) const
{
if ( messageOrder . size ( ) = = 0 ) {
return " " ;
} else {
return messageOrder . begin ( ) - > second - > getId ( ) ;
}
}
2019-09-05 15:25:31 +00:00
void MessageLine : : showBusyIndicator ( )
{
if ( ! busyShown ) {
layout - > insertLayout ( 0 , & busyLayout ) ;
busyShown = true ;
rotation . start ( ) ;
busyLabel . show ( ) ;
}
}
void MessageLine : : hideBusyIndicator ( )
{
if ( busyShown ) {
busyLabel . hide ( ) ;
rotation . stop ( ) ;
layout - > removeItem ( & busyLayout ) ;
busyShown = false ;
}
}
void MessageLine : : onAnimationValueChanged ( const QVariant & value )
{
2019-09-05 23:44:20 +00:00
busyPixmap - > setRotation ( value . toReal ( ) ) ;
2019-09-05 15:25:31 +00:00
}