2009-01-30 14:52:47 -05:00
/****************************************************************
* RetroShare is distributed under the following license :
*
* Copyright ( C ) 2006 , crypton
*
* 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 2
* 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 , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor ,
* Boston , MA 02110 - 1301 , USA .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <QtGui>
2009-05-11 10:35:50 -04:00
# include <sys/stat.h>
2009-01-30 14:52:47 -05:00
# include "PopupChatDialog.h"
# include <QTextCodec>
# include <QTextEdit>
# include <QToolBar>
# include <QTextCursor>
# include <QTextList>
# include <QString>
# include <QtDebug>
# include <QIcon>
# include <QPixmap>
# include <QHashIterator>
2009-05-11 10:21:11 -04:00
# include <QDesktopServices>
2009-01-30 14:52:47 -05:00
# include "rsiface/rspeers.h"
# include "rsiface/rsmsgs.h"
2009-05-11 10:21:11 -04:00
# include "rsiface/rsfiles.h"
2010-01-25 09:35:32 -05:00
# include "gui/feeds/AttachFileItem.h"
2010-01-20 17:02:43 -05:00
# include <time.h>
2009-01-30 14:52:47 -05:00
# define appDir QApplication::applicationDirPath()
/* Define the format used for displaying the date and time */
# define DATETIME_FMT "MMM dd hh:mm:ss"
# include <sstream>
/*****
* # define CHAT_DEBUG 1
* * * * */
/** Default constructor */
PopupChatDialog : : PopupChatDialog ( std : : string id , std : : string name ,
QWidget * parent , Qt : : WFlags flags )
: QMainWindow ( parent , flags ) , dialogId ( id ) , dialogName ( name ) ,
lastChatTime ( 0 ) , lastChatName ( " " )
{
/* Invoke Qt Designer generated QObject setup routine */
ui . setupUi ( this ) ;
RshareSettings config ;
config . loadWidgetInformation ( this ) ;
2010-01-18 17:50:14 -05:00
this - > move ( qrand ( ) % 100 , qrand ( ) % 100 ) ; //avoid to stack multiple popup chat windows on the same position
2009-01-30 14:52:47 -05:00
loadEmoticons ( ) ;
2009-05-05 09:18:53 -04:00
last_status_send_time = 0 ;
2009-05-14 17:15:43 -04:00
styleHtm = " :/qss/chat/default.htm " ;
2009-01-30 14:52:47 -05:00
/* Hide Avatar frame */
showAvatarFrame ( false ) ;
connect ( ui . avatarFrameButton , SIGNAL ( toggled ( bool ) ) , this , SLOT ( showAvatarFrame ( bool ) ) ) ;
connect ( ui . actionAvatar , SIGNAL ( triggered ( ) ) , this , SLOT ( getAvatar ( ) ) ) ;
connect ( ui . chattextEdit , SIGNAL ( textChanged ( ) ) , this , SLOT ( checkChat ( ) ) ) ;
connect ( ui . sendButton , SIGNAL ( clicked ( ) ) , this , SLOT ( sendChat ( ) ) ) ;
2009-05-11 10:21:11 -04:00
connect ( ui . addFileButton , SIGNAL ( clicked ( ) ) , this , SLOT ( addExtraFile ( ) ) ) ;
2009-01-30 14:52:47 -05:00
connect ( ui . textboldButton , SIGNAL ( clicked ( ) ) , this , SLOT ( setFont ( ) ) ) ;
connect ( ui . textunderlineButton , SIGNAL ( clicked ( ) ) , this , SLOT ( setFont ( ) ) ) ;
connect ( ui . textitalicButton , SIGNAL ( clicked ( ) ) , this , SLOT ( setFont ( ) ) ) ;
connect ( ui . fontButton , SIGNAL ( clicked ( ) ) , this , SLOT ( getFont ( ) ) ) ;
connect ( ui . colorButton , SIGNAL ( clicked ( ) ) , this , SLOT ( setColor ( ) ) ) ;
connect ( ui . emoteiconButton , SIGNAL ( clicked ( ) ) , this , SLOT ( smileyWidget ( ) ) ) ;
connect ( ui . styleButton , SIGNAL ( clicked ( ) ) , SLOT ( changeStyle ( ) ) ) ;
2009-05-11 10:21:11 -04:00
connect ( ui . textBrowser , SIGNAL ( anchorClicked ( const QUrl & ) ) , SLOT ( anchorClicked ( const QUrl & ) ) ) ;
2009-01-30 14:52:47 -05:00
// Create the status bar
2009-05-05 09:18:53 -04:00
resetStatusBar ( ) ;
2010-02-07 07:36:37 -05:00
//ui.textBrowser->setOpenExternalLinks ( false );
//ui.textBrowser->setOpenLinks ( false );
2009-01-30 14:52:47 -05:00
QString title = QString : : fromStdString ( name ) + " : " + tr ( " RetroShare - Encrypted Chat " ) ;
setWindowTitle ( title ) ;
2009-09-07 09:59:38 -04:00
2009-01-30 14:52:47 -05:00
setWindowIcon ( QIcon ( QString ( " :/images/rstray3.png " ) ) ) ;
ui . textboldButton - > setIcon ( QIcon ( QString ( " :/images/edit-bold.png " ) ) ) ;
ui . textunderlineButton - > setIcon ( QIcon ( QString ( " :/images/edit-underline.png " ) ) ) ;
ui . textitalicButton - > setIcon ( QIcon ( QString ( " :/images/edit-italic.png " ) ) ) ;
ui . fontButton - > setIcon ( QIcon ( QString ( " :/images/fonts.png " ) ) ) ;
ui . emoteiconButton - > setIcon ( QIcon ( QString ( " :/images/emoticons/kopete/kopete020.png " ) ) ) ;
ui . styleButton - > setIcon ( QIcon ( QString ( " :/images/looknfeel.png " ) ) ) ;
ui . textboldButton - > setCheckable ( true ) ;
ui . textunderlineButton - > setCheckable ( true ) ;
ui . textitalicButton - > setCheckable ( true ) ;
2009-05-11 10:27:45 -04:00
setAcceptDrops ( true ) ;
ui . chattextEdit - > setAcceptDrops ( false ) ;
2009-01-30 14:52:47 -05:00
/*Disabled style Button when will switch chat style RetroShare will crash need to be fix */
//ui.styleButton->setEnabled(false);
2009-09-07 09:59:38 -04:00
2009-01-30 14:52:47 -05:00
mCurrentColor = Qt : : black ;
mCurrentFont = QFont ( " Comic Sans MS " , 10 ) ;
colorChanged ( mCurrentColor ) ;
setFont ( ) ;
updateAvatar ( ) ;
updatePeerAvatar ( id ) ;
}
2009-05-05 09:18:53 -04:00
void PopupChatDialog : : resetStatusBar ( )
{
2010-01-18 17:50:14 -05:00
statusBar ( ) - > showMessage ( tr ( " Chatting with " ) + QString : : fromStdString ( dialogName ) ) ;
2009-05-05 09:18:53 -04:00
}
void PopupChatDialog : : updateStatusTyping ( )
{
if ( time ( NULL ) - last_status_send_time > 5 ) // limit 'peer is typing' packets to at most every 10 sec
{
rsMsgs - > sendStatusString ( dialogId , rsiface - > getConfig ( ) . ownName + " is typing... " ) ;
last_status_send_time = time ( NULL ) ;
}
}
// Called by libretroshare through notifyQt to display the peer's status
//
void PopupChatDialog : : updateStatusString ( const QString & status_string )
{
2009-05-14 17:15:43 -04:00
statusBar ( ) - > showMessage ( status_string , 5000 ) ; // displays info for 5 secs.
2009-05-05 09:18:53 -04:00
2009-05-14 17:15:43 -04:00
QTimer : : singleShot ( 5000 , this , SLOT ( resetStatusBar ( ) ) ) ;
2009-05-05 09:18:53 -04:00
}
2009-01-30 14:52:47 -05:00
/** Destructor. */
PopupChatDialog : : ~ PopupChatDialog ( )
{
}
/**
Overloads the default show ( ) slot so we can set opacity */
void PopupChatDialog : : show ( )
{
if ( ! this - > isVisible ( ) ) {
QMainWindow : : show ( ) ;
} else {
//QMainWindow::activateWindow();
//setWindowState(windowState() & ~Qt::WindowMinimized | Qt::WindowActive);
//QMainWindow::raise();
}
}
void PopupChatDialog : : getfocus ( )
{
QMainWindow : : activateWindow ( ) ;
setWindowState ( ( windowState ( ) & ( ~ Qt : : WindowMinimized ) ) | Qt : : WindowActive ) ;
QMainWindow : : raise ( ) ;
}
void PopupChatDialog : : flash ( )
{
if ( ! this - > isVisible ( ) ) {
//QMainWindow::show();
} else {
// Want to reduce the interference on other applications.
//QMainWindow::activateWindow();
//setWindowState(windowState() & ~Qt::WindowMinimized | Qt::WindowActive);
//QMainWindow::raise();
}
}
void PopupChatDialog : : closeEvent ( QCloseEvent * event )
{
RshareSettings config ;
config . saveWidgetInformation ( this ) ;
hide ( ) ;
event - > ignore ( ) ;
}
void PopupChatDialog : : updateChat ( )
{
/* get chat off queue */
/* write it out */
}
void PopupChatDialog : : addChatMsg ( ChatInfo * ci )
{
bool offline = true ;
{
RsPeerDetails detail ;
if ( ! rsPeers - > getPeerDetails ( dialogId , detail ) )
{
# ifdef CHAT_DEBUG
std : : cerr < < " WARNING CANNOT GET PEER INFO!!!! " < < std : : endl ;
# endif
}
else if ( detail . state & RS_PEER_STATE_CONNECTED )
{
offline = false ;
}
}
if ( offline )
{
QString offlineMsg = " <br> \n <span style= \" color:#1D84C9 \" ><strong> ----- PEER OFFLINE (Chat will be lost) -----</strong></span> \n <br> " ;
2010-01-02 16:46:20 -05:00
ui . textBrowser - > append ( offlineMsg ) ;
2009-01-30 14:52:47 -05:00
}
QString timestamp = " [ " + QDateTime : : currentDateTime ( ) . toString ( " hh:mm:ss " ) + " ] " ;
QString name = QString : : fromStdString ( ci - > name ) ;
QString message = QString : : fromStdWString ( ci - > msg ) ;
2009-11-28 12:52:17 -05:00
//replace http://, https:// and www. with <a href> links
QRegExp rx ( " (https?://[^ <>]*) | ( www \ \ . [ ^ < > ] * ) " ) ;
2009-05-14 11:54:38 -04:00
int count = 0 ;
2010-02-07 07:36:37 -05:00
int pos = 100 ; //ignore the first 100 char because of the standard DTD ref
2009-05-14 11:54:38 -04:00
while ( ( pos = rx . indexIn ( message , pos ) ) ! = - 1 ) {
//we need to look ahead to see if it's already a well formed link
if ( message . mid ( pos - 6 , 6 ) ! = " href= \" " & & message . mid ( pos - 6 , 6 ) ! = " href=' " & & message . mid ( pos - 6 , 6 ) ! = " ttp:// " ) {
QString tempMessg = message . left ( pos ) + " <a href= \" " + rx . cap ( count ) + " \" > " + rx . cap ( count ) + " </a> " + message . mid ( pos + rx . matchedLength ( ) , - 1 ) ;
message = tempMessg ;
}
pos + = rx . matchedLength ( ) + 15 ;
2010-02-07 07:36:37 -05:00
count + + ;
}
2009-05-11 10:21:11 -04:00
# ifdef CHAT_DEBUG
std : : cout < < " PopupChatDialog:addChatMsg message : " < < message . toStdString ( ) < < std : : endl ;
# endif
2009-01-30 14:52:47 -05:00
QHashIterator < QString , QString > i ( smileys ) ;
while ( i . hasNext ( ) )
{
i . next ( ) ;
foreach ( QString code , i . key ( ) . split ( " | " ) )
message . replace ( code , " <img src= \" " + i . value ( ) + " \" /> " ) ;
}
history /*<< nickColor << color << font << fontSize*/ < < timestamp < < name < < message ;
QString formatMsg = loadEmptyStyle ( ) /*.replace(nickColor)
. replace ( color )
. replace ( font )
. replace ( fontSize ) */
. replace ( " %timestamp% " , timestamp )
. replace ( " %name% " , name )
. replace ( " %message% " , message ) ;
2009-11-27 17:05:38 -05:00
if ( ( ui . textBrowser - > verticalScrollBar ( ) - > maximum ( ) - 30 ) < ui . textBrowser - > verticalScrollBar ( ) - > value ( ) ) {
ui . textBrowser - > append ( formatMsg + " \n " ) ;
} else {
//the vertical scroll is not at the bottom, so just update the text, the scroll will stay at the current position
int scroll = ui . textBrowser - > verticalScrollBar ( ) - > value ( ) ;
ui . textBrowser - > setHtml ( ui . textBrowser - > toHtml ( ) + formatMsg + " \n " ) ;
ui . textBrowser - > verticalScrollBar ( ) - > setValue ( scroll ) ;
ui . textBrowser - > update ( ) ;
}
2009-05-14 17:15:43 -04:00
resetStatusBar ( ) ;
2009-01-30 14:52:47 -05:00
}
void PopupChatDialog : : checkChat ( )
{
/* if <return> at the end of the text -> we can send it! */
2009-05-05 09:18:53 -04:00
QTextEdit * chatWidget = ui . chattextEdit ;
std : : string txt = chatWidget - > toPlainText ( ) . toStdString ( ) ;
if ( ' \n ' = = txt [ txt . length ( ) - 1 ] & & txt . length ( ) - 1 = = txt . find ( ' \n ' ) ) /* only if on first line! */
sendChat ( ) ;
2009-01-30 14:52:47 -05:00
else
2009-05-05 09:18:53 -04:00
updateStatusTyping ( ) ;
2009-01-30 14:52:47 -05:00
}
void PopupChatDialog : : sendChat ( )
{
2009-05-11 10:21:11 -04:00
QTextEdit * chatWidget = ui . chattextEdit ;
2009-01-30 14:52:47 -05:00
ChatInfo ci ;
{
rsiface - > lockData ( ) ; /* Lock Interface */
const RsConfig & conf = rsiface - > getConfig ( ) ;
ci . rsid = conf . ownId ;
ci . name = conf . ownName ;
rsiface - > unlockData ( ) ; /* Unlock Interface */
}
ci . msg = chatWidget - > toHtml ( ) . toStdWString ( ) ;
ci . chatflags = RS_CHAT_PRIVATE ;
# ifdef CHAT_DEBUG
std : : cout < < " PopupChatDialog:sendChat " < < styleHtm . toStdString ( ) < < std : : endl ;
# endif
addChatMsg ( & ci ) ;
/* put proper destination */
ci . rsid = dialogId ;
ci . name = dialogName ;
rsMsgs - > ChatSend ( ci ) ;
chatWidget - > clear ( ) ;
setFont ( ) ;
/* redraw send list */
}
/**
Toggles the ToolBox on and off , changes toggle button text
*/
void PopupChatDialog : : showAvatarFrame ( bool show )
{
if ( show ) {
ui . avatarframe - > setVisible ( true ) ;
ui . avatarFrameButton - > setChecked ( true ) ;
ui . avatarFrameButton - > setToolTip ( tr ( " Hide Avatar " ) ) ;
ui . avatarFrameButton - > setIcon ( QIcon ( tr ( " :images/hide_toolbox_frame.png " ) ) ) ;
} else {
ui . avatarframe - > setVisible ( false ) ;
ui . avatarFrameButton - > setChecked ( false ) ;
ui . avatarFrameButton - > setToolTip ( tr ( " Show Avatar " ) ) ;
ui . avatarFrameButton - > setIcon ( QIcon ( tr ( " :images/show_toolbox_frame.png " ) ) ) ;
}
}
void PopupChatDialog : : setColor ( )
{
bool ok ;
QRgb color = QColorDialog : : getRgba ( ui . chattextEdit - > textColor ( ) . rgba ( ) , & ok , this ) ;
if ( ok ) {
mCurrentColor = QColor ( color ) ;
colorChanged ( mCurrentColor ) ;
}
setFont ( ) ;
}
void PopupChatDialog : : colorChanged ( const QColor & c )
{
QPixmap pix ( 16 , 16 ) ;
pix . fill ( c ) ;
ui . colorButton - > setIcon ( pix ) ;
}
void PopupChatDialog : : getFont ( )
{
bool ok ;
mCurrentFont = QFontDialog : : getFont ( & ok , mCurrentFont , this ) ;
setFont ( ) ;
}
void PopupChatDialog : : setFont ( )
{
mCurrentFont . setBold ( ui . textboldButton - > isChecked ( ) ) ;
mCurrentFont . setUnderline ( ui . textunderlineButton - > isChecked ( ) ) ;
mCurrentFont . setItalic ( ui . textitalicButton - > isChecked ( ) ) ;
ui . chattextEdit - > setFont ( mCurrentFont ) ;
ui . chattextEdit - > setTextColor ( mCurrentColor ) ;
ui . chattextEdit - > setFocus ( ) ;
}
void PopupChatDialog : : loadEmoticons2 ( )
{
QDir smdir ( QApplication : : applicationDirPath ( ) + " /emoticons/kopete " ) ;
//QDir smdir(":/gui/images/emoticons/kopete");
QFileInfoList sminfo = smdir . entryInfoList ( QStringList ( ) < < " *.gif " < < " *.png " , QDir : : Files , QDir : : Name ) ;
foreach ( QFileInfo info , sminfo )
{
QString smcode = info . fileName ( ) . replace ( " .gif " , " " ) ;
QString smstring ;
for ( int i = 0 ; i < 9 ; i + = 3 )
{
smstring + = QString ( ( char ) smcode . mid ( i , 3 ) . toInt ( ) ) ;
}
//qDebug(smstring.toAscii());
smileys . insert ( smstring , info . absoluteFilePath ( ) ) ;
}
}
void PopupChatDialog : : loadEmoticons ( )
{
QString sm_codes ;
# if defined(Q_OS_WIN32)
QFile sm_file ( QApplication : : applicationDirPath ( ) + " /emoticons/emotes.acs " ) ;
# else
QFile sm_file ( QString ( " :/smileys/emotes.acs " ) ) ;
# endif
if ( ! sm_file . open ( QIODevice : : ReadOnly ) )
{
std : : cout < < " error opening ressource file " < < std : : endl ;
return ;
}
sm_codes = sm_file . readAll ( ) ;
sm_file . close ( ) ;
sm_codes . remove ( " \n " ) ;
sm_codes . remove ( " \r " ) ;
int i = 0 ;
QString smcode ;
QString smfile ;
while ( sm_codes [ i ] ! = ' { ' )
{
i + + ;
}
while ( i < sm_codes . length ( ) - 2 )
{
smcode = " " ;
smfile = " " ;
while ( sm_codes [ i ] ! = ' \" ' )
{
i + + ;
}
i + + ;
while ( sm_codes [ i ] ! = ' \" ' )
{
smcode + = sm_codes [ i ] ;
i + + ;
}
i + + ;
while ( sm_codes [ i ] ! = ' \" ' )
{
i + + ;
}
i + + ;
while ( sm_codes [ i ] ! = ' \" ' & & sm_codes [ i + 1 ] ! = ' ; ' )
{
smfile + = sm_codes [ i ] ;
i + + ;
}
i + + ;
if ( ! smcode . isEmpty ( ) & & ! smfile . isEmpty ( ) )
# if defined(Q_OS_WIN32)
2009-01-25 13:25:36 -05:00
smileys . insert ( smcode , smfile ) ;
2009-01-30 14:52:47 -05:00
# else
smileys . insert ( smcode , " :/ " + smfile ) ;
2009-01-25 13:25:36 -05:00
# endif
2009-01-30 14:52:47 -05:00
}
}
2009-03-12 13:57:30 -04:00
//============================================================================
2009-01-30 14:52:47 -05:00
void PopupChatDialog : : smileyWidget ( )
{
qDebug ( " MainWindow::smileyWidget() " ) ;
2009-03-12 13:57:30 -04:00
QWidget * smWidget = new QWidget ( this , Qt : : Popup ) ;
smWidget - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
2009-01-30 14:52:47 -05:00
smWidget - > setWindowTitle ( " Emoticons " ) ;
smWidget - > setWindowIcon ( QIcon ( QString ( " :/images/rstray3.png " ) ) ) ;
2009-03-12 13:57:30 -04:00
smWidget - > setBaseSize ( 4 * 24 , ( smileys . size ( ) / 4 ) * 24 ) ;
//Warning: this part of code was taken from kadu instant messenger;
// It was EmoticonSelector::alignTo(QWidget* w) function there
// comments are Polish, I dont' know how does it work...
// oblicz pozycj<63> widgetu do kt<6B> rego r<> wnamy
QWidget * w = ui . emoteiconButton ;
QPoint w_pos = w - > mapToGlobal ( QPoint ( 0 , 0 ) ) ;
// oblicz rozmiar selektora
QSize e_size = smWidget - > sizeHint ( ) ;
// oblicz rozmiar pulpitu
QSize s_size = QApplication : : desktop ( ) - > size ( ) ;
// oblicz dystanse od widgetu do lewego brzegu i do prawego
int l_dist = w_pos . x ( ) ;
int r_dist = s_size . width ( ) - ( w_pos . x ( ) + w - > width ( ) ) ;
// oblicz pozycj<63> w zale<6C> no<6E> ci od tego czy po lewej stronie
// jest wi<77> cej miejsca czy po prawej
int x ;
if ( l_dist > = r_dist )
x = w_pos . x ( ) - e_size . width ( ) ;
else
x = w_pos . x ( ) + w - > width ( ) ;
// oblicz pozycj<63> y - centrujemy w pionie
int y = w_pos . y ( ) + w - > height ( ) / 2 - e_size . height ( ) / 2 ;
// je<6A> li wychodzi poza doln<6C> kraw<61> d<EFBFBD> to r<> wnamy do niej
if ( y + e_size . height ( ) > s_size . height ( ) )
y = s_size . height ( ) - e_size . height ( ) ;
// je<6A> li wychodzi poza g<> rn<72> kraw<61> d<EFBFBD> to r<> wnamy do niej
if ( y < 0 )
y = 0 ;
// ustawiamy selektor na wyliczonej pozycji
smWidget - > move ( x , y ) ;
2009-01-30 14:52:47 -05:00
2009-03-12 13:57:30 -04:00
x = 0 ;
y = 0 ;
2009-01-30 14:52:47 -05:00
QHashIterator < QString , QString > i ( smileys ) ;
while ( i . hasNext ( ) )
{
i . next ( ) ;
QPushButton * smButton = new QPushButton ( " " , smWidget ) ;
smButton - > setGeometry ( x * 24 , y * 24 , 24 , 24 ) ;
smButton - > setIconSize ( QSize ( 24 , 24 ) ) ;
smButton - > setIcon ( QPixmap ( i . value ( ) ) ) ;
smButton - > setToolTip ( i . key ( ) ) ;
+ + x ;
if ( x > 4 )
{
x = 0 ;
y + + ;
}
connect ( smButton , SIGNAL ( clicked ( ) ) , this , SLOT ( addSmiley ( ) ) ) ;
2009-03-12 13:57:30 -04:00
connect ( smButton , SIGNAL ( clicked ( ) ) , smWidget , SLOT ( close ( ) ) ) ;
2009-01-30 14:52:47 -05:00
}
smWidget - > show ( ) ;
}
2009-03-12 13:57:30 -04:00
//============================================================================
2009-01-30 14:52:47 -05:00
void PopupChatDialog : : addSmiley ( )
{
ui . chattextEdit - > setText ( ui . chattextEdit - > toHtml ( ) + qobject_cast < QPushButton * > ( sender ( ) ) - > toolTip ( ) . split ( " | " ) . first ( ) ) ;
}
2009-03-12 13:57:30 -04:00
//============================================================================
2009-01-30 14:52:47 -05:00
QString PopupChatDialog : : loadEmptyStyle ( )
{
# ifdef CHAT_DEBUG
std : : cout < < " PopupChatDialog:loadEmptyStyle " < < styleHtm . toStdString ( ) < < std : : endl ;
# endif
QString ret ;
QFile file ( styleHtm ) ;
//file.open(QIODevice::ReadOnly);
if ( file . open ( QIODevice : : ReadOnly ) ) {
ret = file . readAll ( ) ;
file . close ( ) ;
QString styleTmp = styleHtm ;
QString styleCss = styleTmp . remove ( styleHtm . lastIndexOf ( " . " ) , styleHtm . length ( ) - styleHtm . lastIndexOf ( " . " ) ) + " .css " ;
qDebug ( ) < < styleCss . toAscii ( ) ;
QFile css ( styleCss ) ;
QString tmp ;
if ( css . open ( QIODevice : : ReadOnly ) ) {
tmp = css . readAll ( ) ;
css . close ( ) ;
}
else {
# ifdef CHAT_DEBUG
std : : cerr < < " PopupChatDialog:loadEmptyStyle " < < " Missing file of default css " < < std : : endl ;
# endif
tmp = " " ;
}
ret . replace ( " %css-style% " , tmp ) ;
return ret ;
}
else {
# ifdef CHAT_DEBUG
std : : cerr < < " PopupChatDialog:loadEmptyStyle " < < " Missing file of default style " < < std : : endl ;
# endif
ret = " %timestamp% %name% \n %message% " ;
return ret ;
}
}
void PopupChatDialog : : changeStyle ( )
{
QString newStyle = QFileDialog : : getOpenFileName ( this , tr ( " Open Style " ) ,
appDir + " /style/chat/ " ,
tr ( " Styles (*.htm) " ) ) ;
if ( ! newStyle . isEmpty ( ) )
{
QString wholeChat ;
styleHtm = newStyle ;
for ( int i = 0 ; i < history . size ( ) ; i + = 4 )
{
QString formatMsg = loadEmptyStyle ( ) ;
wholeChat + = formatMsg . replace ( " %timestamp% " , history . at ( i + 1 ) )
. replace ( " %name% " , history . at ( i + 2 ) )
. replace ( " %message% " , history . at ( i + 3 ) ) + " \n " ;
}
ui . textBrowser - > setHtml ( wholeChat ) ;
}
QTextCursor cursor = ui . textBrowser - > textCursor ( ) ;
cursor . movePosition ( QTextCursor : : End ) ;
ui . textBrowser - > setTextCursor ( cursor ) ;
}
void PopupChatDialog : : updatePeerAvatar ( const std : : string & peer_id )
{
2009-09-30 16:53:18 -04:00
std : : cerr < < " popupchatDialog: updating avatar for peer " < < peer_id < < std : : endl ;
2009-01-30 14:52:47 -05:00
unsigned char * data = NULL ;
int size = 0 ;
std : : cerr < < " Requesting avatar image for peer " < < peer_id < < std : : endl ;
rsMsgs - > getAvatarData ( peer_id , data , size ) ;
std : : cerr < < " Image size = " < < size < < std : : endl ;
if ( size = = 0 )
{
std : : cerr < < " Got no image " < < std : : endl ;
2010-02-05 14:30:18 -05:00
ui . avatarlabel - > setPixmap ( QPixmap ( " :/images/no_avatar_70.png " ) ) ;
2009-01-30 14:52:47 -05:00
return ;
}
// set the image
QPixmap pix ;
2009-09-30 16:53:18 -04:00
pix . loadFromData ( data , size , " PNG " ) ;
2009-01-30 14:52:47 -05:00
ui . avatarlabel - > setPixmap ( pix ) ; // writes image into ba in JPG format
delete [ ] data ;
}
void PopupChatDialog : : updateAvatar ( )
{
unsigned char * data = NULL ;
int size = 0 ;
rsMsgs - > getOwnAvatarData ( data , size ) ;
std : : cerr < < " Image size = " < < size < < std : : endl ;
if ( size = = 0 )
std : : cerr < < " Got no image " < < std : : endl ;
// set the image
QPixmap pix ;
2009-09-07 09:59:38 -04:00
pix . loadFromData ( data , size , " PNG " ) ;
ui . myavatarlabel - > setPixmap ( pix ) ; // writes image into ba in PNGformat
2009-01-30 14:52:47 -05:00
delete [ ] data ;
}
void PopupChatDialog : : getAvatar ( )
{
QString fileName = QFileDialog : : getOpenFileName ( this , " Load File " , QDir : : homePath ( ) , " Pictures (*.png *.xpm *.jpg) " ) ;
2009-03-01 10:18:34 -05:00
2009-01-30 14:52:47 -05:00
if ( ! fileName . isEmpty ( ) )
{
2009-05-15 10:31:37 -04:00
picture = QPixmap ( fileName ) . scaled ( 82 , 82 , Qt : : IgnoreAspectRatio , Qt : : SmoothTransformation ) ;
2009-01-30 14:52:47 -05:00
std : : cerr < < " Sending avatar image down the pipe " < < std : : endl ;
// send avatar down the pipe for other peers to get it.
QByteArray ba ;
QBuffer buffer ( & ba ) ;
buffer . open ( QIODevice : : WriteOnly ) ;
2009-09-07 09:59:38 -04:00
picture . save ( & buffer , " PNG " ) ; // writes image into ba in PNG format
2009-01-30 14:52:47 -05:00
std : : cerr < < " Image size = " < < ba . size ( ) < < std : : endl ;
rsMsgs - > setOwnAvatarData ( ( unsigned char * ) ( ba . data ( ) ) , ba . size ( ) ) ; // last char 0 included.
updateAvatar ( ) ;
}
}
2009-05-11 10:21:11 -04:00
void PopupChatDialog : : addExtraFile ( )
{
// select a file
QString qfile = QFileDialog : : getOpenFileName ( this , tr ( " Add Extra File " ) , " " , " " , 0 ,
QFileDialog : : DontResolveSymlinks ) ;
std : : string filePath = qfile . toStdString ( ) ;
if ( filePath ! = " " )
{
2009-05-11 10:27:45 -04:00
PopupChatDialog : : addAttachment ( filePath ) ;
}
}
void PopupChatDialog : : addAttachment ( std : : string filePath ) {
2010-01-25 09:35:32 -05:00
/* add a AttachFileItem to the attachment section */
2009-05-11 10:21:11 -04:00
std : : cerr < < " PopupChatDialog::addExtraFile() hashing file. " ;
std : : cerr < < std : : endl ;
/* add widget in for new destination */
2010-01-25 09:35:32 -05:00
AttachFileItem * file = new AttachFileItem ( filePath ) ;
2009-05-11 10:21:11 -04:00
//file->
ui . vboxLayout - > addWidget ( file , 1 , 0 ) ;
//when the file is local or is finished hashing, call the fileHashingFinished method to send a chat message
2010-01-25 09:35:32 -05:00
if ( file - > getState ( ) = = AFI_STATE_LOCAL ) {
2009-05-11 10:21:11 -04:00
fileHashingFinished ( file ) ;
} else {
2010-01-25 09:35:32 -05:00
QObject : : connect ( file , SIGNAL ( fileFinished ( AttachFileItem * ) ) , SLOT ( fileHashingFinished ( AttachFileItem * ) ) ) ;
2009-05-11 10:21:11 -04:00
}
}
2010-01-25 09:35:32 -05:00
void PopupChatDialog : : fileHashingFinished ( AttachFileItem * file ) {
2009-05-11 10:21:11 -04:00
std : : cerr < < " PopupChatDialog::fileHashingFinished() started. " ;
std : : cerr < < std : : endl ;
2009-05-14 11:54:38 -04:00
//check that the file is ok tos end
2010-01-25 09:35:32 -05:00
if ( file - > getState ( ) = = AFI_STATE_ERROR ) {
2009-05-14 11:54:38 -04:00
# ifdef CHAT_DEBUG
std : : cerr < < " PopupChatDialog::fileHashingFinished error file is not hashed. " ;
# endif
return ;
}
2009-05-11 10:21:11 -04:00
ChatInfo ci ;
{
rsiface - > lockData ( ) ; /* Lock Interface */
const RsConfig & conf = rsiface - > getConfig ( ) ;
ci . rsid = conf . ownId ;
ci . name = conf . ownName ;
rsiface - > unlockData ( ) ; /* Unlock Interface */
}
//convert fileSize from uint_64 to string for html link
char fileSizeChar [ 100 ] ;
sprintf ( fileSizeChar , " %lld " , file - > FileSize ( ) ) ;
std : : string fileSize = * ( & fileSizeChar ) ;
std : : string mesgString = " <a href='file:?fileHash= " + ( file - > FileHash ( ) ) + " &fileName= " + ( file - > FileName ( ) ) + " &fileSize= " + fileSize + " '> " + ( file - > FileName ( ) ) + " </a> " ;
# ifdef CHAT_DEBUG
2009-05-14 11:54:38 -04:00
std : : cerr < < " PopupChatDialog::anchorClicked mesgString : " < < mesgString < < std : : endl ;
2009-05-11 10:21:11 -04:00
# endif
const char * messageString = mesgString . c_str ( ) ;
//convert char massageString to w_char
wchar_t * message ;
2009-05-14 11:54:38 -04:00
int requiredSize = mbstowcs ( NULL , messageString , 0 ) ; // C4996
/* Add one to leave room for the NULL terminator */
message = ( wchar_t * ) malloc ( ( requiredSize + 1 ) * sizeof ( wchar_t ) ) ;
if ( ! message ) {
std : : cerr < < ( " Memory allocation failure. \n " ) ;
}
int size = mbstowcs ( message , messageString , requiredSize + 1 ) ; // C4996
if ( size = = ( size_t ) ( - 1 ) ) {
printf ( " Couldn't convert string--invalid multibyte character. \n " ) ;
}
2009-05-11 10:21:11 -04:00
ci . msg = message ;
ci . chatflags = RS_CHAT_PRIVATE ;
addChatMsg ( & ci ) ;
/* put proper destination */
ci . rsid = dialogId ;
ci . name = dialogName ;
rsMsgs - > ChatSend ( ci ) ;
}
void PopupChatDialog : : anchorClicked ( const QUrl & link ) {
2010-01-16 10:42:26 -05:00
# ifdef CHAT_DEBUG
std : : cerr < < " PopupChatDialog::anchorClicked link.scheme() : " < < link . scheme ( ) . toStdString ( ) < < std : : endl ;
# endif
2009-05-11 10:21:11 -04:00
if ( link . scheme ( ) = = " file " ) {
2010-01-16 10:42:26 -05:00
std : : string fileName = link . queryItemValue ( QString ( " fileName " ) ) . toStdString ( ) ;
std : : string fileHash = link . queryItemValue ( QString ( " fileHash " ) ) . toStdString ( ) ;
uint32_t fileSize = link . queryItemValue ( QString ( " fileSize " ) ) . toInt ( ) ;
# ifdef CHAT_DEBUG
std : : cerr < < " PopupChatDialog::anchorClicked FileRequest : fileName : " < < fileName < < " . fileHash : " < < fileHash < < " . fileSize : " < < fileSize ;
std : : cerr < < " . source id : " < < dialogId < < std : : endl ;
# endif
if ( fileName ! = " " & &
fileHash ! = " " ) {
std : : list < std : : string > srcIds ;
srcIds . push_front ( dialogId ) ;
if ( rsFiles - > FileRequest ( fileName , fileHash , fileSize , " " , RS_FILE_HINTS_ASSUME_AVAILABILITY , srcIds ) )
{
QMessageBox mb ( tr ( " File Request Confirmation " ) , tr ( " The file has been added to your download list. " ) , QMessageBox : : Information , QMessageBox : : Ok , 0 , 0 ) ;
mb . setButtonText ( QMessageBox : : Ok , " OK " ) ;
mb . exec ( ) ;
}
else
{
QMessageBox mb ( tr ( " File Request canceled " ) , tr ( " The file has not been added to your download list, because you already have it, or you're already downloading it. " ) , QMessageBox : : Information , QMessageBox : : Ok , 0 , 0 ) ;
mb . setButtonText ( QMessageBox : : Ok , " OK " ) ;
mb . exec ( ) ;
}
}
else
{
QMessageBox mb ( tr ( " File Request Error " ) , tr ( " The file link is malformed. " ) , QMessageBox : : Information , QMessageBox : : Ok , 0 , 0 ) ;
mb . setButtonText ( QMessageBox : : Ok , " OK " ) ;
mb . exec ( ) ;
}
}
else if ( link . scheme ( ) = = " http " )
QDesktopServices : : openUrl ( link ) ;
else if ( link . scheme ( ) = = " " )
{
//it's probably a web adress, let's add http:// at the beginning of the link
QString newAddress = link . toString ( ) ;
newAddress . prepend ( " http:// " ) ;
QDesktopServices : : openUrl ( QUrl ( newAddress ) ) ;
2009-05-11 10:21:11 -04:00
}
}
2009-05-11 10:27:45 -04:00
void PopupChatDialog : : dropEvent ( QDropEvent * event )
{
if ( ! ( Qt : : CopyAction & event - > possibleActions ( ) ) )
{
std : : cerr < < " PopupChatDialog::dropEvent() Rejecting uncopyable DropAction " ;
std : : cerr < < std : : endl ;
/* can't do it */
return ;
}
std : : cerr < < " PopupChatDialog::dropEvent() Formats " ;
std : : cerr < < std : : endl ;
QStringList formats = event - > mimeData ( ) - > formats ( ) ;
QStringList : : iterator it ;
for ( it = formats . begin ( ) ; it ! = formats . end ( ) ; it + + )
{
std : : cerr < < " Format: " < < ( * it ) . toStdString ( ) ;
std : : cerr < < std : : endl ;
}
if ( event - > mimeData ( ) - > hasUrls ( ) )
{
2009-05-11 10:35:50 -04:00
std : : cerr < < " PopupChatDialog::dropEvent() Urls: " ;
2009-05-11 10:27:45 -04:00
std : : cerr < < std : : endl ;
QList < QUrl > urls = event - > mimeData ( ) - > urls ( ) ;
QList < QUrl > : : iterator uit ;
for ( uit = urls . begin ( ) ; uit ! = urls . end ( ) ; uit + + )
{
std : : string localpath = uit - > toLocalFile ( ) . toStdString ( ) ;
std : : cerr < < " Whole URL: " < < uit - > toString ( ) . toStdString ( ) ;
std : : cerr < < std : : endl ;
std : : cerr < < " or As Local File: " < < localpath ;
std : : cerr < < std : : endl ;
if ( localpath . size ( ) > 0 )
{
2009-05-11 10:35:50 -04:00
struct stat buf ;
//Check that the file does exist and is not a directory
if ( ( - 1 = = stat ( localpath . c_str ( ) , & buf ) ) ) {
std : : cerr < < " PopupChatDialog::dropEvent() file does not exists. " < < std : : endl ;
2009-05-14 11:54:38 -04:00
QMessageBox mb ( tr ( " Drop file error. " ) , tr ( " File not found or file name not accepted. " ) , QMessageBox : : Information , QMessageBox : : Ok , 0 , 0 ) ;
2009-05-11 10:35:50 -04:00
mb . setButtonText ( QMessageBox : : Ok , " OK " ) ;
mb . exec ( ) ;
} else if ( S_ISDIR ( buf . st_mode ) ) {
std : : cerr < < " PopupChatDialog::dropEvent() directory not accepted. " < < std : : endl ;
QMessageBox mb ( tr ( " Drop file error. " ) , tr ( " Directory can't be dropped, only files are accepted. " ) , QMessageBox : : Information , QMessageBox : : Ok , 0 , 0 ) ;
mb . setButtonText ( QMessageBox : : Ok , " OK " ) ;
mb . exec ( ) ;
} else {
PopupChatDialog : : addAttachment ( localpath ) ;
}
2009-05-11 10:27:45 -04:00
}
}
}
event - > setDropAction ( Qt : : CopyAction ) ;
event - > accept ( ) ;
}
void PopupChatDialog : : dragEnterEvent ( QDragEnterEvent * event )
{
/* print out mimeType */
std : : cerr < < " PopupChatDialog::dragEnterEvent() Formats " ;
std : : cerr < < std : : endl ;
QStringList formats = event - > mimeData ( ) - > formats ( ) ;
QStringList : : iterator it ;
for ( it = formats . begin ( ) ; it ! = formats . end ( ) ; it + + )
{
std : : cerr < < " Format: " < < ( * it ) . toStdString ( ) ;
std : : cerr < < std : : endl ;
}
if ( event - > mimeData ( ) - > hasUrls ( ) )
{
std : : cerr < < " PopupChatDialog::dragEnterEvent() Accepting Urls " ;
std : : cerr < < std : : endl ;
event - > acceptProposedAction ( ) ;
}
else
{
std : : cerr < < " PopupChatDialog::dragEnterEvent() No Urls " ;
std : : cerr < < std : : endl ;
}
}